starwind 0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Boston343 (webreaper)
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 ADDED
@@ -0,0 +1,39 @@
1
+ # Starwind
2
+
3
+ A CLI for adding Astro components to your project.
4
+
5
+ ## Initialization
6
+
7
+ Use the `init` command to initialize your project:
8
+
9
+ ```bash
10
+ npx starwind@latest init
11
+ ```
12
+
13
+ ## Adding Components
14
+
15
+ Use the `add` command to add components to your project:
16
+
17
+ ```bash
18
+ npx starwind@latest add [components...]
19
+ ```
20
+
21
+ ### Example
22
+
23
+ ```bash
24
+ npx starwind@latest add button
25
+ ```
26
+
27
+ You can also run the command without any argument to view a list of available components:
28
+
29
+ ```bash
30
+ npx starwind@latest add
31
+ ```
32
+
33
+ ## Documentation
34
+
35
+ Visit [https://starwind.dev/](https://starwind.dev/) to view the documentation.
36
+
37
+ ## License
38
+
39
+ Licensed under the [MIT license](https://github.com/boston343/starwind-ui/blob/main/LICENSE).
@@ -0,0 +1,621 @@
1
+ // src/commands/init.ts
2
+ import path from "node:path";
3
+
4
+ // src/templates/starwind.css.ts
5
+ var tailwindConfig = `@import "tailwindcss";
6
+ @plugin "tailwindcss-animate";
7
+ @plugin "@tailwindcss/forms";
8
+ @variant dark (&:where(.dark, .dark *));
9
+
10
+ @theme {
11
+ --animate-accordion-down: accordion-down 0.2s ease-out;
12
+ --animate-accordion-up: accordion-up 0.2s ease-out;
13
+
14
+ @keyframes accordion-down {
15
+ from {
16
+ height: 0;
17
+ }
18
+ to {
19
+ height: var(--starwind-accordion-content-height);
20
+ }
21
+ }
22
+
23
+ @keyframes accordion-up {
24
+ from {
25
+ height: var(--starwind-accordion-content-height);
26
+ }
27
+ to {
28
+ height: 0;
29
+ }
30
+ }
31
+ }
32
+
33
+ @theme inline {
34
+ --color-background: var(--background);
35
+ --color-foreground: var(--foreground);
36
+ --color-card: var(--card);
37
+ --color-card-foreground: var(--card-foreground);
38
+ --color-popover: var(--popover);
39
+ --color-popover-foreground: var(--popover-foreground);
40
+ --color-primary: var(--primary);
41
+ --color-primary-foreground: var(--primary-foreground);
42
+ --color-secondary: var(--secondary);
43
+ --color-secondary-foreground: var(--secondary-foreground);
44
+ --color-muted: var(--muted);
45
+ --color-muted-foreground: var(--muted-foreground);
46
+ --color-accent: var(--accent);
47
+ --color-accent-foreground: var(--accent-foreground);
48
+ --color-info: var(--info);
49
+ --color-info-foreground: var(--info-foreground);
50
+ --color-success: var(--success);
51
+ --color-success-foreground: var(--success-foreground);
52
+ --color-warning: var(--warning);
53
+ --color-warning-foreground: var(--warning-foreground);
54
+ --color-error: var(--error);
55
+ --color-error-foreground: var(--error-foreground);
56
+ --color-border: var(--border);
57
+ --color-input: var(--input);
58
+ --color-outline: var(--outline);
59
+
60
+ --radius-xs: calc(var(--radius) - 0.375rem);
61
+ --radius-sm: calc(var(--radius) - 0.25rem);
62
+ --radius-md: calc(var(--radius) - 0.125rem);
63
+ --radius-lg: var(--radius);
64
+ --radius-xl: calc(var(--radius) + 0.25rem);
65
+ --radius-2xl: calc(var(--radius) + 0.5rem);
66
+ --radius-3xl: calc(var(--radius) + 1rem);
67
+ }
68
+
69
+ @layer base {
70
+ :root {
71
+ --background: var(--color-neutral-50);
72
+ --foreground: var(--color-neutral-950);
73
+ --card: var(--color-neutral-50);
74
+ --card-foreground: var(--color-neutral-950);
75
+ --popover: var(--color-neutral-50);
76
+ --popover-foreground: var(--color-neutral-950);
77
+ --primary: var(--color-blue-700);
78
+ --primary-foreground: var(--color-neutral-50);
79
+ --secondary: var(--color-fuchsia-700);
80
+ --secondary-foreground: var(--color-neutral-50);
81
+ --muted: var(--color-neutral-100);
82
+ --muted-foreground: var(--color-neutral-600);
83
+ --accent: var(--color-neutral-200);
84
+ --accent-foreground: var(--color-neutral-900);
85
+ --info: var(--color-sky-300);
86
+ --info-foreground: var(--color-sky-950);
87
+ --success: var(--color-green-300);
88
+ --success-foreground: var(--color-green-950);
89
+ --warning: var(--color-amber-300);
90
+ --warning-foreground: var(--color-amber-950);
91
+ --error: var(--color-red-700);
92
+ --error-foreground: var(--color-neutral-50);
93
+ --border: var(--color-neutral-200);
94
+ --input: var(--color-neutral-200);
95
+ --outline: var(--color-blue-600);
96
+ --radius: 0.5rem;
97
+ }
98
+
99
+ .dark {
100
+ --background: var(--color-neutral-950);
101
+ --foreground: var(--color-neutral-50);
102
+ --card: var(--color-neutral-950);
103
+ --card-foreground: var(--color-neutral-50);
104
+ --popover: var(--color-neutral-950);
105
+ --popover-foreground: var(--color-neutral-50);
106
+ --primary: var(--color-blue-700);
107
+ --primary-foreground: var(--color-neutral-50);
108
+ --secondary: var(--color-fuchsia-300);
109
+ --secondary-foreground: var(--color-neutral-950);
110
+ --muted: var(--color-neutral-900);
111
+ --muted-foreground: var(--color-neutral-400);
112
+ --accent: var(--color-neutral-900);
113
+ --accent-foreground: var(--color-neutral-100);
114
+ --info: var(--color-sky-300);
115
+ --info-foreground: var(--color-sky-950);
116
+ --success: var(--color-green-300);
117
+ --success-foreground: var(--color-green-950);
118
+ --warning: var(--color-amber-300);
119
+ --warning-foreground: var(--color-amber-950);
120
+ --error: var(--color-red-800);
121
+ --error-foreground: var(--color-neutral-50);
122
+ --border: var(--color-neutral-800);
123
+ --input: var(--color-neutral-800);
124
+ --outline: var(--color-blue-600);
125
+ --radius: 0.5rem;
126
+ }
127
+
128
+ * {
129
+ @apply border-border;
130
+ }
131
+ *:focus-visible {
132
+ @apply outline-outline;
133
+ }
134
+ html {
135
+ @apply bg-background text-foreground scheme-light dark:scheme-dark;
136
+ }
137
+ button {
138
+ @apply cursor-pointer;
139
+ }
140
+ }
141
+
142
+ @layer utilities {
143
+ /* transition-colors but without outline-color transition property */
144
+ .starwind-transition-colors {
145
+ transition-property: color, background-color, border-color, text-decoration-color, fill, stroke,
146
+ --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;
147
+ transition-timing-function: var(--default-transition-timing-function);
148
+ transition-duration: var(--default-transition-duration);
149
+ }
150
+ }
151
+ `;
152
+
153
+ // src/utils/highlighter.ts
154
+ import chalk from "chalk";
155
+ var highlighter = {
156
+ error: chalk.red,
157
+ warn: chalk.yellow,
158
+ info: chalk.cyan,
159
+ infoBright: chalk.cyanBright,
160
+ success: chalk.greenBright,
161
+ underline: chalk.underline,
162
+ title: chalk.bgBlue
163
+ };
164
+
165
+ // src/utils/astro-config.ts
166
+ import * as p from "@clack/prompts";
167
+ import fs2 from "fs-extra";
168
+
169
+ // src/utils/fs.ts
170
+ import fs from "fs-extra";
171
+ async function ensureDirectory(dir) {
172
+ await fs.ensureDir(dir);
173
+ }
174
+ async function readJsonFile(filePath) {
175
+ return fs.readJson(filePath);
176
+ }
177
+ async function writeJsonFile(filePath, data) {
178
+ await fs.writeJson(filePath, data, { spaces: 2 });
179
+ }
180
+ async function fileExists(filePath) {
181
+ return fs.pathExists(filePath);
182
+ }
183
+ async function writeCssFile(filePath, content) {
184
+ await fs.writeFile(filePath, content, "utf-8");
185
+ }
186
+
187
+ // src/utils/astro-config.ts
188
+ var CONFIG_EXTENSIONS = ["ts", "js", "mjs", "cjs"];
189
+ async function findAstroConfig() {
190
+ for (const ext of CONFIG_EXTENSIONS) {
191
+ const configPath = `astro.config.${ext}`;
192
+ if (await fileExists(configPath)) {
193
+ return configPath;
194
+ }
195
+ }
196
+ return null;
197
+ }
198
+ async function setupAstroConfig() {
199
+ try {
200
+ let configPath = await findAstroConfig();
201
+ let content = "";
202
+ if (configPath) {
203
+ content = await fs2.readFile(configPath, "utf-8");
204
+ } else {
205
+ configPath = "astro.config.ts";
206
+ content = `import { defineConfig } from "astro/config";
207
+
208
+ export default defineConfig({});
209
+ `;
210
+ }
211
+ if (!content.includes('import tailwindcss from "@tailwindcss/vite"')) {
212
+ content = `import tailwindcss from "@tailwindcss/vite";
213
+ ${content}`;
214
+ }
215
+ const configStart = content.indexOf("defineConfig(") + "defineConfig(".length;
216
+ const configEnd = content.lastIndexOf(");");
217
+ let config = content.slice(configStart, configEnd);
218
+ config = config.trim().replace(/^{|}$/g, "").trim();
219
+ if (!config.includes("experimental")) {
220
+ config += `
221
+ experimental: {
222
+ svg: {
223
+ mode: "sprite",
224
+ },
225
+ },`;
226
+ } else if (!config.includes("svg: {")) {
227
+ const expEnd = config.indexOf("experimental:") + "experimental:".length;
228
+ const blockStart = config.indexOf("{", expEnd) + 1;
229
+ config = config.slice(0, blockStart) + `
230
+ svg: {
231
+ mode: "sprite",
232
+ },` + config.slice(blockStart);
233
+ }
234
+ if (!config.includes("vite:")) {
235
+ config += `
236
+ vite: {
237
+ plugins: [tailwindcss()],
238
+ },`;
239
+ } else if (!config.includes("plugins: [")) {
240
+ const viteEnd = config.indexOf("vite:") + "vite:".length;
241
+ const blockStart = config.indexOf("{", viteEnd) + 1;
242
+ config = config.slice(0, blockStart) + `
243
+ plugins: [tailwindcss()],` + config.slice(blockStart);
244
+ } else if (!config.includes("tailwindcss()")) {
245
+ const pluginsStart = config.indexOf("plugins:") + "plugins:".length;
246
+ const arrayStart = config.indexOf("[", pluginsStart) + 1;
247
+ config = config.slice(0, arrayStart) + `tailwindcss(), ` + config.slice(arrayStart);
248
+ }
249
+ const newContent = `${content.slice(0, configStart)}{
250
+ ${config}
251
+ }${content.slice(configEnd)}`;
252
+ await fs2.writeFile(configPath, newContent, "utf-8");
253
+ return true;
254
+ } catch (error) {
255
+ const errorMessage = error instanceof Error ? error.message : "An unknown error occurred";
256
+ p.log.error(highlighter.error(`Failed to setup Astro config: ${errorMessage}`));
257
+ return false;
258
+ }
259
+ }
260
+
261
+ // src/utils/constants.ts
262
+ var MIN_ASTRO_VERSION = "5.0.0";
263
+ var PATHS = {
264
+ STARWIND_CORE: "@starwind-ui/core",
265
+ STARWIND_CORE_COMPONENTS: "src/components",
266
+ STARWIND_CORE_REGISTRY: "registry.json",
267
+ LOCAL_CSS_FILE: "src/styles/starwind.css",
268
+ LOCAL_CONFIG_FILE: "starwind.config.json",
269
+ LOCAL_STYLES_DIR: "src/styles",
270
+ LOCAL_COMPONENTS_DIR: "src/components"
271
+ };
272
+ var ASTRO_PACKAGES = {
273
+ core: "astro@latest"
274
+ };
275
+ var OTHER_PACKAGES = {
276
+ tailwindCore: "tailwindcss@latest",
277
+ tailwindVite: "@tailwindcss/vite@latest",
278
+ tailwindForms: "@tailwindcss/forms@latest",
279
+ tailwindAnimate: "tailwindcss-animate@latest",
280
+ tablerIcons: "@tabler/icons@latest"
281
+ };
282
+ function getOtherPackages() {
283
+ return Object.values(OTHER_PACKAGES);
284
+ }
285
+
286
+ // src/utils/config.ts
287
+ var defaultConfig = {
288
+ tailwind: {
289
+ css: "src/styles/starwind.css",
290
+ baseColor: "gray",
291
+ cssVariables: true
292
+ },
293
+ // aliases: {
294
+ // components: "@/components",
295
+ // },
296
+ componentDir: "src/components/starwind",
297
+ components: []
298
+ };
299
+ async function getConfig() {
300
+ try {
301
+ if (await fileExists(PATHS.LOCAL_CONFIG_FILE)) {
302
+ const config = await readJsonFile(PATHS.LOCAL_CONFIG_FILE);
303
+ return {
304
+ ...defaultConfig,
305
+ ...config,
306
+ components: Array.isArray(config.components) ? config.components : []
307
+ };
308
+ }
309
+ } catch (error) {
310
+ console.error("Error reading config:", error);
311
+ }
312
+ return defaultConfig;
313
+ }
314
+ async function updateConfig(updates, options = { appendComponents: true }) {
315
+ const currentConfig = await getConfig();
316
+ const currentComponents = Array.isArray(currentConfig.components) ? currentConfig.components : [];
317
+ const newConfig = {
318
+ ...currentConfig,
319
+ tailwind: {
320
+ ...currentConfig.tailwind,
321
+ ...updates.tailwind || {}
322
+ },
323
+ componentDir: updates.componentDir ? updates.componentDir : currentConfig.componentDir,
324
+ components: updates.components ? options.appendComponents ? [...currentComponents, ...updates.components] : updates.components : currentComponents
325
+ };
326
+ try {
327
+ await writeJsonFile(PATHS.LOCAL_CONFIG_FILE, newConfig);
328
+ } catch (error) {
329
+ throw new Error(
330
+ `Failed to update config: ${error instanceof Error ? error.message : "Unknown error"}`
331
+ );
332
+ }
333
+ }
334
+
335
+ // src/utils/package-manager.ts
336
+ import * as p2 from "@clack/prompts";
337
+ import { execa } from "execa";
338
+ async function requestPackageManager() {
339
+ const pm = await p2.select({
340
+ message: "Select your preferred package manager",
341
+ options: [
342
+ { value: "pnpm", label: "pnpm", hint: "Default" },
343
+ { value: "npm", label: "npm" },
344
+ { value: "yarn", label: "yarn" },
345
+ { value: "bun", label: "bun" }
346
+ ]
347
+ });
348
+ if (p2.isCancel(pm)) {
349
+ p2.log.warn("No package manager selected, defaulting to npm");
350
+ return "npm";
351
+ }
352
+ return pm;
353
+ }
354
+ async function installDependencies(packages, pm, dev = false, force = false) {
355
+ const args = [
356
+ pm === "npm" ? "install" : "add",
357
+ ...packages,
358
+ dev ? pm === "npm" || pm === "pnpm" ? "-D" : "--dev" : "",
359
+ force ? "--force" : ""
360
+ ].filter(Boolean);
361
+ await execa(pm, args);
362
+ }
363
+
364
+ // src/utils/sleep.ts
365
+ var sleep = async (ms) => {
366
+ await new Promise((resolve) => setTimeout(resolve, ms));
367
+ };
368
+
369
+ // src/commands/init.ts
370
+ import * as p3 from "@clack/prompts";
371
+ import semver from "semver";
372
+ async function init(withinAdd = false) {
373
+ if (!withinAdd) {
374
+ p3.intro(highlighter.title(" Welcome to the Starwind CLI "));
375
+ }
376
+ try {
377
+ if (!await fileExists("package.json")) {
378
+ throw new Error(
379
+ "No package.json found. Please run this command in the root of your project."
380
+ );
381
+ }
382
+ const pkg = await readJsonFile("package.json");
383
+ const installTasks = [];
384
+ const configTasks = [];
385
+ const configChoices = await p3.group(
386
+ {
387
+ // ask where to install components
388
+ installLocation: () => p3.text({
389
+ message: "What is your components directory?",
390
+ placeholder: PATHS.LOCAL_COMPONENTS_DIR,
391
+ initialValue: PATHS.LOCAL_COMPONENTS_DIR,
392
+ validate(value) {
393
+ if (value.length === 0) return `Value is required!`;
394
+ if (path.isAbsolute(value)) return `Please use a relative path`;
395
+ if (value.includes("..")) return `Path traversal is not allowed`;
396
+ const invalidChars = /[<>:"|?*]/;
397
+ if (invalidChars.test(value)) return `Path contains invalid characters`;
398
+ const systemDirs = ["windows", "program files", "system32"];
399
+ if (systemDirs.some((dir) => value.toLowerCase().startsWith(dir))) {
400
+ return `Cannot install in system directories`;
401
+ }
402
+ }
403
+ }),
404
+ // ask where to add the css file
405
+ cssFile: () => p3.text({
406
+ message: `Where would you like to add the Tailwind ${highlighter.info(".css")} file?`,
407
+ placeholder: PATHS.LOCAL_CSS_FILE,
408
+ initialValue: PATHS.LOCAL_CSS_FILE,
409
+ validate(value) {
410
+ if (value.length === 0) return `Value is required!`;
411
+ if (!value.endsWith(".css")) return `File must end with .css extension`;
412
+ if (path.isAbsolute(value)) return `Please use a relative path`;
413
+ if (value.includes("..")) return `Path traversal is not allowed`;
414
+ const invalidChars = /[<>:"|?*]/;
415
+ if (invalidChars.test(value)) return `Path contains invalid characters`;
416
+ const systemDirs = ["windows", "program files", "system32"];
417
+ if (systemDirs.some((dir) => value.toLowerCase().startsWith(dir))) {
418
+ return `Cannot use system directories`;
419
+ }
420
+ const basename = path.basename(value, ".css");
421
+ if (!basename || basename.trim().length === 0) {
422
+ return `Invalid filename`;
423
+ }
424
+ }
425
+ }),
426
+ twBaseColor: () => p3.select({
427
+ message: "What Tailwind base color would you like to use?",
428
+ initialValue: "neutral",
429
+ options: [
430
+ { label: "Neutral (default)", value: "neutral" },
431
+ { label: "Stone", value: "stone" },
432
+ { label: "Zinc", value: "zinc" },
433
+ { label: "Gray", value: "gray" },
434
+ { label: "Slate", value: "slate" }
435
+ ]
436
+ })
437
+ },
438
+ {
439
+ // On Cancel callback that wraps the group
440
+ // So if the user cancels one of the prompts in the group this function will be called
441
+ onCancel: () => {
442
+ p3.cancel("Operation cancelled.");
443
+ process.exit(0);
444
+ }
445
+ }
446
+ );
447
+ const cssFileDir = path.dirname(configChoices.cssFile);
448
+ const componentInstallDir = path.join(configChoices.installLocation, "starwind");
449
+ configTasks.push({
450
+ title: "Creating project structure",
451
+ task: async () => {
452
+ await ensureDirectory(componentInstallDir);
453
+ await ensureDirectory(cssFileDir);
454
+ await sleep(250);
455
+ return "Created project structure";
456
+ }
457
+ });
458
+ configTasks.push({
459
+ title: "Setup Astro config file",
460
+ task: async () => {
461
+ const success = await setupAstroConfig();
462
+ if (!success) {
463
+ throw new Error("Failed to setup Astro config");
464
+ }
465
+ await sleep(250);
466
+ return "Astro config setup completed";
467
+ }
468
+ });
469
+ const cssFileExists = await fileExists(configChoices.cssFile);
470
+ let updatedTailwindConfig = tailwindConfig;
471
+ if (configChoices.twBaseColor !== "gray") {
472
+ updatedTailwindConfig = updatedTailwindConfig.replace(
473
+ /--color-neutral-/g,
474
+ `--color-${configChoices.twBaseColor}-`
475
+ );
476
+ }
477
+ if (cssFileExists) {
478
+ const shouldOverride = await p3.confirm({
479
+ message: `${highlighter.info(configChoices.cssFile)} already exists. Do you want to override it?`
480
+ });
481
+ if (!shouldOverride) {
482
+ p3.log.info("Skipping Tailwind CSS configuration");
483
+ } else {
484
+ configTasks.push({
485
+ title: "Creating Tailwind CSS configuration",
486
+ task: async () => {
487
+ await writeCssFile(configChoices.cssFile, updatedTailwindConfig);
488
+ await sleep(250);
489
+ return "Created Tailwind configuration";
490
+ }
491
+ });
492
+ }
493
+ } else {
494
+ configTasks.push({
495
+ title: "Creating Tailwind CSS configuration",
496
+ task: async () => {
497
+ await writeCssFile(configChoices.cssFile, updatedTailwindConfig);
498
+ await sleep(250);
499
+ return "Created Tailwind configuration";
500
+ }
501
+ });
502
+ }
503
+ configTasks.push({
504
+ title: "Updating project configuration",
505
+ task: async () => {
506
+ await updateConfig({
507
+ tailwind: {
508
+ css: configChoices.cssFile,
509
+ baseColor: configChoices.twBaseColor,
510
+ cssVariables: true
511
+ },
512
+ // aliases: {
513
+ // components: "@/components",
514
+ // },
515
+ componentDir: configChoices.installLocation,
516
+ components: []
517
+ });
518
+ await sleep(250);
519
+ return "Updated project starwind configuration";
520
+ }
521
+ });
522
+ const pm = await requestPackageManager();
523
+ if (pkg.dependencies?.astro) {
524
+ const astroVersion = pkg.dependencies.astro.replace(/^\^|~/, "");
525
+ if (!semver.gte(astroVersion, MIN_ASTRO_VERSION)) {
526
+ const shouldUpgrade = await p3.confirm({
527
+ message: `Starwind requires Astro v${MIN_ASTRO_VERSION} or higher. Would you like to upgrade from v${astroVersion}?`,
528
+ initialValue: true
529
+ });
530
+ if (p3.isCancel(shouldUpgrade)) {
531
+ p3.cancel("Operation cancelled");
532
+ return process.exit(0);
533
+ }
534
+ if (!shouldUpgrade) {
535
+ p3.cancel("Astro v5 or higher is required to use Starwind");
536
+ return process.exit(1);
537
+ }
538
+ installTasks.push({
539
+ title: "Upgrading Astro",
540
+ task: async () => {
541
+ await installDependencies([ASTRO_PACKAGES.core], pm);
542
+ return "Upgraded Astro successfully";
543
+ }
544
+ });
545
+ }
546
+ } else {
547
+ const shouldInstall2 = await p3.confirm({
548
+ message: `Starwind requires Astro v${MIN_ASTRO_VERSION} or higher. Would you like to install it?`,
549
+ initialValue: true
550
+ });
551
+ if (p3.isCancel(shouldInstall2)) {
552
+ p3.cancel("Operation cancelled");
553
+ return process.exit(0);
554
+ }
555
+ if (!shouldInstall2) {
556
+ p3.cancel("Astro is required to use Starwind");
557
+ return process.exit(1);
558
+ }
559
+ installTasks.push({
560
+ title: `Installing ${ASTRO_PACKAGES.core}`,
561
+ task: async () => {
562
+ await installDependencies([ASTRO_PACKAGES.core], pm);
563
+ return `Installed ${highlighter.info(ASTRO_PACKAGES.core)} successfully`;
564
+ }
565
+ });
566
+ }
567
+ const otherPackages = getOtherPackages();
568
+ const shouldInstall = await p3.confirm({
569
+ message: `Install ${highlighter.info(otherPackages.join(", "))} using ${highlighter.info(pm)}?`
570
+ });
571
+ if (p3.isCancel(shouldInstall)) {
572
+ p3.cancel("Operation cancelled");
573
+ return process.exit(0);
574
+ }
575
+ if (shouldInstall) {
576
+ installTasks.push({
577
+ title: `Installing packages`,
578
+ task: async () => {
579
+ await installDependencies(getOtherPackages(), pm, false, false);
580
+ return `${highlighter.info("Packages installed successfully")}`;
581
+ }
582
+ });
583
+ } else {
584
+ p3.log.warn(
585
+ highlighter.warn(`Skipped installation of packages. Make sure to install them manually`)
586
+ );
587
+ }
588
+ if (installTasks.length > 0) {
589
+ await p3.tasks(installTasks);
590
+ }
591
+ if (configTasks.length > 0) {
592
+ await p3.tasks(configTasks);
593
+ }
594
+ await sleep(250);
595
+ p3.note(
596
+ `Make sure your layout imports the ${highlighter.infoBright(configChoices.cssFile)} file`,
597
+ "Next steps"
598
+ );
599
+ if (!withinAdd) {
600
+ sleep(1e3);
601
+ p3.outro("Enjoy using Starwind UI \u{1F680}");
602
+ }
603
+ } catch (error) {
604
+ p3.log.error(error instanceof Error ? error.message : "Failed to add components");
605
+ p3.cancel("Operation cancelled");
606
+ process.exit(1);
607
+ }
608
+ }
609
+
610
+ export {
611
+ PATHS,
612
+ fileExists,
613
+ highlighter,
614
+ getConfig,
615
+ updateConfig,
616
+ requestPackageManager,
617
+ installDependencies,
618
+ sleep,
619
+ init
620
+ };
621
+ //# sourceMappingURL=chunk-JUEM67WU.js.map