starwind 1.12.4 → 1.14.0
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 +2 -0
- package/dist/index.js +456 -169
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Command } from "commander";
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "starwind",
|
|
9
|
-
version: "1.
|
|
9
|
+
version: "1.14.0",
|
|
10
10
|
description: "Add beautifully designed components to your Astro applications",
|
|
11
11
|
license: "MIT",
|
|
12
12
|
author: {
|
|
@@ -44,6 +44,8 @@ var package_default = {
|
|
|
44
44
|
dev: "tsup --watch",
|
|
45
45
|
"cli:link": "pnpm link --global",
|
|
46
46
|
"cli:unlink": "pnpm rm --global starwind",
|
|
47
|
+
"cli:yalc:link": "yalc publish && yalc link @starwind-ui/core",
|
|
48
|
+
"cli:yalc:unlink": "yalc remove @starwind-ui/core && yalc remove starwind",
|
|
47
49
|
test: "vitest",
|
|
48
50
|
"test:run": "vitest run",
|
|
49
51
|
"test:coverage": "vitest run --coverage",
|
|
@@ -56,7 +58,7 @@ var package_default = {
|
|
|
56
58
|
},
|
|
57
59
|
dependencies: {
|
|
58
60
|
"@clack/prompts": "^0.11.0",
|
|
59
|
-
"@starwind-ui/core": "1.
|
|
61
|
+
"@starwind-ui/core": "1.14.0",
|
|
60
62
|
chalk: "^5.6.2",
|
|
61
63
|
commander: "^14.0.2",
|
|
62
64
|
execa: "^9.6.0",
|
|
@@ -77,7 +79,7 @@ var package_default = {
|
|
|
77
79
|
};
|
|
78
80
|
|
|
79
81
|
// src/commands/add.ts
|
|
80
|
-
import * as
|
|
82
|
+
import * as p9 from "@clack/prompts";
|
|
81
83
|
import { execa as execa2 } from "execa";
|
|
82
84
|
|
|
83
85
|
// src/utils/constants.ts
|
|
@@ -158,6 +160,21 @@ async function getConfig() {
|
|
|
158
160
|
async function updateConfig(updates, options = { appendComponents: true }) {
|
|
159
161
|
const currentConfig = await getConfig();
|
|
160
162
|
const currentComponents = Array.isArray(currentConfig.components) ? currentConfig.components : [];
|
|
163
|
+
let finalComponents = currentComponents;
|
|
164
|
+
if (updates.components) {
|
|
165
|
+
if (options.appendComponents) {
|
|
166
|
+
const componentMap = /* @__PURE__ */ new Map();
|
|
167
|
+
for (const comp of currentComponents) {
|
|
168
|
+
componentMap.set(comp.name, comp);
|
|
169
|
+
}
|
|
170
|
+
for (const comp of updates.components) {
|
|
171
|
+
componentMap.set(comp.name, comp);
|
|
172
|
+
}
|
|
173
|
+
finalComponents = Array.from(componentMap.values());
|
|
174
|
+
} else {
|
|
175
|
+
finalComponents = updates.components;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
161
178
|
const newConfig = {
|
|
162
179
|
...currentConfig,
|
|
163
180
|
tailwind: {
|
|
@@ -165,7 +182,7 @@ async function updateConfig(updates, options = { appendComponents: true }) {
|
|
|
165
182
|
...updates.tailwind || {}
|
|
166
183
|
},
|
|
167
184
|
componentDir: updates.componentDir ? updates.componentDir : currentConfig.componentDir,
|
|
168
|
-
components:
|
|
185
|
+
components: finalComponents
|
|
169
186
|
};
|
|
170
187
|
try {
|
|
171
188
|
await writeJsonFile(PATHS.LOCAL_CONFIG_FILE, newConfig);
|
|
@@ -265,7 +282,7 @@ async function copyComponent(name, overwrite = false) {
|
|
|
265
282
|
return {
|
|
266
283
|
status: "skipped",
|
|
267
284
|
name,
|
|
268
|
-
version: existingComponent?.version
|
|
285
|
+
version: existingComponent?.version ?? "unknown"
|
|
269
286
|
};
|
|
270
287
|
}
|
|
271
288
|
const componentDir = path.join(config.componentDir, "starwind", name);
|
|
@@ -382,7 +399,7 @@ async function updateComponent(name, currentVersion, skipConfirm) {
|
|
|
382
399
|
return {
|
|
383
400
|
name,
|
|
384
401
|
status: "failed",
|
|
385
|
-
error: result.error
|
|
402
|
+
error: result.status === "failed" ? result.error : "Failed to update component"
|
|
386
403
|
};
|
|
387
404
|
}
|
|
388
405
|
} catch (error) {
|
|
@@ -634,7 +651,7 @@ import { confirm as confirm2, multiselect } from "@clack/prompts";
|
|
|
634
651
|
async function selectComponents() {
|
|
635
652
|
const components = await getAllComponents();
|
|
636
653
|
const selected = await multiselect({
|
|
637
|
-
message: "Select components to add",
|
|
654
|
+
message: "Select components to add ('a' for all, space to select, enter to confirm)",
|
|
638
655
|
options: components.map((component) => ({
|
|
639
656
|
label: component.name,
|
|
640
657
|
value: component.name
|
|
@@ -654,16 +671,10 @@ async function confirmStarwindDependencies(componentNames) {
|
|
|
654
671
|
}
|
|
655
672
|
const toInstall = resolutions.filter((r) => r.needsInstall);
|
|
656
673
|
const toUpdate = resolutions.filter((r) => r.needsUpdate);
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
message += `${highlighter.info("Components to install:")}
|
|
660
|
-
`;
|
|
661
|
-
for (const dep of toInstall) {
|
|
662
|
-
message += ` \u2022 ${dep.component} (requires ${dep.requiredVersion})
|
|
663
|
-
`;
|
|
664
|
-
}
|
|
665
|
-
message += "\n";
|
|
674
|
+
if (toUpdate.length === 0) {
|
|
675
|
+
return true;
|
|
666
676
|
}
|
|
677
|
+
let message = "This component has Starwind component dependencies that need updating:\n\n";
|
|
667
678
|
if (toUpdate.length > 0) {
|
|
668
679
|
message += `${highlighter.warn("Components to update:")}
|
|
669
680
|
`;
|
|
@@ -673,7 +684,16 @@ async function confirmStarwindDependencies(componentNames) {
|
|
|
673
684
|
}
|
|
674
685
|
message += "\n";
|
|
675
686
|
}
|
|
676
|
-
|
|
687
|
+
if (toInstall.length > 0) {
|
|
688
|
+
message += `${highlighter.info("Components to install (automatic):")}
|
|
689
|
+
`;
|
|
690
|
+
for (const dep of toInstall) {
|
|
691
|
+
message += ` \u2022 ${dep.component} (requires ${dep.requiredVersion})
|
|
692
|
+
`;
|
|
693
|
+
}
|
|
694
|
+
message += "\n";
|
|
695
|
+
}
|
|
696
|
+
message += "Proceed with updates?";
|
|
677
697
|
const confirmed = await confirm2({ message });
|
|
678
698
|
if (typeof confirmed === "symbol") {
|
|
679
699
|
return false;
|
|
@@ -700,7 +720,7 @@ async function confirmInstall(component) {
|
|
|
700
720
|
const dependenciesToInstall = await filterUninstalledDependencies(npmDependencies);
|
|
701
721
|
if (dependenciesToInstall.length > 0) {
|
|
702
722
|
const confirmed = await confirm2({
|
|
703
|
-
message: `
|
|
723
|
+
message: `The ${component.name} component requires the following npm dependencies: ${dependenciesToInstall.join(", ")}. Install them?`
|
|
704
724
|
});
|
|
705
725
|
if (typeof confirmed === "symbol" || !confirmed) {
|
|
706
726
|
return false;
|
|
@@ -806,7 +826,7 @@ async function installStarwindDependencies(resolutions) {
|
|
|
806
826
|
const componentsToUpdate = [];
|
|
807
827
|
for (const resolution of resolutions) {
|
|
808
828
|
if (resolution.needsInstall) {
|
|
809
|
-
const result = await copyComponent(resolution.component);
|
|
829
|
+
const result = await copyComponent(resolution.component, true);
|
|
810
830
|
results.push(result);
|
|
811
831
|
if (result.status === "installed" && result.version) {
|
|
812
832
|
componentsToInstall.push({ name: result.name, version: result.version });
|
|
@@ -951,7 +971,7 @@ async function isValidComponent(component, availableComponents) {
|
|
|
951
971
|
|
|
952
972
|
// src/commands/init.ts
|
|
953
973
|
import path2 from "path";
|
|
954
|
-
import * as
|
|
974
|
+
import * as p8 from "@clack/prompts";
|
|
955
975
|
import semver4 from "semver";
|
|
956
976
|
|
|
957
977
|
// src/templates/starwind.css.ts
|
|
@@ -1192,10 +1212,258 @@ ${content}`;
|
|
|
1192
1212
|
}
|
|
1193
1213
|
}
|
|
1194
1214
|
|
|
1215
|
+
// src/utils/env.ts
|
|
1216
|
+
import * as p5 from "@clack/prompts";
|
|
1217
|
+
import fs4 from "fs-extra";
|
|
1218
|
+
var ENV_LOCAL_PATH = ".env.local";
|
|
1219
|
+
var GITIGNORE_PATH = ".gitignore";
|
|
1220
|
+
var STARWIND_ENV_CONTENT = `# Starwind Pro registry setup
|
|
1221
|
+
STARWIND_LICENSE_KEY=your_starwind_pro_license_key
|
|
1222
|
+
`;
|
|
1223
|
+
var DEFAULT_GITIGNORE_CONTENT = `# build output
|
|
1224
|
+
dist/
|
|
1225
|
+
|
|
1226
|
+
# generated types
|
|
1227
|
+
.astro/
|
|
1228
|
+
|
|
1229
|
+
# dependencies
|
|
1230
|
+
node_modules/
|
|
1231
|
+
|
|
1232
|
+
# logs
|
|
1233
|
+
npm-debug.log*
|
|
1234
|
+
yarn-debug.log*
|
|
1235
|
+
yarn-error.log*
|
|
1236
|
+
pnpm-debug.log*
|
|
1237
|
+
|
|
1238
|
+
# environment variables
|
|
1239
|
+
.env
|
|
1240
|
+
.env.local
|
|
1241
|
+
.env.production
|
|
1242
|
+
|
|
1243
|
+
# macOS-specific files
|
|
1244
|
+
.DS_Store
|
|
1245
|
+
|
|
1246
|
+
# jetbrains setting folder
|
|
1247
|
+
.idea/
|
|
1248
|
+
`;
|
|
1249
|
+
function hasStarwindLicenseKey(content) {
|
|
1250
|
+
return /^STARWIND_LICENSE_KEY\s*=/m.test(content);
|
|
1251
|
+
}
|
|
1252
|
+
function hasEnvLocalInGitignore(content) {
|
|
1253
|
+
const lines = content.split(/\r?\n/);
|
|
1254
|
+
return lines.some((line) => {
|
|
1255
|
+
const trimmed = line.trim();
|
|
1256
|
+
return trimmed === ".env.local" || trimmed === ".env.local/" || trimmed === ".env*" || trimmed === ".env.*" || trimmed === "*.local";
|
|
1257
|
+
});
|
|
1258
|
+
}
|
|
1259
|
+
async function setupEnvLocal() {
|
|
1260
|
+
try {
|
|
1261
|
+
const exists = await fileExists(ENV_LOCAL_PATH);
|
|
1262
|
+
if (exists) {
|
|
1263
|
+
const content = await fs4.readFile(ENV_LOCAL_PATH, "utf-8");
|
|
1264
|
+
if (hasStarwindLicenseKey(content)) {
|
|
1265
|
+
return true;
|
|
1266
|
+
}
|
|
1267
|
+
const newContent = STARWIND_ENV_CONTENT + "\n" + content;
|
|
1268
|
+
await fs4.writeFile(ENV_LOCAL_PATH, newContent, "utf-8");
|
|
1269
|
+
} else {
|
|
1270
|
+
await fs4.writeFile(ENV_LOCAL_PATH, STARWIND_ENV_CONTENT, "utf-8");
|
|
1271
|
+
}
|
|
1272
|
+
return true;
|
|
1273
|
+
} catch (error) {
|
|
1274
|
+
const errorMessage = error instanceof Error ? error.message : "An unknown error occurred";
|
|
1275
|
+
p5.log.error(highlighter.error(`Failed to setup .env.local: ${errorMessage}`));
|
|
1276
|
+
return false;
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
async function setupGitignore() {
|
|
1280
|
+
try {
|
|
1281
|
+
const exists = await fileExists(GITIGNORE_PATH);
|
|
1282
|
+
if (exists) {
|
|
1283
|
+
const content = await fs4.readFile(GITIGNORE_PATH, "utf-8");
|
|
1284
|
+
if (hasEnvLocalInGitignore(content)) {
|
|
1285
|
+
return true;
|
|
1286
|
+
}
|
|
1287
|
+
const needsNewline = content.length > 0 && !content.endsWith("\n");
|
|
1288
|
+
const newContent = content + (needsNewline ? "\n" : "") + ".env.local\n";
|
|
1289
|
+
await fs4.writeFile(GITIGNORE_PATH, newContent, "utf-8");
|
|
1290
|
+
} else {
|
|
1291
|
+
await fs4.writeFile(GITIGNORE_PATH, DEFAULT_GITIGNORE_CONTENT, "utf-8");
|
|
1292
|
+
}
|
|
1293
|
+
return true;
|
|
1294
|
+
} catch (error) {
|
|
1295
|
+
const errorMessage = error instanceof Error ? error.message : "An unknown error occurred";
|
|
1296
|
+
p5.log.error(highlighter.error(`Failed to setup .gitignore: ${errorMessage}`));
|
|
1297
|
+
return false;
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
async function setupStarwindProEnv() {
|
|
1301
|
+
const envResult = await setupEnvLocal();
|
|
1302
|
+
const gitignoreResult = await setupGitignore();
|
|
1303
|
+
return envResult && gitignoreResult;
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
// src/utils/layout.ts
|
|
1307
|
+
import * as p6 from "@clack/prompts";
|
|
1308
|
+
import fs5 from "fs-extra";
|
|
1309
|
+
var LAYOUT_PATHS = ["src/layouts/Layout.astro", "src/layouts/BaseLayout.astro"];
|
|
1310
|
+
async function findLayoutFile() {
|
|
1311
|
+
for (const layoutPath of LAYOUT_PATHS) {
|
|
1312
|
+
if (await fileExists(layoutPath)) {
|
|
1313
|
+
return layoutPath;
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
return null;
|
|
1317
|
+
}
|
|
1318
|
+
function hasCssImport(content, cssPath) {
|
|
1319
|
+
const normalizedCssPath = cssPath.replace(/\\/g, "/");
|
|
1320
|
+
const importPatterns = [
|
|
1321
|
+
// import "@/styles/starwind.css"
|
|
1322
|
+
new RegExp(`import\\s+["']${escapeRegExp(normalizedCssPath)}["']`),
|
|
1323
|
+
// import "@/styles/starwind.css";
|
|
1324
|
+
new RegExp(`import\\s+["']${escapeRegExp(normalizedCssPath)}["'];?`),
|
|
1325
|
+
// Handle paths without @/ prefix if cssPath starts with src/
|
|
1326
|
+
...normalizedCssPath.startsWith("src/") ? [new RegExp(`import\\s+["']@/${escapeRegExp(normalizedCssPath.slice(4))}["']`)] : [],
|
|
1327
|
+
// Handle @/ paths if cssPath doesn't have it
|
|
1328
|
+
...!normalizedCssPath.startsWith("@/") ? [new RegExp(`import\\s+["']@/${escapeRegExp(normalizedCssPath)}["']`)] : []
|
|
1329
|
+
];
|
|
1330
|
+
return importPatterns.some((pattern) => pattern.test(content));
|
|
1331
|
+
}
|
|
1332
|
+
function escapeRegExp(string) {
|
|
1333
|
+
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1334
|
+
}
|
|
1335
|
+
function toImportPath(cssPath) {
|
|
1336
|
+
const normalizedPath = cssPath.replace(/\\/g, "/");
|
|
1337
|
+
if (normalizedPath.startsWith("@/")) {
|
|
1338
|
+
return normalizedPath;
|
|
1339
|
+
}
|
|
1340
|
+
if (normalizedPath.startsWith("src/")) {
|
|
1341
|
+
return `@/${normalizedPath.slice(4)}`;
|
|
1342
|
+
}
|
|
1343
|
+
return `@/${normalizedPath}`;
|
|
1344
|
+
}
|
|
1345
|
+
function addCssImportToLayout(content, cssPath) {
|
|
1346
|
+
const importPath = toImportPath(cssPath);
|
|
1347
|
+
const importStatement = `import "${importPath}";`;
|
|
1348
|
+
const frontmatterMatch = content.match(/^---\r?\n/);
|
|
1349
|
+
if (frontmatterMatch) {
|
|
1350
|
+
const insertPosition = frontmatterMatch[0].length;
|
|
1351
|
+
return content.slice(0, insertPosition) + importStatement + "\n" + content.slice(insertPosition);
|
|
1352
|
+
} else {
|
|
1353
|
+
return `---
|
|
1354
|
+
${importStatement}
|
|
1355
|
+
---
|
|
1356
|
+
|
|
1357
|
+
${content}`;
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
async function setupLayoutCssImport(cssPath) {
|
|
1361
|
+
try {
|
|
1362
|
+
const layoutPath = await findLayoutFile();
|
|
1363
|
+
if (!layoutPath) {
|
|
1364
|
+
return true;
|
|
1365
|
+
}
|
|
1366
|
+
const content = await fs5.readFile(layoutPath, "utf-8");
|
|
1367
|
+
if (hasCssImport(content, cssPath)) {
|
|
1368
|
+
return true;
|
|
1369
|
+
}
|
|
1370
|
+
const updatedContent = addCssImportToLayout(content, cssPath);
|
|
1371
|
+
await fs5.writeFile(layoutPath, updatedContent, "utf-8");
|
|
1372
|
+
return true;
|
|
1373
|
+
} catch (error) {
|
|
1374
|
+
const errorMessage = error instanceof Error ? error.message : "An unknown error occurred";
|
|
1375
|
+
p6.log.error(highlighter.error(`Failed to setup CSS import in layout: ${errorMessage}`));
|
|
1376
|
+
return false;
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1380
|
+
// src/utils/tsconfig.ts
|
|
1381
|
+
import * as p7 from "@clack/prompts";
|
|
1382
|
+
var REQUIRED_TSCONFIG = {
|
|
1383
|
+
extends: "astro/tsconfigs/strict",
|
|
1384
|
+
compilerOptions: {
|
|
1385
|
+
baseUrl: ".",
|
|
1386
|
+
paths: {
|
|
1387
|
+
"@/*": ["src/*"]
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
};
|
|
1391
|
+
function validateTsConfig(config) {
|
|
1392
|
+
const hasExtends = config.extends === REQUIRED_TSCONFIG.extends;
|
|
1393
|
+
const hasBaseUrl = config.compilerOptions?.baseUrl === REQUIRED_TSCONFIG.compilerOptions.baseUrl;
|
|
1394
|
+
const paths = config.compilerOptions?.paths;
|
|
1395
|
+
const hasPathAlias = paths !== void 0 && "@/*" in paths && Array.isArray(paths["@/*"]) && paths["@/*"].includes("src/*");
|
|
1396
|
+
return {
|
|
1397
|
+
hasExtends,
|
|
1398
|
+
hasBaseUrl,
|
|
1399
|
+
hasPathAlias,
|
|
1400
|
+
isComplete: hasExtends && hasBaseUrl && hasPathAlias
|
|
1401
|
+
};
|
|
1402
|
+
}
|
|
1403
|
+
function mergeTsConfig(existingConfig) {
|
|
1404
|
+
const validation = validateTsConfig(existingConfig);
|
|
1405
|
+
if (validation.isComplete) {
|
|
1406
|
+
return existingConfig;
|
|
1407
|
+
}
|
|
1408
|
+
const merged = { ...existingConfig };
|
|
1409
|
+
if (!validation.hasExtends) {
|
|
1410
|
+
merged.extends = REQUIRED_TSCONFIG.extends;
|
|
1411
|
+
}
|
|
1412
|
+
if (!merged.compilerOptions) {
|
|
1413
|
+
merged.compilerOptions = {};
|
|
1414
|
+
}
|
|
1415
|
+
if (!validation.hasBaseUrl) {
|
|
1416
|
+
merged.compilerOptions.baseUrl = REQUIRED_TSCONFIG.compilerOptions.baseUrl;
|
|
1417
|
+
}
|
|
1418
|
+
if (!validation.hasPathAlias) {
|
|
1419
|
+
if (!merged.compilerOptions.paths) {
|
|
1420
|
+
merged.compilerOptions.paths = {};
|
|
1421
|
+
}
|
|
1422
|
+
if (!merged.compilerOptions.paths["@/*"] || !merged.compilerOptions.paths["@/*"].includes("src/*")) {
|
|
1423
|
+
merged.compilerOptions.paths["@/*"] = REQUIRED_TSCONFIG.compilerOptions.paths["@/*"];
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
return merged;
|
|
1427
|
+
}
|
|
1428
|
+
function createDefaultTsConfig() {
|
|
1429
|
+
return {
|
|
1430
|
+
extends: REQUIRED_TSCONFIG.extends,
|
|
1431
|
+
compilerOptions: {
|
|
1432
|
+
baseUrl: REQUIRED_TSCONFIG.compilerOptions.baseUrl,
|
|
1433
|
+
paths: {
|
|
1434
|
+
"@/*": [...REQUIRED_TSCONFIG.compilerOptions.paths["@/*"]]
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
};
|
|
1438
|
+
}
|
|
1439
|
+
async function setupTsConfig() {
|
|
1440
|
+
const TSCONFIG_PATH = "tsconfig.json";
|
|
1441
|
+
try {
|
|
1442
|
+
const exists = await fileExists(TSCONFIG_PATH);
|
|
1443
|
+
if (exists) {
|
|
1444
|
+
const existingConfig = await readJsonFile(TSCONFIG_PATH);
|
|
1445
|
+
const validation = validateTsConfig(existingConfig);
|
|
1446
|
+
if (validation.isComplete) {
|
|
1447
|
+
return true;
|
|
1448
|
+
}
|
|
1449
|
+
const mergedConfig = mergeTsConfig(existingConfig);
|
|
1450
|
+
await writeJsonFile(TSCONFIG_PATH, mergedConfig);
|
|
1451
|
+
} else {
|
|
1452
|
+
const defaultConfig2 = createDefaultTsConfig();
|
|
1453
|
+
await writeJsonFile(TSCONFIG_PATH, defaultConfig2);
|
|
1454
|
+
}
|
|
1455
|
+
return true;
|
|
1456
|
+
} catch (error) {
|
|
1457
|
+
const errorMessage = error instanceof Error ? error.message : "An unknown error occurred";
|
|
1458
|
+
p7.log.error(highlighter.error(`Failed to setup tsconfig.json: ${errorMessage}`));
|
|
1459
|
+
return false;
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1195
1463
|
// src/commands/init.ts
|
|
1196
1464
|
async function init(withinAdd = false, options) {
|
|
1197
1465
|
if (!withinAdd) {
|
|
1198
|
-
|
|
1466
|
+
p8.intro(highlighter.title(" Welcome to the Starwind CLI "));
|
|
1199
1467
|
}
|
|
1200
1468
|
try {
|
|
1201
1469
|
if (!await fileExists("package.json")) {
|
|
@@ -1214,13 +1482,13 @@ async function init(withinAdd = false, options) {
|
|
|
1214
1482
|
twBaseColor: "neutral"
|
|
1215
1483
|
};
|
|
1216
1484
|
if (!withinAdd) {
|
|
1217
|
-
|
|
1485
|
+
p8.log.info("Using default configuration values");
|
|
1218
1486
|
}
|
|
1219
1487
|
} else {
|
|
1220
|
-
configChoices = await
|
|
1488
|
+
configChoices = await p8.group(
|
|
1221
1489
|
{
|
|
1222
1490
|
// ask where to install components
|
|
1223
|
-
installLocation: () =>
|
|
1491
|
+
installLocation: () => p8.text({
|
|
1224
1492
|
message: "What is your components directory?",
|
|
1225
1493
|
placeholder: PATHS.LOCAL_COMPONENTS_DIR,
|
|
1226
1494
|
initialValue: PATHS.LOCAL_COMPONENTS_DIR,
|
|
@@ -1237,7 +1505,7 @@ async function init(withinAdd = false, options) {
|
|
|
1237
1505
|
}
|
|
1238
1506
|
}),
|
|
1239
1507
|
// ask where to add the css file
|
|
1240
|
-
cssFile: () =>
|
|
1508
|
+
cssFile: () => p8.text({
|
|
1241
1509
|
message: `Where would you like to add the Tailwind ${highlighter.info(".css")} file?`,
|
|
1242
1510
|
placeholder: PATHS.LOCAL_CSS_FILE,
|
|
1243
1511
|
initialValue: PATHS.LOCAL_CSS_FILE,
|
|
@@ -1258,7 +1526,7 @@ async function init(withinAdd = false, options) {
|
|
|
1258
1526
|
}
|
|
1259
1527
|
}
|
|
1260
1528
|
}),
|
|
1261
|
-
twBaseColor: () =>
|
|
1529
|
+
twBaseColor: () => p8.select({
|
|
1262
1530
|
message: "What Tailwind base color would you like to use?",
|
|
1263
1531
|
initialValue: "neutral",
|
|
1264
1532
|
options: [
|
|
@@ -1274,7 +1542,7 @@ async function init(withinAdd = false, options) {
|
|
|
1274
1542
|
// On Cancel callback that wraps the group
|
|
1275
1543
|
// So if the user cancels one of the prompts in the group this function will be called
|
|
1276
1544
|
onCancel: () => {
|
|
1277
|
-
|
|
1545
|
+
p8.cancel("Operation cancelled.");
|
|
1278
1546
|
process.exit(0);
|
|
1279
1547
|
}
|
|
1280
1548
|
}
|
|
@@ -1302,6 +1570,17 @@ async function init(withinAdd = false, options) {
|
|
|
1302
1570
|
return "Astro config setup completed";
|
|
1303
1571
|
}
|
|
1304
1572
|
});
|
|
1573
|
+
configTasks.push({
|
|
1574
|
+
title: "Setup TypeScript path aliases",
|
|
1575
|
+
task: async () => {
|
|
1576
|
+
const success = await setupTsConfig();
|
|
1577
|
+
if (!success) {
|
|
1578
|
+
throw new Error("Failed to setup tsconfig.json");
|
|
1579
|
+
}
|
|
1580
|
+
await sleep(250);
|
|
1581
|
+
return "TypeScript path aliases configured";
|
|
1582
|
+
}
|
|
1583
|
+
});
|
|
1305
1584
|
const cssFileExists = await fileExists(configChoices.cssFile);
|
|
1306
1585
|
let updatedTailwindConfig = tailwindConfig;
|
|
1307
1586
|
if (configChoices.twBaseColor !== "neutral") {
|
|
@@ -1311,15 +1590,15 @@ async function init(withinAdd = false, options) {
|
|
|
1311
1590
|
);
|
|
1312
1591
|
}
|
|
1313
1592
|
if (cssFileExists) {
|
|
1314
|
-
const shouldOverride = options?.defaults ? true : await
|
|
1593
|
+
const shouldOverride = options?.defaults ? true : await p8.confirm({
|
|
1315
1594
|
message: `${highlighter.info(configChoices.cssFile)} already exists. Do you want to override it?`
|
|
1316
1595
|
});
|
|
1317
|
-
if (
|
|
1318
|
-
|
|
1596
|
+
if (p8.isCancel(shouldOverride)) {
|
|
1597
|
+
p8.cancel("Operation cancelled");
|
|
1319
1598
|
return process.exit(0);
|
|
1320
1599
|
}
|
|
1321
1600
|
if (!shouldOverride) {
|
|
1322
|
-
|
|
1601
|
+
p8.log.info("Skipping Tailwind CSS configuration");
|
|
1323
1602
|
} else {
|
|
1324
1603
|
configTasks.push({
|
|
1325
1604
|
title: "Creating Tailwind CSS configuration",
|
|
@@ -1340,6 +1619,17 @@ async function init(withinAdd = false, options) {
|
|
|
1340
1619
|
}
|
|
1341
1620
|
});
|
|
1342
1621
|
}
|
|
1622
|
+
configTasks.push({
|
|
1623
|
+
title: "Adding CSS import to layout",
|
|
1624
|
+
task: async () => {
|
|
1625
|
+
const success = await setupLayoutCssImport(configChoices.cssFile);
|
|
1626
|
+
if (!success) {
|
|
1627
|
+
throw new Error("Failed to add CSS import to layout");
|
|
1628
|
+
}
|
|
1629
|
+
await sleep(250);
|
|
1630
|
+
return "CSS import added to layout";
|
|
1631
|
+
}
|
|
1632
|
+
});
|
|
1343
1633
|
configTasks.push({
|
|
1344
1634
|
title: "Updating project configuration",
|
|
1345
1635
|
task: async () => {
|
|
@@ -1363,7 +1653,7 @@ async function init(withinAdd = false, options) {
|
|
|
1363
1653
|
const alreadyHasPro = await hasStarwindProRegistry();
|
|
1364
1654
|
if (!alreadyHasPro) {
|
|
1365
1655
|
if (!withinAdd) {
|
|
1366
|
-
|
|
1656
|
+
p8.log.info(highlighter.info("Setting up Starwind Pro configuration..."));
|
|
1367
1657
|
}
|
|
1368
1658
|
configTasks.push({
|
|
1369
1659
|
title: "Setting up Starwind Pro registry",
|
|
@@ -1373,9 +1663,20 @@ async function init(withinAdd = false, options) {
|
|
|
1373
1663
|
return "Configured Starwind Pro registry in components.json";
|
|
1374
1664
|
}
|
|
1375
1665
|
});
|
|
1666
|
+
configTasks.push({
|
|
1667
|
+
title: "Setting up Starwind Pro environment",
|
|
1668
|
+
task: async () => {
|
|
1669
|
+
const success = await setupStarwindProEnv();
|
|
1670
|
+
if (!success) {
|
|
1671
|
+
throw new Error("Failed to setup Starwind Pro environment");
|
|
1672
|
+
}
|
|
1673
|
+
await sleep(250);
|
|
1674
|
+
return "Created .env.local and updated .gitignore";
|
|
1675
|
+
}
|
|
1676
|
+
});
|
|
1376
1677
|
} else {
|
|
1377
1678
|
if (!withinAdd) {
|
|
1378
|
-
|
|
1679
|
+
p8.log.info(highlighter.info("Starwind Pro registry already configured"));
|
|
1379
1680
|
}
|
|
1380
1681
|
}
|
|
1381
1682
|
}
|
|
@@ -1383,16 +1684,16 @@ async function init(withinAdd = false, options) {
|
|
|
1383
1684
|
if (pkg.dependencies?.astro) {
|
|
1384
1685
|
const astroVersion = pkg.dependencies.astro.replace(/^\^|~/, "");
|
|
1385
1686
|
if (!semver4.gte(astroVersion, MIN_ASTRO_VERSION)) {
|
|
1386
|
-
const shouldUpgrade = options?.defaults ? true : await
|
|
1687
|
+
const shouldUpgrade = options?.defaults ? true : await p8.confirm({
|
|
1387
1688
|
message: `Starwind requires Astro v${MIN_ASTRO_VERSION} or higher. Would you like to upgrade from v${astroVersion}?`,
|
|
1388
1689
|
initialValue: true
|
|
1389
1690
|
});
|
|
1390
|
-
if (
|
|
1391
|
-
|
|
1691
|
+
if (p8.isCancel(shouldUpgrade)) {
|
|
1692
|
+
p8.cancel("Operation cancelled");
|
|
1392
1693
|
return process.exit(0);
|
|
1393
1694
|
}
|
|
1394
1695
|
if (!shouldUpgrade) {
|
|
1395
|
-
|
|
1696
|
+
p8.cancel("Astro v5 or higher is required to use Starwind");
|
|
1396
1697
|
return process.exit(1);
|
|
1397
1698
|
}
|
|
1398
1699
|
installTasks.push({
|
|
@@ -1404,16 +1705,16 @@ async function init(withinAdd = false, options) {
|
|
|
1404
1705
|
});
|
|
1405
1706
|
}
|
|
1406
1707
|
} else {
|
|
1407
|
-
const shouldInstall2 = options?.defaults ? true : await
|
|
1708
|
+
const shouldInstall2 = options?.defaults ? true : await p8.confirm({
|
|
1408
1709
|
message: `Starwind requires Astro v${MIN_ASTRO_VERSION} or higher. Would you like to install it?`,
|
|
1409
1710
|
initialValue: true
|
|
1410
1711
|
});
|
|
1411
|
-
if (
|
|
1412
|
-
|
|
1712
|
+
if (p8.isCancel(shouldInstall2)) {
|
|
1713
|
+
p8.cancel("Operation cancelled");
|
|
1413
1714
|
return process.exit(0);
|
|
1414
1715
|
}
|
|
1415
1716
|
if (!shouldInstall2) {
|
|
1416
|
-
|
|
1717
|
+
p8.cancel("Astro is required to use Starwind");
|
|
1417
1718
|
return process.exit(1);
|
|
1418
1719
|
}
|
|
1419
1720
|
installTasks.push({
|
|
@@ -1425,11 +1726,11 @@ async function init(withinAdd = false, options) {
|
|
|
1425
1726
|
});
|
|
1426
1727
|
}
|
|
1427
1728
|
const otherPackages = getOtherPackages();
|
|
1428
|
-
const shouldInstall = options?.defaults ? true : await
|
|
1729
|
+
const shouldInstall = options?.defaults ? true : await p8.confirm({
|
|
1429
1730
|
message: `Install ${highlighter.info(otherPackages.join(", "))} using ${highlighter.info(pm)}?`
|
|
1430
1731
|
});
|
|
1431
|
-
if (
|
|
1432
|
-
|
|
1732
|
+
if (p8.isCancel(shouldInstall)) {
|
|
1733
|
+
p8.cancel("Operation cancelled");
|
|
1433
1734
|
return process.exit(0);
|
|
1434
1735
|
}
|
|
1435
1736
|
if (shouldInstall) {
|
|
@@ -1441,15 +1742,15 @@ async function init(withinAdd = false, options) {
|
|
|
1441
1742
|
}
|
|
1442
1743
|
});
|
|
1443
1744
|
} else {
|
|
1444
|
-
|
|
1745
|
+
p8.log.warn(
|
|
1445
1746
|
highlighter.warn(`Skipped installation of packages. Make sure to install them manually`)
|
|
1446
1747
|
);
|
|
1447
1748
|
}
|
|
1448
1749
|
if (installTasks.length > 0) {
|
|
1449
|
-
await
|
|
1750
|
+
await p8.tasks(installTasks);
|
|
1450
1751
|
}
|
|
1451
1752
|
if (configTasks.length > 0) {
|
|
1452
|
-
await
|
|
1753
|
+
await p8.tasks(configTasks);
|
|
1453
1754
|
}
|
|
1454
1755
|
await sleep(250);
|
|
1455
1756
|
let nextStepsMessage = `Make sure your layout imports the ${highlighter.infoBright(configChoices.cssFile)} file`;
|
|
@@ -1459,17 +1760,17 @@ async function init(withinAdd = false, options) {
|
|
|
1459
1760
|
Starwind Pro is now configured! You can install pro components using:
|
|
1460
1761
|
${highlighter.info("npx starwind@latest add @starwind-pro/component-name")}
|
|
1461
1762
|
|
|
1462
|
-
Make sure to set your ${highlighter.infoBright("STARWIND_LICENSE_KEY")} environment variable.`;
|
|
1763
|
+
Make sure to set your ${highlighter.infoBright("STARWIND_LICENSE_KEY")} environment variable in ${highlighter.infoBright(".env.local")}.`;
|
|
1463
1764
|
}
|
|
1464
|
-
|
|
1765
|
+
p8.note(nextStepsMessage, "Next steps");
|
|
1465
1766
|
if (!withinAdd) {
|
|
1466
1767
|
sleep(1e3);
|
|
1467
|
-
const outroMessage = options?.pro ? "Enjoy using Starwind UI with Pro components! \u{1F680}
|
|
1468
|
-
|
|
1768
|
+
const outroMessage = options?.pro ? "Enjoy using Starwind UI with Pro components! \u{1F680}" : "Enjoy using Starwind UI \u{1F680}";
|
|
1769
|
+
p8.outro(outroMessage);
|
|
1469
1770
|
}
|
|
1470
1771
|
} catch (error) {
|
|
1471
|
-
|
|
1472
|
-
|
|
1772
|
+
p8.log.error(error instanceof Error ? error.message : "Failed to add components");
|
|
1773
|
+
p8.cancel("Operation cancelled");
|
|
1473
1774
|
process.exit(1);
|
|
1474
1775
|
}
|
|
1475
1776
|
}
|
|
@@ -1477,21 +1778,21 @@ Make sure to set your ${highlighter.infoBright("STARWIND_LICENSE_KEY")} environm
|
|
|
1477
1778
|
// src/commands/add.ts
|
|
1478
1779
|
async function add(components, options) {
|
|
1479
1780
|
try {
|
|
1480
|
-
|
|
1781
|
+
p9.intro(highlighter.title(" Welcome to the Starwind CLI "));
|
|
1481
1782
|
const configExists = await fileExists(PATHS.LOCAL_CONFIG_FILE);
|
|
1482
1783
|
if (!configExists) {
|
|
1483
|
-
const shouldInit = await
|
|
1784
|
+
const shouldInit = await p9.confirm({
|
|
1484
1785
|
message: `Starwind configuration not found. Would you like to run ${highlighter.info("starwind init")} now?`,
|
|
1485
1786
|
initialValue: true
|
|
1486
1787
|
});
|
|
1487
|
-
if (
|
|
1488
|
-
|
|
1788
|
+
if (p9.isCancel(shouldInit)) {
|
|
1789
|
+
p9.cancel("Operation cancelled");
|
|
1489
1790
|
process.exit(0);
|
|
1490
1791
|
}
|
|
1491
1792
|
if (shouldInit) {
|
|
1492
1793
|
await init(true);
|
|
1493
1794
|
} else {
|
|
1494
|
-
|
|
1795
|
+
p9.log.error(
|
|
1495
1796
|
`Please initialize starwind with ${highlighter.info("starwind init")} before adding components`
|
|
1496
1797
|
);
|
|
1497
1798
|
process.exit(1);
|
|
@@ -1503,7 +1804,7 @@ async function add(components, options) {
|
|
|
1503
1804
|
if (options?.all) {
|
|
1504
1805
|
const availableComponents = await getAllComponents();
|
|
1505
1806
|
componentsToInstall = availableComponents.map((c) => c.name);
|
|
1506
|
-
|
|
1807
|
+
p9.log.info(`Adding all ${componentsToInstall.length} available components...`);
|
|
1507
1808
|
} else if (components && components.length > 0) {
|
|
1508
1809
|
const regularComponents = [];
|
|
1509
1810
|
for (const component of components) {
|
|
@@ -1516,16 +1817,16 @@ async function add(components, options) {
|
|
|
1516
1817
|
if (registryComponents.length > 0) {
|
|
1517
1818
|
const hasProRegistry = await hasStarwindProRegistry();
|
|
1518
1819
|
if (!hasProRegistry) {
|
|
1519
|
-
const shouldSetupPro = await
|
|
1820
|
+
const shouldSetupPro = await p9.confirm({
|
|
1520
1821
|
message: `Starwind Pro registry not configured. Would you like to set it up now to install ${registryComponents.join(", ")}?`,
|
|
1521
1822
|
initialValue: true
|
|
1522
1823
|
});
|
|
1523
|
-
if (
|
|
1524
|
-
|
|
1824
|
+
if (p9.isCancel(shouldSetupPro)) {
|
|
1825
|
+
p9.cancel("Operation cancelled");
|
|
1525
1826
|
process.exit(0);
|
|
1526
1827
|
}
|
|
1527
1828
|
if (shouldSetupPro) {
|
|
1528
|
-
|
|
1829
|
+
p9.log.info(highlighter.info("Setting up Starwind Pro configuration..."));
|
|
1529
1830
|
let cssFile = PATHS.LOCAL_CSS_FILE;
|
|
1530
1831
|
let baseColor = "neutral";
|
|
1531
1832
|
try {
|
|
@@ -1535,14 +1836,14 @@ async function add(components, options) {
|
|
|
1535
1836
|
} catch {
|
|
1536
1837
|
}
|
|
1537
1838
|
await setupShadcnProConfig(cssFile, baseColor);
|
|
1538
|
-
|
|
1839
|
+
p9.log.success("Starwind Pro registry configured successfully!");
|
|
1539
1840
|
} else {
|
|
1540
|
-
|
|
1541
|
-
|
|
1841
|
+
p9.log.error("Cannot install registry components without Starwind Pro configuration");
|
|
1842
|
+
p9.cancel("Operation cancelled");
|
|
1542
1843
|
process.exit(1);
|
|
1543
1844
|
}
|
|
1544
1845
|
}
|
|
1545
|
-
|
|
1846
|
+
p9.log.info(`Installing registry components: ${registryComponents.join(", ")}`);
|
|
1546
1847
|
const [command, baseArgs] = await getShadcnCommand();
|
|
1547
1848
|
registryResults = {
|
|
1548
1849
|
success: [],
|
|
@@ -1550,7 +1851,7 @@ async function add(components, options) {
|
|
|
1550
1851
|
};
|
|
1551
1852
|
for (const registryComponent of registryComponents) {
|
|
1552
1853
|
try {
|
|
1553
|
-
|
|
1854
|
+
p9.log.info(`Installing ${highlighter.info(registryComponent)} via shadcn...`);
|
|
1554
1855
|
await execa2(command, [...baseArgs, "add", registryComponent], {
|
|
1555
1856
|
stdio: "inherit",
|
|
1556
1857
|
cwd: process.cwd()
|
|
@@ -1577,7 +1878,7 @@ async function add(components, options) {
|
|
|
1577
1878
|
Promise.resolve({ valid: [], invalid: [] })
|
|
1578
1879
|
);
|
|
1579
1880
|
if (invalid.length > 0) {
|
|
1580
|
-
|
|
1881
|
+
p9.log.warn(
|
|
1581
1882
|
`${highlighter.warn("Invalid components found:")}
|
|
1582
1883
|
${invalid.map((name) => ` ${name}`).join("\n")}`
|
|
1583
1884
|
);
|
|
@@ -1585,22 +1886,22 @@ ${invalid.map((name) => ` ${name}`).join("\n")}`
|
|
|
1585
1886
|
if (valid.length > 0) {
|
|
1586
1887
|
componentsToInstall = valid;
|
|
1587
1888
|
} else if (registryComponents.length === 0) {
|
|
1588
|
-
|
|
1589
|
-
|
|
1889
|
+
p9.log.warn(`${highlighter.warn("No valid components to install")}`);
|
|
1890
|
+
p9.cancel("Operation cancelled");
|
|
1590
1891
|
return process.exit(0);
|
|
1591
1892
|
}
|
|
1592
1893
|
}
|
|
1593
1894
|
} else {
|
|
1594
1895
|
const selected = await selectComponents();
|
|
1595
1896
|
if (!selected) {
|
|
1596
|
-
|
|
1897
|
+
p9.cancel("No components selected");
|
|
1597
1898
|
return process.exit(0);
|
|
1598
1899
|
}
|
|
1599
1900
|
componentsToInstall = selected;
|
|
1600
1901
|
}
|
|
1601
1902
|
if (componentsToInstall.length === 0 && registryComponents.length === 0) {
|
|
1602
|
-
|
|
1603
|
-
|
|
1903
|
+
p9.log.warn(`${highlighter.warn("No components selected")}`);
|
|
1904
|
+
p9.cancel("Operation cancelled");
|
|
1604
1905
|
return process.exit(0);
|
|
1605
1906
|
}
|
|
1606
1907
|
const results = {
|
|
@@ -1608,132 +1909,118 @@ ${invalid.map((name) => ` ${name}`).join("\n")}`
|
|
|
1608
1909
|
skipped: [],
|
|
1609
1910
|
failed: []
|
|
1610
1911
|
};
|
|
1912
|
+
const installedThisSession = /* @__PURE__ */ new Set();
|
|
1913
|
+
const addResult = (result) => {
|
|
1914
|
+
const name = result.name;
|
|
1915
|
+
if (result.status === "installed") {
|
|
1916
|
+
if (!installedThisSession.has(name)) {
|
|
1917
|
+
installedThisSession.add(name);
|
|
1918
|
+
results.installed.push(result);
|
|
1919
|
+
}
|
|
1920
|
+
} else if (result.status === "skipped") {
|
|
1921
|
+
if (!installedThisSession.has(name)) {
|
|
1922
|
+
results.skipped.push(result);
|
|
1923
|
+
}
|
|
1924
|
+
} else if (result.status === "failed") {
|
|
1925
|
+
results.failed.push(result);
|
|
1926
|
+
}
|
|
1927
|
+
};
|
|
1611
1928
|
const installedComponents = [];
|
|
1612
1929
|
for (const comp of componentsToInstall) {
|
|
1930
|
+
if (installedThisSession.has(comp)) {
|
|
1931
|
+
continue;
|
|
1932
|
+
}
|
|
1613
1933
|
const result = await installComponent(comp);
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
results.installed.push(depResult);
|
|
1623
|
-
break;
|
|
1624
|
-
case "skipped":
|
|
1625
|
-
results.skipped.push(depResult);
|
|
1626
|
-
break;
|
|
1627
|
-
case "failed":
|
|
1628
|
-
results.failed.push(depResult);
|
|
1629
|
-
break;
|
|
1630
|
-
}
|
|
1631
|
-
}
|
|
1632
|
-
}
|
|
1633
|
-
break;
|
|
1634
|
-
case "skipped":
|
|
1635
|
-
results.skipped.push(result);
|
|
1636
|
-
break;
|
|
1637
|
-
case "failed":
|
|
1638
|
-
results.failed.push(result);
|
|
1639
|
-
if (result.dependencyResults) {
|
|
1640
|
-
for (const depResult of result.dependencyResults) {
|
|
1641
|
-
switch (depResult.status) {
|
|
1642
|
-
case "installed":
|
|
1643
|
-
results.installed.push(depResult);
|
|
1644
|
-
break;
|
|
1645
|
-
case "skipped":
|
|
1646
|
-
results.skipped.push(depResult);
|
|
1647
|
-
break;
|
|
1648
|
-
case "failed":
|
|
1649
|
-
results.failed.push(depResult);
|
|
1650
|
-
break;
|
|
1651
|
-
}
|
|
1652
|
-
}
|
|
1653
|
-
}
|
|
1654
|
-
break;
|
|
1934
|
+
if (result.dependencyResults) {
|
|
1935
|
+
for (const depResult of result.dependencyResults) {
|
|
1936
|
+
addResult(depResult);
|
|
1937
|
+
}
|
|
1938
|
+
}
|
|
1939
|
+
addResult(result);
|
|
1940
|
+
if (result.status === "installed") {
|
|
1941
|
+
installedComponents.push({ name: result.name, version: result.version });
|
|
1655
1942
|
}
|
|
1656
1943
|
}
|
|
1657
1944
|
if (installedComponents.length > 0) {
|
|
1658
1945
|
try {
|
|
1659
1946
|
await updateConfig({ components: installedComponents }, { appendComponents: true });
|
|
1660
1947
|
} catch (error) {
|
|
1661
|
-
|
|
1948
|
+
p9.log.error(
|
|
1662
1949
|
`Failed to update config: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
1663
1950
|
);
|
|
1664
1951
|
process.exit(1);
|
|
1665
1952
|
}
|
|
1666
1953
|
}
|
|
1667
|
-
|
|
1954
|
+
p9.log.message(`
|
|
1668
1955
|
|
|
1669
1956
|
${highlighter.underline("Installation Summary")}`);
|
|
1670
1957
|
if (results.failed.length > 0) {
|
|
1671
|
-
|
|
1958
|
+
p9.log.error(
|
|
1672
1959
|
`${highlighter.error("Failed to install components:")}
|
|
1673
|
-
${results.failed.map((r) => ` ${r.name} - ${r.error}`).join("\n")}`
|
|
1960
|
+
${results.failed.map((r) => ` ${r.name} - ${r.status === "failed" ? r.error : "Unknown error"}`).join("\n")}`
|
|
1674
1961
|
);
|
|
1675
1962
|
}
|
|
1676
1963
|
if (results.skipped.length > 0) {
|
|
1677
|
-
|
|
1964
|
+
p9.log.warn(
|
|
1678
1965
|
`${highlighter.warn("Skipped components (already installed):")}
|
|
1679
1966
|
${results.skipped.map((r) => ` ${r.name} v${r.version}`).join("\n")}`
|
|
1680
1967
|
);
|
|
1681
1968
|
}
|
|
1682
1969
|
if (results.installed.length > 0) {
|
|
1683
|
-
|
|
1970
|
+
p9.log.success(
|
|
1684
1971
|
`${highlighter.success("Successfully installed components:")}
|
|
1685
1972
|
${results.installed.map((r) => ` ${r.name} v${r.version}`).join("\n")}`
|
|
1686
1973
|
);
|
|
1687
1974
|
}
|
|
1688
1975
|
if (registryResults) {
|
|
1689
1976
|
if (registryResults.failed.length > 0) {
|
|
1690
|
-
|
|
1977
|
+
p9.log.error(
|
|
1691
1978
|
`${highlighter.error("Failed to install registry components:")}
|
|
1692
1979
|
${registryResults.failed.map((name) => ` ${name} - see the error message above for further details`).join("\n")}`
|
|
1693
1980
|
);
|
|
1694
1981
|
}
|
|
1695
1982
|
if (registryResults.success.length > 0) {
|
|
1696
|
-
|
|
1983
|
+
p9.log.success(
|
|
1697
1984
|
`${highlighter.success("Successfully installed registry components:")}
|
|
1698
1985
|
${registryResults.success.map((name) => ` ${name}`).join("\n")}`
|
|
1699
1986
|
);
|
|
1700
1987
|
}
|
|
1701
1988
|
}
|
|
1702
1989
|
await sleep(1e3);
|
|
1703
|
-
|
|
1990
|
+
p9.outro("Enjoy using Starwind UI \u{1F680}");
|
|
1704
1991
|
} catch (error) {
|
|
1705
|
-
|
|
1706
|
-
|
|
1992
|
+
p9.log.error(error instanceof Error ? error.message : "Failed to add components");
|
|
1993
|
+
p9.cancel("Operation cancelled");
|
|
1707
1994
|
process.exit(1);
|
|
1708
1995
|
}
|
|
1709
1996
|
}
|
|
1710
1997
|
|
|
1711
1998
|
// src/commands/remove.ts
|
|
1712
|
-
import * as
|
|
1999
|
+
import * as p10 from "@clack/prompts";
|
|
1713
2000
|
async function remove(components, options) {
|
|
1714
2001
|
try {
|
|
1715
|
-
|
|
2002
|
+
p10.intro(highlighter.title(" Welcome to the Starwind CLI "));
|
|
1716
2003
|
const configExists = await fileExists(PATHS.LOCAL_CONFIG_FILE);
|
|
1717
2004
|
if (!configExists) {
|
|
1718
|
-
|
|
2005
|
+
p10.log.error("No Starwind configuration found. Please run starwind init first.");
|
|
1719
2006
|
process.exit(1);
|
|
1720
2007
|
}
|
|
1721
2008
|
const config = await getConfig();
|
|
1722
2009
|
const installedComponents = config.components;
|
|
1723
2010
|
if (installedComponents.length === 0) {
|
|
1724
|
-
|
|
2011
|
+
p10.log.warn("No components are currently installed.");
|
|
1725
2012
|
process.exit(0);
|
|
1726
2013
|
}
|
|
1727
2014
|
let componentsToRemove = [];
|
|
1728
2015
|
if (options?.all) {
|
|
1729
2016
|
componentsToRemove = installedComponents.map((comp) => comp.name);
|
|
1730
|
-
|
|
2017
|
+
p10.log.info(`Removing all ${componentsToRemove.length} installed components...`);
|
|
1731
2018
|
} else if (components && components.length > 0) {
|
|
1732
2019
|
const invalid = components.filter(
|
|
1733
2020
|
(comp) => !installedComponents.some((ic) => ic.name === comp)
|
|
1734
2021
|
);
|
|
1735
2022
|
if (invalid.length > 0) {
|
|
1736
|
-
|
|
2023
|
+
p10.log.warn(
|
|
1737
2024
|
`${highlighter.warn("Components not found:")}
|
|
1738
2025
|
${invalid.map((name) => ` ${name}`).join("\n")}`
|
|
1739
2026
|
);
|
|
@@ -1742,7 +2029,7 @@ ${invalid.map((name) => ` ${name}`).join("\n")}`
|
|
|
1742
2029
|
(comp) => installedComponents.some((ic) => ic.name === comp)
|
|
1743
2030
|
);
|
|
1744
2031
|
if (componentsToRemove.length === 0) {
|
|
1745
|
-
|
|
2032
|
+
p10.log.warn("No valid components to remove");
|
|
1746
2033
|
process.exit(0);
|
|
1747
2034
|
}
|
|
1748
2035
|
} else {
|
|
@@ -1750,25 +2037,25 @@ ${invalid.map((name) => ` ${name}`).join("\n")}`
|
|
|
1750
2037
|
value: comp.name,
|
|
1751
2038
|
label: comp.name
|
|
1752
2039
|
}));
|
|
1753
|
-
const selected = await
|
|
2040
|
+
const selected = await p10.multiselect({
|
|
1754
2041
|
message: "Select components to remove",
|
|
1755
2042
|
options: choices
|
|
1756
2043
|
});
|
|
1757
|
-
if (
|
|
1758
|
-
|
|
2044
|
+
if (p10.isCancel(selected)) {
|
|
2045
|
+
p10.cancel("Operation cancelled");
|
|
1759
2046
|
process.exit(0);
|
|
1760
2047
|
}
|
|
1761
2048
|
componentsToRemove = selected;
|
|
1762
2049
|
}
|
|
1763
2050
|
if (componentsToRemove.length === 0) {
|
|
1764
|
-
|
|
2051
|
+
p10.log.warn("No components selected for removal");
|
|
1765
2052
|
process.exit(0);
|
|
1766
2053
|
}
|
|
1767
|
-
const confirmed = await
|
|
2054
|
+
const confirmed = await p10.confirm({
|
|
1768
2055
|
message: `Remove ${componentsToRemove.map((comp) => highlighter.info(comp)).join(", ")} ${componentsToRemove.length > 1 ? "components" : "component"}?`
|
|
1769
2056
|
});
|
|
1770
|
-
if (!confirmed ||
|
|
1771
|
-
|
|
2057
|
+
if (!confirmed || p10.isCancel(confirmed)) {
|
|
2058
|
+
p10.cancel("Operation cancelled");
|
|
1772
2059
|
process.exit(0);
|
|
1773
2060
|
}
|
|
1774
2061
|
const results = {
|
|
@@ -1793,61 +2080,61 @@ ${invalid.map((name) => ` ${name}`).join("\n")}`
|
|
|
1793
2080
|
},
|
|
1794
2081
|
{ appendComponents: false }
|
|
1795
2082
|
);
|
|
1796
|
-
|
|
2083
|
+
p10.log.message(`
|
|
1797
2084
|
|
|
1798
2085
|
${highlighter.underline("Removal Summary")}`);
|
|
1799
2086
|
if (results.failed.length > 0) {
|
|
1800
|
-
|
|
2087
|
+
p10.log.error(
|
|
1801
2088
|
`${highlighter.error("Failed to remove components:")}
|
|
1802
2089
|
${results.failed.map((r) => ` ${r.name} - ${r.error}`).join("\n")}`
|
|
1803
2090
|
);
|
|
1804
2091
|
}
|
|
1805
2092
|
if (results.removed.length > 0) {
|
|
1806
|
-
|
|
2093
|
+
p10.log.success(
|
|
1807
2094
|
`${highlighter.success("Successfully removed components:")}
|
|
1808
2095
|
${results.removed.map((r) => ` ${r.name}`).join("\n")}`
|
|
1809
2096
|
);
|
|
1810
2097
|
}
|
|
1811
2098
|
await sleep(1e3);
|
|
1812
2099
|
if (results.removed.length > 0) {
|
|
1813
|
-
|
|
2100
|
+
p10.outro("Components removed successfully \u{1F5D1}\uFE0F");
|
|
1814
2101
|
} else {
|
|
1815
|
-
|
|
2102
|
+
p10.cancel("Errors occurred while removing components");
|
|
1816
2103
|
process.exit(1);
|
|
1817
2104
|
}
|
|
1818
2105
|
} catch (error) {
|
|
1819
|
-
|
|
1820
|
-
|
|
2106
|
+
p10.log.error(error instanceof Error ? error.message : "Failed to remove components");
|
|
2107
|
+
p10.cancel("Operation cancelled");
|
|
1821
2108
|
process.exit(1);
|
|
1822
2109
|
}
|
|
1823
2110
|
}
|
|
1824
2111
|
|
|
1825
2112
|
// src/commands/update.ts
|
|
1826
|
-
import * as
|
|
2113
|
+
import * as p11 from "@clack/prompts";
|
|
1827
2114
|
async function update(components, options) {
|
|
1828
2115
|
try {
|
|
1829
|
-
|
|
2116
|
+
p11.intro(highlighter.title(" Welcome to the Starwind CLI "));
|
|
1830
2117
|
const configExists = await fileExists(PATHS.LOCAL_CONFIG_FILE);
|
|
1831
2118
|
if (!configExists) {
|
|
1832
|
-
|
|
2119
|
+
p11.log.error("No Starwind configuration found. Please run starwind init first.");
|
|
1833
2120
|
process.exit(1);
|
|
1834
2121
|
}
|
|
1835
2122
|
const config = await getConfig();
|
|
1836
2123
|
const installedComponents = config.components;
|
|
1837
2124
|
if (installedComponents.length === 0) {
|
|
1838
|
-
|
|
2125
|
+
p11.log.warn("No components are currently installed.");
|
|
1839
2126
|
process.exit(0);
|
|
1840
2127
|
}
|
|
1841
2128
|
let componentsToUpdate = [];
|
|
1842
2129
|
if (options?.all) {
|
|
1843
2130
|
componentsToUpdate = installedComponents.map((comp) => comp.name);
|
|
1844
|
-
|
|
2131
|
+
p11.log.info(`Checking updates for all ${componentsToUpdate.length} installed components...`);
|
|
1845
2132
|
} else if (components && components.length > 0) {
|
|
1846
2133
|
const invalid = components.filter(
|
|
1847
2134
|
(comp) => !installedComponents.some((ic) => ic.name === comp)
|
|
1848
2135
|
);
|
|
1849
2136
|
if (invalid.length > 0) {
|
|
1850
|
-
|
|
2137
|
+
p11.log.warn(
|
|
1851
2138
|
`${highlighter.warn("Components not found in project:")}
|
|
1852
2139
|
${invalid.map((name) => ` ${name}`).join("\n")}`
|
|
1853
2140
|
);
|
|
@@ -1856,7 +2143,7 @@ ${invalid.map((name) => ` ${name}`).join("\n")}`
|
|
|
1856
2143
|
(comp) => installedComponents.some((ic) => ic.name === comp)
|
|
1857
2144
|
);
|
|
1858
2145
|
if (componentsToUpdate.length === 0) {
|
|
1859
|
-
|
|
2146
|
+
p11.log.warn("No valid components to update");
|
|
1860
2147
|
process.exit(0);
|
|
1861
2148
|
}
|
|
1862
2149
|
} else {
|
|
@@ -1864,18 +2151,18 @@ ${invalid.map((name) => ` ${name}`).join("\n")}`
|
|
|
1864
2151
|
value: comp.name,
|
|
1865
2152
|
label: comp.name
|
|
1866
2153
|
}));
|
|
1867
|
-
const selected = await
|
|
2154
|
+
const selected = await p11.multiselect({
|
|
1868
2155
|
message: "Select components to update",
|
|
1869
2156
|
options: choices
|
|
1870
2157
|
});
|
|
1871
|
-
if (
|
|
1872
|
-
|
|
2158
|
+
if (p11.isCancel(selected)) {
|
|
2159
|
+
p11.cancel("Operation cancelled");
|
|
1873
2160
|
process.exit(0);
|
|
1874
2161
|
}
|
|
1875
2162
|
componentsToUpdate = selected;
|
|
1876
2163
|
}
|
|
1877
2164
|
if (componentsToUpdate.length === 0) {
|
|
1878
|
-
|
|
2165
|
+
p11.log.warn("No components selected for update");
|
|
1879
2166
|
process.exit(0);
|
|
1880
2167
|
}
|
|
1881
2168
|
const results = {
|
|
@@ -1926,45 +2213,45 @@ ${invalid.map((name) => ` ${name}`).join("\n")}`
|
|
|
1926
2213
|
{ appendComponents: false }
|
|
1927
2214
|
);
|
|
1928
2215
|
} catch (error) {
|
|
1929
|
-
|
|
2216
|
+
p11.log.error(
|
|
1930
2217
|
`Failed to update config: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
1931
2218
|
);
|
|
1932
2219
|
process.exit(1);
|
|
1933
2220
|
}
|
|
1934
2221
|
}
|
|
1935
|
-
|
|
2222
|
+
p11.log.message(`
|
|
1936
2223
|
|
|
1937
2224
|
${highlighter.underline("Update Summary")}`);
|
|
1938
2225
|
if (results.failed.length > 0) {
|
|
1939
|
-
|
|
2226
|
+
p11.log.error(
|
|
1940
2227
|
`${highlighter.error("Failed to update components:")}
|
|
1941
2228
|
${results.failed.map((r) => ` ${r.name} - ${r.error}`).join("\n")}`
|
|
1942
2229
|
);
|
|
1943
2230
|
}
|
|
1944
2231
|
if (results.skipped.length > 0) {
|
|
1945
|
-
|
|
2232
|
+
p11.log.info(
|
|
1946
2233
|
`${highlighter.info("Components already up to date or skipped:")}
|
|
1947
2234
|
${results.skipped.map((r) => ` ${r.name} (${r.oldVersion})`).join("\n")}`
|
|
1948
2235
|
);
|
|
1949
2236
|
}
|
|
1950
2237
|
if (results.updated.length > 0) {
|
|
1951
|
-
|
|
2238
|
+
p11.log.success(
|
|
1952
2239
|
`${highlighter.success("Successfully updated components:")}
|
|
1953
2240
|
${results.updated.map((r) => ` ${r.name} (${r.oldVersion} \u2192 ${r.newVersion})`).join("\n")}`
|
|
1954
2241
|
);
|
|
1955
2242
|
}
|
|
1956
2243
|
await sleep(1e3);
|
|
1957
2244
|
if (results.updated.length > 0) {
|
|
1958
|
-
|
|
2245
|
+
p11.outro("Components updated successfully \u{1F680}");
|
|
1959
2246
|
} else if (results.skipped.length > 0 && results.failed.length === 0) {
|
|
1960
|
-
|
|
2247
|
+
p11.outro("Components already up to date or skipped \u2728");
|
|
1961
2248
|
} else {
|
|
1962
|
-
|
|
2249
|
+
p11.cancel("No components were updated");
|
|
1963
2250
|
process.exit(1);
|
|
1964
2251
|
}
|
|
1965
2252
|
} catch (error) {
|
|
1966
|
-
|
|
1967
|
-
|
|
2253
|
+
p11.log.error(error instanceof Error ? error.message : "Failed to update components");
|
|
2254
|
+
p11.cancel("Operation cancelled");
|
|
1968
2255
|
process.exit(1);
|
|
1969
2256
|
}
|
|
1970
2257
|
}
|
|
@@ -1975,5 +2262,5 @@ program.command("init").description("Initialize your project with Starwind").opt
|
|
|
1975
2262
|
program.command("add").description("Add Starwind components to your project").argument("[components...]", "The components to add (space separated)").allowExcessArguments().option("-a, --all", "Add all available components").action(add);
|
|
1976
2263
|
program.command("update").description("Update Starwind components to their latest versions").argument("[components...]", "The components to update (space separated)").allowExcessArguments().option("-a, --all", "Update all installed components").option("-y, --yes", "Skip confirmation prompts").action(update);
|
|
1977
2264
|
program.command("remove").description("Remove Starwind components from your project").argument("[components...]", "The components to remove (space separated)").allowExcessArguments().option("-a, --all", "Remove all installed components").action(remove);
|
|
1978
|
-
program.parse();
|
|
2265
|
+
program.parse(process.argv);
|
|
1979
2266
|
//# sourceMappingURL=index.js.map
|