galaxy-design 0.2.73 → 0.2.74

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 (50) hide show
  1. package/README.md +113 -95
  2. package/dist/bin.js +17 -1
  3. package/dist/bin.js.map +1 -1
  4. package/dist/commands/add.js +59 -99
  5. package/dist/commands/add.js.map +1 -1
  6. package/dist/commands/init.js +120 -611
  7. package/dist/commands/init.js.map +1 -1
  8. package/dist/commands/migrate-tailwind.js +90 -0
  9. package/dist/commands/migrate-tailwind.js.map +1 -0
  10. package/dist/index.js +6 -1
  11. package/dist/index.js.map +1 -1
  12. package/dist/registries/registry-angular.json +145 -537
  13. package/dist/registry-angular.json +145 -537
  14. package/dist/schemas/components-schema.json +66 -11
  15. package/dist/schemas/registry-framework-schema.json +17 -7
  16. package/dist/utils/angular-provider-manager.js +1 -1
  17. package/dist/utils/angular-provider-manager.js.map +1 -1
  18. package/dist/utils/component-copier.js +102 -62
  19. package/dist/utils/component-copier.js.map +1 -1
  20. package/dist/utils/component-transformer.js +86 -16
  21. package/dist/utils/component-transformer.js.map +1 -1
  22. package/dist/utils/config-schema.js +160 -9
  23. package/dist/utils/config-schema.js.map +1 -1
  24. package/dist/utils/framework-registry-service.js +181 -0
  25. package/dist/utils/framework-registry-service.js.map +1 -0
  26. package/dist/utils/framework-registry.js +1 -138
  27. package/dist/utils/framework-registry.js.map +1 -1
  28. package/dist/utils/github-fetcher.js +55 -27
  29. package/dist/utils/github-fetcher.js.map +1 -1
  30. package/dist/utils/index.js +4 -3
  31. package/dist/utils/index.js.map +1 -1
  32. package/dist/utils/init-runtime.js +477 -0
  33. package/dist/utils/init-runtime.js.map +1 -0
  34. package/dist/utils/init-scaffold.js +115 -0
  35. package/dist/utils/init-scaffold.js.map +1 -0
  36. package/dist/utils/init-workflow.js +189 -0
  37. package/dist/utils/init-workflow.js.map +1 -0
  38. package/dist/utils/package-manager.js +77 -2
  39. package/dist/utils/package-manager.js.map +1 -1
  40. package/dist/utils/platform-detector.js +12 -8
  41. package/dist/utils/platform-detector.js.map +1 -1
  42. package/dist/utils/registry-loader.js +20 -41
  43. package/dist/utils/registry-loader.js.map +1 -1
  44. package/dist/utils/tailwind-detector.js +162 -0
  45. package/dist/utils/tailwind-detector.js.map +1 -0
  46. package/dist/utils/tailwind-migration.js +401 -0
  47. package/dist/utils/tailwind-migration.js.map +1 -0
  48. package/dist/utils/tailwind-scaffold.js +398 -0
  49. package/dist/utils/tailwind-scaffold.js.map +1 -0
  50. package/package.json +20 -2
@@ -3,7 +3,12 @@
3
3
  "title": "Galaxy UI Configuration",
4
4
  "description": "Configuration file for Galaxy UI components",
5
5
  "type": "object",
