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