@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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shohojdhara/atomix",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.15",
|
|
4
4
|
"description": "Atomix Design System - A modern component library for web applications",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": [
|
|
@@ -111,6 +111,12 @@
|
|
|
111
111
|
"import": "./dist/heavy.js",
|
|
112
112
|
"default": "./dist/heavy.js"
|
|
113
113
|
},
|
|
114
|
+
"./build-tools": {
|
|
115
|
+
"types": "./build-tools/index.d.ts",
|
|
116
|
+
"import": "./build-tools/index.js",
|
|
117
|
+
"require": "./build-tools/index.js",
|
|
118
|
+
"default": "./build-tools/index.js"
|
|
119
|
+
},
|
|
114
120
|
"./package.json": "./package.json"
|
|
115
121
|
},
|
|
116
122
|
"dependencies": {
|
|
@@ -128,6 +134,8 @@
|
|
|
128
134
|
},
|
|
129
135
|
"devDependencies": {
|
|
130
136
|
"@arethetypeswrong/cli": "^0.15.0",
|
|
137
|
+
"jest-axe": "^8.0.0",
|
|
138
|
+
"rollup-plugin-preserve-shebangs": "^0.2.0",
|
|
131
139
|
"@babel/core": "^7.23.0",
|
|
132
140
|
"@babel/plugin-transform-runtime": "^7.23.0",
|
|
133
141
|
"@babel/preset-env": "^7.23.0",
|
|
@@ -135,14 +143,13 @@
|
|
|
135
143
|
"@babel/preset-typescript": "^7.23.0",
|
|
136
144
|
"@babel/runtime-corejs3": "^7.23.0",
|
|
137
145
|
"@changesets/cli": "^2.26.0",
|
|
138
|
-
"browserslist": "^4.23.0",
|
|
139
146
|
"@phosphor-icons/react": "2.1.10",
|
|
140
147
|
"@rollup/plugin-babel": "^6.0.0",
|
|
141
148
|
"@rollup/plugin-commonjs": "^25.0.0",
|
|
142
149
|
"@rollup/plugin-node-resolve": "^15.0.0",
|
|
143
150
|
"@rollup/plugin-terser": "^0.4.0",
|
|
144
151
|
"@rollup/plugin-typescript": "^11.0.0",
|
|
145
|
-
"
|
|
152
|
+
"@storybook/addon-a11y": "^8.6.14",
|
|
146
153
|
"@storybook/addon-essentials": "^8.6.14",
|
|
147
154
|
"@storybook/addon-interactions": "^8.6.14",
|
|
148
155
|
"@storybook/addon-links": "^8.6.14",
|
|
@@ -170,6 +177,8 @@
|
|
|
170
177
|
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
|
171
178
|
"@typescript-eslint/parser": "^6.0.0",
|
|
172
179
|
"@vitejs/plugin-react": "^4.0.0",
|
|
180
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
181
|
+
"browserslist": "^4.23.0",
|
|
173
182
|
"concurrently": "^8.0.0",
|
|
174
183
|
"eslint": "^8.0.0",
|
|
175
184
|
"eslint-plugin-import": "^2.29.0",
|
|
@@ -189,6 +198,7 @@
|
|
|
189
198
|
"rollup-plugin-dts": "^6.0.0",
|
|
190
199
|
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
191
200
|
"rollup-plugin-postcss": "^4.0.0",
|
|
201
|
+
"rollup-plugin-visualizer": "^5.12.0",
|
|
192
202
|
"storybook": "^8.6.14",
|
|
193
203
|
"storybook-theme-switch-addon": "^1.0.2",
|
|
194
204
|
"ts-node": "^10.9.0",
|
|
@@ -200,19 +210,20 @@
|
|
|
200
210
|
},
|
|
201
211
|
"scripts": {
|
|
202
212
|
"dev": "storybook dev -p 6006",
|
|
203
|
-
"build": "npm run prebuild && npm run build:parallel",
|
|
213
|
+
"build": "npm run prebuild && npm run build:parallel && npm run postbuild",
|
|
204
214
|
"build:sequential": "rollup -c",
|
|
205
215
|
"build:js": "rollup -c rollup.config.build.js",
|
|
206
216
|
"build:types": "rollup -c rollup.config.types.js",
|
|
207
217
|
"build:styles": "rollup -c rollup.config.styles.js",
|
|
208
218
|
"build:themes": "rollup -c rollup/config/themes.js",
|
|
209
219
|
"build:parallel": "concurrently \"npm:build:js\" \"npm:build:types\" \"npm:build:styles\"",
|
|
220
|
+
"build:cli": "rollup -c rollup.config.cli.js",
|
|
221
|
+
"build:cli:dev": "rollup -c rollup.config.cli.js --environment NODE_ENV:development",
|
|
210
222
|
"build:analyze": "ANALYZE=true rollup -c",
|
|
211
223
|
"build:storybook": "storybook build",
|
|
212
224
|
"test": "vitest",
|
|
213
|
-
"test:
|
|
214
|
-
"test:cli": "vitest
|
|
215
|
-
"test:cli:watch": "vitest scripts/cli/__tests__",
|
|
225
|
+
"test:cli": "vitest run --config vitest.config.cli.js scripts/cli/__tests__",
|
|
226
|
+
"test:cli:watch": "vitest --config vitest.config.cli.js scripts/cli/__tests__",
|
|
216
227
|
"test:cli:coverage": "vitest run --coverage scripts/cli/__tests__",
|
|
217
228
|
"lint": "eslint src",
|
|
218
229
|
"lint:fix": "eslint src --fix",
|
|
@@ -229,6 +240,7 @@
|
|
|
229
240
|
"prebuild:with-tokens": "npm run sync:tokens && npm run validate:config",
|
|
230
241
|
"verify:build": "node scripts/verify-build.js",
|
|
231
242
|
"test:build": "node scripts/test-build.js",
|
|
243
|
+
"postbuild": "mkdir -p dist/build-tools && cp -r build-tools/* dist/build-tools/",
|
|
232
244
|
"prepublishOnly": "npm run clean && npm run build && npm run attw",
|
|
233
245
|
"prepack": "echo 'Preparing package for publishing...'"
|
|
234
246
|
},
|
|
@@ -240,6 +252,9 @@
|
|
|
240
252
|
"src/layouts/**/*",
|
|
241
253
|
"scripts/atomix-cli.js",
|
|
242
254
|
"scripts/cli/**/*",
|
|
255
|
+
"build-tools/**/*",
|
|
256
|
+
"build-tools/**/*.d.ts",
|
|
257
|
+
"themes/**/*",
|
|
243
258
|
"atomix.config.ts",
|
|
244
259
|
"README.md",
|
|
245
260
|
"LICENSE",
|
|
@@ -265,7 +280,7 @@
|
|
|
265
280
|
"type": "git",
|
|
266
281
|
"url": "git+https://github.com/Shohojdhara/atomix.git"
|
|
267
282
|
},
|
|
268
|
-
"author": "liimonx <
|
|
283
|
+
"author": "liimonx <limonkhan669@gmail.com>",
|
|
269
284
|
"license": "Apache-2.0",
|
|
270
285
|
"funding": {
|
|
271
286
|
"type": "github",
|
package/scripts/atomix-cli.js
CHANGED
|
@@ -9,7 +9,7 @@ import { program } from 'commander';
|
|
|
9
9
|
import { readFile, writeFile, mkdir, access, stat, rm } from 'fs/promises';
|
|
10
10
|
import { join, dirname, basename, relative, resolve } from 'path';
|
|
11
11
|
import { fileURLToPath } from 'url';
|
|
12
|
-
import { existsSync } from 'fs';
|
|
12
|
+
import { existsSync, cpSync } from 'fs';
|
|
13
13
|
import * as sass from 'sass';
|
|
14
14
|
import postcss from 'postcss';
|
|
15
15
|
import autoprefixer from 'autoprefixer';
|
|
@@ -20,6 +20,11 @@ import chokidar from 'chokidar';
|
|
|
20
20
|
import inquirer from 'inquirer';
|
|
21
21
|
import boxen from 'boxen';
|
|
22
22
|
import { runInitWizard } from './cli/interactive-init.js';
|
|
23
|
+
import {
|
|
24
|
+
checkDependencies,
|
|
25
|
+
validateProjectStructure,
|
|
26
|
+
validateFrameworkConfig
|
|
27
|
+
} from './cli/dependency-checker.js';
|
|
23
28
|
import {
|
|
24
29
|
migrateTailwind,
|
|
25
30
|
migrateBootstrap,
|
|
@@ -39,8 +44,6 @@ import {
|
|
|
39
44
|
validateComponentName,
|
|
40
45
|
validateThemeName,
|
|
41
46
|
sanitizeInput,
|
|
42
|
-
fileExists,
|
|
43
|
-
isDebug as checkDebugMode,
|
|
44
47
|
checkNodeVersion,
|
|
45
48
|
AtomixCLIError
|
|
46
49
|
} from './cli/utils.js';
|
|
@@ -54,9 +57,6 @@ import {
|
|
|
54
57
|
generateAnimationTokens
|
|
55
58
|
} from './cli/templates.js';
|
|
56
59
|
import {
|
|
57
|
-
COMPLEXITY_LEVELS,
|
|
58
|
-
COMPONENT_FEATURES,
|
|
59
|
-
generateComponentByComplexity,
|
|
60
60
|
interactiveComponentGeneration,
|
|
61
61
|
validateGeneratedComponent,
|
|
62
62
|
displayValidationReport
|
|
@@ -346,17 +346,19 @@ program
|
|
|
346
346
|
|
|
347
347
|
try {
|
|
348
348
|
debug(`Generating ${type} with name: ${name}`, options);
|
|
349
|
-
|
|
349
|
+
let safeName = sanitizeInput(name);
|
|
350
350
|
|
|
351
351
|
if (type === 'component' || type === 'c') {
|
|
352
352
|
// Handle interactive generation
|
|
353
353
|
if (options.interactive) {
|
|
354
354
|
const interactiveResult = await interactiveComponentGeneration();
|
|
355
355
|
if (!interactiveResult) {
|
|
356
|
+
spinner.stop();
|
|
356
357
|
return; // User cancelled
|
|
357
358
|
}
|
|
358
|
-
// Update options with interactive results
|
|
359
|
-
Object.assign(options, interactiveResult
|
|
359
|
+
// Update options with interactive results (name, complexity, features, outputPath)
|
|
360
|
+
Object.assign(options, interactiveResult);
|
|
361
|
+
safeName = sanitizeInput(options.name);
|
|
360
362
|
}
|
|
361
363
|
|
|
362
364
|
const nameValidation = validateComponentName(safeName);
|
|
@@ -408,7 +410,7 @@ program
|
|
|
408
410
|
// Generate composable hook
|
|
409
411
|
const hookPath = join(process.cwd(), 'src/lib/composables');
|
|
410
412
|
if (existsSync(hookPath)) {
|
|
411
|
-
const hookContent = componentTemplates.composable.
|
|
413
|
+
const hookContent = componentTemplates.composable.useHook(safeName);
|
|
412
414
|
const hookFilePath = join(hookPath, `use${safeName}.ts`);
|
|
413
415
|
|
|
414
416
|
if (!existsSync(hookFilePath) || options.force) {
|
|
@@ -497,7 +499,7 @@ program
|
|
|
497
499
|
// Generate settings file first
|
|
498
500
|
const settingsPath = join(process.cwd(), 'src/styles/01-settings');
|
|
499
501
|
if (existsSync(settingsPath)) {
|
|
500
|
-
const settingsContent = componentTemplates.react.
|
|
502
|
+
const settingsContent = componentTemplates.react.settings(safeName);
|
|
501
503
|
const settingsFilename = `_settings.${safeName.toLowerCase()}.scss`;
|
|
502
504
|
const settingsFilePath = join(settingsPath, settingsFilename);
|
|
503
505
|
|
|
@@ -524,7 +526,7 @@ program
|
|
|
524
526
|
}
|
|
525
527
|
|
|
526
528
|
// Generate component SCSS file
|
|
527
|
-
const scssContent = componentTemplates.
|
|
529
|
+
const scssContent = componentTemplates.scss.component(safeName);
|
|
528
530
|
const scssPath = join(process.cwd(), 'src/styles/06-components');
|
|
529
531
|
const scssFilename = `_components.${safeName.toLowerCase()}.scss`;
|
|
530
532
|
const scssFilePath = join(scssPath, scssFilename);
|
|
@@ -568,7 +570,7 @@ program
|
|
|
568
570
|
|
|
569
571
|
// Generate Storybook story
|
|
570
572
|
if (options.story) {
|
|
571
|
-
const storyContent = componentTemplates.
|
|
573
|
+
const storyContent = componentTemplates.storybook.story(safeName);
|
|
572
574
|
await writeFile(
|
|
573
575
|
join(componentPath, `${safeName}.stories.tsx`),
|
|
574
576
|
storyContent,
|
|
@@ -591,7 +593,7 @@ program
|
|
|
591
593
|
// Post-generation validation if requested
|
|
592
594
|
if (options.validate) {
|
|
593
595
|
const validationResult = await validateGeneratedComponent(safeName, componentPath);
|
|
594
|
-
const isValid = displayValidationReport(validationResult
|
|
596
|
+
const isValid = displayValidationReport(validationResult);
|
|
595
597
|
|
|
596
598
|
if (!isValid) {
|
|
597
599
|
console.log(chalk.yellow('\nđĄ Some issues were found. Consider addressing them for better component quality.'));
|
|
@@ -619,7 +621,19 @@ program
|
|
|
619
621
|
));
|
|
620
622
|
|
|
621
623
|
} else if (type === 'hook' || type === 'h') {
|
|
622
|
-
const
|
|
624
|
+
const hookPathValidation = validatePath(sanitizeInput(options.path));
|
|
625
|
+
if (!hookPathValidation.isValid) {
|
|
626
|
+
throw new AtomixCLIError(
|
|
627
|
+
hookPathValidation.error,
|
|
628
|
+
'INVALID_PATH',
|
|
629
|
+
[
|
|
630
|
+
'Ensure the path is within the project directory',
|
|
631
|
+
'Avoid using ".." to navigate outside the project',
|
|
632
|
+
'Example: --path ./src/components'
|
|
633
|
+
]
|
|
634
|
+
);
|
|
635
|
+
}
|
|
636
|
+
const componentPath = join(hookPathValidation.safePath, `use${safeName}`);
|
|
623
637
|
await mkdir(componentPath, { recursive: true });
|
|
624
638
|
|
|
625
639
|
const hookContent = componentTemplates.hook.hook(safeName);
|
|
@@ -633,7 +647,19 @@ program
|
|
|
633
647
|
spinner.succeed(chalk.green(`â Created hook use${safeName}`));
|
|
634
648
|
|
|
635
649
|
} else if (type === 'layout' || type === 'l') {
|
|
636
|
-
const
|
|
650
|
+
const layoutPathValidation = validatePath(sanitizeInput(options.path));
|
|
651
|
+
if (!layoutPathValidation.isValid) {
|
|
652
|
+
throw new AtomixCLIError(
|
|
653
|
+
layoutPathValidation.error,
|
|
654
|
+
'INVALID_PATH',
|
|
655
|
+
[
|
|
656
|
+
'Ensure the path is within the project directory',
|
|
657
|
+
'Avoid using ".." to navigate outside the project',
|
|
658
|
+
'Example: --path ./src/layouts'
|
|
659
|
+
]
|
|
660
|
+
);
|
|
661
|
+
}
|
|
662
|
+
const layoutPath = join(layoutPathValidation.safePath, safeName);
|
|
637
663
|
await mkdir(layoutPath, { recursive: true });
|
|
638
664
|
|
|
639
665
|
const componentContent = componentTemplates.layout.component(safeName);
|
|
@@ -661,7 +687,19 @@ program
|
|
|
661
687
|
spinner.succeed(chalk.green(`â Created layout ${safeName}`));
|
|
662
688
|
|
|
663
689
|
} else if (type === 'context' || type === 'ctx') {
|
|
664
|
-
const
|
|
690
|
+
const contextPathValidation = validatePath(sanitizeInput(options.path));
|
|
691
|
+
if (!contextPathValidation.isValid) {
|
|
692
|
+
throw new AtomixCLIError(
|
|
693
|
+
contextPathValidation.error,
|
|
694
|
+
'INVALID_PATH',
|
|
695
|
+
[
|
|
696
|
+
'Ensure the path is within the project directory',
|
|
697
|
+
'Avoid using ".." to navigate outside the project',
|
|
698
|
+
'Example: --path ./src/contexts'
|
|
699
|
+
]
|
|
700
|
+
);
|
|
701
|
+
}
|
|
702
|
+
const contextPath = join(contextPathValidation.safePath, `${safeName}Context`);
|
|
665
703
|
await mkdir(contextPath, { recursive: true });
|
|
666
704
|
|
|
667
705
|
const contextContent = componentTemplates.context.context(safeName);
|
|
@@ -1118,14 +1156,13 @@ program
|
|
|
1118
1156
|
}
|
|
1119
1157
|
}
|
|
1120
1158
|
|
|
1121
|
-
// Create backup if requested
|
|
1159
|
+
// Create backup if requested (cross-platform: fs.cpSync works on Windows and Unix)
|
|
1122
1160
|
if (options.createBackup && !options.dryRun) {
|
|
1123
1161
|
const backupSpinner = ora('Creating backup...').start();
|
|
1124
1162
|
const backupDir = `${sourcePath}.backup.${Date.now()}`;
|
|
1125
1163
|
|
|
1126
1164
|
try {
|
|
1127
|
-
|
|
1128
|
-
execSync(`cp -r "${sourcePath}" "${backupDir}"`, { stdio: 'ignore' });
|
|
1165
|
+
cpSync(sourcePath, backupDir, { recursive: true });
|
|
1129
1166
|
backupSpinner.succeed(chalk.green(`â Backup created: ${backupDir}`));
|
|
1130
1167
|
} catch (error) {
|
|
1131
1168
|
backupSpinner.warn(chalk.yellow('Could not create backup, continuing anyway...'));
|
|
@@ -1680,100 +1717,142 @@ docsCommand
|
|
|
1680
1717
|
*/
|
|
1681
1718
|
program
|
|
1682
1719
|
.command('doctor')
|
|
1720
|
+
.alias('audit')
|
|
1683
1721
|
.description('Diagnose common issues with your Atomix setup')
|
|
1684
1722
|
.action(async () => {
|
|
1685
1723
|
const spinner = ora('Running diagnostics...').start();
|
|
1686
1724
|
|
|
1687
1725
|
try {
|
|
1688
|
-
const
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1726
|
+
const results = {
|
|
1727
|
+
system: [],
|
|
1728
|
+
dependencies: [],
|
|
1729
|
+
structure: [],
|
|
1730
|
+
framework: [],
|
|
1731
|
+
theme: []
|
|
1732
|
+
};
|
|
1733
|
+
|
|
1734
|
+
// 1. System Checks
|
|
1735
|
+
const nodeVersion = checkNodeVersion('18.0.0');
|
|
1736
|
+
results.system.push({
|
|
1737
|
+
name: 'Node.js',
|
|
1738
|
+
status: nodeVersion.compatible ? 'â
' : 'â',
|
|
1739
|
+
message: nodeVersion.compatible
|
|
1740
|
+
? `v${nodeVersion.current} (supported)`
|
|
1741
|
+
: `v${nodeVersion.current} (requires Node ${nodeVersion.required}+)`,
|
|
1698
1742
|
});
|
|
1699
1743
|
|
|
1700
|
-
//
|
|
1744
|
+
// 2. Dependency Checks
|
|
1701
1745
|
const atomixPath = join(process.cwd(), 'node_modules', '@shohojdhara', 'atomix');
|
|
1702
|
-
|
|
1703
|
-
name: 'Atomix
|
|
1746
|
+
results.dependencies.push({
|
|
1747
|
+
name: 'Atomix Package',
|
|
1704
1748
|
status: existsSync(atomixPath) ? 'â
' : 'â',
|
|
1705
1749
|
message: existsSync(atomixPath)
|
|
1706
1750
|
? 'Installed correctly'
|
|
1707
1751
|
: 'Not found - run: npm install @shohojdhara/atomix',
|
|
1708
1752
|
});
|
|
1709
1753
|
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1754
|
+
const peerDeps = [
|
|
1755
|
+
{ name: 'react', required: '>= 18.0.0' },
|
|
1756
|
+
{ name: 'react-dom', required: '>= 18.0.0' },
|
|
1757
|
+
{ name: 'sass', required: 'installed' }
|
|
1758
|
+
];
|
|
1759
|
+
|
|
1760
|
+
for (const dep of peerDeps) {
|
|
1761
|
+
const depPath = join(process.cwd(), 'node_modules', dep.name);
|
|
1762
|
+
const exists = existsSync(depPath);
|
|
1763
|
+
results.dependencies.push({
|
|
1764
|
+
name: dep.name,
|
|
1765
|
+
status: exists ? 'â
' : 'â ď¸',
|
|
1766
|
+
message: exists ? 'Installed' : `Missing (required: ${dep.required})`,
|
|
1720
1767
|
});
|
|
1721
1768
|
}
|
|
1722
1769
|
|
|
1723
|
-
//
|
|
1724
|
-
const
|
|
1725
|
-
|
|
1726
|
-
|
|
1770
|
+
// 3. Project Structure Checks
|
|
1771
|
+
const structureChecks = validateProjectStructure();
|
|
1772
|
+
|
|
1773
|
+
structureChecks.forEach(check => {
|
|
1774
|
+
let statusIcon = 'â
';
|
|
1775
|
+
if (!check.valid && check.required) statusIcon = 'â';
|
|
1776
|
+
else if (!check.message.includes('exists') && !check.required) statusIcon = 'â ď¸';
|
|
1777
|
+
|
|
1778
|
+
results.structure.push({
|
|
1779
|
+
name: check.name,
|
|
1780
|
+
status: statusIcon,
|
|
1781
|
+
message: check.message.replace(/â |â |â /, '')
|
|
1782
|
+
});
|
|
1783
|
+
});
|
|
1784
|
+
|
|
1785
|
+
// 4. Framework & Config Checks
|
|
1786
|
+
const frameworkChecks = validateFrameworkConfig();
|
|
1787
|
+
|
|
1788
|
+
frameworkChecks.forEach(check => {
|
|
1789
|
+
results.framework.push({
|
|
1790
|
+
name: check.name,
|
|
1791
|
+
status: check.valid ? 'â
' : 'đĄ',
|
|
1792
|
+
message: check.message.replace(/â |⢠/, '')
|
|
1793
|
+
});
|
|
1794
|
+
});
|
|
1795
|
+
|
|
1796
|
+
const configFiles = ['.atomixrc', 'atomix.config.js', 'atomix.config.json', 'theme.config.ts', 'atomix.config.ts'];
|
|
1797
|
+
let foundConfig = null;
|
|
1727
1798
|
for (const file of configFiles) {
|
|
1728
1799
|
if (existsSync(join(process.cwd(), file))) {
|
|
1729
|
-
|
|
1730
|
-
configFile = file;
|
|
1800
|
+
foundConfig = file;
|
|
1731
1801
|
break;
|
|
1732
1802
|
}
|
|
1733
1803
|
}
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
message: hasConfig
|
|
1739
|
-
? `Configuration found (${configFile})`
|
|
1740
|
-
: 'No config file (using defaults)',
|
|
1804
|
+
results.framework.push({
|
|
1805
|
+
name: 'Atomix Config',
|
|
1806
|
+
status: foundConfig ? 'â
' : 'đĄ',
|
|
1807
|
+
message: foundConfig ? `Found (${foundConfig})` : 'No config file (using defaults)',
|
|
1741
1808
|
});
|
|
1742
1809
|
|
|
1743
|
-
//
|
|
1810
|
+
// 5. Theme CLI Checks
|
|
1744
1811
|
const themeCLIAvailable = await import('./cli/theme-bridge.js')
|
|
1745
1812
|
.then(m => m.isThemeCLIAvailable())
|
|
1746
1813
|
.catch(() => false);
|
|
1747
1814
|
|
|
1748
|
-
|
|
1749
|
-
name: 'Theme
|
|
1815
|
+
results.theme.push({
|
|
1816
|
+
name: 'Theme Devtools',
|
|
1750
1817
|
status: themeCLIAvailable ? 'â
' : 'â ď¸',
|
|
1751
|
-
message: themeCLIAvailable
|
|
1752
|
-
? 'Available'
|
|
1753
|
-
: 'Theme devtools not found',
|
|
1818
|
+
message: themeCLIAvailable ? 'Available' : 'Theme devtools not found',
|
|
1754
1819
|
});
|
|
1755
1820
|
|
|
1756
1821
|
spinner.stop();
|
|
1757
1822
|
|
|
1758
1823
|
// Display results
|
|
1759
|
-
console.log(chalk.bold('\nđĽ Atomix Doctor Report\n'));
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1824
|
+
console.log(chalk.bold('\nđĽ Atomix Doctor / Audit Report\n'));
|
|
1825
|
+
|
|
1826
|
+
const categories = [
|
|
1827
|
+
{ key: 'system', label: 'đť System environment' },
|
|
1828
|
+
{ key: 'dependencies', label: 'đŚ Core dependencies' },
|
|
1829
|
+
{ key: 'structure', label: 'đď¸ Project structure' },
|
|
1830
|
+
{ key: 'framework', label: 'âď¸ Configuration & Framework' },
|
|
1831
|
+
{ key: 'theme', label: 'đ¨ Design System tools' }
|
|
1832
|
+
];
|
|
1833
|
+
|
|
1834
|
+
categories.forEach(cat => {
|
|
1835
|
+
console.log(chalk.cyan.bold(`\n${cat.label}`));
|
|
1836
|
+
console.log(chalk.gray('-'.repeat(40)));
|
|
1837
|
+
results[cat.key].forEach(check => {
|
|
1838
|
+
console.log(` ${check.status} ${chalk.bold(check.name.padEnd(20))} ${chalk.gray(check.message)}`);
|
|
1839
|
+
});
|
|
1765
1840
|
});
|
|
1766
1841
|
|
|
1767
|
-
const hasIssues =
|
|
1768
|
-
const hasWarnings =
|
|
1842
|
+
const hasIssues = Object.values(results).flat().some(c => c.status === 'â');
|
|
1843
|
+
const hasWarnings = Object.values(results).flat().some(c => c.status === 'â ď¸');
|
|
1769
1844
|
|
|
1845
|
+
console.log('\n' + chalk.gray('='.repeat(60)));
|
|
1770
1846
|
if (hasIssues) {
|
|
1771
|
-
console.log(chalk.red('\nâ Some issues need attention'));
|
|
1847
|
+
console.log(chalk.red.bold('\nâ Some critical issues need attention.'));
|
|
1848
|
+
console.log(chalk.gray('Check the report above and follow the suggested fixes.'));
|
|
1772
1849
|
} else if (hasWarnings) {
|
|
1773
|
-
console.log(chalk.yellow('\nâ ď¸
|
|
1850
|
+
console.log(chalk.yellow.bold('\nâ ď¸ Your setup is functional but could be improved.'));
|
|
1851
|
+
console.log(chalk.gray('Recommended directories or scripts are missing.'));
|
|
1774
1852
|
} else {
|
|
1775
|
-
console.log(chalk.green('\n
|
|
1853
|
+
console.log(chalk.green.bold('\n⨠Everything looks great! Your project is Atomix-ready.'));
|
|
1776
1854
|
}
|
|
1855
|
+
console.log(chalk.gray('='.repeat(60)) + '\n');
|
|
1777
1856
|
|
|
1778
1857
|
} catch (error) {
|
|
1779
1858
|
handleError(error, spinner);
|
|
@@ -1782,6 +1861,24 @@ program
|
|
|
1782
1861
|
|
|
1783
1862
|
|
|
1784
1863
|
|
|
1864
|
+
// Check dependencies before execution (except for doctor command)
|
|
1865
|
+
const args = process.argv.slice(2);
|
|
1866
|
+
const command = args[0];
|
|
1867
|
+
|
|
1868
|
+
// Skip dependency check for doctor command or help
|
|
1869
|
+
if (command !== 'doctor' && command !== '--help' && command !== '-h' && !args.includes('--help') && !args.includes('-h') && !process.env.ATOMIX_SKIP_DEP_CHECK) {
|
|
1870
|
+
try {
|
|
1871
|
+
const depResult = await checkDependencies();
|
|
1872
|
+
if (!depResult.success) {
|
|
1873
|
+
console.log(chalk.yellow('\nâ ď¸ Some dependencies are missing. Run `atomix doctor` for detailed information.'));
|
|
1874
|
+
// Don't exit - allow users to see help or run doctor
|
|
1875
|
+
}
|
|
1876
|
+
} catch (error) {
|
|
1877
|
+
// Silently continue if dependency check fails
|
|
1878
|
+
debug('Dependency check failed:', error.message);
|
|
1879
|
+
}
|
|
1880
|
+
}
|
|
1881
|
+
|
|
1785
1882
|
// Parse arguments
|
|
1786
1883
|
program.parse(process.argv);
|
|
1787
1884
|
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# CLI Tests
|
|
2
|
+
|
|
3
|
+
This directory contains comprehensive tests for the Atomix CLI tools.
|
|
4
|
+
|
|
5
|
+
## Test Structure
|
|
6
|
+
|
|
7
|
+
### Files
|
|
8
|
+
- `basic.test.js` - Core utility functions (validatePath, validateComponentName, etc.)
|
|
9
|
+
- `utils.test.js` - Extended utility tests with file system operations
|
|
10
|
+
- `token-manager.test.js` - Token management functionality
|
|
11
|
+
- `component-generator.test.js` - Component generation and validation
|
|
12
|
+
- `integration.test.js` - End-to-end CLI command tests
|
|
13
|
+
- `test-setup.js` - Global test configuration and mocks
|
|
14
|
+
|
|
15
|
+
## Running Tests
|
|
16
|
+
|
|
17
|
+
### Run all CLI tests
|
|
18
|
+
```bash
|
|
19
|
+
npm run test:cli
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Run with watch mode
|
|
23
|
+
```bash
|
|
24
|
+
npm run test:cli:watch
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Run with coverage
|
|
28
|
+
```bash
|
|
29
|
+
npm run test:cli:coverage
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Run specific test file
|
|
33
|
+
```bash
|
|
34
|
+
npx vitest run scripts/cli/__tests__/basic.test.js
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Test Categories
|
|
38
|
+
|
|
39
|
+
### Unit Tests
|
|
40
|
+
- **Utils**: Path validation, name validation, input sanitization
|
|
41
|
+
- **Token Manager**: Token parsing, validation, export/import
|
|
42
|
+
- **Component Generator**: Component creation, validation, templates
|
|
43
|
+
|
|
44
|
+
### Integration Tests
|
|
45
|
+
- Full CLI command execution
|
|
46
|
+
- File system operations
|
|
47
|
+
- Error handling scenarios
|
|
48
|
+
|
|
49
|
+
## Coverage Goals
|
|
50
|
+
|
|
51
|
+
- **Overall Coverage**: 80%+
|
|
52
|
+
- **Functions**: 80%+
|
|
53
|
+
- **Branches**: 80%+
|
|
54
|
+
- **Lines**: 80%+
|
|
55
|
+
- **Statements**: 80%+
|
|
56
|
+
|
|
57
|
+
## Mock Strategy
|
|
58
|
+
|
|
59
|
+
- External dependencies (ora, chalk, inquirer) are mocked
|
|
60
|
+
- File system operations use temporary directories
|
|
61
|
+
- CLI commands are tested in isolated environments
|
|
62
|
+
|
|
63
|
+
## Adding New Tests
|
|
64
|
+
|
|
65
|
+
1. Create test file with `.test.js` extension
|
|
66
|
+
2. Use descriptive test names
|
|
67
|
+
3. Mock external dependencies
|
|
68
|
+
4. Clean up temporary files in afterEach
|
|
69
|
+
5. Follow existing patterns for consistency
|
|
70
|
+
|
|
71
|
+
## Debugging Failed Tests
|
|
72
|
+
|
|
73
|
+
Run tests with verbose output:
|
|
74
|
+
```bash
|
|
75
|
+
npx vitest run --reporter=verbose scripts/cli/__tests__/
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
For specific test debugging:
|
|
79
|
+
```bash
|
|
80
|
+
npx vitest run --no-coverage scripts/cli/__tests__/basic.test.js
|
|
81
|
+
```
|