@glass-ui-kit/cli 0.2.4 → 0.2.5
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/LICENSE +21 -0
- package/README.md +44 -44
- package/dist/index.js +476 -171
- package/package.json +60 -59
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Juan Tellez
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,44 +1,44 @@
|
|
|
1
|
-
# @glass-ui-kit/cli
|
|
2
|
-
|
|
3
|
-
The official CLI for Glass UI. Add premium glassmorphism components to your React projects in seconds.
|
|
4
|
-
|
|
5
|
-
## init
|
|
6
|
-
|
|
7
|
-
Use the `init` command to initialize the project configuration.
|
|
8
|
-
|
|
9
|
-
The `init` command:
|
|
10
|
-
|
|
11
|
-
1. Creates a `glass.config.json` file.
|
|
12
|
-
2. Generates the `cn` utility at `src/lib/utils.ts`.
|
|
13
|
-
3. Installs necessary dependencies (`clsx`, `tailwind-merge`).
|
|
14
|
-
4. Injects Glass Physics variables into your global CSS.
|
|
15
|
-
|
|
16
|
-
```bash
|
|
17
|
-
npx @glass-ui-kit/cli init
|
|
18
|
-
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
## add
|
|
22
|
-
|
|
23
|
-
Use the `add` command to add components to your project.
|
|
24
|
-
The `add` command downloads the component source code and places it directly into your project.
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
npx @glass-ui-kit/cli add [component]
|
|
28
|
-
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
### Example
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
npx @glass-ui-kit/cli add card
|
|
35
|
-
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## Documentation
|
|
39
|
-
|
|
40
|
-
Visit [https://ui-glass.vercel.app](https://ui-glass.vercel.app) to view the registry and documentation.
|
|
41
|
-
|
|
42
|
-
## License
|
|
43
|
-
|
|
44
|
-
Licensed under the [MIT license](https://github.com/jntellez/glass-ui/blob/master/LICENSE).
|
|
1
|
+
# @glass-ui-kit/cli
|
|
2
|
+
|
|
3
|
+
The official CLI for Glass UI. Add premium glassmorphism components to your React projects in seconds.
|
|
4
|
+
|
|
5
|
+
## init
|
|
6
|
+
|
|
7
|
+
Use the `init` command to initialize the project configuration.
|
|
8
|
+
|
|
9
|
+
The `init` command:
|
|
10
|
+
|
|
11
|
+
1. Creates a `glass.config.json` file.
|
|
12
|
+
2. Generates the `cn` utility at `src/lib/utils.ts`.
|
|
13
|
+
3. Installs necessary dependencies (`clsx`, `tailwind-merge`).
|
|
14
|
+
4. Injects Glass Physics variables into your global CSS.
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npx @glass-ui-kit/cli init
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## add
|
|
22
|
+
|
|
23
|
+
Use the `add` command to add components to your project.
|
|
24
|
+
The `add` command downloads the component source code and places it directly into your project.
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npx @glass-ui-kit/cli add [component]
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Example
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npx @glass-ui-kit/cli add card
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Documentation
|
|
39
|
+
|
|
40
|
+
Visit [https://ui-glass.vercel.app](https://ui-glass.vercel.app) to view the registry and documentation.
|
|
41
|
+
|
|
42
|
+
## License
|
|
43
|
+
|
|
44
|
+
Licensed under the [MIT license](https://github.com/jntellez/glass-ui/blob/master/LICENSE).
|
package/dist/index.js
CHANGED
|
@@ -4,45 +4,135 @@
|
|
|
4
4
|
import { Command as Command3 } from "commander";
|
|
5
5
|
|
|
6
6
|
// src/commands/init.ts
|
|
7
|
-
import
|
|
7
|
+
import chalk2 from "chalk";
|
|
8
8
|
import { Command } from "commander";
|
|
9
|
+
|
|
10
|
+
// src/utils/init/options.ts
|
|
11
|
+
import path from "path";
|
|
12
|
+
var SUPPORTED_INIT_FRAMEWORKS = ["react", "vite", "next", "remix"];
|
|
13
|
+
function resolveInitOptions(options = {}, currentWorkingDirectory = process.cwd()) {
|
|
14
|
+
validateFrameworkOverride(options.framework);
|
|
15
|
+
return {
|
|
16
|
+
projectRoot: path.resolve(currentWorkingDirectory, options.cwd ?? "."),
|
|
17
|
+
cssOverride: options.css,
|
|
18
|
+
componentsAliasOverride: options.components,
|
|
19
|
+
utilsAliasOverride: options.utils,
|
|
20
|
+
frameworkOverride: options.framework,
|
|
21
|
+
force: options.force === true,
|
|
22
|
+
install: options.install !== false
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function validateFrameworkOverride(framework) {
|
|
26
|
+
if (framework === void 0) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if (SUPPORTED_INIT_FRAMEWORKS.includes(framework)) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
throw new Error(
|
|
33
|
+
`Unsupported framework "${framework}". Supported values: ${SUPPORTED_INIT_FRAMEWORKS.join(", ")}.`
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// src/utils/init/paths.ts
|
|
9
38
|
import path2 from "path";
|
|
39
|
+
function resolveInitPaths({
|
|
40
|
+
projectRoot,
|
|
41
|
+
hasSrc,
|
|
42
|
+
framework,
|
|
43
|
+
detectedCssPath,
|
|
44
|
+
cssOverride,
|
|
45
|
+
componentsAliasOverride,
|
|
46
|
+
utilsAliasOverride
|
|
47
|
+
}) {
|
|
48
|
+
let baseDir = hasSrc ? "src" : "";
|
|
49
|
+
if (framework === "remix") {
|
|
50
|
+
baseDir = "app";
|
|
51
|
+
}
|
|
52
|
+
let cssPath = cssOverride ?? detectedCssPath;
|
|
53
|
+
if (!cssPath) {
|
|
54
|
+
if (framework === "next") {
|
|
55
|
+
cssPath = hasSrc ? "src/app/globals.css" : "app/globals.css";
|
|
56
|
+
} else if (framework === "remix") {
|
|
57
|
+
cssPath = "app/app.css";
|
|
58
|
+
} else {
|
|
59
|
+
cssPath = hasSrc ? "src/index.css" : "index.css";
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const defaultComponentsAlias = `${framework === "remix" ? "~" : "@"}/components/ui`;
|
|
63
|
+
const defaultUtilsAlias = `${framework === "remix" ? "~" : "@"}/lib/utils`;
|
|
64
|
+
const componentsAlias = componentsAliasOverride ?? defaultComponentsAlias;
|
|
65
|
+
const utilsAlias = utilsAliasOverride ?? defaultUtilsAlias;
|
|
66
|
+
const utilsRelativePath = resolveUtilsRelativePath(utilsAlias, baseDir);
|
|
67
|
+
const utilsPath = path2.join(projectRoot, utilsRelativePath);
|
|
68
|
+
const aliasPrefix = framework === "remix" ? "~" : "@";
|
|
69
|
+
return {
|
|
70
|
+
framework,
|
|
71
|
+
cssPath,
|
|
72
|
+
utilsRelativePath,
|
|
73
|
+
utilsPath,
|
|
74
|
+
aliasPrefix,
|
|
75
|
+
config: {
|
|
76
|
+
framework,
|
|
77
|
+
style: "default",
|
|
78
|
+
css: cssPath,
|
|
79
|
+
aliases: {
|
|
80
|
+
components: componentsAlias,
|
|
81
|
+
utils: utilsAlias
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function resolveUtilsRelativePath(utilsAlias, baseDir) {
|
|
87
|
+
const aliasBody = stripAliasPrefix(utilsAlias);
|
|
88
|
+
const relativePath = baseDir && !aliasBody.startsWith(`${baseDir}/`) ? path2.posix.join(baseDir, aliasBody) : aliasBody;
|
|
89
|
+
return path2.posix.extname(relativePath) ? relativePath : `${relativePath}.ts`;
|
|
90
|
+
}
|
|
91
|
+
function stripAliasPrefix(alias) {
|
|
92
|
+
return alias.replace(/^[@~]\//, "");
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// src/utils/init/run-init.ts
|
|
96
|
+
import chalk from "chalk";
|
|
10
97
|
|
|
11
98
|
// src/utils/filesystem.ts
|
|
12
99
|
import fs from "fs";
|
|
13
|
-
import
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
100
|
+
import path3 from "path";
|
|
101
|
+
function resolveFromBaseDir(filePath, baseDir = process.cwd()) {
|
|
102
|
+
return path3.resolve(baseDir, filePath);
|
|
103
|
+
}
|
|
104
|
+
async function writeFile(filePath, content, baseDir = process.cwd()) {
|
|
105
|
+
const absolutePath = resolveFromBaseDir(filePath, baseDir);
|
|
106
|
+
const dir = path3.dirname(absolutePath);
|
|
17
107
|
if (!fs.existsSync(dir)) {
|
|
18
108
|
await fs.promises.mkdir(dir, { recursive: true });
|
|
19
109
|
}
|
|
20
110
|
await fs.promises.writeFile(absolutePath, content, "utf-8");
|
|
21
111
|
return absolutePath;
|
|
22
112
|
}
|
|
23
|
-
async function readFile(filePath) {
|
|
24
|
-
const absolutePath =
|
|
113
|
+
async function readFile(filePath, baseDir = process.cwd()) {
|
|
114
|
+
const absolutePath = resolveFromBaseDir(filePath, baseDir);
|
|
25
115
|
if (!fs.existsSync(absolutePath)) {
|
|
26
116
|
throw new Error(`File not found: ${filePath}`);
|
|
27
117
|
}
|
|
28
118
|
return await fs.promises.readFile(absolutePath, "utf-8");
|
|
29
119
|
}
|
|
30
|
-
function exists(filePath) {
|
|
31
|
-
return fs.existsSync(
|
|
120
|
+
function exists(filePath, baseDir = process.cwd()) {
|
|
121
|
+
return fs.existsSync(resolveFromBaseDir(filePath, baseDir));
|
|
32
122
|
}
|
|
33
123
|
|
|
34
124
|
// src/utils/get-project-info.ts
|
|
35
125
|
import { spawn } from "child_process";
|
|
36
|
-
async function getPackageManager() {
|
|
37
|
-
if (exists("bun.lockb")) return "bun";
|
|
38
|
-
if (exists("pnpm-lock.yaml")) return "pnpm";
|
|
39
|
-
if (exists("yarn.lock")) return "yarn";
|
|
126
|
+
async function getPackageManager(projectRoot = process.cwd()) {
|
|
127
|
+
if (exists("bun.lockb", projectRoot)) return "bun";
|
|
128
|
+
if (exists("pnpm-lock.yaml", projectRoot)) return "pnpm";
|
|
129
|
+
if (exists("yarn.lock", projectRoot)) return "yarn";
|
|
40
130
|
return "npm";
|
|
41
131
|
}
|
|
42
|
-
async function getFramework() {
|
|
43
|
-
if (!exists("package.json")) return "unknown";
|
|
132
|
+
async function getFramework(projectRoot = process.cwd()) {
|
|
133
|
+
if (!exists("package.json", projectRoot)) return "unknown";
|
|
44
134
|
try {
|
|
45
|
-
const content = await readFile("package.json");
|
|
135
|
+
const content = await readFile("package.json", projectRoot);
|
|
46
136
|
const pkg = JSON.parse(content);
|
|
47
137
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
48
138
|
if (deps["@remix-run/react"] || deps["@remix-run/dev"] || deps["@react-router/dev"] || deps["@react-router/node"]) {
|
|
@@ -56,29 +146,26 @@ async function getFramework() {
|
|
|
56
146
|
}
|
|
57
147
|
return "unknown";
|
|
58
148
|
}
|
|
59
|
-
function getCssPath(framework) {
|
|
149
|
+
function getCssPath(framework, projectRoot = process.cwd()) {
|
|
60
150
|
const paths = {
|
|
151
|
+
react: ["src/index.css", "src/main.css", "src/style.css", "index.css"],
|
|
61
152
|
next: ["app/globals.css", "src/app/globals.css", "styles/globals.css"],
|
|
62
153
|
vite: ["src/index.css", "src/main.css", "src/style.css"],
|
|
63
154
|
astro: ["src/styles/global.css", "src/global.css"],
|
|
64
|
-
remix: [
|
|
65
|
-
"app/app.css",
|
|
66
|
-
"app/tailwind.css",
|
|
67
|
-
"app/globals.css",
|
|
68
|
-
"app/styles/tailwind.css"
|
|
69
|
-
],
|
|
155
|
+
remix: ["app/app.css", "app/tailwind.css", "app/globals.css", "app/styles/tailwind.css"],
|
|
70
156
|
unknown: ["src/index.css", "styles.css"]
|
|
71
157
|
};
|
|
72
158
|
for (const p of paths[framework] || []) {
|
|
73
|
-
if (exists(p)) return p;
|
|
159
|
+
if (exists(p, projectRoot)) return p;
|
|
74
160
|
}
|
|
75
161
|
return paths[framework]?.[0] || null;
|
|
76
162
|
}
|
|
77
|
-
async function installDependencies(deps, pm) {
|
|
163
|
+
async function installDependencies(deps, pm, projectRoot = process.cwd()) {
|
|
78
164
|
const installCmd = pm === "npm" ? "install" : "add";
|
|
79
165
|
console.log(`Running ${pm} ${installCmd}...`);
|
|
80
166
|
return new Promise((resolve, reject) => {
|
|
81
167
|
const child = spawn(pm, [installCmd, ...deps], {
|
|
168
|
+
cwd: projectRoot,
|
|
82
169
|
stdio: "inherit",
|
|
83
170
|
shell: true
|
|
84
171
|
});
|
|
@@ -287,113 +374,152 @@ export function cn(...inputs: ClassValue[]) {
|
|
|
287
374
|
}
|
|
288
375
|
`;
|
|
289
376
|
|
|
290
|
-
// src/
|
|
291
|
-
var
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
console.log(chalk.gray(" glass.config.json already exists."));
|
|
336
|
-
}
|
|
337
|
-
if (!exists(utilsPath)) {
|
|
338
|
-
await writeFile(utilsPath, UTILS_CN);
|
|
339
|
-
console.log(chalk.green(` Created ${utilsRelativePath}`));
|
|
340
|
-
} else {
|
|
341
|
-
console.log(chalk.gray(` ${utilsRelativePath} already exists.`));
|
|
377
|
+
// src/utils/init/run-init.ts
|
|
378
|
+
var defaultRuntime = {
|
|
379
|
+
cwd: () => process.cwd(),
|
|
380
|
+
exists,
|
|
381
|
+
readFile,
|
|
382
|
+
writeFile,
|
|
383
|
+
getFramework,
|
|
384
|
+
getPackageManager,
|
|
385
|
+
getCssPath,
|
|
386
|
+
installDependencies,
|
|
387
|
+
log: console.log
|
|
388
|
+
};
|
|
389
|
+
async function runInitCommand(options = {}, runtime = defaultRuntime) {
|
|
390
|
+
const resolvedOptions = resolveInitOptions(options, runtime.cwd());
|
|
391
|
+
runtime.log(chalk.bold("\nInitializing Glass UI..."));
|
|
392
|
+
const framework = resolvedOptions.frameworkOverride ?? await runtime.getFramework(resolvedOptions.projectRoot);
|
|
393
|
+
const pm = await runtime.getPackageManager(resolvedOptions.projectRoot);
|
|
394
|
+
const configPath = "glass.config.json";
|
|
395
|
+
const hasSrc = runtime.exists("src", resolvedOptions.projectRoot);
|
|
396
|
+
const plan = resolveInitPaths({
|
|
397
|
+
projectRoot: resolvedOptions.projectRoot,
|
|
398
|
+
hasSrc,
|
|
399
|
+
framework,
|
|
400
|
+
detectedCssPath: runtime.getCssPath(framework, resolvedOptions.projectRoot),
|
|
401
|
+
cssOverride: resolvedOptions.cssOverride,
|
|
402
|
+
componentsAliasOverride: resolvedOptions.componentsAliasOverride,
|
|
403
|
+
utilsAliasOverride: resolvedOptions.utilsAliasOverride
|
|
404
|
+
});
|
|
405
|
+
const writes = [
|
|
406
|
+
{
|
|
407
|
+
filePath: configPath,
|
|
408
|
+
content: JSON.stringify(plan.config, null, 2),
|
|
409
|
+
label: "glass.config.json"
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
filePath: plan.utilsRelativePath,
|
|
413
|
+
content: UTILS_CN,
|
|
414
|
+
label: plan.utilsRelativePath
|
|
415
|
+
},
|
|
416
|
+
{
|
|
417
|
+
filePath: plan.cssPath,
|
|
418
|
+
content: `@import "tailwindcss";
|
|
419
|
+
|
|
420
|
+
${GLASS_BASE_STYLES}`,
|
|
421
|
+
label: plan.cssPath
|
|
342
422
|
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
}
|
|
350
|
-
} catch (e) {
|
|
423
|
+
];
|
|
424
|
+
for (const write of writes.slice(0, 2)) {
|
|
425
|
+
const alreadyExists = runtime.exists(write.filePath, resolvedOptions.projectRoot);
|
|
426
|
+
if (alreadyExists && !resolvedOptions.force) {
|
|
427
|
+
runtime.log(chalk.yellow(` Skipped ${write.label} (already exists)`));
|
|
428
|
+
continue;
|
|
351
429
|
}
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
430
|
+
await runtime.writeFile(write.filePath, write.content, resolvedOptions.projectRoot);
|
|
431
|
+
runtime.log(
|
|
432
|
+
alreadyExists ? chalk.green(` Replaced ${write.label}`) : chalk.green(` Created ${write.label}`)
|
|
433
|
+
);
|
|
434
|
+
}
|
|
435
|
+
const cssWrite = writes[2];
|
|
436
|
+
const cssAlreadyExists = runtime.exists(cssWrite.filePath, resolvedOptions.projectRoot);
|
|
437
|
+
if (!cssAlreadyExists) {
|
|
438
|
+
await runtime.writeFile(cssWrite.filePath, cssWrite.content, resolvedOptions.projectRoot);
|
|
439
|
+
runtime.log(chalk.green(` Created ${cssWrite.label}`));
|
|
440
|
+
} else if (resolvedOptions.force) {
|
|
441
|
+
await runtime.writeFile(cssWrite.filePath, cssWrite.content, resolvedOptions.projectRoot);
|
|
442
|
+
runtime.log(chalk.green(` Replaced ${cssWrite.label}`));
|
|
443
|
+
} else {
|
|
444
|
+
const existingCss = await runtime.readFile(cssWrite.filePath, resolvedOptions.projectRoot) ?? "";
|
|
445
|
+
if (existingCss.includes("--glass-bg")) {
|
|
446
|
+
runtime.log(chalk.yellow(` Skipped ${cssWrite.label} (already exists)`));
|
|
362
447
|
} else {
|
|
363
|
-
|
|
448
|
+
const updatedCss = `${existingCss.trimEnd()}
|
|
449
|
+
|
|
450
|
+
${GLASS_BASE_STYLES}
|
|
451
|
+
`;
|
|
452
|
+
await runtime.writeFile(cssWrite.filePath, updatedCss, resolvedOptions.projectRoot);
|
|
453
|
+
runtime.log(chalk.green(` Updated ${cssWrite.label} with Glass tokens`));
|
|
364
454
|
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
console.log(chalk.bold.green("\nSetup complete."));
|
|
373
|
-
console.log(`Try adding a component:
|
|
374
|
-
`);
|
|
375
|
-
console.log(
|
|
376
|
-
chalk.cyan(` ${runCommand} @glass-ui-kit/cli@latest add card`)
|
|
455
|
+
}
|
|
456
|
+
if (resolvedOptions.install) {
|
|
457
|
+
runtime.log(chalk.cyan(` Installing dependencies (clsx, tailwind-merge, lucide-react)...`));
|
|
458
|
+
await runtime.installDependencies(
|
|
459
|
+
["clsx", "tailwind-merge", "lucide-react"],
|
|
460
|
+
pm,
|
|
461
|
+
resolvedOptions.projectRoot
|
|
377
462
|
);
|
|
378
|
-
|
|
463
|
+
} else {
|
|
464
|
+
runtime.log(chalk.gray(" Skipped dependency installation (--no-install)."));
|
|
465
|
+
}
|
|
466
|
+
const runCommand = pm === "bun" ? "bunx" : pm === "pnpm" ? "pnpm dlx" : "npx";
|
|
467
|
+
runtime.log(chalk.bold.green("\nSetup complete."));
|
|
468
|
+
runtime.log(chalk.gray(` Project root: ${resolvedOptions.projectRoot}`));
|
|
469
|
+
runtime.log(chalk.gray(` Framework: ${plan.framework}`));
|
|
470
|
+
runtime.log("Try adding a component:\n");
|
|
471
|
+
runtime.log(chalk.cyan(` ${runCommand} @glass-ui-kit/cli@latest add card`));
|
|
472
|
+
runtime.log("");
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
// src/commands/init.ts
|
|
476
|
+
var InitCommandError = class extends Error {
|
|
477
|
+
};
|
|
478
|
+
async function runInitCommand2(options = {}, runtime = defaultRuntime) {
|
|
479
|
+
try {
|
|
480
|
+
await runInitCommand(options, runtime);
|
|
379
481
|
} catch (error) {
|
|
380
|
-
console.error(chalk.red("\nInitialization failed:"));
|
|
381
482
|
if (error instanceof Error) {
|
|
382
|
-
|
|
383
|
-
} else {
|
|
384
|
-
console.error(chalk.gray(String(error)));
|
|
483
|
+
throw new InitCommandError(error.message);
|
|
385
484
|
}
|
|
386
|
-
|
|
485
|
+
throw new InitCommandError(String(error));
|
|
387
486
|
}
|
|
388
|
-
}
|
|
487
|
+
}
|
|
488
|
+
function createInitAction(deps = {
|
|
489
|
+
runInitCommand: runInitCommand2,
|
|
490
|
+
error: console.error,
|
|
491
|
+
exit: process.exit
|
|
492
|
+
}) {
|
|
493
|
+
return async (options = {}) => {
|
|
494
|
+
try {
|
|
495
|
+
await deps.runInitCommand({
|
|
496
|
+
cwd: options.cwd,
|
|
497
|
+
css: options.css,
|
|
498
|
+
components: options.components,
|
|
499
|
+
utils: options.utils,
|
|
500
|
+
framework: options.framework,
|
|
501
|
+
force: options.force === true,
|
|
502
|
+
install: options.install
|
|
503
|
+
});
|
|
504
|
+
} catch (error) {
|
|
505
|
+
deps.error(chalk2.red("\nInitialization failed:"));
|
|
506
|
+
if (error instanceof Error) {
|
|
507
|
+
deps.error(chalk2.gray(error.message));
|
|
508
|
+
} else {
|
|
509
|
+
deps.error(chalk2.gray(String(error)));
|
|
510
|
+
}
|
|
511
|
+
deps.exit(1);
|
|
512
|
+
}
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
var init = new Command().name("init").description("Initialize configuration and dependencies").option("-y, --yes", "Skip confirmation prompt", false).option("--cwd <path>", "Run the command against another project directory").option("--css <path>", "Use a custom CSS file instead of autodetecting one").option("--components <alias>", "Set the components alias saved in glass.config.json").option("--utils <alias>", "Set the utils alias saved in glass.config.json").option("--framework <name>", "Force the framework instead of autodetecting it").option("--force", "Overwrite generated files if they already exist").option("--no-install", "Skip dependency installation").action(createInitAction());
|
|
389
516
|
|
|
390
517
|
// src/commands/add.ts
|
|
391
|
-
import
|
|
518
|
+
import chalk4 from "chalk";
|
|
392
519
|
import { Command as Command2 } from "commander";
|
|
393
|
-
import path4 from "path";
|
|
394
520
|
|
|
395
521
|
// src/utils/registry.ts
|
|
396
|
-
import
|
|
522
|
+
import path4 from "path";
|
|
397
523
|
import os from "os";
|
|
398
524
|
import fs2 from "fs/promises";
|
|
399
525
|
|
|
@@ -427,8 +553,8 @@ var registryIndexSchema = z.array(registryItemSchema);
|
|
|
427
553
|
|
|
428
554
|
// src/utils/registry.ts
|
|
429
555
|
var DEFAULT_REGISTRY_URL = "https://ui-glass.vercel.app/registry.json";
|
|
430
|
-
var CACHE_DIR =
|
|
431
|
-
var CACHE_FILE =
|
|
556
|
+
var CACHE_DIR = path4.join(os.homedir(), ".glass-ui");
|
|
557
|
+
var CACHE_FILE = path4.join(CACHE_DIR, "registry.json");
|
|
432
558
|
var CACHE_TTL = 1e3 * 60 * 60 * 24;
|
|
433
559
|
function getRegistryUrl() {
|
|
434
560
|
return process.env.GLASS_UI_REGISTRY_URL || DEFAULT_REGISTRY_URL;
|
|
@@ -469,14 +595,10 @@ async function fetchRegistry() {
|
|
|
469
595
|
try {
|
|
470
596
|
response = await fetch(url);
|
|
471
597
|
} catch (error) {
|
|
472
|
-
throw new Error(
|
|
473
|
-
"Network error: Unable to connect to registry. Check your internet connection."
|
|
474
|
-
);
|
|
598
|
+
throw new Error("Network error: Unable to connect to registry. Check your internet connection.");
|
|
475
599
|
}
|
|
476
600
|
if (!response.ok) {
|
|
477
|
-
throw new Error(
|
|
478
|
-
`Registry unavailable. URL: ${url} (Status: ${response.status})`
|
|
479
|
-
);
|
|
601
|
+
throw new Error(`Registry unavailable. URL: ${url} (Status: ${response.status})`);
|
|
480
602
|
}
|
|
481
603
|
let data;
|
|
482
604
|
try {
|
|
@@ -497,6 +619,85 @@ async function fetchRegistry() {
|
|
|
497
619
|
function getItem(registry, name) {
|
|
498
620
|
return registry.find((item) => item.name === name);
|
|
499
621
|
}
|
|
622
|
+
function getItems(registry, names) {
|
|
623
|
+
const items = [];
|
|
624
|
+
const missing = [];
|
|
625
|
+
for (const name of names) {
|
|
626
|
+
const item = getItem(registry, name);
|
|
627
|
+
if (item) {
|
|
628
|
+
items.push(item);
|
|
629
|
+
continue;
|
|
630
|
+
}
|
|
631
|
+
missing.push(name);
|
|
632
|
+
}
|
|
633
|
+
return { items, missing };
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
// src/utils/add/selection.ts
|
|
637
|
+
function dedupeNames(names) {
|
|
638
|
+
const uniqueNames = [];
|
|
639
|
+
const seen = /* @__PURE__ */ new Set();
|
|
640
|
+
for (const name of names) {
|
|
641
|
+
if (seen.has(name)) {
|
|
642
|
+
continue;
|
|
643
|
+
}
|
|
644
|
+
seen.add(name);
|
|
645
|
+
uniqueNames.push(name);
|
|
646
|
+
}
|
|
647
|
+
return uniqueNames;
|
|
648
|
+
}
|
|
649
|
+
function resolveAddSelection(registry, requestedNames, selectAll) {
|
|
650
|
+
if (selectAll && requestedNames.length > 0) {
|
|
651
|
+
return { ok: false, reason: "invalid-combination" };
|
|
652
|
+
}
|
|
653
|
+
if (selectAll) {
|
|
654
|
+
return { ok: true, items: registry };
|
|
655
|
+
}
|
|
656
|
+
const uniqueRequestedNames = dedupeNames(requestedNames);
|
|
657
|
+
if (uniqueRequestedNames.length === 0) {
|
|
658
|
+
return { ok: false, reason: "empty-selection" };
|
|
659
|
+
}
|
|
660
|
+
const { items, missing } = getItems(registry, uniqueRequestedNames);
|
|
661
|
+
if (missing.length > 0) {
|
|
662
|
+
return { ok: false, reason: "missing-components", names: missing };
|
|
663
|
+
}
|
|
664
|
+
return { ok: true, items };
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
// src/utils/add/dependencies.ts
|
|
668
|
+
function collectDependencies(items) {
|
|
669
|
+
const dependencies = [];
|
|
670
|
+
const seen = /* @__PURE__ */ new Set();
|
|
671
|
+
for (const item of items) {
|
|
672
|
+
for (const dependency of item.dependencies || []) {
|
|
673
|
+
if (seen.has(dependency)) {
|
|
674
|
+
continue;
|
|
675
|
+
}
|
|
676
|
+
seen.add(dependency);
|
|
677
|
+
dependencies.push(dependency);
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
return dependencies;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
// src/utils/add/paths.ts
|
|
684
|
+
function resolveTargetDir(config, hasSrc, explicitPath) {
|
|
685
|
+
if (explicitPath) {
|
|
686
|
+
return explicitPath;
|
|
687
|
+
}
|
|
688
|
+
const targetDirAlias = config.aliases.components || "@/components/ui";
|
|
689
|
+
const relativeAliasPath = targetDirAlias.replace(/^[@~]\//, "");
|
|
690
|
+
if (config.framework === "remix") {
|
|
691
|
+
return `./app/${relativeAliasPath}`;
|
|
692
|
+
}
|
|
693
|
+
if (hasSrc) {
|
|
694
|
+
return `./src/${relativeAliasPath}`;
|
|
695
|
+
}
|
|
696
|
+
return `./${relativeAliasPath}`;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
// src/utils/add/planner.ts
|
|
700
|
+
import path5 from "path";
|
|
500
701
|
|
|
501
702
|
// src/utils/transformers.ts
|
|
502
703
|
function transformImports(content, config) {
|
|
@@ -519,63 +720,167 @@ function transformImports(content, config) {
|
|
|
519
720
|
return transformed;
|
|
520
721
|
}
|
|
521
722
|
|
|
522
|
-
// src/
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
723
|
+
// src/utils/add/planner.ts
|
|
724
|
+
function buildWritePlan(items, config, hasSrc, options) {
|
|
725
|
+
const targetDir = resolveTargetDir(config, hasSrc, options.path);
|
|
726
|
+
return items.flatMap(
|
|
727
|
+
(item) => item.files.filter((file) => Boolean(file.content)).map((file) => {
|
|
728
|
+
const fileName = path5.basename(file.path);
|
|
729
|
+
const filePath = path5.join(targetDir, fileName);
|
|
730
|
+
return {
|
|
731
|
+
filePath,
|
|
732
|
+
content: transformImports(file.content || "", config),
|
|
733
|
+
action: !options.overwrite && options.exists(filePath) ? "skip-existing" : "write"
|
|
734
|
+
};
|
|
735
|
+
})
|
|
736
|
+
);
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
// src/utils/add/run-add.ts
|
|
740
|
+
import path6 from "path";
|
|
741
|
+
import chalk3 from "chalk";
|
|
742
|
+
var defaultRuntime2 = {
|
|
743
|
+
cwd: () => process.cwd(),
|
|
744
|
+
exists,
|
|
745
|
+
readFile,
|
|
746
|
+
writeFile,
|
|
747
|
+
fetchRegistry,
|
|
748
|
+
getPackageManager,
|
|
749
|
+
installDependencies,
|
|
750
|
+
log: console.log
|
|
751
|
+
};
|
|
752
|
+
function buildMissingComponentsMessage(names) {
|
|
753
|
+
return `Components not found: ${names.join(", ")}.`;
|
|
754
|
+
}
|
|
755
|
+
function resolveProjectRoot(cwdOption, cwd) {
|
|
756
|
+
return cwdOption ? path6.resolve(cwd, cwdOption) : cwd;
|
|
757
|
+
}
|
|
758
|
+
async function runAddCommand(componentNames = [], options = {}, runtime = defaultRuntime2) {
|
|
759
|
+
const projectRoot = resolveProjectRoot(options.cwd, runtime.cwd?.() ?? process.cwd());
|
|
760
|
+
if (options.depsOnly && options.install === false) {
|
|
761
|
+
throw new Error("invalid-install-combination");
|
|
762
|
+
}
|
|
763
|
+
if (!runtime.exists("glass.config.json", projectRoot)) {
|
|
764
|
+
throw new Error("config-not-found");
|
|
765
|
+
}
|
|
766
|
+
const config = JSON.parse(await runtime.readFile("glass.config.json", projectRoot));
|
|
767
|
+
runtime.log(chalk3.bold("Fetching components..."));
|
|
768
|
+
const registry = await runtime.fetchRegistry();
|
|
769
|
+
const selection = resolveAddSelection(registry, componentNames, Boolean(options.all));
|
|
770
|
+
if (!selection.ok) {
|
|
771
|
+
if (selection.reason === "invalid-combination") {
|
|
772
|
+
throw new Error("invalid-combination");
|
|
539
773
|
}
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
const relativeAliasPath = targetDirAlias.replace(/^[@~]\//, "");
|
|
543
|
-
let targetDir = "";
|
|
544
|
-
if (config.framework === "remix") {
|
|
545
|
-
targetDir = `./app/${relativeAliasPath}`;
|
|
546
|
-
} else if (hasSrc) {
|
|
547
|
-
targetDir = `./src/${relativeAliasPath}`;
|
|
548
|
-
} else {
|
|
549
|
-
targetDir = `./${relativeAliasPath}`;
|
|
774
|
+
if (selection.reason === "missing-components") {
|
|
775
|
+
throw new Error(buildMissingComponentsMessage(selection.names || []));
|
|
550
776
|
}
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
777
|
+
throw new Error("empty-selection");
|
|
778
|
+
}
|
|
779
|
+
const shouldWrite = options.depsOnly !== true;
|
|
780
|
+
const shouldInstall = options.install !== false;
|
|
781
|
+
if (shouldWrite) {
|
|
782
|
+
const plannedWrites = buildWritePlan(
|
|
783
|
+
selection.items,
|
|
784
|
+
config,
|
|
785
|
+
runtime.exists("src", projectRoot),
|
|
786
|
+
{
|
|
787
|
+
exists: (filePath) => runtime.exists(filePath, projectRoot),
|
|
788
|
+
overwrite: options.overwrite,
|
|
789
|
+
path: options.path
|
|
790
|
+
}
|
|
791
|
+
);
|
|
792
|
+
for (const file of plannedWrites) {
|
|
793
|
+
if (file.action === "skip-existing") {
|
|
794
|
+
runtime.log(chalk3.yellow(` Skipped ${file.filePath} (already exists)`));
|
|
555
795
|
continue;
|
|
556
796
|
}
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
console.log(chalk2.green(` Created ${filePath}`));
|
|
797
|
+
await runtime.writeFile(file.filePath, file.content, projectRoot);
|
|
798
|
+
runtime.log(chalk3.green(` Created ${file.filePath}`));
|
|
560
799
|
}
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
800
|
+
}
|
|
801
|
+
const dependencies = collectDependencies(selection.items);
|
|
802
|
+
if (shouldInstall && dependencies.length > 0) {
|
|
803
|
+
const pm = await runtime.getPackageManager(projectRoot);
|
|
804
|
+
runtime.log(chalk3.cyan(" Installing dependencies..."));
|
|
805
|
+
await runtime.installDependencies(dependencies, pm, projectRoot);
|
|
806
|
+
}
|
|
807
|
+
runtime.log(chalk3.bold.green("\nDone."));
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
// src/commands/add.ts
|
|
811
|
+
var AddCommandError = class extends Error {
|
|
812
|
+
constructor(code, message) {
|
|
813
|
+
super(message);
|
|
814
|
+
this.code = code;
|
|
815
|
+
}
|
|
816
|
+
code;
|
|
817
|
+
};
|
|
818
|
+
async function runAddCommand2(componentNames = [], options = {}, runtime = defaultRuntime2) {
|
|
819
|
+
try {
|
|
820
|
+
await runAddCommand(componentNames, options, runtime);
|
|
567
821
|
} catch (error) {
|
|
568
|
-
console.error(chalk2.red("\nOperation failed:"));
|
|
569
822
|
if (error instanceof Error) {
|
|
570
|
-
|
|
823
|
+
if (error.message === "config-not-found") {
|
|
824
|
+
throw new AddCommandError("config-not-found", "Configuration file not found.");
|
|
825
|
+
}
|
|
826
|
+
if (error.message === "invalid-combination") {
|
|
827
|
+
throw new AddCommandError(
|
|
828
|
+
"invalid-combination",
|
|
829
|
+
"Cannot combine --all with specific component names."
|
|
830
|
+
);
|
|
831
|
+
}
|
|
832
|
+
if (error.message === "invalid-install-combination") {
|
|
833
|
+
throw new AddCommandError(
|
|
834
|
+
"invalid-combination",
|
|
835
|
+
"Cannot combine --deps-only with --no-install."
|
|
836
|
+
);
|
|
837
|
+
}
|
|
838
|
+
if (error.message === "empty-selection") {
|
|
839
|
+
throw new AddCommandError(
|
|
840
|
+
"empty-selection",
|
|
841
|
+
"Please specify at least one component or use --all."
|
|
842
|
+
);
|
|
843
|
+
}
|
|
844
|
+
if (error.message.startsWith("Components not found:")) {
|
|
845
|
+
throw new AddCommandError("missing-components", error.message);
|
|
846
|
+
}
|
|
571
847
|
}
|
|
572
|
-
|
|
848
|
+
throw error;
|
|
573
849
|
}
|
|
574
|
-
}
|
|
850
|
+
}
|
|
851
|
+
function createAddAction(deps = {
|
|
852
|
+
runAddCommand: runAddCommand2,
|
|
853
|
+
error: console.error,
|
|
854
|
+
log: console.log,
|
|
855
|
+
exit: process.exit
|
|
856
|
+
}) {
|
|
857
|
+
return async (componentNames = [], options = {}) => {
|
|
858
|
+
try {
|
|
859
|
+
await deps.runAddCommand(componentNames, options);
|
|
860
|
+
} catch (error) {
|
|
861
|
+
if (error instanceof AddCommandError) {
|
|
862
|
+
if (error.code === "config-not-found") {
|
|
863
|
+
deps.error(chalk4.red(error.message));
|
|
864
|
+
deps.log(chalk4.gray("Please run the init command first:"));
|
|
865
|
+
deps.log(chalk4.cyan(" npx @glass-ui-kit/cli@latest init"));
|
|
866
|
+
deps.exit(1);
|
|
867
|
+
}
|
|
868
|
+
deps.error(chalk4.red(error.message));
|
|
869
|
+
deps.exit(1);
|
|
870
|
+
}
|
|
871
|
+
deps.error(chalk4.red("\nOperation failed:"));
|
|
872
|
+
if (error instanceof Error) {
|
|
873
|
+
deps.error(chalk4.gray(` ${error.message}`));
|
|
874
|
+
}
|
|
875
|
+
deps.exit(1);
|
|
876
|
+
}
|
|
877
|
+
};
|
|
878
|
+
}
|
|
879
|
+
var add = new Command2().name("add").description("Add one or more components to your project").argument("[components...]", "The components to add").option("--all", "Add all available components").option("--overwrite", "Replace existing component files").option("--path <dir>", "Use a custom output directory").option("--no-install", "Skip dependency installation").option("--deps-only", "Install dependencies without writing component files").option("--cwd <path>", "Run the command against another project directory").action(createAddAction());
|
|
575
880
|
|
|
576
881
|
// src/index.ts
|
|
577
882
|
var program = new Command3();
|
|
578
|
-
program.name("glass-ui").description("The Glass UI CLI - Add glassmorphism components to your app").version("0.
|
|
883
|
+
program.name("glass-ui").description("The Glass UI CLI - Add glassmorphism components to your app").version("0.2.5");
|
|
579
884
|
program.addCommand(init);
|
|
580
885
|
program.addCommand(add);
|
|
581
886
|
program.parse(process.argv);
|
package/package.json
CHANGED
|
@@ -1,59 +1,60 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@glass-ui-kit/cli",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "The official CLI for Glass UI. Add glassmorphism components to your React projects in seconds.",
|
|
5
|
-
"keywords": [
|
|
6
|
-
"glassmorphism",
|
|
7
|
-
"design-system",
|
|
8
|
-
"react",
|
|
9
|
-
"cli",
|
|
10
|
-
"ui",
|
|
11
|
-
"tailwind"
|
|
12
|
-
],
|
|
13
|
-
"homepage": "https://github.com/jntellez/glass-ui#readme",
|
|
14
|
-
"bugs": {
|
|
15
|
-
"url": "https://github.com/jntellez/glass-ui/issues"
|
|
16
|
-
},
|
|
17
|
-
"repository": {
|
|
18
|
-
"type": "git",
|
|
19
|
-
"url": "git+https://github.com/jntellez/glass-ui.git",
|
|
20
|
-
"directory": "packages/cli"
|
|
21
|
-
},
|
|
22
|
-
"license": "MIT",
|
|
23
|
-
"author": "Glass UI Team",
|
|
24
|
-
"type": "module",
|
|
25
|
-
"bin": {
|
|
26
|
-
"glass-ui": "./dist/index.js"
|
|
27
|
-
},
|
|
28
|
-
"files": [
|
|
29
|
-
"dist",
|
|
30
|
-
"README.md"
|
|
31
|
-
],
|
|
32
|
-
"engines": {
|
|
33
|
-
"node": ">=18.0.0"
|
|
34
|
-
},
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
"
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
"
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
"
|
|
58
|
-
|
|
59
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@glass-ui-kit/cli",
|
|
3
|
+
"version": "0.2.5",
|
|
4
|
+
"description": "The official CLI for Glass UI. Add glassmorphism components to your React projects in seconds.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"glassmorphism",
|
|
7
|
+
"design-system",
|
|
8
|
+
"react",
|
|
9
|
+
"cli",
|
|
10
|
+
"ui",
|
|
11
|
+
"tailwind"
|
|
12
|
+
],
|
|
13
|
+
"homepage": "https://github.com/jntellez/glass-ui#readme",
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/jntellez/glass-ui/issues"
|
|
16
|
+
},
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/jntellez/glass-ui.git",
|
|
20
|
+
"directory": "packages/cli"
|
|
21
|
+
},
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"author": "Glass UI Team",
|
|
24
|
+
"type": "module",
|
|
25
|
+
"bin": {
|
|
26
|
+
"glass-ui": "./dist/index.js"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist",
|
|
30
|
+
"README.md"
|
|
31
|
+
],
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=18.0.0"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"chalk": "^5.3.0",
|
|
37
|
+
"commander": "^11.1.0",
|
|
38
|
+
"node-fetch": "^3.3.2",
|
|
39
|
+
"zod": "^3.22.4"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@types/node": "^20.11.0",
|
|
43
|
+
"bun-types": "latest",
|
|
44
|
+
"vitest": "^3.2.4",
|
|
45
|
+
"tsup": "^8.0.1",
|
|
46
|
+
"typescript": "^5.3.3",
|
|
47
|
+
"@glass-ui-kit/schema": "0.0.1",
|
|
48
|
+
"@glass-ui-kit/tsconfig": "0.0.1"
|
|
49
|
+
},
|
|
50
|
+
"publishConfig": {
|
|
51
|
+
"access": "public"
|
|
52
|
+
},
|
|
53
|
+
"scripts": {
|
|
54
|
+
"sync": "node scripts/sync-styles.mjs",
|
|
55
|
+
"build": "pnpm run sync && tsup src/index.ts --format esm --clean",
|
|
56
|
+
"dev": "pnpm run sync && bun run ./src/index.ts",
|
|
57
|
+
"lint": "eslint src",
|
|
58
|
+
"test": "vitest run"
|
|
59
|
+
}
|
|
60
|
+
}
|