@ratiu5/solidui-cli 0.7.2 → 0.7.3
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 +1229 -0
- package/package.json +1 -1
package/dist/index.js
ADDED
|
@@ -0,0 +1,1229 @@
|
|
|
1
|
+
#! /usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/index.ts
|
|
4
|
+
import { Command as Command3 } from "commander";
|
|
5
|
+
|
|
6
|
+
// src/commands/add.ts
|
|
7
|
+
import { existsSync as existsSync2 } from "fs";
|
|
8
|
+
import { mkdir, writeFile } from "fs/promises";
|
|
9
|
+
import path3 from "path";
|
|
10
|
+
import * as p2 from "@clack/prompts";
|
|
11
|
+
import { Command } from "commander";
|
|
12
|
+
import { execa } from "execa";
|
|
13
|
+
|
|
14
|
+
// ../../node_modules/.bun/valibot@0.36.0/node_modules/valibot/dist/index.js
|
|
15
|
+
var store;
|
|
16
|
+
function getGlobalConfig(config2) {
|
|
17
|
+
return {
|
|
18
|
+
lang: config2?.lang ?? store?.lang,
|
|
19
|
+
message: config2?.message,
|
|
20
|
+
abortEarly: config2?.abortEarly ?? store?.abortEarly,
|
|
21
|
+
abortPipeEarly: config2?.abortPipeEarly ?? store?.abortPipeEarly
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
var store2;
|
|
25
|
+
function getGlobalMessage(lang) {
|
|
26
|
+
return store2?.get(lang);
|
|
27
|
+
}
|
|
28
|
+
var store3;
|
|
29
|
+
function getSchemaMessage(lang) {
|
|
30
|
+
return store3?.get(lang);
|
|
31
|
+
}
|
|
32
|
+
var store4;
|
|
33
|
+
function getSpecificMessage(reference, lang) {
|
|
34
|
+
return store4?.get(reference)?.get(lang);
|
|
35
|
+
}
|
|
36
|
+
function _stringify(input) {
|
|
37
|
+
const type = typeof input;
|
|
38
|
+
if (type === "string") {
|
|
39
|
+
return `"${input}"`;
|
|
40
|
+
}
|
|
41
|
+
if (type === "number" || type === "bigint" || type === "boolean") {
|
|
42
|
+
return `${input}`;
|
|
43
|
+
}
|
|
44
|
+
if (type === "object" || type === "function") {
|
|
45
|
+
return (input && Object.getPrototypeOf(input)?.constructor?.name) ?? "null";
|
|
46
|
+
}
|
|
47
|
+
return type;
|
|
48
|
+
}
|
|
49
|
+
function _addIssue(context, label, dataset, config2, other) {
|
|
50
|
+
const input = other && "input" in other ? other.input : dataset.value;
|
|
51
|
+
const expected = other?.expected ?? context.expects ?? null;
|
|
52
|
+
const received = other?.received ?? _stringify(input);
|
|
53
|
+
const issue = {
|
|
54
|
+
kind: context.kind,
|
|
55
|
+
type: context.type,
|
|
56
|
+
input,
|
|
57
|
+
expected,
|
|
58
|
+
received,
|
|
59
|
+
message: `Invalid ${label}: ${expected ? `Expected ${expected} but r` : "R"}eceived ${received}`,
|
|
60
|
+
// @ts-expect-error
|
|
61
|
+
requirement: context.requirement,
|
|
62
|
+
path: other?.path,
|
|
63
|
+
issues: other?.issues,
|
|
64
|
+
lang: config2.lang,
|
|
65
|
+
abortEarly: config2.abortEarly,
|
|
66
|
+
abortPipeEarly: config2.abortPipeEarly
|
|
67
|
+
};
|
|
68
|
+
const isSchema = context.kind === "schema";
|
|
69
|
+
const message = other?.message ?? // @ts-expect-error
|
|
70
|
+
context.message ?? getSpecificMessage(context.reference, issue.lang) ?? (isSchema ? getSchemaMessage(issue.lang) : null) ?? config2.message ?? getGlobalMessage(issue.lang);
|
|
71
|
+
if (message) {
|
|
72
|
+
issue.message = typeof message === "function" ? message(issue) : message;
|
|
73
|
+
}
|
|
74
|
+
if (isSchema) {
|
|
75
|
+
dataset.typed = false;
|
|
76
|
+
}
|
|
77
|
+
if (dataset.issues) {
|
|
78
|
+
dataset.issues.push(issue);
|
|
79
|
+
} else {
|
|
80
|
+
dataset.issues = [issue];
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
var ValiError = class extends Error {
|
|
84
|
+
/**
|
|
85
|
+
* The error issues.
|
|
86
|
+
*/
|
|
87
|
+
issues;
|
|
88
|
+
/**
|
|
89
|
+
* Creates a Valibot error with useful information.
|
|
90
|
+
*
|
|
91
|
+
* @param issues The error issues.
|
|
92
|
+
*/
|
|
93
|
+
constructor(issues) {
|
|
94
|
+
super(issues[0].message);
|
|
95
|
+
this.name = "ValiError";
|
|
96
|
+
this.issues = issues;
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
function getDefault(schema, dataset, config2) {
|
|
100
|
+
return typeof schema.default === "function" ? (
|
|
101
|
+
// @ts-expect-error
|
|
102
|
+
schema.default(dataset, config2)
|
|
103
|
+
) : (
|
|
104
|
+
// @ts-expect-error
|
|
105
|
+
schema.default
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
function array(item, message) {
|
|
109
|
+
return {
|
|
110
|
+
kind: "schema",
|
|
111
|
+
type: "array",
|
|
112
|
+
reference: array,
|
|
113
|
+
expects: "Array",
|
|
114
|
+
async: false,
|
|
115
|
+
item,
|
|
116
|
+
message,
|
|
117
|
+
_run(dataset, config2) {
|
|
118
|
+
const input = dataset.value;
|
|
119
|
+
if (Array.isArray(input)) {
|
|
120
|
+
dataset.typed = true;
|
|
121
|
+
dataset.value = [];
|
|
122
|
+
for (let key = 0; key < input.length; key++) {
|
|
123
|
+
const value2 = input[key];
|
|
124
|
+
const itemDataset = this.item._run({ typed: false, value: value2 }, config2);
|
|
125
|
+
if (itemDataset.issues) {
|
|
126
|
+
const pathItem = {
|
|
127
|
+
type: "array",
|
|
128
|
+
origin: "value",
|
|
129
|
+
input,
|
|
130
|
+
key,
|
|
131
|
+
value: value2
|
|
132
|
+
};
|
|
133
|
+
for (const issue of itemDataset.issues) {
|
|
134
|
+
if (issue.path) {
|
|
135
|
+
issue.path.unshift(pathItem);
|
|
136
|
+
} else {
|
|
137
|
+
issue.path = [pathItem];
|
|
138
|
+
}
|
|
139
|
+
dataset.issues?.push(issue);
|
|
140
|
+
}
|
|
141
|
+
if (!dataset.issues) {
|
|
142
|
+
dataset.issues = itemDataset.issues;
|
|
143
|
+
}
|
|
144
|
+
if (config2.abortEarly) {
|
|
145
|
+
dataset.typed = false;
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (!itemDataset.typed) {
|
|
150
|
+
dataset.typed = false;
|
|
151
|
+
}
|
|
152
|
+
dataset.value.push(itemDataset.value);
|
|
153
|
+
}
|
|
154
|
+
} else {
|
|
155
|
+
_addIssue(this, "type", dataset, config2);
|
|
156
|
+
}
|
|
157
|
+
return dataset;
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
function boolean(message) {
|
|
162
|
+
return {
|
|
163
|
+
kind: "schema",
|
|
164
|
+
type: "boolean",
|
|
165
|
+
reference: boolean,
|
|
166
|
+
expects: "boolean",
|
|
167
|
+
async: false,
|
|
168
|
+
message,
|
|
169
|
+
_run(dataset, config2) {
|
|
170
|
+
if (typeof dataset.value === "boolean") {
|
|
171
|
+
dataset.typed = true;
|
|
172
|
+
} else {
|
|
173
|
+
_addIssue(this, "type", dataset, config2);
|
|
174
|
+
}
|
|
175
|
+
return dataset;
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
function object(entries, message) {
|
|
180
|
+
return {
|
|
181
|
+
kind: "schema",
|
|
182
|
+
type: "object",
|
|
183
|
+
reference: object,
|
|
184
|
+
expects: "Object",
|
|
185
|
+
async: false,
|
|
186
|
+
entries,
|
|
187
|
+
message,
|
|
188
|
+
_run(dataset, config2) {
|
|
189
|
+
const input = dataset.value;
|
|
190
|
+
if (input && typeof input === "object") {
|
|
191
|
+
dataset.typed = true;
|
|
192
|
+
dataset.value = {};
|
|
193
|
+
for (const key in this.entries) {
|
|
194
|
+
const value2 = input[key];
|
|
195
|
+
const valueDataset = this.entries[key]._run(
|
|
196
|
+
{ typed: false, value: value2 },
|
|
197
|
+
config2
|
|
198
|
+
);
|
|
199
|
+
if (valueDataset.issues) {
|
|
200
|
+
const pathItem = {
|
|
201
|
+
type: "object",
|
|
202
|
+
origin: "value",
|
|
203
|
+
input,
|
|
204
|
+
key,
|
|
205
|
+
value: value2
|
|
206
|
+
};
|
|
207
|
+
for (const issue of valueDataset.issues) {
|
|
208
|
+
if (issue.path) {
|
|
209
|
+
issue.path.unshift(pathItem);
|
|
210
|
+
} else {
|
|
211
|
+
issue.path = [pathItem];
|
|
212
|
+
}
|
|
213
|
+
dataset.issues?.push(issue);
|
|
214
|
+
}
|
|
215
|
+
if (!dataset.issues) {
|
|
216
|
+
dataset.issues = valueDataset.issues;
|
|
217
|
+
}
|
|
218
|
+
if (config2.abortEarly) {
|
|
219
|
+
dataset.typed = false;
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
if (!valueDataset.typed) {
|
|
224
|
+
dataset.typed = false;
|
|
225
|
+
}
|
|
226
|
+
if (valueDataset.value !== void 0 || key in input) {
|
|
227
|
+
dataset.value[key] = valueDataset.value;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
} else {
|
|
231
|
+
_addIssue(this, "type", dataset, config2);
|
|
232
|
+
}
|
|
233
|
+
return dataset;
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
function optional(wrapped, ...args) {
|
|
238
|
+
const schema = {
|
|
239
|
+
kind: "schema",
|
|
240
|
+
type: "optional",
|
|
241
|
+
reference: optional,
|
|
242
|
+
expects: `${wrapped.expects} | undefined`,
|
|
243
|
+
async: false,
|
|
244
|
+
wrapped,
|
|
245
|
+
_run(dataset, config2) {
|
|
246
|
+
if (dataset.value === void 0) {
|
|
247
|
+
if ("default" in this) {
|
|
248
|
+
dataset.value = getDefault(
|
|
249
|
+
this,
|
|
250
|
+
dataset,
|
|
251
|
+
config2
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
if (dataset.value === void 0) {
|
|
255
|
+
dataset.typed = true;
|
|
256
|
+
return dataset;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return this.wrapped._run(dataset, config2);
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
if (0 in args) {
|
|
263
|
+
schema.default = args[0];
|
|
264
|
+
}
|
|
265
|
+
return schema;
|
|
266
|
+
}
|
|
267
|
+
function picklist(options, message) {
|
|
268
|
+
return {
|
|
269
|
+
kind: "schema",
|
|
270
|
+
type: "picklist",
|
|
271
|
+
reference: picklist,
|
|
272
|
+
expects: options.map(_stringify).join(" | ") || "never",
|
|
273
|
+
async: false,
|
|
274
|
+
options,
|
|
275
|
+
message,
|
|
276
|
+
_run(dataset, config2) {
|
|
277
|
+
if (this.options.includes(dataset.value)) {
|
|
278
|
+
dataset.typed = true;
|
|
279
|
+
} else {
|
|
280
|
+
_addIssue(this, "type", dataset, config2);
|
|
281
|
+
}
|
|
282
|
+
return dataset;
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
function string(message) {
|
|
287
|
+
return {
|
|
288
|
+
kind: "schema",
|
|
289
|
+
type: "string",
|
|
290
|
+
reference: string,
|
|
291
|
+
expects: "string",
|
|
292
|
+
async: false,
|
|
293
|
+
message,
|
|
294
|
+
_run(dataset, config2) {
|
|
295
|
+
if (typeof dataset.value === "string") {
|
|
296
|
+
dataset.typed = true;
|
|
297
|
+
} else {
|
|
298
|
+
_addIssue(this, "type", dataset, config2);
|
|
299
|
+
}
|
|
300
|
+
return dataset;
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
function parse(schema, input, config2) {
|
|
305
|
+
const dataset = schema._run(
|
|
306
|
+
{ typed: false, value: input },
|
|
307
|
+
getGlobalConfig(config2)
|
|
308
|
+
);
|
|
309
|
+
if (dataset.issues) {
|
|
310
|
+
throw new ValiError(dataset.issues);
|
|
311
|
+
}
|
|
312
|
+
return dataset.value;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// src/utils/config.ts
|
|
316
|
+
import { existsSync, readFileSync } from "fs";
|
|
317
|
+
import path from "path";
|
|
318
|
+
import { loadConfig } from "tsconfig-paths";
|
|
319
|
+
|
|
320
|
+
// src/utils/resolve-import.ts
|
|
321
|
+
import { createMatchPath } from "tsconfig-paths";
|
|
322
|
+
async function resolveImport(importPath, config) {
|
|
323
|
+
return createMatchPath(config.absoluteBaseUrl, config.paths)(importPath, void 0, () => true, [
|
|
324
|
+
".ts",
|
|
325
|
+
".tsx"
|
|
326
|
+
]);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// src/utils/config.ts
|
|
330
|
+
var DEFAULT_COMPONENTS = "~/components/ui";
|
|
331
|
+
var DEFAULT_UTILS = "~/lib/utils";
|
|
332
|
+
var DEFAULT_CSS_FILE = "src/app.css";
|
|
333
|
+
var DEFAULT_TAILWIND_CONFIG = "tailwind.config.cjs";
|
|
334
|
+
var DEFAULT_TAILWIND_PREFIX = "";
|
|
335
|
+
var RawConfigSchema = object({
|
|
336
|
+
$schema: optional(string()),
|
|
337
|
+
tsx: boolean(),
|
|
338
|
+
tailwind: object({
|
|
339
|
+
css: string(),
|
|
340
|
+
config: string(),
|
|
341
|
+
prefix: optional(string(), "")
|
|
342
|
+
}),
|
|
343
|
+
aliases: object({
|
|
344
|
+
components: string(),
|
|
345
|
+
utils: string()
|
|
346
|
+
})
|
|
347
|
+
});
|
|
348
|
+
var ConfigSchema = object({
|
|
349
|
+
...RawConfigSchema.entries,
|
|
350
|
+
resolvedPaths: object({
|
|
351
|
+
tailwindConfig: string(),
|
|
352
|
+
tailwindCss: string(),
|
|
353
|
+
utils: string(),
|
|
354
|
+
components: string()
|
|
355
|
+
})
|
|
356
|
+
});
|
|
357
|
+
async function resolveConfigPaths(cwd, config) {
|
|
358
|
+
const tsConfig = await loadConfig(cwd);
|
|
359
|
+
if (tsConfig.resultType === "failed") {
|
|
360
|
+
throw new Error(
|
|
361
|
+
`Failed to load ${config.tsx ? "tsconfig" : "jsconfig"}.json. ${tsConfig.message ?? ""}`.trim()
|
|
362
|
+
);
|
|
363
|
+
}
|
|
364
|
+
return parse(ConfigSchema, {
|
|
365
|
+
...config,
|
|
366
|
+
resolvedPaths: {
|
|
367
|
+
tailwindConfig: path.resolve(cwd, config.tailwind.config),
|
|
368
|
+
tailwindCss: path.resolve(cwd, config.tailwind.css),
|
|
369
|
+
utils: await resolveImport(config.aliases.utils, tsConfig),
|
|
370
|
+
components: await resolveImport(config.aliases.components, tsConfig)
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
function getRawConfig(cwd) {
|
|
375
|
+
try {
|
|
376
|
+
const configPath = path.resolve(cwd, "ui.config.json");
|
|
377
|
+
if (!existsSync(configPath)) {
|
|
378
|
+
return null;
|
|
379
|
+
}
|
|
380
|
+
const config = JSON.parse(readFileSync(configPath).toString());
|
|
381
|
+
return parse(RawConfigSchema, config);
|
|
382
|
+
} catch (error) {
|
|
383
|
+
throw new Error(`Invalid configuration found in ${cwd}/ui.config.json.`);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
async function getConfig(cwd) {
|
|
387
|
+
const config = getRawConfig(cwd);
|
|
388
|
+
if (!config) {
|
|
389
|
+
return null;
|
|
390
|
+
}
|
|
391
|
+
return await resolveConfigPaths(cwd, config);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// src/utils/get-package-manager.ts
|
|
395
|
+
import { detect } from "@antfu/ni";
|
|
396
|
+
async function getPackageManager(targetDir) {
|
|
397
|
+
const packageManager = await detect({ programmatic: true, cwd: targetDir });
|
|
398
|
+
if (packageManager === "yarn@berry") return "yarn";
|
|
399
|
+
if (packageManager === "pnpm@6") return "pnpm";
|
|
400
|
+
if (packageManager === "bun") return "bun";
|
|
401
|
+
return packageManager ?? "npm";
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// src/utils/logger.ts
|
|
405
|
+
import * as p from "@clack/prompts";
|
|
406
|
+
import chalk from "chalk";
|
|
407
|
+
var headline = (text2) => chalk.bgGreen.bold.black(text2);
|
|
408
|
+
var highlight = (text2) => chalk.bold.green(text2);
|
|
409
|
+
var subtle = (text2) => chalk.grey(text2);
|
|
410
|
+
function handleError(error) {
|
|
411
|
+
p.log.message();
|
|
412
|
+
if (typeof error === "string") {
|
|
413
|
+
p.cancel(error);
|
|
414
|
+
process.exit(1);
|
|
415
|
+
}
|
|
416
|
+
if (error instanceof Error) {
|
|
417
|
+
p.cancel(error.stack);
|
|
418
|
+
process.exit(1);
|
|
419
|
+
}
|
|
420
|
+
p.cancel("Something went wrong. Please try again.");
|
|
421
|
+
process.exit(1);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// src/utils/registry.ts
|
|
425
|
+
var BASE_URL = "https://www.solid-ui.com";
|
|
426
|
+
var RegistryIndexSchema = array(
|
|
427
|
+
object({
|
|
428
|
+
name: string(),
|
|
429
|
+
dependencies: optional(array(string())),
|
|
430
|
+
registryDependencies: optional(array(string())),
|
|
431
|
+
files: array(string()),
|
|
432
|
+
type: picklist(["ui", "example"])
|
|
433
|
+
})
|
|
434
|
+
);
|
|
435
|
+
var RegistryItemSchema = object({
|
|
436
|
+
name: string(),
|
|
437
|
+
dependencies: optional(array(string())),
|
|
438
|
+
files: array(
|
|
439
|
+
object({
|
|
440
|
+
name: string(),
|
|
441
|
+
content: string()
|
|
442
|
+
})
|
|
443
|
+
),
|
|
444
|
+
type: picklist(["ui", "example"])
|
|
445
|
+
});
|
|
446
|
+
async function fetchRegistry(paths) {
|
|
447
|
+
try {
|
|
448
|
+
const results = await Promise.all(
|
|
449
|
+
paths.map(async (path5) => {
|
|
450
|
+
const response = await fetch(`${BASE_URL}/registry/${path5}`);
|
|
451
|
+
return await response.json();
|
|
452
|
+
})
|
|
453
|
+
);
|
|
454
|
+
return results;
|
|
455
|
+
} catch (e) {
|
|
456
|
+
console.log(e);
|
|
457
|
+
throw new Error(`Failed to fetch registry from ${BASE_URL}.`);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
async function getRegistryIndex() {
|
|
461
|
+
try {
|
|
462
|
+
const [result] = await fetchRegistry(["index.json"]);
|
|
463
|
+
return parse(RegistryIndexSchema, result).filter((item) => item.type === "ui");
|
|
464
|
+
} catch (e) {
|
|
465
|
+
throw new Error(`Failed to fetch components from registry.`);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
async function resolveTree(index, names) {
|
|
469
|
+
const tree = [];
|
|
470
|
+
for (const name of names) {
|
|
471
|
+
const entry = index.find((entry2) => entry2.name === name);
|
|
472
|
+
if (!entry) {
|
|
473
|
+
continue;
|
|
474
|
+
}
|
|
475
|
+
tree.push(entry);
|
|
476
|
+
if (entry.registryDependencies) {
|
|
477
|
+
const dependencies = await resolveTree(index, entry.registryDependencies);
|
|
478
|
+
tree.push(...dependencies);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
return tree.filter(
|
|
482
|
+
(component, idx, self) => self.findIndex((c) => c.name === component.name) === idx
|
|
483
|
+
);
|
|
484
|
+
}
|
|
485
|
+
async function fetchTree(tree) {
|
|
486
|
+
try {
|
|
487
|
+
const paths = tree.map((item) => `ui/${item.name}.json`);
|
|
488
|
+
const results = await fetchRegistry(paths);
|
|
489
|
+
return parse(array(RegistryItemSchema), results);
|
|
490
|
+
} catch (e) {
|
|
491
|
+
throw new Error(`Failed to fetch components from registry.`);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
// src/utils/transformers/index.ts
|
|
496
|
+
import { mkdtemp } from "fs/promises";
|
|
497
|
+
import { tmpdir } from "os";
|
|
498
|
+
import path2 from "path";
|
|
499
|
+
import { Project, ScriptKind } from "ts-morph";
|
|
500
|
+
|
|
501
|
+
// src/utils/transformers/transform-import.ts
|
|
502
|
+
var transformImport = async ({ sourceFile, config }) => {
|
|
503
|
+
const importDeclarations = sourceFile.getImportDeclarations();
|
|
504
|
+
for (const importDeclaration of importDeclarations) {
|
|
505
|
+
const moduleSpecifier = importDeclaration.getModuleSpecifierValue();
|
|
506
|
+
if (moduleSpecifier.startsWith("~/registry/")) {
|
|
507
|
+
importDeclaration.setModuleSpecifier(
|
|
508
|
+
moduleSpecifier.replace(/^~\/registry\/ui/, config.aliases.components)
|
|
509
|
+
);
|
|
510
|
+
} else if (moduleSpecifier === "~/lib/utils") {
|
|
511
|
+
importDeclaration.setModuleSpecifier(
|
|
512
|
+
moduleSpecifier.replace(/^~\/lib\/utils/, config.aliases.utils)
|
|
513
|
+
);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
return sourceFile;
|
|
517
|
+
};
|
|
518
|
+
|
|
519
|
+
// src/utils/transformers/transform-jsx.ts
|
|
520
|
+
import { transformFromAstSync } from "@babel/core";
|
|
521
|
+
import { parse as parse2 } from "@babel/parser";
|
|
522
|
+
import transformTypescript from "@babel/plugin-transform-typescript";
|
|
523
|
+
import * as recast from "recast";
|
|
524
|
+
var PARSE_OPTIONS = {
|
|
525
|
+
sourceType: "module",
|
|
526
|
+
allowImportExportEverywhere: true,
|
|
527
|
+
allowReturnOutsideFunction: true,
|
|
528
|
+
startLine: 1,
|
|
529
|
+
tokens: true,
|
|
530
|
+
plugins: [
|
|
531
|
+
"asyncGenerators",
|
|
532
|
+
"bigInt",
|
|
533
|
+
"classPrivateMethods",
|
|
534
|
+
"classPrivateProperties",
|
|
535
|
+
"classProperties",
|
|
536
|
+
"classStaticBlock",
|
|
537
|
+
"decimal",
|
|
538
|
+
"decorators-legacy",
|
|
539
|
+
"doExpressions",
|
|
540
|
+
"dynamicImport",
|
|
541
|
+
"exportDefaultFrom",
|
|
542
|
+
"exportNamespaceFrom",
|
|
543
|
+
"functionBind",
|
|
544
|
+
"functionSent",
|
|
545
|
+
"importAssertions",
|
|
546
|
+
"importMeta",
|
|
547
|
+
"nullishCoalescingOperator",
|
|
548
|
+
"numericSeparator",
|
|
549
|
+
"objectRestSpread",
|
|
550
|
+
"optionalCatchBinding",
|
|
551
|
+
"optionalChaining",
|
|
552
|
+
[
|
|
553
|
+
"pipelineOperator",
|
|
554
|
+
{
|
|
555
|
+
proposal: "minimal"
|
|
556
|
+
}
|
|
557
|
+
],
|
|
558
|
+
[
|
|
559
|
+
"recordAndTuple",
|
|
560
|
+
{
|
|
561
|
+
syntaxType: "hash"
|
|
562
|
+
}
|
|
563
|
+
],
|
|
564
|
+
"throwExpressions",
|
|
565
|
+
"topLevelAwait",
|
|
566
|
+
"v8intrinsic",
|
|
567
|
+
"typescript",
|
|
568
|
+
"jsx"
|
|
569
|
+
]
|
|
570
|
+
};
|
|
571
|
+
var transformJsx = async ({ sourceFile, config }) => {
|
|
572
|
+
const output = sourceFile.getFullText();
|
|
573
|
+
if (config.tsx) {
|
|
574
|
+
return output;
|
|
575
|
+
}
|
|
576
|
+
const ast = recast.parse(output, {
|
|
577
|
+
parser: {
|
|
578
|
+
parse: (code) => {
|
|
579
|
+
return parse2(code, PARSE_OPTIONS);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
});
|
|
583
|
+
const result = transformFromAstSync(ast, output, {
|
|
584
|
+
cloneInputAst: false,
|
|
585
|
+
code: false,
|
|
586
|
+
ast: true,
|
|
587
|
+
plugins: [transformTypescript],
|
|
588
|
+
configFile: false
|
|
589
|
+
});
|
|
590
|
+
if (!result || !result.ast) {
|
|
591
|
+
throw new Error("Failed to transform JSX");
|
|
592
|
+
}
|
|
593
|
+
return recast.print(result.ast).code;
|
|
594
|
+
};
|
|
595
|
+
|
|
596
|
+
// src/utils/transformers/transform-tw-prefix.ts
|
|
597
|
+
import { SyntaxKind } from "ts-morph";
|
|
598
|
+
var transformTwPrefix = async ({ sourceFile, config }) => {
|
|
599
|
+
if (!config.tailwind.prefix) {
|
|
600
|
+
return sourceFile;
|
|
601
|
+
}
|
|
602
|
+
sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression).filter((node) => node.getExpression().getText() === "cva").forEach((node) => {
|
|
603
|
+
if (node.getArguments()[0]?.isKind(SyntaxKind.StringLiteral)) {
|
|
604
|
+
const defaultClassNames = node.getArguments()[0];
|
|
605
|
+
if (defaultClassNames) {
|
|
606
|
+
defaultClassNames.replaceWithText(
|
|
607
|
+
`"${applyPrefix(defaultClassNames.getText()?.replace(/"/g, ""), config.tailwind.prefix)}"`
|
|
608
|
+
);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
if (node.getArguments()[1]?.isKind(SyntaxKind.ObjectLiteralExpression)) {
|
|
612
|
+
node.getArguments()[1]?.getDescendantsOfKind(SyntaxKind.PropertyAssignment).find((node2) => node2.getName() === "variants")?.getDescendantsOfKind(SyntaxKind.PropertyAssignment).forEach((node2) => {
|
|
613
|
+
node2.getDescendantsOfKind(SyntaxKind.PropertyAssignment).forEach((node3) => {
|
|
614
|
+
const classNames = node3.getInitializerIfKind(SyntaxKind.StringLiteral);
|
|
615
|
+
if (classNames) {
|
|
616
|
+
classNames?.replaceWithText(
|
|
617
|
+
`"${applyPrefix(classNames.getText()?.replace(/"/g, ""), config.tailwind.prefix)}"`
|
|
618
|
+
);
|
|
619
|
+
}
|
|
620
|
+
});
|
|
621
|
+
});
|
|
622
|
+
}
|
|
623
|
+
});
|
|
624
|
+
sourceFile.getDescendantsOfKind(SyntaxKind.JsxAttribute).forEach((node) => {
|
|
625
|
+
if (node.getName() === "class") {
|
|
626
|
+
if (node.getInitializer()?.isKind(SyntaxKind.StringLiteral)) {
|
|
627
|
+
const value = node.getInitializer();
|
|
628
|
+
if (value) {
|
|
629
|
+
value.replaceWithText(
|
|
630
|
+
`"${applyPrefix(value.getText()?.replace(/"/g, ""), config.tailwind.prefix)}"`
|
|
631
|
+
);
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
if (node.getInitializer()?.isKind(SyntaxKind.JsxExpression)) {
|
|
635
|
+
const callExpression = node.getInitializer()?.getDescendantsOfKind(SyntaxKind.CallExpression).find((node2) => node2.getExpression().getText() === "cn");
|
|
636
|
+
if (callExpression) {
|
|
637
|
+
callExpression.getArguments().forEach((node2) => {
|
|
638
|
+
if (node2.isKind(SyntaxKind.ConditionalExpression) || node2.isKind(SyntaxKind.BinaryExpression)) {
|
|
639
|
+
node2.getChildrenOfKind(SyntaxKind.StringLiteral).forEach((node3) => {
|
|
640
|
+
node3.replaceWithText(
|
|
641
|
+
`"${applyPrefix(node3.getText()?.replace(/"/g, ""), config.tailwind.prefix)}"`
|
|
642
|
+
);
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
if (node2.isKind(SyntaxKind.StringLiteral)) {
|
|
646
|
+
node2.replaceWithText(
|
|
647
|
+
`"${applyPrefix(node2.getText()?.replace(/"/g, ""), config.tailwind.prefix)}"`
|
|
648
|
+
);
|
|
649
|
+
}
|
|
650
|
+
});
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
});
|
|
655
|
+
return sourceFile;
|
|
656
|
+
};
|
|
657
|
+
function applyPrefix(input, prefix = "") {
|
|
658
|
+
const classNames = input.split(" ");
|
|
659
|
+
const prefixed = [];
|
|
660
|
+
for (const className of classNames) {
|
|
661
|
+
const [variant, value, modifier] = splitClassName(className);
|
|
662
|
+
if (variant) {
|
|
663
|
+
modifier ? prefixed.push(`${variant}:${prefix}${value}/${modifier}`) : prefixed.push(`${variant}:${prefix}${value}`);
|
|
664
|
+
} else {
|
|
665
|
+
modifier ? prefixed.push(`${prefix}${value}/${modifier}`) : prefixed.push(`${prefix}${value}`);
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
return prefixed.join(" ");
|
|
669
|
+
}
|
|
670
|
+
function splitClassName(className) {
|
|
671
|
+
if (!className.includes("/") && !className.includes(":")) {
|
|
672
|
+
return [null, className, null];
|
|
673
|
+
}
|
|
674
|
+
const parts = [];
|
|
675
|
+
const [rest, alpha] = className.split("/");
|
|
676
|
+
if (!rest?.includes(":")) {
|
|
677
|
+
return [null, rest, alpha];
|
|
678
|
+
}
|
|
679
|
+
const split = rest?.split(":");
|
|
680
|
+
const name = split.pop();
|
|
681
|
+
const variant = split.join(":");
|
|
682
|
+
parts.push(variant ?? null, name ?? null, alpha ?? null);
|
|
683
|
+
return parts;
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
// src/utils/transformers/index.ts
|
|
687
|
+
var project = new Project({
|
|
688
|
+
compilerOptions: {}
|
|
689
|
+
});
|
|
690
|
+
async function createTempSourceFile(filename) {
|
|
691
|
+
const dir = await mkdtemp(path2.join(tmpdir(), "solidui-"));
|
|
692
|
+
return path2.join(dir, filename);
|
|
693
|
+
}
|
|
694
|
+
async function transform(props) {
|
|
695
|
+
const tempFile = await createTempSourceFile(props.filename);
|
|
696
|
+
const sourceFile = project.createSourceFile(tempFile, props.raw, { scriptKind: ScriptKind.TSX });
|
|
697
|
+
transformImport({ sourceFile, ...props });
|
|
698
|
+
transformTwPrefix({ sourceFile, ...props });
|
|
699
|
+
return await transformJsx({ sourceFile, ...props });
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
// src/commands/add.ts
|
|
703
|
+
var addOptionsSchema = object({
|
|
704
|
+
components: optional(array(string()), []),
|
|
705
|
+
cwd: string(),
|
|
706
|
+
overwrite: boolean(),
|
|
707
|
+
all: boolean()
|
|
708
|
+
});
|
|
709
|
+
var add = new Command().name("add").description("add components to your project").argument("[components...]", "the components to add").option("-c, --cwd <cwd>", "the working directory", process.cwd()).option("-o --overwrite", "overwrite existing files", false).option("-a, --all", "add all available components", false).action(async (components, opts) => {
|
|
710
|
+
try {
|
|
711
|
+
const options = parse(addOptionsSchema, { components, ...opts });
|
|
712
|
+
const cwd = path3.resolve(options.cwd);
|
|
713
|
+
if (!existsSync2(cwd)) {
|
|
714
|
+
throw new Error(`The path ${cwd} does not exist. Please try again.`);
|
|
715
|
+
}
|
|
716
|
+
const config = await getConfig(cwd);
|
|
717
|
+
if (!config) {
|
|
718
|
+
p2.log.warning(
|
|
719
|
+
`Configuration is missing. Please run ${highlight(`init`)} to create a components.json file.`
|
|
720
|
+
);
|
|
721
|
+
process.exit(1);
|
|
722
|
+
}
|
|
723
|
+
const registryIndex = await getRegistryIndex();
|
|
724
|
+
let selectedComponents = options.all ? registryIndex.map((v) => v.name) : options.components;
|
|
725
|
+
if (!selectedComponents.length) {
|
|
726
|
+
const prompts = await p2.group(
|
|
727
|
+
{
|
|
728
|
+
components: () => p2.multiselect({
|
|
729
|
+
message: `Which ${highlight("components")} would you like to add?`,
|
|
730
|
+
options: registryIndex.map((v) => ({ label: v.name, value: v.name })),
|
|
731
|
+
maxItems: 10
|
|
732
|
+
})
|
|
733
|
+
},
|
|
734
|
+
{
|
|
735
|
+
onCancel: () => {
|
|
736
|
+
p2.cancel("Cancelled.");
|
|
737
|
+
process.exit(0);
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
);
|
|
741
|
+
selectedComponents = prompts.components;
|
|
742
|
+
}
|
|
743
|
+
if (!selectedComponents.length) {
|
|
744
|
+
p2.log.warn(`No components selected. Exiting.`);
|
|
745
|
+
process.exit(0);
|
|
746
|
+
}
|
|
747
|
+
const tree = await resolveTree(registryIndex, selectedComponents);
|
|
748
|
+
const payload = await fetchTree(tree);
|
|
749
|
+
if (!payload.length) {
|
|
750
|
+
p2.log.warn(`Selected components not found. Exiting.`);
|
|
751
|
+
process.exit(0);
|
|
752
|
+
}
|
|
753
|
+
const spinner3 = p2.spinner();
|
|
754
|
+
spinner3.start("Installing...");
|
|
755
|
+
const targetDir = config.resolvedPaths.components;
|
|
756
|
+
if (!existsSync2(targetDir)) {
|
|
757
|
+
await mkdir(targetDir, { recursive: true });
|
|
758
|
+
}
|
|
759
|
+
for (const item of payload) {
|
|
760
|
+
spinner3.message(`Installing ${highlight(item.name)}...`);
|
|
761
|
+
const existingComponent = item.files.filter(
|
|
762
|
+
(file) => existsSync2(path3.resolve(targetDir, file.name))
|
|
763
|
+
);
|
|
764
|
+
if (existingComponent.length && !options.overwrite) {
|
|
765
|
+
if (selectedComponents.includes(item.name)) {
|
|
766
|
+
spinner3.stop();
|
|
767
|
+
const prompts = await p2.group(
|
|
768
|
+
{
|
|
769
|
+
overwrite: () => p2.confirm({
|
|
770
|
+
message: `Component ${item.name} already exists. Would you like to overwrite?`,
|
|
771
|
+
initialValue: false
|
|
772
|
+
})
|
|
773
|
+
},
|
|
774
|
+
{
|
|
775
|
+
onCancel: () => {
|
|
776
|
+
p2.cancel("Cancelled.");
|
|
777
|
+
process.exit(0);
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
);
|
|
781
|
+
const overwrite = prompts.overwrite;
|
|
782
|
+
if (!overwrite) {
|
|
783
|
+
p2.log.info(
|
|
784
|
+
`Skipped ${item.name}. To overwrite, run with the ${highlight("--overwrite")} flag.`
|
|
785
|
+
);
|
|
786
|
+
continue;
|
|
787
|
+
}
|
|
788
|
+
spinner3.start(`Installing ${highlight(item.name)}...`);
|
|
789
|
+
} else {
|
|
790
|
+
continue;
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
for (const file of item.files) {
|
|
794
|
+
let filePath = path3.resolve(targetDir, file.name);
|
|
795
|
+
const content = await transform({
|
|
796
|
+
filename: file.name,
|
|
797
|
+
raw: file.content,
|
|
798
|
+
config
|
|
799
|
+
});
|
|
800
|
+
if (!config.tsx) {
|
|
801
|
+
filePath = filePath.replace(/\.tsx$/, ".jsx");
|
|
802
|
+
filePath = filePath.replace(/\.ts$/, ".js");
|
|
803
|
+
}
|
|
804
|
+
await writeFile(filePath, content, "utf-8");
|
|
805
|
+
}
|
|
806
|
+
if (item.dependencies?.length) {
|
|
807
|
+
const packageManager = await getPackageManager(cwd);
|
|
808
|
+
await execa(packageManager, [
|
|
809
|
+
"add",
|
|
810
|
+
...packageManager === "deno" ? ["--npm"] : [],
|
|
811
|
+
...item.dependencies
|
|
812
|
+
], { cwd });
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
spinner3.stop("Done.");
|
|
816
|
+
} catch (e) {
|
|
817
|
+
handleError(e);
|
|
818
|
+
}
|
|
819
|
+
});
|
|
820
|
+
|
|
821
|
+
// src/commands/init.ts
|
|
822
|
+
import { existsSync as existsSync3 } from "fs";
|
|
823
|
+
import { mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
|
|
824
|
+
import path4 from "path";
|
|
825
|
+
import * as p3 from "@clack/prompts";
|
|
826
|
+
import { Command as Command2 } from "commander";
|
|
827
|
+
import { execa as execa2 } from "execa";
|
|
828
|
+
|
|
829
|
+
// src/utils/get-package-info.ts
|
|
830
|
+
import fs from "fs";
|
|
831
|
+
import { dirname, resolve } from "path";
|
|
832
|
+
import { fileURLToPath } from "url";
|
|
833
|
+
var __filename = fileURLToPath(import.meta.url);
|
|
834
|
+
var __dirname = dirname(__filename);
|
|
835
|
+
function getPackageInfo() {
|
|
836
|
+
const location = resolve(__dirname, "..", "package.json");
|
|
837
|
+
return readJSONSync(location);
|
|
838
|
+
}
|
|
839
|
+
function readJSONSync(path5) {
|
|
840
|
+
const content = fs.readFileSync(path5, { encoding: "utf-8" });
|
|
841
|
+
return JSON.parse(content);
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
// src/utils/templates.ts
|
|
845
|
+
var UTILS = `import { type ClassValue, clsx } from "clsx"
|
|
846
|
+
import { twMerge } from "tailwind-merge"
|
|
847
|
+
|
|
848
|
+
export function cn(...inputs: ClassValue[]) {
|
|
849
|
+
return twMerge(clsx(inputs))
|
|
850
|
+
}
|
|
851
|
+
`;
|
|
852
|
+
var UTILS_JS = `import { clsx } from "clsx"
|
|
853
|
+
import { twMerge } from "tailwind-merge"
|
|
854
|
+
|
|
855
|
+
export function cn(...inputs) {
|
|
856
|
+
return twMerge(clsx(inputs))
|
|
857
|
+
}
|
|
858
|
+
`;
|
|
859
|
+
var TAILWIND_CONFIG = `/** @type {import('tailwindcss').Config} */
|
|
860
|
+
export default {
|
|
861
|
+
darkMode: ["variant", [".dark &", '[data-kb-theme="dark"] &']],
|
|
862
|
+
content: ["./src/**/*.{ts,tsx}"],
|
|
863
|
+
prefix: "<%- prefix %>",
|
|
864
|
+
theme: {
|
|
865
|
+
container: {
|
|
866
|
+
center: true,
|
|
867
|
+
padding: "2rem",
|
|
868
|
+
screens: {
|
|
869
|
+
"2xl": "1400px"
|
|
870
|
+
}
|
|
871
|
+
},
|
|
872
|
+
extend: {
|
|
873
|
+
colors: {
|
|
874
|
+
border: "hsl(var(--border))",
|
|
875
|
+
input: "hsl(var(--input))",
|
|
876
|
+
ring: "hsl(var(--ring))",
|
|
877
|
+
background: "hsl(var(--background))",
|
|
878
|
+
foreground: "hsl(var(--foreground))",
|
|
879
|
+
primary: {
|
|
880
|
+
DEFAULT: "hsl(var(--primary))",
|
|
881
|
+
foreground: "hsl(var(--primary-foreground))"
|
|
882
|
+
},
|
|
883
|
+
secondary: {
|
|
884
|
+
DEFAULT: "hsl(var(--secondary))",
|
|
885
|
+
foreground: "hsl(var(--secondary-foreground))"
|
|
886
|
+
},
|
|
887
|
+
destructive: {
|
|
888
|
+
DEFAULT: "hsl(var(--destructive))",
|
|
889
|
+
foreground: "hsl(var(--destructive-foreground))"
|
|
890
|
+
},
|
|
891
|
+
info: {
|
|
892
|
+
DEFAULT: "hsl(var(--info))",
|
|
893
|
+
foreground: "hsl(var(--info-foreground))"
|
|
894
|
+
},
|
|
895
|
+
success: {
|
|
896
|
+
DEFAULT: "hsl(var(--success))",
|
|
897
|
+
foreground: "hsl(var(--success-foreground))"
|
|
898
|
+
},
|
|
899
|
+
warning: {
|
|
900
|
+
DEFAULT: "hsl(var(--warning))",
|
|
901
|
+
foreground: "hsl(var(--warning-foreground))"
|
|
902
|
+
},
|
|
903
|
+
error: {
|
|
904
|
+
DEFAULT: "hsl(var(--error))",
|
|
905
|
+
foreground: "hsl(var(--error-foreground))"
|
|
906
|
+
},
|
|
907
|
+
muted: {
|
|
908
|
+
DEFAULT: "hsl(var(--muted))",
|
|
909
|
+
foreground: "hsl(var(--muted-foreground))"
|
|
910
|
+
},
|
|
911
|
+
accent: {
|
|
912
|
+
DEFAULT: "hsl(var(--accent))",
|
|
913
|
+
foreground: "hsl(var(--accent-foreground))"
|
|
914
|
+
},
|
|
915
|
+
popover: {
|
|
916
|
+
DEFAULT: "hsl(var(--popover))",
|
|
917
|
+
foreground: "hsl(var(--popover-foreground))"
|
|
918
|
+
},
|
|
919
|
+
card: {
|
|
920
|
+
DEFAULT: "hsl(var(--card))",
|
|
921
|
+
foreground: "hsl(var(--card-foreground))"
|
|
922
|
+
}
|
|
923
|
+
},
|
|
924
|
+
borderRadius: {
|
|
925
|
+
xl: "calc(var(--radius) + 4px)",
|
|
926
|
+
lg: "var(--radius)",
|
|
927
|
+
md: "calc(var(--radius) - 2px)",
|
|
928
|
+
sm: "calc(var(--radius) - 4px)"
|
|
929
|
+
},
|
|
930
|
+
keyframes: {
|
|
931
|
+
"accordion-down": {
|
|
932
|
+
from: { height: 0 },
|
|
933
|
+
to: { height: "var(--kb-accordion-content-height)" }
|
|
934
|
+
},
|
|
935
|
+
"accordion-up": {
|
|
936
|
+
from: { height: "var(--kb-accordion-content-height)" },
|
|
937
|
+
to: { height: 0 }
|
|
938
|
+
},
|
|
939
|
+
"content-show": {
|
|
940
|
+
from: { opacity: 0, transform: "scale(0.96)" },
|
|
941
|
+
to: { opacity: 1, transform: "scale(1)" }
|
|
942
|
+
},
|
|
943
|
+
"content-hide": {
|
|
944
|
+
from: { opacity: 1, transform: "scale(1)" },
|
|
945
|
+
to: { opacity: 0, transform: "scale(0.96)" }
|
|
946
|
+
},
|
|
947
|
+
"caret-blink": {
|
|
948
|
+
"0%,70%,100%": { opacity: "1" },
|
|
949
|
+
"20%,50%": { opacity: "0" }
|
|
950
|
+
}
|
|
951
|
+
},
|
|
952
|
+
animation: {
|
|
953
|
+
"accordion-down": "accordion-down 0.2s ease-out",
|
|
954
|
+
"accordion-up": "accordion-up 0.2s ease-out",
|
|
955
|
+
"content-show": "content-show 0.2s ease-out",
|
|
956
|
+
"content-hide": "content-hide 0.2s ease-out",
|
|
957
|
+
"caret-blink": "caret-blink 1.25s ease-out infinite"
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
},
|
|
961
|
+
plugins: [require("tailwindcss-animate")]
|
|
962
|
+
}
|
|
963
|
+
`;
|
|
964
|
+
var TAILWIND_CSS = `@tailwind base;
|
|
965
|
+
@tailwind components;
|
|
966
|
+
@tailwind utilities;
|
|
967
|
+
|
|
968
|
+
@layer base {
|
|
969
|
+
:root {
|
|
970
|
+
--background: 0 0% 100%;
|
|
971
|
+
--foreground: 240 10% 3.9%;
|
|
972
|
+
|
|
973
|
+
--muted: 240 4.8% 95.9%;
|
|
974
|
+
--muted-foreground: 240 3.8% 46.1%;
|
|
975
|
+
|
|
976
|
+
--popover: 0 0% 100%;
|
|
977
|
+
--popover-foreground: 240 10% 3.9%;
|
|
978
|
+
|
|
979
|
+
--border: 240 5.9% 90%;
|
|
980
|
+
--input: 240 5.9% 90%;
|
|
981
|
+
|
|
982
|
+
--card: 0 0% 100%;
|
|
983
|
+
--card-foreground: 240 10% 3.9%;
|
|
984
|
+
|
|
985
|
+
--primary: 240 5.9% 10%;
|
|
986
|
+
--primary-foreground: 0 0% 98%;
|
|
987
|
+
|
|
988
|
+
--secondary: 240 4.8% 95.9%;
|
|
989
|
+
--secondary-foreground: 240 5.9% 10%;
|
|
990
|
+
|
|
991
|
+
--accent: 240 4.8% 95.9%;
|
|
992
|
+
--accent-foreground: 240 5.9% 10%;
|
|
993
|
+
|
|
994
|
+
--destructive: 0 84.2% 60.2%;
|
|
995
|
+
--destructive-foreground: 0 0% 98%;
|
|
996
|
+
|
|
997
|
+
--info: 204 94% 94%;
|
|
998
|
+
--info-foreground: 199 89% 48%;
|
|
999
|
+
|
|
1000
|
+
--success: 149 80% 90%;
|
|
1001
|
+
--success-foreground: 160 84% 39%;
|
|
1002
|
+
|
|
1003
|
+
--warning: 48 96% 89%;
|
|
1004
|
+
--warning-foreground: 25 95% 53%;
|
|
1005
|
+
|
|
1006
|
+
--error: 0 93% 94%;
|
|
1007
|
+
--error-foreground: 0 84% 60%;
|
|
1008
|
+
|
|
1009
|
+
--ring: 240 5.9% 10%;
|
|
1010
|
+
|
|
1011
|
+
--radius: 0.5rem;
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
.dark,
|
|
1015
|
+
[data-kb-theme="dark"] {
|
|
1016
|
+
--background: 240 10% 3.9%;
|
|
1017
|
+
--foreground: 0 0% 98%;
|
|
1018
|
+
|
|
1019
|
+
--muted: 240 3.7% 15.9%;
|
|
1020
|
+
--muted-foreground: 240 5% 64.9%;
|
|
1021
|
+
|
|
1022
|
+
--accent: 240 3.7% 15.9%;
|
|
1023
|
+
--accent-foreground: 0 0% 98%;
|
|
1024
|
+
|
|
1025
|
+
--popover: 240 10% 3.9%;
|
|
1026
|
+
--popover-foreground: 0 0% 98%;
|
|
1027
|
+
|
|
1028
|
+
--border: 240 3.7% 15.9%;
|
|
1029
|
+
--input: 240 3.7% 15.9%;
|
|
1030
|
+
|
|
1031
|
+
--card: 240 10% 3.9%;
|
|
1032
|
+
--card-foreground: 0 0% 98%;
|
|
1033
|
+
|
|
1034
|
+
--primary: 0 0% 98%;
|
|
1035
|
+
--primary-foreground: 240 5.9% 10%;
|
|
1036
|
+
|
|
1037
|
+
--secondary: 240 3.7% 15.9%;
|
|
1038
|
+
--secondary-foreground: 0 0% 98%;
|
|
1039
|
+
|
|
1040
|
+
--destructive: 0 62.8% 30.6%;
|
|
1041
|
+
--destructive-foreground: 0 0% 98%;
|
|
1042
|
+
|
|
1043
|
+
--info: 204 94% 94%;
|
|
1044
|
+
--info-foreground: 199 89% 48%;
|
|
1045
|
+
|
|
1046
|
+
--success: 149 80% 90%;
|
|
1047
|
+
--success-foreground: 160 84% 39%;
|
|
1048
|
+
|
|
1049
|
+
--warning: 48 96% 89%;
|
|
1050
|
+
--warning-foreground: 25 95% 53%;
|
|
1051
|
+
|
|
1052
|
+
--error: 0 93% 94%;
|
|
1053
|
+
--error-foreground: 0 84% 60%;
|
|
1054
|
+
|
|
1055
|
+
--ring: 240 4.9% 83.9%;
|
|
1056
|
+
|
|
1057
|
+
--radius: 0.5rem;
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
@layer base {
|
|
1062
|
+
* {
|
|
1063
|
+
@apply border-border;
|
|
1064
|
+
}
|
|
1065
|
+
body {
|
|
1066
|
+
@apply bg-background text-foreground;
|
|
1067
|
+
font-feature-settings:
|
|
1068
|
+
"rlig" 1,
|
|
1069
|
+
"calt" 1;
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
@layer utilities {
|
|
1074
|
+
.step {
|
|
1075
|
+
counter-increment: step;
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
.step:before {
|
|
1079
|
+
@apply absolute w-9 h-9 bg-muted rounded-full font-mono font-medium text-center text-base inline-flex items-center justify-center -indent-px border-4 border-background;
|
|
1080
|
+
@apply ml-[-50px] mt-[-4px];
|
|
1081
|
+
content: counter(step);
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
@media (max-width: 640px) {
|
|
1086
|
+
.container {
|
|
1087
|
+
@apply px-4;
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
::-webkit-scrollbar {
|
|
1092
|
+
width: 16px;
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
::-webkit-scrollbar-thumb {
|
|
1096
|
+
border-radius: 9999px;
|
|
1097
|
+
border: 4px solid transparent;
|
|
1098
|
+
background-clip: content-box;
|
|
1099
|
+
@apply bg-accent;
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
::-webkit-scrollbar-corner {
|
|
1103
|
+
display: none;
|
|
1104
|
+
}
|
|
1105
|
+
`;
|
|
1106
|
+
|
|
1107
|
+
// src/commands/init.ts
|
|
1108
|
+
var PROJECT_DEPENDENCIES = [
|
|
1109
|
+
"tailwindcss-animate",
|
|
1110
|
+
"class-variance-authority",
|
|
1111
|
+
"clsx",
|
|
1112
|
+
"tailwind-merge"
|
|
1113
|
+
];
|
|
1114
|
+
var initOptionsSchema = object({
|
|
1115
|
+
cwd: string()
|
|
1116
|
+
});
|
|
1117
|
+
var init = new Command2().name("init").description("initialize your project and install dependencies").option("-c, --cwd <cwd>", "the working directory", process.cwd()).action(async (opts) => {
|
|
1118
|
+
try {
|
|
1119
|
+
const options = parse(initOptionsSchema, opts);
|
|
1120
|
+
const cwd = path4.resolve(options.cwd);
|
|
1121
|
+
if (!existsSync3(cwd)) {
|
|
1122
|
+
throw new Error(`The path ${cwd} does not exist. Please try again.`);
|
|
1123
|
+
}
|
|
1124
|
+
const info = getPackageInfo();
|
|
1125
|
+
p3.intro(headline(` ${info.name} - ${info.version} `));
|
|
1126
|
+
const rawConfig = await promptForConfig();
|
|
1127
|
+
const spinner3 = p3.spinner();
|
|
1128
|
+
spinner3.start(`Creating ui.config.json...`);
|
|
1129
|
+
const targetPath = path4.resolve(cwd, "ui.config.json");
|
|
1130
|
+
await writeFile2(targetPath, JSON.stringify(rawConfig, null, 2), "utf-8");
|
|
1131
|
+
spinner3.stop(`ui.config.json created.`);
|
|
1132
|
+
const config = await resolveConfigPaths(cwd, rawConfig);
|
|
1133
|
+
spinner3.start(`Initializing project...`);
|
|
1134
|
+
for (const [key, resolvedPath] of Object.entries(config.resolvedPaths)) {
|
|
1135
|
+
let dirname2 = path4.extname(resolvedPath) ? path4.dirname(resolvedPath) : resolvedPath;
|
|
1136
|
+
if (key === "utils" && resolvedPath.endsWith("/utils")) {
|
|
1137
|
+
dirname2 = dirname2.replace(/\/utils$/, "");
|
|
1138
|
+
}
|
|
1139
|
+
if (!existsSync3(dirname2)) {
|
|
1140
|
+
await mkdir2(dirname2, { recursive: true });
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
const extension = config.tsx ? "ts" : "js";
|
|
1144
|
+
await writeFile2(
|
|
1145
|
+
config.resolvedPaths.tailwindConfig,
|
|
1146
|
+
TAILWIND_CONFIG.replace("<%- prefix %>", config.tailwind.prefix),
|
|
1147
|
+
"utf-8"
|
|
1148
|
+
);
|
|
1149
|
+
await writeFile2(config.resolvedPaths.tailwindCss, TAILWIND_CSS, "utf-8");
|
|
1150
|
+
await writeFile2(
|
|
1151
|
+
`${config.resolvedPaths.utils}.${extension}`,
|
|
1152
|
+
extension === "ts" ? UTILS : UTILS_JS,
|
|
1153
|
+
"utf-8"
|
|
1154
|
+
);
|
|
1155
|
+
spinner3.stop(`Project initialized.`);
|
|
1156
|
+
spinner3.start(`Installing dependencies...`);
|
|
1157
|
+
const packageManager = await getPackageManager(cwd);
|
|
1158
|
+
await execa2(packageManager, [
|
|
1159
|
+
"add",
|
|
1160
|
+
packageManager === "deno" ? "--npm" : "",
|
|
1161
|
+
...PROJECT_DEPENDENCIES
|
|
1162
|
+
], { cwd });
|
|
1163
|
+
spinner3.stop(`Dependencies installed.`);
|
|
1164
|
+
p3.outro(
|
|
1165
|
+
`${highlight("Success!")} Project initialization completed. You may now add components.`
|
|
1166
|
+
);
|
|
1167
|
+
} catch (e) {
|
|
1168
|
+
handleError(e);
|
|
1169
|
+
}
|
|
1170
|
+
});
|
|
1171
|
+
async function promptForConfig() {
|
|
1172
|
+
const options = await p3.group(
|
|
1173
|
+
{
|
|
1174
|
+
typescript: () => p3.confirm({
|
|
1175
|
+
message: `Would you like to use ${highlight("Typescript")} (recommended)?`,
|
|
1176
|
+
initialValue: true
|
|
1177
|
+
}),
|
|
1178
|
+
cssFile: () => p3.text({
|
|
1179
|
+
message: `Where is your ${highlight("global CSS")} file? ${subtle("(this file will be overwritten)")}`,
|
|
1180
|
+
initialValue: DEFAULT_CSS_FILE
|
|
1181
|
+
}),
|
|
1182
|
+
tailwindConfig: () => p3.text({
|
|
1183
|
+
message: `Where is your ${highlight("Tailwind config")} located? ${subtle("(this file will be overwritten)")}`,
|
|
1184
|
+
initialValue: DEFAULT_TAILWIND_CONFIG
|
|
1185
|
+
}),
|
|
1186
|
+
tailwindPrefix: () => p3.text({
|
|
1187
|
+
message: `Are you using a custom ${highlight("tailwind prefix eg. tw-")}? (Leave blank if not)`,
|
|
1188
|
+
initialValue: DEFAULT_TAILWIND_PREFIX
|
|
1189
|
+
}),
|
|
1190
|
+
components: () => p3.text({
|
|
1191
|
+
message: `Configure the import alias for ${highlight("components")}:`,
|
|
1192
|
+
initialValue: DEFAULT_COMPONENTS
|
|
1193
|
+
}),
|
|
1194
|
+
utils: () => p3.text({
|
|
1195
|
+
message: `Configure the import alias for ${highlight("utils")}:`,
|
|
1196
|
+
initialValue: DEFAULT_UTILS
|
|
1197
|
+
})
|
|
1198
|
+
},
|
|
1199
|
+
{
|
|
1200
|
+
onCancel: () => {
|
|
1201
|
+
p3.cancel("Cancelled.");
|
|
1202
|
+
process.exit(0);
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
);
|
|
1206
|
+
return parse(RawConfigSchema, {
|
|
1207
|
+
$schema: "https://solid-ui.com/schema.json",
|
|
1208
|
+
tsx: options.typescript,
|
|
1209
|
+
tailwind: {
|
|
1210
|
+
css: options.cssFile,
|
|
1211
|
+
config: options.tailwindConfig,
|
|
1212
|
+
prefix: options.tailwindPrefix
|
|
1213
|
+
},
|
|
1214
|
+
aliases: {
|
|
1215
|
+
components: options.components,
|
|
1216
|
+
utils: options.utils
|
|
1217
|
+
}
|
|
1218
|
+
});
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
// src/index.ts
|
|
1222
|
+
process.on("SIGINT", () => process.exit(0));
|
|
1223
|
+
process.on("SIGTERM", () => process.exit(0));
|
|
1224
|
+
async function main() {
|
|
1225
|
+
console.clear();
|
|
1226
|
+
const packageInfo = getPackageInfo();
|
|
1227
|
+
new Command3().name("solidui-cli").description("add SolidUI components to your project").version(packageInfo.version || "0.0.0", "-v, --version", "display the version number").addCommand(init).addCommand(add).parse();
|
|
1228
|
+
}
|
|
1229
|
+
main();
|