galaxy-design 0.2.2 β†’ 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,12 +1,12 @@
1
1
  # Galaxy UI CLI
2
2
 
3
- A modern, framework-agnostic CLI tool for adding beautiful, accessible UI components to your projects. Inspired by shadcn/ui, but supporting React, Vue, and Angular.
3
+ A modern, framework-agnostic CLI tool for adding beautiful, accessible UI components to your projects. Inspired by shadcn/ui, but supporting React, Vue, Angular, Next.js, and Nuxt.js.
4
4
 
5
5
  ## 🌟 Features
6
6
 
7
- - πŸš€ **Multi-framework support**: React, Vue, and Angular
7
+ - πŸš€ **Multi-framework support**: React, Vue, Angular, Next.js, and Nuxt.js
8
8
  - πŸ“¦ **41 production-ready components** across 8 categories
9
- - 🎨 **Built with Radix UI primitives** (radix-ui for React, radix-vue for Vue, radix-ng for Angular)
9
+ - 🎨 **Built with Radix UI primitives** (radix-ui for React/Next.js, radix-vue for Vue/Nuxt.js, radix-ng for Angular)
10
10
  - πŸŒ™ **Dark mode support** out of the box
11
11
  - πŸ“± **Responsive design** with mobile-first approach
12
12
  - β™Ώ **Accessibility-focused** (WAI-ARIA compliant)
@@ -35,7 +35,7 @@ npx galaxy-design@latest init
35
35
 
36
36
  This interactive command will:
37
37
 
38
- - βœ… Detect your framework (React, Vue, or Angular)
38
+ - βœ… Detect your framework (React, Vue, Angular, Next.js, or Nuxt.js)
39
39
  - βœ… Detect your package manager (npm, pnpm, yarn, or bun)
40
40
  - βœ… Install required dependencies (lucide icons, clsx, tailwind-merge, radix primitives)
41
41
  - βœ… Create component directory structure
@@ -183,6 +183,46 @@ import {InputComponent} from '@/components/ui/input';
183
183
  export class MyComponent {}
