@elytracms/studio 0.0.8 → 0.0.9
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/convex/guard.ts +16 -0
- package/convex/members.ts +14 -3
- package/dist/components/assets/asset-library.js.map +1 -1
- package/dist/components/assets/asset-metadata.js.map +1 -1
- package/dist/components/assets/asset-search.js.map +1 -1
- package/dist/components/assets/asset-selection.js.map +1 -1
- package/dist/components/assets/assets-store.js.map +1 -1
- package/dist/components/auth-context.js.map +1 -1
- package/dist/components/backend-gate.js.map +1 -1
- package/dist/components/breadcrumb-context.js.map +1 -1
- package/dist/components/builder/blocks-model.js.map +1 -1
- package/dist/components/builder/blocks-panel.js.map +1 -1
- package/dist/components/builder/builder-store.js.map +1 -1
- package/dist/components/builder/canvas-stylesheet.js.map +1 -1
- package/dist/components/builder/canvas.js.map +1 -1
- package/dist/components/builder/clipboard-actions.js.map +1 -1
- package/dist/components/builder/composition-field-editor.js.map +1 -1
- package/dist/components/builder/composition-scope.js.map +1 -1
- package/dist/components/builder/drag-session.js.map +1 -1
- package/dist/components/builder/fixture-thumbnail.js.map +1 -1
- package/dist/components/builder/inline-edit.js.map +1 -1
- package/dist/components/builder/insert-context.js.map +1 -1
- package/dist/components/builder/insert-menu.js.map +1 -1
- package/dist/components/builder/layout-inspector.js.map +1 -1
- package/dist/components/builder/node-factory.js.map +1 -1
- package/dist/components/builder/page-tree.js.map +1 -1
- package/dist/components/builder/property-inspector.js.map +1 -1
- package/dist/components/builder/rich-text-toolbar.js.map +1 -1
- package/dist/components/builder/spacing-handles.js.map +1 -1
- package/dist/components/cms/alias-selector.d.ts +20 -0
- package/dist/components/cms/alias-selector.js +34 -0
- package/dist/components/cms/alias-selector.js.map +1 -0
- package/dist/components/cms/asset-picker.js.map +1 -1
- package/dist/components/cms/bulk-actions.js.map +1 -1
- package/dist/components/cms/bulk-bar.js.map +1 -1
- package/dist/components/cms/cell-edit.js.map +1 -1
- package/dist/components/cms/cell.js.map +1 -1
- package/dist/components/cms/cms-index.js.map +1 -1
- package/dist/components/cms/cms-store.d.ts +4 -5
- package/dist/components/cms/cms-store.js +36 -13
- package/dist/components/cms/cms-store.js.map +1 -1
- package/dist/components/cms/collection-table.js +10 -2
- package/dist/components/cms/collection-table.js.map +1 -1
- package/dist/components/cms/collections-sidebar.js.map +1 -1
- package/dist/components/cms/detail-editor.js +53 -35
- package/dist/components/cms/detail-editor.js.map +1 -1
- package/dist/components/cms/doc-state.js.map +1 -1
- package/dist/components/cms/document-editor-context.js.map +1 -1
- package/dist/components/cms/editable-cell.js.map +1 -1
- package/dist/components/cms/field-control.js.map +1 -1
- package/dist/components/cms/filter-builder.js.map +1 -1
- package/dist/components/cms/import-export.js.map +1 -1
- package/dist/components/cms/issues-pane.d.ts +19 -0
- package/dist/components/cms/issues-pane.js +33 -0
- package/dist/components/cms/issues-pane.js.map +1 -0
- package/dist/components/cms/new-page-dialog.js.map +1 -1
- package/dist/components/cms/reference-confirm.js.map +1 -1
- package/dist/components/cms/relation-picker.js.map +1 -1
- package/dist/components/cms/use-cell-edit.js.map +1 -1
- package/dist/components/cms/versions-model.js.map +1 -1
- package/dist/components/cms/versions-pane.js.map +1 -1
- package/dist/components/cms/view-bar.js.map +1 -1
- package/dist/components/collab/collab-context.js.map +1 -1
- package/dist/components/collab/collab-seed.js.map +1 -1
- package/dist/components/components/component-detail.js.map +1 -1
- package/dist/components/components/component-status.js.map +1 -1
- package/dist/components/components/components-index.js.map +1 -1
- package/dist/components/components/field-inspector.js.map +1 -1
- package/dist/components/components/fixture-runner.js.map +1 -1
- package/dist/components/components/registry-browser.js.map +1 -1
- package/dist/components/current-user-menu.js.map +1 -1
- package/dist/components/delivery-health-banner.js.map +1 -1
- package/dist/components/dev-login-badge.js.map +1 -1
- package/dist/components/extensions/extensions-view.js.map +1 -1
- package/dist/components/guards.js.map +1 -1
- package/dist/components/inspector/inspector-sidebar.d.ts +2 -0
- package/dist/components/inspector/inspector-sidebar.js +1 -1
- package/dist/components/inspector/inspector-sidebar.js.map +1 -1
- package/dist/components/operation-error.js.map +1 -1
- package/dist/components/playground-badge.js.map +1 -1
- package/dist/components/project-list.js.map +1 -1
- package/dist/components/project-session.js.map +1 -1
- package/dist/components/project-switcher.js.map +1 -1
- package/dist/components/references/builder-deep-link.js.map +1 -1
- package/dist/components/references/references-panel.js.map +1 -1
- package/dist/components/routes/redirect-chain.js.map +1 -1
- package/dist/components/routes/redirect-manager.js.map +1 -1
- package/dist/components/routes/route-list.js.map +1 -1
- package/dist/components/routes/routes-shell.js.map +1 -1
- package/dist/components/section-nav.js.map +1 -1
- package/dist/components/section-state.js.map +1 -1
- package/dist/components/section-surface.js.map +1 -1
- package/dist/components/sections.js.map +1 -1
- package/dist/components/settings-form.js.map +1 -1
- package/dist/components/studio-context.js.map +1 -1
- package/dist/components/studio-project-screen.js +32 -5
- package/dist/components/studio-project-screen.js.map +1 -1
- package/dist/components/studio-shell.js.map +1 -1
- package/dist/components/theme-context.js.map +1 -1
- package/dist/components/workspace-gate.js.map +1 -1
- package/dist/components/workspace-projects.js.map +1 -1
- package/dist/lib/assets/delete-asset.js.map +1 -1
- package/dist/lib/assets/image-dimensions.js.map +1 -1
- package/dist/lib/assets/index.js.map +1 -1
- package/dist/lib/assets/upload-state.js.map +1 -1
- package/dist/lib/assets/upload.js.map +1 -1
- package/dist/lib/auth/auth-adapter.js.map +1 -1
- package/dist/lib/auth/convex-auth-adapter.js.map +1 -1
- package/dist/lib/auth/dev-auto-login-adapter.js.map +1 -1
- package/dist/lib/auth/index.js.map +1 -1
- package/dist/lib/auth/local-auth-adapter.js.map +1 -1
- package/dist/lib/auth/route-guard.js.map +1 -1
- package/dist/lib/auth-errors.js.map +1 -1
- package/dist/lib/bindings/section-bindings.js.map +1 -1
- package/dist/lib/clipboard/index.js.map +1 -1
- package/dist/lib/clipboard/os-clipboard.js.map +1 -1
- package/dist/lib/clipboard/paste-issues.js.map +1 -1
- package/dist/lib/clipboard/paste-target.js.map +1 -1
- package/dist/lib/cms/published-documents.js.map +1 -1
- package/dist/lib/cms-views/index.js.map +1 -1
- package/dist/lib/cms-views/selection.js.map +1 -1
- package/dist/lib/cms-views/view-model.js.map +1 -1
- package/dist/lib/cms-views/views-store.js.map +1 -1
- package/dist/lib/data/collection-content.js.map +1 -1
- package/dist/lib/data/data-store.js.map +1 -1
- package/dist/lib/data/index.js.map +1 -1
- package/dist/lib/data/providers.js.map +1 -1
- package/dist/lib/data/sample-capture.js.map +1 -1
- package/dist/lib/data/sources-store.js.map +1 -1
- package/dist/lib/delivery/instant-publish.js.map +1 -1
- package/dist/lib/dnd/drop-rules.js.map +1 -1
- package/dist/lib/dnd/gap-drag.js.map +1 -1
- package/dist/lib/locale/binding-fallback.js.map +1 -1
- package/dist/lib/locale/fallback.js.map +1 -1
- package/dist/lib/locale/index.js.map +1 -1
- package/dist/lib/locale/locale-store.js.map +1 -1
- package/dist/lib/locale/locale-switcher.js.map +1 -1
- package/dist/lib/locale/route-variant.js.map +1 -1
- package/dist/lib/locale/use-studio-locale.js.map +1 -1
- package/dist/lib/operations/asset-repository.js.map +1 -1
- package/dist/lib/operations/cms-persistence.js.map +1 -1
- package/dist/lib/operations/graph-commands.js.map +1 -1
- package/dist/lib/operations/graph-persistence.js.map +1 -1
- package/dist/lib/operations/index.js.map +1 -1
- package/dist/lib/operations/operations-package.js.map +1 -1
- package/dist/lib/operations/persist-queue.js.map +1 -1
- package/dist/lib/operations/session-hydration.js.map +1 -1
- package/dist/lib/operations/studio-operations.js.map +1 -1
- package/dist/lib/persistence/backend-mode.js.map +1 -1
- package/dist/lib/persistence/convex-adapter.js +8 -4
- package/dist/lib/persistence/convex-adapter.js.map +1 -1
- package/dist/lib/persistence/convex-blob-storage.js.map +1 -1
- package/dist/lib/persistence/convex-client.js.map +1 -1
- package/dist/lib/persistence/index.js.map +1 -1
- package/dist/lib/persona/labels.js +4 -0
- package/dist/lib/persona/labels.js.map +1 -1
- package/dist/lib/rail.js.map +1 -1
- package/dist/lib/references/impact.js.map +1 -1
- package/dist/lib/references/index.js.map +1 -1
- package/dist/lib/references/reference-model.js.map +1 -1
- package/dist/lib/references/references-store.js.map +1 -1
- package/dist/lib/registry/index.js.map +1 -1
- package/dist/lib/registry/preview.js.map +1 -1
- package/dist/lib/registry/project-components.js.map +1 -1
- package/dist/lib/routing/index.js.map +1 -1
- package/dist/lib/routing/routing-analysis.js.map +1 -1
- package/dist/lib/routing/routing-store.js.map +1 -1
- package/dist/lib/starters/kit-session.js.map +1 -1
- package/dist/lib/theme.js.map +1 -1
- package/dist/lib/utils.js.map +1 -1
- package/dist/lib/webhooks/config.js.map +1 -1
- package/dist/lib/webhooks/dispatcher.js.map +1 -1
- package/dist/lib/webhooks/index.js.map +1 -1
- package/dist/lib/webhooks/signing.js.map +1 -1
- package/dist/lib/webhooks/tags.js.map +1 -1
- package/dist/lib/working-graph.js.map +1 -1
- package/dist/lib/workspace/index.js.map +1 -1
- package/dist/lib/workspace/switcher-source.js.map +1 -1
- package/dist/lib/workspace/workspace-source.js.map +1 -1
- package/dist/router/index.js.map +1 -1
- package/dist/router/match.js.map +1 -1
- package/dist/router/search.js.map +1 -1
- package/dist/ui/avatar.js.map +1 -1
- package/dist/ui/badge.js.map +1 -1
- package/dist/ui/button.js.map +1 -1
- package/dist/ui/card.js.map +1 -1
- package/dist/ui/dialog.js.map +1 -1
- package/dist/ui/dropdown-menu.js.map +1 -1
- package/dist/ui/field.js.map +1 -1
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/input.js.map +1 -1
- package/dist/ui/inspector.js.map +1 -1
- package/dist/ui/layout.js.map +1 -1
- package/dist/ui/panel.js.map +1 -1
- package/dist/ui/separator.js.map +1 -1
- package/dist/ui/toast.js.map +1 -1
- package/dist/ui/toolbar.js.map +1 -1
- package/dist/ui/typography.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"studio-project-screen.js","sourceRoot":"","sources":["../../src/components/studio-project-screen.tsx"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"studio-project-screen.js","sourceRoot":"","sources":["../../src/components/studio-project-screen.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect } from 'react'\nimport type { ReactNode } from 'react'\nimport { isSingleton, resolveSingletonDocument } from '@elytracms/core/cms-core'\nimport { validSampleGraph } from '@elytracms/core/project-graph'\nimport type { Project, SectionState } from '@elytracms/core/studio-core'\nimport {\n Link,\n Navigate,\n STUDIO_PROJECT_ROUTE,\n studioPath,\n useParams,\n useSearch,\n} from '@elytracms/studio/router'\nimport { matchStudioRoute } from '@elytracms/studio/router/match'\nimport type { StudioRouteMatch } from '@elytracms/studio/router/match'\nimport { studioSearch } from '@elytracms/studio/router/search'\nimport type { StudioSearch } from '@elytracms/studio/router/search'\nimport { Button, Heading, Stack, Text } from '@elytracms/studio/ui'\nimport { DataProvider } from '@elytracms/studio/lib/data'\nimport { getInstantiatedKit } from '@elytracms/studio/lib/starters/kit-session'\nimport { useStudio } from './studio-context'\nimport { StudioShell } from './studio-shell'\nimport { firstAvailableSection } from './sections'\nimport { SectionSurface } from './section-surface'\nimport { SectionStateView } from './section-state'\nimport { SettingsForm } from './settings-form'\nimport { AssetLibrary } from './assets/asset-library'\nimport { AssetsProvider } from './assets/assets-store'\nimport { BuilderProvider } from './builder/builder-store'\nimport { CollabProvider } from './collab/collab-context'\nimport { RoutesShell } from './routes/routes-shell'\nimport { ExtensionsView } from './extensions/extensions-view'\nimport { RegistryBrowser } from './components/registry-browser'\nimport { ComponentsIndex } from './components/components-index'\nimport { ComponentDetail } from './components/component-detail'\nimport {\n CmsSessionGate,\n ProjectSessionProvider,\n useProjectSession,\n} from './project-session'\nimport { CmsProvider, useCms } from './cms/cms-store'\nimport { CollectionsSidebar } from './cms/collections-sidebar'\nimport { CmsIndex } from './cms/cms-index'\nimport { CollectionTable } from './cms/collection-table'\nimport { DetailEditor } from './cms/detail-editor'\nimport { OperationErrorBanner } from './operation-error'\n\n/**\n * EC-223 Stage 6 (catch-all routing): the studio's per-project route component.\n *\n * The consumer mounts ONE splat route (`/$projectId/$`) whose component is this.\n * Everything that was a per-project file route — the provider stack, the section\n * rail shell, and every section screen — now lives inside the package and is\n * resolved here from the URL. The consumer's route tree shrinks to a single\n * ~10-line mount, which is the whole point of Stage 6: the engine owns its\n * navigation, so an external repo consumes the studio without rebuilding a route\n * file per screen.\n *\n * `projectId` stays a real route param (the `$projectId` segment); the trailing\n * pathname (`_splat`) is matched against the engine route table\n * (`matchStudioRoute`) and the deeper ids (collection / document / component)\n * flow down as props. Every screen already takes its ids as props, so this\n * collapse is mechanical — the package never read deep params through the router;\n * the disappearing route-file wrappers did.\n */\nexport function StudioProjectScreen() {\n const params = useParams({ strict: false }) as { projectId?: string; _splat?: string }\n // The route's VALIDATED search (the splat's `validateSearch: studioSearch`).\n // Read it through `useSearch`, not `useLocation().search`: the validated search\n // is resolved at route-match time and stable from the component's first render,\n // whereas `location.search` can lag a tick during hydration — long enough for a\n // child `<Navigate>` (the builder redirect) to fire on a momentarily-empty\n // search and drop its `?page=` deep-link target.\n const rawSearch = useSearch({ strict: false }) as Record<string, unknown>\n const studio = useStudio()\n const projectId = params.projectId ?? ''\n const project = studio.getProject(projectId)\n\n // Record the active project once it resolves (preserves recents across sections).\n useEffect(() => {\n if (project) studio.activate(project.id)\n }, [project, studio])\n\n if (!project) return <ProjectNotFound />\n\n const match = matchStudioRoute(params._splat ?? '')\n const search = studioSearch(rawSearch)\n\n return (\n <StudioShell project={project}>\n {/* EC-177 gap 1: in Convex mode the session HYDRATES from persistence\n before any provider mounts — the builder boots from the latest\n persisted revision, publishing reflects the persisted state, and the\n preview content engine serves live documents. Playground renders\n synchronously from fixtures (session: null), exactly as before. */}\n <ProjectSessionProvider key={project.id} projectId={project.id}>\n <ProjectProviders project={project}>\n <StudioSectionResolver project={project} match={match} search={search} />\n </ProjectProviders>\n </ProjectSessionProvider>\n </StudioShell>\n )\n}\n\n/** The per-project provider stack, mounted once the session source is known. */\nfunction ProjectProviders({ project, children }: { project: Project; children: ReactNode }) {\n const { session } = useProjectSession()\n // A project created from a starter kit (EC-119) opens on the kit's graph —\n // but only until something is persisted: the hydrated revision wins.\n const kit = getInstantiatedKit(project.id)\n const graph = session?.graph ?? kit?.graph ?? validSampleGraph\n\n return (\n // Key by project id so the session data sources + graph reset when switching projects.\n // One canonical graph per project session: the Builder canvas and its Content tab\n // (bindings, repeating sections, template pages) read the same live graph. The data\n // store hydrates/persists this project's `cms-data-sources` records.\n <DataProvider key={project.id} projectId={project.id}>\n <BuilderProvider key={project.id} graph={graph} projectId={project.id}>\n {/* EC-195: project-level so the canvas resolves `asset`-typed Image props\n and the inspector picks from the live library — not just the Assets\n section. Asset METADATA only (small); blobs stay lazy. */}\n <AssetsProvider key={project.id} projectId={project.id}>\n <CollabProvider\n key={project.id}\n projectId={project.id}\n graph={graph}\n publish={session?.publish}\n >\n {children}\n </CollabProvider>\n </AssetsProvider>\n </BuilderProvider>\n </DataProvider>\n )\n}\n\n/**\n * The URL→screen switch (EC-223 Stage 6) — what the per-section `<Outlet />`s\n * used to resolve. Renders inside the shell + provider stack, so every screen\n * sees the same live graph, CMS store, and breadcrumb context the file routes\n * gave it. `index` and `builder` are redirect-only screens, kept here (rather\n * than short-circuited before the shell) because the retired routes nested under\n * the project layout too — they mounted the stack and then navigated, exact\n * parity.\n */\nfunction StudioSectionResolver({\n project,\n match,\n search,\n}: {\n project: Project\n match: StudioRouteMatch\n search: StudioSearch\n}) {\n const projectId = project.id\n\n switch (match.section) {\n case 'index':\n // Bare `/$projectId` → the project's first available section.\n return (\n <Navigate\n to={STUDIO_PROJECT_ROUTE}\n params={{ projectId, _splat: firstAvailableSection(project) }}\n replace\n />\n )\n\n case 'settings':\n return (\n <SectionSurface project={project} section=\"settings\" forcedState={search.state}>\n <SettingsForm project={project} />\n </SectionSurface>\n )\n\n case 'assets':\n return (\n <SectionSurface project={project} section=\"assets\" forcedState={search.state}>\n {/* The AssetsProvider is mounted at the project level (EC-195). */}\n <AssetLibrary projectId={projectId} focusAssetId={search.asset} />\n </SectionSurface>\n )\n\n case 'routes':\n // Deterministic forced states (?state=) for the surface (EC-036).\n return search.state && search.state !== 'working' ? (\n <SectionStateView state={search.state} title=\"Routes\" />\n ) : (\n <RoutesShell project={project} />\n )\n\n case 'extensions':\n return search.state && search.state !== 'working' ? (\n <SectionStateView state={search.state} title=\"Extensions\" />\n ) : (\n <ExtensionsView />\n )\n\n case 'builder':\n // Retired surface (EC-187 slice 6): a page is a document in the `page`\n // collection. A `?page=<id>` deep link lands on that document's editor;\n // otherwise the page-collection list. The page-graph-only params have no\n // home here and are dropped.\n return (\n <Navigate\n to={STUDIO_PROJECT_ROUTE}\n params={{\n projectId,\n _splat: search.page\n ? studioPath.cmsDocument('page', search.page)\n : studioPath.cmsCollection('page'),\n }}\n replace\n />\n )\n\n case 'components':\n return (\n <ComponentsScreen\n projectId={projectId}\n componentId={match.componentId}\n state={search.state}\n />\n )\n\n case 'cms':\n return (\n <CmsScreen\n project={project}\n collectionId={match.collectionId}\n documentId={match.documentId}\n state={search.state}\n field={search.field}\n />\n )\n\n case 'not-found':\n default:\n return <StudioRouteNotFound />\n }\n}\n\n/**\n * Components section (EC-050): a registry-browser sidebar beside the active\n * screen — the index (no selection) or a component's detail. Forced states\n * (?state=) replace the whole surface.\n */\nfunction ComponentsScreen({\n projectId,\n componentId,\n state,\n}: {\n projectId: string\n componentId: string | null\n state?: SectionState\n}) {\n if (state && state !== 'working') {\n return <SectionStateView state={state} title=\"Components\" />\n }\n return (\n <div className=\"flex h-full min-h-0\">\n <aside className=\"hidden h-full min-h-0 w-[300px] shrink-0 border-r border-border md:block\">\n <RegistryBrowser projectId={projectId} activeComponentId={componentId ?? undefined} />\n </aside>\n <div className=\"min-h-0 flex-1 overflow-auto\">\n {componentId === null ? (\n <ComponentsIndex projectId={projectId} />\n ) : (\n <ComponentDetail projectId={projectId} componentId={componentId} />\n )}\n </div>\n </div>\n )\n}\n\n/**\n * CMS section: hydrates the persisted (or kit-seeded) collections + documents,\n * then renders the collections sidebar beside the active screen (index, a\n * collection table, or a document editor). Forced states (?state=) replace the\n * whole surface before the provider mounts.\n */\nfunction CmsScreen({\n project,\n collectionId,\n documentId,\n state,\n field,\n}: {\n project: Project\n collectionId: string | null\n documentId: string | null\n state?: SectionState\n field?: string\n}) {\n const projectId = project.id\n if (state && state !== 'working') {\n return <SectionStateView state={state} title=\"CMS\" />\n }\n\n // A project created from a starter kit (EC-119) opens the CMS on the kit's schemas + content.\n const kit = getInstantiatedKit(projectId)\n\n return (\n // EC-177 gap 1: in Convex mode every CMS mount loads the CURRENT persisted\n // schema + documents (fixtures only when nothing is persisted — first run).\n // Playground renders synchronously with `null` → fixture seeds, as before.\n <CmsSessionGate>\n {(cms) => (\n <CmsProvider\n key={projectId}\n projectId={projectId}\n initialCollections={cms?.collections ?? kit?.collections}\n initialDocuments={cms?.documents ?? kit?.documents}\n initialPublishedKeys={cms?.publishedKeys}\n initialLocaleConfig={\n cms\n ? // Hydrated sessions follow the project's persisted locale settings.\n { default: project.settings.defaultLocale, locales: [...project.settings.locales] }\n : kit?.localeConfig\n }\n >\n <div className=\"flex h-full min-h-0 flex-col\">\n <CmsPersistErrorBanner />\n <div className=\"flex min-h-0 flex-1\">\n <aside className=\"hidden h-full min-h-0 w-[240px] shrink-0 border-r border-border md:block\">\n <CollectionsSidebar\n projectId={projectId}\n activeCollectionId={collectionId ?? undefined}\n />\n </aside>\n <div className=\"min-h-0 flex-1 overflow-hidden\">\n <CmsContent\n projectId={projectId}\n collectionId={collectionId}\n documentId={documentId}\n field={field}\n />\n </div>\n </div>\n </div>\n </CmsProvider>\n )}\n </CmsSessionGate>\n )\n}\n\n/** Resolves the active CMS screen inside the provider (needs the live store). */\nfunction CmsContent({\n projectId,\n collectionId,\n documentId,\n field,\n}: {\n projectId: string\n collectionId: string | null\n documentId: string | null\n field?: string\n}) {\n const cms = useCms()\n\n if (collectionId === null) return <CmsIndex projectId={projectId} />\n\n if (documentId === null) {\n const collection = cms.getCollection(collectionId)\n // EC-274: a singleton is a UI lens — at the collection URL it opens its one\n // document directly *while in its expected shape*, but degrades to the list\n // (with a \"for review\" lane) on drift. SingletonGate decides per the data.\n if (collection && isSingleton(collection)) {\n return <SingletonGate projectId={projectId} collectionId={collectionId} />\n }\n return <CollectionTable projectId={projectId} collectionId={collectionId} />\n }\n\n return (\n <DetailEditor\n projectId={projectId}\n collectionId={collectionId}\n documentId={documentId}\n focusPath={field}\n />\n )\n}\n\n/**\n * EC-274 — the singleton lens gate. At a singleton collection's URL, resolve its\n * lone document and open it directly; on drift (> 1 document) fall back to the\n * list with the \"for review\" lane so an editor can resolve the conflict. The one\n * document keeps a normal id — nothing here names a literal document id.\n */\nfunction SingletonGate({ projectId, collectionId }: { projectId: string; collectionId: string }) {\n const cms = useCms()\n const collection = cms.getCollection(collectionId)\n const docs = cms.documentsOf(collectionId)\n const resolution = collection\n ? resolveSingletonDocument(collection, docs)\n : ({ kind: 'empty' } as const)\n\n // Materialize the lone document on first visit (an empty draft, persisted like\n // any create). Idempotent in the store; only fires while genuinely empty.\n useEffect(() => {\n if (resolution.kind === 'empty') cms.ensureSingletonDocument(collectionId)\n }, [resolution.kind, cms, collectionId])\n\n if (resolution.kind === 'ready') {\n return (\n <DetailEditor projectId={projectId} collectionId={collectionId} documentId={resolution.doc.id} />\n )\n }\n if (resolution.kind === 'drift') {\n return <CollectionTable projectId={projectId} collectionId={collectionId} />\n }\n return (\n <div className=\"grid h-full place-items-center p-8\">\n <Text size=\"sm\" tone=\"muted\">\n Opening {collection?.form?.label ?? collectionId}…\n </Text>\n </div>\n )\n}\n\n/** Failed/denied persisted CMS mutations are always visible (EC-141). */\nfunction CmsPersistErrorBanner() {\n const cms = useCms()\n if (!cms.persistError) return null\n return (\n <div className=\"shrink-0 border-b border-border p-2\">\n <OperationErrorBanner error={cms.persistError} onDismiss={cms.clearPersistError} />\n </div>\n )\n}\n\nfunction ProjectNotFound() {\n return (\n <div className=\"grid min-h-dvh place-items-center p-8\">\n <Stack gap=\"3\" align=\"center\" className=\"max-w-sm text-center\">\n <Heading size=\"display\">Project not found</Heading>\n <Text tone=\"muted\">\n This project doesn’t exist or was deleted. It may only have existed in this session.\n </Text>\n <Button asChild>\n <Link to=\"/\">Back to projects</Link>\n </Button>\n </Stack>\n </div>\n )\n}\n\nfunction StudioRouteNotFound() {\n return (\n <div className=\"grid h-full place-items-center p-8\">\n <Stack gap=\"2\" align=\"center\" className=\"max-w-sm text-center\">\n <Heading level={2} size=\"h2\">\n Page not found\n </Heading>\n <Text tone=\"muted\">This studio URL doesn’t resolve to a section.</Text>\n </Stack>\n </div>\n )\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"studio-shell.js","sourceRoot":"","sources":["../../src/components/studio-shell.tsx"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"studio-shell.js","sourceRoot":"","sources":["../../src/components/studio-shell.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Link, STUDIO_PROJECT_ROUTE, useLocation } from '@elytracms/studio/router'\nimport { ChevronRight } from 'lucide-react'\nimport { useCallback, useEffect, useState } from 'react'\nimport type { ReactNode } from 'react'\nimport type { Project, ProjectId } from '@elytracms/core/studio-core'\nimport { Row, Spacer, Text, Toaster } from '@elytracms/studio/ui'\nimport { readRailCollapsed, storeRailCollapsed } from '@elytracms/studio/lib/rail'\nimport { CurrentUserMenu } from './current-user-menu'\nimport { DeliveryHealthBanner } from './delivery-health-banner'\nimport { PlaygroundBadge } from './playground-badge'\nimport { DevLoginBadge } from './dev-login-badge'\nimport { ProjectSwitcher } from './project-switcher'\nimport { SectionNav } from './section-nav'\nimport { activeSectionFromPath, sectionNavItem } from './sections'\nimport type { StudioNavId } from './sections'\nimport { BreadcrumbProvider, useBreadcrumbTrail } from './breadcrumb-context'\n\nexport interface StudioShellProps {\n project: Project\n children: ReactNode\n}\n\n/**\n * The Studio shell (brief §4.3, §8.1): a persistent top bar + section rail that\n * preserve the active project while the user moves between surfaces. The top bar\n * carries the single global breadcrumb reaching the active record (EC-214) — no\n * secondary band, no per-view title repeating the section. Responsive and\n * overflow-safe.\n */\nexport function StudioShell({ project, children }: StudioShellProps) {\n const { pathname } = useLocation()\n const activeSection = activeSectionFromPath(pathname)\n\n // User-toggled, persisted rail collapse (EC-214). Defaults to expanded; the\n // stored preference is read after mount (no flash script needed for a rail).\n const [railCollapsed, setRailCollapsed] = useState(false)\n useEffect(() => {\n setRailCollapsed(readRailCollapsed())\n }, [])\n const toggleRail = useCallback(() => {\n setRailCollapsed((prev) => {\n const next = !prev\n storeRailCollapsed(next)\n return next\n })\n }, [])\n\n return (\n <BreadcrumbProvider>\n <div className=\"flex h-dvh flex-col bg-background\">\n {/* Top bar — global controls + the one breadcrumb to the active record. */}\n <header className=\"flex h-12 shrink-0 items-center gap-2 border-b border-border px-3\">\n <Link to=\"/\" className=\"grid size-6 shrink-0 place-items-center\" aria-label=\"All projects\">\n <span className=\"size-5 rounded-[5px] bg-primary shadow-sm\" />\n </Link>\n <ProjectSwitcher activeProject={project} />\n <HeaderBreadcrumb projectId={project.id} activeSection={activeSection} />\n <Spacer />\n {/* EC-153: explicit playground-mode marker (renders nothing on Convex). */}\n <PlaygroundBadge />\n {/* Dev-only unattended-auth marker (renders nothing in prod / when unset). */}\n <DevLoginBadge />\n {/* EC-150: signed-in user + their role on this project + sign-out. */}\n <CurrentUserMenu projectId={project.id} />\n </header>\n\n {/* EC-268: warns when instant-publish env is incomplete (connected mode only). */}\n <DeliveryHealthBanner />\n\n <div className=\"flex min-h-0 flex-1\">\n <SectionNav\n projectId={project.id}\n activeSection={activeSection}\n availability={project.settings.sectionAvailability}\n collapsed={railCollapsed}\n onToggleCollapsed={toggleRail}\n />\n\n <main className=\"flex min-w-0 flex-1 flex-col overflow-hidden\">\n <div className=\"min-h-0 flex-1 overflow-auto\">{children}</div>\n </main>\n </div>\n </div>\n {/* EC-268: transient action feedback (e.g. a publish that fails at transport). */}\n <Toaster />\n </BreadcrumbProvider>\n )\n}\n\nconst CRUMB_LINK =\n 'max-w-[12rem] truncate text-muted-foreground transition-colors hover:text-foreground'\nconst CRUMB_CURRENT = 'max-w-[16rem] truncate font-medium text-foreground'\n\n/**\n * The single global breadcrumb (EC-214): project (the switcher) › section › …the\n * active record. The section crumb is shell-owned; deeper crumbs are contributed\n * by the active surface via {@link useBreadcrumbTrail}. The last crumb is the\n * current page (plain text); earlier crumbs link back.\n */\nfunction HeaderBreadcrumb({\n projectId,\n activeSection,\n}: {\n projectId: ProjectId\n activeSection: StudioNavId | null\n}) {\n const extra = useBreadcrumbTrail()\n if (!activeSection) return null\n const sectionIsLast = extra.length === 0\n\n return (\n <Row gap=\"1\" className=\"min-w-0 text-sm\" aria-label=\"Breadcrumb\">\n <ChevronRight className=\"size-3.5 shrink-0 text-muted-foreground/50\" aria-hidden />\n {sectionIsLast ? (\n <span className={CRUMB_CURRENT}>{sectionNavItem(activeSection).label}</span>\n ) : (\n <Link\n to={STUDIO_PROJECT_ROUTE}\n params={{ projectId, _splat: activeSection }}\n className={CRUMB_LINK}\n >\n {sectionNavItem(activeSection).label}\n </Link>\n )}\n {extra.map((item, index) => {\n const isLast = index === extra.length - 1\n return (\n <Row gap=\"1\" key={`${item.label}-${index}`} className=\"min-w-0\">\n <ChevronRight className=\"size-3.5 shrink-0 text-muted-foreground/50\" aria-hidden />\n {!isLast && item.to ? (\n // `to` and `params` are always contributed as a unit (the type\n // pairs them); the assertion satisfies the route's required params.\n <Link to={item.to} params={item.params!} className={CRUMB_LINK}>\n {item.label}\n </Link>\n ) : (\n <span className={isLast ? CRUMB_CURRENT : CRUMB_LINK}>{item.label}</span>\n )}\n </Row>\n )\n })}\n </Row>\n )\n}\n\n/** Small inline helper used by section surfaces that want a consistent empty hint. */\nexport function SurfaceHint({ children }: { children: ReactNode }) {\n return (\n <Text size=\"sm\" tone=\"muted\" className=\"px-1\">\n {children}\n </Text>\n )\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme-context.js","sourceRoot":"","sources":["../../src/components/theme-context.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAE5F,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AAepG,MAAM,YAAY,GAAG,aAAa,CAAoB,IAAI,CAAC,CAAA;AAE3D,MAAM,UAAU,aAAa,CAAC,EAAE,QAAQ,EAA2B;IACjE,MAAM,CAAC,KAAK,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAQ,aAAa,CAAC,CAAA;IAE7D,mEAAmE;IACnE,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,MAAM,GAAG,eAAe,EAAE,CAAA;QAChC,aAAa,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAA;IACnG,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,IAAW,EAAE,EAAE;QAC3C,aAAa,CAAC,IAAI,CAAC,CAAA;QACnB,UAAU,CAAC,IAAI,CAAC,CAAA;QAChB,UAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAA;IAC5C,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,MAAM,KAAK,GAAG,OAAO,CACnB,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EACxF,CAAC,KAAK,EAAE,QAAQ,CAAC,CAClB,CAAA;IAED,OAAO,KAAC,YAAY,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YAAG,QAAQ,GAAyB,CAAA;AAChF,CAAC;AAED,MAAM,UAAU,QAAQ;IACtB,MAAM,KAAK,GAAG,UAAU,CAAC,YAAY,CAAC,CAAA;IACtC,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAA;IAC9E,OAAO,KAAK,CAAA;AACd,CAAC"}
|
|
1
|
+
{"version":3,"file":"theme-context.js","sourceRoot":"","sources":["../../src/components/theme-context.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAE5F,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AAepG,MAAM,YAAY,GAAG,aAAa,CAAoB,IAAI,CAAC,CAAA;AAE3D,MAAM,UAAU,aAAa,CAAC,EAAE,QAAQ,EAA2B;IACjE,MAAM,CAAC,KAAK,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAQ,aAAa,CAAC,CAAA;IAE7D,mEAAmE;IACnE,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,MAAM,GAAG,eAAe,EAAE,CAAA;QAChC,aAAa,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAA;IACnG,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,IAAW,EAAE,EAAE;QAC3C,aAAa,CAAC,IAAI,CAAC,CAAA;QACnB,UAAU,CAAC,IAAI,CAAC,CAAA;QAChB,UAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAA;IAC5C,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,MAAM,KAAK,GAAG,OAAO,CACnB,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EACxF,CAAC,KAAK,EAAE,QAAQ,CAAC,CAClB,CAAA;IAED,OAAO,KAAC,YAAY,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YAAG,QAAQ,GAAyB,CAAA;AAChF,CAAC;AAED,MAAM,UAAU,QAAQ;IACtB,MAAM,KAAK,GAAG,UAAU,CAAC,YAAY,CAAC,CAAA;IACtC,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAA;IAC9E,OAAO,KAAK,CAAA;AACd,CAAC","sourcesContent":["import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react'\nimport type { ReactNode } from 'react'\nimport { DEFAULT_THEME, applyTheme, readStoredTheme, storeTheme } from '@elytracms/studio/lib/theme'\nimport type { Theme } from '@elytracms/studio/lib/theme'\n\n/**\n * Theme store: owns the active light/dark theme, persists the choice, and keeps\n * the `dark` class on the document element in sync. The pre-hydration script\n * (THEME_INIT_SCRIPT) sets the initial class; this provider syncs React state to\n * it on mount so toggling is reactive.\n */\nexport interface ThemeStore {\n theme: Theme\n setTheme: (theme: Theme) => void\n toggle: () => void\n}\n\nconst ThemeContext = createContext<ThemeStore | null>(null)\n\nexport function ThemeProvider({ children }: { children: ReactNode }) {\n const [theme, setThemeState] = useState<Theme>(DEFAULT_THEME)\n\n // Sync state to whatever the pre-hydration script already applied.\n useEffect(() => {\n const stored = readStoredTheme()\n setThemeState(stored ?? (document.documentElement.classList.contains('dark') ? 'dark' : 'light'))\n }, [])\n\n const setTheme = useCallback((next: Theme) => {\n setThemeState(next)\n storeTheme(next)\n applyTheme(next, document.documentElement)\n }, [])\n\n const store = useMemo<ThemeStore>(\n () => ({ theme, setTheme, toggle: () => setTheme(theme === 'dark' ? 'light' : 'dark') }),\n [theme, setTheme],\n )\n\n return <ThemeContext.Provider value={store}>{children}</ThemeContext.Provider>\n}\n\nexport function useTheme(): ThemeStore {\n const store = useContext(ThemeContext)\n if (!store) throw new Error('useTheme must be used within a <ThemeProvider>.')\n return store\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-gate.js","sourceRoot":"","sources":["../../src/components/workspace-gate.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAA;AAClG,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAA;AAGnE;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,EAAE,QAAQ,EAA2B;IACjE,MAAM,SAAS,GAAG,iBAAiB,EAAE,CAAA;IACrC,IAAI,SAAS,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,KAAC,0BAA0B,IAAC,SAAS,EAAE,SAAS,GAAI,CAAA;IAC7F,OAAO,4BAAG,QAAQ,GAAI,CAAA;AACxB,CAAC;AAED,SAAS,0BAA0B,CAAC,EAClC,SAAS,GAGV;IACC,OAAO,CACL,cAAK,SAAS,EAAC,qDAAqD,YAClE,MAAC,IAAI,IAAC,SAAS,EAAC,iCAAiC,aAC/C,KAAC,UAAU,cACT,KAAC,SAAS,8CAAwC,GACvC,EACb,KAAC,WAAW,cACV,MAAC,KAAK,IAAC,GAAG,EAAC,GAAG,aACZ,MAAC,IAAI,IAAC,IAAI,EAAC,IAAI,EAAC,IAAI,EAAC,OAAO,2DACgB,KAAC,IAAI,cAAE,SAAS,CAAC,MAAM,GAAQ,0JAGpE,EACP,KAAC,KAAK,IAAC,GAAG,EAAC,GAAG,EAAC,IAAI,EAAC,MAAM,gBAAY,yBAAyB,YAC5D,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CACtC,KAAC,kBAAkB,IAEjB,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,OAAO,EAAE,KAAK,CAAC,OAAO,EACtB,QAAQ,EAAE,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,IAHhC,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,EAAE,CAI7B,CACH,CAAC,GACI,EACR,MAAC,IAAI,IAAC,IAAI,EAAC,IAAI,EAAC,IAAI,EAAC,OAAO,uCACJ,KAAC,IAAI,gDAA2C,yEAEjE,IACD,GACI,IACT,GACH,CACP,CAAA;AACH,CAAC;AAED,SAAS,kBAAkB,CAAC,EAC1B,IAAI,EACJ,OAAO,EACP,QAAQ,GAKT;IACC,OAAO,CACL,eAAK,IAAI,EAAC,UAAU,EAAC,SAAS,EAAC,8DAA8D,aAC3F,MAAC,IAAI,IAAC,IAAI,EAAC,IAAI,EAAC,IAAI,QAAC,SAAS,EAAC,kBAAkB,kBAC7C,IAAI,OAAG,QAAQ,CAAC,CAAC,CAAC,OAAO,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,IACrC,EACP,KAAC,IAAI,IAAC,IAAI,EAAC,IAAI,YAAE,OAAO,GAAQ,IAC5B,CACP,CAAA;AACH,CAAC;AAED,SAAS,eAAe,CAAC,IAAoC;IAC3D,OAAO,IAAI,CAAC,MAAM,CAChB,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAC7F,EAAE,CACH,CAAA;AACH,CAAC"}
|
|
1
|
+
{"version":3,"file":"workspace-gate.js","sourceRoot":"","sources":["../../src/components/workspace-gate.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAA;AAClG,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAA;AAGnE;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,EAAE,QAAQ,EAA2B;IACjE,MAAM,SAAS,GAAG,iBAAiB,EAAE,CAAA;IACrC,IAAI,SAAS,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,KAAC,0BAA0B,IAAC,SAAS,EAAE,SAAS,GAAI,CAAA;IAC7F,OAAO,4BAAG,QAAQ,GAAI,CAAA;AACxB,CAAC;AAED,SAAS,0BAA0B,CAAC,EAClC,SAAS,GAGV;IACC,OAAO,CACL,cAAK,SAAS,EAAC,qDAAqD,YAClE,MAAC,IAAI,IAAC,SAAS,EAAC,iCAAiC,aAC/C,KAAC,UAAU,cACT,KAAC,SAAS,8CAAwC,GACvC,EACb,KAAC,WAAW,cACV,MAAC,KAAK,IAAC,GAAG,EAAC,GAAG,aACZ,MAAC,IAAI,IAAC,IAAI,EAAC,IAAI,EAAC,IAAI,EAAC,OAAO,2DACgB,KAAC,IAAI,cAAE,SAAS,CAAC,MAAM,GAAQ,0JAGpE,EACP,KAAC,KAAK,IAAC,GAAG,EAAC,GAAG,EAAC,IAAI,EAAC,MAAM,gBAAY,yBAAyB,YAC5D,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CACtC,KAAC,kBAAkB,IAEjB,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,OAAO,EAAE,KAAK,CAAC,OAAO,EACtB,QAAQ,EAAE,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,IAHhC,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,EAAE,CAI7B,CACH,CAAC,GACI,EACR,MAAC,IAAI,IAAC,IAAI,EAAC,IAAI,EAAC,IAAI,EAAC,OAAO,uCACJ,KAAC,IAAI,gDAA2C,yEAEjE,IACD,GACI,IACT,GACH,CACP,CAAA;AACH,CAAC;AAED,SAAS,kBAAkB,CAAC,EAC1B,IAAI,EACJ,OAAO,EACP,QAAQ,GAKT;IACC,OAAO,CACL,eAAK,IAAI,EAAC,UAAU,EAAC,SAAS,EAAC,8DAA8D,aAC3F,MAAC,IAAI,IAAC,IAAI,EAAC,IAAI,EAAC,IAAI,QAAC,SAAS,EAAC,kBAAkB,kBAC7C,IAAI,OAAG,QAAQ,CAAC,CAAC,CAAC,OAAO,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,IACrC,EACP,KAAC,IAAI,IAAC,IAAI,EAAC,IAAI,YAAE,OAAO,GAAQ,IAC5B,CACP,CAAA;AACH,CAAC;AAED,SAAS,eAAe,CAAC,IAAoC;IAC3D,OAAO,IAAI,CAAC,MAAM,CAChB,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAC7F,EAAE,CACH,CAAA;AACH,CAAC","sourcesContent":["import type { ReactNode } from 'react'\nimport { Card, CardContent, CardHeader, CardTitle, Code, Stack, Text } from '@elytracms/studio/ui'\nimport { getWorkspaceState } from '@elytracms/studio/lib/workspace'\nimport type { WorkspaceState } from '@elytracms/studio/lib/workspace'\n\n/**\n * Workspace-config boot gate (EC-154) — sibling of the EC-153 `BackendGate`.\n * The workspace config is static boot input (bundled `elytra.config.ts` or\n * env-injected JSON), so an *invalid* config is a deterministic boot-error\n * state rendered before auth and the studio store: structured, file-located\n * issues — never a silent fall-back to unconfigured behavior. No config and a\n * valid config render children untouched.\n */\nexport function WorkspaceGate({ children }: { children: ReactNode }) {\n const workspace = getWorkspaceState()\n if (workspace.kind === 'invalid') return <WorkspaceConfigErrorScreen workspace={workspace} />\n return <>{children}</>\n}\n\nfunction WorkspaceConfigErrorScreen({\n workspace,\n}: {\n workspace: Extract<WorkspaceState, { kind: 'invalid' }>\n}) {\n return (\n <div className=\"grid min-h-dvh place-items-center bg-background p-6\">\n <Card className=\"max-w-2xl border-destructive/40\">\n <CardHeader>\n <CardTitle>Workspace config is invalid</CardTitle>\n </CardHeader>\n <CardContent>\n <Stack gap=\"3\">\n <Text size=\"sm\" tone=\"muted\">\n The studio loaded a workspace config from <Code>{workspace.source}</Code>, but it\n failed validation. Fix the issues below and reload — the studio never falls back to\n unconfigured behavior while a config is present.\n </Text>\n <Stack gap=\"2\" role=\"list\" aria-label=\"Workspace config issues\">\n {workspace.issues.map((issue, index) => (\n <WorkspaceIssueLine\n key={`${issue.code}-${index}`}\n code={issue.code}\n message={issue.message}\n location={formatIssuePath(issue.path)}\n />\n ))}\n </Stack>\n <Text size=\"xs\" tone=\"muted\">\n Validate locally with <Code>builder init --project <slug></Code> — the CLI runs\n the same schema and reports the same issues.\n </Text>\n </Stack>\n </CardContent>\n </Card>\n </div>\n )\n}\n\nfunction WorkspaceIssueLine({\n code,\n message,\n location,\n}: {\n code: string\n message: string\n location: string\n}) {\n return (\n <div role=\"listitem\" className=\"rounded-md border border-destructive/30 bg-destructive/5 p-2\">\n <Text size=\"xs\" mono className=\"text-destructive\">\n [{code}]{location ? ` at ${location}` : ''}\n </Text>\n <Text size=\"sm\">{message}</Text>\n </div>\n )\n}\n\nfunction formatIssuePath(path: ReadonlyArray<string | number>): string {\n return path.reduce<string>(\n (acc, part) => (typeof part === 'number' ? `${acc}[${part}]` : acc ? `${acc}.${part}` : part),\n '',\n )\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-projects.js","sourceRoot":"","sources":["../../src/components/workspace-projects.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAC/B,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAA;AAE3F,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAE5C;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAC1B,MAAM,SAAS,GAAG,iBAAiB,EAAE,CAAA;IACrC,MAAM,OAAO,GAAG,OAAO,CACrB,GAAG,EAAE,CAAC,sBAAsB,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,EACvE,CAAC,SAAS,EAAE,MAAM,CAAC,QAAQ,CAAC,CAC7B,CAAA;IACD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,CAAA;AAC/B,CAAC"}
|
|
1
|
+
{"version":3,"file":"workspace-projects.js","sourceRoot":"","sources":["../../src/components/workspace-projects.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAC/B,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAA;AAE3F,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAE5C;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAC1B,MAAM,SAAS,GAAG,iBAAiB,EAAE,CAAA;IACrC,MAAM,OAAO,GAAG,OAAO,CACrB,GAAG,EAAE,CAAC,sBAAsB,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,EACvE,CAAC,SAAS,EAAE,MAAM,CAAC,QAAQ,CAAC,CAC7B,CAAA;IACD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,CAAA;AAC/B,CAAC","sourcesContent":["import { useMemo } from 'react'\nimport { getWorkspaceState, selectSwitcherProjects } from '@elytracms/studio/lib/workspace'\nimport type { SwitcherEntry, WorkspaceState } from '@elytracms/studio/lib/workspace'\nimport { useStudio } from './studio-context'\n\n/**\n * Config-driven project source for the switcher + launcher (EC-154, reframed for\n * EC-179). The decision logic is the pure `selectSwitcherProjects`; this hook\n * wires it to the studio store (config-derived read model) and the workspace\n * state. Visibility is config-driven and NOT membership-filtered — one project\n * per backend, so access is enforced per-backend on entry (sign-in + role hook),\n * never by hiding a project you would authenticate into.\n */\nexport function useSwitcherEntries(): { entries: SwitcherEntry[]; workspace: WorkspaceState } {\n const studio = useStudio()\n const workspace = getWorkspaceState()\n const entries = useMemo(\n () => selectSwitcherProjects({ workspace, persisted: studio.projects }),\n [workspace, studio.projects],\n )\n return { entries, workspace }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delete-asset.js","sourceRoot":"","sources":["../../../src/lib/assets/delete-asset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AAoCjE,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,IAAqB,EACrB,SAAiB,EACjB,OAAe,EACf,UAA8B,EAAE;IAEhC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;QAC7D,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,CAAA;QAE3C,MAAM,UAAU,GAAG,MAAM,eAAe,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAA;QAClE,IAAI,UAAU,GAAG,CAAC,IAAI,OAAO,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;YACpD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,CAAA;QAC3C,CAAC;QAED,yEAAyE;QACzE,8DAA8D;QAC9D,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;QACzC,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;QACjD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,CAAA;IAC/B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,mBAAmB;YAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,CAAA;QACzE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAA;IAC9F,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,eAAe,CAC5B,IAAqB,EACrB,SAAiB,EACjB,OAAe;IAEf,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAA;IACxF,MAAM,QAAQ,GAAG,IAAI,GAAG,CACtB,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAChF,CAAA;IACD,OAAO,QAAQ,CAAC,IAAI,CAAA;AACtB,CAAC"}
|
|
1
|
+
{"version":3,"file":"delete-asset.js","sourceRoot":"","sources":["../../../src/lib/assets/delete-asset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AAoCjE,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,IAAqB,EACrB,SAAiB,EACjB,OAAe,EACf,UAA8B,EAAE;IAEhC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;QAC7D,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,CAAA;QAE3C,MAAM,UAAU,GAAG,MAAM,eAAe,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAA;QAClE,IAAI,UAAU,GAAG,CAAC,IAAI,OAAO,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;YACpD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,CAAA;QAC3C,CAAC;QAED,yEAAyE;QACzE,8DAA8D;QAC9D,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;QACzC,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;QACjD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,CAAA;IAC/B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,mBAAmB;YAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,CAAA;QACzE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAA;IAC9F,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,eAAe,CAC5B,IAAqB,EACrB,SAAiB,EACjB,OAAe;IAEf,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAA;IACxF,MAAM,QAAQ,GAAG,IAAI,GAAG,CACtB,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAChF,CAAA;IACD,OAAO,QAAQ,CAAC,IAAI,CAAA;AACtB,CAAC","sourcesContent":["import { RecordNotFoundError } from '@elytracms/core/persistence'\nimport type {\n AssetRepository,\n BlobStorageAdapter,\n ReferenceIndexRepository,\n} from '@elytracms/core/persistence'\n\n/**\n * Reference-respecting asset deletion (EC-151, reworked EC-202). Deleting an\n * asset that is referenced is blocked until explicitly confirmed; the usage\n * count comes from the **EC-155 reference index** (`references.inbound` for the\n * `{ type: 'asset' }` target) — index-accurate, replacing the interim string\n * scan (`find-asset-usages`), which could miss rich-text asset hrefs and\n * false-positive on unrelated strings. Deleting an unused asset removes bytes\n * (blob) AND the metadata record. Results are structured data — never throws.\n */\n\nexport interface DeleteAssetDeps {\n assets: AssetRepository\n blobs: BlobStorageAdapter\n /** The EC-155 reference index — the accurate inbound-usage source (EC-202). */\n references: Pick<ReferenceIndexRepository, 'inbound'>\n}\n\nexport type DeleteAssetResult =\n | { outcome: 'deleted' }\n /** The asset is referenced and `confirmInUse` was not set: nothing was removed. */\n | { outcome: 'blocked'; usageCount: number }\n | { outcome: 'not-found' }\n | { outcome: 'error'; message: string }\n\nexport interface DeleteAssetOptions {\n /** Caller has seen the usage count and explicitly confirmed deletion. */\n confirmInUse?: boolean\n}\n\nexport async function deleteAsset(\n deps: DeleteAssetDeps,\n projectId: string,\n assetId: string,\n options: DeleteAssetOptions = {},\n): Promise<DeleteAssetResult> {\n try {\n const asset = await deps.assets.findAsset(projectId, assetId)\n if (!asset) return { outcome: 'not-found' }\n\n const usageCount = await assetUsageCount(deps, projectId, assetId)\n if (usageCount > 0 && options.confirmInUse !== true) {\n return { outcome: 'blocked', usageCount }\n }\n\n // Bytes first, metadata last: a failure midway leaves a visible metadata\n // record (re-deletable) rather than invisible orphaned bytes.\n await deps.blobs.delete(asset.storageKey)\n await deps.assets.removeAsset(projectId, assetId)\n return { outcome: 'deleted' }\n } catch (error) {\n if (error instanceof RecordNotFoundError) return { outcome: 'not-found' }\n return { outcome: 'error', message: error instanceof Error ? error.message : String(error) }\n }\n}\n\n/**\n * Distinct inbound usages of an asset from the reference index (EC-202). One\n * `source + path` (e.g. `post:hello · values/cover`) can carry both a draft and\n * a published index entry — that is a single usage, so variants collapse before\n * counting (the gate is \"is this referenced\", not \"how many index rows\").\n */\nasync function assetUsageCount(\n deps: DeleteAssetDeps,\n projectId: string,\n assetId: string,\n): Promise<number> {\n const inbound = await deps.references.inbound(projectId, { type: 'asset', id: assetId })\n const distinct = new Set(\n inbound.map((entry) => `${entry.source.type}:${entry.source.id}:${entry.path}`),\n )\n return distinct.size\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image-dimensions.js","sourceRoot":"","sources":["../../../src/lib/assets/image-dimensions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,IAA6B,EAC7B,eAA0C,OAAO,iBAAiB,KAAK,UAAU;IAC/E,CAAC,CAAC,iBAAiB;IACnB,CAAC,CAAC,SAAS;IAEb,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,SAAS,CAAA;IACrD,IAAI,CAAC,YAAY;QAAE,OAAO,SAAS,CAAA;IACnC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAA;QACvC,MAAM,UAAU,GACd,MAAM,CAAC,KAAK,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;YACnC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;YAChD,CAAC,CAAC,SAAS,CAAA;QACf,MAAM,CAAC,KAAK,EAAE,EAAE,CAAA;QAChB,OAAO,UAAU,CAAA;IACnB,CAAC;IAAC,MAAM,CAAC;QACP,wEAAwE;QACxE,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC"}
|
|
1
|
+
{"version":3,"file":"image-dimensions.js","sourceRoot":"","sources":["../../../src/lib/assets/image-dimensions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,IAA6B,EAC7B,eAA0C,OAAO,iBAAiB,KAAK,UAAU;IAC/E,CAAC,CAAC,iBAAiB;IACnB,CAAC,CAAC,SAAS;IAEb,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,SAAS,CAAA;IACrD,IAAI,CAAC,YAAY;QAAE,OAAO,SAAS,CAAA;IACnC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAA;QACvC,MAAM,UAAU,GACd,MAAM,CAAC,KAAK,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;YACnC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;YAChD,CAAC,CAAC,SAAS,CAAA;QACf,MAAM,CAAC,KAAK,EAAE,EAAE,CAAA;QAChB,OAAO,UAAU,CAAA;IACnB,CAAC;IAAC,MAAM,CAAC;QACP,wEAAwE;QACxE,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC","sourcesContent":["/**\n * Client-side image dimension detection (EC-151). Uses `createImageBitmap`\n * when available (injectable for tests); failure is never fatal — an asset\n * without detectable dimensions simply stores no width/height.\n */\n\nexport interface ImageDimensions {\n width: number\n height: number\n}\n\ntype BitmapFactory = (blob: Blob) => Promise<{ width: number; height: number; close?: () => void }>\n\nexport async function detectImageDimensions(\n file: Blob & { type: string },\n createBitmap: BitmapFactory | undefined = typeof createImageBitmap === 'function'\n ? createImageBitmap\n : undefined,\n): Promise<ImageDimensions | undefined> {\n if (!file.type.startsWith('image/')) return undefined\n if (!createBitmap) return undefined\n try {\n const bitmap = await createBitmap(file)\n const dimensions =\n bitmap.width > 0 && bitmap.height > 0\n ? { width: bitmap.width, height: bitmap.height }\n : undefined\n bitmap.close?.()\n return dimensions\n } catch {\n // Undecodable image (corrupt bytes, unsupported format) — not an error.\n return undefined\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/assets/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,gBAAgB,CAAA;AAC9B,cAAc,oBAAoB,CAAA;AAClC,cAAc,UAAU,CAAA;AACxB,cAAc,gBAAgB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/assets/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,gBAAgB,CAAA;AAC9B,cAAc,oBAAoB,CAAA;AAClC,cAAc,UAAU,CAAA;AACxB,cAAc,gBAAgB,CAAA","sourcesContent":["/**\n * Asset upload, deletion, and usage logic (EC-151). Pure/injectable modules:\n * the studio UI consumes these; storage is reached only through the\n * `BlobStorageAdapter` boundary.\n */\nexport * from './upload-state'\nexport * from './image-dimensions'\nexport * from './upload'\nexport * from './delete-asset'\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload-state.js","sourceRoot":"","sources":["../../../src/lib/assets/upload-state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAkCH,MAAM,CAAC,MAAM,kBAAkB,GAAgB,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAA;AAEzF,MAAM,OAAO,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAE7F;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAAkB,EAAE,KAAkB;IAClE,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,OAAO;YACV,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM;gBAAE,OAAO,KAAK,CAAA;YACxC,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAA;QACxD,KAAK,WAAW;YACd,IAAI,KAAK,CAAC,KAAK,KAAK,WAAW;gBAAE,OAAO,KAAK,CAAA;YAC7C,OAAO,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAA;QACtD,KAAK,UAAU;YACb,IAAI,KAAK,CAAC,KAAK,KAAK,WAAW;gBAAE,OAAO,KAAK,CAAA;YAC7C,OAAO,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QAC1F,KAAK,aAAa;YAChB,IAAI,KAAK,CAAC,KAAK,KAAK,WAAW,IAAI,KAAK,CAAC,KAAK,KAAK,WAAW;gBAAE,OAAO,KAAK,CAAA;YAC5E,OAAO,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAA;QACvD,KAAK,WAAW;YACd,IAAI,KAAK,CAAC,KAAK,KAAK,YAAY;gBAAE,OAAO,KAAK,CAAA;YAC9C,OAAO,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAA;QACzE,KAAK,QAAQ;YACX,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM;gBAAE,OAAO,KAAK,CAAA;YAClE,OAAO;gBACL,GAAG,KAAK;gBACR,KAAK,EAAE,QAAQ;gBACf,OAAO,EAAE;oBACP,KAAK,EAAE,KAAK,CAAC,KAAK;oBAClB,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI;iBACnC;aACF,CAAA;QACH,KAAK,OAAO;YACV,IAAI,KAAK,CAAC,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,EAAE,SAAS,KAAK,KAAK;gBAAE,OAAO,KAAK,CAAA;YAChF,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,GAAG,CAAC,EAAE,CAAA;QACxE,KAAK,OAAO;YACV,OAAO,kBAAkB,CAAA;QAC3B,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,KAAK,GAAU,KAAK,CAAA;YAC1B,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
1
|
+
{"version":3,"file":"upload-state.js","sourceRoot":"","sources":["../../../src/lib/assets/upload-state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAkCH,MAAM,CAAC,MAAM,kBAAkB,GAAgB,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAA;AAEzF,MAAM,OAAO,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAE7F;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAAkB,EAAE,KAAkB;IAClE,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,OAAO;YACV,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM;gBAAE,OAAO,KAAK,CAAA;YACxC,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAA;QACxD,KAAK,WAAW;YACd,IAAI,KAAK,CAAC,KAAK,KAAK,WAAW;gBAAE,OAAO,KAAK,CAAA;YAC7C,OAAO,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAA;QACtD,KAAK,UAAU;YACb,IAAI,KAAK,CAAC,KAAK,KAAK,WAAW;gBAAE,OAAO,KAAK,CAAA;YAC7C,OAAO,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QAC1F,KAAK,aAAa;YAChB,IAAI,KAAK,CAAC,KAAK,KAAK,WAAW,IAAI,KAAK,CAAC,KAAK,KAAK,WAAW;gBAAE,OAAO,KAAK,CAAA;YAC5E,OAAO,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAA;QACvD,KAAK,WAAW;YACd,IAAI,KAAK,CAAC,KAAK,KAAK,YAAY;gBAAE,OAAO,KAAK,CAAA;YAC9C,OAAO,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAA;QACzE,KAAK,QAAQ;YACX,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM;gBAAE,OAAO,KAAK,CAAA;YAClE,OAAO;gBACL,GAAG,KAAK;gBACR,KAAK,EAAE,QAAQ;gBACf,OAAO,EAAE;oBACP,KAAK,EAAE,KAAK,CAAC,KAAK;oBAClB,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI;iBACnC;aACF,CAAA;QACH,KAAK,OAAO;YACV,IAAI,KAAK,CAAC,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,EAAE,SAAS,KAAK,KAAK;gBAAE,OAAO,KAAK,CAAA;YAChF,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,GAAG,CAAC,EAAE,CAAA;QACxE,KAAK,OAAO;YACV,OAAO,kBAAkB,CAAA;QAC3B,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,KAAK,GAAU,KAAK,CAAA;YAC1B,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["/**\n * Upload state machine (EC-151). Pure, deterministic transition logic for the\n * studio upload flow: request upload URL → transfer bytes → confirm metadata.\n * Failure at any stage is an explicit, visible state with a retry affordance —\n * never a silent loss. Kept free of DOM/network so it unit-tests as plain data.\n */\n\nexport type UploadStage = 'prepare' | 'transfer' | 'confirm'\n\nexport type UploadPhase = 'idle' | 'preparing' | 'uploading' | 'confirming' | 'done' | 'failed'\n\nexport interface UploadFailure {\n stage: UploadStage\n message: string\n /** Whether retrying the same file can plausibly succeed (default true). */\n retryable: boolean\n}\n\nexport interface UploadState {\n phase: UploadPhase\n /** Byte progress in [0, 1]; only meaningful while `uploading`. */\n progress: number\n /** 1-based attempt counter; increments on `retry`. */\n attempt: number\n failure?: UploadFailure\n /** The created asset id once `done`. */\n assetId?: string\n}\n\nexport type UploadEvent =\n | { type: 'start' }\n | { type: 'url-ready' }\n | { type: 'progress'; loaded: number; total: number }\n | { type: 'transferred' }\n | { type: 'confirmed'; assetId: string }\n | { type: 'failed'; stage: UploadStage; message: string; retryable?: boolean }\n | { type: 'retry' }\n | { type: 'reset' }\n\nexport const initialUploadState: UploadState = { phase: 'idle', progress: 0, attempt: 0 }\n\nconst clamp01 = (n: number): number => (Number.isFinite(n) ? Math.min(1, Math.max(0, n)) : 0)\n\n/**\n * Pure reducer. Invalid transitions return the state unchanged (deterministic,\n * never throws) so a late progress event after a failure cannot corrupt the UI.\n */\nexport function uploadReducer(state: UploadState, event: UploadEvent): UploadState {\n switch (event.type) {\n case 'start':\n if (state.phase !== 'idle') return state\n return { phase: 'preparing', progress: 0, attempt: 1 }\n case 'url-ready':\n if (state.phase !== 'preparing') return state\n return { ...state, phase: 'uploading', progress: 0 }\n case 'progress':\n if (state.phase !== 'uploading') return state\n return { ...state, progress: clamp01(event.total > 0 ? event.loaded / event.total : 0) }\n case 'transferred':\n if (state.phase !== 'uploading' && state.phase !== 'preparing') return state\n return { ...state, phase: 'confirming', progress: 1 }\n case 'confirmed':\n if (state.phase !== 'confirming') return state\n return { ...state, phase: 'done', progress: 1, assetId: event.assetId }\n case 'failed':\n if (state.phase === 'done' || state.phase === 'idle') return state\n return {\n ...state,\n phase: 'failed',\n failure: {\n stage: event.stage,\n message: event.message,\n retryable: event.retryable ?? true,\n },\n }\n case 'retry':\n if (state.phase !== 'failed' || state.failure?.retryable === false) return state\n return { phase: 'preparing', progress: 0, attempt: state.attempt + 1 }\n case 'reset':\n return initialUploadState\n default: {\n const never: never = event\n return never\n }\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../../src/lib/assets/upload.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../../src/lib/assets/upload.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AssetRecord, AssetRepository, BlobStorageAdapter } from '@elytracms/core/persistence'\nimport { detectImageDimensions } from './image-dimensions'\nimport type { ImageDimensions } from './image-dimensions'\nimport { initialUploadState, uploadReducer } from './upload-state'\nimport type { UploadEvent, UploadFailure, UploadState } from './upload-state'\n\n/**\n * Upload orchestration (EC-151): request upload URL → transfer bytes →\n * confirm by writing the EC-044 metadata record (dimensions, mime, serve URL).\n * Storage is reached *only* through the {@link BlobStorageAdapter}; every\n * effect is injectable so the whole flow unit-tests without a browser or a\n * live Convex deployment.\n */\n\n/** The structural slice of a browser `File` the upload flow needs. */\nexport interface UploadableFile {\n name: string\n type: string\n size: number\n arrayBuffer(): Promise<ArrayBuffer>\n}\n\n/** Sends bytes to an upload URL, reporting progress; returns the assigned storage key. */\nexport type UploadTransport = (\n uploadUrl: string,\n file: UploadableFile,\n onProgress: (loaded: number, total: number) => void,\n) => Promise<{ storageKey: string }>\n\n/**\n * Default browser transport: XMLHttpRequest POST for real byte progress\n * (fetch has no upload progress without streams support everywhere).\n */\nexport const xhrUploadTransport: UploadTransport = (uploadUrl, file, onProgress) =>\n new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest()\n xhr.open('POST', uploadUrl)\n if (file.type) xhr.setRequestHeader('Content-Type', file.type)\n xhr.upload.onprogress = (event) => {\n if (event.lengthComputable) onProgress(event.loaded, event.total)\n }\n xhr.onerror = () => reject(new Error('Network error while uploading bytes.'))\n xhr.onabort = () => reject(new Error('Upload was aborted.'))\n xhr.onload = () => {\n if (xhr.status < 200 || xhr.status >= 300) {\n reject(new Error(`Upload failed with HTTP ${xhr.status}.`))\n return\n }\n try {\n const payload = JSON.parse(xhr.responseText) as { storageId?: unknown }\n if (typeof payload.storageId === 'string' && payload.storageId.length > 0) {\n resolve({ storageKey: payload.storageId })\n } else {\n reject(new Error('Upload response did not include a storageId.'))\n }\n } catch {\n reject(new Error('Upload response was not valid JSON.'))\n }\n }\n void file.arrayBuffer().then(\n (bytes) => xhr.send(bytes),\n () => reject(new Error('Could not read file bytes.')),\n )\n })\n\nexport interface UploadDeps {\n blobs: BlobStorageAdapter\n assets: AssetRepository\n /** Client-direct transport; only used when `blobs.createUploadUrl` exists. */\n transport?: UploadTransport\n /** Injectable dimension detection; defaults to `createImageBitmap`-based. */\n detectDimensions?: (file: UploadableFile) => Promise<ImageDimensions | undefined>\n}\n\nexport interface UploadRequest {\n projectId: string\n file: UploadableFile\n alt?: string\n /** Observe every state transition (drives progress UI). */\n onState?: (state: UploadState) => void\n}\n\nexport type UploadResult =\n | { ok: true; asset: AssetRecord; state: UploadState }\n | { ok: false; failure: UploadFailure; state: UploadState }\n\nasync function defaultDetectDimensions(file: UploadableFile): Promise<ImageDimensions | undefined> {\n if (typeof Blob === 'undefined' || !(file instanceof Blob)) return undefined\n return detectImageDimensions(file as Blob & { type: string })\n}\n\nfunction failureOf(stage: UploadFailure['stage'], error: unknown): UploadFailure {\n return {\n stage,\n message: error instanceof Error ? error.message : String(error),\n retryable: true,\n }\n}\n\n/**\n * Run one upload attempt. Resolves with a discriminated result — it never\n * throws, and a failed transfer leaves no metadata record behind. Pass the\n * previous `state` to retry (the attempt counter carries over).\n */\nexport async function runUpload(\n deps: UploadDeps,\n request: UploadRequest,\n previous?: UploadState,\n): Promise<UploadResult> {\n let state = previous ?? initialUploadState\n const dispatch = (event: UploadEvent): void => {\n state = uploadReducer(state, event)\n request.onState?.(state)\n }\n dispatch(state.phase === 'failed' ? { type: 'retry' } : { type: 'start' })\n\n const { blobs, assets } = deps\n const { projectId, file } = request\n\n // --- prepare + transfer ---------------------------------------------------\n let storageKey: string\n try {\n if (blobs.createUploadUrl && deps.transport) {\n const uploadUrl = await blobs.createUploadUrl()\n dispatch({ type: 'url-ready' })\n try {\n const sent = await deps.transport(uploadUrl, file, (loaded, total) =>\n dispatch({ type: 'progress', loaded, total }),\n )\n storageKey = sent.storageKey\n } catch (error) {\n dispatch({ type: 'failed', ...failureOf('transfer', error) })\n return { ok: false, failure: failureOf('transfer', error), state }\n }\n } else {\n // Backend without client-direct uploads: push bytes through the adapter.\n dispatch({ type: 'url-ready' })\n const bytes = new Uint8Array(await file.arrayBuffer())\n try {\n if (blobs.store) {\n storageKey = await blobs.store(bytes, file.type)\n } else {\n storageKey = `${projectId}/${file.name}`\n await blobs.put(storageKey, bytes, file.type)\n }\n } catch (error) {\n dispatch({ type: 'failed', ...failureOf('transfer', error) })\n return { ok: false, failure: failureOf('transfer', error), state }\n }\n }\n } catch (error) {\n dispatch({ type: 'failed', ...failureOf('prepare', error) })\n return { ok: false, failure: failureOf('prepare', error), state }\n }\n dispatch({ type: 'transferred' })\n\n // --- confirm: metadata record linked to the stored blob --------------------\n try {\n const detect = deps.detectDimensions ?? defaultDetectDimensions\n const dimensions = await detect(file)\n const url = (await blobs.resolveUrl?.(storageKey)) ?? blobs.url(storageKey)\n const asset = await assets.upsertAsset(projectId, {\n filename: file.name,\n contentType: file.type || 'application/octet-stream',\n byteSize: file.size,\n storageKey,\n url,\n ...(dimensions ? { width: dimensions.width, height: dimensions.height } : {}),\n ...(request.alt !== undefined ? { alt: request.alt } : {}),\n })\n dispatch({ type: 'confirmed', assetId: asset.id })\n return { ok: true, asset, state }\n } catch (error) {\n dispatch({ type: 'failed', ...failureOf('confirm', error) })\n return { ok: false, failure: failureOf('confirm', error), state }\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-adapter.js","sourceRoot":"","sources":["../../../src/lib/auth/auth-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
|
|
1
|
+
{"version":3,"file":"auth-adapter.js","sourceRoot":"","sources":["../../../src/lib/auth/auth-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG","sourcesContent":["/**\n * Project-owned auth boundary (EC-150, vision AD-7). The studio talks to\n * authentication ONLY through {@link AuthAdapter} — the Convex Auth\n * implementation (`convex-auth-adapter.ts`) and the deterministic local\n * implementation (`local-auth-adapter.ts`) both satisfy it, mirroring how\n * `PersistenceAdapter` keeps Convex out of the app's type graph.\n *\n * Swapping providers (e.g. Convex Auth → Clerk) means writing one new\n * implementation of this interface and teaching `selectAuthAdapter` to pick\n * it; no UI or store code changes.\n */\n\n/** The signed-in user as the studio sees it. */\nexport interface AuthUser {\n /** Stable user id — the key `projectMembers.userId` is matched against. */\n readonly id: string\n readonly email: string\n readonly name?: string\n /**\n * Global (workspace-level) capability flags forwarded onto the operations\n * `Principal.roles`, e.g. `system` (internal tooling only). Per-project roles\n * do NOT live here — they live in the members repository. Currently no\n * browser-session flag is granted: project creation is config/CLI-owned\n * (AD-11), so there is no `create-projects` capability.\n */\n readonly globalFlags?: readonly string[]\n}\n\nexport interface AuthSession {\n readonly user: AuthUser\n}\n\nexport interface SignInCredentials {\n readonly email: string\n readonly password: string\n}\n\n/** Structured sign-in outcome — invalid credentials are a state, not a throw. */\nexport type SignInResult =\n | { readonly ok: true; readonly session: AuthSession }\n | {\n readonly ok: false\n readonly reason: 'invalid-credentials' | 'account-exists' | 'unavailable'\n readonly message: string\n }\n\nexport interface AuthAdapter {\n /** Restore the current session, if any (page load / refresh). */\n currentSession(): Promise<AuthSession | null>\n /** Password sign-in. Resolves a structured result; never throws for bad input. */\n signIn(credentials: SignInCredentials): Promise<SignInResult>\n /**\n * Create a password account and sign in (EC-179). One project per backend, so\n * a freshly-provisioned deployment starts with no users — the first member\n * registers here, then is granted a role. `account-exists` is a state, not a\n * throw.\n */\n signUp(credentials: SignInCredentials): Promise<SignInResult>\n /** End the session (idempotent). */\n signOut(): Promise<void>\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convex-auth-adapter.js","sourceRoot":"","sources":["../../../src/lib/auth/convex-auth-adapter.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"convex-auth-adapter.js","sourceRoot":"","sources":["../../../src/lib/auth/convex-auth-adapter.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ConvexHttpClient } from 'convex/browser'\nimport { actionRef, queryRef } from '../persistence/convex-client'\nimport type { AuthAdapter, AuthSession, SignInCredentials, SignInResult } from './auth-adapter'\nimport type { SessionStore } from './local-auth-adapter'\n\n/**\n * Convex Auth implementation of the project-owned {@link AuthAdapter}\n * (EC-150). Decision record (also in `convex/auth.ts`): **Convex Auth** over\n * Clerk — self-contained on the Convex stack, sessions in our own tables, no\n * extra vendor; reachable only through this adapter so a swap stays local.\n *\n * Flow (server side lives in `convex/auth.ts` + `convex/users.ts`):\n * 1. `signIn` calls the `auth:signIn` action with the Password provider\n * (`flow: 'signIn'`); on success Convex returns a JWT + refresh token.\n * 2. The JWT is set on the *shared* Convex client (`client.setAuth`), so every\n * subsequent persistence query/mutation runs authenticated and the\n * server-side `requireRole` guards see the caller.\n * 3. `currentSession` restores the JWT from storage and asks `users:me`.\n * 4. `signOut` calls `auth:signOut` and clears the JWT.\n *\n * v1 scope note: the stored JWT is short-lived and this adapter does not yet\n * run the refresh-token loop (the official `@convex-dev/auth/react` client\n * does); an expired session simply resolves to \"signed out\" and the user signs\n * in again. Live-deployment hardening is EC-156. No live deployment exists in\n * this repo — this file is typecheck-verified and exercised against the local\n * adapter's shared interface.\n */\n\nconst TOKEN_STORAGE_PREFIX = 'elytra.convex-auth.jwt'\n\n/**\n * Per-deployment token key (EC-179, vision AD-8). One project per backend, so a\n * session is scoped to its deployment: signing into Aurora's backend must not\n * carry a JWT to Northwind's. Keying the stored token by the deployment URL\n * makes each backend's session independent — switching to a project on a\n * not-yet-authenticated backend reads no token and the guard asks for sign-in.\n * (A future shared external IdP — WorkOS/Clerk — would issue one identity valid\n * on every deployment, collapsing this back to a single session.)\n */\nexport function tokenStorageKey(deploymentUrl?: string): string {\n return deploymentUrl ? `${TOKEN_STORAGE_PREFIX}::${deploymentUrl}` : TOKEN_STORAGE_PREFIX\n}\n\n/**\n * Best-effort \"is there a session for this deployment?\" — a synchronous token\n * presence check used to label per-backend projects in the switcher/launcher\n * (EC-179). It does not validate the token (an expired one still redirects to\n * sign-in on entry); it just answers \"has the user signed into this backend?\".\n */\nexport function hasStoredConvexSession(\n deploymentUrl: string,\n store: SessionStore = defaultStore(),\n): boolean {\n return store.getItem(tokenStorageKey(deploymentUrl)) !== null\n}\n\ninterface SignInActionResult {\n tokens?: { token: string; refreshToken: string } | null\n}\n\ninterface MeResult {\n id: string\n email: string\n name?: string\n}\n\nfunction defaultStore(): SessionStore {\n if (typeof window !== 'undefined' && window.sessionStorage) return window.sessionStorage\n const memory = new Map<string, string>()\n return {\n getItem: (key) => memory.get(key) ?? null,\n setItem: (key, value) => void memory.set(key, value),\n removeItem: (key) => void memory.delete(key),\n }\n}\n\nexport class ConvexAuthAdapter implements AuthAdapter {\n private readonly tokenKey: string\n\n constructor(\n private readonly client: ConvexHttpClient,\n private readonly store: SessionStore = defaultStore(),\n /** Deployment URL the token is scoped to (per-backend sessions, EC-179). */\n deploymentUrl?: string,\n ) {\n this.tokenKey = tokenStorageKey(deploymentUrl)\n }\n\n async currentSession(): Promise<AuthSession | null> {\n const token = this.store.getItem(this.tokenKey)\n if (!token) return null\n this.client.setAuth(token)\n try {\n const me = (await this.client.query(queryRef('users:me'), {})) as MeResult | null\n if (!me) {\n this.clearToken()\n return null\n }\n return { user: this.toUser(me) }\n } catch {\n // Expired/invalid JWT or unreachable backend → treat as signed out.\n this.clearToken()\n return null\n }\n }\n\n async signIn(credentials: SignInCredentials): Promise<SignInResult> {\n return this.authenticate('signIn', credentials)\n }\n\n async signUp(credentials: SignInCredentials): Promise<SignInResult> {\n return this.authenticate('signUp', credentials)\n }\n\n /**\n * Shared password flow (EC-150/EC-179). `signIn` and `signUp` differ only by\n * the Convex Auth `flow` param; both return a token + load `users:me`.\n */\n private async authenticate(\n flow: 'signIn' | 'signUp',\n credentials: SignInCredentials,\n ): Promise<SignInResult> {\n let result: SignInActionResult\n try {\n result = (await this.client.action(actionRef('auth:signIn'), {\n provider: 'password',\n params: {\n email: credentials.email.trim().toLowerCase(),\n password: credentials.password,\n flow,\n },\n })) as SignInActionResult\n } catch (error) {\n // Convex Auth surfaces credential/registration problems as thrown errors.\n const message = error instanceof Error ? error.message : String(error)\n if (flow === 'signUp' && /already|exists|InvalidAccountId/i.test(message)) {\n return {\n ok: false,\n reason: 'account-exists',\n message: 'An account with this email already exists — sign in instead.',\n }\n }\n if (/InvalidSecret|InvalidAccountId|credential|password/i.test(message)) {\n return {\n ok: false,\n reason: 'invalid-credentials',\n message:\n flow === 'signUp'\n ? 'That email or password can’t be used (password too short?).'\n : 'Email or password is incorrect.',\n }\n }\n const verb = flow === 'signUp' ? 'Sign-up' : 'Sign-in'\n return { ok: false, reason: 'unavailable', message: `${verb} is currently unavailable.` }\n }\n if (!result.tokens) {\n return {\n ok: false,\n reason: 'invalid-credentials',\n message: 'Email or password is incorrect.',\n }\n }\n this.store.setItem(this.tokenKey, result.tokens.token)\n this.client.setAuth(result.tokens.token)\n const me = (await this.client.query(queryRef('users:me'), {})) as MeResult | null\n if (!me) {\n this.clearToken()\n return { ok: false, reason: 'unavailable', message: 'Sign-in is currently unavailable.' }\n }\n return { ok: true, session: { user: this.toUser(me) } }\n }\n\n async signOut(): Promise<void> {\n try {\n await this.client.action(actionRef('auth:signOut'), {})\n } catch {\n // Already signed out / unreachable — clearing local state is what matters.\n }\n this.clearToken()\n }\n\n private toUser(me: MeResult): AuthSession['user'] {\n return {\n id: me.id,\n email: me.email,\n ...(me.name ? { name: me.name } : {}),\n // No global flags: project creation is config/CLI-owned (AD-11), so there\n // is no in-studio `create-projects` capability. Per-project roles come\n // from `projectMembers`.\n globalFlags: [],\n }\n }\n\n private clearToken(): void {\n this.store.removeItem(this.tokenKey)\n this.client.clearAuth()\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev-auto-login-adapter.js","sourceRoot":"","sources":["../../../src/lib/auth/dev-auto-login-adapter.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,mBAAmB;IAEX;IACA;IAFnB,YACmB,KAAkB,EAClB,WAA8B;QAD9B,UAAK,GAAL,KAAK,CAAa;QAClB,gBAAW,GAAX,WAAW,CAAmB;IAC9C,CAAC;IAEJ,KAAK,CAAC,cAAc;QAClB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,CAAA;QAClD,IAAI,QAAQ;YAAE,OAAO,QAAQ,CAAA;QAC7B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;QACxD,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAA;IAC1C,CAAC;IAED,MAAM,CAAC,WAA8B;QACnC,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;IACvC,CAAC;IAED,MAAM,CAAC,WAA8B;QACnC,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;IACvC,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAA;IAC7B,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"dev-auto-login-adapter.js","sourceRoot":"","sources":["../../../src/lib/auth/dev-auto-login-adapter.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,mBAAmB;IAEX;IACA;IAFnB,YACmB,KAAkB,EAClB,WAA8B;QAD9B,UAAK,GAAL,KAAK,CAAa;QAClB,gBAAW,GAAX,WAAW,CAAmB;IAC9C,CAAC;IAEJ,KAAK,CAAC,cAAc;QAClB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,CAAA;QAClD,IAAI,QAAQ;YAAE,OAAO,QAAQ,CAAA;QAC7B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;QACxD,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAA;IAC1C,CAAC;IAED,MAAM,CAAC,WAA8B;QACnC,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;IACvC,CAAC;IAED,MAAM,CAAC,WAA8B;QACnC,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;IACvC,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAA;IAC7B,CAAC;CACF","sourcesContent":["import type { AuthAdapter, AuthSession, SignInCredentials, SignInResult } from './auth-adapter'\n\n/**\n * Dev-only unattended-auth decorator (testing de-friction). Wraps any\n * {@link AuthAdapter}: when no session can be restored, it transparently signs\n * in with the configured dev credentials so the studio boots already\n * authenticated for local/automated testing.\n *\n * This is **not** an auth bypass — it performs a real {@link AuthAdapter.signIn},\n * so the resulting session is a genuine backend session and the server-side\n * role guards still apply (a non-member or wrong password surfaces as the normal\n * signed-out state, not silent access). It is only ever constructed in a dev\n * build (see `resolveDevAutoLogin`), so it cannot reach production.\n *\n * Every method but {@link currentSession} delegates unchanged; `currentSession`\n * adds the auto-sign-in fallback after the wrapped adapter reports no session.\n */\nexport class DevAutoLoginAdapter implements AuthAdapter {\n constructor(\n private readonly inner: AuthAdapter,\n private readonly credentials: SignInCredentials,\n ) {}\n\n async currentSession(): Promise<AuthSession | null> {\n const restored = await this.inner.currentSession()\n if (restored) return restored\n const result = await this.inner.signIn(this.credentials)\n return result.ok ? result.session : null\n }\n\n signIn(credentials: SignInCredentials): Promise<SignInResult> {\n return this.inner.signIn(credentials)\n }\n\n signUp(credentials: SignInCredentials): Promise<SignInResult> {\n return this.inner.signUp(credentials)\n }\n\n signOut(): Promise<void> {\n return this.inner.signOut()\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAA;AAC9D,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AACvF,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AAGzE,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AACjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AASvD,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAE9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,eAAe,CAAA;AAGtB;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,MAAM,GAAG,oBAAoB,EAAE,CAAA;IACrC,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,2EAA2E;QAC3E,uEAAuE;QACvE,MAAM,GAAG,GAAG,oBAAoB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAC5C,MAAM,IAAI,GAAG,IAAI,iBAAiB,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,GAAG,CAAC,CAAA;QACxE,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAA;IAC/B,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,YAAY;QAAE,OAAO,IAAI,gBAAgB,EAAE,CAAA;IAC/D,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;AAChC,CAAC;AAED;;;;GAIG;AACH,SAAS,gBAAgB,CAAC,OAAoB;IAC5C,MAAM,WAAW,GAAG,mBAAmB,EAAE,CAAA;IACzC,OAAO,WAAW,CAAC,CAAC,CAAC,IAAI,mBAAmB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;AAC9E,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,QAAQ;IACtB,MAAM,MAAM,GAAG,oBAAoB,EAAE,CAAA;IACrC,IAAI,MAAM,CAAC,IAAI,KAAK,eAAe;QAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IACnE,OAAO,MAAM,CAAC,IAAI,CAAA;AACpB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,MAAM,MAAM,GAAG,oBAAoB,EAAE,CAAA;IACrC,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAA;IACzC,OAAO,sBAAsB,CAAC,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;AACvE,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAA;AAC9D,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AACvF,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AAGzE,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AACjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AASvD,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAE9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,eAAe,CAAA;AAGtB;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,MAAM,GAAG,oBAAoB,EAAE,CAAA;IACrC,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,2EAA2E;QAC3E,uEAAuE;QACvE,MAAM,GAAG,GAAG,oBAAoB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAC5C,MAAM,IAAI,GAAG,IAAI,iBAAiB,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,GAAG,CAAC,CAAA;QACxE,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAA;IAC/B,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,YAAY;QAAE,OAAO,IAAI,gBAAgB,EAAE,CAAA;IAC/D,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;AAChC,CAAC;AAED;;;;GAIG;AACH,SAAS,gBAAgB,CAAC,OAAoB;IAC5C,MAAM,WAAW,GAAG,mBAAmB,EAAE,CAAA;IACzC,OAAO,WAAW,CAAC,CAAC,CAAC,IAAI,mBAAmB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;AAC9E,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,QAAQ;IACtB,MAAM,MAAM,GAAG,oBAAoB,EAAE,CAAA;IACrC,IAAI,MAAM,CAAC,IAAI,KAAK,eAAe;QAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IACnE,OAAO,MAAM,CAAC,IAAI,CAAA;AACpB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,MAAM,MAAM,GAAG,oBAAoB,EAAE,CAAA;IACrC,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAA;IACzC,OAAO,sBAAsB,CAAC,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;AACvE,CAAC","sourcesContent":["import { getConvexClient } from '../persistence/convex-client'\nimport { resolveBackendConfig, resolveDevAutoLogin } from '../persistence/backend-mode'\nimport { deploymentUrlForSlug, resolveDeploymentUrl } from '../workspace'\nimport type { StudioBackendMode } from '../persistence/backend-mode'\nimport type { AuthAdapter } from './auth-adapter'\nimport { ConvexAuthAdapter, hasStoredConvexSession } from './convex-auth-adapter'\nimport { DevAutoLoginAdapter } from './dev-auto-login-adapter'\nimport { LocalAuthAdapter } from './local-auth-adapter'\n\nexport type {\n AuthAdapter,\n AuthSession,\n AuthUser,\n SignInCredentials,\n SignInResult,\n} from './auth-adapter'\nexport { LocalAuthAdapter, LOCAL_DEV_CREDENTIALS } from './local-auth-adapter'\nexport type { SessionStore } from './local-auth-adapter'\nexport { ConvexAuthAdapter } from './convex-auth-adapter'\nexport { DevAutoLoginAdapter } from './dev-auto-login-adapter'\nexport {\n SIGN_IN_PATH,\n isPublicPath,\n postSignInTarget,\n resolveRouteGuard,\n sessionPrincipal,\n} from './route-guard'\nexport type { AuthStatus, RouteGuardDecision } from './route-guard'\n\n/**\n * Select the auth backend (EC-150/EC-153), mirroring `selectPersistenceAdapter`\n * exactly: Convex mode means Convex Auth (over the same shared client the\n * persistence adapter uses, so the session JWT authenticates every call); the\n * explicit playground mode means the deterministic local adapter with the\n * seeded dev users. A misconfigured backend is a hard error here too — never\n * a silent local fallback (the `BackendGate` renders it before this runs).\n */\nexport function selectAuthAdapter(): AuthAdapter {\n const config = resolveBackendConfig()\n if (config.kind === 'convex') {\n // The active project (EC-179) selects the deployment; the session token is\n // scoped to that deployment URL so each backend keeps its own session.\n const url = resolveDeploymentUrl(config.url)\n const base = new ConvexAuthAdapter(getConvexClient(url), undefined, url)\n return withDevAutoLogin(base)\n }\n if (config.kind === 'playground') return new LocalAuthAdapter()\n throw new Error(config.detail)\n}\n\n/**\n * Dev-only: wrap an adapter so the studio auto-signs-in for unattended testing\n * when `VITE_ELYTRA_DEV_LOGIN` is configured in a dev build. No-op otherwise\n * (and dead-code-eliminated in production builds — see `resolveDevAutoLogin`).\n */\nfunction withDevAutoLogin(adapter: AuthAdapter): AuthAdapter {\n const credentials = resolveDevAutoLogin()\n return credentials ? new DevAutoLoginAdapter(adapter, credentials) : adapter\n}\n\n/** Mirrors `persistenceMode()` — auth and persistence always agree (EC-150). */\nexport function authMode(): StudioBackendMode {\n const config = resolveBackendConfig()\n if (config.kind === 'misconfigured') throw new Error(config.detail)\n return config.kind\n}\n\n/**\n * Whether the user has a session on a given project's backend (EC-179). One\n * project per backend, so this is the per-project sign-in state the switcher and\n * launcher surface (\"Sign in\" vs \"Open project\"). Playground mode is a single\n * local backend — always \"signed in\". Best-effort (token presence, see\n * {@link hasStoredConvexSession}); entry still enforces a valid session.\n */\nexport function hasProjectSession(slug: string): boolean {\n const config = resolveBackendConfig()\n if (config.kind !== 'convex') return true\n return hasStoredConvexSession(deploymentUrlForSlug(slug, config.url))\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-auth-adapter.js","sourceRoot":"","sources":["../../../src/lib/auth/local-auth-adapter.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"local-auth-adapter.js","sourceRoot":"","sources":["../../../src/lib/auth/local-auth-adapter.ts"],"names":[],"mappings":"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","sourcesContent":["import { DEV_USERS } from '@elytracms/core/persistence'\nimport type { AuthAdapter, AuthSession, SignInCredentials, SignInResult } from './auth-adapter'\n\n/**\n * Deterministic local auth (EC-150) for the in-memory persistence mode: the\n * whole sign-in → role-enforcement → sign-out flow works offline, in tests,\n * and in fixtures with zero backend setup. User ids are the canonical\n * `DEV_USERS` ids from `@elytracms/core/persistence`, which the seeded\n * `projectMembers` fixtures reference — so `admin@example.com` is admin,\n * `editor@…` editor, `viewer@…` viewer on every sample project.\n *\n * Dev credentials (fixed, documented, local-only):\n * - admin@example.com / elytra-admin\n * - editor@example.com / elytra-editor\n * - viewer@example.com / elytra-viewer\n *\n * Adminness is the `projectMembers` role, not a global flag — project creation\n * is config/CLI-owned now (AD-11), so there is no in-studio `create-projects`\n * capability to grant.\n *\n * The session survives reloads via injected storage (defaults to\n * `sessionStorage` in the browser, an in-memory map elsewhere).\n */\n\nexport const LOCAL_DEV_CREDENTIALS = [\n { user: DEV_USERS.admin, password: 'elytra-admin' },\n { user: DEV_USERS.editor, password: 'elytra-editor' },\n { user: DEV_USERS.viewer, password: 'elytra-viewer' },\n] as const\n\nconst STORAGE_KEY = 'elytra.local-auth.user-id'\n\n/** The storage slice the adapter needs (sessionStorage-compatible). */\nexport interface SessionStore {\n getItem(key: string): string | null\n setItem(key: string, value: string): void\n removeItem(key: string): void\n}\n\nfunction defaultStore(): SessionStore {\n if (typeof window !== 'undefined' && window.sessionStorage) return window.sessionStorage\n const memory = new Map<string, string>()\n return {\n getItem: (key) => memory.get(key) ?? null,\n setItem: (key, value) => void memory.set(key, value),\n removeItem: (key) => void memory.delete(key),\n }\n}\n\nexport class LocalAuthAdapter implements AuthAdapter {\n private readonly store: SessionStore\n\n constructor(store: SessionStore = defaultStore()) {\n this.store = store\n }\n\n async currentSession(): Promise<AuthSession | null> {\n const userId = this.store.getItem(STORAGE_KEY)\n if (!userId) return null\n const entry = LOCAL_DEV_CREDENTIALS.find((c) => c.user.id === userId)\n return entry ? { user: entry.user } : null\n }\n\n async signIn(credentials: SignInCredentials): Promise<SignInResult> {\n const email = credentials.email.trim().toLowerCase()\n const entry = LOCAL_DEV_CREDENTIALS.find((c) => c.user.email === email)\n if (!entry || entry.password !== credentials.password) {\n // Deliberately identical for unknown email vs wrong password.\n return {\n ok: false,\n reason: 'invalid-credentials',\n message: 'Email or password is incorrect.',\n }\n }\n this.store.setItem(STORAGE_KEY, entry.user.id)\n return { ok: true, session: { user: entry.user } }\n }\n\n async signUp(): Promise<SignInResult> {\n // Playground mode has a fixed, documented set of dev users — there is no\n // registration. Surfaced as a state, not a throw, so the sign-in screen can\n // explain it.\n return {\n ok: false,\n reason: 'unavailable',\n message: 'Sign-up isn’t available in playground mode — use the dev credentials below.',\n }\n }\n\n async signOut(): Promise<void> {\n this.store.removeItem(STORAGE_KEY)\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-guard.js","sourceRoot":"","sources":["../../../src/lib/auth/route-guard.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CAAA;AAEtC;;;;GAIG;AACH,MAAM,YAAY,GAAwB,IAAI,GAAG,CAAC,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC,CAAA;AAEhF,MAAM,UAAU,YAAY,CAAC,QAAgB;IAC3C,OAAO,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAA;AAC9C,CAAC;AAcD,MAAM,UAAU,iBAAiB,CAAC,QAAgB,EAAE,MAAkB;IACpE,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAA;IAChC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,wEAAwE;QACxE,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;IACrE,CAAC;IACD,IAAI,MAAM,KAAK,YAAY,EAAE,CAAC;QAC5B,IAAI,YAAY,CAAC,IAAI,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;QAChD,OAAO,EAAE,IAAI,EAAE,qBAAqB,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAA;IACxD,CAAC;IACD,YAAY;IACZ,IAAI,IAAI,KAAK,YAAY;QAAE,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,CAAA;IAC3D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;AAC1B,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,gBAAgB,CAAC,QAA4B;IAC3D,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,GAAG,CAAA;IACnF,OAAO,SAAS,CAAC,QAAQ,CAAC,KAAK,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAA;AAC9D,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,gBAAgB,CAAC,OAAoB;IACnD,OAAO;QACL,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE;QACnB,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACzE,CAAA;AACH,CAAC;AAED,SAAS,SAAS,CAAC,QAAgB;IACjC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IAC/E,OAAO,QAAQ,CAAA;AACjB,CAAC"}
|
|
1
|
+
{"version":3,"file":"route-guard.js","sourceRoot":"","sources":["../../../src/lib/auth/route-guard.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CAAA;AAEtC;;;;GAIG;AACH,MAAM,YAAY,GAAwB,IAAI,GAAG,CAAC,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC,CAAA;AAEhF,MAAM,UAAU,YAAY,CAAC,QAAgB;IAC3C,OAAO,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAA;AAC9C,CAAC;AAcD,MAAM,UAAU,iBAAiB,CAAC,QAAgB,EAAE,MAAkB;IACpE,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAA;IAChC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,wEAAwE;QACxE,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;IACrE,CAAC;IACD,IAAI,MAAM,KAAK,YAAY,EAAE,CAAC;QAC5B,IAAI,YAAY,CAAC,IAAI,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;QAChD,OAAO,EAAE,IAAI,EAAE,qBAAqB,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAA;IACxD,CAAC;IACD,YAAY;IACZ,IAAI,IAAI,KAAK,YAAY;QAAE,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,CAAA;IAC3D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;AAC1B,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,gBAAgB,CAAC,QAA4B;IAC3D,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,GAAG,CAAA;IACnF,OAAO,SAAS,CAAC,QAAQ,CAAC,KAAK,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAA;AAC9D,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,gBAAgB,CAAC,OAAoB;IACnD,OAAO;QACL,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE;QACnB,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACzE,CAAA;AACH,CAAC;AAED,SAAS,SAAS,CAAC,QAAgB;IACjC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IAC/E,OAAO,QAAQ,CAAA;AACjB,CAAC","sourcesContent":["import type { Principal } from '@elytracms/core/operations'\nimport type { AuthSession } from './auth-adapter'\n\n/**\n * Pure route-guard + principal-mapping logic (EC-150), kept free of React and\n * router types so it is unit-testable and deterministic. The `__root` layout\n * applies {@link resolveRouteGuard} on every location change.\n */\n\nexport const SIGN_IN_PATH = '/sign-in'\n\n/**\n * Paths reachable without a session: the sign-in screen itself and the\n * component styleguide (a static internal reference, not a project surface).\n * Everything else — project surfaces, the launcher — requires a session.\n */\nconst PUBLIC_PATHS: ReadonlySet<string> = new Set([SIGN_IN_PATH, '/styleguide'])\n\nexport function isPublicPath(pathname: string): boolean {\n return PUBLIC_PATHS.has(normalize(pathname))\n}\n\nexport type AuthStatus = 'loading' | 'signed-in' | 'signed-out'\n\nexport type RouteGuardDecision =\n /** Render the route. */\n | { readonly kind: 'allow' }\n /** Session still resolving — render the deterministic checking state. */\n | { readonly kind: 'pending' }\n /** Unauthenticated on a protected path → sign-in, preserving the target. */\n | { readonly kind: 'redirect-to-sign-in'; readonly redirect: string }\n /** Authenticated user on the sign-in screen → send them home (or back). */\n | { readonly kind: 'redirect-home' }\n\nexport function resolveRouteGuard(pathname: string, status: AuthStatus): RouteGuardDecision {\n const path = normalize(pathname)\n if (status === 'loading') {\n // Public paths render immediately; protected ones wait for the session.\n return isPublicPath(path) ? { kind: 'allow' } : { kind: 'pending' }\n }\n if (status === 'signed-out') {\n if (isPublicPath(path)) return { kind: 'allow' }\n return { kind: 'redirect-to-sign-in', redirect: path }\n }\n // signed-in\n if (path === SIGN_IN_PATH) return { kind: 'redirect-home' }\n return { kind: 'allow' }\n}\n\n/** Where to navigate after a successful sign-in. Rejects external targets. */\nexport function postSignInTarget(redirect: string | undefined): string {\n if (!redirect || !redirect.startsWith('/') || redirect.startsWith('//')) return '/'\n return normalize(redirect) === SIGN_IN_PATH ? '/' : redirect\n}\n\n/** Map a session onto the operations-layer {@link Principal}. */\nexport function sessionPrincipal(session: AuthSession): Principal {\n return {\n id: session.user.id,\n ...(session.user.name ? { name: session.user.name } : {}),\n ...(session.user.globalFlags ? { roles: session.user.globalFlags } : {}),\n }\n}\n\nfunction normalize(pathname: string): string {\n if (pathname.length > 1 && pathname.endsWith('/')) return pathname.slice(0, -1)\n return pathname\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-errors.js","sourceRoot":"","sources":["../../src/lib/auth-errors.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AAEH,oEAAoE;AACpE,MAAM,CAAC,MAAM,uBAAuB,GAClC,qIAAqI,CAAA;AAEvI,MAAM,CAAC,MAAM,mBAAmB,GAAG,eAAe,CAAA;AAElD;;;;GAIG;AACH,SAAS,gBAAgB,CAAC,OAAe;IACvC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAClC,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;IACpC,IAAI,KAAK,KAAK,CAAC,CAAC,IAAI,GAAG,IAAI,KAAK;QAAE,OAAO,SAAS,CAAA;IAClD,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAA;QACjE,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAClD,MAAM,IAAI,GAAI,MAA6B,CAAC,IAAI,CAAA;YAChD,IAAI,OAAO,IAAI,KAAK,QAAQ;gBAAE,OAAO,IAAI,CAAA;QAC3C,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,0DAA0D;IAC5D,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAqB;IACzD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,qBAAqB;QAAE,OAAO,KAAK,CAAA;IAClF,IAAI,gBAAgB,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,iBAAiB;QAAE,OAAO,IAAI,CAAA;IACtE,IAAI,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAA;IAC1D,OAAO,8BAA8B,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;AAC3D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,QAA+C;IACxE,MAAM,MAAM,GAAG,GAAG,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAC,MAAM,IAAI,EAAE,EAAE,CAAA;IAC7D,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAA;IAClF,OAAO,qBAAqB,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAA;AAC5D,CAAC"}
|
|
1
|
+
{"version":3,"file":"auth-errors.js","sourceRoot":"","sources":["../../src/lib/auth-errors.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AAEH,oEAAoE;AACpE,MAAM,CAAC,MAAM,uBAAuB,GAClC,qIAAqI,CAAA;AAEvI,MAAM,CAAC,MAAM,mBAAmB,GAAG,eAAe,CAAA;AAElD;;;;GAIG;AACH,SAAS,gBAAgB,CAAC,OAAe;IACvC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAClC,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;IACpC,IAAI,KAAK,KAAK,CAAC,CAAC,IAAI,GAAG,IAAI,KAAK;QAAE,OAAO,SAAS,CAAA;IAClD,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAA;QACjE,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAClD,MAAM,IAAI,GAAI,MAA6B,CAAC,IAAI,CAAA;YAChD,IAAI,OAAO,IAAI,KAAK,QAAQ;gBAAE,OAAO,IAAI,CAAA;QAC3C,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,0DAA0D;IAC5D,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAqB;IACzD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,qBAAqB;QAAE,OAAO,KAAK,CAAA;IAClF,IAAI,gBAAgB,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,iBAAiB;QAAE,OAAO,IAAI,CAAA;IACtE,IAAI,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAA;IAC1D,OAAO,8BAA8B,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;AAC3D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,QAA+C;IACxE,MAAM,MAAM,GAAG,GAAG,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAC,MAAM,IAAI,EAAE,EAAE,CAAA;IAC7D,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAA;IAClF,OAAO,qBAAqB,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAA;AAC5D,CAAC","sourcesContent":["import type { OperationError } from './operations'\n\n/**\n * Session-expiry detection + plain-language mapping (EC-177 gap 9).\n *\n * An expired Convex session surfaces as a raw backend blob thrown by the\n * transport — e.g. `{\"code\":\"Unauthenticated\",\"message\":\"Could not verify\n * OIDC token claim…\"}` — which `toOperationError` can only normalize to an\n * `unknown`/`backend-unavailable` `OperationError` whose message *is* that\n * blob. Rendering it verbatim is editor-hostile, and the real problem (edits\n * silently stop persisting) is invisible.\n *\n * This module is the one chokepoint that recognizes that shape on the\n * structured `OperationError` (the seam every studio failure already flows\n * through), so UI surfaces never string-match raw messages themselves: the\n * shared banner asks {@link isSessionExpiredError} and renders the\n * plain-language copy + a \"Sign in again\" action instead.\n */\n\n/** Editor-facing copy: plain language, no auth/transport jargon. */\nexport const SESSION_EXPIRED_MESSAGE =\n \"You've been signed out, so your latest changes aren't being saved. Sign in again to keep editing — you'll come back to this screen.\"\n\nexport const SIGN_IN_AGAIN_LABEL = 'Sign in again'\n\n/**\n * Extract the `code` of a JSON object embedded in a transport error message.\n * Convex auth failures carry `{\"code\":\"Unauthenticated\", …}`, sometimes\n * wrapped in client prefixes (`[CONVEX M(graph:save)] … Server Error: {…}`).\n */\nfunction embeddedJsonCode(message: string): string | undefined {\n const start = message.indexOf('{')\n const end = message.lastIndexOf('}')\n if (start === -1 || end <= start) return undefined\n try {\n const parsed: unknown = JSON.parse(message.slice(start, end + 1))\n if (parsed !== null && typeof parsed === 'object') {\n const code = (parsed as { code?: unknown }).code\n if (typeof code === 'string') return code\n }\n } catch {\n // Not a JSON payload — fall through to the marker checks.\n }\n return undefined\n}\n\n/**\n * Does this operation failure mean \"the session is no longer valid\"?\n *\n * Only the transport-shaped codes can carry the backend auth blob: structured\n * studio-level failures (`validation`, `unauthorized` from the role hook,\n * `not-found`, `conflict`) are never session expiry. Within those, detect the\n * Convex unauthenticated shape: an embedded `{\"code\":\"Unauthenticated\"}`\n * payload, the bare `Unauthenticated` server-error marker, or the OIDC claim\n * message it ships with.\n */\nexport function isSessionExpiredError(error: OperationError): boolean {\n if (error.code !== 'unknown' && error.code !== 'backend-unavailable') return false\n if (embeddedJsonCode(error.message) === 'Unauthenticated') return true\n if (/\\bUnauthenticated\\b/.test(error.message)) return true\n return /could not verify oidc token/i.test(error.message)\n}\n\n/**\n * Where the \"Sign in again\" action navigates: the sign-in screen, carrying the\n * current location so a successful sign-in returns the editor to the exact\n * screen they were on (the sign-in route's `redirect` search param, EC-150).\n * External/protocol-relative targets are rejected, mirroring\n * `postSignInTarget`.\n */\nexport function signInHref(location: { pathname: string; search?: string }): string {\n const target = `${location.pathname}${location.search ?? ''}`\n const redirect = target.startsWith('/') && !target.startsWith('//') ? target : '/'\n return `/sign-in?redirect=${encodeURIComponent(redirect)}`\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"section-bindings.js","sourceRoot":"","sources":["../../../src/lib/bindings/section-bindings.ts"],"names":[],"mappings":"AAyBA,kFAAkF;AAClF,MAAM,UAAU,iBAAiB,CAAC,MAAsB;IACtD,OAAO;QACL,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,MAAoB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxF,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC/D,CAAA;AACH,CAAC"}
|
|
1
|
+
{"version":3,"file":"section-bindings.js","sourceRoot":"","sources":["../../../src/lib/bindings/section-bindings.ts"],"names":[],"mappings":"AAyBA,kFAAkF;AAClF,MAAM,UAAU,iBAAiB,CAAC,MAAsB;IACtD,OAAO;QACL,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,MAAoB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxF,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC/D,CAAA;AACH,CAAC","sourcesContent":["import type { CmsSource } from '@elytracms/core/data-binding'\nimport type { ListDocumentsQuery, WhereInput } from '@elytracms/core/content'\n\n/**\n * Stored repeating-section / template-page query config (EC-166), reduced to\n * what survives the EC-190 v1 realignment.\n *\n * The editor surfaces that AUTHORED these queries — the repeating-section and\n * template-page binding panels — are gone (the v1 canvas edits static props\n * only). What remains is the read-only side the canvas preview and the\n * locale-fallback marker still need: replaying a STORED query config as the\n * exact delivery `listDocuments` query, so a parked section/template source\n * previews through the same `@elytracms/core/content` resolution delivery runs. The\n * query-building, picker-vocabulary, and plain-language description helpers were\n * removed with the panels.\n */\n\n/**\n * The CMS source config of a section/template source — exactly the canonical\n * `@elytracms/core/data-binding` cms config: the AD-3 `where` shape is valid JSON and\n * stores verbatim in `filter`; `sort` and `limit` are first-class\n * `cmsConfigSchema` fields, so the full query round-trips Zod validation.\n */\nexport type QueryCmsConfig = CmsSource['config']\n\n/** The `listDocuments` query a stored source config replays (delivery parity). */\nexport function listQueryOfConfig(config: QueryCmsConfig): ListDocumentsQuery {\n return {\n ...(Object.keys(config.filter).length > 0 ? { where: config.filter as WhereInput } : {}),\n ...(config.sort !== undefined ? { sort: config.sort } : {}),\n ...(config.limit !== undefined ? { limit: config.limit } : {}),\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/clipboard/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAc,gBAAgB,CAAA;AAC9B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,gBAAgB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/clipboard/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAc,gBAAgB,CAAA;AAC9B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,gBAAgB,CAAA","sourcesContent":["/**\n * Studio clipboard helpers (EC-175): paste-target resolution, permissive-paste\n * diffing, and the OS-clipboard transport over the EC-174 fragment format.\n */\nexport * from './paste-target'\nexport * from './paste-issues'\nexport * from './os-clipboard'\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"os-clipboard.js","sourceRoot":"","sources":["../../../src/lib/clipboard/os-clipboard.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"os-clipboard.js","sourceRoot":"","sources":["../../../src/lib/clipboard/os-clipboard.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n parseFragmentFromClipboard,\n toClipboardRepresentations,\n} from '@elytracms/core/clipboard'\nimport type { ClipboardFragment, ParseFragmentResult } from '@elytracms/core/clipboard'\n\n/**\n * OS-clipboard transport (EC-175). The studio NEVER keeps an app-internal\n * copy buffer: every copy writes the EC-174 fragment representations to the\n * operating-system clipboard, and every paste reads them back — which is what\n * makes copy/paste work across documents, pages, projects, and browser tabs\n * for free.\n *\n * Two transports, by trigger:\n * - **ClipboardEvent / DataTransfer** (synchronous, no permissions): native\n * copy/cut/paste events expose `clipboardData` and accept arbitrary types,\n * so the canonical JSON travels as `application/json` alongside\n * `text/plain` + `text/html`.\n * - **navigator.clipboard** (async, used by explicit button affordances):\n * `write()` with a `ClipboardItem` carrying `text/html` + `text/plain`\n * (the JSON rides in `text/plain` and embedded in the HTML), falling back\n * to `writeText(json)` where `write`/`ClipboardItem` are unavailable.\n */\n\n/** The DataTransfer type carrying the canonical fragment JSON. */\nexport const DATA_TRANSFER_JSON_TYPE = 'application/json'\n\ninterface DataTransferWriter {\n setData(type: string, data: string): void\n}\n\ninterface DataTransferReader {\n getData(type: string): string\n}\n\n/** Write all three EC-174 representations onto a clipboard event's DataTransfer. */\nexport function writeFragmentToDataTransfer(dt: DataTransferWriter, fragment: ClipboardFragment): void {\n const reps = toClipboardRepresentations(fragment)\n dt.setData('text/plain', reps.text)\n dt.setData('text/html', reps.html)\n dt.setData(DATA_TRANSFER_JSON_TYPE, reps.json)\n}\n\n/** Read a fragment from a paste event's DataTransfer, in fidelity order. */\nexport function readFragmentFromDataTransfer(dt: DataTransferReader): ParseFragmentResult {\n const json = dt.getData(DATA_TRANSFER_JSON_TYPE)\n const html = dt.getData('text/html')\n const text = dt.getData('text/plain')\n return parseFragmentFromClipboard({\n json: json || undefined,\n html: html || undefined,\n text: text || undefined,\n })\n}\n\n/** The async-clipboard surface we use (subset of `Navigator['clipboard']`). */\nexport interface AsyncClipboard {\n write?(items: ClipboardItem[]): Promise<void>\n writeText?(text: string): Promise<void>\n read?(): Promise<ClipboardItems>\n readText?(): Promise<string>\n}\n\n/**\n * Write a fragment via the async Clipboard API. Tries the multi-representation\n * `ClipboardItem` first; falls back to `writeText` with the canonical JSON\n * (which `parseFragmentFromClipboard` restores from `text/plain`).\n */\nexport async function writeFragmentToClipboard(\n clipboard: AsyncClipboard | undefined,\n fragment: ClipboardFragment,\n): Promise<void> {\n if (!clipboard) throw new Error('Clipboard API is unavailable.')\n const reps = toClipboardRepresentations(fragment)\n const ClipboardItemCtor = (globalThis as { ClipboardItem?: typeof ClipboardItem }).ClipboardItem\n if (clipboard.write && ClipboardItemCtor) {\n try {\n await clipboard.write([\n new ClipboardItemCtor({\n 'text/plain': new Blob([reps.text], { type: 'text/plain' }),\n 'text/html': new Blob([reps.html], { type: 'text/html' }),\n }),\n ])\n return\n } catch {\n // fall through to writeText\n }\n }\n if (!clipboard.writeText) throw new Error('Clipboard API is unavailable.')\n await clipboard.writeText(reps.json)\n}\n\n/** Read a fragment via the async Clipboard API (`read`, falling back to `readText`). */\nexport async function readFragmentFromClipboard(\n clipboard: AsyncClipboard | undefined,\n): Promise<ParseFragmentResult> {\n if (clipboard?.read) {\n try {\n const items = await clipboard.read()\n let html: string | undefined\n let text: string | undefined\n for (const item of items) {\n if (item.types.includes('text/html')) html = await (await item.getType('text/html')).text()\n if (item.types.includes('text/plain')) text = await (await item.getType('text/plain')).text()\n }\n if (html !== undefined || text !== undefined) {\n return parseFragmentFromClipboard({ html, text })\n }\n } catch {\n // fall through to readText\n }\n }\n if (clipboard?.readText) {\n try {\n const text = await clipboard.readText()\n return parseFragmentFromClipboard({ text })\n } catch {\n // fall through to the structured error below\n }\n }\n return {\n ok: false,\n error: {\n code: 'foreign-format',\n message: 'The clipboard could not be read (no permission or unsupported browser).',\n },\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paste-issues.js","sourceRoot":"","sources":["../../../src/lib/clipboard/paste-issues.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"paste-issues.js","sourceRoot":"","sources":["../../../src/lib/clipboard/paste-issues.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BindingReference, ComponentNode } from '@elytracms/core/project-graph'\n\n/**\n * Permissive-paste validation (EC-175): pasting NEVER refuses a structurally\n * valid fragment. Instead, the inserted subtree is diffed against the TARGET\n * project's registry and data sources at paste time (cross-project semantics:\n * the fragment's source project is irrelevant — what matters is what *this*\n * project can resolve), and every mismatch becomes a visible, node-addressed\n * issue the notice deep-links. The renderer's existing fallbacks keep the\n * pasted nodes visible meanwhile.\n */\n\nexport interface PasteIssue {\n kind: 'missing-component' | 'unresolved-binding'\n message: string\n /** The inserted node carrying the problem — deep-link target. */\n nodeId: string\n}\n\nexport interface PasteDiff {\n /** Distinct component ids absent from the target registry. */\n missingComponents: string[]\n /** Distinct binding source ids the target cannot resolve. */\n unresolvedBindings: string[]\n issues: PasteIssue[]\n}\n\nfunction walk(node: ComponentNode, visit: (node: ComponentNode) => void): void {\n visit(node)\n for (const children of Object.values(node.slots ?? {})) {\n for (const child of children) walk(child, visit)\n }\n}\n\n/**\n * Diff an inserted subtree (with its final, session-assigned node ids)\n * against the target project's registry + known data sources.\n */\nexport function diffPastedSubtree(args: {\n node: ComponentNode\n hasComponent: (componentId: string) => boolean\n knownSourceIds: ReadonlySet<string>\n}): PasteDiff {\n const missingComponents = new Map<string, string>() // componentId -> first nodeId\n const unresolvedBindings = new Map<string, PasteIssue>() // nodeId+sourceId -> issue\n const unresolvedSourceIds = new Set<string>()\n walk(args.node, (node) => {\n if (!args.hasComponent(node.componentId) && !missingComponents.has(node.componentId)) {\n missingComponents.set(node.componentId, node.id)\n }\n const bindings: BindingReference[] = []\n for (const value of Object.values(node.props ?? {})) {\n if (value.kind === 'binding') bindings.push(value.binding)\n }\n if (node.condition) bindings.push(node.condition.source)\n for (const binding of bindings) {\n if (args.knownSourceIds.has(binding.sourceId)) continue\n unresolvedSourceIds.add(binding.sourceId)\n const key = `${node.id} ${binding.sourceId}`\n if (!unresolvedBindings.has(key)) {\n unresolvedBindings.set(key, {\n kind: 'unresolved-binding',\n message: `Binding source \"${binding.sourceId}\" is not available in this project.`,\n nodeId: node.id,\n })\n }\n }\n })\n const issues: PasteIssue[] = [\n ...[...unresolvedBindings.values()],\n ...[...missingComponents.entries()].map(\n ([componentId, nodeId]): PasteIssue => ({\n kind: 'missing-component',\n message: `Component \"${componentId}\" is not registered in this project.`,\n nodeId,\n }),\n ),\n ]\n return {\n missingComponents: [...missingComponents.keys()],\n unresolvedBindings: [...unresolvedSourceIds],\n issues,\n }\n}\n\n/** “Pasted — 2 bindings unresolved, 1 component missing”, or just “Pasted”. */\nexport function pasteSummaryMessage(diff: PasteDiff): string {\n const parts: string[] = []\n const bindings = diff.issues.filter((i) => i.kind === 'unresolved-binding').length\n if (bindings > 0) parts.push(`${bindings} binding${bindings === 1 ? '' : 's'} unresolved`)\n if (diff.missingComponents.length > 0) {\n const n = diff.missingComponents.length\n parts.push(`${n} component${n === 1 ? '' : 's'} missing`)\n }\n return parts.length > 0 ? `Pasted — ${parts.join(', ')}` : 'Pasted'\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paste-target.js","sourceRoot":"","sources":["../../../src/lib/clipboard/paste-target.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAkBtE,SAAS,OAAO,CAAC,WAAmB;IAClC,OAAO,WAAW,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;AAC5E,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAKlC;IACC,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,IAAI,CAAA;IAClC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAChF,MAAM,IAAI,GAAG,MAAM,IAAI,IAAI,CAAA;IAE3B,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IAC9C,MAAM,SAAS,GACb,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC;QAClD,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAA;IAClD,IAAI,SAAS,EAAE,CAAC;QACd,OAAO;YACL,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE;YACnD,gBAAgB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,SAAS,CAAC,IAAI,EAAE;SACrE,CAAA;IACH,CAAC;IAED,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAAA;IACzC,IAAI,IAAI,EAAE,CAAC;QACT,OAAO;YACL,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE;YAC5E,gBAAgB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE;SACvE,CAAA;IACH,CAAC;IAED,8EAA8E;IAC9E,OAAO,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,gBAAgB,EAAE,MAAM,EAAE,CAAA;AACtF,CAAC"}
|
|
1
|
+
{"version":3,"file":"paste-target.js","sourceRoot":"","sources":["../../../src/lib/clipboard/paste-target.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAkBtE,SAAS,OAAO,CAAC,WAAmB;IAClC,OAAO,WAAW,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;AAC5E,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAKlC;IACC,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,IAAI,CAAA;IAClC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAChF,MAAM,IAAI,GAAG,MAAM,IAAI,IAAI,CAAA;IAE3B,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IAC9C,MAAM,SAAS,GACb,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC;QAClD,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAA;IAClD,IAAI,SAAS,EAAE,CAAC;QACd,OAAO;YACL,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE;YACnD,gBAAgB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,SAAS,CAAC,IAAI,EAAE;SACrE,CAAA;IACH,CAAC;IAED,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAAA;IACzC,IAAI,IAAI,EAAE,CAAC;QACT,OAAO;YACL,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE;YAC5E,gBAAgB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE;SACvE,CAAA;IACH,CAAC;IAED,8EAA8E;IAC9E,OAAO,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,gBAAgB,EAAE,MAAM,EAAE,CAAA;AACtF,CAAC","sourcesContent":["import { getNode, getParentInfo } from '@elytracms/core/project-graph'\nimport type { ComponentNode, InsertTarget } from '@elytracms/core/project-graph'\nimport type { ComponentManifest } from '@elytracms/core/component-registry'\n\n/**\n * Paste landing-spot resolution (EC-175) — the same placement rule the Insert\n * dialog uses (`insert-context.ts`): a pasted subtree lands *into*\n * the anchor node's child slot when it has one, else *after* the anchor as a\n * sibling, else appended to the page root. Pure and selection-driven so the\n * canvas, the page tree, and keyboard paste all share one rule.\n */\n\nexport interface PasteTarget {\n target: InsertTarget\n /** Human label of where the paste lands (notices/debugging). */\n destinationLabel: string\n}\n\nfunction shortId(componentId: string): string {\n return componentId.replace('base.primitives.', '').replace('project.', '')\n}\n\nexport function resolvePasteTarget(args: {\n root: ComponentNode\n /** The anchor node (usually the selection); `null` falls back to the root. */\n anchorId: string | null\n getManifest: (componentId: string) => ComponentManifest | undefined\n}): PasteTarget {\n const { root, getManifest } = args\n const anchor = args.anchorId !== null ? getNode(root, args.anchorId) : undefined\n const node = anchor ?? root\n\n const manifest = getManifest(node.componentId)\n const childSlot =\n manifest?.slots.find((s) => s.name === 'children') ??\n manifest?.slots.find((s) => s.name !== 'outlet')\n if (childSlot) {\n return {\n target: { parentId: node.id, slot: childSlot.name },\n destinationLabel: `${shortId(node.componentId)} · ${childSlot.name}`,\n }\n }\n\n const info = getParentInfo(root, node.id)\n if (info) {\n return {\n target: { parentId: info.parent.id, slot: info.slot, index: info.index + 1 },\n destinationLabel: `${shortId(info.parent.componentId)} · ${info.slot}`,\n }\n }\n\n // Leaf root with no declared slots (degenerate graphs): append to `children`.\n return { target: { parentId: root.id, slot: 'children' }, destinationLabel: 'root' }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"published-documents.js","sourceRoot":"","sources":["../../../src/lib/cms/published-documents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAEhE,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AAwBnD,6EAA6E;AAC7E,MAAM,UAAU,GAAwB,IAAI,GAAG,CAAC;IAC9C,mBAAmB;IACnB,qBAAqB;IACrB,mBAAmB;IACnB,kBAAkB;CACnB,CAAC,CAAA;AAEF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,UAA4B,EAC5B,SAAiB,EACjB,YAAoB;IAEpB,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC,CAAA;IACvF,IAAI,CAAC,MAAM,CAAC,EAAE;QAAE,OAAO,IAAI,GAAG,EAAE,CAAA;IAChC,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAA;IACxF,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,GAAG,CACjC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;QAC7B,MAAM,GAAG,GAAG,EAAE,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,EAAE,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAA;QAC9E,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAA;QAC5E,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,OAAO,IAAI,CAAA;QAC7B,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,MAAM,CAAC,gBAAgB,CAAC,EAAE,QAAQ,IAAI,IAAI,CAAA;IAC5F,CAAC,CAAC,CACH,CAAA;IACD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAuB,CAAA;IAC3C,KAAK,MAAM,QAAQ,IAAI,SAAS;QAAE,IAAI,QAAQ;YAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAA;IAC/E,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,SAA6B,EAC7B,YAAoB;IAEpB,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAqB,EAAE,IAAI,EAAE,IAAI,GAAG,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAA;IAC9F,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;IAE1B,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QAClC,MAAM,KAAK,GAAG,EAAE,QAAQ,CAAC,OAAO,CAAA;QAChC,MAAM,MAAM,GAAG,CAAC,IAA8B,EAAE,EAAE;YAChD,IAAI,QAAQ,CAAC,OAAO,KAAK,KAAK;gBAAE,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAA;QACrE,CAAC,CAAA;QACD,2EAA2E;QAC3E,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC,CAAA;YACjB,OAAM;QACR,CAAC;QACD,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,mBAAmB,EAAE,CAAA;QAClD,MAAM,CAAC,MAAM,sBAAsB,CAAC,UAAU,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC,CAAA;IAC3E,CAAC,EAAE,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,CAAA;IAE7B,SAAS,CAAC,GAAG,EAAE;QACb,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,CAAA;QAC5D,KAAK,IAAI,EAAE,CAAA;QACX,IAAI,QAAQ,GAAG,KAAK,CAAA;QACpB,IAAI,WAAqC,CAAA;QACzC,KAAK,mBAAmB,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;YACzC,IAAI,QAAQ;gBAAE,OAAM;YACpB,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE;gBACzD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW;oBAAE,OAAM;gBACpE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC;oBAAE,OAAM;gBAC5C,KAAK,IAAI,EAAE,CAAA;YACb,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;QACF,OAAO,GAAG,EAAE;YACV,QAAQ,GAAG,IAAI,CAAA;YACf,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAA;YACrB,WAAW,EAAE,EAAE,CAAA;QACjB,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;IAEV,OAAO,KAAK,CAAA;AACd,CAAC"}
|
|
1
|
+
{"version":3,"file":"published-documents.js","sourceRoot":"","sources":["../../../src/lib/cms/published-documents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAEhE,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AAwBnD,6EAA6E;AAC7E,MAAM,UAAU,GAAwB,IAAI,GAAG,CAAC;IAC9C,mBAAmB;IACnB,qBAAqB;IACrB,mBAAmB;IACnB,kBAAkB;CACnB,CAAC,CAAA;AAEF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,UAA4B,EAC5B,SAAiB,EACjB,YAAoB;IAEpB,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC,CAAA;IACvF,IAAI,CAAC,MAAM,CAAC,EAAE;QAAE,OAAO,IAAI,GAAG,EAAE,CAAA;IAChC,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAA;IACxF,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,GAAG,CACjC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;QAC7B,MAAM,GAAG,GAAG,EAAE,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,EAAE,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAA;QAC9E,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAA;QAC5E,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,OAAO,IAAI,CAAA;QAC7B,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,MAAM,CAAC,gBAAgB,CAAC,EAAE,QAAQ,IAAI,IAAI,CAAA;IAC5F,CAAC,CAAC,CACH,CAAA;IACD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAuB,CAAA;IAC3C,KAAK,MAAM,QAAQ,IAAI,SAAS;QAAE,IAAI,QAAQ;YAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAA;IAC/E,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,SAA6B,EAC7B,YAAoB;IAEpB,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAqB,EAAE,IAAI,EAAE,IAAI,GAAG,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAA;IAC9F,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;IAE1B,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QAClC,MAAM,KAAK,GAAG,EAAE,QAAQ,CAAC,OAAO,CAAA;QAChC,MAAM,MAAM,GAAG,CAAC,IAA8B,EAAE,EAAE;YAChD,IAAI,QAAQ,CAAC,OAAO,KAAK,KAAK;gBAAE,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAA;QACrE,CAAC,CAAA;QACD,2EAA2E;QAC3E,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC,CAAA;YACjB,OAAM;QACR,CAAC;QACD,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,mBAAmB,EAAE,CAAA;QAClD,MAAM,CAAC,MAAM,sBAAsB,CAAC,UAAU,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC,CAAA;IAC3E,CAAC,EAAE,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,CAAA;IAE7B,SAAS,CAAC,GAAG,EAAE;QACb,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,CAAA;QAC5D,KAAK,IAAI,EAAE,CAAA;QACX,IAAI,QAAQ,GAAG,KAAK,CAAA;QACpB,IAAI,WAAqC,CAAA;QACzC,KAAK,mBAAmB,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;YACzC,IAAI,QAAQ;gBAAE,OAAM;YACpB,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE;gBACzD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW;oBAAE,OAAM;gBACpE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC;oBAAE,OAAM;gBAC5C,KAAK,IAAI,EAAE,CAAA;YACb,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;QACF,OAAO,GAAG,EAAE;YACV,QAAQ,GAAG,IAAI,CAAA;YACf,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAA;YACrB,WAAW,EAAE,EAAE,CAAA;QACjB,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;IAEV,OAAO,KAAK,CAAA;AACd,CAAC","sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react'\nimport type { CmsDocument } from '@elytracms/core/cms-core'\nimport { getStudioOperations } from '../operations'\nimport type { OperationsClient } from '../operations'\n\n/**\n * The PUBLISHED-perspective documents of a collection (EC-205, \"live = published\")\n * — the pinned published snapshot of each currently-published document, keyed by\n * id. Live surfaces (a document's live URL + \"View live\", EC-216) MUST derive\n * from this, never from the draft rows the studio edits: an unpublished document,\n * or an unpublished `slug`/`parent` edit, must never leak into a \"live\" URL. The\n * pool is exactly the set the live site would serve, so composing a nested page's\n * URL from these ancestors yields the URL the live site actually resolves.\n *\n * Loaded lazily; reloaded only when a publish/unpublish/restore/delete command\n * succeeds (NOT on every autosave upsert — a draft edit doesn't change what's\n * published). Cost: one `listVersions` per published document (there is no bulk\n * published-content query yet) — fine for v1 collections; a bulk\n * `documents.listPublished` is the perf follow-up for large collections.\n */\nexport interface PublishedDocuments {\n /** Pinned published snapshot per published document id. Empty while loading. */\n byId: ReadonlyMap<string, CmsDocument>\n status: 'loading' | 'ready'\n}\n\n/** Commands that change which version is pinned live (and thus the pool). */\nconst RELOAD_OPS: ReadonlySet<string> = new Set([\n 'documents.publish',\n 'documents.unpublish',\n 'documents.restore',\n 'documents.delete',\n])\n\n/**\n * Build the published pool of a collection (pure over the operations client): the\n * pinned published snapshot of every currently-published document, keyed by id.\n * The `publishedVersion` pointer comes from the document record; its snapshot\n * from the recorded versions. Read failures degrade to an empty pool.\n */\nexport async function loadPublishedDocuments(\n operations: OperationsClient,\n projectId: string,\n collectionId: string,\n): Promise<Map<string, CmsDocument>> {\n const listed = await operations.documents.list({ projectId, collection: collectionId })\n if (!listed.ok) return new Map()\n const published = listed.value.filter((record) => record.publishedVersion !== undefined)\n const snapshots = await Promise.all(\n published.map(async (record) => {\n const ref = { collection: record.document.collection, id: record.document.id }\n const versions = await operations.documents.listVersions({ projectId, ref })\n if (!versions.ok) return null\n return versions.value.find((v) => v.version === record.publishedVersion)?.snapshot ?? null\n }),\n )\n const byId = new Map<string, CmsDocument>()\n for (const snapshot of snapshots) if (snapshot) byId.set(snapshot.id, snapshot)\n return byId\n}\n\nexport function usePublishedDocuments(\n projectId: string | undefined,\n collectionId: string,\n): PublishedDocuments {\n const [state, setState] = useState<PublishedDocuments>({ byId: new Map(), status: 'loading' })\n const epochRef = useRef(0)\n\n const load = useCallback(async () => {\n const epoch = ++epochRef.current\n const settle = (byId: Map<string, CmsDocument>) => {\n if (epochRef.current === epoch) setState({ byId, status: 'ready' })\n }\n // Playground/fixture mode (no backend): nothing is published via versions.\n if (projectId === undefined) {\n settle(new Map())\n return\n }\n const { operations } = await getStudioOperations()\n settle(await loadPublishedDocuments(operations, projectId, collectionId))\n }, [projectId, collectionId])\n\n useEffect(() => {\n setState((prev) => ({ byId: prev.byId, status: 'loading' }))\n void load()\n let disposed = false\n let unsubscribe: (() => void) | undefined\n void getStudioOperations().then((studio) => {\n if (disposed) return\n unsubscribe = studio.operations.events.subscribe((event) => {\n if (event.kind !== 'command' || event.status !== 'succeeded') return\n if (!RELOAD_OPS.has(event.operation)) return\n void load()\n })\n })\n return () => {\n disposed = true\n epochRef.current += 1\n unsubscribe?.()\n }\n }, [load])\n\n return state\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/cms-views/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/cms-views/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA","sourcesContent":["/**\n * Saved views & table-view model for the CMS collection table (EC-169):\n * the pure filter/sort/column model (`view-model`), row selection\n * (`selection`), and project-scoped persistence through `@elytracms/core/operations`\n * (`views-store`).\n */\nexport * from './view-model'\nexport * from './selection'\nexport * from './views-store'\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selection.js","sourceRoot":"","sources":["../../../src/lib/cms-views/selection.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,MAAM,CAAC,MAAM,eAAe,GAAmB,EAAE,GAAG,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAA;AAE1E;;;;GAIG;AACH,MAAM,UAAU,SAAS,CACvB,KAAqB,EACrB,UAA6B,EAC7B,EAAU,EACV,UAAmB;IAEnB,IAAI,UAAU,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;QAC1C,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;QACtD,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QAC3C,IAAI,WAAW,IAAI,CAAC,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;YAC1C,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GACZ,WAAW,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,WAAW,CAAC,CAAA;YACzF,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,CAAA;YAC1C,OAAO,EAAE,GAAG,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAA;QAClF,CAAC;IACH,CAAC;IACD,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;IACvC,OAAO;QACL,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,EAAE,EAAE,CAAC;QACpF,QAAQ,EAAE,EAAE;KACb,CAAA;AACH,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,SAAS,CAAC,UAA6B;IACrD,OAAO,EAAE,GAAG,EAAE,CAAC,GAAG,UAAU,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAA;AACjD,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,eAAe,CAAA;AACxB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,KAAqB,EACrB,UAA6B;IAE7B,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACnC,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;AACpD,CAAC"}
|
|
1
|
+
{"version":3,"file":"selection.js","sourceRoot":"","sources":["../../../src/lib/cms-views/selection.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,MAAM,CAAC,MAAM,eAAe,GAAmB,EAAE,GAAG,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAA;AAE1E;;;;GAIG;AACH,MAAM,UAAU,SAAS,CACvB,KAAqB,EACrB,UAA6B,EAC7B,EAAU,EACV,UAAmB;IAEnB,IAAI,UAAU,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;QAC1C,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;QACtD,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QAC3C,IAAI,WAAW,IAAI,CAAC,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;YAC1C,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GACZ,WAAW,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,WAAW,CAAC,CAAA;YACzF,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,CAAA;YAC1C,OAAO,EAAE,GAAG,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAA;QAClF,CAAC;IACH,CAAC;IACD,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;IACvC,OAAO;QACL,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,EAAE,EAAE,CAAC;QACpF,QAAQ,EAAE,EAAE;KACb,CAAA;AACH,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,SAAS,CAAC,UAA6B;IACrD,OAAO,EAAE,GAAG,EAAE,CAAC,GAAG,UAAU,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAA;AACjD,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,eAAe,CAAA;AACxB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,KAAqB,EACrB,UAA6B;IAE7B,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACnC,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;AACpD,CAAC","sourcesContent":["/**\n * Row-selection model for the collection table (EC-169). Pure data +\n * functions: plain click toggles one row (and moves the range anchor),\n * shift-click selects the whole anchor→row range, the header checkbox selects\n * everything in the current view. The table prunes against the *visible*\n * (filtered) row order at read time, so a selection never silently includes\n * rows the active view filtered out.\n */\n\nexport interface SelectionState {\n /** Selected document ids, in click order (pruned/re-ordered at read time). */\n ids: readonly string[]\n /** The last plainly-clicked row — the start of a shift-range. */\n anchorId: string | null\n}\n\nexport const EMPTY_SELECTION: SelectionState = { ids: [], anchorId: null }\n\n/**\n * Apply one row-checkbox click. `shiftRange` (shift held, with a valid anchor)\n * selects every row between the anchor and the clicked row inclusive; a plain\n * click toggles the row and re-anchors on it.\n */\nexport function toggleRow(\n state: SelectionState,\n orderedIds: readonly string[],\n id: string,\n shiftRange: boolean,\n): SelectionState {\n if (shiftRange && state.anchorId !== null) {\n const anchorIndex = orderedIds.indexOf(state.anchorId)\n const clickedIndex = orderedIds.indexOf(id)\n if (anchorIndex >= 0 && clickedIndex >= 0) {\n const [lo, hi] =\n anchorIndex <= clickedIndex ? [anchorIndex, clickedIndex] : [clickedIndex, anchorIndex]\n const range = orderedIds.slice(lo, hi + 1)\n return { ids: [...new Set([...state.ids, ...range])], anchorId: state.anchorId }\n }\n }\n const selected = state.ids.includes(id)\n return {\n ids: selected ? state.ids.filter((existing) => existing !== id) : [...state.ids, id],\n anchorId: id,\n }\n}\n\n/** Select every row in the current view (header checkbox). */\nexport function selectAll(orderedIds: readonly string[]): SelectionState {\n return { ids: [...orderedIds], anchorId: null }\n}\n\nexport function clearSelection(): SelectionState {\n return EMPTY_SELECTION\n}\n\n/**\n * The selection that is actually in the current view, in view order — what\n * the count, the header checkbox, and every bulk action operate on.\n */\nexport function visibleSelection(\n state: SelectionState,\n visibleIds: readonly string[],\n): string[] {\n const selected = new Set(state.ids)\n return visibleIds.filter((id) => selected.has(id))\n}\n"]}
|