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 +44 -4
- package/dist/commands/init.js +5 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/registries/registry-react.json +64 -4
- package/dist/utils/component-copier.js +34 -7
- package/dist/utils/component-copier.js.map +1 -1
- package/dist/utils/component-transformer.js +175 -0
- package/dist/utils/component-transformer.js.map +1 -0
- package/dist/utils/config-schema.js +43 -1
- package/dist/utils/config-schema.js.map +1 -1
- package/dist/utils/detect.js +8 -0
- package/dist/utils/detect.js.map +1 -1
- package/dist/utils/framework-registry.js +9 -2
- package/dist/utils/framework-registry.js.map +1 -1
- package/dist/utils/platform-detector.js +33 -1
- package/dist/utils/platform-detector.js.map +1 -1
- package/package.json +6 -2
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
|
|
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
|
|
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
|
|
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:
|
package/dist/commands/init.js
CHANGED
|
@@ -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 {
|
|
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
|
-
|
|
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
|
-
|
|
123
|
-
|
|
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
|
-
|
|
126
|
-
|
|
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 '
|
|
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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"}
|
package/dist/utils/detect.js
CHANGED
|
@@ -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
|
}
|
package/dist/utils/detect.js.map
CHANGED
|
@@ -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
|
-
|
|
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-${
|
|
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.
|
|
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",
|