grg-kit-cli 0.6.14 ā 0.6.16
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 +8 -0
- package/commands/add.js +7 -14
- package/commands/init.js +70 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -151,6 +151,14 @@ Examples:
|
|
|
151
151
|
| `shell` | `sidebar`, `sidebar-footer`, `topnav`, `topnav-footer`, `collapsible`, `collapsible-footer` |
|
|
152
152
|
| `settings` | `profile`, `security`, `notification`, `danger-zone` |
|
|
153
153
|
|
|
154
|
+
**Search tags** (for MCP server discoverability):
|
|
155
|
+
|
|
156
|
+
| Block | Search Terms |
|
|
157
|
+
|-------|--------------|
|
|
158
|
+
| `auth` | signin, sign-in, signup, register, password, credentials, onboarding |
|
|
159
|
+
| `shell` | dashboard, admin, navbar, menu, left-nav, top-bar, wrapper |
|
|
160
|
+
| `settings` | user-settings, my-account, configuration, notifications, privacy |
|
|
161
|
+
|
|
154
162
|
### `grg list [category]`
|
|
155
163
|
|
|
156
164
|
List available blocks and themes.
|
package/commands/add.js
CHANGED
|
@@ -200,11 +200,6 @@ function showUsage(RESOURCES) {
|
|
|
200
200
|
* grg add component --all # All components
|
|
201
201
|
*/
|
|
202
202
|
async function addComponent(componentName, options) {
|
|
203
|
-
// Fetch catalog dynamically (with caching)
|
|
204
|
-
const spinner = ora('Fetching catalog...').start();
|
|
205
|
-
const RESOURCES = await fetchCatalog({ silent: true });
|
|
206
|
-
spinner.stop();
|
|
207
|
-
|
|
208
203
|
// Handle --all flag (download all components)
|
|
209
204
|
if (options.all) {
|
|
210
205
|
console.log(chalk.bold.cyan(`\nš¦ Adding all components\n`));
|
|
@@ -296,11 +291,6 @@ function showComponentUsage(RESOURCES) {
|
|
|
296
291
|
* grg add theme modern-minimal # Download and set modern-minimal theme
|
|
297
292
|
*/
|
|
298
293
|
async function addTheme(themeName, options) {
|
|
299
|
-
// Fetch catalog dynamically (with caching)
|
|
300
|
-
const spinner = ora('Fetching catalog...').start();
|
|
301
|
-
const RESOURCES = await fetchCatalog({ silent: true });
|
|
302
|
-
spinner.stop();
|
|
303
|
-
|
|
304
294
|
// Validate theme name
|
|
305
295
|
if (!themeName) {
|
|
306
296
|
showThemeUsage(RESOURCES);
|
|
@@ -360,10 +350,12 @@ async function downloadTheme(theme, customOutput) {
|
|
|
360
350
|
stylesContent = '';
|
|
361
351
|
}
|
|
362
352
|
|
|
363
|
-
|
|
353
|
+
// Use relative path from src/ to the theme file
|
|
354
|
+
const relativeThemePath = path.relative('src', outputPath).replace(/\\/g, '/');
|
|
355
|
+
const themeImport = `@import './${relativeThemePath}';`;
|
|
364
356
|
|
|
365
|
-
// Check if any theme is already imported
|
|
366
|
-
const themeImportRegex = /@import\s+['"]
|
|
357
|
+
// Check if any theme is already imported (match any .css file import from relative paths)
|
|
358
|
+
const themeImportRegex = /@import\s+['"]\.\/.+\.css['"];?\n?/g;
|
|
367
359
|
const existingThemeImports = stylesContent.match(themeImportRegex);
|
|
368
360
|
|
|
369
361
|
if (existingThemeImports && existingThemeImports.length > 0) {
|
|
@@ -400,7 +392,8 @@ async function downloadTheme(theme, customOutput) {
|
|
|
400
392
|
} catch (error) {
|
|
401
393
|
downloadSpinner.warn(chalk.yellow('Could not update src/styles.css automatically'));
|
|
402
394
|
console.log(chalk.gray('\nPlease add the following to your src/styles.css:'));
|
|
403
|
-
|
|
395
|
+
const relativeThemePath = path.relative('src', outputPath).replace(/\\/g, '/');
|
|
396
|
+
console.log(chalk.cyan(` @import './${relativeThemePath}';`));
|
|
404
397
|
}
|
|
405
398
|
|
|
406
399
|
console.log();
|
package/commands/init.js
CHANGED
|
@@ -10,6 +10,71 @@ const { RESOURCES, REPO } = require('../config/resources');
|
|
|
10
10
|
|
|
11
11
|
const execAsync = promisify(exec);
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Strip comments and trailing commas from JSON (for tsconfig.json parsing)
|
|
15
|
+
* Handles: block comments, line comments, and trailing commas
|
|
16
|
+
* Preserves // inside strings (like URLs)
|
|
17
|
+
*/
|
|
18
|
+
function stripJsonComments(jsonString) {
|
|
19
|
+
let result = '';
|
|
20
|
+
let i = 0;
|
|
21
|
+
let inString = false;
|
|
22
|
+
let stringChar = '';
|
|
23
|
+
|
|
24
|
+
while (i < jsonString.length) {
|
|
25
|
+
const char = jsonString[i];
|
|
26
|
+
const nextChar = jsonString[i + 1];
|
|
27
|
+
|
|
28
|
+
// Handle string boundaries
|
|
29
|
+
if ((char === '"' || char === "'") && (i === 0 || jsonString[i - 1] !== '\\')) {
|
|
30
|
+
if (!inString) {
|
|
31
|
+
inString = true;
|
|
32
|
+
stringChar = char;
|
|
33
|
+
} else if (char === stringChar) {
|
|
34
|
+
inString = false;
|
|
35
|
+
}
|
|
36
|
+
result += char;
|
|
37
|
+
i++;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Inside a string, copy everything
|
|
42
|
+
if (inString) {
|
|
43
|
+
result += char;
|
|
44
|
+
i++;
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Block comment /* ... */
|
|
49
|
+
if (char === '/' && nextChar === '*') {
|
|
50
|
+
const endIndex = jsonString.indexOf('*/', i + 2);
|
|
51
|
+
if (endIndex !== -1) {
|
|
52
|
+
i = endIndex + 2;
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Line comment // ...
|
|
58
|
+
if (char === '/' && nextChar === '/') {
|
|
59
|
+
const endIndex = jsonString.indexOf('\n', i);
|
|
60
|
+
if (endIndex !== -1) {
|
|
61
|
+
i = endIndex;
|
|
62
|
+
continue;
|
|
63
|
+
} else {
|
|
64
|
+
break; // Comment goes to end of file
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
result += char;
|
|
69
|
+
i++;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Remove trailing commas before } or ]
|
|
73
|
+
result = result.replace(/,(\s*[}\]])/g, '$1');
|
|
74
|
+
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
|
|
13
78
|
/**
|
|
14
79
|
* Download a file from a URL
|
|
15
80
|
*/
|
|
@@ -82,7 +147,7 @@ async function init(options) {
|
|
|
82
147
|
// Step 2: Install Tailwind CSS v4
|
|
83
148
|
spinner.start('Installing Tailwind CSS v4...');
|
|
84
149
|
try {
|
|
85
|
-
await execAsync('npm install tailwindcss @tailwindcss/postcss postcss --
|
|
150
|
+
await execAsync('npm install tailwindcss @tailwindcss/postcss postcss --legacy-peer-deps');
|
|
86
151
|
spinner.succeed(chalk.green('ā Tailwind CSS v4 installed'));
|
|
87
152
|
} catch (error) {
|
|
88
153
|
spinner.fail(chalk.red('Failed to install Tailwind CSS v4'));
|
|
@@ -107,7 +172,7 @@ async function init(options) {
|
|
|
107
172
|
// Step 4: Install Spartan-NG CLI
|
|
108
173
|
spinner.start('Installing Spartan-NG CLI...');
|
|
109
174
|
try {
|
|
110
|
-
await execAsync('npm install -D @spartan-ng/cli');
|
|
175
|
+
await execAsync('npm install -D @spartan-ng/cli --legacy-peer-deps');
|
|
111
176
|
spinner.succeed(chalk.green('ā Spartan-NG CLI installed'));
|
|
112
177
|
} catch (error) {
|
|
113
178
|
spinner.fail(chalk.red('Failed to install Spartan-NG CLI'));
|
|
@@ -135,14 +200,9 @@ async function init(options) {
|
|
|
135
200
|
let tsconfigContent = await fs.readFile(tsconfigPath, 'utf-8');
|
|
136
201
|
|
|
137
202
|
// Strip comments from tsconfig (Angular generates tsconfig with comments)
|
|
138
|
-
//
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
.replace(/^\s*\/\/.*/gm, ''); // Remove line comments (only at start of line after whitespace)
|
|
142
|
-
|
|
143
|
-
// Remove trailing commas (common in tsconfig files)
|
|
144
|
-
tsconfigContent = tsconfigContent
|
|
145
|
-
.replace(/,(\s*[}\]])/g, '$1');
|
|
203
|
+
// This handles: /* block comments */, // line comments, and trailing commas
|
|
204
|
+
// We need to be careful not to strip // inside strings
|
|
205
|
+
tsconfigContent = stripJsonComments(tsconfigContent);
|
|
146
206
|
|
|
147
207
|
const tsconfig = JSON.parse(tsconfigContent);
|
|
148
208
|
|