6
- "required": ["framework", "typescript", "tailwind", "aliases"],
6
+ "required": [
7
+ "framework",
8
+ "typescript",
9
+ "tailwind",
10
+ "aliases"
11
+ ],
7
12
  "properties": {
8
13
  "$schema": {
9
14
  "type": "string",
@@ -11,7 +16,15 @@
11
16
  },
12
17
  "framework": {
13
18
  "type": "string",
14
- "enum": ["vue", "react", "angular"],
19
+ "enum": [
20
+ "vue",
21
+ "react",
22
+ "angular",
23
+ "react-native",
24
+ "flutter",
25
+ "nextjs",
26
+ "nuxtjs"
27
+ ],
15
28
  "description": "The framework used in the project"
16
29
  },
17
30
  "typescript": {
@@ -21,11 +34,26 @@
21
34
  },
22
35
  "tailwind": {
23
36
  "type": "object",
24
- "required": ["config", "css"],
37
+ "required": [
38
+ "config",
39
+ "css"
40
+ ],
25
41
  "properties": {
42
+ "version": {
43
+ "type": [
44
+ "integer",
45
+ "null"
46
+ ],
47
+ "enum": [
48
+ 3,
49
+ 4,
50
+ null
51
+ ],
52
+ "description": "Detected or selected Tailwind major version"
53
+ },
26
54
  "config": {
27
55
  "type": "string",
28
- "description": "Path to the Tailwind configuration file",
56
+ "description": "Path to the Tailwind configuration file. May be empty when using Tailwind v4 CSS-first setup.",
29
57
  "default": "tailwind.config.js"
30
58
  },
31
59
  "css": {
@@ -40,7 +68,13 @@
40
68
  "baseColor": {
41
69
  "type": "string",
42
70
  "description": "Base color for components",
43
- "enum": ["slate", "gray", "zinc", "neutral", "stone"],
71
+ "enum": [
72
+ "slate",
73
+ "gray",
74
+ "zinc",
75
+ "neutral",
76
+ "stone"
77
+ ],
44
78
  "default": "slate"
45
79
  },
46
80
  "cssVariables": {
@@ -57,33 +91,54 @@
57
91
  },
58
92
  "aliases": {
59
93
  "type": "object",
60
- "required": ["components", "utils"],
94
+ "required": [
95
+ "components",
96
+ "utils"
97
+ ],
61
98
  "properties": {
62
99
  "components": {
63
100
  "type": "string",
64
101
  "description": "Import alias for components directory",
65
- "examples": ["@/components", "~/components", "src/components"]
102
+ "examples": [
103
+ "@/components",
104
+ "~/components",
105
+ "src/components"
106
+ ]
66
107
  },
67
108
  "utils": {
68
109
  "type": "string",
69
110
  "description": "Import alias for utils directory",
70
- "examples": ["@/lib/utils", "@/utils", "~/lib/utils"]
111
+ "examples": [
112
+ "@/lib/utils",
113
+ "@/utils",
114
+ "~/lib/utils"
115
+ ]
71
116
  },
72
117
  "ui": {
73
118
  "type": "string",
74
119
  "description": "Import alias for UI components directory",
75
- "examples": ["@/components/ui", "~/components/ui"]
120
+ "examples": [
121
+ "@/components/ui",
122
+ "~/components/ui"
123
+ ]
76
124
  },
77
125
  "lib": {
78
126
  "type": "string",
79
127
  "description": "Import alias for lib directory",
80
- "examples": ["@/lib", "~/lib"]
128
+ "examples": [
129
+ "@/lib",
130
+ "~/lib"
131
+ ]
81
132
  }
82
133
  }
83
134
  },
84
135
  "iconLibrary": {
85
136
  "type": "string",
86
- "enum": ["lucide", "heroicons", "radix-icons"],
137
+ "enum": [
138
+ "lucide",
139
+ "heroicons",
140
+ "radix-icons"
141
+ ],
87
142
  "description": "Icon library to use",
88
143
  "default": "lucide"
89
144
  }
@@ -10,13 +10,7 @@
10
10
  },
11
11
  "framework": {
12
12
  "type": "string",
13
- "enum": [
14
- "react",
15
- "vue",
16
- "angular",
17
- "react-native",
18
- "flutter"
19
- ]
13
+ "enum": ["react", "vue", "angular", "react-native", "flutter"]
20
14
  },
21
15
  "components": {
22
16
  "type": "object",
@@ -48,6 +42,19 @@
48
42
  },
49
43
  "additionalProperties": false
50
44
  },
45
+ "providerConfig": {
46
+ "type": "object",
47
+ "required": ["import", "function"],
48
+ "properties": {
49
+ "import": {
50
+ "type": "string"
51
+ },
52
+ "function": {
53
+ "type": "string"
54
+ }
55
+ },
56
+ "additionalProperties": false
57
+ },
51
58
  "frameworkComponent": {
52
59
  "type": "object",
53
60
  "required": [
@@ -67,6 +74,9 @@
67
74
  "selector": {
68
75
  "type": "string"
69
76
  },
77
+ "providers": {
78
+ "$ref": "#/definitions/providerConfig"
79
+ },
70
80
  "type": {
71
81
  "type": "string",
72
82
  "enum": [
@@ -1,7 +1,7 @@
1
1
  import { readdirSync, existsSync } from 'fs';
2
2
  import { join } from 'path';
3
3
  import { writeFile } from './files.js';
4
- import { getFrameworkComponent } from './framework-registry.js';
4
+ import { getFrameworkComponent } from './framework-registry-service.js';
5
5
  /**
6
6
  * Generate or update the components/ui/index.ts file with auto-generated providers
7
7
  * This implements Solution 4 - dynamic provider management based on installed components
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/angular-provider-manager.ts"],"sourcesContent":["import { readdirSync, existsSync } from 'fs';\nimport { join } from 'path';\nimport { writeFile } from './files.js';\nimport { getFrameworkComponent } from './framework-registry.js';\n\n/**\n * Provider configuration from registry\n */\ninterface ProviderConfig {\n import: string;\n function: string;\n}\n\n/**\n * Component with provider information\n */\ninterface ComponentWithProvider {\n componentKey: string;\n componentName: string;\n provider: ProviderConfig;\n}\n\n/**\n * Generate or update the components/ui/index.ts file with auto-generated providers\n * This implements Solution 4 - dynamic provider management based on installed components\n *\n * @param componentsUiPath - Path to components/ui directory\n * @param framework - Framework (should be 'angular')\n * @returns Success boolean\n */\nexport function generateAngularProvidersIndex(\n componentsUiPath: string,\n framework: 'angular' = 'angular'\n): boolean {\n try {\n // Scan components/ui directory to find all installed components\n if (!existsSync(componentsUiPath)) {\n console.log(`Components directory does not exist: ${componentsUiPath}`);\n return false;\n }\n\n const installedComponents = readdirSync(componentsUiPath, { withFileTypes: true })\n .filter((dirent) => dirent.isDirectory())\n .map((dirent) => dirent.name)\n .filter((name) => !name.startsWith('.') && !name.startsWith('_'));\n\n // For each installed component, check if it has provider configuration\n const componentsWithProviders: ComponentWithProvider[] = [];\n\n for (const componentKey of installedComponents) {\n const component = getFrameworkComponent(framework, componentKey);\n\n if (component && component.providers) {\n componentsWithProviders.push({\n componentKey,\n componentName: component.name,\n provider: component.providers,\n });\n }\n }\n\n // Generate the index.ts file content\n const content = generateIndexContent(installedComponents, componentsWithProviders);\n\n // Write the file\n const indexPath = join(componentsUiPath, 'index.ts');\n writeFile(indexPath, content);\n\n return true;\n } catch (error) {\n console.error('Failed to generate Angular providers index:', error);\n return false;\n }\n}\n\n/**\n * Generate the content for the auto-generated index.ts file\n *\n * @param allComponents - All installed component keys\n * @param componentsWithProviders - Components that have provider configuration\n * @returns Generated file content\n */\nfunction generateIndexContent(\n allComponents: string[],\n componentsWithProviders: ComponentWithProvider[]\n): string {\n const lines: string[] = [];\n\n // Header comment\n lines.push('// Auto-generated by galaxy-design CLI - DO NOT EDIT MANUALLY');\n lines.push('// This file is regenerated every time you add or remove components');\n lines.push('');\n\n // Export all components\n lines.push('// Component exports');\n for (const componentKey of allComponents.sort()) {\n lines.push(`export * from './${componentKey}';`);\n }\n\n // Only add providers section if there are components with providers\n if (componentsWithProviders.length > 0) {\n lines.push('');\n lines.push('// Provider imports for components that require Angular providers');\n\n // Add import statements\n const uniqueImports = new Set<string>();\n for (const { provider } of componentsWithProviders) {\n uniqueImports.add(provider.import);\n }\n\n for (const importStatement of Array.from(uniqueImports).sort()) {\n lines.push(importStatement);\n }\n\n lines.push('');\n lines.push('/**');\n lines.push(' * Provide all required Angular providers for Galaxy UI components');\n lines.push(' * Add this to your app.config.ts providers array:');\n lines.push(' * ');\n lines.push(' * ```typescript');\n lines.push(' * export const appConfig: ApplicationConfig = {');\n lines.push(' * providers: [');\n lines.push(' * provideGalaxyComponents(),');\n lines.push(' * // ... other providers');\n lines.push(' * ]');\n lines.push(' * };');\n lines.push(' * ```');\n lines.push(' * ');\n lines.push(\n ` * This function provides configuration for: ${componentsWithProviders.map((c) => c.componentName).join(', ')}`\n );\n lines.push(' */');\n lines.push('export function provideGalaxyComponents() {');\n lines.push(' return [');\n\n // Add provider function calls\n for (const { provider } of componentsWithProviders) {\n lines.push(` ${provider.function},`);\n }\n\n lines.push(' ];');\n lines.push('}');\n } else {\n lines.push('');\n lines.push('// No components requiring Angular providers are currently installed');\n }\n\n lines.push('');\n\n return lines.join('\\n');\n}\n\n/**\n * Check if a component has provider configuration\n *\n * @param componentKey - Component key\n * @param framework - Framework\n * @returns True if component has providers\n */\nexport function componentHasProviders(\n componentKey: string,\n framework: 'angular' = 'angular'\n): boolean {\n const component = getFrameworkComponent(framework, componentKey);\n return !!(component && component.providers);\n}\n"],"names":["readdirSync","existsSync","join","writeFile","getFrameworkComponent","generateAngularProvidersIndex","componentsUiPath","framework","console","log","installedComponents","withFileTypes","filter","dirent","isDirectory","map","name","startsWith","componentsWithProviders","componentKey","component","providers","push","componentName","provider","content","generateIndexContent","indexPath","error","allComponents","lines","sort","length","uniqueImports","Set","add","import","importStatement","Array","from","c","function","componentHasProviders"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/utils/angular-provider-manager.ts"],"sourcesContent":["import { readdirSync, existsSync } from 'fs';\nimport { join } from 'path';\nimport { writeFile } from './files.js';\nimport { getFrameworkComponent } from './framework-registry-service.js';\n\n/**\n * Provider configuration from registry\n */\ninterface ProviderConfig {\n import: string;\n function: string;\n}\n\n/**\n * Component with provider information\n */\ninterface ComponentWithProvider {\n componentKey: string;\n componentName: string;\n provider: ProviderConfig;\n}\n\n/**\n * Generate or update the components/ui/index.ts file with auto-generated providers\n * This implements Solution 4 - dynamic provider management based on installed components\n *\n * @param componentsUiPath - Path to components/ui directory\n * @param framework - Framework (should be 'angular')\n * @returns Success boolean\n */\nexport function generateAngularProvidersIndex(\n componentsUiPath: string,\n framework: 'angular' = 'angular',\n): boolean {\n try {\n // Scan components/ui directory to find all installed components\n if (!existsSync(componentsUiPath)) {\n console.log(`Components directory does not exist: ${componentsUiPath}`);\n return false;\n }\n\n const installedComponents = readdirSync(componentsUiPath, {\n withFileTypes: true,\n })\n .filter((dirent) => dirent.isDirectory())\n .map((dirent) => dirent.name)\n .filter((name) => !name.startsWith('.') && !name.startsWith('_'));\n\n // For each installed component, check if it has provider configuration\n const componentsWithProviders: ComponentWithProvider[] = [];\n\n for (const componentKey of installedComponents) {\n const component = getFrameworkComponent(framework, componentKey);\n\n if (component && component.providers) {\n componentsWithProviders.push({\n componentKey,\n componentName: component.name,\n provider: component.providers,\n });\n }\n }\n\n // Generate the index.ts file content\n const content = generateIndexContent(\n installedComponents,\n componentsWithProviders,\n );\n\n // Write the file\n const indexPath = join(componentsUiPath, 'index.ts');\n writeFile(indexPath, content);\n\n return true;\n } catch (error) {\n console.error('Failed to generate Angular providers index:', error);\n return false;\n }\n}\n\n/**\n * Generate the content for the auto-generated index.ts file\n *\n * @param allComponents - All installed component keys\n * @param componentsWithProviders - Components that have provider configuration\n * @returns Generated file content\n */\nfunction generateIndexContent(\n allComponents: string[],\n componentsWithProviders: ComponentWithProvider[],\n): string {\n const lines: string[] = [];\n\n // Header comment\n lines.push('// Auto-generated by galaxy-design CLI - DO NOT EDIT MANUALLY');\n lines.push(\n '// This file is regenerated every time you add or remove components',\n );\n lines.push('');\n\n // Export all components\n lines.push('// Component exports');\n for (const componentKey of allComponents.sort()) {\n lines.push(`export * from './${componentKey}';`);\n }\n\n // Only add providers section if there are components with providers\n if (componentsWithProviders.length > 0) {\n lines.push('');\n lines.push(\n '// Provider imports for components that require Angular providers',\n );\n\n // Add import statements\n const uniqueImports = new Set<string>();\n for (const { provider } of componentsWithProviders) {\n uniqueImports.add(provider.import);\n }\n\n for (const importStatement of Array.from(uniqueImports).sort()) {\n lines.push(importStatement);\n }\n\n lines.push('');\n lines.push('/**');\n lines.push(\n ' * Provide all required Angular providers for Galaxy UI components',\n );\n lines.push(' * Add this to your app.config.ts providers array:');\n lines.push(' * ');\n lines.push(' * ```typescript');\n lines.push(' * export const appConfig: ApplicationConfig = {');\n lines.push(' * providers: [');\n lines.push(' * provideGalaxyComponents(),');\n lines.push(' * // ... other providers');\n lines.push(' * ]');\n lines.push(' * };');\n lines.push(' * ```');\n lines.push(' * ');\n lines.push(\n ` * This function provides configuration for: ${componentsWithProviders.map((c) => c.componentName).join(', ')}`,\n );\n lines.push(' */');\n lines.push('export function provideGalaxyComponents() {');\n lines.push(' return [');\n\n // Add provider function calls\n for (const { provider } of componentsWithProviders) {\n lines.push(` ${provider.function},`);\n }\n\n lines.push(' ];');\n lines.push('}');\n } else {\n lines.push('');\n lines.push(\n '// No components requiring Angular providers are currently installed',\n );\n }\n\n lines.push('');\n\n return lines.join('\\n');\n}\n\n/**\n * Check if a component has provider configuration\n *\n * @param componentKey - Component key\n * @param framework - Framework\n * @returns True if component has providers\n */\nexport function componentHasProviders(\n componentKey: string,\n framework: 'angular' = 'angular',\n): boolean {\n const component = getFrameworkComponent(framework, componentKey);\n return !!(component && component.providers);\n}\n"],"names":["readdirSync","existsSync","join","writeFile","getFrameworkComponent","generateAngularProvidersIndex","componentsUiPath","framework","console","log","installedComponents","withFileTypes","filter","dirent","isDirectory","map","name","startsWith","componentsWithProviders","componentKey","component","providers","push","componentName","provider","content","generateIndexContent","indexPath","error","allComponents","lines","sort","length","uniqueImports","Set","add","import","importStatement","Array","from","c","function","componentHasProviders"],"mappings":"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"}
@@ -1,105 +1,143 @@
1
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
1
+ import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'fs';
2
2
  import { dirname, join, relative } from 'path';
3
- import { getComponentSourceDir, isMobilePlatform } from './platform-detector';
4
- import { getComponent, validateComponentDependencies } from './registry-loader';
5
- import { fetchAndSaveFile, getComponentGitHubPath } from './github-fetcher';
6
- import { transformComponent } from './component-transformer';
7
- /**
8
- * Copy a component to target project
9
- *
10
- * @param componentName - Name of component to copy
11
- * @param options - Copy options
12
- * @returns Copy result
13
- */ export async function copyComponent(componentName, options) {
3
+ import { getComponentSourceDir } from './platform-detector.js';
4
+ import { getFrameworkComponent, validateFrameworkComponentDependencies } from './framework-registry-service.js';
5
+ import { fetchFileFromGitHub, getComponentGitHubPath } from './github-fetcher.js';
6
+ import { transformComponent } from './component-transformer.js';
7
+ function normalizeSourcePlatform(platform) {
8
+ if (platform === 'nextjs') {
9
+ return 'react';
10
+ }
11
+ if (platform === 'nuxtjs') {
12
+ return 'vue';
13
+ }
14
+ return platform;
15
+ }
16
+ export async function copyComponentFilesToDirectory(options) {
14
17
  const result = {
15
- componentName,
16
18
  success: false,
17
19
  filesCopied: [],
18
20
  errors: [],
19
21
  skipped: []
20
22
  };
21
- // Get component metadata
22
- const component = getComponent(componentName, options.platform, options.registryDir);
23
- if (!component) {
24
- result.errors.push(`Component "${componentName}" not found in registry`);
25
- return result;
26
- }
27
- // Validate dependencies
28
- const validation = validateComponentDependencies(componentName, options.platform, options.registryDir);
29
- if (!validation.valid) {
30
- result.errors.push(`Missing dependencies: ${validation.missing.join(', ')}. Please add these components first.`);
31
- return result;
32
- }
33
- // Determine target directory based on platform
34
- const componentsTargetDir = getComponentsTargetDir(options.platform, options.targetDir);
35
- // Determine source mode: GitHub or local
36
23
  const useGitHub = !options.packagesDir;
37
- // Copy each file
38
- for (const file of component.files){
39
- const targetFile = join(componentsTargetDir, file);
40
- // Check if target already exists
24
+ const writtenFiles = [];
25
+ const sourcePlatform = normalizeSourcePlatform(options.sourcePlatform);
26
+ const sourceType = options.componentType === 'block' ? 'blocks' : 'components';
27
+ for (const file of options.componentFiles){
28
+ const targetFile = join(options.targetDirectory, file);
41
29
  if (existsSync(targetFile) && !options.overwrite) {
42
- result.skipped.push(relative(options.targetDir, targetFile));
30
+ const relativeTarget = relative(options.relativeTo, targetFile);
31
+ result.skipped.push(relativeTarget);
32
+ options.onSkippedFile == null ? void 0 : options.onSkippedFile.call(options, file, targetFile);
43
33
  continue;
44
34
  }
45
- // Dry run - don't actually copy
46
35
  if (options.dryRun) {
47
- result.filesCopied.push(relative(options.targetDir, targetFile));
36
+ result.filesCopied.push(relative(options.relativeTo, targetFile));
48
37
  continue;
49
38
  }
50
- // Create target directory if needed
51
39
  const targetDir = dirname(targetFile);
52
40
  if (!existsSync(targetDir)) {
53
41
  mkdirSync(targetDir, {
54
42
  recursive: true
55
43
  });
56
44
  }
57
- // Copy file - from GitHub or local
58
45
  try {
59
46
  let fileContent;
60
47
  if (useGitHub) {
61
- // Fetch from GitHub
62
- const githubPath = getComponentGitHubPath(options.platform, componentName, file);
63
- const success = await fetchAndSaveFile(githubPath, targetFile);
64
- if (!success) {
65
- result.errors.push(`Failed to fetch ${file} from GitHub`);
66
- continue;
67
- }
68
- // Read the fetched content for transformation
69
- fileContent = readFileSync(targetFile, 'utf-8');
48
+ const githubPath = getComponentGitHubPath(sourcePlatform, options.componentName, file, sourceType);
49
+ fileContent = await fetchFileFromGitHub(githubPath);
70
50
  } else {
71
- // Copy from local packages directory (for development)
72
- const packagesDir = options.packagesDir;
73
- const componentSourceDir = getComponentSourceDir(options.platform);
74
- const sourceDir = join(packagesDir, componentSourceDir);
75
- const sourceFile = join(sourceDir, file);
51
+ const componentSourceDir = getComponentSourceDir(sourcePlatform);
52
+ const sourceFile = join(options.packagesDir, componentSourceDir, options.componentName, file);
76
53
  if (!existsSync(sourceFile)) {
77
- result.errors.push(`Source file not found: ${sourceFile}`);
54
+ result.errors.push(`${file}: Source file not found: ${sourceFile}`);
78
55
  continue;
79
56
  }
80
57
  fileContent = readFileSync(sourceFile, 'utf-8');
81
58
  }
82
- // Transform component if needed (Next.js, Nuxt.js)
83
59
  const transformResult = transformComponent(fileContent, {
84
- platform: options.platform,
85
- componentName,
60
+ platform: options.targetPlatform,
61
+ componentName: options.componentName,
86
62
  filePath: targetFile
87
63
  });
88
- // Write the transformed content
89
64
  writeFileSync(targetFile, transformResult.content, 'utf-8');
90
- // Log transformation notes if modified
91
65
  if (transformResult.modified && transformResult.notes.length > 0) {
92
- // Store notes for later display (optional)
93
- console.log(` 📝 ${file}: ${transformResult.notes.join(', ')}`);
66
+ options.onTransformedFile == null ? void 0 : options.onTransformedFile.call(options, file, transformResult.notes);
94
67
  }
95
- result.filesCopied.push(relative(options.targetDir, targetFile));
68
+ result.filesCopied.push(relative(options.relativeTo, targetFile));
69
+ writtenFiles.push(targetFile);
96
70
  } catch (error) {
97
- result.errors.push(`Failed to copy ${file}: ${error instanceof Error ? error.message : 'Unknown error'}`);
71
+ result.errors.push(`${file}: ${error instanceof Error ? error.message : 'Unknown error'}`);
98
72
  }
99
73
  }
74
+ if (result.errors.length > 0) {
75
+ for (const writtenFile of writtenFiles){
76
+ try {
77
+ unlinkSync(writtenFile);
78
+ } catch (e) {
79
+ // Ignore cleanup failures and preserve the original copy errors.
80
+ }
81
+ }
82
+ result.filesCopied = [];
83
+ }
100
84
  result.success = result.errors.length === 0;
101
85
  return result;
102
86
  }
87
+ /**
88
+ * Copy a component to target project
89
+ *
90
+ * @param componentName - Name of component to copy
91
+ * @param options - Copy options
92
+ * @returns Copy result
93
+ */ export async function copyComponent(componentName, options) {
94
+ const result = {
95
+ componentName,
96
+ success: false,
97
+ filesCopied: [],
98
+ errors: [],
99
+ skipped: []
100
+ };
101
+ // Get component metadata
102
+ const component = getFrameworkComponent(options.platform, componentName, {
103
+ registryDir: options.registryDir
104
+ });
105
+ if (!component) {
106
+ result.errors.push(`Component "${componentName}" not found in registry`);
107
+ return result;
108
+ }
109
+ // Validate dependencies
110
+ const validation = validateFrameworkComponentDependencies(options.platform, componentName, {
111
+ registryDir: options.registryDir
112
+ });
113
+ if (!validation.valid) {
114
+ result.errors.push(`Missing dependencies: ${validation.missing.join(', ')}. Please add these components first.`);
115
+ return result;
116
+ }
117
+ // Determine target directory based on platform
118
+ const componentsTargetDir = getComponentsTargetDir(options.platform, options.targetDir);
119
+ const componentTargetDir = join(componentsTargetDir, componentName);
120
+ const copyResult = await copyComponentFilesToDirectory({
121
+ componentName,
122
+ componentFiles: component.files,
123
+ componentType: component.type,
124
+ sourcePlatform: options.platform,
125
+ targetPlatform: options.platform,
126
+ targetDirectory: componentTargetDir,
127
+ relativeTo: options.targetDir,
128
+ overwrite: options.overwrite,
129
+ dryRun: options.dryRun,
130
+ packagesDir: options.packagesDir,
131
+ onTransformedFile: (file, notes)=>{
132
+ console.log(` 📝 ${file}: ${notes.join(', ')}`);
133
+ }
134
+ });
135
+ result.filesCopied = copyResult.filesCopied;
136
+ result.errors = copyResult.errors;
137
+ result.skipped = copyResult.skipped;
138
+ result.success = copyResult.success;
139
+ return result;
140
+ }
103
141
  /**
104
142
  * Copy multiple components
105
143
  *
@@ -168,7 +206,9 @@ import { transformComponent } from './component-transformer';
168
206
  * @param options - Options
169
207
  * @returns Import statement
170
208
  */ export function generateImportStatement(componentName, platform, options) {
171
- const component = getComponent(componentName, platform, options == null ? void 0 : options.registryDir);
209
+ const component = getFrameworkComponent(platform, componentName, {
210
+ registryDir: options == null ? void 0 : options.registryDir
211
+ });
172
212
  if (!component) {
173
213
  return `// Component "${componentName}" not found`;
174
214
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/component-copier.ts"],"sourcesContent":["import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';\nimport { dirname, join, relative } from 'path';\nimport type { Platform } from './platform-detector';\nimport { getComponentSourceDir, isMobilePlatform } from './platform-detector';\nimport { getComponent, validateComponentDependencies } from './registry-loader';\nimport {\n\tfetchAndSaveFile,\n\tgetComponentGitHubPath,\n\tcheckGitHubConnection,\n} from './github-fetcher';\nimport { transformComponent } from './component-transformer';\n\n/**\n * Component copy options\n */\nexport interface ComponentCopyOptions {\n\t/** Target directory to copy components to */\n\ttargetDir: string;\n\t/** Platform to copy for */\n\tplatform: Platform;\n\t/** Overwrite existing files */\n\toverwrite?: boolean;\n\t/** Dry run (don't actually copy) */\n\tdryRun?: boolean;\n\t/** Registry directory (for testing) */\n\tregistryDir?: string;\n\t/** Source packages directory (for testing) */\n\tpackagesDir?: string;\n}\n\n/**\n * Copy result for a single component\n */\nexport interface ComponentCopyResult {\n\tcomponentName: string;\n\tsuccess: boolean;\n\tfilesCopied: string[];\n\terrors: string[];\n\tskipped: string[];\n}\n\n/**\n * Copy a component to target project\n *\n * @param componentName - Name of component to copy\n * @param options - Copy options\n * @returns Copy result\n */\nexport async function copyComponent(\n\tcomponentName: string,\n\toptions: ComponentCopyOptions,\n): Promise<ComponentCopyResult> {\n\tconst result: ComponentCopyResult = {\n\t\tcomponentName,\n\t\tsuccess: false,\n\t\tfilesCopied: [],\n\t\terrors: [],\n\t\tskipped: [],\n\t};\n\n\t// Get component metadata\n\tconst component = getComponent(componentName, options.platform, options.registryDir);\n\n\tif (!component) {\n\t\tresult.errors.push(`Component \"${componentName}\" not found in registry`);\n\t\treturn result;\n\t}\n\n\t// Validate dependencies\n\tconst validation = validateComponentDependencies(\n\t\tcomponentName,\n\t\toptions.platform,\n\t\toptions.registryDir,\n\t);\n\n\tif (!validation.valid) {\n\t\tresult.errors.push(\n\t\t\t`Missing dependencies: ${validation.missing.join(', ')}. Please add these components first.`,\n\t\t);\n\t\treturn result;\n\t}\n\n\t// Determine target directory based on platform\n\tconst componentsTargetDir = getComponentsTargetDir(options.platform, options.targetDir);\n\n\t// Determine source mode: GitHub or local\n\tconst useGitHub = !options.packagesDir;\n\n\t// Copy each file\n\tfor (const file of component.files) {\n\t\tconst targetFile = join(componentsTargetDir, file);\n\n\t\t// Check if target already exists\n\t\tif (existsSync(targetFile) && !options.overwrite) {\n\t\t\tresult.skipped.push(relative(options.targetDir, targetFile));\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Dry run - don't actually copy\n\t\tif (options.dryRun) {\n\t\t\tresult.filesCopied.push(relative(options.targetDir, targetFile));\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Create target directory if needed\n\t\tconst targetDir = dirname(targetFile);\n\t\tif (!existsSync(targetDir)) {\n\t\t\tmkdirSync(targetDir, { recursive: true });\n\t\t}\n\n\t\t// Copy file - from GitHub or local\n\t\ttry {\n\t\t\tlet fileContent: string;\n\n\t\t\tif (useGitHub) {\n\t\t\t\t// Fetch from GitHub\n\t\t\t\tconst githubPath = getComponentGitHubPath(options.platform, componentName, file);\n\t\t\t\tconst success = await fetchAndSaveFile(githubPath, targetFile);\n\n\t\t\t\tif (!success) {\n\t\t\t\t\tresult.errors.push(`Failed to fetch ${file} from GitHub`);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Read the fetched content for transformation\n\t\t\t\tfileContent = readFileSync(targetFile, 'utf-8');\n\t\t\t} else {\n\t\t\t\t// Copy from local packages directory (for development)\n\t\t\t\tconst packagesDir = options.packagesDir!;\n\t\t\t\tconst componentSourceDir = getComponentSourceDir(options.platform);\n\t\t\t\tconst sourceDir = join(packagesDir, componentSourceDir);\n\t\t\t\tconst sourceFile = join(sourceDir, file);\n\n\t\t\t\tif (!existsSync(sourceFile)) {\n\t\t\t\t\tresult.errors.push(`Source file not found: ${sourceFile}`);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tfileContent = readFileSync(sourceFile, 'utf-8');\n\t\t\t}\n\n\t\t\t// Transform component if needed (Next.js, Nuxt.js)\n\t\t\tconst transformResult = transformComponent(fileContent, {\n\t\t\t\tplatform: options.platform,\n\t\t\t\tcomponentName,\n\t\t\t\tfilePath: targetFile,\n\t\t\t});\n\n\t\t\t// Write the transformed content\n\t\t\twriteFileSync(targetFile, transformResult.content, 'utf-8');\n\n\t\t\t// Log transformation notes if modified\n\t\t\tif (transformResult.modified && transformResult.notes.length > 0) {\n\t\t\t\t// Store notes for later display (optional)\n\t\t\t\tconsole.log(` 📝 ${file}: ${transformResult.notes.join(', ')}`);\n\t\t\t}\n\n\t\t\tresult.filesCopied.push(relative(options.targetDir, targetFile));\n\t\t} catch (error) {\n\t\t\tresult.errors.push(\n\t\t\t\t`Failed to copy ${file}: ${error instanceof Error ? error.message : 'Unknown error'}`,\n\t\t\t);\n\t\t}\n\t}\n\n\tresult.success = result.errors.length === 0;\n\treturn result;\n}\n\n/**\n * Copy multiple components\n *\n * @param componentNames - Array of component names\n * @param options - Copy options\n * @returns Array of copy results\n */\nexport async function copyComponents(\n\tcomponentNames: string[],\n\toptions: ComponentCopyOptions,\n): Promise<ComponentCopyResult[]> {\n\tconst results: ComponentCopyResult[] = [];\n\n\tfor (const name of componentNames) {\n\t\tconst result = await copyComponent(name, options);\n\t\tresults.push(result);\n\n\t\t// If this component failed, log warning but continue\n\t\tif (!result.success) {\n\t\t\tconsole.warn(`⚠️ Failed to copy component \"${name}\"`);\n\t\t}\n\t}\n\n\treturn results;\n}\n\n/**\n * Get components target directory based on platform\n *\n * @param platform - Target platform\n * @param projectRoot - Project root directory\n * @returns Target directory for components\n */\nfunction getComponentsTargetDir(platform: Platform, projectRoot: string): string {\n\tswitch (platform) {\n\t\tcase 'react-native':\n\t\t\t// React Native: src/components or components\n\t\t\tif (existsSync(join(projectRoot, 'src'))) {\n\t\t\t\treturn join(projectRoot, 'src', 'components');\n\t\t\t}\n\t\t\treturn join(projectRoot, 'components');\n\n\t\tcase 'flutter':\n\t\t\t// Flutter: lib/components\n\t\t\treturn join(projectRoot, 'lib', 'components');\n\n\t\tcase 'vue':\n\t\tcase 'nuxtjs':\n\t\t\t// Vue/Nuxt: src/components or components\n\t\t\tif (existsSync(join(projectRoot, 'src'))) {\n\t\t\t\treturn join(projectRoot, 'src', 'components');\n\t\t\t}\n\t\t\treturn join(projectRoot, 'components');\n\n\t\tcase 'react':\n\t\tcase 'nextjs':\n\t\t\t// React/Next.js: src/components or components\n\t\t\tif (existsSync(join(projectRoot, 'src'))) {\n\t\t\t\treturn join(projectRoot, 'src', 'components');\n\t\t\t}\n\t\t\treturn join(projectRoot, 'components');\n\n\t\tcase 'angular':\n\t\t\t// Angular: src/components or components\n\t\t\tif (existsSync(join(projectRoot, 'src', 'app'))) {\n\t\t\t\treturn join(projectRoot, 'src', 'app', 'components');\n\t\t\t}\n\t\t\treturn join(projectRoot, 'components');\n\n\t\tdefault:\n\t\t\t// Default: components at root\n\t\t\treturn join(projectRoot, 'components');\n\t}\n}\n\n/**\n * Generate import statement for component\n *\n * @param componentName - Component name\n * @param platform - Target platform\n * @param options - Options\n * @returns Import statement\n */\nexport function generateImportStatement(\n\tcomponentName: string,\n\tplatform: Platform,\n\toptions?: { registryDir?: string },\n): string {\n\tconst component = getComponent(componentName, platform, options?.registryDir);\n\n\tif (!component) {\n\t\treturn `// Component \"${componentName}\" not found`;\n\t}\n\n\tconst exports = component.exports;\n\n\tswitch (platform) {\n\t\tcase 'react-native':\n\t\tcase 'react':\n\t\tcase 'nextjs':\n\t\t\t// TypeScript/JSX import\n\t\t\treturn `import { ${exports.join(', ')} } from '@/components/${componentName}';`;\n\n\t\tcase 'flutter':\n\t\t\t// Dart import\n\t\t\treturn `import 'package:your_app/components/${componentName}/${componentName.replace(/-/g, '_')}.dart';`;\n\n\t\tcase 'vue':\n\t\tcase 'nuxtjs':\n\t\t\t// Vue import\n\t\t\treturn `import { ${exports.join(', ')} } from '@/components/${componentName}';`;\n\n\t\tcase 'angular':\n\t\t\t// Angular import\n\t\t\treturn `import { ${exports.join(', ')} } from './components/${componentName}';`;\n\n\t\tdefault:\n\t\t\treturn `// Import for platform \"${platform}\" not supported`;\n\t}\n}\n\n/**\n * Create components.json config file for project\n *\n * @param platform - Target platform\n * @param projectRoot - Project root directory\n * @param options - Additional config options\n */\nexport function createComponentsConfig(\n\tplatform: Platform,\n\tprojectRoot: string,\n\toptions?: {\n\t\tframework?: string;\n\t\ttypescript?: boolean;\n\t\tstyling?: 'tailwind' | 'css' | 'styled-components';\n\t},\n): void {\n\tconst config = {\n\t\t$schema: 'https://galaxy-design.vercel.app/schema.json',\n\t\tplatform: platform,\n\t\tframework: options?.framework || platform,\n\t\ttypescript: options?.typescript !== false,\n\t\tstyling: options?.styling || (isMobilePlatform(platform) ? 'styled-components' : 'tailwind'),\n\t\tcomponents: getComponentsTargetDir(platform, projectRoot),\n\t\tutils: join(projectRoot, isMobilePlatform(platform) ? 'lib' : 'src', 'lib'),\n\t};\n\n\tconst configPath = join(projectRoot, 'components.json');\n\twriteFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');\n}\n\n/**\n * Read components.json config\n *\n * @param projectRoot - Project root directory\n * @returns Config object or null if not found\n */\nexport function readComponentsConfig(projectRoot: string): any | null {\n\tconst configPath = join(projectRoot, 'components.json');\n\n\tif (!existsSync(configPath)) {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\tconst content = readFileSync(configPath, 'utf-8');\n\t\treturn JSON.parse(content);\n\t} catch (error) {\n\t\tconsole.error('Failed to read components.json:', error);\n\t\treturn null;\n\t}\n}\n"],"names":["existsSync","mkdirSync","readFileSync","writeFileSync","dirname","join","relative","getComponentSourceDir","isMobilePlatform","getComponent","validateComponentDependencies","fetchAndSaveFile","getComponentGitHubPath","transformComponent","copyComponent","componentName","options","result","success","filesCopied","errors","skipped","component","platform","registryDir","push","validation","valid","missing","componentsTargetDir","getComponentsTargetDir","targetDir","useGitHub","packagesDir","file","files","targetFile","overwrite","dryRun","recursive","fileContent","githubPath","componentSourceDir","sourceDir","sourceFile","transformResult","filePath","content","modified","notes","length","console","log","error","Error","message","copyComponents","componentNames","results","name","warn","projectRoot","generateImportStatement","exports","replace","createComponentsConfig","config","$schema","framework","typescript","styling","components","utils","configPath","JSON","stringify","readComponentsConfig","parse"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/utils/component-copier.ts"],"sourcesContent":["import {\n existsSync,\n mkdirSync,\n readFileSync,\n unlinkSync,\n writeFileSync,\n} from 'fs';\nimport { dirname, join, relative } from 'path';\nimport type { Platform } from './platform-detector.js';\nimport { getComponentSourceDir } from './platform-detector.js';\nimport {\n getFrameworkComponent,\n validateFrameworkComponentDependencies,\n} from './framework-registry-service.js';\nimport {\n fetchFileFromGitHub,\n getComponentGitHubPath,\n} from './github-fetcher.js';\nimport { transformComponent } from './component-transformer.js';\n\n/**\n * Component copy options\n */\nexport interface ComponentCopyOptions {\n /** Target directory to copy components to */\n targetDir: string;\n /** Platform to copy for */\n platform: Platform;\n /** Overwrite existing files */\n overwrite?: boolean;\n /** Dry run (don't actually copy) */\n dryRun?: boolean;\n /** Registry directory (for testing) */\n registryDir?: string;\n /** Source packages directory (for testing) */\n packagesDir?: string;\n}\n\n/**\n * Copy result for a single component\n */\nexport interface ComponentCopyResult {\n componentName: string;\n success: boolean;\n filesCopied: string[];\n errors: string[];\n skipped: string[];\n}\n\nexport interface CopyComponentFilesOptions {\n componentName: string;\n componentFiles: string[];\n componentType?: string;\n sourcePlatform: Platform;\n targetPlatform: Platform;\n targetDirectory: string;\n relativeTo: string;\n overwrite?: boolean;\n dryRun?: boolean;\n packagesDir?: string;\n onSkippedFile?: (fileName: string, targetFile: string) => void;\n onTransformedFile?: (fileName: string, notes: string[]) => void;\n}\n\nexport interface CopyComponentFilesResult {\n success: boolean;\n filesCopied: string[];\n errors: string[];\n skipped: string[];\n}\n\nfunction normalizeSourcePlatform(platform: Platform): Platform {\n if (platform === 'nextjs') {\n return 'react';\n }\n\n if (platform === 'nuxtjs') {\n return 'vue';\n }\n\n return platform;\n}\n\nexport async function copyComponentFilesToDirectory(\n options: CopyComponentFilesOptions,\n): Promise<CopyComponentFilesResult> {\n const result: CopyComponentFilesResult = {\n success: false,\n filesCopied: [],\n errors: [],\n skipped: [],\n };\n\n const useGitHub = !options.packagesDir;\n const writtenFiles: string[] = [];\n const sourcePlatform = normalizeSourcePlatform(options.sourcePlatform);\n const sourceType =\n options.componentType === 'block' ? 'blocks' : 'components';\n\n for (const file of options.componentFiles) {\n const targetFile = join(options.targetDirectory, file);\n\n if (existsSync(targetFile) && !options.overwrite) {\n const relativeTarget = relative(options.relativeTo, targetFile);\n result.skipped.push(relativeTarget);\n options.onSkippedFile?.(file, targetFile);\n continue;\n }\n\n if (options.dryRun) {\n result.filesCopied.push(relative(options.relativeTo, targetFile));\n continue;\n }\n\n const targetDir = dirname(targetFile);\n if (!existsSync(targetDir)) {\n mkdirSync(targetDir, { recursive: true });\n }\n\n try {\n let fileContent: string;\n\n if (useGitHub) {\n const githubPath = getComponentGitHubPath(\n sourcePlatform,\n options.componentName,\n file,\n sourceType,\n );\n fileContent = await fetchFileFromGitHub(githubPath);\n } else {\n const componentSourceDir = getComponentSourceDir(sourcePlatform);\n const sourceFile = join(\n options.packagesDir!,\n componentSourceDir,\n options.componentName,\n file,\n );\n\n if (!existsSync(sourceFile)) {\n result.errors.push(`${file}: Source file not found: ${sourceFile}`);\n continue;\n }\n\n fileContent = readFileSync(sourceFile, 'utf-8');\n }\n\n const transformResult = transformComponent(fileContent, {\n platform: options.targetPlatform,\n componentName: options.componentName,\n filePath: targetFile,\n });\n\n writeFileSync(targetFile, transformResult.content, 'utf-8');\n\n if (transformResult.modified && transformResult.notes.length > 0) {\n options.onTransformedFile?.(file, transformResult.notes);\n }\n\n result.filesCopied.push(relative(options.relativeTo, targetFile));\n writtenFiles.push(targetFile);\n } catch (error) {\n result.errors.push(\n `${file}: ${error instanceof Error ? error.message : 'Unknown error'}`,\n );\n }\n }\n\n if (result.errors.length > 0) {\n for (const writtenFile of writtenFiles) {\n try {\n unlinkSync(writtenFile);\n } catch {\n // Ignore cleanup failures and preserve the original copy errors.\n }\n }\n\n result.filesCopied = [];\n }\n\n result.success = result.errors.length === 0;\n return result;\n}\n\n/**\n * Copy a component to target project\n *\n * @param componentName - Name of component to copy\n * @param options - Copy options\n * @returns Copy result\n */\nexport async function copyComponent(\n componentName: string,\n options: ComponentCopyOptions,\n): Promise<ComponentCopyResult> {\n const result: ComponentCopyResult = {\n componentName,\n success: false,\n filesCopied: [],\n errors: [],\n skipped: [],\n };\n\n // Get component metadata\n const component = getFrameworkComponent(options.platform, componentName, {\n registryDir: options.registryDir,\n });\n\n if (!component) {\n result.errors.push(`Component \"${componentName}\" not found in registry`);\n return result;\n }\n\n // Validate dependencies\n const validation = validateFrameworkComponentDependencies(\n options.platform,\n componentName,\n { registryDir: options.registryDir },\n );\n\n if (!validation.valid) {\n result.errors.push(\n `Missing dependencies: ${validation.missing.join(', ')}. Please add these components first.`,\n );\n return result;\n }\n\n // Determine target directory based on platform\n const componentsTargetDir = getComponentsTargetDir(\n options.platform,\n options.targetDir,\n );\n\n const componentTargetDir = join(componentsTargetDir, componentName);\n const copyResult = await copyComponentFilesToDirectory({\n componentName,\n componentFiles: component.files,\n componentType: component.type,\n sourcePlatform: options.platform,\n targetPlatform: options.platform,\n targetDirectory: componentTargetDir,\n relativeTo: options.targetDir,\n overwrite: options.overwrite,\n dryRun: options.dryRun,\n packagesDir: options.packagesDir,\n onTransformedFile: (file, notes) => {\n console.log(` 📝 ${file}: ${notes.join(', ')}`);\n },\n });\n\n result.filesCopied = copyResult.filesCopied;\n result.errors = copyResult.errors;\n result.skipped = copyResult.skipped;\n result.success = copyResult.success;\n return result;\n}\n\n/**\n * Copy multiple components\n *\n * @param componentNames - Array of component names\n * @param options - Copy options\n * @returns Array of copy results\n */\nexport async function copyComponents(\n componentNames: string[],\n options: ComponentCopyOptions,\n): Promise<ComponentCopyResult[]> {\n const results: ComponentCopyResult[] = [];\n\n for (const name of componentNames) {\n const result = await copyComponent(name, options);\n results.push(result);\n\n // If this component failed, log warning but continue\n if (!result.success) {\n console.warn(`⚠️ Failed to copy component \"${name}\"`);\n }\n }\n\n return results;\n}\n\n/**\n * Get components target directory based on platform\n *\n * @param platform - Target platform\n * @param projectRoot - Project root directory\n * @returns Target directory for components\n */\nfunction getComponentsTargetDir(\n platform: Platform,\n projectRoot: string,\n): string {\n switch (platform) {\n case 'react-native':\n // React Native: src/components or components\n if (existsSync(join(projectRoot, 'src'))) {\n return join(projectRoot, 'src', 'components');\n }\n return join(projectRoot, 'components');\n\n case 'flutter':\n // Flutter: lib/components\n return join(projectRoot, 'lib', 'components');\n\n case 'vue':\n case 'nuxtjs':\n // Vue/Nuxt: src/components or components\n if (existsSync(join(projectRoot, 'src'))) {\n return join(projectRoot, 'src', 'components');\n }\n return join(projectRoot, 'components');\n\n case 'react':\n case 'nextjs':\n // React/Next.js: src/components or components\n if (existsSync(join(projectRoot, 'src'))) {\n return join(projectRoot, 'src', 'components');\n }\n return join(projectRoot, 'components');\n\n case 'angular':\n // Angular: src/components or components\n if (existsSync(join(projectRoot, 'src', 'app'))) {\n return join(projectRoot, 'src', 'app', 'components');\n }\n return join(projectRoot, 'components');\n\n default:\n // Default: components at root\n return join(projectRoot, 'components');\n }\n}\n\n/**\n * Generate import statement for component\n *\n * @param componentName - Component name\n * @param platform - Target platform\n * @param options - Options\n * @returns Import statement\n */\nexport function generateImportStatement(\n componentName: string,\n platform: Platform,\n options?: { registryDir?: string },\n): string {\n const component = getFrameworkComponent(platform, componentName, {\n registryDir: options?.registryDir,\n });\n\n if (!component) {\n return `// Component \"${componentName}\" not found`;\n }\n\n const exports = component.exports;\n\n switch (platform) {\n case 'react-native':\n case 'react':\n case 'nextjs':\n // TypeScript/JSX import\n return `import { ${exports.join(', ')} } from '@/components/${componentName}';`;\n\n case 'flutter':\n // Dart import\n return `import 'package:your_app/components/${componentName}/${componentName.replace(/-/g, '_')}.dart';`;\n\n case 'vue':\n case 'nuxtjs':\n // Vue import\n return `import { ${exports.join(', ')} } from '@/components/${componentName}';`;\n\n case 'angular':\n // Angular import\n return `import { ${exports.join(', ')} } from './components/${componentName}';`;\n\n default:\n return `// Import for platform \"${platform}\" not supported`;\n }\n}\n\n/**\n * Create components.json config file for project\n *\n * @param platform - Target platform\n * @param projectRoot - Project root directory\n * @param options - Additional config options\n */\nexport function createComponentsConfig(\n platform: Platform,\n projectRoot: string,\n options?: {\n framework?: string;\n typescript?: boolean;\n styling?: 'tailwind' | 'css' | 'styled-components';\n },\n): void {\n const config = {\n $schema: 'https://galaxy-design.vercel.app/schema.json',\n platform: platform,\n framework: options?.framework || platform,\n typescript: options?.typescript !== false,\n styling:\n options?.styling ||\n (isMobilePlatform(platform) ? 'styled-components' : 'tailwind'),\n components: getComponentsTargetDir(platform, projectRoot),\n utils: join(projectRoot, isMobilePlatform(platform) ? 'lib' : 'src', 'lib'),\n };\n\n const configPath = join(projectRoot, 'components.json');\n writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');\n}\n\n/**\n * Read components.json config\n *\n * @param projectRoot - Project root directory\n * @returns Config object or null if not found\n */\nexport function readComponentsConfig(projectRoot: string): any | null {\n const configPath = join(projectRoot, 'components.json');\n\n if (!existsSync(configPath)) {\n return null;\n }\n\n try {\n const content = readFileSync(configPath, 'utf-8');\n return JSON.parse(content);\n } catch (error) {\n console.error('Failed to read components.json:', error);\n return null;\n }\n}\n"],"names":["existsSync","mkdirSync","readFileSync","unlinkSync","writeFileSync","dirname","join","relative","getComponentSourceDir","getFrameworkComponent","validateFrameworkComponentDependencies","fetchFileFromGitHub","getComponentGitHubPath","transformComponent","normalizeSourcePlatform","platform","copyComponentFilesToDirectory","options","result","success","filesCopied","errors","skipped","useGitHub","packagesDir","writtenFiles","sourcePlatform","sourceType","componentType","file","componentFiles","targetFile","targetDirectory","overwrite","relativeTarget","relativeTo","push","onSkippedFile","dryRun","targetDir","recursive","fileContent","githubPath","componentName","componentSourceDir","sourceFile","transformResult","targetPlatform","filePath","content","modified","notes","length","onTransformedFile","error","Error","message","writtenFile","copyComponent","component","registryDir","validation","valid","missing","componentsTargetDir","getComponentsTargetDir","componentTargetDir","copyResult","files","type","console","log","copyComponents","componentNames","results","name","warn","projectRoot","generateImportStatement","exports","replace","createComponentsConfig","config","$schema","framework","typescript","styling","isMobilePlatform","components","utils","configPath","JSON","stringify","readComponentsConfig","parse"],"mappings":"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"}