/** * Canonical content resolver for Elise Studio. * * Ported from site_compiler.py — this is the single source of truth for * content resolution. Used by: * - Live preview (client-side, in the CRM editor) * - Preview renderer (postMessage listener) * - Production compiler (via bun CLI wrapper) * * The resolver merges content blobs by scope, substitutes $key directives, * interpolates {{variable}} tokens, resolves asset URLs, and expands * BuildingSlice / building_template directives. */ import type { SiteConfig } from "../types"; import { type PropSpec } from "../schema/componentSchema"; export type ContentValue = string | AssetValue | ContentValue[] | { [key: string]: ContentValue; }; export interface ImageFocalPoint { x: number; y: number; } export interface AssetCrop { aspect: number; } export interface AssetValue { asset: string; alt?: string | null; focal?: ImageFocalPoint | null; crop?: AssetCrop | null; } export interface ResolvedImage { src: string; srcSet?: string; sizes?: string; width?: number; height?: number; alt?: string; assetAlt?: string; placementAlt?: string; focalPoint?: ImageFocalPoint; crop?: AssetCrop; unresolved?: boolean; quietUnresolved?: boolean; displayFilename?: string; asset?: string; } export interface AssetManifestMetadata { filename?: string; name?: string; key?: string; asset?: string; width?: number | null; height?: number | null; alt?: string | null; display_filename?: string | null; displayFilename?: string | null; focal_point?: ImageFocalPoint | null; focalPoint?: ImageFocalPoint | null; focal?: ImageFocalPoint | null; crop?: AssetCrop | null; metadata?: AssetManifestMetadata; [key: string]: unknown; } export type AssetManifestEntry = string | AssetManifestMetadata; export type AssetManifestScope = AssetManifestEntry[] | Record; export type AssetManifest = Record; export interface ResolveOptions { rawSiteJson: RawSiteConfig; contentBlobs: Record>; assetManifest: AssetManifest; assetCdnBase: string; buildingIds: number[]; preserveKeys?: boolean; /** * Editor/preview-only identity substrate. Default stays off so existing * compiler/consumer output remains byte-identical. */ includeIdentity?: boolean; } /** * A reusable named subtree. `tree` is a template that may contain * `{$prop:"name"}` bindings and named `{type:"Slot",name:"x"}` placeholders, * expanded at compile time by `expandSymbol`. `props`/`slots` are declared * metadata (defaults + per-slot constraints); only `default` is consulted by * the resolver — full validation lives in the lint stage. * * Saved Components (P5) reuse this shape: a `{type:"Symbol", ref:"lib:{componentId}"}` * instance references the org library. The resolver applies NO special handling — a * `lib:`-prefixed ref is an ordinary `symbols` key. Before resolveConfig runs, each * consumer (compiler `_resolve`, CRM `/validate` lint, FE live-preview) hydrates the * referenced library definitions into `symbols`, keyed by the full `lib:{componentId}` * string, transitively to a fixpoint (a def may itself nest `lib:` refs). So expansion * of a Saved Component is identical to an inline symbol — see resolveConfig.lib-hydration.test.ts. */ export interface SymbolDef { props?: Record; slots?: Record; tree: RawNode; } /** * A named data source a `Repeat` iterates. `mode:"compile"` (source `"site.buildings"`) * expands at resolve time, once per building; `mode:"runtime"` is fetched client-side by * the runtime Repeat (P4b), not expanded here. Other fields shape only the runtime fetch. */ export interface DatasetDef { source: string; mode: "compile" | "runtime"; filter?: Record; sort?: string; limit?: number; record?: string; } /** Raw site.json before resolution (has $key directives, building_template pages, etc.) */ export interface RawSiteConfig { meta?: Record; theme?: Record; property?: Record; layouts?: Record; pages?: RawPage[]; /** Authoring-only content schema; stripped from resolved output. */ contentSchema?: Record; /** Reusable named subtrees, expanded at compile time; stripped from output. */ symbols?: Record; /** Named data sources a `Repeat` iterates; consumed at resolve time, stripped from output. */ datasets?: Record; [key: string]: unknown; } interface RawPage { path?: string; tree?: RawNode; building_template?: boolean; layout?: string; meta?: Record; [key: string]: unknown; } type RawNode = Record; /** * Resolve a raw theme's `{$token}` aliases and fold in a per-building mode. * Identity (back-compat) for legacy `{colors,...}` themes with no `tokens`/`modes`. * Reachable via the "./resolve" subpath for the P4a per-building call. */ export declare function assembleTheme(rawTheme: Record | undefined, buildingId?: number): Record | undefined; export declare function resolveConfig(options: ResolveOptions): SiteConfig; export {}; //# sourceMappingURL=resolveConfig.d.ts.map