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
@@ -1,5 +1,6 @@
1
1
  import { _ as _extends } from "@swc/helpers/_/_extends";
2
2
  import { readFileSync } from 'fs';
3
+ import { dirname, join, relative, sep } from 'path';
3
4
  /**
4
5
  * Check if a React/Next.js component needs 'use client' directive
5
6
  *
@@ -36,6 +37,36 @@ import { readFileSync } from 'fs';
36
37
  const firstNonEmptyLine = lines.find((line)=>line.trim() !== '');
37
38
  return (firstNonEmptyLine == null ? void 0 : firstNonEmptyLine.trim().startsWith("'use client'")) || (firstNonEmptyLine == null ? void 0 : firstNonEmptyLine.trim().startsWith('"use client"')) || false;
38
39
  }
40
+ function getDirectiveInsertionIndex(content) {
41
+ let index = 0;
42
+ if (content.startsWith('#!')) {
43
+ const shebangEnd = content.indexOf('\n');
44
+ index = shebangEnd === -1 ? content.length : shebangEnd + 1;
45
+ }
46
+ while(index < content.length){
47
+ const remaining = content.slice(index);
48
+ const whitespaceMatch = remaining.match(/^[\t\r\n ]+/);
49
+ if (whitespaceMatch) {
50
+ index += whitespaceMatch[0].length;
51
+ continue;
52
+ }
53
+ if (remaining.startsWith('//')) {
54
+ const lineEnd = remaining.indexOf('\n');
55
+ index += lineEnd === -1 ? remaining.length : lineEnd + 1;
56
+ continue;
57
+ }
58
+ if (remaining.startsWith('/*')) {
59
+ const commentEnd = remaining.indexOf('*/');
60
+ if (commentEnd === -1) {
61
+ return index;
62
+ }
63
+ index += commentEnd + 2;
64
+ continue;
65
+ }
66
+ break;
67
+ }
68
+ return index;
69
+ }
39
70
  /**
40
71
  * Add 'use client' directive to Next.js component
41
72
  */ function addUseClientDirective(content) {
@@ -43,21 +74,13 @@ import { readFileSync } from 'fs';
43
74
  if (hasUseClientDirective(content)) {
44
75
  return content;
45
76
  }
46
- // Find the first import or code line
47
- const lines = content.split('\n');
48
- let insertIndex = 0;
49
- // Skip shebang and comments at the top
50
- for(let i = 0; i < lines.length; i++){
51
- const line = lines[i].trim();
52
- if (line === '' || line.startsWith('//') || line.startsWith('/*')) {
53
- insertIndex = i + 1;
54
- } else {
55
- break;
56
- }
77
+ const insertIndex = getDirectiveInsertionIndex(content);
78
+ const prefix = content.slice(0, insertIndex).trimEnd();
79
+ const suffix = content.slice(insertIndex).trimStart();
80
+ if (!prefix) {
81
+ return `'use client'\n\n${suffix}`;
57
82
  }
58
- // Insert 'use client' directive
59
- lines.splice(insertIndex, 0, "'use client'", '');
60
- return lines.join('\n');
83
+ return `${prefix}\n\n'use client'\n\n${suffix}`;
61
84
  }
62
85
  /**
63
86
  * Transform component for Next.js
@@ -107,6 +130,51 @@ import { readFileSync } from 'fs';
107
130
  notes
108
131
  };
109
132
  }
133
+ function getSrcRoot(filePath) {
134
+ const srcSegment = `${sep}src${sep}`;
135
+ const srcIndex = filePath.lastIndexOf(srcSegment);
136
+ if (srcIndex === -1) {
137
+ return null;
138
+ }
139
+ return filePath.slice(0, srcIndex + srcSegment.length - 1);
140
+ }
141
+ /**
142
+ * Transform Angular relative imports to match the copied component layout.
143
+ *
144
+ * Angular source files live under packages/angular/src/components/* and often
145
+ * import ../../lib/utils. When copied into src/components/ui/*, that same
146
+ * relative path needs to point one directory higher.
147
+ */ function transformAngularComponent(content, filePath) {
148
+ const notes = [];
149
+ let modified = false;
150
+ const srcRoot = getSrcRoot(filePath);
151
+ if (!srcRoot) {
152
+ return {
153
+ content,
154
+ modified: false,
155
+ notes: [
156
+ 'Angular file path does not include src/, skipping relative import rewrite'
157
+ ]
158
+ };
159
+ }
160
+ const currentDir = dirname(filePath);
161
+ const utilsDir = join(srcRoot, 'lib');
162
+ const utilsImportPrefix = relative(currentDir, utilsDir).split(sep).join('/');
163
+ const transformedContent = content.replace(/from\s+['"]\.\.\/\.\.\/lib\/([^'"]+)['"]/g, (_match, importPath)=>{
164
+ modified = true;
165
+ return `from '${utilsImportPrefix}/${importPath}'`;
166
+ });
167
+ if (modified) {
168
+ notes.push(`Rewrote Angular relative lib imports to ${utilsImportPrefix}/... for copied component layout`);
169
+ } else {
170
+ notes.push('No Angular relative lib imports needed rewriting');
171
+ }
172
+ return {
173
+ content: transformedContent,
174
+ modified,
175
+ notes
176
+ };
177
+ }
110
178
  /**
111
179
  * Transform import paths to match user's project structure
112
180
  *
@@ -140,7 +208,7 @@ import { readFileSync } from 'fs';
140
208
  * @param options - Transform options
141
209
  * @returns Transform result
142
210
  */ export function transformComponent(content, options) {
143
- const { platform, componentName } = options;
211
+ const { platform, componentName, filePath } = options;
144
212
  // First, apply import path transformations for all platforms
145
213
  const importTransform = transformImportPaths(content);
146
214
  let transformedContent = importTransform.content;
@@ -157,10 +225,12 @@ import { readFileSync } from 'fs';
157
225
  case 'nuxtjs':
158
226
  platformResult = transformNuxtjsComponent(transformedContent, componentName);
159
227
  break;
228
+ case 'angular':
229
+ platformResult = transformAngularComponent(transformedContent, filePath);
230
+ break;
160
231
  // Other platforms don't need additional transformation
161
232
  case 'react':
162
233
  case 'vue':
163
- case 'angular':
164
234
  case 'react-native':
165
235
  case 'flutter':
166
236
  default:
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/component-transformer.ts"],"sourcesContent":["import { readFileSync } from 'fs';\nimport type { Platform } from './platform-detector';\n\n/**\n * Transform options for component files\n */\nexport interface TransformOptions {\n\t/** Target platform */\n\tplatform: Platform;\n\t/** Component name */\n\tcomponentName: string;\n\t/** File path */\n\tfilePath: string;\n}\n\n/**\n * Transform result\n */\nexport interface TransformResult {\n\t/** Transformed content */\n\tcontent: string;\n\t/** Whether content was modified */\n\tmodified: boolean;\n\t/** Transformation notes */\n\tnotes: string[];\n}\n\n/**\n * Check if a React/Next.js component needs 'use client' directive\n *\n * Components need 'use client' if they use:\n * - React hooks (useState, useEffect, etc.)\n * - Event handlers (onClick, onChange, etc.)\n * - Browser APIs (window, document, etc.)\n * - Client-side libraries\n */\nfunction needsUseClient(content: string): boolean {\n\tconst clientIndicators = [\n\t\t// React hooks\n\t\t/\\buse[A-Z]\\w+\\s*\\(/,\n\t\t/useState|useEffect|useContext|useReducer|useCallback|useMemo|useRef/,\n\n\t\t// Event handlers\n\t\t/\\bon[A-Z]\\w+\\s*=/,\n\t\t/onClick|onChange|onSubmit|onFocus|onBlur|onKeyDown|onKeyUp|onMouseEnter|onMouseLeave/,\n\n\t\t// Browser APIs\n\t\t/\\bwindow\\./,\n\t\t/\\bdocument\\./,\n\t\t/\\bnavigator\\./,\n\t\t/\\blocalStorage\\./,\n\t\t/\\bsessionStorage\\./,\n\n\t\t// Client-side only features\n\t\t/addEventListener/,\n\t\t/removeEventListener/,\n\t\t/createPortal/,\n\t];\n\n\treturn clientIndicators.some(indicator => indicator.test(content));\n}\n\n/**\n * Check if file already has 'use client' directive\n */\nfunction hasUseClientDirective(content: string): boolean {\n\tconst lines = content.split('\\n');\n\tconst firstNonEmptyLine = lines.find(line => line.trim() !== '');\n\treturn firstNonEmptyLine?.trim().startsWith(\"'use client'\") ||\n\t firstNonEmptyLine?.trim().startsWith('\"use client\"') || false;\n}\n\n/**\n * Add 'use client' directive to Next.js component\n */\nfunction addUseClientDirective(content: string): string {\n\t// Skip if already has the directive\n\tif (hasUseClientDirective(content)) {\n\t\treturn content;\n\t}\n\n\t// Find the first import or code line\n\tconst lines = content.split('\\n');\n\tlet insertIndex = 0;\n\n\t// Skip shebang and comments at the top\n\tfor (let i = 0; i < lines.length; i++) {\n\t\tconst line = lines[i].trim();\n\t\tif (line === '' || line.startsWith('//') || line.startsWith('/*')) {\n\t\t\tinsertIndex = i + 1;\n\t\t} else {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Insert 'use client' directive\n\tlines.splice(insertIndex, 0, \"'use client'\", '');\n\treturn lines.join('\\n');\n}\n\n/**\n * Transform component for Next.js\n *\n * Adds 'use client' directive if component uses client-side features\n */\nfunction transformNextjsComponent(content: string, componentName: string): TransformResult {\n\tconst notes: string[] = [];\n\tlet modified = false;\n\tlet transformedContent = content;\n\n\t// Check if component needs 'use client'\n\tif (needsUseClient(content) && !hasUseClientDirective(content)) {\n\t\ttransformedContent = addUseClientDirective(content);\n\t\tmodified = true;\n\t\tnotes.push(`Added 'use client' directive (component uses client-side features)`);\n\t} else if (hasUseClientDirective(content)) {\n\t\tnotes.push(`Component already has 'use client' directive`);\n\t} else {\n\t\tnotes.push(`Component appears to be server-safe (no 'use client' needed)`);\n\t}\n\n\treturn {\n\t\tcontent: transformedContent,\n\t\tmodified,\n\t\tnotes,\n\t};\n}\n\n/**\n * Transform component for Nuxt.js\n *\n * Currently no transformations needed, but placeholder for future enhancements\n */\nfunction transformNuxtjsComponent(content: string, componentName: string): TransformResult {\n\tconst notes: string[] = [];\n\n\t// Check for Nuxt-specific patterns\n\tconst hasNuxtImports = /from ['\"]#app['\"]/.test(content);\n\tconst hasAutoImports = /\\b(navigateTo|useFetch|useAsyncData|useState)\\b/.test(content);\n\n\tif (hasNuxtImports) {\n\t\tnotes.push('Component uses Nuxt 3 auto-imports (#app)');\n\t}\n\tif (hasAutoImports) {\n\t\tnotes.push('Component uses Nuxt 3 composables (auto-imported)');\n\t}\n\tif (!hasNuxtImports && !hasAutoImports) {\n\t\tnotes.push('Component appears to be standard Vue 3 (works in Nuxt)');\n\t}\n\n\treturn {\n\t\tcontent,\n\t\tmodified: false,\n\t\tnotes,\n\t};\n}\n\n/**\n * Transform import paths to match user's project structure\n *\n * Transforms @/components/xxx to @/components/ui/xxx\n */\nfunction transformImportPaths(content: string): TransformResult {\n\tconst notes: string[] = [];\n\tlet modified = false;\n\tlet transformedContent = content;\n\n\t// Transform @/components/ imports to @/components/ui/\n\t// Match patterns like: from '@/components/calendar'\n\tconst importPattern = /from\\s+['\"]@\\/components\\/([^'\"]+)['\"]/g;\n\n\ttransformedContent = content.replace(importPattern, (match, componentPath) => {\n\t\t// Skip if already has /ui/ in path\n\t\tif (componentPath.includes('ui/')) {\n\t\t\treturn match;\n\t\t}\n\t\tmodified = true;\n\t\tnotes.push(`Transformed import path: @/components/${componentPath} -> @/components/ui/${componentPath}`);\n\t\treturn `from '@/components/ui/${componentPath}'`;\n\t});\n\n\treturn {\n\t\tcontent: transformedContent,\n\t\tmodified,\n\t\tnotes,\n\t};\n}\n\n/**\n * Transform component file based on platform\n *\n * @param content - File content\n * @param options - Transform options\n * @returns Transform result\n */\nexport function transformComponent(content: string, options: TransformOptions): TransformResult {\n\tconst { platform, componentName } = options;\n\n\t// First, apply import path transformations for all platforms\n\tconst importTransform = transformImportPaths(content);\n\tlet transformedContent = importTransform.content;\n\tlet notes = [...importTransform.notes];\n\tlet modified = importTransform.modified;\n\n\t// Then apply platform-specific transformations\n\tlet platformResult: TransformResult;\n\tswitch (platform) {\n\t\tcase 'nextjs':\n\t\t\tplatformResult = transformNextjsComponent(transformedContent, componentName);\n\t\t\tbreak;\n\n\t\tcase 'nuxtjs':\n\t\t\tplatformResult = transformNuxtjsComponent(transformedContent, componentName);\n\t\t\tbreak;\n\n\t\t// Other platforms don't need additional transformation\n\t\tcase 'react':\n\t\tcase 'vue':\n\t\tcase 'angular':\n\t\tcase 'react-native':\n\t\tcase 'flutter':\n\t\tdefault:\n\t\t\tplatformResult = {\n\t\t\t\tcontent: transformedContent,\n\t\t\t\tmodified: false,\n\t\t\t\tnotes: modified ? [] : ['No transformation needed for this platform'],\n\t\t\t};\n\t}\n\n\treturn {\n\t\tcontent: platformResult.content,\n\t\tmodified: modified || platformResult.modified,\n\t\tnotes: [...notes, ...platformResult.notes],\n\t};\n}\n\n/**\n * Transform component file from file path\n *\n * @param filePath - Path to component file\n * @param options - Transform options\n * @returns Transform result\n */\nexport function transformComponentFile(filePath: string, options: Omit<TransformOptions, 'filePath'>): TransformResult {\n\tconst content = readFileSync(filePath, 'utf-8');\n\treturn transformComponent(content, { ...options, filePath });\n}\n\n/**\n * Batch transform multiple files\n *\n * @param files - Array of file paths\n * @param options - Transform options (without filePath)\n * @returns Array of transform results\n */\nexport function transformComponentFiles(\n\tfiles: string[],\n\toptions: Omit<TransformOptions, 'filePath' | 'componentName'>\n): Map<string, TransformResult> {\n\tconst results = new Map<string, TransformResult>();\n\n\tfor (const filePath of files) {\n\t\tconst componentName = options.componentName || extractComponentName(filePath);\n\t\tconst result = transformComponentFile(filePath, { ...options, componentName });\n\t\tresults.set(filePath, result);\n\t}\n\n\treturn results;\n}\n\n/**\n * Extract component name from file path\n */\nfunction extractComponentName(filePath: string): string {\n\tconst fileName = filePath.split('/').pop() || '';\n\treturn fileName.replace(/\\.(tsx?|vue|js|jsx)$/, '');\n}\n"],"names":["readFileSync","needsUseClient","content","clientIndicators","some","indicator","test","hasUseClientDirective","lines","split","firstNonEmptyLine","find","line","trim","startsWith","addUseClientDirective","insertIndex","i","length","splice","join","transformNextjsComponent","componentName","notes","modified","transformedContent","push","transformNuxtjsComponent","hasNuxtImports","hasAutoImports","transformImportPaths","importPattern","replace","match","componentPath","includes","transformComponent","options","platform","importTransform","platformResult","transformComponentFile","filePath","transformComponentFiles","files","results","Map","extractComponentName","result","set","fileName","pop"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/utils/component-transformer.ts"],"sourcesContent":["import { readFileSync } from 'fs';\nimport { dirname, join, relative, sep } from 'path';\nimport type { Platform } from './platform-detector.js';\n\n/**\n * Transform options for component files\n */\nexport interface TransformOptions {\n /** Target platform */\n platform: Platform;\n /** Component name */\n componentName: string;\n /** File path */\n filePath: string;\n}\n\n/**\n * Transform result\n */\nexport interface TransformResult {\n /** Transformed content */\n content: string;\n /** Whether content was modified */\n modified: boolean;\n /** Transformation notes */\n notes: string[];\n}\n\n/**\n * Check if a React/Next.js component needs 'use client' directive\n *\n * Components need 'use client' if they use:\n * - React hooks (useState, useEffect, etc.)\n * - Event handlers (onClick, onChange, etc.)\n * - Browser APIs (window, document, etc.)\n * - Client-side libraries\n */\nfunction needsUseClient(content: string): boolean {\n const clientIndicators = [\n // React hooks\n /\\buse[A-Z]\\w+\\s*\\(/,\n /useState|useEffect|useContext|useReducer|useCallback|useMemo|useRef/,\n\n // Event handlers\n /\\bon[A-Z]\\w+\\s*=/,\n /onClick|onChange|onSubmit|onFocus|onBlur|onKeyDown|onKeyUp|onMouseEnter|onMouseLeave/,\n\n // Browser APIs\n /\\bwindow\\./,\n /\\bdocument\\./,\n /\\bnavigator\\./,\n /\\blocalStorage\\./,\n /\\bsessionStorage\\./,\n\n // Client-side only features\n /addEventListener/,\n /removeEventListener/,\n /createPortal/,\n ];\n\n return clientIndicators.some((indicator) => indicator.test(content));\n}\n\n/**\n * Check if file already has 'use client' directive\n */\nfunction hasUseClientDirective(content: string): boolean {\n const lines = content.split('\\n');\n const firstNonEmptyLine = lines.find((line) => line.trim() !== '');\n return (\n firstNonEmptyLine?.trim().startsWith(\"'use client'\") ||\n firstNonEmptyLine?.trim().startsWith('\"use client\"') ||\n false\n );\n}\n\nfunction getDirectiveInsertionIndex(content: string): number {\n let index = 0;\n\n if (content.startsWith('#!')) {\n const shebangEnd = content.indexOf('\\n');\n index = shebangEnd === -1 ? content.length : shebangEnd + 1;\n }\n\n while (index < content.length) {\n const remaining = content.slice(index);\n\n const whitespaceMatch = remaining.match(/^[\\t\\r\\n ]+/);\n if (whitespaceMatch) {\n index += whitespaceMatch[0].length;\n continue;\n }\n\n if (remaining.startsWith('//')) {\n const lineEnd = remaining.indexOf('\\n');\n index += lineEnd === -1 ? remaining.length : lineEnd + 1;\n continue;\n }\n\n if (remaining.startsWith('/*')) {\n const commentEnd = remaining.indexOf('*/');\n if (commentEnd === -1) {\n return index;\n }\n\n index += commentEnd + 2;\n continue;\n }\n\n break;\n }\n\n return index;\n}\n\n/**\n * Add 'use client' directive to Next.js component\n */\nfunction addUseClientDirective(content: string): string {\n // Skip if already has the directive\n if (hasUseClientDirective(content)) {\n return content;\n }\n\n const insertIndex = getDirectiveInsertionIndex(content);\n const prefix = content.slice(0, insertIndex).trimEnd();\n const suffix = content.slice(insertIndex).trimStart();\n\n if (!prefix) {\n return `'use client'\\n\\n${suffix}`;\n }\n\n return `${prefix}\\n\\n'use client'\\n\\n${suffix}`;\n}\n\n/**\n * Transform component for Next.js\n *\n * Adds 'use client' directive if component uses client-side features\n */\nfunction transformNextjsComponent(\n content: string,\n componentName: string,\n): TransformResult {\n const notes: string[] = [];\n let modified = false;\n let transformedContent = content;\n\n // Check if component needs 'use client'\n if (needsUseClient(content) && !hasUseClientDirective(content)) {\n transformedContent = addUseClientDirective(content);\n modified = true;\n notes.push(\n `Added 'use client' directive (component uses client-side features)`,\n );\n } else if (hasUseClientDirective(content)) {\n notes.push(`Component already has 'use client' directive`);\n } else {\n notes.push(`Component appears to be server-safe (no 'use client' needed)`);\n }\n\n return {\n content: transformedContent,\n modified,\n notes,\n };\n}\n\n/**\n * Transform component for Nuxt.js\n *\n * Currently no transformations needed, but placeholder for future enhancements\n */\nfunction transformNuxtjsComponent(\n content: string,\n componentName: string,\n): TransformResult {\n const notes: string[] = [];\n\n // Check for Nuxt-specific patterns\n const hasNuxtImports = /from ['\"]#app['\"]/.test(content);\n const hasAutoImports = /\\b(navigateTo|useFetch|useAsyncData|useState)\\b/.test(\n content,\n );\n\n if (hasNuxtImports) {\n notes.push('Component uses Nuxt 3 auto-imports (#app)');\n }\n if (hasAutoImports) {\n notes.push('Component uses Nuxt 3 composables (auto-imported)');\n }\n if (!hasNuxtImports && !hasAutoImports) {\n notes.push('Component appears to be standard Vue 3 (works in Nuxt)');\n }\n\n return {\n content,\n modified: false,\n notes,\n };\n}\n\nfunction getSrcRoot(filePath: string): string | null {\n const srcSegment = `${sep}src${sep}`;\n const srcIndex = filePath.lastIndexOf(srcSegment);\n\n if (srcIndex === -1) {\n return null;\n }\n\n return filePath.slice(0, srcIndex + srcSegment.length - 1);\n}\n\n/**\n * Transform Angular relative imports to match the copied component layout.\n *\n * Angular source files live under packages/angular/src/components/* and often\n * import ../../lib/utils. When copied into src/components/ui/*, that same\n * relative path needs to point one directory higher.\n */\nfunction transformAngularComponent(\n content: string,\n filePath: string,\n): TransformResult {\n const notes: string[] = [];\n let modified = false;\n\n const srcRoot = getSrcRoot(filePath);\n if (!srcRoot) {\n return {\n content,\n modified: false,\n notes: [\n 'Angular file path does not include src/, skipping relative import rewrite',\n ],\n };\n }\n\n const currentDir = dirname(filePath);\n const utilsDir = join(srcRoot, 'lib');\n const utilsImportPrefix = relative(currentDir, utilsDir).split(sep).join('/');\n\n const transformedContent = content.replace(\n /from\\s+['\"]\\.\\.\\/\\.\\.\\/lib\\/([^'\"]+)['\"]/g,\n (_match, importPath) => {\n modified = true;\n return `from '${utilsImportPrefix}/${importPath}'`;\n },\n );\n\n if (modified) {\n notes.push(\n `Rewrote Angular relative lib imports to ${utilsImportPrefix}/... for copied component layout`,\n );\n } else {\n notes.push('No Angular relative lib imports needed rewriting');\n }\n\n return {\n content: transformedContent,\n modified,\n notes,\n };\n}\n\n/**\n * Transform import paths to match user's project structure\n *\n * Transforms @/components/xxx to @/components/ui/xxx\n */\nfunction transformImportPaths(content: string): TransformResult {\n const notes: string[] = [];\n let modified = false;\n let transformedContent = content;\n\n // Transform @/components/ imports to @/components/ui/\n // Match patterns like: from '@/components/calendar'\n const importPattern = /from\\s+['\"]@\\/components\\/([^'\"]+)['\"]/g;\n\n transformedContent = content.replace(\n importPattern,\n (match, componentPath) => {\n // Skip if already has /ui/ in path\n if (componentPath.includes('ui/')) {\n return match;\n }\n modified = true;\n notes.push(\n `Transformed import path: @/components/${componentPath} -> @/components/ui/${componentPath}`,\n );\n return `from '@/components/ui/${componentPath}'`;\n },\n );\n\n return {\n content: transformedContent,\n modified,\n notes,\n };\n}\n\n/**\n * Transform component file based on platform\n *\n * @param content - File content\n * @param options - Transform options\n * @returns Transform result\n */\nexport function transformComponent(\n content: string,\n options: TransformOptions,\n): TransformResult {\n const { platform, componentName, filePath } = options;\n\n // First, apply import path transformations for all platforms\n const importTransform = transformImportPaths(content);\n let transformedContent = importTransform.content;\n let notes = [...importTransform.notes];\n let modified = importTransform.modified;\n\n // Then apply platform-specific transformations\n let platformResult: TransformResult;\n switch (platform) {\n case 'nextjs':\n platformResult = transformNextjsComponent(\n transformedContent,\n componentName,\n );\n break;\n\n case 'nuxtjs':\n platformResult = transformNuxtjsComponent(\n transformedContent,\n componentName,\n );\n break;\n\n case 'angular':\n platformResult = transformAngularComponent(transformedContent, filePath);\n break;\n\n // Other platforms don't need additional transformation\n case 'react':\n case 'vue':\n case 'react-native':\n case 'flutter':\n default:\n platformResult = {\n content: transformedContent,\n modified: false,\n notes: modified ? [] : ['No transformation needed for this platform'],\n };\n }\n\n return {\n content: platformResult.content,\n modified: modified || platformResult.modified,\n notes: [...notes, ...platformResult.notes],\n };\n}\n\n/**\n * Transform component file from file path\n *\n * @param filePath - Path to component file\n * @param options - Transform options\n * @returns Transform result\n */\nexport function transformComponentFile(\n filePath: string,\n options: Omit<TransformOptions, 'filePath'>,\n): TransformResult {\n const content = readFileSync(filePath, 'utf-8');\n return transformComponent(content, { ...options, filePath });\n}\n\n/**\n * Batch transform multiple files\n *\n * @param files - Array of file paths\n * @param options - Transform options (without filePath)\n * @returns Array of transform results\n */\nexport function transformComponentFiles(\n files: string[],\n options: Omit<TransformOptions, 'filePath' | 'componentName'>,\n): Map<string, TransformResult> {\n const results = new Map<string, TransformResult>();\n\n for (const filePath of files) {\n const componentName =\n options.componentName || extractComponentName(filePath);\n const result = transformComponentFile(filePath, {\n ...options,\n componentName,\n });\n results.set(filePath, result);\n }\n\n return results;\n}\n\n/**\n * Extract component name from file path\n */\nfunction extractComponentName(filePath: string): string {\n const fileName = filePath.split('/').pop() || '';\n return fileName.replace(/\\.(tsx?|vue|js|jsx)$/, '');\n}\n"],"names":["readFileSync","dirname","join","relative","sep","needsUseClient","content","clientIndicators","some","indicator","test","hasUseClientDirective","lines","split","firstNonEmptyLine","find","line","trim","startsWith","getDirectiveInsertionIndex","index","shebangEnd","indexOf","length","remaining","slice","whitespaceMatch","match","lineEnd","commentEnd","addUseClientDirective","insertIndex","prefix","trimEnd","suffix","trimStart","transformNextjsComponent","componentName","notes","modified","transformedContent","push","transformNuxtjsComponent","hasNuxtImports","hasAutoImports","getSrcRoot","filePath","srcSegment","srcIndex","lastIndexOf","transformAngularComponent","srcRoot","currentDir","utilsDir","utilsImportPrefix","replace","_match","importPath","transformImportPaths","importPattern","componentPath","includes","transformComponent","options","platform","importTransform","platformResult","transformComponentFile","transformComponentFiles","files","results","Map","extractComponentName","result","set","fileName","pop"],"mappings":"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"}
@@ -1,7 +1,6 @@
1
1
  import { _ as _extends } from "@swc/helpers/_/_extends";
2
2
  import { z } from 'zod';
3
- // Framework types
4
- export const frameworkSchema = z.enum([
3
+ export const frameworkValues = [
5
4
  'vue',
6
5
  'react',
7
6
  'angular',
@@ -9,23 +8,32 @@ export const frameworkSchema = z.enum([
9
8
  'flutter',
10
9
  'nextjs',
11
10
  'nuxtjs'
12
- ]);
13
- // Base color types
14
- export const baseColorSchema = z.enum([
11
+ ];
12
+ // Framework types
13
+ export const frameworkSchema = z.enum(frameworkValues);
14
+ export const baseColorValues = [
15
15
  'slate',
16
16
  'gray',
17
17
  'zinc',
18
18
  'neutral',
19
19
  'stone'
20
- ]);
21
- // Icon library types
22
- export const iconLibrarySchema = z.enum([
20
+ ];
21
+ // Base color types
22
+ export const baseColorSchema = z.enum(baseColorValues);
23
+ export const iconLibraryValues = [
23
24
  'lucide',
24
25
  'heroicons',
25
26
  'radix-icons'
26
- ]);
27
+ ];
28
+ // Icon library types
29
+ export const iconLibrarySchema = z.enum(iconLibraryValues);
30
+ export const tailwindVersionSchema = z.union([
31
+ z.literal(3),
32
+ z.literal(4)
33
+ ]).nullable();
27
34
  // Tailwind configuration
28
35
  export const tailwindConfigSchema = z.object({
36
+ version: tailwindVersionSchema.optional(),
29
37
  config: z.string().default('tailwind.config.js'),
30
38
  css: z.string(),
31
39
  baseColor: baseColorSchema.default('slate'),
@@ -48,12 +56,149 @@ export const componentsConfigSchema = z.object({
48
56
  aliases: aliasesSchema,
49
57
  iconLibrary: iconLibrarySchema.default('lucide')
50
58
  });
59
+ export function createComponentsJsonSchema() {
60
+ return {
61
+ $schema: 'http://json-schema.org/draft-07/schema#',
62
+ title: 'Galaxy UI Configuration',
63
+ description: 'Configuration file for Galaxy UI components',
64
+ type: 'object',
65
+ required: [
66
+ 'framework',
67
+ 'typescript',
68
+ 'tailwind',
69
+ 'aliases'
70
+ ],
71
+ properties: {
72
+ $schema: {
73
+ type: 'string',
74
+ description: 'Path to the schema file'
75
+ },
76
+ framework: {
77
+ type: 'string',
78
+ enum: [
79
+ ...frameworkValues
80
+ ],
81
+ description: 'The framework used in the project'
82
+ },
83
+ typescript: {
84
+ type: 'boolean',
85
+ description: 'Whether TypeScript is used',
86
+ default: true
87
+ },
88
+ tailwind: {
89
+ type: 'object',
90
+ required: [
91
+ 'config',
92
+ 'css'
93
+ ],
94
+ properties: {
95
+ version: {
96
+ type: [
97
+ 'integer',
98
+ 'null'
99
+ ],
100
+ enum: [
101
+ 3,
102
+ 4,
103
+ null
104
+ ],
105
+ description: 'Detected or selected Tailwind major version'
106
+ },
107
+ config: {
108
+ type: 'string',
109
+ description: 'Path to the Tailwind configuration file. May be empty when using Tailwind v4 CSS-first setup.',
110
+ default: 'tailwind.config.js'
111
+ },
112
+ css: {
113
+ type: 'string',
114
+ description: 'Path to the global CSS file',
115
+ examples: [
116
+ 'src/styles/globals.css',
117
+ 'src/assets/styles/global.css',
118
+ 'src/app/globals.css'
119
+ ]
120
+ },
121
+ baseColor: {
122
+ type: 'string',
123
+ description: 'Base color for components',
124
+ enum: [
125
+ ...baseColorValues
126
+ ],
127
+ default: 'slate'
128
+ },
129
+ cssVariables: {
130
+ type: 'boolean',
131
+ description: 'Use CSS variables for theming',
132
+ default: true
133
+ },
134
+ prefix: {
135
+ type: 'string',
136
+ description: 'Prefix for Tailwind utility classes',
137
+ default: ''
138
+ }
139
+ }
140
+ },
141
+ aliases: {
142
+ type: 'object',
143
+ required: [
144
+ 'components',
145
+ 'utils'
146
+ ],
147
+ properties: {
148
+ components: {
149
+ type: 'string',
150
+ description: 'Import alias for components directory',
151
+ examples: [
152
+ '@/components',
153
+ '~/components',
154
+ 'src/components'
155
+ ]
156
+ },
157
+ utils: {
158
+ type: 'string',
159
+ description: 'Import alias for utils directory',
160
+ examples: [
161
+ '@/lib/utils',
162
+ '@/utils',
163
+ '~/lib/utils'
164
+ ]
165
+ },
166
+ ui: {
167
+ type: 'string',
168
+ description: 'Import alias for UI components directory',
169
+ examples: [
170
+ '@/components/ui',
171
+ '~/components/ui'
172
+ ]
173
+ },
174
+ lib: {
175
+ type: 'string',
176
+ description: 'Import alias for lib directory',
177
+ examples: [
178
+ '@/lib',
179
+ '~/lib'
180
+ ]
181
+ }
182
+ }
183
+ },
184
+ iconLibrary: {
185
+ type: 'string',
186
+ enum: [
187
+ ...iconLibraryValues
188
+ ],
189
+ description: 'Icon library to use',
190
+ default: 'lucide'
191
+ }
192
+ }
193
+ };
194
+ }
51
195
  // Default configurations per framework
52
196
  export const defaultConfigs = {
53
197
  vue: {
54
198
  framework: 'vue',
55
199
  typescript: true,
56
200
  tailwind: {
201
+ version: 4,
57
202
  config: 'tailwind.config.js',
58
203
  css: 'src/style.css',
59
204
  baseColor: 'slate',
@@ -72,6 +217,7 @@ export const defaultConfigs = {
72
217
  framework: 'react',
73
218
  typescript: true,
74
219
  tailwind: {
220
+ version: 4,
75
221
  config: 'tailwind.config.js',
76
222
  css: 'src/index.css',
77
223
  baseColor: 'slate',
@@ -90,6 +236,7 @@ export const defaultConfigs = {
90
236
  framework: 'angular',
91
237
  typescript: true,
92
238
  tailwind: {
239
+ version: 4,
93
240
  config: 'tailwind.config.js',
94
241
  css: 'src/styles.css',
95
242
  baseColor: 'slate',
@@ -108,6 +255,7 @@ export const defaultConfigs = {
108
255
  framework: 'react-native',
109
256
  typescript: true,
110
257
  tailwind: {
258
+ version: 4,
111
259
  config: 'tailwind.config.js',
112
260
  css: 'global.css',
113
261
  baseColor: 'slate',
@@ -126,6 +274,7 @@ export const defaultConfigs = {
126
274
  framework: 'flutter',
127
275
  typescript: false,
128
276
  tailwind: {
277
+ version: null,
129
278
  config: '',
130
279
  css: '',
131
280
  baseColor: 'slate',
@@ -144,6 +293,7 @@ export const defaultConfigs = {
144
293
  framework: 'nextjs',
145
294
  typescript: true,
146
295
  tailwind: {
296
+ version: 4,
147
297
  config: 'tailwind.config.ts',
148
298
  css: 'app/globals.css',
149
299
  baseColor: 'slate',
@@ -162,6 +312,7 @@ export const defaultConfigs = {
162
312
  framework: 'nuxtjs',
163
313
  typescript: true,
164
314
  tailwind: {
315
+ version: 4,
165
316
  config: 'tailwind.config.js',
166
317
  css: 'assets/css/main.css',
167
318
  baseColor: 'slate',
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/config-schema.ts"],"sourcesContent":["import { z } from 'zod';\n\n// Framework types\nexport const frameworkSchema = z.enum(['vue', 'react', 'angular', 'react-native', 'flutter', 'nextjs', 'nuxtjs']);\nexport type Framework = z.infer<typeof frameworkSchema>;\n\n// Base color types\nexport const baseColorSchema = z.enum(['slate', 'gray', 'zinc', 'neutral', 'stone']);\nexport type BaseColor = z.infer<typeof baseColorSchema>;\n\n// Icon library types\nexport const iconLibrarySchema = z.enum(['lucide', 'heroicons', 'radix-icons']);\nexport type IconLibrary = z.infer<typeof iconLibrarySchema>;\n\n// Tailwind configuration\nexport const tailwindConfigSchema = z.object({\n config: z.string().default('tailwind.config.js'),\n css: z.string(),\n baseColor: baseColorSchema.default('slate'),\n cssVariables: z.boolean().default(true),\n prefix: z.string().optional().default(''),\n});\nexport type TailwindConfig = z.infer<typeof tailwindConfigSchema>;\n\n// Aliases configuration\nexport const aliasesSchema = z.object({\n components: z.string(),\n utils: z.string(),\n ui: z.string().optional(),\n lib: z.string().optional(),\n});\nexport type Aliases = z.infer<typeof aliasesSchema>;\n\n// Main components.json schema\nexport const componentsConfigSchema = z.object({\n $schema: z.string().optional(),\n framework: frameworkSchema,\n typescript: z.boolean().default(true),\n tailwind: tailwindConfigSchema,\n aliases: aliasesSchema,\n iconLibrary: iconLibrarySchema.default('lucide'),\n});\nexport type ComponentsConfig = z.infer<typeof componentsConfigSchema>;\n\n// Default configurations per framework\nexport const defaultConfigs: Record<Framework, Partial<ComponentsConfig>> = {\n vue: {\n framework: 'vue',\n typescript: true,\n tailwind: {\n config: 'tailwind.config.js',\n css: 'src/style.css',\n baseColor: 'slate',\n cssVariables: true,\n prefix: '',\n },\n aliases: {\n components: '@/components',\n utils: '@/lib/utils',\n ui: '@/components/ui',\n lib: '@/lib',\n },\n iconLibrary: 'lucide',\n },\n react: {\n framework: 'react',\n typescript: true,\n tailwind: {\n config: 'tailwind.config.js',\n css: 'src/index.css',\n baseColor: 'slate',\n cssVariables: true,\n prefix: '',\n },\n aliases: {\n components: '@/components',\n utils: '@/lib/utils',\n ui: '@/components/ui',\n lib: '@/lib',\n },\n iconLibrary: 'lucide',\n },\n angular: {\n framework: 'angular',\n typescript: true,\n tailwind: {\n config: 'tailwind.config.js',\n css: 'src/styles.css',\n baseColor: 'slate',\n cssVariables: true,\n prefix: '',\n },\n aliases: {\n components: '@/components',\n utils: '@/lib/utils',\n ui: '@/components/ui',\n lib: '@/lib',\n },\n iconLibrary: 'lucide',\n },\n 'react-native': {\n framework: 'react-native',\n typescript: true,\n tailwind: {\n config: 'tailwind.config.js',\n css: 'global.css',\n baseColor: 'slate',\n cssVariables: true,\n prefix: '',\n },\n aliases: {\n components: '@/components',\n utils: '@/lib/utils',\n ui: '@/components/ui',\n lib: '@/lib',\n },\n iconLibrary: 'lucide',\n },\n flutter: {\n framework: 'flutter',\n typescript: false, // Flutter uses Dart\n tailwind: {\n config: '', // Flutter doesn't use Tailwind\n css: '',\n baseColor: 'slate',\n cssVariables: false,\n prefix: '',\n },\n aliases: {\n components: 'lib/components',\n utils: 'lib/utils',\n ui: 'lib/components/ui',\n lib: 'lib',\n },\n iconLibrary: 'lucide',\n },\n nextjs: {\n framework: 'nextjs',\n typescript: true,\n tailwind: {\n config: 'tailwind.config.ts',\n css: 'app/globals.css', // Next.js App Router\n baseColor: 'slate',\n cssVariables: true,\n prefix: '',\n },\n aliases: {\n components: '@/components',\n utils: '@/lib/utils',\n ui: '@/components/ui',\n lib: '@/lib',\n },\n iconLibrary: 'lucide',\n },\n nuxtjs: {\n framework: 'nuxtjs',\n typescript: true,\n tailwind: {\n config: 'tailwind.config.js',\n css: 'assets/css/main.css', // Nuxt 3 default\n baseColor: 'slate',\n cssVariables: true,\n prefix: '',\n },\n aliases: {\n components: '@/components',\n utils: '@/lib/utils',\n ui: '@/components/ui',\n lib: '@/lib',\n },\n iconLibrary: 'lucide',\n },\n};\n\n/**\n * Get default config for a framework\n */\nexport function getDefaultConfig(framework: Framework): ComponentsConfig {\n const defaults = defaultConfigs[framework];\n return {\n $schema: 'https://galaxy-design.vercel.app/schema.json',\n ...defaults,\n } as ComponentsConfig;\n}\n\n/**\n * Validate components.json config\n */\nexport function validateConfig(config: unknown): ComponentsConfig {\n try {\n return componentsConfigSchema.parse(config);\n } catch (error) {\n if (error instanceof z.ZodError) {\n throw new Error(\n `Invalid components.json configuration:\\n${error.issues\n .map((e: z.ZodIssue) => ` - ${e.path.join('.')}: ${e.message}`)\n .join('\\n')}`\n );\n }\n throw error;\n }\n}\n\n/**\n * Get framework-specific file extensions\n */\nexport function getFileExtensions(framework: Framework, typescript: boolean): string[] {\n const ext = typescript ? 'ts' : 'js';\n\n switch (framework) {\n case 'vue':\n case 'nuxtjs':\n return ['.vue', `.${ext}`];\n case 'react':\n case 'nextjs':\n return [`.tsx`, `.jsx`, `.${ext}`];\n case 'react-native':\n return [`.tsx`, `.jsx`, `.native.${ext}`, `.${ext}`];\n case 'angular':\n return [`.component.ts`, `.service.ts`, `.directive.ts`, `.${ext}`];\n case 'flutter':\n return ['.dart'];\n default:\n return [`.${ext}`];\n }\n}\n\n/**\n * Get framework-specific component path patterns\n */\nexport function getComponentPath(framework: Framework): string {\n switch (framework) {\n case 'vue':\n case 'nuxtjs':\n return 'src/components';\n case 'react':\n case 'nextjs':\n return 'src/components';\n case 'react-native':\n return 'src/components';\n case 'angular':\n return 'src/app/components';\n case 'flutter':\n return 'lib/components';\n default:\n return 'src/components';\n }\n}\n"],"names":["z","frameworkSchema","enum","baseColorSchema","iconLibrarySchema","tailwindConfigSchema","object","config","string","default","css","baseColor","cssVariables","boolean","prefix","optional","aliasesSchema","components","utils","ui","lib","componentsConfigSchema","$schema","framework","typescript","tailwind","aliases","iconLibrary","defaultConfigs","vue","react","angular","flutter","nextjs","nuxtjs","getDefaultConfig","defaults","validateConfig","parse","error","ZodError","Error","issues","map","e","path","join","message","getFileExtensions","ext","getComponentPath"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/utils/config-schema.ts"],"sourcesContent":["import { z } from 'zod';\n\nexport const frameworkValues = [\n 'vue',\n 'react',\n 'angular',\n 'react-native',\n 'flutter',\n 'nextjs',\n 'nuxtjs',\n] as const;\n\n// Framework types\nexport const frameworkSchema = z.enum(frameworkValues);\nexport type Framework = z.infer<typeof frameworkSchema>;\n\nexport const baseColorValues = [\n 'slate',\n 'gray',\n 'zinc',\n 'neutral',\n 'stone',\n] as const;\n\n// Base color types\nexport const baseColorSchema = z.enum(baseColorValues);\nexport type BaseColor = z.infer<typeof baseColorSchema>;\n\nexport const iconLibraryValues = [\n 'lucide',\n 'heroicons',\n 'radix-icons',\n] as const;\n\n// Icon library types\nexport const iconLibrarySchema = z.enum(iconLibraryValues);\nexport type IconLibrary = z.infer<typeof iconLibrarySchema>;\n\nexport interface JsonSchemaObject {\n [key: string]: JsonSchemaValue;\n}\n\nexport type JsonSchemaValue =\n | string\n | number\n | boolean\n | null\n | JsonSchemaObject\n | JsonSchemaValue[];\n\nexport const tailwindVersionSchema = z\n .union([z.literal(3), z.literal(4)])\n .nullable();\nexport type TailwindVersion = z.infer<typeof tailwindVersionSchema>;\n\n// Tailwind configuration\nexport const tailwindConfigSchema = z.object({\n version: tailwindVersionSchema.optional(),\n config: z.string().default('tailwind.config.js'),\n css: z.string(),\n baseColor: baseColorSchema.default('slate'),\n cssVariables: z.boolean().default(true),\n prefix: z.string().optional().default(''),\n});\nexport type TailwindConfig = z.infer<typeof tailwindConfigSchema>;\n\n// Aliases configuration\nexport const aliasesSchema = z.object({\n components: z.string(),\n utils: z.string(),\n ui: z.string().optional(),\n lib: z.string().optional(),\n});\nexport type Aliases = z.infer<typeof aliasesSchema>;\n\n// Main components.json schema\nexport const componentsConfigSchema = z.object({\n $schema: z.string().optional(),\n framework: frameworkSchema,\n typescript: z.boolean().default(true),\n tailwind: tailwindConfigSchema,\n aliases: aliasesSchema,\n iconLibrary: iconLibrarySchema.default('lucide'),\n});\nexport type ComponentsConfig = z.infer<typeof componentsConfigSchema>;\n\nexport function createComponentsJsonSchema(): JsonSchemaObject {\n return {\n $schema: 'http://json-schema.org/draft-07/schema#',\n title: 'Galaxy UI Configuration',\n description: 'Configuration file for Galaxy UI components',\n type: 'object',\n required: ['framework', 'typescript', 'tailwind', 'aliases'],\n properties: {\n $schema: {\n type: 'string',\n description: 'Path to the schema file',\n },\n framework: {\n type: 'string',\n enum: [...frameworkValues],\n description: 'The framework used in the project',\n },\n typescript: {\n type: 'boolean',\n description: 'Whether TypeScript is used',\n default: true,\n },\n tailwind: {\n type: 'object',\n required: ['config', 'css'],\n properties: {\n version: {\n type: ['integer', 'null'],\n enum: [3, 4, null],\n description: 'Detected or selected Tailwind major version',\n },\n config: {\n type: 'string',\n description:\n 'Path to the Tailwind configuration file. May be empty when using Tailwind v4 CSS-first setup.',\n default: 'tailwind.config.js',\n },\n css: {\n type: 'string',\n description: 'Path to the global CSS file',\n examples: [\n 'src/styles/globals.css',\n 'src/assets/styles/global.css',\n 'src/app/globals.css',\n ],\n },\n baseColor: {\n type: 'string',\n description: 'Base color for components',\n enum: [...baseColorValues],\n default: 'slate',\n },\n cssVariables: {\n type: 'boolean',\n description: 'Use CSS variables for theming',\n default: true,\n },\n prefix: {\n type: 'string',\n description: 'Prefix for Tailwind utility classes',\n default: '',\n },\n },\n },\n aliases: {\n type: 'object',\n required: ['components', 'utils'],\n properties: {\n components: {\n type: 'string',\n description: 'Import alias for components directory',\n examples: ['@/components', '~/components', 'src/components'],\n },\n utils: {\n type: 'string',\n description: 'Import alias for utils directory',\n examples: ['@/lib/utils', '@/utils', '~/lib/utils'],\n },\n ui: {\n type: 'string',\n description: 'Import alias for UI components directory',\n examples: ['@/components/ui', '~/components/ui'],\n },\n lib: {\n type: 'string',\n description: 'Import alias for lib directory',\n examples: ['@/lib', '~/lib'],\n },\n },\n },\n iconLibrary: {\n type: 'string',\n enum: [...iconLibraryValues],\n description: 'Icon library to use',\n default: 'lucide',\n },\n },\n };\n}\n\n// Default configurations per framework\nexport const defaultConfigs: Record<Framework, Partial<ComponentsConfig>> = {\n vue: {\n framework: 'vue',\n typescript: true,\n tailwind: {\n version: 4,\n config: 'tailwind.config.js',\n css: 'src/style.css',\n baseColor: 'slate',\n cssVariables: true,\n prefix: '',\n },\n aliases: {\n components: '@/components',\n utils: '@/lib/utils',\n ui: '@/components/ui',\n lib: '@/lib',\n },\n iconLibrary: 'lucide',\n },\n react: {\n framework: 'react',\n typescript: true,\n tailwind: {\n version: 4,\n config: 'tailwind.config.js',\n css: 'src/index.css',\n baseColor: 'slate',\n cssVariables: true,\n prefix: '',\n },\n aliases: {\n components: '@/components',\n utils: '@/lib/utils',\n ui: '@/components/ui',\n lib: '@/lib',\n },\n iconLibrary: 'lucide',\n },\n angular: {\n framework: 'angular',\n typescript: true,\n tailwind: {\n version: 4,\n config: 'tailwind.config.js',\n css: 'src/styles.css',\n baseColor: 'slate',\n cssVariables: true,\n prefix: '',\n },\n aliases: {\n components: '@/components',\n utils: '@/lib/utils',\n ui: '@/components/ui',\n lib: '@/lib',\n },\n iconLibrary: 'lucide',\n },\n 'react-native': {\n framework: 'react-native',\n typescript: true,\n tailwind: {\n version: 4,\n config: 'tailwind.config.js',\n css: 'global.css',\n baseColor: 'slate',\n cssVariables: true,\n prefix: '',\n },\n aliases: {\n components: '@/components',\n utils: '@/lib/utils',\n ui: '@/components/ui',\n lib: '@/lib',\n },\n iconLibrary: 'lucide',\n },\n flutter: {\n framework: 'flutter',\n typescript: false, // Flutter uses Dart\n tailwind: {\n version: null,\n config: '', // Flutter doesn't use Tailwind\n css: '',\n baseColor: 'slate',\n cssVariables: false,\n prefix: '',\n },\n aliases: {\n components: 'lib/components',\n utils: 'lib/utils',\n ui: 'lib/components/ui',\n lib: 'lib',\n },\n iconLibrary: 'lucide',\n },\n nextjs: {\n framework: 'nextjs',\n typescript: true,\n tailwind: {\n version: 4,\n config: 'tailwind.config.ts',\n css: 'app/globals.css', // Next.js App Router\n baseColor: 'slate',\n cssVariables: true,\n prefix: '',\n },\n aliases: {\n components: '@/components',\n utils: '@/lib/utils',\n ui: '@/components/ui',\n lib: '@/lib',\n },\n iconLibrary: 'lucide',\n },\n nuxtjs: {\n framework: 'nuxtjs',\n typescript: true,\n tailwind: {\n version: 4,\n config: 'tailwind.config.js',\n css: 'assets/css/main.css', // Nuxt 3 default\n baseColor: 'slate',\n cssVariables: true,\n prefix: '',\n },\n aliases: {\n components: '@/components',\n utils: '@/lib/utils',\n ui: '@/components/ui',\n lib: '@/lib',\n },\n iconLibrary: 'lucide',\n },\n};\n\n/**\n * Get default config for a framework\n */\nexport function getDefaultConfig(framework: Framework): ComponentsConfig {\n const defaults = defaultConfigs[framework];\n return {\n $schema: 'https://galaxy-design.vercel.app/schema.json',\n ...defaults,\n } as ComponentsConfig;\n}\n\n/**\n * Validate components.json config\n */\nexport function validateConfig(config: unknown): ComponentsConfig {\n try {\n return componentsConfigSchema.parse(config);\n } catch (error) {\n if (error instanceof z.ZodError) {\n throw new Error(\n `Invalid components.json configuration:\\n${error.issues\n .map((e: z.ZodIssue) => ` - ${e.path.join('.')}: ${e.message}`)\n .join('\\n')}`,\n );\n }\n throw error;\n }\n}\n\n/**\n * Get framework-specific file extensions\n */\nexport function getFileExtensions(\n framework: Framework,\n typescript: boolean,\n): string[] {\n const ext = typescript ? 'ts' : 'js';\n\n switch (framework) {\n case 'vue':\n case 'nuxtjs':\n return ['.vue', `.${ext}`];\n case 'react':\n case 'nextjs':\n return [`.tsx`, `.jsx`, `.${ext}`];\n case 'react-native':\n return [`.tsx`, `.jsx`, `.native.${ext}`, `.${ext}`];\n case 'angular':\n return [`.component.ts`, `.service.ts`, `.directive.ts`, `.${ext}`];\n case 'flutter':\n return ['.dart'];\n default:\n return [`.${ext}`];\n }\n}\n\n/**\n * Get framework-specific component path patterns\n */\nexport function getComponentPath(framework: Framework): string {\n switch (framework) {\n case 'vue':\n case 'nuxtjs':\n return 'src/components';\n case 'react':\n case 'nextjs':\n return 'src/components';\n case 'react-native':\n return 'src/components';\n case 'angular':\n return 'src/app/components';\n case 'flutter':\n return 'lib/components';\n default:\n return 'src/components';\n }\n}\n"],"names":["z","frameworkValues","frameworkSchema","enum","baseColorValues","baseColorSchema","iconLibraryValues","iconLibrarySchema","tailwindVersionSchema","union","literal","nullable","tailwindConfigSchema","object","version","optional","config","string","default","css","baseColor","cssVariables","boolean","prefix","aliasesSchema","components","utils","ui","lib","componentsConfigSchema","$schema","framework","typescript","tailwind","aliases","iconLibrary","createComponentsJsonSchema","title","description","type","required","properties","examples","defaultConfigs","vue","react","angular","flutter","nextjs","nuxtjs","getDefaultConfig","defaults","validateConfig","parse","error","ZodError","Error","issues","map","e","path","join","message","getFileExtensions","ext","getComponentPath"],"mappings":"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"}