starwind 1.16.2 → 2.0.1
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 +1 -1
- package/dist/index.js +351 -63
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
**Create animated websites in record time.**
|
|
6
6
|
|
|
7
|
-
Starwind UI is a collection of
|
|
7
|
+
Starwind UI is a collection of 49+ beautifully designed, animated, and accessible components built purely with Astro and vanilla JS. Inspired by [shadcn/ui](https://ui.shadcn.com/), components are added directly to your codebase, giving you full ownership and complete control.
|
|
8
8
|
|
|
9
9
|
**[Get Started →](https://starwind.dev/docs/getting-started/installation/)** | **[Explore Components](https://starwind.dev/docs/components/)**
|
|
10
10
|
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Command, Option } from "commander";
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "starwind",
|
|
9
|
-
version: "
|
|
9
|
+
version: "2.0.1",
|
|
10
10
|
description: "Add beautifully designed components to your Astro applications",
|
|
11
11
|
license: "MIT",
|
|
12
12
|
homepage: "https://starwind.dev/",
|
|
@@ -44,7 +44,7 @@ var package_default = {
|
|
|
44
44
|
scripts: {
|
|
45
45
|
build: "tsup",
|
|
46
46
|
dev: "tsup --watch",
|
|
47
|
-
"cli:link": "pnpm
|
|
47
|
+
"cli:link": "pnpm add --global . --ignore-scripts",
|
|
48
48
|
"cli:unlink": "pnpm rm --global starwind",
|
|
49
49
|
"cli:yalc:link": "yalc publish && yalc link @starwind-ui/core",
|
|
50
50
|
"cli:yalc:unlink": "yalc remove @starwind-ui/core && yalc remove starwind",
|
|
@@ -60,7 +60,7 @@ var package_default = {
|
|
|
60
60
|
},
|
|
61
61
|
dependencies: {
|
|
62
62
|
"@clack/prompts": "^0.11.0",
|
|
63
|
-
"@starwind-ui/core": "
|
|
63
|
+
"@starwind-ui/core": "2.0.1",
|
|
64
64
|
chalk: "^5.6.2",
|
|
65
65
|
commander: "^14.0.2",
|
|
66
66
|
execa: "^9.6.0",
|
|
@@ -76,7 +76,7 @@ var package_default = {
|
|
|
76
76
|
tsup: "^8.5.1"
|
|
77
77
|
},
|
|
78
78
|
engines: {
|
|
79
|
-
node: "
|
|
79
|
+
node: ">=22.12.0"
|
|
80
80
|
}
|
|
81
81
|
};
|
|
82
82
|
|
|
@@ -90,6 +90,7 @@ var PATHS = {
|
|
|
90
90
|
STARWIND_CORE: "@starwind-ui/core",
|
|
91
91
|
STARWIND_CORE_COMPONENTS: "src/components",
|
|
92
92
|
STARWIND_CORE_UTILS: "src/lib/utils",
|
|
93
|
+
STARWIND_DOCS_BASE_URL: "https://starwind.dev/docs/components",
|
|
93
94
|
STARWIND_REMOTE_COMPONENT_REGISTRY: "https://starwind.dev/registry.json",
|
|
94
95
|
STARWIND_PRO_REGISTRY: "https://pro.starwind.dev/r/{name}",
|
|
95
96
|
LOCAL_CSS_FILE: "src/styles/starwind.css",
|
|
@@ -2227,32 +2228,67 @@ ${registryResults.success.map((name) => ` ${name}`).join("\n")}`
|
|
|
2227
2228
|
}
|
|
2228
2229
|
}
|
|
2229
2230
|
|
|
2230
|
-
// src/commands/
|
|
2231
|
+
// src/commands/docs.ts
|
|
2231
2232
|
import * as p10 from "@clack/prompts";
|
|
2233
|
+
var DOCS_BASE_URL = "https://starwind.dev/docs/components";
|
|
2234
|
+
async function docs(components, options) {
|
|
2235
|
+
if (!options?.json) {
|
|
2236
|
+
p10.intro(highlighter.title(" Starwind Docs "));
|
|
2237
|
+
}
|
|
2238
|
+
try {
|
|
2239
|
+
const registry = await getAllComponents();
|
|
2240
|
+
const results = [];
|
|
2241
|
+
for (const name of components) {
|
|
2242
|
+
const exists = registry.find((c) => c.name === name);
|
|
2243
|
+
if (!exists) {
|
|
2244
|
+
p10.log.error(`Component ${highlighter.info(name)} not found in the Starwind registry.`);
|
|
2245
|
+
process.exit(1);
|
|
2246
|
+
}
|
|
2247
|
+
results.push({ component: name, url: `${DOCS_BASE_URL}/${name}/` });
|
|
2248
|
+
}
|
|
2249
|
+
if (options?.json) {
|
|
2250
|
+
console.log(JSON.stringify(results, null, 2));
|
|
2251
|
+
return;
|
|
2252
|
+
}
|
|
2253
|
+
const maxNameLength = Math.max(...results.map((r) => r.component.length));
|
|
2254
|
+
p10.log.message(highlighter.underline("Documentation links"));
|
|
2255
|
+
for (const { component, url } of results) {
|
|
2256
|
+
p10.log.info(` ${highlighter.info(component.padEnd(maxNameLength + 2))}${url}`);
|
|
2257
|
+
}
|
|
2258
|
+
p10.outro(`Found docs for ${results.length} component${results.length === 1 ? "" : "s"}`);
|
|
2259
|
+
} catch (error) {
|
|
2260
|
+
p10.log.error(error instanceof Error ? error.message : "Failed to fetch documentation");
|
|
2261
|
+
p10.cancel("Operation cancelled");
|
|
2262
|
+
process.exit(1);
|
|
2263
|
+
}
|
|
2264
|
+
}
|
|
2265
|
+
|
|
2266
|
+
// src/commands/remove.ts
|
|
2267
|
+
import * as p11 from "@clack/prompts";
|
|
2232
2268
|
async function remove(components, options) {
|
|
2233
2269
|
try {
|
|
2234
|
-
|
|
2270
|
+
p11.intro(highlighter.title(" Welcome to the Starwind CLI "));
|
|
2235
2271
|
const configExists = await fileExists(PATHS.LOCAL_CONFIG_FILE);
|
|
2236
2272
|
if (!configExists) {
|
|
2237
|
-
|
|
2273
|
+
p11.log.error("No Starwind configuration found. Please run starwind init first.");
|
|
2238
2274
|
process.exit(1);
|
|
2239
2275
|
}
|
|
2240
2276
|
const config = await getConfig();
|
|
2241
2277
|
const installedComponents = config.components;
|
|
2242
2278
|
if (installedComponents.length === 0) {
|
|
2243
|
-
|
|
2279
|
+
p11.log.warn("No components are currently installed.");
|
|
2244
2280
|
process.exit(0);
|
|
2245
2281
|
}
|
|
2246
2282
|
let componentsToRemove = [];
|
|
2247
2283
|
if (options?.all) {
|
|
2248
2284
|
componentsToRemove = installedComponents.map((comp) => comp.name);
|
|
2249
|
-
|
|
2285
|
+
p11.log.info(`Removing all ${componentsToRemove.length} installed components...`);
|
|
2250
2286
|
} else if (components && components.length > 0) {
|
|
2251
2287
|
const invalid = components.filter(
|
|
2252
2288
|
(comp) => !installedComponents.some((ic) => ic.name === comp)
|
|
2253
2289
|
);
|
|
2254
2290
|
if (invalid.length > 0) {
|
|
2255
|
-
|
|
2291
|
+
p11.log.warn(
|
|
2256
2292
|
`${highlighter.warn("Components not found:")}
|
|
2257
2293
|
${invalid.map((name) => ` ${name}`).join("\n")}`
|
|
2258
2294
|
);
|
|
@@ -2261,7 +2297,7 @@ ${invalid.map((name) => ` ${name}`).join("\n")}`
|
|
|
2261
2297
|
(comp) => installedComponents.some((ic) => ic.name === comp)
|
|
2262
2298
|
);
|
|
2263
2299
|
if (componentsToRemove.length === 0) {
|
|
2264
|
-
|
|
2300
|
+
p11.log.warn("No valid components to remove");
|
|
2265
2301
|
process.exit(0);
|
|
2266
2302
|
}
|
|
2267
2303
|
} else {
|
|
@@ -2269,25 +2305,25 @@ ${invalid.map((name) => ` ${name}`).join("\n")}`
|
|
|
2269
2305
|
value: comp.name,
|
|
2270
2306
|
label: comp.name
|
|
2271
2307
|
}));
|
|
2272
|
-
const selected = await
|
|
2308
|
+
const selected = await p11.multiselect({
|
|
2273
2309
|
message: "Select components to remove",
|
|
2274
2310
|
options: choices
|
|
2275
2311
|
});
|
|
2276
|
-
if (
|
|
2277
|
-
|
|
2312
|
+
if (p11.isCancel(selected)) {
|
|
2313
|
+
p11.cancel("Operation cancelled");
|
|
2278
2314
|
process.exit(0);
|
|
2279
2315
|
}
|
|
2280
2316
|
componentsToRemove = selected;
|
|
2281
2317
|
}
|
|
2282
2318
|
if (componentsToRemove.length === 0) {
|
|
2283
|
-
|
|
2319
|
+
p11.log.warn("No components selected for removal");
|
|
2284
2320
|
process.exit(0);
|
|
2285
2321
|
}
|
|
2286
|
-
const confirmed = await
|
|
2322
|
+
const confirmed = await p11.confirm({
|
|
2287
2323
|
message: `Remove ${componentsToRemove.map((comp) => highlighter.info(comp)).join(", ")} ${componentsToRemove.length > 1 ? "components" : "component"}?`
|
|
2288
2324
|
});
|
|
2289
|
-
if (!confirmed ||
|
|
2290
|
-
|
|
2325
|
+
if (!confirmed || p11.isCancel(confirmed)) {
|
|
2326
|
+
p11.cancel("Operation cancelled");
|
|
2291
2327
|
process.exit(0);
|
|
2292
2328
|
}
|
|
2293
2329
|
const results = {
|
|
@@ -2312,60 +2348,295 @@ ${invalid.map((name) => ` ${name}`).join("\n")}`
|
|
|
2312
2348
|
},
|
|
2313
2349
|
{ appendComponents: false }
|
|
2314
2350
|
);
|
|
2315
|
-
|
|
2351
|
+
p11.log.message(`
|
|
2316
2352
|
|
|
2317
2353
|
${highlighter.underline("Removal Summary")}`);
|
|
2318
2354
|
if (results.failed.length > 0) {
|
|
2319
|
-
|
|
2355
|
+
p11.log.error(
|
|
2320
2356
|
`${highlighter.error("Failed to remove components:")}
|
|
2321
2357
|
${results.failed.map((r) => ` ${r.name} - ${r.error}`).join("\n")}`
|
|
2322
2358
|
);
|
|
2323
2359
|
}
|
|
2324
2360
|
if (results.removed.length > 0) {
|
|
2325
|
-
|
|
2361
|
+
p11.log.success(
|
|
2326
2362
|
`${highlighter.success("Successfully removed components:")}
|
|
2327
2363
|
${results.removed.map((r) => ` ${r.name}`).join("\n")}`
|
|
2328
2364
|
);
|
|
2329
2365
|
}
|
|
2330
2366
|
await sleep(1e3);
|
|
2331
2367
|
if (results.removed.length > 0) {
|
|
2332
|
-
|
|
2368
|
+
p11.outro("Components removed successfully \u{1F5D1}\uFE0F");
|
|
2333
2369
|
} else {
|
|
2334
|
-
|
|
2370
|
+
p11.cancel("Errors occurred while removing components");
|
|
2335
2371
|
process.exit(1);
|
|
2336
2372
|
}
|
|
2337
2373
|
} catch (error) {
|
|
2338
|
-
|
|
2339
|
-
|
|
2374
|
+
p11.log.error(error instanceof Error ? error.message : "Failed to remove components");
|
|
2375
|
+
p11.cancel("Operation cancelled");
|
|
2376
|
+
process.exit(1);
|
|
2377
|
+
}
|
|
2378
|
+
}
|
|
2379
|
+
|
|
2380
|
+
// src/commands/search.ts
|
|
2381
|
+
import * as p12 from "@clack/prompts";
|
|
2382
|
+
|
|
2383
|
+
// src/utils/pro-manifest.ts
|
|
2384
|
+
import { z as z2 } from "zod";
|
|
2385
|
+
var manifestBlockSchema = z2.object({
|
|
2386
|
+
id: z2.string(),
|
|
2387
|
+
name: z2.string(),
|
|
2388
|
+
description: z2.string(),
|
|
2389
|
+
categories: z2.array(z2.string()),
|
|
2390
|
+
keywords: z2.array(z2.string()),
|
|
2391
|
+
plan: z2.enum(["free", "pro"]),
|
|
2392
|
+
installCommand: z2.string(),
|
|
2393
|
+
previewUrl: z2.string()
|
|
2394
|
+
});
|
|
2395
|
+
var manifestSchema = z2.object({
|
|
2396
|
+
$schema: z2.string().optional(),
|
|
2397
|
+
name: z2.string(),
|
|
2398
|
+
version: z2.string(),
|
|
2399
|
+
generatedAt: z2.string(),
|
|
2400
|
+
baseUrl: z2.string(),
|
|
2401
|
+
totalBlocks: z2.number(),
|
|
2402
|
+
categories: z2.array(z2.string()),
|
|
2403
|
+
blocks: z2.array(manifestBlockSchema)
|
|
2404
|
+
});
|
|
2405
|
+
var MANIFEST_URL = "https://pro.starwind.dev/r/manifest.json";
|
|
2406
|
+
var CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
2407
|
+
var manifestCache = null;
|
|
2408
|
+
async function getProManifest() {
|
|
2409
|
+
if (manifestCache && Date.now() < manifestCache.expiresAt) {
|
|
2410
|
+
return { manifest: manifestCache.data, source: "cache" };
|
|
2411
|
+
}
|
|
2412
|
+
try {
|
|
2413
|
+
const response = await fetch(MANIFEST_URL);
|
|
2414
|
+
if (!response.ok) {
|
|
2415
|
+
throw new Error(`Failed to fetch manifest: ${response.status} ${response.statusText}`);
|
|
2416
|
+
}
|
|
2417
|
+
const raw = await response.json();
|
|
2418
|
+
const manifest = manifestSchema.parse(raw);
|
|
2419
|
+
manifestCache = {
|
|
2420
|
+
data: manifest,
|
|
2421
|
+
timestamp: Date.now(),
|
|
2422
|
+
expiresAt: Date.now() + CACHE_TTL_MS
|
|
2423
|
+
};
|
|
2424
|
+
return { manifest, source: "network" };
|
|
2425
|
+
} catch (error) {
|
|
2426
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
2427
|
+
throw new Error(`Error fetching Starwind Pro manifest: ${message}`);
|
|
2428
|
+
}
|
|
2429
|
+
}
|
|
2430
|
+
function scoreBlockMatch(block, query) {
|
|
2431
|
+
const q = query.toLowerCase();
|
|
2432
|
+
let score = 0;
|
|
2433
|
+
if (block.name.toLowerCase() === q) score += 100;
|
|
2434
|
+
else if (block.name.toLowerCase().includes(q)) score += 50;
|
|
2435
|
+
if (block.id.toLowerCase().includes(q)) score += 40;
|
|
2436
|
+
if (block.keywords.some((k) => k.toLowerCase() === q)) score += 30;
|
|
2437
|
+
if (block.keywords.some((k) => k.toLowerCase().includes(q))) score += 20;
|
|
2438
|
+
if (block.description.toLowerCase().includes(q)) score += 10;
|
|
2439
|
+
if (block.categories.some((c) => c.toLowerCase().includes(q))) score += 15;
|
|
2440
|
+
return score;
|
|
2441
|
+
}
|
|
2442
|
+
async function searchProBlocks(options = {}) {
|
|
2443
|
+
const { query, category, plan, limit = 50, offset = 0 } = options;
|
|
2444
|
+
const { manifest } = await getProManifest();
|
|
2445
|
+
let results = [...manifest.blocks];
|
|
2446
|
+
if (category) {
|
|
2447
|
+
const catLower = category.toLowerCase();
|
|
2448
|
+
results = results.filter((b) => b.categories.some((c) => c.toLowerCase() === catLower));
|
|
2449
|
+
}
|
|
2450
|
+
if (plan) {
|
|
2451
|
+
results = results.filter((b) => b.plan === plan);
|
|
2452
|
+
}
|
|
2453
|
+
if (query) {
|
|
2454
|
+
const scored = results.map((block) => ({ block, score: scoreBlockMatch(block, query) })).filter(({ score }) => score > 0).sort((a, b) => b.score - a.score);
|
|
2455
|
+
results = scored.map(({ block }) => block);
|
|
2456
|
+
}
|
|
2457
|
+
const effectiveLimit = Math.min(Math.max(1, limit), 50);
|
|
2458
|
+
const effectiveOffset = Math.max(0, offset);
|
|
2459
|
+
return results.slice(effectiveOffset, effectiveOffset + effectiveLimit);
|
|
2460
|
+
}
|
|
2461
|
+
|
|
2462
|
+
// src/commands/search.ts
|
|
2463
|
+
async function search(query, options) {
|
|
2464
|
+
if (!options?.json) {
|
|
2465
|
+
p12.intro(highlighter.title(" Starwind Search "));
|
|
2466
|
+
}
|
|
2467
|
+
try {
|
|
2468
|
+
const proOnly = !!(options?.category || options?.plan);
|
|
2469
|
+
let proBlocks = [];
|
|
2470
|
+
let matchedComponents = [];
|
|
2471
|
+
if (options?.json) {
|
|
2472
|
+
proBlocks = await searchProBlocks({
|
|
2473
|
+
query,
|
|
2474
|
+
category: options?.category,
|
|
2475
|
+
plan: options?.plan,
|
|
2476
|
+
limit: options?.limit ?? 20,
|
|
2477
|
+
offset: options?.offset ?? 0
|
|
2478
|
+
});
|
|
2479
|
+
if (!proOnly) {
|
|
2480
|
+
const coreComponents = await getAllComponents();
|
|
2481
|
+
if (query) {
|
|
2482
|
+
const q = query.toLowerCase();
|
|
2483
|
+
matchedComponents = coreComponents.filter(
|
|
2484
|
+
(c) => c.name.toLowerCase().includes(q) || (c.dependencies ?? []).some((dep) => dep.toLowerCase().includes(q))
|
|
2485
|
+
);
|
|
2486
|
+
} else {
|
|
2487
|
+
matchedComponents = coreComponents;
|
|
2488
|
+
}
|
|
2489
|
+
}
|
|
2490
|
+
} else {
|
|
2491
|
+
const searchTasks = [
|
|
2492
|
+
{
|
|
2493
|
+
title: "Searching Starwind Pro blocks",
|
|
2494
|
+
task: async () => {
|
|
2495
|
+
proBlocks = await searchProBlocks({
|
|
2496
|
+
query,
|
|
2497
|
+
category: options?.category,
|
|
2498
|
+
plan: options?.plan,
|
|
2499
|
+
limit: options?.limit ?? 20,
|
|
2500
|
+
offset: options?.offset ?? 0
|
|
2501
|
+
});
|
|
2502
|
+
return `Found ${proBlocks.length} Pro block${proBlocks.length === 1 ? "" : "s"}`;
|
|
2503
|
+
}
|
|
2504
|
+
}
|
|
2505
|
+
];
|
|
2506
|
+
if (!proOnly) {
|
|
2507
|
+
searchTasks.push({
|
|
2508
|
+
title: "Searching core components",
|
|
2509
|
+
task: async () => {
|
|
2510
|
+
const coreComponents = await getAllComponents();
|
|
2511
|
+
if (query) {
|
|
2512
|
+
const q = query.toLowerCase();
|
|
2513
|
+
matchedComponents = coreComponents.filter(
|
|
2514
|
+
(c) => c.name.toLowerCase().includes(q) || (c.dependencies ?? []).some((dep) => dep.toLowerCase().includes(q))
|
|
2515
|
+
);
|
|
2516
|
+
} else {
|
|
2517
|
+
matchedComponents = coreComponents;
|
|
2518
|
+
}
|
|
2519
|
+
return `Found ${matchedComponents.length} core component${matchedComponents.length === 1 ? "" : "s"}`;
|
|
2520
|
+
}
|
|
2521
|
+
});
|
|
2522
|
+
}
|
|
2523
|
+
await p12.tasks(searchTasks);
|
|
2524
|
+
}
|
|
2525
|
+
if (options?.json) {
|
|
2526
|
+
console.log(
|
|
2527
|
+
JSON.stringify(
|
|
2528
|
+
{
|
|
2529
|
+
query: query || null,
|
|
2530
|
+
filters: {
|
|
2531
|
+
category: options?.category || null,
|
|
2532
|
+
plan: options?.plan || null,
|
|
2533
|
+
limit: options?.limit ?? 20
|
|
2534
|
+
},
|
|
2535
|
+
proBlocks: {
|
|
2536
|
+
total: proBlocks.length,
|
|
2537
|
+
results: proBlocks.map((b) => ({
|
|
2538
|
+
id: b.id,
|
|
2539
|
+
name: b.name,
|
|
2540
|
+
description: b.description,
|
|
2541
|
+
categories: b.categories,
|
|
2542
|
+
plan: b.plan,
|
|
2543
|
+
installCommand: b.installCommand + " --yes"
|
|
2544
|
+
}))
|
|
2545
|
+
},
|
|
2546
|
+
coreComponents: {
|
|
2547
|
+
total: matchedComponents.length,
|
|
2548
|
+
results: matchedComponents.map((c) => ({
|
|
2549
|
+
name: c.name,
|
|
2550
|
+
version: c.version,
|
|
2551
|
+
dependencies: c.dependencies,
|
|
2552
|
+
docsUrl: `${PATHS.STARWIND_DOCS_BASE_URL}/${c.name}/`
|
|
2553
|
+
}))
|
|
2554
|
+
},
|
|
2555
|
+
proSetupTip: "Run `starwind setup` to enable Starwind Pro blocks"
|
|
2556
|
+
},
|
|
2557
|
+
null,
|
|
2558
|
+
2
|
|
2559
|
+
)
|
|
2560
|
+
);
|
|
2561
|
+
return;
|
|
2562
|
+
}
|
|
2563
|
+
const hasPro = proBlocks.length > 0;
|
|
2564
|
+
const hasCore = matchedComponents.length > 0;
|
|
2565
|
+
if (!hasPro && !hasCore) {
|
|
2566
|
+
p12.log.warn("No results found for your search.");
|
|
2567
|
+
p12.outro("Try a different query or browse all categories.");
|
|
2568
|
+
return;
|
|
2569
|
+
}
|
|
2570
|
+
if (hasPro) {
|
|
2571
|
+
p12.log.message(highlighter.underline("Pro Blocks"));
|
|
2572
|
+
const maxNameLen = Math.max(...proBlocks.map((b) => b.name.length));
|
|
2573
|
+
for (const block of proBlocks) {
|
|
2574
|
+
const planBadge = block.plan === "pro" ? highlighter.info("[pro] ") : highlighter.success("[free]");
|
|
2575
|
+
const paddedName = block.name.padEnd(maxNameLen + 2);
|
|
2576
|
+
p12.log.info(` ${highlighter.info(paddedName)}${planBadge} ${block.installCommand}`);
|
|
2577
|
+
}
|
|
2578
|
+
console.log();
|
|
2579
|
+
}
|
|
2580
|
+
if (hasCore) {
|
|
2581
|
+
p12.log.message(highlighter.underline("Core Components"));
|
|
2582
|
+
const maxNameLen = Math.max(...matchedComponents.map((c) => c.name.length));
|
|
2583
|
+
for (const comp of matchedComponents) {
|
|
2584
|
+
const paddedName = comp.name.padEnd(maxNameLen + 2);
|
|
2585
|
+
p12.log.info(` ${highlighter.info(paddedName)}starwind add ${comp.name}`);
|
|
2586
|
+
}
|
|
2587
|
+
console.log();
|
|
2588
|
+
}
|
|
2589
|
+
if (proBlocks.length > 0) {
|
|
2590
|
+
const proConfigured = await hasStarwindProRegistry();
|
|
2591
|
+
const hasPaidBlocks = proBlocks.some((b) => b.plan === "pro");
|
|
2592
|
+
if (!proConfigured) {
|
|
2593
|
+
p12.note(
|
|
2594
|
+
`Pro blocks require Starwind Pro setup.
|
|
2595
|
+
Run ${highlighter.info("starwind setup")} to configure.`,
|
|
2596
|
+
"Pro Tip"
|
|
2597
|
+
);
|
|
2598
|
+
} else if (hasPaidBlocks) {
|
|
2599
|
+
p12.note(
|
|
2600
|
+
`Unlock premium blocks at ${highlighter.info("https://pro.starwind.dev/")}`,
|
|
2601
|
+
"Pro Tip"
|
|
2602
|
+
);
|
|
2603
|
+
}
|
|
2604
|
+
}
|
|
2605
|
+
p12.outro(
|
|
2606
|
+
`Found ${proBlocks.length + matchedComponents.length} result${proBlocks.length + matchedComponents.length === 1 ? "" : "s"} \u{1F50E}`
|
|
2607
|
+
);
|
|
2608
|
+
} catch (error) {
|
|
2609
|
+
p12.log.error(error instanceof Error ? error.message : "Failed to search");
|
|
2610
|
+
p12.cancel("Operation cancelled");
|
|
2340
2611
|
process.exit(1);
|
|
2341
2612
|
}
|
|
2342
2613
|
}
|
|
2343
2614
|
|
|
2344
2615
|
// src/commands/setup.ts
|
|
2345
|
-
import * as
|
|
2616
|
+
import * as p13 from "@clack/prompts";
|
|
2346
2617
|
async function setup(options) {
|
|
2347
|
-
|
|
2618
|
+
p13.intro(highlighter.title(" Using Starwind Setup "));
|
|
2348
2619
|
try {
|
|
2349
2620
|
const configExists = await fileExists(PATHS.LOCAL_CONFIG_FILE);
|
|
2350
2621
|
if (!configExists) {
|
|
2351
|
-
const shouldInit = options?.yes ? true : await
|
|
2622
|
+
const shouldInit = options?.yes ? true : await p13.confirm({
|
|
2352
2623
|
message: `Starwind configuration not found. Would you like to run ${highlighter.info("starwind init")} now?`,
|
|
2353
2624
|
initialValue: true
|
|
2354
2625
|
});
|
|
2355
|
-
if (
|
|
2356
|
-
|
|
2626
|
+
if (p13.isCancel(shouldInit)) {
|
|
2627
|
+
p13.cancel("Operation cancelled");
|
|
2357
2628
|
process.exit(0);
|
|
2358
2629
|
}
|
|
2359
2630
|
if (shouldInit) {
|
|
2360
2631
|
await init(true, { defaults: options?.yes, packageManager: options?.packageManager });
|
|
2361
2632
|
} else {
|
|
2362
|
-
|
|
2633
|
+
p13.log.error(
|
|
2363
2634
|
`Please initialize starwind with ${highlighter.info("starwind init")} before running setup`
|
|
2364
2635
|
);
|
|
2365
2636
|
process.exit(1);
|
|
2366
2637
|
}
|
|
2367
2638
|
}
|
|
2368
|
-
const
|
|
2639
|
+
const tasks5 = [
|
|
2369
2640
|
{
|
|
2370
2641
|
name: "Starwind Pro",
|
|
2371
2642
|
value: "pro",
|
|
@@ -2377,32 +2648,32 @@ async function setup(options) {
|
|
|
2377
2648
|
];
|
|
2378
2649
|
const selectedTasks = [];
|
|
2379
2650
|
if (options?.pro) {
|
|
2380
|
-
const proTask =
|
|
2651
|
+
const proTask = tasks5.find((t) => t.value === "pro");
|
|
2381
2652
|
if (proTask) selectedTasks.push(proTask);
|
|
2382
2653
|
} else {
|
|
2383
|
-
const proTask =
|
|
2654
|
+
const proTask = tasks5.find((t) => t.value === "pro");
|
|
2384
2655
|
if (proTask) selectedTasks.push(proTask);
|
|
2385
2656
|
}
|
|
2386
2657
|
if (selectedTasks.length === 0) {
|
|
2387
|
-
|
|
2658
|
+
p13.log.warn("No setup tasks selected.");
|
|
2388
2659
|
process.exit(0);
|
|
2389
2660
|
}
|
|
2390
2661
|
for (const task of selectedTasks) {
|
|
2391
2662
|
await task.run();
|
|
2392
2663
|
}
|
|
2393
2664
|
} catch (error) {
|
|
2394
|
-
|
|
2395
|
-
|
|
2665
|
+
p13.log.error(error instanceof Error ? error.message : "Failed to run setup");
|
|
2666
|
+
p13.cancel("Operation cancelled");
|
|
2396
2667
|
process.exit(1);
|
|
2397
2668
|
}
|
|
2398
2669
|
}
|
|
2399
2670
|
async function runProSetup() {
|
|
2400
|
-
|
|
2671
|
+
p13.log.info(highlighter.info("Setting up Starwind Pro..."));
|
|
2401
2672
|
const configTasks = [];
|
|
2402
2673
|
const hasRegistry = await hasStarwindProRegistry();
|
|
2403
2674
|
const hasEnv = await checkStarwindProEnv();
|
|
2404
2675
|
if (hasRegistry && hasEnv) {
|
|
2405
|
-
|
|
2676
|
+
p13.log.info(highlighter.info("Starwind Pro registry and environment already configured"));
|
|
2406
2677
|
} else {
|
|
2407
2678
|
let cssFile = PATHS.LOCAL_CSS_FILE;
|
|
2408
2679
|
let baseColor = "neutral";
|
|
@@ -2436,7 +2707,7 @@ async function runProSetup() {
|
|
|
2436
2707
|
});
|
|
2437
2708
|
}
|
|
2438
2709
|
if (configTasks.length > 0) {
|
|
2439
|
-
await
|
|
2710
|
+
await p13.tasks(configTasks);
|
|
2440
2711
|
}
|
|
2441
2712
|
}
|
|
2442
2713
|
await sleep(250);
|
|
@@ -2444,37 +2715,37 @@ async function runProSetup() {
|
|
|
2444
2715
|
${highlighter.info("npx starwind@latest add @starwind-pro/component-name")}
|
|
2445
2716
|
|
|
2446
2717
|
Make sure to set your ${highlighter.infoBright("STARWIND_LICENSE_KEY")} environment variable in ${highlighter.infoBright(".env.local")}`;
|
|
2447
|
-
|
|
2718
|
+
p13.note(nextStepsMessage, "Next steps");
|
|
2448
2719
|
await sleep(1e3);
|
|
2449
|
-
|
|
2720
|
+
p13.outro("Enjoy using Starwind UI with Pro components! \u{1F680}");
|
|
2450
2721
|
}
|
|
2451
2722
|
|
|
2452
2723
|
// src/commands/update.ts
|
|
2453
|
-
import * as
|
|
2724
|
+
import * as p14 from "@clack/prompts";
|
|
2454
2725
|
async function update(components, options) {
|
|
2455
2726
|
try {
|
|
2456
|
-
|
|
2727
|
+
p14.intro(highlighter.title(" Welcome to the Starwind CLI "));
|
|
2457
2728
|
const configExists = await fileExists(PATHS.LOCAL_CONFIG_FILE);
|
|
2458
2729
|
if (!configExists) {
|
|
2459
|
-
|
|
2730
|
+
p14.log.error("No Starwind configuration found. Please run starwind init first.");
|
|
2460
2731
|
process.exit(1);
|
|
2461
2732
|
}
|
|
2462
2733
|
const config = await getConfig();
|
|
2463
2734
|
const installedComponents = config.components;
|
|
2464
2735
|
if (installedComponents.length === 0) {
|
|
2465
|
-
|
|
2736
|
+
p14.log.warn("No components are currently installed.");
|
|
2466
2737
|
process.exit(0);
|
|
2467
2738
|
}
|
|
2468
2739
|
let componentsToUpdate = [];
|
|
2469
2740
|
if (options?.all) {
|
|
2470
2741
|
componentsToUpdate = installedComponents.map((comp) => comp.name);
|
|
2471
|
-
|
|
2742
|
+
p14.log.info(`Checking updates for all ${componentsToUpdate.length} installed components...`);
|
|
2472
2743
|
} else if (components && components.length > 0) {
|
|
2473
2744
|
const invalid = components.filter(
|
|
2474
2745
|
(comp) => !installedComponents.some((ic) => ic.name === comp)
|
|
2475
2746
|
);
|
|
2476
2747
|
if (invalid.length > 0) {
|
|
2477
|
-
|
|
2748
|
+
p14.log.warn(
|
|
2478
2749
|
`${highlighter.warn("Components not found in project:")}
|
|
2479
2750
|
${invalid.map((name) => ` ${name}`).join("\n")}`
|
|
2480
2751
|
);
|
|
@@ -2483,7 +2754,7 @@ ${invalid.map((name) => ` ${name}`).join("\n")}`
|
|
|
2483
2754
|
(comp) => installedComponents.some((ic) => ic.name === comp)
|
|
2484
2755
|
);
|
|
2485
2756
|
if (componentsToUpdate.length === 0) {
|
|
2486
|
-
|
|
2757
|
+
p14.log.warn("No valid components to update");
|
|
2487
2758
|
process.exit(0);
|
|
2488
2759
|
}
|
|
2489
2760
|
} else {
|
|
@@ -2491,18 +2762,18 @@ ${invalid.map((name) => ` ${name}`).join("\n")}`
|
|
|
2491
2762
|
value: comp.name,
|
|
2492
2763
|
label: comp.name
|
|
2493
2764
|
}));
|
|
2494
|
-
const selected = await
|
|
2765
|
+
const selected = await p14.multiselect({
|
|
2495
2766
|
message: "Select components to update",
|
|
2496
2767
|
options: choices
|
|
2497
2768
|
});
|
|
2498
|
-
if (
|
|
2499
|
-
|
|
2769
|
+
if (p14.isCancel(selected)) {
|
|
2770
|
+
p14.cancel("Operation cancelled");
|
|
2500
2771
|
process.exit(0);
|
|
2501
2772
|
}
|
|
2502
2773
|
componentsToUpdate = selected;
|
|
2503
2774
|
}
|
|
2504
2775
|
if (componentsToUpdate.length === 0) {
|
|
2505
|
-
|
|
2776
|
+
p14.log.warn("No components selected for update");
|
|
2506
2777
|
process.exit(0);
|
|
2507
2778
|
}
|
|
2508
2779
|
const results = {
|
|
@@ -2553,45 +2824,45 @@ ${invalid.map((name) => ` ${name}`).join("\n")}`
|
|
|
2553
2824
|
{ appendComponents: false }
|
|
2554
2825
|
);
|
|
2555
2826
|
} catch (error) {
|
|
2556
|
-
|
|
2827
|
+
p14.log.error(
|
|
2557
2828
|
`Failed to update config: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
2558
2829
|
);
|
|
2559
2830
|
process.exit(1);
|
|
2560
2831
|
}
|
|
2561
2832
|
}
|
|
2562
|
-
|
|
2833
|
+
p14.log.message(`
|
|
2563
2834
|
|
|
2564
2835
|
${highlighter.underline("Update Summary")}`);
|
|
2565
2836
|
if (results.failed.length > 0) {
|
|
2566
|
-
|
|
2837
|
+
p14.log.error(
|
|
2567
2838
|
`${highlighter.error("Failed to update components:")}
|
|
2568
2839
|
${results.failed.map((r) => ` ${r.name} - ${r.error}`).join("\n")}`
|
|
2569
2840
|
);
|
|
2570
2841
|
}
|
|
2571
2842
|
if (results.skipped.length > 0) {
|
|
2572
|
-
|
|
2843
|
+
p14.log.info(
|
|
2573
2844
|
`${highlighter.info("Components already up to date or skipped:")}
|
|
2574
2845
|
${results.skipped.map((r) => ` ${r.name} (${r.oldVersion})`).join("\n")}`
|
|
2575
2846
|
);
|
|
2576
2847
|
}
|
|
2577
2848
|
if (results.updated.length > 0) {
|
|
2578
|
-
|
|
2849
|
+
p14.log.success(
|
|
2579
2850
|
`${highlighter.success("Successfully updated components:")}
|
|
2580
2851
|
${results.updated.map((r) => ` ${r.name} (${r.oldVersion} \u2192 ${r.newVersion})`).join("\n")}`
|
|
2581
2852
|
);
|
|
2582
2853
|
}
|
|
2583
2854
|
await sleep(1e3);
|
|
2584
2855
|
if (results.updated.length > 0) {
|
|
2585
|
-
|
|
2856
|
+
p14.outro("Components updated successfully \u{1F680}");
|
|
2586
2857
|
} else if (results.skipped.length > 0 && results.failed.length === 0) {
|
|
2587
|
-
|
|
2858
|
+
p14.outro("Components already up to date or skipped \u2728");
|
|
2588
2859
|
} else {
|
|
2589
|
-
|
|
2860
|
+
p14.cancel("No components were updated");
|
|
2590
2861
|
process.exit(1);
|
|
2591
2862
|
}
|
|
2592
2863
|
} catch (error) {
|
|
2593
|
-
|
|
2594
|
-
|
|
2864
|
+
p14.log.error(error instanceof Error ? error.message : "Failed to update components");
|
|
2865
|
+
p14.cancel("Operation cancelled");
|
|
2595
2866
|
process.exit(1);
|
|
2596
2867
|
}
|
|
2597
2868
|
}
|
|
@@ -2606,6 +2877,23 @@ program.command("add").description("Add Starwind components to your project").ar
|
|
|
2606
2877
|
"yarn"
|
|
2607
2878
|
])
|
|
2608
2879
|
).action(add);
|
|
2880
|
+
program.command("docs").description("Open documentation for Starwind components").argument("[components...]", "The components to look up (space separated)").allowExcessArguments().option("--json", "Output as JSON").action(docs);
|
|
2881
|
+
program.command("search").description("Search Starwind components and Pro blocks").argument("[query]", "Search query string").allowExcessArguments().option("-p, --plan <plan>", "Filter Pro blocks by plan type (free or pro)").option("-c, --category <category>", "Filter Pro blocks by category").option("-l, --limit <number>", "Maximum number of Pro blocks to display", "20").option("-o, --offset <number>", "Offset for paginating Pro block results", "0").option("--json", "Output as JSON").action(
|
|
2882
|
+
async (query, opts) => {
|
|
2883
|
+
const parsedLimit = Math.min(Math.max(parseInt(opts.limit, 10) || 20, 1), 50);
|
|
2884
|
+
const parsedOffset = Math.max(parseInt(opts.offset, 10) || 0, 0);
|
|
2885
|
+
if (opts.plan && opts.plan !== "free" && opts.plan !== "pro") {
|
|
2886
|
+
program.error(`Invalid plan "${opts.plan}". Must be "free" or "pro".`);
|
|
2887
|
+
}
|
|
2888
|
+
await search(query, {
|
|
2889
|
+
plan: opts.plan,
|
|
2890
|
+
category: opts.category,
|
|
2891
|
+
limit: parsedLimit,
|
|
2892
|
+
offset: parsedOffset,
|
|
2893
|
+
json: opts.json
|
|
2894
|
+
});
|
|
2895
|
+
}
|
|
2896
|
+
);
|
|
2609
2897
|
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").addOption(
|
|
2610
2898
|
new Option("-m, --package-manager <pm>", "Package manager to use").choices([
|
|
2611
2899
|
"npm",
|