184
184
  ```
185
185
 
186
+ ### Next.js
187
+
188
+ ```tsx
189
+ 'use client'
190
+
191
+ import {Button} from '@/components/ui/button'
192
+ import {Input} from '@/components/ui/input'
193
+
194
+ export default function MyComponent() {
195
+ return (
196
+ <div>
197
+ <Button variant="default" size="lg">
198
+ Click me
199
+ </Button>
200
+ <Input placeholder="Enter text..." />
201
+ </div>
202
+ )
203
+ }
204
+ ```
205
+
206
+ **Note:** Galaxy UI CLI automatically adds the `'use client'` directive to components that use client-side features (hooks, event handlers, browser APIs). Server-compatible components won't have this directive added.
207
+
208
+ ### Nuxt.js
209
+
210
+ ```vue
211
+ <script setup lang="ts">
212
+ import {Button} from '@/components/ui/button'
213
+ import {Input} from '@/components/ui/input'
214
+ </script>
215
+
216
+ <template>
217
+ <div>
218
+ <Button variant="default" size="lg">Click me</Button>
219
+ <Input placeholder="Enter text..." />
220
+ </div>
221
+ </template>
222
+ ```
223
+
224
+ **Note:** Components work seamlessly with Nuxt 3's auto-import feature. Make sure to configure the `@/` alias in your `nuxt.config.ts`.
225
+
186
226
  ## βš™οΈ Configuration
187
227
 
188
228
  Galaxy UI stores configuration in `components.json` at your project root:
@@ -28,7 +28,7 @@ export async function initCommand(options) {
28
28
  // Detect framework
29
29
  const detectedFramework = detectFramework(cwd);
30
30
  if (detectedFramework === 'unknown') {
31
- console.log(chalk.red('❌ Could not detect framework. Please ensure you are in a valid Angular, React, Vue, React Native, or Flutter project.'));
31
+ console.log(chalk.red('❌ Could not detect framework. Please ensure you are in a valid Angular, React, Vue, Next.js, Nuxt.js, React Native, or Flutter project.'));
32
32
  return;
33
33
  }
34
34
  console.log(chalk.green(`βœ“ Detected ${chalk.bold(detectedFramework)} framework`));
@@ -39,6 +39,8 @@ export async function initCommand(options) {
39
39
  vue: 'vue',
40
40
  'react-native': 'react-native',
41
41
  flutter: 'flutter',
42
+ nextjs: 'nextjs',
43
+ nuxtjs: 'nuxtjs',
42
44
  unknown: null
43
45
  };
44
46
  const framework = frameworkMap[detectedFramework];
@@ -153,6 +155,7 @@ export async function initCommand(options) {
153
155
  // Framework-specific dependencies
154
156
  switch(framework){
155
157
  case 'vue':
158
+ case 'nuxtjs':
156
159
  dependencies.push('radix-vue');
157
160
  devDependencies.push('tailwindcss', 'autoprefixer', 'postcss');
158
161
  if (config.iconLibrary === 'lucide') {
@@ -160,6 +163,7 @@ export async function initCommand(options) {
160
163
  }
161
164
  break;
162
165
  case 'react':
166
+ case 'nextjs':
163
167
  dependencies.push('@radix-ui/react-slot');
164
168
  devDependencies.push('tailwindcss', 'autoprefixer', 'postcss');
165
169
  if (config.iconLibrary === 'lucide') {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/init.ts"],"sourcesContent":["import prompts from 'prompts';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport {\n detectFramework,\n detectPackageManager,\n type Framework as DetectedFramework,\n} from '../utils/detect.js';\nimport {\n createComponentsConfig,\n hasComponentsConfig,\n loadComponentsConfig,\n type Framework,\n} from '../utils/components-config.js';\nimport {\n getDefaultConfig,\n type BaseColor,\n type IconLibrary,\n} from '../utils/config-schema.js';\nimport { writeFile, ensureDir } from '../utils/files.js';\nimport { installDependencies } from '../utils/package-manager.js';\nimport { resolve } from 'path';\n\ninterface InitOptions {\n yes?: boolean;\n cwd: string;\n}\n\nexport async function initCommand(options: InitOptions) {\n console.log(chalk.bold.cyan('\\n🌌 Galaxy UI CLI - Multi-Framework Edition\\n'));\n\n const cwd = options.cwd;\n\n // Check if already initialized\n if (hasComponentsConfig(cwd)) {\n console.log(chalk.yellow('⚠ components.json already exists in this project.'));\n const { overwrite } = await prompts({\n type: 'confirm',\n name: 'overwrite',\n message: 'Do you want to overwrite the existing configuration?',\n initial: false,\n });\n\n if (!overwrite) {\n console.log(chalk.gray('Initialization cancelled.'));\n return;\n }\n }\n\n // Detect framework\n const detectedFramework = detectFramework(cwd);\n\n if (detectedFramework === 'unknown') {\n console.log(\n chalk.red(\n '❌ Could not detect framework. Please ensure you are in a valid Angular, React, Vue, React Native, or Flutter project.'\n )\n );\n return;\n }\n\n console.log(chalk.green(`βœ“ Detected ${chalk.bold(detectedFramework)} framework`));\n\n // Map detected framework to Framework type\n const frameworkMap: Record<DetectedFramework, Framework | null> = {\n angular: 'angular',\n react: 'react',\n vue: 'vue',\n 'react-native': 'react-native',\n flutter: 'flutter',\n unknown: null,\n };\n\n const framework = frameworkMap[detectedFramework];\n if (!framework) {\n console.log(chalk.red('❌ Unsupported framework detected.'));\n return;\n }\n\n // Detect package manager\n const packageManager = detectPackageManager(cwd);\n console.log(chalk.green(`βœ“ Using ${chalk.bold(packageManager)} package manager`));\n\n // Get configuration from user (or use defaults with --yes)\n let config = getDefaultConfig(framework);\n\n if (!options.yes) {\n console.log(chalk.cyan('\\nπŸ“ Configuration\\n'));\n\n // Build prompts based on framework\n const promptQuestions: any[] = [];\n\n // TypeScript prompt (not for Flutter)\n if (framework !== 'flutter') {\n promptQuestions.push({\n type: 'toggle',\n name: 'typescript',\n message: 'Would you like to use TypeScript?',\n initial: true,\n active: 'yes',\n inactive: 'no',\n });\n }\n\n // Base color prompt (for all frameworks)\n promptQuestions.push({\n type: 'select',\n name: 'baseColor',\n message: 'Which base color would you like to use?',\n choices: [\n { title: 'Slate', value: 'slate' },\n { title: 'Gray', value: 'gray' },\n { title: 'Zinc', value: 'zinc' },\n { title: 'Neutral', value: 'neutral' },\n { title: 'Stone', value: 'stone' },\n ],\n initial: 0,\n });\n\n // Icon library prompt (not for Flutter - uses built-in icons)\n if (framework !== 'flutter') {\n promptQuestions.push({\n type: 'select',\n name: 'iconLibrary',\n message: 'Which icon library would you like to use?',\n choices: [\n { title: 'Lucide (Recommended)', value: 'lucide' },\n { title: 'Heroicons', value: 'heroicons' },\n { title: 'Radix Icons', value: 'radix-icons' },\n ],\n initial: 0,\n });\n }\n\n // CSS file prompt (only for web frameworks and React Native)\n if (framework !== 'flutter' && config.tailwind.css) {\n promptQuestions.push({\n type: 'text',\n name: 'cssFile',\n message: framework === 'react-native'\n ? 'Where is your global CSS file (for NativeWind)?'\n : 'Where is your global CSS file?',\n initial: config.tailwind.css,\n });\n }\n\n const answers = await prompts(promptQuestions);\n\n if (Object.keys(answers).length === 0) {\n console.log(chalk.gray('Initialization cancelled.'));\n return;\n }\n\n // Update config with user choices\n config = {\n ...config,\n typescript: answers.typescript ?? config.typescript,\n iconLibrary: (answers.iconLibrary as IconLibrary) ?? config.iconLibrary,\n tailwind: {\n ...config.tailwind,\n baseColor: (answers.baseColor as BaseColor) ?? config.tailwind.baseColor,\n css: answers.cssFile ?? config.tailwind.css,\n },\n };\n }\n\n console.log(chalk.cyan('\\nπŸ“¦ Installing dependencies...\\n'));\n\n // Install dependencies\n const spinner = ora('Installing dependencies...').start();\n\n const dependencies: string[] = [];\n const devDependencies: string[] = [];\n\n // Common dependencies\n dependencies.push('clsx', 'tailwind-merge');\n\n // Framework-specific dependencies\n switch (framework) {\n case 'vue':\n dependencies.push('radix-vue');\n devDependencies.push('tailwindcss', 'autoprefixer', 'postcss');\n if (config.iconLibrary === 'lucide') {\n dependencies.push('lucide-vue-next');\n }\n break;\n\n case 'react':\n dependencies.push('@radix-ui/react-slot');\n devDependencies.push('tailwindcss', 'autoprefixer', 'postcss');\n if (config.iconLibrary === 'lucide') {\n dependencies.push('lucide-react');\n }\n if (config.typescript) {\n devDependencies.push('@types/react', '@types/react-dom');\n }\n break;\n\n case 'angular':\n // Angular components use Radix NG primitives\n dependencies.push('@radix-ng/primitives');\n if (config.iconLibrary === 'lucide') {\n dependencies.push('lucide-angular');\n }\n break;\n }\n\n try {\n // Install dependencies\n if (dependencies.length > 0) {\n await installDependencies(dependencies, {\n cwd,\n silent: true,\n });\n }\n\n // Install devDependencies\n if (devDependencies.length > 0) {\n await installDependencies(devDependencies, {\n cwd,\n dev: true,\n silent: true,\n });\n }\n\n spinner.succeed('Dependencies installed');\n } catch (error) {\n spinner.fail('Failed to install dependencies');\n console.error(chalk.red(error));\n return;\n }\n\n // Create directories\n const dirSpinner = ora('Creating directories...').start();\n\n try {\n const componentsPath = resolve(cwd, config.aliases.components.replace('@/', ''));\n const utilsPath = resolve(cwd, config.aliases.utils.replace('@/', ''));\n\n await ensureDir(componentsPath);\n await ensureDir(resolve(componentsPath, 'ui'));\n await ensureDir(utilsPath.replace('/utils', '')); // Create lib dir\n\n dirSpinner.succeed('Directories created');\n } catch (error) {\n dirSpinner.fail('Failed to create directories');\n console.error(chalk.red(error));\n return;\n }\n\n // Create utils file\n const utilsSpinner = ora('Creating utility functions...').start();\n\n try {\n const utilsPath = resolve(cwd, config.aliases.utils.replace('@/', '') + '.ts');\n const utilsContent = getUtilsContent();\n writeFile(utilsPath, utilsContent);\n\n utilsSpinner.succeed('Utility functions created');\n } catch (error) {\n utilsSpinner.fail('Failed to create utility functions');\n console.error(chalk.red(error));\n return;\n }\n\n // Save components.json\n const configSpinner = ora('Creating components.json...').start();\n\n try {\n createComponentsConfig(cwd, framework);\n configSpinner.succeed('components.json created');\n } catch (error) {\n configSpinner.fail('Failed to create components.json');\n console.error(chalk.red(error));\n return;\n }\n\n // Success message\n console.log(chalk.green('\\n✨ Success! Galaxy UI has been initialized.\\n'));\n console.log(chalk.cyan('Next steps:\\n'));\n console.log(chalk.white(` 1. Configure Tailwind CSS in ${config.tailwind.config}`));\n console.log(chalk.white(` 2. Import utilities in ${config.tailwind.css}`));\n console.log(chalk.white(` 3. Add components:`));\n console.log(chalk.gray(` galaxy-design add button`));\n console.log(chalk.gray(` galaxy-design add input card`));\n console.log(chalk.gray(` galaxy-design add --all\\n`));\n\n console.log(chalk.cyan('Learn more:'));\n console.log(chalk.white(' Documentation: https://galaxy-design.vercel.app'));\n console.log(chalk.white(' GitHub: https://github.com/buikevin/galaxy-design\\n'));\n}\n\n/**\n * Get utils.ts content\n */\nfunction getUtilsContent(): string {\n return `import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\n/**\n * Merge Tailwind CSS classes\n */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n`;\n}\n"],"names":["prompts","chalk","ora","detectFramework","detectPackageManager","createComponentsConfig","hasComponentsConfig","getDefaultConfig","writeFile","ensureDir","installDependencies","resolve","initCommand","options","console","log","bold","cyan","cwd","yellow","overwrite","type","name","message","initial","gray","detectedFramework","red","green","frameworkMap","angular","react","vue","flutter","unknown","framework","packageManager","config","yes","promptQuestions","push","active","inactive","choices","title","value","tailwind","css","answers","Object","keys","length","typescript","iconLibrary","baseColor","cssFile","spinner","start","dependencies","devDependencies","silent","dev","succeed","error","fail","dirSpinner","componentsPath","aliases","components","replace","utilsPath","utils","utilsSpinner","utilsContent","getUtilsContent","configSpinner","white"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/commands/init.ts"],"sourcesContent":["import prompts from 'prompts';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport {\n detectFramework,\n detectPackageManager,\n type Framework as DetectedFramework,\n} from '../utils/detect.js';\nimport {\n createComponentsConfig,\n hasComponentsConfig,\n loadComponentsConfig,\n type Framework,\n} from '../utils/components-config.js';\nimport {\n getDefaultConfig,\n type BaseColor,\n type IconLibrary,\n} from '../utils/config-schema.js';\nimport { writeFile, ensureDir } from '../utils/files.js';\nimport { installDependencies } from '../utils/package-manager.js';\nimport { resolve } from 'path';\n\ninterface InitOptions {\n yes?: boolean;\n cwd: string;\n}\n\nexport async function initCommand(options: InitOptions) {\n console.log(chalk.bold.cyan('\\n🌌 Galaxy UI CLI - Multi-Framework Edition\\n'));\n\n const cwd = options.cwd;\n\n // Check if already initialized\n if (hasComponentsConfig(cwd)) {\n console.log(chalk.yellow('⚠ components.json already exists in this project.'));\n const { overwrite } = await prompts({\n type: 'confirm',\n name: 'overwrite',\n message: 'Do you want to overwrite the existing configuration?',\n initial: false,\n });\n\n if (!overwrite) {\n console.log(chalk.gray('Initialization cancelled.'));\n return;\n }\n }\n\n // Detect framework\n const detectedFramework = detectFramework(cwd);\n\n if (detectedFramework === 'unknown') {\n console.log(\n chalk.red(\n '❌ Could not detect framework. Please ensure you are in a valid Angular, React, Vue, Next.js, Nuxt.js, React Native, or Flutter project.'\n )\n );\n return;\n }\n\n console.log(chalk.green(`βœ“ Detected ${chalk.bold(detectedFramework)} framework`));\n\n // Map detected framework to Framework type\n const frameworkMap: Record<DetectedFramework, Framework | null> = {\n angular: 'angular',\n react: 'react',\n vue: 'vue',\n 'react-native': 'react-native',\n flutter: 'flutter',\n nextjs: 'nextjs',\n nuxtjs: 'nuxtjs',\n unknown: null,\n };\n\n const framework = frameworkMap[detectedFramework];\n if (!framework) {\n console.log(chalk.red('❌ Unsupported framework detected.'));\n return;\n }\n\n // Detect package manager\n const packageManager = detectPackageManager(cwd);\n console.log(chalk.green(`βœ“ Using ${chalk.bold(packageManager)} package manager`));\n\n // Get configuration from user (or use defaults with --yes)\n let config = getDefaultConfig(framework);\n\n if (!options.yes) {\n console.log(chalk.cyan('\\nπŸ“ Configuration\\n'));\n\n // Build prompts based on framework\n const promptQuestions: any[] = [];\n\n // TypeScript prompt (not for Flutter)\n if (framework !== 'flutter') {\n promptQuestions.push({\n type: 'toggle',\n name: 'typescript',\n message: 'Would you like to use TypeScript?',\n initial: true,\n active: 'yes',\n inactive: 'no',\n });\n }\n\n // Base color prompt (for all frameworks)\n promptQuestions.push({\n type: 'select',\n name: 'baseColor',\n message: 'Which base color would you like to use?',\n choices: [\n { title: 'Slate', value: 'slate' },\n { title: 'Gray', value: 'gray' },\n { title: 'Zinc', value: 'zinc' },\n { title: 'Neutral', value: 'neutral' },\n { title: 'Stone', value: 'stone' },\n ],\n initial: 0,\n });\n\n // Icon library prompt (not for Flutter - uses built-in icons)\n if (framework !== 'flutter') {\n promptQuestions.push({\n type: 'select',\n name: 'iconLibrary',\n message: 'Which icon library would you like to use?',\n choices: [\n { title: 'Lucide (Recommended)', value: 'lucide' },\n { title: 'Heroicons', value: 'heroicons' },\n { title: 'Radix Icons', value: 'radix-icons' },\n ],\n initial: 0,\n });\n }\n\n // CSS file prompt (only for web frameworks and React Native)\n if (framework !== 'flutter' && config.tailwind.css) {\n promptQuestions.push({\n type: 'text',\n name: 'cssFile',\n message: framework === 'react-native'\n ? 'Where is your global CSS file (for NativeWind)?'\n : 'Where is your global CSS file?',\n initial: config.tailwind.css,\n });\n }\n\n const answers = await prompts(promptQuestions);\n\n if (Object.keys(answers).length === 0) {\n console.log(chalk.gray('Initialization cancelled.'));\n return;\n }\n\n // Update config with user choices\n config = {\n ...config,\n typescript: answers.typescript ?? config.typescript,\n iconLibrary: (answers.iconLibrary as IconLibrary) ?? config.iconLibrary,\n tailwind: {\n ...config.tailwind,\n baseColor: (answers.baseColor as BaseColor) ?? config.tailwind.baseColor,\n css: answers.cssFile ?? config.tailwind.css,\n },\n };\n }\n\n console.log(chalk.cyan('\\nπŸ“¦ Installing dependencies...\\n'));\n\n // Install dependencies\n const spinner = ora('Installing dependencies...').start();\n\n const dependencies: string[] = [];\n const devDependencies: string[] = [];\n\n // Common dependencies\n dependencies.push('clsx', 'tailwind-merge');\n\n // Framework-specific dependencies\n switch (framework) {\n case 'vue':\n case 'nuxtjs':\n dependencies.push('radix-vue');\n devDependencies.push('tailwindcss', 'autoprefixer', 'postcss');\n if (config.iconLibrary === 'lucide') {\n dependencies.push('lucide-vue-next');\n }\n break;\n\n case 'react':\n case 'nextjs':\n dependencies.push('@radix-ui/react-slot');\n devDependencies.push('tailwindcss', 'autoprefixer', 'postcss');\n if (config.iconLibrary === 'lucide') {\n dependencies.push('lucide-react');\n }\n if (config.typescript) {\n devDependencies.push('@types/react', '@types/react-dom');\n }\n break;\n\n case 'angular':\n // Angular components use Radix NG primitives\n dependencies.push('@radix-ng/primitives');\n if (config.iconLibrary === 'lucide') {\n dependencies.push('lucide-angular');\n }\n break;\n }\n\n try {\n // Install dependencies\n if (dependencies.length > 0) {\n await installDependencies(dependencies, {\n cwd,\n silent: true,\n });\n }\n\n // Install devDependencies\n if (devDependencies.length > 0) {\n await installDependencies(devDependencies, {\n cwd,\n dev: true,\n silent: true,\n });\n }\n\n spinner.succeed('Dependencies installed');\n } catch (error) {\n spinner.fail('Failed to install dependencies');\n console.error(chalk.red(error));\n return;\n }\n\n // Create directories\n const dirSpinner = ora('Creating directories...').start();\n\n try {\n const componentsPath = resolve(cwd, config.aliases.components.replace('@/', ''));\n const utilsPath = resolve(cwd, config.aliases.utils.replace('@/', ''));\n\n await ensureDir(componentsPath);\n await ensureDir(resolve(componentsPath, 'ui'));\n await ensureDir(utilsPath.replace('/utils', '')); // Create lib dir\n\n dirSpinner.succeed('Directories created');\n } catch (error) {\n dirSpinner.fail('Failed to create directories');\n console.error(chalk.red(error));\n return;\n }\n\n // Create utils file\n const utilsSpinner = ora('Creating utility functions...').start();\n\n try {\n const utilsPath = resolve(cwd, config.aliases.utils.replace('@/', '') + '.ts');\n const utilsContent = getUtilsContent();\n writeFile(utilsPath, utilsContent);\n\n utilsSpinner.succeed('Utility functions created');\n } catch (error) {\n utilsSpinner.fail('Failed to create utility functions');\n console.error(chalk.red(error));\n return;\n }\n\n // Save components.json\n const configSpinner = ora('Creating components.json...').start();\n\n try {\n createComponentsConfig(cwd, framework);\n configSpinner.succeed('components.json created');\n } catch (error) {\n configSpinner.fail('Failed to create components.json');\n console.error(chalk.red(error));\n return;\n }\n\n // Success message\n console.log(chalk.green('\\n✨ Success! Galaxy UI has been initialized.\\n'));\n console.log(chalk.cyan('Next steps:\\n'));\n console.log(chalk.white(` 1. Configure Tailwind CSS in ${config.tailwind.config}`));\n console.log(chalk.white(` 2. Import utilities in ${config.tailwind.css}`));\n console.log(chalk.white(` 3. Add components:`));\n console.log(chalk.gray(` galaxy-design add button`));\n console.log(chalk.gray(` galaxy-design add input card`));\n console.log(chalk.gray(` galaxy-design add --all\\n`));\n\n console.log(chalk.cyan('Learn more:'));\n console.log(chalk.white(' Documentation: https://galaxy-design.vercel.app'));\n console.log(chalk.white(' GitHub: https://github.com/buikevin/galaxy-design\\n'));\n}\n\n/**\n * Get utils.ts content\n */\nfunction getUtilsContent(): string {\n return `import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\n/**\n * Merge Tailwind CSS classes\n */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n`;\n}\n"],"names":["prompts","chalk","ora","detectFramework","detectPackageManager","createComponentsConfig","hasComponentsConfig","getDefaultConfig","writeFile","ensureDir","installDependencies","resolve","initCommand","options","console","log","bold","cyan","cwd","yellow","overwrite","type","name","message","initial","gray","detectedFramework","red","green","frameworkMap","angular","react","vue","flutter","nextjs","nuxtjs","unknown","framework","packageManager","config","yes","promptQuestions","push","active","inactive","choices","title","value","tailwind","css","answers","Object","keys","length","typescript","iconLibrary","baseColor","cssFile","spinner","start","dependencies","devDependencies","silent","dev","succeed","error","fail","dirSpinner","componentsPath","aliases","components","replace","utilsPath","utils","utilsSpinner","utilsContent","getUtilsContent","configSpinner","white"],"mappings":"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"}
@@ -92,6 +92,16 @@
92
92
  "files": ["Textarea.tsx", "index.ts"],
93
93
  "category": "form"
94
94
  },
95
+ "form": {
96
+ "name": "Form",
97
+ "type": "form",
98
+ "description": "Building forms with React Hook Form and Zod validation",
99
+ "dependencies": ["react-hook-form", "@hookform/resolvers", "zod"],
100
+ "devDependencies": [],
101
+ "registryDependencies": ["button", "input", "label"],
102
+ "files": ["Form.tsx", "index.ts"],
103
+ "category": "form"
104
+ },
95
105
  "separator": {
96
106
  "name": "Separator",
97
107
  "type": "layout",
@@ -142,6 +152,16 @@
142
152
  "files": ["Collapsible.tsx", "index.ts"],
143
153
  "category": "layout"
144
154
  },
155
+ "card": {
156
+ "name": "Card",
157
+ "type": "layout",
158
+ "description": "Displays a card with header, content, and footer",
159
+ "dependencies": [],
160
+ "devDependencies": [],
161
+ "registryDependencies": [],
162
+ "files": ["Card.tsx", "index.ts"],
163
+ "category": "layout"
164
+ },
145
165
  "alert-dialog": {
146
166
  "name": "Alert Dialog",
147
167
  "type": "feedback",
@@ -152,6 +172,16 @@
152
172
  "files": ["AlertDialog.tsx", "index.ts"],
153
173
  "category": "feedback"
154
174
  },
175
+ "alert": {
176
+ "name": "Alert",
177
+ "type": "feedback",
178
+ "description": "Displays a callout for user attention",
179
+ "dependencies": [],
180
+ "devDependencies": [],
181
+ "registryDependencies": [],
182
+ "files": ["Alert.tsx", "index.ts"],
183
+ "category": "feedback"
184
+ },
155
185
  "progress": {
156
186
  "name": "Progress",
157
187
  "type": "feedback",
@@ -202,6 +232,16 @@
202
232
  "files": ["NavigationMenu.tsx", "index.ts"],
203
233
  "category": "navigation"
204
234
  },
235
+ "breadcrumb": {
236
+ "name": "Breadcrumb",
237
+ "type": "navigation",
238
+ "description": "Displays the path to the current resource using a hierarchy of links",
239
+ "dependencies": [],
240
+ "devDependencies": [],
241
+ "registryDependencies": [],
242
+ "files": ["Breadcrumb.tsx", "index.ts"],
243
+ "category": "navigation"
244
+ },
205
245
  "menubar": {
206
246
  "name": "Menubar",
207
247
  "type": "navigation",
@@ -392,6 +432,26 @@
392
432
  "files": ["Skeleton.tsx", "index.ts"],
393
433
  "category": "feedback"
394
434
  },
435
+ "badge": {
436
+ "name": "Badge",
437
+ "type": "feedback",
438
+ "description": "Displays a badge or a component that looks like a badge",
439
+ "dependencies": [],
440
+ "devDependencies": [],
441
+ "registryDependencies": [],
442
+ "files": ["Badge.tsx", "index.ts"],
443
+ "category": "feedback"
444
+ },
445
+ "toast": {
446
+ "name": "Toast",
447
+ "type": "feedback",
448
+ "description": "A succinct message that is displayed temporarily",
449
+ "dependencies": ["@radix-ui/react-toast"],
450
+ "devDependencies": [],
451
+ "registryDependencies": [],
452
+ "files": ["Toast.tsx", "Toaster.tsx", "index.ts"],
453
+ "category": "feedback"
454
+ },
395
455
  "kbd": {
396
456
  "name": "Kbd",
397
457
  "type": "data-display",
@@ -496,11 +556,11 @@
496
556
  "groups": {
497
557
  "form": {
498
558
  "name": "Form Components",
499
- "components": ["button", "input", "label", "select", "checkbox", "radio-group", "switch", "slider", "textarea", "calendar", "calendar-range", "tags-input"]
559
+ "components": ["button", "input", "label", "select", "checkbox", "radio-group", "switch", "slider", "textarea", "form", "calendar", "calendar-range", "tags-input"]
500
560
  },
501
561
  "layout": {
502
562
  "name": "Layout Components",
503
- "components": ["separator", "accordion", "tabs", "dialog", "collapsible", "scroll-area", "aspect-ratio", "resizable", "sheet", "toolbar"]
563
+ "components": ["card", "separator", "accordion", "tabs", "dialog", "collapsible", "scroll-area", "aspect-ratio", "resizable", "sheet", "toolbar"]
504
564
  },
505
565
  "interactive": {
506
566
  "name": "Interactive Components",
@@ -508,7 +568,7 @@
508
568
  },
509
569
  "feedback": {
510
570
  "name": "Feedback Components",
511
- "components": ["alert-dialog", "progress", "empty", "skeleton"]
571
+ "components": ["alert-dialog", "alert", "progress", "empty", "skeleton", "badge", "toast"]
512
572
  },
513
573
  "data-display": {
514
574
  "name": "Data Display Components",
@@ -516,7 +576,7 @@
516
576
  },
517
577
  "navigation": {
518
578
  "name": "Navigation Components",
519
- "components": ["dropdown-menu", "navigation-menu", "menubar", "context-menu", "popover", "tooltip", "pagination", "command"]
579
+ "components": ["dropdown-menu", "navigation-menu", "breadcrumb", "menubar", "context-menu", "popover", "tooltip", "pagination", "command"]
520
580
  },
521
581
  "charts": {
522
582
  "name": "Chart Components",
@@ -1,8 +1,9 @@
1
- import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
2
2
  import { dirname, join, relative } from 'path';
3
3
  import { getComponentSourceDir, isMobilePlatform } from './platform-detector';
4
4
  import { getComponent, validateComponentDependencies } from './registry-loader';
5
5
  import { fetchAndSaveFile, getComponentGitHubPath } from './github-fetcher';
6
+ import { transformComponent } from './component-transformer';
6
7
  /**
7
8
  * Copy a component to target project
8
9
  *
@@ -55,6 +56,7 @@ import { fetchAndSaveFile, getComponentGitHubPath } from './github-fetcher';
55
56
  }
56
57
  // Copy file - from GitHub or local
57
58
  try {
59
+ let fileContent;
58
60
  if (useGitHub) {
59
61
  // Fetch from GitHub
60
62
  const githubPath = getComponentGitHubPath(options.platform, componentName, file);
@@ -63,6 +65,8 @@ import { fetchAndSaveFile, getComponentGitHubPath } from './github-fetcher';
63
65
  result.errors.push(`Failed to fetch ${file} from GitHub`);
64
66
  continue;
65
67
  }
68
+ // Read the fetched content for transformation
69
+ fileContent = readFileSync(targetFile, 'utf-8');
66
70
  } else {
67
71
  // Copy from local packages directory (for development)
68
72
  const packagesDir = options.packagesDir;
@@ -73,7 +77,20 @@ import { fetchAndSaveFile, getComponentGitHubPath } from './github-fetcher';
73
77
  result.errors.push(`Source file not found: ${sourceFile}`);
74
78
  continue;
75
79
  }
76
- copyFileSync(sourceFile, targetFile);
80
+ fileContent = readFileSync(sourceFile, 'utf-8');
81
+ }
82
+ // Transform component if needed (Next.js, Nuxt.js)
83
+ const transformResult = transformComponent(fileContent, {
84
+ platform: options.platform,
85
+ componentName,
86
+ filePath: targetFile
87
+ });
88
+ // Write the transformed content
89
+ writeFileSync(targetFile, transformResult.content, 'utf-8');
90
+ // Log transformation notes if modified
91
+ if (transformResult.modified && transformResult.notes.length > 0) {
92
+ // Store notes for later display (optional)
93
+ console.log(` πŸ“ ${file}: ${transformResult.notes.join(', ')}`);
77
94
  }
78
95
  result.filesCopied.push(relative(options.targetDir, targetFile));
79
96
  } catch (error) {
@@ -119,11 +136,19 @@ import { fetchAndSaveFile, getComponentGitHubPath } from './github-fetcher';
119
136
  // Flutter: lib/components
120
137
  return join(projectRoot, 'lib', 'components');
121
138
  case 'vue':
122
- // Vue: src/components
123
- return join(projectRoot, 'src', 'components');
139
+ case 'nuxtjs':
140
+ // Vue/Nuxt: src/components or components
141
+ if (existsSync(join(projectRoot, 'src'))) {
142
+ return join(projectRoot, 'src', 'components');
143
+ }
144
+ return join(projectRoot, 'components');
124
145
  case 'react':
125
- // React: src/components
126
- return join(projectRoot, 'src', 'components');
146
+ case 'nextjs':
147
+ // React/Next.js: src/components or components
148
+ if (existsSync(join(projectRoot, 'src'))) {
149
+ return join(projectRoot, 'src', 'components');
150
+ }
151
+ return join(projectRoot, 'components');
127
152
  case 'angular':
128
153
  // Angular: src/components or components
129
154
  if (existsSync(join(projectRoot, 'src', 'app'))) {
@@ -151,12 +176,14 @@ import { fetchAndSaveFile, getComponentGitHubPath } from './github-fetcher';
151
176
  switch(platform){
152
177
  case 'react-native':
153
178
  case 'react':
179
+ case 'nextjs':
154
180
  // TypeScript/JSX import
155
- return `import { ${exports.join(', ')} } from './components/${componentName}';`;
181
+ return `import { ${exports.join(', ')} } from '@/components/${componentName}';`;
156
182
  case 'flutter':
157
183
  // Dart import
158
184
  return `import 'package:your_app/components/${componentName}/${componentName.replace(/-/g, '_')}.dart';`;
159
185
  case 'vue':
186
+ case 'nuxtjs':
160
187
  // Vue import
161
188
  return `import { ${exports.join(', ')} } from '@/components/${componentName}';`;
162
189
  case 'angular':
@@ -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';\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\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\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\tcopyFileSync(sourceFile, targetFile);\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\t\t// Vue: src/components\n\t\t\treturn join(projectRoot, 'src', 'components');\n\n\t\tcase 'react':\n\t\t\t// React: src/components\n\t\t\treturn join(projectRoot, 'src', '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\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\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":["copyFileSync","existsSync","mkdirSync","readFileSync","writeFileSync","dirname","join","relative","getComponentSourceDir","isMobilePlatform","getComponent","validateComponentDependencies","fetchAndSaveFile","getComponentGitHubPath","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","githubPath","componentSourceDir","sourceDir","sourceFile","error","Error","message","length","copyComponents","componentNames","results","name","console","warn","projectRoot","generateImportStatement","exports","replace","createComponentsConfig","config","$schema","framework","typescript","styling","components","utils","configPath","JSON","stringify","readComponentsConfig","content","parse"],"mappings":"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"}
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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"}
@@ -0,0 +1,175 @@
1
+ import { _ as _extends } from "@swc/helpers/_/_extends";
2
+ import { readFileSync } from 'fs';
3
+ /**
4
+ * Check if a React/Next.js component needs 'use client' directive
5
+ *
6
+ * Components need 'use client' if they use:
7
+ * - React hooks (useState, useEffect, etc.)
8
+ * - Event handlers (onClick, onChange, etc.)
9
+ * - Browser APIs (window, document, etc.)
10
+ * - Client-side libraries
11
+ */ function needsUseClient(content) {
12
+ const clientIndicators = [
13
+ // React hooks
14
+ /\buse[A-Z]\w+\s*\(/,
15
+ /useState|useEffect|useContext|useReducer|useCallback|useMemo|useRef/,
16
+ // Event handlers
17
+ /\bon[A-Z]\w+\s*=/,
18
+ /onClick|onChange|onSubmit|onFocus|onBlur|onKeyDown|onKeyUp|onMouseEnter|onMouseLeave/,
19
+ // Browser APIs
20
+ /\bwindow\./,
21
+ /\bdocument\./,
22
+ /\bnavigator\./,
23
+ /\blocalStorage\./,
24
+ /\bsessionStorage\./,
25
+ // Client-side only features
26
+ /addEventListener/,
27
+ /removeEventListener/,
28
+ /createPortal/
29
+ ];
30
+ return clientIndicators.some((indicator)=>indicator.test(content));
31
+ }
32
+ /**
33
+ * Check if file already has 'use client' directive
34
+ */ function hasUseClientDirective(content) {
35
+ const lines = content.split('\n');
36
+ const firstNonEmptyLine = lines.find((line)=>line.trim() !== '');
37
+ return (firstNonEmptyLine == null ? void 0 : firstNonEmptyLine.trim().startsWith("'use client'")) || (firstNonEmptyLine == null ? void 0 : firstNonEmptyLine.trim().startsWith('"use client"')) || false;
38
+ }
39
+ /**
40
+ * Add 'use client' directive to Next.js component
41
+ */ function addUseClientDirective(content) {
42
+ // Skip if already has the directive
43
+ if (hasUseClientDirective(content)) {
44
+ return content;
45
+ }
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
+ }
57
+ }
58
+ // Insert 'use client' directive
59
+ lines.splice(insertIndex, 0, "'use client'", '');
60
+ return lines.join('\n');
61
+ }
62
+ /**
63
+ * Transform component for Next.js
64
+ *
65
+ * Adds 'use client' directive if component uses client-side features
66
+ */ function transformNextjsComponent(content, componentName) {
67
+ const notes = [];
68
+ let modified = false;
69
+ let transformedContent = content;
70
+ // Check if component needs 'use client'
71
+ if (needsUseClient(content) && !hasUseClientDirective(content)) {
72
+ transformedContent = addUseClientDirective(content);
73
+ modified = true;
74
+ notes.push(`Added 'use client' directive (component uses client-side features)`);
75
+ } else if (hasUseClientDirective(content)) {
76
+ notes.push(`Component already has 'use client' directive`);
77
+ } else {
78
+ notes.push(`Component appears to be server-safe (no 'use client' needed)`);
79
+ }
80
+ return {
81
+ content: transformedContent,
82
+ modified,
83
+ notes
84
+ };
85
+ }
86
+ /**
87
+ * Transform component for Nuxt.js
88
+ *
89
+ * Currently no transformations needed, but placeholder for future enhancements
90
+ */ function transformNuxtjsComponent(content, componentName) {
91
+ const notes = [];
92
+ // Check for Nuxt-specific patterns
93
+ const hasNuxtImports = /from ['"]#app['"]/.test(content);
94
+ const hasAutoImports = /\b(navigateTo|useFetch|useAsyncData|useState)\b/.test(content);
95
+ if (hasNuxtImports) {
96
+ notes.push('Component uses Nuxt 3 auto-imports (#app)');
97
+ }
98
+ if (hasAutoImports) {
99
+ notes.push('Component uses Nuxt 3 composables (auto-imported)');
100
+ }
101
+ if (!hasNuxtImports && !hasAutoImports) {
102
+ notes.push('Component appears to be standard Vue 3 (works in Nuxt)');
103
+ }
104
+ return {
105
+ content,
106
+ modified: false,
107
+ notes
108
+ };
109
+ }
110
+ /**
111
+ * Transform component file based on platform
112
+ *
113
+ * @param content - File content
114
+ * @param options - Transform options
115
+ * @returns Transform result
116
+ */ export function transformComponent(content, options) {
117
+ const { platform, componentName } = options;
118
+ switch(platform){
119
+ case 'nextjs':
120
+ return transformNextjsComponent(content, componentName);
121
+ case 'nuxtjs':
122
+ return transformNuxtjsComponent(content, componentName);
123
+ // Other platforms don't need transformation
124
+ case 'react':
125
+ case 'vue':
126
+ case 'angular':
127
+ case 'react-native':
128
+ case 'flutter':
129
+ default:
130
+ return {
131
+ content,
132
+ modified: false,
133
+ notes: [
134
+ 'No transformation needed for this platform'
135
+ ]
136
+ };
137
+ }
138
+ }
139
+ /**
140
+ * Transform component file from file path
141
+ *
142
+ * @param filePath - Path to component file
143
+ * @param options - Transform options
144
+ * @returns Transform result
145
+ */ export function transformComponentFile(filePath, options) {
146
+ const content = readFileSync(filePath, 'utf-8');
147
+ return transformComponent(content, _extends({}, options, {
148
+ filePath
149
+ }));
150
+ }
151
+ /**
152
+ * Batch transform multiple files
153
+ *
154
+ * @param files - Array of file paths
155
+ * @param options - Transform options (without filePath)
156
+ * @returns Array of transform results
157
+ */ export function transformComponentFiles(files, options) {
158
+ const results = new Map();
159
+ for (const filePath of files){
160
+ const componentName = options.componentName || extractComponentName(filePath);
161
+ const result = transformComponentFile(filePath, _extends({}, options, {
162
+ componentName
163
+ }));
164
+ results.set(filePath, result);
165
+ }
166
+ return results;
167
+ }
168
+ /**
169
+ * Extract component name from file path
170
+ */ function extractComponentName(filePath) {
171
+ const fileName = filePath.split('/').pop() || '';
172
+ return fileName.replace(/\.(tsx?|vue|js|jsx)$/, '');
173
+ }
174
+
175
+ //# sourceMappingURL=component-transformer.js.map
@@ -0,0 +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 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\tswitch (platform) {\n\t\tcase 'nextjs':\n\t\t\treturn transformNextjsComponent(content, componentName);\n\n\t\tcase 'nuxtjs':\n\t\t\treturn transformNuxtjsComponent(content, componentName);\n\n\t\t// Other platforms don't need 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\treturn {\n\t\t\t\tcontent,\n\t\t\t\tmodified: false,\n\t\t\t\tnotes: ['No transformation needed for this platform'],\n\t\t\t};\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","transformComponent","options","platform","transformComponentFile","filePath","transformComponentFiles","files","results","Map","extractComponentName","result","set","fileName","pop","replace"],"mappings":"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"}
@@ -6,7 +6,9 @@ export const frameworkSchema = z.enum([
6
6
  'react',
7
7
  'angular',
8
8
  'react-native',
9
- 'flutter'
9
+ 'flutter',
10
+ 'nextjs',
11
+ 'nuxtjs'
10
12
  ]);
11
13
  // Base color types
12
14
  export const baseColorSchema = z.enum([
@@ -137,6 +139,42 @@ export const defaultConfigs = {
137
139
  lib: 'lib'
138
140
  },
139
141
  iconLibrary: 'lucide'
142
+ },
143
+ nextjs: {
144
+ framework: 'nextjs',
145
+ typescript: true,
146
+ tailwind: {
147
+ config: 'tailwind.config.ts',
148
+ css: 'app/globals.css',
149
+ baseColor: 'slate',
150
+ cssVariables: true,
151
+ prefix: ''
152
+ },
153
+ aliases: {
154
+ components: '@/components',
155
+ utils: '@/lib/utils',
156
+ ui: '@/components/ui',
157
+ lib: '@/lib'
158
+ },
159
+ iconLibrary: 'lucide'
160
+ },
161
+ nuxtjs: {
162
+ framework: 'nuxtjs',
163
+ typescript: true,
164
+ tailwind: {
165
+ config: 'tailwind.config.js',
166
+ css: 'assets/css/main.css',
167
+ baseColor: 'slate',
168
+ cssVariables: true,
169
+ prefix: ''
170
+ },
171
+ aliases: {
172
+ components: '@/components',
173
+ utils: '@/lib/utils',
174
+ ui: '@/components/ui',
175
+ lib: '@/lib'
176
+ },
177
+ iconLibrary: 'lucide'
140
178
  }
141
179
  };
142
180
  /**
@@ -165,11 +203,13 @@ export const defaultConfigs = {
165
203
  const ext = typescript ? 'ts' : 'js';
166
204
  switch(framework){
167
205
  case 'vue':
206
+ case 'nuxtjs':
168
207
  return [
169
208
  '.vue',
170
209
  `.${ext}`
171
210
  ];
172
211
  case 'react':
212
+ case 'nextjs':
173
213
  return [
174
214
  `.tsx`,
175
215
  `.jsx`,
@@ -204,8 +244,10 @@ export const defaultConfigs = {
204
244
  */ export function getComponentPath(framework) {
205
245
  switch(framework){
206
246
  case 'vue':
247
+ case 'nuxtjs':
207
248
  return 'src/components';
208
249
  case 'react':
250
+ case 'nextjs':
209
251
  return 'src/components';
210
252
  case 'react-native':
211
253
  return 'src/components';
@@ -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']);\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/assets/styles/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 react: {\n framework: 'react',\n typescript: true,\n tailwind: {\n config: 'tailwind.config.js',\n css: 'src/app/globals.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};\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 return ['.vue', `.${ext}`];\n case 'react':\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 return 'src/components';\n case 'react':\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","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\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/assets/styles/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 react: {\n framework: 'react',\n typescript: true,\n tailwind: {\n config: 'tailwind.config.js',\n css: 'src/app/globals.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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"}
@@ -20,6 +20,14 @@ import { resolve } from 'path';
20
20
  if (deps['react-native']) {
21
21
  return 'react-native';
22
22
  }
23
+ // Check for Next.js (must be before React check)
24
+ if (deps['next']) {
25
+ return 'nextjs';
26
+ }
27
+ // Check for Nuxt.js (must be before Vue check)
28
+ if (deps['nuxt'] || deps['nuxt3']) {
29
+ return 'nuxtjs';
30
+ }
23
31
  if (deps['@angular/core']) {
24
32
  return 'angular';
25
33
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/detect.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'fs';\nimport { resolve } from 'path';\n\nexport type Framework = 'angular' | 'react' | 'vue' | 'react-native' | 'flutter' | 'unknown';\nexport type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun' | 'pub';\n\n/**\n * Detect the framework being used in the project\n */\nexport function detectFramework(cwd: string): Framework {\n // Check for Flutter first (uses pubspec.yaml instead of package.json)\n const pubspecPath = resolve(cwd, 'pubspec.yaml');\n if (existsSync(pubspecPath)) {\n return 'flutter';\n }\n\n const packageJsonPath = resolve(cwd, 'package.json');\n\n if (!existsSync(packageJsonPath)) {\n return 'unknown';\n }\n\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n const deps = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n };\n\n // Check for React Native (must be before React check)\n if (deps['react-native']) {\n return 'react-native';\n }\n\n if (deps['@angular/core']) {\n return 'angular';\n }\n if (deps['react']) {\n return 'react';\n }\n if (deps['vue']) {\n return 'vue';\n }\n\n return 'unknown';\n } catch {\n return 'unknown';\n }\n}\n\n/**\n * Detect the package manager being used\n */\nexport function detectPackageManager(cwd: string): PackageManager {\n // Check for Flutter package manager\n if (existsSync(resolve(cwd, 'pubspec.yaml'))) {\n return 'pub';\n }\n\n if (existsSync(resolve(cwd, 'bun.lockb')) || existsSync(resolve(cwd, 'bun.lock'))) {\n return 'bun';\n }\n if (existsSync(resolve(cwd, 'pnpm-lock.yaml'))) {\n return 'pnpm';\n }\n if (existsSync(resolve(cwd, 'yarn.lock'))) {\n return 'yarn';\n }\n return 'npm';\n}\n\n/**\n * Check if project is already initialized with Galaxy UI\n */\nexport function isGalaxyInitialized(cwd: string): boolean {\n const packageJsonPath = resolve(cwd, 'package.json');\n\n if (!existsSync(packageJsonPath)) {\n return false;\n }\n\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n const deps = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n };\n\n return !!(deps['lucide-angular'] && deps['clsx'] && deps['tailwind-merge']);\n } catch {\n return false;\n }\n}\n\n/**\n * Check if Tailwind CSS is installed\n */\nexport function isTailwindInstalled(cwd: string): boolean {\n const packageJsonPath = resolve(cwd, 'package.json');\n\n if (!existsSync(packageJsonPath)) {\n return false;\n }\n\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n const deps = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n };\n\n return !!deps['tailwindcss'];\n } catch {\n return false;\n }\n}\n"],"names":["existsSync","readFileSync","resolve","detectFramework","cwd","pubspecPath","packageJsonPath","packageJson","JSON","parse","deps","dependencies","devDependencies","detectPackageManager","isGalaxyInitialized","isTailwindInstalled"],"mappings":";AAAA,SAASA,UAAU,EAAEC,YAAY,QAAQ,KAAK;AAC9C,SAASC,OAAO,QAAQ,OAAO;AAK/B;;CAEC,GACD,OAAO,SAASC,gBAAgBC,GAAW;IACzC,sEAAsE;IACtE,MAAMC,cAAcH,QAAQE,KAAK;IACjC,IAAIJ,WAAWK,cAAc;QAC3B,OAAO;IACT;IAEA,MAAMC,kBAAkBJ,QAAQE,KAAK;IAErC,IAAI,CAACJ,WAAWM,kBAAkB;QAChC,OAAO;IACT;IAEA,IAAI;QACF,MAAMC,cAAcC,KAAKC,KAAK,CAACR,aAAaK,iBAAiB;QAC7D,MAAMI,OAAO,aACRH,YAAYI,YAAY,EACxBJ,YAAYK,eAAe;QAGhC,sDAAsD;QACtD,IAAIF,IAAI,CAAC,eAAe,EAAE;YACxB,OAAO;QACT;QAEA,IAAIA,IAAI,CAAC,gBAAgB,EAAE;YACzB,OAAO;QACT;QACA,IAAIA,IAAI,CAAC,QAAQ,EAAE;YACjB,OAAO;QACT;QACA,IAAIA,IAAI,CAAC,MAAM,EAAE;YACf,OAAO;QACT;QAEA,OAAO;IACT,EAAE,UAAM;QACN,OAAO;IACT;AACF;AAEA;;CAEC,GACD,OAAO,SAASG,qBAAqBT,GAAW;IAC9C,oCAAoC;IACpC,IAAIJ,WAAWE,QAAQE,KAAK,kBAAkB;QAC5C,OAAO;IACT;IAEA,IAAIJ,WAAWE,QAAQE,KAAK,iBAAiBJ,WAAWE,QAAQE,KAAK,cAAc;QACjF,OAAO;IACT;IACA,IAAIJ,WAAWE,QAAQE,KAAK,oBAAoB;QAC9C,OAAO;IACT;IACA,IAAIJ,WAAWE,QAAQE,KAAK,eAAe;QACzC,OAAO;IACT;IACA,OAAO;AACT;AAEA;;CAEC,GACD,OAAO,SAASU,oBAAoBV,GAAW;IAC7C,MAAME,kBAAkBJ,QAAQE,KAAK;IAErC,IAAI,CAACJ,WAAWM,kBAAkB;QAChC,OAAO;IACT;IAEA,IAAI;QACF,MAAMC,cAAcC,KAAKC,KAAK,CAACR,aAAaK,iBAAiB;QAC7D,MAAMI,OAAO,aACRH,YAAYI,YAAY,EACxBJ,YAAYK,eAAe;QAGhC,OAAO,CAAC,CAAEF,CAAAA,IAAI,CAAC,iBAAiB,IAAIA,IAAI,CAAC,OAAO,IAAIA,IAAI,CAAC,iBAAiB,AAAD;IAC3E,EAAE,UAAM;QACN,OAAO;IACT;AACF;AAEA;;CAEC,GACD,OAAO,SAASK,oBAAoBX,GAAW;IAC7C,MAAME,kBAAkBJ,QAAQE,KAAK;IAErC,IAAI,CAACJ,WAAWM,kBAAkB;QAChC,OAAO;IACT;IAEA,IAAI;QACF,MAAMC,cAAcC,KAAKC,KAAK,CAACR,aAAaK,iBAAiB;QAC7D,MAAMI,OAAO,aACRH,YAAYI,YAAY,EACxBJ,YAAYK,eAAe;QAGhC,OAAO,CAAC,CAACF,IAAI,CAAC,cAAc;IAC9B,EAAE,UAAM;QACN,OAAO;IACT;AACF"}
1
+ {"version":3,"sources":["../../src/utils/detect.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'fs';\nimport { resolve } from 'path';\n\nexport type Framework = 'angular' | 'react' | 'vue' | 'react-native' | 'flutter' | 'nextjs' | 'nuxtjs' | 'unknown';\nexport type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun' | 'pub';\n\n/**\n * Detect the framework being used in the project\n */\nexport function detectFramework(cwd: string): Framework {\n // Check for Flutter first (uses pubspec.yaml instead of package.json)\n const pubspecPath = resolve(cwd, 'pubspec.yaml');\n if (existsSync(pubspecPath)) {\n return 'flutter';\n }\n\n const packageJsonPath = resolve(cwd, 'package.json');\n\n if (!existsSync(packageJsonPath)) {\n return 'unknown';\n }\n\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n const deps = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n };\n\n // Check for React Native (must be before React check)\n if (deps['react-native']) {\n return 'react-native';\n }\n\n // Check for Next.js (must be before React check)\n if (deps['next']) {\n return 'nextjs';\n }\n\n // Check for Nuxt.js (must be before Vue check)\n if (deps['nuxt'] || deps['nuxt3']) {\n return 'nuxtjs';\n }\n\n if (deps['@angular/core']) {\n return 'angular';\n }\n if (deps['react']) {\n return 'react';\n }\n if (deps['vue']) {\n return 'vue';\n }\n\n return 'unknown';\n } catch {\n return 'unknown';\n }\n}\n\n/**\n * Detect the package manager being used\n */\nexport function detectPackageManager(cwd: string): PackageManager {\n // Check for Flutter package manager\n if (existsSync(resolve(cwd, 'pubspec.yaml'))) {\n return 'pub';\n }\n\n if (existsSync(resolve(cwd, 'bun.lockb')) || existsSync(resolve(cwd, 'bun.lock'))) {\n return 'bun';\n }\n if (existsSync(resolve(cwd, 'pnpm-lock.yaml'))) {\n return 'pnpm';\n }\n if (existsSync(resolve(cwd, 'yarn.lock'))) {\n return 'yarn';\n }\n return 'npm';\n}\n\n/**\n * Check if project is already initialized with Galaxy UI\n */\nexport function isGalaxyInitialized(cwd: string): boolean {\n const packageJsonPath = resolve(cwd, 'package.json');\n\n if (!existsSync(packageJsonPath)) {\n return false;\n }\n\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n const deps = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n };\n\n return !!(deps['lucide-angular'] && deps['clsx'] && deps['tailwind-merge']);\n } catch {\n return false;\n }\n}\n\n/**\n * Check if Tailwind CSS is installed\n */\nexport function isTailwindInstalled(cwd: string): boolean {\n const packageJsonPath = resolve(cwd, 'package.json');\n\n if (!existsSync(packageJsonPath)) {\n return false;\n }\n\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n const deps = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n };\n\n return !!deps['tailwindcss'];\n } catch {\n return false;\n }\n}\n"],"names":["existsSync","readFileSync","resolve","detectFramework","cwd","pubspecPath","packageJsonPath","packageJson","JSON","parse","deps","dependencies","devDependencies","detectPackageManager","isGalaxyInitialized","isTailwindInstalled"],"mappings":";AAAA,SAASA,UAAU,EAAEC,YAAY,QAAQ,KAAK;AAC9C,SAASC,OAAO,QAAQ,OAAO;AAK/B;;CAEC,GACD,OAAO,SAASC,gBAAgBC,GAAW;IACzC,sEAAsE;IACtE,MAAMC,cAAcH,QAAQE,KAAK;IACjC,IAAIJ,WAAWK,cAAc;QAC3B,OAAO;IACT;IAEA,MAAMC,kBAAkBJ,QAAQE,KAAK;IAErC,IAAI,CAACJ,WAAWM,kBAAkB;QAChC,OAAO;IACT;IAEA,IAAI;QACF,MAAMC,cAAcC,KAAKC,KAAK,CAACR,aAAaK,iBAAiB;QAC7D,MAAMI,OAAO,aACRH,YAAYI,YAAY,EACxBJ,YAAYK,eAAe;QAGhC,sDAAsD;QACtD,IAAIF,IAAI,CAAC,eAAe,EAAE;YACxB,OAAO;QACT;QAEA,iDAAiD;QACjD,IAAIA,IAAI,CAAC,OAAO,EAAE;YAChB,OAAO;QACT;QAEA,+CAA+C;QAC/C,IAAIA,IAAI,CAAC,OAAO,IAAIA,IAAI,CAAC,QAAQ,EAAE;YACjC,OAAO;QACT;QAEA,IAAIA,IAAI,CAAC,gBAAgB,EAAE;YACzB,OAAO;QACT;QACA,IAAIA,IAAI,CAAC,QAAQ,EAAE;YACjB,OAAO;QACT;QACA,IAAIA,IAAI,CAAC,MAAM,EAAE;YACf,OAAO;QACT;QAEA,OAAO;IACT,EAAE,UAAM;QACN,OAAO;IACT;AACF;AAEA;;CAEC,GACD,OAAO,SAASG,qBAAqBT,GAAW;IAC9C,oCAAoC;IACpC,IAAIJ,WAAWE,QAAQE,KAAK,kBAAkB;QAC5C,OAAO;IACT;IAEA,IAAIJ,WAAWE,QAAQE,KAAK,iBAAiBJ,WAAWE,QAAQE,KAAK,cAAc;QACjF,OAAO;IACT;IACA,IAAIJ,WAAWE,QAAQE,KAAK,oBAAoB;QAC9C,OAAO;IACT;IACA,IAAIJ,WAAWE,QAAQE,KAAK,eAAe;QACzC,OAAO;IACT;IACA,OAAO;AACT;AAEA;;CAEC,GACD,OAAO,SAASU,oBAAoBV,GAAW;IAC7C,MAAME,kBAAkBJ,QAAQE,KAAK;IAErC,IAAI,CAACJ,WAAWM,kBAAkB;QAChC,OAAO;IACT;IAEA,IAAI;QACF,MAAMC,cAAcC,KAAKC,KAAK,CAACR,aAAaK,iBAAiB;QAC7D,MAAMI,OAAO,aACRH,YAAYI,YAAY,EACxBJ,YAAYK,eAAe;QAGhC,OAAO,CAAC,CAAEF,CAAAA,IAAI,CAAC,iBAAiB,IAAIA,IAAI,CAAC,OAAO,IAAIA,IAAI,CAAC,iBAAiB,AAAD;IAC3E,EAAE,UAAM;QACN,OAAO;IACT;AACF;AAEA;;CAEC,GACD,OAAO,SAASK,oBAAoBX,GAAW;IAC7C,MAAME,kBAAkBJ,QAAQE,KAAK;IAErC,IAAI,CAACJ,WAAWM,kBAAkB;QAChC,OAAO;IACT;IAEA,IAAI;QACF,MAAMC,cAAcC,KAAKC,KAAK,CAACR,aAAaK,iBAAiB;QAC7D,MAAMI,OAAO,aACRH,YAAYI,YAAY,EACxBJ,YAAYK,eAAe;QAGhC,OAAO,CAAC,CAACF,IAAI,CAAC,cAAc;IAC9B,EAAE,UAAM;QACN,OAAO;IACT;AACF"}
@@ -13,7 +13,14 @@ const registryCache = new Map();
13
13
  if (registryCache.has(framework)) {
14
14
  return registryCache.get(framework);
15
15
  }
16
- const registryPath = resolve(__dirname, `../registries/registry-${framework}.json`);
16
+ // Map Next.js to React registry and Nuxt.js to Vue registry
17
+ let registryFramework = framework;
18
+ if (framework === 'nextjs') {
19
+ registryFramework = 'react';
20
+ } else if (framework === 'nuxtjs') {
21
+ registryFramework = 'vue';
22
+ }
23
+ const registryPath = resolve(__dirname, `../registries/registry-${registryFramework}.json`);
17
24
  if (!existsSync(registryPath)) {
18
25
  throw new Error(`Registry not found for framework: ${framework}. Expected at ${registryPath}`);
19
26
  }
@@ -21,7 +28,7 @@ const registryCache = new Map();
21
28
  const registryContent = readFileSync(registryPath, 'utf-8');
22
29
  const registry = JSON.parse(registryContent);
23
30
  // Try to load and merge blocks registry
24
- const blocksRegistryPath = resolve(__dirname, `../registries/blocks-${framework}.json`);
31
+ const blocksRegistryPath = resolve(__dirname, `../registries/blocks-${registryFramework}.json`);
25
32
  if (existsSync(blocksRegistryPath)) {
26
33
  try {
27
34
  const blocksContent = readFileSync(blocksRegistryPath, 'utf-8');
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/framework-registry.ts"],"sourcesContent":["import { readFileSync, existsSync } from 'fs';\nimport { resolve, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport type { Framework } from './config-schema.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nexport interface FrameworkComponent {\n name: string;\n type: 'form' | 'layout' | 'navigation' | 'feedback' | 'data-display' | 'modal-overlay' | 'block' | 'other';\n description: string;\n files: string[];\n dependencies: string[];\n devDependencies: string[];\n peerDependencies?: string[];\n registryDependencies: string[];\n category: string;\n}\n\nexport interface FrameworkComponentGroup {\n name: string;\n components: string[];\n}\n\nexport interface FrameworkRegistry {\n name: string;\n components: Record<string, FrameworkComponent>;\n groups: Record<string, FrameworkComponentGroup>;\n}\n\n// Cache registries by framework\nconst registryCache: Map<Framework, FrameworkRegistry> = new Map();\n\n/**\n * Load framework-specific registry (includes both components and blocks)\n */\nexport function loadFrameworkRegistry(framework: Framework): FrameworkRegistry {\n // Check cache first\n if (registryCache.has(framework)) {\n return registryCache.get(framework)!;\n }\n\n const registryPath = resolve(__dirname, `../registries/registry-${framework}.json`);\n\n if (!existsSync(registryPath)) {\n throw new Error(\n `Registry not found for framework: ${framework}. Expected at ${registryPath}`\n );\n }\n\n try {\n const registryContent = readFileSync(registryPath, 'utf-8');\n const registry: FrameworkRegistry = JSON.parse(registryContent);\n\n // Try to load and merge blocks registry\n const blocksRegistryPath = resolve(__dirname, `../registries/blocks-${framework}.json`);\n if (existsSync(blocksRegistryPath)) {\n try {\n const blocksContent = readFileSync(blocksRegistryPath, 'utf-8');\n const blocksRegistry: FrameworkRegistry = JSON.parse(blocksContent);\n\n // Merge blocks into main registry\n registry.components = {\n ...registry.components,\n ...blocksRegistry.components,\n };\n\n registry.groups = {\n ...registry.groups,\n ...blocksRegistry.groups,\n };\n } catch (error) {\n // Blocks registry is optional, so we just log and continue\n console.warn(`Warning: Failed to load blocks registry for ${framework}`);\n }\n }\n\n // Cache the merged registry\n registryCache.set(framework, registry);\n\n return registry;\n } catch (error) {\n throw new Error(`Failed to load registry for ${framework}: ${error}`);\n }\n}\n\n/**\n * Get a component by name from framework registry\n */\nexport function getFrameworkComponent(\n framework: Framework,\n name: string\n): FrameworkComponent | undefined {\n const registry = loadFrameworkRegistry(framework);\n return registry.components[name];\n}\n\n/**\n * Get all components from framework registry\n */\nexport function getAllFrameworkComponents(\n framework: Framework\n): Record<string, FrameworkComponent> {\n const registry = loadFrameworkRegistry(framework);\n return registry.components;\n}\n\n/**\n * Get components by type from framework registry\n */\nexport function getFrameworkComponentsByType(\n framework: Framework,\n type: FrameworkComponent['type']\n): FrameworkComponent[] {\n const registry = loadFrameworkRegistry(framework);\n return Object.values(registry.components).filter((c) => c.type === type);\n}\n\n/**\n * Get components by group name from framework registry\n */\nexport function getFrameworkComponentsByGroup(\n framework: Framework,\n groupName: string\n): FrameworkComponent[] {\n const registry = loadFrameworkRegistry(framework);\n const group = registry.groups[groupName];\n\n if (!group) {\n return [];\n }\n\n return group.components\n .map((name) => registry.components[name])\n .filter(Boolean);\n}\n\n/**\n * Get all component groups from framework registry\n */\nexport function getAllFrameworkGroups(\n framework: Framework\n): Record<string, FrameworkComponentGroup> {\n const registry = loadFrameworkRegistry(framework);\n return registry.groups;\n}\n\n/**\n * Check if a component exists in framework registry\n */\nexport function frameworkComponentExists(\n framework: Framework,\n name: string\n): boolean {\n const registry = loadFrameworkRegistry(framework);\n return !!registry.components[name];\n}\n\n/**\n * Get component dependencies (including registry dependencies)\n */\nexport function getFrameworkComponentDependencies(\n framework: Framework,\n name: string\n): {\n dependencies: string[];\n devDependencies: string[];\n registryDependencies: string[];\n} {\n const component = getFrameworkComponent(framework, name);\n\n if (!component) {\n return {\n dependencies: [],\n devDependencies: [],\n registryDependencies: [],\n };\n }\n\n // Merge peerDependencies into dependencies for installation\n const allDependencies = [\n ...(component.dependencies || []),\n ...(component.peerDependencies || []),\n ];\n\n return {\n dependencies: allDependencies,\n devDependencies: component.devDependencies || [],\n registryDependencies: component.registryDependencies || [],\n };\n}\n\n/**\n * Resolve component name with aliases (case-insensitive match)\n */\nexport function resolveFrameworkComponentName(\n framework: Framework,\n input: string\n): string | null {\n const registry = loadFrameworkRegistry(framework);\n\n // Check exact match\n if (registry.components[input]) {\n return input;\n }\n\n // Check group match\n if (registry.groups[input]) {\n return input;\n }\n\n // Check case-insensitive match\n const lowerInput = input.toLowerCase();\n for (const name of Object.keys(registry.components)) {\n if (name.toLowerCase() === lowerInput) {\n return name;\n }\n }\n\n return null;\n}\n\n/**\n * Clear registry cache (useful for testing)\n */\nexport function clearRegistryCache(): void {\n registryCache.clear();\n}\n"],"names":["readFileSync","existsSync","resolve","dirname","fileURLToPath","__filename","url","__dirname","registryCache","Map","loadFrameworkRegistry","framework","has","get","registryPath","Error","registryContent","registry","JSON","parse","blocksRegistryPath","blocksContent","blocksRegistry","components","groups","error","console","warn","set","getFrameworkComponent","name","getAllFrameworkComponents","getFrameworkComponentsByType","type","Object","values","filter","c","getFrameworkComponentsByGroup","groupName","group","map","Boolean","getAllFrameworkGroups","frameworkComponentExists","getFrameworkComponentDependencies","component","dependencies","devDependencies","registryDependencies","allDependencies","peerDependencies","resolveFrameworkComponentName","input","lowerInput","toLowerCase","keys","clearRegistryCache","clear"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/utils/framework-registry.ts"],"sourcesContent":["import { readFileSync, existsSync } from 'fs';\nimport { resolve, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport type { Framework } from './config-schema.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nexport interface FrameworkComponent {\n name: string;\n type: 'form' | 'layout' | 'navigation' | 'feedback' | 'data-display' | 'modal-overlay' | 'block' | 'other';\n description: string;\n files: string[];\n dependencies: string[];\n devDependencies: string[];\n peerDependencies?: string[];\n registryDependencies: string[];\n category: string;\n}\n\nexport interface FrameworkComponentGroup {\n name: string;\n components: string[];\n}\n\nexport interface FrameworkRegistry {\n name: string;\n components: Record<string, FrameworkComponent>;\n groups: Record<string, FrameworkComponentGroup>;\n}\n\n// Cache registries by framework\nconst registryCache: Map<Framework, FrameworkRegistry> = new Map();\n\n/**\n * Load framework-specific registry (includes both components and blocks)\n */\nexport function loadFrameworkRegistry(framework: Framework): FrameworkRegistry {\n // Check cache first\n if (registryCache.has(framework)) {\n return registryCache.get(framework)!;\n }\n\n // Map Next.js to React registry and Nuxt.js to Vue registry\n let registryFramework = framework;\n if (framework === 'nextjs') {\n registryFramework = 'react';\n } else if (framework === 'nuxtjs') {\n registryFramework = 'vue';\n }\n\n const registryPath = resolve(__dirname, `../registries/registry-${registryFramework}.json`);\n\n if (!existsSync(registryPath)) {\n throw new Error(\n `Registry not found for framework: ${framework}. Expected at ${registryPath}`\n );\n }\n\n try {\n const registryContent = readFileSync(registryPath, 'utf-8');\n const registry: FrameworkRegistry = JSON.parse(registryContent);\n\n // Try to load and merge blocks registry\n const blocksRegistryPath = resolve(__dirname, `../registries/blocks-${registryFramework}.json`);\n if (existsSync(blocksRegistryPath)) {\n try {\n const blocksContent = readFileSync(blocksRegistryPath, 'utf-8');\n const blocksRegistry: FrameworkRegistry = JSON.parse(blocksContent);\n\n // Merge blocks into main registry\n registry.components = {\n ...registry.components,\n ...blocksRegistry.components,\n };\n\n registry.groups = {\n ...registry.groups,\n ...blocksRegistry.groups,\n };\n } catch (error) {\n // Blocks registry is optional, so we just log and continue\n console.warn(`Warning: Failed to load blocks registry for ${framework}`);\n }\n }\n\n // Cache the merged registry\n registryCache.set(framework, registry);\n\n return registry;\n } catch (error) {\n throw new Error(`Failed to load registry for ${framework}: ${error}`);\n }\n}\n\n/**\n * Get a component by name from framework registry\n */\nexport function getFrameworkComponent(\n framework: Framework,\n name: string\n): FrameworkComponent | undefined {\n const registry = loadFrameworkRegistry(framework);\n return registry.components[name];\n}\n\n/**\n * Get all components from framework registry\n */\nexport function getAllFrameworkComponents(\n framework: Framework\n): Record<string, FrameworkComponent> {\n const registry = loadFrameworkRegistry(framework);\n return registry.components;\n}\n\n/**\n * Get components by type from framework registry\n */\nexport function getFrameworkComponentsByType(\n framework: Framework,\n type: FrameworkComponent['type']\n): FrameworkComponent[] {\n const registry = loadFrameworkRegistry(framework);\n return Object.values(registry.components).filter((c) => c.type === type);\n}\n\n/**\n * Get components by group name from framework registry\n */\nexport function getFrameworkComponentsByGroup(\n framework: Framework,\n groupName: string\n): FrameworkComponent[] {\n const registry = loadFrameworkRegistry(framework);\n const group = registry.groups[groupName];\n\n if (!group) {\n return [];\n }\n\n return group.components\n .map((name) => registry.components[name])\n .filter(Boolean);\n}\n\n/**\n * Get all component groups from framework registry\n */\nexport function getAllFrameworkGroups(\n framework: Framework\n): Record<string, FrameworkComponentGroup> {\n const registry = loadFrameworkRegistry(framework);\n return registry.groups;\n}\n\n/**\n * Check if a component exists in framework registry\n */\nexport function frameworkComponentExists(\n framework: Framework,\n name: string\n): boolean {\n const registry = loadFrameworkRegistry(framework);\n return !!registry.components[name];\n}\n\n/**\n * Get component dependencies (including registry dependencies)\n */\nexport function getFrameworkComponentDependencies(\n framework: Framework,\n name: string\n): {\n dependencies: string[];\n devDependencies: string[];\n registryDependencies: string[];\n} {\n const component = getFrameworkComponent(framework, name);\n\n if (!component) {\n return {\n dependencies: [],\n devDependencies: [],\n registryDependencies: [],\n };\n }\n\n // Merge peerDependencies into dependencies for installation\n const allDependencies = [\n ...(component.dependencies || []),\n ...(component.peerDependencies || []),\n ];\n\n return {\n dependencies: allDependencies,\n devDependencies: component.devDependencies || [],\n registryDependencies: component.registryDependencies || [],\n };\n}\n\n/**\n * Resolve component name with aliases (case-insensitive match)\n */\nexport function resolveFrameworkComponentName(\n framework: Framework,\n input: string\n): string | null {\n const registry = loadFrameworkRegistry(framework);\n\n // Check exact match\n if (registry.components[input]) {\n return input;\n }\n\n // Check group match\n if (registry.groups[input]) {\n return input;\n }\n\n // Check case-insensitive match\n const lowerInput = input.toLowerCase();\n for (const name of Object.keys(registry.components)) {\n if (name.toLowerCase() === lowerInput) {\n return name;\n }\n }\n\n return null;\n}\n\n/**\n * Clear registry cache (useful for testing)\n */\nexport function clearRegistryCache(): void {\n registryCache.clear();\n}\n"],"names":["readFileSync","existsSync","resolve","dirname","fileURLToPath","__filename","url","__dirname","registryCache","Map","loadFrameworkRegistry","framework","has","get","registryFramework","registryPath","Error","registryContent","registry","JSON","parse","blocksRegistryPath","blocksContent","blocksRegistry","components","groups","error","console","warn","set","getFrameworkComponent","name","getAllFrameworkComponents","getFrameworkComponentsByType","type","Object","values","filter","c","getFrameworkComponentsByGroup","groupName","group","map","Boolean","getAllFrameworkGroups","frameworkComponentExists","getFrameworkComponentDependencies","component","dependencies","devDependencies","registryDependencies","allDependencies","peerDependencies","resolveFrameworkComponentName","input","lowerInput","toLowerCase","keys","clearRegistryCache","clear"],"mappings":"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"}
@@ -63,6 +63,32 @@ import { join } from 'path';
63
63
  try {
64
64
  const packageJson = require(join(cwd, 'package.json'));
65
65
  const deps = _extends({}, packageJson.dependencies, packageJson.devDependencies);
66
+ // Check for Next.js (must be before React check)
67
+ if (deps['next']) {
68
+ evidence.push('Found Next.js in dependencies');
69
+ if (existsSync(join(cwd, 'next.config.js')) || existsSync(join(cwd, 'next.config.ts'))) {
70
+ evidence.push('Found next.config (Next.js config)');
71
+ }
72
+ return {
73
+ platform: 'nextjs',
74
+ confidence: 'high',
75
+ evidence,
76
+ framework: 'nextjs'
77
+ };
78
+ }
79
+ // Check for Nuxt.js (must be before Vue check)
80
+ if (deps['nuxt'] || deps['nuxt3']) {
81
+ evidence.push('Found Nuxt.js in dependencies');
82
+ if (existsSync(join(cwd, 'nuxt.config.ts')) || existsSync(join(cwd, 'nuxt.config.js'))) {
83
+ evidence.push('Found nuxt.config (Nuxt.js config)');
84
+ }
85
+ return {
86
+ platform: 'nuxtjs',
87
+ confidence: 'high',
88
+ evidence,
89
+ framework: 'nuxtjs'
90
+ };
91
+ }
66
92
  // Check for Vue
67
93
  if (deps['vue'] || deps['@vue/cli']) {
68
94
  evidence.push('Found Vue in dependencies');
@@ -124,6 +150,8 @@ import { join } from 'path';
124
150
  'vue': 'Vue.js',
125
151
  'react': 'React',
126
152
  'angular': 'Angular',
153
+ 'nextjs': 'Next.js',
154
+ 'nuxtjs': 'Nuxt.js',
127
155
  'unknown': 'Unknown'
128
156
  };
129
157
  return names[platform];
@@ -136,7 +164,7 @@ import { join } from 'path';
136
164
  /**
137
165
  * Check if platform is web
138
166
  */ export function isWebPlatform(platform) {
139
- return platform === 'vue' || platform === 'react' || platform === 'angular';
167
+ return platform === 'vue' || platform === 'react' || platform === 'angular' || platform === 'nextjs' || platform === 'nuxtjs';
140
168
  }
141
169
  /**
142
170
  * Get registry file name for platform
@@ -147,7 +175,9 @@ import { join } from 'path';
147
175
  case 'flutter':
148
176
  return 'registry-flutter.json';
149
177
  case 'vue':
178
+ case 'nuxtjs':
150
179
  case 'react':
180
+ case 'nextjs':
151
181
  case 'angular':
152
182
  return 'registry.json'; // Web platforms use same registry
153
183
  default:
@@ -163,8 +193,10 @@ import { join } from 'path';
163
193
  case 'flutter':
164
194
  return 'packages/flutter/lib/components';
165
195
  case 'vue':
196
+ case 'nuxtjs':
166
197
  return 'packages/vue/src/components';
167
198
  case 'react':
199
+ case 'nextjs':
168
200
  return 'packages/react/src/components';
169
201
  case 'angular':
170
202
  return 'packages/angular/src/components';
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/platform-detector.ts"],"sourcesContent":["import { existsSync } from 'fs';\nimport { join } from 'path';\n\n/**\n * Supported platforms for Galaxy UI CLI\n */\nexport type Platform = 'react-native' | 'flutter' | 'vue' | 'react' | 'angular' | 'unknown';\n\n/**\n * Platform detection result with confidence level\n */\nexport interface PlatformDetectionResult {\n\tplatform: Platform;\n\tconfidence: 'high' | 'medium' | 'low';\n\tevidence: string[];\n\tframework?: string; // For web platforms: vue, react, angular\n}\n\n/**\n * Detect project platform based on file structure and config files\n *\n * Detection priority:\n * 1. Mobile platforms (React Native, Flutter) - highest priority\n * 2. Web frameworks (Vue, React, Angular)\n * 3. Unknown\n */\nexport function detectPlatform(cwd: string): PlatformDetectionResult {\n\tconst evidence: string[] = [];\n\n\t// Check for Flutter (highest priority for mobile)\n\tif (existsSync(join(cwd, 'pubspec.yaml'))) {\n\t\tevidence.push('Found pubspec.yaml (Flutter project file)');\n\n\t\t// Additional Flutter indicators\n\t\tif (existsSync(join(cwd, 'lib'))) {\n\t\t\tevidence.push('Found lib/ directory (Flutter source directory)');\n\t\t}\n\t\tif (existsSync(join(cwd, 'android')) && existsSync(join(cwd, 'ios'))) {\n\t\t\tevidence.push('Found android/ and ios/ directories (Flutter mobile platforms)');\n\t\t}\n\n\t\treturn {\n\t\t\tplatform: 'flutter',\n\t\t\tconfidence: 'high',\n\t\t\tevidence,\n\t\t};\n\t}\n\n\t// Check for React Native\n\tconst hasPackageJson = existsSync(join(cwd, 'package.json'));\n\tconst hasIosDir = existsSync(join(cwd, 'ios'));\n\tconst hasAndroidDir = existsSync(join(cwd, 'android'));\n\tconst hasAppJson = existsSync(join(cwd, 'app.json'));\n\n\tif (hasPackageJson && (hasIosDir || hasAndroidDir)) {\n\t\tevidence.push('Found package.json with mobile platform directories');\n\n\t\tif (hasIosDir) evidence.push('Found ios/ directory');\n\t\tif (hasAndroidDir) evidence.push('Found android/ directory');\n\t\tif (hasAppJson) evidence.push('Found app.json (React Native config)');\n\n\t\t// Check package.json for react-native dependency\n\t\ttry {\n\t\t\tconst packageJson = require(join(cwd, 'package.json'));\n\t\t\tif (packageJson.dependencies?.['react-native']) {\n\t\t\t\tevidence.push('Found react-native in dependencies');\n\t\t\t\treturn {\n\t\t\t\t\tplatform: 'react-native',\n\t\t\t\t\tconfidence: 'high',\n\t\t\t\t\tevidence,\n\t\t\t\t};\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// Ignore JSON parse errors\n\t\t}\n\n\t\t// If has mobile dirs but no react-native dep, still consider it RN with medium confidence\n\t\treturn {\n\t\t\tplatform: 'react-native',\n\t\t\tconfidence: 'medium',\n\t\t\tevidence,\n\t\t};\n\t}\n\n\t// Check for Web frameworks (only if not mobile)\n\tif (hasPackageJson) {\n\t\ttry {\n\t\t\tconst packageJson = require(join(cwd, 'package.json'));\n\t\t\tconst deps = { ...packageJson.dependencies, ...packageJson.devDependencies };\n\n\t\t\t// Check for Vue\n\t\t\tif (deps['vue'] || deps['@vue/cli']) {\n\t\t\t\tevidence.push('Found Vue in dependencies');\n\t\t\t\tif (existsSync(join(cwd, 'vite.config.ts')) || existsSync(join(cwd, 'vite.config.js'))) {\n\t\t\t\t\tevidence.push('Found vite.config (Vue + Vite)');\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tplatform: 'vue',\n\t\t\t\t\tconfidence: 'high',\n\t\t\t\t\tevidence,\n\t\t\t\t\tframework: 'vue',\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Check for Angular\n\t\t\tif (deps['@angular/core']) {\n\t\t\t\tevidence.push('Found @angular/core in dependencies');\n\t\t\t\tif (existsSync(join(cwd, 'angular.json'))) {\n\t\t\t\t\tevidence.push('Found angular.json (Angular config)');\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tplatform: 'angular',\n\t\t\t\t\tconfidence: 'high',\n\t\t\t\t\tevidence,\n\t\t\t\t\tframework: 'angular',\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Check for React (web)\n\t\t\tif (deps['react'] && !hasIosDir && !hasAndroidDir) {\n\t\t\t\tevidence.push('Found React in dependencies (web project)');\n\t\t\t\tif (existsSync(join(cwd, 'vite.config.ts')) || existsSync(join(cwd, 'vite.config.js'))) {\n\t\t\t\t\tevidence.push('Found vite.config (React + Vite)');\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tplatform: 'react',\n\t\t\t\t\tconfidence: 'high',\n\t\t\t\t\tevidence,\n\t\t\t\t\tframework: 'react',\n\t\t\t\t};\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// Ignore errors\n\t\t}\n\t}\n\n\t// Unknown platform\n\treturn {\n\t\tplatform: 'unknown',\n\t\tconfidence: 'low',\n\t\tevidence: ['No recognized project structure found'],\n\t};\n}\n\n/**\n * Get human-readable platform name\n */\nexport function getPlatformDisplayName(platform: Platform): string {\n\tconst names: Record<Platform, string> = {\n\t\t'react-native': 'React Native',\n\t\t'flutter': 'Flutter',\n\t\t'vue': 'Vue.js',\n\t\t'react': 'React',\n\t\t'angular': 'Angular',\n\t\t'unknown': 'Unknown',\n\t};\n\treturn names[platform];\n}\n\n/**\n * Check if platform is mobile\n */\nexport function isMobilePlatform(platform: Platform): boolean {\n\treturn platform === 'react-native' || platform === 'flutter';\n}\n\n/**\n * Check if platform is web\n */\nexport function isWebPlatform(platform: Platform): boolean {\n\treturn platform === 'vue' || platform === 'react' || platform === 'angular';\n}\n\n/**\n * Get registry file name for platform\n */\nexport function getRegistryFileName(platform: Platform): string {\n\tswitch (platform) {\n\t\tcase 'react-native':\n\t\t\treturn 'registry-react-native.json';\n\t\tcase 'flutter':\n\t\t\treturn 'registry-flutter.json';\n\t\tcase 'vue':\n\t\tcase 'react':\n\t\tcase 'angular':\n\t\t\treturn 'registry.json'; // Web platforms use same registry\n\t\tdefault:\n\t\t\treturn 'registry.json';\n\t}\n}\n\n/**\n * Get component source directory for platform\n */\nexport function getComponentSourceDir(platform: Platform): string {\n\tswitch (platform) {\n\t\tcase 'react-native':\n\t\t\treturn 'packages/react-native/src/components';\n\t\tcase 'flutter':\n\t\t\treturn 'packages/flutter/lib/components';\n\t\tcase 'vue':\n\t\t\treturn 'packages/vue/src/components';\n\t\tcase 'react':\n\t\t\treturn 'packages/react/src/components';\n\t\tcase 'angular':\n\t\t\treturn 'packages/angular/src/components';\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown platform: ${platform}`);\n\t}\n}\n"],"names":["existsSync","join","detectPlatform","cwd","evidence","push","platform","confidence","hasPackageJson","hasIosDir","hasAndroidDir","hasAppJson","packageJson","require","dependencies","error","deps","devDependencies","framework","getPlatformDisplayName","names","isMobilePlatform","isWebPlatform","getRegistryFileName","getComponentSourceDir","Error"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/utils/platform-detector.ts"],"sourcesContent":["import { existsSync } from 'fs';\nimport { join } from 'path';\n\n/**\n * Supported platforms for Galaxy UI CLI\n */\nexport type Platform = 'react-native' | 'flutter' | 'vue' | 'react' | 'angular' | 'nextjs' | 'nuxtjs' | 'unknown';\n\n/**\n * Platform detection result with confidence level\n */\nexport interface PlatformDetectionResult {\n\tplatform: Platform;\n\tconfidence: 'high' | 'medium' | 'low';\n\tevidence: string[];\n\tframework?: string; // For web platforms: vue, react, angular\n}\n\n/**\n * Detect project platform based on file structure and config files\n *\n * Detection priority:\n * 1. Mobile platforms (React Native, Flutter) - highest priority\n * 2. Web frameworks (Vue, React, Angular)\n * 3. Unknown\n */\nexport function detectPlatform(cwd: string): PlatformDetectionResult {\n\tconst evidence: string[] = [];\n\n\t// Check for Flutter (highest priority for mobile)\n\tif (existsSync(join(cwd, 'pubspec.yaml'))) {\n\t\tevidence.push('Found pubspec.yaml (Flutter project file)');\n\n\t\t// Additional Flutter indicators\n\t\tif (existsSync(join(cwd, 'lib'))) {\n\t\t\tevidence.push('Found lib/ directory (Flutter source directory)');\n\t\t}\n\t\tif (existsSync(join(cwd, 'android')) && existsSync(join(cwd, 'ios'))) {\n\t\t\tevidence.push('Found android/ and ios/ directories (Flutter mobile platforms)');\n\t\t}\n\n\t\treturn {\n\t\t\tplatform: 'flutter',\n\t\t\tconfidence: 'high',\n\t\t\tevidence,\n\t\t};\n\t}\n\n\t// Check for React Native\n\tconst hasPackageJson = existsSync(join(cwd, 'package.json'));\n\tconst hasIosDir = existsSync(join(cwd, 'ios'));\n\tconst hasAndroidDir = existsSync(join(cwd, 'android'));\n\tconst hasAppJson = existsSync(join(cwd, 'app.json'));\n\n\tif (hasPackageJson && (hasIosDir || hasAndroidDir)) {\n\t\tevidence.push('Found package.json with mobile platform directories');\n\n\t\tif (hasIosDir) evidence.push('Found ios/ directory');\n\t\tif (hasAndroidDir) evidence.push('Found android/ directory');\n\t\tif (hasAppJson) evidence.push('Found app.json (React Native config)');\n\n\t\t// Check package.json for react-native dependency\n\t\ttry {\n\t\t\tconst packageJson = require(join(cwd, 'package.json'));\n\t\t\tif (packageJson.dependencies?.['react-native']) {\n\t\t\t\tevidence.push('Found react-native in dependencies');\n\t\t\t\treturn {\n\t\t\t\t\tplatform: 'react-native',\n\t\t\t\t\tconfidence: 'high',\n\t\t\t\t\tevidence,\n\t\t\t\t};\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// Ignore JSON parse errors\n\t\t}\n\n\t\t// If has mobile dirs but no react-native dep, still consider it RN with medium confidence\n\t\treturn {\n\t\t\tplatform: 'react-native',\n\t\t\tconfidence: 'medium',\n\t\t\tevidence,\n\t\t};\n\t}\n\n\t// Check for Web frameworks (only if not mobile)\n\tif (hasPackageJson) {\n\t\ttry {\n\t\t\tconst packageJson = require(join(cwd, 'package.json'));\n\t\t\tconst deps = { ...packageJson.dependencies, ...packageJson.devDependencies };\n\n\t\t\t// Check for Next.js (must be before React check)\n\t\t\tif (deps['next']) {\n\t\t\t\tevidence.push('Found Next.js in dependencies');\n\t\t\t\tif (existsSync(join(cwd, 'next.config.js')) || existsSync(join(cwd, 'next.config.ts'))) {\n\t\t\t\t\tevidence.push('Found next.config (Next.js config)');\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tplatform: 'nextjs',\n\t\t\t\t\tconfidence: 'high',\n\t\t\t\t\tevidence,\n\t\t\t\t\tframework: 'nextjs',\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Check for Nuxt.js (must be before Vue check)\n\t\t\tif (deps['nuxt'] || deps['nuxt3']) {\n\t\t\t\tevidence.push('Found Nuxt.js in dependencies');\n\t\t\t\tif (existsSync(join(cwd, 'nuxt.config.ts')) || existsSync(join(cwd, 'nuxt.config.js'))) {\n\t\t\t\t\tevidence.push('Found nuxt.config (Nuxt.js config)');\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tplatform: 'nuxtjs',\n\t\t\t\t\tconfidence: 'high',\n\t\t\t\t\tevidence,\n\t\t\t\t\tframework: 'nuxtjs',\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Check for Vue\n\t\t\tif (deps['vue'] || deps['@vue/cli']) {\n\t\t\t\tevidence.push('Found Vue in dependencies');\n\t\t\t\tif (existsSync(join(cwd, 'vite.config.ts')) || existsSync(join(cwd, 'vite.config.js'))) {\n\t\t\t\t\tevidence.push('Found vite.config (Vue + Vite)');\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tplatform: 'vue',\n\t\t\t\t\tconfidence: 'high',\n\t\t\t\t\tevidence,\n\t\t\t\t\tframework: 'vue',\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Check for Angular\n\t\t\tif (deps['@angular/core']) {\n\t\t\t\tevidence.push('Found @angular/core in dependencies');\n\t\t\t\tif (existsSync(join(cwd, 'angular.json'))) {\n\t\t\t\t\tevidence.push('Found angular.json (Angular config)');\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tplatform: 'angular',\n\t\t\t\t\tconfidence: 'high',\n\t\t\t\t\tevidence,\n\t\t\t\t\tframework: 'angular',\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Check for React (web)\n\t\t\tif (deps['react'] && !hasIosDir && !hasAndroidDir) {\n\t\t\t\tevidence.push('Found React in dependencies (web project)');\n\t\t\t\tif (existsSync(join(cwd, 'vite.config.ts')) || existsSync(join(cwd, 'vite.config.js'))) {\n\t\t\t\t\tevidence.push('Found vite.config (React + Vite)');\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tplatform: 'react',\n\t\t\t\t\tconfidence: 'high',\n\t\t\t\t\tevidence,\n\t\t\t\t\tframework: 'react',\n\t\t\t\t};\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// Ignore errors\n\t\t}\n\t}\n\n\t// Unknown platform\n\treturn {\n\t\tplatform: 'unknown',\n\t\tconfidence: 'low',\n\t\tevidence: ['No recognized project structure found'],\n\t};\n}\n\n/**\n * Get human-readable platform name\n */\nexport function getPlatformDisplayName(platform: Platform): string {\n\tconst names: Record<Platform, string> = {\n\t\t'react-native': 'React Native',\n\t\t'flutter': 'Flutter',\n\t\t'vue': 'Vue.js',\n\t\t'react': 'React',\n\t\t'angular': 'Angular',\n\t\t'nextjs': 'Next.js',\n\t\t'nuxtjs': 'Nuxt.js',\n\t\t'unknown': 'Unknown',\n\t};\n\treturn names[platform];\n}\n\n/**\n * Check if platform is mobile\n */\nexport function isMobilePlatform(platform: Platform): boolean {\n\treturn platform === 'react-native' || platform === 'flutter';\n}\n\n/**\n * Check if platform is web\n */\nexport function isWebPlatform(platform: Platform): boolean {\n\treturn platform === 'vue' || platform === 'react' || platform === 'angular' || platform === 'nextjs' || platform === 'nuxtjs';\n}\n\n/**\n * Get registry file name for platform\n */\nexport function getRegistryFileName(platform: Platform): string {\n\tswitch (platform) {\n\t\tcase 'react-native':\n\t\t\treturn 'registry-react-native.json';\n\t\tcase 'flutter':\n\t\t\treturn 'registry-flutter.json';\n\t\tcase 'vue':\n\t\tcase 'nuxtjs':\n\t\tcase 'react':\n\t\tcase 'nextjs':\n\t\tcase 'angular':\n\t\t\treturn 'registry.json'; // Web platforms use same registry\n\t\tdefault:\n\t\t\treturn 'registry.json';\n\t}\n}\n\n/**\n * Get component source directory for platform\n */\nexport function getComponentSourceDir(platform: Platform): string {\n\tswitch (platform) {\n\t\tcase 'react-native':\n\t\t\treturn 'packages/react-native/src/components';\n\t\tcase 'flutter':\n\t\t\treturn 'packages/flutter/lib/components';\n\t\tcase 'vue':\n\t\tcase 'nuxtjs':\n\t\t\treturn 'packages/vue/src/components';\n\t\tcase 'react':\n\t\tcase 'nextjs':\n\t\t\treturn 'packages/react/src/components';\n\t\tcase 'angular':\n\t\t\treturn 'packages/angular/src/components';\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown platform: ${platform}`);\n\t}\n}\n"],"names":["existsSync","join","detectPlatform","cwd","evidence","push","platform","confidence","hasPackageJson","hasIosDir","hasAndroidDir","hasAppJson","packageJson","require","dependencies","error","deps","devDependencies","framework","getPlatformDisplayName","names","isMobilePlatform","isWebPlatform","getRegistryFileName","getComponentSourceDir","Error"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "galaxy-design",
3
- "version": "0.2.2",
4
- "description": "CLI tool for adding Galaxy UI components to your Vue, React, Angular, React Native, or Flutter project",
3
+ "version": "0.2.3",
4
+ "description": "CLI tool for adding Galaxy UI components to your Vue, React, Angular, Next.js, Nuxt.js, React Native, or Flutter project",
5
5
  "author": "BΓΉi Trọng HiαΊΏu (kevinbui) <kevinbui210191@gmail.com>",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -19,6 +19,10 @@
19
19
  "vue",
20
20
  "react",
21
21
  "angular",
22
+ "nextjs",
23
+ "next.js",
24
+ "nuxtjs",
25
+ "nuxt.js",
22
26
  "react-native",
23
27
  "flutter",
24
28
  "mobile",