@shohojdhara/atomix 0.3.14 → 0.3.15
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/CHANGELOG.md +20 -0
- package/build-tools/EXAMPLES.md +372 -0
- package/build-tools/README.md +242 -0
- package/build-tools/__tests__/error-handler.test.js +230 -0
- package/build-tools/__tests__/index.test.js +141 -0
- package/build-tools/__tests__/rollup-plugin.test.js +194 -0
- package/build-tools/__tests__/utils.test.js +161 -0
- package/build-tools/__tests__/vite-plugin.test.js +129 -0
- package/build-tools/__tests__/webpack-loader.test.js +190 -0
- package/build-tools/error-handler.js +308 -0
- package/build-tools/index.d.ts +43 -0
- package/build-tools/index.js +88 -0
- package/build-tools/package.json +67 -0
- package/build-tools/rollup-plugin.js +236 -0
- package/build-tools/types.d.ts +163 -0
- package/build-tools/utils.js +203 -0
- package/build-tools/vite-plugin.js +161 -0
- package/build-tools/webpack-loader.js +123 -0
- package/dist/atomix.css +203 -90
- package/dist/atomix.css.map +1 -1
- package/dist/atomix.min.css +3 -3
- package/dist/atomix.min.css.map +1 -1
- package/dist/build-tools/EXAMPLES.md +372 -0
- package/dist/build-tools/README.md +242 -0
- package/dist/build-tools/__tests__/error-handler.test.js +230 -0
- package/dist/build-tools/__tests__/index.test.js +141 -0
- package/dist/build-tools/__tests__/rollup-plugin.test.js +194 -0
- package/dist/build-tools/__tests__/utils.test.js +161 -0
- package/dist/build-tools/__tests__/vite-plugin.test.js +129 -0
- package/dist/build-tools/__tests__/webpack-loader.test.js +190 -0
- package/dist/build-tools/error-handler.js +308 -0
- package/dist/build-tools/index.d.ts +43 -0
- package/dist/build-tools/index.js +88 -0
- package/dist/build-tools/package.json +67 -0
- package/dist/build-tools/rollup-plugin.js +236 -0
- package/dist/build-tools/types.d.ts +163 -0
- package/dist/build-tools/utils.js +203 -0
- package/dist/build-tools/vite-plugin.js +161 -0
- package/dist/build-tools/webpack-loader.js +123 -0
- package/dist/charts.d.ts +1 -1
- package/dist/charts.js +86 -57
- package/dist/charts.js.map +1 -1
- package/dist/core.d.ts +1 -1
- package/dist/core.js +136 -112
- package/dist/core.js.map +1 -1
- package/dist/forms.d.ts +2 -5
- package/dist/forms.js +140 -128
- package/dist/forms.js.map +1 -1
- package/dist/heavy.d.ts +1 -1
- package/dist/heavy.js +136 -112
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +9 -61
- package/dist/index.esm.js +237 -286
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +250 -299
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/package.json +23 -8
- package/scripts/atomix-cli.js +170 -73
- package/scripts/cli/__tests__/README.md +81 -0
- package/scripts/cli/__tests__/basic.test.js +115 -0
- package/scripts/cli/__tests__/component-generator.test.js +332 -0
- package/scripts/cli/__tests__/integration.test.js +327 -0
- package/scripts/cli/__tests__/test-setup.js +133 -0
- package/scripts/cli/__tests__/token-manager.test.js +251 -0
- package/scripts/cli/__tests__/utils.test.js +161 -0
- package/scripts/cli/component-generator.js +253 -299
- package/scripts/cli/dependency-checker.js +355 -0
- package/scripts/cli/interactive-init.js +46 -5
- package/scripts/cli/template-manager.js +0 -2
- package/scripts/cli/templates/common-templates.js +636 -0
- package/scripts/cli/templates/composable-templates.js +148 -126
- package/scripts/cli/templates/index.js +23 -16
- package/scripts/cli/templates/project-templates.js +151 -23
- package/scripts/cli/templates/react-templates.js +280 -210
- package/scripts/cli/templates/scss-templates.js +90 -91
- package/scripts/cli/templates/testing-templates.js +206 -27
- package/scripts/cli/templates/testing-utils.js +278 -0
- package/scripts/cli/templates/types-templates.js +70 -56
- package/scripts/cli/theme-bridge.js +8 -2
- package/scripts/cli/token-manager.js +318 -206
- package/scripts/cli/utils.js +0 -1
- package/src/components/Accordion/Accordion.stories.tsx +369 -870
- package/src/components/AtomixGlass/AtomixGlass.tsx +80 -39
- package/src/components/AtomixGlass/AtomixGlassContainer.tsx +103 -81
- package/src/components/AtomixGlass/__snapshots__/AtomixGlass.test.tsx.snap +8 -7
- package/src/components/AtomixGlass/glass-utils.ts +2 -2
- package/src/components/AtomixGlass/shader-utils.ts +5 -0
- package/src/components/AtomixGlass/stories/Customization.stories.tsx +131 -0
- package/src/components/AtomixGlass/stories/Examples.stories.tsx +2957 -2853
- package/src/components/AtomixGlass/stories/Modes.stories.tsx +1 -1
- package/src/components/AtomixGlass/stories/Overview.stories.tsx +348 -0
- package/src/components/AtomixGlass/stories/Performance.stories.tsx +103 -0
- package/src/components/AtomixGlass/stories/Playground.stories.tsx +50 -35
- package/src/components/AtomixGlass/stories/{ShaderVariants.stories.tsx → Shaders.stories.tsx} +1 -1
- package/src/components/AtomixGlass/stories/shared-components.tsx +90 -190
- package/src/components/Avatar/Avatar.stories.tsx +213 -1
- package/src/components/Badge/Badge.stories.tsx +121 -362
- package/src/components/Block/Block.stories.tsx +21 -12
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +141 -23
- package/src/components/Button/Button.stories.tsx +463 -1126
- package/src/components/Button/Button.test.tsx +107 -0
- package/src/components/Button/Button.tsx +46 -50
- package/src/components/Button/ButtonGroup.stories.tsx +373 -217
- package/src/components/Callout/Callout.stories.tsx +289 -634
- package/src/components/Card/Card.stories.tsx +248 -68
- package/src/components/Chart/Chart.stories.tsx +150 -8
- package/src/components/ColorModeToggle/ColorModeToggle.stories.tsx +151 -69
- package/src/components/Countdown/Countdown.stories.tsx +115 -8
- package/src/components/DataTable/DataTable.stories.tsx +346 -146
- package/src/components/DatePicker/DatePicker.stories.tsx +325 -1066
- package/src/components/Dropdown/Dropdown.stories.tsx +153 -33
- package/src/components/EdgePanel/EdgePanel.stories.tsx +230 -21
- package/src/components/Footer/Footer.stories.tsx +392 -328
- package/src/components/Form/Checkbox.stories.tsx +140 -6
- package/src/components/Form/Checkbox.test.tsx +63 -0
- package/src/components/Form/Checkbox.tsx +87 -51
- package/src/components/Form/Form.stories.tsx +119 -20
- package/src/components/Form/FormGroup.stories.tsx +127 -4
- package/src/components/Form/Radio.stories.tsx +140 -5
- package/src/components/Form/Select.stories.tsx +140 -8
- package/src/components/Form/Textarea.stories.tsx +149 -6
- package/src/components/Hero/Hero.stories.tsx +333 -32
- package/src/components/List/List.stories.tsx +141 -3
- package/src/components/Modal/Modal.stories.tsx +181 -42
- package/src/components/Popover/Popover.stories.tsx +448 -98
- package/src/components/Progress/Progress.stories.tsx +167 -5
- package/src/components/River/River.stories.tsx +1 -1
- package/src/components/SectionIntro/SectionIntro.stories.tsx +240 -48
- package/src/components/Spinner/Spinner.stories.tsx +102 -8
- package/src/components/Steps/Steps.stories.tsx +172 -43
- package/src/components/Tabs/Tabs.stories.tsx +136 -10
- package/src/components/Testimonial/Testimonial.stories.tsx +120 -3
- package/src/components/Todo/Todo.stories.tsx +198 -9
- package/src/components/Toggle/Toggle.stories.tsx +126 -39
- package/src/components/Tooltip/Tooltip.stories.tsx +194 -104
- package/src/components/Upload/Upload.stories.tsx +113 -24
- package/src/lib/README.md +2 -2
- package/src/lib/__tests__/theme-tools.test.ts +193 -0
- package/src/lib/composables/index.ts +2 -2
- package/src/lib/composables/useAtomixGlass.ts +28 -56
- package/src/lib/composables/useChartExport.ts +2 -7
- package/src/lib/composables/useDataTable.ts +46 -29
- package/src/lib/constants/components.ts +9 -32
- package/src/lib/theme/devtools/CLI.ts +1 -1
- package/src/lib/types/components.ts +1 -1
- package/src/lib/utils/__tests__/csv.test.ts +45 -0
- package/src/lib/utils/csv.ts +17 -0
- package/src/lib/utils/dataTableExport.ts +1 -10
- package/src/styles/01-settings/_index.scss +2 -1
- package/src/styles/01-settings/_settings.accordion.scss +28 -7
- package/src/styles/01-settings/_settings.colors.scss +11 -11
- package/src/styles/01-settings/_settings.typography.scss +5 -5
- package/src/styles/02-tools/_tools.utility-api.scss +14 -0
- package/src/styles/06-components/_components.accordion.scss +56 -14
- package/src/styles/06-components/_components.checkbox.scss +23 -17
- package/src/styles/99-utilities/_index.scss +2 -0
- package/src/styles/99-utilities/_utilities.scss +3 -1
- package/src/styles/99-utilities/_utilities.text-gradient.scss +45 -0
- package/themes/dark-complementary/README.md +98 -0
- package/themes/dark-complementary/index.scss +158 -0
- package/themes/default-light/README.md +81 -0
- package/themes/default-light/index.scss +154 -0
- package/themes/high-contrast/README.md +105 -0
- package/themes/high-contrast/index.scss +172 -0
- package/themes/test-theme/README.md +38 -0
- package/themes/test-theme/index.scss +47 -0
- package/scripts/cli/templates-original-backup.js +0 -1655
- package/scripts/cli/templates_backup.js +0 -684
- package/src/components/AtomixGlass/stories/AtomixGlass.stories.tsx +0 -1438
- package/src/lib/composables/useButton.ts +0 -93
- package/src/lib/composables/useCheckbox.ts +0 -70
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dependency Checker
|
|
3
|
+
* Validates required dependencies before CLI execution
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { execSync } from 'child_process';
|
|
7
|
+
import { readFileSync, existsSync } from 'fs';
|
|
8
|
+
import { join } from 'path';
|
|
9
|
+
import chalk from 'chalk';
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Check if a command exists in PATH
|
|
14
|
+
* @param {string} command - Command to check
|
|
15
|
+
* @returns {boolean} Whether command exists
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Get package version from node_modules
|
|
20
|
+
* @param {string} packageName - Package name
|
|
21
|
+
* @returns {string|null} Version string or null
|
|
22
|
+
*/
|
|
23
|
+
function getPackageVersion(packageName) {
|
|
24
|
+
try {
|
|
25
|
+
const packageJsonPath = join(process.cwd(), 'node_modules', packageName, 'package.json');
|
|
26
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
|
27
|
+
return packageJson.version;
|
|
28
|
+
} catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Compare semantic versions
|
|
35
|
+
* @param {string} v1 - First version
|
|
36
|
+
* @param {string} v2 - Second version
|
|
37
|
+
* @returns {number} -1 if v1 < v2, 0 if equal, 1 if v1 > v2
|
|
38
|
+
*/
|
|
39
|
+
function compareVersions(v1, v2) {
|
|
40
|
+
const parts1 = v1.replace(/^v/, '').split('.').map(Number);
|
|
41
|
+
const parts2 = v2.replace(/^v/, '').split('.').map(Number);
|
|
42
|
+
|
|
43
|
+
for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
|
|
44
|
+
const part1 = parts1[i] || 0;
|
|
45
|
+
const part2 = parts2[i] || 0;
|
|
46
|
+
|
|
47
|
+
if (part1 > part2) return 1;
|
|
48
|
+
if (part1 < part2) return -1;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return 0;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Validate Node.js version
|
|
56
|
+
* @returns {Object} Validation result
|
|
57
|
+
*/
|
|
58
|
+
function validateNodeVersion() {
|
|
59
|
+
const version = process.version;
|
|
60
|
+
const minVersion = '18.0.0';
|
|
61
|
+
|
|
62
|
+
const isValid = compareVersions(version, minVersion) >= 0;
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
name: 'Node.js',
|
|
66
|
+
version,
|
|
67
|
+
required: `>= ${minVersion}`,
|
|
68
|
+
valid: isValid,
|
|
69
|
+
message: isValid
|
|
70
|
+
? chalk.green(`✓ Node.js ${version} meets minimum requirement`)
|
|
71
|
+
: chalk.red(`✗ Node.js ${version} is below minimum requirement (${minVersion})`)
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Validate npm version
|
|
77
|
+
* @returns {Object} Validation result
|
|
78
|
+
*/
|
|
79
|
+
function validateNpmVersion() {
|
|
80
|
+
try {
|
|
81
|
+
const version = execSync('npm --version', { encoding: 'utf8' }).trim();
|
|
82
|
+
const minVersion = '8.0.0';
|
|
83
|
+
|
|
84
|
+
const isValid = compareVersions(version, minVersion) >= 0;
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
name: 'npm',
|
|
88
|
+
version,
|
|
89
|
+
required: `>= ${minVersion}`,
|
|
90
|
+
valid: isValid,
|
|
91
|
+
message: isValid
|
|
92
|
+
? chalk.green(`✓ npm ${version} meets minimum requirement`)
|
|
93
|
+
: chalk.red(`✗ npm ${version} is below minimum requirement (${minVersion})`)
|
|
94
|
+
};
|
|
95
|
+
} catch (error) {
|
|
96
|
+
return {
|
|
97
|
+
name: 'npm',
|
|
98
|
+
version: 'unknown',
|
|
99
|
+
required: '>= 8.0.0',
|
|
100
|
+
valid: false,
|
|
101
|
+
message: chalk.red('✗ npm not found in PATH')
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Validate peer dependencies
|
|
108
|
+
* @returns {Array} Array of validation results
|
|
109
|
+
*/
|
|
110
|
+
/**
|
|
111
|
+
* Peer dependencies for Atomix CLI.
|
|
112
|
+
* @phosphor-icons/react: minimum 2.0.0 (icons used by components). Exact version not required.
|
|
113
|
+
*/
|
|
114
|
+
function validatePeerDependencies() {
|
|
115
|
+
const dependencies = [
|
|
116
|
+
{ name: 'react', minVersion: '18.0.0' },
|
|
117
|
+
{ name: 'react-dom', minVersion: '18.0.0' },
|
|
118
|
+
{ name: '@phosphor-icons/react', minVersion: '2.0.0' }
|
|
119
|
+
];
|
|
120
|
+
|
|
121
|
+
return dependencies.map(dep => {
|
|
122
|
+
const installedVersion = getPackageVersion(dep.name);
|
|
123
|
+
|
|
124
|
+
if (!installedVersion) {
|
|
125
|
+
return {
|
|
126
|
+
name: dep.name,
|
|
127
|
+
version: 'not installed',
|
|
128
|
+
required: dep.exactVersion ? `=${dep.exactVersion}` : `>= ${dep.minVersion}`,
|
|
129
|
+
valid: false,
|
|
130
|
+
message: chalk.red(`✗ ${dep.name} not installed`)
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
let isValid = true;
|
|
135
|
+
let requirement = '';
|
|
136
|
+
|
|
137
|
+
if (dep.exactVersion) {
|
|
138
|
+
isValid = installedVersion === dep.exactVersion;
|
|
139
|
+
requirement = `=${dep.exactVersion}`;
|
|
140
|
+
} else {
|
|
141
|
+
isValid = compareVersions(installedVersion, dep.minVersion) >= 0;
|
|
142
|
+
requirement = `>= ${dep.minVersion}`;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return {
|
|
146
|
+
name: dep.name,
|
|
147
|
+
version: installedVersion,
|
|
148
|
+
required: requirement,
|
|
149
|
+
valid: isValid,
|
|
150
|
+
message: isValid
|
|
151
|
+
? chalk.green(`✓ ${dep.name}@${installedVersion} satisfies requirement`)
|
|
152
|
+
: chalk.red(`✗ ${dep.name}@${installedVersion} does not meet requirement (${requirement})`)
|
|
153
|
+
};
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Validate development dependencies
|
|
159
|
+
* @returns {Array} Array of validation results
|
|
160
|
+
*/
|
|
161
|
+
function validateDevDependencies() {
|
|
162
|
+
const dependencies = [
|
|
163
|
+
{ name: '@testing-library/react', optional: true },
|
|
164
|
+
{ name: 'vitest', optional: true },
|
|
165
|
+
{ name: 'sass', optional: true },
|
|
166
|
+
{ name: 'typescript', optional: true }
|
|
167
|
+
];
|
|
168
|
+
|
|
169
|
+
return dependencies.map(dep => {
|
|
170
|
+
const installedVersion = getPackageVersion(dep.name);
|
|
171
|
+
|
|
172
|
+
if (!installedVersion) {
|
|
173
|
+
return {
|
|
174
|
+
name: dep.name,
|
|
175
|
+
version: 'not installed',
|
|
176
|
+
required: 'recommended',
|
|
177
|
+
valid: dep.optional,
|
|
178
|
+
message: dep.optional
|
|
179
|
+
? chalk.yellow(`⚠ ${dep.name} not installed (optional)`)
|
|
180
|
+
: chalk.red(`✗ ${dep.name} not installed (recommended)`)
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return {
|
|
185
|
+
name: dep.name,
|
|
186
|
+
version: installedVersion,
|
|
187
|
+
required: 'installed',
|
|
188
|
+
valid: true,
|
|
189
|
+
message: chalk.green(`✓ ${dep.name}@${installedVersion} installed`)
|
|
190
|
+
};
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Check project structure
|
|
196
|
+
* @returns {Array} Array of validation results
|
|
197
|
+
*/
|
|
198
|
+
export function validateProjectStructure() {
|
|
199
|
+
const recommendedDirs = [
|
|
200
|
+
{ path: 'src', description: 'Source directory', required: true },
|
|
201
|
+
{ path: 'src/components', description: 'Components directory', required: true },
|
|
202
|
+
{ path: 'src/styles', description: 'Styles directory', required: true },
|
|
203
|
+
{ path: 'src/lib/composables', description: 'Generated hooks directory', required: false },
|
|
204
|
+
{ path: 'src/lib/constants', description: 'Component constants directory', required: false },
|
|
205
|
+
{ path: 'src/lib/types', description: 'Type definitions directory', required: false },
|
|
206
|
+
{ path: 'src/styles/01-settings', description: 'Component settings directory', required: false },
|
|
207
|
+
{ path: 'src/styles/06-components', description: 'Component styles directory', required: false },
|
|
208
|
+
{ path: 'stories', description: 'Storybook stories directory', required: false },
|
|
209
|
+
{ path: 'tests', description: 'Test files directory', required: false }
|
|
210
|
+
];
|
|
211
|
+
|
|
212
|
+
const results = [];
|
|
213
|
+
|
|
214
|
+
recommendedDirs.forEach(dir => {
|
|
215
|
+
const fullPath = join(process.cwd(), dir.path);
|
|
216
|
+
const exists = existsSync(fullPath);
|
|
217
|
+
|
|
218
|
+
results.push({
|
|
219
|
+
name: dir.path,
|
|
220
|
+
status: exists ? 'exists' : (dir.required ? 'missing' : 'recommended'),
|
|
221
|
+
required: dir.required,
|
|
222
|
+
valid: exists || !dir.required,
|
|
223
|
+
message: exists
|
|
224
|
+
? chalk.green(`✓ ${dir.description} exists`)
|
|
225
|
+
: (dir.required
|
|
226
|
+
? chalk.red(`✗ ${dir.description} missing (required)`)
|
|
227
|
+
: chalk.yellow(`⚠ ${dir.description} missing (recommended)`))
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
return results;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Validate framework-specific configuration
|
|
236
|
+
* @returns {Array} Array of validation results
|
|
237
|
+
*/
|
|
238
|
+
export function validateFrameworkConfig() {
|
|
239
|
+
const configs = [
|
|
240
|
+
{
|
|
241
|
+
name: 'Next.js',
|
|
242
|
+
file: 'next.config.js',
|
|
243
|
+
description: 'Next.js configuration'
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
name: 'Vite',
|
|
247
|
+
file: 'vite.config.ts',
|
|
248
|
+
description: 'Vite configuration'
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
name: 'Vite (JS)',
|
|
252
|
+
file: 'vite.config.js',
|
|
253
|
+
description: 'Vite configuration'
|
|
254
|
+
}
|
|
255
|
+
];
|
|
256
|
+
|
|
257
|
+
const results = [];
|
|
258
|
+
let foundFramework = false;
|
|
259
|
+
|
|
260
|
+
for (const config of configs) {
|
|
261
|
+
if (existsSync(join(process.cwd(), config.file))) {
|
|
262
|
+
foundFramework = true;
|
|
263
|
+
results.push({
|
|
264
|
+
name: config.name,
|
|
265
|
+
status: 'found',
|
|
266
|
+
valid: true,
|
|
267
|
+
message: chalk.green(`✓ ${config.description} found (${config.file})`)
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
if (!foundFramework) {
|
|
273
|
+
results.push({
|
|
274
|
+
name: 'Framework',
|
|
275
|
+
status: 'not_found',
|
|
276
|
+
valid: true,
|
|
277
|
+
message: chalk.gray('• No common framework configuration detected (Next.js/Vite)')
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return results;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Perform all dependency checks
|
|
286
|
+
* @returns {Object} Complete validation results
|
|
287
|
+
*/
|
|
288
|
+
export async function checkDependencies() {
|
|
289
|
+
console.log(chalk.blue('🔍 Validating Atomix CLI dependencies...\n'));
|
|
290
|
+
|
|
291
|
+
const results = {
|
|
292
|
+
system: [
|
|
293
|
+
validateNodeVersion(),
|
|
294
|
+
validateNpmVersion()
|
|
295
|
+
],
|
|
296
|
+
peerDependencies: validatePeerDependencies(),
|
|
297
|
+
devDependencies: validateDevDependencies(),
|
|
298
|
+
projectStructure: validateProjectStructure()
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
// Display results
|
|
302
|
+
Object.entries(results).forEach(([category, checks]) => {
|
|
303
|
+
if (checks.length > 0) {
|
|
304
|
+
console.log(chalk.bold.underline(category.replace(/([A-Z])/g, ' $1').trim()));
|
|
305
|
+
checks.forEach(check => {
|
|
306
|
+
console.log(` ${check.message}`);
|
|
307
|
+
});
|
|
308
|
+
console.log('');
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
// Calculate overall status
|
|
313
|
+
const allChecks = [].concat(...Object.values(results));
|
|
314
|
+
const failedChecks = allChecks.filter(check => !check.valid);
|
|
315
|
+
const warningChecks = allChecks.filter(check => check.valid === null || !check.valid && check.required === 'recommended');
|
|
316
|
+
|
|
317
|
+
if (failedChecks.length === 0) {
|
|
318
|
+
console.log(chalk.green.bold('✅ All required dependencies are satisfied!'));
|
|
319
|
+
console.log(chalk.gray('You\'re ready to use the Atomix CLI.\n'));
|
|
320
|
+
return { success: true, warnings: warningChecks.length };
|
|
321
|
+
} else {
|
|
322
|
+
console.log(chalk.red.bold(`❌ ${failedChecks.length} dependency issues found:`));
|
|
323
|
+
failedChecks.forEach(check => {
|
|
324
|
+
console.log(chalk.red(` • ${check.name}: ${check.message.replace(/✗ /, '')}`));
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
console.log(chalk.yellow('\n💡 To fix these issues:'));
|
|
328
|
+
console.log(chalk.gray(' Run: npm install react@^18.0.0 react-dom@^18.0.0'));
|
|
329
|
+
console.log(chalk.gray(' See: docs/CLI_PEER_DEPENDENCIES.md\n'));
|
|
330
|
+
|
|
331
|
+
return { success: false, errors: failedChecks.length, warnings: warningChecks.length };
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Quick dependency check for CI/CD
|
|
337
|
+
* @returns {boolean} Whether all dependencies are valid
|
|
338
|
+
*/
|
|
339
|
+
export async function quickDependencyCheck() {
|
|
340
|
+
const nodeCheck = validateNodeVersion();
|
|
341
|
+
const npmCheck = validateNpmVersion();
|
|
342
|
+
const peerChecks = validatePeerDependencies();
|
|
343
|
+
|
|
344
|
+
return nodeCheck.valid && npmCheck.valid && peerChecks.every(check => check.valid);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
export default {
|
|
348
|
+
checkDependencies,
|
|
349
|
+
quickDependencyCheck,
|
|
350
|
+
validateNodeVersion,
|
|
351
|
+
validateNpmVersion,
|
|
352
|
+
validatePeerDependencies,
|
|
353
|
+
validateProjectStructure,
|
|
354
|
+
validateFrameworkConfig
|
|
355
|
+
};
|
|
@@ -8,8 +8,10 @@ import { readFile, writeFile, mkdir } from 'fs/promises';
|
|
|
8
8
|
import { join, dirname, basename } from 'path';
|
|
9
9
|
import { existsSync } from 'fs';
|
|
10
10
|
import boxen from 'boxen';
|
|
11
|
+
import ora from 'ora';
|
|
11
12
|
|
|
12
13
|
import { projectTemplates, configTemplates } from './templates.js';
|
|
14
|
+
import { commonTemplates } from './templates/common-templates.js';
|
|
13
15
|
|
|
14
16
|
/**
|
|
15
17
|
* Run the interactive init wizard
|
|
@@ -57,16 +59,17 @@ export async function runInitWizard() {
|
|
|
57
59
|
}
|
|
58
60
|
]);
|
|
59
61
|
|
|
60
|
-
let
|
|
62
|
+
let prebuiltThemeName = null;
|
|
61
63
|
if (themeChoice === 'prebuilt') {
|
|
62
64
|
const { theme } = await inquirer.prompt([
|
|
63
65
|
{
|
|
64
66
|
type: 'input',
|
|
65
67
|
name: 'theme',
|
|
66
68
|
message: 'Enter the name of the pre-built theme:',
|
|
69
|
+
default: 'default'
|
|
67
70
|
}
|
|
68
71
|
]);
|
|
69
|
-
|
|
72
|
+
prebuiltThemeName = (theme && String(theme).trim()) || 'default';
|
|
70
73
|
}
|
|
71
74
|
|
|
72
75
|
// Step 3: Features
|
|
@@ -160,10 +163,13 @@ export async function runInitWizard() {
|
|
|
160
163
|
});
|
|
161
164
|
|
|
162
165
|
// Merge scripts carefully
|
|
166
|
+
const themePath = themeChoice === 'prebuilt' && prebuiltThemeName
|
|
167
|
+
? `themes/${prebuiltThemeName}`
|
|
168
|
+
: 'themes/custom';
|
|
163
169
|
const newScripts = {
|
|
164
170
|
'dev': projectType === 'nextjs' ? 'next dev' : 'vite',
|
|
165
171
|
'build': projectType === 'nextjs' ? 'next build' : 'vite build',
|
|
166
|
-
'build:theme':
|
|
172
|
+
'build:theme': `atomix build-theme ${themePath}`,
|
|
167
173
|
'generate:component': 'atomix generate component',
|
|
168
174
|
'validate': 'atomix validate --tokens --theme'
|
|
169
175
|
};
|
|
@@ -206,6 +212,10 @@ export async function runInitWizard() {
|
|
|
206
212
|
}
|
|
207
213
|
|
|
208
214
|
// Write template files
|
|
215
|
+
const spinner = ora('Creating project files...').start();
|
|
216
|
+
let filesCreated = 0;
|
|
217
|
+
const totalFiles = Object.keys(template.files).length;
|
|
218
|
+
|
|
209
219
|
for (const [path, content] of Object.entries(template.files)) {
|
|
210
220
|
const filePath = join(process.cwd(), path);
|
|
211
221
|
const dir = dirname(filePath);
|
|
@@ -215,8 +225,27 @@ export async function runInitWizard() {
|
|
|
215
225
|
}
|
|
216
226
|
|
|
217
227
|
await writeFile(filePath, content, 'utf8');
|
|
218
|
-
|
|
228
|
+
filesCreated++;
|
|
229
|
+
spinner.text = `Creating project files... (${filesCreated}/${totalFiles})`;
|
|
219
230
|
}
|
|
231
|
+
|
|
232
|
+
spinner.succeed(chalk.green(`✓ Created ${filesCreated} files`));
|
|
233
|
+
|
|
234
|
+
// Generate README
|
|
235
|
+
const readmeSpinner = ora('Generating README...').start();
|
|
236
|
+
const projectName = basename(process.cwd());
|
|
237
|
+
const readmeTemplate = projectType === 'react'
|
|
238
|
+
? commonTemplates.readme.react(projectName)
|
|
239
|
+
: projectType === 'nextjs'
|
|
240
|
+
? commonTemplates.readme.nextjs(projectName)
|
|
241
|
+
: commonTemplates.readme.vanilla(projectName);
|
|
242
|
+
|
|
243
|
+
await writeFile(
|
|
244
|
+
join(process.cwd(), 'README.md'),
|
|
245
|
+
readmeTemplate,
|
|
246
|
+
'utf8'
|
|
247
|
+
);
|
|
248
|
+
readmeSpinner.succeed(chalk.green('✓ Generated README.md'));
|
|
220
249
|
}
|
|
221
250
|
|
|
222
251
|
// Create configuration file
|
|
@@ -224,12 +253,24 @@ export async function runInitWizard() {
|
|
|
224
253
|
const configTemplate = configType === 'json'
|
|
225
254
|
? configTemplates.basic
|
|
226
255
|
: configTemplates.advanced;
|
|
256
|
+
const themePathForConfig = themeChoice === 'prebuilt' && prebuiltThemeName
|
|
257
|
+
? `themes/${prebuiltThemeName}`
|
|
258
|
+
: 'themes/custom';
|
|
227
259
|
|
|
228
260
|
for (const [filename, content] of Object.entries(configTemplate)) {
|
|
229
|
-
|
|
261
|
+
let configContent = typeof content === 'object'
|
|
230
262
|
? JSON.stringify(content, null, 2)
|
|
231
263
|
: content;
|
|
232
264
|
|
|
265
|
+
if (themeChoice === 'prebuilt' && prebuiltThemeName) {
|
|
266
|
+
if (typeof content === 'object' && content.theme) {
|
|
267
|
+
const merged = { ...content, theme: { ...content.theme, path: themePathForConfig } };
|
|
268
|
+
configContent = JSON.stringify(merged, null, 2);
|
|
269
|
+
} else if (typeof content === 'string') {
|
|
270
|
+
configContent = content.replace(/path:\s*['"]themes\/custom['"]/g, `path: '${themePathForConfig}'`);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
233
274
|
await writeFile(
|
|
234
275
|
join(process.cwd(), filename),
|
|
235
276
|
configContent,
|