meno-core 1.0.38 → 1.0.39
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/build-astro.ts +914 -0
- package/dist/build-static.js +2 -2
- package/dist/chunks/{chunk-UR7L5UZ3.js → chunk-HNAS6BSS.js} +2 -2
- package/dist/chunks/{chunk-EUCAKI5U.js → chunk-W6HDII4T.js} +8 -1
- package/dist/chunks/{chunk-EUCAKI5U.js.map → chunk-W6HDII4T.js.map} +2 -2
- package/dist/chunks/{chunk-JACS3C25.js → chunk-WK5XLASY.js} +2 -2
- package/dist/entries/server-router.js +2 -2
- package/dist/lib/client/index.js +5 -3
- package/dist/lib/client/index.js.map +2 -2
- package/dist/lib/server/index.js +1840 -5
- package/dist/lib/server/index.js.map +4 -4
- package/dist/lib/shared/index.js +5 -3
- package/dist/lib/shared/index.js.map +2 -2
- package/lib/client/theme.ts +4 -1
- package/lib/server/astro/componentEmitter.ts +208 -0
- package/lib/server/astro/cssCollector.ts +147 -0
- package/lib/server/astro/index.ts +5 -0
- package/lib/server/astro/nodeToAstro.ts +771 -0
- package/lib/server/astro/pageEmitter.ts +190 -0
- package/lib/server/astro/tailwindMapper.ts +547 -0
- package/lib/server/index.ts +3 -0
- package/lib/server/ssr/htmlGenerator.ts +3 -0
- package/lib/server/ssr/ssrRenderer.test.ts +8 -4
- package/lib/server/ssr/ssrRenderer.ts +1 -3
- package/lib/shared/themeDefaults.test.ts +1 -1
- package/lib/shared/themeDefaults.ts +4 -1
- package/package.json +1 -1
- /package/dist/chunks/{chunk-UR7L5UZ3.js.map → chunk-HNAS6BSS.js.map} +0 -0
- /package/dist/chunks/{chunk-JACS3C25.js.map → chunk-WK5XLASY.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../lib/shared/index.ts", "../../../lib/shared/treePathUtils.ts", "../../../lib/shared/colorProperties.ts", "../../../lib/shared/tree/PathBuilder.ts", "../../../lib/shared/validation/index.ts", "../../../lib/shared/validation/cmsValidators.ts", "../../../lib/shared/utils.ts", "../../../lib/shared/themeDefaults.ts", "../../../lib/shared/colorVariableUtils.ts", "../../../lib/shared/errors.ts", "../../../lib/shared/colorConversions.ts", "../../../lib/shared/gradientUtils.ts", "../../../lib/shared/cmsQueryParser.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * meno-core shared exports\n * Re-exports all types, constants, and utilities from shared modules\n */\n\n// Types\nexport * from './types';\n\n// Constants\nexport * from './constants';\n\n// Path utilities\nexport * from './pathArrayUtils';\nexport * from './treePathUtils';\nexport * from './paths';\n\n// Node utilities\nexport * from './nodeUtils';\n\n// Style utilities\nexport * from './breakpoints';\nexport * from './styleUtils';\nexport * from './cssProperties';\nexport * from './cssGeneration';\nexport * from './colorProperties';\nexport * from './utilityClassMapper';\nexport * from './elementClassName';\nexport * from './styleValueRegistry';\n\n// i18n utilities\nexport * from './i18n';\n\n// Slugify utilities\nexport * from './slugify';\n\n// Tree utilities\nexport * from './tree/PathBuilder';\n\n// Validation - use explicit exports to avoid ValidationError conflict with types/errors.ts\nexport {\n // Schemas\n StyleMappingSchema,\n StyleObjectSchema,\n ResponsiveStyleObjectSchema,\n StyleValueSchema,\n InteractiveStyleRuleSchema,\n InteractiveStylesSchema,\n PageDataSchema,\n PageDataWithComponentSchema,\n PropDefinitionSchema,\n ComponentNodeSchema,\n ComponentDefinitionSchema,\n StructuredComponentDefinitionSchema,\n PageMetaDataSchema,\n CMSClientDataStrategySchema,\n CMSClientDataConfigSchema,\n CMSSchemaSchema,\n CMSItemSchema,\n // Validators\n type ValidationResult,\n validatePropDefinition,\n validateComponentNode,\n validateComponentDefinition,\n validateStructuredComponentDefinition,\n validatePageData,\n validatePageDataWithComponent,\n validatePageMetaData,\n validateCMSSchema,\n validateCMSItem,\n // Prop validator\n type PropValidationError,\n type PropValidationResult,\n validateComponentProps,\n // CMS validators\n isValidCollectionId,\n validateCollectionId,\n CMS_COLLECTION_ID_REGEX,\n CMSCollectionIdSchema,\n} from './validation';\n\n// Utils\nexport * from './utils';\n\n// Registry\nexport * from './registry';\n\n// Theme defaults\nexport * from './themeDefaults';\n\n// Color variable utilities\nexport * from './colorVariableUtils';\n\n// Responsive style utilities\nexport * from './responsiveStyleUtils';\n\n// Item template utilities (for CMS List)\nexport * from './itemTemplateUtils';\n\n// Path security utilities\nexport * from './pathSecurity';\n\n// Interactive style mapping utilities\nexport * from './interactiveStyleMappings';\n\n// Rich text utilities (Tiptap)\nexport * from './richtext';\n\n// Error handling\nexport * from './errors';\nexport { logRuntimeError, logNetworkError, setErrorHandler } from './errorLogger';\n\n// Global template context\nexport * from './globalTemplateContext';\n\n// Link utilities\nexport * from './linkUtils';\n\n// Color conversion utilities\nexport * from './colorConversions';\n\n// Gradient utilities\nexport * from './gradientUtils';\n\n// CMS query parsing utilities\nexport * from './cmsQueryParser';\n\n// Prop resolution utilities\nexport { resolvePropsFromDefinition, isRichTextMarker, richTextMarkerToHtml } from './propResolver';\n", "/**\n * Tree path utilities for parsing and navigating tree structure paths\n */\n\nimport { ComponentNode, PageData, JSONPage } from './types';\nimport type { PropDefinition } from './types';\nimport type { Path } from './pathArrayUtils';\nimport { stringToPath } from './pathArrayUtils';\n\n// Type for page data that can have component structure\ntype PageDataWithComponent = PageData & {\n component?: {\n structure?: ComponentNode;\n interface?: Record<string, PropDefinition>;\n };\n};\n\nexport interface NodeLocation {\n parent: ComponentNode | PageData | null;\n index: number;\n node: ComponentNode | null;\n}\n\n/**\n * Validate that component data has a valid structure\n * @param pageData - PageData to validate\n * @returns true if component has valid structure, false otherwise\n */\nexport function validateComponentStructure(pageData: PageData | null): boolean {\n if (!pageData) return false;\n \n // Check for page format (has root property)\n if ('root' in pageData && pageData.root) {\n return true;\n }\n \n // Check for component format (has component.structure property)\n if ('component' in pageData && pageData.component) {\n if ('structure' in pageData.component && pageData.component.structure) {\n return true;\n }\n // Component exists but structure is missing\n return false;\n }\n \n return false;\n}\n\n/**\n * Get the root data from pageData (handles both page and component structures\n * Logs warnings when structure is missing for better debugging\n */\nexport function getRootData(pageData: PageData | null): ComponentNode | null {\n if (!pageData) return null;\n \n // Check for page format (has root property)\n if ('root' in pageData && pageData.root) {\n return pageData.root;\n }\n \n // Check for component format (has component.structure property)\n if ('component' in pageData && pageData.component) {\n if ('structure' in pageData.component) {\n const structure = pageData.component.structure;\n if (structure) {\n return structure;\n }\n // Structure field exists but is null/undefined\n } else {\n // Component exists but structure field is missing\n }\n }\n \n return null;\n}\n\n/**\n * Parse a tree path and return the parent, index, and node\n * Handles paths like: root_0, root_0_children_0, root_0_children_0_children_1\n * Also accepts array paths: [0], [0,0], [0,0,1]\n */\nexport function getParentAndIndexFromPath(\n path: Path | string, \n pageData: PageData\n): NodeLocation | null {\n const rootData = getRootData(pageData);\n if (!rootData) return null;\n\n // Convert string to array if needed\n const pathArray = typeof path === 'string' ? stringToPath(path) : path;\n\n // Handle root [0] specially\n if (pathArray.length === 1 && pathArray[0] === 0) {\n return {\n parent: pageData,\n index: 0,\n node: rootData\n };\n }\n\n // Navigate through path array\n let current: ComponentNode = rootData;\n let parent: ComponentNode | PageData | null = null;\n let lastIndex = -1;\n\n // Skip first element (root index 0), navigate through rest\n for (let i = 1; i < pathArray.length; i++) {\n const childIndex = pathArray[i];\n\n if (!current || !('children' in current) || !Array.isArray(current.children)) {\n return null;\n }\n \n if (isNaN(childIndex) || childIndex < 0 || childIndex >= current.children.length) {\n return null;\n }\n\n parent = current;\n const child = current.children[childIndex];\n if (typeof child === 'string') {\n return null;\n }\n current = child;\n lastIndex = childIndex;\n\n // If this is the last navigation step, we found our node\n if (i === pathArray.length - 1) {\n return { parent, index: childIndex, node: current };\n }\n }\n\n // Return the last valid location if we got here\n if (parent && lastIndex >= 0) {\n return { parent, index: lastIndex, node: current };\n }\n\n return null;\n}\n\n/**\n * Extract structure without styles/props for tree comparison\n * This allows tree to only regenerate when structure changes, not styles\n */\nexport function extractStructureWithoutStyles(node: ComponentNode | string | null | undefined): ComponentNode | string | null | undefined {\n if (!node || typeof node === 'string') {\n return node;\n }\n\n if (typeof node !== 'object') {\n return node;\n }\n\n // Create a new object with only structure-relevant properties\n const { type } = node;\n const tag = 'tag' in node ? (node.tag as string | undefined) : undefined;\n const label = 'label' in node ? (node as any).label : undefined;\n const component = 'component' in node ? (node as any).component : undefined;\n const ifCondition = 'if' in node ? node.if : undefined;\n const children = 'children' in node ? node.children : undefined;\n \n // Recursively process children\n let processedChildren: ComponentNode | (ComponentNode | string)[] | string | undefined;\n if (children) {\n if (Array.isArray(children)) {\n processedChildren = children.map((child: ComponentNode | string) =>\n typeof child === 'string' ? child : extractStructureWithoutStyles(child) as ComponentNode\n );\n } else if (typeof children === 'string') {\n processedChildren = children;\n } else if (typeof children === 'object' && 'type' in children) {\n processedChildren = extractStructureWithoutStyles(children as ComponentNode) as ComponentNode;\n }\n }\n\n const result: Partial<ComponentNode> = { type };\n if (tag !== undefined) {\n (result as { tag?: string }).tag = tag;\n }\n if (label !== undefined) {\n (result as any).label = label;\n }\n if (component !== undefined) {\n (result as any).component = component;\n }\n if (ifCondition !== undefined) {\n (result as { if?: any }).if = ifCondition;\n }\n if (processedChildren !== undefined) {\n (result as { children?: typeof processedChildren }).children = processedChildren;\n }\n return result as ComponentNode;\n}\n\n/**\n * Calculate insertion index based on drop target information\n */\nexport function calculateInsertionIndex(\n target: {\n childIndex?: number;\n childAfterItem?: { index: string };\n childBeforeItem?: { index: string };\n linearIndex?: number;\n },\n parentChildren: Array<ComponentNode | string>,\n nodeDataMap: Map<string, ComponentNode | string>\n): number {\n if (target.childIndex !== undefined && target.childIndex >= 0) {\n // Most reliable: use childIndex directly\n return Math.min(Math.max(0, target.childIndex), parentChildren.length);\n }\n\n if (target.childAfterItem?.index) {\n const afterPath = target.childAfterItem.index;\n const afterNode = nodeDataMap.get(afterPath);\n if (afterNode) {\n const afterIndex = parentChildren.findIndex((child: ComponentNode | string) => child === afterNode);\n if (afterIndex >= 0) {\n return afterIndex + 1;\n }\n }\n // Fallback: append\n return parentChildren.length;\n }\n\n if (target.childBeforeItem?.index) {\n const beforePath = target.childBeforeItem.index;\n const beforeNode = nodeDataMap.get(beforePath);\n if (beforeNode) {\n const beforeIndex = parentChildren.findIndex((child: ComponentNode | string) => child === beforeNode);\n if (beforeIndex >= 0) {\n return beforeIndex;\n }\n }\n // Fallback: prepend\n return 0;\n }\n\n // Last resort: use linearIndex or append\n if (target.linearIndex !== undefined) {\n return Math.min(Math.max(0, target.linearIndex), parentChildren.length);\n }\n\n return parentChildren.length;\n}\n\n/**\n * Type guard to check if a value is a valid NodeLocation\n */\nexport function isValidNodeLocation(location: unknown): location is NodeLocation {\n if (!location || typeof location !== 'object') {\n return false;\n }\n \n // Use proper type narrowing instead of assertion\n const loc = location as Record<string, unknown>;\n const hasParent = 'parent' in loc && (loc.parent === null || typeof loc.parent === 'object');\n const hasIndex = 'index' in loc && typeof loc.index === 'number' && loc.index >= 0;\n const hasNode = 'node' in loc && (loc.node === null || typeof loc.node === 'object');\n \n return hasParent && hasIndex && hasNode;\n}\n\n/**\n * Type guard to check if a value is a valid Path\n */\nexport function isValidPath(path: unknown): path is Path {\n if (!Array.isArray(path)) {\n return false;\n }\n \n // Path is an array of numbers\n return path.every((item): item is number => typeof item === 'number' && item >= 0);\n}\n\n/**\n * Type guard to check if parent is PageData\n */\nexport function isPageDataParent(\n parent: ComponentNode | PageData | null\n): parent is PageData {\n if (!parent) return false;\n \n // Check for JSONPage format (has root property)\n if ('root' in parent) return true;\n \n // Check for component format - component must be an object, not a string\n if ('component' in parent) {\n return typeof parent.component === 'object' && parent.component !== null;\n }\n \n return false;\n}\n\n/**\n * Type guard to check if parent is ComponentNode\n */\nexport function isComponentNodeParent(\n parent: ComponentNode | PageData | null\n): parent is ComponentNode {\n if (!parent) return false;\n // Check for 'type' property (all ComponentNodes have it)\n // Then check for specific node types that can have children:\n // - HtmlNode: has 'tag' property\n // - ComponentInstanceNode: has 'component' property\n // - SlotMarker: type === 'slot'\n // - LinkNode: type === 'link'\n // - EmbedNode: type === 'embed'\n // - ListNode: type === 'list' (also handles legacy 'cms-list' for migration)\n const nodeType = (parent as any).type;\n return 'type' in parent && (\n 'tag' in parent ||\n 'component' in parent ||\n nodeType === 'slot' ||\n nodeType === 'link' ||\n nodeType === 'embed' ||\n nodeType === 'cms-list' || // Legacy support for migration\n nodeType === 'list'\n );\n}\n\n/**\n * Get children array from parent (handles both PageData and ComponentNode)\n */\nexport function getParentChildren(\n parent: ComponentNode | PageData | null\n): Array<ComponentNode | string> | null {\n if (!parent) return null;\n \n if (isPageDataParent(parent)) {\n const rootData = getRootData(parent);\n return rootData && 'children' in rootData ? (rootData.children as Array<ComponentNode | string> | undefined) || null : null;\n }\n\n if (isComponentNodeParent(parent)) {\n return 'children' in parent ? (parent.children as Array<ComponentNode | string> | undefined) || null : null;\n }\n\n return null;\n}\n\n/**\n * Set children array on parent (handles both PageData and ComponentNode)\n */\nexport function setParentChildren(\n parent: ComponentNode | PageData | null,\n children: Array<ComponentNode | string>\n): void {\n if (!parent) return;\n \n if (isPageDataParent(parent)) {\n const rootData = getRootData(parent);\n if (rootData && 'children' in rootData) {\n rootData.children = children;\n }\n } else if (isComponentNodeParent(parent)) {\n if ('children' in parent) {\n parent.children = children;\n }\n }\n}\n\n", "/**\n * Color Property Utilities\n * Helps identify and work with CSS properties that accept color values\n */\n\n/**\n * List of CSS properties that accept color values\n */\nconst COLOR_PROPERTIES = new Set([\n 'color',\n 'backgroundColor',\n 'borderColor',\n 'borderTopColor',\n 'borderRightColor',\n 'borderBottomColor',\n 'borderLeftColor',\n 'outlineColor',\n 'fill',\n 'stroke',\n 'textDecorationColor',\n 'caretColor',\n 'columnRuleColor',\n 'floodColor',\n 'lightingColor',\n 'stopColor',\n]);\n\n/**\n * Check if a CSS property is a color property\n */\nexport function isColorProperty(propertyName: string): boolean {\n return COLOR_PROPERTIES.has(propertyName);\n}\n\n/**\n * Get all color properties\n */\nexport function getColorProperties(): string[] {\n return Array.from(COLOR_PROPERTIES);\n}\n", "/**\n * Path Builder Utilities\n *\n * Build tree structures with both logical and rendered paths for each node.\n *\n * Logical Path: Position in the JSON data structure\n * Rendered Path: Position after component structure transformations (slot markers)\n */\n\nimport type { Path } from '../pathArrayUtils';\nimport type { PageData, ComponentNode } from '../types';\nimport { getRootData } from '../treePathUtils';\nimport { isComponentNode, isSlotMarker, isLocaleListNode, isCMSListNode, isListNode } from '../nodeUtils';\n\n/**\n * Node path data containing both logical and rendered paths\n */\nexport interface NodePathData {\n path: Path; // Logical path in data structure\n renderedPath: Path; // Path adjusted for component structure wrapping\n}\n\n/**\n * Find the path to the slot marker in a component structure\n * Returns the path as an array of indices\n *\n * @example\n * // Structure: div > div > children\n * findSlotMarkerPath(structure) // Returns [0, 0, 1] (or null if not found)\n */\nfunction findSlotMarkerPath(structure: any, currentPath: Path = [0]): Path | null {\n if (!structure || typeof structure !== 'object') return null;\n\n if (isSlotMarker(structure)) {\n return currentPath;\n }\n\n if (!Array.isArray((structure as any).children)) {\n return null;\n }\n\n for (let i = 0; i < (structure as any).children.length; i++) {\n const child = (structure as any).children[i];\n\n if (isSlotMarker(child)) {\n return [...currentPath, i];\n }\n\n if (child && typeof child === 'object' && !Array.isArray(child)) {\n const found = findSlotMarkerPath(child, [...currentPath, i]);\n if (found) return found;\n }\n }\n\n return null;\n}\n\n/**\n * Calculate rendered path accounting for component structure wrapping\n *\n * When a component has a {type: \"slot\"} marker nested inside its structure,\n * the rendered path needs adjustment for the nesting depth.\n *\n * This algorithm builds the rendered path incrementally, checking if each\n * parent node is a component and calculating the correct rendered position\n * based on the component's slot path.\n *\n * @example\n * Section structure: div > div > slot (slotPath = [0, 0, 0])\n * Stack structure: div > div > slot (slotPath = [0, 0, 0])\n *\n * Logical path [0, 1, 0, 0] (Subtitle inside Stack inside Section):\n * - i=1: root div is NOT component, renderedPath = [0, 1]\n * - i=2: Section IS component, slotPath=[0,0,0], prefix=[0], renderedPath = [0, 1, 0, 0]\n * - i=3: Stack IS component, slotPath=[0,0,0], prefix=[0], renderedPath = [0, 1, 0, 0, 0, 0]\n */\nfunction calculateRenderedPath(\n logicalPath: Path,\n currentNode: any,\n globalComponentRegistry: any,\n navigationHistory?: NavigationContext[]\n): Path {\n if (!currentNode || logicalPath.length === 0) {\n return logicalPath;\n }\n\n // For the root element, logical and rendered paths are the same\n if (logicalPath.length === 1) {\n return logicalPath;\n }\n\n // Handle editing a component definition with slot marker\n // This calculates the offset for elements that come AFTER the slot in the structure\n // The offset is applied during the component slot wrapping calculation below\n let postSlotOffset = 0;\n let postSlotDepth = -1;\n\n if (navigationHistory && navigationHistory.length > 0) {\n // Use the most recent (current) navigation context's instanceChildren\n // When editing nested components A > B, we need B's instanceChildren, not A's\n const currentContext = navigationHistory[navigationHistory.length - 1];\n const instanceChildren = currentContext.instanceChildren;\n const instanceChildrenCount = Array.isArray(instanceChildren) ? instanceChildren.length : 0;\n\n if (instanceChildrenCount > 0) {\n const rootSlotPath = findSlotMarkerPath(currentNode);\n\n if (rootSlotPath && rootSlotPath.length > 1) {\n // Check if this path is for an element AFTER the slot marker\n const markerDepth = rootSlotPath.length - 1;\n if (logicalPath.length > markerDepth) {\n const indexAtMarkerLevel = logicalPath[markerDepth];\n const markerIndex = rootSlotPath[markerDepth];\n\n if (indexAtMarkerLevel > markerIndex) {\n // This path is after the slot marker in the structure\n // Calculate offset but DON'T return early - we still need to handle\n // component slot wrapping (e.g., if root is a component like Layout)\n postSlotOffset = instanceChildrenCount - 1;\n postSlotDepth = markerDepth;\n }\n }\n }\n }\n }\n\n // Build rendered path incrementally by walking through the logical path\n // and checking if each parent is a component with a nested slot\n let renderedPath: Path = [0];\n let node = currentNode;\n\n for (let i = 1; i < logicalPath.length; i++) {\n let childIndex = logicalPath[i];\n\n // Apply post-slot offset at the appropriate depth\n // This handles elements that come AFTER a slot marker in the component structure\n if (i === postSlotDepth && postSlotOffset > 0) {\n childIndex += postSlotOffset;\n }\n\n if (!node || !(node as any).children) break;\n\n const children = Array.isArray((node as any).children)\n ? (node as any).children\n : [(node as any).children];\n const childNode = children[logicalPath[i]]; // Use original index for traversal\n\n // Check if current node (the parent) is a component\n if (isComponentNode(node)) {\n const componentName = (node as any).component;\n const componentDef = globalComponentRegistry?.get?.(componentName);\n\n if (componentDef?.component?.structure) {\n const slotPath = findSlotMarkerPath(componentDef.component.structure);\n\n if (slotPath && slotPath.length > 1) {\n // slotPath is like [0, 0, 0] meaning: root \u2192 child0 \u2192 child0 \u2192 slot\n // prefix = path from component root to slot's parent container\n // For [0, 0, 0]: prefix = [0] (the middle elements, excluding root and slot index)\n const prefix = slotPath.slice(1, -1);\n const slotIndex = slotPath[slotPath.length - 1];\n\n // Child renders at: currentRenderedPath + prefix + (slotIndex + adjustedChildIndex)\n renderedPath = [...renderedPath, ...prefix, slotIndex + childIndex];\n } else {\n // No nested slot or slot at root level, direct child mapping\n renderedPath = [...renderedPath, childIndex];\n }\n } else {\n // Component has no structure defined\n renderedPath = [...renderedPath, childIndex];\n }\n } else {\n // Regular HTML node - direct mapping\n renderedPath = [...renderedPath, childIndex];\n }\n\n node = childNode;\n }\n\n return renderedPath;\n}\n\n/**\n * Navigation context for component editing\n * Used to convert component-relative paths to page-relative paths\n *\n * Note: This matches FileStore's NavigationContext structure for compatibility\n */\n/**\n * CMS item context for elements inside CMS List(s)\n */\nexport interface CMSItemContext {\n itemIndexPath: number[]; // e.g., [0] for single list, [0, 2] for nested\n listPaths: Path[]; // Parallel array of list node paths\n}\n\nexport interface NavigationContext {\n file?: any; // FileItem - optional as not all contexts have file\n componentInstancePath: Path | null;\n componentInstanceRenderedPath?: Path | null; // Rendered path for accurate DOM queries\n instanceChildren?: Array<ComponentNode | string>; // Children of the component instance (for path offset calculation)\n cmsItemContext?: CMSItemContext | null; // CMS context when editing component inside CMS List\n}\n\n/**\n * Build all paths from tree with both logical and rendered paths\n *\n * Recursively traverses the tree structure and creates NodePathData entries\n * for each node, including both the logical path and the rendered path.\n *\n * When editing a component (navigationHistory provided), paths are adjusted\n * to be page-relative by prepending the cumulative component instance path.\n *\n * @param pageData - The page or component data\n * @param globalComponentRegistry - Registry for component definitions\n * @param navigationHistory - Optional navigation context for component editing\n * @returns Array of NodePathData with both logical and rendered paths\n *\n * @example\n * // When editing a page\n * const pathsData = buildTreePathsWithRendered(pageData, registry);\n * pathsData.forEach(({path, renderedPath}) => {\n * console.log(`Node at [${path}] renders as [${renderedPath}]`);\n * });\n *\n * // When editing a component\n * const navigationHistory = [{componentInstancePath: [0, 2]}];\n * const pathsData = buildTreePathsWithRendered(componentData, registry, navigationHistory);\n * // Returns paths relative to the page (e.g., [0, 2, 0] for first child of component)\n */\nexport function buildTreePathsWithRendered(\n pageData: PageData,\n globalComponentRegistry?: any,\n navigationHistory?: NavigationContext[]\n): NodePathData[] {\n const rootData = getRootData(pageData);\n if (!rootData) return [];\n\n // Calculate cumulative component instance path for nested editing\n // Use rendered paths to ensure DOM queries have correct element paths\n let cumulativeInstancePath: Path | null = null;\n if (navigationHistory && navigationHistory.length > 0) {\n // Use rendered path for accurate DOM queries\n cumulativeInstancePath = navigationHistory[0].componentInstanceRenderedPath ?? navigationHistory[0].componentInstancePath;\n\n // For nested components, chain the paths\n for (let i = 1; i < navigationHistory.length; i++) {\n const nextPath = navigationHistory[i].componentInstanceRenderedPath ?? navigationHistory[i].componentInstancePath;\n if (nextPath && cumulativeInstancePath) {\n // Append path segments except root\n cumulativeInstancePath = [\n ...cumulativeInstancePath,\n ...nextPath.slice(1)\n ];\n }\n }\n }\n\n const result: NodePathData[] = [];\n\n function traverse(node: ComponentNode, currentPath: Path = [0]): void {\n // Calculate rendered path for this node\n // Call calculateRenderedPath when:\n // 1. globalComponentRegistry exists (for component slot offsets), OR\n // 2. navigationHistory exists (for post-slot element offsets when editing a component)\n const needsPathCalculation = globalComponentRegistry || (navigationHistory && navigationHistory.length > 0);\n const renderedPath = needsPathCalculation\n ? calculateRenderedPath(currentPath, rootData, globalComponentRegistry, navigationHistory)\n : currentPath;\n\n // When editing a component, adjust rendered path to be page-relative\n // Logical path always stays component-relative (starting from [0])\n const adjustedRenderedPath = cumulativeInstancePath\n ? [...cumulativeInstancePath, ...renderedPath.slice(1)]\n : renderedPath;\n\n result.push({\n path: currentPath, // Keep logical path component-relative\n renderedPath: adjustedRenderedPath, // Adjust rendered path for page-relative queries\n });\n\n // Traverse children\n // Include markers when editing a component instance (has navigationHistory)\n // to ensure they get proper rendered paths\n const nodeWithChildren = node as any;\n if (nodeWithChildren.children && Array.isArray(nodeWithChildren.children)) {\n nodeWithChildren.children.forEach((child: any, index: number) => {\n if (\n typeof child === 'object' &&\n child !== null &&\n ('tag' in child || 'component' in child || 'html' in child || 'src' in child || 'href' in child || isLocaleListNode(child) || isCMSListNode(child) || isListNode(child) || (cumulativeInstancePath && isSlotMarker(child)))\n ) {\n const childPath = [...currentPath, index];\n traverse(child as ComponentNode, childPath);\n }\n });\n }\n }\n\n traverse(rootData);\n return result;\n}\n\n/**\n * Build tree paths for a specific component context\n *\n * When editing a component, use this to get paths for the component definition\n * with proper accounting for slot marker positions.\n *\n * @param componentStructure - Component definition structure\n * @param globalComponentRegistry - Registry for nested components\n * @param navigationHistory - Optional navigation context to adjust paths to page-relative\n * @returns Array of NodePathData\n */\nexport function buildComponentTreePaths(\n componentStructure: ComponentNode,\n globalComponentRegistry?: any,\n navigationHistory?: NavigationContext[]\n): NodePathData[] {\n const result: NodePathData[] = [];\n\n // Calculate cumulative component instance path for navigation context\n let cumulativeInstancePath: Path | null = null;\n if (navigationHistory && navigationHistory.length > 0) {\n cumulativeInstancePath = navigationHistory[0].componentInstanceRenderedPath ?? navigationHistory[0].componentInstancePath;\n\n for (let i = 1; i < navigationHistory.length; i++) {\n const nextPath = navigationHistory[i].componentInstanceRenderedPath ?? navigationHistory[i].componentInstancePath;\n if (nextPath && cumulativeInstancePath) {\n cumulativeInstancePath = [\n ...cumulativeInstancePath,\n ...nextPath.slice(1)\n ];\n }\n }\n }\n\n function traverse(node: ComponentNode, currentPath: Path = [0]): void {\n // In component context, logical and rendered paths may differ\n // based on nested slot markers\n const needsPathCalculation = globalComponentRegistry || (navigationHistory && navigationHistory.length > 0);\n const renderedPath = needsPathCalculation\n ? calculateRenderedPath(currentPath, componentStructure, globalComponentRegistry, navigationHistory)\n : currentPath;\n\n // Adjust to page-relative paths if navigating into an instance\n const adjustedRenderedPath = cumulativeInstancePath\n ? [...cumulativeInstancePath, ...renderedPath.slice(1)]\n : renderedPath;\n\n result.push({\n path: currentPath,\n renderedPath: adjustedRenderedPath,\n });\n\n // Traverse children\n const nodeWithChildren = node as any;\n if (nodeWithChildren.children && Array.isArray(nodeWithChildren.children)) {\n nodeWithChildren.children.forEach((child: any, index: number) => {\n if (\n typeof child === 'object' &&\n child !== null &&\n ('tag' in child || 'component' in child || 'html' in child || 'src' in child || 'href' in child || isLocaleListNode(child) || isCMSListNode(child) || isListNode(child) || isSlotMarker(child))\n ) {\n const childPath = [...currentPath, index];\n traverse(child as ComponentNode, childPath);\n }\n });\n }\n }\n\n traverse(componentStructure);\n return result;\n}\n\n/**\n * Find NodePathData by logical path\n */\nexport function findPathData(\n pathsData: NodePathData[],\n searchPath: Path\n): NodePathData | undefined {\n return pathsData.find(\n (item) =>\n item.path.length === searchPath.length &&\n item.path.every((val, idx) => val === searchPath[idx])\n );\n}\n\n/**\n * Get all ancestors for a path (including the path itself)\n */\nexport function getPathAncestors(\n pathsData: NodePathData[],\n searchPath: Path\n): NodePathData[] {\n const ancestors: NodePathData[] = [];\n\n for (let i = 1; i <= searchPath.length; i++) {\n const ancestorPath = searchPath.slice(0, i);\n const found = findPathData(pathsData, ancestorPath);\n if (found) {\n ancestors.push(found);\n }\n }\n\n return ancestors;\n}\n", "/**\n * Validation exports\n */\n\nexport * from './schemas';\nexport * from './validators';\nexport * from './propValidator';\nexport * from './cmsValidators';\n", "/**\n * CMS Validation Utilities\n * Centralized validation for CMS-specific fields to ensure consistency\n */\n\nimport { z } from 'zod';\n\n/**\n * Regex pattern for valid CMS collection IDs\n * Allows alphanumeric characters, underscores, and hyphens\n */\nexport const CMS_COLLECTION_ID_REGEX = /^[a-zA-Z0-9_-]+$/;\n\n/**\n * Zod schema for CMS collection ID validation\n */\nexport const CMSCollectionIdSchema = z.string()\n .min(1, 'Collection ID is required')\n .regex(CMS_COLLECTION_ID_REGEX, 'Collection ID must contain only letters, numbers, underscores, and hyphens');\n\n/**\n * Validate a CMS collection ID\n * @returns Object with valid boolean and optional error message\n */\nexport function validateCollectionId(id: string): { valid: boolean; error?: string } {\n const result = CMSCollectionIdSchema.safeParse(id);\n if (result.success) {\n return { valid: true };\n }\n return { valid: false, error: result.error.errors[0]?.message };\n}\n\n/**\n * Check if a string is a valid CMS collection ID (simple boolean check)\n */\nexport function isValidCollectionId(id: string): boolean {\n return CMS_COLLECTION_ID_REGEX.test(id);\n}\n", "/**\n * Shared utility functions used across the codebase\n */\n\nimport type { Path } from './pathArrayUtils';\nimport { stringToPath, pathToLegacyString, getParentPath, isRootPath as isRootPathArray } from './pathArrayUtils';\nimport { ROOT_0_STRING } from './pathArrayUtils';\n\n/**\n * Deep clone an object using structuredClone\n * @param obj - The object to clone\n * @returns A deep clone of the object\n */\nexport function deepClone<T>(obj: T): T {\n return structuredClone(obj);\n}\n\n/**\n * Wait for a specified amount of time\n * @param ms - Milliseconds to wait\n */\nexport function wait(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n/**\n * Check if the currently focused element is editable (input, textarea, or contenteditable)\n * Also checks if the active element is INSIDE a contenteditable element (for rich text editors like Tiptap/ProseMirror)\n * Also returns true if text is selected (to allow native copy/paste)\n * @returns true if the active element is editable or text is selected\n */\nexport function isEditableElement(): boolean {\n // Allow native copy/paste when text is selected\n // Note: window.getSelection() only returns selections from the current document,\n // NOT from iframe documents. So in the parent window, any selection is from\n // sidebar/panels and should allow native copy.\n const selection = window.getSelection();\n if (selection && selection.toString().trim().length > 0) {\n return true;\n }\n\n const activeElement = document.activeElement;\n if (!activeElement) return false;\n\n // Textarea always accepts text\n if (activeElement.tagName === 'TEXTAREA') {\n return true;\n }\n\n // For inputs, only block shortcuts for text-accepting types\n if (activeElement.tagName === 'INPUT') {\n const inputType = (activeElement as HTMLInputElement).type.toLowerCase();\n const textInputTypes = ['text', 'password', 'email', 'number', 'search', 'tel', 'url', 'date', 'time', 'datetime-local', 'month', 'week'];\n // Allow shortcuts for: checkbox, radio, button, submit, reset, color, file, range, hidden\n return textInputTypes.includes(inputType);\n }\n\n // Check if activeElement or any parent is contenteditable\n // This handles rich text editors where focus may be on an internal element\n let element: Element | null = activeElement;\n while (element) {\n if (\n element.hasAttribute('contenteditable') ||\n (element as HTMLElement).isContentEditable\n ) {\n return true;\n }\n element = element.parentElement;\n }\n\n return false;\n}\n\n/**\n * Extract the parent path from a tree path\n * Example: root_0_children_0 -> root_0, root_0_children_0_children_1 -> root_0_children_0\n * Also accepts array paths: [0,0] -> \"root_0\", [0,0,1] -> \"root_0_children_0\"\n * \n * @param treePath - The tree path (string or Path array)\n * @param rootPath - The root path constant (default: 'root_0')\n * @returns The parent path, or rootPath if no parent found\n */\nexport function getParentPathFromTreePath(treePath: string | Path, rootPath: string = ROOT_0_STRING): string {\n // Convert to array if needed\n const pathArray = typeof treePath === 'string' ? stringToPath(treePath) : treePath;\n \n // Handle root paths\n if (isRootPathArray(pathArray)) {\n return rootPath;\n }\n \n // Use array operations to get parent path\n const parentArray = getParentPath(pathArray);\n return pathToLegacyString(parentArray);\n}\n\n/**\n * Normalize children property to always be an array\n * Mutates the node object directly (for performance in large trees)\n * Handles cases where children might be undefined, a single item, or already an array\n * @param node - The node object with a children property (will be mutated)\n */\nexport function normalizeChildrenArray(node: { children?: any[] | any }): void {\n if (!node.children) {\n node.children = [];\n } else if (!Array.isArray(node.children)) {\n // Single child - wrap in array\n node.children = [node.children];\n }\n // If already an array, no change needed\n}\n\n", "/**\n * Shared theme color defaults\n * Used by PropsPanel and StyleEditor to avoid duplication\n */\n\nexport interface PropsPanelColors {\n background: string;\n backgroundSecondary: string;\n backgroundTertiary: string;\n border: string;\n borderSecondary: string;\n text: string;\n textSecondary: string;\n textMuted: string;\n codeString: string;\n codeNumber: string;\n codeKey: string;\n codeType: string;\n buttonPrimary: string;\n buttonPrimaryHover: string;\n buttonSecondary: string;\n buttonDanger: string;\n buttonDangerHover: string;\n inputBackground: string;\n inputBorder: string;\n hoverBackground: string;\n}\n\n/**\n * Spacing constants for props panel components\n */\nexport interface PropsPanelSpacing {\n tight: string; // 2px - for label:colon:input gaps\n normal: string; // 4px - for standard gaps\n loose: string; // 8px - for larger gaps\n}\n\nexport const DEFAULT_PROPS_PANEL_SPACING: PropsPanelSpacing = {\n tight: '2px',\n normal: '4px',\n loose: '8px',\n};\n\n/**\n * Base input style properties\n */\nexport interface PropsPanelInputStyle {\n fontFamily: string;\n fontSize: string;\n padding: string;\n borderRadius: string;\n outline: string;\n border?: string;\n}\n\n/**\n * Base input style defaults\n */\nexport const DEFAULT_INPUT_STYLE: Omit<PropsPanelInputStyle, 'border' | 'color' | 'background'> = {\n fontFamily: \"'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif\",\n fontSize: '13px',\n padding: '6px 8px',\n borderRadius: '3px',\n outline: 'none',\n};\n\n/**\n * Base textarea style defaults\n */\nexport const DEFAULT_TEXTAREA_STYLE: Omit<PropsPanelInputStyle, 'border' | 'color' | 'background'> = {\n fontFamily: 'inherit',\n fontSize: '13px',\n padding: '6px 8px',\n borderRadius: '3px',\n outline: 'none',\n};\n\n/**\n * Default dark theme colors for props panel\n */\nexport const DEFAULT_PROPS_PANEL_COLORS: PropsPanelColors = {\n background: '#1e1e1e',\n backgroundSecondary: '#2d2d2d',\n backgroundTertiary: '#252525',\n border: '#333333',\n borderSecondary: '#444444',\n text: '#cccccc',\n textSecondary: '#cccccc',\n textMuted: '#888888',\n codeString: '#ce9178',\n codeNumber: '#b5cea8',\n codeKey: '#9cdcfe',\n codeType: '#4ec9b0',\n buttonPrimary: '#007acc',\n buttonPrimaryHover: '#0098ff',\n buttonSecondary: '#007acc',\n buttonDanger: '#f48771',\n buttonDangerHover: '#ff6b6b',\n inputBackground: '#2a2a2a',\n inputBorder: '#444444',\n hoverBackground: '#2a2d2e',\n};\n\n/**\n * Light theme colors for props panel\n */\nexport const LIGHT_PROPS_PANEL_COLORS: PropsPanelColors = {\n background: '#ffffff',\n backgroundSecondary: '#f5f5f5',\n backgroundTertiary: '#fafafa',\n border: '#e4e8ec',\n borderSecondary: '#d0d0d0',\n text: '#1a1a1a',\n textSecondary: '#333333',\n textMuted: '#666666',\n codeString: '#a31515',\n codeNumber: '#098658',\n codeKey: '#0451a5',\n codeType: '#267f99',\n buttonPrimary: '#0078d4',\n buttonPrimaryHover: '#106ebe',\n buttonSecondary: '#0078d4',\n buttonDanger: '#d13438',\n buttonDangerHover: '#a4262c',\n inputBackground: '#f5f7fa',\n inputBorder: '#d0d0d0',\n hoverBackground: '#f0f0f0',\n};\n\n", "/**\n * Color Variable Utilities\n * Handles resolution and validation of color variables in styles\n */\n\n/**\n * Check if a value is a color variable reference\n * @example \"var(--primary-color)\" -> true\n */\nexport function isColorVariable(value: string | unknown): value is string {\n if (typeof value !== 'string') return false;\n return /^var\\(--[\\w-]+\\)$/.test(value.trim());\n}\n\n/**\n * Extract variable name from a color variable reference\n * @example \"var(--primary-color)\" -> \"primary-color\"\n */\nexport function extractVariableName(value: string): string | null {\n const match = value.match(/^var\\(--([^)]+)\\)$/);\n return match ? match[1] : null;\n}\n\n/**\n * Create a color variable reference\n * @example \"primary-color\" -> \"var(--primary-color)\"\n */\nexport function createVariableReference(variableName: string): string {\n return `var(--${variableName})`;\n}\n\n/**\n * Resolve a color variable to its actual value\n * @param value - The style value (may be a variable reference or actual color)\n * @param colorMap - Map of variable names to color values\n * @returns Resolved color value or original value if not a variable\n */\nexport function resolveColorVariable(\n value: string | unknown,\n colorMap: Record<string, string>\n): string {\n if (!isColorVariable(value)) {\n return String(value);\n }\n\n const varName = extractVariableName(value);\n if (!varName) {\n return String(value);\n }\n\n return colorMap[varName] || String(value);\n}\n\n/**\n * Replace color variables in a style object\n * @param styles - Style object with potential variable references\n * @param colorMap - Map of variable names to color values\n * @returns New style object with variables resolved\n */\nexport function resolveColorVariablesInStyles(\n styles: Record<string, any>,\n colorMap: Record<string, string>\n): Record<string, any> {\n const resolved: Record<string, any> = {};\n\n for (const [key, value] of Object.entries(styles)) {\n if (typeof value === 'string') {\n resolved[key] = resolveColorVariable(value, colorMap);\n } else {\n resolved[key] = value;\n }\n }\n\n return resolved;\n}\n\n/**\n * Get all color variable references from a style object\n * @param styles - Style object to search\n * @returns Array of variable names found in styles\n */\nexport function getColorVariablesFromStyles(\n styles: Record<string, any>\n): string[] {\n const variables = new Set<string>();\n\n for (const value of Object.values(styles)) {\n if (isColorVariable(value)) {\n const varName = extractVariableName(value);\n if (varName) {\n variables.add(varName);\n }\n }\n }\n\n return Array.from(variables);\n}\n", "/**\n * Error Types\n * Structured error types for consistent error handling across the codebase\n */\n\n/**\n * Error categories for filtering and handling\n */\nexport type ErrorCategory =\n | 'validation' // Invalid input/state\n | 'runtime' // Runtime failures (graceful degradation)\n | 'network' // API/fetch failures\n | 'internal'; // Unexpected errors\n\n/**\n * Structured error type for consistent error handling\n */\nexport interface AppError {\n readonly category: ErrorCategory;\n readonly code: string;\n readonly message: string;\n readonly context?: Record<string, unknown>;\n readonly cause?: Error;\n}\n\n/**\n * Create a structured error object\n */\nexport function createError(\n category: ErrorCategory,\n code: string,\n message: string,\n context?: Record<string, unknown>,\n cause?: Error\n): AppError {\n return { category, code, message, context, cause };\n}\n\n/**\n * Type guard for AppError\n */\nexport function isAppError(error: unknown): error is AppError {\n return (\n typeof error === 'object' &&\n error !== null &&\n 'category' in error &&\n 'code' in error &&\n 'message' in error\n );\n}\n", "/**\n * Color conversion utilities for HEX, RGB, and HSL formats\n */\n\nexport type ColorMode = 'hex' | 'rgb' | 'hsl';\n\nexport interface RgbColor {\n r: number;\n g: number;\n b: number;\n}\n\nexport interface HslColor {\n h: number;\n s: number;\n l: number;\n}\n\n// \u2500\u2500 Detection \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst HEX_RE = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i;\nconst RGB_RE = /^rgb\\(\\s*(\\d{1,3})\\s*[,\\s]\\s*(\\d{1,3})\\s*[,\\s]\\s*(\\d{1,3})\\s*\\)$/i;\nconst HSL_RE = /^hsl\\(\\s*(\\d{1,3}(?:\\.\\d+)?)\\s*[,\\s]\\s*(\\d{1,3}(?:\\.\\d+)?)%?\\s*[,\\s]\\s*(\\d{1,3}(?:\\.\\d+)?)%?\\s*\\)$/i;\n\n/** Detect the color mode from a CSS color string */\nexport function detectColorMode(value: string): ColorMode | null {\n if (!value) return null;\n const v = value.trim();\n if (HEX_RE.test(v)) return 'hex';\n if (RGB_RE.test(v)) return 'rgb';\n if (HSL_RE.test(v)) return 'hsl';\n return null;\n}\n\n// \u2500\u2500 Parsing \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Parse a CSS rgb() string to an RgbColor object */\nexport function parseCssRgb(value: string): RgbColor | null {\n const m = value.trim().match(RGB_RE);\n if (!m) return null;\n return {\n r: clamp(parseInt(m[1], 10), 0, 255),\n g: clamp(parseInt(m[2], 10), 0, 255),\n b: clamp(parseInt(m[3], 10), 0, 255),\n };\n}\n\n/** Parse a CSS hsl() string to an HslColor object */\nexport function parseCssHsl(value: string): HslColor | null {\n const m = value.trim().match(HSL_RE);\n if (!m) return null;\n return {\n h: clamp(parseFloat(m[1]), 0, 360),\n s: clamp(parseFloat(m[2]), 0, 100),\n l: clamp(parseFloat(m[3]), 0, 100),\n };\n}\n\n// \u2500\u2500 Formatting \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Format an RgbColor to a CSS rgb() string */\nexport function rgbToCssString(rgb: RgbColor): string {\n return `rgb(${Math.round(rgb.r)}, ${Math.round(rgb.g)}, ${Math.round(rgb.b)})`;\n}\n\n/** Format an HslColor to a CSS hsl() string */\nexport function hslToCssString(hsl: HslColor): string {\n return `hsl(${Math.round(hsl.h)}, ${Math.round(hsl.s)}%, ${Math.round(hsl.l)}%)`;\n}\n\n// \u2500\u2500 Hex \u2194 RGB \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Expand 3-char hex to 6-char hex */\nfunction expandHex(hex: string): string {\n const h = hex.replace('#', '');\n if (h.length === 3) {\n return '#' + h[0] + h[0] + h[1] + h[1] + h[2] + h[2];\n }\n return '#' + h;\n}\n\n/** Convert a hex color string to an RgbColor */\nexport function hexToRgb(hex: string): RgbColor {\n const h = expandHex(hex).replace('#', '');\n return {\n r: parseInt(h.substring(0, 2), 16),\n g: parseInt(h.substring(2, 4), 16),\n b: parseInt(h.substring(4, 6), 16),\n };\n}\n\n/** Convert an RgbColor to a hex color string */\nexport function rgbToHex(rgb: RgbColor): string {\n const r = clamp(Math.round(rgb.r), 0, 255);\n const g = clamp(Math.round(rgb.g), 0, 255);\n const b = clamp(Math.round(rgb.b), 0, 255);\n return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);\n}\n\n// \u2500\u2500 RGB \u2194 HSL \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Convert an RgbColor to an HslColor */\nexport function rgbToHsl(rgb: RgbColor): HslColor {\n const r = rgb.r / 255;\n const g = rgb.g / 255;\n const b = rgb.b / 255;\n\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const l = (max + min) / 2;\n\n if (max === min) {\n return { h: 0, s: 0, l: Math.round(l * 100) };\n }\n\n const d = max - min;\n const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n\n let h = 0;\n if (max === r) {\n h = ((g - b) / d + (g < b ? 6 : 0)) / 6;\n } else if (max === g) {\n h = ((b - r) / d + 2) / 6;\n } else {\n h = ((r - g) / d + 4) / 6;\n }\n\n return {\n h: Math.round(h * 360),\n s: Math.round(s * 100),\n l: Math.round(l * 100),\n };\n}\n\n/** Convert an HslColor to an RgbColor */\nexport function hslToRgb(hsl: HslColor): RgbColor {\n const h = hsl.h / 360;\n const s = hsl.s / 100;\n const l = hsl.l / 100;\n\n if (s === 0) {\n const v = Math.round(l * 255);\n return { r: v, g: v, b: v };\n }\n\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n\n return {\n r: Math.round(hueToRgb(p, q, h + 1 / 3) * 255),\n g: Math.round(hueToRgb(p, q, h) * 255),\n b: Math.round(hueToRgb(p, q, h - 1 / 3) * 255),\n };\n}\n\nfunction hueToRgb(p: number, q: number, t: number): number {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n}\n\n// \u2500\u2500 Hex \u2194 HSL (via RGB) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Convert a hex color string to an HslColor */\nexport function hexToHsl(hex: string): HslColor {\n return rgbToHsl(hexToRgb(hex));\n}\n\n/** Convert an HslColor to a hex color string */\nexport function hslToHex(hsl: HslColor): string {\n return rgbToHex(hslToRgb(hsl));\n}\n\n// \u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n", "/**\n * Gradient parsing and building utilities\n */\n\nexport interface GradientStop {\n color: string;\n position: number;\n}\n\nexport interface GradientConfig {\n type: 'linear' | 'radial' | 'conic';\n angle: number;\n shape?: 'circle' | 'ellipse';\n stops: GradientStop[];\n}\n\nconst LINEAR_RE = /^linear-gradient\\((.+)\\)$/i;\nconst RADIAL_RE = /^radial-gradient\\((.+)\\)$/i;\nconst CONIC_RE = /^conic-gradient\\((.+)\\)$/i;\n\n/** Check if a CSS value is a gradient */\nexport function isGradientValue(value: string): boolean {\n if (!value) return false;\n const v = value.trim().toLowerCase();\n return v.startsWith('linear-gradient(') ||\n v.startsWith('radial-gradient(') ||\n v.startsWith('conic-gradient(');\n}\n\n/** Parse a CSS gradient string into a GradientConfig */\nexport function parseGradient(cssValue: string): GradientConfig | null {\n if (!cssValue) return null;\n const v = cssValue.trim();\n\n let match: RegExpMatchArray | null;\n let type: GradientConfig['type'];\n\n if ((match = v.match(LINEAR_RE))) {\n type = 'linear';\n } else if ((match = v.match(RADIAL_RE))) {\n type = 'radial';\n } else if ((match = v.match(CONIC_RE))) {\n type = 'conic';\n } else {\n return null;\n }\n\n const inner = match[1];\n const parts = splitGradientArgs(inner);\n\n let angle = type === 'linear' ? 180 : 0;\n let shape: 'circle' | 'ellipse' | undefined;\n let stopsStartIndex = 0;\n\n if (type === 'linear') {\n const first = parts[0]?.trim();\n if (first) {\n const angleDeg = parseAngle(first);\n if (angleDeg !== null) {\n angle = angleDeg;\n stopsStartIndex = 1;\n } else if (first.startsWith('to ')) {\n angle = directionToAngle(first);\n stopsStartIndex = 1;\n }\n }\n } else if (type === 'radial') {\n const first = parts[0]?.trim().toLowerCase();\n if (first) {\n if (first.startsWith('circle') || first === 'circle') {\n shape = 'circle';\n stopsStartIndex = 1;\n } else if (first.startsWith('ellipse') || first === 'ellipse') {\n shape = 'ellipse';\n stopsStartIndex = 1;\n }\n }\n } else if (type === 'conic') {\n const first = parts[0]?.trim();\n if (first) {\n const fromAngle = first.match(/^from\\s+(\\d+(?:\\.\\d+)?)deg/i);\n if (fromAngle) {\n angle = parseFloat(fromAngle[1]);\n stopsStartIndex = 1;\n }\n }\n }\n\n const stops = parseStops(parts.slice(stopsStartIndex));\n if (stops.length < 2) return null;\n\n return { type, angle, shape, stops };\n}\n\n/** Build a CSS gradient string from a GradientConfig */\nexport function buildGradientCss(config: GradientConfig): string {\n const stopStrings = config.stops.map(\n s => `${s.color} ${Math.round(s.position)}%`\n );\n\n switch (config.type) {\n case 'linear': {\n return `linear-gradient(${config.angle}deg, ${stopStrings.join(', ')})`;\n }\n case 'radial': {\n const shape = config.shape || 'circle';\n return `radial-gradient(${shape}, ${stopStrings.join(', ')})`;\n }\n case 'conic': {\n const from = config.angle ? `from ${config.angle}deg, ` : '';\n return `conic-gradient(${from}${stopStrings.join(', ')})`;\n }\n }\n}\n\n// \u2500\u2500 Internal helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Split gradient arguments respecting nested parentheses */\nfunction splitGradientArgs(inner: string): string[] {\n const parts: string[] = [];\n let depth = 0;\n let current = '';\n\n for (const char of inner) {\n if (char === '(') depth++;\n if (char === ')') depth--;\n if (char === ',' && depth === 0) {\n parts.push(current.trim());\n current = '';\n } else {\n current += char;\n }\n }\n if (current.trim()) parts.push(current.trim());\n return parts;\n}\n\nfunction parseAngle(part: string): number | null {\n const m = part.match(/^(-?\\d+(?:\\.\\d+)?)deg$/i);\n return m ? parseFloat(m[1]) : null;\n}\n\nfunction directionToAngle(direction: string): number {\n const d = direction.trim().toLowerCase();\n const map: Record<string, number> = {\n 'to top': 0,\n 'to top right': 45,\n 'to right': 90,\n 'to bottom right': 135,\n 'to bottom': 180,\n 'to bottom left': 225,\n 'to left': 270,\n 'to top left': 315,\n };\n return map[d] ?? 180;\n}\n\nfunction parseStops(parts: string[]): GradientStop[] {\n const stops: GradientStop[] = [];\n const total = parts.length;\n\n for (let i = 0; i < total; i++) {\n const part = parts[i].trim();\n if (!part) continue;\n\n // Match color and optional position percentage\n const posMatch = part.match(/\\s+(\\d+(?:\\.\\d+)?)%\\s*$/);\n let color: string;\n let position: number;\n\n if (posMatch) {\n color = part.slice(0, posMatch.index!).trim();\n position = parseFloat(posMatch[1]);\n } else {\n color = part;\n // Auto-distribute position\n position = total <= 1 ? 0 : (i / (total - 1)) * 100;\n }\n\n stops.push({ color, position });\n }\n\n return stops;\n}\n", "/**\n * CMS Query Parser\n * Utilities for parsing and serializing sort/filter expressions for CMS List nodes.\n *\n * Sort Expression Syntax:\n * field [asc|desc]\n * Multiple fields separated by comma: date desc, title asc\n *\n * Filter Expression Syntax:\n * field operator value\n * Operators: =, ==, !=, <>, >, >=, <, <=, contains, ~, in\n * Multiple conditions on separate lines or semicolon-separated\n * Supports template values: category = {{cms.category}}\n */\n\nimport type { CMSFilterCondition, CMSSortConfig, CMSFilterOperator } from './types/cms';\n\n/**\n * Parse sort expression: \"date desc, title asc\"\n * Note: \"asc\" is the default and can be omitted. The serializer outputs \"date\" for ascending.\n */\nexport function parseSortExpression(expr: string): CMSSortConfig | CMSSortConfig[] | undefined {\n if (!expr.trim()) return undefined;\n\n const parts = expr.split(',').map(p => p.trim()).filter(Boolean);\n const sorts: CMSSortConfig[] = parts.map(part => {\n const tokens = part.split(/\\s+/);\n const field = tokens[0];\n const order = tokens[1]?.toLowerCase() === 'desc' ? 'desc' : 'asc';\n return { field, order };\n });\n\n return sorts.length === 1 ? sorts[0] : sorts;\n}\n\n/**\n * Serialize sort config back to expression\n */\nexport function serializeSortExpression(sort: CMSSortConfig | CMSSortConfig[] | undefined): string {\n if (!sort) return '';\n const sorts = Array.isArray(sort) ? sort : [sort];\n return sorts.map(s => `${s.field}${s.order === 'desc' ? ' desc' : ''}`).join(', ');\n}\n\n/**\n * Parse filter expression: \"featured = true; price > 100\"\n */\nexport function parseFilterExpression(\n expr: string\n): CMSFilterCondition | CMSFilterCondition[] | Record<string, unknown> | undefined {\n if (!expr.trim()) return undefined;\n\n // Split by newline or semicolon\n const lines = expr.split(/[;\\n]/).map(l => l.trim()).filter(Boolean);\n const conditions: CMSFilterCondition[] = [];\n\n for (const line of lines) {\n const condition = parseFilterLine(line);\n if (condition) conditions.push(condition);\n }\n\n if (conditions.length === 0) return undefined;\n\n // Single simple equality can use shorthand: { field: value }\n if (conditions.length === 1 && (!conditions[0].operator || conditions[0].operator === 'eq')) {\n return { [conditions[0].field]: conditions[0].value };\n }\n\n return conditions.length === 1 ? conditions[0] : conditions;\n}\n\nfunction parseFilterLine(line: string): CMSFilterCondition | null {\n // Match: field operator value\n // Operators listed longest-first to avoid partial matches (e.g., gte before gt)\n const match = line.match(/^(\\w+)\\s*(==|!=|<>|>=|<=|=|>|<|contains|~|in|gte|lte|neq|gt|lt|eq)\\s*(.+)$/i);\n if (!match) return null;\n\n const [, field, op, rawValue] = match;\n const operator = normalizeOperator(op);\n const value = parseValue(rawValue.trim(), operator);\n\n // For simple equality, we can omit operator\n if (operator === 'eq') {\n return { field, value };\n }\n\n return { field, operator, value };\n}\n\nfunction normalizeOperator(op: string): CMSFilterOperator {\n const normalized = op.toLowerCase();\n const map: Record<string, CMSFilterOperator> = {\n '=': 'eq', '==': 'eq', 'eq': 'eq',\n '!=': 'neq', '<>': 'neq', 'neq': 'neq',\n '>': 'gt', 'gt': 'gt',\n '>=': 'gte', 'gte': 'gte',\n '<': 'lt', 'lt': 'lt',\n '<=': 'lte', 'lte': 'lte',\n 'contains': 'contains', '~': 'contains',\n 'in': 'in'\n };\n return map[normalized] || 'eq';\n}\n\nfunction parseValue(raw: string, operator: CMSFilterOperator): unknown {\n // Template expression - keep as string\n if (raw.startsWith('{{') && raw.endsWith('}}')) {\n return raw;\n }\n\n // Handle 'in' operator - comma separated list\n if (operator === 'in') {\n return raw.split(',').map(v => parseScalarValue(v.trim()));\n }\n\n return parseScalarValue(raw);\n}\n\nfunction parseScalarValue(raw: string): unknown {\n // Boolean\n if (raw.toLowerCase() === 'true') return true;\n if (raw.toLowerCase() === 'false') return false;\n\n // Number\n const num = Number(raw);\n if (!isNaN(num) && raw !== '') return num;\n\n // String (strip quotes if present)\n if ((raw.startsWith('\"') && raw.endsWith('\"')) || (raw.startsWith(\"'\") && raw.endsWith(\"'\"))) {\n return raw.slice(1, -1);\n }\n\n return raw;\n}\n\n/**\n * Serialize filter config back to expression\n */\nexport function serializeFilterExpression(\n filter: CMSFilterCondition | CMSFilterCondition[] | Record<string, unknown> | undefined\n): string {\n if (!filter) return '';\n\n // Simple object filter: { featured: true }\n if (!Array.isArray(filter) && !isFilterCondition(filter)) {\n return Object.entries(filter)\n .map(([field, value]) => `${field} = ${serializeValue(value)}`)\n .join('\\n');\n }\n\n // Array or single condition\n const conditions = Array.isArray(filter) ? filter : [filter as CMSFilterCondition];\n return conditions.map(c => {\n const op = c.operator || 'eq';\n const opStr = operatorToString(op);\n const valStr = op === 'in' && Array.isArray(c.value)\n ? c.value.map(v => serializeValue(v)).join(', ')\n : serializeValue(c.value);\n return `${c.field} ${opStr} ${valStr}`;\n }).join('\\n');\n}\n\nfunction operatorToString(op: CMSFilterOperator): string {\n const map: Record<CMSFilterOperator, string> = {\n 'eq': '=',\n 'neq': '!=',\n 'gt': '>',\n 'gte': '>=',\n 'lt': '<',\n 'lte': '<=',\n 'contains': 'contains',\n 'in': 'in'\n };\n return map[op] || '=';\n}\n\nfunction isFilterCondition(obj: unknown): obj is CMSFilterCondition {\n return typeof obj === 'object' && obj !== null && 'field' in obj;\n}\n\nfunction serializeValue(value: unknown): string {\n if (typeof value === 'string') {\n // Template or simple alphanumeric - no quotes needed\n if (value.startsWith('{{') || /^[\\w-]+$/.test(value)) return value;\n return `\"${value}\"`;\n }\n return String(value);\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * meno-core shared exports\n * Re-exports all types, constants, and utilities from shared modules\n */\n\n// Types\nexport * from './types';\n\n// Constants\nexport * from './constants';\n\n// Path utilities\nexport * from './pathArrayUtils';\nexport * from './treePathUtils';\nexport * from './paths';\n\n// Node utilities\nexport * from './nodeUtils';\n\n// Style utilities\nexport * from './breakpoints';\nexport * from './styleUtils';\nexport * from './cssProperties';\nexport * from './cssGeneration';\nexport * from './colorProperties';\nexport * from './utilityClassMapper';\nexport * from './elementClassName';\nexport * from './styleValueRegistry';\n\n// i18n utilities\nexport * from './i18n';\n\n// Slugify utilities\nexport * from './slugify';\n\n// Tree utilities\nexport * from './tree/PathBuilder';\n\n// Validation - use explicit exports to avoid ValidationError conflict with types/errors.ts\nexport {\n // Schemas\n StyleMappingSchema,\n StyleObjectSchema,\n ResponsiveStyleObjectSchema,\n StyleValueSchema,\n InteractiveStyleRuleSchema,\n InteractiveStylesSchema,\n PageDataSchema,\n PageDataWithComponentSchema,\n PropDefinitionSchema,\n ComponentNodeSchema,\n ComponentDefinitionSchema,\n StructuredComponentDefinitionSchema,\n PageMetaDataSchema,\n CMSClientDataStrategySchema,\n CMSClientDataConfigSchema,\n CMSSchemaSchema,\n CMSItemSchema,\n // Validators\n type ValidationResult,\n validatePropDefinition,\n validateComponentNode,\n validateComponentDefinition,\n validateStructuredComponentDefinition,\n validatePageData,\n validatePageDataWithComponent,\n validatePageMetaData,\n validateCMSSchema,\n validateCMSItem,\n // Prop validator\n type PropValidationError,\n type PropValidationResult,\n validateComponentProps,\n // CMS validators\n isValidCollectionId,\n validateCollectionId,\n CMS_COLLECTION_ID_REGEX,\n CMSCollectionIdSchema,\n} from './validation';\n\n// Utils\nexport * from './utils';\n\n// Registry\nexport * from './registry';\n\n// Theme defaults\nexport * from './themeDefaults';\n\n// Color variable utilities\nexport * from './colorVariableUtils';\n\n// Responsive style utilities\nexport * from './responsiveStyleUtils';\n\n// Item template utilities (for CMS List)\nexport * from './itemTemplateUtils';\n\n// Path security utilities\nexport * from './pathSecurity';\n\n// Interactive style mapping utilities\nexport * from './interactiveStyleMappings';\n\n// Rich text utilities (Tiptap)\nexport * from './richtext';\n\n// Error handling\nexport * from './errors';\nexport { logRuntimeError, logNetworkError, setErrorHandler } from './errorLogger';\n\n// Global template context\nexport * from './globalTemplateContext';\n\n// Link utilities\nexport * from './linkUtils';\n\n// Color conversion utilities\nexport * from './colorConversions';\n\n// Gradient utilities\nexport * from './gradientUtils';\n\n// CMS query parsing utilities\nexport * from './cmsQueryParser';\n\n// Prop resolution utilities\nexport { resolvePropsFromDefinition, isRichTextMarker, richTextMarkerToHtml } from './propResolver';\n", "/**\n * Tree path utilities for parsing and navigating tree structure paths\n */\n\nimport { ComponentNode, PageData, JSONPage } from './types';\nimport type { PropDefinition } from './types';\nimport type { Path } from './pathArrayUtils';\nimport { stringToPath } from './pathArrayUtils';\n\n// Type for page data that can have component structure\ntype PageDataWithComponent = PageData & {\n component?: {\n structure?: ComponentNode;\n interface?: Record<string, PropDefinition>;\n };\n};\n\nexport interface NodeLocation {\n parent: ComponentNode | PageData | null;\n index: number;\n node: ComponentNode | null;\n}\n\n/**\n * Validate that component data has a valid structure\n * @param pageData - PageData to validate\n * @returns true if component has valid structure, false otherwise\n */\nexport function validateComponentStructure(pageData: PageData | null): boolean {\n if (!pageData) return false;\n \n // Check for page format (has root property)\n if ('root' in pageData && pageData.root) {\n return true;\n }\n \n // Check for component format (has component.structure property)\n if ('component' in pageData && pageData.component) {\n if ('structure' in pageData.component && pageData.component.structure) {\n return true;\n }\n // Component exists but structure is missing\n return false;\n }\n \n return false;\n}\n\n/**\n * Get the root data from pageData (handles both page and component structures\n * Logs warnings when structure is missing for better debugging\n */\nexport function getRootData(pageData: PageData | null): ComponentNode | null {\n if (!pageData) return null;\n \n // Check for page format (has root property)\n if ('root' in pageData && pageData.root) {\n return pageData.root;\n }\n \n // Check for component format (has component.structure property)\n if ('component' in pageData && pageData.component) {\n if ('structure' in pageData.component) {\n const structure = pageData.component.structure;\n if (structure) {\n return structure;\n }\n // Structure field exists but is null/undefined\n } else {\n // Component exists but structure field is missing\n }\n }\n \n return null;\n}\n\n/**\n * Parse a tree path and return the parent, index, and node\n * Handles paths like: root_0, root_0_children_0, root_0_children_0_children_1\n * Also accepts array paths: [0], [0,0], [0,0,1]\n */\nexport function getParentAndIndexFromPath(\n path: Path | string, \n pageData: PageData\n): NodeLocation | null {\n const rootData = getRootData(pageData);\n if (!rootData) return null;\n\n // Convert string to array if needed\n const pathArray = typeof path === 'string' ? stringToPath(path) : path;\n\n // Handle root [0] specially\n if (pathArray.length === 1 && pathArray[0] === 0) {\n return {\n parent: pageData,\n index: 0,\n node: rootData\n };\n }\n\n // Navigate through path array\n let current: ComponentNode = rootData;\n let parent: ComponentNode | PageData | null = null;\n let lastIndex = -1;\n\n // Skip first element (root index 0), navigate through rest\n for (let i = 1; i < pathArray.length; i++) {\n const childIndex = pathArray[i];\n\n if (!current || !('children' in current) || !Array.isArray(current.children)) {\n return null;\n }\n \n if (isNaN(childIndex) || childIndex < 0 || childIndex >= current.children.length) {\n return null;\n }\n\n parent = current;\n const child = current.children[childIndex];\n if (typeof child === 'string') {\n return null;\n }\n current = child;\n lastIndex = childIndex;\n\n // If this is the last navigation step, we found our node\n if (i === pathArray.length - 1) {\n return { parent, index: childIndex, node: current };\n }\n }\n\n // Return the last valid location if we got here\n if (parent && lastIndex >= 0) {\n return { parent, index: lastIndex, node: current };\n }\n\n return null;\n}\n\n/**\n * Extract structure without styles/props for tree comparison\n * This allows tree to only regenerate when structure changes, not styles\n */\nexport function extractStructureWithoutStyles(node: ComponentNode | string | null | undefined): ComponentNode | string | null | undefined {\n if (!node || typeof node === 'string') {\n return node;\n }\n\n if (typeof node !== 'object') {\n return node;\n }\n\n // Create a new object with only structure-relevant properties\n const { type } = node;\n const tag = 'tag' in node ? (node.tag as string | undefined) : undefined;\n const label = 'label' in node ? (node as any).label : undefined;\n const component = 'component' in node ? (node as any).component : undefined;\n const ifCondition = 'if' in node ? node.if : undefined;\n const children = 'children' in node ? node.children : undefined;\n \n // Recursively process children\n let processedChildren: ComponentNode | (ComponentNode | string)[] | string | undefined;\n if (children) {\n if (Array.isArray(children)) {\n processedChildren = children.map((child: ComponentNode | string) =>\n typeof child === 'string' ? child : extractStructureWithoutStyles(child) as ComponentNode\n );\n } else if (typeof children === 'string') {\n processedChildren = children;\n } else if (typeof children === 'object' && 'type' in children) {\n processedChildren = extractStructureWithoutStyles(children as ComponentNode) as ComponentNode;\n }\n }\n\n const result: Partial<ComponentNode> = { type };\n if (tag !== undefined) {\n (result as { tag?: string }).tag = tag;\n }\n if (label !== undefined) {\n (result as any).label = label;\n }\n if (component !== undefined) {\n (result as any).component = component;\n }\n if (ifCondition !== undefined) {\n (result as { if?: any }).if = ifCondition;\n }\n if (processedChildren !== undefined) {\n (result as { children?: typeof processedChildren }).children = processedChildren;\n }\n return result as ComponentNode;\n}\n\n/**\n * Calculate insertion index based on drop target information\n */\nexport function calculateInsertionIndex(\n target: {\n childIndex?: number;\n childAfterItem?: { index: string };\n childBeforeItem?: { index: string };\n linearIndex?: number;\n },\n parentChildren: Array<ComponentNode | string>,\n nodeDataMap: Map<string, ComponentNode | string>\n): number {\n if (target.childIndex !== undefined && target.childIndex >= 0) {\n // Most reliable: use childIndex directly\n return Math.min(Math.max(0, target.childIndex), parentChildren.length);\n }\n\n if (target.childAfterItem?.index) {\n const afterPath = target.childAfterItem.index;\n const afterNode = nodeDataMap.get(afterPath);\n if (afterNode) {\n const afterIndex = parentChildren.findIndex((child: ComponentNode | string) => child === afterNode);\n if (afterIndex >= 0) {\n return afterIndex + 1;\n }\n }\n // Fallback: append\n return parentChildren.length;\n }\n\n if (target.childBeforeItem?.index) {\n const beforePath = target.childBeforeItem.index;\n const beforeNode = nodeDataMap.get(beforePath);\n if (beforeNode) {\n const beforeIndex = parentChildren.findIndex((child: ComponentNode | string) => child === beforeNode);\n if (beforeIndex >= 0) {\n return beforeIndex;\n }\n }\n // Fallback: prepend\n return 0;\n }\n\n // Last resort: use linearIndex or append\n if (target.linearIndex !== undefined) {\n return Math.min(Math.max(0, target.linearIndex), parentChildren.length);\n }\n\n return parentChildren.length;\n}\n\n/**\n * Type guard to check if a value is a valid NodeLocation\n */\nexport function isValidNodeLocation(location: unknown): location is NodeLocation {\n if (!location || typeof location !== 'object') {\n return false;\n }\n \n // Use proper type narrowing instead of assertion\n const loc = location as Record<string, unknown>;\n const hasParent = 'parent' in loc && (loc.parent === null || typeof loc.parent === 'object');\n const hasIndex = 'index' in loc && typeof loc.index === 'number' && loc.index >= 0;\n const hasNode = 'node' in loc && (loc.node === null || typeof loc.node === 'object');\n \n return hasParent && hasIndex && hasNode;\n}\n\n/**\n * Type guard to check if a value is a valid Path\n */\nexport function isValidPath(path: unknown): path is Path {\n if (!Array.isArray(path)) {\n return false;\n }\n \n // Path is an array of numbers\n return path.every((item): item is number => typeof item === 'number' && item >= 0);\n}\n\n/**\n * Type guard to check if parent is PageData\n */\nexport function isPageDataParent(\n parent: ComponentNode | PageData | null\n): parent is PageData {\n if (!parent) return false;\n \n // Check for JSONPage format (has root property)\n if ('root' in parent) return true;\n \n // Check for component format - component must be an object, not a string\n if ('component' in parent) {\n return typeof parent.component === 'object' && parent.component !== null;\n }\n \n return false;\n}\n\n/**\n * Type guard to check if parent is ComponentNode\n */\nexport function isComponentNodeParent(\n parent: ComponentNode | PageData | null\n): parent is ComponentNode {\n if (!parent) return false;\n // Check for 'type' property (all ComponentNodes have it)\n // Then check for specific node types that can have children:\n // - HtmlNode: has 'tag' property\n // - ComponentInstanceNode: has 'component' property\n // - SlotMarker: type === 'slot'\n // - LinkNode: type === 'link'\n // - EmbedNode: type === 'embed'\n // - ListNode: type === 'list' (also handles legacy 'cms-list' for migration)\n const nodeType = (parent as any).type;\n return 'type' in parent && (\n 'tag' in parent ||\n 'component' in parent ||\n nodeType === 'slot' ||\n nodeType === 'link' ||\n nodeType === 'embed' ||\n nodeType === 'cms-list' || // Legacy support for migration\n nodeType === 'list'\n );\n}\n\n/**\n * Get children array from parent (handles both PageData and ComponentNode)\n */\nexport function getParentChildren(\n parent: ComponentNode | PageData | null\n): Array<ComponentNode | string> | null {\n if (!parent) return null;\n \n if (isPageDataParent(parent)) {\n const rootData = getRootData(parent);\n return rootData && 'children' in rootData ? (rootData.children as Array<ComponentNode | string> | undefined) || null : null;\n }\n\n if (isComponentNodeParent(parent)) {\n return 'children' in parent ? (parent.children as Array<ComponentNode | string> | undefined) || null : null;\n }\n\n return null;\n}\n\n/**\n * Set children array on parent (handles both PageData and ComponentNode)\n */\nexport function setParentChildren(\n parent: ComponentNode | PageData | null,\n children: Array<ComponentNode | string>\n): void {\n if (!parent) return;\n \n if (isPageDataParent(parent)) {\n const rootData = getRootData(parent);\n if (rootData && 'children' in rootData) {\n rootData.children = children;\n }\n } else if (isComponentNodeParent(parent)) {\n if ('children' in parent) {\n parent.children = children;\n }\n }\n}\n\n", "/**\n * Color Property Utilities\n * Helps identify and work with CSS properties that accept color values\n */\n\n/**\n * List of CSS properties that accept color values\n */\nconst COLOR_PROPERTIES = new Set([\n 'color',\n 'backgroundColor',\n 'borderColor',\n 'borderTopColor',\n 'borderRightColor',\n 'borderBottomColor',\n 'borderLeftColor',\n 'outlineColor',\n 'fill',\n 'stroke',\n 'textDecorationColor',\n 'caretColor',\n 'columnRuleColor',\n 'floodColor',\n 'lightingColor',\n 'stopColor',\n]);\n\n/**\n * Check if a CSS property is a color property\n */\nexport function isColorProperty(propertyName: string): boolean {\n return COLOR_PROPERTIES.has(propertyName);\n}\n\n/**\n * Get all color properties\n */\nexport function getColorProperties(): string[] {\n return Array.from(COLOR_PROPERTIES);\n}\n", "/**\n * Path Builder Utilities\n *\n * Build tree structures with both logical and rendered paths for each node.\n *\n * Logical Path: Position in the JSON data structure\n * Rendered Path: Position after component structure transformations (slot markers)\n */\n\nimport type { Path } from '../pathArrayUtils';\nimport type { PageData, ComponentNode } from '../types';\nimport { getRootData } from '../treePathUtils';\nimport { isComponentNode, isSlotMarker, isLocaleListNode, isCMSListNode, isListNode } from '../nodeUtils';\n\n/**\n * Node path data containing both logical and rendered paths\n */\nexport interface NodePathData {\n path: Path; // Logical path in data structure\n renderedPath: Path; // Path adjusted for component structure wrapping\n}\n\n/**\n * Find the path to the slot marker in a component structure\n * Returns the path as an array of indices\n *\n * @example\n * // Structure: div > div > children\n * findSlotMarkerPath(structure) // Returns [0, 0, 1] (or null if not found)\n */\nfunction findSlotMarkerPath(structure: any, currentPath: Path = [0]): Path | null {\n if (!structure || typeof structure !== 'object') return null;\n\n if (isSlotMarker(structure)) {\n return currentPath;\n }\n\n if (!Array.isArray((structure as any).children)) {\n return null;\n }\n\n for (let i = 0; i < (structure as any).children.length; i++) {\n const child = (structure as any).children[i];\n\n if (isSlotMarker(child)) {\n return [...currentPath, i];\n }\n\n if (child && typeof child === 'object' && !Array.isArray(child)) {\n const found = findSlotMarkerPath(child, [...currentPath, i]);\n if (found) return found;\n }\n }\n\n return null;\n}\n\n/**\n * Calculate rendered path accounting for component structure wrapping\n *\n * When a component has a {type: \"slot\"} marker nested inside its structure,\n * the rendered path needs adjustment for the nesting depth.\n *\n * This algorithm builds the rendered path incrementally, checking if each\n * parent node is a component and calculating the correct rendered position\n * based on the component's slot path.\n *\n * @example\n * Section structure: div > div > slot (slotPath = [0, 0, 0])\n * Stack structure: div > div > slot (slotPath = [0, 0, 0])\n *\n * Logical path [0, 1, 0, 0] (Subtitle inside Stack inside Section):\n * - i=1: root div is NOT component, renderedPath = [0, 1]\n * - i=2: Section IS component, slotPath=[0,0,0], prefix=[0], renderedPath = [0, 1, 0, 0]\n * - i=3: Stack IS component, slotPath=[0,0,0], prefix=[0], renderedPath = [0, 1, 0, 0, 0, 0]\n */\nfunction calculateRenderedPath(\n logicalPath: Path,\n currentNode: any,\n globalComponentRegistry: any,\n navigationHistory?: NavigationContext[]\n): Path {\n if (!currentNode || logicalPath.length === 0) {\n return logicalPath;\n }\n\n // For the root element, logical and rendered paths are the same\n if (logicalPath.length === 1) {\n return logicalPath;\n }\n\n // Handle editing a component definition with slot marker\n // This calculates the offset for elements that come AFTER the slot in the structure\n // The offset is applied during the component slot wrapping calculation below\n let postSlotOffset = 0;\n let postSlotDepth = -1;\n\n if (navigationHistory && navigationHistory.length > 0) {\n // Use the most recent (current) navigation context's instanceChildren\n // When editing nested components A > B, we need B's instanceChildren, not A's\n const currentContext = navigationHistory[navigationHistory.length - 1];\n const instanceChildren = currentContext.instanceChildren;\n const instanceChildrenCount = Array.isArray(instanceChildren) ? instanceChildren.length : 0;\n\n if (instanceChildrenCount > 0) {\n const rootSlotPath = findSlotMarkerPath(currentNode);\n\n if (rootSlotPath && rootSlotPath.length > 1) {\n // Check if this path is for an element AFTER the slot marker\n const markerDepth = rootSlotPath.length - 1;\n if (logicalPath.length > markerDepth) {\n const indexAtMarkerLevel = logicalPath[markerDepth];\n const markerIndex = rootSlotPath[markerDepth];\n\n if (indexAtMarkerLevel > markerIndex) {\n // This path is after the slot marker in the structure\n // Calculate offset but DON'T return early - we still need to handle\n // component slot wrapping (e.g., if root is a component like Layout)\n postSlotOffset = instanceChildrenCount - 1;\n postSlotDepth = markerDepth;\n }\n }\n }\n }\n }\n\n // Build rendered path incrementally by walking through the logical path\n // and checking if each parent is a component with a nested slot\n let renderedPath: Path = [0];\n let node = currentNode;\n\n for (let i = 1; i < logicalPath.length; i++) {\n let childIndex = logicalPath[i];\n\n // Apply post-slot offset at the appropriate depth\n // This handles elements that come AFTER a slot marker in the component structure\n if (i === postSlotDepth && postSlotOffset > 0) {\n childIndex += postSlotOffset;\n }\n\n if (!node || !(node as any).children) break;\n\n const children = Array.isArray((node as any).children)\n ? (node as any).children\n : [(node as any).children];\n const childNode = children[logicalPath[i]]; // Use original index for traversal\n\n // Check if current node (the parent) is a component\n if (isComponentNode(node)) {\n const componentName = (node as any).component;\n const componentDef = globalComponentRegistry?.get?.(componentName);\n\n if (componentDef?.component?.structure) {\n const slotPath = findSlotMarkerPath(componentDef.component.structure);\n\n if (slotPath && slotPath.length > 1) {\n // slotPath is like [0, 0, 0] meaning: root \u2192 child0 \u2192 child0 \u2192 slot\n // prefix = path from component root to slot's parent container\n // For [0, 0, 0]: prefix = [0] (the middle elements, excluding root and slot index)\n const prefix = slotPath.slice(1, -1);\n const slotIndex = slotPath[slotPath.length - 1];\n\n // Child renders at: currentRenderedPath + prefix + (slotIndex + adjustedChildIndex)\n renderedPath = [...renderedPath, ...prefix, slotIndex + childIndex];\n } else {\n // No nested slot or slot at root level, direct child mapping\n renderedPath = [...renderedPath, childIndex];\n }\n } else {\n // Component has no structure defined\n renderedPath = [...renderedPath, childIndex];\n }\n } else {\n // Regular HTML node - direct mapping\n renderedPath = [...renderedPath, childIndex];\n }\n\n node = childNode;\n }\n\n return renderedPath;\n}\n\n/**\n * Navigation context for component editing\n * Used to convert component-relative paths to page-relative paths\n *\n * Note: This matches FileStore's NavigationContext structure for compatibility\n */\n/**\n * CMS item context for elements inside CMS List(s)\n */\nexport interface CMSItemContext {\n itemIndexPath: number[]; // e.g., [0] for single list, [0, 2] for nested\n listPaths: Path[]; // Parallel array of list node paths\n}\n\nexport interface NavigationContext {\n file?: any; // FileItem - optional as not all contexts have file\n componentInstancePath: Path | null;\n componentInstanceRenderedPath?: Path | null; // Rendered path for accurate DOM queries\n instanceChildren?: Array<ComponentNode | string>; // Children of the component instance (for path offset calculation)\n cmsItemContext?: CMSItemContext | null; // CMS context when editing component inside CMS List\n}\n\n/**\n * Build all paths from tree with both logical and rendered paths\n *\n * Recursively traverses the tree structure and creates NodePathData entries\n * for each node, including both the logical path and the rendered path.\n *\n * When editing a component (navigationHistory provided), paths are adjusted\n * to be page-relative by prepending the cumulative component instance path.\n *\n * @param pageData - The page or component data\n * @param globalComponentRegistry - Registry for component definitions\n * @param navigationHistory - Optional navigation context for component editing\n * @returns Array of NodePathData with both logical and rendered paths\n *\n * @example\n * // When editing a page\n * const pathsData = buildTreePathsWithRendered(pageData, registry);\n * pathsData.forEach(({path, renderedPath}) => {\n * console.log(`Node at [${path}] renders as [${renderedPath}]`);\n * });\n *\n * // When editing a component\n * const navigationHistory = [{componentInstancePath: [0, 2]}];\n * const pathsData = buildTreePathsWithRendered(componentData, registry, navigationHistory);\n * // Returns paths relative to the page (e.g., [0, 2, 0] for first child of component)\n */\nexport function buildTreePathsWithRendered(\n pageData: PageData,\n globalComponentRegistry?: any,\n navigationHistory?: NavigationContext[]\n): NodePathData[] {\n const rootData = getRootData(pageData);\n if (!rootData) return [];\n\n // Calculate cumulative component instance path for nested editing\n // Use rendered paths to ensure DOM queries have correct element paths\n let cumulativeInstancePath: Path | null = null;\n if (navigationHistory && navigationHistory.length > 0) {\n // Use rendered path for accurate DOM queries\n cumulativeInstancePath = navigationHistory[0].componentInstanceRenderedPath ?? navigationHistory[0].componentInstancePath;\n\n // For nested components, chain the paths\n for (let i = 1; i < navigationHistory.length; i++) {\n const nextPath = navigationHistory[i].componentInstanceRenderedPath ?? navigationHistory[i].componentInstancePath;\n if (nextPath && cumulativeInstancePath) {\n // Append path segments except root\n cumulativeInstancePath = [\n ...cumulativeInstancePath,\n ...nextPath.slice(1)\n ];\n }\n }\n }\n\n const result: NodePathData[] = [];\n\n function traverse(node: ComponentNode, currentPath: Path = [0]): void {\n // Calculate rendered path for this node\n // Call calculateRenderedPath when:\n // 1. globalComponentRegistry exists (for component slot offsets), OR\n // 2. navigationHistory exists (for post-slot element offsets when editing a component)\n const needsPathCalculation = globalComponentRegistry || (navigationHistory && navigationHistory.length > 0);\n const renderedPath = needsPathCalculation\n ? calculateRenderedPath(currentPath, rootData, globalComponentRegistry, navigationHistory)\n : currentPath;\n\n // When editing a component, adjust rendered path to be page-relative\n // Logical path always stays component-relative (starting from [0])\n const adjustedRenderedPath = cumulativeInstancePath\n ? [...cumulativeInstancePath, ...renderedPath.slice(1)]\n : renderedPath;\n\n result.push({\n path: currentPath, // Keep logical path component-relative\n renderedPath: adjustedRenderedPath, // Adjust rendered path for page-relative queries\n });\n\n // Traverse children\n // Include markers when editing a component instance (has navigationHistory)\n // to ensure they get proper rendered paths\n const nodeWithChildren = node as any;\n if (nodeWithChildren.children && Array.isArray(nodeWithChildren.children)) {\n nodeWithChildren.children.forEach((child: any, index: number) => {\n if (\n typeof child === 'object' &&\n child !== null &&\n ('tag' in child || 'component' in child || 'html' in child || 'src' in child || 'href' in child || isLocaleListNode(child) || isCMSListNode(child) || isListNode(child) || (cumulativeInstancePath && isSlotMarker(child)))\n ) {\n const childPath = [...currentPath, index];\n traverse(child as ComponentNode, childPath);\n }\n });\n }\n }\n\n traverse(rootData);\n return result;\n}\n\n/**\n * Build tree paths for a specific component context\n *\n * When editing a component, use this to get paths for the component definition\n * with proper accounting for slot marker positions.\n *\n * @param componentStructure - Component definition structure\n * @param globalComponentRegistry - Registry for nested components\n * @param navigationHistory - Optional navigation context to adjust paths to page-relative\n * @returns Array of NodePathData\n */\nexport function buildComponentTreePaths(\n componentStructure: ComponentNode,\n globalComponentRegistry?: any,\n navigationHistory?: NavigationContext[]\n): NodePathData[] {\n const result: NodePathData[] = [];\n\n // Calculate cumulative component instance path for navigation context\n let cumulativeInstancePath: Path | null = null;\n if (navigationHistory && navigationHistory.length > 0) {\n cumulativeInstancePath = navigationHistory[0].componentInstanceRenderedPath ?? navigationHistory[0].componentInstancePath;\n\n for (let i = 1; i < navigationHistory.length; i++) {\n const nextPath = navigationHistory[i].componentInstanceRenderedPath ?? navigationHistory[i].componentInstancePath;\n if (nextPath && cumulativeInstancePath) {\n cumulativeInstancePath = [\n ...cumulativeInstancePath,\n ...nextPath.slice(1)\n ];\n }\n }\n }\n\n function traverse(node: ComponentNode, currentPath: Path = [0]): void {\n // In component context, logical and rendered paths may differ\n // based on nested slot markers\n const needsPathCalculation = globalComponentRegistry || (navigationHistory && navigationHistory.length > 0);\n const renderedPath = needsPathCalculation\n ? calculateRenderedPath(currentPath, componentStructure, globalComponentRegistry, navigationHistory)\n : currentPath;\n\n // Adjust to page-relative paths if navigating into an instance\n const adjustedRenderedPath = cumulativeInstancePath\n ? [...cumulativeInstancePath, ...renderedPath.slice(1)]\n : renderedPath;\n\n result.push({\n path: currentPath,\n renderedPath: adjustedRenderedPath,\n });\n\n // Traverse children\n const nodeWithChildren = node as any;\n if (nodeWithChildren.children && Array.isArray(nodeWithChildren.children)) {\n nodeWithChildren.children.forEach((child: any, index: number) => {\n if (\n typeof child === 'object' &&\n child !== null &&\n ('tag' in child || 'component' in child || 'html' in child || 'src' in child || 'href' in child || isLocaleListNode(child) || isCMSListNode(child) || isListNode(child) || isSlotMarker(child))\n ) {\n const childPath = [...currentPath, index];\n traverse(child as ComponentNode, childPath);\n }\n });\n }\n }\n\n traverse(componentStructure);\n return result;\n}\n\n/**\n * Find NodePathData by logical path\n */\nexport function findPathData(\n pathsData: NodePathData[],\n searchPath: Path\n): NodePathData | undefined {\n return pathsData.find(\n (item) =>\n item.path.length === searchPath.length &&\n item.path.every((val, idx) => val === searchPath[idx])\n );\n}\n\n/**\n * Get all ancestors for a path (including the path itself)\n */\nexport function getPathAncestors(\n pathsData: NodePathData[],\n searchPath: Path\n): NodePathData[] {\n const ancestors: NodePathData[] = [];\n\n for (let i = 1; i <= searchPath.length; i++) {\n const ancestorPath = searchPath.slice(0, i);\n const found = findPathData(pathsData, ancestorPath);\n if (found) {\n ancestors.push(found);\n }\n }\n\n return ancestors;\n}\n", "/**\n * Validation exports\n */\n\nexport * from './schemas';\nexport * from './validators';\nexport * from './propValidator';\nexport * from './cmsValidators';\n", "/**\n * CMS Validation Utilities\n * Centralized validation for CMS-specific fields to ensure consistency\n */\n\nimport { z } from 'zod';\n\n/**\n * Regex pattern for valid CMS collection IDs\n * Allows alphanumeric characters, underscores, and hyphens\n */\nexport const CMS_COLLECTION_ID_REGEX = /^[a-zA-Z0-9_-]+$/;\n\n/**\n * Zod schema for CMS collection ID validation\n */\nexport const CMSCollectionIdSchema = z.string()\n .min(1, 'Collection ID is required')\n .regex(CMS_COLLECTION_ID_REGEX, 'Collection ID must contain only letters, numbers, underscores, and hyphens');\n\n/**\n * Validate a CMS collection ID\n * @returns Object with valid boolean and optional error message\n */\nexport function validateCollectionId(id: string): { valid: boolean; error?: string } {\n const result = CMSCollectionIdSchema.safeParse(id);\n if (result.success) {\n return { valid: true };\n }\n return { valid: false, error: result.error.errors[0]?.message };\n}\n\n/**\n * Check if a string is a valid CMS collection ID (simple boolean check)\n */\nexport function isValidCollectionId(id: string): boolean {\n return CMS_COLLECTION_ID_REGEX.test(id);\n}\n", "/**\n * Shared utility functions used across the codebase\n */\n\nimport type { Path } from './pathArrayUtils';\nimport { stringToPath, pathToLegacyString, getParentPath, isRootPath as isRootPathArray } from './pathArrayUtils';\nimport { ROOT_0_STRING } from './pathArrayUtils';\n\n/**\n * Deep clone an object using structuredClone\n * @param obj - The object to clone\n * @returns A deep clone of the object\n */\nexport function deepClone<T>(obj: T): T {\n return structuredClone(obj);\n}\n\n/**\n * Wait for a specified amount of time\n * @param ms - Milliseconds to wait\n */\nexport function wait(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n/**\n * Check if the currently focused element is editable (input, textarea, or contenteditable)\n * Also checks if the active element is INSIDE a contenteditable element (for rich text editors like Tiptap/ProseMirror)\n * Also returns true if text is selected (to allow native copy/paste)\n * @returns true if the active element is editable or text is selected\n */\nexport function isEditableElement(): boolean {\n // Allow native copy/paste when text is selected\n // Note: window.getSelection() only returns selections from the current document,\n // NOT from iframe documents. So in the parent window, any selection is from\n // sidebar/panels and should allow native copy.\n const selection = window.getSelection();\n if (selection && selection.toString().trim().length > 0) {\n return true;\n }\n\n const activeElement = document.activeElement;\n if (!activeElement) return false;\n\n // Textarea always accepts text\n if (activeElement.tagName === 'TEXTAREA') {\n return true;\n }\n\n // For inputs, only block shortcuts for text-accepting types\n if (activeElement.tagName === 'INPUT') {\n const inputType = (activeElement as HTMLInputElement).type.toLowerCase();\n const textInputTypes = ['text', 'password', 'email', 'number', 'search', 'tel', 'url', 'date', 'time', 'datetime-local', 'month', 'week'];\n // Allow shortcuts for: checkbox, radio, button, submit, reset, color, file, range, hidden\n return textInputTypes.includes(inputType);\n }\n\n // Check if activeElement or any parent is contenteditable\n // This handles rich text editors where focus may be on an internal element\n let element: Element | null = activeElement;\n while (element) {\n if (\n element.hasAttribute('contenteditable') ||\n (element as HTMLElement).isContentEditable\n ) {\n return true;\n }\n element = element.parentElement;\n }\n\n return false;\n}\n\n/**\n * Extract the parent path from a tree path\n * Example: root_0_children_0 -> root_0, root_0_children_0_children_1 -> root_0_children_0\n * Also accepts array paths: [0,0] -> \"root_0\", [0,0,1] -> \"root_0_children_0\"\n * \n * @param treePath - The tree path (string or Path array)\n * @param rootPath - The root path constant (default: 'root_0')\n * @returns The parent path, or rootPath if no parent found\n */\nexport function getParentPathFromTreePath(treePath: string | Path, rootPath: string = ROOT_0_STRING): string {\n // Convert to array if needed\n const pathArray = typeof treePath === 'string' ? stringToPath(treePath) : treePath;\n \n // Handle root paths\n if (isRootPathArray(pathArray)) {\n return rootPath;\n }\n \n // Use array operations to get parent path\n const parentArray = getParentPath(pathArray);\n return pathToLegacyString(parentArray);\n}\n\n/**\n * Normalize children property to always be an array\n * Mutates the node object directly (for performance in large trees)\n * Handles cases where children might be undefined, a single item, or already an array\n * @param node - The node object with a children property (will be mutated)\n */\nexport function normalizeChildrenArray(node: { children?: any[] | any }): void {\n if (!node.children) {\n node.children = [];\n } else if (!Array.isArray(node.children)) {\n // Single child - wrap in array\n node.children = [node.children];\n }\n // If already an array, no change needed\n}\n\n", "/**\n * Shared theme color defaults\n * Used by PropsPanel and StyleEditor to avoid duplication\n */\n\nexport interface PropsPanelColors {\n background: string;\n backgroundSecondary: string;\n backgroundTertiary: string;\n border: string;\n borderSecondary: string;\n text: string;\n textSecondary: string;\n textMuted: string;\n codeString: string;\n codeNumber: string;\n codeKey: string;\n codeType: string;\n buttonPrimary: string;\n buttonPrimaryHover: string;\n buttonSecondary: string;\n buttonDanger: string;\n buttonDangerHover: string;\n inputBackground: string;\n inputBorder: string;\n hoverBackground: string;\n variableBackground?: string;\n}\n\n/**\n * Spacing constants for props panel components\n */\nexport interface PropsPanelSpacing {\n tight: string; // 2px - for label:colon:input gaps\n normal: string; // 4px - for standard gaps\n loose: string; // 8px - for larger gaps\n}\n\nexport const DEFAULT_PROPS_PANEL_SPACING: PropsPanelSpacing = {\n tight: '2px',\n normal: '4px',\n loose: '8px',\n};\n\n/**\n * Base input style properties\n */\nexport interface PropsPanelInputStyle {\n fontFamily: string;\n fontSize: string;\n padding: string;\n borderRadius: string;\n outline: string;\n border?: string;\n}\n\n/**\n * Base input style defaults\n */\nexport const DEFAULT_INPUT_STYLE: Omit<PropsPanelInputStyle, 'border' | 'color' | 'background'> = {\n fontFamily: \"'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif\",\n fontSize: '13px',\n padding: '6px 8px',\n borderRadius: '3px',\n outline: 'none',\n};\n\n/**\n * Base textarea style defaults\n */\nexport const DEFAULT_TEXTAREA_STYLE: Omit<PropsPanelInputStyle, 'border' | 'color' | 'background'> = {\n fontFamily: 'inherit',\n fontSize: '13px',\n padding: '6px 8px',\n borderRadius: '3px',\n outline: 'none',\n};\n\n/**\n * Default dark theme colors for props panel\n */\nexport const DEFAULT_PROPS_PANEL_COLORS: PropsPanelColors = {\n background: '#1e1e1e',\n backgroundSecondary: '#2d2d2d',\n backgroundTertiary: '#252525',\n border: '#333333',\n borderSecondary: '#444444',\n text: '#cccccc',\n textSecondary: '#cccccc',\n textMuted: '#888888',\n codeString: '#ffffff',\n codeNumber: '#b5cea8',\n codeKey: '#9cdcfe',\n codeType: '#4ec9b0',\n buttonPrimary: '#007acc',\n buttonPrimaryHover: '#0098ff',\n buttonSecondary: '#007acc',\n buttonDanger: '#f48771',\n buttonDangerHover: '#ff6b6b',\n inputBackground: '#2a2a2a',\n inputBorder: '#444444',\n hoverBackground: '#2a2d2e',\n variableBackground: '#2a2a2a',\n};\n\n/**\n * Light theme colors for props panel\n */\nexport const LIGHT_PROPS_PANEL_COLORS: PropsPanelColors = {\n background: '#ffffff',\n backgroundSecondary: '#f5f5f5',\n backgroundTertiary: '#fafafa',\n border: '#e4e8ec',\n borderSecondary: '#d0d0d0',\n text: '#1a1a1a',\n textSecondary: '#333333',\n textMuted: '#666666',\n codeString: '#a31515',\n codeNumber: '#098658',\n codeKey: '#0451a5',\n codeType: '#267f99',\n buttonPrimary: '#0078d4',\n buttonPrimaryHover: '#106ebe',\n buttonSecondary: '#0078d4',\n buttonDanger: '#d13438',\n buttonDangerHover: '#a4262c',\n inputBackground: '#f5f7fa',\n inputBorder: '#d0d0d0',\n hoverBackground: '#f0f0f0',\n variableBackground: '#ebedf0',\n};\n\n", "/**\n * Color Variable Utilities\n * Handles resolution and validation of color variables in styles\n */\n\n/**\n * Check if a value is a color variable reference\n * @example \"var(--primary-color)\" -> true\n */\nexport function isColorVariable(value: string | unknown): value is string {\n if (typeof value !== 'string') return false;\n return /^var\\(--[\\w-]+\\)$/.test(value.trim());\n}\n\n/**\n * Extract variable name from a color variable reference\n * @example \"var(--primary-color)\" -> \"primary-color\"\n */\nexport function extractVariableName(value: string): string | null {\n const match = value.match(/^var\\(--([^)]+)\\)$/);\n return match ? match[1] : null;\n}\n\n/**\n * Create a color variable reference\n * @example \"primary-color\" -> \"var(--primary-color)\"\n */\nexport function createVariableReference(variableName: string): string {\n return `var(--${variableName})`;\n}\n\n/**\n * Resolve a color variable to its actual value\n * @param value - The style value (may be a variable reference or actual color)\n * @param colorMap - Map of variable names to color values\n * @returns Resolved color value or original value if not a variable\n */\nexport function resolveColorVariable(\n value: string | unknown,\n colorMap: Record<string, string>\n): string {\n if (!isColorVariable(value)) {\n return String(value);\n }\n\n const varName = extractVariableName(value);\n if (!varName) {\n return String(value);\n }\n\n return colorMap[varName] || String(value);\n}\n\n/**\n * Replace color variables in a style object\n * @param styles - Style object with potential variable references\n * @param colorMap - Map of variable names to color values\n * @returns New style object with variables resolved\n */\nexport function resolveColorVariablesInStyles(\n styles: Record<string, any>,\n colorMap: Record<string, string>\n): Record<string, any> {\n const resolved: Record<string, any> = {};\n\n for (const [key, value] of Object.entries(styles)) {\n if (typeof value === 'string') {\n resolved[key] = resolveColorVariable(value, colorMap);\n } else {\n resolved[key] = value;\n }\n }\n\n return resolved;\n}\n\n/**\n * Get all color variable references from a style object\n * @param styles - Style object to search\n * @returns Array of variable names found in styles\n */\nexport function getColorVariablesFromStyles(\n styles: Record<string, any>\n): string[] {\n const variables = new Set<string>();\n\n for (const value of Object.values(styles)) {\n if (isColorVariable(value)) {\n const varName = extractVariableName(value);\n if (varName) {\n variables.add(varName);\n }\n }\n }\n\n return Array.from(variables);\n}\n", "/**\n * Error Types\n * Structured error types for consistent error handling across the codebase\n */\n\n/**\n * Error categories for filtering and handling\n */\nexport type ErrorCategory =\n | 'validation' // Invalid input/state\n | 'runtime' // Runtime failures (graceful degradation)\n | 'network' // API/fetch failures\n | 'internal'; // Unexpected errors\n\n/**\n * Structured error type for consistent error handling\n */\nexport interface AppError {\n readonly category: ErrorCategory;\n readonly code: string;\n readonly message: string;\n readonly context?: Record<string, unknown>;\n readonly cause?: Error;\n}\n\n/**\n * Create a structured error object\n */\nexport function createError(\n category: ErrorCategory,\n code: string,\n message: string,\n context?: Record<string, unknown>,\n cause?: Error\n): AppError {\n return { category, code, message, context, cause };\n}\n\n/**\n * Type guard for AppError\n */\nexport function isAppError(error: unknown): error is AppError {\n return (\n typeof error === 'object' &&\n error !== null &&\n 'category' in error &&\n 'code' in error &&\n 'message' in error\n );\n}\n", "/**\n * Color conversion utilities for HEX, RGB, and HSL formats\n */\n\nexport type ColorMode = 'hex' | 'rgb' | 'hsl';\n\nexport interface RgbColor {\n r: number;\n g: number;\n b: number;\n}\n\nexport interface HslColor {\n h: number;\n s: number;\n l: number;\n}\n\n// \u2500\u2500 Detection \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst HEX_RE = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i;\nconst RGB_RE = /^rgb\\(\\s*(\\d{1,3})\\s*[,\\s]\\s*(\\d{1,3})\\s*[,\\s]\\s*(\\d{1,3})\\s*\\)$/i;\nconst HSL_RE = /^hsl\\(\\s*(\\d{1,3}(?:\\.\\d+)?)\\s*[,\\s]\\s*(\\d{1,3}(?:\\.\\d+)?)%?\\s*[,\\s]\\s*(\\d{1,3}(?:\\.\\d+)?)%?\\s*\\)$/i;\n\n/** Detect the color mode from a CSS color string */\nexport function detectColorMode(value: string): ColorMode | null {\n if (!value) return null;\n const v = value.trim();\n if (HEX_RE.test(v)) return 'hex';\n if (RGB_RE.test(v)) return 'rgb';\n if (HSL_RE.test(v)) return 'hsl';\n return null;\n}\n\n// \u2500\u2500 Parsing \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Parse a CSS rgb() string to an RgbColor object */\nexport function parseCssRgb(value: string): RgbColor | null {\n const m = value.trim().match(RGB_RE);\n if (!m) return null;\n return {\n r: clamp(parseInt(m[1], 10), 0, 255),\n g: clamp(parseInt(m[2], 10), 0, 255),\n b: clamp(parseInt(m[3], 10), 0, 255),\n };\n}\n\n/** Parse a CSS hsl() string to an HslColor object */\nexport function parseCssHsl(value: string): HslColor | null {\n const m = value.trim().match(HSL_RE);\n if (!m) return null;\n return {\n h: clamp(parseFloat(m[1]), 0, 360),\n s: clamp(parseFloat(m[2]), 0, 100),\n l: clamp(parseFloat(m[3]), 0, 100),\n };\n}\n\n// \u2500\u2500 Formatting \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Format an RgbColor to a CSS rgb() string */\nexport function rgbToCssString(rgb: RgbColor): string {\n return `rgb(${Math.round(rgb.r)}, ${Math.round(rgb.g)}, ${Math.round(rgb.b)})`;\n}\n\n/** Format an HslColor to a CSS hsl() string */\nexport function hslToCssString(hsl: HslColor): string {\n return `hsl(${Math.round(hsl.h)}, ${Math.round(hsl.s)}%, ${Math.round(hsl.l)}%)`;\n}\n\n// \u2500\u2500 Hex \u2194 RGB \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Expand 3-char hex to 6-char hex */\nfunction expandHex(hex: string): string {\n const h = hex.replace('#', '');\n if (h.length === 3) {\n return '#' + h[0] + h[0] + h[1] + h[1] + h[2] + h[2];\n }\n return '#' + h;\n}\n\n/** Convert a hex color string to an RgbColor */\nexport function hexToRgb(hex: string): RgbColor {\n const h = expandHex(hex).replace('#', '');\n return {\n r: parseInt(h.substring(0, 2), 16),\n g: parseInt(h.substring(2, 4), 16),\n b: parseInt(h.substring(4, 6), 16),\n };\n}\n\n/** Convert an RgbColor to a hex color string */\nexport function rgbToHex(rgb: RgbColor): string {\n const r = clamp(Math.round(rgb.r), 0, 255);\n const g = clamp(Math.round(rgb.g), 0, 255);\n const b = clamp(Math.round(rgb.b), 0, 255);\n return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);\n}\n\n// \u2500\u2500 RGB \u2194 HSL \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Convert an RgbColor to an HslColor */\nexport function rgbToHsl(rgb: RgbColor): HslColor {\n const r = rgb.r / 255;\n const g = rgb.g / 255;\n const b = rgb.b / 255;\n\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const l = (max + min) / 2;\n\n if (max === min) {\n return { h: 0, s: 0, l: Math.round(l * 100) };\n }\n\n const d = max - min;\n const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n\n let h = 0;\n if (max === r) {\n h = ((g - b) / d + (g < b ? 6 : 0)) / 6;\n } else if (max === g) {\n h = ((b - r) / d + 2) / 6;\n } else {\n h = ((r - g) / d + 4) / 6;\n }\n\n return {\n h: Math.round(h * 360),\n s: Math.round(s * 100),\n l: Math.round(l * 100),\n };\n}\n\n/** Convert an HslColor to an RgbColor */\nexport function hslToRgb(hsl: HslColor): RgbColor {\n const h = hsl.h / 360;\n const s = hsl.s / 100;\n const l = hsl.l / 100;\n\n if (s === 0) {\n const v = Math.round(l * 255);\n return { r: v, g: v, b: v };\n }\n\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n\n return {\n r: Math.round(hueToRgb(p, q, h + 1 / 3) * 255),\n g: Math.round(hueToRgb(p, q, h) * 255),\n b: Math.round(hueToRgb(p, q, h - 1 / 3) * 255),\n };\n}\n\nfunction hueToRgb(p: number, q: number, t: number): number {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n}\n\n// \u2500\u2500 Hex \u2194 HSL (via RGB) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Convert a hex color string to an HslColor */\nexport function hexToHsl(hex: string): HslColor {\n return rgbToHsl(hexToRgb(hex));\n}\n\n/** Convert an HslColor to a hex color string */\nexport function hslToHex(hsl: HslColor): string {\n return rgbToHex(hslToRgb(hsl));\n}\n\n// \u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n", "/**\n * Gradient parsing and building utilities\n */\n\nexport interface GradientStop {\n color: string;\n position: number;\n}\n\nexport interface GradientConfig {\n type: 'linear' | 'radial' | 'conic';\n angle: number;\n shape?: 'circle' | 'ellipse';\n stops: GradientStop[];\n}\n\nconst LINEAR_RE = /^linear-gradient\\((.+)\\)$/i;\nconst RADIAL_RE = /^radial-gradient\\((.+)\\)$/i;\nconst CONIC_RE = /^conic-gradient\\((.+)\\)$/i;\n\n/** Check if a CSS value is a gradient */\nexport function isGradientValue(value: string): boolean {\n if (!value) return false;\n const v = value.trim().toLowerCase();\n return v.startsWith('linear-gradient(') ||\n v.startsWith('radial-gradient(') ||\n v.startsWith('conic-gradient(');\n}\n\n/** Parse a CSS gradient string into a GradientConfig */\nexport function parseGradient(cssValue: string): GradientConfig | null {\n if (!cssValue) return null;\n const v = cssValue.trim();\n\n let match: RegExpMatchArray | null;\n let type: GradientConfig['type'];\n\n if ((match = v.match(LINEAR_RE))) {\n type = 'linear';\n } else if ((match = v.match(RADIAL_RE))) {\n type = 'radial';\n } else if ((match = v.match(CONIC_RE))) {\n type = 'conic';\n } else {\n return null;\n }\n\n const inner = match[1];\n const parts = splitGradientArgs(inner);\n\n let angle = type === 'linear' ? 180 : 0;\n let shape: 'circle' | 'ellipse' | undefined;\n let stopsStartIndex = 0;\n\n if (type === 'linear') {\n const first = parts[0]?.trim();\n if (first) {\n const angleDeg = parseAngle(first);\n if (angleDeg !== null) {\n angle = angleDeg;\n stopsStartIndex = 1;\n } else if (first.startsWith('to ')) {\n angle = directionToAngle(first);\n stopsStartIndex = 1;\n }\n }\n } else if (type === 'radial') {\n const first = parts[0]?.trim().toLowerCase();\n if (first) {\n if (first.startsWith('circle') || first === 'circle') {\n shape = 'circle';\n stopsStartIndex = 1;\n } else if (first.startsWith('ellipse') || first === 'ellipse') {\n shape = 'ellipse';\n stopsStartIndex = 1;\n }\n }\n } else if (type === 'conic') {\n const first = parts[0]?.trim();\n if (first) {\n const fromAngle = first.match(/^from\\s+(\\d+(?:\\.\\d+)?)deg/i);\n if (fromAngle) {\n angle = parseFloat(fromAngle[1]);\n stopsStartIndex = 1;\n }\n }\n }\n\n const stops = parseStops(parts.slice(stopsStartIndex));\n if (stops.length < 2) return null;\n\n return { type, angle, shape, stops };\n}\n\n/** Build a CSS gradient string from a GradientConfig */\nexport function buildGradientCss(config: GradientConfig): string {\n const stopStrings = config.stops.map(\n s => `${s.color} ${Math.round(s.position)}%`\n );\n\n switch (config.type) {\n case 'linear': {\n return `linear-gradient(${config.angle}deg, ${stopStrings.join(', ')})`;\n }\n case 'radial': {\n const shape = config.shape || 'circle';\n return `radial-gradient(${shape}, ${stopStrings.join(', ')})`;\n }\n case 'conic': {\n const from = config.angle ? `from ${config.angle}deg, ` : '';\n return `conic-gradient(${from}${stopStrings.join(', ')})`;\n }\n }\n}\n\n// \u2500\u2500 Internal helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Split gradient arguments respecting nested parentheses */\nfunction splitGradientArgs(inner: string): string[] {\n const parts: string[] = [];\n let depth = 0;\n let current = '';\n\n for (const char of inner) {\n if (char === '(') depth++;\n if (char === ')') depth--;\n if (char === ',' && depth === 0) {\n parts.push(current.trim());\n current = '';\n } else {\n current += char;\n }\n }\n if (current.trim()) parts.push(current.trim());\n return parts;\n}\n\nfunction parseAngle(part: string): number | null {\n const m = part.match(/^(-?\\d+(?:\\.\\d+)?)deg$/i);\n return m ? parseFloat(m[1]) : null;\n}\n\nfunction directionToAngle(direction: string): number {\n const d = direction.trim().toLowerCase();\n const map: Record<string, number> = {\n 'to top': 0,\n 'to top right': 45,\n 'to right': 90,\n 'to bottom right': 135,\n 'to bottom': 180,\n 'to bottom left': 225,\n 'to left': 270,\n 'to top left': 315,\n };\n return map[d] ?? 180;\n}\n\nfunction parseStops(parts: string[]): GradientStop[] {\n const stops: GradientStop[] = [];\n const total = parts.length;\n\n for (let i = 0; i < total; i++) {\n const part = parts[i].trim();\n if (!part) continue;\n\n // Match color and optional position percentage\n const posMatch = part.match(/\\s+(\\d+(?:\\.\\d+)?)%\\s*$/);\n let color: string;\n let position: number;\n\n if (posMatch) {\n color = part.slice(0, posMatch.index!).trim();\n position = parseFloat(posMatch[1]);\n } else {\n color = part;\n // Auto-distribute position\n position = total <= 1 ? 0 : (i / (total - 1)) * 100;\n }\n\n stops.push({ color, position });\n }\n\n return stops;\n}\n", "/**\n * CMS Query Parser\n * Utilities for parsing and serializing sort/filter expressions for CMS List nodes.\n *\n * Sort Expression Syntax:\n * field [asc|desc]\n * Multiple fields separated by comma: date desc, title asc\n *\n * Filter Expression Syntax:\n * field operator value\n * Operators: =, ==, !=, <>, >, >=, <, <=, contains, ~, in\n * Multiple conditions on separate lines or semicolon-separated\n * Supports template values: category = {{cms.category}}\n */\n\nimport type { CMSFilterCondition, CMSSortConfig, CMSFilterOperator } from './types/cms';\n\n/**\n * Parse sort expression: \"date desc, title asc\"\n * Note: \"asc\" is the default and can be omitted. The serializer outputs \"date\" for ascending.\n */\nexport function parseSortExpression(expr: string): CMSSortConfig | CMSSortConfig[] | undefined {\n if (!expr.trim()) return undefined;\n\n const parts = expr.split(',').map(p => p.trim()).filter(Boolean);\n const sorts: CMSSortConfig[] = parts.map(part => {\n const tokens = part.split(/\\s+/);\n const field = tokens[0];\n const order = tokens[1]?.toLowerCase() === 'desc' ? 'desc' : 'asc';\n return { field, order };\n });\n\n return sorts.length === 1 ? sorts[0] : sorts;\n}\n\n/**\n * Serialize sort config back to expression\n */\nexport function serializeSortExpression(sort: CMSSortConfig | CMSSortConfig[] | undefined): string {\n if (!sort) return '';\n const sorts = Array.isArray(sort) ? sort : [sort];\n return sorts.map(s => `${s.field}${s.order === 'desc' ? ' desc' : ''}`).join(', ');\n}\n\n/**\n * Parse filter expression: \"featured = true; price > 100\"\n */\nexport function parseFilterExpression(\n expr: string\n): CMSFilterCondition | CMSFilterCondition[] | Record<string, unknown> | undefined {\n if (!expr.trim()) return undefined;\n\n // Split by newline or semicolon\n const lines = expr.split(/[;\\n]/).map(l => l.trim()).filter(Boolean);\n const conditions: CMSFilterCondition[] = [];\n\n for (const line of lines) {\n const condition = parseFilterLine(line);\n if (condition) conditions.push(condition);\n }\n\n if (conditions.length === 0) return undefined;\n\n // Single simple equality can use shorthand: { field: value }\n if (conditions.length === 1 && (!conditions[0].operator || conditions[0].operator === 'eq')) {\n return { [conditions[0].field]: conditions[0].value };\n }\n\n return conditions.length === 1 ? conditions[0] : conditions;\n}\n\nfunction parseFilterLine(line: string): CMSFilterCondition | null {\n // Match: field operator value\n // Operators listed longest-first to avoid partial matches (e.g., gte before gt)\n const match = line.match(/^(\\w+)\\s*(==|!=|<>|>=|<=|=|>|<|contains|~|in|gte|lte|neq|gt|lt|eq)\\s*(.+)$/i);\n if (!match) return null;\n\n const [, field, op, rawValue] = match;\n const operator = normalizeOperator(op);\n const value = parseValue(rawValue.trim(), operator);\n\n // For simple equality, we can omit operator\n if (operator === 'eq') {\n return { field, value };\n }\n\n return { field, operator, value };\n}\n\nfunction normalizeOperator(op: string): CMSFilterOperator {\n const normalized = op.toLowerCase();\n const map: Record<string, CMSFilterOperator> = {\n '=': 'eq', '==': 'eq', 'eq': 'eq',\n '!=': 'neq', '<>': 'neq', 'neq': 'neq',\n '>': 'gt', 'gt': 'gt',\n '>=': 'gte', 'gte': 'gte',\n '<': 'lt', 'lt': 'lt',\n '<=': 'lte', 'lte': 'lte',\n 'contains': 'contains', '~': 'contains',\n 'in': 'in'\n };\n return map[normalized] || 'eq';\n}\n\nfunction parseValue(raw: string, operator: CMSFilterOperator): unknown {\n // Template expression - keep as string\n if (raw.startsWith('{{') && raw.endsWith('}}')) {\n return raw;\n }\n\n // Handle 'in' operator - comma separated list\n if (operator === 'in') {\n return raw.split(',').map(v => parseScalarValue(v.trim()));\n }\n\n return parseScalarValue(raw);\n}\n\nfunction parseScalarValue(raw: string): unknown {\n // Boolean\n if (raw.toLowerCase() === 'true') return true;\n if (raw.toLowerCase() === 'false') return false;\n\n // Number\n const num = Number(raw);\n if (!isNaN(num) && raw !== '') return num;\n\n // String (strip quotes if present)\n if ((raw.startsWith('\"') && raw.endsWith('\"')) || (raw.startsWith(\"'\") && raw.endsWith(\"'\"))) {\n return raw.slice(1, -1);\n }\n\n return raw;\n}\n\n/**\n * Serialize filter config back to expression\n */\nexport function serializeFilterExpression(\n filter: CMSFilterCondition | CMSFilterCondition[] | Record<string, unknown> | undefined\n): string {\n if (!filter) return '';\n\n // Simple object filter: { featured: true }\n if (!Array.isArray(filter) && !isFilterCondition(filter)) {\n return Object.entries(filter)\n .map(([field, value]) => `${field} = ${serializeValue(value)}`)\n .join('\\n');\n }\n\n // Array or single condition\n const conditions = Array.isArray(filter) ? filter : [filter as CMSFilterCondition];\n return conditions.map(c => {\n const op = c.operator || 'eq';\n const opStr = operatorToString(op);\n const valStr = op === 'in' && Array.isArray(c.value)\n ? c.value.map(v => serializeValue(v)).join(', ')\n : serializeValue(c.value);\n return `${c.field} ${opStr} ${valStr}`;\n }).join('\\n');\n}\n\nfunction operatorToString(op: CMSFilterOperator): string {\n const map: Record<CMSFilterOperator, string> = {\n 'eq': '=',\n 'neq': '!=',\n 'gt': '>',\n 'gte': '>=',\n 'lt': '<',\n 'lte': '<=',\n 'contains': 'contains',\n 'in': 'in'\n };\n return map[op] || '=';\n}\n\nfunction isFilterCondition(obj: unknown): obj is CMSFilterCondition {\n return typeof obj === 'object' && obj !== null && 'field' in obj;\n}\n\nfunction serializeValue(value: unknown): string {\n if (typeof value === 'string') {\n // Template or simple alphanumeric - no quotes needed\n if (value.startsWith('{{') || /^[\\w-]+$/.test(value)) return value;\n return `\"${value}\"`;\n }\n return String(value);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/lib/client/theme.ts
CHANGED
|
@@ -44,6 +44,7 @@ export interface ThemeColors {
|
|
|
44
44
|
inputBackground: string;
|
|
45
45
|
inputBorder: string;
|
|
46
46
|
hoverBackground: string;
|
|
47
|
+
variableBackground?: string;
|
|
47
48
|
};
|
|
48
49
|
}
|
|
49
50
|
|
|
@@ -91,6 +92,7 @@ const lightThemeColors: ThemeColors = {
|
|
|
91
92
|
inputBackground: '#f9fafb',
|
|
92
93
|
inputBorder: '#e4e7ed',
|
|
93
94
|
hoverBackground: '#f1f3f5',
|
|
95
|
+
variableBackground: '#ebedf0',
|
|
94
96
|
},
|
|
95
97
|
};
|
|
96
98
|
|
|
@@ -126,7 +128,7 @@ const darkThemeColors: ThemeColors = {
|
|
|
126
128
|
text: '#cccccc',
|
|
127
129
|
textSecondary: '#cccccc',
|
|
128
130
|
textMuted: '#888888',
|
|
129
|
-
codeString: '#
|
|
131
|
+
codeString: '#ffffff',
|
|
130
132
|
codeNumber: '#b5cea8',
|
|
131
133
|
codeKey: '#9cdcfe',
|
|
132
134
|
codeType: '#4ec9b0',
|
|
@@ -138,6 +140,7 @@ const darkThemeColors: ThemeColors = {
|
|
|
138
140
|
inputBackground: '#1e1e1e',
|
|
139
141
|
inputBorder: '#444444',
|
|
140
142
|
hoverBackground: '#2a2d2e',
|
|
143
|
+
variableBackground: '#2a2a2a',
|
|
141
144
|
},
|
|
142
145
|
};
|
|
143
146
|
|