@kubuild/core 0.7.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/document/document-utils.ts","../src/document/command-tree-utils.ts","../src/document/commands.ts","../src/document/artboards.ts","../src/document/history.ts","../src/runtime/binding-resolver.ts","../src/runtime/variable-catalog.ts","../src/runtime/interpolator.ts","../src/runtime/conditional-resolver.ts","../src/runtime/pipeline-executor.ts","../src/runtime/state-store.ts","../src/runtime/server-tracking.ts","../src/runtime/tracking-relay.ts","../src/io/exporter.ts","../src/validation/validator.ts","../src/validation/security.ts","../src/io/tracking-sanitizer.ts","../src/io/importer.ts","../src/io/migration.ts","../src/io/load-project.ts","../src/io/round-trip-comparator.ts","../src/io/template-utils.ts","../src/validation/project-validator.ts","../src/validation/validation-engine.ts"],"sourcesContent":["import { PageDocument, Node, SCHEMA_NAME, CURRENT_SCHEMA_VERSION } from '@kubuild/schema';\nimport type { ComponentRegistryLike } from '../validation/validator';\n\n\nexport function createBlankDocument(title = 'Untitled Page'): PageDocument {\n return {\n schema: SCHEMA_NAME,\n version: CURRENT_SCHEMA_VERSION,\n metadata: {\n title,\n description: '',\n author: '',\n tags: [],\n category: 'general',\n version: '1.0.0',\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n },\n document: {\n id: 'root-page',\n type: 'page',\n props: { title },\n styles: { base: { minHeight: '100vh', backgroundColor: '#ffffff' } },\n children: [] as Node[],\n },\n };\n}\n\nexport function findNodeById(rootNode: Node, targetId: string): Node | null {\n if (rootNode.id === targetId) return rootNode;\n if (!rootNode.children) return null;\n for (const child of rootNode.children) {\n const found = findNodeById(child, targetId);\n if (found) return found;\n }\n return null;\n}\n\nexport interface CollectedAssetReference {\n assetId: string;\n reference: {\n type: 'asset';\n assetId: string;\n filename?: string;\n mimeType?: string;\n fallbackUrl?: string;\n };\n nodeId: string;\n propPath: string;\n}\n\n/**\n * Collect all AssetReference objects throughout a document tree.\n */\nexport function collectAssetReferences(rootNode: Node): CollectedAssetReference[] {\n const results: CollectedAssetReference[] = [];\n\n function traverseProps(propsObj: unknown, currentPath: string, nodeId: string): void {\n if (!propsObj || typeof propsObj !== 'object') return;\n\n if (Array.isArray(propsObj)) {\n propsObj.forEach((item, index) => {\n traverseProps(item, `${currentPath}/${index}`, nodeId);\n });\n return;\n }\n\n const record = propsObj as Record<string, unknown>;\n\n if (record.type === 'asset' && typeof record.assetId === 'string' && record.assetId.trim().length > 0) {\n results.push({\n assetId: record.assetId,\n reference: {\n type: 'asset',\n assetId: record.assetId,\n filename: typeof record.filename === 'string' ? record.filename : undefined,\n mimeType: typeof record.mimeType === 'string' ? record.mimeType : undefined,\n fallbackUrl: typeof record.fallbackUrl === 'string' ? record.fallbackUrl : undefined,\n },\n nodeId,\n propPath: currentPath,\n });\n }\n\n for (const [key, val] of Object.entries(record)) {\n if (val && typeof val === 'object') {\n traverseProps(val, `${currentPath}/${key}`, nodeId);\n }\n }\n }\n\n function traverseNode(node: Node): void {\n if (node.props) {\n traverseProps(node.props, `/document/${node.id}/props`, node.id);\n }\n if (node.children && Array.isArray(node.children)) {\n for (const child of node.children) {\n traverseNode(child);\n }\n }\n }\n\n traverseNode(rootNode);\n return results;\n}\n\nexport interface TreeRequirements {\n requiredComponents: string[];\n requiredCapabilities: string[];\n}\n\n/**\n * Extracts custom component types and capabilities required by a node tree.\n */\nexport function extractRequirementsFromTree(\n rootNode: Node,\n registry?: ComponentRegistryLike,\n): TreeRequirements {\n const requiredComponents = new Set<string>();\n const requiredCapabilities = new Set<string>();\n\n function traverse(node: Node): void {\n if (registry) {\n const def = registry.get(node.type);\n if (def?.category === 'custom') {\n requiredComponents.add(node.type);\n }\n if (def?.capabilities && Array.isArray(def.capabilities)) {\n for (const cap of def.capabilities) {\n requiredCapabilities.add(cap);\n }\n }\n }\n\n if (node.children && Array.isArray(node.children)) {\n for (const child of node.children) {\n traverse(child);\n }\n }\n }\n\n traverse(rootNode);\n\n return {\n requiredComponents: Array.from(requiredComponents).sort(),\n requiredCapabilities: Array.from(requiredCapabilities).sort(),\n };\n}\n\n/**\n * Remap asset references in a node tree based on an ID mapping dictionary.\n * Mutates the node props in place and returns the number of references updated.\n */\nexport function remapAssetReferences(\n rootNode: Node,\n idMap: Record<string, string> | Map<string, string>,\n): number {\n let remappedCount = 0;\n const getMappedId = (id: string): string | undefined => {\n if (idMap instanceof Map) return idMap.get(id);\n return idMap[id];\n };\n\n function traverseProps(propsObj: unknown): void {\n if (!propsObj || typeof propsObj !== 'object') return;\n\n if (Array.isArray(propsObj)) {\n for (const item of propsObj) {\n traverseProps(item);\n }\n return;\n }\n\n const record = propsObj as Record<string, unknown>;\n\n if (record.type === 'asset' && typeof record.assetId === 'string') {\n const newId = getMappedId(record.assetId);\n if (newId !== undefined && newId !== record.assetId) {\n record.assetId = newId;\n remappedCount++;\n }\n }\n\n for (const val of Object.values(record)) {\n if (val && typeof val === 'object') {\n traverseProps(val);\n }\n }\n }\n\n function traverseNode(node: Node): void {\n if (node.props) {\n traverseProps(node.props);\n }\n if (node.children && Array.isArray(node.children)) {\n for (const child of node.children) {\n traverseNode(child);\n }\n }\n }\n\n traverseNode(rootNode);\n return remappedCount;\n}\n\n/**\n * Remaps all asset references throughout a PageDocument.\n */\nexport function remapDocumentAssetReferences(\n doc: PageDocument,\n idMap: Record<string, string> | Map<string, string>,\n): PageDocument {\n if (doc && doc.document) {\n remapAssetReferences(doc.document, idMap);\n }\n return doc;\n}\n\nexport interface MissingComponentNodeInfo {\n nodeId: string;\n componentType: string;\n props: Record<string, unknown>;\n node: Node;\n}\n\n/**\n * Finds all nodes in a node tree that reference component types not registered in the host.\n * This is useful in placeholder mode to inspect missing nodes and their preserved props.\n */\nexport function findMissingComponentNodes(\n rootNode: Node,\n registry?: ComponentRegistryLike,\n knownTypes?: string[] | Set<string>,\n): MissingComponentNodeInfo[] {\n const missing: MissingComponentNodeInfo[] = [];\n const knownSet = new Set<string>();\n\n if (knownTypes) {\n for (const t of knownTypes) knownSet.add(t);\n }\n\n const standardBuiltIns = [\n 'page',\n 'section',\n 'container',\n 'columns',\n 'heading',\n 'text',\n 'image',\n 'button',\n 'collection',\n ];\n for (const b of standardBuiltIns) knownSet.add(b);\n\n function checkNode(node: Node): void {\n let isSupported = knownSet.has(node.type);\n if (!isSupported && registry) {\n isSupported = registry.has(node.type);\n }\n\n if (!isSupported) {\n missing.push({\n nodeId: node.id,\n componentType: node.type,\n props: node.props ? { ...node.props } : {},\n node,\n });\n }\n\n if (node.children && Array.isArray(node.children)) {\n for (const child of node.children) {\n checkNode(child);\n }\n }\n }\n\n checkNode(rootNode);\n return missing;\n}\n\n\n","import { Node, collectNodeIds } from '@kubuild/schema';\n\n/**\n * Deep clone an object immutably (JSON-safe).\n */\nexport function deepClone<T>(val: T): T {\n return JSON.parse(JSON.stringify(val));\n}\n\nexport interface NodeLocation {\n node: Node;\n parent: Node | null;\n index: number;\n}\n\n/**\n * Find a node, its parent, and index within the parent's children array.\n */\nexport function findNodeLocation(root: Node, targetId: string): NodeLocation | null {\n if (root.id === targetId) {\n return {\n node: root,\n parent: null,\n index: -1,\n };\n }\n\n return searchNodeLocationRecursive(root, targetId);\n}\n\nfunction searchNodeLocationRecursive(currentParent: Node, targetId: string): NodeLocation | null {\n if (!currentParent.children || currentParent.children.length === 0) {\n return null;\n }\n\n for (let i = 0; i < currentParent.children.length; i++) {\n const child = currentParent.children[i];\n if (child.id === targetId) {\n return {\n node: child,\n parent: currentParent,\n index: i,\n };\n }\n\n const foundInSubtree = searchNodeLocationRecursive(child, targetId);\n if (foundInSubtree) {\n return foundInSubtree;\n }\n }\n\n return null;\n}\n\nexport type NavigationDirection = 'parent' | 'child' | 'previous-sibling' | 'next-sibling';\n\n/**\n * Resolve the node id reached by moving from `nodeId` in a tree-navigation direction.\n * Returns null when there is nowhere to go (e.g. root has no parent, a leaf has no child,\n * or the node sits at the start/end of its sibling list).\n */\nexport function getNavigationTarget(\n root: Node,\n nodeId: string,\n direction: NavigationDirection,\n): string | null {\n const location = findNodeLocation(root, nodeId);\n if (!location) return null;\n\n switch (direction) {\n case 'parent':\n return location.parent?.id ?? null;\n case 'child':\n return location.node.children?.[0]?.id ?? null;\n case 'previous-sibling': {\n if (!location.parent) return null;\n return (location.parent.children ?? [])[location.index - 1]?.id ?? null;\n }\n case 'next-sibling': {\n if (!location.parent) return null;\n return (location.parent.children ?? [])[location.index + 1]?.id ?? null;\n }\n }\n}\n\n/**\n * Returns the chain of ancestor node ids from the root down to (but excluding)\n * `targetId`, root first. Returns [] if targetId is the root or is not found.\n */\nexport function getAncestorChain(root: Node, targetId: string): string[] {\n if (root.id === targetId) return [];\n\n function walk(node: Node, acc: string[]): string[] | null {\n if (!node.children) return null;\n for (const child of node.children) {\n if (child.id === targetId) return acc;\n const found = walk(child, [...acc, child.id]);\n if (found) return found;\n }\n return null;\n }\n\n return walk(root, [root.id]) ?? [];\n}\n\n/**\n * STORA-232: Find the direct parent node of `targetId` in a single O(N) traversal.\n * Returns null when the target is the root or is not found in the tree.\n */\nexport function getParentNodeId(root: Node, targetId: string): string | null {\n if (root.id === targetId) return null;\n\n const stack: Node[] = [root];\n while (stack.length > 0) {\n const current = stack.pop()!;\n const children = current.children;\n if (!children) continue;\n for (const child of children) {\n if (child.id === targetId) return current.id;\n stack.push(child);\n }\n }\n return null;\n}\n\n/**\n * STORA-232: Return the full ancestor path of `targetId` as an array of nodes,\n * ordered from the root down to (and including) the target node itself.\n * Single O(N) traversal: the path is tracked during descent, so no re-walks.\n * Returns [] when the target is not found.\n */\nexport function getNodeAncestors(root: Node, targetId: string): Node[] {\n const path: Node[] = [];\n\n function walk(node: Node): boolean {\n path.push(node);\n if (node.id === targetId) return true;\n if (node.children) {\n for (const child of node.children) {\n if (walk(child)) return true;\n }\n }\n path.pop();\n return false;\n }\n\n return walk(root) ? path : [];\n}\n\n/**\n * Check whether `targetId` is a descendant of `ancestorNode` (or equal to ancestorNode.id).\n */\nexport function isDescendantOf(ancestorNode: Node, targetId: string): boolean {\n if (ancestorNode.id === targetId) {\n return true;\n }\n\n if (!ancestorNode.children || ancestorNode.children.length === 0) {\n return false;\n }\n\n for (const child of ancestorNode.children) {\n if (isDescendantOf(child, targetId)) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Collect all node IDs present in a node subtree as a Set.\n */\nexport function collectNodeIdSet(root: Node): Set<string> {\n return new Set(collectNodeIds(root));\n}\n\n/**\n * Default unique ID generator function for node duplication.\n */\nexport function defaultIdGenerator(oldId: string, existingIds?: Set<string>): string {\n // Strip existing suffix like _copy or _copy_1 if exists\n const baseName = oldId.replace(/_copy(_\\d+)?$/, '');\n let candidate = `${baseName}_copy`;\n let counter = 1;\n\n if (existingIds) {\n while (existingIds.has(candidate)) {\n candidate = `${baseName}_copy_${counter}`;\n counter++;\n }\n existingIds.add(candidate);\n }\n\n return candidate;\n}\n\nexport interface ClonedSubtreeResult {\n clonedNode: Node;\n idMap: Map<string, string>; // oldId -> newId\n}\n\n/**\n * Recursively clone a node and its entire subtree, generating fresh unique IDs\n * for every node while preserving types, props, and responsive styles.\n */\nexport function cloneTreeWithNewIds(\n root: Node,\n idGenerator?: (oldId: string) => string,\n existingIds?: Set<string>,\n): ClonedSubtreeResult {\n const idMap = new Map<string, string>();\n const idGen = idGenerator || ((oldId: string) => defaultIdGenerator(oldId, existingIds));\n\n function cloneRecursive(node: Node): Node {\n const newId = idGen(node.id);\n idMap.set(node.id, newId);\n\n const clonedProps = node.props ? deepClone(node.props) : undefined;\n const clonedStyles = node.styles ? deepClone(node.styles) : undefined;\n const clonedChildren = node.children\n ? node.children.map((child) => cloneRecursive(child))\n : [];\n\n return {\n id: newId,\n type: node.type,\n ...(clonedProps ? { props: clonedProps } : {}),\n ...(clonedStyles ? { styles: clonedStyles } : {}),\n children: clonedChildren,\n };\n }\n\n const clonedNode = cloneRecursive(root);\n return { clonedNode, idMap };\n}\n","import {\n PageDocument,\n Node,\n ResponsiveStyles,\n StyleDefinition,\n StyleDefinitionSchema,\n ResponsiveStylesSchema,\n AnimationConfig,\n AnimationConfigSchema,\n ActionPipeline,\n ActionPipelineSchema,\n FormConfig,\n FormConfigSchema,\n} from '@kubuild/schema';\nimport {\n deepClone,\n findNodeLocation,\n isDescendantOf,\n collectNodeIdSet,\n cloneTreeWithNewIds,\n} from './command-tree-utils';\n\nexport type DocumentChangeType =\n | 'NODE_INSERTED'\n | 'NODE_MOVED'\n | 'PROPS_UPDATED'\n | 'STYLE_UPDATED'\n | 'ANIMATION_UPDATED'\n | 'ACTIONS_UPDATED'\n | 'FORM_CONFIG_UPDATED'\n | 'NODE_REMOVED'\n | 'NODE_DUPLICATED'\n | 'NODE_WRAPPED'\n | 'NODE_UNGROUPED'\n | 'NODE_REPLACED';\n\nexport interface DocumentChangeEvent {\n type: DocumentChangeType;\n timestamp: string;\n nodeId: string;\n parentId?: string;\n previousParentId?: string;\n index?: number;\n previousIndex?: number;\n payload?: Record<string, unknown>;\n}\n\nexport interface CommandResult {\n document: PageDocument;\n event: DocumentChangeEvent;\n}\n\nexport interface InsertNodeParams {\n parentId: string;\n node: Node;\n index?: number;\n}\n\nexport interface MoveNodeParams {\n nodeId: string;\n targetParentId: string;\n index?: number;\n}\n\nexport interface UpdatePropsParams {\n nodeId: string;\n props: Record<string, unknown>;\n /**\n * If true (default), shallow merges new props with existing props.\n * If false, replaces the entire props object.\n */\n merge?: boolean;\n}\n\nexport interface UpdateStyleParams {\n nodeId: string;\n styles: ResponsiveStyles | StyleDefinition;\n /**\n * Target breakpoint to update directly, or if omitted, applies to whole ResponsiveStyles structure.\n */\n breakpoint?: 'base' | 'desktop' | 'tablet' | 'mobile';\n /**\n * Target pseudo-state layer (e.g. ':hover', ':active', ':focus') — STORA-221.\n * When set, `styles` is written to `node.styles.states[state]` instead of a\n * breakpoint layer, leaving default (breakpoint) values untouched.\n */\n state?: string;\n /**\n * If true (default), shallow merges style definitions at target breakpoint.\n * If false, replaces the style definition object.\n */\n merge?: boolean;\n}\n\nexport interface RemoveNodeParams {\n nodeId: string;\n}\n\nexport interface DuplicateNodeParams {\n nodeId: string;\n targetParentId?: string;\n index?: number;\n idGenerator?: (oldId: string) => string;\n}\n\nexport interface WrapNodeIntoFrameParams {\n /** Single node ID to wrap into a frame. */\n nodeId?: string;\n /** Multiple node IDs to wrap into a frame. */\n nodeIds?: string[] | string;\n /** Optional custom ID for the created flex frame container. */\n frameId?: string;\n /** Optional custom props for the flex frame container. */\n frameProps?: Record<string, unknown>;\n /** Optional custom responsive styles for the flex frame container. */\n frameStyles?: ResponsiveStyles;\n}\n\nexport interface UngroupNodeFrameParams {\n /** Node ID of the flex container to unwrap. */\n nodeId: string;\n}\n\nexport interface ReplaceNodeParams {\n /** ID of the existing node to replace. */\n nodeId: string;\n /** Full replacement node — its `id` must match `nodeId` (identity is never silently changed). */\n node: Node;\n}\n\n/**\n * 1. Insert a node into a target parent node.\n * Returns a new PageDocument and a NODE_INSERTED event.\n */\nexport function insertNode(\n document: PageDocument,\n params: InsertNodeParams,\n): CommandResult {\n const { parentId, node, index } = params;\n\n if (!node || typeof node !== 'object' || !node.id || !node.type) {\n throw new Error('Invalid node: Node must be an object with non-empty \"id\" and \"type\"');\n }\n\n const newDoc = deepClone(document);\n const existingIds = collectNodeIdSet(newDoc.document);\n\n // Check duplicate ID\n const incomingIds = collectNodeIdSet(node);\n for (const incId of incomingIds) {\n if (existingIds.has(incId)) {\n throw new Error(`Cannot insert node: Duplicate node ID \"${incId}\" already exists in document.`);\n }\n }\n\n const parentLoc = findNodeLocation(newDoc.document, parentId);\n if (!parentLoc) {\n throw new Error(`Cannot insert node: Target parent node with ID \"${parentId}\" not found.`);\n }\n\n const parentNode = parentLoc.node;\n if (!parentNode.children) {\n parentNode.children = [];\n }\n\n const insertIndex =\n typeof index === 'number' && index >= 0 && index <= parentNode.children.length\n ? index\n : parentNode.children.length;\n\n parentNode.children.splice(insertIndex, 0, deepClone(node));\n\n return {\n document: newDoc,\n event: {\n type: 'NODE_INSERTED',\n timestamp: new Date().toISOString(),\n nodeId: node.id,\n parentId,\n index: insertIndex,\n payload: {\n nodeType: node.type,\n },\n },\n };\n}\n\n/**\n * 2. Move a node from its current location to a new parent location.\n * Prevents moving the root node or moving a node into its own descendant tree.\n * Returns a new PageDocument and a NODE_MOVED event.\n */\nexport function moveNode(\n document: PageDocument,\n params: MoveNodeParams,\n): CommandResult {\n const { nodeId, targetParentId, index } = params;\n\n if (nodeId === document.document.id) {\n throw new Error('Cannot move the root page node.');\n }\n\n const newDoc = deepClone(document);\n\n const sourceLoc = findNodeLocation(newDoc.document, nodeId);\n if (!sourceLoc || !sourceLoc.parent) {\n throw new Error(`Cannot move node: Node with ID \"${nodeId}\" not found in document.`);\n }\n\n const targetLoc = findNodeLocation(newDoc.document, targetParentId);\n if (!targetLoc) {\n throw new Error(`Cannot move node: Target parent with ID \"${targetParentId}\" not found in document.`);\n }\n\n // Descendant cycle check: Cannot move node into itself or any of its descendants\n if (isDescendantOf(sourceLoc.node, targetParentId)) {\n throw new Error(\n `Cannot move node: Target parent \"${targetParentId}\" is the node itself or a descendant of node \"${nodeId}\".`,\n );\n }\n\n const previousParentId = sourceLoc.parent.id;\n const previousIndex = sourceLoc.index;\n\n // Remove node from source parent\n const [removedNode] = sourceLoc.parent.children!.splice(previousIndex, 1);\n\n // Target parent might be the same parent or different parent\n const targetParent = targetLoc.node;\n if (!targetParent.children) {\n targetParent.children = [];\n }\n\n let targetIndex =\n typeof index === 'number' && index >= 0 && index <= targetParent.children.length\n ? index\n : targetParent.children.length;\n\n targetParent.children.splice(targetIndex, 0, removedNode);\n\n return {\n document: newDoc,\n event: {\n type: 'NODE_MOVED',\n timestamp: new Date().toISOString(),\n nodeId,\n parentId: targetParentId,\n previousParentId,\n index: targetIndex,\n previousIndex,\n },\n };\n}\n\n/**\n * 3. Update the props of an existing node.\n * Returns a new PageDocument and a PROPS_UPDATED event.\n */\nexport function updateProps(\n document: PageDocument,\n params: UpdatePropsParams,\n): CommandResult {\n const { nodeId, props, merge = true } = params;\n\n if (!props || typeof props !== 'object' || Array.isArray(props)) {\n throw new Error('Props must be an object.');\n }\n\n const newDoc = deepClone(document);\n const loc = findNodeLocation(newDoc.document, nodeId);\n if (!loc) {\n throw new Error(`Cannot update props: Node with ID \"${nodeId}\" not found in document.`);\n }\n\n const targetNode = loc.node;\n const previousProps = targetNode.props ? deepClone(targetNode.props) : {};\n\n if (merge) {\n targetNode.props = {\n ...previousProps,\n ...deepClone(props),\n };\n for (const key of Object.keys(props)) {\n if (props[key] === undefined) {\n delete targetNode.props[key];\n }\n }\n } else {\n targetNode.props = deepClone(props);\n }\n\n return {\n document: newDoc,\n event: {\n type: 'PROPS_UPDATED',\n timestamp: new Date().toISOString(),\n nodeId,\n parentId: loc.parent ? loc.parent.id : undefined,\n payload: {\n props: targetNode.props,\n previousProps,\n },\n },\n };\n}\n\n/**\n * 4. Update the responsive styles of an existing node.\n * Supports updating a specific breakpoint ('base', 'desktop', etc.) or the whole ResponsiveStyles object.\n * Returns a new PageDocument and a STYLE_UPDATED event.\n */\nexport function updateStyle(\n document: PageDocument,\n params: UpdateStyleParams,\n): CommandResult {\n const { nodeId, styles, breakpoint, state, merge = true } = params;\n\n if (!styles || typeof styles !== 'object' || Array.isArray(styles)) {\n throw new Error('Styles must be an object.');\n }\n\n const newDoc = deepClone(document);\n const loc = findNodeLocation(newDoc.document, nodeId);\n if (!loc) {\n throw new Error(`Cannot update style: Node with ID \"${nodeId}\" not found in document.`);\n }\n\n const targetNode = loc.node;\n const currentStyles: ResponsiveStyles = targetNode.styles ? deepClone(targetNode.styles) : {};\n const previousStyles = deepClone(currentStyles);\n\n if (state) {\n // Pseudo-state layer update (STORA-221): writes into styles.states[state]\n // without touching default breakpoint values. Parsed through\n // StyleDefinitionSchema so unsafe values are rejected here too.\n const newBreakpointStyles = StyleDefinitionSchema.parse(styles);\n const states = { ...(currentStyles.states ?? {}) };\n const currentStateStyles = states[state] ?? {};\n\n if (merge) {\n states[state] = { ...currentStateStyles, ...deepClone(newBreakpointStyles) };\n } else {\n states[state] = deepClone(newBreakpointStyles);\n }\n\n targetNode.styles = { ...currentStyles, states } as ResponsiveStyles;\n\n return {\n document: newDoc,\n event: {\n type: 'STYLE_UPDATED',\n timestamp: new Date().toISOString(),\n nodeId,\n parentId: loc.parent ? loc.parent.id : undefined,\n payload: {\n styles: targetNode.styles,\n previousStyles,\n state,\n },\n },\n };\n }\n\n if (breakpoint) {\n // Updating a single breakpoint style definition. Parsed through\n // StyleDefinitionSchema so unsafe/non-serializable values (STORA-023)\n // are rejected here too, not just at document-parse time.\n const currentBreakpointStyles = (currentStyles[breakpoint] as StyleDefinition) || {};\n const newBreakpointStyles = StyleDefinitionSchema.parse(styles);\n\n if (merge) {\n currentStyles[breakpoint] = {\n ...currentBreakpointStyles,\n ...deepClone(newBreakpointStyles),\n };\n } else {\n currentStyles[breakpoint] = deepClone(newBreakpointStyles);\n }\n } else {\n // Updating responsive styles container\n const responsiveStylesInput = ResponsiveStylesSchema.parse(styles);\n if (merge) {\n for (const bp of ['base', 'desktop', 'tablet', 'mobile'] as const) {\n if (responsiveStylesInput[bp] !== undefined) {\n const currentBp = (currentStyles[bp] as StyleDefinition) || {};\n const incomingBp = (responsiveStylesInput[bp] as StyleDefinition) || {};\n currentStyles[bp] = {\n ...currentBp,\n ...deepClone(incomingBp),\n };\n }\n }\n } else {\n targetNode.styles = deepClone(responsiveStylesInput);\n return {\n document: newDoc,\n event: {\n type: 'STYLE_UPDATED',\n timestamp: new Date().toISOString(),\n nodeId,\n parentId: loc.parent ? loc.parent.id : undefined,\n payload: {\n styles: targetNode.styles,\n previousStyles,\n },\n },\n };\n }\n }\n\n targetNode.styles = currentStyles;\n\n return {\n document: newDoc,\n event: {\n type: 'STYLE_UPDATED',\n timestamp: new Date().toISOString(),\n nodeId,\n parentId: loc.parent ? loc.parent.id : undefined,\n payload: {\n styles: currentStyles,\n previousStyles,\n breakpoint,\n },\n },\n };\n}\n\n/**\n * 5. Remove a node from the document tree.\n * Prevents removing the root page node.\n * Returns a new PageDocument and a NODE_REMOVED event.\n */\nexport function removeNode(\n document: PageDocument,\n params: RemoveNodeParams,\n): CommandResult {\n const { nodeId } = params;\n\n if (nodeId === document.document.id) {\n throw new Error('Cannot remove the root page node.');\n }\n\n const newDoc = deepClone(document);\n const loc = findNodeLocation(newDoc.document, nodeId);\n if (!loc || !loc.parent) {\n throw new Error(`Cannot remove node: Node with ID \"${nodeId}\" not found in document.`);\n }\n\n const parentId = loc.parent.id;\n const index = loc.index;\n\n const [removedNode] = loc.parent.children!.splice(index, 1);\n\n return {\n document: newDoc,\n event: {\n type: 'NODE_REMOVED',\n timestamp: new Date().toISOString(),\n nodeId,\n parentId,\n index,\n payload: {\n node: removedNode,\n },\n },\n };\n}\n\n/**\n * 6. Duplicate a node and its entire subtree.\n * Generates fresh unique IDs for all cloned nodes in the subtree, preserves props/styles,\n * and inserts the duplicate right after the original node (or at specified targetParentId/index).\n * Returns a new PageDocument and a NODE_DUPLICATED event.\n */\nexport function duplicateNode(\n document: PageDocument,\n params: DuplicateNodeParams,\n): CommandResult {\n const { nodeId, targetParentId, index, idGenerator } = params;\n\n if (nodeId === document.document.id) {\n throw new Error('Cannot duplicate the root page node.');\n }\n\n const newDoc = deepClone(document);\n const loc = findNodeLocation(newDoc.document, nodeId);\n if (!loc || !loc.parent) {\n throw new Error(`Cannot duplicate node: Node with ID \"${nodeId}\" not found in document.`);\n }\n\n const existingIds = collectNodeIdSet(newDoc.document);\n const { clonedNode, idMap } = cloneTreeWithNewIds(loc.node, idGenerator, existingIds);\n\n const destinationParentId = targetParentId || loc.parent.id;\n const destParentLoc = findNodeLocation(newDoc.document, destinationParentId);\n if (!destParentLoc) {\n throw new Error(`Cannot duplicate node: Destination parent \"${destinationParentId}\" not found.`);\n }\n\n const destParent = destParentLoc.node;\n if (!destParent.children) {\n destParent.children = [];\n }\n\n // Default insertion position is right after the source node if in same parent, else appended\n let insertIndex: number;\n if (typeof index === 'number' && index >= 0 && index <= destParent.children.length) {\n insertIndex = index;\n } else if (destinationParentId === loc.parent.id) {\n insertIndex = loc.index + 1;\n } else {\n insertIndex = destParent.children.length;\n }\n\n destParent.children.splice(insertIndex, 0, clonedNode);\n\n return {\n document: newDoc,\n event: {\n type: 'NODE_DUPLICATED',\n timestamp: new Date().toISOString(),\n nodeId: clonedNode.id,\n parentId: destinationParentId,\n index: insertIndex,\n payload: {\n originalNodeId: nodeId,\n idMap: Object.fromEntries(idMap.entries()),\n },\n },\n };\n}\n\nexport interface UpdateAnimationParams {\n nodeId: string;\n animation: Partial<AnimationConfig> | null;\n /**\n * If true (default), shallow merges new animation properties with existing animation config.\n * If false, replaces the animation config with the provided object.\n * If animation is null, removes the animation configuration from the node.\n */\n merge?: boolean;\n}\n\n/**\n * 7. Update the animation configuration of an existing node.\n * Returns a new PageDocument and an ANIMATION_UPDATED event.\n */\nexport function updateAnimation(\n document: PageDocument,\n params: UpdateAnimationParams,\n): CommandResult {\n const { nodeId, animation, merge = true } = params;\n\n const newDoc = deepClone(document);\n const loc = findNodeLocation(newDoc.document, nodeId);\n if (!loc) {\n throw new Error(`Cannot update animation: Node with ID \"${nodeId}\" not found in document.`);\n }\n\n const targetNode = loc.node;\n const previousAnimation = targetNode.animation ? deepClone(targetNode.animation) : undefined;\n\n if (animation === null) {\n delete targetNode.animation;\n } else {\n const currentAnimation = targetNode.animation ? deepClone(targetNode.animation) : {};\n const candidate = merge\n ? { ...currentAnimation, ...deepClone(animation) }\n : deepClone(animation);\n targetNode.animation = AnimationConfigSchema.parse(candidate);\n }\n\n return {\n document: newDoc,\n event: {\n type: 'ANIMATION_UPDATED',\n timestamp: new Date().toISOString(),\n nodeId,\n parentId: loc.parent ? loc.parent.id : undefined,\n payload: {\n animation: targetNode.animation,\n previousAnimation,\n },\n },\n };\n}\n\nexport interface UpdateActionsParams {\n nodeId: string;\n actions: ActionPipeline[] | null;\n}\n\n/**\n * 8. Update the action pipelines of an existing node.\n * Returns a new PageDocument and an ACTIONS_UPDATED event.\n */\nexport function updateActions(\n document: PageDocument,\n params: UpdateActionsParams,\n): CommandResult {\n const { nodeId, actions } = params;\n\n const newDoc = deepClone(document);\n const loc = findNodeLocation(newDoc.document, nodeId);\n if (!loc) {\n throw new Error(`Cannot update actions: Node with ID \"${nodeId}\" not found in document.`);\n }\n\n const targetNode = loc.node;\n const previousActions = targetNode.actions ? deepClone(targetNode.actions) : undefined;\n\n if (actions === null || (Array.isArray(actions) && actions.length === 0)) {\n delete targetNode.actions;\n } else {\n targetNode.actions = ActionPipelineSchema.array().parse(actions);\n }\n\n return {\n document: newDoc,\n event: {\n type: 'ACTIONS_UPDATED',\n timestamp: new Date().toISOString(),\n nodeId,\n parentId: loc.parent ? loc.parent.id : undefined,\n payload: {\n actions: targetNode.actions,\n previousActions,\n },\n },\n };\n}\n\nexport interface UpdateFormConfigParams {\n nodeId: string;\n formConfig: Partial<FormConfig> | null;\n /**\n * If true (default), shallow merges new formConfig properties with existing config.\n * If false, replaces the formConfig with the provided object.\n * If formConfig is null, removes the form configuration from the node.\n */\n merge?: boolean;\n}\n\n/**\n * 9. Update the form configuration of an existing node.\n * Returns a new PageDocument and a FORM_CONFIG_UPDATED event.\n */\nexport function updateFormConfig(\n document: PageDocument,\n params: UpdateFormConfigParams,\n): CommandResult {\n const { nodeId, formConfig, merge = true } = params;\n\n const newDoc = deepClone(document);\n const loc = findNodeLocation(newDoc.document, nodeId);\n if (!loc) {\n throw new Error(`Cannot update formConfig: Node with ID \"${nodeId}\" not found in document.`);\n }\n\n const targetNode = loc.node;\n const previousFormConfig = targetNode.formConfig ? deepClone(targetNode.formConfig) : undefined;\n\n if (formConfig === null) {\n delete targetNode.formConfig;\n } else {\n const currentFormConfig = targetNode.formConfig ? deepClone(targetNode.formConfig) : { formId: nodeId };\n const candidate = merge\n ? { ...currentFormConfig, ...deepClone(formConfig) }\n : deepClone(formConfig);\n if (!candidate.formId) {\n candidate.formId = nodeId;\n }\n targetNode.formConfig = FormConfigSchema.parse(candidate);\n }\n\n return {\n document: newDoc,\n event: {\n type: 'FORM_CONFIG_UPDATED',\n timestamp: new Date().toISOString(),\n nodeId,\n parentId: loc.parent ? loc.parent.id : undefined,\n payload: {\n formConfig: targetNode.formConfig,\n previousFormConfig,\n },\n },\n };\n}\n\n/**\n * 10. Wrap specified node(s) into a new flex container node at the same position in the parent.\n * Preserves sibling ordering and returns a new PageDocument and a NODE_WRAPPED event.\n * Full undo/redo compatibility with DocumentHistoryManager. (STORA-105)\n */\nexport function wrapNodeIntoFrame(\n document: PageDocument,\n params: WrapNodeIntoFrameParams,\n): CommandResult {\n const rawIds =\n params.nodeIds !== undefined\n ? Array.isArray(params.nodeIds)\n ? params.nodeIds\n : [params.nodeIds]\n : params.nodeId\n ? [params.nodeId]\n : [];\n\n const targetIds = Array.from(\n new Set(rawIds.filter((id): id is string => typeof id === 'string' && id.trim().length > 0)),\n );\n\n if (targetIds.length === 0) {\n throw new Error('Cannot wrap nodes: At least one node ID must be provided.');\n }\n\n // Prevent wrapping the root page node\n if (targetIds.includes(document.document.id)) {\n throw new Error('Cannot wrap the root page node.');\n }\n\n const newDoc = deepClone(document);\n\n // Locate all target nodes in the tree\n const locations: Array<{ node: Node; parent: Node; index: number }> = [];\n for (const id of targetIds) {\n const loc = findNodeLocation(newDoc.document, id);\n if (!loc || !loc.parent) {\n throw new Error(`Cannot wrap node: Node with ID \"${id}\" not found in document.`);\n }\n locations.push(loc as { node: Node; parent: Node; index: number });\n }\n\n // Verify all target nodes share the exact same parent container\n const parentId = locations[0].parent.id;\n const parentNode = locations[0].parent;\n for (const loc of locations) {\n if (loc.parent.id !== parentId) {\n throw new Error('Cannot wrap nodes: All nodes must share the same parent container.');\n }\n }\n\n // Determine frame ID\n const existingIds = collectNodeIdSet(newDoc.document);\n let frameId = params.frameId;\n if (frameId) {\n if (existingIds.has(frameId)) {\n throw new Error(`Cannot wrap nodes: Node ID \"${frameId}\" already exists in document.`);\n }\n } else {\n let counter = 1;\n while (existingIds.has(`flex_${counter}`)) {\n counter++;\n }\n frameId = `flex_${counter}`;\n }\n\n // Sort locations by their index in the parent to preserve original sibling order\n locations.sort((a, b) => a.index - b.index);\n\n // The insertion position in the parent is the index of the first node being wrapped\n const minIndex = locations[0].index;\n const wrappedNodes = locations.map((loc) => loc.node);\n\n // Remove the target nodes from the parent's children\n const targetIdSet = new Set(targetIds);\n parentNode.children = (parentNode.children || []).filter((child) => !targetIdSet.has(child.id));\n\n // Default flex container styles (STORA-102)\n const defaultFlexStyles: ResponsiveStyles = {\n base: {\n display: 'flex',\n flexDirection: 'column',\n gap: '16px',\n },\n };\n\n const frameNode: Node = {\n id: frameId,\n type: 'flex',\n props: deepClone(params.frameProps || {}),\n styles: deepClone(params.frameStyles || defaultFlexStyles),\n children: wrappedNodes,\n };\n\n // Insert the frame node into the parent at minIndex\n const insertIndex = Math.min(minIndex, parentNode.children.length);\n parentNode.children.splice(insertIndex, 0, frameNode);\n\n return {\n document: newDoc,\n event: {\n type: 'NODE_WRAPPED',\n timestamp: new Date().toISOString(),\n nodeId: frameId,\n parentId,\n index: insertIndex,\n payload: {\n wrappedNodeIds: targetIds,\n frameNode: deepClone(frameNode),\n },\n },\n };\n}\n\n/**\n * 11. Unwrap a flex frame container, moving all of its children to its parent at its position,\n * and removing the container.\n * Returns a new PageDocument and a NODE_UNGROUPED event.\n * Full undo/redo compatibility with DocumentHistoryManager. (STORA-106)\n */\nexport function ungroupNodeFrame(\n document: PageDocument,\n params: UngroupNodeFrameParams,\n): CommandResult {\n const { nodeId } = params;\n\n if (!nodeId || typeof nodeId !== 'string' || nodeId.trim().length === 0) {\n throw new Error('Invalid nodeId: Node ID must be a non-empty string.');\n }\n\n if (nodeId === document.document.id) {\n throw new Error('Cannot ungroup the root page node.');\n }\n\n const newDoc = deepClone(document);\n const loc = findNodeLocation(newDoc.document, nodeId);\n if (!loc || !loc.parent) {\n throw new Error(`Cannot ungroup node: Node with ID \"${nodeId}\" not found in document.`);\n }\n\n const targetNode = loc.node;\n const parentNode = loc.parent;\n const targetIndex = loc.index;\n\n // Verify that the node is a flex container\n if (targetNode.type !== 'flex') {\n throw new Error(`Cannot ungroup node: Node \"${nodeId}\" is not a flex container (type is \"${targetNode.type}\").`);\n }\n\n const unwrappedChildren = targetNode.children ? deepClone(targetNode.children) : [];\n\n if (!parentNode.children) {\n parentNode.children = [];\n }\n\n // Replace the frame container at targetIndex with all of its children in place\n parentNode.children.splice(targetIndex, 1, ...unwrappedChildren);\n\n return {\n document: newDoc,\n event: {\n type: 'NODE_UNGROUPED',\n timestamp: new Date().toISOString(),\n nodeId,\n parentId: parentNode.id,\n index: targetIndex,\n payload: {\n unwrappedChildIds: unwrappedChildren.map((c) => c.id),\n unwrappedChildren,\n removedNode: deepClone(targetNode),\n },\n },\n };\n}\n\n/**\n * 12. Replace an existing node's entire subtree (props, styles, children, animation,\n * actions, formConfig) in place, preserving its position in the parent.\n *\n * Used by AI \"enhance\" flows (STORA-514) when a validated candidate node differs\n * structurally from the original (e.g. AI regenerated nested children) — a change\n * `updateProps`/`updateStyle` alone can't express since they only ever touch one\n * property bag at a time. The replacement node's `id` must match `nodeId`; this command\n * never lets identity (id) drift, the same guarantee `@kubuild/ai`'s\n * `normalizeAndValidateRefactoredNode` already enforces upstream on `type`/`id`.\n *\n * Returns a new PageDocument and a NODE_REPLACED event.\n */\nexport function replaceNode(\n document: PageDocument,\n params: ReplaceNodeParams,\n): CommandResult {\n const { nodeId, node } = params;\n\n if (!node || typeof node !== 'object' || !node.id || !node.type) {\n throw new Error('Invalid node: Node must be an object with non-empty \"id\" and \"type\"');\n }\n\n if (node.id !== nodeId) {\n throw new Error(\n `Cannot replace node: replacement node id \"${node.id}\" must match target node id \"${nodeId}\".`,\n );\n }\n\n if (nodeId === document.document.id) {\n throw new Error('Cannot replace the root page node.');\n }\n\n const newDoc = deepClone(document);\n const loc = findNodeLocation(newDoc.document, nodeId);\n if (!loc || !loc.parent) {\n throw new Error(`Cannot replace node: Node with ID \"${nodeId}\" not found in document.`);\n }\n\n // A replacement subtree may introduce ids that collide with the rest of the document\n // (outside the subtree being replaced) — reject rather than silently corrupting ids.\n const existingIds = collectNodeIdSet(newDoc.document);\n for (const id of collectNodeIdSet(loc.node)) {\n existingIds.delete(id);\n }\n for (const incomingId of collectNodeIdSet(node)) {\n if (existingIds.has(incomingId)) {\n throw new Error(\n `Cannot replace node: Duplicate node ID \"${incomingId}\" already exists elsewhere in document.`,\n );\n }\n }\n\n const previousNode = deepClone(loc.node);\n const replacement = deepClone(node);\n loc.parent.children![loc.index] = replacement;\n\n return {\n document: newDoc,\n event: {\n type: 'NODE_REPLACED',\n timestamp: new Date().toISOString(),\n nodeId,\n parentId: loc.parent.id,\n index: loc.index,\n payload: {\n node: replacement,\n previousNode,\n },\n },\n };\n}\n\n","import {\n Artboard,\n ArtboardType,\n Node,\n PageDocument,\n ProjectDocument,\n SCHEMA_NAME,\n PROJECT_SCHEMA_NAME,\n CURRENT_PROJECT_SCHEMA_VERSION,\n CURRENT_SCHEMA_VERSION,\n ARTBOARD_REFERENCE_NODE_TYPE,\n} from '@kubuild/schema';\nimport { deepClone, findNodeLocation, collectNodeIdSet } from './command-tree-utils';\nimport { createBlankDocument } from './document-utils';\n\nexport type ArtboardChangeType =\n | 'ARTBOARD_ADDED'\n | 'ARTBOARD_REMOVED'\n | 'ARTBOARD_RENAMED'\n | 'ACTIVE_ARTBOARD_CHANGED'\n | 'NODE_EXTRACTED_TO_ARTBOARD';\n\nexport interface ArtboardChangeEvent {\n type: ArtboardChangeType;\n timestamp: string;\n artboardId: string;\n /** Source artboard, for operations that move content between artboards. */\n sourceArtboardId?: string;\n nodeId?: string;\n payload?: Record<string, unknown>;\n}\n\n/**\n * Mirrors CommandResult from commands.ts, but at the project (multi-artboard) level.\n * Node-level commands keep returning CommandResult and keep operating on a single\n * PageDocument, unchanged.\n */\nexport interface ProjectCommandResult {\n project: ProjectDocument;\n event: ArtboardChangeEvent;\n}\n\nexport interface AddArtboardParams {\n artboard: Artboard;\n index?: number;\n /** Make the newly added artboard active (default: true). */\n activate?: boolean;\n}\n\nexport interface RemoveArtboardParams {\n artboardId: string;\n}\n\nexport interface RenameArtboardParams {\n artboardId: string;\n name: string;\n}\n\nexport interface SetActiveArtboardParams {\n artboardId: string;\n}\n\nexport interface ExtractNodeToArtboardParams {\n /** Artboard currently holding the node. */\n artboardId: string;\n /** Node whose subtree becomes the new artboard's content. */\n nodeId: string;\n /** Optional explicit name for the new artboard (defaults to the node type). */\n name?: string;\n /** Optional explicit id for the new artboard. */\n newArtboardId?: string;\n /** Make the new artboard active (default: false — authors usually keep editing the page). */\n activate?: boolean;\n}\n\nconst now = (): string => new Date().toISOString();\n\n/**\n * Collect every node id used anywhere in the project (across all artboards).\n * Node ids must be unique project-wide so that content can move between artboards\n * without silently colliding.\n */\nexport function collectProjectNodeIds(project: ProjectDocument): Set<string> {\n const ids = new Set<string>();\n for (const artboard of project.artboards) {\n for (const id of collectNodeIdSet(artboard.document.document)) {\n ids.add(id);\n }\n }\n return ids;\n}\n\nfunction uniqueId(prefix: string, taken: Set<string>): string {\n let counter = 1;\n while (taken.has(`${prefix}_${counter}`)) {\n counter++;\n }\n return `${prefix}_${counter}`;\n}\n\nexport function findArtboardById(\n project: ProjectDocument,\n artboardId: string,\n): Artboard | undefined {\n return project.artboards.find((artboard) => artboard.id === artboardId);\n}\n\n/**\n * Resolve the component artboard an `open_modal` / `close_modal` action targets.\n * ModalManager keys off plain strings, so a trigger in one artboard can address\n * content in another with no additional wiring.\n */\nexport function findArtboardByTriggerId(\n project: ProjectDocument,\n triggerId: string,\n): Artboard | undefined {\n if (!triggerId) return undefined;\n return project.artboards.find(\n (artboard) => artboard.artboardType === 'component' && artboard.triggerId === triggerId,\n );\n}\n\nexport function getActiveArtboard(project: ProjectDocument): Artboard | undefined {\n if (project.activeArtboardId) {\n const active = findArtboardById(project, project.activeArtboardId);\n if (active) return active;\n }\n return project.artboards[0];\n}\n\nexport function getPageArtboards(project: ProjectDocument): Artboard[] {\n return project.artboards.filter((artboard) => artboard.artboardType === 'page');\n}\n\nexport function getComponentArtboards(project: ProjectDocument): Artboard[] {\n return project.artboards.filter((artboard) => artboard.artboardType === 'component');\n}\n\nexport interface CreateArtboardOptions {\n id?: string;\n slug?: string;\n triggerId?: string;\n viewport?: Artboard['viewport'];\n width?: number;\n}\n\n/**\n * Build a page artboard around a fresh blank document.\n */\nexport function createPageArtboard(\n name = 'Untitled Page',\n options: CreateArtboardOptions = {},\n): Artboard {\n return {\n id: options.id ?? `artboard-page-${Date.now()}`,\n name,\n artboardType: 'page',\n slug: options.slug ?? '/',\n document: createBlankDocument(name),\n ...(options.viewport ? { viewport: options.viewport } : {}),\n ...(options.width !== undefined ? { width: options.width } : {}),\n };\n}\n\n/**\n * Wrap an existing node as the sole child of a synthetic `page` root and return it as a\n * component artboard. The synthetic root exists so each artboard's `document` stays a\n * fully valid PageDocument, meaning no existing command, validator, or history code\n * needs to know that component artboards exist at all.\n */\nexport function createComponentArtboard(\n node: Node,\n options: CreateArtboardOptions & { name?: string; rootId?: string } = {},\n): Artboard {\n const name = options.name ?? node.type;\n const triggerId =\n options.triggerId ??\n (typeof node.props?.modalId === 'string' && node.props.modalId.trim().length > 0\n ? (node.props.modalId as string)\n : node.id);\n\n const document: PageDocument = {\n schema: SCHEMA_NAME,\n version: CURRENT_SCHEMA_VERSION,\n metadata: {\n title: name,\n description: '',\n author: '',\n tags: [],\n category: 'component',\n version: CURRENT_SCHEMA_VERSION,\n createdAt: now(),\n updatedAt: now(),\n },\n document: {\n id: options.rootId ?? `${node.id}-artboard-root`,\n type: 'page',\n props: { title: name },\n // Transparent surface: a component artboard is a canvas for the node, not a page.\n styles: { base: { minHeight: 'auto', backgroundColor: 'transparent' } },\n children: [deepClone(node)],\n },\n };\n\n return {\n id: options.id ?? `artboard-component-${node.id}`,\n name,\n artboardType: 'component',\n triggerId,\n document,\n ...(options.viewport ? { viewport: options.viewport } : {}),\n ...(options.width !== undefined ? { width: options.width } : {}),\n };\n}\n\n/**\n * Create a project containing a single blank page artboard.\n */\nexport function createBlankProject(title = 'Untitled Page'): ProjectDocument {\n const artboard = createPageArtboard(title, { id: 'artboard-page-1' });\n return {\n schema: PROJECT_SCHEMA_NAME,\n version: CURRENT_PROJECT_SCHEMA_VERSION,\n metadata: artboard.document.metadata,\n artboards: [artboard],\n activeArtboardId: artboard.id,\n };\n}\n\nexport function addArtboard(\n project: ProjectDocument,\n params: AddArtboardParams,\n): ProjectCommandResult {\n const { artboard } = params;\n if (!artboard?.id) {\n throw new Error('Cannot add artboard: artboard must have an id.');\n }\n if (findArtboardById(project, artboard.id)) {\n throw new Error(`Cannot add artboard: id \"${artboard.id}\" already exists in the project.`);\n }\n\n const next = deepClone(project);\n const index = params.index ?? next.artboards.length;\n next.artboards.splice(Math.max(0, Math.min(index, next.artboards.length)), 0, deepClone(artboard));\n\n if (params.activate !== false) {\n next.activeArtboardId = artboard.id;\n }\n\n return {\n project: next,\n event: {\n type: 'ARTBOARD_ADDED',\n timestamp: now(),\n artboardId: artboard.id,\n payload: { artboardType: artboard.artboardType, index },\n },\n };\n}\n\nexport function removeArtboard(\n project: ProjectDocument,\n params: RemoveArtboardParams,\n): ProjectCommandResult {\n const { artboardId } = params;\n const existing = findArtboardById(project, artboardId);\n if (!existing) {\n throw new Error(`Cannot remove artboard: id \"${artboardId}\" not found.`);\n }\n if (project.artboards.length === 1) {\n throw new Error('Cannot remove artboard: a project must keep at least one artboard.');\n }\n\n const next = deepClone(project);\n next.artboards = next.artboards.filter((artboard) => artboard.id !== artboardId);\n\n if (next.activeArtboardId === artboardId) {\n next.activeArtboardId = next.artboards[0]?.id;\n }\n\n return {\n project: next,\n event: {\n type: 'ARTBOARD_REMOVED',\n timestamp: now(),\n artboardId,\n payload: { artboardType: existing.artboardType },\n },\n };\n}\n\nexport function renameArtboard(\n project: ProjectDocument,\n params: RenameArtboardParams,\n): ProjectCommandResult {\n const { artboardId, name } = params;\n if (!name || name.trim().length === 0) {\n throw new Error('Cannot rename artboard: name must be a non-empty string.');\n }\n const existing = findArtboardById(project, artboardId);\n if (!existing) {\n throw new Error(`Cannot rename artboard: id \"${artboardId}\" not found.`);\n }\n\n const next = deepClone(project);\n const target = findArtboardById(next, artboardId)!;\n const previousName = target.name;\n target.name = name;\n\n return {\n project: next,\n event: {\n type: 'ARTBOARD_RENAMED',\n timestamp: now(),\n artboardId,\n payload: { previousName, name },\n },\n };\n}\n\nexport function setActiveArtboard(\n project: ProjectDocument,\n params: SetActiveArtboardParams,\n): ProjectCommandResult {\n const { artboardId } = params;\n if (!findArtboardById(project, artboardId)) {\n throw new Error(`Cannot activate artboard: id \"${artboardId}\" not found.`);\n }\n\n const next = deepClone(project);\n const previousArtboardId = next.activeArtboardId;\n next.activeArtboardId = artboardId;\n\n return {\n project: next,\n event: {\n type: 'ACTIVE_ARTBOARD_CHANGED',\n timestamp: now(),\n artboardId,\n payload: { previousArtboardId },\n },\n };\n}\n\n/**\n * Detach a node's subtree into its own component artboard, leaving an\n * `artboard-reference` stub at the original position.\n *\n * The stub matters: selection, move/delete, copy/paste, the Layers panel, and history\n * diffing all walk nodes that are physically present in the tree, so a bare deletion would\n * leave the page with no visible, selectable anchor for \"this surface opens artboard X\"\n * and would strand the trigger's id with nothing pointing back at it.\n *\n * Undo scoping caveat (Phase 1): the editor's history is per-document, so this operation —\n * which spans two artboards — is applied as one atomic project-level step rather than being\n * finely undoable inside each artboard's own stack.\n */\nexport function extractNodeToArtboard(\n project: ProjectDocument,\n params: ExtractNodeToArtboardParams,\n): ProjectCommandResult {\n const { artboardId, nodeId } = params;\n\n const sourceArtboard = findArtboardById(project, artboardId);\n if (!sourceArtboard) {\n throw new Error(`Cannot extract node: artboard \"${artboardId}\" not found.`);\n }\n if (sourceArtboard.document.document.id === nodeId) {\n throw new Error('Cannot extract node: the artboard root cannot be detached.');\n }\n\n const next = deepClone(project);\n const workingArtboard = findArtboardById(next, artboardId)!;\n const location = findNodeLocation(workingArtboard.document.document, nodeId);\n if (!location || !location.parent) {\n throw new Error(`Cannot extract node: node \"${nodeId}\" not found in artboard \"${artboardId}\".`);\n }\n\n const { node, parent, index } = location as { node: Node; parent: Node; index: number };\n const extracted = deepClone(node);\n\n const takenNodeIds = collectProjectNodeIds(next);\n const takenArtboardIds = new Set(next.artboards.map((artboard) => artboard.id));\n\n const newArtboardId = params.newArtboardId ?? `artboard-component-${extracted.id}`;\n if (takenArtboardIds.has(newArtboardId)) {\n throw new Error(`Cannot extract node: artboard id \"${newArtboardId}\" already exists.`);\n }\n\n const componentArtboard = createComponentArtboard(extracted, {\n id: newArtboardId,\n name: params.name ?? extracted.type,\n rootId: uniqueId('artboard-root', takenNodeIds),\n viewport: sourceArtboard.viewport,\n });\n\n // Replace the node in place with a reference stub rather than deleting it outright.\n const stub: Node = {\n id: uniqueId('artboard_ref', takenNodeIds),\n type: ARTBOARD_REFERENCE_NODE_TYPE,\n props: {\n artboardId: componentArtboard.id,\n triggerId: componentArtboard.triggerId,\n label: componentArtboard.name,\n },\n styles: {},\n children: [],\n };\n parent.children = parent.children || [];\n parent.children.splice(index, 1, stub);\n\n next.artboards.push(componentArtboard);\n if (params.activate) {\n next.activeArtboardId = componentArtboard.id;\n }\n\n return {\n project: next,\n event: {\n type: 'NODE_EXTRACTED_TO_ARTBOARD',\n timestamp: now(),\n artboardId: componentArtboard.id,\n sourceArtboardId: artboardId,\n nodeId: extracted.id,\n payload: {\n stubNodeId: stub.id,\n triggerId: componentArtboard.triggerId,\n artboardType: 'component' satisfies ArtboardType,\n },\n },\n };\n}\n\n/**\n * Replace one artboard's document wholesale. Used by the editor when committing the\n * single active PageDocument it holds back into the project.\n */\nexport function updateArtboardDocument(\n project: ProjectDocument,\n artboardId: string,\n document: PageDocument,\n): ProjectDocument {\n const next = deepClone(project);\n const target = findArtboardById(next, artboardId);\n if (!target) {\n throw new Error(`Cannot update artboard document: id \"${artboardId}\" not found.`);\n }\n target.document = deepClone(document);\n return next;\n}\n","import { PageDocument } from '@kubuild/schema';\nimport { DocumentChangeEvent, CommandResult } from './commands';\nimport { deepClone } from './command-tree-utils';\n\nexport interface HistoryOptions {\n /**\n * Maximum number of historical states stored in the undo stack.\n * Defaults to 50.\n */\n maxHistory?: number;\n}\n\nexport interface HistoryEntry<T> {\n state: T;\n event?: DocumentChangeEvent;\n timestamp: string;\n}\n\nexport interface HistoryState<T> {\n canUndo: boolean;\n canRedo: boolean;\n undoCount: number;\n redoCount: number;\n present: T;\n}\n\nexport const DEFAULT_MAX_HISTORY = 50;\n\n/**\n * Generic History Engine for immutable state transitions.\n * Maintains undo/redo stacks, enforces maximum history limit,\n * clears redo stack on new actions, and supports resetting state.\n */\nexport class HistoryEngine<T = PageDocument> {\n private past: HistoryEntry<T>[] = [];\n private current: HistoryEntry<T>;\n private future: HistoryEntry<T>[] = [];\n private readonly maxHistory: number;\n // STORA-510: grouped-history transaction bookkeeping. `transactionAnchor` is the\n // entry that was `current` immediately before the outermost `beginTransaction()`\n // call — the single state `endTransaction()` restores undo history to.\n private transactionDepth = 0;\n private transactionAnchor: HistoryEntry<T> | null = null;\n\n constructor(initialState: T, options: HistoryOptions = {}) {\n if (initialState === undefined || initialState === null) {\n throw new Error('Initial state must be defined.');\n }\n\n const limit = options.maxHistory ?? DEFAULT_MAX_HISTORY;\n if (typeof limit !== 'number' || limit <= 0 || !Number.isFinite(limit)) {\n throw new Error('maxHistory option must be a positive integer.');\n }\n\n this.maxHistory = Math.floor(limit);\n this.current = {\n state: deepClone(initialState),\n timestamp: new Date().toISOString(),\n };\n }\n\n /**\n * Get the current active state (returns an immutable clone).\n */\n get present(): T {\n return deepClone(this.current.state);\n }\n\n /**\n * Check if undo is available.\n */\n canUndo(): boolean {\n return this.past.length > 0;\n }\n\n /**\n * Check if redo is available.\n */\n canRedo(): boolean {\n return this.future.length > 0;\n }\n\n /**\n * Get total number of states in undo stack.\n */\n get undoCount(): number {\n return this.past.length;\n }\n\n /**\n * Get total number of states in redo stack.\n */\n get redoCount(): number {\n return this.future.length;\n }\n\n /**\n * Get max history limit.\n */\n get limit(): number {\n return this.maxHistory;\n }\n\n /**\n * Push a new state.\n * Clears the redo stack and shifts oldest past entries if maxHistory is exceeded.\n *\n * STORA-510: while a transaction is active (see `beginTransaction`), pushes update\n * `current` in place without creating an individual undo entry — the whole group\n * collapses into one entry when `endTransaction()` is called.\n */\n push(nextState: T, event?: DocumentChangeEvent): void {\n if (nextState === undefined || nextState === null) {\n throw new Error('Cannot push undefined or null state into history.');\n }\n\n if (this.transactionDepth > 0) {\n this.current = {\n state: deepClone(nextState),\n event,\n timestamp: new Date().toISOString(),\n };\n return;\n }\n\n // Save current to past\n this.past.push(this.current);\n\n // Enforce maxHistory limit on undo stack\n while (this.past.length > this.maxHistory) {\n this.past.shift();\n }\n\n // Set new current\n this.current = {\n state: deepClone(nextState),\n event,\n timestamp: new Date().toISOString(),\n };\n\n // Any new action clears redo future stack\n this.future = [];\n }\n\n /**\n * Begin a grouped-history transaction (STORA-510).\n *\n * Every `push()` made between `beginTransaction()` and the matching outermost\n * `endTransaction()` updates the live state immediately (so `present`/`getState()`\n * always reflect the latest change), but no individual undo entry is recorded until\n * the transaction ends. This is how a multi-step action (e.g. one `streamPage`\n * generation session inserting several sections) collapses into a single undo step.\n *\n * Transactions may be nested; only the outermost `beginTransaction`/`endTransaction`\n * pair has any effect, so a batching caller can safely wrap calls that themselves\n * might also start their own (nested) transaction.\n */\n beginTransaction(): void {\n if (this.transactionDepth === 0) {\n this.transactionAnchor = this.current;\n }\n this.transactionDepth += 1;\n }\n\n /**\n * Ends the current transaction (see `beginTransaction`). Once the outermost\n * transaction ends, the state as it was immediately before `beginTransaction()` is\n * pushed as a single past entry (exactly as one `push()` would) and the redo stack\n * is cleared — unless nothing actually changed during the transaction, in which case\n * this is a no-op and no empty undo entry is created.\n *\n * Calling `endTransaction()` without a matching `beginTransaction()` is a no-op.\n */\n endTransaction(): void {\n if (this.transactionDepth === 0) return;\n this.transactionDepth -= 1;\n if (this.transactionDepth > 0) return;\n\n const anchor = this.transactionAnchor;\n this.transactionAnchor = null;\n if (!anchor || anchor === this.current) return;\n\n this.past.push(anchor);\n while (this.past.length > this.maxHistory) {\n this.past.shift();\n }\n this.future = [];\n }\n\n /**\n * Whether a grouped-history transaction is currently active.\n */\n get inTransaction(): boolean {\n return this.transactionDepth > 0;\n }\n\n /**\n * Undo to the previous state.\n * Returns the restored state, or undefined if undo is not possible.\n */\n undo(): T | undefined {\n if (!this.canUndo()) {\n return undefined;\n }\n\n const previousEntry = this.past.pop()!;\n this.future.unshift(this.current);\n this.current = previousEntry;\n\n return this.present;\n }\n\n /**\n * Redo to the next state in future stack.\n * Returns the restored state, or undefined if redo is not possible.\n */\n redo(): T | undefined {\n if (!this.canRedo()) {\n return undefined;\n }\n\n const nextEntry = this.future.shift()!;\n this.past.push(this.current);\n this.current = nextEntry;\n\n return this.present;\n }\n\n /**\n * Reset the history engine with a new initial state.\n * Clears both undo and redo stacks (e.g. when loading a new document).\n */\n reset(newState: T): void {\n if (newState === undefined || newState === null) {\n throw new Error('New state must be defined when resetting history.');\n }\n\n this.past = [];\n this.future = [];\n this.current = {\n state: deepClone(newState),\n timestamp: new Date().toISOString(),\n };\n }\n\n /**\n * Clear both past and future stacks without changing the current state.\n */\n clear(): void {\n this.past = [];\n this.future = [];\n }\n\n /**\n * Get a snapshot of current history status.\n */\n getState(): HistoryState<T> {\n return {\n canUndo: this.canUndo(),\n canRedo: this.canRedo(),\n undoCount: this.undoCount,\n redoCount: this.redoCount,\n present: this.present,\n };\n }\n}\n\n/**\n * Document History Manager for PageDocument.\n * Connects HistoryEngine with core command execution.\n */\nexport class DocumentHistoryManager {\n private history: HistoryEngine<PageDocument>;\n\n constructor(initialDocument: PageDocument, options?: HistoryOptions) {\n this.history = new HistoryEngine<PageDocument>(initialDocument, options);\n }\n\n get document(): PageDocument {\n return this.history.present;\n }\n\n get canUndo(): boolean {\n return this.history.canUndo();\n }\n\n get canRedo(): boolean {\n return this.history.canRedo();\n }\n\n /**\n * Execute a mutation command immutably and record the resulting state and change event in history.\n */\n execute(executor: (currentDoc: PageDocument) => CommandResult): CommandResult {\n const currentDoc = this.history.present;\n const result = executor(currentDoc);\n this.history.push(result.document, result.event);\n return result;\n }\n\n undo(): PageDocument | undefined {\n return this.history.undo();\n }\n\n redo(): PageDocument | undefined {\n return this.history.redo();\n }\n\n /**\n * Begin a grouped-history transaction (STORA-510) — see `HistoryEngine.beginTransaction`.\n * Every `execute()` call made until the matching `endTransaction()` updates\n * `document` immediately but is collapsed into a single undo entry.\n */\n beginTransaction(): void {\n this.history.beginTransaction();\n }\n\n /**\n * Ends a grouped-history transaction started with `beginTransaction()` — see\n * `HistoryEngine.endTransaction`.\n */\n endTransaction(): void {\n this.history.endTransaction();\n }\n\n get inTransaction(): boolean {\n return this.history.inTransaction;\n }\n\n reset(newDocument: PageDocument): void {\n this.history.reset(newDocument);\n }\n\n clear(): void {\n this.history.clear();\n }\n\n getState(): HistoryState<PageDocument> {\n return this.history.getState();\n }\n}\n","import type { VariableBinding } from '@kubuild/schema';\nimport type { RuntimeContext } from '../types/interfaces';\n\n/**\n * Segments a VariableBinding key must never traverse into, checked before any\n * property access so it can't be bypassed by proxies/getters on the traversed object.\n */\nconst FORBIDDEN_KEY_SEGMENTS = new Set(['__proto__', 'constructor', 'prototype']);\n\nexport type ResolveOutcome =\n | { status: 'resolved'; value: unknown }\n | { status: 'fallback'; value: unknown }\n | { status: 'empty'; value: '' };\n\n// `key`/`fallback` are never passed to eval/Function/any code-execution path in this\n// module — resolution is pure data traversal, never expression evaluation.\nexport function resolveBinding(\n binding: Pick<VariableBinding, 'key' | 'fallback'>,\n context: RuntimeContext | undefined,\n): ResolveOutcome {\n const segments = binding.key.split('.').filter(Boolean);\n if (segments.some((segment) => FORBIDDEN_KEY_SEGMENTS.has(segment))) {\n return applyMissingPolicy(binding);\n }\n\n // Fast-path: Check if context.variables contains the key directly as a flat property\n if (\n context?.variables &&\n typeof context.variables === 'object' &&\n Object.prototype.hasOwnProperty.call(context.variables, binding.key)\n ) {\n const directValue = (context.variables as Record<string, unknown>)[binding.key];\n if (directValue !== undefined && typeof directValue !== 'function') {\n return { status: 'resolved', value: directValue };\n }\n }\n\n let current: unknown = context?.variables;\n\n for (const segment of segments) {\n if (FORBIDDEN_KEY_SEGMENTS.has(segment)) {\n return applyMissingPolicy(binding);\n }\n if (current === null || typeof current !== 'object') {\n return applyMissingPolicy(binding);\n }\n if (!Object.prototype.hasOwnProperty.call(current, segment)) {\n return applyMissingPolicy(binding);\n }\n current = (current as Record<string, unknown>)[segment];\n }\n\n if (current === undefined || typeof current === 'function') {\n return applyMissingPolicy(binding);\n }\n\n return { status: 'resolved', value: current };\n}\n\nfunction applyMissingPolicy(binding: Pick<VariableBinding, 'fallback'>): ResolveOutcome {\n if (binding.fallback !== undefined) {\n return { status: 'fallback', value: binding.fallback };\n }\n return { status: 'empty', value: '' };\n}\n\n/** Convenience wrapper returning just the resolved/fallback/empty value. */\nexport function resolveBindingValue(\n binding: Pick<VariableBinding, 'key' | 'fallback'>,\n context: RuntimeContext | undefined,\n): unknown {\n return resolveBinding(binding, context).value;\n}\n","import type { VariableCatalog } from '../types/interfaces';\n\n/**\n * Segments never traversed/assigned while expanding a catalog key — mirrors the guard\n * in binding-resolver.ts so a host-declared key can't be used to reach the prototype chain.\n */\nconst FORBIDDEN_KEY_SEGMENTS = new Set(['__proto__', 'constructor', 'prototype']);\n\n/**\n * Expands a host `VariableCatalog`'s dotted `sampleValue` keys (e.g. `'site.name'`,\n * `'products'`) into a nested object shaped the same way `resolveBinding` expects\n * `context.variables` to be shaped. Editor/preview-only: the result should be merged\n * into a `RuntimeContext.variables` for canvas preview, never written to a document.\n */\nexport function buildSampleVariablesFromCatalog(catalog?: VariableCatalog): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n if (!catalog) {\n return result;\n }\n\n for (const entry of catalog) {\n const segments = entry.key.split('.').filter(Boolean);\n if (segments.length === 0 || segments.some((segment) => FORBIDDEN_KEY_SEGMENTS.has(segment))) {\n continue;\n }\n\n let cursor: Record<string, unknown> = result;\n for (let i = 0; i < segments.length - 1; i += 1) {\n const segment = segments[i];\n const existing = cursor[segment];\n if (existing === null || typeof existing !== 'object' || Array.isArray(existing)) {\n cursor[segment] = {};\n }\n cursor = cursor[segment] as Record<string, unknown>;\n }\n cursor[segments[segments.length - 1]] = entry.sampleValue;\n }\n\n return result;\n}\n","/**\n * Template and Expression Variable Interpolator\n *\n * Provides safe, deterministic resolution and interpolation of template strings\n * like `{{form.email}}`, `{{variables.token}}`, and `{{response.data.id}}` into\n * targets without using eval() or Function().\n */\n\n/**\n * Segments a path must never traverse into, preventing prototype pollution\n * and unauthorized object introspection.\n */\nconst FORBIDDEN_KEY_SEGMENTS = new Set(['__proto__', 'constructor', 'prototype']);\n\n/**\n * Regex matching `{{ expression }}` template placeholders.\n */\nconst TEMPLATE_EXPRESSION_REGEX = /\\{\\{\\s*([a-zA-Z0-9_$.,\\-[\\]\\s]+?)\\s*\\}\\}/g;\n\n/**\n * Regex matching an exact single `{{ expression }}` placeholder without surrounding text.\n */\nconst EXACT_TEMPLATE_REGEX = /^\\{\\{\\s*([a-zA-Z0-9_$.,\\-[\\]\\s]+?)\\s*\\}\\}$/;\n\n/**\n * Standard structured runtime context for interpolations.\n */\nexport interface InterpolationContext {\n form?: Record<string, unknown>;\n variables?: Record<string, unknown>;\n response?: Record<string, unknown>;\n state?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\n/**\n * Checks if a string contains one or more `{{ ... }}` template expressions.\n */\nexport function hasTemplateExpressions(text: unknown): boolean {\n if (typeof text !== 'string') return false;\n return /\\{\\{\\s*[\\s\\S]+?\\s*\\}\\}/.test(text);\n}\n\n/**\n * Extracts all unique property keys / variable paths referenced inside `{{ ... }}`.\n */\nexport function extractTemplateVariables(text: string): string[] {\n if (!text || typeof text !== 'string') return [];\n const matches: string[] = [];\n const regex = new RegExp(TEMPLATE_EXPRESSION_REGEX.source, 'g');\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(text)) !== null) {\n if (match[1]) {\n const trimmed = match[1].trim();\n if (trimmed && !matches.includes(trimmed)) {\n matches.push(trimmed);\n }\n }\n }\n\n return matches;\n}\n\n/**\n * Safely traverses a nested data source to resolve a dot/bracket path\n * (e.g. `form.user.profile.name`, `response.data[0].id`, `items.0.title`).\n *\n * Returns `fallback` if any segment is missing, undefined, null, or points to\n * a function or forbidden prototype property.\n */\nexport function resolvePropertyPath(\n source: unknown,\n path: string,\n fallback?: unknown,\n): unknown {\n const defaultFallback = arguments.length < 3 ? '' : fallback;\n if (!path || typeof path !== 'string' || source === null || source === undefined) {\n return defaultFallback;\n }\n\n // Normalize bracket notations: `items[0]` -> `items.0`\n const normalizedPath = path.replace(/\\[(\\d+)\\]/g, '.$1');\n const segments = normalizedPath.split('.').map((s) => s.trim()).filter(Boolean);\n\n if (segments.length === 0) {\n return defaultFallback;\n }\n\n let current: unknown = source;\n\n for (const segment of segments) {\n if (FORBIDDEN_KEY_SEGMENTS.has(segment)) {\n return defaultFallback;\n }\n if (current === null || current === undefined) {\n return defaultFallback;\n }\n if (typeof current !== 'object') {\n return defaultFallback;\n }\n\n if (Array.isArray(current)) {\n const index = Number(segment);\n if (!Number.isInteger(index) || index < 0 || index >= current.length) {\n return defaultFallback;\n }\n current = current[index];\n } else if (Object.prototype.hasOwnProperty.call(current, segment)) {\n current = (current as Record<string, unknown>)[segment];\n } else {\n return defaultFallback;\n }\n }\n\n if (current === undefined || typeof current === 'function') {\n return defaultFallback;\n }\n\n return current;\n}\n\n/**\n * Interpolates all `{{ path }}` placeholders in a template string using values\n * from the provided context object.\n *\n * If a variable cannot be resolved, it replaces it with `fallback` (default: `\"\"`).\n */\nexport function interpolateTemplateString(\n template: string,\n context?: Record<string, unknown>,\n fallback: string = '',\n): string {\n if (!template || typeof template !== 'string') return '';\n if (!hasTemplateExpressions(template)) return template;\n\n return template.replace(/\\{\\{\\s*([a-zA-Z0-9_$.,\\-[\\]\\s]+?)\\s*\\}\\}/g, (_match, rawKey) => {\n const key = rawKey.trim();\n if (!key) return fallback;\n\n const resolved = resolvePropertyPath(context, key, fallback);\n if (resolved === undefined || resolved === null) {\n return fallback;\n }\n if (typeof resolved === 'object') {\n try {\n return JSON.stringify(resolved);\n } catch {\n return fallback;\n }\n }\n return String(resolved);\n });\n}\n\n/**\n * Recursively interpolates any value (string, object, array, primitive).\n *\n * - If string is exactly `{{ path }}`, returns the raw resolved value (retaining type: number, boolean, object, array).\n * - If string contains embedded templates (e.g. `Bearer {{token}}`), returns the interpolated string.\n * - If array, interpolates every element.\n * - If object, interpolates every property value while stripping forbidden prototype keys.\n */\nexport function interpolateValue(value: unknown, context?: Record<string, unknown>): unknown {\n if (value === null || value === undefined) {\n return value;\n }\n\n if (typeof value === 'string') {\n const trimmed = value.trim();\n const exactMatch = EXACT_TEMPLATE_REGEX.exec(trimmed);\n if (exactMatch && exactMatch[1]) {\n const key = exactMatch[1].trim();\n return resolvePropertyPath(context, key, '');\n }\n return interpolateTemplateString(value, context);\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => interpolateValue(item, context));\n }\n\n if (typeof value === 'object') {\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n if (!FORBIDDEN_KEY_SEGMENTS.has(k)) {\n result[k] = interpolateValue(v, context);\n }\n }\n return result;\n }\n\n return value;\n}\n","import type { ActionStepCondition, ConditionOperator } from '@kubuild/schema';\nimport { resolvePropertyPath } from './interpolator';\n\n/**\n * Extended condition operators supported by the evaluator.\n */\nexport type ExtendedConditionOperator =\n | ConditionOperator\n | 'starts_with'\n | 'ends_with'\n | 'is_empty'\n | 'is_not_empty'\n | 'in'\n | 'not_in';\n\n/**\n * Options for fine-tuning condition evaluation.\n */\nexport interface ConditionEvaluationOptions {\n caseInsensitive?: boolean;\n trimStrings?: boolean;\n}\n\n/**\n * Represents a group of conditions evaluated together using AND / OR combinators.\n */\nexport interface ConditionGroup {\n combinator: 'and' | 'or';\n conditions: (ActionStepCondition | ConditionGroup)[];\n}\n\n/**\n * Type guard to check if a condition item is a ConditionGroup.\n */\nexport function isConditionGroup(\n item: ActionStepCondition | ConditionGroup,\n): item is ConditionGroup {\n return typeof item === 'object' && item !== null && 'combinator' in item && 'conditions' in item;\n}\n\n/**\n * Checks whether a given value is considered empty.\n * Returns true for undefined, null, empty string, empty array, or empty object.\n */\nexport function isValueEmpty(value: unknown): boolean {\n if (value === undefined || value === null) {\n return true;\n }\n if (typeof value === 'string') {\n return value.trim().length === 0;\n }\n if (Array.isArray(value)) {\n return value.length === 0;\n }\n if (typeof value === 'object') {\n return Object.keys(value as Record<string, unknown>).length === 0;\n }\n return false;\n}\n\n/**\n * Evaluates an operator against an actual value and an optional expected value.\n */\nexport function evaluateOperator(\n operator: ExtendedConditionOperator | string,\n actual: unknown,\n expected?: unknown,\n options?: ConditionEvaluationOptions,\n): boolean {\n let act = actual;\n let exp = expected;\n\n if (options?.trimStrings) {\n if (typeof act === 'string') act = act.trim();\n if (typeof exp === 'string') exp = exp.trim();\n }\n\n if (options?.caseInsensitive) {\n if (typeof act === 'string') act = act.toLowerCase();\n if (typeof exp === 'string') exp = exp.toLowerCase();\n }\n\n switch (operator) {\n case 'equals': {\n if (act === exp) return true;\n // Handle numeric type coercion if one is string and the other is number\n if (typeof act === 'number' && typeof exp === 'string' && exp.trim() !== '') {\n const numExp = Number(exp);\n return !Number.isNaN(numExp) && act === numExp;\n }\n if (typeof act === 'string' && typeof exp === 'number' && act.trim() !== '') {\n const numAct = Number(act);\n return !Number.isNaN(numAct) && numAct === exp;\n }\n // Handle boolean string coercion (\"true\" / \"false\")\n if (typeof act === 'boolean' && typeof exp === 'string') {\n return act === (exp.toLowerCase() === 'true');\n }\n if (typeof act === 'string' && typeof exp === 'boolean') {\n return (act.toLowerCase() === 'true') === exp;\n }\n return false;\n }\n\n case 'not_equals':\n return !evaluateOperator('equals', actual, expected, options);\n\n case 'is_truthy':\n if (Array.isArray(act)) {\n return act.length > 0;\n }\n if (act && typeof act === 'object') {\n return Object.keys(act as Record<string, unknown>).length > 0;\n }\n return Boolean(act);\n\n case 'is_falsy':\n return !evaluateOperator('is_truthy', actual, undefined, options);\n\n case 'is_empty':\n return isValueEmpty(actual);\n\n case 'is_not_empty':\n return !isValueEmpty(actual);\n\n case 'contains': {\n if (typeof act === 'string') {\n const needle = options?.caseInsensitive && typeof exp === 'string' ? exp : String(exp ?? '');\n return act.includes(needle);\n }\n if (Array.isArray(act)) {\n if (options?.caseInsensitive && typeof exp === 'string') {\n return act.some((item) => typeof item === 'string' && item.toLowerCase() === exp);\n }\n return act.includes(exp);\n }\n if (act && typeof act === 'object') {\n return exp !== undefined && String(exp) in (act as Record<string, unknown>);\n }\n return false;\n }\n\n case 'not_contains':\n return !evaluateOperator('contains', actual, expected, options);\n\n case 'starts_with': {\n if (typeof act !== 'string') return false;\n const prefix = options?.caseInsensitive && typeof exp === 'string' ? exp : String(exp ?? '');\n return act.startsWith(prefix);\n }\n\n case 'ends_with': {\n if (typeof act !== 'string') return false;\n const suffix = options?.caseInsensitive && typeof exp === 'string' ? exp : String(exp ?? '');\n return act.endsWith(suffix);\n }\n\n case 'gt': {\n const actNum = Number(act);\n const expNum = Number(exp);\n return !Number.isNaN(actNum) && !Number.isNaN(expNum) && actNum > expNum;\n }\n\n case 'gte': {\n const actNum = Number(act);\n const expNum = Number(exp);\n return !Number.isNaN(actNum) && !Number.isNaN(expNum) && actNum >= expNum;\n }\n\n case 'lt': {\n const actNum = Number(act);\n const expNum = Number(exp);\n return !Number.isNaN(actNum) && !Number.isNaN(expNum) && actNum < expNum;\n }\n\n case 'lte': {\n const actNum = Number(act);\n const expNum = Number(exp);\n return !Number.isNaN(actNum) && !Number.isNaN(expNum) && actNum <= expNum;\n }\n\n case 'in': {\n if (Array.isArray(exp)) {\n if (options?.caseInsensitive && typeof act === 'string') {\n return exp.some((item) => typeof item === 'string' && item.toLowerCase() === act);\n }\n return exp.includes(act);\n }\n if (typeof exp === 'string') {\n return exp.includes(String(act ?? ''));\n }\n return false;\n }\n\n case 'not_in':\n return !evaluateOperator('in', actual, expected, options);\n\n case 'regex': {\n try {\n const patternStr = String(exp ?? '');\n const flags = options?.caseInsensitive ? 'i' : '';\n const regex = new RegExp(patternStr, flags);\n return regex.test(String(act ?? ''));\n } catch {\n return false;\n }\n }\n\n default:\n return true;\n }\n}\n\n/**\n * Resolves a field value from context and evaluates a single ActionStepCondition.\n */\nexport function evaluateCondition(\n condition: ActionStepCondition | undefined,\n context: Record<string, unknown>,\n options?: ConditionEvaluationOptions,\n): boolean {\n if (!condition) return true;\n\n const rawField = condition.field;\n if (!rawField || typeof rawField !== 'string') return true;\n\n // Clean template wrapper syntax `{{ path }}` if provided\n const fieldPath = rawField.replace(/^\\{\\{\\s*/, '').replace(/\\s*\\}\\}$/, '').trim();\n const actualValue = resolvePropertyPath(context, fieldPath, undefined);\n\n return evaluateOperator(condition.operator, actualValue, condition.value, options);\n}\n\n/**\n * Evaluates a ConditionGroup (AND / OR group with nested conditions).\n */\nexport function evaluateConditionGroup(\n group: ConditionGroup,\n context: Record<string, unknown>,\n options?: ConditionEvaluationOptions,\n): boolean {\n if (!group || !Array.isArray(group.conditions) || group.conditions.length === 0) {\n return true;\n }\n\n const combinator = group.combinator === 'or' ? 'or' : 'and';\n\n if (combinator === 'and') {\n return group.conditions.every((item) => {\n if (isConditionGroup(item)) {\n return evaluateConditionGroup(item, context, options);\n }\n return evaluateCondition(item, context, options);\n });\n }\n\n return group.conditions.some((item) => {\n if (isConditionGroup(item)) {\n return evaluateConditionGroup(item, context, options);\n }\n return evaluateCondition(item, context, options);\n });\n}\n\n/**\n * Evaluates a list of conditions and/or condition groups using a given combinator ('and' | 'or').\n */\nexport function evaluateConditions(\n conditions: (ActionStepCondition | ConditionGroup)[],\n context: Record<string, unknown>,\n combinator: 'and' | 'or' = 'and',\n options?: ConditionEvaluationOptions,\n): boolean {\n return evaluateConditionGroup({ combinator, conditions }, context, options);\n}\n\n","import type {\n ActionPipeline,\n ActionStep,\n ActionStepCondition,\n ActionStepType,\n} from '@kubuild/schema';\nimport { interpolateValue, resolvePropertyPath } from './interpolator';\nimport { evaluateCondition } from './conditional-resolver';\n\n/**\n * Execution context shared across action steps in a pipeline.\n */\nexport interface PipelineExecutionContext {\n form?: Record<string, unknown>;\n variables?: Record<string, unknown>;\n state?: Record<string, unknown>;\n response?: unknown;\n stepResults?: Record<string, StepExecutionResult>;\n error?: unknown;\n lastError?: unknown;\n nodeId?: string;\n document?: unknown;\n [key: string]: unknown;\n}\n\n/**\n * Status of an individual step execution.\n */\nexport type StepExecutionStatus = 'success' | 'error' | 'skipped' | 'cancelled';\n\n/**\n * Result of executing an individual action step.\n */\nexport interface StepExecutionResult {\n stepId: string;\n stepType: ActionStepType | string;\n status: StepExecutionStatus;\n data?: unknown;\n error?: Error | unknown;\n durationMs: number;\n subResults?: StepExecutionResult[];\n}\n\n/**\n * Overall result of executing an action pipeline.\n */\nexport interface PipelineExecutionResult {\n pipelineId: string;\n success: boolean;\n status: 'completed' | 'failed' | 'cancelled';\n stepResults: StepExecutionResult[];\n context: PipelineExecutionContext;\n error?: Error | unknown;\n durationMs: number;\n}\n\n/**\n * Handler function signature for an individual step type.\n */\nexport type PipelineStepHandler<TContext = PipelineExecutionContext> = (\n step: ActionStep,\n context: TContext,\n signal: AbortSignal,\n) => Promise<unknown> | unknown;\n\n/**\n * Options for configuring the execution of an action pipeline.\n */\nexport interface ExecutePipelineOptions {\n context?: PipelineExecutionContext;\n signal?: AbortSignal;\n timeout?: number;\n throwOnError?: boolean;\n handlers?: Record<string, PipelineStepHandler>;\n onStepStart?: (step: ActionStep, context: PipelineExecutionContext) => void;\n onStepComplete?: (\n step: ActionStep,\n result: StepExecutionResult,\n context: PipelineExecutionContext,\n ) => void;\n}\n\n/**\n * Configuration options for creating an ActionPipelineExecutor instance.\n */\nexport interface ActionPipelineExecutorOptions {\n handlers?: Record<string, PipelineStepHandler>;\n defaultTimeout?: number;\n throwOnError?: boolean;\n}\n\n/**\n * Custom error thrown when a step or pipeline times out.\n */\nexport class ActionTimeoutError extends Error {\n readonly stepId?: string;\n readonly timeoutMs: number;\n\n constructor(message: string, timeoutMs: number, stepId?: string) {\n super(message);\n this.name = 'ActionTimeoutError';\n this.timeoutMs = timeoutMs;\n this.stepId = stepId;\n }\n}\n\n/**\n * Custom error thrown when an action execution is aborted/cancelled.\n */\nexport class ActionCancellationError extends Error {\n readonly stepId?: string;\n\n constructor(message: string = 'Action execution cancelled', stepId?: string) {\n super(message);\n this.name = 'ActionCancellationError';\n this.stepId = stepId;\n }\n}\n\n/**\n * Evaluates an ActionStepCondition against a pipeline execution context.\n */\nexport function evaluateActionCondition(\n condition: ActionStepCondition | undefined,\n context: PipelineExecutionContext,\n): boolean {\n return evaluateCondition(condition, context);\n}\n\n/**\n * Normalizes an abort reason into an ActionTimeoutError or ActionCancellationError.\n */\nfunction normalizeAbortError(reason: unknown, stepId?: string): Error {\n if (reason instanceof ActionTimeoutError) {\n return reason;\n }\n if (reason instanceof ActionCancellationError) {\n return reason;\n }\n const msg = reason instanceof Error ? reason.message : 'Action execution cancelled';\n return new ActionCancellationError(msg, stepId);\n}\n\n/**\n * Creates a combined abort controller that aborts when either parent signal triggers or timeout fires.\n */\nfunction createTimeoutAbortSignal(\n parentSignal?: AbortSignal,\n timeoutMs?: number,\n timeoutMessage?: string,\n stepId?: string,\n): { signal: AbortSignal; cleanup: () => void } {\n const controller = new AbortController();\n let timerId: ReturnType<typeof setTimeout> | undefined;\n\n const onParentAbort = () => {\n controller.abort(normalizeAbortError(parentSignal?.reason, stepId));\n };\n\n if (parentSignal) {\n if (parentSignal.aborted) {\n onParentAbort();\n } else {\n parentSignal.addEventListener('abort', onParentAbort, { once: true });\n }\n }\n\n if (timeoutMs !== undefined && timeoutMs > 0) {\n timerId = setTimeout(() => {\n controller.abort(\n new ActionTimeoutError(\n timeoutMessage || `Action execution timed out after ${timeoutMs}ms`,\n timeoutMs,\n stepId,\n ),\n );\n }, timeoutMs);\n }\n\n const cleanup = () => {\n if (timerId !== undefined) {\n clearTimeout(timerId);\n }\n if (parentSignal) {\n parentSignal.removeEventListener('abort', onParentAbort);\n }\n };\n\n return { signal: controller.signal, cleanup };\n}\n\n/**\n * ActionPipelineExecutor manages step handlers, sequential execution of action pipelines,\n * timeouts, cancellation, conditional evaluation, and onSuccess / onError branching.\n */\nexport class ActionPipelineExecutor {\n private handlers = new Map<string, PipelineStepHandler>();\n private defaultTimeout?: number;\n private throwOnError: boolean;\n\n constructor(options?: ActionPipelineExecutorOptions) {\n this.defaultTimeout = options?.defaultTimeout;\n this.throwOnError = options?.throwOnError ?? false;\n\n // Register built-in default handlers\n this.registerBuiltInHandlers();\n\n // Register user-provided handlers\n if (options?.handlers) {\n for (const [type, handler] of Object.entries(options.handlers)) {\n this.registerHandler(type, handler);\n }\n }\n }\n\n /**\n * Registers default built-in handlers for core step types like `set_state` and `reset_form`.\n */\n private registerBuiltInHandlers(): void {\n // 1. set_state: Updates runtime state or variables\n this.registerHandler('set_state', (step, context) => {\n const key = String(step.payload?.key || '');\n const value = step.payload?.value;\n const scope = String(step.payload?.scope || 'runtime');\n\n if (!key) return;\n\n if (!context.state) context.state = {};\n if (!context.variables) context.variables = {};\n\n if (scope === 'runtime' || scope === 'document') {\n context.state[key] = value;\n context.variables[key] = value;\n } else {\n context.state[key] = value;\n }\n\n return { key, value, scope };\n });\n\n // 2. reset_form: Clears/resets form inputs\n this.registerHandler('reset_form', (_step, context) => {\n if (context.form && typeof context.form === 'object') {\n for (const k of Object.keys(context.form)) {\n context.form[k] = '';\n }\n }\n return { reset: true };\n });\n }\n\n /**\n * Registers a handler for a step type.\n */\n public registerHandler(type: ActionStepType | string, handler: PipelineStepHandler): this {\n this.handlers.set(type, handler);\n return this;\n }\n\n /**\n * Unregisters a handler for a step type.\n */\n public unregisterHandler(type: ActionStepType | string): this {\n this.handlers.delete(type);\n return this;\n }\n\n /**\n * Checks if a handler exists for a step type.\n */\n public hasHandler(type: ActionStepType | string): boolean {\n return this.handlers.has(type);\n }\n\n /**\n * Gets the registered handler for a step type.\n */\n public getHandler(type: ActionStepType | string): PipelineStepHandler | undefined {\n return this.handlers.get(type);\n }\n\n /**\n * Executes a full ActionPipeline sequentially with support for timeouts, cancellation,\n * condition evaluation, and branching.\n */\n public async execute(\n pipeline: ActionPipeline,\n options?: ExecutePipelineOptions,\n ): Promise<PipelineExecutionResult> {\n const startTime = Date.now();\n const context: PipelineExecutionContext = options?.context ?? {};\n\n if (!context.variables) context.variables = {};\n if (!context.state) context.state = {};\n if (!context.form) context.form = {};\n if (!context.stepResults) context.stepResults = {};\n\n const timeoutMs = options?.timeout ?? this.defaultTimeout;\n const { signal, cleanup } = createTimeoutAbortSignal(\n options?.signal,\n timeoutMs,\n `Pipeline \"${pipeline.id}\" timed out after ${timeoutMs}ms`,\n );\n\n let pipelineStatus: 'completed' | 'failed' | 'cancelled' = 'completed';\n let pipelineError: Error | unknown = undefined;\n const allStepResults: StepExecutionResult[] = [];\n\n try {\n if (pipeline.enabled === false) {\n return {\n pipelineId: pipeline.id,\n success: true,\n status: 'completed',\n stepResults: [],\n context,\n durationMs: Date.now() - startTime,\n };\n }\n\n const { success, results, error } = await this.executeSteps(\n pipeline.steps,\n context,\n signal,\n options,\n );\n\n allStepResults.push(...results);\n\n if (!success) {\n pipelineStatus = signal.aborted ? 'cancelled' : 'failed';\n pipelineError = error;\n }\n } catch (err: unknown) {\n pipelineStatus = signal.aborted ? 'cancelled' : 'failed';\n pipelineError = err;\n } finally {\n cleanup();\n }\n\n const isSuccess = pipelineStatus === 'completed';\n const result: PipelineExecutionResult = {\n pipelineId: pipeline.id,\n success: isSuccess,\n status: pipelineStatus,\n stepResults: allStepResults,\n context,\n error: pipelineError,\n durationMs: Date.now() - startTime,\n };\n\n const shouldThrow = options?.throwOnError ?? this.throwOnError;\n if (!isSuccess && shouldThrow) {\n throw pipelineError || new Error(`Action pipeline \"${pipeline.id}\" failed`);\n }\n\n return result;\n }\n\n /**\n * Executes an ordered list of ActionSteps sequentially.\n */\n private async executeSteps(\n steps: ActionStep[],\n context: PipelineExecutionContext,\n parentSignal: AbortSignal,\n options?: ExecutePipelineOptions,\n ): Promise<{ success: boolean; results: StepExecutionResult[]; error?: Error | unknown }> {\n const results: StepExecutionResult[] = [];\n\n for (const step of steps) {\n if (parentSignal.aborted) {\n const cancelError = normalizeAbortError(parentSignal.reason, step.id);\n\n const cancelledResult: StepExecutionResult = {\n stepId: step.id,\n stepType: step.type,\n status: 'cancelled',\n error: cancelError,\n durationMs: 0,\n };\n results.push(cancelledResult);\n context.stepResults![step.id] = cancelledResult;\n\n return { success: false, results, error: cancelError };\n }\n\n const stepResult = await this.executeSingleStep(step, context, parentSignal, options);\n results.push(stepResult);\n context.stepResults![step.id] = stepResult;\n\n if (stepResult.status === 'error' || stepResult.status === 'cancelled') {\n if (!step.continueOnError) {\n return { success: false, results, error: stepResult.error };\n }\n }\n }\n\n return { success: true, results };\n }\n\n /**\n * Executes a single ActionStep with condition checking, payload interpolation, timeout,\n * handler execution, response context passing, and branch execution.\n */\n public async executeSingleStep(\n step: ActionStep,\n context: PipelineExecutionContext,\n parentSignal: AbortSignal,\n options?: ExecutePipelineOptions,\n ): Promise<StepExecutionResult> {\n const stepStartTime = Date.now();\n\n // 1. Evaluate condition\n if (step.condition && !evaluateActionCondition(step.condition, context)) {\n const skippedResult: StepExecutionResult = {\n stepId: step.id,\n stepType: step.type,\n status: 'skipped',\n durationMs: Date.now() - stepStartTime,\n };\n options?.onStepComplete?.(step, skippedResult, context);\n return skippedResult;\n }\n\n options?.onStepStart?.(step, context);\n\n // 2. Setup per-step timeout & signal\n const stepTimeout = step.timeout;\n const { signal: stepSignal, cleanup: cleanupStepSignal } = createTimeoutAbortSignal(\n parentSignal,\n stepTimeout,\n `Step \"${step.id}\" timed out after ${stepTimeout}ms`,\n step.id,\n );\n\n // 3. Interpolate payload with current context\n const rawPayload = step.payload || {};\n const interpolatedPayload = (interpolateValue(rawPayload, context) || {}) as Record<\n string,\n unknown\n >;\n const resolvedStep: ActionStep = {\n ...step,\n payload: interpolatedPayload,\n };\n\n // 4. Find handler\n const customHandler = options?.handlers?.[step.type];\n const handler = customHandler || this.getHandler(step.type);\n\n let stepOutput: unknown;\n let stepError: Error | unknown;\n let stepStatus: StepExecutionStatus = 'success';\n const subResults: StepExecutionResult[] = [];\n\n try {\n if (!handler) {\n throw new Error(`No handler registered for action step type: \"${step.type}\"`);\n }\n\n if (stepSignal.aborted) {\n throw normalizeAbortError(stepSignal.reason, step.id);\n }\n\n stepOutput = await handler(resolvedStep, context, stepSignal);\n\n // On successful execution: update context response (if returned) & response mapping\n if (stepOutput !== undefined) {\n context.response = stepOutput;\n }\n delete context.lastError;\n\n if (interpolatedPayload.responseMapping && typeof interpolatedPayload.responseMapping === 'object') {\n const mapping = interpolatedPayload.responseMapping as Record<string, string>;\n for (const [targetVar, sourcePath] of Object.entries(mapping)) {\n const evalContext = {\n ...context,\n response: stepOutput !== undefined ? stepOutput : context.response,\n };\n const cleanPath = String(sourcePath).replace(/^\\{\\{\\s*/, '').replace(/\\s*\\}\\}$/, '').trim();\n const mappedVal = resolvePropertyPath(evalContext, cleanPath, undefined);\n if (mappedVal !== undefined) {\n if (!context.variables) context.variables = {};\n context.variables[targetVar] = mappedVal;\n }\n }\n }\n\n // Execute onSuccess branching if defined\n if (step.onSuccess && Array.isArray(step.onSuccess) && step.onSuccess.length > 0) {\n const successBranch = await this.executeSteps(\n step.onSuccess,\n context,\n stepSignal,\n options,\n );\n subResults.push(...successBranch.results);\n\n if (!successBranch.success) {\n stepStatus = 'error';\n stepError = successBranch.error;\n }\n }\n } catch (err: unknown) {\n stepError = err;\n stepStatus = stepSignal.aborted ? 'cancelled' : 'error';\n context.lastError = err;\n context.error = err;\n\n // Execute onError branching if defined\n if (step.onError && Array.isArray(step.onError) && step.onError.length > 0) {\n try {\n const errorBranch = await this.executeSteps(\n step.onError,\n context,\n parentSignal, // Use parent signal so error branch can run even if step timed out\n options,\n );\n subResults.push(...errorBranch.results);\n } catch (onErrorErr) {\n // Keep original error as primary\n }\n }\n } finally {\n cleanupStepSignal();\n }\n\n const result: StepExecutionResult = {\n stepId: step.id,\n stepType: step.type,\n status: stepStatus,\n data: stepOutput,\n error: stepError,\n durationMs: Date.now() - stepStartTime,\n ...(subResults.length > 0 ? { subResults } : {}),\n };\n\n options?.onStepComplete?.(step, result, context);\n\n return result;\n }\n}\n\n/**\n * Convenience helper to execute an action pipeline using default or custom executor settings.\n */\nexport async function executeActionPipeline(\n pipeline: ActionPipeline,\n options?: ExecutePipelineOptions,\n): Promise<PipelineExecutionResult> {\n const executor = new ActionPipelineExecutor();\n return executor.execute(pipeline, options);\n}\n\n","import { resolvePropertyPath } from './interpolator';\n\n/**\n * Forbidden object keys to protect against prototype pollution.\n */\nconst FORBIDDEN_KEY_SEGMENTS = new Set(['__proto__', 'constructor', 'prototype']);\n\n/**\n * Standard form state structure managed inside the store.\n */\nexport interface FormState {\n values: Record<string, unknown>;\n errors: Record<string, string>;\n touched: Record<string, boolean>;\n isSubmitting: boolean;\n isValid: boolean;\n dirty: boolean;\n initialValues?: Record<string, unknown>;\n}\n\n/**\n * Root state managed by the RuntimeStateStore.\n */\nexport interface RuntimeStoreState {\n variables: Record<string, unknown>;\n forms: Record<string, FormState>;\n state: Record<string, unknown>;\n [key: string]: unknown;\n}\n\nexport type Unsubscribe = () => void;\nexport type StoreListener = (\n state: Readonly<RuntimeStoreState>,\n prevState: Readonly<RuntimeStoreState>,\n) => void;\nexport type KeyChangeListener<T = unknown> = (newValue: T, prevValue: T) => void;\nexport type PathChangeListener<T = unknown> = (newValue: T, prevValue: T) => void;\nexport type FormChangeListener = (newForm: FormState, prevForm?: FormState) => void;\n\n/**\n * Creates an initial clean FormState object.\n */\nexport function createDefaultFormState(initialValues?: Record<string, unknown>): FormState {\n const init = initialValues ? { ...initialValues } : {};\n return {\n values: { ...init },\n errors: {},\n touched: {},\n isSubmitting: false,\n isValid: true,\n dirty: false,\n initialValues: { ...init },\n };\n}\n\n/**\n * Deep clones an object safely.\n */\nfunction cloneState<T>(obj: T): T {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n if (Array.isArray(obj)) {\n return obj.map((item) => cloneState(item)) as unknown as T;\n }\n const copy: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj as Record<string, unknown>)) {\n if (!FORBIDDEN_KEY_SEGMENTS.has(k)) {\n copy[k] = cloneState(v);\n }\n }\n return copy as T;\n}\n\n/**\n * Sets a value at a nested dotted path on a target object.\n */\nfunction setNestedPath(target: Record<string, unknown>, path: string, value: unknown): boolean {\n if (!path || typeof path !== 'string' || !target || typeof target !== 'object') {\n return false;\n }\n\n const normalized = path.replace(/\\[(\\d+)\\]/g, '.$1');\n const segments = normalized.split('.').map((s) => s.trim()).filter(Boolean);\n\n if (segments.length === 0) return false;\n\n let current: Record<string, unknown> = target;\n\n for (let i = 0; i < segments.length - 1; i++) {\n const seg = segments[i];\n if (FORBIDDEN_KEY_SEGMENTS.has(seg)) return false;\n\n if (current[seg] === undefined || current[seg] === null || typeof current[seg] !== 'object') {\n current[seg] = {};\n }\n current = current[seg] as Record<string, unknown>;\n }\n\n const lastSeg = segments[segments.length - 1];\n if (FORBIDDEN_KEY_SEGMENTS.has(lastSeg)) return false;\n\n current[lastSeg] = value;\n return true;\n}\n\n/**\n * Deletes a value at a nested dotted path on a target object.\n */\nfunction deleteNestedPath(target: Record<string, unknown>, path: string): boolean {\n if (!path || typeof path !== 'string' || !target || typeof target !== 'object') {\n return false;\n }\n\n const normalized = path.replace(/\\[(\\d+)\\]/g, '.$1');\n const segments = normalized.split('.').map((s) => s.trim()).filter(Boolean);\n\n if (segments.length === 0) return false;\n\n let current: Record<string, unknown> = target;\n\n for (let i = 0; i < segments.length - 1; i++) {\n const seg = segments[i];\n if (FORBIDDEN_KEY_SEGMENTS.has(seg) || !(seg in current) || typeof current[seg] !== 'object') {\n return false;\n }\n current = current[seg] as Record<string, unknown>;\n }\n\n const lastSeg = segments[segments.length - 1];\n if (FORBIDDEN_KEY_SEGMENTS.has(lastSeg) || !(lastSeg in current)) {\n return false;\n }\n\n delete current[lastSeg];\n return true;\n}\n\n/**\n * Reactive State Store & Context Manager for form states and runtime variables.\n */\nexport class RuntimeStateStore {\n private state: RuntimeStoreState;\n private listeners = new Set<StoreListener>();\n private pathListeners = new Map<string, Set<PathChangeListener>>();\n private formListeners = new Map<string, Set<FormChangeListener>>();\n private isBatching = false;\n private batchOldState?: RuntimeStoreState;\n private isNotifying = false;\n\n constructor(initialState?: Partial<RuntimeStoreState>) {\n this.state = {\n variables: initialState?.variables ? { ...initialState.variables } : {},\n forms: initialState?.forms ? cloneState(initialState.forms) : {},\n state: initialState?.state ? { ...initialState.state } : {},\n ...initialState,\n };\n }\n\n /**\n * Retrieves a value at a specified path or the entire state snapshot.\n */\n public get<T = unknown>(path?: string, fallback?: T): T {\n if (!path || path.trim() === '') {\n return this.getSnapshot() as unknown as T;\n }\n const cleanPath = path.replace(/^\\{\\{\\s*/, '').replace(/\\s*\\}\\}$/, '').trim();\n const resolved = resolvePropertyPath(this.state, cleanPath, fallback);\n return resolved as T;\n }\n\n /**\n * Gets an immutable snapshot of the current state.\n */\n public getSnapshot(): RuntimeStoreState {\n return cloneState(this.state);\n }\n\n /**\n * Sets a value at a dotted path and notifies subscribers.\n */\n public set(path: string, value: unknown): this {\n if (!path) return this;\n\n const oldState = this.isBatching ? undefined : cloneState(this.state);\n const cleanPath = path.replace(/^\\{\\{\\s*/, '').replace(/\\s*\\}\\}$/, '').trim();\n\n const success = setNestedPath(this.state, cleanPath, value);\n if (!success) return this;\n\n if (!this.isBatching && oldState) {\n this.notifyChanges(oldState, this.state);\n }\n\n return this;\n }\n\n /**\n * Performs multiple updates atomically, triggering subscriber notifications once.\n */\n public setBatch(updates: Record<string, unknown>): this {\n if (!updates || typeof updates !== 'object') return this;\n\n const oldState = this.batchOldState || cloneState(this.state);\n this.isBatching = true;\n this.batchOldState = oldState;\n\n try {\n for (const [path, value] of Object.entries(updates)) {\n this.set(path, value);\n }\n } finally {\n this.isBatching = false;\n this.batchOldState = undefined;\n this.notifyChanges(oldState, this.state);\n }\n\n return this;\n }\n\n /**\n * Deletes a property at the specified path.\n */\n public delete(path: string): boolean {\n if (!path) return false;\n\n const oldState = this.isBatching ? undefined : cloneState(this.state);\n const cleanPath = path.replace(/^\\{\\{\\s*/, '').replace(/\\s*\\}\\}$/, '').trim();\n\n const deleted = deleteNestedPath(this.state, cleanPath);\n if (deleted && !this.isBatching && oldState) {\n this.notifyChanges(oldState, this.state);\n }\n\n return deleted;\n }\n\n /**\n * Resets the store state to an initial or clean state.\n */\n public reset(initialState?: Partial<RuntimeStoreState>): this {\n const oldState = cloneState(this.state);\n this.state = {\n variables: initialState?.variables ? { ...initialState.variables } : {},\n forms: initialState?.forms ? cloneState(initialState.forms) : {},\n state: initialState?.state ? { ...initialState.state } : {},\n ...initialState,\n };\n this.notifyChanges(oldState, this.state);\n return this;\n }\n\n /**\n * Subscribes a listener to any state changes.\n */\n public subscribe(listener: StoreListener): Unsubscribe {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n /**\n * Subscribes a listener to changes on a top-level key.\n */\n public subscribeKey<T = unknown>(key: string, listener: KeyChangeListener<T>): Unsubscribe {\n return this.subscribePath(key, listener as PathChangeListener);\n }\n\n /**\n * Subscribes a listener to changes at a specific dotted path.\n */\n public subscribePath<T = unknown>(path: string, listener: PathChangeListener<T>): Unsubscribe {\n const cleanPath = path.replace(/^\\{\\{\\s*/, '').replace(/\\s*\\}\\}$/, '').trim();\n if (!this.pathListeners.has(cleanPath)) {\n this.pathListeners.set(cleanPath, new Set());\n }\n const set = this.pathListeners.get(cleanPath)!;\n set.add(listener as PathChangeListener);\n\n return () => {\n set.delete(listener as PathChangeListener);\n if (set.size === 0) {\n this.pathListeners.delete(cleanPath);\n }\n };\n }\n\n /**\n * Subscribes a listener to changes of a specific form state.\n */\n public subscribeForm(formId: string, listener: FormChangeListener): Unsubscribe {\n if (!this.formListeners.has(formId)) {\n this.formListeners.set(formId, new Set());\n }\n const set = this.formListeners.get(formId)!;\n set.add(listener);\n\n return () => {\n set.delete(listener);\n if (set.size === 0) {\n this.formListeners.delete(formId);\n }\n };\n }\n\n /**\n * Notifies all relevant listeners when state changes.\n */\n private notifyChanges(oldState: RuntimeStoreState, newState: RuntimeStoreState): void {\n if (this.isNotifying) return;\n this.isNotifying = true;\n\n try {\n const readOnlyNew = Object.freeze(cloneState(newState));\n const readOnlyOld = Object.freeze(cloneState(oldState));\n\n // 1. Notify global listeners\n for (const listener of this.listeners) {\n try {\n listener(readOnlyNew, readOnlyOld);\n } catch {\n // Prevent listener errors from breaking other subscriptions\n }\n }\n\n // 2. Notify path listeners\n for (const [path, listeners] of this.pathListeners.entries()) {\n const oldVal = resolvePropertyPath(oldState, path, undefined);\n const newVal = resolvePropertyPath(newState, path, undefined);\n\n if (oldVal !== newVal) {\n for (const listener of listeners) {\n try {\n listener(newVal, oldVal);\n } catch {\n // Ignore subscriber errors\n }\n }\n }\n }\n\n // 3. Notify form listeners\n for (const [formId, listeners] of this.formListeners.entries()) {\n const oldForm = oldState.forms?.[formId];\n const newForm = newState.forms?.[formId];\n\n if (oldForm !== newForm) {\n for (const listener of listeners) {\n try {\n listener(newForm || createDefaultFormState(), oldForm);\n } catch {\n // Ignore subscriber errors\n }\n }\n }\n }\n } finally {\n this.isNotifying = false;\n }\n }\n\n // ==========================================\n // Form State Management Helpers\n // ==========================================\n\n /**\n * Retrieves the FormState for a formId, initializing default form state if not present.\n */\n public getForm(formId: string): FormState {\n if (!this.state.forms[formId]) {\n this.state.forms[formId] = createDefaultFormState();\n }\n return this.state.forms[formId];\n }\n\n /**\n * Updates a single field value in a form and marks dirty if changed from initial.\n */\n public setFormFieldValue(formId: string, fieldName: string, value: unknown): this {\n const form = this.getForm(formId);\n const oldValues = { ...form.values };\n form.values[fieldName] = value;\n\n // Check dirty state\n const initialVal = form.initialValues?.[fieldName];\n form.dirty = Object.keys(form.values).some((k) => form.values[k] !== form.initialValues?.[k]);\n\n this.set(`forms.${formId}.values.${fieldName}`, value);\n return this;\n }\n\n /**\n * Sets or clears an error for a form field.\n */\n public setFormFieldError(formId: string, fieldName: string, error: string | null): this {\n const form = this.getForm(formId);\n if (error) {\n form.errors[fieldName] = error;\n } else {\n delete form.errors[fieldName];\n }\n form.isValid = Object.keys(form.errors).length === 0;\n\n this.set(`forms.${formId}.errors`, { ...form.errors });\n this.set(`forms.${formId}.isValid`, form.isValid);\n return this;\n }\n\n /**\n * Marks a form field as touched (or untouched).\n */\n public setFormFieldTouched(formId: string, fieldName: string, touched: boolean = true): this {\n const form = this.getForm(formId);\n form.touched[fieldName] = touched;\n\n this.set(`forms.${formId}.touched.${fieldName}`, touched);\n return this;\n }\n\n /**\n * Updates multiple form errors simultaneously.\n */\n public setFormErrors(formId: string, errors: Record<string, string>): this {\n const form = this.getForm(formId);\n form.errors = { ...errors };\n form.isValid = Object.keys(errors).length === 0;\n\n this.set(`forms.${formId}.errors`, form.errors);\n this.set(`forms.${formId}.isValid`, form.isValid);\n return this;\n }\n\n /**\n * Sets multiple form field values simultaneously.\n */\n public setFormValues(\n formId: string,\n values: Record<string, unknown>,\n replace: boolean = false,\n ): this {\n const form = this.getForm(formId);\n form.values = replace ? { ...values } : { ...form.values, ...values };\n form.dirty = Object.keys(form.values).some((k) => form.values[k] !== form.initialValues?.[k]);\n\n this.set(`forms.${formId}.values`, { ...form.values });\n this.set(`forms.${formId}.dirty`, form.dirty);\n return this;\n }\n\n /**\n * Sets the submitting status of a form.\n */\n public setFormSubmitting(formId: string, isSubmitting: boolean): this {\n const form = this.getForm(formId);\n form.isSubmitting = isSubmitting;\n\n this.set(`forms.${formId}.isSubmitting`, isSubmitting);\n return this;\n }\n\n /**\n * Resets a form's values, errors, touched, and submitting state to defaults or specified values.\n */\n public resetForm(formId: string, initialValues?: Record<string, unknown>): this {\n const newFormState = createDefaultFormState(\n initialValues || this.state.forms[formId]?.initialValues,\n );\n this.set(`forms.${formId}`, newFormState);\n return this;\n }\n\n // ==========================================\n // Scoping & Isolation\n // ==========================================\n\n /**\n * Creates an isolated child scope store for a page or component container.\n */\n public createScope(scopeId: string, initialValues?: Record<string, unknown>): RuntimeStateStore {\n const scopedState: Partial<RuntimeStoreState> = {\n variables: { ...(initialValues || {}) },\n forms: {},\n state: {},\n };\n return new RuntimeStateStore(scopedState);\n }\n}\n\n/**\n * Factory function to create a new RuntimeStateStore instance.\n */\nexport function createRuntimeStore(initialState?: Partial<RuntimeStoreState>): RuntimeStateStore {\n return new RuntimeStateStore(initialState);\n}\n\n","import type {\n TrackingConfig,\n MetaTrackingProviderConfig,\n GoogleTrackingProviderConfig,\n TikTokTrackingProviderConfig,\n CustomTrackingProviderConfig,\n MetaTrackingSecrets,\n GoogleTrackingSecrets,\n TikTokTrackingSecrets,\n CustomTrackingSecrets,\n TrackingProviderSecrets,\n ServerTrackingProviderType,\n TrackEventProvider,\n} from '@kubuild/schema';\n\n/**\n * Reference passed to a host `TrackingSecretResolver`. `credentialId` comes from the trusted\n * tracking config (`providers.<provider>.credentialId`), never from an untrusted request.\n */\nexport interface TrackingSecretRef {\n provider: ServerTrackingProviderType;\n credentialId?: string;\n documentId?: string;\n}\n\n/**\n * Host-provided function that returns the secret material for one provider, or `null` when the\n * host has none. Implement it against any secret store (env vars, KMS, DB, Vault, ...).\n * A missing secret makes the provider be skipped with a reason — it never throws.\n */\nexport type TrackingSecretResolver = (\n ref: TrackingSecretRef,\n) => Promise<TrackingProviderSecrets | null | undefined> | TrackingProviderSecrets | null | undefined;\n\n/**\n * Normalized Server Tracking Event\n */\nexport interface ServerTrackingEvent {\n eventName: string;\n eventType?: 'standard' | 'custom';\n eventId?: string;\n eventTime?: number;\n eventSourceUrl?: string;\n actionSource?: 'website' | 'app' | 'system_generated';\n params?: Record<string, unknown>;\n userData?: {\n email?: string;\n phone?: string;\n firstName?: string;\n lastName?: string;\n gender?: string;\n dateOfBirth?: string;\n city?: string;\n state?: string;\n zip?: string;\n country?: string;\n clientIp?: string;\n clientUserAgent?: string;\n fbp?: string;\n fbc?: string;\n externalId?: string;\n [key: string]: unknown;\n };\n customData?: Record<string, unknown>;\n}\n\n/**\n * Result of a single provider delivery\n */\nexport interface TrackingDeliveryResult {\n provider: string;\n success: boolean;\n status?: number;\n data?: unknown;\n error?: string;\n skipped?: boolean;\n /** Why the provider was skipped (e.g. no secret resolved). */\n reason?: string;\n}\n\n/**\n * Aggregate result from dispatchServerTracking\n */\nexport interface ServerTrackingDispatchResult {\n success: boolean;\n eventId: string;\n skipped?: boolean;\n reason?: string;\n results: Record<string, TrackingDeliveryResult>;\n}\n\n/**\n * Options for configuring server tracking dispatch\n */\nexport interface ServerTrackingOptions {\n /**\n * Resolves provider secrets by `credentialId`. The ONLY way secrets reach the dispatcher —\n * the document never contains them. Without it, every server provider is skipped.\n */\n resolveSecrets?: TrackingSecretResolver;\n /** Host document id, forwarded to `resolveSecrets`. */\n documentId?: string;\n /** Restrict dispatch to one provider ('all' by default). 'gtm' is client-only. */\n provider?: TrackEventProvider;\n fetchFn?: typeof fetch;\n clientIp?: string;\n clientUserAgent?: string;\n sourceUrl?: string;\n simulateInDebug?: boolean;\n onLog?: (message: string, data?: unknown) => void;\n}\n\n/**\n * Normalizes an email string (lowercase, trim) according to Meta CAPI specification.\n */\nexport function normalizeEmail(email: string): string {\n return (email || '').trim().toLowerCase();\n}\n\n/**\n * Normalizes a phone number (removes non-digits, strips leading zeros if needed) per CAPI spec.\n */\nexport function normalizePhone(phone: string): string {\n return (phone || '').replace(/[^0-9]/g, '');\n}\n\n/**\n * Normalizes text names (trim, lowercase).\n */\nexport function normalizeText(text: string): string {\n return (text || '').trim().toLowerCase();\n}\n\n/**\n * Generates a SHA-256 hash formatted as a hex string.\n * Uses universal Web Crypto API (supported in Node 18+, Bun, Deno, and modern browsers).\n */\nexport async function hashSha256(value: string): Promise<string> {\n const normalized = (value || '').trim();\n if (!normalized) return '';\n\n if (typeof globalThis.crypto?.subtle?.digest === 'function') {\n const encoder = new TextEncoder();\n const data = encoder.encode(normalized);\n const hashBuffer = await globalThis.crypto.subtle.digest('SHA-256', data);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n return hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');\n }\n\n // Fallback for environments where crypto.subtle is not accessible\n throw new Error('Web Crypto API (crypto.subtle) is not available in current runtime environment.');\n}\n\n/**\n * Generates a unique deduplication event ID.\n */\nexport function generateTrackingEventId(prefix = 'evt'): string {\n const timestamp = Date.now().toString(36);\n const randomPart = Math.random().toString(36).substring(2, 10);\n return `${prefix}_${timestamp}_${randomPart}`;\n}\n\n/**\n * Dispatches an event to Meta Conversions API (CAPI).\n * Spec: https://developers.facebook.com/docs/marketing-api/conversions-api\n */\nexport async function sendMetaCapiEvent(\n event: ServerTrackingEvent,\n config: MetaTrackingProviderConfig,\n secrets: MetaTrackingSecrets | null | undefined,\n options?: ServerTrackingOptions,\n): Promise<TrackingDeliveryResult> {\n const fetcher = options?.fetchFn || globalThis.fetch;\n if (!config.pixelId) {\n return {\n provider: 'meta',\n success: false,\n error: 'Meta Pixel ID is missing',\n };\n }\n\n // Prepare hashed user data\n const rawUserData = event.userData || {};\n const hashedUserData: Record<string, unknown> = {};\n\n if (rawUserData.email) {\n hashedUserData.em = [await hashSha256(normalizeEmail(String(rawUserData.email)))];\n }\n if (rawUserData.phone) {\n hashedUserData.ph = [await hashSha256(normalizePhone(String(rawUserData.phone)))];\n }\n if (rawUserData.firstName) {\n hashedUserData.fn = [await hashSha256(normalizeText(String(rawUserData.firstName)))];\n }\n if (rawUserData.lastName) {\n hashedUserData.ln = [await hashSha256(normalizeText(String(rawUserData.lastName)))];\n }\n if (rawUserData.city) {\n hashedUserData.ct = [await hashSha256(normalizeText(String(rawUserData.city)))];\n }\n if (rawUserData.state) {\n hashedUserData.st = [await hashSha256(normalizeText(String(rawUserData.state)))];\n }\n if (rawUserData.zip) {\n hashedUserData.zp = [await hashSha256(normalizeText(String(rawUserData.zip)))];\n }\n if (rawUserData.country) {\n hashedUserData.country = [await hashSha256(normalizeText(String(rawUserData.country)))];\n }\n\n // Client IP & User Agent (unhashed per Meta spec)\n const clientIp = rawUserData.clientIp || options?.clientIp;\n if (clientIp) hashedUserData.client_ip_address = clientIp;\n\n const clientUserAgent = rawUserData.clientUserAgent || options?.clientUserAgent;\n if (clientUserAgent) hashedUserData.client_user_agent = clientUserAgent;\n\n if (rawUserData.fbp) hashedUserData.fbp = rawUserData.fbp;\n if (rawUserData.fbc) hashedUserData.fbc = rawUserData.fbc;\n if (rawUserData.externalId) {\n hashedUserData.external_id = [await hashSha256(String(rawUserData.externalId))];\n }\n\n const eventTime = event.eventTime || Math.floor(Date.now() / 1000);\n const eventSourceUrl = event.eventSourceUrl || options?.sourceUrl;\n\n const capiPayload: Record<string, unknown> = {\n data: [\n {\n event_name: event.eventName,\n event_time: eventTime,\n event_id: event.eventId,\n event_source_url: eventSourceUrl,\n action_source: event.actionSource || 'website',\n user_data: hashedUserData,\n custom_data: {\n ...(event.params || {}),\n ...(event.customData || {}),\n },\n },\n ],\n };\n\n if (config.testEventCode) {\n capiPayload.test_event_code = config.testEventCode;\n }\n\n if (options?.simulateInDebug) {\n options.onLog?.('[Meta CAPI SIMULATED]', capiPayload);\n return { provider: 'meta', success: true, data: { simulated: true, payload: capiPayload } };\n }\n\n try {\n const url = `https://graph.facebook.com/v19.0/${encodeURIComponent(config.pixelId)}/events`;\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n if (!secrets?.capiAccessToken) {\n return skippedResult('meta', 'No Meta CAPI access token resolved for this credential');\n }\n headers['Authorization'] = `Bearer ${secrets.capiAccessToken}`;\n\n const res = await fetcher(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(capiPayload),\n });\n\n const resJson = await res.json().catch(() => ({}));\n if (!res.ok) {\n return {\n provider: 'meta',\n success: false,\n status: res.status,\n error: (resJson as { error?: { message?: string } })?.error?.message || `HTTP ${res.status}`,\n data: resJson,\n };\n }\n\n return {\n provider: 'meta',\n success: true,\n status: res.status,\n data: resJson,\n };\n } catch (err: unknown) {\n return {\n provider: 'meta',\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n}\n\n/**\n * Dispatches an event to TikTok Events API.\n * Spec: https://business-api.tiktok.com/portal/docs\n */\nexport async function sendTikTokEventsApi(\n event: ServerTrackingEvent,\n config: TikTokTrackingProviderConfig,\n secrets: TikTokTrackingSecrets | null | undefined,\n options?: ServerTrackingOptions,\n): Promise<TrackingDeliveryResult> {\n const fetcher = options?.fetchFn || globalThis.fetch;\n if (!config.pixelId) {\n return { provider: 'tiktok', success: false, error: 'TikTok Pixel ID is missing' };\n }\n\n const rawUserData = event.userData || {};\n const user: Record<string, unknown> = {};\n\n if (rawUserData.email) {\n user.email = await hashSha256(normalizeEmail(String(rawUserData.email)));\n }\n if (rawUserData.phone) {\n user.phone_number = await hashSha256(normalizePhone(String(rawUserData.phone)));\n }\n if (rawUserData.clientIp || options?.clientIp) {\n user.ip = rawUserData.clientIp || options?.clientIp;\n }\n if (rawUserData.clientUserAgent || options?.clientUserAgent) {\n user.user_agent = rawUserData.clientUserAgent || options?.clientUserAgent;\n }\n\n const tiktokPayload: Record<string, unknown> = {\n event_source: 'web',\n event_source_id: config.pixelId,\n data: [\n {\n event: event.eventName,\n event_id: event.eventId,\n timestamp: new Date((event.eventTime ? event.eventTime * 1000 : Date.now())).toISOString(),\n user,\n properties: {\n ...(event.params || {}),\n ...(event.customData || {}),\n },\n page: {\n url: event.eventSourceUrl || options?.sourceUrl,\n },\n },\n ],\n };\n\n if (config.testEventCode) {\n tiktokPayload.test_event_code = config.testEventCode;\n }\n\n if (options?.simulateInDebug) {\n options.onLog?.('[TikTok Events API SIMULATED]', tiktokPayload);\n return { provider: 'tiktok', success: true, data: { simulated: true, payload: tiktokPayload } };\n }\n\n try {\n const url = 'https://business-api.tiktok.com/open_api/v1.3/event/track/';\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n if (!secrets?.accessToken) {\n return skippedResult('tiktok', 'No TikTok Events API access token resolved for this credential');\n }\n headers['Access-Token'] = secrets.accessToken;\n\n const res = await fetcher(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(tiktokPayload),\n });\n\n const resJson = await res.json().catch(() => ({}));\n if (!res.ok) {\n return {\n provider: 'tiktok',\n success: false,\n status: res.status,\n error: (resJson as { message?: string })?.message || `HTTP ${res.status}`,\n data: resJson,\n };\n }\n\n return { provider: 'tiktok', success: true, status: res.status, data: resJson };\n } catch (err: unknown) {\n return {\n provider: 'tiktok',\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n}\n\n/**\n * Dispatches an event to Google Analytics 4 Measurement Protocol.\n * Spec: https://developers.google.com/analytics/devguides/collection/protocol/ga4\n */\nexport async function sendGa4MeasurementEvent(\n event: ServerTrackingEvent,\n config: GoogleTrackingProviderConfig,\n secrets: GoogleTrackingSecrets | null | undefined,\n options?: ServerTrackingOptions,\n): Promise<TrackingDeliveryResult> {\n const fetcher = options?.fetchFn || globalThis.fetch;\n if (!config.measurementId) {\n return { provider: 'google', success: false, error: 'GA4 Measurement ID is missing' };\n }\n\n const clientId =\n (event.userData?.clientId as string | undefined) ||\n (event.userData?.externalId as string | undefined) ||\n 'anonymous_client';\n\n const ga4Payload = {\n client_id: clientId,\n events: [\n {\n name: event.eventName.toLowerCase().replace(/[^a-z0-9_]/g, '_'),\n params: {\n ...(event.params || {}),\n ...(event.customData || {}),\n event_id: event.eventId,\n },\n },\n ],\n };\n\n if (options?.simulateInDebug) {\n options.onLog?.('[GA4 Measurement Protocol SIMULATED]', ga4Payload);\n return { provider: 'google', success: true, data: { simulated: true, payload: ga4Payload } };\n }\n\n try {\n if (!secrets?.measurementProtocolSecret) {\n return skippedResult('google', 'No GA4 Measurement Protocol API secret resolved for this credential');\n }\n const url =\n `https://www.google-analytics.com/mp/collect?measurement_id=${encodeURIComponent(config.measurementId)}` +\n `&api_secret=${encodeURIComponent(secrets.measurementProtocolSecret)}`;\n\n const res = await fetcher(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(ga4Payload),\n });\n\n return {\n provider: 'google',\n success: res.ok,\n status: res.status,\n data: { status: res.status },\n };\n } catch (err: unknown) {\n return {\n provider: 'google',\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n}\n\n/**\n * Dispatches an event to a Custom Webhook.\n */\nexport async function sendCustomWebhookEvent(\n event: ServerTrackingEvent,\n _config: CustomTrackingProviderConfig,\n secrets: CustomTrackingSecrets | null | undefined,\n options?: ServerTrackingOptions,\n): Promise<TrackingDeliveryResult> {\n const fetcher = options?.fetchFn || globalThis.fetch;\n\n const webhookPayload = {\n event: event.eventName,\n eventId: event.eventId,\n timestamp: event.eventTime ? event.eventTime * 1000 : Date.now(),\n userData: event.userData,\n params: event.params,\n customData: event.customData,\n sourceUrl: event.eventSourceUrl || options?.sourceUrl,\n };\n\n if (options?.simulateInDebug) {\n options.onLog?.('[Custom Webhook SIMULATED]', webhookPayload);\n return { provider: 'custom', success: true, data: { simulated: true, payload: webhookPayload } };\n }\n\n if (!secrets?.endpointUrl) {\n return skippedResult('custom', 'No custom webhook destination resolved for this credential');\n }\n\n try {\n const res = await fetcher(secrets.endpointUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(secrets.headers || {}),\n },\n body: JSON.stringify(webhookPayload),\n });\n\n const resJson = await res.json().catch(() => ({}));\n return {\n provider: 'custom',\n success: res.ok,\n status: res.status,\n data: resJson,\n };\n } catch (err: unknown) {\n return {\n provider: 'custom',\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n}\n\n\nfunction skippedResult(provider: string, reason: string): TrackingDeliveryResult {\n return { provider, success: true, skipped: true, reason };\n}\n\ntype ProviderTask = {\n key: ServerTrackingProviderType;\n credentialId?: string;\n run: (secrets: TrackingProviderSecrets | null) => Promise<TrackingDeliveryResult>;\n};\n\n/**\n * High-Level Server Tracking Dispatcher (server-side only).\n *\n * Evaluates the master toggle, selects enabled server providers, resolves each provider's\n * secrets through `options.resolveSecrets` (keyed by the `credentialId` in the trusted\n * config) and dispatches in parallel. A provider without a resolved secret is skipped with a\n * `reason` — this function never throws for missing secrets.\n *\n * Never call this from the browser: the renderer posts to a host relay instead\n * (see `createTrackingRelayHandler`).\n */\nexport async function dispatchServerTracking(\n event: ServerTrackingEvent,\n config?: TrackingConfig,\n options?: ServerTrackingOptions,\n): Promise<ServerTrackingDispatchResult> {\n const eventId = event.eventId || generateTrackingEventId();\n const eventWithId: ServerTrackingEvent = { ...event, eventId };\n\n // 1. Dynamic master toggle check: if tracking is disabled, cleanly return without any network activity\n if (!config || config.enabled === false) {\n return {\n success: true,\n eventId,\n skipped: true,\n reason: 'Tracking is disabled globally',\n results: {},\n };\n }\n\n const isDebug = Boolean(config.debugMode);\n const simulate = isDebug && options?.simulateInDebug !== false;\n\n const mergedOptions: ServerTrackingOptions = {\n ...options,\n simulateInDebug: simulate,\n onLog: (msg, data) => {\n if (isDebug) {\n // eslint-disable-next-line no-console\n console.log(`[KUBUILD Tracking] ${msg}`, data || '');\n }\n options?.onLog?.(msg, data);\n },\n };\n\n const target = options?.provider || 'all';\n const wants = (key: ServerTrackingProviderType) => target === 'all' || target === key;\n const providers = config.providers || {};\n const tasks: ProviderTask[] = [];\n\n const meta = providers.meta;\n if (wants('meta') && meta && meta.enabled !== false && meta.capiEnabled) {\n tasks.push({\n key: 'meta',\n credentialId: meta.credentialId,\n run: (s) => sendMetaCapiEvent(eventWithId, meta, s as MetaTrackingSecrets | null, mergedOptions),\n });\n }\n\n const tiktok = providers.tiktok;\n if (wants('tiktok') && tiktok && tiktok.enabled !== false && tiktok.eventsApiEnabled) {\n tasks.push({\n key: 'tiktok',\n credentialId: tiktok.credentialId,\n run: (s) => sendTikTokEventsApi(eventWithId, tiktok, s as TikTokTrackingSecrets | null, mergedOptions),\n });\n }\n\n const google = providers.google;\n if (wants('google') && google && google.enabled !== false && google.measurementId) {\n tasks.push({\n key: 'google',\n credentialId: google.credentialId,\n run: (s) => sendGa4MeasurementEvent(eventWithId, google, s as GoogleTrackingSecrets | null, mergedOptions),\n });\n }\n\n const custom = providers.custom;\n if (wants('custom') && custom && custom.enabled !== false) {\n tasks.push({\n key: 'custom',\n credentialId: custom.credentialId,\n run: (s) => sendCustomWebhookEvent(eventWithId, custom, s as CustomTrackingSecrets | null, mergedOptions),\n });\n }\n\n if (tasks.length === 0) {\n return {\n success: true,\n eventId,\n skipped: true,\n reason:\n target === 'gtm'\n ? 'GTM is client-side only (dataLayer); no server delivery'\n : 'No server-side tracking provider is enabled',\n results: {},\n };\n }\n\n const resolve = options?.resolveSecrets;\n\n const runTask = async (task: ProviderTask): Promise<TrackingDeliveryResult> => {\n let secrets: TrackingProviderSecrets | null = null;\n if (resolve) {\n try {\n secrets =\n (await resolve({ provider: task.key, credentialId: task.credentialId, documentId: options?.documentId })) ??\n null;\n } catch (err: unknown) {\n return {\n provider: task.key,\n success: false,\n error: `Secret resolution failed: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n }\n\n // In debug simulation we still build the payload (no network), even without secrets.\n if (!secrets && !simulate) {\n const reason = resolve\n ? `No secret resolved for provider \"${task.key}\"${task.credentialId ? ` (credentialId \"${task.credentialId}\")` : ' (no credentialId linked)'}`\n : 'No secret resolver configured (options.resolveSecrets)';\n mergedOptions.onLog?.(`[${task.key}] skipped: ${reason}`);\n return skippedResult(task.key, reason);\n }\n\n return task.run(secrets);\n };\n\n const settled = await Promise.allSettled(tasks.map((task) => runTask(task)));\n const results: Record<string, TrackingDeliveryResult> = {};\n let overallSuccess = true;\n let delivered = 0;\n\n settled.forEach((item, index) => {\n const key = tasks[index].key;\n if (item.status === 'fulfilled') {\n results[key] = item.value;\n if (!item.value.success) overallSuccess = false;\n if (!item.value.skipped) delivered++;\n } else {\n overallSuccess = false;\n results[key] = {\n provider: key,\n success: false,\n error: item.reason instanceof Error ? item.reason.message : String(item.reason),\n };\n }\n });\n\n const allSkipped = delivered === 0 && overallSuccess;\n\n return {\n success: overallSuccess,\n eventId,\n ...(allSkipped ? { skipped: true, reason: 'All server providers were skipped' } : {}),\n results,\n };\n}\n","import {\n TRACKING_RELAY_PROTOCOL_VERSION,\n TrackingRelayRequestSchema,\n type TrackingConfig,\n type TrackEventProvider,\n type TrackingRelayErrorCode,\n type TrackingRelayProviderResult,\n type TrackingRelayRequest,\n type TrackingRelayResponse,\n} from '@kubuild/schema';\nimport {\n dispatchServerTracking,\n type ServerTrackingEvent,\n type TrackingSecretResolver,\n} from './server-tracking';\n\n/** Context handed to `getConfig` — use it to look up the trusted config for this page. */\nexport interface TrackingRelayConfigContext {\n request: Request;\n /** Untrusted hint from the request body; use it only as a lookup key you authorize. */\n documentId?: string;\n /** Untrusted hint from the request body. */\n credentialId?: string;\n provider: TrackEventProvider;\n}\n\nexport interface CreateTrackingRelayHandlerOptions {\n /**\n * Loads the tracking config from the HOST (database, published page, env, ...).\n * The relay never trusts a config sent in the request body. Return `null` if unknown.\n */\n getConfig: (\n ctx: TrackingRelayConfigContext,\n ) => Promise<TrackingConfig | null | undefined> | TrackingConfig | null | undefined;\n /** Resolves provider secrets by `credentialId` (from the trusted config). */\n resolveSecrets: TrackingSecretResolver;\n /**\n * Allowed browser origins. When set, requests whose `Origin` header is missing or not in\n * the list are rejected with 403, and CORS headers are returned for allowed origins.\n */\n allowedOrigins?: readonly string[] | ((origin: string) => boolean);\n fetchFn?: typeof fetch;\n /** Override client IP extraction (defaults to x-forwarded-for / x-real-ip / cf-connecting-ip). */\n getClientIp?: (request: Request) => string | undefined;\n /** Max accepted body size in bytes (default 64 KiB). */\n maxBodyBytes?: number;\n onLog?: (message: string, data?: unknown) => void;\n}\n\nconst DEFAULT_MAX_BODY_BYTES = 64 * 1024;\n\nfunction defaultClientIp(request: Request): string | undefined {\n const forwarded = request.headers.get('x-forwarded-for');\n if (forwarded) {\n const first = forwarded.split(',')[0]?.trim();\n if (first) return first;\n }\n return (\n request.headers.get('cf-connecting-ip')?.trim() ||\n request.headers.get('x-real-ip')?.trim() ||\n undefined\n );\n}\n\nfunction isOriginAllowed(\n origin: string | null,\n allowed: CreateTrackingRelayHandlerOptions['allowedOrigins'],\n): boolean {\n if (!allowed) return true;\n if (!origin) return false;\n if (typeof allowed === 'function') return allowed(origin);\n return allowed.includes(origin);\n}\n\n/**\n * Creates a reference tracking relay endpoint using only Web-standard `Request`/`Response`\n * (works in Next.js route handlers, Hono, Bun, Deno, Cloudflare Workers, Node 18+ adapters).\n *\n * Flow: validate origin -> validate body with `TrackingRelayRequestSchema` -> load the trusted\n * config via `getConfig` -> attach client IP / UA from request headers -> `dispatchServerTracking`\n * with `resolveSecrets`. The response follows `TrackingRelayResponseSchema` and never echoes\n * provider response bodies.\n *\n * Non-JS backends can implement the same protocol — see `getTrackingRelayRequestJsonSchema()`.\n */\nexport function createTrackingRelayHandler(options: CreateTrackingRelayHandlerOptions) {\n const maxBodyBytes = options.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES;\n\n return async (request: Request): Promise<Response> => {\n const origin = request.headers.get('origin');\n const corsHeaders: Record<string, string> = {};\n if (options.allowedOrigins && origin && isOriginAllowed(origin, options.allowedOrigins)) {\n corsHeaders['Access-Control-Allow-Origin'] = origin;\n corsHeaders['Vary'] = 'Origin';\n }\n\n const json = (body: TrackingRelayResponse, status: number, extra?: Record<string, string>) =>\n new Response(JSON.stringify(body), {\n status,\n headers: { 'Content-Type': 'application/json', ...corsHeaders, ...(extra || {}) },\n });\n\n const fail = (code: TrackingRelayErrorCode, message: string, status: number, extra?: Record<string, string>) =>\n json({ version: TRACKING_RELAY_PROTOCOL_VERSION, success: false, error: { code, message } }, status, extra);\n\n if (!isOriginAllowed(origin, options.allowedOrigins)) {\n return fail('FORBIDDEN_ORIGIN', 'Origin is not allowed', 403);\n }\n\n if (request.method === 'OPTIONS') {\n return new Response(null, {\n status: 204,\n headers: {\n ...corsHeaders,\n 'Access-Control-Allow-Methods': 'POST, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type',\n 'Access-Control-Max-Age': '600',\n },\n });\n }\n\n if (request.method !== 'POST') {\n return fail('METHOD_NOT_ALLOWED', 'Only POST requests are accepted', 405, { Allow: 'POST, OPTIONS' });\n }\n\n try {\n const text = await request.text();\n if (text.length > maxBodyBytes) {\n return fail('INVALID_REQUEST', `Request body exceeds ${maxBodyBytes} bytes`, 413);\n }\n\n let raw: unknown;\n try {\n raw = JSON.parse(text);\n } catch {\n return fail('INVALID_REQUEST', 'Request body must be valid JSON', 400);\n }\n\n if (\n raw &&\n typeof raw === 'object' &&\n 'version' in raw &&\n (raw as { version: unknown }).version !== TRACKING_RELAY_PROTOCOL_VERSION\n ) {\n return fail(\n 'UNSUPPORTED_VERSION',\n `Unsupported relay protocol version; expected ${TRACKING_RELAY_PROTOCOL_VERSION}`,\n 400,\n );\n }\n\n const parsed = TrackingRelayRequestSchema.safeParse(raw);\n if (!parsed.success) {\n const issues = parsed.error.issues\n .slice(0, 5)\n .map((i) => `${i.path.join('.') || '(root)'}: ${i.message}`)\n .join('; ');\n return fail('INVALID_REQUEST', `Invalid relay request: ${issues}`, 400);\n }\n const body: TrackingRelayRequest = parsed.data;\n\n // Trusted config comes from the host, never from the body.\n const config = await options.getConfig({\n request,\n documentId: body.documentId,\n credentialId: body.credentialId,\n provider: body.provider,\n });\n if (!config) {\n return fail('CONFIG_NOT_FOUND', 'No tracking configuration found for this page', 404);\n }\n\n const clientIp = (options.getClientIp ?? defaultClientIp)(request);\n const clientUserAgent = request.headers.get('user-agent') || undefined;\n\n // Client-supplied network identity is not trusted; use what the server observed.\n const userData = { ...(body.event.userData || {}) } as NonNullable<ServerTrackingEvent['userData']>;\n delete userData.clientIp;\n delete userData.clientUserAgent;\n\n const event: ServerTrackingEvent = { ...body.event, userData };\n\n const outcome = await dispatchServerTracking(event, config, {\n resolveSecrets: options.resolveSecrets,\n documentId: body.documentId,\n provider: body.provider,\n fetchFn: options.fetchFn,\n clientIp,\n clientUserAgent,\n onLog: options.onLog,\n });\n\n const results: Record<string, TrackingRelayProviderResult> = {};\n for (const [key, r] of Object.entries(outcome.results)) {\n results[key] = {\n provider: r.provider,\n success: r.success,\n ...(r.status !== undefined ? { status: r.status } : {}),\n ...(r.skipped ? { skipped: true } : {}),\n ...(r.reason ? { reason: r.reason } : {}),\n ...(r.error ? { error: r.error } : {}),\n };\n }\n\n return json(\n {\n version: TRACKING_RELAY_PROTOCOL_VERSION,\n success: outcome.success,\n eventId: outcome.eventId,\n ...(outcome.skipped ? { skipped: true } : {}),\n ...(outcome.reason ? { reason: outcome.reason } : {}),\n results,\n },\n 200,\n );\n } catch (err: unknown) {\n options.onLog?.('[Tracking relay] internal error', err);\n return fail('INTERNAL_ERROR', 'Tracking relay failed', 500);\n }\n };\n}\n","import { zipSync, strToU8 } from 'fflate';\nimport {\n PageDocument,\n DocumentMetadata,\n Manifest,\n ManifestAssetItem,\n SCHEMA_NAME,\n CURRENT_SCHEMA_VERSION,\n} from '@kubuild/schema';\nimport {\n validateDocument,\n DocumentValidationError,\n ValidationOptions,\n ComponentRegistryLike,\n} from '../validation/validator';\nimport {\n collectAssetReferences,\n extractRequirementsFromTree,\n CollectedAssetReference,\n} from '../document/document-utils';\nimport type { AssetProvider } from '../types/interfaces';\nimport { stripDocumentTrackingSecretsInPlace } from './tracking-sanitizer';\n\nexport interface ExportAssetData {\n data: Uint8Array | ArrayBuffer | Blob | string;\n mimeType?: string;\n filename?: string;\n}\n\nexport type AssetBytesProvider = (\n assetId: string,\n assetRef: CollectedAssetReference,\n) =>\n | Promise<Uint8Array | ArrayBuffer | Blob | string | ExportAssetData | null | undefined>\n | Uint8Array\n | ArrayBuffer\n | Blob\n | string\n | ExportAssetData\n | null\n | undefined;\n\nexport interface ExportPackageOptions {\n /**\n * Component registry to validate document components and extract requirements.\n */\n componentRegistry?: ComponentRegistryLike;\n\n /**\n * Known component types if registry is not passed.\n */\n knownComponentTypes?: string[] | Set<string>;\n\n /**\n * Directly supplied asset binary map (keyed by assetId).\n */\n assets?:\n | Record<string, Uint8Array | ArrayBuffer | Blob | string | ExportAssetData>\n | Map<string, Uint8Array | ArrayBuffer | Blob | string | ExportAssetData>;\n\n /**\n * Host function to retrieve asset binary data dynamically.\n */\n getAssetBytes?: AssetBytesProvider;\n\n /**\n * Host AssetProvider instance to resolve assets if bytes provider is not present.\n */\n assetProvider?: AssetProvider;\n\n /**\n * Package version to write in manifest (defaults to \"1.0.0\").\n */\n packageVersion?: string;\n\n /**\n * Builder compatibility semver range (defaults to \">=0.1.0\").\n */\n builderCompatibility?: string;\n\n /**\n * If true, assets that have a fallbackUrl or are externally hosted will not cause export failure if local bytes are missing.\n * If false and a referenced asset has no bytes available, export fails.\n */\n allowExternalFallback?: boolean;\n\n /**\n * Additional validation options passed to validateDocument.\n */\n validationOptions?: ValidationOptions;\n\n /**\n * Optional metadata overrides (e.g. author, tags).\n */\n metadata?: Partial<DocumentMetadata>;\n}\n\nexport interface ExportPackageSuccess {\n success: true;\n archive: Uint8Array;\n manifest: Manifest;\n page: PageDocument;\n metadata: DocumentMetadata;\n assetCount: number;\n}\n\nexport interface ExportPackageFailure {\n success: false;\n errors: DocumentValidationError[];\n diagnosticMessage: string;\n}\n\nexport type ExportPackageResult = ExportPackageSuccess | ExportPackageFailure;\n\n/**\n * Pure TypeScript SHA-256 implementation (zero native dependencies, deterministic).\n */\nexport function sha256Sync(data: Uint8Array): string {\n const K = [\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\n ];\n\n let h0 = 0x6a09e667;\n let h1 = 0xbb67ae85;\n let h2 = 0x3c6ef372;\n let h3 = 0xa54ff53a;\n let h4 = 0x510e527f;\n let h5 = 0x9b05688c;\n let h6 = 0x1f83d9ab;\n let h7 = 0x5be0cd19;\n\n const length = data.length;\n const bitLength = length * 8;\n const newLength = ((length + 9 + 63) >>> 6) << 6;\n const padded = new Uint8Array(newLength);\n padded.set(data);\n padded[length] = 0x80;\n\n const view = new DataView(padded.buffer);\n view.setUint32(newLength - 4, bitLength >>> 0, false);\n view.setUint32(newLength - 8, Math.floor(bitLength / 0x100000000), false);\n\n const w = new Uint32Array(64);\n\n for (let chunk = 0; chunk < newLength; chunk += 64) {\n for (let i = 0; i < 16; i++) {\n w[i] = view.getUint32(chunk + i * 4, false);\n }\n for (let i = 16; i < 64; i++) {\n const s0 =\n ((w[i - 15] >>> 7) | (w[i - 15] << 25)) ^\n ((w[i - 15] >>> 18) | (w[i - 15] << 14)) ^\n (w[i - 15] >>> 3);\n const s1 =\n ((w[i - 2] >>> 17) | (w[i - 2] << 15)) ^\n ((w[i - 2] >>> 19) | (w[i - 2] << 13)) ^\n (w[i - 2] >>> 10);\n w[i] = (w[i - 16] + s0 + w[i - 7] + s1) >>> 0;\n }\n\n let a = h0;\n let b = h1;\n let c = h2;\n let d = h3;\n let e = h4;\n let f = h5;\n let g = h6;\n let h = h7;\n\n for (let i = 0; i < 64; i++) {\n const S1 = ((e >>> 6) | (e << 26)) ^ ((e >>> 11) | (e << 21)) ^ ((e >>> 25) | (e << 7));\n const ch = (e & f) ^ (~e & g);\n const temp1 = (h + S1 + ch + K[i] + w[i]) >>> 0;\n const S0 = ((a >>> 2) | (a << 30)) ^ ((a >>> 13) | (a << 19)) ^ ((a >>> 22) | (a << 10));\n const maj = (a & b) ^ (a & c) ^ (b & c);\n const temp2 = (S0 + maj) >>> 0;\n\n h = g;\n g = f;\n f = e;\n e = (d + temp1) >>> 0;\n d = c;\n c = b;\n b = a;\n a = (temp1 + temp2) >>> 0;\n }\n\n h0 = (h0 + a) >>> 0;\n h1 = (h1 + b) >>> 0;\n h2 = (h2 + c) >>> 0;\n h3 = (h3 + d) >>> 0;\n h4 = (h4 + e) >>> 0;\n h5 = (h5 + f) >>> 0;\n h6 = (h6 + g) >>> 0;\n h7 = (h7 + h) >>> 0;\n }\n\n const result = [h0, h1, h2, h3, h4, h5, h6, h7]\n .map((val) => val.toString(16).padStart(8, '0'))\n .join('');\n\n return result;\n}\n\n/**\n * Compute SHA-256 checksum with \"sha256:\" prefix.\n */\nexport async function calculateChecksum(data: Uint8Array): Promise<string> {\n if (typeof globalThis !== 'undefined' && globalThis.crypto?.subtle?.digest) {\n try {\n const buffer = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength) as ArrayBuffer;\n const hashBuffer = await globalThis.crypto.subtle.digest('SHA-256', buffer);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');\n return `sha256:${hashHex}`;\n } catch {\n // fallback to sync implementation\n }\n }\n return `sha256:${sha256Sync(data)}`;\n}\n\n\n/**\n * Sanitize asset file names to prevent zip-slip or directory traversal vulnerabilities.\n */\nexport function sanitizeFilename(filename: string | undefined, assetId: string, mimeType?: string): string {\n let name = (filename || '').trim();\n\n // Strip path traversal characters and directory separators\n name = name.replace(/^[./\\\\]+/, '').replace(/[/\\\\]+/g, '_').replace(/\\0/g, '');\n name = name.replace(/[^a-zA-Z0-9._-]/g, '_');\n\n if (!name || name === '.' || name === '..') {\n const ext = getExtensionFromMime(mimeType) || 'bin';\n const cleanId = assetId.replace(/[^a-zA-Z0-9_-]/g, '_');\n name = `${cleanId}.${ext}`;\n }\n\n return name;\n}\n\nfunction getExtensionFromMime(mimeType?: string): string | null {\n if (!mimeType) return null;\n const m = mimeType.toLowerCase();\n if (m.includes('png')) return 'png';\n if (m.includes('jpeg') || m.includes('jpg')) return 'jpg';\n if (m.includes('webp')) return 'webp';\n if (m.includes('svg')) return 'svg';\n if (m.includes('gif')) return 'gif';\n if (m.includes('json')) return 'json';\n if (m.includes('pdf')) return 'pdf';\n if (m.includes('mp4')) return 'mp4';\n if (m.includes('mp3')) return 'mp3';\n return null;\n}\n\nasync function convertToUint8Array(input: unknown): Promise<Uint8Array | null> {\n if (!input) return null;\n\n if (input instanceof Uint8Array) {\n return input;\n }\n\n if (input instanceof ArrayBuffer) {\n return new Uint8Array(input);\n }\n\n if (typeof Blob !== 'undefined' && input instanceof Blob) {\n const arrayBuffer = await input.arrayBuffer();\n return new Uint8Array(arrayBuffer);\n }\n\n if (typeof input === 'string') {\n // Check if data URL\n if (input.startsWith('data:')) {\n const commaIdx = input.indexOf(',');\n if (commaIdx !== -1) {\n const meta = input.substring(0, commaIdx);\n const rawData = input.substring(commaIdx + 1);\n if (meta.includes(';base64')) {\n if (typeof atob === 'function') {\n const binary = atob(rawData);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n }\n }\n }\n }\n return new TextEncoder().encode(input);\n }\n\n return null;\n}\n\n/**\n * Validates document, collects asset references, resolves local asset bytes,\n * writes manifest.json, page.json, metadata.json, and packages everything into a .stora archive.\n */\nexport async function exportPackage(\n document: unknown,\n options: ExportPackageOptions = {},\n): Promise<ExportPackageResult> {\n // 1. Validate the Document\n const validation = validateDocument(document, {\n componentRegistry: options.componentRegistry,\n knownComponentTypes: options.knownComponentTypes,\n ...options.validationOptions,\n });\n\n if (!validation.valid || !validation.data) {\n const diagnosticMessage = `Document validation failed with ${validation.errors.length} error(s):\\n` +\n validation.errors.map((e) => `[${e.code}] ${e.path}: ${e.message}`).join('\\n');\n\n return {\n success: false,\n errors: validation.errors,\n diagnosticMessage,\n };\n }\n\n const pageDoc: PageDocument = JSON.parse(JSON.stringify(validation.data));\n // Defensive: a shareable .stora package must never carry tracking secrets.\n stripDocumentTrackingSecretsInPlace(pageDoc);\n\n // Merge optional metadata overrides safely\n if (options.metadata) {\n pageDoc.metadata = {\n ...(pageDoc.metadata || {\n title: 'Untitled Page',\n description: '',\n author: '',\n tags: [],\n category: 'general',\n version: '1.0.0',\n }),\n ...options.metadata,\n updatedAt: new Date().toISOString(),\n };\n }\n\n // 2. Collect Asset References from the document tree\n const collectedAssets = collectAssetReferences(pageDoc.document);\n const assetRefsById = new Map<string, CollectedAssetReference>();\n for (const item of collectedAssets) {\n if (!assetRefsById.has(item.assetId)) {\n assetRefsById.set(item.assetId, item);\n }\n }\n\n // 3. Extract Component and Capability Requirements\n const requirements = extractRequirementsFromTree(pageDoc.document, options.componentRegistry);\n\n // 4. Resolve Asset Bytes and build Manifest Assets\n const manifestAssets: ManifestAssetItem[] = [];\n const archiveFiles: Record<string, Uint8Array> = {};\n const assetCollectionErrors: DocumentValidationError[] = [];\n const usedArchivePaths = new Set<string>();\n\n for (const [assetId, assetRef] of assetRefsById.entries()) {\n let rawAsset: Uint8Array | ArrayBuffer | Blob | string | ExportAssetData | null | undefined;\n let customMime: string | undefined = assetRef.reference.mimeType;\n let customFilename: string | undefined = assetRef.reference.filename;\n\n // Check options.assets map/record\n if (options.assets) {\n if (options.assets instanceof Map) {\n rawAsset = options.assets.get(assetId);\n } else if (typeof options.assets === 'object' && assetId in options.assets) {\n rawAsset = options.assets[assetId];\n }\n }\n\n // Check options.getAssetBytes\n if (!rawAsset && options.getAssetBytes) {\n try {\n rawAsset = await options.getAssetBytes(assetId, assetRef);\n } catch (err) {\n assetCollectionErrors.push({\n code: 'INVALID_ASSET_REFERENCE',\n message: `Failed to retrieve asset bytes for \"${assetId}\": ${err instanceof Error ? err.message : String(err)}`,\n path: assetRef.propPath,\n nodeId: assetRef.nodeId,\n });\n continue;\n }\n }\n\n // Check options.assetProvider\n if (!rawAsset && options.assetProvider?.resolve) {\n try {\n const resolved = await options.assetProvider.resolve(assetId);\n if (resolved) {\n rawAsset = resolved;\n }\n } catch {\n // Continue to fallback check\n }\n }\n\n // Unpack ExportAssetData if provided\n let dataToConvert: unknown = rawAsset;\n if (rawAsset && typeof rawAsset === 'object' && 'data' in rawAsset) {\n const assetObj = rawAsset as ExportAssetData;\n dataToConvert = assetObj.data;\n if (assetObj.mimeType) customMime = assetObj.mimeType;\n if (assetObj.filename) customFilename = assetObj.filename;\n }\n\n const assetBytes = await convertToUint8Array(dataToConvert);\n\n if (assetBytes) {\n // Local asset found and collected\n const sanitizedName = sanitizeFilename(customFilename, assetId, customMime);\n let archivePath = `assets/${sanitizedName}`;\n\n // Avoid collision inside archive\n let counter = 1;\n while (usedArchivePaths.has(archivePath)) {\n const extDot = sanitizedName.lastIndexOf('.');\n if (extDot !== -1) {\n archivePath = `assets/${sanitizedName.substring(0, extDot)}_${counter}${sanitizedName.substring(extDot)}`;\n } else {\n archivePath = `assets/${sanitizedName}_${counter}`;\n }\n counter++;\n }\n usedArchivePaths.add(archivePath);\n\n const mimeType = customMime || 'application/octet-stream';\n const checksum = await calculateChecksum(assetBytes);\n\n manifestAssets.push({\n id: assetId,\n path: archivePath,\n mimeType,\n size: assetBytes.byteLength,\n checksum,\n });\n\n archiveFiles[archivePath] = assetBytes;\n } else {\n // Asset bytes not collected\n const isExternal = Boolean(assetRef.reference.fallbackUrl || options.allowExternalFallback);\n\n if (!isExternal) {\n assetCollectionErrors.push({\n code: 'INVALID_ASSET_REFERENCE',\n message: `Required asset \"${assetId}\" could not be collected for export and has no external fallback`,\n path: assetRef.propPath,\n nodeId: assetRef.nodeId,\n });\n }\n }\n }\n\n // If any required asset could not be collected, abort export\n if (assetCollectionErrors.length > 0) {\n const diagnosticMessage = `Asset collection failed with ${assetCollectionErrors.length} error(s):\\n` +\n assetCollectionErrors.map((e) => `[${e.code}] ${e.path}: ${e.message}`).join('\\n');\n\n return {\n success: false,\n errors: assetCollectionErrors,\n diagnosticMessage,\n };\n }\n\n // 5. Construct Manifest and Metadata\n const metadata: DocumentMetadata = pageDoc.metadata || {\n title: 'Untitled Page',\n description: '',\n author: '',\n tags: [],\n category: 'general',\n version: '1.0.0',\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n };\n\n const manifest: Manifest = {\n schema: SCHEMA_NAME,\n schemaVersion: pageDoc.version || CURRENT_SCHEMA_VERSION,\n packageVersion: options.packageVersion || '1.0.0',\n builderCompatibility: options.builderCompatibility || '>=0.1.0',\n requiredComponents: requirements.requiredComponents,\n requiredCapabilities: requirements.requiredCapabilities,\n assets: manifestAssets,\n createdAt: new Date().toISOString(),\n };\n\n // 6. Write Archive Files\n archiveFiles['manifest.json'] = strToU8(JSON.stringify(manifest, null, 2));\n archiveFiles['page.json'] = strToU8(JSON.stringify(pageDoc, null, 2));\n archiveFiles['metadata.json'] = strToU8(JSON.stringify(metadata, null, 2));\n\n // 7. Compress into .stora ZIP Archive\n const archive = zipSync(archiveFiles, { level: 6 });\n\n return {\n success: true,\n archive,\n manifest,\n page: pageDoc,\n metadata,\n assetCount: manifestAssets.length,\n };\n}\n\n/**\n * Alias for exportPackage.\n */\nexport const exportStoraPackage = exportPackage;\n","import {\n PageDocument,\n PageDocumentSchema,\n SCHEMA_NAME,\n} from '@kubuild/schema';\nimport {\n DocumentSecurityLimits,\n validateDocumentSecurity,\n} from './security';\n\nexport type DocumentValidationErrorCode =\n | 'GLOBAL_SCHEMA_INVALID'\n | 'ROOT_NODE_INVALID'\n | 'NODE_SHAPE_INVALID'\n | 'DUPLICATE_NODE_ID'\n | 'TREE_CYCLE_DETECTED'\n | 'UNKNOWN_COMPONENT_TYPE'\n | 'CHILD_POLICY_VIOLATION'\n | 'INVALID_ASSET_REFERENCE'\n | 'INVALID_VARIABLE_BINDING'\n | 'INVALID_ACTION_BINDING'\n | 'INVALID_METADATA'\n | 'PROTOTYPE_POLLUTION_DETECTED'\n | 'SECURITY_LIMIT_EXCEEDED';\n\nexport interface DocumentValidationError {\n code: DocumentValidationErrorCode;\n message: string;\n path: string;\n nodeId?: string;\n details?: Record<string, unknown>;\n}\n\nexport type DocumentValidationWarningCode =\n | 'CHILD_POLICY_VIOLATION'\n | 'UNKNOWN_COMPONENT_TYPE'\n | 'UNRESOLVED_ASSET_REFERENCE'\n | (string & {});\n\nexport interface DocumentValidationWarning {\n code: DocumentValidationWarningCode;\n message: string;\n path: string;\n nodeId?: string;\n details?: Record<string, unknown>;\n}\n\nexport interface ComponentDefinitionLike {\n type: string;\n category?: string;\n capabilities?: string[];\n acceptsChildren?: boolean;\n allowedChildren?: string[];\n disallowedParents?: string[];\n}\n\nexport interface ComponentRegistryLike {\n get(type: string): ComponentDefinitionLike | undefined;\n has(type: string): boolean;\n}\n\nexport interface ValidationOptions {\n componentRegistry?: ComponentRegistryLike;\n knownComponentTypes?: string[] | Set<string>;\n strictComponentTypes?: boolean;\n /**\n * Whether to treat child policy mismatches (e.g. allowedChildren) strictly as blocking errors.\n * If false or undefined (default), allowedChildren mismatches are emitted as non-blocking warnings.\n */\n strictChildPolicy?: boolean;\n /**\n * Validate asset references (`{ type: 'asset', assetId, fallbackUrl? }`) found in node props.\n * Checks that `assetId` is a non-empty string and `fallbackUrl` (if present) is a string.\n * When `knownAssetIds` is also supplied, every referenced `assetId` must be in that set.\n * Defaults to `true`.\n */\n checkAssetReferences?: boolean;\n /**\n * Known asset IDs used to verify that asset references resolve. A `PageDocument` carries\n * no asset registry of its own (assets live in the `.stora` manifest or the host's asset\n * provider), so this existence check only runs when the caller supplies the IDs.\n * An unresolved reference is an `INVALID_ASSET_REFERENCE` error, or a non-blocking\n * `UNRESOLVED_ASSET_REFERENCE` warning when the reference has a `fallbackUrl`.\n * Ignored when `checkAssetReferences` is `false`.\n */\n knownAssetIds?: string[] | Set<string>;\n /**\n * Validate variable bindings (`{ type: 'variable', key }`) in node props: `key` must be a\n * non-empty string. Defaults to `true`.\n */\n checkVariableBindings?: boolean;\n /**\n * Validate action bindings in node props (a prop named `action`, or any object with a string\n * `type` and a `payload`): `type` must be a non-empty string. Defaults to `true`.\n */\n checkActionBindings?: boolean;\n securityLimits?: DocumentSecurityLimits;\n}\n\nexport interface DocumentValidationResult {\n valid: boolean;\n success: boolean;\n errors: DocumentValidationError[];\n warnings: DocumentValidationWarning[];\n data?: PageDocument;\n}\n\n/**\n * Validate a page document against global schema, node shape, child policy,\n * ID uniqueness, cycles, unknown component types, and structural bindings.\n */\nexport function validateDocument(\n input: unknown,\n options: ValidationOptions = {},\n): DocumentValidationResult {\n const errors: DocumentValidationError[] = [];\n const warnings: DocumentValidationWarning[] = [];\n\n // 1. Basic Object check\n if (!input || typeof input !== 'object' || Array.isArray(input)) {\n return {\n valid: false,\n success: false,\n errors: [\n {\n code: 'GLOBAL_SCHEMA_INVALID',\n message: 'Document must be a valid non-null object',\n path: '',\n },\n ],\n warnings: [],\n };\n }\n\n const doc = input as Record<string, unknown>;\n\n // 1.5 Security Limits & Prototype Pollution Check\n const securityCheck = validateDocumentSecurity(doc, options.securityLimits);\n if (!securityCheck.safe) {\n for (const secErr of securityCheck.errors) {\n errors.push({\n code: secErr.code === 'PROTOTYPE_POLLUTION_DETECTED'\n ? 'PROTOTYPE_POLLUTION_DETECTED'\n : 'SECURITY_LIMIT_EXCEEDED',\n message: secErr.message,\n path: secErr.path || '',\n details: secErr.details,\n });\n }\n if (securityCheck.errors.some((e) => e.code === 'PROTOTYPE_POLLUTION_DETECTED')) {\n return {\n valid: false,\n success: false,\n errors,\n warnings: [],\n };\n }\n }\n\n // 2. Global Schema / Version / Document field checks\n if (doc.schema !== SCHEMA_NAME) {\n errors.push({\n code: 'GLOBAL_SCHEMA_INVALID',\n message: `Invalid schema identifier. Expected \"${SCHEMA_NAME}\", received \"${String(doc.schema)}\"`,\n path: '/schema',\n });\n }\n\n if (typeof doc.version !== 'string' || doc.version.trim().length === 0) {\n errors.push({\n code: 'GLOBAL_SCHEMA_INVALID',\n message: 'Schema version must be a non-empty string',\n path: '/version',\n });\n }\n\n if (!doc.document || typeof doc.document !== 'object' || Array.isArray(doc.document)) {\n errors.push({\n code: 'GLOBAL_SCHEMA_INVALID',\n message: 'Document must contain a root document node object',\n path: '/document',\n });\n return {\n valid: false,\n success: false,\n errors,\n warnings,\n };\n }\n\n const rootNode = doc.document as Record<string, unknown>;\n\n // 3. Root Node Type check (must be 'page')\n if (rootNode.type !== 'page') {\n errors.push({\n code: 'ROOT_NODE_INVALID',\n message: `Root node type must be \"page\", received \"${String(rootNode.type)}\"`,\n path: '/document/type',\n nodeId: typeof rootNode.id === 'string' ? rootNode.id : undefined,\n });\n }\n\n // 4. Metadata check\n if (doc.metadata !== undefined) {\n if (typeof doc.metadata !== 'object' || doc.metadata === null || Array.isArray(doc.metadata)) {\n errors.push({\n code: 'INVALID_METADATA',\n message: 'Document metadata must be an object',\n path: '/metadata',\n });\n } else {\n const meta = doc.metadata as Record<string, unknown>;\n if (meta.title !== undefined && (typeof meta.title !== 'string' || meta.title.trim().length === 0)) {\n errors.push({\n code: 'INVALID_METADATA',\n message: 'Metadata title must be a non-empty string when provided',\n path: '/metadata/title',\n });\n }\n }\n }\n\n // 5. Deep Recursive Node Tree Validation (Cycle, ID Uniqueness, Node Shape, Registry, Bindings)\n const seenIds = new Map<string, string>(); // nodeId -> path\n const visitedObjects = new Set<object>();\n\n validateNodeRecursive(\n rootNode,\n '/document',\n undefined,\n seenIds,\n visitedObjects,\n options,\n errors,\n warnings,\n );\n\n // 6. Schema Zod safe parse fallback to capture any missed structural issues\n if (errors.length === 0) {\n const zodResult = PageDocumentSchema.safeParse(input);\n if (!zodResult.success) {\n for (const issue of zodResult.error.issues) {\n const jsonPath = '/' + issue.path.join('/');\n errors.push({\n code: 'GLOBAL_SCHEMA_INVALID',\n message: issue.message,\n path: jsonPath === '/' ? '' : jsonPath,\n });\n }\n } else {\n return {\n valid: true,\n success: true,\n errors: [],\n warnings,\n data: zodResult.data as unknown as PageDocument,\n };\n }\n }\n\n return {\n valid: errors.length === 0,\n success: errors.length === 0,\n errors,\n warnings,\n };\n}\n\nfunction validateNodeRecursive(\n nodeObj: Record<string, unknown>,\n currentPath: string,\n parentNode: { id: string; type: string } | undefined,\n seenIds: Map<string, string>,\n visitedObjects: Set<object>,\n options: ValidationOptions,\n errors: DocumentValidationError[],\n warnings: DocumentValidationWarning[],\n): void {\n // Cycle Detection\n if (visitedObjects.has(nodeObj)) {\n errors.push({\n code: 'TREE_CYCLE_DETECTED',\n message: `Cyclic reference detected at node path ${currentPath}`,\n path: currentPath,\n nodeId: typeof nodeObj.id === 'string' ? nodeObj.id : undefined,\n });\n return;\n }\n visitedObjects.add(nodeObj);\n\n // Validate Node ID\n const nodeId = nodeObj.id;\n if (typeof nodeId !== 'string' || nodeId.trim().length === 0) {\n errors.push({\n code: 'NODE_SHAPE_INVALID',\n message: 'Node id must be a non-empty string',\n path: `${currentPath}/id`,\n });\n } else {\n if (seenIds.has(nodeId)) {\n errors.push({\n code: 'DUPLICATE_NODE_ID',\n message: `Duplicate node ID \"${nodeId}\" found at ${currentPath} (first seen at ${seenIds.get(nodeId)})`,\n path: `${currentPath}/id`,\n nodeId,\n details: { firstSeenAt: seenIds.get(nodeId) },\n });\n } else {\n seenIds.set(nodeId, currentPath);\n }\n }\n\n // Validate Node Type\n const nodeType = nodeObj.type;\n if (typeof nodeType !== 'string' || nodeType.trim().length === 0) {\n errors.push({\n code: 'NODE_SHAPE_INVALID',\n message: 'Node type must be a non-empty string',\n path: `${currentPath}/type`,\n nodeId: typeof nodeId === 'string' ? nodeId : undefined,\n });\n }\n\n const effectiveNodeId = typeof nodeId === 'string' ? nodeId : undefined;\n const effectiveNodeType = typeof nodeType === 'string' ? nodeType : '';\n\n // Validate against Component Registry or known types\n let componentDef: ComponentDefinitionLike | undefined;\n if (effectiveNodeType) {\n if (options.componentRegistry) {\n componentDef = options.componentRegistry.get(effectiveNodeType);\n if (!componentDef && (options.strictComponentTypes || !options.componentRegistry.has(effectiveNodeType))) {\n errors.push({\n code: 'UNKNOWN_COMPONENT_TYPE',\n message: `Unknown component type: \"${effectiveNodeType}\"`,\n path: `${currentPath}/type`,\n nodeId: effectiveNodeId,\n });\n }\n } else if (options.knownComponentTypes) {\n const isKnown = Array.isArray(options.knownComponentTypes)\n ? options.knownComponentTypes.includes(effectiveNodeType)\n : options.knownComponentTypes.has(effectiveNodeType);\n\n if (!isKnown && options.strictComponentTypes) {\n errors.push({\n code: 'UNKNOWN_COMPONENT_TYPE',\n message: `Unknown component type: \"${effectiveNodeType}\"`,\n path: `${currentPath}/type`,\n nodeId: effectiveNodeId,\n });\n }\n }\n }\n\n // Validate Child Policy\n const children = nodeObj.children;\n if (children !== undefined) {\n if (!Array.isArray(children)) {\n errors.push({\n code: 'NODE_SHAPE_INVALID',\n message: 'Node children must be an array',\n path: `${currentPath}/children`,\n nodeId: effectiveNodeId,\n });\n } else {\n if (componentDef && componentDef.acceptsChildren === false && children.length > 0) {\n errors.push({\n code: 'CHILD_POLICY_VIOLATION',\n message: `Component \"${effectiveNodeType}\" does not accept children, but found ${children.length} child node(s)`,\n path: `${currentPath}/children`,\n nodeId: effectiveNodeId,\n });\n }\n\n if (parentNode && componentDef?.disallowedParents?.includes(parentNode.type)) {\n errors.push({\n code: 'CHILD_POLICY_VIOLATION',\n message: `Component \"${effectiveNodeType}\" cannot be a child of \"${parentNode.type}\"`,\n path: currentPath,\n nodeId: effectiveNodeId,\n });\n }\n\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n const childPath = `${currentPath}/children/${i}`;\n\n if (!child || typeof child !== 'object' || Array.isArray(child)) {\n errors.push({\n code: 'NODE_SHAPE_INVALID',\n message: `Child at index ${i} must be a valid node object`,\n path: childPath,\n nodeId: effectiveNodeId,\n });\n continue;\n }\n\n const childRecord = child as Record<string, unknown>;\n const childType = typeof childRecord.type === 'string' ? childRecord.type : '';\n const childIsKnown = !options.componentRegistry || options.componentRegistry.has(childType);\n const childCategory = options.componentRegistry?.get(childType)?.category;\n\n if (\n componentDef?.allowedChildren &&\n childType &&\n childIsKnown &&\n !componentDef.allowedChildren.includes(childType) &&\n !componentDef.allowedChildren.includes('*') &&\n !(childCategory && componentDef.allowedChildren.includes(childCategory))\n ) {\n const violationMessage = `Component type \"${childType}\" is not allowed as a child of \"${effectiveNodeType}\". Allowed types: ${componentDef.allowedChildren.join(', ')}`;\n if (options.strictChildPolicy) {\n errors.push({\n code: 'CHILD_POLICY_VIOLATION',\n message: violationMessage,\n path: `${childPath}/type`,\n nodeId: typeof childRecord.id === 'string' ? childRecord.id : undefined,\n });\n } else {\n warnings.push({\n code: 'CHILD_POLICY_VIOLATION',\n message: violationMessage,\n path: `${childPath}/type`,\n nodeId: typeof childRecord.id === 'string' ? childRecord.id : undefined,\n });\n }\n }\n\n validateNodeRecursive(\n childRecord,\n childPath,\n { id: effectiveNodeId || '', type: effectiveNodeType },\n seenIds,\n visitedObjects,\n options,\n errors,\n warnings,\n );\n }\n }\n }\n\n // Validate Props and structural bindings (Assets, Variables, Actions)\n if (nodeObj.props !== undefined) {\n if (typeof nodeObj.props !== 'object' || nodeObj.props === null || Array.isArray(nodeObj.props)) {\n errors.push({\n code: 'NODE_SHAPE_INVALID',\n message: 'Node props must be an object',\n path: `${currentPath}/props`,\n nodeId: effectiveNodeId,\n });\n } else {\n validatePropsBindings(\n nodeObj.props as Record<string, unknown>,\n `${currentPath}/props`,\n effectiveNodeId,\n options,\n errors,\n warnings,\n );\n }\n }\n\n // Validate Styles\n if (nodeObj.styles !== undefined) {\n if (typeof nodeObj.styles !== 'object' || nodeObj.styles === null || Array.isArray(nodeObj.styles)) {\n errors.push({\n code: 'NODE_SHAPE_INVALID',\n message: 'Node styles must be an object',\n path: `${currentPath}/styles`,\n nodeId: effectiveNodeId,\n });\n }\n }\n}\n\n/**\n * Recursively inspect props object for structural bindings (asset, variable, action).\n * Each binding kind is gated by its `ValidationOptions` flag (all default to `true`).\n */\nfunction validatePropsBindings(\n propsObj: Record<string, unknown>,\n propsPath: string,\n nodeId: string | undefined,\n options: ValidationOptions,\n errors: DocumentValidationError[],\n warnings: DocumentValidationWarning[],\n): void {\n const checkAssets = options.checkAssetReferences !== false;\n const checkVariables = options.checkVariableBindings !== false;\n const checkActions = options.checkActionBindings !== false;\n\n for (const [key, value] of Object.entries(propsObj)) {\n const currentPath = `${propsPath}/${key}`;\n\n if (!value || typeof value !== 'object') {\n continue;\n }\n\n if (Array.isArray(value)) {\n value.forEach((item, index) => {\n if (item && typeof item === 'object' && !Array.isArray(item)) {\n validatePropsBindings(\n item as Record<string, unknown>,\n `${currentPath}/${index}`,\n nodeId,\n options,\n errors,\n warnings,\n );\n }\n });\n continue;\n }\n\n const record = value as Record<string, unknown>;\n\n // Check if it's an Asset Reference\n if (record.type === 'asset') {\n if (!checkAssets) continue;\n const assetId =\n typeof record.assetId === 'string' && record.assetId.trim().length > 0 ? record.assetId : undefined;\n if (assetId === undefined) {\n errors.push({\n code: 'INVALID_ASSET_REFERENCE',\n message: 'Asset reference must have a non-empty \"assetId\"',\n path: `${currentPath}/assetId`,\n nodeId,\n });\n }\n if (record.fallbackUrl !== undefined && typeof record.fallbackUrl !== 'string') {\n errors.push({\n code: 'INVALID_ASSET_REFERENCE',\n message: 'Asset fallbackUrl must be a string if provided',\n path: `${currentPath}/fallbackUrl`,\n nodeId,\n });\n }\n if (assetId !== undefined && options.knownAssetIds && !isKnownId(options.knownAssetIds, assetId)) {\n if (typeof record.fallbackUrl === 'string' && record.fallbackUrl.length > 0) {\n warnings.push({\n code: 'UNRESOLVED_ASSET_REFERENCE',\n message: `Asset \"${assetId}\" is not among the known assets; its fallbackUrl will be used`,\n path: `${currentPath}/assetId`,\n nodeId,\n details: { assetId },\n });\n } else {\n errors.push({\n code: 'INVALID_ASSET_REFERENCE',\n message: `Asset \"${assetId}\" is not among the known assets and has no fallbackUrl`,\n path: `${currentPath}/assetId`,\n nodeId,\n details: { assetId },\n });\n }\n }\n }\n // Check if it's a Variable Binding\n else if (record.type === 'variable') {\n if (!checkVariables) continue;\n if (typeof record.key !== 'string' || record.key.trim().length === 0) {\n errors.push({\n code: 'INVALID_VARIABLE_BINDING',\n message: 'Variable binding must have a non-empty \"key\"',\n path: `${currentPath}/key`,\n nodeId,\n });\n }\n }\n // Check if it's an Action Binding (either key is 'action' or has explicit action shape)\n else if (key === 'action' || (typeof record.type === 'string' && record.payload !== undefined)) {\n if (!checkActions) continue;\n if (typeof record.type !== 'string' || record.type.trim().length === 0) {\n errors.push({\n code: 'INVALID_ACTION_BINDING',\n message: 'Action binding must have a non-empty \"type\"',\n path: `${currentPath}/type`,\n nodeId,\n });\n }\n } else {\n // Recurse into nested objects\n validatePropsBindings(record, currentPath, nodeId, options, errors, warnings);\n }\n }\n}\n\nfunction isKnownId(ids: string[] | Set<string>, id: string): boolean {\n return Array.isArray(ids) ? ids.includes(id) : ids.has(id);\n}\n","/**\n * Security Limits and Sanitization Utilities for KUBUILD documents, assets, and actions.\n */\n\nexport interface DocumentSecurityLimits {\n /**\n * Maximum allowed total nodes in the document tree (default: 5000).\n */\n maxNodeCount?: number;\n\n /**\n * Maximum allowed nesting depth of nodes (default: 32).\n */\n maxTreeDepth?: number;\n\n /**\n * Maximum number of direct properties per node (default: 200).\n */\n maxPropsCount?: number;\n\n /**\n * Maximum character length for any individual string property (default: 100,000).\n */\n maxStringLength?: number;\n\n /**\n * Maximum number of direct children per node (default: 1000).\n */\n maxChildrenPerNode?: number;\n\n /**\n * Maximum allowed JSON serialized size in bytes (default: 10MB).\n */\n maxDocumentSizeBytes?: number;\n\n /**\n * Allowed URL schemes for links and media.\n * Default: ['http:', 'https:', 'mailto:', 'tel:', '#', 'relative', 'data:image/']\n */\n allowedUrlSchemes?: string[];\n\n /**\n * Prohibited property keys to defend against Prototype Pollution.\n * Default: ['__proto__', 'constructor', 'prototype', '__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__']\n */\n prohibitedPropertyKeys?: string[];\n\n /**\n * Prohibited asset file extensions to prevent executable uploads.\n * Default: ['.exe', '.dll', '.so', '.sh', '.bat', '.cmd', '.js', '.mjs', '.cjs', '.php', '.py', '.vbs', '.wasm', '.bin', '.com', '.scr', '.pif']\n */\n prohibitedAssetExtensions?: string[];\n\n /**\n * Maximum compression expansion ratio before flagging potential zip bomb (default: 100).\n */\n maxZipExpansionRatio?: number;\n}\n\nexport const DEFAULT_DOCUMENT_SECURITY_LIMITS: Required<DocumentSecurityLimits> = {\n maxNodeCount: 5000,\n maxTreeDepth: 32,\n maxPropsCount: 200,\n maxStringLength: 100_000,\n maxChildrenPerNode: 1000,\n maxDocumentSizeBytes: 10 * 1024 * 1024, // 10 MB\n allowedUrlSchemes: ['http:', 'https:', 'mailto:', 'tel:', '#', 'relative', 'data:image/'],\n prohibitedPropertyKeys: [\n '__proto__',\n 'constructor',\n 'prototype',\n '__defineGetter__',\n '__defineSetter__',\n '__lookupGetter__',\n '__lookupSetter__',\n ],\n prohibitedAssetExtensions: [\n '.exe',\n '.dll',\n '.so',\n '.sh',\n '.bat',\n '.cmd',\n '.js',\n '.mjs',\n '.cjs',\n '.php',\n '.py',\n '.vbs',\n '.wasm',\n '.bin',\n '.com',\n '.scr',\n '.pif',\n '.hta',\n '.jar',\n ],\n maxZipExpansionRatio: 100,\n};\n\nexport interface SecurityViolation {\n code:\n | 'PROTOTYPE_POLLUTION_DETECTED'\n | 'MAX_NODE_COUNT_EXCEEDED'\n | 'MAX_TREE_DEPTH_EXCEEDED'\n | 'MAX_PROPS_COUNT_EXCEEDED'\n | 'MAX_STRING_LENGTH_EXCEEDED'\n | 'MAX_CHILDREN_COUNT_EXCEEDED'\n | 'MAX_DOCUMENT_SIZE_EXCEEDED'\n | 'UNSAFE_URL_DETECTED'\n | 'EXECUTABLE_ASSET_DETECTED'\n | 'ZIP_BOMB_DETECTED';\n message: string;\n path?: string;\n details?: Record<string, unknown>;\n}\n\n/**\n * Checks whether a URL is safe according to the allowed URL schemes.\n * Rejects dangerous schemes such as javascript:, vbscript:, data:text/html, etc.\n */\nexport function isSafeUrl(\n url: unknown,\n options?: {\n allowedSchemes?: string[];\n allowDataImage?: boolean;\n /** Allow `blob:` URLs (runtime-only, e.g. in-memory uploaded media previews). */\n allowBlobMedia?: boolean;\n }\n): boolean {\n if (typeof url !== 'string') return false;\n\n const trimmed = url.trim();\n if (trimmed.length === 0) return true;\n\n // Relative URLs & fragments are safe\n if (\n trimmed.startsWith('/') ||\n trimmed.startsWith('#') ||\n trimmed.startsWith('./') ||\n trimmed.startsWith('../') ||\n trimmed.startsWith('?')\n ) {\n return true;\n }\n\n // Check for control characters or null bytes\n if (/[\\u0000-\\u001F\\u007F-\\u009F]/.test(trimmed)) {\n return false;\n }\n\n // Extract scheme\n const colonIndex = trimmed.indexOf(':');\n if (colonIndex === -1) {\n // Relative path or plain fragment without scheme\n return true;\n }\n\n const scheme = trimmed.substring(0, colonIndex + 1).toLowerCase();\n\n // Explicitly block dangerous protocols\n const dangerousSchemes = ['javascript:', 'vbscript:', 'file:', 'data:'];\n if (scheme !== 'data:' && dangerousSchemes.includes(scheme)) {\n // `blob:` URLs are runtime-only references to in-memory media (e.g. files\n // uploaded in the current editor session). They never originate from\n // imported documents, so they are safe to allow for media previews.\n if (scheme === 'blob:' && options?.allowBlobMedia) {\n return true;\n }\n return false;\n }\n\n // Handle data: scheme\n if (scheme === 'data:') {\n const allowDataImage = options?.allowDataImage ?? true;\n if (!allowDataImage) return false;\n\n // Only allow safe data:image/ mime types\n const dataPrefix = trimmed.substring(0, 30).toLowerCase();\n const safeDataImagePrefixes = [\n 'data:image/png',\n 'data:image/jpeg',\n 'data:image/jpg',\n 'data:image/webp',\n 'data:image/gif',\n 'data:image/avif',\n 'data:image/svg+xml',\n ];\n return safeDataImagePrefixes.some((p) => dataPrefix.startsWith(p));\n }\n\n // Verify against allowed schemes list\n const allowed = options?.allowedSchemes || DEFAULT_DOCUMENT_SECURITY_LIMITS.allowedUrlSchemes;\n return allowed.some((s) => s.toLowerCase() === scheme);\n}\n\n/**\n * Sanitizes a URL, returning a safe URL or a fallback (default empty string or '#').\n */\nexport function sanitizeUrl(\n url: unknown,\n fallback: string = '',\n options?: Parameters<typeof isSafeUrl>[1]\n): string {\n if (typeof url !== 'string') return fallback;\n return isSafeUrl(url, options) ? url : fallback;\n}\n\n/**\n * Checks an object recursively for prohibited prototype pollution keys.\n */\nexport function containsProhibitedKeys(\n obj: unknown,\n prohibitedKeys: string[] = DEFAULT_DOCUMENT_SECURITY_LIMITS.prohibitedPropertyKeys\n): { found: boolean; path: string; key: string } {\n const prohibitedSet = new Set(prohibitedKeys.map((k) => k.toLowerCase()));\n const visited = new WeakSet<object>();\n\n function check(value: unknown, currentPath: string): { found: boolean; path: string; key: string } {\n if (!value || typeof value !== 'object') {\n return { found: false, path: '', key: '' };\n }\n\n if (visited.has(value)) {\n return { found: false, path: '', key: '' };\n }\n visited.add(value);\n\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i++) {\n const res = check(value[i], `${currentPath}[${i}]`);\n if (res.found) return res;\n }\n return { found: false, path: '', key: '' };\n }\n\n const record = value as Record<string, unknown>;\n const keysToCheck = Array.from(new Set([...Object.keys(record), ...Object.getOwnPropertyNames(record)]));\n\n for (const key of keysToCheck) {\n if (prohibitedSet.has(key.toLowerCase())) {\n return { found: true, path: currentPath ? `${currentPath}.${key}` : key, key };\n }\n const res = check(record[key], currentPath ? `${currentPath}.${key}` : key);\n if (res.found) return res;\n }\n\n // Check if __proto__ was injected and altered standard prototype\n if (Object.prototype.hasOwnProperty.call(record, '__proto__')) {\n return { found: true, path: currentPath ? `${currentPath}.__proto__` : '__proto__', key: '__proto__' };\n }\n\n return { found: false, path: '', key: '' };\n }\n\n return check(obj, '');\n}\n\n/**\n * Validates a document against security limits (node count, tree depth, props count, string length, prototype pollution).\n */\nexport function validateDocumentSecurity(\n doc: unknown,\n customLimits?: DocumentSecurityLimits\n): { safe: boolean; errors: SecurityViolation[] } {\n const limits = { ...DEFAULT_DOCUMENT_SECURITY_LIMITS, ...customLimits };\n const errors: SecurityViolation[] = [];\n\n if (!doc || typeof doc !== 'object') {\n return { safe: true, errors: [] };\n }\n\n // 1. Prototype Pollution Check\n const protoCheck = containsProhibitedKeys(doc, limits.prohibitedPropertyKeys);\n if (protoCheck.found) {\n errors.push({\n code: 'PROTOTYPE_POLLUTION_DETECTED',\n message: `Prohibited property key \"${protoCheck.key}\" detected at path \"${protoCheck.path}\" (Prototype Pollution Defense).`,\n path: protoCheck.path,\n details: { key: protoCheck.key },\n });\n }\n\n // 2. Document Serialized Size Check\n try {\n const jsonStr = JSON.stringify(doc);\n if (jsonStr.length > limits.maxDocumentSizeBytes) {\n errors.push({\n code: 'MAX_DOCUMENT_SIZE_EXCEEDED',\n message: `Document size (${jsonStr.length} bytes) exceeds limit of ${limits.maxDocumentSizeBytes} bytes.`,\n details: { size: jsonStr.length, limit: limits.maxDocumentSizeBytes },\n });\n }\n } catch {\n // Ignore JSON stringify errors\n }\n\n // 3. Tree Depth & Node Count Checks\n const docObj = doc as Record<string, unknown>;\n const rootNode = docObj.document;\n\n if (rootNode && typeof rootNode === 'object') {\n let totalNodes = 0;\n\n function traverse(node: unknown, depth: number, currentPath: string): void {\n if (!node || typeof node !== 'object' || Array.isArray(node)) return;\n\n totalNodes++;\n if (totalNodes > limits.maxNodeCount) {\n errors.push({\n code: 'MAX_NODE_COUNT_EXCEEDED',\n message: `Total document nodes (${totalNodes}) exceeded security limit of ${limits.maxNodeCount}.`,\n path: currentPath,\n details: { nodeCount: totalNodes, limit: limits.maxNodeCount },\n });\n return;\n }\n\n if (depth > limits.maxTreeDepth) {\n errors.push({\n code: 'MAX_TREE_DEPTH_EXCEEDED',\n message: `Document nesting depth (${depth}) exceeded security limit of ${limits.maxTreeDepth}.`,\n path: currentPath,\n details: { depth, limit: limits.maxTreeDepth },\n });\n return;\n }\n\n const nodeRecord = node as Record<string, unknown>;\n\n // Check Props Limits\n if (nodeRecord.props && typeof nodeRecord.props === 'object' && !Array.isArray(nodeRecord.props)) {\n const propsRecord = nodeRecord.props as Record<string, unknown>;\n const propKeys = Object.keys(propsRecord);\n\n if (propKeys.length > limits.maxPropsCount) {\n errors.push({\n code: 'MAX_PROPS_COUNT_EXCEEDED',\n message: `Node has ${propKeys.length} props, exceeding limit of ${limits.maxPropsCount}.`,\n path: `${currentPath}/props`,\n details: { count: propKeys.length, limit: limits.maxPropsCount },\n });\n }\n\n for (const [k, val] of Object.entries(propsRecord)) {\n if (typeof val === 'string' && val.length > limits.maxStringLength) {\n errors.push({\n code: 'MAX_STRING_LENGTH_EXCEEDED',\n message: `Prop \"${k}\" string length (${val.length}) exceeds limit of ${limits.maxStringLength}.`,\n path: `${currentPath}/props/${k}`,\n details: { length: val.length, limit: limits.maxStringLength },\n });\n }\n }\n }\n\n // Check Children Limits\n if (nodeRecord.children && Array.isArray(nodeRecord.children)) {\n if (nodeRecord.children.length > limits.maxChildrenPerNode) {\n errors.push({\n code: 'MAX_CHILDREN_COUNT_EXCEEDED',\n message: `Node has ${nodeRecord.children.length} direct children, exceeding limit of ${limits.maxChildrenPerNode}.`,\n path: `${currentPath}/children`,\n details: { count: nodeRecord.children.length, limit: limits.maxChildrenPerNode },\n });\n }\n\n for (let i = 0; i < nodeRecord.children.length; i++) {\n traverse(nodeRecord.children[i], depth + 1, `${currentPath}/children/${i}`);\n }\n }\n }\n\n traverse(rootNode, 1, '/document');\n }\n\n return {\n safe: errors.length === 0,\n errors,\n };\n}\n\n/**\n * Checks if an asset filename has a dangerous or executable extension.\n */\nexport function isDangerousAssetFilename(\n filename: string,\n prohibitedExtensions: string[] = DEFAULT_DOCUMENT_SECURITY_LIMITS.prohibitedAssetExtensions\n): boolean {\n if (!filename || typeof filename !== 'string') return true;\n\n const lower = filename.toLowerCase().trim();\n\n // Check double extensions like \"malicious.exe.png\" or \"script.php.jpg\"\n return prohibitedExtensions.some((ext) => {\n const extLower = ext.toLowerCase();\n return lower.endsWith(extLower) || lower.includes(`${extLower}.`);\n });\n}\n\n/**\n * Checks whether an archive expansion ratio indicates a zip bomb attack.\n */\nexport function checkZipBomb(\n compressedSize: number,\n uncompressedSize: number,\n maxRatio: number = DEFAULT_DOCUMENT_SECURITY_LIMITS.maxZipExpansionRatio\n): boolean {\n if (compressedSize <= 0) return false;\n // Only enforce ratio for archives whose uncompressed payload is non-trivial (>10MB)\n if (uncompressedSize > 10 * 1024 * 1024) {\n const ratio = uncompressedSize / compressedSize;\n return ratio > maxRatio;\n }\n return false;\n}\n\n/**\n * Sanitizes an HTML string by stripping unsafe tags (<script>, <object>, <embed>, <applet>, <base>, <link rel=\"import\">),\n * removing inline event handlers (on* attributes like onclick, onerror, onload, etc.),\n * and disarming javascript:/vbscript:/data:text/html URLs in attributes.\n */\nexport function sanitizeHtml(rawHtml: unknown): string {\n if (typeof rawHtml !== 'string') return '';\n let html = rawHtml;\n\n // 1. Remove script tags and their content\n html = html.replace(/<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi, '');\n\n // 2. Remove object, embed, applet, base, and link tags\n html = html.replace(/<\\/?(object|embed|applet|base|link)\\b[^>]*>/gi, '');\n\n // 3. Remove on* event handler attributes (e.g. onload=, onclick=, onerror=, onfocus=)\n html = html.replace(/\\s+on[a-z0-9_-]+\\s*=\\s*(?:'[^']*'|\"[^\"]*\"|[^\\s>]+)/gi, '');\n\n // 4. Disarm javascript:, vbscript:, and data:text/html protocol attributes in href/src/data/action\n html = html.replace(\n /\\b(href|src|data|action)\\s*=\\s*(['\"])\\s*(?:javascript:|vbscript:|data:text\\/html)[^'\"]*\\2/gi,\n '$1=\"#\"'\n );\n html = html.replace(\n /\\b(href|src|data|action)\\s*=\\s*(?:javascript:|vbscript:|data:text\\/html)[^\\s>]+/gi,\n '$1=\"#\"'\n );\n\n return html;\n}\n\n","import { LEGACY_TRACKING_SECRET_KEYS, type TrackingProviderType } from '@kubuild/schema';\n\n/**\n * Removes host-owned secret / destination fields (e.g. Meta `capiAccessToken`, TikTok\n * `accessToken`, GA4 `measurementProtocolSecret`, `serverRelayUrl`, custom `endpointUrl` /\n * `headers`) from a tracking config object IN PLACE.\n *\n * Returns the dotted paths (relative to the tracking object) of every field removed.\n * Safe on untrusted input: non-object values are ignored.\n */\nexport function stripTrackingSecretsInPlace(tracking: unknown, basePath = 'tracking'): string[] {\n const removed: string[] = [];\n if (!tracking || typeof tracking !== 'object' || Array.isArray(tracking)) return removed;\n\n const providers = (tracking as Record<string, unknown>).providers;\n if (!providers || typeof providers !== 'object' || Array.isArray(providers)) return removed;\n\n for (const provider of Object.keys(LEGACY_TRACKING_SECRET_KEYS) as TrackingProviderType[]) {\n const cfg = (providers as Record<string, unknown>)[provider];\n if (!cfg || typeof cfg !== 'object' || Array.isArray(cfg)) continue;\n for (const key of LEGACY_TRACKING_SECRET_KEYS[provider]) {\n if (Object.prototype.hasOwnProperty.call(cfg, key)) {\n delete (cfg as Record<string, unknown>)[key];\n removed.push(`${basePath}.providers.${provider}.${key}`);\n }\n }\n }\n return removed;\n}\n\n/**\n * Strips tracking secrets from every place a document (page or project) can carry a\n * tracking config: `tracking`, `metadata.tracking`, and each `artboards[i].document.tracking`.\n * Mutates `doc` in place; pass a clone if the original must be preserved.\n */\nexport function stripDocumentTrackingSecretsInPlace(doc: unknown): string[] {\n const removed: string[] = [];\n if (!doc || typeof doc !== 'object' || Array.isArray(doc)) return removed;\n const record = doc as Record<string, unknown>;\n\n removed.push(...stripTrackingSecretsInPlace(record.tracking, 'tracking'));\n\n const metadata = record.metadata;\n if (metadata && typeof metadata === 'object' && !Array.isArray(metadata)) {\n removed.push(\n ...stripTrackingSecretsInPlace((metadata as Record<string, unknown>).tracking, 'metadata.tracking'),\n );\n }\n\n if (Array.isArray(record.artboards)) {\n record.artboards.forEach((artboard, index) => {\n if (artboard && typeof artboard === 'object') {\n const inner = (artboard as Record<string, unknown>).document;\n for (const path of stripDocumentTrackingSecretsInPlace(inner)) {\n removed.push(`artboards.${index}.document.${path}`);\n }\n }\n });\n }\n\n return removed;\n}\n\n/**\n * Non-mutating variant: returns a sanitized deep copy plus the removed field paths.\n */\nexport function sanitizeDocumentTracking<T>(doc: T): { document: T; removed: string[] } {\n if (!doc || typeof doc !== 'object') return { document: doc, removed: [] };\n const copy = JSON.parse(JSON.stringify(doc)) as T;\n const removed = stripDocumentTrackingSecretsInPlace(copy);\n return { document: copy, removed };\n}\n","import { unzipSync, strFromU8 } from 'fflate';\nimport {\n PageDocument,\n DocumentMetadata,\n Manifest,\n ManifestAssetItem,\n ManifestSchema,\n CURRENT_SCHEMA_VERSION,\n SCHEMA_NAME,\n} from '@kubuild/schema';\nimport {\n validateDocument,\n ComponentRegistryLike,\n} from '../validation/validator';\nimport {\n canMigrate,\n getMigrationPath,\n migrateDocument,\n MigrationRegistry,\n defaultMigrationRegistry,\n} from './migration';\nimport { calculateChecksum } from './exporter';\nimport { sanitizeDocumentTracking, stripDocumentTrackingSecretsInPlace } from './tracking-sanitizer';\nimport { remapDocumentAssetReferences } from '../document/document-utils';\nimport {\n isDangerousAssetFilename,\n checkZipBomb,\n containsProhibitedKeys,\n} from '../validation/security';\nimport type { AssetProvider, AssetInfo } from '../types/interfaces';\n\nexport interface SecurityLimits {\n /**\n * Maximum allowed size for the compressed archive in bytes (default: 50MB).\n */\n maxArchiveSize?: number;\n\n /**\n * Maximum total uncompressed size across all files in bytes (default: 100MB).\n */\n maxUncompressedSize?: number;\n\n /**\n * Maximum number of files in the archive (default: 1000).\n */\n maxFileCount?: number;\n\n /**\n * Maximum size for any individual asset in bytes (default: 25MB).\n */\n maxAssetSize?: number;\n}\n\nexport const DEFAULT_SECURITY_LIMITS: Required<SecurityLimits> = {\n maxArchiveSize: 50 * 1024 * 1024, // 50 MB\n maxUncompressedSize: 100 * 1024 * 1024, // 100 MB\n maxFileCount: 1000,\n maxAssetSize: 25 * 1024 * 1024, // 25 MB\n};\n\nexport type MissingDependencyPolicy =\n | 'cancel'\n | 'import-with-placeholder'\n | 'install-or-register-before-import';\n\nexport type AssetCollisionStrategy =\n | 'reject'\n | 'rename'\n | 'overwrite'\n | 'reuse-existing';\n\nexport interface AssetConflict {\n assetId: string;\n path: string;\n mimeType: string;\n size: number;\n existingAsset?: AssetInfo | Record<string, unknown>;\n}\n\nexport interface AssetConflictResolution {\n action: AssetCollisionStrategy;\n newAssetId?: string;\n}\n\nexport type PreflightDiagnosticCode =\n | 'ARCHIVE_EMPTY'\n | 'ARCHIVE_CORRUPT'\n | 'SIZE_LIMIT_EXCEEDED'\n | 'FILE_COUNT_EXCEEDED'\n | 'ZIP_SLIP_DETECTED'\n | 'EXECUTABLE_ASSET_DETECTED'\n | 'PROTOTYPE_POLLUTION_DETECTED'\n | 'MISSING_MANIFEST'\n | 'INVALID_MANIFEST'\n | 'MISSING_PAGE_DOCUMENT'\n | 'INVALID_PAGE_DOCUMENT'\n | 'UNSUPPORTED_SCHEMA_VERSION'\n | 'NO_MIGRATION_PATH'\n | 'MIGRATION_FAILED'\n | 'ASSET_FILE_MISSING'\n | 'ASSET_SIZE_MISMATCH'\n | 'ASSET_CHECKSUM_MISMATCH'\n | 'ASSET_LIMIT_EXCEEDED'\n | 'ASSET_CONFLICT'\n | 'MISSING_COMPONENTS'\n | 'MISSING_CAPABILITIES'\n | 'HOST_ADAPTER_ERROR'\n | 'TRACKING_SECRET_REMOVED';\n\nexport interface PreflightDiagnostic {\n code: PreflightDiagnosticCode;\n severity: 'error' | 'warning' | 'info';\n message: string;\n path?: string;\n details?: Record<string, unknown>;\n}\n\nexport interface PreflightOptions {\n /**\n * Component registry to check required custom components.\n */\n componentRegistry?: ComponentRegistryLike;\n\n /**\n * Allowlist of known component type names (used if componentRegistry is not provided or in combination).\n */\n knownComponentTypes?: string[] | Set<string>;\n\n /**\n * Allowlist of capabilities supported by host.\n */\n supportedCapabilities?: string[] | Set<string>;\n\n /**\n * Security limits for archive and files.\n */\n securityLimits?: SecurityLimits;\n\n /**\n * Custom migration registry.\n */\n migrationRegistry?: MigrationRegistry;\n\n /**\n * Target schema version (defaults to CURRENT_SCHEMA_VERSION).\n */\n targetSchemaVersion?: string;\n\n /**\n * Policy for handling missing custom components and capabilities.\n * - 'cancel' (default): Abort import with blocking errors when components/capabilities are missing.\n * - 'import-with-placeholder': Allow import, keeping missing component nodes and props intact for placeholder rendering.\n * - 'install-or-register-before-import': Call onMissingDependency to register/install before finalizing import.\n */\n dependencyPolicy?: MissingDependencyPolicy;\n\n /**\n * Hook called when dependencyPolicy is 'install-or-register-before-import'.\n */\n onMissingDependency?: (\n missing: { components: string[]; capabilities: string[] },\n preflight: PreflightReport,\n ) => Promise<boolean | void> | boolean | void;\n\n /**\n * If true, missing components are treated as warnings rather than blocking errors.\n * (Equivalent to setting dependencyPolicy: 'import-with-placeholder')\n */\n allowMissingComponents?: boolean;\n\n /**\n * If true, missing capabilities are treated as warnings rather than blocking errors.\n * (Equivalent to setting dependencyPolicy: 'import-with-placeholder')\n */\n allowMissingCapabilities?: boolean;\n\n /**\n * Strategy for resolving asset collisions with existing host assets.\n * - 'reject' (default): Refuse import if asset collision is detected without an explicit resolution strategy.\n * - 'rename': Rename the incoming asset to avoid overwriting host assets, and automatically remap document asset references.\n * - 'overwrite': Explicitly overwrite host assets with incoming archive assets.\n * - 'reuse-existing': Reuse existing host assets and skip writing archive asset binaries.\n */\n assetCollisionStrategy?: AssetCollisionStrategy;\n\n /**\n * Existing host asset IDs or checker function to detect collisions.\n */\n existingAssetIds?: string[] | Set<string> | ((assetId: string) => boolean | Promise<boolean>);\n\n /**\n * Custom naming function when renaming colliding assets.\n */\n renameAssetStrategy?: (incoming: ManifestAssetItem, existingIds: Set<string>) => string;\n\n /**\n * Host AssetProvider to resolve existing assets or upload extracted local assets.\n */\n assetProvider?: AssetProvider;\n\n /**\n * Fine-grained callback for resolving individual asset conflicts.\n */\n onAssetConflict?: (\n conflict: AssetConflict,\n ) => Promise<AssetConflictResolution | AssetCollisionStrategy> | AssetConflictResolution | AssetCollisionStrategy;\n}\n\nexport interface PreflightReport {\n /**\n * True if archive is completely safe and syntactically valid.\n */\n valid: boolean;\n\n /**\n * True if archive can be safely imported given the host's supported components/capabilities and asset policies.\n */\n canImport: boolean;\n\n /**\n * Parsed manifest if available.\n */\n manifest?: Manifest;\n\n /**\n * Parsed metadata if available.\n */\n rawMetadata?: DocumentMetadata;\n\n /**\n * Schema version reported in the document/manifest.\n */\n sourceVersion?: string;\n\n /**\n * Target schema version.\n */\n targetVersion: string;\n\n /**\n * True if the document version differs from target version and requires migration.\n */\n requiresMigration: boolean;\n\n /**\n * Migration path version sequence if migration is needed.\n */\n migrationPath?: string[];\n\n /**\n * List of custom component types required by package that are missing in host.\n */\n missingComponents: string[];\n\n /**\n * List of capabilities required by package that are missing in host.\n */\n missingCapabilities: string[];\n\n /**\n * Active policy for missing dependencies.\n */\n dependencyPolicy: MissingDependencyPolicy;\n\n /**\n * Number of valid local assets declared in manifest.\n */\n assetCount: number;\n\n /**\n * List of detected asset collisions with existing host assets.\n */\n assetConflicts: AssetConflict[];\n\n /**\n * Active strategy for handling asset collisions.\n */\n assetCollisionStrategy: AssetCollisionStrategy;\n\n /**\n * Total uncompressed size of all files in archive.\n */\n totalUncompressedBytes: number;\n\n /**\n * Diagnostics collected during inspection.\n */\n diagnostics: PreflightDiagnostic[];\n}\n\nexport interface ImportPackageOptions extends PreflightOptions {\n /**\n * Custom asset importer hook called for each extracted asset.\n */\n onAssetImport?: (\n assetId: string,\n assetBytes: Uint8Array,\n assetMeta: ManifestAssetItem,\n ) => Promise<AssetInfo | string | void> | AssetInfo | string | void;\n}\n\nexport interface ExtractedAsset {\n bytes: Uint8Array;\n meta: ManifestAssetItem;\n hostInfo?: AssetInfo | string;\n}\n\nexport interface ImportPackageSuccess {\n success: true;\n document: PageDocument;\n manifest: Manifest;\n metadata: DocumentMetadata;\n extractedAssets: Map<string, ExtractedAsset>;\n renamedAssets?: Record<string, string>;\n preflight: PreflightReport;\n /** Non-fatal notes produced while importing (e.g. tracking secrets stripped). */\n warnings?: PreflightDiagnostic[];\n}\n\nexport interface ImportPackageFailure {\n success: false;\n errors: PreflightDiagnostic[];\n diagnosticMessage: string;\n preflight?: PreflightReport;\n}\n\nexport type ImportPackageResult = ImportPackageSuccess | ImportPackageFailure;\n\n/**\n * Checks if a zip entry path contains zip-slip or directory traversal attempts.\n */\nexport function isDangerousPath(filepath: string): boolean {\n if (!filepath || typeof filepath !== 'string') return true;\n\n // Check for null bytes\n if (filepath.includes('\\0')) return true;\n\n // Check for absolute paths (Unix or Windows drive)\n if (filepath.startsWith('/') || filepath.startsWith('\\\\') || /^[a-zA-Z]:/.test(filepath)) {\n return true;\n }\n\n // Normalize slashes\n const normalized = filepath.replace(/\\\\/g, '/');\n\n // Check path segments\n const segments = normalized.split('/');\n for (const seg of segments) {\n if (seg === '..' || seg.trim() === '..') {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Inspects a .stora archive and runs non-destructive preflight validation.\n * Verifies security limits, path safety, manifest, checksums, component/capability requirements, and migration status.\n */\nexport async function preflightPackage(\n archiveData: Uint8Array | ArrayBuffer,\n options: PreflightOptions = {},\n): Promise<PreflightReport> {\n const limits: Required<SecurityLimits> = {\n ...DEFAULT_SECURITY_LIMITS,\n ...options.securityLimits,\n };\n\n const targetVersion = options.targetSchemaVersion || CURRENT_SCHEMA_VERSION;\n const migrationRegistry = options.migrationRegistry || defaultMigrationRegistry;\n const diagnostics: PreflightDiagnostic[] = [];\n\n let dependencyPolicy: MissingDependencyPolicy = options.dependencyPolicy || 'cancel';\n if (!options.dependencyPolicy) {\n if (options.allowMissingComponents && options.allowMissingCapabilities) {\n dependencyPolicy = 'import-with-placeholder';\n }\n }\n\n const assetCollisionStrategy: AssetCollisionStrategy = options.assetCollisionStrategy || 'reject';\n\n const archiveBytes = archiveData instanceof Uint8Array ? archiveData : new Uint8Array(archiveData);\n\n // 1. Check archive size limit\n if (!archiveBytes || archiveBytes.byteLength === 0) {\n diagnostics.push({\n code: 'ARCHIVE_EMPTY',\n severity: 'error',\n message: 'Archive is empty or 0 bytes.',\n });\n return buildReport(false, false, { targetVersion, dependencyPolicy, assetCollisionStrategy, diagnostics });\n }\n\n if (archiveBytes.byteLength > limits.maxArchiveSize) {\n diagnostics.push({\n code: 'SIZE_LIMIT_EXCEEDED',\n severity: 'error',\n message: `Archive size (${archiveBytes.byteLength} bytes) exceeds maximum limit of ${limits.maxArchiveSize} bytes.`,\n details: { actualBytes: archiveBytes.byteLength, limitBytes: limits.maxArchiveSize },\n });\n return buildReport(false, false, { targetVersion, dependencyPolicy, assetCollisionStrategy, diagnostics });\n }\n\n // 2. Safe Unzip\n let unzipped: Record<string, Uint8Array>;\n try {\n unzipped = unzipSync(archiveBytes);\n } catch (err) {\n diagnostics.push({\n code: 'ARCHIVE_CORRUPT',\n severity: 'error',\n message: `Failed to unzip archive: ${err instanceof Error ? err.message : String(err)}`,\n });\n return buildReport(false, false, { targetVersion, dependencyPolicy, assetCollisionStrategy, diagnostics });\n }\n\n const entries = Object.keys(unzipped);\n\n // Check file count limit\n if (entries.length > limits.maxFileCount) {\n diagnostics.push({\n code: 'FILE_COUNT_EXCEEDED',\n severity: 'error',\n message: `Archive file count (${entries.length}) exceeds maximum limit of ${limits.maxFileCount}.`,\n details: { fileCount: entries.length, limit: limits.maxFileCount },\n });\n }\n\n // 3. Security checks: Zip-Slip and Total Uncompressed Size\n let totalUncompressedBytes = 0;\n for (const entryPath of entries) {\n // Check path safety\n if (isDangerousPath(entryPath)) {\n diagnostics.push({\n code: 'ZIP_SLIP_DETECTED',\n severity: 'error',\n message: `Security violation: Path traversal or Zip-Slip attempt detected in archive entry \"${entryPath}\".`,\n path: entryPath,\n });\n }\n\n // Check dangerous/executable asset file extensions\n if (entryPath.startsWith('assets/') && isDangerousAssetFilename(entryPath)) {\n diagnostics.push({\n code: 'EXECUTABLE_ASSET_DETECTED',\n severity: 'error',\n message: `Security violation: Executable or dangerous asset file extension detected in archive entry \"${entryPath}\".`,\n path: entryPath,\n });\n }\n\n const fileBytes = unzipped[entryPath];\n if (fileBytes) {\n totalUncompressedBytes += fileBytes.byteLength;\n\n // Check single asset size limit if in assets/\n if (entryPath.startsWith('assets/') && fileBytes.byteLength > limits.maxAssetSize) {\n diagnostics.push({\n code: 'ASSET_LIMIT_EXCEEDED',\n severity: 'error',\n message: `Asset \"${entryPath}\" size (${fileBytes.byteLength} bytes) exceeds maximum limit of ${limits.maxAssetSize} bytes.`,\n path: entryPath,\n details: { actualBytes: fileBytes.byteLength, limitBytes: limits.maxAssetSize },\n });\n }\n }\n }\n\n if (totalUncompressedBytes > limits.maxUncompressedSize) {\n diagnostics.push({\n code: 'SIZE_LIMIT_EXCEEDED',\n severity: 'error',\n message: `Total uncompressed archive size (${totalUncompressedBytes} bytes) exceeds maximum limit of ${limits.maxUncompressedSize} bytes.`,\n details: { actualBytes: totalUncompressedBytes, limitBytes: limits.maxUncompressedSize },\n });\n }\n\n // Check Zip Bomb expansion ratio\n if (checkZipBomb(archiveBytes.byteLength, totalUncompressedBytes)) {\n diagnostics.push({\n code: 'SIZE_LIMIT_EXCEEDED',\n severity: 'error',\n message: `Security violation: Potential Zip Bomb attack detected (excessive compression ratio).`,\n details: { compressedBytes: archiveBytes.byteLength, uncompressedBytes: totalUncompressedBytes },\n });\n }\n\n // 4. Check Mandatory Files: manifest.json & page.json\n const manifestEntry = unzipped['manifest.json'];\n if (!manifestEntry) {\n diagnostics.push({\n code: 'MISSING_MANIFEST',\n severity: 'error',\n message: 'Archive is missing mandatory \"manifest.json\" file.',\n });\n }\n\n const pageEntry = unzipped['page.json'];\n if (!pageEntry) {\n diagnostics.push({\n code: 'MISSING_PAGE_DOCUMENT',\n severity: 'error',\n message: 'Archive is missing mandatory \"page.json\" file.',\n });\n }\n\n // If mandatory files missing or security violated, stop preflight early\n if (!manifestEntry || !pageEntry || diagnostics.some((d) => d.code === 'ZIP_SLIP_DETECTED')) {\n return buildReport(false, false, {\n targetVersion,\n dependencyPolicy,\n assetCollisionStrategy,\n totalUncompressedBytes,\n diagnostics,\n });\n }\n\n // 5. Parse & Validate Manifest\n let parsedManifest: Manifest | undefined;\n try {\n const manifestJson = JSON.parse(strFromU8(manifestEntry));\n const manifestProtoCheck = containsProhibitedKeys(manifestJson);\n if (manifestProtoCheck.found) {\n diagnostics.push({\n code: 'PROTOTYPE_POLLUTION_DETECTED',\n severity: 'error',\n message: `Security violation: Prohibited key \"${manifestProtoCheck.key}\" in manifest.json.`,\n path: manifestProtoCheck.path,\n });\n }\n\n const parseResult = ManifestSchema.safeParse(manifestJson);\n if (!parseResult.success) {\n const issues = parseResult.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join(', ');\n diagnostics.push({\n code: 'INVALID_MANIFEST',\n severity: 'error',\n message: `Manifest validation failed: ${issues}`,\n details: { issues: parseResult.error.issues },\n });\n } else {\n parsedManifest = parseResult.data;\n }\n } catch (err) {\n diagnostics.push({\n code: 'INVALID_MANIFEST',\n severity: 'error',\n message: `Failed to parse \"manifest.json\" as valid JSON: ${err instanceof Error ? err.message : String(err)}`,\n });\n }\n\n // 6. Parse Metadata (Optional metadata.json)\n let rawMetadata: DocumentMetadata | undefined;\n const metadataEntry = unzipped['metadata.json'];\n if (metadataEntry) {\n try {\n rawMetadata = JSON.parse(strFromU8(metadataEntry)) as DocumentMetadata;\n } catch {\n // Non-critical, fallback will use page.json metadata\n }\n }\n\n // 7. Parse & Inspect page.json\n let rawPageDoc: Record<string, unknown> | undefined;\n try {\n rawPageDoc = JSON.parse(strFromU8(pageEntry)) as Record<string, unknown>;\n const secretScan = sanitizeDocumentTracking(rawPageDoc);\n if (secretScan.removed.length > 0) {\n diagnostics.push({\n code: 'TRACKING_SECRET_REMOVED',\n severity: 'warning',\n message:\n 'Tracking secrets found in page.json will be removed on import; re-link credentials via credentialId.',\n path: 'page.json',\n details: { paths: secretScan.removed },\n });\n }\n const pageProtoCheck = containsProhibitedKeys(rawPageDoc);\n if (pageProtoCheck.found) {\n diagnostics.push({\n code: 'PROTOTYPE_POLLUTION_DETECTED',\n severity: 'error',\n message: `Security violation: Prohibited key \"${pageProtoCheck.key}\" in page.json.`,\n path: pageProtoCheck.path,\n });\n }\n } catch (err) {\n diagnostics.push({\n code: 'INVALID_PAGE_DOCUMENT',\n severity: 'error',\n message: `Failed to parse \"page.json\" as valid JSON: ${err instanceof Error ? err.message : String(err)}`,\n });\n }\n\n const docVersion = typeof rawPageDoc?.version === 'string'\n ? rawPageDoc.version\n : parsedManifest?.schemaVersion || 'unknown';\n\n let requiresMigration = false;\n let migrationPath: string[] | undefined;\n\n if (rawPageDoc) {\n if (docVersion !== targetVersion) {\n if (canMigrate(docVersion, targetVersion, migrationRegistry)) {\n requiresMigration = true;\n migrationPath = getMigrationPath(docVersion, targetVersion, migrationRegistry) || undefined;\n diagnostics.push({\n code: 'UNSUPPORTED_SCHEMA_VERSION',\n severity: 'info',\n message: `Document schema version \"${docVersion}\" requires migration to current version \"${targetVersion}\".`,\n details: { sourceVersion: docVersion, targetVersion, migrationPath },\n });\n } else {\n diagnostics.push({\n code: 'NO_MIGRATION_PATH',\n severity: 'error',\n message: `Document schema version \"${docVersion}\" is not compatible and no migration path exists to \"${targetVersion}\".`,\n details: { sourceVersion: docVersion, targetVersion },\n });\n }\n } else {\n // Validate current schema structure\n const docValidation = validateDocument(rawPageDoc, {\n componentRegistry: options.componentRegistry,\n knownComponentTypes: options.knownComponentTypes,\n });\n const criticalDocErrors = docValidation.errors.filter((e) => {\n if (e.code === 'UNKNOWN_COMPONENT_TYPE' && dependencyPolicy !== 'cancel') {\n return false;\n }\n return true;\n });\n if (criticalDocErrors.length > 0) {\n diagnostics.push({\n code: 'INVALID_PAGE_DOCUMENT',\n severity: 'error',\n message: `Document validation failed with ${criticalDocErrors.length} error(s):\\n` +\n criticalDocErrors.map((e) => `[${e.code}] ${e.path}: ${e.message}`).join('\\n'),\n });\n }\n }\n }\n\n // 8. Verify Asset Inventory & Checksums\n const missingComponents: string[] = [];\n const missingCapabilities: string[] = [];\n const assetConflicts: AssetConflict[] = [];\n\n // Build existing host assets set\n const existingAssetIdsSet = new Set<string>();\n if (options.existingAssetIds) {\n if (Array.isArray(options.existingAssetIds)) {\n for (const id of options.existingAssetIds) existingAssetIdsSet.add(id);\n } else if (options.existingAssetIds instanceof Set) {\n for (const id of options.existingAssetIds) existingAssetIdsSet.add(id);\n }\n }\n\n // Check host assetProvider list if available and existingAssetIds not given\n if (options.assetProvider?.list && !options.existingAssetIds) {\n try {\n const list = await options.assetProvider.list();\n if (Array.isArray(list)) {\n for (const item of list) {\n if (item?.id) existingAssetIdsSet.add(item.id);\n }\n }\n } catch {\n // Non-fatal\n }\n }\n\n if (parsedManifest) {\n for (const assetItem of parsedManifest.assets) {\n // Validate asset path in archive\n const assetFile = unzipped[assetItem.path];\n if (!assetFile) {\n diagnostics.push({\n code: 'ASSET_FILE_MISSING',\n severity: 'error',\n message: `Declared asset \"${assetItem.id}\" is missing in archive at path \"${assetItem.path}\".`,\n path: assetItem.path,\n details: { assetId: assetItem.id },\n });\n continue;\n }\n\n // Validate size\n if (assetFile.byteLength !== assetItem.size) {\n diagnostics.push({\n code: 'ASSET_SIZE_MISMATCH',\n severity: 'error',\n message: `Asset \"${assetItem.id}\" size mismatch: expected ${assetItem.size} bytes, found ${assetFile.byteLength} bytes.`,\n path: assetItem.path,\n details: { assetId: assetItem.id, expected: assetItem.size, actual: assetFile.byteLength },\n });\n }\n\n // Validate checksum if provided\n if (assetItem.checksum) {\n const actualChecksum = await calculateChecksum(assetFile);\n if (actualChecksum !== assetItem.checksum) {\n diagnostics.push({\n code: 'ASSET_CHECKSUM_MISMATCH',\n severity: 'error',\n message: `Asset \"${assetItem.id}\" checksum mismatch: expected ${assetItem.checksum}, calculated ${actualChecksum}.`,\n path: assetItem.path,\n details: { assetId: assetItem.id, expected: assetItem.checksum, actual: actualChecksum },\n });\n }\n }\n\n // Check collision with host assets\n let isConflict = false;\n if (typeof options.existingAssetIds === 'function') {\n const fnRes = await options.existingAssetIds(assetItem.id);\n if (fnRes) isConflict = true;\n } else if (existingAssetIdsSet.has(assetItem.id)) {\n isConflict = true;\n }\n\n if (isConflict) {\n assetConflicts.push({\n assetId: assetItem.id,\n path: assetItem.path,\n mimeType: assetItem.mimeType,\n size: assetItem.size,\n });\n }\n }\n\n // Report Asset Collision diagnostics\n if (assetConflicts.length > 0) {\n const conflictIds = assetConflicts.map((c) => c.assetId).join(', ');\n if (assetCollisionStrategy === 'reject' && !options.onAssetConflict) {\n diagnostics.push({\n code: 'ASSET_CONFLICT',\n severity: 'error',\n message: `Asset collision detected for asset(s): ${conflictIds}. Host assets will not be overwritten without an explicit assetCollisionStrategy.`,\n details: { assetConflicts, strategy: assetCollisionStrategy },\n });\n } else {\n diagnostics.push({\n code: 'ASSET_CONFLICT',\n severity: 'info',\n message: `Asset collision detected for asset(s): ${conflictIds}. Strategy \"${assetCollisionStrategy}\" will be applied on import.`,\n details: { assetConflicts, strategy: assetCollisionStrategy },\n });\n }\n }\n\n // 9. Component Requirements Check\n const knownSet = new Set<string>();\n if (options.knownComponentTypes) {\n for (const t of options.knownComponentTypes) knownSet.add(t);\n }\n // Add standard built-ins\n const builtIns = ['page', 'section', 'container', 'columns', 'heading', 'text', 'image', 'button', 'collection'];\n for (const b of builtIns) knownSet.add(b);\n\n for (const compType of parsedManifest.requiredComponents) {\n let isSupported = knownSet.has(compType);\n if (!isSupported && options.componentRegistry) {\n isSupported = options.componentRegistry.has(compType);\n }\n if (!isSupported) {\n missingComponents.push(compType);\n }\n }\n\n if (missingComponents.length > 0) {\n if (dependencyPolicy === 'cancel' && !options.allowMissingComponents) {\n diagnostics.push({\n code: 'MISSING_COMPONENTS',\n severity: 'error',\n message: `Package requires custom component(s) not registered in host: ${missingComponents.join(', ')}.`,\n details: { missingComponents, policy: dependencyPolicy },\n });\n } else if (dependencyPolicy === 'import-with-placeholder' || options.allowMissingComponents) {\n diagnostics.push({\n code: 'MISSING_COMPONENTS',\n severity: 'warning',\n message: `Package requires custom component(s) [${missingComponents.join(', ')}] not registered in host. Nodes and props are preserved intact for placeholder rendering.`,\n details: { missingComponents, policy: dependencyPolicy },\n });\n } else if (dependencyPolicy === 'install-or-register-before-import') {\n diagnostics.push({\n code: 'MISSING_COMPONENTS',\n severity: 'info',\n message: `Package requires custom component(s) [${missingComponents.join(', ')}]. Installation/registration required before import.`,\n details: { missingComponents, policy: dependencyPolicy },\n });\n }\n }\n\n // 10. Capability Requirements Check\n const supportedCaps = new Set<string>();\n if (options.supportedCapabilities) {\n for (const c of options.supportedCapabilities) supportedCaps.add(c);\n }\n\n for (const cap of parsedManifest.requiredCapabilities) {\n if (!supportedCaps.has(cap)) {\n missingCapabilities.push(cap);\n }\n }\n\n if (missingCapabilities.length > 0) {\n if (dependencyPolicy === 'cancel' && !options.allowMissingCapabilities) {\n diagnostics.push({\n code: 'MISSING_CAPABILITIES',\n severity: 'error',\n message: `Package requires capability/capabilities not supported by host: ${missingCapabilities.join(', ')}.`,\n details: { missingCapabilities, policy: dependencyPolicy },\n });\n } else if (dependencyPolicy === 'import-with-placeholder' || options.allowMissingCapabilities) {\n diagnostics.push({\n code: 'MISSING_CAPABILITIES',\n severity: 'warning',\n message: `Package requires capability/capabilities [${missingCapabilities.join(', ')}] not supported by host. Placeholder rendering enabled.`,\n details: { missingCapabilities, policy: dependencyPolicy },\n });\n } else if (dependencyPolicy === 'install-or-register-before-import') {\n diagnostics.push({\n code: 'MISSING_CAPABILITIES',\n severity: 'info',\n message: `Package requires capability/capabilities [${missingCapabilities.join(', ')}]. Registration required before import.`,\n details: { missingCapabilities, policy: dependencyPolicy },\n });\n }\n }\n }\n\n const hasErrors = diagnostics.some((d) => d.severity === 'error');\n const valid = !hasErrors;\n const canImport = valid;\n\n return buildReport(valid, canImport, {\n manifest: parsedManifest,\n rawMetadata,\n sourceVersion: docVersion,\n targetVersion,\n requiresMigration,\n migrationPath,\n missingComponents,\n missingCapabilities,\n dependencyPolicy,\n assetCount: parsedManifest?.assets.length || 0,\n assetConflicts,\n assetCollisionStrategy,\n totalUncompressedBytes,\n diagnostics,\n });\n}\n\nfunction buildReport(\n valid: boolean,\n canImport: boolean,\n fields: Partial<PreflightReport>,\n): PreflightReport {\n return {\n valid,\n canImport,\n targetVersion: fields.targetVersion || CURRENT_SCHEMA_VERSION,\n requiresMigration: fields.requiresMigration || false,\n missingComponents: fields.missingComponents || [],\n missingCapabilities: fields.missingCapabilities || [],\n dependencyPolicy: fields.dependencyPolicy || 'cancel',\n assetCount: fields.assetCount || 0,\n assetConflicts: fields.assetConflicts || [],\n assetCollisionStrategy: fields.assetCollisionStrategy || 'reject',\n totalUncompressedBytes: fields.totalUncompressedBytes || 0,\n diagnostics: fields.diagnostics || [],\n ...fields,\n };\n}\n\n/**\n * Preview a .stora package without mutating host state.\n * Returns missing dependencies, asset conflicts, schema migration status, and diagnostics.\n */\nexport const previewImportPackage = preflightPackage;\n\n/**\n * Alias for preflightPackage.\n */\nexport const inspectPackage = preflightPackage;\n\n/**\n * Default generator for renaming colliding asset IDs.\n */\nexport function defaultRenameAssetStrategy(\n incoming: ManifestAssetItem,\n existingIds: Set<string>,\n): string {\n let candidate = `${incoming.id}_imported`;\n let counter = 1;\n while (existingIds.has(candidate)) {\n candidate = `${incoming.id}_imported_${counter}`;\n counter++;\n }\n return candidate;\n}\n\n/**\n * Imports a .stora package with preflight safety checks, schema migration, missing dependency policy,\n * and host-controlled asset collision handling.\n */\nexport async function importPackage(\n archiveData: Uint8Array | ArrayBuffer,\n options: ImportPackageOptions = {},\n): Promise<ImportPackageResult> {\n // 1. Run Preflight Inspection first\n let preflight = await preflightPackage(archiveData, options);\n\n // 2. Handle 'install-or-register-before-import' policy hook\n const dependencyPolicy = options.dependencyPolicy || preflight.dependencyPolicy;\n if (\n dependencyPolicy === 'install-or-register-before-import' &&\n (preflight.missingComponents.length > 0 || preflight.missingCapabilities.length > 0) &&\n options.onMissingDependency\n ) {\n try {\n await options.onMissingDependency(\n {\n components: [...preflight.missingComponents],\n capabilities: [...preflight.missingCapabilities],\n },\n preflight,\n );\n\n // Re-run preflight after hook execution\n preflight = await preflightPackage(archiveData, {\n ...options,\n dependencyPolicy: 'cancel', // Strict check after install attempt\n });\n } catch (err) {\n const diag: PreflightDiagnostic = {\n code: 'HOST_ADAPTER_ERROR',\n severity: 'error',\n message: `Dynamic dependency registration failed: ${err instanceof Error ? err.message : String(err)}`,\n };\n return {\n success: false,\n errors: [diag],\n diagnosticMessage: diag.message,\n preflight,\n };\n }\n }\n\n if (!preflight.canImport || !preflight.manifest) {\n const errorDiagnostics = preflight.diagnostics.filter((d) => d.severity === 'error');\n const diagnosticMessage = `Package import rejected with ${errorDiagnostics.length} error(s):\\n` +\n errorDiagnostics.map((d) => `[${d.code}] ${d.path ? d.path + ': ' : ''}${d.message}`).join('\\n');\n\n return {\n success: false,\n errors: errorDiagnostics,\n diagnosticMessage,\n preflight,\n };\n }\n\n const archiveBytes = archiveData instanceof Uint8Array ? archiveData : new Uint8Array(archiveData);\n const unzipped = unzipSync(archiveBytes);\n\n // 3. Read and Migrate Page Document\n const pageRaw = JSON.parse(strFromU8(unzipped['page.json']));\n let finalDocument: PageDocument;\n\n if (preflight.requiresMigration) {\n const migrationRegistry = options.migrationRegistry || defaultMigrationRegistry;\n const migrationRes = migrateDocument(pageRaw, {\n targetVersion: options.targetSchemaVersion || CURRENT_SCHEMA_VERSION,\n registry: migrationRegistry,\n validate: true,\n });\n\n if (!migrationRes.success || !migrationRes.document) {\n const err: PreflightDiagnostic = {\n code: 'MIGRATION_FAILED',\n severity: 'error',\n message: `Failed to migrate document from \"${preflight.sourceVersion}\" to \"${preflight.targetVersion}\".`,\n details: { diagnostic: migrationRes.diagnostic },\n };\n return {\n success: false,\n errors: [err],\n diagnosticMessage: err.message,\n preflight,\n };\n }\n\n finalDocument = migrationRes.document;\n } else {\n finalDocument = pageRaw as PageDocument;\n }\n\n // Untrusted input: never let tracking secrets / server destinations into the host document.\n const importWarnings: PreflightDiagnostic[] = [];\n const strippedSecrets = stripDocumentTrackingSecretsInPlace(finalDocument);\n if (strippedSecrets.length > 0) {\n importWarnings.push({\n code: 'TRACKING_SECRET_REMOVED',\n severity: 'warning',\n message: 'Tracking secret removed from imported document; re-link credential via credentialId.',\n path: 'page.json',\n details: { paths: strippedSecrets },\n });\n }\n\n // 4. Extract and Merge Metadata\n let metadata: DocumentMetadata = finalDocument.metadata || {\n title: 'Imported Page',\n description: '',\n author: '',\n tags: [],\n category: 'general',\n version: finalDocument.version || CURRENT_SCHEMA_VERSION,\n };\n\n if (unzipped['metadata.json']) {\n try {\n const metaFromFile = JSON.parse(strFromU8(unzipped['metadata.json'])) as DocumentMetadata;\n metadata = {\n ...metadata,\n ...metaFromFile,\n };\n } catch {\n // Use document metadata\n }\n }\n\n finalDocument.metadata = metadata;\n\n // 5. Build existing host assets set\n const existingAssetIdsSet = new Set<string>();\n if (options.existingAssetIds) {\n if (Array.isArray(options.existingAssetIds)) {\n for (const id of options.existingAssetIds) existingAssetIdsSet.add(id);\n } else if (options.existingAssetIds instanceof Set) {\n for (const id of options.existingAssetIds) existingAssetIdsSet.add(id);\n }\n }\n\n if (options.assetProvider?.list && !options.existingAssetIds) {\n try {\n const list = await options.assetProvider.list();\n if (Array.isArray(list)) {\n for (const item of list) {\n if (item?.id) existingAssetIdsSet.add(item.id);\n }\n }\n } catch {\n // Non-fatal\n }\n }\n\n const renameAssetFn = options.renameAssetStrategy || defaultRenameAssetStrategy;\n const renameMap: Record<string, string> = {};\n const extractedAssets = new Map<string, ExtractedAsset>();\n\n // 6. Extract Assets with Host-Controlled Collision Resolution\n for (const assetItem of preflight.manifest.assets) {\n const assetBytes = unzipped[assetItem.path];\n if (assetBytes) {\n let targetAssetId = assetItem.id;\n let effectiveStrategy: AssetCollisionStrategy = options.assetCollisionStrategy || 'reject';\n\n const conflictInfo = preflight.assetConflicts.find((c) => c.assetId === assetItem.id);\n\n if (conflictInfo) {\n if (options.onAssetConflict) {\n try {\n const conflictRes = await options.onAssetConflict(conflictInfo);\n if (typeof conflictRes === 'string') {\n effectiveStrategy = conflictRes;\n } else {\n effectiveStrategy = conflictRes.action;\n if (conflictRes.newAssetId) {\n targetAssetId = conflictRes.newAssetId;\n }\n }\n } catch (err) {\n const diag: PreflightDiagnostic = {\n code: 'HOST_ADAPTER_ERROR',\n severity: 'error',\n message: `Asset conflict resolution handler failed for \"${assetItem.id}\": ${err instanceof Error ? err.message : String(err)}`,\n path: assetItem.path,\n };\n return {\n success: false,\n errors: [diag],\n diagnosticMessage: diag.message,\n preflight,\n };\n }\n }\n\n if (effectiveStrategy === 'reject') {\n const diag: PreflightDiagnostic = {\n code: 'ASSET_CONFLICT',\n severity: 'error',\n message: `Import aborted: Asset \"${assetItem.id}\" collides with host asset. No overwrite strategy specified.`,\n path: assetItem.path,\n };\n return {\n success: false,\n errors: [diag],\n diagnosticMessage: diag.message,\n preflight,\n };\n }\n\n if (effectiveStrategy === 'rename') {\n if (targetAssetId === assetItem.id) {\n targetAssetId = renameAssetFn(assetItem, existingAssetIdsSet);\n }\n renameMap[assetItem.id] = targetAssetId;\n existingAssetIdsSet.add(targetAssetId);\n }\n }\n\n let hostInfo: AssetInfo | string | undefined;\n\n if (effectiveStrategy === 'reuse-existing' && conflictInfo) {\n // Reuse existing asset: skip binary upload and resolve from host provider\n if (options.assetProvider?.resolve) {\n hostInfo = await options.assetProvider.resolve(targetAssetId);\n }\n } else {\n // Upload or pass to onAssetImport hook\n const effectiveMeta: ManifestAssetItem = {\n ...assetItem,\n id: targetAssetId,\n };\n\n if (options.onAssetImport) {\n try {\n const result = await options.onAssetImport(targetAssetId, assetBytes, effectiveMeta);\n if (result) hostInfo = result;\n } catch (err) {\n const diag: PreflightDiagnostic = {\n code: 'HOST_ADAPTER_ERROR',\n severity: 'error',\n message: `Host asset import hook failed for \"${targetAssetId}\": ${err instanceof Error ? err.message : String(err)}`,\n path: assetItem.path,\n };\n return {\n success: false,\n errors: [diag],\n diagnosticMessage: diag.message,\n preflight,\n };\n }\n } else if (options.assetProvider?.upload) {\n try {\n const blob = new Blob([assetBytes], { type: assetItem.mimeType });\n const filename = assetItem.path.replace(/^assets\\//, '');\n const file = new File([blob], filename, { type: assetItem.mimeType });\n const info = await options.assetProvider.upload(file, {\n assetId: targetAssetId,\n originalAssetId: assetItem.id,\n });\n if (info) hostInfo = info;\n } catch {\n // Non-fatal if upload not strictly required\n }\n }\n }\n\n extractedAssets.set(targetAssetId, {\n bytes: assetBytes,\n meta: {\n ...assetItem,\n id: targetAssetId,\n },\n hostInfo,\n });\n }\n }\n\n // 7. Remap Asset References in Document if Any Assets Were Renamed\n if (Object.keys(renameMap).length > 0) {\n remapDocumentAssetReferences(finalDocument, renameMap);\n }\n\n return {\n success: true,\n document: finalDocument,\n manifest: preflight.manifest,\n metadata,\n extractedAssets,\n renamedAssets: Object.keys(renameMap).length > 0 ? renameMap : undefined,\n preflight,\n ...(importWarnings.length > 0 ? { warnings: importWarnings } : {}),\n };\n}\n\n/**\n * Alias for importPackage.\n */\nexport const importStoraPackage = importPackage;\n","import {\n PageDocument,\n PageDocumentSchema,\n CURRENT_SCHEMA_VERSION,\n SCHEMA_NAME,\n ResponsiveStyles,\n} from '@kubuild/schema';\nimport { deepClone } from '../document/command-tree-utils';\nimport { validateDocument } from '../validation/validator';\nimport { stripDocumentTrackingSecretsInPlace } from './tracking-sanitizer';\n\nexport type MigrationErrorCode =\n | 'NO_MIGRATION_PATH'\n | 'UNSUPPORTED_SCHEMA_VERSION'\n | 'INVALID_SOURCE_DOCUMENT'\n | 'MIGRATION_EXECUTION_FAILED';\n\nexport interface MigrationError {\n code: MigrationErrorCode;\n message: string;\n sourceVersion: string;\n targetVersion: string;\n details?: Record<string, unknown>;\n}\n\nexport type MigrationWarningCode = 'TRACKING_SECRET_REMOVED';\n\n/**\n * Non-fatal note emitted by a migration step (the migration still succeeds).\n */\nexport interface MigrationWarning {\n code: MigrationWarningCode | (string & {});\n message: string;\n /** Step that emitted the warning, e.g. \"1.0.0->1.1.0\". */\n step?: string;\n /** Dotted document paths affected. */\n paths?: string[];\n}\n\nexport interface MigrationDiagnostic {\n success: boolean;\n sourceVersion: string;\n targetVersion: string;\n migrationPath: string[];\n stepsApplied: number;\n dryRun: boolean;\n errors?: MigrationError[];\n /** Non-fatal notes, e.g. tracking secrets stripped from the document. */\n warnings?: MigrationWarning[];\n}\n\nexport interface MigrationResult {\n success: boolean;\n document?: PageDocument;\n diagnostic: MigrationDiagnostic;\n}\n\nexport interface MigrateOptions {\n /**\n * Target schema version (defaults to CURRENT_SCHEMA_VERSION).\n */\n targetVersion?: string;\n /**\n * If true, validates path and simulates migration without modifying production data.\n */\n dryRun?: boolean;\n /**\n * Custom migration registry (defaults to defaultMigrationRegistry).\n */\n registry?: MigrationRegistry;\n /**\n * Validate document with schema validator after migration (default: true).\n */\n validate?: boolean;\n}\n\n/** Context handed to each migration step. */\nexport interface MigrationStepContext {\n /** Records a non-fatal warning on the final `MigrationDiagnostic`. */\n warn: (warning: MigrationWarning) => void;\n}\n\nexport type MigrationFunction = (\n rawDoc: Record<string, unknown>,\n context: MigrationStepContext,\n) => Record<string, unknown>;\n\nexport interface MigrationStep {\n fromVersion: string;\n toVersion: string;\n migrate: MigrationFunction;\n description?: string;\n}\n\n/**\n * Migration Registry to manage version transition steps.\n */\nexport class MigrationRegistry {\n private steps: Map<string, MigrationStep> = new Map();\n\n /**\n * Register a migration step from one version to another.\n */\n register(step: MigrationStep): void {\n const key = this.getKey(step.fromVersion, step.toVersion);\n this.steps.set(key, step);\n }\n\n private getKey(fromVersion: string, toVersion: string): string {\n return `${fromVersion}->${toVersion}`;\n }\n\n /**\n * Find shortest path of versions to migrate from source to target using BFS.\n */\n findPath(sourceVersion: string, targetVersion: string): string[] | null {\n if (sourceVersion === targetVersion) {\n return [sourceVersion];\n }\n\n const queue: { version: string; path: string[] }[] = [\n { version: sourceVersion, path: [sourceVersion] },\n ];\n const visited = new Set<string>([sourceVersion]);\n\n while (queue.length > 0) {\n const { version: currentVersion, path } = queue.shift()!;\n\n for (const step of this.steps.values()) {\n if (step.fromVersion === currentVersion) {\n const nextVersion = step.toVersion;\n if (nextVersion === targetVersion) {\n return [...path, nextVersion];\n }\n\n if (!visited.has(nextVersion)) {\n visited.add(nextVersion);\n queue.push({ version: nextVersion, path: [...path, nextVersion] });\n }\n }\n }\n }\n\n return null;\n }\n\n /**\n * Check if a valid migration path exists between source and target versions.\n */\n hasPath(sourceVersion: string, targetVersion: string): boolean {\n return this.findPath(sourceVersion, targetVersion) !== null;\n }\n\n /**\n * Get the migration step handler for a direct version step.\n */\n getStep(fromVersion: string, toVersion: string): MigrationStep | undefined {\n return this.steps.get(this.getKey(fromVersion, toVersion));\n }\n}\n\n/**\n * Helper to recursively migrate legacy flat styles: { color: 'red' } to responsive: { base: { color: 'red' } }\n */\nfunction convertNodeStylesToResponsive(node: Record<string, unknown>): void {\n if (node.styles && typeof node.styles === 'object' && !Array.isArray(node.styles)) {\n const styles = node.styles as Record<string, unknown>;\n const hasBreakpointKeys = 'base' in styles || 'desktop' in styles || 'tablet' in styles || 'mobile' in styles;\n if (!hasBreakpointKeys) {\n node.styles = {\n base: { ...styles },\n } as ResponsiveStyles;\n }\n }\n\n if (Array.isArray(node.children)) {\n for (const child of node.children) {\n if (child && typeof child === 'object') {\n convertNodeStylesToResponsive(child as Record<string, unknown>);\n }\n }\n }\n}\n\n// Built-in Default Registry\nexport const defaultMigrationRegistry = new MigrationRegistry();\n\n// 1. Migration from 0.1.0 -> 1.0.0 (Alpha to v1)\ndefaultMigrationRegistry.register({\n fromVersion: '0.1.0',\n toVersion: '1.0.0',\n description: 'Migrate alpha 0.1.0 schema (root node key, flat styles) to v1.0.0',\n migrate: (rawDoc: Record<string, unknown>) => {\n const migrated = deepClone(rawDoc);\n migrated.schema = SCHEMA_NAME;\n migrated.version = '1.0.0';\n\n // Migrate root node key: legacy used 'root' instead of 'document'\n if (migrated.root && !migrated.document) {\n migrated.document = migrated.root;\n delete migrated.root;\n }\n\n // Default metadata\n if (!migrated.metadata || typeof migrated.metadata !== 'object') {\n migrated.metadata = {\n title: 'Migrated Page',\n description: '',\n author: '',\n tags: [],\n category: 'general',\n version: '1.0.0',\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n };\n } else {\n const meta = migrated.metadata as Record<string, unknown>;\n meta.title = meta.title || 'Migrated Page';\n meta.tags = Array.isArray(meta.tags) ? meta.tags : [];\n meta.version = '1.0.0';\n }\n\n // Migrate node tree flat styles\n if (migrated.document && typeof migrated.document === 'object') {\n convertNodeStylesToResponsive(migrated.document as Record<string, unknown>);\n }\n\n return migrated;\n },\n});\n\n// 2. Migration from 0.2.0 -> 1.0.0\ndefaultMigrationRegistry.register({\n fromVersion: '0.2.0',\n toVersion: '1.0.0',\n description: 'Migrate 0.2.0 schema to v1.0.0',\n migrate: (rawDoc: Record<string, unknown>) => {\n const migrated = deepClone(rawDoc);\n migrated.schema = SCHEMA_NAME;\n migrated.version = '1.0.0';\n\n if (migrated.document && typeof migrated.document === 'object') {\n convertNodeStylesToResponsive(migrated.document as Record<string, unknown>);\n }\n\n return migrated;\n },\n});\n\n// 3. Migration from 0.9.0 -> 1.0.0 (Beta to v1)\ndefaultMigrationRegistry.register({\n fromVersion: '0.9.0',\n toVersion: '1.0.0',\n description: 'Migrate 0.9.0 beta schema to v1.0.0',\n migrate: (rawDoc: Record<string, unknown>) => {\n const migrated = deepClone(rawDoc);\n migrated.schema = SCHEMA_NAME;\n migrated.version = '1.0.0';\n\n if (!migrated.metadata || typeof migrated.metadata !== 'object') {\n migrated.metadata = {\n title: 'Migrated Page',\n description: '',\n author: '',\n tags: [],\n category: 'general',\n version: '1.0.0',\n };\n }\n\n return migrated;\n },\n});\n\n// 4. Shorthand \"1.0\" -> \"1.0.0\"\ndefaultMigrationRegistry.register({\n fromVersion: '1.0',\n toVersion: '1.0.0',\n description: 'Normalize 1.0 version string to 1.0.0',\n migrate: (rawDoc: Record<string, unknown>) => {\n const migrated = deepClone(rawDoc);\n migrated.version = '1.0.0';\n return migrated;\n },\n});\n\n// 5. 1.0.0 -> 1.1.0: tracking secrets move out of the document (host-owned, resolved by credentialId)\ndefaultMigrationRegistry.register({\n fromVersion: '1.0.0',\n toVersion: '1.1.0',\n description:\n 'Remove tracking secrets and server destinations (capiAccessToken, accessToken, measurementProtocolSecret, serverRelayUrl, custom endpointUrl/headers) from the document',\n migrate: (rawDoc: Record<string, unknown>, context) => {\n const migrated = deepClone(rawDoc);\n migrated.version = '1.1.0';\n const removed = stripDocumentTrackingSecretsInPlace(migrated);\n if (removed.length > 0) {\n context.warn({\n code: 'TRACKING_SECRET_REMOVED',\n message:\n 'Tracking secret removed; re-link credential via credentialId (secrets are now stored by the host and resolved server-side).',\n step: '1.0.0->1.1.0',\n paths: removed,\n });\n }\n return migrated;\n },\n});\n\n/**\n * Check whether a migration path exists between source and target versions.\n */\nexport function canMigrate(\n sourceVersion: string,\n targetVersion: string = CURRENT_SCHEMA_VERSION,\n registry: MigrationRegistry = defaultMigrationRegistry,\n): boolean {\n if (!sourceVersion || !targetVersion) return false;\n if (sourceVersion === targetVersion) return true;\n return registry.hasPath(sourceVersion, targetVersion);\n}\n\n/**\n * Get the sequence of versions forming the migration path.\n */\nexport function getMigrationPath(\n sourceVersion: string,\n targetVersion: string = CURRENT_SCHEMA_VERSION,\n registry: MigrationRegistry = defaultMigrationRegistry,\n): string[] | null {\n if (!sourceVersion || !targetVersion) return null;\n return registry.findPath(sourceVersion, targetVersion);\n}\n\n/**\n * Migrate a page document from an older schema version to current (or specified) schema version.\n * Supports dry-run execution, step diagnostics, and structured error reporting.\n */\nexport function migrateDocument(\n rawDocument: unknown,\n options: MigrateOptions = {},\n): MigrationResult {\n const targetVersion = options.targetVersion ?? CURRENT_SCHEMA_VERSION;\n const dryRun = options.dryRun ?? false;\n const registry = options.registry ?? defaultMigrationRegistry;\n const validate = options.validate ?? true;\n\n // 1. Basic object validation\n if (!rawDocument || typeof rawDocument !== 'object' || Array.isArray(rawDocument)) {\n const error: MigrationError = {\n code: 'INVALID_SOURCE_DOCUMENT',\n message: 'Source document must be a non-null object.',\n sourceVersion: 'unknown',\n targetVersion,\n };\n return {\n success: false,\n diagnostic: {\n success: false,\n sourceVersion: 'unknown',\n targetVersion,\n migrationPath: [],\n stepsApplied: 0,\n dryRun,\n errors: [error],\n },\n };\n }\n\n const doc = rawDocument as Record<string, unknown>;\n const sourceVersion = typeof doc.version === 'string' ? doc.version.trim() : 'unknown';\n\n // 2. If already on target version\n if (sourceVersion === targetVersion) {\n const cloned = deepClone(doc) as unknown as PageDocument;\n // Defensive: a current-version document must never carry tracking secrets either.\n const removedSecrets = stripDocumentTrackingSecretsInPlace(cloned);\n const currentWarnings: MigrationWarning[] =\n removedSecrets.length > 0\n ? [\n {\n code: 'TRACKING_SECRET_REMOVED',\n message:\n 'Tracking secret removed; re-link credential via credentialId (secrets are stored by the host and resolved server-side).',\n paths: removedSecrets,\n },\n ]\n : [];\n if (validate) {\n const validation = validateDocument(cloned);\n if (!validation.valid) {\n return {\n success: false,\n diagnostic: {\n success: false,\n sourceVersion,\n targetVersion,\n migrationPath: [sourceVersion],\n stepsApplied: 0,\n dryRun,\n errors: validation.errors.map((e) => ({\n code: 'INVALID_SOURCE_DOCUMENT',\n message: `Validation error: ${e.message} at ${e.path}`,\n sourceVersion,\n targetVersion,\n })),\n },\n };\n }\n }\n\n return {\n success: true,\n document: cloned,\n diagnostic: {\n success: true,\n sourceVersion,\n targetVersion,\n migrationPath: [sourceVersion],\n stepsApplied: 0,\n dryRun,\n ...(currentWarnings.length > 0 ? { warnings: currentWarnings } : {}),\n },\n };\n }\n\n // 3. Find migration path\n const path = registry.findPath(sourceVersion, targetVersion);\n if (!path || path.length <= 1) {\n const error: MigrationError = {\n code: 'NO_MIGRATION_PATH',\n message: `No migration path found from schema version \"${sourceVersion}\" to \"${targetVersion}\".`,\n sourceVersion,\n targetVersion,\n };\n return {\n success: false,\n diagnostic: {\n success: false,\n sourceVersion,\n targetVersion,\n migrationPath: [],\n stepsApplied: 0,\n dryRun,\n errors: [error],\n },\n };\n }\n\n // 4. If dry-run mode, return simulation success without modifying\n if (dryRun) {\n return {\n success: true,\n diagnostic: {\n success: true,\n sourceVersion,\n targetVersion,\n migrationPath: path,\n stepsApplied: path.length - 1,\n dryRun: true,\n },\n };\n }\n\n // 5. Execute migration path steps sequentially\n let currentDoc = deepClone(doc);\n let stepsApplied = 0;\n const warnings: MigrationWarning[] = [];\n const stepContext: MigrationStepContext = { warn: (w) => warnings.push(w) };\n\n for (let i = 0; i < path.length - 1; i++) {\n const fromVer = path[i];\n const toVer = path[i + 1];\n const step = registry.getStep(fromVer, toVer);\n\n if (!step) {\n const error: MigrationError = {\n code: 'MIGRATION_EXECUTION_FAILED',\n message: `Registered migration step for \"${fromVer}\" -> \"${toVer}\" is missing executor.`,\n sourceVersion,\n targetVersion,\n };\n return {\n success: false,\n diagnostic: {\n success: false,\n sourceVersion,\n targetVersion,\n migrationPath: path,\n stepsApplied,\n dryRun,\n errors: [error],\n },\n };\n }\n\n try {\n currentDoc = step.migrate(currentDoc, stepContext);\n stepsApplied++;\n } catch (err: unknown) {\n const error: MigrationError = {\n code: 'MIGRATION_EXECUTION_FAILED',\n message: `Failed executing migration step from \"${fromVer}\" to \"${toVer}\": ${err instanceof Error ? err.message : String(err)}`,\n sourceVersion,\n targetVersion,\n details: { stepFrom: fromVer, stepTo: toVer },\n };\n return {\n success: false,\n diagnostic: {\n success: false,\n sourceVersion,\n targetVersion,\n migrationPath: path,\n stepsApplied,\n dryRun,\n errors: [error],\n },\n };\n }\n }\n\n // 6. Validate final migrated document\n const finalDoc = currentDoc as unknown as PageDocument;\n if (validate) {\n const validation = validateDocument(finalDoc);\n if (!validation.valid) {\n return {\n success: false,\n diagnostic: {\n success: false,\n sourceVersion,\n targetVersion,\n migrationPath: path,\n stepsApplied,\n dryRun,\n errors: validation.errors.map((e) => ({\n code: 'MIGRATION_EXECUTION_FAILED',\n message: `Post-migration validation error: ${e.message} at ${e.path}`,\n sourceVersion,\n targetVersion,\n })),\n },\n };\n }\n }\n\n return {\n success: true,\n document: finalDoc,\n diagnostic: {\n success: true,\n sourceVersion,\n targetVersion,\n migrationPath: path,\n stepsApplied,\n dryRun: false,\n ...(warnings.length > 0 ? { warnings } : {}),\n },\n };\n}\n","import {\n Artboard,\n PageDocument,\n ProjectDocument,\n ProjectDocumentSchema,\n PROJECT_SCHEMA_NAME,\n CURRENT_PROJECT_SCHEMA_VERSION,\n looksLikeProjectDocument,\n} from '@kubuild/schema';\nimport { migrateDocument, MigrationError } from './migration';\n\nexport type ProjectLoadErrorCode =\n | 'INVALID_SOURCE'\n | 'PROJECT_SCHEMA_INVALID'\n | 'LEGACY_MIGRATION_FAILED';\n\nexport interface ProjectLoadError {\n code: ProjectLoadErrorCode;\n message: string;\n details?: Record<string, unknown>;\n}\n\nexport interface ProjectLoadResult {\n success: boolean;\n project?: ProjectDocument;\n /** True when the payload arrived as a legacy single-page document and was wrapped. */\n wrappedFromLegacyPage: boolean;\n errors: ProjectLoadError[];\n}\n\nexport interface WrapPageAsProjectOptions {\n artboardId?: string;\n name?: string;\n slug?: string;\n width?: number;\n}\n\nconst DEFAULT_PAGE_ARTBOARD_ID = 'artboard-page-1';\n\n/**\n * Wrap a single PageDocument into a one-artboard ProjectDocument.\n * Used both by the legacy load path and by consumers that still hold a lone page.\n */\nexport function wrapPageDocumentAsProject(\n document: PageDocument,\n options: WrapPageAsProjectOptions = {},\n): ProjectDocument {\n const artboardId = options.artboardId ?? DEFAULT_PAGE_ARTBOARD_ID;\n const artboard: Artboard = {\n id: artboardId,\n name: options.name ?? document.metadata?.title ?? 'Page',\n artboardType: 'page',\n slug: options.slug ?? '/',\n document,\n ...(options.width !== undefined ? { width: options.width } : {}),\n };\n\n return {\n schema: PROJECT_SCHEMA_NAME,\n version: CURRENT_PROJECT_SCHEMA_VERSION,\n metadata: document.metadata,\n artboards: [artboard],\n activeArtboardId: artboardId,\n };\n}\n\n/**\n * Load a raw payload as a ProjectDocument.\n *\n * `PageDocument -> ProjectDocument` is a schema *kind* switch (`document` singular vs.\n * `artboards[]`, different `schema` literal), not a version step, so it cannot be expressed\n * as a MigrationRegistry step. This loader sniffs the shape and routes accordingly:\n *\n * - already a project (`schema === 'stora.project'` or has `artboards[]`) -> parse as a project\n * - anything else -> run the existing page migration pipeline untouched, then wrap the\n * fully-migrated page into a single-artboard project\n *\n * Legacy inline modal/drawer/collapsible nodes are deliberately NOT auto-extracted into\n * component artboards here; that stays an explicit, author-triggered action so no existing\n * document silently changes how it renders.\n */\nexport function loadProjectDocument(raw: unknown): ProjectLoadResult {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n return {\n success: false,\n wrappedFromLegacyPage: false,\n errors: [\n {\n code: 'INVALID_SOURCE',\n message: 'Source must be a non-null object.',\n },\n ],\n };\n }\n\n if (looksLikeProjectDocument(raw)) {\n const parsed = ProjectDocumentSchema.safeParse(raw);\n if (!parsed.success) {\n return {\n success: false,\n wrappedFromLegacyPage: false,\n errors: [\n {\n code: 'PROJECT_SCHEMA_INVALID',\n message: 'Payload looks like a project document but failed schema validation.',\n details: { issues: parsed.error.issues },\n },\n ],\n };\n }\n return {\n success: true,\n project: parsed.data,\n wrappedFromLegacyPage: false,\n errors: [],\n };\n }\n\n const migration = migrateDocument(raw);\n if (!migration.success || !migration.document) {\n return {\n success: false,\n wrappedFromLegacyPage: false,\n errors: [\n {\n code: 'LEGACY_MIGRATION_FAILED',\n message: 'Payload is not a project document and could not be migrated as a page document.',\n details: {\n migrationErrors: (migration.diagnostic.errors ?? []) as MigrationError[],\n },\n },\n ],\n };\n }\n\n return {\n success: true,\n project: wrapPageDocumentAsProject(migration.document),\n wrappedFromLegacyPage: true,\n errors: [],\n };\n}\n","import {\n PageDocument,\n Node,\n ResponsiveStyles,\n StyleDefinition,\n Manifest,\n VariableBinding,\n ActionBinding,\n AssetReference,\n} from '@kubuild/schema';\n\nexport type SemanticDifferenceKind =\n | 'METADATA_MISMATCH'\n | 'NODE_MISSING'\n | 'NODE_EXTRA'\n | 'NODE_ORDER'\n | 'NODE_TYPE'\n | 'PROP_MISMATCH'\n | 'STYLE_MISMATCH'\n | 'BINDING_MISMATCH'\n | 'ACTION_MISMATCH'\n | 'ASSET_MISMATCH'\n | 'DEPENDENCY_MISMATCH';\n\nexport interface SemanticDifference {\n path: string;\n kind: SemanticDifferenceKind;\n message: string;\n expected?: unknown;\n actual?: unknown;\n}\n\nexport interface SemanticCompareOptions {\n /**\n * Optional map of original asset IDs to host-remapped asset IDs.\n * Used when host renamed colliding assets during import.\n */\n assetIdMap?: Record<string, string> | Map<string, string>;\n\n /**\n * Whether to ignore transient timestamp fields (e.g. createdAt/updatedAt).\n * Default: true.\n */\n ignoreTimestamps?: boolean;\n}\n\nexport interface SemanticComparisonResult {\n equivalent: boolean;\n differences: SemanticDifference[];\n}\n\nfunction isAssetReferenceLike(val: unknown): val is AssetReference {\n if (!val || typeof val !== 'object') return false;\n const obj = val as Record<string, unknown>;\n return obj.type === 'asset' && typeof obj.assetId === 'string' && obj.assetId.trim().length > 0;\n}\n\nfunction isVariableBindingLike(val: unknown): val is VariableBinding {\n if (!val || typeof val !== 'object') return false;\n const obj = val as Record<string, unknown>;\n return obj.type === 'variable' && typeof obj.key === 'string' && obj.key.trim().length > 0;\n}\n\nfunction isActionBindingLike(val: unknown): val is ActionBinding {\n if (!val || typeof val !== 'object') return false;\n const obj = val as Record<string, unknown>;\n return obj.type !== undefined && typeof obj.type === 'string' && obj.type.trim().length > 0 && ('payload' in obj || Object.keys(obj).length <= 2);\n}\n\nfunction normalizeAssetId(\n id: string,\n assetIdMap?: Record<string, string> | Map<string, string>,\n): string {\n if (!assetIdMap) return id;\n if (assetIdMap instanceof Map) {\n return assetIdMap.get(id) ?? id;\n }\n return assetIdMap[id] ?? id;\n}\n\nfunction deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (a === null || b === null || typeof a !== 'object' || typeof b !== 'object') {\n return false;\n }\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (!deepEqual(a[i], b[i])) return false;\n }\n return true;\n }\n\n const objA = a as Record<string, unknown>;\n const objB = b as Record<string, unknown>;\n const keysA = Object.keys(objA);\n const keysB = Object.keys(objB);\n\n if (keysA.length !== keysB.length) return false;\n for (const k of keysA) {\n if (!Object.prototype.hasOwnProperty.call(objB, k)) return false;\n if (!deepEqual(objA[k], objB[k])) return false;\n }\n return true;\n}\n\n/**\n * Recursively compares two props values, checking for variable bindings, action bindings,\n * and asset references (with asset ID mapping support).\n */\nfunction comparePropValues(\n path: string,\n expected: unknown,\n actual: unknown,\n differences: SemanticDifference[],\n options?: SemanticCompareOptions,\n): void {\n // 1. Variable Binding check\n if (isVariableBindingLike(expected)) {\n if (!isVariableBindingLike(actual)) {\n differences.push({\n path,\n kind: 'BINDING_MISMATCH',\n message: `Expected variable binding at \"${path}\", but got non-binding value.`,\n expected,\n actual,\n });\n return;\n }\n const expBinding = expected as VariableBinding;\n const actBinding = actual as VariableBinding;\n if (expBinding.key !== actBinding.key) {\n differences.push({\n path: `${path}.key`,\n kind: 'BINDING_MISMATCH',\n message: `Variable binding key mismatch at \"${path}\": expected \"${expBinding.key}\", got \"${actBinding.key}\".`,\n expected: expBinding.key,\n actual: actBinding.key,\n });\n }\n if (!deepEqual(expBinding.fallback, actBinding.fallback)) {\n differences.push({\n path: `${path}.fallback`,\n kind: 'BINDING_MISMATCH',\n message: `Variable binding fallback mismatch at \"${path}\".`,\n expected: expBinding.fallback,\n actual: actBinding.fallback,\n });\n }\n return;\n }\n\n // 2. Action Binding check\n if (isActionBindingLike(expected) && !isAssetReferenceLike(expected) && !isVariableBindingLike(expected)) {\n if (!isActionBindingLike(actual)) {\n differences.push({\n path,\n kind: 'ACTION_MISMATCH',\n message: `Expected action binding at \"${path}\", but got non-action value.`,\n expected,\n actual,\n });\n return;\n }\n const expAction = expected as ActionBinding;\n const actAction = actual as ActionBinding;\n if (expAction.type !== actAction.type) {\n differences.push({\n path: `${path}.type`,\n kind: 'ACTION_MISMATCH',\n message: `Action binding type mismatch at \"${path}\": expected \"${expAction.type}\", got \"${actAction.type}\".`,\n expected: expAction.type,\n actual: actAction.type,\n });\n }\n if (!deepEqual(expAction.payload ?? {}, actAction.payload ?? {})) {\n differences.push({\n path: `${path}.payload`,\n kind: 'ACTION_MISMATCH',\n message: `Action binding payload mismatch at \"${path}\".`,\n expected: expAction.payload,\n actual: actAction.payload,\n });\n }\n return;\n }\n\n // 3. Asset Reference check\n if (isAssetReferenceLike(expected)) {\n if (!isAssetReferenceLike(actual)) {\n differences.push({\n path,\n kind: 'ASSET_MISMATCH',\n message: `Expected asset reference at \"${path}\", but got non-asset value.`,\n expected,\n actual,\n });\n return;\n }\n const expAsset = expected as AssetReference;\n const actAsset = actual as AssetReference;\n const expectedMappedId = normalizeAssetId(expAsset.assetId, options?.assetIdMap);\n\n if (actAsset.assetId !== expectedMappedId) {\n differences.push({\n path: `${path}.assetId`,\n kind: 'ASSET_MISMATCH',\n message: `Asset reference ID mismatch at \"${path}\": expected \"${expectedMappedId}\" (original: \"${expAsset.assetId}\"), got \"${actAsset.assetId}\".`,\n expected: expectedMappedId,\n actual: actAsset.assetId,\n });\n }\n if (expAsset.filename !== actAsset.filename) {\n differences.push({\n path: `${path}.filename`,\n kind: 'ASSET_MISMATCH',\n message: `Asset reference filename mismatch at \"${path}\": expected \"${expAsset.filename}\", got \"${actAsset.filename}\".`,\n expected: expAsset.filename,\n actual: actAsset.filename,\n });\n }\n if (expAsset.mimeType !== actAsset.mimeType) {\n differences.push({\n path: `${path}.mimeType`,\n kind: 'ASSET_MISMATCH',\n message: `Asset reference mimeType mismatch at \"${path}\": expected \"${expAsset.mimeType}\", got \"${actAsset.mimeType}\".`,\n expected: expAsset.mimeType,\n actual: actAsset.mimeType,\n });\n }\n return;\n }\n\n // 4. Object recursion\n if (\n expected !== null &&\n actual !== null &&\n typeof expected === 'object' &&\n typeof actual === 'object'\n ) {\n if (Array.isArray(expected) !== Array.isArray(actual)) {\n differences.push({\n path,\n kind: 'PROP_MISMATCH',\n message: `Type mismatch at \"${path}\": one is array, other is object.`,\n expected,\n actual,\n });\n return;\n }\n\n if (Array.isArray(expected) && Array.isArray(actual)) {\n if (expected.length !== actual.length) {\n differences.push({\n path,\n kind: 'PROP_MISMATCH',\n message: `Array length mismatch at \"${path}\": expected length ${expected.length}, got ${actual.length}.`,\n expected,\n actual,\n });\n return;\n }\n for (let i = 0; i < expected.length; i++) {\n comparePropValues(`${path}[${i}]`, expected[i], actual[i], differences, options);\n }\n return;\n }\n\n const expObj = expected as Record<string, unknown>;\n const actObj = actual as Record<string, unknown>;\n const allKeys = new Set([...Object.keys(expObj), ...Object.keys(actObj)]);\n\n for (const key of allKeys) {\n if (!(key in expObj)) {\n differences.push({\n path: `${path}.${key}`,\n kind: 'PROP_MISMATCH',\n message: `Unexpected extra prop key \"${key}\" at \"${path}\".`,\n actual: actObj[key],\n });\n } else if (!(key in actObj)) {\n differences.push({\n path: `${path}.${key}`,\n kind: 'PROP_MISMATCH',\n message: `Missing expected prop key \"${key}\" at \"${path}\".`,\n expected: expObj[key],\n });\n } else {\n comparePropValues(`${path}.${key}`, expObj[key], actObj[key], differences, options);\n }\n }\n return;\n }\n\n // 5. Primitive equality check\n if (expected !== actual) {\n differences.push({\n path,\n kind: 'PROP_MISMATCH',\n message: `Value mismatch at \"${path}\": expected \"${String(expected)}\", got \"${String(actual)}\".`,\n expected,\n actual,\n });\n }\n}\n\n/**\n * Compares responsive styles across all breakpoints (base, desktop, tablet, mobile).\n */\nfunction compareStyles(\n nodePath: string,\n expected?: ResponsiveStyles,\n actual?: ResponsiveStyles,\n differences: SemanticDifference[] = [],\n): void {\n const breakpoints = ['base', 'desktop', 'tablet', 'mobile'] as const;\n const expStyles = expected || {};\n const actStyles = actual || {};\n\n for (const bp of breakpoints) {\n const expBp = (expStyles[bp] as StyleDefinition | undefined) || {};\n const actBp = (actStyles[bp] as StyleDefinition | undefined) || {};\n\n const allKeys = new Set([...Object.keys(expBp), ...Object.keys(actBp)]);\n for (const key of allKeys) {\n const expVal = expBp[key];\n const actVal = actBp[key];\n\n // Treat undefined and empty string as equivalent empty style values\n const expNorm = expVal === undefined || expVal === '' ? undefined : expVal;\n const actNorm = actVal === undefined || actVal === '' ? undefined : actVal;\n\n if (expNorm !== actNorm) {\n differences.push({\n path: `${nodePath}.styles.${bp}.${key}`,\n kind: 'STYLE_MISMATCH',\n message: `Style mismatch at \"${nodePath}.styles.${bp}.${key}\": expected \"${String(expVal)}\", got \"${String(actVal)}\".`,\n expected: expVal,\n actual: actVal,\n });\n }\n }\n }\n}\n\n/**\n * Recursively compares two component trees, strictly verifying node identity, order,\n * props, styles, and children.\n */\nfunction compareNodes(\n expected: Node,\n actual: Node,\n nodePath: string,\n differences: SemanticDifference[],\n options?: SemanticCompareOptions,\n): void {\n // 1. Check ID\n if (expected.id !== actual.id) {\n differences.push({\n path: `${nodePath}.id`,\n kind: 'NODE_MISSING',\n message: `Node ID mismatch at \"${nodePath}\": expected \"${expected.id}\", got \"${actual.id}\".`,\n expected: expected.id,\n actual: actual.id,\n });\n }\n\n // 2. Check Type\n if (expected.type !== actual.type) {\n differences.push({\n path: `${nodePath}.type`,\n kind: 'NODE_TYPE',\n message: `Node type mismatch for \"${expected.id}\": expected \"${expected.type}\", got \"${actual.type}\".`,\n expected: expected.type,\n actual: actual.type,\n });\n }\n\n // 3. Compare Props\n comparePropValues(`${nodePath}.props`, expected.props || {}, actual.props || {}, differences, options);\n\n // 4. Compare Styles\n compareStyles(nodePath, expected.styles, actual.styles, differences);\n\n // 5. Compare Children (Order and Content)\n const expChildren = expected.children || [];\n const actChildren = actual.children || [];\n\n if (expChildren.length !== actChildren.length) {\n differences.push({\n path: `${nodePath}.children`,\n kind: 'NODE_ORDER',\n message: `Children count mismatch for node \"${expected.id}\": expected ${expChildren.length}, got ${actChildren.length}.`,\n expected: expChildren.map((c) => c.id),\n actual: actChildren.map((c) => c.id),\n });\n }\n\n const maxLen = Math.max(expChildren.length, actChildren.length);\n for (let i = 0; i < maxLen; i++) {\n const expChild = expChildren[i];\n const actChild = actChildren[i];\n\n if (!expChild && actChild) {\n differences.push({\n path: `${nodePath}.children[${i}]`,\n kind: 'NODE_EXTRA',\n message: `Unexpected extra child node \"${actChild.id}\" at index ${i}.`,\n actual: actChild.id,\n });\n } else if (expChild && !actChild) {\n differences.push({\n path: `${nodePath}.children[${i}]`,\n kind: 'NODE_MISSING',\n message: `Missing child node \"${expChild.id}\" at index ${i}.`,\n expected: expChild.id,\n });\n } else if (expChild && actChild) {\n if (expChild.id !== actChild.id) {\n differences.push({\n path: `${nodePath}.children[${i}]`,\n kind: 'NODE_ORDER',\n message: `Node order mismatch at index ${i}: expected node \"${expChild.id}\", got \"${actChild.id}\".`,\n expected: expChild.id,\n actual: actChild.id,\n });\n }\n compareNodes(expChild, actChild, `${nodePath}.children[${i}](${expChild.id})`, differences, options);\n }\n }\n}\n\n/**\n * Semantically compares two PageDocuments, checking metadata, tree structure,\n * node order, props, responsive styles, bindings, action references, and asset mappings.\n *\n * Only documented transient fields (e.g. transient timestamps, host-generated asset IDs)\n * are ignored or normalized per options.\n */\nexport function compareDocumentsSemantically(\n expected: PageDocument,\n actual: PageDocument,\n options: SemanticCompareOptions = {},\n): SemanticComparisonResult {\n const differences: SemanticDifference[] = [];\n const { ignoreTimestamps = true } = options;\n\n // 1. Schema & Version check\n if (expected.schema !== actual.schema) {\n differences.push({\n path: 'schema',\n kind: 'METADATA_MISMATCH',\n message: `Schema mismatch: expected \"${expected.schema}\", got \"${actual.schema}\".`,\n expected: expected.schema,\n actual: actual.schema,\n });\n }\n if (expected.version !== actual.version) {\n differences.push({\n path: 'version',\n kind: 'METADATA_MISMATCH',\n message: `Schema version mismatch: expected \"${expected.version}\", got \"${actual.version}\".`,\n expected: expected.version,\n actual: actual.version,\n });\n }\n\n // 2. Metadata check\n const expMeta = expected.metadata || ({} as Record<string, unknown>);\n const actMeta = actual.metadata || ({} as Record<string, unknown>);\n const metaKeys = new Set([...Object.keys(expMeta), ...Object.keys(actMeta)]);\n\n for (const k of metaKeys) {\n if (ignoreTimestamps && (k === 'updatedAt' || k === 'createdAt')) {\n continue;\n }\n const expVal = (expMeta as Record<string, unknown>)[k];\n const actVal = (actMeta as Record<string, unknown>)[k];\n if (!deepEqual(expVal, actVal)) {\n differences.push({\n path: `metadata.${k}`,\n kind: 'METADATA_MISMATCH',\n message: `Metadata mismatch at \"metadata.${k}\": expected \"${String(expVal)}\", got \"${String(actVal)}\".`,\n expected: expVal,\n actual: actVal,\n });\n }\n }\n\n // 3. Tree comparison\n compareNodes(\n expected.document,\n actual.document,\n `root(${expected.document.id})`,\n differences,\n options,\n );\n\n return {\n equivalent: differences.length === 0,\n differences,\n };\n}\n\n/**\n * Semantically compares exported and imported package manifests.\n */\nexport function compareManifestsSemantically(\n expected: Manifest,\n actual: Manifest,\n options: SemanticCompareOptions = {},\n): SemanticComparisonResult {\n const differences: SemanticDifference[] = [];\n const { ignoreTimestamps = true } = options;\n\n if (expected.schema !== actual.schema) {\n differences.push({\n path: 'manifest.schema',\n kind: 'METADATA_MISMATCH',\n message: `Manifest schema mismatch: expected \"${expected.schema}\", got \"${actual.schema}\".`,\n expected: expected.schema,\n actual: actual.schema,\n });\n }\n\n if (expected.schemaVersion !== actual.schemaVersion) {\n differences.push({\n path: 'manifest.schemaVersion',\n kind: 'METADATA_MISMATCH',\n message: `Manifest schemaVersion mismatch: expected \"${expected.schemaVersion}\", got \"${actual.schemaVersion}\".`,\n expected: expected.schemaVersion,\n actual: actual.schemaVersion,\n });\n }\n\n // Compare requiredComponents\n const expComponents = new Set(expected.requiredComponents || []);\n const actComponents = new Set(actual.requiredComponents || []);\n for (const c of expComponents) {\n if (!actComponents.has(c)) {\n differences.push({\n path: 'manifest.requiredComponents',\n kind: 'DEPENDENCY_MISMATCH',\n message: `Missing required component in manifest: \"${c}\".`,\n expected: c,\n });\n }\n }\n for (const c of actComponents) {\n if (!expComponents.has(c)) {\n differences.push({\n path: 'manifest.requiredComponents',\n kind: 'DEPENDENCY_MISMATCH',\n message: `Unexpected extra required component in manifest: \"${c}\".`,\n actual: c,\n });\n }\n }\n\n // Compare requiredCapabilities\n const expCaps = new Set(expected.requiredCapabilities || []);\n const actCaps = new Set(actual.requiredCapabilities || []);\n for (const c of expCaps) {\n if (!actCaps.has(c)) {\n differences.push({\n path: 'manifest.requiredCapabilities',\n kind: 'DEPENDENCY_MISMATCH',\n message: `Missing required capability in manifest: \"${c}\".`,\n expected: c,\n });\n }\n }\n for (const c of actCaps) {\n if (!expCaps.has(c)) {\n differences.push({\n path: 'manifest.requiredCapabilities',\n kind: 'DEPENDENCY_MISMATCH',\n message: `Unexpected extra required capability in manifest: \"${c}\".`,\n actual: c,\n });\n }\n }\n\n // Compare assets\n if (expected.assets.length !== actual.assets.length) {\n differences.push({\n path: 'manifest.assets',\n kind: 'ASSET_MISMATCH',\n message: `Manifest asset count mismatch: expected ${expected.assets.length}, got ${actual.assets.length}.`,\n expected: expected.assets.length,\n actual: actual.assets.length,\n });\n }\n\n return {\n equivalent: differences.length === 0,\n differences,\n };\n}\n","import {\n TemplateRecordSchema,\n collectNodeIds,\n isTemplateRecord,\n type TemplateRecord,\n type TemplateRequirements,\n type PageDocument,\n type Node,\n} from '@kubuild/schema';\nimport { deepClone } from '../document/command-tree-utils';\nimport { validateDocument } from '../validation/validator';\n\n/**\n * Standard core built-in component types\n */\nexport const CORE_BUILTIN_COMPONENTS = new Set([\n 'page',\n 'section',\n 'container',\n 'columns',\n 'column',\n 'heading',\n 'text',\n 'image',\n 'button',\n 'collection',\n]);\n\n/**\n * Structured validation error entry\n */\nexport interface TemplateValidationError {\n code: string;\n message: string;\n path: string;\n}\n\n/**\n * Result of template record validation\n */\nexport interface TemplateValidationResult {\n valid: boolean;\n data?: TemplateRecord;\n errors?: TemplateValidationError[];\n}\n\n/**\n * Validates a template record value against TemplateRecordSchema and returns structured errors.\n */\nexport function validateTemplate(value: unknown): TemplateValidationResult {\n const parseResult = TemplateRecordSchema.safeParse(value);\n\n if (parseResult.success) {\n return {\n valid: true,\n data: parseResult.data,\n };\n }\n\n const errors: TemplateValidationError[] = parseResult.error.issues.map((issue) => ({\n code: issue.code,\n message: issue.message,\n path: `/${issue.path.join('/')}`,\n }));\n\n return {\n valid: false,\n errors,\n };\n}\n\n/**\n * Helper to recursively collect all component types used in a node tree.\n */\nfunction collectComponentTypes(node: Node, types: Set<string>): void {\n if (node.type) {\n types.add(node.type);\n }\n if (node.children && Array.isArray(node.children)) {\n for (const child of node.children) {\n collectComponentTypes(child, types);\n }\n }\n}\n\n/**\n * Extracts required components and capabilities from a PageDocument.\n * Detects any custom/non-core component types used in the document tree.\n */\nexport function extractTemplateRequirements(\n doc: PageDocument,\n builtinComponents: Set<string> = CORE_BUILTIN_COMPONENTS\n): TemplateRequirements {\n const componentTypes = new Set<string>();\n if (doc?.document) {\n collectComponentTypes(doc.document, componentTypes);\n }\n\n const customComponents: string[] = [];\n for (const type of componentTypes) {\n if (!builtinComponents.has(type)) {\n customComponents.push(type);\n }\n }\n\n return {\n requiredComponents: customComponents.sort(),\n requiredCapabilities: [],\n };\n}\n\n/**\n * Parameters for creating a TemplateRecord\n */\nexport interface CreateTemplateParams {\n id: string;\n name: string;\n description?: string;\n category?: string;\n tags?: string[];\n thumbnail?: TemplateRecord['thumbnail'];\n author?: string;\n version?: string;\n document?: PageDocument;\n packageReference?: TemplateRecord['packageReference'];\n requirements?: TemplateRequirements;\n createdAt?: string;\n updatedAt?: string;\n custom?: Record<string, unknown>;\n}\n\n/**\n * Creates and validates a TemplateRecord.\n * Automatically extracts requirements from the embedded document if requirements are not explicitly supplied.\n */\nexport function createTemplateRecord(params: CreateTemplateParams): TemplateRecord {\n const now = new Date().toISOString();\n\n let requirements = params.requirements;\n if (!requirements && params.document) {\n requirements = extractTemplateRequirements(params.document);\n }\n\n const candidate: TemplateRecord = {\n id: params.id,\n name: params.name,\n description: params.description ?? '',\n category: params.category ?? 'general',\n tags: params.tags ?? [],\n thumbnail: params.thumbnail,\n author: params.author ?? '',\n version: params.version ?? '1.0.0',\n document: params.document,\n packageReference: params.packageReference,\n requirements: requirements ?? { requiredComponents: [], requiredCapabilities: [] },\n createdAt: params.createdAt ?? now,\n updatedAt: params.updatedAt ?? now,\n custom: params.custom,\n };\n\n const validation = validateTemplate(candidate);\n if (!validation.valid || !validation.data) {\n const errorDetails = validation.errors?.map((e) => `${e.path}: ${e.message}`).join(', ');\n throw new Error(`Invalid template record: ${errorDetails}`);\n }\n\n return validation.data;\n}\n\n/**\n * Required metadata parameters for saving a draft as a template.\n * id and name are strictly required and non-empty.\n */\nexport interface SaveTemplateMetadata {\n id: string;\n name: string;\n description?: string;\n category?: string;\n tags?: string[];\n thumbnail?: TemplateRecord['thumbnail'];\n author?: string;\n version?: string;\n custom?: Record<string, unknown>;\n}\n\nexport interface SaveDraftAsTemplateOptions {\n validateDraft?: boolean;\n requirements?: TemplateRequirements;\n}\n\n/**\n * Exports a draft document snapshot as an immutable reusable TemplateRecord.\n * - Requires mandatory metadata (id, name).\n * - Validates draft document structure.\n * - Extracts component/capability requirements.\n * - Creates a deep-cloned immutable snapshot completely decoupled from the active draft.\n */\nexport function saveDraftAsTemplate(\n draft: PageDocument,\n metadata: SaveTemplateMetadata,\n options: SaveDraftAsTemplateOptions = {}\n): TemplateRecord {\n if (!metadata || typeof metadata !== 'object') {\n throw new Error('Save as template requires metadata with id and name.');\n }\n\n const cleanId = metadata.id?.trim();\n if (!cleanId) {\n throw new Error('Template ID is required and cannot be empty.');\n }\n\n const cleanName = metadata.name?.trim();\n if (!cleanName) {\n throw new Error('Template name is required and cannot be empty.');\n }\n\n if (!draft || !draft.document) {\n throw new Error('Invalid draft document: document tree is missing.');\n }\n\n if (options.validateDraft !== false) {\n const validation = validateDocument(draft);\n if (!validation.valid) {\n const errorMsg = validation.errors.map((e) => `${e.path}: ${e.message}`).join('; ');\n throw new Error(`Cannot save invalid draft as template: ${errorMsg}`);\n }\n }\n\n // Deep clone to guarantee the template snapshot is isolated from future draft edits\n const draftSnapshot: PageDocument = deepClone(draft);\n\n return createTemplateRecord({\n id: cleanId,\n name: cleanName,\n description: metadata.description?.trim() ?? '',\n category: metadata.category?.trim() ?? 'general',\n tags: metadata.tags ? [...metadata.tags] : [],\n thumbnail: metadata.thumbnail,\n author: metadata.author?.trim() ?? '',\n version: metadata.version?.trim() ?? '1.0.0',\n document: draftSnapshot,\n requirements: options.requirements,\n custom: metadata.custom ? deepClone(metadata.custom) : undefined,\n });\n}\n\n/**\n * Options for cloning/instantiating a template into a new page document.\n */\nexport interface CloneTemplateOptions {\n /**\n * Title for the newly created page document. Defaults to template name or document title.\n */\n title?: string;\n /**\n * Author for the newly created page document.\n */\n author?: string;\n /**\n * Optional custom ID generator function for node duplication.\n */\n idGenerator?: (oldId: string, node: Node) => string;\n /**\n * Custom ID prefix for freshly generated node IDs. Defaults to random string / timestamp.\n */\n idPrefix?: string;\n /**\n * Whether to record origin template metadata in metadata.custom.originTemplate (defaults to true).\n */\n recordOrigin?: boolean;\n /**\n * Additional custom metadata for the new document.\n */\n customMetadata?: Record<string, unknown>;\n}\n\n/**\n * Recursively clone a node tree, regenerating 100% fresh unique node IDs for every node\n * including root page node and all descendants, while strictly preserving props and styles.\n */\nfunction cloneTreeWithFreshIds(\n root: Node,\n idGen: (oldId: string, node: Node) => string\n): Node {\n function cloneRec(node: Node): Node {\n const newId = idGen(node.id, node);\n const clonedProps = node.props ? deepClone(node.props) : undefined;\n const clonedStyles = node.styles ? deepClone(node.styles) : undefined;\n const clonedChildren = node.children\n ? node.children.map((child) => cloneRec(child))\n : [];\n\n return {\n id: newId,\n type: node.type,\n ...(clonedProps ? { props: clonedProps } : {}),\n ...(clonedStyles ? { styles: clonedStyles } : {}),\n children: clonedChildren,\n };\n }\n\n return cloneRec(root);\n}\n\n/**\n * Clones a template (or existing document) into a brand new PageDocument.\n * - Generates ALL NEW node IDs across the entire tree (root page node and all children).\n * - Ensures 100% ID difference from the source template.\n * - Sets fresh creation/update timestamps.\n * - Preserves origin template version/id in custom metadata.\n * - Guarantees full memory and reference isolation from the template source.\n */\nexport function cloneTemplateAsPage(\n templateOrDoc: TemplateRecord | PageDocument,\n options: CloneTemplateOptions = {}\n): PageDocument {\n let sourceDoc: PageDocument;\n let templateOrigin: { id: string; name: string; version: string } | null = null;\n\n if (isTemplateRecord(templateOrDoc)) {\n if (!templateOrDoc.document) {\n throw new Error(\n `Template \"${templateOrDoc.name}\" (${templateOrDoc.id}) does not contain an inline document snapshot to clone from.`\n );\n }\n sourceDoc = templateOrDoc.document;\n templateOrigin = {\n id: templateOrDoc.id,\n name: templateOrDoc.name,\n version: templateOrDoc.version ?? '1.0.0',\n };\n } else if ('schema' in templateOrDoc && 'document' in templateOrDoc) {\n sourceDoc = templateOrDoc;\n } else {\n throw new Error('Invalid input: expected a TemplateRecord or PageDocument.');\n }\n\n const existingIdsInSource = new Set(collectNodeIds(sourceDoc.document));\n const assignedNewIds = new Set<string>();\n\n // Determine unique seed prefix for this clone instance\n const prefix = options.idPrefix || `page_${Date.now().toString(36)}_${Math.random().toString(36).substring(2, 6)}`;\n let counter = 1;\n\n const defaultIdGen = (oldId: string, node: Node): string => {\n // Generate an ID that is guaranteed never to match oldId or any existing ID in source\n let candidate = `${node.type}_${prefix}_${counter}`;\n while (existingIdsInSource.has(candidate) || assignedNewIds.has(candidate)) {\n counter++;\n candidate = `${node.type}_${prefix}_${counter}`;\n }\n counter++;\n assignedNewIds.add(candidate);\n return candidate;\n };\n\n const idGen = options.idGenerator || defaultIdGen;\n\n const clonedRootNode = cloneTreeWithFreshIds(sourceDoc.document, idGen);\n\n // Guarantee root node type is 'page'\n const rootPageNode: Node & { type: 'page' } = {\n ...clonedRootNode,\n type: 'page',\n };\n\n const now = new Date().toISOString();\n const pageTitle =\n options.title ??\n (templateOrigin ? `${templateOrigin.name}` : sourceDoc.metadata?.title ?? 'Untitled Page');\n\n const customMetadata: Record<string, unknown> = {\n ...(sourceDoc.metadata?.custom ? deepClone(sourceDoc.metadata.custom) : {}),\n ...(options.customMetadata ? deepClone(options.customMetadata) : {}),\n };\n\n if (options.recordOrigin !== false && templateOrigin) {\n customMetadata.originTemplate = templateOrigin;\n }\n\n const newDoc: PageDocument = {\n schema: sourceDoc.schema,\n version: sourceDoc.version,\n metadata: {\n title: pageTitle,\n description: sourceDoc.metadata?.description ?? '',\n author: options.author ?? sourceDoc.metadata?.author ?? '',\n tags: sourceDoc.metadata?.tags ? [...sourceDoc.metadata.tags] : [],\n category: sourceDoc.metadata?.category ?? 'general',\n version: '1.0.0',\n createdAt: now,\n updatedAt: now,\n custom: customMetadata,\n },\n document: rootPageNode,\n };\n\n return newDoc;\n}\n\n/**\n * Helper to verify that two PageDocuments share ZERO overlapping node IDs.\n */\nexport function areNodeIdsCompletelyDistinct(docA: PageDocument, docB: PageDocument): boolean {\n if (!docA?.document || !docB?.document) return true;\n const idsA = new Set(collectNodeIds(docA.document));\n const idsB = collectNodeIds(docB.document);\n\n for (const id of idsB) {\n if (idsA.has(id)) {\n return false;\n }\n }\n return true;\n}\n","import {\n Artboard,\n Node,\n ProjectDocument,\n ProjectDocumentSchema,\n PROJECT_SCHEMA_NAME,\n ARTBOARD_REFERENCE_NODE_TYPE,\n} from '@kubuild/schema';\nimport {\n DocumentValidationError,\n ValidationOptions,\n validateDocument,\n} from './validator';\n\nexport type ProjectValidationErrorCode =\n | 'PROJECT_SCHEMA_INVALID'\n | 'DUPLICATE_ARTBOARD_ID'\n | 'DUPLICATE_NODE_ID_ACROSS_ARTBOARDS'\n | 'DANGLING_ARTBOARD_REFERENCE'\n | 'DUPLICATE_TRIGGER_ID'\n | 'INVALID_ACTIVE_ARTBOARD'\n | 'ARTBOARD_DOCUMENT_INVALID';\n\nexport interface ProjectValidationError {\n code: ProjectValidationErrorCode;\n message: string;\n path: string;\n artboardId?: string;\n nodeId?: string;\n details?: Record<string, unknown>;\n}\n\nexport interface ProjectValidationResult {\n valid: boolean;\n success: boolean;\n errors: ProjectValidationError[];\n /** Per-artboard results from the existing single-document validator. */\n artboardErrors: Record<string, DocumentValidationError[]>;\n data?: ProjectDocument;\n}\n\nfunction walk(node: Node, visit: (node: Node) => void): void {\n visit(node);\n for (const child of node.children ?? []) {\n walk(child, visit);\n }\n}\n\nfunction collectArtboardReferences(artboard: Artboard): Array<{ nodeId: string; artboardId?: string }> {\n const refs: Array<{ nodeId: string; artboardId?: string }> = [];\n walk(artboard.document.document, (node) => {\n if (node.type === ARTBOARD_REFERENCE_NODE_TYPE) {\n const target = node.props?.artboardId;\n refs.push({\n nodeId: node.id,\n artboardId: typeof target === 'string' ? target : undefined,\n });\n }\n });\n return refs;\n}\n\n/**\n * Validate a multi-artboard project.\n *\n * Each artboard's document is handed to the existing `validateDocument` unchanged; this\n * function only adds the checks that cannot exist at single-document scope:\n * artboard-id uniqueness, node-id uniqueness *across* artboards (so content moved between\n * artboards can't silently collide), duplicate component trigger ids, and reference stubs\n * that point at an artboard which no longer exists.\n */\nexport function validateProject(\n input: unknown,\n options: ValidationOptions = {},\n): ProjectValidationResult {\n const errors: ProjectValidationError[] = [];\n const artboardErrors: Record<string, DocumentValidationError[]> = {};\n\n if (!input || typeof input !== 'object' || Array.isArray(input)) {\n return {\n valid: false,\n success: false,\n errors: [\n {\n code: 'PROJECT_SCHEMA_INVALID',\n message: 'Project must be a valid non-null object',\n path: '',\n },\n ],\n artboardErrors,\n };\n }\n\n const parsed = ProjectDocumentSchema.safeParse(input);\n if (!parsed.success) {\n return {\n valid: false,\n success: false,\n errors: [\n {\n code: 'PROJECT_SCHEMA_INVALID',\n message: `Project failed schema validation. Expected schema \"${PROJECT_SCHEMA_NAME}\".`,\n path: '',\n details: { issues: parsed.error.issues },\n },\n ],\n artboardErrors,\n };\n }\n\n const project = parsed.data;\n\n // 1. Artboard id uniqueness\n const seenArtboardIds = new Set<string>();\n for (const artboard of project.artboards) {\n if (seenArtboardIds.has(artboard.id)) {\n errors.push({\n code: 'DUPLICATE_ARTBOARD_ID',\n message: `Duplicate artboard id \"${artboard.id}\"`,\n path: '/artboards',\n artboardId: artboard.id,\n });\n }\n seenArtboardIds.add(artboard.id);\n }\n\n // 2. Active artboard must resolve\n if (project.activeArtboardId && !seenArtboardIds.has(project.activeArtboardId)) {\n errors.push({\n code: 'INVALID_ACTIVE_ARTBOARD',\n message: `activeArtboardId \"${project.activeArtboardId}\" does not match any artboard`,\n path: '/activeArtboardId',\n });\n }\n\n // 3. Per-artboard document validation, reusing the existing single-document validator\n const nodeIdOwner = new Map<string, string>();\n for (const artboard of project.artboards) {\n const result = validateDocument(artboard.document, options);\n if (!result.valid) {\n artboardErrors[artboard.id] = result.errors;\n errors.push({\n code: 'ARTBOARD_DOCUMENT_INVALID',\n message: `Artboard \"${artboard.id}\" has ${result.errors.length} document validation error(s)`,\n path: `/artboards/${artboard.id}/document`,\n artboardId: artboard.id,\n });\n }\n\n // 4. Node id uniqueness across artboards\n walk(artboard.document.document, (node) => {\n const owner = nodeIdOwner.get(node.id);\n if (owner && owner !== artboard.id) {\n errors.push({\n code: 'DUPLICATE_NODE_ID_ACROSS_ARTBOARDS',\n message: `Node id \"${node.id}\" appears in both artboard \"${owner}\" and \"${artboard.id}\"`,\n path: `/artboards/${artboard.id}/document`,\n artboardId: artboard.id,\n nodeId: node.id,\n });\n } else if (!owner) {\n nodeIdOwner.set(node.id, artboard.id);\n }\n });\n }\n\n // 5. Duplicate trigger ids among component artboards (would make open_modal ambiguous)\n const seenTriggerIds = new Set<string>();\n for (const artboard of project.artboards) {\n if (artboard.artboardType !== 'component' || !artboard.triggerId) continue;\n if (seenTriggerIds.has(artboard.triggerId)) {\n errors.push({\n code: 'DUPLICATE_TRIGGER_ID',\n message: `Duplicate component triggerId \"${artboard.triggerId}\" — open_modal targets would be ambiguous`,\n path: `/artboards/${artboard.id}/triggerId`,\n artboardId: artboard.id,\n });\n }\n seenTriggerIds.add(artboard.triggerId);\n }\n\n // 6. Reference stubs must point at an existing artboard\n for (const artboard of project.artboards) {\n for (const ref of collectArtboardReferences(artboard)) {\n if (!ref.artboardId || !seenArtboardIds.has(ref.artboardId)) {\n errors.push({\n code: 'DANGLING_ARTBOARD_REFERENCE',\n message: `Node \"${ref.nodeId}\" references artboard \"${String(ref.artboardId)}\" which does not exist`,\n path: `/artboards/${artboard.id}/document`,\n artboardId: artboard.id,\n nodeId: ref.nodeId,\n });\n }\n }\n }\n\n const valid = errors.length === 0;\n return {\n valid,\n success: valid,\n errors,\n artboardErrors,\n data: valid ? project : undefined,\n };\n}\n\n/**\n * Collect artboard-reference stubs in a single page document. Used by the exporter guard\n * to refuse silently-incomplete single-page exports.\n */\nexport function collectArtboardReferenceNodes(root: Node): Array<{ nodeId: string; artboardId?: string }> {\n const refs: Array<{ nodeId: string; artboardId?: string }> = [];\n walk(root, (node) => {\n if (node.type === ARTBOARD_REFERENCE_NODE_TYPE) {\n const target = node.props?.artboardId;\n refs.push({ nodeId: node.id, artboardId: typeof target === 'string' ? target : undefined });\n }\n });\n return refs;\n}\n","import type { FormFieldBinding, ValidationRule } from '@kubuild/schema';\n\n/**\n * Checks whether a field value is considered empty.\n * Empty values include undefined, null, empty string, empty array, or boolean false.\n */\nexport function isEmptyValue(value: unknown): boolean {\n if (value === undefined || value === null) {\n return true;\n }\n if (typeof value === 'string') {\n return value.trim().length === 0;\n }\n if (Array.isArray(value)) {\n return value.length === 0;\n }\n if (typeof value === 'boolean') {\n return value === false;\n }\n return false;\n}\n\n/**\n * Standard safe email validation regex.\n */\nconst EMAIL_REGEX = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\n/**\n * Standard safe HTTP/HTTPS URL validation regex.\n */\nconst URL_REGEX = /^(https?:\\/\\/)([\\w.-]+)(:[0-9]+)?(\\/.*)?$/i;\n\n/**\n * Applies a value transformation to a field value prior to validation.\n */\nexport function applyFieldTransform(\n value: unknown,\n transform?: 'trim' | 'lowercase' | 'uppercase' | 'number' | string,\n): unknown {\n if (value === undefined || value === null || !transform) {\n return value;\n }\n\n if (typeof value === 'string') {\n switch (transform) {\n case 'trim':\n return value.trim();\n case 'lowercase':\n return value.toLowerCase();\n case 'uppercase':\n return value.toUpperCase();\n case 'number': {\n const trimmed = value.trim();\n if (trimmed === '') return value;\n const num = Number(trimmed);\n return Number.isNaN(num) ? value : num;\n }\n default:\n return value;\n }\n }\n\n if (typeof value === 'number' && transform === 'number') {\n return value;\n }\n\n return value;\n}\n\n/**\n * Evaluates a single validation rule against a field value.\n * Returns the rule's error message if invalid, or null if valid.\n */\nexport function evaluateRule(\n rule: ValidationRule,\n value: unknown,\n allFormValues?: Record<string, unknown>,\n): string | null {\n const isValueEmpty = isEmptyValue(value);\n\n // For non-required rules, empty values are treated as valid (optional fields)\n if (rule.type !== 'required' && isValueEmpty) {\n return null;\n }\n\n switch (rule.type) {\n case 'required': {\n if (isValueEmpty) {\n return rule.message;\n }\n return null;\n }\n\n case 'email': {\n if (typeof value !== 'string' || !EMAIL_REGEX.test(value.trim())) {\n return rule.message;\n }\n return null;\n }\n\n case 'url': {\n if (typeof value !== 'string' || !URL_REGEX.test(value.trim())) {\n return rule.message;\n }\n return null;\n }\n\n case 'min_length': {\n const min = Number(rule.value);\n if (Number.isFinite(min)) {\n if (typeof value === 'string' && value.length < min) {\n return rule.message;\n }\n if (Array.isArray(value) && value.length < min) {\n return rule.message;\n }\n }\n return null;\n }\n\n case 'max_length': {\n const max = Number(rule.value);\n if (Number.isFinite(max)) {\n if (typeof value === 'string' && value.length > max) {\n return rule.message;\n }\n if (Array.isArray(value) && value.length > max) {\n return rule.message;\n }\n }\n return null;\n }\n\n case 'numeric_min': {\n const min = Number(rule.value);\n const num = Number(value);\n if (Number.isNaN(num) || !Number.isFinite(num) || num < min) {\n return rule.message;\n }\n return null;\n }\n\n case 'numeric_max': {\n const max = Number(rule.value);\n const num = Number(value);\n if (Number.isNaN(num) || !Number.isFinite(num) || num > max) {\n return rule.message;\n }\n return null;\n }\n\n case 'pattern':\n case 'custom_regex': {\n try {\n const patternStr = String(rule.value || '');\n const regex = new RegExp(patternStr);\n if (!regex.test(String(value ?? ''))) {\n return rule.message;\n }\n } catch {\n return rule.message;\n }\n return null;\n }\n\n case 'match_field': {\n const targetFieldName = String(rule.value || '');\n const targetValue = allFormValues?.[targetFieldName];\n if (value !== targetValue) {\n return rule.message;\n }\n return null;\n }\n\n default:\n return null;\n }\n}\n\n/**\n * Validates a single field value against an array of ValidationRules.\n * Returns the first failing error message, or null if all rules pass.\n */\nexport function validateFieldValue(\n value: unknown,\n rules?: ValidationRule[] | null,\n allFormValues?: Record<string, unknown>,\n): string | null {\n if (!rules || !Array.isArray(rules) || rules.length === 0) {\n return null;\n }\n\n for (const rule of rules) {\n const error = evaluateRule(rule, value, allFormValues);\n if (error) {\n return error;\n }\n }\n\n return null;\n}\n\n/**\n * Asynchronously validates a single field value against an array of ValidationRules.\n */\nexport async function validateFieldValueAsync(\n value: unknown,\n rules?: ValidationRule[] | null,\n allFormValues?: Record<string, unknown>,\n): Promise<string | null> {\n return validateFieldValue(value, rules, allFormValues);\n}\n\n/**\n * Validates an entire form values object against field configs.\n * Returns a map of field names to error messages (Record<string, string>).\n * If all fields are valid, returns an empty object {}.\n */\nexport function validateForm(\n values: Record<string, unknown>,\n fieldConfigs:\n | FormFieldBinding[]\n | Record<string, FormFieldBinding | ValidationRule[]>,\n): Record<string, string> {\n const errors: Record<string, string> = {};\n\n if (!fieldConfigs) {\n return errors;\n }\n\n if (Array.isArray(fieldConfigs)) {\n for (const field of fieldConfigs) {\n if (!field?.name) continue;\n\n let value = values?.[field.name];\n if (field.transform) {\n value = applyFieldTransform(value, field.transform);\n }\n\n const rules: ValidationRule[] = [...(field.rules || [])];\n\n // Handle shorthand `required: true` if not already present in rules\n if (field.required && !rules.some((r) => r.type === 'required')) {\n rules.unshift({\n type: 'required',\n message: `${field.label || field.name} is required`,\n });\n }\n\n const error = validateFieldValue(value, rules, values);\n if (error) {\n errors[field.name] = error;\n }\n }\n } else if (typeof fieldConfigs === 'object') {\n for (const [fieldName, config] of Object.entries(fieldConfigs)) {\n let value = values?.[fieldName];\n let rules: ValidationRule[] = [];\n\n if (Array.isArray(config)) {\n rules = config;\n } else if (config && typeof config === 'object') {\n if (config.transform) {\n value = applyFieldTransform(value, config.transform);\n }\n rules = [...(config.rules || [])];\n if (config.required && !rules.some((r) => r.type === 'required')) {\n rules.unshift({\n type: 'required',\n message: `${config.label || fieldName} is required`,\n });\n }\n }\n\n const error = validateFieldValue(value, rules, values);\n if (error) {\n errors[fieldName] = error;\n }\n }\n }\n\n return errors;\n}\n\n/**\n * Asynchronously validates an entire form values object against field configs.\n */\nexport async function validateFormAsync(\n values: Record<string, unknown>,\n fieldConfigs:\n | FormFieldBinding[]\n | Record<string, FormFieldBinding | ValidationRule[]>,\n): Promise<Record<string, string>> {\n return validateForm(values, fieldConfigs);\n}\n\n/**\n * Convenience helper to determine if a form error map is completely valid (no errors).\n */\nexport function isFormValid(errors: Record<string, string>): boolean {\n return Object.keys(errors).length === 0;\n}\n\n"],"mappings":"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","names":["walk","SCHEMA_NAME","CURRENT_SCHEMA_VERSION","SCHEMA_NAME","CURRENT_SCHEMA_VERSION","FORBIDDEN_KEY_SEGMENTS","FORBIDDEN_KEY_SEGMENTS","skippedResult","FORBIDDEN_KEY_SEGMENTS","SCHEMA_NAME","CURRENT_SCHEMA_VERSION","SCHEMA_NAME","traverse","SCHEMA_NAME","SCHEMA_NAME","CURRENT_SCHEMA_VERSION","CURRENT_SCHEMA_VERSION","CURRENT_SCHEMA_VERSION","SCHEMA_NAME","SCHEMA_NAME","CURRENT_SCHEMA_VERSION","CURRENT_SCHEMA_VERSION","PROJECT_SCHEMA_NAME","CURRENT_PROJECT_SCHEMA_VERSION","PROJECT_SCHEMA_NAME","CURRENT_PROJECT_SCHEMA_VERSION","collectNodeIds","now","collectNodeIds","ProjectDocumentSchema","PROJECT_SCHEMA_NAME","ARTBOARD_REFERENCE_NODE_TYPE","ARTBOARD_REFERENCE_NODE_TYPE","ProjectDocumentSchema","PROJECT_SCHEMA_NAME","isValueEmpty"]}
1
+ {"version":3,"sources":["../src/document/document-utils.ts","../src/document/command-tree-utils.ts","../src/document/commands.ts","../src/document/artboards.ts","../src/document/history.ts","../src/runtime/binding-resolver.ts","../src/runtime/variable-catalog.ts","../src/runtime/interpolator.ts","../src/runtime/conditional-resolver.ts","../src/runtime/pipeline-executor.ts","../src/runtime/state-store.ts","../src/runtime/server-tracking.ts","../src/runtime/tracking-relay.ts","../src/io/exporter.ts","../src/validation/validator.ts","../src/validation/security.ts","../src/io/tracking-sanitizer.ts","../src/io/importer.ts","../src/io/migration.ts","../src/io/load-project.ts","../src/io/round-trip-comparator.ts","../src/io/template-utils.ts","../src/validation/project-validator.ts","../src/validation/validation-engine.ts"],"sourcesContent":["import { PageDocument, Node, SCHEMA_NAME, CURRENT_SCHEMA_VERSION } from '@kubuild/schema';\nimport type { ComponentRegistryLike } from '../validation/validator';\n\n\nexport function createBlankDocument(title = 'Untitled Page'): PageDocument {\n return {\n schema: SCHEMA_NAME,\n version: CURRENT_SCHEMA_VERSION,\n metadata: {\n title,\n description: '',\n author: '',\n tags: [],\n category: 'general',\n version: '1.0.0',\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n },\n document: {\n id: 'root-page',\n type: 'page',\n props: { title },\n styles: { base: { minHeight: '100vh', backgroundColor: '#ffffff' } },\n children: [] as Node[],\n },\n };\n}\n\nexport function findNodeById(rootNode: Node, targetId: string): Node | null {\n if (rootNode.id === targetId) return rootNode;\n if (!rootNode.children) return null;\n for (const child of rootNode.children) {\n const found = findNodeById(child, targetId);\n if (found) return found;\n }\n return null;\n}\n\nexport interface CollectedAssetReference {\n assetId: string;\n reference: {\n type: 'asset';\n assetId: string;\n filename?: string;\n mimeType?: string;\n fallbackUrl?: string;\n };\n nodeId: string;\n propPath: string;\n}\n\n/**\n * Collect all AssetReference objects throughout a document tree.\n */\nexport function collectAssetReferences(rootNode: Node): CollectedAssetReference[] {\n const results: CollectedAssetReference[] = [];\n\n function traverseProps(propsObj: unknown, currentPath: string, nodeId: string): void {\n if (!propsObj || typeof propsObj !== 'object') return;\n\n if (Array.isArray(propsObj)) {\n propsObj.forEach((item, index) => {\n traverseProps(item, `${currentPath}/${index}`, nodeId);\n });\n return;\n }\n\n const record = propsObj as Record<string, unknown>;\n\n if (record.type === 'asset' && typeof record.assetId === 'string' && record.assetId.trim().length > 0) {\n results.push({\n assetId: record.assetId,\n reference: {\n type: 'asset',\n assetId: record.assetId,\n filename: typeof record.filename === 'string' ? record.filename : undefined,\n mimeType: typeof record.mimeType === 'string' ? record.mimeType : undefined,\n fallbackUrl: typeof record.fallbackUrl === 'string' ? record.fallbackUrl : undefined,\n },\n nodeId,\n propPath: currentPath,\n });\n }\n\n for (const [key, val] of Object.entries(record)) {\n if (val && typeof val === 'object') {\n traverseProps(val, `${currentPath}/${key}`, nodeId);\n }\n }\n }\n\n function traverseNode(node: Node): void {\n if (node.props) {\n traverseProps(node.props, `/document/${node.id}/props`, node.id);\n }\n if (node.children && Array.isArray(node.children)) {\n for (const child of node.children) {\n traverseNode(child);\n }\n }\n }\n\n traverseNode(rootNode);\n return results;\n}\n\nexport interface TreeRequirements {\n requiredComponents: string[];\n requiredCapabilities: string[];\n}\n\n/**\n * Extracts custom component types and capabilities required by a node tree.\n */\nexport function extractRequirementsFromTree(\n rootNode: Node,\n registry?: ComponentRegistryLike,\n): TreeRequirements {\n const requiredComponents = new Set<string>();\n const requiredCapabilities = new Set<string>();\n\n function traverse(node: Node): void {\n if (registry) {\n const def = registry.get(node.type);\n if (def?.category === 'custom') {\n requiredComponents.add(node.type);\n }\n if (def?.capabilities && Array.isArray(def.capabilities)) {\n for (const cap of def.capabilities) {\n requiredCapabilities.add(cap);\n }\n }\n }\n\n if (node.children && Array.isArray(node.children)) {\n for (const child of node.children) {\n traverse(child);\n }\n }\n }\n\n traverse(rootNode);\n\n return {\n requiredComponents: Array.from(requiredComponents).sort(),\n requiredCapabilities: Array.from(requiredCapabilities).sort(),\n };\n}\n\n/**\n * Remap asset references in a node tree based on an ID mapping dictionary.\n * Mutates the node props in place and returns the number of references updated.\n */\nexport function remapAssetReferences(\n rootNode: Node,\n idMap: Record<string, string> | Map<string, string>,\n): number {\n let remappedCount = 0;\n const getMappedId = (id: string): string | undefined => {\n if (idMap instanceof Map) return idMap.get(id);\n return idMap[id];\n };\n\n function traverseProps(propsObj: unknown): void {\n if (!propsObj || typeof propsObj !== 'object') return;\n\n if (Array.isArray(propsObj)) {\n for (const item of propsObj) {\n traverseProps(item);\n }\n return;\n }\n\n const record = propsObj as Record<string, unknown>;\n\n if (record.type === 'asset' && typeof record.assetId === 'string') {\n const newId = getMappedId(record.assetId);\n if (newId !== undefined && newId !== record.assetId) {\n record.assetId = newId;\n remappedCount++;\n }\n }\n\n for (const val of Object.values(record)) {\n if (val && typeof val === 'object') {\n traverseProps(val);\n }\n }\n }\n\n function traverseNode(node: Node): void {\n if (node.props) {\n traverseProps(node.props);\n }\n if (node.children && Array.isArray(node.children)) {\n for (const child of node.children) {\n traverseNode(child);\n }\n }\n }\n\n traverseNode(rootNode);\n return remappedCount;\n}\n\n/**\n * Remaps all asset references throughout a PageDocument.\n */\nexport function remapDocumentAssetReferences(\n doc: PageDocument,\n idMap: Record<string, string> | Map<string, string>,\n): PageDocument {\n if (doc && doc.document) {\n remapAssetReferences(doc.document, idMap);\n }\n return doc;\n}\n\nexport interface MissingComponentNodeInfo {\n nodeId: string;\n componentType: string;\n props: Record<string, unknown>;\n node: Node;\n}\n\n/**\n * Finds all nodes in a node tree that reference component types not registered in the host.\n * This is useful in placeholder mode to inspect missing nodes and their preserved props.\n */\nexport function findMissingComponentNodes(\n rootNode: Node,\n registry?: ComponentRegistryLike,\n knownTypes?: string[] | Set<string>,\n): MissingComponentNodeInfo[] {\n const missing: MissingComponentNodeInfo[] = [];\n const knownSet = new Set<string>();\n\n if (knownTypes) {\n for (const t of knownTypes) knownSet.add(t);\n }\n\n const standardBuiltIns = [\n 'page',\n 'section',\n 'container',\n 'columns',\n 'heading',\n 'text',\n 'image',\n 'button',\n 'collection',\n ];\n for (const b of standardBuiltIns) knownSet.add(b);\n\n function checkNode(node: Node): void {\n let isSupported = knownSet.has(node.type);\n if (!isSupported && registry) {\n isSupported = registry.has(node.type);\n }\n\n if (!isSupported) {\n missing.push({\n nodeId: node.id,\n componentType: node.type,\n props: node.props ? { ...node.props } : {},\n node,\n });\n }\n\n if (node.children && Array.isArray(node.children)) {\n for (const child of node.children) {\n checkNode(child);\n }\n }\n }\n\n checkNode(rootNode);\n return missing;\n}\n\n\n","import { Node, collectNodeIds, type ActionStep } from '@kubuild/schema';\n\n/**\n * Deep clone an object immutably (JSON-safe).\n */\nexport function deepClone<T>(val: T): T {\n return JSON.parse(JSON.stringify(val));\n}\n\nexport interface NodeLocation {\n node: Node;\n parent: Node | null;\n index: number;\n}\n\n/**\n * Find a node, its parent, and index within the parent's children array.\n */\nexport function findNodeLocation(root: Node, targetId: string): NodeLocation | null {\n if (root.id === targetId) {\n return {\n node: root,\n parent: null,\n index: -1,\n };\n }\n\n return searchNodeLocationRecursive(root, targetId);\n}\n\nfunction searchNodeLocationRecursive(currentParent: Node, targetId: string): NodeLocation | null {\n if (!currentParent.children || currentParent.children.length === 0) {\n return null;\n }\n\n for (let i = 0; i < currentParent.children.length; i++) {\n const child = currentParent.children[i];\n if (child.id === targetId) {\n return {\n node: child,\n parent: currentParent,\n index: i,\n };\n }\n\n const foundInSubtree = searchNodeLocationRecursive(child, targetId);\n if (foundInSubtree) {\n return foundInSubtree;\n }\n }\n\n return null;\n}\n\nexport type NavigationDirection = 'parent' | 'child' | 'previous-sibling' | 'next-sibling';\n\n/**\n * Resolve the node id reached by moving from `nodeId` in a tree-navigation direction.\n * Returns null when there is nowhere to go (e.g. root has no parent, a leaf has no child,\n * or the node sits at the start/end of its sibling list).\n */\nexport function getNavigationTarget(\n root: Node,\n nodeId: string,\n direction: NavigationDirection,\n): string | null {\n const location = findNodeLocation(root, nodeId);\n if (!location) return null;\n\n switch (direction) {\n case 'parent':\n return location.parent?.id ?? null;\n case 'child':\n return location.node.children?.[0]?.id ?? null;\n case 'previous-sibling': {\n if (!location.parent) return null;\n return (location.parent.children ?? [])[location.index - 1]?.id ?? null;\n }\n case 'next-sibling': {\n if (!location.parent) return null;\n return (location.parent.children ?? [])[location.index + 1]?.id ?? null;\n }\n }\n}\n\n/**\n * Returns the chain of ancestor node ids from the root down to (but excluding)\n * `targetId`, root first. Returns [] if targetId is the root or is not found.\n */\nexport function getAncestorChain(root: Node, targetId: string): string[] {\n if (root.id === targetId) return [];\n\n function walk(node: Node, acc: string[]): string[] | null {\n if (!node.children) return null;\n for (const child of node.children) {\n if (child.id === targetId) return acc;\n const found = walk(child, [...acc, child.id]);\n if (found) return found;\n }\n return null;\n }\n\n return walk(root, [root.id]) ?? [];\n}\n\n/**\n * STORA-232: Find the direct parent node of `targetId` in a single O(N) traversal.\n * Returns null when the target is the root or is not found in the tree.\n */\nexport function getParentNodeId(root: Node, targetId: string): string | null {\n if (root.id === targetId) return null;\n\n const stack: Node[] = [root];\n while (stack.length > 0) {\n const current = stack.pop()!;\n const children = current.children;\n if (!children) continue;\n for (const child of children) {\n if (child.id === targetId) return current.id;\n stack.push(child);\n }\n }\n return null;\n}\n\n/**\n * STORA-232: Return the full ancestor path of `targetId` as an array of nodes,\n * ordered from the root down to (and including) the target node itself.\n * Single O(N) traversal: the path is tracked during descent, so no re-walks.\n * Returns [] when the target is not found.\n */\nexport function getNodeAncestors(root: Node, targetId: string): Node[] {\n const path: Node[] = [];\n\n function walk(node: Node): boolean {\n path.push(node);\n if (node.id === targetId) return true;\n if (node.children) {\n for (const child of node.children) {\n if (walk(child)) return true;\n }\n }\n path.pop();\n return false;\n }\n\n return walk(root) ? path : [];\n}\n\n/**\n * Check whether `targetId` is a descendant of `ancestorNode` (or equal to ancestorNode.id).\n */\nexport function isDescendantOf(ancestorNode: Node, targetId: string): boolean {\n if (ancestorNode.id === targetId) {\n return true;\n }\n\n if (!ancestorNode.children || ancestorNode.children.length === 0) {\n return false;\n }\n\n for (const child of ancestorNode.children) {\n if (isDescendantOf(child, targetId)) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Collect all node IDs present in a node subtree as a Set.\n */\nexport function collectNodeIdSet(root: Node): Set<string> {\n return new Set(collectNodeIds(root));\n}\n\n/**\n * Default unique ID generator function for node duplication.\n */\nexport function defaultIdGenerator(oldId: string, existingIds?: Set<string>): string {\n // Strip existing suffix like _copy or _copy_1 if exists\n const baseName = oldId.replace(/_copy(_\\d+)?$/, '');\n let candidate = `${baseName}_copy`;\n let counter = 1;\n\n if (existingIds) {\n while (existingIds.has(candidate)) {\n candidate = `${baseName}_copy_${counter}`;\n counter++;\n }\n existingIds.add(candidate);\n }\n\n return candidate;\n}\n\nexport interface ClonedSubtreeResult {\n clonedNode: Node;\n idMap: Map<string, string>; // oldId -> newId\n}\n\n/**\n * Keys (in step payloads, legacy `props.action.payload`, and node props) whose string value\n * is a reference to another node's id. When a subtree is cloned with fresh ids, references\n * that point at a node *inside* that subtree are rewritten to the clone's new id; references\n * to nodes outside the subtree are left untouched.\n */\nexport const NODE_ID_REFERENCE_KEYS: ReadonlySet<string> = new Set([\n 'modalId',\n 'modalNodeId',\n 'targetModalId',\n 'targetNodeId',\n 'nodeId',\n 'formId',\n 'targetId',\n]);\n\n/**\n * Keys whose string value may be an in-page anchor (`#<nodeId>`) — a node's DOM id is its\n * node id, so anchors to nodes inside a cloned subtree must follow the new id as well.\n */\nconst ANCHOR_REFERENCE_KEYS: ReadonlySet<string> = new Set(['url', 'href']);\n\nfunction remapReferenceValue(key: string, value: unknown, idMap: ReadonlyMap<string, string>): unknown {\n if (typeof value !== 'string') return value;\n if (NODE_ID_REFERENCE_KEYS.has(key)) {\n return idMap.get(value) ?? idMap.get(value.trim()) ?? value;\n }\n if (ANCHOR_REFERENCE_KEYS.has(key) && value.startsWith('#')) {\n const mapped = idMap.get(value.slice(1));\n return mapped ? `#${mapped}` : value;\n }\n return value;\n}\n\n/** Remaps node-id references in a flat key/value record (props, step payloads). Mutates in place. */\nfunction remapReferenceRecord(record: Record<string, unknown>, idMap: ReadonlyMap<string, string>): void {\n for (const [key, value] of Object.entries(record)) {\n record[key] = remapReferenceValue(key, value, idMap);\n }\n}\n\nfunction remapStepReferences(steps: ActionStep[] | undefined, idMap: ReadonlyMap<string, string>): void {\n if (!Array.isArray(steps)) return;\n for (const step of steps) {\n if (step.payload && typeof step.payload === 'object') {\n remapReferenceRecord(step.payload, idMap);\n }\n remapStepReferences(step.onSuccess, idMap);\n remapStepReferences(step.onError, idMap);\n }\n}\n\n/**\n * Rewrites node-id references inside a single (already cloned) node so they follow `idMap`.\n * Covers action pipeline step payloads (incl. onSuccess/onError branches), `formConfig.formId`,\n * id-reference props (e.g. `modalId`, `formId`), `#anchor` hrefs, and the legacy `props.action`\n * payload. Mutates the node in place; callers must pass a clone they own.\n */\nexport function remapNodeReferences(node: Node, idMap: ReadonlyMap<string, string>): void {\n if (node.props && typeof node.props === 'object') {\n remapReferenceRecord(node.props, idMap);\n const legacyAction = node.props.action as { payload?: unknown } | undefined;\n if (\n legacyAction &&\n typeof legacyAction === 'object' &&\n legacyAction.payload &&\n typeof legacyAction.payload === 'object' &&\n !Array.isArray(legacyAction.payload)\n ) {\n remapReferenceRecord(legacyAction.payload as Record<string, unknown>, idMap);\n }\n }\n if (node.formConfig && typeof node.formConfig.formId === 'string') {\n node.formConfig.formId = idMap.get(node.formConfig.formId) ?? node.formConfig.formId;\n }\n if (Array.isArray(node.actions)) {\n for (const pipeline of node.actions) {\n remapStepReferences(pipeline.steps, idMap);\n }\n }\n}\n\n/**\n * Deep-clones a node subtree assigning every node a fresh id via `idGen`, preserving every\n * other `Node` field (props, styles, animation, actions, formConfig, and any future field),\n * then rewrites intra-subtree node-id references (see {@link remapNodeReferences}).\n */\nexport function cloneNodeTreeWithFreshIds(\n root: Node,\n idGen: (oldId: string, node: Node) => string,\n): ClonedSubtreeResult {\n const idMap = new Map<string, string>();\n const clonedNodes: Node[] = [];\n\n function cloneRecursive(node: Node): Node {\n const newId = idGen(node.id, node);\n idMap.set(node.id, newId);\n\n const { children, ...rest } = node;\n const cloned: Node = {\n ...deepClone(rest),\n id: newId,\n children: children ? children.map((child) => cloneRecursive(child)) : [],\n };\n clonedNodes.push(cloned);\n return cloned;\n }\n\n const clonedNode = cloneRecursive(root);\n for (const cloned of clonedNodes) {\n remapNodeReferences(cloned, idMap);\n }\n return { clonedNode, idMap };\n}\n\n/**\n * Recursively clone a node and its entire subtree, generating fresh unique IDs\n * for every node while preserving every other node field (props, styles, animation,\n * actions, formConfig) and remapping intra-subtree node-id references.\n */\nexport function cloneTreeWithNewIds(\n root: Node,\n idGenerator?: (oldId: string) => string,\n existingIds?: Set<string>,\n): ClonedSubtreeResult {\n const idGen = idGenerator || ((oldId: string) => defaultIdGenerator(oldId, existingIds));\n return cloneNodeTreeWithFreshIds(root, (oldId) => idGen(oldId));\n}\n","import {\n PageDocument,\n Node,\n ResponsiveStyles,\n StyleDefinition,\n StyleDefinitionSchema,\n ResponsiveStylesSchema,\n AnimationConfig,\n AnimationConfigSchema,\n ActionPipeline,\n ActionPipelineSchema,\n FormConfig,\n FormConfigSchema,\n Theme,\n ThemeSchema,\n THEME_TOKEN_GROUPS,\n} from '@kubuild/schema';\nimport {\n deepClone,\n findNodeLocation,\n isDescendantOf,\n collectNodeIdSet,\n cloneTreeWithNewIds,\n} from './command-tree-utils';\n\nexport type DocumentChangeType =\n | 'NODE_INSERTED'\n | 'NODE_MOVED'\n | 'PROPS_UPDATED'\n | 'STYLE_UPDATED'\n | 'ANIMATION_UPDATED'\n | 'ACTIONS_UPDATED'\n | 'FORM_CONFIG_UPDATED'\n | 'NODE_REMOVED'\n | 'NODE_DUPLICATED'\n | 'NODE_WRAPPED'\n | 'NODE_UNGROUPED'\n | 'NODE_REPLACED'\n | 'THEME_UPDATED';\n\nexport interface DocumentChangeEvent {\n type: DocumentChangeType;\n timestamp: string;\n nodeId: string;\n parentId?: string;\n previousParentId?: string;\n index?: number;\n previousIndex?: number;\n payload?: Record<string, unknown>;\n}\n\nexport interface CommandResult {\n document: PageDocument;\n event: DocumentChangeEvent;\n}\n\nexport interface InsertNodeParams {\n parentId: string;\n node: Node;\n index?: number;\n}\n\nexport interface MoveNodeParams {\n nodeId: string;\n targetParentId: string;\n index?: number;\n}\n\nexport interface UpdatePropsParams {\n nodeId: string;\n props: Record<string, unknown>;\n /**\n * If true (default), shallow merges new props with existing props.\n * If false, replaces the entire props object.\n */\n merge?: boolean;\n}\n\nexport interface UpdateStyleParams {\n nodeId: string;\n styles: ResponsiveStyles | StyleDefinition;\n /**\n * Target breakpoint to update directly, or if omitted, applies to whole ResponsiveStyles structure.\n */\n breakpoint?: 'base' | 'desktop' | 'tablet' | 'mobile';\n /**\n * Target pseudo-state layer (e.g. ':hover', ':active', ':focus') — STORA-221.\n * When set, `styles` is written to `node.styles.states[state]` instead of a\n * breakpoint layer, leaving default (breakpoint) values untouched.\n */\n state?: string;\n /**\n * If true (default), shallow merges style definitions at target breakpoint.\n * If false, replaces the style definition object.\n */\n merge?: boolean;\n}\n\nexport interface RemoveNodeParams {\n nodeId: string;\n}\n\nexport interface DuplicateNodeParams {\n nodeId: string;\n targetParentId?: string;\n index?: number;\n idGenerator?: (oldId: string) => string;\n}\n\nexport interface WrapNodeIntoFrameParams {\n /** Single node ID to wrap into a frame. */\n nodeId?: string;\n /** Multiple node IDs to wrap into a frame. */\n nodeIds?: string[] | string;\n /** Optional custom ID for the created flex frame container. */\n frameId?: string;\n /** Optional custom props for the flex frame container. */\n frameProps?: Record<string, unknown>;\n /** Optional custom responsive styles for the flex frame container. */\n frameStyles?: ResponsiveStyles;\n}\n\nexport interface UngroupNodeFrameParams {\n /** Node ID of the flex container to unwrap. */\n nodeId: string;\n}\n\nexport interface ReplaceNodeParams {\n /** ID of the existing node to replace. */\n nodeId: string;\n /** Full replacement node — its `id` must match `nodeId` (identity is never silently changed). */\n node: Node;\n}\n\n/**\n * 1. Insert a node into a target parent node.\n * Returns a new PageDocument and a NODE_INSERTED event.\n */\nexport function insertNode(\n document: PageDocument,\n params: InsertNodeParams,\n): CommandResult {\n const { parentId, node, index } = params;\n\n if (!node || typeof node !== 'object' || !node.id || !node.type) {\n throw new Error('Invalid node: Node must be an object with non-empty \"id\" and \"type\"');\n }\n\n const newDoc = deepClone(document);\n const existingIds = collectNodeIdSet(newDoc.document);\n\n // Check duplicate ID\n const incomingIds = collectNodeIdSet(node);\n for (const incId of incomingIds) {\n if (existingIds.has(incId)) {\n throw new Error(`Cannot insert node: Duplicate node ID \"${incId}\" already exists in document.`);\n }\n }\n\n const parentLoc = findNodeLocation(newDoc.document, parentId);\n if (!parentLoc) {\n throw new Error(`Cannot insert node: Target parent node with ID \"${parentId}\" not found.`);\n }\n\n const parentNode = parentLoc.node;\n if (!parentNode.children) {\n parentNode.children = [];\n }\n\n const insertIndex =\n typeof index === 'number' && index >= 0 && index <= parentNode.children.length\n ? index\n : parentNode.children.length;\n\n parentNode.children.splice(insertIndex, 0, deepClone(node));\n\n return {\n document: newDoc,\n event: {\n type: 'NODE_INSERTED',\n timestamp: new Date().toISOString(),\n nodeId: node.id,\n parentId,\n index: insertIndex,\n payload: {\n nodeType: node.type,\n },\n },\n };\n}\n\n/**\n * 2. Move a node from its current location to a new parent location.\n * Prevents moving the root node or moving a node into its own descendant tree.\n * Returns a new PageDocument and a NODE_MOVED event.\n */\nexport function moveNode(\n document: PageDocument,\n params: MoveNodeParams,\n): CommandResult {\n const { nodeId, targetParentId, index } = params;\n\n if (nodeId === document.document.id) {\n throw new Error('Cannot move the root page node.');\n }\n\n const newDoc = deepClone(document);\n\n const sourceLoc = findNodeLocation(newDoc.document, nodeId);\n if (!sourceLoc || !sourceLoc.parent) {\n throw new Error(`Cannot move node: Node with ID \"${nodeId}\" not found in document.`);\n }\n\n const targetLoc = findNodeLocation(newDoc.document, targetParentId);\n if (!targetLoc) {\n throw new Error(`Cannot move node: Target parent with ID \"${targetParentId}\" not found in document.`);\n }\n\n // Descendant cycle check: Cannot move node into itself or any of its descendants\n if (isDescendantOf(sourceLoc.node, targetParentId)) {\n throw new Error(\n `Cannot move node: Target parent \"${targetParentId}\" is the node itself or a descendant of node \"${nodeId}\".`,\n );\n }\n\n const previousParentId = sourceLoc.parent.id;\n const previousIndex = sourceLoc.index;\n\n // Remove node from source parent\n const [removedNode] = sourceLoc.parent.children!.splice(previousIndex, 1);\n\n // Target parent might be the same parent or different parent\n const targetParent = targetLoc.node;\n if (!targetParent.children) {\n targetParent.children = [];\n }\n\n let targetIndex =\n typeof index === 'number' && index >= 0 && index <= targetParent.children.length\n ? index\n : targetParent.children.length;\n\n targetParent.children.splice(targetIndex, 0, removedNode);\n\n return {\n document: newDoc,\n event: {\n type: 'NODE_MOVED',\n timestamp: new Date().toISOString(),\n nodeId,\n parentId: targetParentId,\n previousParentId,\n index: targetIndex,\n previousIndex,\n },\n };\n}\n\n/**\n * 3. Update the props of an existing node.\n * Returns a new PageDocument and a PROPS_UPDATED event.\n */\nexport function updateProps(\n document: PageDocument,\n params: UpdatePropsParams,\n): CommandResult {\n const { nodeId, props, merge = true } = params;\n\n if (!props || typeof props !== 'object' || Array.isArray(props)) {\n throw new Error('Props must be an object.');\n }\n\n const newDoc = deepClone(document);\n const loc = findNodeLocation(newDoc.document, nodeId);\n if (!loc) {\n throw new Error(`Cannot update props: Node with ID \"${nodeId}\" not found in document.`);\n }\n\n const targetNode = loc.node;\n const previousProps = targetNode.props ? deepClone(targetNode.props) : {};\n\n if (merge) {\n targetNode.props = {\n ...previousProps,\n ...deepClone(props),\n };\n for (const key of Object.keys(props)) {\n if (props[key] === undefined) {\n delete targetNode.props[key];\n }\n }\n } else {\n targetNode.props = deepClone(props);\n }\n\n return {\n document: newDoc,\n event: {\n type: 'PROPS_UPDATED',\n timestamp: new Date().toISOString(),\n nodeId,\n parentId: loc.parent ? loc.parent.id : undefined,\n payload: {\n props: targetNode.props,\n previousProps,\n },\n },\n };\n}\n\n/**\n * 4. Update the responsive styles of an existing node.\n * Supports updating a specific breakpoint ('base', 'desktop', etc.) or the whole ResponsiveStyles object.\n * Returns a new PageDocument and a STYLE_UPDATED event.\n */\nexport function updateStyle(\n document: PageDocument,\n params: UpdateStyleParams,\n): CommandResult {\n const { nodeId, styles, breakpoint, state, merge = true } = params;\n\n if (!styles || typeof styles !== 'object' || Array.isArray(styles)) {\n throw new Error('Styles must be an object.');\n }\n\n const newDoc = deepClone(document);\n const loc = findNodeLocation(newDoc.document, nodeId);\n if (!loc) {\n throw new Error(`Cannot update style: Node with ID \"${nodeId}\" not found in document.`);\n }\n\n const targetNode = loc.node;\n const currentStyles: ResponsiveStyles = targetNode.styles ? deepClone(targetNode.styles) : {};\n const previousStyles = deepClone(currentStyles);\n\n if (state) {\n // Pseudo-state layer update (STORA-221): writes into styles.states[state]\n // without touching default breakpoint values. Parsed through\n // StyleDefinitionSchema so unsafe values are rejected here too.\n const newBreakpointStyles = StyleDefinitionSchema.parse(styles);\n const states = { ...(currentStyles.states ?? {}) };\n const currentStateStyles = states[state] ?? {};\n\n if (merge) {\n states[state] = { ...currentStateStyles, ...deepClone(newBreakpointStyles) };\n } else {\n states[state] = deepClone(newBreakpointStyles);\n }\n\n targetNode.styles = { ...currentStyles, states } as ResponsiveStyles;\n\n return {\n document: newDoc,\n event: {\n type: 'STYLE_UPDATED',\n timestamp: new Date().toISOString(),\n nodeId,\n parentId: loc.parent ? loc.parent.id : undefined,\n payload: {\n styles: targetNode.styles,\n previousStyles,\n state,\n },\n },\n };\n }\n\n if (breakpoint) {\n // Updating a single breakpoint style definition. Parsed through\n // StyleDefinitionSchema so unsafe/non-serializable values (STORA-023)\n // are rejected here too, not just at document-parse time.\n const currentBreakpointStyles = (currentStyles[breakpoint] as StyleDefinition) || {};\n const newBreakpointStyles = StyleDefinitionSchema.parse(styles);\n\n if (merge) {\n currentStyles[breakpoint] = {\n ...currentBreakpointStyles,\n ...deepClone(newBreakpointStyles),\n };\n } else {\n currentStyles[breakpoint] = deepClone(newBreakpointStyles);\n }\n } else {\n // Updating responsive styles container\n const responsiveStylesInput = ResponsiveStylesSchema.parse(styles);\n if (merge) {\n for (const bp of ['base', 'desktop', 'tablet', 'mobile'] as const) {\n if (responsiveStylesInput[bp] !== undefined) {\n const currentBp = (currentStyles[bp] as StyleDefinition) || {};\n const incomingBp = (responsiveStylesInput[bp] as StyleDefinition) || {};\n currentStyles[bp] = {\n ...currentBp,\n ...deepClone(incomingBp),\n };\n }\n }\n } else {\n targetNode.styles = deepClone(responsiveStylesInput);\n return {\n document: newDoc,\n event: {\n type: 'STYLE_UPDATED',\n timestamp: new Date().toISOString(),\n nodeId,\n parentId: loc.parent ? loc.parent.id : undefined,\n payload: {\n styles: targetNode.styles,\n previousStyles,\n },\n },\n };\n }\n }\n\n targetNode.styles = currentStyles;\n\n return {\n document: newDoc,\n event: {\n type: 'STYLE_UPDATED',\n timestamp: new Date().toISOString(),\n nodeId,\n parentId: loc.parent ? loc.parent.id : undefined,\n payload: {\n styles: currentStyles,\n previousStyles,\n breakpoint,\n },\n },\n };\n}\n\n/**\n * 5. Remove a node from the document tree.\n * Prevents removing the root page node.\n * Returns a new PageDocument and a NODE_REMOVED event.\n */\nexport function removeNode(\n document: PageDocument,\n params: RemoveNodeParams,\n): CommandResult {\n const { nodeId } = params;\n\n if (nodeId === document.document.id) {\n throw new Error('Cannot remove the root page node.');\n }\n\n const newDoc = deepClone(document);\n const loc = findNodeLocation(newDoc.document, nodeId);\n if (!loc || !loc.parent) {\n throw new Error(`Cannot remove node: Node with ID \"${nodeId}\" not found in document.`);\n }\n\n const parentId = loc.parent.id;\n const index = loc.index;\n\n const [removedNode] = loc.parent.children!.splice(index, 1);\n\n return {\n document: newDoc,\n event: {\n type: 'NODE_REMOVED',\n timestamp: new Date().toISOString(),\n nodeId,\n parentId,\n index,\n payload: {\n node: removedNode,\n },\n },\n };\n}\n\n/**\n * 6. Duplicate a node and its entire subtree.\n * Generates fresh unique IDs for all cloned nodes in the subtree, preserves props/styles,\n * and inserts the duplicate right after the original node (or at specified targetParentId/index).\n * Returns a new PageDocument and a NODE_DUPLICATED event.\n */\nexport function duplicateNode(\n document: PageDocument,\n params: DuplicateNodeParams,\n): CommandResult {\n const { nodeId, targetParentId, index, idGenerator } = params;\n\n if (nodeId === document.document.id) {\n throw new Error('Cannot duplicate the root page node.');\n }\n\n const newDoc = deepClone(document);\n const loc = findNodeLocation(newDoc.document, nodeId);\n if (!loc || !loc.parent) {\n throw new Error(`Cannot duplicate node: Node with ID \"${nodeId}\" not found in document.`);\n }\n\n const existingIds = collectNodeIdSet(newDoc.document);\n const { clonedNode, idMap } = cloneTreeWithNewIds(loc.node, idGenerator, existingIds);\n\n const destinationParentId = targetParentId || loc.parent.id;\n const destParentLoc = findNodeLocation(newDoc.document, destinationParentId);\n if (!destParentLoc) {\n throw new Error(`Cannot duplicate node: Destination parent \"${destinationParentId}\" not found.`);\n }\n\n const destParent = destParentLoc.node;\n if (!destParent.children) {\n destParent.children = [];\n }\n\n // Default insertion position is right after the source node if in same parent, else appended\n let insertIndex: number;\n if (typeof index === 'number' && index >= 0 && index <= destParent.children.length) {\n insertIndex = index;\n } else if (destinationParentId === loc.parent.id) {\n insertIndex = loc.index + 1;\n } else {\n insertIndex = destParent.children.length;\n }\n\n destParent.children.splice(insertIndex, 0, clonedNode);\n\n return {\n document: newDoc,\n event: {\n type: 'NODE_DUPLICATED',\n timestamp: new Date().toISOString(),\n nodeId: clonedNode.id,\n parentId: destinationParentId,\n index: insertIndex,\n payload: {\n originalNodeId: nodeId,\n idMap: Object.fromEntries(idMap.entries()),\n },\n },\n };\n}\n\nexport interface UpdateAnimationParams {\n nodeId: string;\n animation: Partial<AnimationConfig> | null;\n /**\n * If true (default), shallow merges new animation properties with existing animation config.\n * If false, replaces the animation config with the provided object.\n * If animation is null, removes the animation configuration from the node.\n */\n merge?: boolean;\n}\n\n/**\n * 7. Update the animation configuration of an existing node.\n * Returns a new PageDocument and an ANIMATION_UPDATED event.\n */\nexport function updateAnimation(\n document: PageDocument,\n params: UpdateAnimationParams,\n): CommandResult {\n const { nodeId, animation, merge = true } = params;\n\n const newDoc = deepClone(document);\n const loc = findNodeLocation(newDoc.document, nodeId);\n if (!loc) {\n throw new Error(`Cannot update animation: Node with ID \"${nodeId}\" not found in document.`);\n }\n\n const targetNode = loc.node;\n const previousAnimation = targetNode.animation ? deepClone(targetNode.animation) : undefined;\n\n if (animation === null) {\n delete targetNode.animation;\n } else {\n const currentAnimation = targetNode.animation ? deepClone(targetNode.animation) : {};\n const candidate = merge\n ? { ...currentAnimation, ...deepClone(animation) }\n : deepClone(animation);\n targetNode.animation = AnimationConfigSchema.parse(candidate);\n }\n\n return {\n document: newDoc,\n event: {\n type: 'ANIMATION_UPDATED',\n timestamp: new Date().toISOString(),\n nodeId,\n parentId: loc.parent ? loc.parent.id : undefined,\n payload: {\n animation: targetNode.animation,\n previousAnimation,\n },\n },\n };\n}\n\nexport interface UpdateActionsParams {\n nodeId: string;\n actions: ActionPipeline[] | null;\n}\n\n/**\n * 8. Update the action pipelines of an existing node.\n * Returns a new PageDocument and an ACTIONS_UPDATED event.\n */\nexport function updateActions(\n document: PageDocument,\n params: UpdateActionsParams,\n): CommandResult {\n const { nodeId, actions } = params;\n\n const newDoc = deepClone(document);\n const loc = findNodeLocation(newDoc.document, nodeId);\n if (!loc) {\n throw new Error(`Cannot update actions: Node with ID \"${nodeId}\" not found in document.`);\n }\n\n const targetNode = loc.node;\n const previousActions = targetNode.actions ? deepClone(targetNode.actions) : undefined;\n\n if (actions === null || (Array.isArray(actions) && actions.length === 0)) {\n delete targetNode.actions;\n } else {\n targetNode.actions = ActionPipelineSchema.array().parse(actions);\n }\n\n return {\n document: newDoc,\n event: {\n type: 'ACTIONS_UPDATED',\n timestamp: new Date().toISOString(),\n nodeId,\n parentId: loc.parent ? loc.parent.id : undefined,\n payload: {\n actions: targetNode.actions,\n previousActions,\n },\n },\n };\n}\n\nexport interface UpdateFormConfigParams {\n nodeId: string;\n formConfig: Partial<FormConfig> | null;\n /**\n * If true (default), shallow merges new formConfig properties with existing config.\n * If false, replaces the formConfig with the provided object.\n * If formConfig is null, removes the form configuration from the node.\n */\n merge?: boolean;\n}\n\n/**\n * 9. Update the form configuration of an existing node.\n * Returns a new PageDocument and a FORM_CONFIG_UPDATED event.\n */\nexport function updateFormConfig(\n document: PageDocument,\n params: UpdateFormConfigParams,\n): CommandResult {\n const { nodeId, formConfig, merge = true } = params;\n\n const newDoc = deepClone(document);\n const loc = findNodeLocation(newDoc.document, nodeId);\n if (!loc) {\n throw new Error(`Cannot update formConfig: Node with ID \"${nodeId}\" not found in document.`);\n }\n\n const targetNode = loc.node;\n const previousFormConfig = targetNode.formConfig ? deepClone(targetNode.formConfig) : undefined;\n\n if (formConfig === null) {\n delete targetNode.formConfig;\n } else {\n const currentFormConfig = targetNode.formConfig ? deepClone(targetNode.formConfig) : { formId: nodeId };\n const candidate = merge\n ? { ...currentFormConfig, ...deepClone(formConfig) }\n : deepClone(formConfig);\n if (!candidate.formId) {\n candidate.formId = nodeId;\n }\n targetNode.formConfig = FormConfigSchema.parse(candidate);\n }\n\n return {\n document: newDoc,\n event: {\n type: 'FORM_CONFIG_UPDATED',\n timestamp: new Date().toISOString(),\n nodeId,\n parentId: loc.parent ? loc.parent.id : undefined,\n payload: {\n formConfig: targetNode.formConfig,\n previousFormConfig,\n },\n },\n };\n}\n\n/**\n * 10. Wrap specified node(s) into a new flex container node at the same position in the parent.\n * Preserves sibling ordering and returns a new PageDocument and a NODE_WRAPPED event.\n * Full undo/redo compatibility with DocumentHistoryManager. (STORA-105)\n */\nexport function wrapNodeIntoFrame(\n document: PageDocument,\n params: WrapNodeIntoFrameParams,\n): CommandResult {\n const rawIds =\n params.nodeIds !== undefined\n ? Array.isArray(params.nodeIds)\n ? params.nodeIds\n : [params.nodeIds]\n : params.nodeId\n ? [params.nodeId]\n : [];\n\n const targetIds = Array.from(\n new Set(rawIds.filter((id): id is string => typeof id === 'string' && id.trim().length > 0)),\n );\n\n if (targetIds.length === 0) {\n throw new Error('Cannot wrap nodes: At least one node ID must be provided.');\n }\n\n // Prevent wrapping the root page node\n if (targetIds.includes(document.document.id)) {\n throw new Error('Cannot wrap the root page node.');\n }\n\n const newDoc = deepClone(document);\n\n // Locate all target nodes in the tree\n const locations: Array<{ node: Node; parent: Node; index: number }> = [];\n for (const id of targetIds) {\n const loc = findNodeLocation(newDoc.document, id);\n if (!loc || !loc.parent) {\n throw new Error(`Cannot wrap node: Node with ID \"${id}\" not found in document.`);\n }\n locations.push(loc as { node: Node; parent: Node; index: number });\n }\n\n // Verify all target nodes share the exact same parent container\n const parentId = locations[0].parent.id;\n const parentNode = locations[0].parent;\n for (const loc of locations) {\n if (loc.parent.id !== parentId) {\n throw new Error('Cannot wrap nodes: All nodes must share the same parent container.');\n }\n }\n\n // Determine frame ID\n const existingIds = collectNodeIdSet(newDoc.document);\n let frameId = params.frameId;\n if (frameId) {\n if (existingIds.has(frameId)) {\n throw new Error(`Cannot wrap nodes: Node ID \"${frameId}\" already exists in document.`);\n }\n } else {\n let counter = 1;\n while (existingIds.has(`flex_${counter}`)) {\n counter++;\n }\n frameId = `flex_${counter}`;\n }\n\n // Sort locations by their index in the parent to preserve original sibling order\n locations.sort((a, b) => a.index - b.index);\n\n // The insertion position in the parent is the index of the first node being wrapped\n const minIndex = locations[0].index;\n const wrappedNodes = locations.map((loc) => loc.node);\n\n // Remove the target nodes from the parent's children\n const targetIdSet = new Set(targetIds);\n parentNode.children = (parentNode.children || []).filter((child) => !targetIdSet.has(child.id));\n\n // Default flex container styles (STORA-102)\n const defaultFlexStyles: ResponsiveStyles = {\n base: {\n display: 'flex',\n flexDirection: 'column',\n gap: '16px',\n },\n };\n\n const frameNode: Node = {\n id: frameId,\n type: 'flex',\n props: deepClone(params.frameProps || {}),\n styles: deepClone(params.frameStyles || defaultFlexStyles),\n children: wrappedNodes,\n };\n\n // Insert the frame node into the parent at minIndex\n const insertIndex = Math.min(minIndex, parentNode.children.length);\n parentNode.children.splice(insertIndex, 0, frameNode);\n\n return {\n document: newDoc,\n event: {\n type: 'NODE_WRAPPED',\n timestamp: new Date().toISOString(),\n nodeId: frameId,\n parentId,\n index: insertIndex,\n payload: {\n wrappedNodeIds: targetIds,\n frameNode: deepClone(frameNode),\n },\n },\n };\n}\n\n/**\n * 11. Unwrap a flex frame container, moving all of its children to its parent at its position,\n * and removing the container.\n * Returns a new PageDocument and a NODE_UNGROUPED event.\n * Full undo/redo compatibility with DocumentHistoryManager. (STORA-106)\n */\nexport function ungroupNodeFrame(\n document: PageDocument,\n params: UngroupNodeFrameParams,\n): CommandResult {\n const { nodeId } = params;\n\n if (!nodeId || typeof nodeId !== 'string' || nodeId.trim().length === 0) {\n throw new Error('Invalid nodeId: Node ID must be a non-empty string.');\n }\n\n if (nodeId === document.document.id) {\n throw new Error('Cannot ungroup the root page node.');\n }\n\n const newDoc = deepClone(document);\n const loc = findNodeLocation(newDoc.document, nodeId);\n if (!loc || !loc.parent) {\n throw new Error(`Cannot ungroup node: Node with ID \"${nodeId}\" not found in document.`);\n }\n\n const targetNode = loc.node;\n const parentNode = loc.parent;\n const targetIndex = loc.index;\n\n // Verify that the node is a flex container\n if (targetNode.type !== 'flex') {\n throw new Error(`Cannot ungroup node: Node \"${nodeId}\" is not a flex container (type is \"${targetNode.type}\").`);\n }\n\n const unwrappedChildren = targetNode.children ? deepClone(targetNode.children) : [];\n\n if (!parentNode.children) {\n parentNode.children = [];\n }\n\n // Replace the frame container at targetIndex with all of its children in place\n parentNode.children.splice(targetIndex, 1, ...unwrappedChildren);\n\n return {\n document: newDoc,\n event: {\n type: 'NODE_UNGROUPED',\n timestamp: new Date().toISOString(),\n nodeId,\n parentId: parentNode.id,\n index: targetIndex,\n payload: {\n unwrappedChildIds: unwrappedChildren.map((c) => c.id),\n unwrappedChildren,\n removedNode: deepClone(targetNode),\n },\n },\n };\n}\n\n/**\n * 12. Replace an existing node's entire subtree (props, styles, children, animation,\n * actions, formConfig) in place, preserving its position in the parent.\n *\n * Used by AI \"enhance\" flows (STORA-514) when a validated candidate node differs\n * structurally from the original (e.g. AI regenerated nested children) — a change\n * `updateProps`/`updateStyle` alone can't express since they only ever touch one\n * property bag at a time. The replacement node's `id` must match `nodeId`; this command\n * never lets identity (id) drift, the same guarantee `@kubuild/ai`'s\n * `normalizeAndValidateRefactoredNode` already enforces upstream on `type`/`id`.\n *\n * Returns a new PageDocument and a NODE_REPLACED event.\n */\nexport function replaceNode(\n document: PageDocument,\n params: ReplaceNodeParams,\n): CommandResult {\n const { nodeId, node } = params;\n\n if (!node || typeof node !== 'object' || !node.id || !node.type) {\n throw new Error('Invalid node: Node must be an object with non-empty \"id\" and \"type\"');\n }\n\n if (node.id !== nodeId) {\n throw new Error(\n `Cannot replace node: replacement node id \"${node.id}\" must match target node id \"${nodeId}\".`,\n );\n }\n\n if (nodeId === document.document.id) {\n throw new Error('Cannot replace the root page node.');\n }\n\n const newDoc = deepClone(document);\n const loc = findNodeLocation(newDoc.document, nodeId);\n if (!loc || !loc.parent) {\n throw new Error(`Cannot replace node: Node with ID \"${nodeId}\" not found in document.`);\n }\n\n // A replacement subtree may introduce ids that collide with the rest of the document\n // (outside the subtree being replaced) — reject rather than silently corrupting ids.\n const existingIds = collectNodeIdSet(newDoc.document);\n for (const id of collectNodeIdSet(loc.node)) {\n existingIds.delete(id);\n }\n for (const incomingId of collectNodeIdSet(node)) {\n if (existingIds.has(incomingId)) {\n throw new Error(\n `Cannot replace node: Duplicate node ID \"${incomingId}\" already exists elsewhere in document.`,\n );\n }\n }\n\n const previousNode = deepClone(loc.node);\n const replacement = deepClone(node);\n loc.parent.children![loc.index] = replacement;\n\n return {\n document: newDoc,\n event: {\n type: 'NODE_REPLACED',\n timestamp: new Date().toISOString(),\n nodeId,\n parentId: loc.parent.id,\n index: loc.index,\n payload: {\n node: replacement,\n previousNode,\n },\n },\n };\n}\n\nexport interface UpdateThemeParams {\n /**\n * Token changes. With `merge` (default) each group is merged token-by-token and a token\n * set to `null` is removed; without `merge` the theme is replaced. `null` removes the\n * whole theme.\n */\n theme: { [G in keyof Theme]?: Record<string, string | number | null> | null } | null;\n merge?: boolean;\n}\n\n/**\n * Update the document-level design tokens (`PageDocument.theme`, STORA-551).\n * The result is validated with `ThemeSchema`, so unsafe keys/values (CSS injection) throw.\n * Returns a new PageDocument and a THEME_UPDATED event keyed to the root node.\n */\nexport function updateTheme(document: PageDocument, params: UpdateThemeParams): CommandResult {\n const { theme, merge = true } = params;\n const newDoc = deepClone(document);\n const previousTheme = newDoc.theme ? deepClone(newDoc.theme) : undefined;\n\n if (theme === null) {\n delete newDoc.theme;\n } else {\n const next: Record<string, Record<string, unknown>> = {};\n for (const group of THEME_TOKEN_GROUPS) {\n const base = merge ? { ...((previousTheme?.[group] as Record<string, unknown> | undefined) ?? {}) } : {};\n const patch = theme[group];\n if (patch === null) {\n continue;\n }\n if (patch) {\n for (const [key, value] of Object.entries(patch)) {\n if (value === null) {\n delete base[key];\n } else {\n base[key] = value;\n }\n }\n }\n if (Object.keys(base).length > 0) {\n next[group] = base;\n }\n }\n const parsed = ThemeSchema.parse(next);\n if (Object.keys(parsed).length > 0) {\n newDoc.theme = parsed;\n } else {\n delete newDoc.theme;\n }\n }\n\n return {\n document: newDoc,\n event: {\n type: 'THEME_UPDATED',\n timestamp: new Date().toISOString(),\n nodeId: newDoc.document.id,\n payload: {\n theme: newDoc.theme,\n previousTheme,\n },\n },\n };\n}\n","import {\n Artboard,\n ArtboardType,\n Node,\n PageDocument,\n ProjectDocument,\n SCHEMA_NAME,\n PROJECT_SCHEMA_NAME,\n CURRENT_PROJECT_SCHEMA_VERSION,\n CURRENT_SCHEMA_VERSION,\n ARTBOARD_REFERENCE_NODE_TYPE,\n} from '@kubuild/schema';\nimport { deepClone, findNodeLocation, collectNodeIdSet } from './command-tree-utils';\nimport { createBlankDocument } from './document-utils';\n\nexport type ArtboardChangeType =\n | 'ARTBOARD_ADDED'\n | 'ARTBOARD_REMOVED'\n | 'ARTBOARD_RENAMED'\n | 'ACTIVE_ARTBOARD_CHANGED'\n | 'NODE_EXTRACTED_TO_ARTBOARD';\n\nexport interface ArtboardChangeEvent {\n type: ArtboardChangeType;\n timestamp: string;\n artboardId: string;\n /** Source artboard, for operations that move content between artboards. */\n sourceArtboardId?: string;\n nodeId?: string;\n payload?: Record<string, unknown>;\n}\n\n/**\n * Mirrors CommandResult from commands.ts, but at the project (multi-artboard) level.\n * Node-level commands keep returning CommandResult and keep operating on a single\n * PageDocument, unchanged.\n */\nexport interface ProjectCommandResult {\n project: ProjectDocument;\n event: ArtboardChangeEvent;\n}\n\nexport interface AddArtboardParams {\n artboard: Artboard;\n index?: number;\n /** Make the newly added artboard active (default: true). */\n activate?: boolean;\n}\n\nexport interface RemoveArtboardParams {\n artboardId: string;\n}\n\nexport interface RenameArtboardParams {\n artboardId: string;\n name: string;\n}\n\nexport interface SetActiveArtboardParams {\n artboardId: string;\n}\n\nexport interface ExtractNodeToArtboardParams {\n /** Artboard currently holding the node. */\n artboardId: string;\n /** Node whose subtree becomes the new artboard's content. */\n nodeId: string;\n /** Optional explicit name for the new artboard (defaults to the node type). */\n name?: string;\n /** Optional explicit id for the new artboard. */\n newArtboardId?: string;\n /** Make the new artboard active (default: false — authors usually keep editing the page). */\n activate?: boolean;\n}\n\nconst now = (): string => new Date().toISOString();\n\n/**\n * Collect every node id used anywhere in the project (across all artboards).\n * Node ids must be unique project-wide so that content can move between artboards\n * without silently colliding.\n */\nexport function collectProjectNodeIds(project: ProjectDocument): Set<string> {\n const ids = new Set<string>();\n for (const artboard of project.artboards) {\n for (const id of collectNodeIdSet(artboard.document.document)) {\n ids.add(id);\n }\n }\n return ids;\n}\n\nfunction uniqueId(prefix: string, taken: Set<string>): string {\n let counter = 1;\n while (taken.has(`${prefix}_${counter}`)) {\n counter++;\n }\n return `${prefix}_${counter}`;\n}\n\nexport function findArtboardById(\n project: ProjectDocument,\n artboardId: string,\n): Artboard | undefined {\n return project.artboards.find((artboard) => artboard.id === artboardId);\n}\n\n/**\n * Resolve the component artboard an `open_modal` / `close_modal` action targets.\n * ModalManager keys off plain strings, so a trigger in one artboard can address\n * content in another with no additional wiring.\n */\nexport function findArtboardByTriggerId(\n project: ProjectDocument,\n triggerId: string,\n): Artboard | undefined {\n if (!triggerId) return undefined;\n return project.artboards.find(\n (artboard) => artboard.artboardType === 'component' && artboard.triggerId === triggerId,\n );\n}\n\nexport function getActiveArtboard(project: ProjectDocument): Artboard | undefined {\n if (project.activeArtboardId) {\n const active = findArtboardById(project, project.activeArtboardId);\n if (active) return active;\n }\n return project.artboards[0];\n}\n\nexport function getPageArtboards(project: ProjectDocument): Artboard[] {\n return project.artboards.filter((artboard) => artboard.artboardType === 'page');\n}\n\nexport function getComponentArtboards(project: ProjectDocument): Artboard[] {\n return project.artboards.filter((artboard) => artboard.artboardType === 'component');\n}\n\nexport interface CreateArtboardOptions {\n id?: string;\n slug?: string;\n triggerId?: string;\n viewport?: Artboard['viewport'];\n width?: number;\n}\n\n/**\n * Build a page artboard around a fresh blank document.\n */\nexport function createPageArtboard(\n name = 'Untitled Page',\n options: CreateArtboardOptions = {},\n): Artboard {\n return {\n id: options.id ?? `artboard-page-${Date.now()}`,\n name,\n artboardType: 'page',\n slug: options.slug ?? '/',\n document: createBlankDocument(name),\n ...(options.viewport ? { viewport: options.viewport } : {}),\n ...(options.width !== undefined ? { width: options.width } : {}),\n };\n}\n\n/**\n * Wrap an existing node as the sole child of a synthetic `page` root and return it as a\n * component artboard. The synthetic root exists so each artboard's `document` stays a\n * fully valid PageDocument, meaning no existing command, validator, or history code\n * needs to know that component artboards exist at all.\n */\nexport function createComponentArtboard(\n node: Node,\n options: CreateArtboardOptions & { name?: string; rootId?: string } = {},\n): Artboard {\n const name = options.name ?? node.type;\n const triggerId =\n options.triggerId ??\n (typeof node.props?.modalId === 'string' && node.props.modalId.trim().length > 0\n ? (node.props.modalId as string)\n : node.id);\n\n const document: PageDocument = {\n schema: SCHEMA_NAME,\n version: CURRENT_SCHEMA_VERSION,\n metadata: {\n title: name,\n description: '',\n author: '',\n tags: [],\n category: 'component',\n version: CURRENT_SCHEMA_VERSION,\n createdAt: now(),\n updatedAt: now(),\n },\n document: {\n id: options.rootId ?? `${node.id}-artboard-root`,\n type: 'page',\n props: { title: name },\n // Transparent surface: a component artboard is a canvas for the node, not a page.\n styles: { base: { minHeight: 'auto', backgroundColor: 'transparent' } },\n children: [deepClone(node)],\n },\n };\n\n return {\n id: options.id ?? `artboard-component-${node.id}`,\n name,\n artboardType: 'component',\n triggerId,\n document,\n ...(options.viewport ? { viewport: options.viewport } : {}),\n ...(options.width !== undefined ? { width: options.width } : {}),\n };\n}\n\n/**\n * Create a project containing a single blank page artboard.\n */\nexport function createBlankProject(title = 'Untitled Page'): ProjectDocument {\n const artboard = createPageArtboard(title, { id: 'artboard-page-1' });\n return {\n schema: PROJECT_SCHEMA_NAME,\n version: CURRENT_PROJECT_SCHEMA_VERSION,\n metadata: artboard.document.metadata,\n artboards: [artboard],\n activeArtboardId: artboard.id,\n };\n}\n\nexport function addArtboard(\n project: ProjectDocument,\n params: AddArtboardParams,\n): ProjectCommandResult {\n const { artboard } = params;\n if (!artboard?.id) {\n throw new Error('Cannot add artboard: artboard must have an id.');\n }\n if (findArtboardById(project, artboard.id)) {\n throw new Error(`Cannot add artboard: id \"${artboard.id}\" already exists in the project.`);\n }\n\n const next = deepClone(project);\n const index = params.index ?? next.artboards.length;\n next.artboards.splice(Math.max(0, Math.min(index, next.artboards.length)), 0, deepClone(artboard));\n\n if (params.activate !== false) {\n next.activeArtboardId = artboard.id;\n }\n\n return {\n project: next,\n event: {\n type: 'ARTBOARD_ADDED',\n timestamp: now(),\n artboardId: artboard.id,\n payload: { artboardType: artboard.artboardType, index },\n },\n };\n}\n\nexport function removeArtboard(\n project: ProjectDocument,\n params: RemoveArtboardParams,\n): ProjectCommandResult {\n const { artboardId } = params;\n const existing = findArtboardById(project, artboardId);\n if (!existing) {\n throw new Error(`Cannot remove artboard: id \"${artboardId}\" not found.`);\n }\n if (project.artboards.length === 1) {\n throw new Error('Cannot remove artboard: a project must keep at least one artboard.');\n }\n\n const next = deepClone(project);\n next.artboards = next.artboards.filter((artboard) => artboard.id !== artboardId);\n\n if (next.activeArtboardId === artboardId) {\n next.activeArtboardId = next.artboards[0]?.id;\n }\n\n return {\n project: next,\n event: {\n type: 'ARTBOARD_REMOVED',\n timestamp: now(),\n artboardId,\n payload: { artboardType: existing.artboardType },\n },\n };\n}\n\nexport function renameArtboard(\n project: ProjectDocument,\n params: RenameArtboardParams,\n): ProjectCommandResult {\n const { artboardId, name } = params;\n if (!name || name.trim().length === 0) {\n throw new Error('Cannot rename artboard: name must be a non-empty string.');\n }\n const existing = findArtboardById(project, artboardId);\n if (!existing) {\n throw new Error(`Cannot rename artboard: id \"${artboardId}\" not found.`);\n }\n\n const next = deepClone(project);\n const target = findArtboardById(next, artboardId)!;\n const previousName = target.name;\n target.name = name;\n\n return {\n project: next,\n event: {\n type: 'ARTBOARD_RENAMED',\n timestamp: now(),\n artboardId,\n payload: { previousName, name },\n },\n };\n}\n\nexport function setActiveArtboard(\n project: ProjectDocument,\n params: SetActiveArtboardParams,\n): ProjectCommandResult {\n const { artboardId } = params;\n if (!findArtboardById(project, artboardId)) {\n throw new Error(`Cannot activate artboard: id \"${artboardId}\" not found.`);\n }\n\n const next = deepClone(project);\n const previousArtboardId = next.activeArtboardId;\n next.activeArtboardId = artboardId;\n\n return {\n project: next,\n event: {\n type: 'ACTIVE_ARTBOARD_CHANGED',\n timestamp: now(),\n artboardId,\n payload: { previousArtboardId },\n },\n };\n}\n\n/**\n * Detach a node's subtree into its own component artboard, leaving an\n * `artboard-reference` stub at the original position.\n *\n * The stub matters: selection, move/delete, copy/paste, the Layers panel, and history\n * diffing all walk nodes that are physically present in the tree, so a bare deletion would\n * leave the page with no visible, selectable anchor for \"this surface opens artboard X\"\n * and would strand the trigger's id with nothing pointing back at it.\n *\n * Undo scoping caveat (Phase 1): the editor's history is per-document, so this operation —\n * which spans two artboards — is applied as one atomic project-level step rather than being\n * finely undoable inside each artboard's own stack.\n */\nexport function extractNodeToArtboard(\n project: ProjectDocument,\n params: ExtractNodeToArtboardParams,\n): ProjectCommandResult {\n const { artboardId, nodeId } = params;\n\n const sourceArtboard = findArtboardById(project, artboardId);\n if (!sourceArtboard) {\n throw new Error(`Cannot extract node: artboard \"${artboardId}\" not found.`);\n }\n if (sourceArtboard.document.document.id === nodeId) {\n throw new Error('Cannot extract node: the artboard root cannot be detached.');\n }\n\n const next = deepClone(project);\n const workingArtboard = findArtboardById(next, artboardId)!;\n const location = findNodeLocation(workingArtboard.document.document, nodeId);\n if (!location || !location.parent) {\n throw new Error(`Cannot extract node: node \"${nodeId}\" not found in artboard \"${artboardId}\".`);\n }\n\n const { node, parent, index } = location as { node: Node; parent: Node; index: number };\n const extracted = deepClone(node);\n\n const takenNodeIds = collectProjectNodeIds(next);\n const takenArtboardIds = new Set(next.artboards.map((artboard) => artboard.id));\n\n const newArtboardId = params.newArtboardId ?? `artboard-component-${extracted.id}`;\n if (takenArtboardIds.has(newArtboardId)) {\n throw new Error(`Cannot extract node: artboard id \"${newArtboardId}\" already exists.`);\n }\n\n const componentArtboard = createComponentArtboard(extracted, {\n id: newArtboardId,\n name: params.name ?? extracted.type,\n rootId: uniqueId('artboard-root', takenNodeIds),\n viewport: sourceArtboard.viewport,\n });\n\n // Replace the node in place with a reference stub rather than deleting it outright.\n const stub: Node = {\n id: uniqueId('artboard_ref', takenNodeIds),\n type: ARTBOARD_REFERENCE_NODE_TYPE,\n props: {\n artboardId: componentArtboard.id,\n triggerId: componentArtboard.triggerId,\n label: componentArtboard.name,\n },\n styles: {},\n children: [],\n };\n parent.children = parent.children || [];\n parent.children.splice(index, 1, stub);\n\n next.artboards.push(componentArtboard);\n if (params.activate) {\n next.activeArtboardId = componentArtboard.id;\n }\n\n return {\n project: next,\n event: {\n type: 'NODE_EXTRACTED_TO_ARTBOARD',\n timestamp: now(),\n artboardId: componentArtboard.id,\n sourceArtboardId: artboardId,\n nodeId: extracted.id,\n payload: {\n stubNodeId: stub.id,\n triggerId: componentArtboard.triggerId,\n artboardType: 'component' satisfies ArtboardType,\n },\n },\n };\n}\n\n/**\n * Replace one artboard's document wholesale. Used by the editor when committing the\n * single active PageDocument it holds back into the project.\n */\nexport function updateArtboardDocument(\n project: ProjectDocument,\n artboardId: string,\n document: PageDocument,\n): ProjectDocument {\n const next = deepClone(project);\n const target = findArtboardById(next, artboardId);\n if (!target) {\n throw new Error(`Cannot update artboard document: id \"${artboardId}\" not found.`);\n }\n target.document = deepClone(document);\n return next;\n}\n","import { PageDocument } from '@kubuild/schema';\nimport { DocumentChangeEvent, CommandResult } from './commands';\nimport { deepClone } from './command-tree-utils';\n\nexport interface HistoryOptions {\n /**\n * Maximum number of historical states stored in the undo stack.\n * Defaults to 50.\n */\n maxHistory?: number;\n}\n\nexport interface HistoryEntry<T> {\n state: T;\n event?: DocumentChangeEvent;\n timestamp: string;\n}\n\nexport interface HistoryState<T> {\n canUndo: boolean;\n canRedo: boolean;\n undoCount: number;\n redoCount: number;\n present: T;\n}\n\nexport const DEFAULT_MAX_HISTORY = 50;\n\n/**\n * Generic History Engine for immutable state transitions.\n * Maintains undo/redo stacks, enforces maximum history limit,\n * clears redo stack on new actions, and supports resetting state.\n */\nexport class HistoryEngine<T = PageDocument> {\n private past: HistoryEntry<T>[] = [];\n private current: HistoryEntry<T>;\n private future: HistoryEntry<T>[] = [];\n private readonly maxHistory: number;\n // STORA-510: grouped-history transaction bookkeeping. `transactionAnchor` is the\n // entry that was `current` immediately before the outermost `beginTransaction()`\n // call — the single state `endTransaction()` restores undo history to.\n private transactionDepth = 0;\n private transactionAnchor: HistoryEntry<T> | null = null;\n\n constructor(initialState: T, options: HistoryOptions = {}) {\n if (initialState === undefined || initialState === null) {\n throw new Error('Initial state must be defined.');\n }\n\n const limit = options.maxHistory ?? DEFAULT_MAX_HISTORY;\n if (typeof limit !== 'number' || limit <= 0 || !Number.isFinite(limit)) {\n throw new Error('maxHistory option must be a positive integer.');\n }\n\n this.maxHistory = Math.floor(limit);\n this.current = {\n state: deepClone(initialState),\n timestamp: new Date().toISOString(),\n };\n }\n\n /**\n * Get the current active state (returns an immutable clone).\n */\n get present(): T {\n return deepClone(this.current.state);\n }\n\n /**\n * Check if undo is available.\n */\n canUndo(): boolean {\n return this.past.length > 0;\n }\n\n /**\n * Check if redo is available.\n */\n canRedo(): boolean {\n return this.future.length > 0;\n }\n\n /**\n * Get total number of states in undo stack.\n */\n get undoCount(): number {\n return this.past.length;\n }\n\n /**\n * Get total number of states in redo stack.\n */\n get redoCount(): number {\n return this.future.length;\n }\n\n /**\n * Get max history limit.\n */\n get limit(): number {\n return this.maxHistory;\n }\n\n /**\n * Push a new state.\n * Clears the redo stack and shifts oldest past entries if maxHistory is exceeded.\n *\n * STORA-510: while a transaction is active (see `beginTransaction`), pushes update\n * `current` in place without creating an individual undo entry — the whole group\n * collapses into one entry when `endTransaction()` is called.\n */\n push(nextState: T, event?: DocumentChangeEvent): void {\n if (nextState === undefined || nextState === null) {\n throw new Error('Cannot push undefined or null state into history.');\n }\n\n if (this.transactionDepth > 0) {\n this.current = {\n state: deepClone(nextState),\n event,\n timestamp: new Date().toISOString(),\n };\n return;\n }\n\n // Save current to past\n this.past.push(this.current);\n\n // Enforce maxHistory limit on undo stack\n while (this.past.length > this.maxHistory) {\n this.past.shift();\n }\n\n // Set new current\n this.current = {\n state: deepClone(nextState),\n event,\n timestamp: new Date().toISOString(),\n };\n\n // Any new action clears redo future stack\n this.future = [];\n }\n\n /**\n * Begin a grouped-history transaction (STORA-510).\n *\n * Every `push()` made between `beginTransaction()` and the matching outermost\n * `endTransaction()` updates the live state immediately (so `present`/`getState()`\n * always reflect the latest change), but no individual undo entry is recorded until\n * the transaction ends. This is how a multi-step action (e.g. one `streamPage`\n * generation session inserting several sections) collapses into a single undo step.\n *\n * Transactions may be nested; only the outermost `beginTransaction`/`endTransaction`\n * pair has any effect, so a batching caller can safely wrap calls that themselves\n * might also start their own (nested) transaction.\n */\n beginTransaction(): void {\n if (this.transactionDepth === 0) {\n this.transactionAnchor = this.current;\n }\n this.transactionDepth += 1;\n }\n\n /**\n * Ends the current transaction (see `beginTransaction`). Once the outermost\n * transaction ends, the state as it was immediately before `beginTransaction()` is\n * pushed as a single past entry (exactly as one `push()` would) and the redo stack\n * is cleared — unless nothing actually changed during the transaction, in which case\n * this is a no-op and no empty undo entry is created.\n *\n * Calling `endTransaction()` without a matching `beginTransaction()` is a no-op.\n */\n endTransaction(): void {\n if (this.transactionDepth === 0) return;\n this.transactionDepth -= 1;\n if (this.transactionDepth > 0) return;\n\n const anchor = this.transactionAnchor;\n this.transactionAnchor = null;\n if (!anchor || anchor === this.current) return;\n\n this.past.push(anchor);\n while (this.past.length > this.maxHistory) {\n this.past.shift();\n }\n this.future = [];\n }\n\n /**\n * Whether a grouped-history transaction is currently active.\n */\n get inTransaction(): boolean {\n return this.transactionDepth > 0;\n }\n\n /**\n * Undo to the previous state.\n * Returns the restored state, or undefined if undo is not possible.\n */\n undo(): T | undefined {\n if (!this.canUndo()) {\n return undefined;\n }\n\n const previousEntry = this.past.pop()!;\n this.future.unshift(this.current);\n this.current = previousEntry;\n\n return this.present;\n }\n\n /**\n * Redo to the next state in future stack.\n * Returns the restored state, or undefined if redo is not possible.\n */\n redo(): T | undefined {\n if (!this.canRedo()) {\n return undefined;\n }\n\n const nextEntry = this.future.shift()!;\n this.past.push(this.current);\n this.current = nextEntry;\n\n return this.present;\n }\n\n /**\n * Reset the history engine with a new initial state.\n * Clears both undo and redo stacks (e.g. when loading a new document).\n */\n reset(newState: T): void {\n if (newState === undefined || newState === null) {\n throw new Error('New state must be defined when resetting history.');\n }\n\n this.past = [];\n this.future = [];\n this.current = {\n state: deepClone(newState),\n timestamp: new Date().toISOString(),\n };\n }\n\n /**\n * Clear both past and future stacks without changing the current state.\n */\n clear(): void {\n this.past = [];\n this.future = [];\n }\n\n /**\n * Get a snapshot of current history status.\n */\n getState(): HistoryState<T> {\n return {\n canUndo: this.canUndo(),\n canRedo: this.canRedo(),\n undoCount: this.undoCount,\n redoCount: this.redoCount,\n present: this.present,\n };\n }\n}\n\n/**\n * Document History Manager for PageDocument.\n * Connects HistoryEngine with core command execution.\n */\nexport class DocumentHistoryManager {\n private history: HistoryEngine<PageDocument>;\n\n constructor(initialDocument: PageDocument, options?: HistoryOptions) {\n this.history = new HistoryEngine<PageDocument>(initialDocument, options);\n }\n\n get document(): PageDocument {\n return this.history.present;\n }\n\n get canUndo(): boolean {\n return this.history.canUndo();\n }\n\n get canRedo(): boolean {\n return this.history.canRedo();\n }\n\n /**\n * Execute a mutation command immutably and record the resulting state and change event in history.\n */\n execute(executor: (currentDoc: PageDocument) => CommandResult): CommandResult {\n const currentDoc = this.history.present;\n const result = executor(currentDoc);\n this.history.push(result.document, result.event);\n return result;\n }\n\n undo(): PageDocument | undefined {\n return this.history.undo();\n }\n\n redo(): PageDocument | undefined {\n return this.history.redo();\n }\n\n /**\n * Begin a grouped-history transaction (STORA-510) — see `HistoryEngine.beginTransaction`.\n * Every `execute()` call made until the matching `endTransaction()` updates\n * `document` immediately but is collapsed into a single undo entry.\n */\n beginTransaction(): void {\n this.history.beginTransaction();\n }\n\n /**\n * Ends a grouped-history transaction started with `beginTransaction()` — see\n * `HistoryEngine.endTransaction`.\n */\n endTransaction(): void {\n this.history.endTransaction();\n }\n\n get inTransaction(): boolean {\n return this.history.inTransaction;\n }\n\n reset(newDocument: PageDocument): void {\n this.history.reset(newDocument);\n }\n\n clear(): void {\n this.history.clear();\n }\n\n getState(): HistoryState<PageDocument> {\n return this.history.getState();\n }\n}\n","import type { VariableBinding } from '@kubuild/schema';\nimport type { RuntimeContext } from '../types/interfaces';\n\n/**\n * Segments a VariableBinding key must never traverse into, checked before any\n * property access so it can't be bypassed by proxies/getters on the traversed object.\n */\nconst FORBIDDEN_KEY_SEGMENTS = new Set(['__proto__', 'constructor', 'prototype']);\n\nexport type ResolveOutcome =\n | { status: 'resolved'; value: unknown }\n | { status: 'fallback'; value: unknown }\n | { status: 'empty'; value: '' };\n\n// `key`/`fallback` are never passed to eval/Function/any code-execution path in this\n// module — resolution is pure data traversal, never expression evaluation.\nexport function resolveBinding(\n binding: Pick<VariableBinding, 'key' | 'fallback'>,\n context: RuntimeContext | undefined,\n): ResolveOutcome {\n const segments = binding.key.split('.').filter(Boolean);\n if (segments.some((segment) => FORBIDDEN_KEY_SEGMENTS.has(segment))) {\n return applyMissingPolicy(binding);\n }\n\n // Fast-path: Check if context.variables contains the key directly as a flat property\n if (\n context?.variables &&\n typeof context.variables === 'object' &&\n Object.prototype.hasOwnProperty.call(context.variables, binding.key)\n ) {\n const directValue = (context.variables as Record<string, unknown>)[binding.key];\n if (directValue !== undefined && typeof directValue !== 'function') {\n return { status: 'resolved', value: directValue };\n }\n }\n\n let current: unknown = context?.variables;\n\n for (const segment of segments) {\n if (FORBIDDEN_KEY_SEGMENTS.has(segment)) {\n return applyMissingPolicy(binding);\n }\n if (current === null || typeof current !== 'object') {\n return applyMissingPolicy(binding);\n }\n if (!Object.prototype.hasOwnProperty.call(current, segment)) {\n return applyMissingPolicy(binding);\n }\n current = (current as Record<string, unknown>)[segment];\n }\n\n if (current === undefined || typeof current === 'function') {\n return applyMissingPolicy(binding);\n }\n\n return { status: 'resolved', value: current };\n}\n\nfunction applyMissingPolicy(binding: Pick<VariableBinding, 'fallback'>): ResolveOutcome {\n if (binding.fallback !== undefined) {\n return { status: 'fallback', value: binding.fallback };\n }\n return { status: 'empty', value: '' };\n}\n\n/** Convenience wrapper returning just the resolved/fallback/empty value. */\nexport function resolveBindingValue(\n binding: Pick<VariableBinding, 'key' | 'fallback'>,\n context: RuntimeContext | undefined,\n): unknown {\n return resolveBinding(binding, context).value;\n}\n","import type { VariableCatalog } from '../types/interfaces';\n\n/**\n * Segments never traversed/assigned while expanding a catalog key — mirrors the guard\n * in binding-resolver.ts so a host-declared key can't be used to reach the prototype chain.\n */\nconst FORBIDDEN_KEY_SEGMENTS = new Set(['__proto__', 'constructor', 'prototype']);\n\n/**\n * Expands a host `VariableCatalog`'s dotted `sampleValue` keys (e.g. `'site.name'`,\n * `'products'`) into a nested object shaped the same way `resolveBinding` expects\n * `context.variables` to be shaped. Editor/preview-only: the result should be merged\n * into a `RuntimeContext.variables` for canvas preview, never written to a document.\n */\nexport function buildSampleVariablesFromCatalog(catalog?: VariableCatalog): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n if (!catalog) {\n return result;\n }\n\n for (const entry of catalog) {\n const segments = entry.key.split('.').filter(Boolean);\n if (segments.length === 0 || segments.some((segment) => FORBIDDEN_KEY_SEGMENTS.has(segment))) {\n continue;\n }\n\n let cursor: Record<string, unknown> = result;\n for (let i = 0; i < segments.length - 1; i += 1) {\n const segment = segments[i];\n const existing = cursor[segment];\n if (existing === null || typeof existing !== 'object' || Array.isArray(existing)) {\n cursor[segment] = {};\n }\n cursor = cursor[segment] as Record<string, unknown>;\n }\n cursor[segments[segments.length - 1]] = entry.sampleValue;\n }\n\n return result;\n}\n","/**\n * Template and Expression Variable Interpolator\n *\n * Provides safe, deterministic resolution and interpolation of template strings\n * like `{{form.email}}`, `{{variables.token}}`, and `{{response.data.id}}` into\n * targets without using eval() or Function().\n */\n\n/**\n * Segments a path must never traverse into, preventing prototype pollution\n * and unauthorized object introspection.\n */\nconst FORBIDDEN_KEY_SEGMENTS = new Set(['__proto__', 'constructor', 'prototype']);\n\n/**\n * Regex matching `{{ expression }}` template placeholders.\n */\nconst TEMPLATE_EXPRESSION_REGEX = /\\{\\{\\s*([a-zA-Z0-9_$.,\\-[\\]\\s]+?)\\s*\\}\\}/g;\n\n/**\n * Regex matching an exact single `{{ expression }}` placeholder without surrounding text.\n */\nconst EXACT_TEMPLATE_REGEX = /^\\{\\{\\s*([a-zA-Z0-9_$.,\\-[\\]\\s]+?)\\s*\\}\\}$/;\n\n/**\n * Standard structured runtime context for interpolations.\n */\nexport interface InterpolationContext {\n form?: Record<string, unknown>;\n variables?: Record<string, unknown>;\n response?: Record<string, unknown>;\n state?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\n/**\n * Checks if a string contains one or more `{{ ... }}` template expressions.\n */\nexport function hasTemplateExpressions(text: unknown): boolean {\n if (typeof text !== 'string') return false;\n return /\\{\\{\\s*[\\s\\S]+?\\s*\\}\\}/.test(text);\n}\n\n/**\n * Extracts all unique property keys / variable paths referenced inside `{{ ... }}`.\n */\nexport function extractTemplateVariables(text: string): string[] {\n if (!text || typeof text !== 'string') return [];\n const matches: string[] = [];\n const regex = new RegExp(TEMPLATE_EXPRESSION_REGEX.source, 'g');\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(text)) !== null) {\n if (match[1]) {\n const trimmed = match[1].trim();\n if (trimmed && !matches.includes(trimmed)) {\n matches.push(trimmed);\n }\n }\n }\n\n return matches;\n}\n\n/**\n * Safely traverses a nested data source to resolve a dot/bracket path\n * (e.g. `form.user.profile.name`, `response.data[0].id`, `items.0.title`).\n *\n * Returns `fallback` if any segment is missing, undefined, null, or points to\n * a function or forbidden prototype property.\n */\nexport function resolvePropertyPath(\n source: unknown,\n path: string,\n fallback?: unknown,\n): unknown {\n const defaultFallback = arguments.length < 3 ? '' : fallback;\n if (!path || typeof path !== 'string' || source === null || source === undefined) {\n return defaultFallback;\n }\n\n // Normalize bracket notations: `items[0]` -> `items.0`\n const normalizedPath = path.replace(/\\[(\\d+)\\]/g, '.$1');\n const segments = normalizedPath.split('.').map((s) => s.trim()).filter(Boolean);\n\n if (segments.length === 0) {\n return defaultFallback;\n }\n\n let current: unknown = source;\n\n for (const segment of segments) {\n if (FORBIDDEN_KEY_SEGMENTS.has(segment)) {\n return defaultFallback;\n }\n if (current === null || current === undefined) {\n return defaultFallback;\n }\n if (typeof current !== 'object') {\n return defaultFallback;\n }\n\n if (Array.isArray(current)) {\n const index = Number(segment);\n if (!Number.isInteger(index) || index < 0 || index >= current.length) {\n return defaultFallback;\n }\n current = current[index];\n } else if (Object.prototype.hasOwnProperty.call(current, segment)) {\n current = (current as Record<string, unknown>)[segment];\n } else {\n return defaultFallback;\n }\n }\n\n if (current === undefined || typeof current === 'function') {\n return defaultFallback;\n }\n\n return current;\n}\n\n/**\n * Interpolates all `{{ path }}` placeholders in a template string using values\n * from the provided context object.\n *\n * If a variable cannot be resolved, it replaces it with `fallback` (default: `\"\"`).\n */\nexport function interpolateTemplateString(\n template: string,\n context?: Record<string, unknown>,\n fallback: string = '',\n): string {\n if (!template || typeof template !== 'string') return '';\n if (!hasTemplateExpressions(template)) return template;\n\n return template.replace(/\\{\\{\\s*([a-zA-Z0-9_$.,\\-[\\]\\s]+?)\\s*\\}\\}/g, (_match, rawKey) => {\n const key = rawKey.trim();\n if (!key) return fallback;\n\n const resolved = resolvePropertyPath(context, key, fallback);\n if (resolved === undefined || resolved === null) {\n return fallback;\n }\n if (typeof resolved === 'object') {\n try {\n return JSON.stringify(resolved);\n } catch {\n return fallback;\n }\n }\n return String(resolved);\n });\n}\n\n/**\n * Recursively interpolates any value (string, object, array, primitive).\n *\n * - If string is exactly `{{ path }}`, returns the raw resolved value (retaining type: number, boolean, object, array).\n * - If string contains embedded templates (e.g. `Bearer {{token}}`), returns the interpolated string.\n * - If array, interpolates every element.\n * - If object, interpolates every property value while stripping forbidden prototype keys.\n */\nexport function interpolateValue(value: unknown, context?: Record<string, unknown>): unknown {\n if (value === null || value === undefined) {\n return value;\n }\n\n if (typeof value === 'string') {\n const trimmed = value.trim();\n const exactMatch = EXACT_TEMPLATE_REGEX.exec(trimmed);\n if (exactMatch && exactMatch[1]) {\n const key = exactMatch[1].trim();\n return resolvePropertyPath(context, key, '');\n }\n return interpolateTemplateString(value, context);\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => interpolateValue(item, context));\n }\n\n if (typeof value === 'object') {\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n if (!FORBIDDEN_KEY_SEGMENTS.has(k)) {\n result[k] = interpolateValue(v, context);\n }\n }\n return result;\n }\n\n return value;\n}\n","import type { ActionStepCondition, ConditionOperator } from '@kubuild/schema';\nimport { resolvePropertyPath } from './interpolator';\n\n/**\n * Extended condition operators supported by the evaluator.\n */\nexport type ExtendedConditionOperator =\n | ConditionOperator\n | 'starts_with'\n | 'ends_with'\n | 'is_empty'\n | 'is_not_empty'\n | 'in'\n | 'not_in';\n\n/**\n * Options for fine-tuning condition evaluation.\n */\nexport interface ConditionEvaluationOptions {\n caseInsensitive?: boolean;\n trimStrings?: boolean;\n}\n\n/**\n * Represents a group of conditions evaluated together using AND / OR combinators.\n */\nexport interface ConditionGroup {\n combinator: 'and' | 'or';\n conditions: (ActionStepCondition | ConditionGroup)[];\n}\n\n/**\n * Type guard to check if a condition item is a ConditionGroup.\n */\nexport function isConditionGroup(\n item: ActionStepCondition | ConditionGroup,\n): item is ConditionGroup {\n return typeof item === 'object' && item !== null && 'combinator' in item && 'conditions' in item;\n}\n\n/**\n * Checks whether a given value is considered empty.\n * Returns true for undefined, null, empty string, empty array, or empty object.\n */\nexport function isValueEmpty(value: unknown): boolean {\n if (value === undefined || value === null) {\n return true;\n }\n if (typeof value === 'string') {\n return value.trim().length === 0;\n }\n if (Array.isArray(value)) {\n return value.length === 0;\n }\n if (typeof value === 'object') {\n return Object.keys(value as Record<string, unknown>).length === 0;\n }\n return false;\n}\n\n/**\n * Evaluates an operator against an actual value and an optional expected value.\n */\nexport function evaluateOperator(\n operator: ExtendedConditionOperator | string,\n actual: unknown,\n expected?: unknown,\n options?: ConditionEvaluationOptions,\n): boolean {\n let act = actual;\n let exp = expected;\n\n if (options?.trimStrings) {\n if (typeof act === 'string') act = act.trim();\n if (typeof exp === 'string') exp = exp.trim();\n }\n\n if (options?.caseInsensitive) {\n if (typeof act === 'string') act = act.toLowerCase();\n if (typeof exp === 'string') exp = exp.toLowerCase();\n }\n\n switch (operator) {\n case 'equals': {\n if (act === exp) return true;\n // Handle numeric type coercion if one is string and the other is number\n if (typeof act === 'number' && typeof exp === 'string' && exp.trim() !== '') {\n const numExp = Number(exp);\n return !Number.isNaN(numExp) && act === numExp;\n }\n if (typeof act === 'string' && typeof exp === 'number' && act.trim() !== '') {\n const numAct = Number(act);\n return !Number.isNaN(numAct) && numAct === exp;\n }\n // Handle boolean string coercion (\"true\" / \"false\")\n if (typeof act === 'boolean' && typeof exp === 'string') {\n return act === (exp.toLowerCase() === 'true');\n }\n if (typeof act === 'string' && typeof exp === 'boolean') {\n return (act.toLowerCase() === 'true') === exp;\n }\n return false;\n }\n\n case 'not_equals':\n return !evaluateOperator('equals', actual, expected, options);\n\n case 'is_truthy':\n if (Array.isArray(act)) {\n return act.length > 0;\n }\n if (act && typeof act === 'object') {\n return Object.keys(act as Record<string, unknown>).length > 0;\n }\n return Boolean(act);\n\n case 'is_falsy':\n return !evaluateOperator('is_truthy', actual, undefined, options);\n\n case 'is_empty':\n return isValueEmpty(actual);\n\n case 'is_not_empty':\n return !isValueEmpty(actual);\n\n case 'contains': {\n if (typeof act === 'string') {\n const needle = options?.caseInsensitive && typeof exp === 'string' ? exp : String(exp ?? '');\n return act.includes(needle);\n }\n if (Array.isArray(act)) {\n if (options?.caseInsensitive && typeof exp === 'string') {\n return act.some((item) => typeof item === 'string' && item.toLowerCase() === exp);\n }\n return act.includes(exp);\n }\n if (act && typeof act === 'object') {\n return exp !== undefined && String(exp) in (act as Record<string, unknown>);\n }\n return false;\n }\n\n case 'not_contains':\n return !evaluateOperator('contains', actual, expected, options);\n\n case 'starts_with': {\n if (typeof act !== 'string') return false;\n const prefix = options?.caseInsensitive && typeof exp === 'string' ? exp : String(exp ?? '');\n return act.startsWith(prefix);\n }\n\n case 'ends_with': {\n if (typeof act !== 'string') return false;\n const suffix = options?.caseInsensitive && typeof exp === 'string' ? exp : String(exp ?? '');\n return act.endsWith(suffix);\n }\n\n case 'gt': {\n const actNum = Number(act);\n const expNum = Number(exp);\n return !Number.isNaN(actNum) && !Number.isNaN(expNum) && actNum > expNum;\n }\n\n case 'gte': {\n const actNum = Number(act);\n const expNum = Number(exp);\n return !Number.isNaN(actNum) && !Number.isNaN(expNum) && actNum >= expNum;\n }\n\n case 'lt': {\n const actNum = Number(act);\n const expNum = Number(exp);\n return !Number.isNaN(actNum) && !Number.isNaN(expNum) && actNum < expNum;\n }\n\n case 'lte': {\n const actNum = Number(act);\n const expNum = Number(exp);\n return !Number.isNaN(actNum) && !Number.isNaN(expNum) && actNum <= expNum;\n }\n\n case 'in': {\n if (Array.isArray(exp)) {\n if (options?.caseInsensitive && typeof act === 'string') {\n return exp.some((item) => typeof item === 'string' && item.toLowerCase() === act);\n }\n return exp.includes(act);\n }\n if (typeof exp === 'string') {\n return exp.includes(String(act ?? ''));\n }\n return false;\n }\n\n case 'not_in':\n return !evaluateOperator('in', actual, expected, options);\n\n case 'regex': {\n try {\n const patternStr = String(exp ?? '');\n const flags = options?.caseInsensitive ? 'i' : '';\n const regex = new RegExp(patternStr, flags);\n return regex.test(String(act ?? ''));\n } catch {\n return false;\n }\n }\n\n default:\n return true;\n }\n}\n\n/**\n * Resolves a field value from context and evaluates a single ActionStepCondition.\n */\nexport function evaluateCondition(\n condition: ActionStepCondition | undefined,\n context: Record<string, unknown>,\n options?: ConditionEvaluationOptions,\n): boolean {\n if (!condition) return true;\n\n const rawField = condition.field;\n if (!rawField || typeof rawField !== 'string') return true;\n\n // Clean template wrapper syntax `{{ path }}` if provided\n const fieldPath = rawField.replace(/^\\{\\{\\s*/, '').replace(/\\s*\\}\\}$/, '').trim();\n const actualValue = resolvePropertyPath(context, fieldPath, undefined);\n\n return evaluateOperator(condition.operator, actualValue, condition.value, options);\n}\n\n/**\n * Evaluates a ConditionGroup (AND / OR group with nested conditions).\n */\nexport function evaluateConditionGroup(\n group: ConditionGroup,\n context: Record<string, unknown>,\n options?: ConditionEvaluationOptions,\n): boolean {\n if (!group || !Array.isArray(group.conditions) || group.conditions.length === 0) {\n return true;\n }\n\n const combinator = group.combinator === 'or' ? 'or' : 'and';\n\n if (combinator === 'and') {\n return group.conditions.every((item) => {\n if (isConditionGroup(item)) {\n return evaluateConditionGroup(item, context, options);\n }\n return evaluateCondition(item, context, options);\n });\n }\n\n return group.conditions.some((item) => {\n if (isConditionGroup(item)) {\n return evaluateConditionGroup(item, context, options);\n }\n return evaluateCondition(item, context, options);\n });\n}\n\n/**\n * Evaluates a list of conditions and/or condition groups using a given combinator ('and' | 'or').\n */\nexport function evaluateConditions(\n conditions: (ActionStepCondition | ConditionGroup)[],\n context: Record<string, unknown>,\n combinator: 'and' | 'or' = 'and',\n options?: ConditionEvaluationOptions,\n): boolean {\n return evaluateConditionGroup({ combinator, conditions }, context, options);\n}\n\n","import type {\n ActionPipeline,\n ActionStep,\n ActionStepCondition,\n ActionStepType,\n} from '@kubuild/schema';\nimport { interpolateValue, resolvePropertyPath } from './interpolator';\nimport { evaluateCondition } from './conditional-resolver';\n\n/**\n * Execution context shared across action steps in a pipeline.\n */\nexport interface PipelineExecutionContext {\n form?: Record<string, unknown>;\n variables?: Record<string, unknown>;\n state?: Record<string, unknown>;\n response?: unknown;\n stepResults?: Record<string, StepExecutionResult>;\n error?: unknown;\n lastError?: unknown;\n nodeId?: string;\n document?: unknown;\n [key: string]: unknown;\n}\n\n/**\n * Status of an individual step execution.\n */\nexport type StepExecutionStatus = 'success' | 'error' | 'skipped' | 'cancelled';\n\n/**\n * Result of executing an individual action step.\n */\nexport interface StepExecutionResult {\n stepId: string;\n stepType: ActionStepType | string;\n status: StepExecutionStatus;\n data?: unknown;\n error?: Error | unknown;\n durationMs: number;\n subResults?: StepExecutionResult[];\n}\n\n/**\n * Overall result of executing an action pipeline.\n */\nexport interface PipelineExecutionResult {\n pipelineId: string;\n success: boolean;\n status: 'completed' | 'failed' | 'cancelled';\n stepResults: StepExecutionResult[];\n context: PipelineExecutionContext;\n error?: Error | unknown;\n durationMs: number;\n}\n\n/**\n * Handler function signature for an individual step type.\n */\nexport type PipelineStepHandler<TContext = PipelineExecutionContext> = (\n step: ActionStep,\n context: TContext,\n signal: AbortSignal,\n) => Promise<unknown> | unknown;\n\n/**\n * Options for configuring the execution of an action pipeline.\n */\nexport interface ExecutePipelineOptions {\n context?: PipelineExecutionContext;\n signal?: AbortSignal;\n timeout?: number;\n throwOnError?: boolean;\n handlers?: Record<string, PipelineStepHandler>;\n onStepStart?: (step: ActionStep, context: PipelineExecutionContext) => void;\n onStepComplete?: (\n step: ActionStep,\n result: StepExecutionResult,\n context: PipelineExecutionContext,\n ) => void;\n}\n\n/**\n * Configuration options for creating an ActionPipelineExecutor instance.\n */\nexport interface ActionPipelineExecutorOptions {\n handlers?: Record<string, PipelineStepHandler>;\n defaultTimeout?: number;\n throwOnError?: boolean;\n}\n\n/**\n * Custom error thrown when a step or pipeline times out.\n */\nexport class ActionTimeoutError extends Error {\n readonly stepId?: string;\n readonly timeoutMs: number;\n\n constructor(message: string, timeoutMs: number, stepId?: string) {\n super(message);\n this.name = 'ActionTimeoutError';\n this.timeoutMs = timeoutMs;\n this.stepId = stepId;\n }\n}\n\n/**\n * Custom error thrown when an action execution is aborted/cancelled.\n */\nexport class ActionCancellationError extends Error {\n readonly stepId?: string;\n\n constructor(message: string = 'Action execution cancelled', stepId?: string) {\n super(message);\n this.name = 'ActionCancellationError';\n this.stepId = stepId;\n }\n}\n\n/**\n * Evaluates an ActionStepCondition against a pipeline execution context.\n */\nexport function evaluateActionCondition(\n condition: ActionStepCondition | undefined,\n context: PipelineExecutionContext,\n): boolean {\n return evaluateCondition(condition, context);\n}\n\n/**\n * Normalizes an abort reason into an ActionTimeoutError or ActionCancellationError.\n */\nfunction normalizeAbortError(reason: unknown, stepId?: string): Error {\n if (reason instanceof ActionTimeoutError) {\n return reason;\n }\n if (reason instanceof ActionCancellationError) {\n return reason;\n }\n const msg = reason instanceof Error ? reason.message : 'Action execution cancelled';\n return new ActionCancellationError(msg, stepId);\n}\n\n/**\n * Creates a combined abort controller that aborts when either parent signal triggers or timeout fires.\n */\nfunction createTimeoutAbortSignal(\n parentSignal?: AbortSignal,\n timeoutMs?: number,\n timeoutMessage?: string,\n stepId?: string,\n): { signal: AbortSignal; cleanup: () => void } {\n const controller = new AbortController();\n let timerId: ReturnType<typeof setTimeout> | undefined;\n\n const onParentAbort = () => {\n controller.abort(normalizeAbortError(parentSignal?.reason, stepId));\n };\n\n if (parentSignal) {\n if (parentSignal.aborted) {\n onParentAbort();\n } else {\n parentSignal.addEventListener('abort', onParentAbort, { once: true });\n }\n }\n\n if (timeoutMs !== undefined && timeoutMs > 0) {\n timerId = setTimeout(() => {\n controller.abort(\n new ActionTimeoutError(\n timeoutMessage || `Action execution timed out after ${timeoutMs}ms`,\n timeoutMs,\n stepId,\n ),\n );\n }, timeoutMs);\n }\n\n const cleanup = () => {\n if (timerId !== undefined) {\n clearTimeout(timerId);\n }\n if (parentSignal) {\n parentSignal.removeEventListener('abort', onParentAbort);\n }\n };\n\n return { signal: controller.signal, cleanup };\n}\n\n/**\n * ActionPipelineExecutor manages step handlers, sequential execution of action pipelines,\n * timeouts, cancellation, conditional evaluation, and onSuccess / onError branching.\n */\nexport class ActionPipelineExecutor {\n private handlers = new Map<string, PipelineStepHandler>();\n private defaultTimeout?: number;\n private throwOnError: boolean;\n\n constructor(options?: ActionPipelineExecutorOptions) {\n this.defaultTimeout = options?.defaultTimeout;\n this.throwOnError = options?.throwOnError ?? false;\n\n // Register built-in default handlers\n this.registerBuiltInHandlers();\n\n // Register user-provided handlers\n if (options?.handlers) {\n for (const [type, handler] of Object.entries(options.handlers)) {\n this.registerHandler(type, handler);\n }\n }\n }\n\n /**\n * Registers default built-in handlers for core step types like `set_state` and `reset_form`.\n */\n private registerBuiltInHandlers(): void {\n // 1. set_state: Updates runtime state or variables\n this.registerHandler('set_state', (step, context) => {\n const key = String(step.payload?.key || '');\n const value = step.payload?.value;\n const scope = String(step.payload?.scope || 'runtime');\n\n if (!key) return;\n\n if (!context.state) context.state = {};\n if (!context.variables) context.variables = {};\n\n if (scope === 'runtime' || scope === 'document') {\n context.state[key] = value;\n context.variables[key] = value;\n } else {\n context.state[key] = value;\n }\n\n return { key, value, scope };\n });\n\n // 2. reset_form: Clears/resets form inputs\n this.registerHandler('reset_form', (_step, context) => {\n if (context.form && typeof context.form === 'object') {\n for (const k of Object.keys(context.form)) {\n context.form[k] = '';\n }\n }\n return { reset: true };\n });\n }\n\n /**\n * Registers a handler for a step type.\n */\n public registerHandler(type: ActionStepType | string, handler: PipelineStepHandler): this {\n this.handlers.set(type, handler);\n return this;\n }\n\n /**\n * Unregisters a handler for a step type.\n */\n public unregisterHandler(type: ActionStepType | string): this {\n this.handlers.delete(type);\n return this;\n }\n\n /**\n * Checks if a handler exists for a step type.\n */\n public hasHandler(type: ActionStepType | string): boolean {\n return this.handlers.has(type);\n }\n\n /**\n * Gets the registered handler for a step type.\n */\n public getHandler(type: ActionStepType | string): PipelineStepHandler | undefined {\n return this.handlers.get(type);\n }\n\n /**\n * Executes a full ActionPipeline sequentially with support for timeouts, cancellation,\n * condition evaluation, and branching.\n */\n public async execute(\n pipeline: ActionPipeline,\n options?: ExecutePipelineOptions,\n ): Promise<PipelineExecutionResult> {\n const startTime = Date.now();\n const context: PipelineExecutionContext = options?.context ?? {};\n\n if (!context.variables) context.variables = {};\n if (!context.state) context.state = {};\n if (!context.form) context.form = {};\n if (!context.stepResults) context.stepResults = {};\n\n const timeoutMs = options?.timeout ?? this.defaultTimeout;\n const { signal, cleanup } = createTimeoutAbortSignal(\n options?.signal,\n timeoutMs,\n `Pipeline \"${pipeline.id}\" timed out after ${timeoutMs}ms`,\n );\n\n let pipelineStatus: 'completed' | 'failed' | 'cancelled' = 'completed';\n let pipelineError: Error | unknown = undefined;\n const allStepResults: StepExecutionResult[] = [];\n\n try {\n if (pipeline.enabled === false) {\n return {\n pipelineId: pipeline.id,\n success: true,\n status: 'completed',\n stepResults: [],\n context,\n durationMs: Date.now() - startTime,\n };\n }\n\n const { success, results, error } = await this.executeSteps(\n pipeline.steps,\n context,\n signal,\n options,\n );\n\n allStepResults.push(...results);\n\n if (!success) {\n pipelineStatus = signal.aborted ? 'cancelled' : 'failed';\n pipelineError = error;\n }\n } catch (err: unknown) {\n pipelineStatus = signal.aborted ? 'cancelled' : 'failed';\n pipelineError = err;\n } finally {\n cleanup();\n }\n\n const isSuccess = pipelineStatus === 'completed';\n const result: PipelineExecutionResult = {\n pipelineId: pipeline.id,\n success: isSuccess,\n status: pipelineStatus,\n stepResults: allStepResults,\n context,\n error: pipelineError,\n durationMs: Date.now() - startTime,\n };\n\n const shouldThrow = options?.throwOnError ?? this.throwOnError;\n if (!isSuccess && shouldThrow) {\n throw pipelineError || new Error(`Action pipeline \"${pipeline.id}\" failed`);\n }\n\n return result;\n }\n\n /**\n * Executes an ordered list of ActionSteps sequentially.\n */\n private async executeSteps(\n steps: ActionStep[],\n context: PipelineExecutionContext,\n parentSignal: AbortSignal,\n options?: ExecutePipelineOptions,\n ): Promise<{ success: boolean; results: StepExecutionResult[]; error?: Error | unknown }> {\n const results: StepExecutionResult[] = [];\n\n for (const step of steps) {\n if (parentSignal.aborted) {\n const cancelError = normalizeAbortError(parentSignal.reason, step.id);\n\n const cancelledResult: StepExecutionResult = {\n stepId: step.id,\n stepType: step.type,\n status: 'cancelled',\n error: cancelError,\n durationMs: 0,\n };\n results.push(cancelledResult);\n context.stepResults![step.id] = cancelledResult;\n\n return { success: false, results, error: cancelError };\n }\n\n const stepResult = await this.executeSingleStep(step, context, parentSignal, options);\n results.push(stepResult);\n context.stepResults![step.id] = stepResult;\n\n if (stepResult.status === 'error' || stepResult.status === 'cancelled') {\n if (!step.continueOnError) {\n return { success: false, results, error: stepResult.error };\n }\n }\n }\n\n return { success: true, results };\n }\n\n /**\n * Executes a single ActionStep with condition checking, payload interpolation, timeout,\n * handler execution, response context passing, and branch execution.\n */\n public async executeSingleStep(\n step: ActionStep,\n context: PipelineExecutionContext,\n parentSignal: AbortSignal,\n options?: ExecutePipelineOptions,\n ): Promise<StepExecutionResult> {\n const stepStartTime = Date.now();\n\n // 1. Evaluate condition\n if (step.condition && !evaluateActionCondition(step.condition, context)) {\n const skippedResult: StepExecutionResult = {\n stepId: step.id,\n stepType: step.type,\n status: 'skipped',\n durationMs: Date.now() - stepStartTime,\n };\n options?.onStepComplete?.(step, skippedResult, context);\n return skippedResult;\n }\n\n options?.onStepStart?.(step, context);\n\n // 2. Setup per-step timeout & signal\n const stepTimeout = step.timeout;\n const { signal: stepSignal, cleanup: cleanupStepSignal } = createTimeoutAbortSignal(\n parentSignal,\n stepTimeout,\n `Step \"${step.id}\" timed out after ${stepTimeout}ms`,\n step.id,\n );\n\n // 3. Interpolate payload with current context\n const rawPayload = step.payload || {};\n const interpolatedPayload = (interpolateValue(rawPayload, context) || {}) as Record<\n string,\n unknown\n >;\n const resolvedStep: ActionStep = {\n ...step,\n payload: interpolatedPayload,\n };\n\n // 4. Find handler\n const customHandler = options?.handlers?.[step.type];\n const handler = customHandler || this.getHandler(step.type);\n\n let stepOutput: unknown;\n let stepError: Error | unknown;\n let stepStatus: StepExecutionStatus = 'success';\n const subResults: StepExecutionResult[] = [];\n\n try {\n if (!handler) {\n throw new Error(`No handler registered for action step type: \"${step.type}\"`);\n }\n\n if (stepSignal.aborted) {\n throw normalizeAbortError(stepSignal.reason, step.id);\n }\n\n stepOutput = await handler(resolvedStep, context, stepSignal);\n\n // On successful execution: update context response (if returned) & response mapping\n if (stepOutput !== undefined) {\n context.response = stepOutput;\n }\n delete context.lastError;\n\n if (interpolatedPayload.responseMapping && typeof interpolatedPayload.responseMapping === 'object') {\n const mapping = interpolatedPayload.responseMapping as Record<string, string>;\n for (const [targetVar, sourcePath] of Object.entries(mapping)) {\n const evalContext = {\n ...context,\n response: stepOutput !== undefined ? stepOutput : context.response,\n };\n const cleanPath = String(sourcePath).replace(/^\\{\\{\\s*/, '').replace(/\\s*\\}\\}$/, '').trim();\n const mappedVal = resolvePropertyPath(evalContext, cleanPath, undefined);\n if (mappedVal !== undefined) {\n if (!context.variables) context.variables = {};\n context.variables[targetVar] = mappedVal;\n }\n }\n }\n\n // Execute onSuccess branching if defined\n if (step.onSuccess && Array.isArray(step.onSuccess) && step.onSuccess.length > 0) {\n const successBranch = await this.executeSteps(\n step.onSuccess,\n context,\n stepSignal,\n options,\n );\n subResults.push(...successBranch.results);\n\n if (!successBranch.success) {\n stepStatus = 'error';\n stepError = successBranch.error;\n }\n }\n } catch (err: unknown) {\n stepError = err;\n stepStatus = stepSignal.aborted ? 'cancelled' : 'error';\n context.lastError = err;\n context.error = err;\n\n // Execute onError branching if defined\n if (step.onError && Array.isArray(step.onError) && step.onError.length > 0) {\n try {\n const errorBranch = await this.executeSteps(\n step.onError,\n context,\n parentSignal, // Use parent signal so error branch can run even if step timed out\n options,\n );\n subResults.push(...errorBranch.results);\n } catch (onErrorErr) {\n // Keep original error as primary\n }\n }\n } finally {\n cleanupStepSignal();\n }\n\n const result: StepExecutionResult = {\n stepId: step.id,\n stepType: step.type,\n status: stepStatus,\n data: stepOutput,\n error: stepError,\n durationMs: Date.now() - stepStartTime,\n ...(subResults.length > 0 ? { subResults } : {}),\n };\n\n options?.onStepComplete?.(step, result, context);\n\n return result;\n }\n}\n\n/**\n * Convenience helper to execute an action pipeline using default or custom executor settings.\n */\nexport async function executeActionPipeline(\n pipeline: ActionPipeline,\n options?: ExecutePipelineOptions,\n): Promise<PipelineExecutionResult> {\n const executor = new ActionPipelineExecutor();\n return executor.execute(pipeline, options);\n}\n\n","import { resolvePropertyPath } from './interpolator';\n\n/**\n * Forbidden object keys to protect against prototype pollution.\n */\nconst FORBIDDEN_KEY_SEGMENTS = new Set(['__proto__', 'constructor', 'prototype']);\n\n/**\n * Standard form state structure managed inside the store.\n */\nexport interface FormState {\n values: Record<string, unknown>;\n errors: Record<string, string>;\n touched: Record<string, boolean>;\n isSubmitting: boolean;\n isValid: boolean;\n dirty: boolean;\n initialValues?: Record<string, unknown>;\n}\n\n/**\n * Root state managed by the RuntimeStateStore.\n */\nexport interface RuntimeStoreState {\n variables: Record<string, unknown>;\n forms: Record<string, FormState>;\n state: Record<string, unknown>;\n [key: string]: unknown;\n}\n\nexport type Unsubscribe = () => void;\nexport type StoreListener = (\n state: Readonly<RuntimeStoreState>,\n prevState: Readonly<RuntimeStoreState>,\n) => void;\nexport type KeyChangeListener<T = unknown> = (newValue: T, prevValue: T) => void;\nexport type PathChangeListener<T = unknown> = (newValue: T, prevValue: T) => void;\nexport type FormChangeListener = (newForm: FormState, prevForm?: FormState) => void;\n\n/**\n * Creates an initial clean FormState object.\n */\nexport function createDefaultFormState(initialValues?: Record<string, unknown>): FormState {\n const init = initialValues ? { ...initialValues } : {};\n return {\n values: { ...init },\n errors: {},\n touched: {},\n isSubmitting: false,\n isValid: true,\n dirty: false,\n initialValues: { ...init },\n };\n}\n\n/**\n * Deep clones an object safely.\n */\nfunction cloneState<T>(obj: T): T {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n if (Array.isArray(obj)) {\n return obj.map((item) => cloneState(item)) as unknown as T;\n }\n const copy: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj as Record<string, unknown>)) {\n if (!FORBIDDEN_KEY_SEGMENTS.has(k)) {\n copy[k] = cloneState(v);\n }\n }\n return copy as T;\n}\n\n/**\n * Sets a value at a nested dotted path on a target object.\n */\nfunction setNestedPath(target: Record<string, unknown>, path: string, value: unknown): boolean {\n if (!path || typeof path !== 'string' || !target || typeof target !== 'object') {\n return false;\n }\n\n const normalized = path.replace(/\\[(\\d+)\\]/g, '.$1');\n const segments = normalized.split('.').map((s) => s.trim()).filter(Boolean);\n\n if (segments.length === 0) return false;\n\n let current: Record<string, unknown> = target;\n\n for (let i = 0; i < segments.length - 1; i++) {\n const seg = segments[i];\n if (FORBIDDEN_KEY_SEGMENTS.has(seg)) return false;\n\n if (current[seg] === undefined || current[seg] === null || typeof current[seg] !== 'object') {\n current[seg] = {};\n }\n current = current[seg] as Record<string, unknown>;\n }\n\n const lastSeg = segments[segments.length - 1];\n if (FORBIDDEN_KEY_SEGMENTS.has(lastSeg)) return false;\n\n current[lastSeg] = value;\n return true;\n}\n\n/**\n * Deletes a value at a nested dotted path on a target object.\n */\nfunction deleteNestedPath(target: Record<string, unknown>, path: string): boolean {\n if (!path || typeof path !== 'string' || !target || typeof target !== 'object') {\n return false;\n }\n\n const normalized = path.replace(/\\[(\\d+)\\]/g, '.$1');\n const segments = normalized.split('.').map((s) => s.trim()).filter(Boolean);\n\n if (segments.length === 0) return false;\n\n let current: Record<string, unknown> = target;\n\n for (let i = 0; i < segments.length - 1; i++) {\n const seg = segments[i];\n if (FORBIDDEN_KEY_SEGMENTS.has(seg) || !(seg in current) || typeof current[seg] !== 'object') {\n return false;\n }\n current = current[seg] as Record<string, unknown>;\n }\n\n const lastSeg = segments[segments.length - 1];\n if (FORBIDDEN_KEY_SEGMENTS.has(lastSeg) || !(lastSeg in current)) {\n return false;\n }\n\n delete current[lastSeg];\n return true;\n}\n\n/**\n * Reactive State Store & Context Manager for form states and runtime variables.\n */\nexport class RuntimeStateStore {\n private state: RuntimeStoreState;\n private listeners = new Set<StoreListener>();\n private pathListeners = new Map<string, Set<PathChangeListener>>();\n private formListeners = new Map<string, Set<FormChangeListener>>();\n private isBatching = false;\n private batchOldState?: RuntimeStoreState;\n private isNotifying = false;\n\n constructor(initialState?: Partial<RuntimeStoreState>) {\n this.state = {\n variables: initialState?.variables ? { ...initialState.variables } : {},\n forms: initialState?.forms ? cloneState(initialState.forms) : {},\n state: initialState?.state ? { ...initialState.state } : {},\n ...initialState,\n };\n }\n\n /**\n * Retrieves a value at a specified path or the entire state snapshot.\n */\n public get<T = unknown>(path?: string, fallback?: T): T {\n if (!path || path.trim() === '') {\n return this.getSnapshot() as unknown as T;\n }\n const cleanPath = path.replace(/^\\{\\{\\s*/, '').replace(/\\s*\\}\\}$/, '').trim();\n const resolved = resolvePropertyPath(this.state, cleanPath, fallback);\n return resolved as T;\n }\n\n /**\n * Gets an immutable snapshot of the current state.\n */\n public getSnapshot(): RuntimeStoreState {\n return cloneState(this.state);\n }\n\n /**\n * Sets a value at a dotted path and notifies subscribers.\n */\n public set(path: string, value: unknown): this {\n if (!path) return this;\n\n const oldState = this.isBatching ? undefined : cloneState(this.state);\n const cleanPath = path.replace(/^\\{\\{\\s*/, '').replace(/\\s*\\}\\}$/, '').trim();\n\n const success = setNestedPath(this.state, cleanPath, value);\n if (!success) return this;\n\n if (!this.isBatching && oldState) {\n this.notifyChanges(oldState, this.state);\n }\n\n return this;\n }\n\n /**\n * Performs multiple updates atomically, triggering subscriber notifications once.\n */\n public setBatch(updates: Record<string, unknown>): this {\n if (!updates || typeof updates !== 'object') return this;\n\n const oldState = this.batchOldState || cloneState(this.state);\n this.isBatching = true;\n this.batchOldState = oldState;\n\n try {\n for (const [path, value] of Object.entries(updates)) {\n this.set(path, value);\n }\n } finally {\n this.isBatching = false;\n this.batchOldState = undefined;\n this.notifyChanges(oldState, this.state);\n }\n\n return this;\n }\n\n /**\n * Deletes a property at the specified path.\n */\n public delete(path: string): boolean {\n if (!path) return false;\n\n const oldState = this.isBatching ? undefined : cloneState(this.state);\n const cleanPath = path.replace(/^\\{\\{\\s*/, '').replace(/\\s*\\}\\}$/, '').trim();\n\n const deleted = deleteNestedPath(this.state, cleanPath);\n if (deleted && !this.isBatching && oldState) {\n this.notifyChanges(oldState, this.state);\n }\n\n return deleted;\n }\n\n /**\n * Resets the store state to an initial or clean state.\n */\n public reset(initialState?: Partial<RuntimeStoreState>): this {\n const oldState = cloneState(this.state);\n this.state = {\n variables: initialState?.variables ? { ...initialState.variables } : {},\n forms: initialState?.forms ? cloneState(initialState.forms) : {},\n state: initialState?.state ? { ...initialState.state } : {},\n ...initialState,\n };\n this.notifyChanges(oldState, this.state);\n return this;\n }\n\n /**\n * Subscribes a listener to any state changes.\n */\n public subscribe(listener: StoreListener): Unsubscribe {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n /**\n * Subscribes a listener to changes on a top-level key.\n */\n public subscribeKey<T = unknown>(key: string, listener: KeyChangeListener<T>): Unsubscribe {\n return this.subscribePath(key, listener as PathChangeListener);\n }\n\n /**\n * Subscribes a listener to changes at a specific dotted path.\n */\n public subscribePath<T = unknown>(path: string, listener: PathChangeListener<T>): Unsubscribe {\n const cleanPath = path.replace(/^\\{\\{\\s*/, '').replace(/\\s*\\}\\}$/, '').trim();\n if (!this.pathListeners.has(cleanPath)) {\n this.pathListeners.set(cleanPath, new Set());\n }\n const set = this.pathListeners.get(cleanPath)!;\n set.add(listener as PathChangeListener);\n\n return () => {\n set.delete(listener as PathChangeListener);\n if (set.size === 0) {\n this.pathListeners.delete(cleanPath);\n }\n };\n }\n\n /**\n * Subscribes a listener to changes of a specific form state.\n */\n public subscribeForm(formId: string, listener: FormChangeListener): Unsubscribe {\n if (!this.formListeners.has(formId)) {\n this.formListeners.set(formId, new Set());\n }\n const set = this.formListeners.get(formId)!;\n set.add(listener);\n\n return () => {\n set.delete(listener);\n if (set.size === 0) {\n this.formListeners.delete(formId);\n }\n };\n }\n\n /**\n * Notifies all relevant listeners when state changes.\n */\n private notifyChanges(oldState: RuntimeStoreState, newState: RuntimeStoreState): void {\n if (this.isNotifying) return;\n this.isNotifying = true;\n\n try {\n const readOnlyNew = Object.freeze(cloneState(newState));\n const readOnlyOld = Object.freeze(cloneState(oldState));\n\n // 1. Notify global listeners\n for (const listener of this.listeners) {\n try {\n listener(readOnlyNew, readOnlyOld);\n } catch {\n // Prevent listener errors from breaking other subscriptions\n }\n }\n\n // 2. Notify path listeners\n for (const [path, listeners] of this.pathListeners.entries()) {\n const oldVal = resolvePropertyPath(oldState, path, undefined);\n const newVal = resolvePropertyPath(newState, path, undefined);\n\n if (oldVal !== newVal) {\n for (const listener of listeners) {\n try {\n listener(newVal, oldVal);\n } catch {\n // Ignore subscriber errors\n }\n }\n }\n }\n\n // 3. Notify form listeners\n for (const [formId, listeners] of this.formListeners.entries()) {\n const oldForm = oldState.forms?.[formId];\n const newForm = newState.forms?.[formId];\n\n if (oldForm !== newForm) {\n for (const listener of listeners) {\n try {\n listener(newForm || createDefaultFormState(), oldForm);\n } catch {\n // Ignore subscriber errors\n }\n }\n }\n }\n } finally {\n this.isNotifying = false;\n }\n }\n\n // ==========================================\n // Form State Management Helpers\n // ==========================================\n\n /**\n * Retrieves the FormState for a formId, initializing default form state if not present.\n */\n public getForm(formId: string): FormState {\n if (!this.state.forms[formId]) {\n this.state.forms[formId] = createDefaultFormState();\n }\n return this.state.forms[formId];\n }\n\n /**\n * Updates a single field value in a form and marks dirty if changed from initial.\n */\n public setFormFieldValue(formId: string, fieldName: string, value: unknown): this {\n const form = this.getForm(formId);\n const oldValues = { ...form.values };\n form.values[fieldName] = value;\n\n // Check dirty state\n const initialVal = form.initialValues?.[fieldName];\n form.dirty = Object.keys(form.values).some((k) => form.values[k] !== form.initialValues?.[k]);\n\n this.set(`forms.${formId}.values.${fieldName}`, value);\n return this;\n }\n\n /**\n * Sets or clears an error for a form field.\n */\n public setFormFieldError(formId: string, fieldName: string, error: string | null): this {\n const form = this.getForm(formId);\n if (error) {\n form.errors[fieldName] = error;\n } else {\n delete form.errors[fieldName];\n }\n form.isValid = Object.keys(form.errors).length === 0;\n\n this.set(`forms.${formId}.errors`, { ...form.errors });\n this.set(`forms.${formId}.isValid`, form.isValid);\n return this;\n }\n\n /**\n * Marks a form field as touched (or untouched).\n */\n public setFormFieldTouched(formId: string, fieldName: string, touched: boolean = true): this {\n const form = this.getForm(formId);\n form.touched[fieldName] = touched;\n\n this.set(`forms.${formId}.touched.${fieldName}`, touched);\n return this;\n }\n\n /**\n * Updates multiple form errors simultaneously.\n */\n public setFormErrors(formId: string, errors: Record<string, string>): this {\n const form = this.getForm(formId);\n form.errors = { ...errors };\n form.isValid = Object.keys(errors).length === 0;\n\n this.set(`forms.${formId}.errors`, form.errors);\n this.set(`forms.${formId}.isValid`, form.isValid);\n return this;\n }\n\n /**\n * Sets multiple form field values simultaneously.\n */\n public setFormValues(\n formId: string,\n values: Record<string, unknown>,\n replace: boolean = false,\n ): this {\n const form = this.getForm(formId);\n form.values = replace ? { ...values } : { ...form.values, ...values };\n form.dirty = Object.keys(form.values).some((k) => form.values[k] !== form.initialValues?.[k]);\n\n this.set(`forms.${formId}.values`, { ...form.values });\n this.set(`forms.${formId}.dirty`, form.dirty);\n return this;\n }\n\n /**\n * Sets the submitting status of a form.\n */\n public setFormSubmitting(formId: string, isSubmitting: boolean): this {\n const form = this.getForm(formId);\n form.isSubmitting = isSubmitting;\n\n this.set(`forms.${formId}.isSubmitting`, isSubmitting);\n return this;\n }\n\n /**\n * Resets a form's values, errors, touched, and submitting state to defaults or specified values.\n */\n public resetForm(formId: string, initialValues?: Record<string, unknown>): this {\n const newFormState = createDefaultFormState(\n initialValues || this.state.forms[formId]?.initialValues,\n );\n this.set(`forms.${formId}`, newFormState);\n return this;\n }\n\n // ==========================================\n // Scoping & Isolation\n // ==========================================\n\n /**\n * Creates an isolated child scope store for a page or component container.\n */\n public createScope(scopeId: string, initialValues?: Record<string, unknown>): RuntimeStateStore {\n const scopedState: Partial<RuntimeStoreState> = {\n variables: { ...(initialValues || {}) },\n forms: {},\n state: {},\n };\n return new RuntimeStateStore(scopedState);\n }\n}\n\n/**\n * Factory function to create a new RuntimeStateStore instance.\n */\nexport function createRuntimeStore(initialState?: Partial<RuntimeStoreState>): RuntimeStateStore {\n return new RuntimeStateStore(initialState);\n}\n\n","import type {\n TrackingConfig,\n MetaTrackingProviderConfig,\n GoogleTrackingProviderConfig,\n TikTokTrackingProviderConfig,\n CustomTrackingProviderConfig,\n MetaTrackingSecrets,\n GoogleTrackingSecrets,\n TikTokTrackingSecrets,\n CustomTrackingSecrets,\n TrackingProviderSecrets,\n ServerTrackingProviderType,\n TrackEventProvider,\n} from '@kubuild/schema';\n\n/**\n * Reference passed to a host `TrackingSecretResolver`. `credentialId` comes from the trusted\n * tracking config (`providers.<provider>.credentialId`), never from an untrusted request.\n */\nexport interface TrackingSecretRef {\n provider: ServerTrackingProviderType;\n credentialId?: string;\n documentId?: string;\n}\n\n/**\n * Host-provided function that returns the secret material for one provider, or `null` when the\n * host has none. Implement it against any secret store (env vars, KMS, DB, Vault, ...).\n * A missing secret makes the provider be skipped with a reason — it never throws.\n */\nexport type TrackingSecretResolver = (\n ref: TrackingSecretRef,\n) => Promise<TrackingProviderSecrets | null | undefined> | TrackingProviderSecrets | null | undefined;\n\n/**\n * Normalized Server Tracking Event\n */\nexport interface ServerTrackingEvent {\n eventName: string;\n eventType?: 'standard' | 'custom';\n eventId?: string;\n eventTime?: number;\n eventSourceUrl?: string;\n actionSource?: 'website' | 'app' | 'system_generated';\n params?: Record<string, unknown>;\n userData?: {\n email?: string;\n phone?: string;\n firstName?: string;\n lastName?: string;\n gender?: string;\n dateOfBirth?: string;\n city?: string;\n state?: string;\n zip?: string;\n country?: string;\n clientIp?: string;\n clientUserAgent?: string;\n fbp?: string;\n fbc?: string;\n externalId?: string;\n [key: string]: unknown;\n };\n customData?: Record<string, unknown>;\n}\n\n/**\n * Result of a single provider delivery\n */\nexport interface TrackingDeliveryResult {\n provider: string;\n success: boolean;\n status?: number;\n data?: unknown;\n error?: string;\n skipped?: boolean;\n /** Why the provider was skipped (e.g. no secret resolved). */\n reason?: string;\n}\n\n/**\n * Aggregate result from dispatchServerTracking\n */\nexport interface ServerTrackingDispatchResult {\n success: boolean;\n eventId: string;\n skipped?: boolean;\n reason?: string;\n results: Record<string, TrackingDeliveryResult>;\n}\n\n/**\n * Options for configuring server tracking dispatch\n */\nexport interface ServerTrackingOptions {\n /**\n * Resolves provider secrets by `credentialId`. The ONLY way secrets reach the dispatcher —\n * the document never contains them. Without it, every server provider is skipped.\n */\n resolveSecrets?: TrackingSecretResolver;\n /** Host document id, forwarded to `resolveSecrets`. */\n documentId?: string;\n /** Restrict dispatch to one provider ('all' by default). 'gtm' is client-only. */\n provider?: TrackEventProvider;\n fetchFn?: typeof fetch;\n clientIp?: string;\n clientUserAgent?: string;\n sourceUrl?: string;\n simulateInDebug?: boolean;\n onLog?: (message: string, data?: unknown) => void;\n}\n\n/**\n * Normalizes an email string (lowercase, trim) according to Meta CAPI specification.\n */\nexport function normalizeEmail(email: string): string {\n return (email || '').trim().toLowerCase();\n}\n\n/**\n * Normalizes a phone number (removes non-digits, strips leading zeros if needed) per CAPI spec.\n */\nexport function normalizePhone(phone: string): string {\n return (phone || '').replace(/[^0-9]/g, '');\n}\n\n/**\n * Normalizes text names (trim, lowercase).\n */\nexport function normalizeText(text: string): string {\n return (text || '').trim().toLowerCase();\n}\n\n/**\n * Generates a SHA-256 hash formatted as a hex string.\n * Uses universal Web Crypto API (supported in Node 18+, Bun, Deno, and modern browsers).\n */\nexport async function hashSha256(value: string): Promise<string> {\n const normalized = (value || '').trim();\n if (!normalized) return '';\n\n if (typeof globalThis.crypto?.subtle?.digest === 'function') {\n const encoder = new TextEncoder();\n const data = encoder.encode(normalized);\n const hashBuffer = await globalThis.crypto.subtle.digest('SHA-256', data);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n return hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');\n }\n\n // Fallback for environments where crypto.subtle is not accessible\n throw new Error('Web Crypto API (crypto.subtle) is not available in current runtime environment.');\n}\n\n/**\n * Generates a unique deduplication event ID.\n */\nexport function generateTrackingEventId(prefix = 'evt'): string {\n const timestamp = Date.now().toString(36);\n const randomPart = Math.random().toString(36).substring(2, 10);\n return `${prefix}_${timestamp}_${randomPart}`;\n}\n\n/**\n * Dispatches an event to Meta Conversions API (CAPI).\n * Spec: https://developers.facebook.com/docs/marketing-api/conversions-api\n */\nexport async function sendMetaCapiEvent(\n event: ServerTrackingEvent,\n config: MetaTrackingProviderConfig,\n secrets: MetaTrackingSecrets | null | undefined,\n options?: ServerTrackingOptions,\n): Promise<TrackingDeliveryResult> {\n const fetcher = options?.fetchFn || globalThis.fetch;\n if (!config.pixelId) {\n return {\n provider: 'meta',\n success: false,\n error: 'Meta Pixel ID is missing',\n };\n }\n\n // Prepare hashed user data\n const rawUserData = event.userData || {};\n const hashedUserData: Record<string, unknown> = {};\n\n if (rawUserData.email) {\n hashedUserData.em = [await hashSha256(normalizeEmail(String(rawUserData.email)))];\n }\n if (rawUserData.phone) {\n hashedUserData.ph = [await hashSha256(normalizePhone(String(rawUserData.phone)))];\n }\n if (rawUserData.firstName) {\n hashedUserData.fn = [await hashSha256(normalizeText(String(rawUserData.firstName)))];\n }\n if (rawUserData.lastName) {\n hashedUserData.ln = [await hashSha256(normalizeText(String(rawUserData.lastName)))];\n }\n if (rawUserData.city) {\n hashedUserData.ct = [await hashSha256(normalizeText(String(rawUserData.city)))];\n }\n if (rawUserData.state) {\n hashedUserData.st = [await hashSha256(normalizeText(String(rawUserData.state)))];\n }\n if (rawUserData.zip) {\n hashedUserData.zp = [await hashSha256(normalizeText(String(rawUserData.zip)))];\n }\n if (rawUserData.country) {\n hashedUserData.country = [await hashSha256(normalizeText(String(rawUserData.country)))];\n }\n\n // Client IP & User Agent (unhashed per Meta spec)\n const clientIp = rawUserData.clientIp || options?.clientIp;\n if (clientIp) hashedUserData.client_ip_address = clientIp;\n\n const clientUserAgent = rawUserData.clientUserAgent || options?.clientUserAgent;\n if (clientUserAgent) hashedUserData.client_user_agent = clientUserAgent;\n\n if (rawUserData.fbp) hashedUserData.fbp = rawUserData.fbp;\n if (rawUserData.fbc) hashedUserData.fbc = rawUserData.fbc;\n if (rawUserData.externalId) {\n hashedUserData.external_id = [await hashSha256(String(rawUserData.externalId))];\n }\n\n const eventTime = event.eventTime || Math.floor(Date.now() / 1000);\n const eventSourceUrl = event.eventSourceUrl || options?.sourceUrl;\n\n const capiPayload: Record<string, unknown> = {\n data: [\n {\n event_name: event.eventName,\n event_time: eventTime,\n event_id: event.eventId,\n event_source_url: eventSourceUrl,\n action_source: event.actionSource || 'website',\n user_data: hashedUserData,\n custom_data: {\n ...(event.params || {}),\n ...(event.customData || {}),\n },\n },\n ],\n };\n\n if (config.testEventCode) {\n capiPayload.test_event_code = config.testEventCode;\n }\n\n if (options?.simulateInDebug) {\n options.onLog?.('[Meta CAPI SIMULATED]', capiPayload);\n return { provider: 'meta', success: true, data: { simulated: true, payload: capiPayload } };\n }\n\n try {\n const url = `https://graph.facebook.com/v19.0/${encodeURIComponent(config.pixelId)}/events`;\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n if (!secrets?.capiAccessToken) {\n return skippedResult('meta', 'No Meta CAPI access token resolved for this credential');\n }\n headers['Authorization'] = `Bearer ${secrets.capiAccessToken}`;\n\n const res = await fetcher(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(capiPayload),\n });\n\n const resJson = await res.json().catch(() => ({}));\n if (!res.ok) {\n return {\n provider: 'meta',\n success: false,\n status: res.status,\n error: (resJson as { error?: { message?: string } })?.error?.message || `HTTP ${res.status}`,\n data: resJson,\n };\n }\n\n return {\n provider: 'meta',\n success: true,\n status: res.status,\n data: resJson,\n };\n } catch (err: unknown) {\n return {\n provider: 'meta',\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n}\n\n/**\n * Dispatches an event to TikTok Events API.\n * Spec: https://business-api.tiktok.com/portal/docs\n */\nexport async function sendTikTokEventsApi(\n event: ServerTrackingEvent,\n config: TikTokTrackingProviderConfig,\n secrets: TikTokTrackingSecrets | null | undefined,\n options?: ServerTrackingOptions,\n): Promise<TrackingDeliveryResult> {\n const fetcher = options?.fetchFn || globalThis.fetch;\n if (!config.pixelId) {\n return { provider: 'tiktok', success: false, error: 'TikTok Pixel ID is missing' };\n }\n\n const rawUserData = event.userData || {};\n const user: Record<string, unknown> = {};\n\n if (rawUserData.email) {\n user.email = await hashSha256(normalizeEmail(String(rawUserData.email)));\n }\n if (rawUserData.phone) {\n user.phone_number = await hashSha256(normalizePhone(String(rawUserData.phone)));\n }\n if (rawUserData.clientIp || options?.clientIp) {\n user.ip = rawUserData.clientIp || options?.clientIp;\n }\n if (rawUserData.clientUserAgent || options?.clientUserAgent) {\n user.user_agent = rawUserData.clientUserAgent || options?.clientUserAgent;\n }\n\n const tiktokPayload: Record<string, unknown> = {\n event_source: 'web',\n event_source_id: config.pixelId,\n data: [\n {\n event: event.eventName,\n event_id: event.eventId,\n timestamp: new Date((event.eventTime ? event.eventTime * 1000 : Date.now())).toISOString(),\n user,\n properties: {\n ...(event.params || {}),\n ...(event.customData || {}),\n },\n page: {\n url: event.eventSourceUrl || options?.sourceUrl,\n },\n },\n ],\n };\n\n if (config.testEventCode) {\n tiktokPayload.test_event_code = config.testEventCode;\n }\n\n if (options?.simulateInDebug) {\n options.onLog?.('[TikTok Events API SIMULATED]', tiktokPayload);\n return { provider: 'tiktok', success: true, data: { simulated: true, payload: tiktokPayload } };\n }\n\n try {\n const url = 'https://business-api.tiktok.com/open_api/v1.3/event/track/';\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n if (!secrets?.accessToken) {\n return skippedResult('tiktok', 'No TikTok Events API access token resolved for this credential');\n }\n headers['Access-Token'] = secrets.accessToken;\n\n const res = await fetcher(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(tiktokPayload),\n });\n\n const resJson = await res.json().catch(() => ({}));\n if (!res.ok) {\n return {\n provider: 'tiktok',\n success: false,\n status: res.status,\n error: (resJson as { message?: string })?.message || `HTTP ${res.status}`,\n data: resJson,\n };\n }\n\n return { provider: 'tiktok', success: true, status: res.status, data: resJson };\n } catch (err: unknown) {\n return {\n provider: 'tiktok',\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n}\n\n/**\n * Dispatches an event to Google Analytics 4 Measurement Protocol.\n * Spec: https://developers.google.com/analytics/devguides/collection/protocol/ga4\n */\nexport async function sendGa4MeasurementEvent(\n event: ServerTrackingEvent,\n config: GoogleTrackingProviderConfig,\n secrets: GoogleTrackingSecrets | null | undefined,\n options?: ServerTrackingOptions,\n): Promise<TrackingDeliveryResult> {\n const fetcher = options?.fetchFn || globalThis.fetch;\n if (!config.measurementId) {\n return { provider: 'google', success: false, error: 'GA4 Measurement ID is missing' };\n }\n\n const clientId =\n (event.userData?.clientId as string | undefined) ||\n (event.userData?.externalId as string | undefined) ||\n 'anonymous_client';\n\n const ga4Payload = {\n client_id: clientId,\n events: [\n {\n name: event.eventName.toLowerCase().replace(/[^a-z0-9_]/g, '_'),\n params: {\n ...(event.params || {}),\n ...(event.customData || {}),\n event_id: event.eventId,\n },\n },\n ],\n };\n\n if (options?.simulateInDebug) {\n options.onLog?.('[GA4 Measurement Protocol SIMULATED]', ga4Payload);\n return { provider: 'google', success: true, data: { simulated: true, payload: ga4Payload } };\n }\n\n try {\n if (!secrets?.measurementProtocolSecret) {\n return skippedResult('google', 'No GA4 Measurement Protocol API secret resolved for this credential');\n }\n const url =\n `https://www.google-analytics.com/mp/collect?measurement_id=${encodeURIComponent(config.measurementId)}` +\n `&api_secret=${encodeURIComponent(secrets.measurementProtocolSecret)}`;\n\n const res = await fetcher(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(ga4Payload),\n });\n\n return {\n provider: 'google',\n success: res.ok,\n status: res.status,\n data: { status: res.status },\n };\n } catch (err: unknown) {\n return {\n provider: 'google',\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n}\n\n/**\n * Dispatches an event to a Custom Webhook.\n */\nexport async function sendCustomWebhookEvent(\n event: ServerTrackingEvent,\n _config: CustomTrackingProviderConfig,\n secrets: CustomTrackingSecrets | null | undefined,\n options?: ServerTrackingOptions,\n): Promise<TrackingDeliveryResult> {\n const fetcher = options?.fetchFn || globalThis.fetch;\n\n const webhookPayload = {\n event: event.eventName,\n eventId: event.eventId,\n timestamp: event.eventTime ? event.eventTime * 1000 : Date.now(),\n userData: event.userData,\n params: event.params,\n customData: event.customData,\n sourceUrl: event.eventSourceUrl || options?.sourceUrl,\n };\n\n if (options?.simulateInDebug) {\n options.onLog?.('[Custom Webhook SIMULATED]', webhookPayload);\n return { provider: 'custom', success: true, data: { simulated: true, payload: webhookPayload } };\n }\n\n if (!secrets?.endpointUrl) {\n return skippedResult('custom', 'No custom webhook destination resolved for this credential');\n }\n\n try {\n const res = await fetcher(secrets.endpointUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(secrets.headers || {}),\n },\n body: JSON.stringify(webhookPayload),\n });\n\n const resJson = await res.json().catch(() => ({}));\n return {\n provider: 'custom',\n success: res.ok,\n status: res.status,\n data: resJson,\n };\n } catch (err: unknown) {\n return {\n provider: 'custom',\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n}\n\n\nfunction skippedResult(provider: string, reason: string): TrackingDeliveryResult {\n return { provider, success: true, skipped: true, reason };\n}\n\ntype ProviderTask = {\n key: ServerTrackingProviderType;\n credentialId?: string;\n run: (secrets: TrackingProviderSecrets | null) => Promise<TrackingDeliveryResult>;\n};\n\n/**\n * High-Level Server Tracking Dispatcher (server-side only).\n *\n * Evaluates the master toggle, selects enabled server providers, resolves each provider's\n * secrets through `options.resolveSecrets` (keyed by the `credentialId` in the trusted\n * config) and dispatches in parallel. A provider without a resolved secret is skipped with a\n * `reason` — this function never throws for missing secrets.\n *\n * Never call this from the browser: the renderer posts to a host relay instead\n * (see `createTrackingRelayHandler`).\n */\nexport async function dispatchServerTracking(\n event: ServerTrackingEvent,\n config?: TrackingConfig,\n options?: ServerTrackingOptions,\n): Promise<ServerTrackingDispatchResult> {\n const eventId = event.eventId || generateTrackingEventId();\n const eventWithId: ServerTrackingEvent = { ...event, eventId };\n\n // 1. Dynamic master toggle check: if tracking is disabled, cleanly return without any network activity\n if (!config || config.enabled === false) {\n return {\n success: true,\n eventId,\n skipped: true,\n reason: 'Tracking is disabled globally',\n results: {},\n };\n }\n\n const isDebug = Boolean(config.debugMode);\n const simulate = isDebug && options?.simulateInDebug !== false;\n\n const mergedOptions: ServerTrackingOptions = {\n ...options,\n simulateInDebug: simulate,\n onLog: (msg, data) => {\n if (isDebug) {\n // eslint-disable-next-line no-console\n console.log(`[KUBUILD Tracking] ${msg}`, data || '');\n }\n options?.onLog?.(msg, data);\n },\n };\n\n const target = options?.provider || 'all';\n const wants = (key: ServerTrackingProviderType) => target === 'all' || target === key;\n const providers = config.providers || {};\n const tasks: ProviderTask[] = [];\n\n const meta = providers.meta;\n if (wants('meta') && meta && meta.enabled !== false && meta.capiEnabled) {\n tasks.push({\n key: 'meta',\n credentialId: meta.credentialId,\n run: (s) => sendMetaCapiEvent(eventWithId, meta, s as MetaTrackingSecrets | null, mergedOptions),\n });\n }\n\n const tiktok = providers.tiktok;\n if (wants('tiktok') && tiktok && tiktok.enabled !== false && tiktok.eventsApiEnabled) {\n tasks.push({\n key: 'tiktok',\n credentialId: tiktok.credentialId,\n run: (s) => sendTikTokEventsApi(eventWithId, tiktok, s as TikTokTrackingSecrets | null, mergedOptions),\n });\n }\n\n const google = providers.google;\n if (wants('google') && google && google.enabled !== false && google.measurementId) {\n tasks.push({\n key: 'google',\n credentialId: google.credentialId,\n run: (s) => sendGa4MeasurementEvent(eventWithId, google, s as GoogleTrackingSecrets | null, mergedOptions),\n });\n }\n\n const custom = providers.custom;\n if (wants('custom') && custom && custom.enabled !== false) {\n tasks.push({\n key: 'custom',\n credentialId: custom.credentialId,\n run: (s) => sendCustomWebhookEvent(eventWithId, custom, s as CustomTrackingSecrets | null, mergedOptions),\n });\n }\n\n if (tasks.length === 0) {\n return {\n success: true,\n eventId,\n skipped: true,\n reason:\n target === 'gtm'\n ? 'GTM is client-side only (dataLayer); no server delivery'\n : 'No server-side tracking provider is enabled',\n results: {},\n };\n }\n\n const resolve = options?.resolveSecrets;\n\n const runTask = async (task: ProviderTask): Promise<TrackingDeliveryResult> => {\n let secrets: TrackingProviderSecrets | null = null;\n if (resolve) {\n try {\n secrets =\n (await resolve({ provider: task.key, credentialId: task.credentialId, documentId: options?.documentId })) ??\n null;\n } catch (err: unknown) {\n return {\n provider: task.key,\n success: false,\n error: `Secret resolution failed: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n }\n\n // In debug simulation we still build the payload (no network), even without secrets.\n if (!secrets && !simulate) {\n const reason = resolve\n ? `No secret resolved for provider \"${task.key}\"${task.credentialId ? ` (credentialId \"${task.credentialId}\")` : ' (no credentialId linked)'}`\n : 'No secret resolver configured (options.resolveSecrets)';\n mergedOptions.onLog?.(`[${task.key}] skipped: ${reason}`);\n return skippedResult(task.key, reason);\n }\n\n return task.run(secrets);\n };\n\n const settled = await Promise.allSettled(tasks.map((task) => runTask(task)));\n const results: Record<string, TrackingDeliveryResult> = {};\n let overallSuccess = true;\n let delivered = 0;\n\n settled.forEach((item, index) => {\n const key = tasks[index].key;\n if (item.status === 'fulfilled') {\n results[key] = item.value;\n if (!item.value.success) overallSuccess = false;\n if (!item.value.skipped) delivered++;\n } else {\n overallSuccess = false;\n results[key] = {\n provider: key,\n success: false,\n error: item.reason instanceof Error ? item.reason.message : String(item.reason),\n };\n }\n });\n\n const allSkipped = delivered === 0 && overallSuccess;\n\n return {\n success: overallSuccess,\n eventId,\n ...(allSkipped ? { skipped: true, reason: 'All server providers were skipped' } : {}),\n results,\n };\n}\n","import {\n TRACKING_RELAY_PROTOCOL_VERSION,\n TrackingRelayRequestSchema,\n type TrackingConfig,\n type TrackEventProvider,\n type TrackingRelayErrorCode,\n type TrackingRelayProviderResult,\n type TrackingRelayRequest,\n type TrackingRelayResponse,\n} from '@kubuild/schema';\nimport {\n dispatchServerTracking,\n type ServerTrackingEvent,\n type TrackingSecretResolver,\n} from './server-tracking';\n\n/** Context handed to `getConfig` — use it to look up the trusted config for this page. */\nexport interface TrackingRelayConfigContext {\n request: Request;\n /** Untrusted hint from the request body; use it only as a lookup key you authorize. */\n documentId?: string;\n /** Untrusted hint from the request body. */\n credentialId?: string;\n provider: TrackEventProvider;\n}\n\nexport interface CreateTrackingRelayHandlerOptions {\n /**\n * Loads the tracking config from the HOST (database, published page, env, ...).\n * The relay never trusts a config sent in the request body. Return `null` if unknown.\n */\n getConfig: (\n ctx: TrackingRelayConfigContext,\n ) => Promise<TrackingConfig | null | undefined> | TrackingConfig | null | undefined;\n /** Resolves provider secrets by `credentialId` (from the trusted config). */\n resolveSecrets: TrackingSecretResolver;\n /**\n * Allowed browser origins. When set, requests whose `Origin` header is missing or not in\n * the list are rejected with 403, and CORS headers are returned for allowed origins.\n */\n allowedOrigins?: readonly string[] | ((origin: string) => boolean);\n fetchFn?: typeof fetch;\n /** Override client IP extraction (defaults to x-forwarded-for / x-real-ip / cf-connecting-ip). */\n getClientIp?: (request: Request) => string | undefined;\n /** Max accepted body size in bytes (default 64 KiB). */\n maxBodyBytes?: number;\n onLog?: (message: string, data?: unknown) => void;\n}\n\nconst DEFAULT_MAX_BODY_BYTES = 64 * 1024;\n\nfunction defaultClientIp(request: Request): string | undefined {\n const forwarded = request.headers.get('x-forwarded-for');\n if (forwarded) {\n const first = forwarded.split(',')[0]?.trim();\n if (first) return first;\n }\n return (\n request.headers.get('cf-connecting-ip')?.trim() ||\n request.headers.get('x-real-ip')?.trim() ||\n undefined\n );\n}\n\nfunction isOriginAllowed(\n origin: string | null,\n allowed: CreateTrackingRelayHandlerOptions['allowedOrigins'],\n): boolean {\n if (!allowed) return true;\n if (!origin) return false;\n if (typeof allowed === 'function') return allowed(origin);\n return allowed.includes(origin);\n}\n\n/**\n * Creates a reference tracking relay endpoint using only Web-standard `Request`/`Response`\n * (works in Next.js route handlers, Hono, Bun, Deno, Cloudflare Workers, Node 18+ adapters).\n *\n * Flow: validate origin -> validate body with `TrackingRelayRequestSchema` -> load the trusted\n * config via `getConfig` -> attach client IP / UA from request headers -> `dispatchServerTracking`\n * with `resolveSecrets`. The response follows `TrackingRelayResponseSchema` and never echoes\n * provider response bodies.\n *\n * Non-JS backends can implement the same protocol — see `getTrackingRelayRequestJsonSchema()`.\n */\nexport function createTrackingRelayHandler(options: CreateTrackingRelayHandlerOptions) {\n const maxBodyBytes = options.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES;\n\n return async (request: Request): Promise<Response> => {\n const origin = request.headers.get('origin');\n const corsHeaders: Record<string, string> = {};\n if (options.allowedOrigins && origin && isOriginAllowed(origin, options.allowedOrigins)) {\n corsHeaders['Access-Control-Allow-Origin'] = origin;\n corsHeaders['Vary'] = 'Origin';\n }\n\n const json = (body: TrackingRelayResponse, status: number, extra?: Record<string, string>) =>\n new Response(JSON.stringify(body), {\n status,\n headers: { 'Content-Type': 'application/json', ...corsHeaders, ...(extra || {}) },\n });\n\n const fail = (code: TrackingRelayErrorCode, message: string, status: number, extra?: Record<string, string>) =>\n json({ version: TRACKING_RELAY_PROTOCOL_VERSION, success: false, error: { code, message } }, status, extra);\n\n if (!isOriginAllowed(origin, options.allowedOrigins)) {\n return fail('FORBIDDEN_ORIGIN', 'Origin is not allowed', 403);\n }\n\n if (request.method === 'OPTIONS') {\n return new Response(null, {\n status: 204,\n headers: {\n ...corsHeaders,\n 'Access-Control-Allow-Methods': 'POST, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type',\n 'Access-Control-Max-Age': '600',\n },\n });\n }\n\n if (request.method !== 'POST') {\n return fail('METHOD_NOT_ALLOWED', 'Only POST requests are accepted', 405, { Allow: 'POST, OPTIONS' });\n }\n\n try {\n const text = await request.text();\n if (text.length > maxBodyBytes) {\n return fail('INVALID_REQUEST', `Request body exceeds ${maxBodyBytes} bytes`, 413);\n }\n\n let raw: unknown;\n try {\n raw = JSON.parse(text);\n } catch {\n return fail('INVALID_REQUEST', 'Request body must be valid JSON', 400);\n }\n\n if (\n raw &&\n typeof raw === 'object' &&\n 'version' in raw &&\n (raw as { version: unknown }).version !== TRACKING_RELAY_PROTOCOL_VERSION\n ) {\n return fail(\n 'UNSUPPORTED_VERSION',\n `Unsupported relay protocol version; expected ${TRACKING_RELAY_PROTOCOL_VERSION}`,\n 400,\n );\n }\n\n const parsed = TrackingRelayRequestSchema.safeParse(raw);\n if (!parsed.success) {\n const issues = parsed.error.issues\n .slice(0, 5)\n .map((i) => `${i.path.join('.') || '(root)'}: ${i.message}`)\n .join('; ');\n return fail('INVALID_REQUEST', `Invalid relay request: ${issues}`, 400);\n }\n const body: TrackingRelayRequest = parsed.data;\n\n // Trusted config comes from the host, never from the body.\n const config = await options.getConfig({\n request,\n documentId: body.documentId,\n credentialId: body.credentialId,\n provider: body.provider,\n });\n if (!config) {\n return fail('CONFIG_NOT_FOUND', 'No tracking configuration found for this page', 404);\n }\n\n const clientIp = (options.getClientIp ?? defaultClientIp)(request);\n const clientUserAgent = request.headers.get('user-agent') || undefined;\n\n // Client-supplied network identity is not trusted; use what the server observed.\n const userData = { ...(body.event.userData || {}) } as NonNullable<ServerTrackingEvent['userData']>;\n delete userData.clientIp;\n delete userData.clientUserAgent;\n\n const event: ServerTrackingEvent = { ...body.event, userData };\n\n const outcome = await dispatchServerTracking(event, config, {\n resolveSecrets: options.resolveSecrets,\n documentId: body.documentId,\n provider: body.provider,\n fetchFn: options.fetchFn,\n clientIp,\n clientUserAgent,\n onLog: options.onLog,\n });\n\n const results: Record<string, TrackingRelayProviderResult> = {};\n for (const [key, r] of Object.entries(outcome.results)) {\n results[key] = {\n provider: r.provider,\n success: r.success,\n ...(r.status !== undefined ? { status: r.status } : {}),\n ...(r.skipped ? { skipped: true } : {}),\n ...(r.reason ? { reason: r.reason } : {}),\n ...(r.error ? { error: r.error } : {}),\n };\n }\n\n return json(\n {\n version: TRACKING_RELAY_PROTOCOL_VERSION,\n success: outcome.success,\n eventId: outcome.eventId,\n ...(outcome.skipped ? { skipped: true } : {}),\n ...(outcome.reason ? { reason: outcome.reason } : {}),\n results,\n },\n 200,\n );\n } catch (err: unknown) {\n options.onLog?.('[Tracking relay] internal error', err);\n return fail('INTERNAL_ERROR', 'Tracking relay failed', 500);\n }\n };\n}\n","import { zipSync, strToU8 } from 'fflate';\nimport {\n PageDocument,\n DocumentMetadata,\n Manifest,\n ManifestAssetItem,\n SCHEMA_NAME,\n CURRENT_SCHEMA_VERSION,\n} from '@kubuild/schema';\nimport {\n validateDocument,\n DocumentValidationError,\n ValidationOptions,\n ComponentRegistryLike,\n} from '../validation/validator';\nimport {\n collectAssetReferences,\n extractRequirementsFromTree,\n CollectedAssetReference,\n} from '../document/document-utils';\nimport type { AssetProvider } from '../types/interfaces';\nimport { stripDocumentTrackingSecretsInPlace } from './tracking-sanitizer';\n\nexport interface ExportAssetData {\n data: Uint8Array | ArrayBuffer | Blob | string;\n mimeType?: string;\n filename?: string;\n}\n\nexport type AssetBytesProvider = (\n assetId: string,\n assetRef: CollectedAssetReference,\n) =>\n | Promise<Uint8Array | ArrayBuffer | Blob | string | ExportAssetData | null | undefined>\n | Uint8Array\n | ArrayBuffer\n | Blob\n | string\n | ExportAssetData\n | null\n | undefined;\n\nexport interface ExportPackageOptions {\n /**\n * Component registry to validate document components and extract requirements.\n */\n componentRegistry?: ComponentRegistryLike;\n\n /**\n * Known component types if registry is not passed.\n */\n knownComponentTypes?: string[] | Set<string>;\n\n /**\n * Directly supplied asset binary map (keyed by assetId).\n */\n assets?:\n | Record<string, Uint8Array | ArrayBuffer | Blob | string | ExportAssetData>\n | Map<string, Uint8Array | ArrayBuffer | Blob | string | ExportAssetData>;\n\n /**\n * Host function to retrieve asset binary data dynamically.\n */\n getAssetBytes?: AssetBytesProvider;\n\n /**\n * Host AssetProvider instance to resolve assets if bytes provider is not present.\n */\n assetProvider?: AssetProvider;\n\n /**\n * Package version to write in manifest (defaults to \"1.0.0\").\n */\n packageVersion?: string;\n\n /**\n * Builder compatibility semver range (defaults to \">=0.1.0\").\n */\n builderCompatibility?: string;\n\n /**\n * If true, assets that have a fallbackUrl or are externally hosted will not cause export failure if local bytes are missing.\n * If false and a referenced asset has no bytes available, export fails.\n */\n allowExternalFallback?: boolean;\n\n /**\n * Additional validation options passed to validateDocument.\n */\n validationOptions?: ValidationOptions;\n\n /**\n * Optional metadata overrides (e.g. author, tags).\n */\n metadata?: Partial<DocumentMetadata>;\n}\n\nexport interface ExportPackageSuccess {\n success: true;\n archive: Uint8Array;\n manifest: Manifest;\n page: PageDocument;\n metadata: DocumentMetadata;\n assetCount: number;\n}\n\nexport interface ExportPackageFailure {\n success: false;\n errors: DocumentValidationError[];\n diagnosticMessage: string;\n}\n\nexport type ExportPackageResult = ExportPackageSuccess | ExportPackageFailure;\n\n/**\n * Pure TypeScript SHA-256 implementation (zero native dependencies, deterministic).\n */\nexport function sha256Sync(data: Uint8Array): string {\n const K = [\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\n ];\n\n let h0 = 0x6a09e667;\n let h1 = 0xbb67ae85;\n let h2 = 0x3c6ef372;\n let h3 = 0xa54ff53a;\n let h4 = 0x510e527f;\n let h5 = 0x9b05688c;\n let h6 = 0x1f83d9ab;\n let h7 = 0x5be0cd19;\n\n const length = data.length;\n const bitLength = length * 8;\n const newLength = ((length + 9 + 63) >>> 6) << 6;\n const padded = new Uint8Array(newLength);\n padded.set(data);\n padded[length] = 0x80;\n\n const view = new DataView(padded.buffer);\n view.setUint32(newLength - 4, bitLength >>> 0, false);\n view.setUint32(newLength - 8, Math.floor(bitLength / 0x100000000), false);\n\n const w = new Uint32Array(64);\n\n for (let chunk = 0; chunk < newLength; chunk += 64) {\n for (let i = 0; i < 16; i++) {\n w[i] = view.getUint32(chunk + i * 4, false);\n }\n for (let i = 16; i < 64; i++) {\n const s0 =\n ((w[i - 15] >>> 7) | (w[i - 15] << 25)) ^\n ((w[i - 15] >>> 18) | (w[i - 15] << 14)) ^\n (w[i - 15] >>> 3);\n const s1 =\n ((w[i - 2] >>> 17) | (w[i - 2] << 15)) ^\n ((w[i - 2] >>> 19) | (w[i - 2] << 13)) ^\n (w[i - 2] >>> 10);\n w[i] = (w[i - 16] + s0 + w[i - 7] + s1) >>> 0;\n }\n\n let a = h0;\n let b = h1;\n let c = h2;\n let d = h3;\n let e = h4;\n let f = h5;\n let g = h6;\n let h = h7;\n\n for (let i = 0; i < 64; i++) {\n const S1 = ((e >>> 6) | (e << 26)) ^ ((e >>> 11) | (e << 21)) ^ ((e >>> 25) | (e << 7));\n const ch = (e & f) ^ (~e & g);\n const temp1 = (h + S1 + ch + K[i] + w[i]) >>> 0;\n const S0 = ((a >>> 2) | (a << 30)) ^ ((a >>> 13) | (a << 19)) ^ ((a >>> 22) | (a << 10));\n const maj = (a & b) ^ (a & c) ^ (b & c);\n const temp2 = (S0 + maj) >>> 0;\n\n h = g;\n g = f;\n f = e;\n e = (d + temp1) >>> 0;\n d = c;\n c = b;\n b = a;\n a = (temp1 + temp2) >>> 0;\n }\n\n h0 = (h0 + a) >>> 0;\n h1 = (h1 + b) >>> 0;\n h2 = (h2 + c) >>> 0;\n h3 = (h3 + d) >>> 0;\n h4 = (h4 + e) >>> 0;\n h5 = (h5 + f) >>> 0;\n h6 = (h6 + g) >>> 0;\n h7 = (h7 + h) >>> 0;\n }\n\n const result = [h0, h1, h2, h3, h4, h5, h6, h7]\n .map((val) => val.toString(16).padStart(8, '0'))\n .join('');\n\n return result;\n}\n\n/**\n * Compute SHA-256 checksum with \"sha256:\" prefix.\n */\nexport async function calculateChecksum(data: Uint8Array): Promise<string> {\n if (typeof globalThis !== 'undefined' && globalThis.crypto?.subtle?.digest) {\n try {\n const buffer = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength) as ArrayBuffer;\n const hashBuffer = await globalThis.crypto.subtle.digest('SHA-256', buffer);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');\n return `sha256:${hashHex}`;\n } catch {\n // fallback to sync implementation\n }\n }\n return `sha256:${sha256Sync(data)}`;\n}\n\n\n/**\n * Sanitize asset file names to prevent zip-slip or directory traversal vulnerabilities.\n */\nexport function sanitizeFilename(filename: string | undefined, assetId: string, mimeType?: string): string {\n let name = (filename || '').trim();\n\n // Strip path traversal characters and directory separators\n name = name.replace(/^[./\\\\]+/, '').replace(/[/\\\\]+/g, '_').replace(/\\0/g, '');\n name = name.replace(/[^a-zA-Z0-9._-]/g, '_');\n\n if (!name || name === '.' || name === '..') {\n const ext = getExtensionFromMime(mimeType) || 'bin';\n const cleanId = assetId.replace(/[^a-zA-Z0-9_-]/g, '_');\n name = `${cleanId}.${ext}`;\n }\n\n return name;\n}\n\nfunction getExtensionFromMime(mimeType?: string): string | null {\n if (!mimeType) return null;\n const m = mimeType.toLowerCase();\n if (m.includes('png')) return 'png';\n if (m.includes('jpeg') || m.includes('jpg')) return 'jpg';\n if (m.includes('webp')) return 'webp';\n if (m.includes('svg')) return 'svg';\n if (m.includes('gif')) return 'gif';\n if (m.includes('json')) return 'json';\n if (m.includes('pdf')) return 'pdf';\n if (m.includes('mp4')) return 'mp4';\n if (m.includes('mp3')) return 'mp3';\n return null;\n}\n\nasync function convertToUint8Array(input: unknown): Promise<Uint8Array | null> {\n if (!input) return null;\n\n if (input instanceof Uint8Array) {\n return input;\n }\n\n if (input instanceof ArrayBuffer) {\n return new Uint8Array(input);\n }\n\n if (typeof Blob !== 'undefined' && input instanceof Blob) {\n const arrayBuffer = await input.arrayBuffer();\n return new Uint8Array(arrayBuffer);\n }\n\n if (typeof input === 'string') {\n // Check if data URL\n if (input.startsWith('data:')) {\n const commaIdx = input.indexOf(',');\n if (commaIdx !== -1) {\n const meta = input.substring(0, commaIdx);\n const rawData = input.substring(commaIdx + 1);\n if (meta.includes(';base64')) {\n if (typeof atob === 'function') {\n const binary = atob(rawData);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n }\n }\n }\n }\n return new TextEncoder().encode(input);\n }\n\n return null;\n}\n\n/**\n * Validates document, collects asset references, resolves local asset bytes,\n * writes manifest.json, page.json, metadata.json, and packages everything into a .stora archive.\n */\nexport async function exportPackage(\n document: unknown,\n options: ExportPackageOptions = {},\n): Promise<ExportPackageResult> {\n // 1. Validate the Document\n const validation = validateDocument(document, {\n componentRegistry: options.componentRegistry,\n knownComponentTypes: options.knownComponentTypes,\n ...options.validationOptions,\n });\n\n if (!validation.valid || !validation.data) {\n const diagnosticMessage = `Document validation failed with ${validation.errors.length} error(s):\\n` +\n validation.errors.map((e) => `[${e.code}] ${e.path}: ${e.message}`).join('\\n');\n\n return {\n success: false,\n errors: validation.errors,\n diagnosticMessage,\n };\n }\n\n const pageDoc: PageDocument = JSON.parse(JSON.stringify(validation.data));\n // Defensive: a shareable .stora package must never carry tracking secrets.\n stripDocumentTrackingSecretsInPlace(pageDoc);\n\n // Merge optional metadata overrides safely\n if (options.metadata) {\n pageDoc.metadata = {\n ...(pageDoc.metadata || {\n title: 'Untitled Page',\n description: '',\n author: '',\n tags: [],\n category: 'general',\n version: '1.0.0',\n }),\n ...options.metadata,\n updatedAt: new Date().toISOString(),\n };\n }\n\n // 2. Collect Asset References from the document tree\n const collectedAssets = collectAssetReferences(pageDoc.document);\n const assetRefsById = new Map<string, CollectedAssetReference>();\n for (const item of collectedAssets) {\n if (!assetRefsById.has(item.assetId)) {\n assetRefsById.set(item.assetId, item);\n }\n }\n\n // 3. Extract Component and Capability Requirements\n const requirements = extractRequirementsFromTree(pageDoc.document, options.componentRegistry);\n\n // 4. Resolve Asset Bytes and build Manifest Assets\n const manifestAssets: ManifestAssetItem[] = [];\n const archiveFiles: Record<string, Uint8Array> = {};\n const assetCollectionErrors: DocumentValidationError[] = [];\n const usedArchivePaths = new Set<string>();\n\n for (const [assetId, assetRef] of assetRefsById.entries()) {\n let rawAsset: Uint8Array | ArrayBuffer | Blob | string | ExportAssetData | null | undefined;\n let customMime: string | undefined = assetRef.reference.mimeType;\n let customFilename: string | undefined = assetRef.reference.filename;\n\n // Check options.assets map/record\n if (options.assets) {\n if (options.assets instanceof Map) {\n rawAsset = options.assets.get(assetId);\n } else if (typeof options.assets === 'object' && assetId in options.assets) {\n rawAsset = options.assets[assetId];\n }\n }\n\n // Check options.getAssetBytes\n if (!rawAsset && options.getAssetBytes) {\n try {\n rawAsset = await options.getAssetBytes(assetId, assetRef);\n } catch (err) {\n assetCollectionErrors.push({\n code: 'INVALID_ASSET_REFERENCE',\n message: `Failed to retrieve asset bytes for \"${assetId}\": ${err instanceof Error ? err.message : String(err)}`,\n path: assetRef.propPath,\n nodeId: assetRef.nodeId,\n });\n continue;\n }\n }\n\n // Check options.assetProvider\n if (!rawAsset && options.assetProvider?.resolve) {\n try {\n const resolved = await options.assetProvider.resolve(assetId);\n if (resolved) {\n rawAsset = resolved;\n }\n } catch {\n // Continue to fallback check\n }\n }\n\n // Unpack ExportAssetData if provided\n let dataToConvert: unknown = rawAsset;\n if (rawAsset && typeof rawAsset === 'object' && 'data' in rawAsset) {\n const assetObj = rawAsset as ExportAssetData;\n dataToConvert = assetObj.data;\n if (assetObj.mimeType) customMime = assetObj.mimeType;\n if (assetObj.filename) customFilename = assetObj.filename;\n }\n\n const assetBytes = await convertToUint8Array(dataToConvert);\n\n if (assetBytes) {\n // Local asset found and collected\n const sanitizedName = sanitizeFilename(customFilename, assetId, customMime);\n let archivePath = `assets/${sanitizedName}`;\n\n // Avoid collision inside archive\n let counter = 1;\n while (usedArchivePaths.has(archivePath)) {\n const extDot = sanitizedName.lastIndexOf('.');\n if (extDot !== -1) {\n archivePath = `assets/${sanitizedName.substring(0, extDot)}_${counter}${sanitizedName.substring(extDot)}`;\n } else {\n archivePath = `assets/${sanitizedName}_${counter}`;\n }\n counter++;\n }\n usedArchivePaths.add(archivePath);\n\n const mimeType = customMime || 'application/octet-stream';\n const checksum = await calculateChecksum(assetBytes);\n\n manifestAssets.push({\n id: assetId,\n path: archivePath,\n mimeType,\n size: assetBytes.byteLength,\n checksum,\n });\n\n archiveFiles[archivePath] = assetBytes;\n } else {\n // Asset bytes not collected\n const isExternal = Boolean(assetRef.reference.fallbackUrl || options.allowExternalFallback);\n\n if (!isExternal) {\n assetCollectionErrors.push({\n code: 'INVALID_ASSET_REFERENCE',\n message: `Required asset \"${assetId}\" could not be collected for export and has no external fallback`,\n path: assetRef.propPath,\n nodeId: assetRef.nodeId,\n });\n }\n }\n }\n\n // If any required asset could not be collected, abort export\n if (assetCollectionErrors.length > 0) {\n const diagnosticMessage = `Asset collection failed with ${assetCollectionErrors.length} error(s):\\n` +\n assetCollectionErrors.map((e) => `[${e.code}] ${e.path}: ${e.message}`).join('\\n');\n\n return {\n success: false,\n errors: assetCollectionErrors,\n diagnosticMessage,\n };\n }\n\n // 5. Construct Manifest and Metadata\n const metadata: DocumentMetadata = pageDoc.metadata || {\n title: 'Untitled Page',\n description: '',\n author: '',\n tags: [],\n category: 'general',\n version: '1.0.0',\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n };\n\n const manifest: Manifest = {\n schema: SCHEMA_NAME,\n schemaVersion: pageDoc.version || CURRENT_SCHEMA_VERSION,\n packageVersion: options.packageVersion || '1.0.0',\n builderCompatibility: options.builderCompatibility || '>=0.1.0',\n requiredComponents: requirements.requiredComponents,\n requiredCapabilities: requirements.requiredCapabilities,\n assets: manifestAssets,\n createdAt: new Date().toISOString(),\n };\n\n // 6. Write Archive Files\n archiveFiles['manifest.json'] = strToU8(JSON.stringify(manifest, null, 2));\n archiveFiles['page.json'] = strToU8(JSON.stringify(pageDoc, null, 2));\n archiveFiles['metadata.json'] = strToU8(JSON.stringify(metadata, null, 2));\n\n // 7. Compress into .stora ZIP Archive\n const archive = zipSync(archiveFiles, { level: 6 });\n\n return {\n success: true,\n archive,\n manifest,\n page: pageDoc,\n metadata,\n assetCount: manifestAssets.length,\n };\n}\n\n/**\n * Alias for exportPackage.\n */\nexport const exportStoraPackage = exportPackage;\n","import {\n PageDocument,\n PageDocumentSchema,\n SCHEMA_NAME,\n} from '@kubuild/schema';\nimport {\n DocumentSecurityLimits,\n validateDocumentSecurity,\n} from './security';\n\nexport type DocumentValidationErrorCode =\n | 'GLOBAL_SCHEMA_INVALID'\n | 'ROOT_NODE_INVALID'\n | 'NODE_SHAPE_INVALID'\n | 'DUPLICATE_NODE_ID'\n | 'TREE_CYCLE_DETECTED'\n | 'UNKNOWN_COMPONENT_TYPE'\n | 'CHILD_POLICY_VIOLATION'\n | 'INVALID_ASSET_REFERENCE'\n | 'INVALID_VARIABLE_BINDING'\n | 'INVALID_ACTION_BINDING'\n | 'INVALID_METADATA'\n | 'PROTOTYPE_POLLUTION_DETECTED'\n | 'SECURITY_LIMIT_EXCEEDED';\n\nexport interface DocumentValidationError {\n code: DocumentValidationErrorCode;\n message: string;\n path: string;\n nodeId?: string;\n details?: Record<string, unknown>;\n}\n\nexport type DocumentValidationWarningCode =\n | 'CHILD_POLICY_VIOLATION'\n | 'UNKNOWN_COMPONENT_TYPE'\n | 'UNRESOLVED_ASSET_REFERENCE'\n | (string & {});\n\nexport interface DocumentValidationWarning {\n code: DocumentValidationWarningCode;\n message: string;\n path: string;\n nodeId?: string;\n details?: Record<string, unknown>;\n}\n\nexport interface ComponentDefinitionLike {\n type: string;\n category?: string;\n capabilities?: string[];\n acceptsChildren?: boolean;\n allowedChildren?: string[];\n disallowedParents?: string[];\n}\n\nexport interface ComponentRegistryLike {\n get(type: string): ComponentDefinitionLike | undefined;\n has(type: string): boolean;\n}\n\nexport interface ValidationOptions {\n componentRegistry?: ComponentRegistryLike;\n knownComponentTypes?: string[] | Set<string>;\n strictComponentTypes?: boolean;\n /**\n * Whether to treat child policy mismatches (e.g. allowedChildren) strictly as blocking errors.\n * If false or undefined (default), allowedChildren mismatches are emitted as non-blocking warnings.\n */\n strictChildPolicy?: boolean;\n /**\n * Validate asset references (`{ type: 'asset', assetId, fallbackUrl? }`) found in node props.\n * Checks that `assetId` is a non-empty string and `fallbackUrl` (if present) is a string.\n * When `knownAssetIds` is also supplied, every referenced `assetId` must be in that set.\n * Defaults to `true`.\n */\n checkAssetReferences?: boolean;\n /**\n * Known asset IDs used to verify that asset references resolve. A `PageDocument` carries\n * no asset registry of its own (assets live in the `.stora` manifest or the host's asset\n * provider), so this existence check only runs when the caller supplies the IDs.\n * An unresolved reference is an `INVALID_ASSET_REFERENCE` error, or a non-blocking\n * `UNRESOLVED_ASSET_REFERENCE` warning when the reference has a `fallbackUrl`.\n * Ignored when `checkAssetReferences` is `false`.\n */\n knownAssetIds?: string[] | Set<string>;\n /**\n * Validate variable bindings (`{ type: 'variable', key }`) in node props: `key` must be a\n * non-empty string. Defaults to `true`.\n */\n checkVariableBindings?: boolean;\n /**\n * Validate action bindings in node props (a prop named `action`, or any object with a string\n * `type` and a `payload`): `type` must be a non-empty string. Defaults to `true`.\n */\n checkActionBindings?: boolean;\n securityLimits?: DocumentSecurityLimits;\n}\n\nexport interface DocumentValidationResult {\n valid: boolean;\n success: boolean;\n errors: DocumentValidationError[];\n warnings: DocumentValidationWarning[];\n data?: PageDocument;\n}\n\n/**\n * Validate a page document against global schema, node shape, child policy,\n * ID uniqueness, cycles, unknown component types, and structural bindings.\n */\nexport function validateDocument(\n input: unknown,\n options: ValidationOptions = {},\n): DocumentValidationResult {\n const errors: DocumentValidationError[] = [];\n const warnings: DocumentValidationWarning[] = [];\n\n // 1. Basic Object check\n if (!input || typeof input !== 'object' || Array.isArray(input)) {\n return {\n valid: false,\n success: false,\n errors: [\n {\n code: 'GLOBAL_SCHEMA_INVALID',\n message: 'Document must be a valid non-null object',\n path: '',\n },\n ],\n warnings: [],\n };\n }\n\n const doc = input as Record<string, unknown>;\n\n // 1.5 Security Limits & Prototype Pollution Check\n const securityCheck = validateDocumentSecurity(doc, options.securityLimits);\n if (!securityCheck.safe) {\n for (const secErr of securityCheck.errors) {\n errors.push({\n code: secErr.code === 'PROTOTYPE_POLLUTION_DETECTED'\n ? 'PROTOTYPE_POLLUTION_DETECTED'\n : 'SECURITY_LIMIT_EXCEEDED',\n message: secErr.message,\n path: secErr.path || '',\n details: secErr.details,\n });\n }\n if (securityCheck.errors.some((e) => e.code === 'PROTOTYPE_POLLUTION_DETECTED')) {\n return {\n valid: false,\n success: false,\n errors,\n warnings: [],\n };\n }\n }\n\n // 2. Global Schema / Version / Document field checks\n if (doc.schema !== SCHEMA_NAME) {\n errors.push({\n code: 'GLOBAL_SCHEMA_INVALID',\n message: `Invalid schema identifier. Expected \"${SCHEMA_NAME}\", received \"${String(doc.schema)}\"`,\n path: '/schema',\n });\n }\n\n if (typeof doc.version !== 'string' || doc.version.trim().length === 0) {\n errors.push({\n code: 'GLOBAL_SCHEMA_INVALID',\n message: 'Schema version must be a non-empty string',\n path: '/version',\n });\n }\n\n if (!doc.document || typeof doc.document !== 'object' || Array.isArray(doc.document)) {\n errors.push({\n code: 'GLOBAL_SCHEMA_INVALID',\n message: 'Document must contain a root document node object',\n path: '/document',\n });\n return {\n valid: false,\n success: false,\n errors,\n warnings,\n };\n }\n\n const rootNode = doc.document as Record<string, unknown>;\n\n // 3. Root Node Type check (must be 'page')\n if (rootNode.type !== 'page') {\n errors.push({\n code: 'ROOT_NODE_INVALID',\n message: `Root node type must be \"page\", received \"${String(rootNode.type)}\"`,\n path: '/document/type',\n nodeId: typeof rootNode.id === 'string' ? rootNode.id : undefined,\n });\n }\n\n // 4. Metadata check\n if (doc.metadata !== undefined) {\n if (typeof doc.metadata !== 'object' || doc.metadata === null || Array.isArray(doc.metadata)) {\n errors.push({\n code: 'INVALID_METADATA',\n message: 'Document metadata must be an object',\n path: '/metadata',\n });\n } else {\n const meta = doc.metadata as Record<string, unknown>;\n if (meta.title !== undefined && (typeof meta.title !== 'string' || meta.title.trim().length === 0)) {\n errors.push({\n code: 'INVALID_METADATA',\n message: 'Metadata title must be a non-empty string when provided',\n path: '/metadata/title',\n });\n }\n }\n }\n\n // 5. Deep Recursive Node Tree Validation (Cycle, ID Uniqueness, Node Shape, Registry, Bindings)\n const seenIds = new Map<string, string>(); // nodeId -> path\n const visitedObjects = new Set<object>();\n\n validateNodeRecursive(\n rootNode,\n '/document',\n undefined,\n seenIds,\n visitedObjects,\n options,\n errors,\n warnings,\n );\n\n // 6. Schema Zod safe parse fallback to capture any missed structural issues\n if (errors.length === 0) {\n const zodResult = PageDocumentSchema.safeParse(input);\n if (!zodResult.success) {\n for (const issue of zodResult.error.issues) {\n const jsonPath = '/' + issue.path.join('/');\n errors.push({\n code: 'GLOBAL_SCHEMA_INVALID',\n message: issue.message,\n path: jsonPath === '/' ? '' : jsonPath,\n });\n }\n } else {\n return {\n valid: true,\n success: true,\n errors: [],\n warnings,\n data: zodResult.data as unknown as PageDocument,\n };\n }\n }\n\n return {\n valid: errors.length === 0,\n success: errors.length === 0,\n errors,\n warnings,\n };\n}\n\nfunction validateNodeRecursive(\n nodeObj: Record<string, unknown>,\n currentPath: string,\n parentNode: { id: string; type: string } | undefined,\n seenIds: Map<string, string>,\n visitedObjects: Set<object>,\n options: ValidationOptions,\n errors: DocumentValidationError[],\n warnings: DocumentValidationWarning[],\n): void {\n // Cycle Detection\n if (visitedObjects.has(nodeObj)) {\n errors.push({\n code: 'TREE_CYCLE_DETECTED',\n message: `Cyclic reference detected at node path ${currentPath}`,\n path: currentPath,\n nodeId: typeof nodeObj.id === 'string' ? nodeObj.id : undefined,\n });\n return;\n }\n visitedObjects.add(nodeObj);\n\n // Validate Node ID\n const nodeId = nodeObj.id;\n if (typeof nodeId !== 'string' || nodeId.trim().length === 0) {\n errors.push({\n code: 'NODE_SHAPE_INVALID',\n message: 'Node id must be a non-empty string',\n path: `${currentPath}/id`,\n });\n } else {\n if (seenIds.has(nodeId)) {\n errors.push({\n code: 'DUPLICATE_NODE_ID',\n message: `Duplicate node ID \"${nodeId}\" found at ${currentPath} (first seen at ${seenIds.get(nodeId)})`,\n path: `${currentPath}/id`,\n nodeId,\n details: { firstSeenAt: seenIds.get(nodeId) },\n });\n } else {\n seenIds.set(nodeId, currentPath);\n }\n }\n\n // Validate Node Type\n const nodeType = nodeObj.type;\n if (typeof nodeType !== 'string' || nodeType.trim().length === 0) {\n errors.push({\n code: 'NODE_SHAPE_INVALID',\n message: 'Node type must be a non-empty string',\n path: `${currentPath}/type`,\n nodeId: typeof nodeId === 'string' ? nodeId : undefined,\n });\n }\n\n const effectiveNodeId = typeof nodeId === 'string' ? nodeId : undefined;\n const effectiveNodeType = typeof nodeType === 'string' ? nodeType : '';\n\n // Validate against Component Registry or known types\n let componentDef: ComponentDefinitionLike | undefined;\n if (effectiveNodeType) {\n if (options.componentRegistry) {\n componentDef = options.componentRegistry.get(effectiveNodeType);\n if (!componentDef && (options.strictComponentTypes || !options.componentRegistry.has(effectiveNodeType))) {\n errors.push({\n code: 'UNKNOWN_COMPONENT_TYPE',\n message: `Unknown component type: \"${effectiveNodeType}\"`,\n path: `${currentPath}/type`,\n nodeId: effectiveNodeId,\n });\n }\n } else if (options.knownComponentTypes) {\n const isKnown = Array.isArray(options.knownComponentTypes)\n ? options.knownComponentTypes.includes(effectiveNodeType)\n : options.knownComponentTypes.has(effectiveNodeType);\n\n if (!isKnown && options.strictComponentTypes) {\n errors.push({\n code: 'UNKNOWN_COMPONENT_TYPE',\n message: `Unknown component type: \"${effectiveNodeType}\"`,\n path: `${currentPath}/type`,\n nodeId: effectiveNodeId,\n });\n }\n }\n }\n\n // Validate Child Policy\n const children = nodeObj.children;\n if (children !== undefined) {\n if (!Array.isArray(children)) {\n errors.push({\n code: 'NODE_SHAPE_INVALID',\n message: 'Node children must be an array',\n path: `${currentPath}/children`,\n nodeId: effectiveNodeId,\n });\n } else {\n if (componentDef && componentDef.acceptsChildren === false && children.length > 0) {\n errors.push({\n code: 'CHILD_POLICY_VIOLATION',\n message: `Component \"${effectiveNodeType}\" does not accept children, but found ${children.length} child node(s)`,\n path: `${currentPath}/children`,\n nodeId: effectiveNodeId,\n });\n }\n\n if (parentNode && componentDef?.disallowedParents?.includes(parentNode.type)) {\n errors.push({\n code: 'CHILD_POLICY_VIOLATION',\n message: `Component \"${effectiveNodeType}\" cannot be a child of \"${parentNode.type}\"`,\n path: currentPath,\n nodeId: effectiveNodeId,\n });\n }\n\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n const childPath = `${currentPath}/children/${i}`;\n\n if (!child || typeof child !== 'object' || Array.isArray(child)) {\n errors.push({\n code: 'NODE_SHAPE_INVALID',\n message: `Child at index ${i} must be a valid node object`,\n path: childPath,\n nodeId: effectiveNodeId,\n });\n continue;\n }\n\n const childRecord = child as Record<string, unknown>;\n const childType = typeof childRecord.type === 'string' ? childRecord.type : '';\n const childIsKnown = !options.componentRegistry || options.componentRegistry.has(childType);\n const childCategory = options.componentRegistry?.get(childType)?.category;\n\n if (\n componentDef?.allowedChildren &&\n childType &&\n childIsKnown &&\n !componentDef.allowedChildren.includes(childType) &&\n !componentDef.allowedChildren.includes('*') &&\n !(childCategory && componentDef.allowedChildren.includes(childCategory))\n ) {\n const violationMessage = `Component type \"${childType}\" is not allowed as a child of \"${effectiveNodeType}\". Allowed types: ${componentDef.allowedChildren.join(', ')}`;\n if (options.strictChildPolicy) {\n errors.push({\n code: 'CHILD_POLICY_VIOLATION',\n message: violationMessage,\n path: `${childPath}/type`,\n nodeId: typeof childRecord.id === 'string' ? childRecord.id : undefined,\n });\n } else {\n warnings.push({\n code: 'CHILD_POLICY_VIOLATION',\n message: violationMessage,\n path: `${childPath}/type`,\n nodeId: typeof childRecord.id === 'string' ? childRecord.id : undefined,\n });\n }\n }\n\n validateNodeRecursive(\n childRecord,\n childPath,\n { id: effectiveNodeId || '', type: effectiveNodeType },\n seenIds,\n visitedObjects,\n options,\n errors,\n warnings,\n );\n }\n }\n }\n\n // Validate Props and structural bindings (Assets, Variables, Actions)\n if (nodeObj.props !== undefined) {\n if (typeof nodeObj.props !== 'object' || nodeObj.props === null || Array.isArray(nodeObj.props)) {\n errors.push({\n code: 'NODE_SHAPE_INVALID',\n message: 'Node props must be an object',\n path: `${currentPath}/props`,\n nodeId: effectiveNodeId,\n });\n } else {\n validatePropsBindings(\n nodeObj.props as Record<string, unknown>,\n `${currentPath}/props`,\n effectiveNodeId,\n options,\n errors,\n warnings,\n );\n }\n }\n\n // Validate Styles\n if (nodeObj.styles !== undefined) {\n if (typeof nodeObj.styles !== 'object' || nodeObj.styles === null || Array.isArray(nodeObj.styles)) {\n errors.push({\n code: 'NODE_SHAPE_INVALID',\n message: 'Node styles must be an object',\n path: `${currentPath}/styles`,\n nodeId: effectiveNodeId,\n });\n }\n }\n}\n\n/**\n * Recursively inspect props object for structural bindings (asset, variable, action).\n * Each binding kind is gated by its `ValidationOptions` flag (all default to `true`).\n */\nfunction validatePropsBindings(\n propsObj: Record<string, unknown>,\n propsPath: string,\n nodeId: string | undefined,\n options: ValidationOptions,\n errors: DocumentValidationError[],\n warnings: DocumentValidationWarning[],\n): void {\n const checkAssets = options.checkAssetReferences !== false;\n const checkVariables = options.checkVariableBindings !== false;\n const checkActions = options.checkActionBindings !== false;\n\n for (const [key, value] of Object.entries(propsObj)) {\n const currentPath = `${propsPath}/${key}`;\n\n if (!value || typeof value !== 'object') {\n continue;\n }\n\n if (Array.isArray(value)) {\n value.forEach((item, index) => {\n if (item && typeof item === 'object' && !Array.isArray(item)) {\n validatePropsBindings(\n item as Record<string, unknown>,\n `${currentPath}/${index}`,\n nodeId,\n options,\n errors,\n warnings,\n );\n }\n });\n continue;\n }\n\n const record = value as Record<string, unknown>;\n\n // Check if it's an Asset Reference\n if (record.type === 'asset') {\n if (!checkAssets) continue;\n const assetId =\n typeof record.assetId === 'string' && record.assetId.trim().length > 0 ? record.assetId : undefined;\n if (assetId === undefined) {\n errors.push({\n code: 'INVALID_ASSET_REFERENCE',\n message: 'Asset reference must have a non-empty \"assetId\"',\n path: `${currentPath}/assetId`,\n nodeId,\n });\n }\n if (record.fallbackUrl !== undefined && typeof record.fallbackUrl !== 'string') {\n errors.push({\n code: 'INVALID_ASSET_REFERENCE',\n message: 'Asset fallbackUrl must be a string if provided',\n path: `${currentPath}/fallbackUrl`,\n nodeId,\n });\n }\n if (assetId !== undefined && options.knownAssetIds && !isKnownId(options.knownAssetIds, assetId)) {\n if (typeof record.fallbackUrl === 'string' && record.fallbackUrl.length > 0) {\n warnings.push({\n code: 'UNRESOLVED_ASSET_REFERENCE',\n message: `Asset \"${assetId}\" is not among the known assets; its fallbackUrl will be used`,\n path: `${currentPath}/assetId`,\n nodeId,\n details: { assetId },\n });\n } else {\n errors.push({\n code: 'INVALID_ASSET_REFERENCE',\n message: `Asset \"${assetId}\" is not among the known assets and has no fallbackUrl`,\n path: `${currentPath}/assetId`,\n nodeId,\n details: { assetId },\n });\n }\n }\n }\n // Check if it's a Variable Binding\n else if (record.type === 'variable') {\n if (!checkVariables) continue;\n if (typeof record.key !== 'string' || record.key.trim().length === 0) {\n errors.push({\n code: 'INVALID_VARIABLE_BINDING',\n message: 'Variable binding must have a non-empty \"key\"',\n path: `${currentPath}/key`,\n nodeId,\n });\n }\n }\n // Check if it's an Action Binding (either key is 'action' or has explicit action shape)\n else if (key === 'action' || (typeof record.type === 'string' && record.payload !== undefined)) {\n if (!checkActions) continue;\n if (typeof record.type !== 'string' || record.type.trim().length === 0) {\n errors.push({\n code: 'INVALID_ACTION_BINDING',\n message: 'Action binding must have a non-empty \"type\"',\n path: `${currentPath}/type`,\n nodeId,\n });\n }\n } else {\n // Recurse into nested objects\n validatePropsBindings(record, currentPath, nodeId, options, errors, warnings);\n }\n }\n}\n\nfunction isKnownId(ids: string[] | Set<string>, id: string): boolean {\n return Array.isArray(ids) ? ids.includes(id) : ids.has(id);\n}\n","/**\n * Security Limits and Sanitization Utilities for KUBUILD documents, assets, and actions.\n */\n\nexport interface DocumentSecurityLimits {\n /**\n * Maximum allowed total nodes in the document tree (default: 5000).\n */\n maxNodeCount?: number;\n\n /**\n * Maximum allowed nesting depth of nodes (default: 32).\n */\n maxTreeDepth?: number;\n\n /**\n * Maximum number of direct properties per node (default: 200).\n */\n maxPropsCount?: number;\n\n /**\n * Maximum character length for any individual string property (default: 100,000).\n */\n maxStringLength?: number;\n\n /**\n * Maximum number of direct children per node (default: 1000).\n */\n maxChildrenPerNode?: number;\n\n /**\n * Maximum allowed JSON serialized size in bytes (default: 10MB).\n */\n maxDocumentSizeBytes?: number;\n\n /**\n * Allowed URL schemes for links and media.\n * Default: ['http:', 'https:', 'mailto:', 'tel:', '#', 'relative', 'data:image/']\n */\n allowedUrlSchemes?: string[];\n\n /**\n * Prohibited property keys to defend against Prototype Pollution.\n * Default: ['__proto__', 'constructor', 'prototype', '__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__']\n */\n prohibitedPropertyKeys?: string[];\n\n /**\n * Prohibited asset file extensions to prevent executable uploads.\n * Default: ['.exe', '.dll', '.so', '.sh', '.bat', '.cmd', '.js', '.mjs', '.cjs', '.php', '.py', '.vbs', '.wasm', '.bin', '.com', '.scr', '.pif']\n */\n prohibitedAssetExtensions?: string[];\n\n /**\n * Maximum compression expansion ratio before flagging potential zip bomb (default: 100).\n */\n maxZipExpansionRatio?: number;\n}\n\nexport const DEFAULT_DOCUMENT_SECURITY_LIMITS: Required<DocumentSecurityLimits> = {\n maxNodeCount: 5000,\n maxTreeDepth: 32,\n maxPropsCount: 200,\n maxStringLength: 100_000,\n maxChildrenPerNode: 1000,\n maxDocumentSizeBytes: 10 * 1024 * 1024, // 10 MB\n allowedUrlSchemes: ['http:', 'https:', 'mailto:', 'tel:', '#', 'relative', 'data:image/'],\n prohibitedPropertyKeys: [\n '__proto__',\n 'constructor',\n 'prototype',\n '__defineGetter__',\n '__defineSetter__',\n '__lookupGetter__',\n '__lookupSetter__',\n ],\n prohibitedAssetExtensions: [\n '.exe',\n '.dll',\n '.so',\n '.sh',\n '.bat',\n '.cmd',\n '.js',\n '.mjs',\n '.cjs',\n '.php',\n '.py',\n '.vbs',\n '.wasm',\n '.bin',\n '.com',\n '.scr',\n '.pif',\n '.hta',\n '.jar',\n ],\n maxZipExpansionRatio: 100,\n};\n\nexport interface SecurityViolation {\n code:\n | 'PROTOTYPE_POLLUTION_DETECTED'\n | 'MAX_NODE_COUNT_EXCEEDED'\n | 'MAX_TREE_DEPTH_EXCEEDED'\n | 'MAX_PROPS_COUNT_EXCEEDED'\n | 'MAX_STRING_LENGTH_EXCEEDED'\n | 'MAX_CHILDREN_COUNT_EXCEEDED'\n | 'MAX_DOCUMENT_SIZE_EXCEEDED'\n | 'UNSAFE_URL_DETECTED'\n | 'EXECUTABLE_ASSET_DETECTED'\n | 'ZIP_BOMB_DETECTED';\n message: string;\n path?: string;\n details?: Record<string, unknown>;\n}\n\n/**\n * Checks whether a URL is safe according to the allowed URL schemes.\n * Rejects dangerous schemes such as javascript:, vbscript:, data:text/html, etc.\n */\nexport function isSafeUrl(\n url: unknown,\n options?: {\n allowedSchemes?: string[];\n allowDataImage?: boolean;\n /** Allow `blob:` URLs (runtime-only, e.g. in-memory uploaded media previews). */\n allowBlobMedia?: boolean;\n }\n): boolean {\n if (typeof url !== 'string') return false;\n\n const trimmed = url.trim();\n if (trimmed.length === 0) return true;\n\n // Relative URLs & fragments are safe\n if (\n trimmed.startsWith('/') ||\n trimmed.startsWith('#') ||\n trimmed.startsWith('./') ||\n trimmed.startsWith('../') ||\n trimmed.startsWith('?')\n ) {\n return true;\n }\n\n // Check for control characters or null bytes\n if (/[\\u0000-\\u001F\\u007F-\\u009F]/.test(trimmed)) {\n return false;\n }\n\n // Extract scheme\n const colonIndex = trimmed.indexOf(':');\n if (colonIndex === -1) {\n // Relative path or plain fragment without scheme\n return true;\n }\n\n const scheme = trimmed.substring(0, colonIndex + 1).toLowerCase();\n\n // Explicitly block dangerous protocols\n const dangerousSchemes = ['javascript:', 'vbscript:', 'file:', 'data:'];\n if (scheme !== 'data:' && dangerousSchemes.includes(scheme)) {\n // `blob:` URLs are runtime-only references to in-memory media (e.g. files\n // uploaded in the current editor session). They never originate from\n // imported documents, so they are safe to allow for media previews.\n if (scheme === 'blob:' && options?.allowBlobMedia) {\n return true;\n }\n return false;\n }\n\n // Handle data: scheme\n if (scheme === 'data:') {\n const allowDataImage = options?.allowDataImage ?? true;\n if (!allowDataImage) return false;\n\n // Only allow safe data:image/ mime types\n const dataPrefix = trimmed.substring(0, 30).toLowerCase();\n const safeDataImagePrefixes = [\n 'data:image/png',\n 'data:image/jpeg',\n 'data:image/jpg',\n 'data:image/webp',\n 'data:image/gif',\n 'data:image/avif',\n 'data:image/svg+xml',\n ];\n return safeDataImagePrefixes.some((p) => dataPrefix.startsWith(p));\n }\n\n // Verify against allowed schemes list\n const allowed = options?.allowedSchemes || DEFAULT_DOCUMENT_SECURITY_LIMITS.allowedUrlSchemes;\n return allowed.some((s) => s.toLowerCase() === scheme);\n}\n\n/**\n * Sanitizes a URL, returning a safe URL or a fallback (default empty string or '#').\n */\nexport function sanitizeUrl(\n url: unknown,\n fallback: string = '',\n options?: Parameters<typeof isSafeUrl>[1]\n): string {\n if (typeof url !== 'string') return fallback;\n return isSafeUrl(url, options) ? url : fallback;\n}\n\n/**\n * Checks an object recursively for prohibited prototype pollution keys.\n */\nexport function containsProhibitedKeys(\n obj: unknown,\n prohibitedKeys: string[] = DEFAULT_DOCUMENT_SECURITY_LIMITS.prohibitedPropertyKeys\n): { found: boolean; path: string; key: string } {\n const prohibitedSet = new Set(prohibitedKeys.map((k) => k.toLowerCase()));\n const visited = new WeakSet<object>();\n\n function check(value: unknown, currentPath: string): { found: boolean; path: string; key: string } {\n if (!value || typeof value !== 'object') {\n return { found: false, path: '', key: '' };\n }\n\n if (visited.has(value)) {\n return { found: false, path: '', key: '' };\n }\n visited.add(value);\n\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i++) {\n const res = check(value[i], `${currentPath}[${i}]`);\n if (res.found) return res;\n }\n return { found: false, path: '', key: '' };\n }\n\n const record = value as Record<string, unknown>;\n const keysToCheck = Array.from(new Set([...Object.keys(record), ...Object.getOwnPropertyNames(record)]));\n\n for (const key of keysToCheck) {\n if (prohibitedSet.has(key.toLowerCase())) {\n return { found: true, path: currentPath ? `${currentPath}.${key}` : key, key };\n }\n const res = check(record[key], currentPath ? `${currentPath}.${key}` : key);\n if (res.found) return res;\n }\n\n // Check if __proto__ was injected and altered standard prototype\n if (Object.prototype.hasOwnProperty.call(record, '__proto__')) {\n return { found: true, path: currentPath ? `${currentPath}.__proto__` : '__proto__', key: '__proto__' };\n }\n\n return { found: false, path: '', key: '' };\n }\n\n return check(obj, '');\n}\n\n/**\n * Validates a document against security limits (node count, tree depth, props count, string length, prototype pollution).\n */\nexport function validateDocumentSecurity(\n doc: unknown,\n customLimits?: DocumentSecurityLimits\n): { safe: boolean; errors: SecurityViolation[] } {\n const limits = { ...DEFAULT_DOCUMENT_SECURITY_LIMITS, ...customLimits };\n const errors: SecurityViolation[] = [];\n\n if (!doc || typeof doc !== 'object') {\n return { safe: true, errors: [] };\n }\n\n // 1. Prototype Pollution Check\n const protoCheck = containsProhibitedKeys(doc, limits.prohibitedPropertyKeys);\n if (protoCheck.found) {\n errors.push({\n code: 'PROTOTYPE_POLLUTION_DETECTED',\n message: `Prohibited property key \"${protoCheck.key}\" detected at path \"${protoCheck.path}\" (Prototype Pollution Defense).`,\n path: protoCheck.path,\n details: { key: protoCheck.key },\n });\n }\n\n // 2. Document Serialized Size Check\n try {\n const jsonStr = JSON.stringify(doc);\n if (jsonStr.length > limits.maxDocumentSizeBytes) {\n errors.push({\n code: 'MAX_DOCUMENT_SIZE_EXCEEDED',\n message: `Document size (${jsonStr.length} bytes) exceeds limit of ${limits.maxDocumentSizeBytes} bytes.`,\n details: { size: jsonStr.length, limit: limits.maxDocumentSizeBytes },\n });\n }\n } catch {\n // Ignore JSON stringify errors\n }\n\n // 3. Tree Depth & Node Count Checks\n const docObj = doc as Record<string, unknown>;\n const rootNode = docObj.document;\n\n if (rootNode && typeof rootNode === 'object') {\n let totalNodes = 0;\n\n function traverse(node: unknown, depth: number, currentPath: string): void {\n if (!node || typeof node !== 'object' || Array.isArray(node)) return;\n\n totalNodes++;\n if (totalNodes > limits.maxNodeCount) {\n errors.push({\n code: 'MAX_NODE_COUNT_EXCEEDED',\n message: `Total document nodes (${totalNodes}) exceeded security limit of ${limits.maxNodeCount}.`,\n path: currentPath,\n details: { nodeCount: totalNodes, limit: limits.maxNodeCount },\n });\n return;\n }\n\n if (depth > limits.maxTreeDepth) {\n errors.push({\n code: 'MAX_TREE_DEPTH_EXCEEDED',\n message: `Document nesting depth (${depth}) exceeded security limit of ${limits.maxTreeDepth}.`,\n path: currentPath,\n details: { depth, limit: limits.maxTreeDepth },\n });\n return;\n }\n\n const nodeRecord = node as Record<string, unknown>;\n\n // Check Props Limits\n if (nodeRecord.props && typeof nodeRecord.props === 'object' && !Array.isArray(nodeRecord.props)) {\n const propsRecord = nodeRecord.props as Record<string, unknown>;\n const propKeys = Object.keys(propsRecord);\n\n if (propKeys.length > limits.maxPropsCount) {\n errors.push({\n code: 'MAX_PROPS_COUNT_EXCEEDED',\n message: `Node has ${propKeys.length} props, exceeding limit of ${limits.maxPropsCount}.`,\n path: `${currentPath}/props`,\n details: { count: propKeys.length, limit: limits.maxPropsCount },\n });\n }\n\n for (const [k, val] of Object.entries(propsRecord)) {\n if (typeof val === 'string' && val.length > limits.maxStringLength) {\n errors.push({\n code: 'MAX_STRING_LENGTH_EXCEEDED',\n message: `Prop \"${k}\" string length (${val.length}) exceeds limit of ${limits.maxStringLength}.`,\n path: `${currentPath}/props/${k}`,\n details: { length: val.length, limit: limits.maxStringLength },\n });\n }\n }\n }\n\n // Check Children Limits\n if (nodeRecord.children && Array.isArray(nodeRecord.children)) {\n if (nodeRecord.children.length > limits.maxChildrenPerNode) {\n errors.push({\n code: 'MAX_CHILDREN_COUNT_EXCEEDED',\n message: `Node has ${nodeRecord.children.length} direct children, exceeding limit of ${limits.maxChildrenPerNode}.`,\n path: `${currentPath}/children`,\n details: { count: nodeRecord.children.length, limit: limits.maxChildrenPerNode },\n });\n }\n\n for (let i = 0; i < nodeRecord.children.length; i++) {\n traverse(nodeRecord.children[i], depth + 1, `${currentPath}/children/${i}`);\n }\n }\n }\n\n traverse(rootNode, 1, '/document');\n }\n\n return {\n safe: errors.length === 0,\n errors,\n };\n}\n\n/**\n * Checks if an asset filename has a dangerous or executable extension.\n */\nexport function isDangerousAssetFilename(\n filename: string,\n prohibitedExtensions: string[] = DEFAULT_DOCUMENT_SECURITY_LIMITS.prohibitedAssetExtensions\n): boolean {\n if (!filename || typeof filename !== 'string') return true;\n\n const lower = filename.toLowerCase().trim();\n\n // Check double extensions like \"malicious.exe.png\" or \"script.php.jpg\"\n return prohibitedExtensions.some((ext) => {\n const extLower = ext.toLowerCase();\n return lower.endsWith(extLower) || lower.includes(`${extLower}.`);\n });\n}\n\n/**\n * Checks whether an archive expansion ratio indicates a zip bomb attack.\n */\nexport function checkZipBomb(\n compressedSize: number,\n uncompressedSize: number,\n maxRatio: number = DEFAULT_DOCUMENT_SECURITY_LIMITS.maxZipExpansionRatio\n): boolean {\n if (compressedSize <= 0) return false;\n // Only enforce ratio for archives whose uncompressed payload is non-trivial (>10MB)\n if (uncompressedSize > 10 * 1024 * 1024) {\n const ratio = uncompressedSize / compressedSize;\n return ratio > maxRatio;\n }\n return false;\n}\n\n/**\n * Sanitizes an HTML string by stripping unsafe tags (<script>, <object>, <embed>, <applet>, <base>, <link rel=\"import\">),\n * removing inline event handlers (on* attributes like onclick, onerror, onload, etc.),\n * and disarming javascript:/vbscript:/data:text/html URLs in attributes.\n */\nexport function sanitizeHtml(rawHtml: unknown): string {\n if (typeof rawHtml !== 'string') return '';\n let html = rawHtml;\n\n // 1. Remove script tags and their content\n html = html.replace(/<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi, '');\n\n // 2. Remove object, embed, applet, base, and link tags\n html = html.replace(/<\\/?(object|embed|applet|base|link)\\b[^>]*>/gi, '');\n\n // 3. Remove on* event handler attributes (e.g. onload=, onclick=, onerror=, onfocus=)\n html = html.replace(/\\s+on[a-z0-9_-]+\\s*=\\s*(?:'[^']*'|\"[^\"]*\"|[^\\s>]+)/gi, '');\n\n // 4. Disarm javascript:, vbscript:, and data:text/html protocol attributes in href/src/data/action\n html = html.replace(\n /\\b(href|src|data|action)\\s*=\\s*(['\"])\\s*(?:javascript:|vbscript:|data:text\\/html)[^'\"]*\\2/gi,\n '$1=\"#\"'\n );\n html = html.replace(\n /\\b(href|src|data|action)\\s*=\\s*(?:javascript:|vbscript:|data:text\\/html)[^\\s>]+/gi,\n '$1=\"#\"'\n );\n\n return html;\n}\n\n","import { LEGACY_TRACKING_SECRET_KEYS, type TrackingProviderType } from '@kubuild/schema';\n\n/**\n * Removes host-owned secret / destination fields (e.g. Meta `capiAccessToken`, TikTok\n * `accessToken`, GA4 `measurementProtocolSecret`, `serverRelayUrl`, custom `endpointUrl` /\n * `headers`) from a tracking config object IN PLACE.\n *\n * Returns the dotted paths (relative to the tracking object) of every field removed.\n * Safe on untrusted input: non-object values are ignored.\n */\nexport function stripTrackingSecretsInPlace(tracking: unknown, basePath = 'tracking'): string[] {\n const removed: string[] = [];\n if (!tracking || typeof tracking !== 'object' || Array.isArray(tracking)) return removed;\n\n const providers = (tracking as Record<string, unknown>).providers;\n if (!providers || typeof providers !== 'object' || Array.isArray(providers)) return removed;\n\n for (const provider of Object.keys(LEGACY_TRACKING_SECRET_KEYS) as TrackingProviderType[]) {\n const cfg = (providers as Record<string, unknown>)[provider];\n if (!cfg || typeof cfg !== 'object' || Array.isArray(cfg)) continue;\n for (const key of LEGACY_TRACKING_SECRET_KEYS[provider]) {\n if (Object.prototype.hasOwnProperty.call(cfg, key)) {\n delete (cfg as Record<string, unknown>)[key];\n removed.push(`${basePath}.providers.${provider}.${key}`);\n }\n }\n }\n return removed;\n}\n\n/**\n * Strips tracking secrets from every place a document (page or project) can carry a\n * tracking config: `tracking`, `metadata.tracking`, and each `artboards[i].document.tracking`.\n * Mutates `doc` in place; pass a clone if the original must be preserved.\n */\nexport function stripDocumentTrackingSecretsInPlace(doc: unknown): string[] {\n const removed: string[] = [];\n if (!doc || typeof doc !== 'object' || Array.isArray(doc)) return removed;\n const record = doc as Record<string, unknown>;\n\n removed.push(...stripTrackingSecretsInPlace(record.tracking, 'tracking'));\n\n const metadata = record.metadata;\n if (metadata && typeof metadata === 'object' && !Array.isArray(metadata)) {\n removed.push(\n ...stripTrackingSecretsInPlace((metadata as Record<string, unknown>).tracking, 'metadata.tracking'),\n );\n }\n\n if (Array.isArray(record.artboards)) {\n record.artboards.forEach((artboard, index) => {\n if (artboard && typeof artboard === 'object') {\n const inner = (artboard as Record<string, unknown>).document;\n for (const path of stripDocumentTrackingSecretsInPlace(inner)) {\n removed.push(`artboards.${index}.document.${path}`);\n }\n }\n });\n }\n\n return removed;\n}\n\n/**\n * Non-mutating variant: returns a sanitized deep copy plus the removed field paths.\n */\nexport function sanitizeDocumentTracking<T>(doc: T): { document: T; removed: string[] } {\n if (!doc || typeof doc !== 'object') return { document: doc, removed: [] };\n const copy = JSON.parse(JSON.stringify(doc)) as T;\n const removed = stripDocumentTrackingSecretsInPlace(copy);\n return { document: copy, removed };\n}\n","import { unzipSync, strFromU8 } from 'fflate';\nimport {\n PageDocument,\n DocumentMetadata,\n Manifest,\n ManifestAssetItem,\n ManifestSchema,\n CURRENT_SCHEMA_VERSION,\n SCHEMA_NAME,\n} from '@kubuild/schema';\nimport {\n validateDocument,\n ComponentRegistryLike,\n} from '../validation/validator';\nimport {\n canMigrate,\n getMigrationPath,\n migrateDocument,\n MigrationRegistry,\n defaultMigrationRegistry,\n} from './migration';\nimport { calculateChecksum } from './exporter';\nimport { sanitizeDocumentTracking, stripDocumentTrackingSecretsInPlace } from './tracking-sanitizer';\nimport { remapDocumentAssetReferences } from '../document/document-utils';\nimport {\n isDangerousAssetFilename,\n checkZipBomb,\n containsProhibitedKeys,\n} from '../validation/security';\nimport type { AssetProvider, AssetInfo } from '../types/interfaces';\n\nexport interface SecurityLimits {\n /**\n * Maximum allowed size for the compressed archive in bytes (default: 50MB).\n */\n maxArchiveSize?: number;\n\n /**\n * Maximum total uncompressed size across all files in bytes (default: 100MB).\n */\n maxUncompressedSize?: number;\n\n /**\n * Maximum number of files in the archive (default: 1000).\n */\n maxFileCount?: number;\n\n /**\n * Maximum size for any individual asset in bytes (default: 25MB).\n */\n maxAssetSize?: number;\n}\n\nexport const DEFAULT_SECURITY_LIMITS: Required<SecurityLimits> = {\n maxArchiveSize: 50 * 1024 * 1024, // 50 MB\n maxUncompressedSize: 100 * 1024 * 1024, // 100 MB\n maxFileCount: 1000,\n maxAssetSize: 25 * 1024 * 1024, // 25 MB\n};\n\nexport type MissingDependencyPolicy =\n | 'cancel'\n | 'import-with-placeholder'\n | 'install-or-register-before-import';\n\nexport type AssetCollisionStrategy =\n | 'reject'\n | 'rename'\n | 'overwrite'\n | 'reuse-existing';\n\nexport interface AssetConflict {\n assetId: string;\n path: string;\n mimeType: string;\n size: number;\n existingAsset?: AssetInfo | Record<string, unknown>;\n}\n\nexport interface AssetConflictResolution {\n action: AssetCollisionStrategy;\n newAssetId?: string;\n}\n\nexport type PreflightDiagnosticCode =\n | 'ARCHIVE_EMPTY'\n | 'ARCHIVE_CORRUPT'\n | 'SIZE_LIMIT_EXCEEDED'\n | 'FILE_COUNT_EXCEEDED'\n | 'ZIP_SLIP_DETECTED'\n | 'EXECUTABLE_ASSET_DETECTED'\n | 'PROTOTYPE_POLLUTION_DETECTED'\n | 'MISSING_MANIFEST'\n | 'INVALID_MANIFEST'\n | 'MISSING_PAGE_DOCUMENT'\n | 'INVALID_PAGE_DOCUMENT'\n | 'UNSUPPORTED_SCHEMA_VERSION'\n | 'NO_MIGRATION_PATH'\n | 'MIGRATION_FAILED'\n | 'ASSET_FILE_MISSING'\n | 'ASSET_SIZE_MISMATCH'\n | 'ASSET_CHECKSUM_MISMATCH'\n | 'ASSET_LIMIT_EXCEEDED'\n | 'ASSET_CONFLICT'\n | 'MISSING_COMPONENTS'\n | 'MISSING_CAPABILITIES'\n | 'HOST_ADAPTER_ERROR'\n | 'TRACKING_SECRET_REMOVED';\n\nexport interface PreflightDiagnostic {\n code: PreflightDiagnosticCode;\n severity: 'error' | 'warning' | 'info';\n message: string;\n path?: string;\n details?: Record<string, unknown>;\n}\n\nexport interface PreflightOptions {\n /**\n * Component registry to check required custom components.\n */\n componentRegistry?: ComponentRegistryLike;\n\n /**\n * Allowlist of known component type names (used if componentRegistry is not provided or in combination).\n */\n knownComponentTypes?: string[] | Set<string>;\n\n /**\n * Allowlist of capabilities supported by host.\n */\n supportedCapabilities?: string[] | Set<string>;\n\n /**\n * Security limits for archive and files.\n */\n securityLimits?: SecurityLimits;\n\n /**\n * Custom migration registry.\n */\n migrationRegistry?: MigrationRegistry;\n\n /**\n * Target schema version (defaults to CURRENT_SCHEMA_VERSION).\n */\n targetSchemaVersion?: string;\n\n /**\n * Policy for handling missing custom components and capabilities.\n * - 'cancel' (default): Abort import with blocking errors when components/capabilities are missing.\n * - 'import-with-placeholder': Allow import, keeping missing component nodes and props intact for placeholder rendering.\n * - 'install-or-register-before-import': Call onMissingDependency to register/install before finalizing import.\n */\n dependencyPolicy?: MissingDependencyPolicy;\n\n /**\n * Hook called when dependencyPolicy is 'install-or-register-before-import'.\n */\n onMissingDependency?: (\n missing: { components: string[]; capabilities: string[] },\n preflight: PreflightReport,\n ) => Promise<boolean | void> | boolean | void;\n\n /**\n * If true, missing components are treated as warnings rather than blocking errors.\n * (Equivalent to setting dependencyPolicy: 'import-with-placeholder')\n */\n allowMissingComponents?: boolean;\n\n /**\n * If true, missing capabilities are treated as warnings rather than blocking errors.\n * (Equivalent to setting dependencyPolicy: 'import-with-placeholder')\n */\n allowMissingCapabilities?: boolean;\n\n /**\n * Strategy for resolving asset collisions with existing host assets.\n * - 'reject' (default): Refuse import if asset collision is detected without an explicit resolution strategy.\n * - 'rename': Rename the incoming asset to avoid overwriting host assets, and automatically remap document asset references.\n * - 'overwrite': Explicitly overwrite host assets with incoming archive assets.\n * - 'reuse-existing': Reuse existing host assets and skip writing archive asset binaries.\n */\n assetCollisionStrategy?: AssetCollisionStrategy;\n\n /**\n * Existing host asset IDs or checker function to detect collisions.\n */\n existingAssetIds?: string[] | Set<string> | ((assetId: string) => boolean | Promise<boolean>);\n\n /**\n * Custom naming function when renaming colliding assets.\n */\n renameAssetStrategy?: (incoming: ManifestAssetItem, existingIds: Set<string>) => string;\n\n /**\n * Host AssetProvider to resolve existing assets or upload extracted local assets.\n */\n assetProvider?: AssetProvider;\n\n /**\n * Fine-grained callback for resolving individual asset conflicts.\n */\n onAssetConflict?: (\n conflict: AssetConflict,\n ) => Promise<AssetConflictResolution | AssetCollisionStrategy> | AssetConflictResolution | AssetCollisionStrategy;\n}\n\nexport interface PreflightReport {\n /**\n * True if archive is completely safe and syntactically valid.\n */\n valid: boolean;\n\n /**\n * True if archive can be safely imported given the host's supported components/capabilities and asset policies.\n */\n canImport: boolean;\n\n /**\n * Parsed manifest if available.\n */\n manifest?: Manifest;\n\n /**\n * Parsed metadata if available.\n */\n rawMetadata?: DocumentMetadata;\n\n /**\n * Schema version reported in the document/manifest.\n */\n sourceVersion?: string;\n\n /**\n * Target schema version.\n */\n targetVersion: string;\n\n /**\n * True if the document version differs from target version and requires migration.\n */\n requiresMigration: boolean;\n\n /**\n * Migration path version sequence if migration is needed.\n */\n migrationPath?: string[];\n\n /**\n * List of custom component types required by package that are missing in host.\n */\n missingComponents: string[];\n\n /**\n * List of capabilities required by package that are missing in host.\n */\n missingCapabilities: string[];\n\n /**\n * Active policy for missing dependencies.\n */\n dependencyPolicy: MissingDependencyPolicy;\n\n /**\n * Number of valid local assets declared in manifest.\n */\n assetCount: number;\n\n /**\n * List of detected asset collisions with existing host assets.\n */\n assetConflicts: AssetConflict[];\n\n /**\n * Active strategy for handling asset collisions.\n */\n assetCollisionStrategy: AssetCollisionStrategy;\n\n /**\n * Total uncompressed size of all files in archive.\n */\n totalUncompressedBytes: number;\n\n /**\n * Diagnostics collected during inspection.\n */\n diagnostics: PreflightDiagnostic[];\n}\n\nexport interface ImportPackageOptions extends PreflightOptions {\n /**\n * Custom asset importer hook called for each extracted asset.\n */\n onAssetImport?: (\n assetId: string,\n assetBytes: Uint8Array,\n assetMeta: ManifestAssetItem,\n ) => Promise<AssetInfo | string | void> | AssetInfo | string | void;\n}\n\nexport interface ExtractedAsset {\n bytes: Uint8Array;\n meta: ManifestAssetItem;\n hostInfo?: AssetInfo | string;\n}\n\nexport interface ImportPackageSuccess {\n success: true;\n document: PageDocument;\n manifest: Manifest;\n metadata: DocumentMetadata;\n extractedAssets: Map<string, ExtractedAsset>;\n renamedAssets?: Record<string, string>;\n preflight: PreflightReport;\n /** Non-fatal notes produced while importing (e.g. tracking secrets stripped). */\n warnings?: PreflightDiagnostic[];\n}\n\nexport interface ImportPackageFailure {\n success: false;\n errors: PreflightDiagnostic[];\n diagnosticMessage: string;\n preflight?: PreflightReport;\n}\n\nexport type ImportPackageResult = ImportPackageSuccess | ImportPackageFailure;\n\n/**\n * Checks if a zip entry path contains zip-slip or directory traversal attempts.\n */\nexport function isDangerousPath(filepath: string): boolean {\n if (!filepath || typeof filepath !== 'string') return true;\n\n // Check for null bytes\n if (filepath.includes('\\0')) return true;\n\n // Check for absolute paths (Unix or Windows drive)\n if (filepath.startsWith('/') || filepath.startsWith('\\\\') || /^[a-zA-Z]:/.test(filepath)) {\n return true;\n }\n\n // Normalize slashes\n const normalized = filepath.replace(/\\\\/g, '/');\n\n // Check path segments\n const segments = normalized.split('/');\n for (const seg of segments) {\n if (seg === '..' || seg.trim() === '..') {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Inspects a .stora archive and runs non-destructive preflight validation.\n * Verifies security limits, path safety, manifest, checksums, component/capability requirements, and migration status.\n */\nexport async function preflightPackage(\n archiveData: Uint8Array | ArrayBuffer,\n options: PreflightOptions = {},\n): Promise<PreflightReport> {\n const limits: Required<SecurityLimits> = {\n ...DEFAULT_SECURITY_LIMITS,\n ...options.securityLimits,\n };\n\n const targetVersion = options.targetSchemaVersion || CURRENT_SCHEMA_VERSION;\n const migrationRegistry = options.migrationRegistry || defaultMigrationRegistry;\n const diagnostics: PreflightDiagnostic[] = [];\n\n let dependencyPolicy: MissingDependencyPolicy = options.dependencyPolicy || 'cancel';\n if (!options.dependencyPolicy) {\n if (options.allowMissingComponents && options.allowMissingCapabilities) {\n dependencyPolicy = 'import-with-placeholder';\n }\n }\n\n const assetCollisionStrategy: AssetCollisionStrategy = options.assetCollisionStrategy || 'reject';\n\n const archiveBytes = archiveData instanceof Uint8Array ? archiveData : new Uint8Array(archiveData);\n\n // 1. Check archive size limit\n if (!archiveBytes || archiveBytes.byteLength === 0) {\n diagnostics.push({\n code: 'ARCHIVE_EMPTY',\n severity: 'error',\n message: 'Archive is empty or 0 bytes.',\n });\n return buildReport(false, false, { targetVersion, dependencyPolicy, assetCollisionStrategy, diagnostics });\n }\n\n if (archiveBytes.byteLength > limits.maxArchiveSize) {\n diagnostics.push({\n code: 'SIZE_LIMIT_EXCEEDED',\n severity: 'error',\n message: `Archive size (${archiveBytes.byteLength} bytes) exceeds maximum limit of ${limits.maxArchiveSize} bytes.`,\n details: { actualBytes: archiveBytes.byteLength, limitBytes: limits.maxArchiveSize },\n });\n return buildReport(false, false, { targetVersion, dependencyPolicy, assetCollisionStrategy, diagnostics });\n }\n\n // 2. Safe Unzip\n let unzipped: Record<string, Uint8Array>;\n try {\n unzipped = unzipSync(archiveBytes);\n } catch (err) {\n diagnostics.push({\n code: 'ARCHIVE_CORRUPT',\n severity: 'error',\n message: `Failed to unzip archive: ${err instanceof Error ? err.message : String(err)}`,\n });\n return buildReport(false, false, { targetVersion, dependencyPolicy, assetCollisionStrategy, diagnostics });\n }\n\n const entries = Object.keys(unzipped);\n\n // Check file count limit\n if (entries.length > limits.maxFileCount) {\n diagnostics.push({\n code: 'FILE_COUNT_EXCEEDED',\n severity: 'error',\n message: `Archive file count (${entries.length}) exceeds maximum limit of ${limits.maxFileCount}.`,\n details: { fileCount: entries.length, limit: limits.maxFileCount },\n });\n }\n\n // 3. Security checks: Zip-Slip and Total Uncompressed Size\n let totalUncompressedBytes = 0;\n for (const entryPath of entries) {\n // Check path safety\n if (isDangerousPath(entryPath)) {\n diagnostics.push({\n code: 'ZIP_SLIP_DETECTED',\n severity: 'error',\n message: `Security violation: Path traversal or Zip-Slip attempt detected in archive entry \"${entryPath}\".`,\n path: entryPath,\n });\n }\n\n // Check dangerous/executable asset file extensions\n if (entryPath.startsWith('assets/') && isDangerousAssetFilename(entryPath)) {\n diagnostics.push({\n code: 'EXECUTABLE_ASSET_DETECTED',\n severity: 'error',\n message: `Security violation: Executable or dangerous asset file extension detected in archive entry \"${entryPath}\".`,\n path: entryPath,\n });\n }\n\n const fileBytes = unzipped[entryPath];\n if (fileBytes) {\n totalUncompressedBytes += fileBytes.byteLength;\n\n // Check single asset size limit if in assets/\n if (entryPath.startsWith('assets/') && fileBytes.byteLength > limits.maxAssetSize) {\n diagnostics.push({\n code: 'ASSET_LIMIT_EXCEEDED',\n severity: 'error',\n message: `Asset \"${entryPath}\" size (${fileBytes.byteLength} bytes) exceeds maximum limit of ${limits.maxAssetSize} bytes.`,\n path: entryPath,\n details: { actualBytes: fileBytes.byteLength, limitBytes: limits.maxAssetSize },\n });\n }\n }\n }\n\n if (totalUncompressedBytes > limits.maxUncompressedSize) {\n diagnostics.push({\n code: 'SIZE_LIMIT_EXCEEDED',\n severity: 'error',\n message: `Total uncompressed archive size (${totalUncompressedBytes} bytes) exceeds maximum limit of ${limits.maxUncompressedSize} bytes.`,\n details: { actualBytes: totalUncompressedBytes, limitBytes: limits.maxUncompressedSize },\n });\n }\n\n // Check Zip Bomb expansion ratio\n if (checkZipBomb(archiveBytes.byteLength, totalUncompressedBytes)) {\n diagnostics.push({\n code: 'SIZE_LIMIT_EXCEEDED',\n severity: 'error',\n message: `Security violation: Potential Zip Bomb attack detected (excessive compression ratio).`,\n details: { compressedBytes: archiveBytes.byteLength, uncompressedBytes: totalUncompressedBytes },\n });\n }\n\n // 4. Check Mandatory Files: manifest.json & page.json\n const manifestEntry = unzipped['manifest.json'];\n if (!manifestEntry) {\n diagnostics.push({\n code: 'MISSING_MANIFEST',\n severity: 'error',\n message: 'Archive is missing mandatory \"manifest.json\" file.',\n });\n }\n\n const pageEntry = unzipped['page.json'];\n if (!pageEntry) {\n diagnostics.push({\n code: 'MISSING_PAGE_DOCUMENT',\n severity: 'error',\n message: 'Archive is missing mandatory \"page.json\" file.',\n });\n }\n\n // If mandatory files missing or security violated, stop preflight early\n if (!manifestEntry || !pageEntry || diagnostics.some((d) => d.code === 'ZIP_SLIP_DETECTED')) {\n return buildReport(false, false, {\n targetVersion,\n dependencyPolicy,\n assetCollisionStrategy,\n totalUncompressedBytes,\n diagnostics,\n });\n }\n\n // 5. Parse & Validate Manifest\n let parsedManifest: Manifest | undefined;\n try {\n const manifestJson = JSON.parse(strFromU8(manifestEntry));\n const manifestProtoCheck = containsProhibitedKeys(manifestJson);\n if (manifestProtoCheck.found) {\n diagnostics.push({\n code: 'PROTOTYPE_POLLUTION_DETECTED',\n severity: 'error',\n message: `Security violation: Prohibited key \"${manifestProtoCheck.key}\" in manifest.json.`,\n path: manifestProtoCheck.path,\n });\n }\n\n const parseResult = ManifestSchema.safeParse(manifestJson);\n if (!parseResult.success) {\n const issues = parseResult.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join(', ');\n diagnostics.push({\n code: 'INVALID_MANIFEST',\n severity: 'error',\n message: `Manifest validation failed: ${issues}`,\n details: { issues: parseResult.error.issues },\n });\n } else {\n parsedManifest = parseResult.data;\n }\n } catch (err) {\n diagnostics.push({\n code: 'INVALID_MANIFEST',\n severity: 'error',\n message: `Failed to parse \"manifest.json\" as valid JSON: ${err instanceof Error ? err.message : String(err)}`,\n });\n }\n\n // 6. Parse Metadata (Optional metadata.json)\n let rawMetadata: DocumentMetadata | undefined;\n const metadataEntry = unzipped['metadata.json'];\n if (metadataEntry) {\n try {\n rawMetadata = JSON.parse(strFromU8(metadataEntry)) as DocumentMetadata;\n } catch {\n // Non-critical, fallback will use page.json metadata\n }\n }\n\n // 7. Parse & Inspect page.json\n let rawPageDoc: Record<string, unknown> | undefined;\n try {\n rawPageDoc = JSON.parse(strFromU8(pageEntry)) as Record<string, unknown>;\n const secretScan = sanitizeDocumentTracking(rawPageDoc);\n if (secretScan.removed.length > 0) {\n diagnostics.push({\n code: 'TRACKING_SECRET_REMOVED',\n severity: 'warning',\n message:\n 'Tracking secrets found in page.json will be removed on import; re-link credentials via credentialId.',\n path: 'page.json',\n details: { paths: secretScan.removed },\n });\n }\n const pageProtoCheck = containsProhibitedKeys(rawPageDoc);\n if (pageProtoCheck.found) {\n diagnostics.push({\n code: 'PROTOTYPE_POLLUTION_DETECTED',\n severity: 'error',\n message: `Security violation: Prohibited key \"${pageProtoCheck.key}\" in page.json.`,\n path: pageProtoCheck.path,\n });\n }\n } catch (err) {\n diagnostics.push({\n code: 'INVALID_PAGE_DOCUMENT',\n severity: 'error',\n message: `Failed to parse \"page.json\" as valid JSON: ${err instanceof Error ? err.message : String(err)}`,\n });\n }\n\n const docVersion = typeof rawPageDoc?.version === 'string'\n ? rawPageDoc.version\n : parsedManifest?.schemaVersion || 'unknown';\n\n let requiresMigration = false;\n let migrationPath: string[] | undefined;\n\n if (rawPageDoc) {\n if (docVersion !== targetVersion) {\n if (canMigrate(docVersion, targetVersion, migrationRegistry)) {\n requiresMigration = true;\n migrationPath = getMigrationPath(docVersion, targetVersion, migrationRegistry) || undefined;\n diagnostics.push({\n code: 'UNSUPPORTED_SCHEMA_VERSION',\n severity: 'info',\n message: `Document schema version \"${docVersion}\" requires migration to current version \"${targetVersion}\".`,\n details: { sourceVersion: docVersion, targetVersion, migrationPath },\n });\n } else {\n diagnostics.push({\n code: 'NO_MIGRATION_PATH',\n severity: 'error',\n message: `Document schema version \"${docVersion}\" is not compatible and no migration path exists to \"${targetVersion}\".`,\n details: { sourceVersion: docVersion, targetVersion },\n });\n }\n } else {\n // Validate current schema structure\n const docValidation = validateDocument(rawPageDoc, {\n componentRegistry: options.componentRegistry,\n knownComponentTypes: options.knownComponentTypes,\n });\n const criticalDocErrors = docValidation.errors.filter((e) => {\n if (e.code === 'UNKNOWN_COMPONENT_TYPE' && dependencyPolicy !== 'cancel') {\n return false;\n }\n return true;\n });\n if (criticalDocErrors.length > 0) {\n diagnostics.push({\n code: 'INVALID_PAGE_DOCUMENT',\n severity: 'error',\n message: `Document validation failed with ${criticalDocErrors.length} error(s):\\n` +\n criticalDocErrors.map((e) => `[${e.code}] ${e.path}: ${e.message}`).join('\\n'),\n });\n }\n }\n }\n\n // 8. Verify Asset Inventory & Checksums\n const missingComponents: string[] = [];\n const missingCapabilities: string[] = [];\n const assetConflicts: AssetConflict[] = [];\n\n // Build existing host assets set\n const existingAssetIdsSet = new Set<string>();\n if (options.existingAssetIds) {\n if (Array.isArray(options.existingAssetIds)) {\n for (const id of options.existingAssetIds) existingAssetIdsSet.add(id);\n } else if (options.existingAssetIds instanceof Set) {\n for (const id of options.existingAssetIds) existingAssetIdsSet.add(id);\n }\n }\n\n // Check host assetProvider list if available and existingAssetIds not given\n if (options.assetProvider?.list && !options.existingAssetIds) {\n try {\n const list = await options.assetProvider.list();\n if (Array.isArray(list)) {\n for (const item of list) {\n if (item?.id) existingAssetIdsSet.add(item.id);\n }\n }\n } catch {\n // Non-fatal\n }\n }\n\n if (parsedManifest) {\n for (const assetItem of parsedManifest.assets) {\n // Validate asset path in archive\n const assetFile = unzipped[assetItem.path];\n if (!assetFile) {\n diagnostics.push({\n code: 'ASSET_FILE_MISSING',\n severity: 'error',\n message: `Declared asset \"${assetItem.id}\" is missing in archive at path \"${assetItem.path}\".`,\n path: assetItem.path,\n details: { assetId: assetItem.id },\n });\n continue;\n }\n\n // Validate size\n if (assetFile.byteLength !== assetItem.size) {\n diagnostics.push({\n code: 'ASSET_SIZE_MISMATCH',\n severity: 'error',\n message: `Asset \"${assetItem.id}\" size mismatch: expected ${assetItem.size} bytes, found ${assetFile.byteLength} bytes.`,\n path: assetItem.path,\n details: { assetId: assetItem.id, expected: assetItem.size, actual: assetFile.byteLength },\n });\n }\n\n // Validate checksum if provided\n if (assetItem.checksum) {\n const actualChecksum = await calculateChecksum(assetFile);\n if (actualChecksum !== assetItem.checksum) {\n diagnostics.push({\n code: 'ASSET_CHECKSUM_MISMATCH',\n severity: 'error',\n message: `Asset \"${assetItem.id}\" checksum mismatch: expected ${assetItem.checksum}, calculated ${actualChecksum}.`,\n path: assetItem.path,\n details: { assetId: assetItem.id, expected: assetItem.checksum, actual: actualChecksum },\n });\n }\n }\n\n // Check collision with host assets\n let isConflict = false;\n if (typeof options.existingAssetIds === 'function') {\n const fnRes = await options.existingAssetIds(assetItem.id);\n if (fnRes) isConflict = true;\n } else if (existingAssetIdsSet.has(assetItem.id)) {\n isConflict = true;\n }\n\n if (isConflict) {\n assetConflicts.push({\n assetId: assetItem.id,\n path: assetItem.path,\n mimeType: assetItem.mimeType,\n size: assetItem.size,\n });\n }\n }\n\n // Report Asset Collision diagnostics\n if (assetConflicts.length > 0) {\n const conflictIds = assetConflicts.map((c) => c.assetId).join(', ');\n if (assetCollisionStrategy === 'reject' && !options.onAssetConflict) {\n diagnostics.push({\n code: 'ASSET_CONFLICT',\n severity: 'error',\n message: `Asset collision detected for asset(s): ${conflictIds}. Host assets will not be overwritten without an explicit assetCollisionStrategy.`,\n details: { assetConflicts, strategy: assetCollisionStrategy },\n });\n } else {\n diagnostics.push({\n code: 'ASSET_CONFLICT',\n severity: 'info',\n message: `Asset collision detected for asset(s): ${conflictIds}. Strategy \"${assetCollisionStrategy}\" will be applied on import.`,\n details: { assetConflicts, strategy: assetCollisionStrategy },\n });\n }\n }\n\n // 9. Component Requirements Check\n const knownSet = new Set<string>();\n if (options.knownComponentTypes) {\n for (const t of options.knownComponentTypes) knownSet.add(t);\n }\n // Add standard built-ins\n const builtIns = ['page', 'section', 'container', 'columns', 'heading', 'text', 'image', 'button', 'collection'];\n for (const b of builtIns) knownSet.add(b);\n\n for (const compType of parsedManifest.requiredComponents) {\n let isSupported = knownSet.has(compType);\n if (!isSupported && options.componentRegistry) {\n isSupported = options.componentRegistry.has(compType);\n }\n if (!isSupported) {\n missingComponents.push(compType);\n }\n }\n\n if (missingComponents.length > 0) {\n if (dependencyPolicy === 'cancel' && !options.allowMissingComponents) {\n diagnostics.push({\n code: 'MISSING_COMPONENTS',\n severity: 'error',\n message: `Package requires custom component(s) not registered in host: ${missingComponents.join(', ')}.`,\n details: { missingComponents, policy: dependencyPolicy },\n });\n } else if (dependencyPolicy === 'import-with-placeholder' || options.allowMissingComponents) {\n diagnostics.push({\n code: 'MISSING_COMPONENTS',\n severity: 'warning',\n message: `Package requires custom component(s) [${missingComponents.join(', ')}] not registered in host. Nodes and props are preserved intact for placeholder rendering.`,\n details: { missingComponents, policy: dependencyPolicy },\n });\n } else if (dependencyPolicy === 'install-or-register-before-import') {\n diagnostics.push({\n code: 'MISSING_COMPONENTS',\n severity: 'info',\n message: `Package requires custom component(s) [${missingComponents.join(', ')}]. Installation/registration required before import.`,\n details: { missingComponents, policy: dependencyPolicy },\n });\n }\n }\n\n // 10. Capability Requirements Check\n const supportedCaps = new Set<string>();\n if (options.supportedCapabilities) {\n for (const c of options.supportedCapabilities) supportedCaps.add(c);\n }\n\n for (const cap of parsedManifest.requiredCapabilities) {\n if (!supportedCaps.has(cap)) {\n missingCapabilities.push(cap);\n }\n }\n\n if (missingCapabilities.length > 0) {\n if (dependencyPolicy === 'cancel' && !options.allowMissingCapabilities) {\n diagnostics.push({\n code: 'MISSING_CAPABILITIES',\n severity: 'error',\n message: `Package requires capability/capabilities not supported by host: ${missingCapabilities.join(', ')}.`,\n details: { missingCapabilities, policy: dependencyPolicy },\n });\n } else if (dependencyPolicy === 'import-with-placeholder' || options.allowMissingCapabilities) {\n diagnostics.push({\n code: 'MISSING_CAPABILITIES',\n severity: 'warning',\n message: `Package requires capability/capabilities [${missingCapabilities.join(', ')}] not supported by host. Placeholder rendering enabled.`,\n details: { missingCapabilities, policy: dependencyPolicy },\n });\n } else if (dependencyPolicy === 'install-or-register-before-import') {\n diagnostics.push({\n code: 'MISSING_CAPABILITIES',\n severity: 'info',\n message: `Package requires capability/capabilities [${missingCapabilities.join(', ')}]. Registration required before import.`,\n details: { missingCapabilities, policy: dependencyPolicy },\n });\n }\n }\n }\n\n const hasErrors = diagnostics.some((d) => d.severity === 'error');\n const valid = !hasErrors;\n const canImport = valid;\n\n return buildReport(valid, canImport, {\n manifest: parsedManifest,\n rawMetadata,\n sourceVersion: docVersion,\n targetVersion,\n requiresMigration,\n migrationPath,\n missingComponents,\n missingCapabilities,\n dependencyPolicy,\n assetCount: parsedManifest?.assets.length || 0,\n assetConflicts,\n assetCollisionStrategy,\n totalUncompressedBytes,\n diagnostics,\n });\n}\n\nfunction buildReport(\n valid: boolean,\n canImport: boolean,\n fields: Partial<PreflightReport>,\n): PreflightReport {\n return {\n valid,\n canImport,\n targetVersion: fields.targetVersion || CURRENT_SCHEMA_VERSION,\n requiresMigration: fields.requiresMigration || false,\n missingComponents: fields.missingComponents || [],\n missingCapabilities: fields.missingCapabilities || [],\n dependencyPolicy: fields.dependencyPolicy || 'cancel',\n assetCount: fields.assetCount || 0,\n assetConflicts: fields.assetConflicts || [],\n assetCollisionStrategy: fields.assetCollisionStrategy || 'reject',\n totalUncompressedBytes: fields.totalUncompressedBytes || 0,\n diagnostics: fields.diagnostics || [],\n ...fields,\n };\n}\n\n/**\n * Preview a .stora package without mutating host state.\n * Returns missing dependencies, asset conflicts, schema migration status, and diagnostics.\n */\nexport const previewImportPackage = preflightPackage;\n\n/**\n * Alias for preflightPackage.\n */\nexport const inspectPackage = preflightPackage;\n\n/**\n * Default generator for renaming colliding asset IDs.\n */\nexport function defaultRenameAssetStrategy(\n incoming: ManifestAssetItem,\n existingIds: Set<string>,\n): string {\n let candidate = `${incoming.id}_imported`;\n let counter = 1;\n while (existingIds.has(candidate)) {\n candidate = `${incoming.id}_imported_${counter}`;\n counter++;\n }\n return candidate;\n}\n\n/**\n * Imports a .stora package with preflight safety checks, schema migration, missing dependency policy,\n * and host-controlled asset collision handling.\n */\nexport async function importPackage(\n archiveData: Uint8Array | ArrayBuffer,\n options: ImportPackageOptions = {},\n): Promise<ImportPackageResult> {\n // 1. Run Preflight Inspection first\n let preflight = await preflightPackage(archiveData, options);\n\n // 2. Handle 'install-or-register-before-import' policy hook\n const dependencyPolicy = options.dependencyPolicy || preflight.dependencyPolicy;\n if (\n dependencyPolicy === 'install-or-register-before-import' &&\n (preflight.missingComponents.length > 0 || preflight.missingCapabilities.length > 0) &&\n options.onMissingDependency\n ) {\n try {\n await options.onMissingDependency(\n {\n components: [...preflight.missingComponents],\n capabilities: [...preflight.missingCapabilities],\n },\n preflight,\n );\n\n // Re-run preflight after hook execution\n preflight = await preflightPackage(archiveData, {\n ...options,\n dependencyPolicy: 'cancel', // Strict check after install attempt\n });\n } catch (err) {\n const diag: PreflightDiagnostic = {\n code: 'HOST_ADAPTER_ERROR',\n severity: 'error',\n message: `Dynamic dependency registration failed: ${err instanceof Error ? err.message : String(err)}`,\n };\n return {\n success: false,\n errors: [diag],\n diagnosticMessage: diag.message,\n preflight,\n };\n }\n }\n\n if (!preflight.canImport || !preflight.manifest) {\n const errorDiagnostics = preflight.diagnostics.filter((d) => d.severity === 'error');\n const diagnosticMessage = `Package import rejected with ${errorDiagnostics.length} error(s):\\n` +\n errorDiagnostics.map((d) => `[${d.code}] ${d.path ? d.path + ': ' : ''}${d.message}`).join('\\n');\n\n return {\n success: false,\n errors: errorDiagnostics,\n diagnosticMessage,\n preflight,\n };\n }\n\n const archiveBytes = archiveData instanceof Uint8Array ? archiveData : new Uint8Array(archiveData);\n const unzipped = unzipSync(archiveBytes);\n\n // 3. Read and Migrate Page Document\n const pageRaw = JSON.parse(strFromU8(unzipped['page.json']));\n let finalDocument: PageDocument;\n\n if (preflight.requiresMigration) {\n const migrationRegistry = options.migrationRegistry || defaultMigrationRegistry;\n const migrationRes = migrateDocument(pageRaw, {\n targetVersion: options.targetSchemaVersion || CURRENT_SCHEMA_VERSION,\n registry: migrationRegistry,\n validate: true,\n });\n\n if (!migrationRes.success || !migrationRes.document) {\n const err: PreflightDiagnostic = {\n code: 'MIGRATION_FAILED',\n severity: 'error',\n message: `Failed to migrate document from \"${preflight.sourceVersion}\" to \"${preflight.targetVersion}\".`,\n details: { diagnostic: migrationRes.diagnostic },\n };\n return {\n success: false,\n errors: [err],\n diagnosticMessage: err.message,\n preflight,\n };\n }\n\n finalDocument = migrationRes.document;\n } else {\n finalDocument = pageRaw as PageDocument;\n }\n\n // Untrusted input: never let tracking secrets / server destinations into the host document.\n const importWarnings: PreflightDiagnostic[] = [];\n const strippedSecrets = stripDocumentTrackingSecretsInPlace(finalDocument);\n if (strippedSecrets.length > 0) {\n importWarnings.push({\n code: 'TRACKING_SECRET_REMOVED',\n severity: 'warning',\n message: 'Tracking secret removed from imported document; re-link credential via credentialId.',\n path: 'page.json',\n details: { paths: strippedSecrets },\n });\n }\n\n // 4. Extract and Merge Metadata\n let metadata: DocumentMetadata = finalDocument.metadata || {\n title: 'Imported Page',\n description: '',\n author: '',\n tags: [],\n category: 'general',\n version: finalDocument.version || CURRENT_SCHEMA_VERSION,\n };\n\n if (unzipped['metadata.json']) {\n try {\n const metaFromFile = JSON.parse(strFromU8(unzipped['metadata.json'])) as DocumentMetadata;\n metadata = {\n ...metadata,\n ...metaFromFile,\n };\n } catch {\n // Use document metadata\n }\n }\n\n finalDocument.metadata = metadata;\n\n // 5. Build existing host assets set\n const existingAssetIdsSet = new Set<string>();\n if (options.existingAssetIds) {\n if (Array.isArray(options.existingAssetIds)) {\n for (const id of options.existingAssetIds) existingAssetIdsSet.add(id);\n } else if (options.existingAssetIds instanceof Set) {\n for (const id of options.existingAssetIds) existingAssetIdsSet.add(id);\n }\n }\n\n if (options.assetProvider?.list && !options.existingAssetIds) {\n try {\n const list = await options.assetProvider.list();\n if (Array.isArray(list)) {\n for (const item of list) {\n if (item?.id) existingAssetIdsSet.add(item.id);\n }\n }\n } catch {\n // Non-fatal\n }\n }\n\n const renameAssetFn = options.renameAssetStrategy || defaultRenameAssetStrategy;\n const renameMap: Record<string, string> = {};\n const extractedAssets = new Map<string, ExtractedAsset>();\n\n // 6. Extract Assets with Host-Controlled Collision Resolution\n for (const assetItem of preflight.manifest.assets) {\n const assetBytes = unzipped[assetItem.path];\n if (assetBytes) {\n let targetAssetId = assetItem.id;\n let effectiveStrategy: AssetCollisionStrategy = options.assetCollisionStrategy || 'reject';\n\n const conflictInfo = preflight.assetConflicts.find((c) => c.assetId === assetItem.id);\n\n if (conflictInfo) {\n if (options.onAssetConflict) {\n try {\n const conflictRes = await options.onAssetConflict(conflictInfo);\n if (typeof conflictRes === 'string') {\n effectiveStrategy = conflictRes;\n } else {\n effectiveStrategy = conflictRes.action;\n if (conflictRes.newAssetId) {\n targetAssetId = conflictRes.newAssetId;\n }\n }\n } catch (err) {\n const diag: PreflightDiagnostic = {\n code: 'HOST_ADAPTER_ERROR',\n severity: 'error',\n message: `Asset conflict resolution handler failed for \"${assetItem.id}\": ${err instanceof Error ? err.message : String(err)}`,\n path: assetItem.path,\n };\n return {\n success: false,\n errors: [diag],\n diagnosticMessage: diag.message,\n preflight,\n };\n }\n }\n\n if (effectiveStrategy === 'reject') {\n const diag: PreflightDiagnostic = {\n code: 'ASSET_CONFLICT',\n severity: 'error',\n message: `Import aborted: Asset \"${assetItem.id}\" collides with host asset. No overwrite strategy specified.`,\n path: assetItem.path,\n };\n return {\n success: false,\n errors: [diag],\n diagnosticMessage: diag.message,\n preflight,\n };\n }\n\n if (effectiveStrategy === 'rename') {\n if (targetAssetId === assetItem.id) {\n targetAssetId = renameAssetFn(assetItem, existingAssetIdsSet);\n }\n renameMap[assetItem.id] = targetAssetId;\n existingAssetIdsSet.add(targetAssetId);\n }\n }\n\n let hostInfo: AssetInfo | string | undefined;\n\n if (effectiveStrategy === 'reuse-existing' && conflictInfo) {\n // Reuse existing asset: skip binary upload and resolve from host provider\n if (options.assetProvider?.resolve) {\n hostInfo = await options.assetProvider.resolve(targetAssetId);\n }\n } else {\n // Upload or pass to onAssetImport hook\n const effectiveMeta: ManifestAssetItem = {\n ...assetItem,\n id: targetAssetId,\n };\n\n if (options.onAssetImport) {\n try {\n const result = await options.onAssetImport(targetAssetId, assetBytes, effectiveMeta);\n if (result) hostInfo = result;\n } catch (err) {\n const diag: PreflightDiagnostic = {\n code: 'HOST_ADAPTER_ERROR',\n severity: 'error',\n message: `Host asset import hook failed for \"${targetAssetId}\": ${err instanceof Error ? err.message : String(err)}`,\n path: assetItem.path,\n };\n return {\n success: false,\n errors: [diag],\n diagnosticMessage: diag.message,\n preflight,\n };\n }\n } else if (options.assetProvider?.upload) {\n try {\n const blob = new Blob([assetBytes], { type: assetItem.mimeType });\n const filename = assetItem.path.replace(/^assets\\//, '');\n const file = new File([blob], filename, { type: assetItem.mimeType });\n const info = await options.assetProvider.upload(file, {\n assetId: targetAssetId,\n originalAssetId: assetItem.id,\n });\n if (info) hostInfo = info;\n } catch {\n // Non-fatal if upload not strictly required\n }\n }\n }\n\n extractedAssets.set(targetAssetId, {\n bytes: assetBytes,\n meta: {\n ...assetItem,\n id: targetAssetId,\n },\n hostInfo,\n });\n }\n }\n\n // 7. Remap Asset References in Document if Any Assets Were Renamed\n if (Object.keys(renameMap).length > 0) {\n remapDocumentAssetReferences(finalDocument, renameMap);\n }\n\n return {\n success: true,\n document: finalDocument,\n manifest: preflight.manifest,\n metadata,\n extractedAssets,\n renamedAssets: Object.keys(renameMap).length > 0 ? renameMap : undefined,\n preflight,\n ...(importWarnings.length > 0 ? { warnings: importWarnings } : {}),\n };\n}\n\n/**\n * Alias for importPackage.\n */\nexport const importStoraPackage = importPackage;\n","import {\n PageDocument,\n PageDocumentSchema,\n CURRENT_SCHEMA_VERSION,\n SCHEMA_NAME,\n ResponsiveStyles,\n getCanonicalTextPropRule,\n} from '@kubuild/schema';\nimport { deepClone } from '../document/command-tree-utils';\nimport { validateDocument } from '../validation/validator';\nimport { stripDocumentTrackingSecretsInPlace } from './tracking-sanitizer';\n\nexport type MigrationErrorCode =\n | 'NO_MIGRATION_PATH'\n | 'UNSUPPORTED_SCHEMA_VERSION'\n | 'INVALID_SOURCE_DOCUMENT'\n | 'MIGRATION_EXECUTION_FAILED';\n\nexport interface MigrationError {\n code: MigrationErrorCode;\n message: string;\n sourceVersion: string;\n targetVersion: string;\n details?: Record<string, unknown>;\n}\n\nexport type MigrationWarningCode = 'TRACKING_SECRET_REMOVED' | 'PROP_ALIAS_MIGRATED';\n\n/**\n * Non-fatal note emitted by a migration step (the migration still succeeds).\n */\nexport interface MigrationWarning {\n code: MigrationWarningCode | (string & {});\n message: string;\n /** Step that emitted the warning, e.g. \"1.0.0->1.1.0\". */\n step?: string;\n /** Dotted document paths affected. */\n paths?: string[];\n}\n\nexport interface MigrationDiagnostic {\n success: boolean;\n sourceVersion: string;\n targetVersion: string;\n migrationPath: string[];\n stepsApplied: number;\n dryRun: boolean;\n errors?: MigrationError[];\n /** Non-fatal notes, e.g. tracking secrets stripped from the document. */\n warnings?: MigrationWarning[];\n}\n\nexport interface MigrationResult {\n success: boolean;\n document?: PageDocument;\n diagnostic: MigrationDiagnostic;\n}\n\nexport interface MigrateOptions {\n /**\n * Target schema version (defaults to CURRENT_SCHEMA_VERSION).\n */\n targetVersion?: string;\n /**\n * If true, validates path and simulates migration without modifying production data.\n */\n dryRun?: boolean;\n /**\n * Custom migration registry (defaults to defaultMigrationRegistry).\n */\n registry?: MigrationRegistry;\n /**\n * Validate document with schema validator after migration (default: true).\n */\n validate?: boolean;\n}\n\n/** Context handed to each migration step. */\nexport interface MigrationStepContext {\n /** Records a non-fatal warning on the final `MigrationDiagnostic`. */\n warn: (warning: MigrationWarning) => void;\n}\n\nexport type MigrationFunction = (\n rawDoc: Record<string, unknown>,\n context: MigrationStepContext,\n) => Record<string, unknown>;\n\nexport interface MigrationStep {\n fromVersion: string;\n toVersion: string;\n migrate: MigrationFunction;\n description?: string;\n}\n\n/**\n * Migration Registry to manage version transition steps.\n */\nexport class MigrationRegistry {\n private steps: Map<string, MigrationStep> = new Map();\n\n /**\n * Register a migration step from one version to another.\n */\n register(step: MigrationStep): void {\n const key = this.getKey(step.fromVersion, step.toVersion);\n this.steps.set(key, step);\n }\n\n private getKey(fromVersion: string, toVersion: string): string {\n return `${fromVersion}->${toVersion}`;\n }\n\n /**\n * Find shortest path of versions to migrate from source to target using BFS.\n */\n findPath(sourceVersion: string, targetVersion: string): string[] | null {\n if (sourceVersion === targetVersion) {\n return [sourceVersion];\n }\n\n const queue: { version: string; path: string[] }[] = [\n { version: sourceVersion, path: [sourceVersion] },\n ];\n const visited = new Set<string>([sourceVersion]);\n\n while (queue.length > 0) {\n const { version: currentVersion, path } = queue.shift()!;\n\n for (const step of this.steps.values()) {\n if (step.fromVersion === currentVersion) {\n const nextVersion = step.toVersion;\n if (nextVersion === targetVersion) {\n return [...path, nextVersion];\n }\n\n if (!visited.has(nextVersion)) {\n visited.add(nextVersion);\n queue.push({ version: nextVersion, path: [...path, nextVersion] });\n }\n }\n }\n }\n\n return null;\n }\n\n /**\n * Check if a valid migration path exists between source and target versions.\n */\n hasPath(sourceVersion: string, targetVersion: string): boolean {\n return this.findPath(sourceVersion, targetVersion) !== null;\n }\n\n /**\n * Get the migration step handler for a direct version step.\n */\n getStep(fromVersion: string, toVersion: string): MigrationStep | undefined {\n return this.steps.get(this.getKey(fromVersion, toVersion));\n }\n}\n\n/**\n * Helper to recursively migrate legacy flat styles: { color: 'red' } to responsive: { base: { color: 'red' } }\n */\nfunction convertNodeStylesToResponsive(node: Record<string, unknown>): void {\n if (node.styles && typeof node.styles === 'object' && !Array.isArray(node.styles)) {\n const styles = node.styles as Record<string, unknown>;\n const hasBreakpointKeys = 'base' in styles || 'desktop' in styles || 'tablet' in styles || 'mobile' in styles;\n if (!hasBreakpointKeys) {\n node.styles = {\n base: { ...styles },\n } as ResponsiveStyles;\n }\n }\n\n if (Array.isArray(node.children)) {\n for (const child of node.children) {\n if (child && typeof child === 'object') {\n convertNodeStylesToResponsive(child as Record<string, unknown>);\n }\n }\n }\n}\n\n// Built-in Default Registry\nexport const defaultMigrationRegistry = new MigrationRegistry();\n\n// 1. Migration from 0.1.0 -> 1.0.0 (Alpha to v1)\ndefaultMigrationRegistry.register({\n fromVersion: '0.1.0',\n toVersion: '1.0.0',\n description: 'Migrate alpha 0.1.0 schema (root node key, flat styles) to v1.0.0',\n migrate: (rawDoc: Record<string, unknown>) => {\n const migrated = deepClone(rawDoc);\n migrated.schema = SCHEMA_NAME;\n migrated.version = '1.0.0';\n\n // Migrate root node key: legacy used 'root' instead of 'document'\n if (migrated.root && !migrated.document) {\n migrated.document = migrated.root;\n delete migrated.root;\n }\n\n // Default metadata\n if (!migrated.metadata || typeof migrated.metadata !== 'object') {\n migrated.metadata = {\n title: 'Migrated Page',\n description: '',\n author: '',\n tags: [],\n category: 'general',\n version: '1.0.0',\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n };\n } else {\n const meta = migrated.metadata as Record<string, unknown>;\n meta.title = meta.title || 'Migrated Page';\n meta.tags = Array.isArray(meta.tags) ? meta.tags : [];\n meta.version = '1.0.0';\n }\n\n // Migrate node tree flat styles\n if (migrated.document && typeof migrated.document === 'object') {\n convertNodeStylesToResponsive(migrated.document as Record<string, unknown>);\n }\n\n return migrated;\n },\n});\n\n// 2. Migration from 0.2.0 -> 1.0.0\ndefaultMigrationRegistry.register({\n fromVersion: '0.2.0',\n toVersion: '1.0.0',\n description: 'Migrate 0.2.0 schema to v1.0.0',\n migrate: (rawDoc: Record<string, unknown>) => {\n const migrated = deepClone(rawDoc);\n migrated.schema = SCHEMA_NAME;\n migrated.version = '1.0.0';\n\n if (migrated.document && typeof migrated.document === 'object') {\n convertNodeStylesToResponsive(migrated.document as Record<string, unknown>);\n }\n\n return migrated;\n },\n});\n\n// 3. Migration from 0.9.0 -> 1.0.0 (Beta to v1)\ndefaultMigrationRegistry.register({\n fromVersion: '0.9.0',\n toVersion: '1.0.0',\n description: 'Migrate 0.9.0 beta schema to v1.0.0',\n migrate: (rawDoc: Record<string, unknown>) => {\n const migrated = deepClone(rawDoc);\n migrated.schema = SCHEMA_NAME;\n migrated.version = '1.0.0';\n\n if (!migrated.metadata || typeof migrated.metadata !== 'object') {\n migrated.metadata = {\n title: 'Migrated Page',\n description: '',\n author: '',\n tags: [],\n category: 'general',\n version: '1.0.0',\n };\n }\n\n return migrated;\n },\n});\n\n// 4. Shorthand \"1.0\" -> \"1.0.0\"\ndefaultMigrationRegistry.register({\n fromVersion: '1.0',\n toVersion: '1.0.0',\n description: 'Normalize 1.0 version string to 1.0.0',\n migrate: (rawDoc: Record<string, unknown>) => {\n const migrated = deepClone(rawDoc);\n migrated.version = '1.0.0';\n return migrated;\n },\n});\n\n// 5. 1.0.0 -> 1.1.0: tracking secrets move out of the document (host-owned, resolved by credentialId)\ndefaultMigrationRegistry.register({\n fromVersion: '1.0.0',\n toVersion: '1.1.0',\n description:\n 'Remove tracking secrets and server destinations (capiAccessToken, accessToken, measurementProtocolSecret, serverRelayUrl, custom endpointUrl/headers) from the document',\n migrate: (rawDoc: Record<string, unknown>, context) => {\n const migrated = deepClone(rawDoc);\n migrated.version = '1.1.0';\n const removed = stripDocumentTrackingSecretsInPlace(migrated);\n if (removed.length > 0) {\n context.warn({\n code: 'TRACKING_SECRET_REMOVED',\n message:\n 'Tracking secret removed; re-link credential via credentialId (secrets are now stored by the host and resolved server-side).',\n step: '1.0.0->1.1.0',\n paths: removed,\n });\n }\n return migrated;\n },\n});\n\n/**\n * Moves deprecated text-prop aliases (`content`, `label`, `quote`, ...) onto each\n * component's canonical prop name (STORA-550), in place. The canonical value becomes\n * whatever the pre-1.2.0 renderer actually displayed (its `legacyReadOrder`), so a\n * migrated document renders identically. Returns the dotted paths of rewritten props.\n */\nexport function canonicalizeTextPropsInPlace(root: unknown, basePath = 'document'): string[] {\n const changed: string[] = [];\n\n const walk = (value: unknown, path: string): void => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return;\n const node = value as Record<string, unknown>;\n const props = node.props;\n const rule = typeof node.type === 'string' ? getCanonicalTextPropRule(node.type) : undefined;\n\n if (rule && props && typeof props === 'object' && !Array.isArray(props)) {\n const record = props as Record<string, unknown>;\n const presentAliases = rule.aliases.filter((alias) => record[alias] !== undefined);\n if (presentAliases.length > 0) {\n const displayedKey = rule.legacyReadOrder.find((key) => record[key] !== undefined);\n // A legacy `text` node whose only text lived in `content` rendered as <p>, not <span>;\n // keep that when the tag was implicit.\n if (\n node.type === 'text' &&\n displayedKey === 'content' &&\n record.as === undefined &&\n record.tag === undefined\n ) {\n record.as = 'p';\n }\n if (displayedKey !== undefined && displayedKey !== rule.canonical) {\n record[rule.canonical] = record[displayedKey];\n }\n for (const alias of presentAliases) {\n delete record[alias];\n changed.push(`${path}.props.${alias}`);\n }\n }\n }\n\n if (Array.isArray(node.children)) {\n node.children.forEach((child, index) => walk(child, `${path}.children.${index}`));\n }\n };\n\n walk(root, basePath);\n return changed;\n}\n\n// 6. 1.1.0 -> 1.2.0: canonical text prop names (STORA-550); `theme` becomes a known field (STORA-551)\ndefaultMigrationRegistry.register({\n fromVersion: '1.1.0',\n toVersion: '1.2.0',\n description:\n 'Rename deprecated text prop aliases to canonical names (heading/text/paragraph/link/badge/blockquote -> text, button -> label)',\n migrate: (rawDoc: Record<string, unknown>, context) => {\n const migrated = deepClone(rawDoc);\n migrated.version = '1.2.0';\n const changed = canonicalizeTextPropsInPlace(migrated.document);\n if (changed.length > 0) {\n context.warn({\n code: 'PROP_ALIAS_MIGRATED',\n message: 'Deprecated text prop aliases were renamed to their canonical names.',\n step: '1.1.0->1.2.0',\n paths: changed,\n });\n }\n return migrated;\n },\n});\n\n/**\n * Check whether a migration path exists between source and target versions.\n */\nexport function canMigrate(\n sourceVersion: string,\n targetVersion: string = CURRENT_SCHEMA_VERSION,\n registry: MigrationRegistry = defaultMigrationRegistry,\n): boolean {\n if (!sourceVersion || !targetVersion) return false;\n if (sourceVersion === targetVersion) return true;\n return registry.hasPath(sourceVersion, targetVersion);\n}\n\n/**\n * Get the sequence of versions forming the migration path.\n */\nexport function getMigrationPath(\n sourceVersion: string,\n targetVersion: string = CURRENT_SCHEMA_VERSION,\n registry: MigrationRegistry = defaultMigrationRegistry,\n): string[] | null {\n if (!sourceVersion || !targetVersion) return null;\n return registry.findPath(sourceVersion, targetVersion);\n}\n\n/**\n * Migrate a page document from an older schema version to current (or specified) schema version.\n * Supports dry-run execution, step diagnostics, and structured error reporting.\n */\nexport function migrateDocument(\n rawDocument: unknown,\n options: MigrateOptions = {},\n): MigrationResult {\n const targetVersion = options.targetVersion ?? CURRENT_SCHEMA_VERSION;\n const dryRun = options.dryRun ?? false;\n const registry = options.registry ?? defaultMigrationRegistry;\n const validate = options.validate ?? true;\n\n // 1. Basic object validation\n if (!rawDocument || typeof rawDocument !== 'object' || Array.isArray(rawDocument)) {\n const error: MigrationError = {\n code: 'INVALID_SOURCE_DOCUMENT',\n message: 'Source document must be a non-null object.',\n sourceVersion: 'unknown',\n targetVersion,\n };\n return {\n success: false,\n diagnostic: {\n success: false,\n sourceVersion: 'unknown',\n targetVersion,\n migrationPath: [],\n stepsApplied: 0,\n dryRun,\n errors: [error],\n },\n };\n }\n\n const doc = rawDocument as Record<string, unknown>;\n const sourceVersion = typeof doc.version === 'string' ? doc.version.trim() : 'unknown';\n\n // 2. If already on target version\n if (sourceVersion === targetVersion) {\n const cloned = deepClone(doc) as unknown as PageDocument;\n // Defensive: a current-version document must never carry tracking secrets either.\n const removedSecrets = stripDocumentTrackingSecretsInPlace(cloned);\n const currentWarnings: MigrationWarning[] =\n removedSecrets.length > 0\n ? [\n {\n code: 'TRACKING_SECRET_REMOVED',\n message:\n 'Tracking secret removed; re-link credential via credentialId (secrets are stored by the host and resolved server-side).',\n paths: removedSecrets,\n },\n ]\n : [];\n if (validate) {\n const validation = validateDocument(cloned);\n if (!validation.valid) {\n return {\n success: false,\n diagnostic: {\n success: false,\n sourceVersion,\n targetVersion,\n migrationPath: [sourceVersion],\n stepsApplied: 0,\n dryRun,\n errors: validation.errors.map((e) => ({\n code: 'INVALID_SOURCE_DOCUMENT',\n message: `Validation error: ${e.message} at ${e.path}`,\n sourceVersion,\n targetVersion,\n })),\n },\n };\n }\n }\n\n return {\n success: true,\n document: cloned,\n diagnostic: {\n success: true,\n sourceVersion,\n targetVersion,\n migrationPath: [sourceVersion],\n stepsApplied: 0,\n dryRun,\n ...(currentWarnings.length > 0 ? { warnings: currentWarnings } : {}),\n },\n };\n }\n\n // 3. Find migration path\n const path = registry.findPath(sourceVersion, targetVersion);\n if (!path || path.length <= 1) {\n const error: MigrationError = {\n code: 'NO_MIGRATION_PATH',\n message: `No migration path found from schema version \"${sourceVersion}\" to \"${targetVersion}\".`,\n sourceVersion,\n targetVersion,\n };\n return {\n success: false,\n diagnostic: {\n success: false,\n sourceVersion,\n targetVersion,\n migrationPath: [],\n stepsApplied: 0,\n dryRun,\n errors: [error],\n },\n };\n }\n\n // 4. If dry-run mode, simulate the steps on a private clone (so the diagnostic can report\n // what *would* change) and return without producing a document.\n if (dryRun) {\n const simulatedWarnings: MigrationWarning[] = [];\n try {\n let simulated = deepClone(doc);\n for (let i = 0; i < path.length - 1; i++) {\n const step = registry.getStep(path[i], path[i + 1]);\n if (!step) break;\n simulated = step.migrate(simulated, { warn: (w) => simulatedWarnings.push(w) });\n }\n } catch {\n // Simulation is best-effort; the real run reports execution failures.\n }\n return {\n success: true,\n diagnostic: {\n success: true,\n sourceVersion,\n targetVersion,\n migrationPath: path,\n stepsApplied: path.length - 1,\n dryRun: true,\n ...(simulatedWarnings.length > 0 ? { warnings: simulatedWarnings } : {}),\n },\n };\n }\n\n // 5. Execute migration path steps sequentially\n let currentDoc = deepClone(doc);\n let stepsApplied = 0;\n const warnings: MigrationWarning[] = [];\n const stepContext: MigrationStepContext = { warn: (w) => warnings.push(w) };\n\n for (let i = 0; i < path.length - 1; i++) {\n const fromVer = path[i];\n const toVer = path[i + 1];\n const step = registry.getStep(fromVer, toVer);\n\n if (!step) {\n const error: MigrationError = {\n code: 'MIGRATION_EXECUTION_FAILED',\n message: `Registered migration step for \"${fromVer}\" -> \"${toVer}\" is missing executor.`,\n sourceVersion,\n targetVersion,\n };\n return {\n success: false,\n diagnostic: {\n success: false,\n sourceVersion,\n targetVersion,\n migrationPath: path,\n stepsApplied,\n dryRun,\n errors: [error],\n },\n };\n }\n\n try {\n currentDoc = step.migrate(currentDoc, stepContext);\n stepsApplied++;\n } catch (err: unknown) {\n const error: MigrationError = {\n code: 'MIGRATION_EXECUTION_FAILED',\n message: `Failed executing migration step from \"${fromVer}\" to \"${toVer}\": ${err instanceof Error ? err.message : String(err)}`,\n sourceVersion,\n targetVersion,\n details: { stepFrom: fromVer, stepTo: toVer },\n };\n return {\n success: false,\n diagnostic: {\n success: false,\n sourceVersion,\n targetVersion,\n migrationPath: path,\n stepsApplied,\n dryRun,\n errors: [error],\n },\n };\n }\n }\n\n // 6. Validate final migrated document\n const finalDoc = currentDoc as unknown as PageDocument;\n if (validate) {\n const validation = validateDocument(finalDoc);\n if (!validation.valid) {\n return {\n success: false,\n diagnostic: {\n success: false,\n sourceVersion,\n targetVersion,\n migrationPath: path,\n stepsApplied,\n dryRun,\n errors: validation.errors.map((e) => ({\n code: 'MIGRATION_EXECUTION_FAILED',\n message: `Post-migration validation error: ${e.message} at ${e.path}`,\n sourceVersion,\n targetVersion,\n })),\n },\n };\n }\n }\n\n return {\n success: true,\n document: finalDoc,\n diagnostic: {\n success: true,\n sourceVersion,\n targetVersion,\n migrationPath: path,\n stepsApplied,\n dryRun: false,\n ...(warnings.length > 0 ? { warnings } : {}),\n },\n };\n}\n","import {\n Artboard,\n PageDocument,\n ProjectDocument,\n ProjectDocumentSchema,\n PROJECT_SCHEMA_NAME,\n CURRENT_PROJECT_SCHEMA_VERSION,\n CURRENT_SCHEMA_VERSION,\n looksLikeProjectDocument,\n} from '@kubuild/schema';\nimport { canMigrate, migrateDocument, MigrationError } from './migration';\n\n/**\n * Brings every artboard's embedded page document up to the current page schema version\n * (e.g. canonical text prop names, STORA-550). Best-effort: an artboard whose migration\n * fails is left untouched rather than failing the whole project load.\n */\nfunction migrateProjectArtboards(project: ProjectDocument): ProjectDocument {\n let changed = false;\n const artboards = project.artboards.map((artboard) => {\n const version = artboard.document.version;\n if (version === CURRENT_SCHEMA_VERSION || !canMigrate(version)) return artboard;\n const migration = migrateDocument(artboard.document);\n if (!migration.success || !migration.document) return artboard;\n changed = true;\n return { ...artboard, document: migration.document };\n });\n return changed ? { ...project, artboards } : project;\n}\n\nexport type ProjectLoadErrorCode =\n | 'INVALID_SOURCE'\n | 'PROJECT_SCHEMA_INVALID'\n | 'LEGACY_MIGRATION_FAILED';\n\nexport interface ProjectLoadError {\n code: ProjectLoadErrorCode;\n message: string;\n details?: Record<string, unknown>;\n}\n\nexport interface ProjectLoadResult {\n success: boolean;\n project?: ProjectDocument;\n /** True when the payload arrived as a legacy single-page document and was wrapped. */\n wrappedFromLegacyPage: boolean;\n errors: ProjectLoadError[];\n}\n\nexport interface WrapPageAsProjectOptions {\n artboardId?: string;\n name?: string;\n slug?: string;\n width?: number;\n}\n\nconst DEFAULT_PAGE_ARTBOARD_ID = 'artboard-page-1';\n\n/**\n * Wrap a single PageDocument into a one-artboard ProjectDocument.\n * Used both by the legacy load path and by consumers that still hold a lone page.\n */\nexport function wrapPageDocumentAsProject(\n document: PageDocument,\n options: WrapPageAsProjectOptions = {},\n): ProjectDocument {\n const artboardId = options.artboardId ?? DEFAULT_PAGE_ARTBOARD_ID;\n const artboard: Artboard = {\n id: artboardId,\n name: options.name ?? document.metadata?.title ?? 'Page',\n artboardType: 'page',\n slug: options.slug ?? '/',\n document,\n ...(options.width !== undefined ? { width: options.width } : {}),\n };\n\n return {\n schema: PROJECT_SCHEMA_NAME,\n version: CURRENT_PROJECT_SCHEMA_VERSION,\n metadata: document.metadata,\n artboards: [artboard],\n activeArtboardId: artboardId,\n };\n}\n\n/**\n * Load a raw payload as a ProjectDocument.\n *\n * `PageDocument -> ProjectDocument` is a schema *kind* switch (`document` singular vs.\n * `artboards[]`, different `schema` literal), not a version step, so it cannot be expressed\n * as a MigrationRegistry step. This loader sniffs the shape and routes accordingly:\n *\n * - already a project (`schema === 'stora.project'` or has `artboards[]`) -> parse as a project\n * - anything else -> run the existing page migration pipeline untouched, then wrap the\n * fully-migrated page into a single-artboard project\n *\n * Legacy inline modal/drawer/collapsible nodes are deliberately NOT auto-extracted into\n * component artboards here; that stays an explicit, author-triggered action so no existing\n * document silently changes how it renders.\n */\nexport function loadProjectDocument(raw: unknown): ProjectLoadResult {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n return {\n success: false,\n wrappedFromLegacyPage: false,\n errors: [\n {\n code: 'INVALID_SOURCE',\n message: 'Source must be a non-null object.',\n },\n ],\n };\n }\n\n if (looksLikeProjectDocument(raw)) {\n const parsed = ProjectDocumentSchema.safeParse(raw);\n if (!parsed.success) {\n return {\n success: false,\n wrappedFromLegacyPage: false,\n errors: [\n {\n code: 'PROJECT_SCHEMA_INVALID',\n message: 'Payload looks like a project document but failed schema validation.',\n details: { issues: parsed.error.issues },\n },\n ],\n };\n }\n return {\n success: true,\n project: migrateProjectArtboards(parsed.data),\n wrappedFromLegacyPage: false,\n errors: [],\n };\n }\n\n const migration = migrateDocument(raw);\n if (!migration.success || !migration.document) {\n return {\n success: false,\n wrappedFromLegacyPage: false,\n errors: [\n {\n code: 'LEGACY_MIGRATION_FAILED',\n message: 'Payload is not a project document and could not be migrated as a page document.',\n details: {\n migrationErrors: (migration.diagnostic.errors ?? []) as MigrationError[],\n },\n },\n ],\n };\n }\n\n return {\n success: true,\n project: wrapPageDocumentAsProject(migration.document),\n wrappedFromLegacyPage: true,\n errors: [],\n };\n}\n","import {\n PageDocument,\n Node,\n ResponsiveStyles,\n StyleDefinition,\n Manifest,\n VariableBinding,\n ActionBinding,\n AssetReference,\n} from '@kubuild/schema';\n\nexport type SemanticDifferenceKind =\n | 'METADATA_MISMATCH'\n | 'NODE_MISSING'\n | 'NODE_EXTRA'\n | 'NODE_ORDER'\n | 'NODE_TYPE'\n | 'PROP_MISMATCH'\n | 'STYLE_MISMATCH'\n | 'BINDING_MISMATCH'\n | 'ACTION_MISMATCH'\n | 'ASSET_MISMATCH'\n | 'DEPENDENCY_MISMATCH';\n\nexport interface SemanticDifference {\n path: string;\n kind: SemanticDifferenceKind;\n message: string;\n expected?: unknown;\n actual?: unknown;\n}\n\nexport interface SemanticCompareOptions {\n /**\n * Optional map of original asset IDs to host-remapped asset IDs.\n * Used when host renamed colliding assets during import.\n */\n assetIdMap?: Record<string, string> | Map<string, string>;\n\n /**\n * Whether to ignore transient timestamp fields (e.g. createdAt/updatedAt).\n * Default: true.\n */\n ignoreTimestamps?: boolean;\n}\n\nexport interface SemanticComparisonResult {\n equivalent: boolean;\n differences: SemanticDifference[];\n}\n\nfunction isAssetReferenceLike(val: unknown): val is AssetReference {\n if (!val || typeof val !== 'object') return false;\n const obj = val as Record<string, unknown>;\n return obj.type === 'asset' && typeof obj.assetId === 'string' && obj.assetId.trim().length > 0;\n}\n\nfunction isVariableBindingLike(val: unknown): val is VariableBinding {\n if (!val || typeof val !== 'object') return false;\n const obj = val as Record<string, unknown>;\n return obj.type === 'variable' && typeof obj.key === 'string' && obj.key.trim().length > 0;\n}\n\nfunction isActionBindingLike(val: unknown): val is ActionBinding {\n if (!val || typeof val !== 'object') return false;\n const obj = val as Record<string, unknown>;\n return obj.type !== undefined && typeof obj.type === 'string' && obj.type.trim().length > 0 && ('payload' in obj || Object.keys(obj).length <= 2);\n}\n\nfunction normalizeAssetId(\n id: string,\n assetIdMap?: Record<string, string> | Map<string, string>,\n): string {\n if (!assetIdMap) return id;\n if (assetIdMap instanceof Map) {\n return assetIdMap.get(id) ?? id;\n }\n return assetIdMap[id] ?? id;\n}\n\nfunction deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (a === null || b === null || typeof a !== 'object' || typeof b !== 'object') {\n return false;\n }\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (!deepEqual(a[i], b[i])) return false;\n }\n return true;\n }\n\n const objA = a as Record<string, unknown>;\n const objB = b as Record<string, unknown>;\n const keysA = Object.keys(objA);\n const keysB = Object.keys(objB);\n\n if (keysA.length !== keysB.length) return false;\n for (const k of keysA) {\n if (!Object.prototype.hasOwnProperty.call(objB, k)) return false;\n if (!deepEqual(objA[k], objB[k])) return false;\n }\n return true;\n}\n\n/**\n * Recursively compares two props values, checking for variable bindings, action bindings,\n * and asset references (with asset ID mapping support).\n */\nfunction comparePropValues(\n path: string,\n expected: unknown,\n actual: unknown,\n differences: SemanticDifference[],\n options?: SemanticCompareOptions,\n): void {\n // 1. Variable Binding check\n if (isVariableBindingLike(expected)) {\n if (!isVariableBindingLike(actual)) {\n differences.push({\n path,\n kind: 'BINDING_MISMATCH',\n message: `Expected variable binding at \"${path}\", but got non-binding value.`,\n expected,\n actual,\n });\n return;\n }\n const expBinding = expected as VariableBinding;\n const actBinding = actual as VariableBinding;\n if (expBinding.key !== actBinding.key) {\n differences.push({\n path: `${path}.key`,\n kind: 'BINDING_MISMATCH',\n message: `Variable binding key mismatch at \"${path}\": expected \"${expBinding.key}\", got \"${actBinding.key}\".`,\n expected: expBinding.key,\n actual: actBinding.key,\n });\n }\n if (!deepEqual(expBinding.fallback, actBinding.fallback)) {\n differences.push({\n path: `${path}.fallback`,\n kind: 'BINDING_MISMATCH',\n message: `Variable binding fallback mismatch at \"${path}\".`,\n expected: expBinding.fallback,\n actual: actBinding.fallback,\n });\n }\n return;\n }\n\n // 2. Action Binding check\n if (isActionBindingLike(expected) && !isAssetReferenceLike(expected) && !isVariableBindingLike(expected)) {\n if (!isActionBindingLike(actual)) {\n differences.push({\n path,\n kind: 'ACTION_MISMATCH',\n message: `Expected action binding at \"${path}\", but got non-action value.`,\n expected,\n actual,\n });\n return;\n }\n const expAction = expected as ActionBinding;\n const actAction = actual as ActionBinding;\n if (expAction.type !== actAction.type) {\n differences.push({\n path: `${path}.type`,\n kind: 'ACTION_MISMATCH',\n message: `Action binding type mismatch at \"${path}\": expected \"${expAction.type}\", got \"${actAction.type}\".`,\n expected: expAction.type,\n actual: actAction.type,\n });\n }\n if (!deepEqual(expAction.payload ?? {}, actAction.payload ?? {})) {\n differences.push({\n path: `${path}.payload`,\n kind: 'ACTION_MISMATCH',\n message: `Action binding payload mismatch at \"${path}\".`,\n expected: expAction.payload,\n actual: actAction.payload,\n });\n }\n return;\n }\n\n // 3. Asset Reference check\n if (isAssetReferenceLike(expected)) {\n if (!isAssetReferenceLike(actual)) {\n differences.push({\n path,\n kind: 'ASSET_MISMATCH',\n message: `Expected asset reference at \"${path}\", but got non-asset value.`,\n expected,\n actual,\n });\n return;\n }\n const expAsset = expected as AssetReference;\n const actAsset = actual as AssetReference;\n const expectedMappedId = normalizeAssetId(expAsset.assetId, options?.assetIdMap);\n\n if (actAsset.assetId !== expectedMappedId) {\n differences.push({\n path: `${path}.assetId`,\n kind: 'ASSET_MISMATCH',\n message: `Asset reference ID mismatch at \"${path}\": expected \"${expectedMappedId}\" (original: \"${expAsset.assetId}\"), got \"${actAsset.assetId}\".`,\n expected: expectedMappedId,\n actual: actAsset.assetId,\n });\n }\n if (expAsset.filename !== actAsset.filename) {\n differences.push({\n path: `${path}.filename`,\n kind: 'ASSET_MISMATCH',\n message: `Asset reference filename mismatch at \"${path}\": expected \"${expAsset.filename}\", got \"${actAsset.filename}\".`,\n expected: expAsset.filename,\n actual: actAsset.filename,\n });\n }\n if (expAsset.mimeType !== actAsset.mimeType) {\n differences.push({\n path: `${path}.mimeType`,\n kind: 'ASSET_MISMATCH',\n message: `Asset reference mimeType mismatch at \"${path}\": expected \"${expAsset.mimeType}\", got \"${actAsset.mimeType}\".`,\n expected: expAsset.mimeType,\n actual: actAsset.mimeType,\n });\n }\n return;\n }\n\n // 4. Object recursion\n if (\n expected !== null &&\n actual !== null &&\n typeof expected === 'object' &&\n typeof actual === 'object'\n ) {\n if (Array.isArray(expected) !== Array.isArray(actual)) {\n differences.push({\n path,\n kind: 'PROP_MISMATCH',\n message: `Type mismatch at \"${path}\": one is array, other is object.`,\n expected,\n actual,\n });\n return;\n }\n\n if (Array.isArray(expected) && Array.isArray(actual)) {\n if (expected.length !== actual.length) {\n differences.push({\n path,\n kind: 'PROP_MISMATCH',\n message: `Array length mismatch at \"${path}\": expected length ${expected.length}, got ${actual.length}.`,\n expected,\n actual,\n });\n return;\n }\n for (let i = 0; i < expected.length; i++) {\n comparePropValues(`${path}[${i}]`, expected[i], actual[i], differences, options);\n }\n return;\n }\n\n const expObj = expected as Record<string, unknown>;\n const actObj = actual as Record<string, unknown>;\n const allKeys = new Set([...Object.keys(expObj), ...Object.keys(actObj)]);\n\n for (const key of allKeys) {\n if (!(key in expObj)) {\n differences.push({\n path: `${path}.${key}`,\n kind: 'PROP_MISMATCH',\n message: `Unexpected extra prop key \"${key}\" at \"${path}\".`,\n actual: actObj[key],\n });\n } else if (!(key in actObj)) {\n differences.push({\n path: `${path}.${key}`,\n kind: 'PROP_MISMATCH',\n message: `Missing expected prop key \"${key}\" at \"${path}\".`,\n expected: expObj[key],\n });\n } else {\n comparePropValues(`${path}.${key}`, expObj[key], actObj[key], differences, options);\n }\n }\n return;\n }\n\n // 5. Primitive equality check\n if (expected !== actual) {\n differences.push({\n path,\n kind: 'PROP_MISMATCH',\n message: `Value mismatch at \"${path}\": expected \"${String(expected)}\", got \"${String(actual)}\".`,\n expected,\n actual,\n });\n }\n}\n\n/**\n * Compares responsive styles across all breakpoints (base, desktop, tablet, mobile).\n */\nfunction compareStyles(\n nodePath: string,\n expected?: ResponsiveStyles,\n actual?: ResponsiveStyles,\n differences: SemanticDifference[] = [],\n): void {\n const breakpoints = ['base', 'desktop', 'tablet', 'mobile'] as const;\n const expStyles = expected || {};\n const actStyles = actual || {};\n\n for (const bp of breakpoints) {\n const expBp = (expStyles[bp] as StyleDefinition | undefined) || {};\n const actBp = (actStyles[bp] as StyleDefinition | undefined) || {};\n\n const allKeys = new Set([...Object.keys(expBp), ...Object.keys(actBp)]);\n for (const key of allKeys) {\n const expVal = expBp[key];\n const actVal = actBp[key];\n\n // Treat undefined and empty string as equivalent empty style values\n const expNorm = expVal === undefined || expVal === '' ? undefined : expVal;\n const actNorm = actVal === undefined || actVal === '' ? undefined : actVal;\n\n if (expNorm !== actNorm) {\n differences.push({\n path: `${nodePath}.styles.${bp}.${key}`,\n kind: 'STYLE_MISMATCH',\n message: `Style mismatch at \"${nodePath}.styles.${bp}.${key}\": expected \"${String(expVal)}\", got \"${String(actVal)}\".`,\n expected: expVal,\n actual: actVal,\n });\n }\n }\n }\n}\n\n/**\n * Recursively compares two component trees, strictly verifying node identity, order,\n * props, styles, and children.\n */\nfunction compareNodes(\n expected: Node,\n actual: Node,\n nodePath: string,\n differences: SemanticDifference[],\n options?: SemanticCompareOptions,\n): void {\n // 1. Check ID\n if (expected.id !== actual.id) {\n differences.push({\n path: `${nodePath}.id`,\n kind: 'NODE_MISSING',\n message: `Node ID mismatch at \"${nodePath}\": expected \"${expected.id}\", got \"${actual.id}\".`,\n expected: expected.id,\n actual: actual.id,\n });\n }\n\n // 2. Check Type\n if (expected.type !== actual.type) {\n differences.push({\n path: `${nodePath}.type`,\n kind: 'NODE_TYPE',\n message: `Node type mismatch for \"${expected.id}\": expected \"${expected.type}\", got \"${actual.type}\".`,\n expected: expected.type,\n actual: actual.type,\n });\n }\n\n // 3. Compare Props\n comparePropValues(`${nodePath}.props`, expected.props || {}, actual.props || {}, differences, options);\n\n // 4. Compare Styles\n compareStyles(nodePath, expected.styles, actual.styles, differences);\n\n // 5. Compare Children (Order and Content)\n const expChildren = expected.children || [];\n const actChildren = actual.children || [];\n\n if (expChildren.length !== actChildren.length) {\n differences.push({\n path: `${nodePath}.children`,\n kind: 'NODE_ORDER',\n message: `Children count mismatch for node \"${expected.id}\": expected ${expChildren.length}, got ${actChildren.length}.`,\n expected: expChildren.map((c) => c.id),\n actual: actChildren.map((c) => c.id),\n });\n }\n\n const maxLen = Math.max(expChildren.length, actChildren.length);\n for (let i = 0; i < maxLen; i++) {\n const expChild = expChildren[i];\n const actChild = actChildren[i];\n\n if (!expChild && actChild) {\n differences.push({\n path: `${nodePath}.children[${i}]`,\n kind: 'NODE_EXTRA',\n message: `Unexpected extra child node \"${actChild.id}\" at index ${i}.`,\n actual: actChild.id,\n });\n } else if (expChild && !actChild) {\n differences.push({\n path: `${nodePath}.children[${i}]`,\n kind: 'NODE_MISSING',\n message: `Missing child node \"${expChild.id}\" at index ${i}.`,\n expected: expChild.id,\n });\n } else if (expChild && actChild) {\n if (expChild.id !== actChild.id) {\n differences.push({\n path: `${nodePath}.children[${i}]`,\n kind: 'NODE_ORDER',\n message: `Node order mismatch at index ${i}: expected node \"${expChild.id}\", got \"${actChild.id}\".`,\n expected: expChild.id,\n actual: actChild.id,\n });\n }\n compareNodes(expChild, actChild, `${nodePath}.children[${i}](${expChild.id})`, differences, options);\n }\n }\n}\n\n/**\n * Semantically compares two PageDocuments, checking metadata, tree structure,\n * node order, props, responsive styles, bindings, action references, and asset mappings.\n *\n * Only documented transient fields (e.g. transient timestamps, host-generated asset IDs)\n * are ignored or normalized per options.\n */\nexport function compareDocumentsSemantically(\n expected: PageDocument,\n actual: PageDocument,\n options: SemanticCompareOptions = {},\n): SemanticComparisonResult {\n const differences: SemanticDifference[] = [];\n const { ignoreTimestamps = true } = options;\n\n // 1. Schema & Version check\n if (expected.schema !== actual.schema) {\n differences.push({\n path: 'schema',\n kind: 'METADATA_MISMATCH',\n message: `Schema mismatch: expected \"${expected.schema}\", got \"${actual.schema}\".`,\n expected: expected.schema,\n actual: actual.schema,\n });\n }\n if (expected.version !== actual.version) {\n differences.push({\n path: 'version',\n kind: 'METADATA_MISMATCH',\n message: `Schema version mismatch: expected \"${expected.version}\", got \"${actual.version}\".`,\n expected: expected.version,\n actual: actual.version,\n });\n }\n\n // 2. Metadata check\n const expMeta = expected.metadata || ({} as Record<string, unknown>);\n const actMeta = actual.metadata || ({} as Record<string, unknown>);\n const metaKeys = new Set([...Object.keys(expMeta), ...Object.keys(actMeta)]);\n\n for (const k of metaKeys) {\n if (ignoreTimestamps && (k === 'updatedAt' || k === 'createdAt')) {\n continue;\n }\n const expVal = (expMeta as Record<string, unknown>)[k];\n const actVal = (actMeta as Record<string, unknown>)[k];\n if (!deepEqual(expVal, actVal)) {\n differences.push({\n path: `metadata.${k}`,\n kind: 'METADATA_MISMATCH',\n message: `Metadata mismatch at \"metadata.${k}\": expected \"${String(expVal)}\", got \"${String(actVal)}\".`,\n expected: expVal,\n actual: actVal,\n });\n }\n }\n\n // 3. Tree comparison\n compareNodes(\n expected.document,\n actual.document,\n `root(${expected.document.id})`,\n differences,\n options,\n );\n\n return {\n equivalent: differences.length === 0,\n differences,\n };\n}\n\n/**\n * Semantically compares exported and imported package manifests.\n */\nexport function compareManifestsSemantically(\n expected: Manifest,\n actual: Manifest,\n options: SemanticCompareOptions = {},\n): SemanticComparisonResult {\n const differences: SemanticDifference[] = [];\n const { ignoreTimestamps = true } = options;\n\n if (expected.schema !== actual.schema) {\n differences.push({\n path: 'manifest.schema',\n kind: 'METADATA_MISMATCH',\n message: `Manifest schema mismatch: expected \"${expected.schema}\", got \"${actual.schema}\".`,\n expected: expected.schema,\n actual: actual.schema,\n });\n }\n\n if (expected.schemaVersion !== actual.schemaVersion) {\n differences.push({\n path: 'manifest.schemaVersion',\n kind: 'METADATA_MISMATCH',\n message: `Manifest schemaVersion mismatch: expected \"${expected.schemaVersion}\", got \"${actual.schemaVersion}\".`,\n expected: expected.schemaVersion,\n actual: actual.schemaVersion,\n });\n }\n\n // Compare requiredComponents\n const expComponents = new Set(expected.requiredComponents || []);\n const actComponents = new Set(actual.requiredComponents || []);\n for (const c of expComponents) {\n if (!actComponents.has(c)) {\n differences.push({\n path: 'manifest.requiredComponents',\n kind: 'DEPENDENCY_MISMATCH',\n message: `Missing required component in manifest: \"${c}\".`,\n expected: c,\n });\n }\n }\n for (const c of actComponents) {\n if (!expComponents.has(c)) {\n differences.push({\n path: 'manifest.requiredComponents',\n kind: 'DEPENDENCY_MISMATCH',\n message: `Unexpected extra required component in manifest: \"${c}\".`,\n actual: c,\n });\n }\n }\n\n // Compare requiredCapabilities\n const expCaps = new Set(expected.requiredCapabilities || []);\n const actCaps = new Set(actual.requiredCapabilities || []);\n for (const c of expCaps) {\n if (!actCaps.has(c)) {\n differences.push({\n path: 'manifest.requiredCapabilities',\n kind: 'DEPENDENCY_MISMATCH',\n message: `Missing required capability in manifest: \"${c}\".`,\n expected: c,\n });\n }\n }\n for (const c of actCaps) {\n if (!expCaps.has(c)) {\n differences.push({\n path: 'manifest.requiredCapabilities',\n kind: 'DEPENDENCY_MISMATCH',\n message: `Unexpected extra required capability in manifest: \"${c}\".`,\n actual: c,\n });\n }\n }\n\n // Compare assets\n if (expected.assets.length !== actual.assets.length) {\n differences.push({\n path: 'manifest.assets',\n kind: 'ASSET_MISMATCH',\n message: `Manifest asset count mismatch: expected ${expected.assets.length}, got ${actual.assets.length}.`,\n expected: expected.assets.length,\n actual: actual.assets.length,\n });\n }\n\n return {\n equivalent: differences.length === 0,\n differences,\n };\n}\n","import {\n TemplateRecordSchema,\n BUILTIN_COMPONENT_TYPES,\n collectNodeIds,\n isTemplateRecord,\n type TemplateRecord,\n type TemplateRequirements,\n type PageDocument,\n type Node,\n} from '@kubuild/schema';\nimport { deepClone, cloneNodeTreeWithFreshIds } from '../document/command-tree-utils';\nimport { validateDocument } from '../validation/validator';\n\n/**\n * Built-in component types (everything `createDefaultComponentRegistry()` registers).\n * Derived from the canonical `BUILTIN_COMPONENT_TYPES` in `@kubuild/schema`; a test in\n * `@kubuild/components` asserts this set equals the default registry's types.\n */\nexport const CORE_BUILTIN_COMPONENTS: ReadonlySet<string> = new Set<string>(BUILTIN_COMPONENT_TYPES);\n\n/**\n * Structured validation error entry\n */\nexport interface TemplateValidationError {\n code: string;\n message: string;\n path: string;\n}\n\n/**\n * Result of template record validation\n */\nexport interface TemplateValidationResult {\n valid: boolean;\n data?: TemplateRecord;\n errors?: TemplateValidationError[];\n}\n\n/**\n * Validates a template record value against TemplateRecordSchema and returns structured errors.\n */\nexport function validateTemplate(value: unknown): TemplateValidationResult {\n const parseResult = TemplateRecordSchema.safeParse(value);\n\n if (parseResult.success) {\n return {\n valid: true,\n data: parseResult.data,\n };\n }\n\n const errors: TemplateValidationError[] = parseResult.error.issues.map((issue) => ({\n code: issue.code,\n message: issue.message,\n path: `/${issue.path.join('/')}`,\n }));\n\n return {\n valid: false,\n errors,\n };\n}\n\n/**\n * Helper to recursively collect all component types used in a node tree.\n */\nfunction collectComponentTypes(node: Node, types: Set<string>): void {\n if (node.type) {\n types.add(node.type);\n }\n if (node.children && Array.isArray(node.children)) {\n for (const child of node.children) {\n collectComponentTypes(child, types);\n }\n }\n}\n\n/**\n * Extracts required components and capabilities from a PageDocument.\n * Detects any custom/non-core component types used in the document tree.\n */\nexport function extractTemplateRequirements(\n doc: PageDocument,\n builtinComponents: ReadonlySet<string> = CORE_BUILTIN_COMPONENTS\n): TemplateRequirements {\n const componentTypes = new Set<string>();\n if (doc?.document) {\n collectComponentTypes(doc.document, componentTypes);\n }\n\n const customComponents: string[] = [];\n for (const type of componentTypes) {\n if (!builtinComponents.has(type)) {\n customComponents.push(type);\n }\n }\n\n return {\n requiredComponents: customComponents.sort(),\n requiredCapabilities: [],\n };\n}\n\n/**\n * Parameters for creating a TemplateRecord\n */\nexport interface CreateTemplateParams {\n id: string;\n name: string;\n description?: string;\n category?: string;\n tags?: string[];\n thumbnail?: TemplateRecord['thumbnail'];\n author?: string;\n version?: string;\n document?: PageDocument;\n packageReference?: TemplateRecord['packageReference'];\n requirements?: TemplateRequirements;\n createdAt?: string;\n updatedAt?: string;\n custom?: Record<string, unknown>;\n}\n\n/**\n * Creates and validates a TemplateRecord.\n * Automatically extracts requirements from the embedded document if requirements are not explicitly supplied.\n */\nexport function createTemplateRecord(params: CreateTemplateParams): TemplateRecord {\n const now = new Date().toISOString();\n\n let requirements = params.requirements;\n if (!requirements && params.document) {\n requirements = extractTemplateRequirements(params.document);\n }\n\n const candidate: TemplateRecord = {\n id: params.id,\n name: params.name,\n description: params.description ?? '',\n category: params.category ?? 'general',\n tags: params.tags ?? [],\n thumbnail: params.thumbnail,\n author: params.author ?? '',\n version: params.version ?? '1.0.0',\n document: params.document,\n packageReference: params.packageReference,\n requirements: requirements ?? { requiredComponents: [], requiredCapabilities: [] },\n createdAt: params.createdAt ?? now,\n updatedAt: params.updatedAt ?? now,\n custom: params.custom,\n };\n\n const validation = validateTemplate(candidate);\n if (!validation.valid || !validation.data) {\n const errorDetails = validation.errors?.map((e) => `${e.path}: ${e.message}`).join(', ');\n throw new Error(`Invalid template record: ${errorDetails}`);\n }\n\n return validation.data;\n}\n\n/**\n * Required metadata parameters for saving a draft as a template.\n * id and name are strictly required and non-empty.\n */\nexport interface SaveTemplateMetadata {\n id: string;\n name: string;\n description?: string;\n category?: string;\n tags?: string[];\n thumbnail?: TemplateRecord['thumbnail'];\n author?: string;\n version?: string;\n custom?: Record<string, unknown>;\n}\n\nexport interface SaveDraftAsTemplateOptions {\n validateDraft?: boolean;\n requirements?: TemplateRequirements;\n}\n\n/**\n * Exports a draft document snapshot as an immutable reusable TemplateRecord.\n * - Requires mandatory metadata (id, name).\n * - Validates draft document structure.\n * - Extracts component/capability requirements.\n * - Creates a deep-cloned immutable snapshot completely decoupled from the active draft.\n */\nexport function saveDraftAsTemplate(\n draft: PageDocument,\n metadata: SaveTemplateMetadata,\n options: SaveDraftAsTemplateOptions = {}\n): TemplateRecord {\n if (!metadata || typeof metadata !== 'object') {\n throw new Error('Save as template requires metadata with id and name.');\n }\n\n const cleanId = metadata.id?.trim();\n if (!cleanId) {\n throw new Error('Template ID is required and cannot be empty.');\n }\n\n const cleanName = metadata.name?.trim();\n if (!cleanName) {\n throw new Error('Template name is required and cannot be empty.');\n }\n\n if (!draft || !draft.document) {\n throw new Error('Invalid draft document: document tree is missing.');\n }\n\n if (options.validateDraft !== false) {\n const validation = validateDocument(draft);\n if (!validation.valid) {\n const errorMsg = validation.errors.map((e) => `${e.path}: ${e.message}`).join('; ');\n throw new Error(`Cannot save invalid draft as template: ${errorMsg}`);\n }\n }\n\n // Deep clone to guarantee the template snapshot is isolated from future draft edits\n const draftSnapshot: PageDocument = deepClone(draft);\n\n return createTemplateRecord({\n id: cleanId,\n name: cleanName,\n description: metadata.description?.trim() ?? '',\n category: metadata.category?.trim() ?? 'general',\n tags: metadata.tags ? [...metadata.tags] : [],\n thumbnail: metadata.thumbnail,\n author: metadata.author?.trim() ?? '',\n version: metadata.version?.trim() ?? '1.0.0',\n document: draftSnapshot,\n requirements: options.requirements,\n custom: metadata.custom ? deepClone(metadata.custom) : undefined,\n });\n}\n\n/**\n * Options for cloning/instantiating a template into a new page document.\n */\nexport interface CloneTemplateOptions {\n /**\n * Title for the newly created page document. Defaults to template name or document title.\n */\n title?: string;\n /**\n * Author for the newly created page document.\n */\n author?: string;\n /**\n * Optional custom ID generator function for node duplication.\n */\n idGenerator?: (oldId: string, node: Node) => string;\n /**\n * Custom ID prefix for freshly generated node IDs. Defaults to random string / timestamp.\n */\n idPrefix?: string;\n /**\n * Whether to record origin template metadata in metadata.custom.originTemplate (defaults to true).\n */\n recordOrigin?: boolean;\n /**\n * Additional custom metadata for the new document.\n */\n customMetadata?: Record<string, unknown>;\n}\n\n/**\n * Clones a template (or existing document) into a brand new PageDocument.\n * - Generates ALL NEW node IDs across the entire tree (root page node and all children).\n * - Deep-copies every other node field (props, styles, animation, actions, formConfig) and\n * remaps node-id references inside the tree (e.g. `modalNodeId`, `formId`) to the new ids;\n * references to ids outside the tree are left untouched.\n * - Ensures 100% ID difference from the source template.\n * - Sets fresh creation/update timestamps.\n * - Preserves origin template version/id in custom metadata.\n * - Guarantees full memory and reference isolation from the template source.\n */\nexport function cloneTemplateAsPage(\n templateOrDoc: TemplateRecord | PageDocument,\n options: CloneTemplateOptions = {}\n): PageDocument {\n let sourceDoc: PageDocument;\n let templateOrigin: { id: string; name: string; version: string } | null = null;\n\n if (isTemplateRecord(templateOrDoc)) {\n if (!templateOrDoc.document) {\n throw new Error(\n `Template \"${templateOrDoc.name}\" (${templateOrDoc.id}) does not contain an inline document snapshot to clone from.`\n );\n }\n sourceDoc = templateOrDoc.document;\n templateOrigin = {\n id: templateOrDoc.id,\n name: templateOrDoc.name,\n version: templateOrDoc.version ?? '1.0.0',\n };\n } else if ('schema' in templateOrDoc && 'document' in templateOrDoc) {\n sourceDoc = templateOrDoc;\n } else {\n throw new Error('Invalid input: expected a TemplateRecord or PageDocument.');\n }\n\n const existingIdsInSource = new Set(collectNodeIds(sourceDoc.document));\n const assignedNewIds = new Set<string>();\n\n // Determine unique seed prefix for this clone instance\n const prefix = options.idPrefix || `page_${Date.now().toString(36)}_${Math.random().toString(36).substring(2, 6)}`;\n let counter = 1;\n\n const defaultIdGen = (oldId: string, node: Node): string => {\n // Generate an ID that is guaranteed never to match oldId or any existing ID in source\n let candidate = `${node.type}_${prefix}_${counter}`;\n while (existingIdsInSource.has(candidate) || assignedNewIds.has(candidate)) {\n counter++;\n candidate = `${node.type}_${prefix}_${counter}`;\n }\n counter++;\n assignedNewIds.add(candidate);\n return candidate;\n };\n\n const idGen = options.idGenerator || defaultIdGen;\n\n const { clonedNode: clonedRootNode } = cloneNodeTreeWithFreshIds(sourceDoc.document, idGen);\n\n // Guarantee root node type is 'page'\n const rootPageNode: Node & { type: 'page' } = {\n ...clonedRootNode,\n type: 'page',\n };\n\n const now = new Date().toISOString();\n const pageTitle =\n options.title ??\n (templateOrigin ? `${templateOrigin.name}` : sourceDoc.metadata?.title ?? 'Untitled Page');\n\n const customMetadata: Record<string, unknown> = {\n ...(sourceDoc.metadata?.custom ? deepClone(sourceDoc.metadata.custom) : {}),\n ...(options.customMetadata ? deepClone(options.customMetadata) : {}),\n };\n\n if (options.recordOrigin !== false && templateOrigin) {\n customMetadata.originTemplate = templateOrigin;\n }\n\n const newDoc: PageDocument = {\n schema: sourceDoc.schema,\n version: sourceDoc.version,\n metadata: {\n title: pageTitle,\n description: sourceDoc.metadata?.description ?? '',\n author: options.author ?? sourceDoc.metadata?.author ?? '',\n tags: sourceDoc.metadata?.tags ? [...sourceDoc.metadata.tags] : [],\n category: sourceDoc.metadata?.category ?? 'general',\n version: '1.0.0',\n createdAt: now,\n updatedAt: now,\n custom: customMetadata,\n },\n document: rootPageNode,\n };\n\n return newDoc;\n}\n\n/**\n * Helper to verify that two PageDocuments share ZERO overlapping node IDs.\n */\nexport function areNodeIdsCompletelyDistinct(docA: PageDocument, docB: PageDocument): boolean {\n if (!docA?.document || !docB?.document) return true;\n const idsA = new Set(collectNodeIds(docA.document));\n const idsB = collectNodeIds(docB.document);\n\n for (const id of idsB) {\n if (idsA.has(id)) {\n return false;\n }\n }\n return true;\n}\n","import {\n Artboard,\n Node,\n ProjectDocument,\n ProjectDocumentSchema,\n PROJECT_SCHEMA_NAME,\n ARTBOARD_REFERENCE_NODE_TYPE,\n} from '@kubuild/schema';\nimport {\n DocumentValidationError,\n ValidationOptions,\n validateDocument,\n} from './validator';\n\nexport type ProjectValidationErrorCode =\n | 'PROJECT_SCHEMA_INVALID'\n | 'DUPLICATE_ARTBOARD_ID'\n | 'DUPLICATE_NODE_ID_ACROSS_ARTBOARDS'\n | 'DANGLING_ARTBOARD_REFERENCE'\n | 'DUPLICATE_TRIGGER_ID'\n | 'INVALID_ACTIVE_ARTBOARD'\n | 'ARTBOARD_DOCUMENT_INVALID';\n\nexport interface ProjectValidationError {\n code: ProjectValidationErrorCode;\n message: string;\n path: string;\n artboardId?: string;\n nodeId?: string;\n details?: Record<string, unknown>;\n}\n\nexport interface ProjectValidationResult {\n valid: boolean;\n success: boolean;\n errors: ProjectValidationError[];\n /** Per-artboard results from the existing single-document validator. */\n artboardErrors: Record<string, DocumentValidationError[]>;\n data?: ProjectDocument;\n}\n\nfunction walk(node: Node, visit: (node: Node) => void): void {\n visit(node);\n for (const child of node.children ?? []) {\n walk(child, visit);\n }\n}\n\nfunction collectArtboardReferences(artboard: Artboard): Array<{ nodeId: string; artboardId?: string }> {\n const refs: Array<{ nodeId: string; artboardId?: string }> = [];\n walk(artboard.document.document, (node) => {\n if (node.type === ARTBOARD_REFERENCE_NODE_TYPE) {\n const target = node.props?.artboardId;\n refs.push({\n nodeId: node.id,\n artboardId: typeof target === 'string' ? target : undefined,\n });\n }\n });\n return refs;\n}\n\n/**\n * Validate a multi-artboard project.\n *\n * Each artboard's document is handed to the existing `validateDocument` unchanged; this\n * function only adds the checks that cannot exist at single-document scope:\n * artboard-id uniqueness, node-id uniqueness *across* artboards (so content moved between\n * artboards can't silently collide), duplicate component trigger ids, and reference stubs\n * that point at an artboard which no longer exists.\n */\nexport function validateProject(\n input: unknown,\n options: ValidationOptions = {},\n): ProjectValidationResult {\n const errors: ProjectValidationError[] = [];\n const artboardErrors: Record<string, DocumentValidationError[]> = {};\n\n if (!input || typeof input !== 'object' || Array.isArray(input)) {\n return {\n valid: false,\n success: false,\n errors: [\n {\n code: 'PROJECT_SCHEMA_INVALID',\n message: 'Project must be a valid non-null object',\n path: '',\n },\n ],\n artboardErrors,\n };\n }\n\n const parsed = ProjectDocumentSchema.safeParse(input);\n if (!parsed.success) {\n return {\n valid: false,\n success: false,\n errors: [\n {\n code: 'PROJECT_SCHEMA_INVALID',\n message: `Project failed schema validation. Expected schema \"${PROJECT_SCHEMA_NAME}\".`,\n path: '',\n details: { issues: parsed.error.issues },\n },\n ],\n artboardErrors,\n };\n }\n\n const project = parsed.data;\n\n // 1. Artboard id uniqueness\n const seenArtboardIds = new Set<string>();\n for (const artboard of project.artboards) {\n if (seenArtboardIds.has(artboard.id)) {\n errors.push({\n code: 'DUPLICATE_ARTBOARD_ID',\n message: `Duplicate artboard id \"${artboard.id}\"`,\n path: '/artboards',\n artboardId: artboard.id,\n });\n }\n seenArtboardIds.add(artboard.id);\n }\n\n // 2. Active artboard must resolve\n if (project.activeArtboardId && !seenArtboardIds.has(project.activeArtboardId)) {\n errors.push({\n code: 'INVALID_ACTIVE_ARTBOARD',\n message: `activeArtboardId \"${project.activeArtboardId}\" does not match any artboard`,\n path: '/activeArtboardId',\n });\n }\n\n // 3. Per-artboard document validation, reusing the existing single-document validator\n const nodeIdOwner = new Map<string, string>();\n for (const artboard of project.artboards) {\n const result = validateDocument(artboard.document, options);\n if (!result.valid) {\n artboardErrors[artboard.id] = result.errors;\n errors.push({\n code: 'ARTBOARD_DOCUMENT_INVALID',\n message: `Artboard \"${artboard.id}\" has ${result.errors.length} document validation error(s)`,\n path: `/artboards/${artboard.id}/document`,\n artboardId: artboard.id,\n });\n }\n\n // 4. Node id uniqueness across artboards\n walk(artboard.document.document, (node) => {\n const owner = nodeIdOwner.get(node.id);\n if (owner && owner !== artboard.id) {\n errors.push({\n code: 'DUPLICATE_NODE_ID_ACROSS_ARTBOARDS',\n message: `Node id \"${node.id}\" appears in both artboard \"${owner}\" and \"${artboard.id}\"`,\n path: `/artboards/${artboard.id}/document`,\n artboardId: artboard.id,\n nodeId: node.id,\n });\n } else if (!owner) {\n nodeIdOwner.set(node.id, artboard.id);\n }\n });\n }\n\n // 5. Duplicate trigger ids among component artboards (would make open_modal ambiguous)\n const seenTriggerIds = new Set<string>();\n for (const artboard of project.artboards) {\n if (artboard.artboardType !== 'component' || !artboard.triggerId) continue;\n if (seenTriggerIds.has(artboard.triggerId)) {\n errors.push({\n code: 'DUPLICATE_TRIGGER_ID',\n message: `Duplicate component triggerId \"${artboard.triggerId}\" — open_modal targets would be ambiguous`,\n path: `/artboards/${artboard.id}/triggerId`,\n artboardId: artboard.id,\n });\n }\n seenTriggerIds.add(artboard.triggerId);\n }\n\n // 6. Reference stubs must point at an existing artboard\n for (const artboard of project.artboards) {\n for (const ref of collectArtboardReferences(artboard)) {\n if (!ref.artboardId || !seenArtboardIds.has(ref.artboardId)) {\n errors.push({\n code: 'DANGLING_ARTBOARD_REFERENCE',\n message: `Node \"${ref.nodeId}\" references artboard \"${String(ref.artboardId)}\" which does not exist`,\n path: `/artboards/${artboard.id}/document`,\n artboardId: artboard.id,\n nodeId: ref.nodeId,\n });\n }\n }\n }\n\n const valid = errors.length === 0;\n return {\n valid,\n success: valid,\n errors,\n artboardErrors,\n data: valid ? project : undefined,\n };\n}\n\n/**\n * Collect artboard-reference stubs in a single page document. Used by the exporter guard\n * to refuse silently-incomplete single-page exports.\n */\nexport function collectArtboardReferenceNodes(root: Node): Array<{ nodeId: string; artboardId?: string }> {\n const refs: Array<{ nodeId: string; artboardId?: string }> = [];\n walk(root, (node) => {\n if (node.type === ARTBOARD_REFERENCE_NODE_TYPE) {\n const target = node.props?.artboardId;\n refs.push({ nodeId: node.id, artboardId: typeof target === 'string' ? target : undefined });\n }\n });\n return refs;\n}\n","import type { FormFieldBinding, ValidationRule } from '@kubuild/schema';\n\n/**\n * Checks whether a field value is considered empty.\n * Empty values include undefined, null, empty string, empty array, or boolean false.\n */\nexport function isEmptyValue(value: unknown): boolean {\n if (value === undefined || value === null) {\n return true;\n }\n if (typeof value === 'string') {\n return value.trim().length === 0;\n }\n if (Array.isArray(value)) {\n return value.length === 0;\n }\n if (typeof value === 'boolean') {\n return value === false;\n }\n return false;\n}\n\n/**\n * Standard safe email validation regex.\n */\nconst EMAIL_REGEX = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\n/**\n * Standard safe HTTP/HTTPS URL validation regex.\n */\nconst URL_REGEX = /^(https?:\\/\\/)([\\w.-]+)(:[0-9]+)?(\\/.*)?$/i;\n\n/**\n * Applies a value transformation to a field value prior to validation.\n */\nexport function applyFieldTransform(\n value: unknown,\n transform?: 'trim' | 'lowercase' | 'uppercase' | 'number' | string,\n): unknown {\n if (value === undefined || value === null || !transform) {\n return value;\n }\n\n if (typeof value === 'string') {\n switch (transform) {\n case 'trim':\n return value.trim();\n case 'lowercase':\n return value.toLowerCase();\n case 'uppercase':\n return value.toUpperCase();\n case 'number': {\n const trimmed = value.trim();\n if (trimmed === '') return value;\n const num = Number(trimmed);\n return Number.isNaN(num) ? value : num;\n }\n default:\n return value;\n }\n }\n\n if (typeof value === 'number' && transform === 'number') {\n return value;\n }\n\n return value;\n}\n\n/**\n * Evaluates a single validation rule against a field value.\n * Returns the rule's error message if invalid, or null if valid.\n */\nexport function evaluateRule(\n rule: ValidationRule,\n value: unknown,\n allFormValues?: Record<string, unknown>,\n): string | null {\n const isValueEmpty = isEmptyValue(value);\n\n // For non-required rules, empty values are treated as valid (optional fields)\n if (rule.type !== 'required' && isValueEmpty) {\n return null;\n }\n\n switch (rule.type) {\n case 'required': {\n if (isValueEmpty) {\n return rule.message;\n }\n return null;\n }\n\n case 'email': {\n if (typeof value !== 'string' || !EMAIL_REGEX.test(value.trim())) {\n return rule.message;\n }\n return null;\n }\n\n case 'url': {\n if (typeof value !== 'string' || !URL_REGEX.test(value.trim())) {\n return rule.message;\n }\n return null;\n }\n\n case 'min_length': {\n const min = Number(rule.value);\n if (Number.isFinite(min)) {\n if (typeof value === 'string' && value.length < min) {\n return rule.message;\n }\n if (Array.isArray(value) && value.length < min) {\n return rule.message;\n }\n }\n return null;\n }\n\n case 'max_length': {\n const max = Number(rule.value);\n if (Number.isFinite(max)) {\n if (typeof value === 'string' && value.length > max) {\n return rule.message;\n }\n if (Array.isArray(value) && value.length > max) {\n return rule.message;\n }\n }\n return null;\n }\n\n case 'numeric_min': {\n const min = Number(rule.value);\n const num = Number(value);\n if (Number.isNaN(num) || !Number.isFinite(num) || num < min) {\n return rule.message;\n }\n return null;\n }\n\n case 'numeric_max': {\n const max = Number(rule.value);\n const num = Number(value);\n if (Number.isNaN(num) || !Number.isFinite(num) || num > max) {\n return rule.message;\n }\n return null;\n }\n\n case 'pattern':\n case 'custom_regex': {\n try {\n const patternStr = String(rule.value || '');\n const regex = new RegExp(patternStr);\n if (!regex.test(String(value ?? ''))) {\n return rule.message;\n }\n } catch {\n return rule.message;\n }\n return null;\n }\n\n case 'match_field': {\n const targetFieldName = String(rule.value || '');\n const targetValue = allFormValues?.[targetFieldName];\n if (value !== targetValue) {\n return rule.message;\n }\n return null;\n }\n\n default:\n return null;\n }\n}\n\n/**\n * Validates a single field value against an array of ValidationRules.\n * Returns the first failing error message, or null if all rules pass.\n */\nexport function validateFieldValue(\n value: unknown,\n rules?: ValidationRule[] | null,\n allFormValues?: Record<string, unknown>,\n): string | null {\n if (!rules || !Array.isArray(rules) || rules.length === 0) {\n return null;\n }\n\n for (const rule of rules) {\n const error = evaluateRule(rule, value, allFormValues);\n if (error) {\n return error;\n }\n }\n\n return null;\n}\n\n/**\n * Asynchronously validates a single field value against an array of ValidationRules.\n */\nexport async function validateFieldValueAsync(\n value: unknown,\n rules?: ValidationRule[] | null,\n allFormValues?: Record<string, unknown>,\n): Promise<string | null> {\n return validateFieldValue(value, rules, allFormValues);\n}\n\n/**\n * Validates an entire form values object against field configs.\n * Returns a map of field names to error messages (Record<string, string>).\n * If all fields are valid, returns an empty object {}.\n */\nexport function validateForm(\n values: Record<string, unknown>,\n fieldConfigs:\n | FormFieldBinding[]\n | Record<string, FormFieldBinding | ValidationRule[]>,\n): Record<string, string> {\n const errors: Record<string, string> = {};\n\n if (!fieldConfigs) {\n return errors;\n }\n\n if (Array.isArray(fieldConfigs)) {\n for (const field of fieldConfigs) {\n if (!field?.name) continue;\n\n let value = values?.[field.name];\n if (field.transform) {\n value = applyFieldTransform(value, field.transform);\n }\n\n const rules: ValidationRule[] = [...(field.rules || [])];\n\n // Handle shorthand `required: true` if not already present in rules\n if (field.required && !rules.some((r) => r.type === 'required')) {\n rules.unshift({\n type: 'required',\n message: `${field.label || field.name} is required`,\n });\n }\n\n const error = validateFieldValue(value, rules, values);\n if (error) {\n errors[field.name] = error;\n }\n }\n } else if (typeof fieldConfigs === 'object') {\n for (const [fieldName, config] of Object.entries(fieldConfigs)) {\n let value = values?.[fieldName];\n let rules: ValidationRule[] = [];\n\n if (Array.isArray(config)) {\n rules = config;\n } else if (config && typeof config === 'object') {\n if (config.transform) {\n value = applyFieldTransform(value, config.transform);\n }\n rules = [...(config.rules || [])];\n if (config.required && !rules.some((r) => r.type === 'required')) {\n rules.unshift({\n type: 'required',\n message: `${config.label || fieldName} is required`,\n });\n }\n }\n\n const error = validateFieldValue(value, rules, values);\n if (error) {\n errors[fieldName] = error;\n }\n }\n }\n\n return errors;\n}\n\n/**\n * Asynchronously validates an entire form values object against field configs.\n */\nexport async function validateFormAsync(\n values: Record<string, unknown>,\n fieldConfigs:\n | FormFieldBinding[]\n | Record<string, FormFieldBinding | ValidationRule[]>,\n): Promise<Record<string, string>> {\n return validateForm(values, fieldConfigs);\n}\n\n/**\n * Convenience helper to determine if a form error map is completely valid (no errors).\n */\nexport function isFormValid(errors: Record<string, string>): boolean {\n return Object.keys(errors).length === 0;\n}\n\n"],"mappings":"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","names":["walk","SCHEMA_NAME","CURRENT_SCHEMA_VERSION","SCHEMA_NAME","CURRENT_SCHEMA_VERSION","FORBIDDEN_KEY_SEGMENTS","FORBIDDEN_KEY_SEGMENTS","skippedResult","FORBIDDEN_KEY_SEGMENTS","SCHEMA_NAME","CURRENT_SCHEMA_VERSION","SCHEMA_NAME","traverse","SCHEMA_NAME","SCHEMA_NAME","CURRENT_SCHEMA_VERSION","CURRENT_SCHEMA_VERSION","CURRENT_SCHEMA_VERSION","SCHEMA_NAME","SCHEMA_NAME","walk","CURRENT_SCHEMA_VERSION","CURRENT_SCHEMA_VERSION","PROJECT_SCHEMA_NAME","CURRENT_PROJECT_SCHEMA_VERSION","CURRENT_SCHEMA_VERSION","CURRENT_SCHEMA_VERSION","PROJECT_SCHEMA_NAME","CURRENT_PROJECT_SCHEMA_VERSION","collectNodeIds","now","collectNodeIds","ProjectDocumentSchema","PROJECT_SCHEMA_NAME","ARTBOARD_REFERENCE_NODE_TYPE","ARTBOARD_REFERENCE_NODE_TYPE","ProjectDocumentSchema","PROJECT_SCHEMA_NAME","isValueEmpty"]}