@bravostudioai/react 0.1.0 → 0.1.2

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.
Files changed (48) hide show
  1. package/dist/_virtual/main.js +3 -2
  2. package/dist/cli/commands/generate.js +161 -1438
  3. package/dist/cli/commands/generate.js.map +1 -1
  4. package/dist/codegen/generator.js +473 -0
  5. package/dist/codegen/generator.js.map +1 -0
  6. package/dist/codegen/parser.js +720 -0
  7. package/dist/codegen/parser.js.map +1 -0
  8. package/dist/components/EncoreApp.js +197 -162
  9. package/dist/components/EncoreApp.js.map +1 -1
  10. package/dist/contexts/EncoreRouterContext.js +13 -0
  11. package/dist/contexts/EncoreRouterContext.js.map +1 -0
  12. package/dist/hooks/usePusherUpdates.js +4 -2
  13. package/dist/hooks/usePusherUpdates.js.map +1 -1
  14. package/dist/lib/dynamicModules.js +75 -85
  15. package/dist/lib/dynamicModules.js.map +1 -1
  16. package/dist/lib/moduleRegistry.js +20 -0
  17. package/dist/lib/moduleRegistry.js.map +1 -0
  18. package/dist/lib/packages.js +1 -3
  19. package/dist/lib/packages.js.map +1 -1
  20. package/dist/src/cli/commands/generate.d.ts.map +1 -1
  21. package/dist/src/codegen/generator.d.ts +10 -0
  22. package/dist/src/codegen/generator.d.ts.map +1 -0
  23. package/dist/src/codegen/index.d.ts +4 -0
  24. package/dist/src/codegen/index.d.ts.map +1 -0
  25. package/dist/src/codegen/parser.d.ts +37 -0
  26. package/dist/src/codegen/parser.d.ts.map +1 -0
  27. package/dist/src/codegen/types.d.ts +53 -0
  28. package/dist/src/codegen/types.d.ts.map +1 -0
  29. package/dist/src/components/EncoreApp.d.ts +5 -1
  30. package/dist/src/components/EncoreApp.d.ts.map +1 -1
  31. package/dist/src/contexts/EncoreRouterContext.d.ts +10 -0
  32. package/dist/src/contexts/EncoreRouterContext.d.ts.map +1 -0
  33. package/dist/src/hooks/useAuthRedirect.d.ts.map +1 -1
  34. package/dist/src/lib/dynamicModules.d.ts +1 -5
  35. package/dist/src/lib/dynamicModules.d.ts.map +1 -1
  36. package/dist/src/lib/moduleRegistry.d.ts +9 -0
  37. package/dist/src/lib/moduleRegistry.d.ts.map +1 -0
  38. package/dist/src/lib/packages.d.ts.map +1 -1
  39. package/package.json +1 -1
  40. package/src/cli/commands/generate.ts +88 -2723
  41. package/src/codegen/generator.ts +877 -0
  42. package/src/codegen/index.ts +3 -0
  43. package/src/codegen/parser.ts +1614 -0
  44. package/src/codegen/types.ts +58 -0
  45. package/src/components/EncoreApp.tsx +75 -22
  46. package/src/contexts/EncoreRouterContext.ts +28 -0
  47. package/src/hooks/useAuthRedirect.ts +56 -55
  48. package/src/lib/packages.ts +8 -15
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sources":["../../src/codegen/parser.ts"],"sourcesContent":["import {\n ComponentInfo,\n SliderInfo,\n InputGroupInfo,\n FormInfo,\n SelectInputInfo,\n ActionButtonInfo,\n} from \"./types\";\n\nexport function sanitizePropName(name: string): string {\n // Convert to camelCase and remove invalid characters\n const cleaned = name\n .replace(/[^a-zA-Z0-9\\s]/g, \"\") // Remove special chars\n .trim();\n\n if (!cleaned) return \"item\";\n\n return cleaned\n .split(/\\s+/)\n .map((word, index) => {\n if (!word) return \"\";\n // Handle all-uppercase words (like \"SHOP\", \"NOW\") by lowercasing them first\n const normalizedWord =\n word === word.toUpperCase() && word.length > 1\n ? word.toLowerCase()\n : word;\n const firstChar = normalizedWord.charAt(0);\n const rest = normalizedWord.slice(1);\n if (index === 0) {\n return firstChar.toLowerCase() + rest;\n }\n return firstChar.toUpperCase() + rest;\n })\n .join(\"\")\n .replace(/^[0-9]/, \"_$&\"); // Prefix numbers with underscore\n}\n\nexport function generateQualifiedPropName(\n componentName: string,\n parentPath: string[]\n): string {\n // Start with the component's own name\n const baseName = sanitizePropName(componentName);\n\n // If no parent path, just return the base name\n if (parentPath.length === 0) {\n return baseName;\n }\n\n // Filter out empty parts and reverse so we build from root to leaf\n const validParentParts = parentPath\n .filter((part) => part && part.trim())\n .reverse();\n\n if (validParentParts.length === 0) {\n return baseName;\n }\n\n // Build qualified name: parent1Parent2ComponentName\n // Each parent part is sanitized individually, then combined\n const sanitizedParentParts = validParentParts.map((part) =>\n sanitizePropName(part)\n );\n\n // Join parent parts (all start uppercase) with base name (starts lowercase)\n const parentPrefix = sanitizedParentParts\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(\"\");\n\n return parentPrefix + baseName;\n}\n\n/**\n * Finds the minimal distinguishing path suffix for a component when compared to others.\n * Returns the shortest suffix (from root side, working towards leaf) that makes this path unique.\n *\n * The algorithm finds where paths first diverge from the root, then takes the minimal\n * distinguishing part from that divergence point towards the leaf.\n */\nexport function findMinimalDistinguishingPath(\n thisPath: string[],\n otherPaths: string[][]\n): string[] {\n if (otherPaths.length === 0) {\n // No other paths to compare, return empty (no qualification needed)\n return [];\n }\n\n // Find the longest common prefix (from root side)\n let commonPrefixLength = 0;\n const maxCommonLength = Math.min(\n thisPath.length,\n ...otherPaths.map((p) => p.length)\n );\n\n for (let i = 0; i < maxCommonLength; i++) {\n const thisPart = thisPath[i];\n // Check if all other paths have the same part at this position\n const allMatch = otherPaths.every((otherPath) => {\n return otherPath[i] === thisPart;\n });\n\n if (allMatch) {\n commonPrefixLength++;\n } else {\n break;\n }\n }\n\n // The distinguishing part starts after the common prefix\n const distinguishingSuffix = thisPath.slice(commonPrefixLength);\n\n // Now find the minimal suffix that's unique\n // Try progressively shorter suffixes (from root side) until we find one that's unique\n for (\n let suffixLength = 1;\n suffixLength <= distinguishingSuffix.length;\n suffixLength++\n ) {\n const thisSuffix = distinguishingSuffix.slice(0, suffixLength);\n\n // Check if this suffix is unique when combined with the common prefix\n const isUnique = otherPaths.every((otherPath) => {\n // If other path is shorter than common prefix + suffix, it can't match\n if (otherPath.length < commonPrefixLength + suffixLength) {\n return true; // Different length means unique\n }\n // Check if the suffix matches at the divergence point\n const otherSuffix = otherPath.slice(\n commonPrefixLength,\n commonPrefixLength + suffixLength\n );\n return !arraysEqual(thisSuffix, otherSuffix);\n });\n\n if (isUnique) {\n // Found minimal distinguishing suffix\n return thisSuffix;\n }\n }\n\n // If we get here, paths are identical (shouldn't happen, but handle it)\n return distinguishingSuffix;\n}\n\n/**\n * Helper to compare two arrays for equality\n */\nexport function arraysEqual(a: string[], b: string[]): boolean {\n if (a.length !== b.length) return false;\n return a.every((val, idx) => val === b[idx]);\n}\n\nexport function getComponentPropType(\n componentType: string,\n _componentName: string\n): string {\n if (componentType === \"component:image\") {\n return \"string\"; // imageUrl\n }\n if (componentType === \"component:text\") {\n return \"string\"; // text\n }\n if (componentType?.startsWith(\"component:input-\")) {\n // Input types generally return strings\n if (componentType === \"component:input-image\") {\n return \"string\"; // image URL\n }\n return \"string\"; // text inputs, email, password, etc.\n }\n // Default to any for unknown types\n return \"any\";\n}\n\nexport function getComponentPropName(componentType: string): string {\n if (componentType === \"component:image\") {\n return \"imageUrl\";\n }\n if (componentType === \"component:text\") {\n return \"text\";\n }\n return \"value\";\n}\n\nexport function findSlidersAndDataBindings(pageData: any): SliderInfo[] {\n const sliders: SliderInfo[] = [];\n\n function traverse(node: any, path: string[] = []): void {\n if (!node || typeof node !== \"object\") return;\n\n // Check if this is a slider container\n if (node.type === \"container:slider\") {\n const slider: SliderInfo = {\n id: node.id,\n name: node.name || \"Slider\",\n arrayContainer: null,\n };\n\n // Recursively look for containers with encore:data:array tag inside the slider\n let arrayContainer: any = null;\n\n const findArrayContainer = (containerNode: any): void => {\n if (arrayContainer) return; // Already found one\n\n if (!containerNode || typeof containerNode !== \"object\") return;\n\n // Check if this node is the array container\n if (\n Array.isArray(containerNode.tags) &&\n (containerNode.tags.includes(\"encore:data:array\") ||\n containerNode.tags.includes(\"bravo:data:array\"))\n ) {\n arrayContainer = containerNode;\n return;\n }\n\n // Recursively search children\n if (containerNode.body && Array.isArray(containerNode.body)) {\n containerNode.body.forEach(findArrayContainer);\n }\n if (\n containerNode.containers &&\n Array.isArray(containerNode.containers)\n ) {\n containerNode.containers.forEach(findArrayContainer);\n }\n if (\n containerNode.components &&\n Array.isArray(containerNode.components)\n ) {\n containerNode.components.forEach(findArrayContainer);\n }\n };\n\n // Start search from the slider node itself (checking its children)\n if (node.containers && Array.isArray(node.containers)) {\n node.containers.forEach(findArrayContainer);\n }\n // Also check components if they exist directly\n if (\n !arrayContainer &&\n node.components &&\n Array.isArray(node.components)\n ) {\n node.components.forEach(findArrayContainer);\n }\n\n if (arrayContainer) {\n const container = arrayContainer;\n let components: ComponentInfo[] = [];\n\n // Find all components with encore:data tag, and also image components\n const imageComponents: any[] = [];\n\n const findDataComponents = (\n comp: any,\n parentPath: string[] = []\n ): void => {\n if (!comp || typeof comp !== \"object\") return;\n\n // Track image components separately (they might not have encore:data tag)\n if (comp.type === \"component:image\") {\n imageComponents.push(comp);\n }\n\n if (\n Array.isArray(comp.tags) &&\n (comp.tags.includes(\"encore:data\") ||\n comp.tags.includes(\"bravo:data\"))\n ) {\n const basePropName = sanitizePropName(comp.name || \"item\");\n const propType = getComponentPropType(comp.type, comp.name);\n // const propKey = getComponentPropName(comp.type);\n\n components.push({\n id: comp.id,\n name: comp.name || \"Unnamed\",\n type: comp.type,\n tags: comp.tags || [],\n propName: basePropName, // Will be qualified later if needed\n propType,\n // Store parent path for later qualification\n _parentPath: [...parentPath],\n } as ComponentInfo & { _parentPath: string[] });\n }\n\n // Build parent path: include this node's name if it's a container/component with a name\n // Skip generic \"Frame\" names - they're usually not meaningful for distinction\n const currentParentPath = [...parentPath];\n if (\n comp.name &&\n (comp.type?.startsWith(\"container:\") ||\n comp.type?.startsWith(\"component:\"))\n ) {\n const name = comp.name.trim();\n // Filter out generic \"Frame\" names (case-insensitive, with or without numbers/spaces)\n // But keep meaningful names like \"TripSlideFrame\" that contain other words\n const isGenericFrame =\n /^frame\\s*\\d*$/i.test(name) || name.toUpperCase() === \"FRAME\";\n if (name && !isGenericFrame) {\n currentParentPath.push(comp.name);\n }\n }\n\n // Recursively search children\n if (comp.body && Array.isArray(comp.body)) {\n comp.body.forEach((child: any) =>\n findDataComponents(child, currentParentPath)\n );\n }\n if (comp.containers && Array.isArray(comp.containers)) {\n comp.containers.forEach((child: any) =>\n findDataComponents(child, currentParentPath)\n );\n }\n if (comp.components && Array.isArray(comp.components)) {\n comp.components.forEach((child: any) =>\n findDataComponents(child, currentParentPath)\n );\n }\n };\n\n if (container.components && Array.isArray(container.components)) {\n container.components.forEach((comp: any) =>\n findDataComponents(comp, [])\n );\n }\n\n // After finding all components, if we have image components but no image with encore:data,\n // add the first image component\n const hasImageWithData = components.some(\n (c) => c.type === \"component:image\"\n );\n if (!hasImageWithData && imageComponents.length > 0) {\n const imageComp = imageComponents[0];\n // For image components, use \"imageUrl\" as the prop name\n // Clean the name first, then if it contains \"image\", just use \"imageUrl\"\n const rawName = (imageComp.name || \"image\").toLowerCase();\n const basePropName = rawName.includes(\"image\")\n ? \"imageUrl\"\n : sanitizePropName(imageComp.name || \"image\");\n components.push({\n id: imageComp.id,\n name: imageComp.name || \"Image\",\n type: imageComp.type,\n tags: imageComp.tags || [],\n propName: basePropName, // Will be qualified later if needed\n propType: \"string\", // imageUrl is always string\n _parentPath: [],\n } as ComponentInfo & { _parentPath: string[] });\n }\n\n // Detect duplicates and qualify them with minimal distinguishing paths\n // First pass: collect all base prop names and group duplicates\n const propNameGroups = new Map<\n string,\n Array<ComponentInfo & { _parentPath: string[] }>\n >();\n components.forEach((comp) => {\n const compWithPath = comp as ComponentInfo & {\n _parentPath: string[];\n };\n const baseName = comp.propName;\n if (!propNameGroups.has(baseName)) {\n propNameGroups.set(baseName, []);\n }\n propNameGroups.get(baseName)!.push(compWithPath);\n });\n\n // Second pass: for each group with duplicates, find minimal distinguishing paths\n // and ensure all qualified names are unique\n propNameGroups.forEach((group, _baseName) => {\n if (group.length === 1) {\n // No duplicates, keep the simple name\n return;\n }\n\n // First, find minimal distinguishing paths for all components\n group.forEach((comp) => {\n const otherPaths = group\n .filter((c) => c.id !== comp.id)\n .map((c) => c._parentPath || []);\n\n const minimalPath = findMinimalDistinguishingPath(\n comp._parentPath || [],\n otherPaths\n );\n\n // Use the minimal distinguishing path to qualify the name\n comp.propName = generateQualifiedPropName(\n comp.name || \"item\",\n minimalPath\n );\n });\n\n // Check if qualified names are still duplicates and expand paths if needed\n let hasDuplicates = true;\n let iteration = 0;\n const maxIterations = 10; // Safety limit\n\n while (hasDuplicates && iteration < maxIterations) {\n iteration++;\n const qualifiedNameGroups = new Map<\n string,\n Array<ComponentInfo & { _parentPath: string[] }>\n >();\n group.forEach((comp) => {\n if (!qualifiedNameGroups.has(comp.propName)) {\n qualifiedNameGroups.set(comp.propName, []);\n }\n qualifiedNameGroups.get(comp.propName)!.push(comp);\n });\n\n hasDuplicates = false;\n // For each group of still-duplicated qualified names, expand their paths\n qualifiedNameGroups.forEach((dupGroup, _qualifiedName) => {\n if (dupGroup.length > 1) {\n hasDuplicates = true;\n // Expand the distinguishing path for each duplicate\n dupGroup.forEach((comp) => {\n // Find a longer distinguishing path by comparing with others in the duplicate group\n const fullPath = comp._parentPath || [];\n const otherFullPaths = dupGroup\n .filter((c) => c.id !== comp.id)\n .map((c) => c._parentPath || []);\n\n // Find where this path diverges from others in the duplicate group\n let commonPrefixLength = 0;\n const maxCommonLength = Math.min(\n fullPath.length,\n ...otherFullPaths.map((p) => p.length)\n );\n\n for (let i = 0; i < maxCommonLength; i++) {\n const thisPart = fullPath[i];\n const allMatch = otherFullPaths.every((otherPath) => {\n return otherPath[i] === thisPart;\n });\n if (allMatch) {\n commonPrefixLength++;\n } else {\n break;\n }\n }\n\n // Use progressively more of the distinguishing suffix until unique\n const distinguishingSuffix =\n fullPath.slice(commonPrefixLength);\n\n // Try expanding the distinguishing suffix until we find a unique name\n let foundUnique = false;\n for (\n let suffixLength = 1;\n suffixLength <= distinguishingSuffix.length;\n suffixLength++\n ) {\n const expandedPath = distinguishingSuffix.slice(\n 0,\n suffixLength\n );\n const testQualifiedName = generateQualifiedPropName(\n comp.name || \"item\",\n expandedPath\n );\n\n // Check if this qualified name is unique among ALL components (not just duplicates)\n const isUnique = components.every((otherComp) => {\n if (otherComp.id === comp.id) return true;\n // If other component is in the same duplicate group, compare expanded paths\n if (dupGroup.some((c) => c.id === otherComp.id)) {\n const otherFullPath =\n (\n otherComp as ComponentInfo & {\n _parentPath: string[];\n }\n )._parentPath || [];\n const otherCommonPrefixLength = Math.min(\n commonPrefixLength,\n otherFullPath.length\n );\n const otherDistinguishingSuffix = otherFullPath.slice(\n otherCommonPrefixLength\n );\n const otherExpandedPath =\n otherDistinguishingSuffix.slice(0, suffixLength);\n const otherQualifiedName = generateQualifiedPropName(\n otherComp.name || \"item\",\n otherExpandedPath\n );\n return testQualifiedName !== otherQualifiedName;\n }\n // For components outside the duplicate group, just check the final prop name\n return testQualifiedName !== otherComp.propName;\n });\n\n if (isUnique) {\n comp.propName = testQualifiedName;\n foundUnique = true;\n break;\n }\n }\n\n // If we couldn't find a unique name with the distinguishing suffix,\n // use the distinguishing suffix we found (it's the minimal we can do)\n // We'll handle truly identical paths with numeric suffixes in the final pass\n if (!foundUnique) {\n // Use the distinguishing suffix - it's the minimal distinguishing part\n // Even if it's not globally unique yet, it's better than the full path\n comp.propName = generateQualifiedPropName(\n comp.name || \"item\",\n distinguishingSuffix.length > 0\n ? distinguishingSuffix\n : []\n );\n }\n });\n }\n });\n }\n\n // Final check: if there are still duplicates after using full paths,\n // and they have identical paths, use numeric suffixes as last resort\n const finalQualifiedNameGroups = new Map<\n string,\n Array<ComponentInfo & { _parentPath: string[] }>\n >();\n group.forEach((comp) => {\n if (!finalQualifiedNameGroups.has(comp.propName)) {\n finalQualifiedNameGroups.set(comp.propName, []);\n }\n finalQualifiedNameGroups.get(comp.propName)!.push(comp);\n });\n\n finalQualifiedNameGroups.forEach(\n (finalDupGroup, finalQualifiedName) => {\n if (finalDupGroup.length > 1) {\n // Check if all duplicates have identical paths\n const allPathsIdentical = finalDupGroup.every((comp) => {\n const thisPath = comp._parentPath || [];\n return finalDupGroup.every((otherComp) => {\n if (otherComp.id === comp.id) return true;\n const otherPath = otherComp._parentPath || [];\n return arraysEqual(thisPath, otherPath);\n });\n });\n\n // Only use numeric suffixes if paths are truly identical\n if (allPathsIdentical) {\n let index = 0;\n finalDupGroup.forEach((comp) => {\n if (index > 0) {\n comp.propName = `${finalQualifiedName}${index + 1}`;\n }\n index++;\n });\n }\n }\n }\n );\n\n // Remove the temporary _parentPath property\n group.forEach((comp) => {\n delete (comp as any)._parentPath;\n });\n });\n\n // If we have an image component, remove color components with similar names\n // (they're usually placeholders/backgrounds)\n if (imageComponents.length > 0) {\n const imageComp = imageComponents[0];\n const imageName = (imageComp.name || \"\").toLowerCase();\n components = components.filter((comp) => {\n // Keep image components\n if (comp.type === \"component:image\") return true;\n // Remove color components that seem to be placeholders for images\n if (comp.type === \"component:color\") {\n const compName = (comp.name || \"\").toLowerCase();\n // If color component name is similar to image name, it's likely a placeholder\n if (imageName.includes(compName) || compName.includes(\"image\")) {\n return false;\n }\n }\n return true;\n });\n }\n\n slider.arrayContainer = {\n id: container.id,\n name: container.name || \"Item\",\n propName: sanitizePropName(container.name || \"items\"),\n components,\n };\n }\n\n sliders.push(slider);\n }\n\n // Recursively traverse children\n if (node.body && Array.isArray(node.body)) {\n node.body.forEach((child: any) => traverse(child, [...path, \"body\"]));\n }\n if (node.containers && Array.isArray(node.containers)) {\n node.containers.forEach((child: any) =>\n traverse(child, [...path, \"containers\"])\n );\n }\n if (node.components && Array.isArray(node.components)) {\n node.components.forEach((child: any) =>\n traverse(child, [...path, \"components\"])\n );\n }\n }\n\n // Start traversal from page data\n // Try multiple possible locations for the body\n const body =\n pageData.data?.body || pageData.body || (pageData as any).data?.body || [];\n\n if (Array.isArray(body) && body.length > 0) {\n body.forEach((node: any) => traverse(node));\n }\n\n return sliders;\n}\n\nexport function findStandaloneComponents(pageData: any): ComponentInfo[] {\n const components: ComponentInfo[] = [];\n const sliderIds = new Set<string>();\n\n // First, collect all slider IDs to exclude their children\n function collectSliderIds(node: any): void {\n if (!node || typeof node !== \"object\") return;\n\n if (node.type === \"container:slider\") {\n sliderIds.add(node.id);\n }\n\n if (node.body && Array.isArray(node.body)) {\n node.body.forEach(collectSliderIds);\n }\n if (node.containers && Array.isArray(node.containers)) {\n node.containers.forEach(collectSliderIds);\n }\n }\n\n // Traverse to find standalone components with bravo:data tags\n // Track parent component names for qualification\n function traverse(\n node: any,\n parentId?: string,\n parentPath: string[] = []\n ): void {\n if (!node || typeof node !== \"object\") return;\n\n // Skip if we're inside a slider\n if (parentId && sliderIds.has(parentId)) return;\n\n // Check if this component has bravo:data tag\n if (\n Array.isArray(node.tags) &&\n (node.tags.includes(\"encore:data\") || node.tags.includes(\"bravo:data\")) &&\n (node.type === \"component:text\" || node.type === \"component:image\")\n ) {\n const basePropName = sanitizePropName(node.name || \"item\");\n const propType = getComponentPropType(node.type, node.name);\n\n components.push({\n id: node.id,\n name: node.name || \"Unnamed\",\n type: node.type,\n tags: node.tags || [],\n propName: basePropName, // Will be qualified later if needed\n propType,\n // Store parent path for later qualification\n _parentPath: [...parentPath],\n } as ComponentInfo & { _parentPath: string[] });\n }\n\n // Build parent path: include this node's name if it's a container/component with a name\n // Skip generic \"Frame\" names - they're usually not meaningful for distinction\n const currentParentPath = [...parentPath];\n if (\n node.name &&\n (node.type?.startsWith(\"container:\") ||\n node.type?.startsWith(\"component:\"))\n ) {\n const name = node.name.trim();\n // Filter out generic \"Frame\" names (case-insensitive, with or without numbers/spaces)\n // But keep meaningful names like \"TripSlideFrame\" that contain other words\n const isGenericFrame =\n /^frame\\s*\\d*$/i.test(name) || name.toUpperCase() === \"FRAME\";\n if (name && !isGenericFrame) {\n currentParentPath.push(node.name);\n }\n }\n\n // Recursively traverse children\n const currentId = node.id;\n if (node.body && Array.isArray(node.body)) {\n node.body.forEach((child: any) =>\n traverse(child, currentId, currentParentPath)\n );\n }\n if (node.containers && Array.isArray(node.containers)) {\n node.containers.forEach((child: any) =>\n traverse(child, currentId, currentParentPath)\n );\n }\n if (node.components && Array.isArray(node.components)) {\n node.components.forEach((child: any) =>\n traverse(child, currentId, currentParentPath)\n );\n }\n }\n\n // Start traversal from page data\n const body =\n pageData.data?.body || pageData.body || (pageData as any).data?.body || [];\n\n if (Array.isArray(body) && body.length > 0) {\n body.forEach(collectSliderIds);\n body.forEach((node: any) => traverse(node));\n }\n\n // Detect duplicates and qualify them with minimal distinguishing paths\n // First pass: collect all base prop names and group duplicates\n const propNameGroups = new Map<\n string,\n Array<ComponentInfo & { _parentPath: string[] }>\n >();\n components.forEach((comp) => {\n const compWithPath = comp as ComponentInfo & { _parentPath: string[] };\n const baseName = comp.propName;\n if (!propNameGroups.has(baseName)) {\n propNameGroups.set(baseName, []);\n }\n propNameGroups.get(baseName)!.push(compWithPath);\n });\n\n // Second pass: for each group with duplicates, find minimal distinguishing paths\n // and ensure all qualified names are unique\n propNameGroups.forEach((group, _baseName) => {\n if (group.length === 1) {\n // No duplicates, keep the simple name\n return;\n }\n\n // First, find minimal distinguishing paths for all components\n group.forEach((comp) => {\n const otherPaths = group\n .filter((c) => c.id !== comp.id)\n .map((c) => c._parentPath || []);\n\n const minimalPath = findMinimalDistinguishingPath(\n comp._parentPath || [],\n otherPaths\n );\n\n // Use the minimal distinguishing path to qualify the name\n comp.propName = generateQualifiedPropName(\n comp.name || \"item\",\n minimalPath\n );\n });\n\n // Check if qualified names are still duplicates and expand paths if needed\n let hasDuplicates = true;\n let iteration = 0;\n const maxIterations = 10; // Safety limit\n\n while (hasDuplicates && iteration < maxIterations) {\n iteration++;\n const qualifiedNameGroups = new Map<\n string,\n Array<ComponentInfo & { _parentPath: string[] }>\n >();\n group.forEach((comp) => {\n if (!qualifiedNameGroups.has(comp.propName)) {\n qualifiedNameGroups.set(comp.propName, []);\n }\n qualifiedNameGroups.get(comp.propName)!.push(comp);\n });\n\n hasDuplicates = false;\n // For each group of still-duplicated qualified names, expand their paths\n qualifiedNameGroups.forEach((dupGroup, _qualifiedName) => {\n if (dupGroup.length > 1) {\n hasDuplicates = true;\n // Expand the distinguishing path for each duplicate\n dupGroup.forEach((comp) => {\n // Find a longer distinguishing path by comparing with others in the duplicate group\n const fullPath = comp._parentPath || [];\n const otherFullPaths = dupGroup\n .filter((c) => c.id !== comp.id)\n .map((c) => c._parentPath || []);\n\n // Find where this path diverges from others in the duplicate group\n let commonPrefixLength = 0;\n const maxCommonLength = Math.min(\n fullPath.length,\n ...otherFullPaths.map((p) => p.length)\n );\n\n for (let i = 0; i < maxCommonLength; i++) {\n const thisPart = fullPath[i];\n const allMatch = otherFullPaths.every((otherPath) => {\n return otherPath[i] === thisPart;\n });\n if (allMatch) {\n commonPrefixLength++;\n } else {\n break;\n }\n }\n\n // Use progressively more of the distinguishing suffix until unique\n const distinguishingSuffix = fullPath.slice(commonPrefixLength);\n\n // Try expanding the distinguishing suffix until we find a unique name\n let foundUnique = false;\n for (\n let suffixLength = 1;\n suffixLength <= distinguishingSuffix.length;\n suffixLength++\n ) {\n const expandedPath = distinguishingSuffix.slice(0, suffixLength);\n const testQualifiedName = generateQualifiedPropName(\n comp.name || \"item\",\n expandedPath\n );\n\n // Check if this qualified name is unique among ALL components (not just duplicates)\n const isUnique = components.every((otherComp) => {\n if (otherComp.id === comp.id) return true;\n // If other component is in the same duplicate group, compare expanded paths\n if (dupGroup.some((c) => c.id === otherComp.id)) {\n const otherFullPath =\n (otherComp as ComponentInfo & { _parentPath: string[] })\n ._parentPath || [];\n const otherCommonPrefixLength = Math.min(\n commonPrefixLength,\n otherFullPath.length\n );\n const otherDistinguishingSuffix = otherFullPath.slice(\n otherCommonPrefixLength\n );\n const otherExpandedPath = otherDistinguishingSuffix.slice(\n 0,\n suffixLength\n );\n const otherQualifiedName = generateQualifiedPropName(\n otherComp.name || \"item\",\n otherExpandedPath\n );\n return testQualifiedName !== otherQualifiedName;\n }\n // For components outside the duplicate group, just check the final prop name\n return testQualifiedName !== otherComp.propName;\n });\n\n if (isUnique) {\n comp.propName = testQualifiedName;\n foundUnique = true;\n break;\n }\n }\n\n // If we couldn't find a unique name with the distinguishing suffix,\n // use the full path to ensure uniqueness (even if it makes names longer)\n if (!foundUnique) {\n comp.propName = generateQualifiedPropName(\n comp.name || \"item\",\n fullPath\n );\n }\n });\n }\n });\n }\n\n // Final check: if there are still duplicates after using full paths,\n // and they have identical paths, use numeric suffixes as last resort\n const finalQualifiedNameGroups = new Map<\n string,\n Array<ComponentInfo & { _parentPath: string[] }>\n >();\n group.forEach((comp) => {\n if (!finalQualifiedNameGroups.has(comp.propName)) {\n finalQualifiedNameGroups.set(comp.propName, []);\n }\n finalQualifiedNameGroups.get(comp.propName)!.push(comp);\n });\n\n finalQualifiedNameGroups.forEach((finalDupGroup, finalQualifiedName) => {\n if (finalDupGroup.length > 1) {\n // Check if all duplicates have identical paths\n const allPathsIdentical = finalDupGroup.every((comp) => {\n const thisPath = comp._parentPath || [];\n return finalDupGroup.every((otherComp) => {\n if (otherComp.id === comp.id) return true;\n const otherPath = otherComp._parentPath || [];\n return arraysEqual(thisPath, otherPath);\n });\n });\n\n // Only use numeric suffixes if paths are truly identical\n if (allPathsIdentical) {\n let index = 0;\n finalDupGroup.forEach((comp) => {\n if (index > 0) {\n comp.propName = `${finalQualifiedName}${index + 1}`;\n }\n index++;\n });\n }\n }\n });\n\n // Remove the temporary _parentPath property\n group.forEach((comp) => {\n delete (comp as any)._parentPath;\n });\n });\n\n return components;\n}\n\nexport function findInputGroups(pageData: any): InputGroupInfo[] {\n const groupsMap = new Map<string, InputGroupInfo>();\n\n function traverse(node: any): void {\n if (!node || typeof node !== \"object\") return;\n\n // Check if this is an input-stateful-set with input-group tag\n if (\n node.type === \"component:input-stateful-set\" &&\n Array.isArray(node.tags)\n ) {\n const inputGroupTag = node.tags.find((tag: string) =>\n tag.startsWith(\"input-group:\")\n );\n if (inputGroupTag) {\n const parts = inputGroupTag.split(\":\");\n if (parts.length >= 3) {\n const groupType = parts[1];\n const groupName = parts[2];\n\n if (!groupsMap.has(groupName)) {\n groupsMap.set(groupName, {\n groupName,\n groupType,\n elements: [],\n });\n }\n\n const group = groupsMap.get(groupName)!;\n group.elements.push({\n id: node.id,\n name: node.name || \"Unnamed\",\n });\n }\n }\n }\n\n // Recursively traverse children\n if (node.body && Array.isArray(node.body)) {\n node.body.forEach(traverse);\n }\n if (node.containers && Array.isArray(node.containers)) {\n node.containers.forEach(traverse);\n }\n if (node.components && Array.isArray(node.components)) {\n node.components.forEach(traverse);\n }\n }\n\n // Start traversal from page data\n const body =\n pageData.data?.body || pageData.body || (pageData as any).data?.body || [];\n\n if (Array.isArray(body) && body.length > 0) {\n body.forEach((node: any) => traverse(node));\n }\n\n return Array.from(groupsMap.values());\n}\n\nexport function findForms(pageData: any): FormInfo[] {\n const forms: FormInfo[] = [];\n\n function traverse(node: any, parentContainer?: any): void {\n if (!node || typeof node !== \"object\") return;\n\n // Check if this is a container that might be a form\n const isContainer =\n node.type?.startsWith(\"container:\") || node.type === \"container:default\";\n const isNamedForm =\n node.name?.toLowerCase().includes(\"form\") ||\n (Array.isArray(node.tags) && node.tags.includes(\"form\"));\n\n // Check if this container or any child has a submit action\n let hasSubmitAction = false;\n let submitButtonId: string | undefined;\n\n function checkForSubmitAction(n: any): void {\n if (!n || typeof n !== \"object\") return;\n\n // Check if this node has a submit action\n if (\n Array.isArray(n.tags) &&\n (n.tags.includes(\"action:submit\") || n.tags.includes(\"submit\"))\n ) {\n hasSubmitAction = true;\n submitButtonId = n.id;\n return;\n }\n\n // Check actions\n if (n.actions?.tap?.action === \"submit\") {\n hasSubmitAction = true;\n submitButtonId = n.id;\n return;\n }\n\n // Recursively check children\n if (n.components && Array.isArray(n.components)) {\n n.components.forEach(checkForSubmitAction);\n }\n if (n.body && Array.isArray(n.body)) {\n n.body.forEach(checkForSubmitAction);\n }\n }\n\n // If this looks like a form container, check for submit actions\n if (isContainer && (isNamedForm || parentContainer === undefined)) {\n checkForSubmitAction(node);\n }\n\n // If we found a form container (has submit action or is named \"form\")\n if (isContainer && (hasSubmitAction || isNamedForm)) {\n const inputs: FormInfo[\"inputs\"] = [];\n\n // Find all input components within this container\n const findInputs = (n: any, parentPath: string[] = []): void => {\n if (!n || typeof n !== \"object\") return;\n\n // Check if this is an input component\n if (\n n.type?.startsWith(\"component:input-\") ||\n n.type === \"component:input-text\" ||\n n.type === \"component:input-image\" ||\n n.type === \"component:input-email\" ||\n n.type === \"component:input-password\" ||\n n.type === \"component:input-select\"\n ) {\n const basePropName = sanitizePropName(n.name || \"Unnamed input\");\n inputs.push({\n id: n.id,\n name: n.name || \"Unnamed input\",\n type: n.type,\n propName: basePropName, // Will be qualified later if needed\n _parentPath: [...parentPath], // Store parent path for qualification\n });\n }\n\n // Build parent path: include this node's name if it's a container/component with a name\n // Skip generic \"Frame\" names - they're usually not meaningful for distinction\n const currentParentPath = [...parentPath];\n if (\n n.name &&\n (n.type?.startsWith(\"container:\") || n.type?.startsWith(\"component:\"))\n ) {\n const name = n.name.trim();\n // Filter out generic \"Frame\" names (case-insensitive, with or without numbers/spaces)\n // But keep meaningful names like \"TripSlideFrame\" that contain other words\n const isGenericFrame =\n /^frame\\s*\\d*$/i.test(name) || name.toUpperCase() === \"FRAME\";\n if (name && !isGenericFrame) {\n currentParentPath.push(n.name);\n }\n }\n\n // Recursively search children\n if (n.components && Array.isArray(n.components)) {\n n.components.forEach((child: any) =>\n findInputs(child, currentParentPath)\n );\n }\n if (n.body && Array.isArray(n.body)) {\n n.body.forEach((child: any) => findInputs(child, currentParentPath));\n }\n };\n\n findInputs(node, []);\n\n // Only add form if it has inputs\n if (inputs.length > 0) {\n forms.push({\n formId: node.id,\n formName: node.name || \"Form\",\n submitButtonId,\n inputs,\n });\n }\n }\n\n // Recursively traverse children\n if (node.body && Array.isArray(node.body)) {\n node.body.forEach((child: any) =>\n traverse(child, isContainer ? node : parentContainer)\n );\n }\n if (node.containers && Array.isArray(node.containers)) {\n node.containers.forEach((child: any) =>\n traverse(child, isContainer ? node : parentContainer)\n );\n }\n if (node.components && Array.isArray(node.components)) {\n node.components.forEach((child: any) =>\n traverse(child, isContainer ? node : parentContainer)\n );\n }\n }\n\n // Start traversal from page data\n const body =\n pageData.data?.body || pageData.body || (pageData as any).data?.body || [];\n\n if (Array.isArray(body) && body.length > 0) {\n body.forEach((node: any) => traverse(node));\n }\n\n return forms;\n}\n\n/**\n * Finds standalone select input components (input-select) that are NOT inside forms.\n * These should be exposed as controlled inputs with value and onChange props.\n */\nexport function findStandaloneSelectInputs(\n pageData: any,\n forms: FormInfo[]\n): SelectInputInfo[] {\n const selectInputs: SelectInputInfo[] = [];\n\n // Collect all input IDs that are already in forms\n const formInputIds = new Set<string>();\n forms.forEach((form) => {\n form.inputs.forEach((input) => {\n formInputIds.add(input.id);\n });\n });\n\n // Traverse to find input-select components not in forms\n function traverse(node: any, parentPath: string[] = []): void {\n if (!node || typeof node !== \"object\") return;\n\n // Check if this is an input-select component\n if (node.type === \"component:input-select\" && !formInputIds.has(node.id)) {\n const basePropName = sanitizePropName(node.name || \"selectInput\");\n selectInputs.push({\n id: node.id,\n name: node.name || \"Select Input\",\n propName: basePropName,\n _parentPath: [...parentPath],\n });\n }\n\n // Build parent path for qualification\n const currentParentPath = [...parentPath];\n if (\n node.name &&\n (node.type?.startsWith(\"container:\") ||\n node.type?.startsWith(\"component:\"))\n ) {\n const name = node.name.trim();\n const isGenericFrame =\n /^frame\\s*\\d*$/i.test(name) || name.toUpperCase() === \"FRAME\";\n if (name && !isGenericFrame) {\n currentParentPath.push(node.name);\n }\n }\n\n // Recursively traverse children\n if (node.body && Array.isArray(node.body)) {\n node.body.forEach((child: any) => traverse(child, currentParentPath));\n }\n if (node.containers && Array.isArray(node.containers)) {\n node.containers.forEach((child: any) =>\n traverse(child, currentParentPath)\n );\n }\n if (node.components && Array.isArray(node.components)) {\n node.components.forEach((child: any) =>\n traverse(child, currentParentPath)\n );\n }\n }\n\n // Start traversal from page data\n const body =\n pageData.data?.body || pageData.body || (pageData as any).data?.body || [];\n\n if (Array.isArray(body) && body.length > 0) {\n body.forEach((node: any) => traverse(node));\n }\n\n // Qualify duplicate prop names\n qualifySelectInputs(selectInputs);\n\n return selectInputs;\n}\n\n/**\n * Qualifies select input prop names to ensure uniqueness.\n */\nfunction qualifySelectInputs(selectInputs: SelectInputInfo[]): void {\n const propNameGroups = new Map<\n string,\n Array<SelectInputInfo & { _parentPath: string[] }>\n >();\n\n selectInputs.forEach((input) => {\n const inputWithPath = input as SelectInputInfo & { _parentPath: string[] };\n const baseName = input.propName;\n if (!propNameGroups.has(baseName)) {\n propNameGroups.set(baseName, []);\n }\n propNameGroups.get(baseName)!.push(inputWithPath);\n });\n\n propNameGroups.forEach((group, _baseName) => {\n if (group.length === 1) {\n delete (group[0] as any)._parentPath;\n return;\n }\n\n // Find minimal distinguishing paths for duplicates\n group.forEach((input) => {\n const otherPaths = group\n .filter((i) => i.id !== input.id)\n .map((i) => i._parentPath || []);\n\n const minimalPath = findMinimalDistinguishingPath(\n input._parentPath || [],\n otherPaths\n );\n\n input.propName = generateQualifiedPropName(\n input.name || \"input\",\n minimalPath\n );\n });\n\n // Clean up\n group.forEach((input) => {\n delete (input as any)._parentPath;\n });\n });\n}\n\n/**\n * Finds action buttons - components that have action tags (action:remote, action:link, etc.)\n * or have actions defined. These should be exposed with onClick handlers.\n */\nexport function findActionButtons(pageData: any): ActionButtonInfo[] {\n const buttons: ActionButtonInfo[] = [];\n\n function traverse(node: any, parentPath: string[] = []): void {\n if (!node || typeof node !== \"object\") return;\n\n // Check if this component has an action tag or actions defined\n const hasActionTag =\n Array.isArray(node.tags) &&\n node.tags.some((tag: string) => tag.startsWith(\"action:\"));\n const hasActions = node.actions && typeof node.actions === \"object\";\n\n if (hasActionTag || hasActions) {\n // Determine the action type\n let actionType = \"tap\";\n if (Array.isArray(node.tags)) {\n const actionTag = node.tags.find((tag: string) =>\n tag.startsWith(\"action:\")\n );\n if (actionTag) {\n actionType = actionTag.replace(\"action:\", \"\");\n }\n }\n if (node.actions?.tap?.action) {\n actionType = node.actions.tap.action;\n }\n\n const basePropName = sanitizePropName(node.name || \"button\");\n buttons.push({\n id: node.id,\n name: node.name || \"Button\",\n propName: basePropName,\n actionType,\n _parentPath: [...parentPath],\n });\n }\n\n // Build parent path for qualification\n const currentParentPath = [...parentPath];\n if (\n node.name &&\n (node.type?.startsWith(\"container:\") ||\n node.type?.startsWith(\"component:\"))\n ) {\n const name = node.name.trim();\n const isGenericFrame =\n /^frame\\s*\\d*$/i.test(name) || name.toUpperCase() === \"FRAME\";\n if (name && !isGenericFrame) {\n currentParentPath.push(node.name);\n }\n }\n\n // Recursively traverse children\n if (node.body && Array.isArray(node.body)) {\n node.body.forEach((child: any) => traverse(child, currentParentPath));\n }\n if (node.containers && Array.isArray(node.containers)) {\n node.containers.forEach((child: any) =>\n traverse(child, currentParentPath)\n );\n }\n if (node.components && Array.isArray(node.components)) {\n node.components.forEach((child: any) =>\n traverse(child, currentParentPath)\n );\n }\n }\n\n // Start traversal from page data\n const body =\n pageData.data?.body || pageData.body || (pageData as any).data?.body || [];\n\n if (Array.isArray(body) && body.length > 0) {\n body.forEach((node: any) => traverse(node));\n }\n\n // Qualify duplicate prop names\n qualifyActionButtons(buttons);\n\n return buttons;\n}\n\n/**\n * Qualifies action button prop names to ensure uniqueness.\n */\nfunction qualifyActionButtons(buttons: ActionButtonInfo[]): void {\n const propNameGroups = new Map<\n string,\n Array<ActionButtonInfo & { _parentPath: string[] }>\n >();\n\n buttons.forEach((button) => {\n const buttonWithPath = button as ActionButtonInfo & {\n _parentPath: string[];\n };\n const baseName = button.propName;\n if (!propNameGroups.has(baseName)) {\n propNameGroups.set(baseName, []);\n }\n propNameGroups.get(baseName)!.push(buttonWithPath);\n });\n\n propNameGroups.forEach((group, _baseName) => {\n if (group.length === 1) {\n delete (group[0] as any)._parentPath;\n return;\n }\n\n // Find minimal distinguishing paths for duplicates\n group.forEach((button) => {\n const otherPaths = group\n .filter((b) => b.id !== button.id)\n .map((b) => b._parentPath || []);\n\n const minimalPath = findMinimalDistinguishingPath(\n button._parentPath || [],\n otherPaths\n );\n\n button.propName = generateQualifiedPropName(\n button.name || \"button\",\n minimalPath\n );\n });\n\n // Clean up\n group.forEach((button) => {\n delete (button as any)._parentPath;\n });\n });\n}\n\n/**\n * Qualifies form input prop names to ensure uniqueness within each form.\n * Only qualifies where necessary, using minimal distinguishing paths.\n */\nexport function qualifyFormInputs(forms: FormInfo[]): void {\n forms.forEach((form) => {\n const inputs = form.inputs;\n\n // Group inputs by base prop name\n const propNameGroups = new Map<\n string,\n Array<FormInfo[\"inputs\"][0] & { _parentPath: string[] }>\n >();\n\n inputs.forEach((input) => {\n const inputWithPath = input as FormInfo[\"inputs\"][0] & {\n _parentPath: string[];\n };\n const baseName = input.propName;\n if (!propNameGroups.has(baseName)) {\n propNameGroups.set(baseName, []);\n }\n propNameGroups.get(baseName)!.push(inputWithPath);\n });\n\n // For each group with duplicates, find minimal distinguishing paths\n propNameGroups.forEach((group, _baseName) => {\n if (group.length === 1) {\n // No duplicates, keep the simple name\n // Remove the temporary _parentPath property\n delete (group[0] as any)._parentPath;\n return;\n }\n\n // Find minimal distinguishing paths for all inputs\n group.forEach((input) => {\n const otherPaths = group\n .filter((i) => i.id !== input.id)\n .map((i) => i._parentPath || []);\n\n const minimalPath = findMinimalDistinguishingPath(\n input._parentPath || [],\n otherPaths\n );\n\n // Use the minimal distinguishing path to qualify the name\n input.propName = generateQualifiedPropName(\n input.name || \"input\",\n minimalPath\n );\n });\n\n // Check if qualified names are still duplicates and expand paths if needed\n let hasDuplicates = true;\n let iteration = 0;\n const maxIterations = 10; // Safety limit\n\n while (hasDuplicates && iteration < maxIterations) {\n iteration++;\n const qualifiedNameGroups = new Map<\n string,\n Array<FormInfo[\"inputs\"][0] & { _parentPath: string[] }>\n >();\n group.forEach((input) => {\n if (!qualifiedNameGroups.has(input.propName)) {\n qualifiedNameGroups.set(input.propName, []);\n }\n qualifiedNameGroups.get(input.propName)!.push(input);\n });\n\n hasDuplicates = false;\n // For each group of still-duplicated qualified names, expand their paths\n qualifiedNameGroups.forEach((dupGroup, _qualifiedName) => {\n if (dupGroup.length > 1) {\n hasDuplicates = true;\n // Expand the distinguishing path for each duplicate\n dupGroup.forEach((input) => {\n const fullPath = input._parentPath || [];\n const otherFullPaths = dupGroup\n .filter((i) => i.id !== input.id)\n .map((i) => i._parentPath || []);\n\n // Find where this path diverges from others in the duplicate group\n let commonPrefixLength = 0;\n const maxCommonLength = Math.min(\n fullPath.length,\n ...otherFullPaths.map((p) => p.length)\n );\n\n for (let i = 0; i < maxCommonLength; i++) {\n const thisPart = fullPath[i];\n const allMatch = otherFullPaths.every((otherPath) => {\n return otherPath[i] === thisPart;\n });\n if (allMatch) {\n commonPrefixLength++;\n } else {\n break;\n }\n }\n\n // Use progressively more of the distinguishing suffix until unique\n const distinguishingSuffix = fullPath.slice(commonPrefixLength);\n\n // Try expanding the distinguishing suffix until we find a unique name\n let foundUnique = false;\n for (\n let suffixLength = 1;\n suffixLength <= distinguishingSuffix.length;\n suffixLength++\n ) {\n const expandedPath = distinguishingSuffix.slice(\n 0,\n suffixLength\n );\n const testQualifiedName = generateQualifiedPropName(\n input.name || \"input\",\n expandedPath\n );\n\n // Check if this qualified name is unique among ALL inputs in this form\n const isUnique = inputs.every((otherInput) => {\n if (otherInput.id === input.id) return true;\n // If other input is in the same duplicate group, compare expanded paths\n if (dupGroup.some((i) => i.id === otherInput.id)) {\n const otherFullPath =\n (\n otherInput as FormInfo[\"inputs\"][0] & {\n _parentPath: string[];\n }\n )._parentPath || [];\n const otherCommonPrefixLength = Math.min(\n commonPrefixLength,\n otherFullPath.length\n );\n const otherDistinguishingSuffix = otherFullPath.slice(\n otherCommonPrefixLength\n );\n const otherExpandedPath = otherDistinguishingSuffix.slice(\n 0,\n suffixLength\n );\n const otherQualifiedName = generateQualifiedPropName(\n otherInput.name || \"input\",\n otherExpandedPath\n );\n return testQualifiedName !== otherQualifiedName;\n }\n // For inputs outside the duplicate group, just check the final prop name\n return testQualifiedName !== otherInput.propName;\n });\n\n if (isUnique) {\n input.propName = testQualifiedName;\n foundUnique = true;\n break;\n }\n }\n\n // If we couldn't find a unique name with the distinguishing suffix,\n // use the distinguishing suffix we found (it's the minimal we can do)\n if (!foundUnique) {\n input.propName = generateQualifiedPropName(\n input.name || \"input\",\n distinguishingSuffix.length > 0 ? distinguishingSuffix : []\n );\n }\n });\n }\n });\n }\n\n // Final check: if there are still duplicates after using full paths,\n // and they have identical paths, use numeric suffixes as last resort\n const finalQualifiedNameGroups = new Map<\n string,\n Array<FormInfo[\"inputs\"][0] & { _parentPath: string[] }>\n >();\n group.forEach((input) => {\n if (!finalQualifiedNameGroups.has(input.propName)) {\n finalQualifiedNameGroups.set(input.propName, []);\n }\n finalQualifiedNameGroups.get(input.propName)!.push(input);\n });\n\n finalQualifiedNameGroups.forEach((finalDupGroup, finalQualifiedName) => {\n if (finalDupGroup.length > 1) {\n // Check if all duplicates have identical paths\n const allPathsIdentical = finalDupGroup.every((input) => {\n const thisPath = input._parentPath || [];\n return finalDupGroup.every((otherInput) => {\n if (otherInput.id === input.id) return true;\n const otherPath = otherInput._parentPath || [];\n return arraysEqual(thisPath, otherPath);\n });\n });\n\n // Only use numeric suffixes if paths are truly identical\n if (allPathsIdentical) {\n let index = 0;\n finalDupGroup.forEach((input) => {\n if (index > 0) {\n input.propName = `${finalQualifiedName}${index + 1}`;\n }\n index++;\n });\n }\n }\n });\n\n // Remove the temporary _parentPath property\n group.forEach((input) => {\n delete (input as any)._parentPath;\n });\n });\n });\n}\n"],"names":["sanitizePropName","name","cleaned","word","index","normalizedWord","firstChar","rest","generateQualifiedPropName","componentName","parentPath","baseName","validParentParts","part","findMinimalDistinguishingPath","thisPath","otherPaths","commonPrefixLength","maxCommonLength","p","i","thisPart","otherPath","distinguishingSuffix","suffixLength","thisSuffix","otherSuffix","arraysEqual","a","b","val","idx","getComponentPropType","componentType","_componentName","getComponentPropName","findSlidersAndDataBindings","pageData","sliders","traverse","node","path","slider","arrayContainer","findArrayContainer","containerNode","container","components","imageComponents","findDataComponents","comp","basePropName","propType","currentParentPath","isGenericFrame","child","c","imageComp","propNameGroups","compWithPath","group","_baseName","minimalPath","hasDuplicates","iteration","maxIterations","qualifiedNameGroups","dupGroup","_qualifiedName","fullPath","otherFullPaths","foundUnique","expandedPath","testQualifiedName","otherComp","otherFullPath","otherCommonPrefixLength","otherExpandedPath","otherQualifiedName","finalQualifiedNameGroups","finalDupGroup","finalQualifiedName","imageName","compName","body","findStandaloneComponents","sliderIds","collectSliderIds","parentId","currentId","findInputGroups","groupsMap","inputGroupTag","tag","parts","groupType","groupName","findForms","forms","parentContainer","isContainer","isNamedForm","hasSubmitAction","submitButtonId","checkForSubmitAction","n","inputs","findInputs","findStandaloneSelectInputs","selectInputs","formInputIds","form","input","qualifySelectInputs","inputWithPath","findActionButtons","buttons","hasActionTag","hasActions","actionType","actionTag","qualifyActionButtons","button","buttonWithPath","qualifyFormInputs","otherInput"],"mappings":"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"}