stera-ui 0.2.0 → 0.3.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/chunk-26HP67ZM.js +695 -0
- package/dist/{chunk-AXIACJ2C.js → chunk-3KADOWKC.js} +26 -4
- package/dist/cli.js +378 -281
- package/dist/index.d.ts +2 -2
- package/dist/index.js +8 -2
- package/dist/schema/index.d.ts +291 -31
- package/dist/schema/index.js +3 -1
- package/dist/utils/index.d.ts +28 -2
- package/dist/utils/index.js +5 -1
- package/package.json +2 -1
- package/dist/chunk-MFUZBXO6.js +0 -375
package/dist/chunk-MFUZBXO6.js
DELETED
|
@@ -1,375 +0,0 @@
|
|
|
1
|
-
// src/utils/transform.ts
|
|
2
|
-
function applyTransforms(content, ctx, transforms) {
|
|
3
|
-
return transforms.reduce((acc, fn) => fn(acc, ctx), content);
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
// src/utils/transform-imports.ts
|
|
7
|
-
var DEFAULT_ALIASES = {
|
|
8
|
-
utils: "@/lib/utils",
|
|
9
|
-
ui: "@/components/ui",
|
|
10
|
-
components: "@/components",
|
|
11
|
-
lib: "@/lib",
|
|
12
|
-
hooks: "@/hooks"
|
|
13
|
-
};
|
|
14
|
-
var transformImports = (content, ctx) => {
|
|
15
|
-
if (!ctx.filename.endsWith(".ts") && !ctx.filename.endsWith(".tsx")) {
|
|
16
|
-
return content;
|
|
17
|
-
}
|
|
18
|
-
const { aliases } = ctx.config;
|
|
19
|
-
const rules = [];
|
|
20
|
-
if (aliases.utils !== DEFAULT_ALIASES.utils) {
|
|
21
|
-
rules.push({ type: "exact", from: DEFAULT_ALIASES.utils, to: aliases.utils });
|
|
22
|
-
}
|
|
23
|
-
if (aliases.ui !== DEFAULT_ALIASES.ui) {
|
|
24
|
-
rules.push({ type: "prefix", from: DEFAULT_ALIASES.ui, to: aliases.ui });
|
|
25
|
-
}
|
|
26
|
-
if (aliases.components !== DEFAULT_ALIASES.components) {
|
|
27
|
-
rules.push({ type: "prefix", from: DEFAULT_ALIASES.components, to: aliases.components });
|
|
28
|
-
}
|
|
29
|
-
if (aliases.lib !== DEFAULT_ALIASES.lib) {
|
|
30
|
-
rules.push({ type: "prefix", from: DEFAULT_ALIASES.lib, to: aliases.lib });
|
|
31
|
-
}
|
|
32
|
-
if (aliases.hooks !== DEFAULT_ALIASES.hooks) {
|
|
33
|
-
rules.push({ type: "prefix", from: DEFAULT_ALIASES.hooks, to: aliases.hooks });
|
|
34
|
-
}
|
|
35
|
-
if (rules.length === 0) {
|
|
36
|
-
return content;
|
|
37
|
-
}
|
|
38
|
-
return content.replace(
|
|
39
|
-
/from\s+(["'])([^"']+)\1/g,
|
|
40
|
-
(match, quote, importPath) => {
|
|
41
|
-
for (const rule of rules) {
|
|
42
|
-
if (rule.type === "exact" && importPath === rule.from) {
|
|
43
|
-
return `from ${quote}${rule.to}${quote}`;
|
|
44
|
-
}
|
|
45
|
-
if (rule.type === "prefix" && importPath.startsWith(rule.from + "/")) {
|
|
46
|
-
const rest = importPath.slice(rule.from.length);
|
|
47
|
-
return `from ${quote}${rule.to}${rest}${quote}`;
|
|
48
|
-
}
|
|
49
|
-
if (rule.type === "prefix" && importPath === rule.from) {
|
|
50
|
-
return `from ${quote}${rule.to}${quote}`;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
return match;
|
|
54
|
-
}
|
|
55
|
-
);
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
// src/utils/resolve-paths.ts
|
|
59
|
-
import path from "path";
|
|
60
|
-
import { loadConfig, createMatchPath } from "tsconfig-paths";
|
|
61
|
-
var TYPE_TO_ALIAS = {
|
|
62
|
-
"registry:ui": "ui",
|
|
63
|
-
"registry:lib": "lib",
|
|
64
|
-
"registry:hook": "hooks",
|
|
65
|
-
"registry:component": "components"
|
|
66
|
-
};
|
|
67
|
-
function resolveAlias(alias, projectRoot) {
|
|
68
|
-
const tsConfig = loadConfig(projectRoot);
|
|
69
|
-
if (tsConfig.resultType === "success") {
|
|
70
|
-
const match = createMatchPath(tsConfig.absoluteBaseUrl, tsConfig.paths);
|
|
71
|
-
const resolved = match(alias, void 0, () => true, [".ts", ".tsx"]);
|
|
72
|
-
if (resolved) {
|
|
73
|
-
return path.relative(projectRoot, resolved);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
return alias.replace(/^@\//, "");
|
|
77
|
-
}
|
|
78
|
-
function resolveOutputPath(config, projectRoot, file) {
|
|
79
|
-
const alias = TYPE_TO_ALIAS[file.type];
|
|
80
|
-
if (alias) {
|
|
81
|
-
const dir = resolveAlias(config.aliases[alias], projectRoot);
|
|
82
|
-
const filename = path.basename(file.path);
|
|
83
|
-
return path.join(projectRoot, dir, filename);
|
|
84
|
-
}
|
|
85
|
-
if (file.type === "registry:style") {
|
|
86
|
-
const cssDir = path.dirname(config.css);
|
|
87
|
-
const filename = path.basename(file.path);
|
|
88
|
-
return path.join(projectRoot, cssDir, filename);
|
|
89
|
-
}
|
|
90
|
-
return path.join(projectRoot, file.path);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// src/utils/resolve-config.ts
|
|
94
|
-
import fs from "fs";
|
|
95
|
-
import path2 from "path";
|
|
96
|
-
var CONFIG_FILE = "components.json";
|
|
97
|
-
function migrateConfig(raw) {
|
|
98
|
-
if (!("version" in raw) && "tailwind" in raw) {
|
|
99
|
-
const legacy = raw;
|
|
100
|
-
return {
|
|
101
|
-
version: 1,
|
|
102
|
-
css: legacy.tailwind.css || "src/styles/globals.css",
|
|
103
|
-
aliases: legacy.aliases
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
return raw;
|
|
107
|
-
}
|
|
108
|
-
function findConfigPath(cwd) {
|
|
109
|
-
let dir = path2.resolve(cwd);
|
|
110
|
-
while (true) {
|
|
111
|
-
const configPath = path2.join(dir, CONFIG_FILE);
|
|
112
|
-
if (fs.existsSync(configPath)) return configPath;
|
|
113
|
-
const parent = path2.dirname(dir);
|
|
114
|
-
if (parent === dir) return null;
|
|
115
|
-
dir = parent;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
function loadConfig2(cwd) {
|
|
119
|
-
const configPath = findConfigPath(cwd);
|
|
120
|
-
if (!configPath) return null;
|
|
121
|
-
try {
|
|
122
|
-
const raw = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
123
|
-
return migrateConfig(raw);
|
|
124
|
-
} catch {
|
|
125
|
-
return null;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// src/utils/detect-project.ts
|
|
130
|
-
import fs2 from "fs";
|
|
131
|
-
import path3 from "path";
|
|
132
|
-
function hasFile(cwd, filenames) {
|
|
133
|
-
return filenames.some((f) => fs2.existsSync(path3.join(cwd, f)));
|
|
134
|
-
}
|
|
135
|
-
function findTailwindCssFile(cwd) {
|
|
136
|
-
const candidates = [
|
|
137
|
-
"src/app/globals.css",
|
|
138
|
-
"src/styles/globals.css",
|
|
139
|
-
"src/index.css",
|
|
140
|
-
"app/globals.css",
|
|
141
|
-
"styles/globals.css",
|
|
142
|
-
"index.css"
|
|
143
|
-
];
|
|
144
|
-
for (const candidate of candidates) {
|
|
145
|
-
const fullPath = path3.join(cwd, candidate);
|
|
146
|
-
if (!fs2.existsSync(fullPath)) continue;
|
|
147
|
-
const content = fs2.readFileSync(fullPath, "utf-8");
|
|
148
|
-
if (content.includes('@import "tailwindcss"') || content.includes("@import 'tailwindcss'") || content.includes("@tailwind base")) {
|
|
149
|
-
return candidate;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
return null;
|
|
153
|
-
}
|
|
154
|
-
function detectProject(cwd) {
|
|
155
|
-
const hasSrc = fs2.existsSync(path3.join(cwd, "src"));
|
|
156
|
-
let framework = "other";
|
|
157
|
-
if (hasFile(cwd, ["next.config.ts", "next.config.js", "next.config.mjs"])) {
|
|
158
|
-
framework = "next";
|
|
159
|
-
} else if (hasFile(cwd, ["vite.config.ts", "vite.config.js", "vite.config.mjs"])) {
|
|
160
|
-
framework = "vite";
|
|
161
|
-
}
|
|
162
|
-
let rsc = false;
|
|
163
|
-
if (framework === "next") {
|
|
164
|
-
const appDir = hasSrc ? "src/app" : "app";
|
|
165
|
-
rsc = fs2.existsSync(path3.join(cwd, appDir));
|
|
166
|
-
}
|
|
167
|
-
const existingCssFile = findTailwindCssFile(cwd);
|
|
168
|
-
let layoutFile = null;
|
|
169
|
-
if (framework === "next") {
|
|
170
|
-
const appDir = hasSrc ? "src/app" : "app";
|
|
171
|
-
for (const ext of ["tsx", "jsx", "ts", "js"]) {
|
|
172
|
-
const candidate = `${appDir}/layout.${ext}`;
|
|
173
|
-
if (fs2.existsSync(path3.join(cwd, candidate))) {
|
|
174
|
-
layoutFile = candidate;
|
|
175
|
-
break;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
} else if (framework === "vite") {
|
|
179
|
-
if (fs2.existsSync(path3.join(cwd, "index.html"))) {
|
|
180
|
-
layoutFile = "index.html";
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
return { hasSrc, framework, rsc, existingCssFile, layoutFile };
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// src/utils/detect-globals.ts
|
|
187
|
-
import fs3 from "fs";
|
|
188
|
-
import path4 from "path";
|
|
189
|
-
function hasGlobalsCss(config, projectRoot) {
|
|
190
|
-
const cssPath = path4.resolve(projectRoot, config.css);
|
|
191
|
-
if (!fs3.existsSync(cssPath)) {
|
|
192
|
-
return false;
|
|
193
|
-
}
|
|
194
|
-
const steraPath = path4.join(path4.dirname(cssPath), "stera-ui.css");
|
|
195
|
-
return fs3.existsSync(steraPath);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
// src/utils/install-deps.ts
|
|
199
|
-
import fs4 from "fs";
|
|
200
|
-
import path5 from "path";
|
|
201
|
-
import { detect } from "@antfu/ni";
|
|
202
|
-
import { execa } from "execa";
|
|
203
|
-
|
|
204
|
-
// src/utils/format.ts
|
|
205
|
-
var BRAND = "\x1B[38;2;166;244;48m";
|
|
206
|
-
var DIM = "\x1B[2m";
|
|
207
|
-
var RESET = "\x1B[0m";
|
|
208
|
-
var enabled = process.stdout.isTTY && !process.env.NO_COLOR;
|
|
209
|
-
var wrap = (code, text) => enabled ? `${code}${text}${RESET}` : text;
|
|
210
|
-
var brand = (text) => wrap(BRAND, text);
|
|
211
|
-
var dim = (text) => wrap(DIM, text);
|
|
212
|
-
var LOGO = brand("\u273B");
|
|
213
|
-
var CHECK = brand("\u2713");
|
|
214
|
-
var CROSS = "\u2717";
|
|
215
|
-
var WARN = "!";
|
|
216
|
-
|
|
217
|
-
// src/utils/spinner.ts
|
|
218
|
-
var FRAMES = ["\u2022", "\u2726", "\u2736", "\u273B"].map(brand);
|
|
219
|
-
var INTERVAL_MS = 150;
|
|
220
|
-
function createSpinner(text) {
|
|
221
|
-
const isTTY = process.stdout.isTTY;
|
|
222
|
-
if (!isTTY) {
|
|
223
|
-
process.stdout.write(` ${text}...
|
|
224
|
-
`);
|
|
225
|
-
return {
|
|
226
|
-
succeed(msg) {
|
|
227
|
-
process.stdout.write(` ${CHECK} ${msg}
|
|
228
|
-
`);
|
|
229
|
-
},
|
|
230
|
-
fail(msg) {
|
|
231
|
-
process.stdout.write(` ${CROSS} ${msg}
|
|
232
|
-
`);
|
|
233
|
-
}
|
|
234
|
-
};
|
|
235
|
-
}
|
|
236
|
-
let frameIndex = 0;
|
|
237
|
-
const interval = setInterval(() => {
|
|
238
|
-
process.stdout.write(`\r ${FRAMES[frameIndex % FRAMES.length]} ${text}`);
|
|
239
|
-
frameIndex++;
|
|
240
|
-
}, INTERVAL_MS);
|
|
241
|
-
const clear = () => {
|
|
242
|
-
clearInterval(interval);
|
|
243
|
-
process.stdout.write("\r" + " ".repeat(text.length + 6) + "\r");
|
|
244
|
-
};
|
|
245
|
-
return {
|
|
246
|
-
succeed(msg) {
|
|
247
|
-
clear();
|
|
248
|
-
process.stdout.write(` ${CHECK} ${msg}
|
|
249
|
-
`);
|
|
250
|
-
},
|
|
251
|
-
fail(msg) {
|
|
252
|
-
clear();
|
|
253
|
-
process.stdout.write(` ${CROSS} ${msg}
|
|
254
|
-
`);
|
|
255
|
-
}
|
|
256
|
-
};
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
// src/utils/install-deps.ts
|
|
260
|
-
async function detectPackageManager(cwd) {
|
|
261
|
-
const detected = await detect({ programmatic: true, cwd });
|
|
262
|
-
if (detected === "pnpm@6" || detected === "pnpm") return "pnpm";
|
|
263
|
-
if (detected === "yarn@berry" || detected === "yarn") return "yarn";
|
|
264
|
-
if (detected === "bun") return "bun";
|
|
265
|
-
if (detected === "npm") return "npm";
|
|
266
|
-
const userAgent = process.env.npm_config_user_agent || "";
|
|
267
|
-
if (userAgent.startsWith("pnpm")) return "pnpm";
|
|
268
|
-
if (userAgent.startsWith("yarn")) return "yarn";
|
|
269
|
-
if (userAgent.startsWith("bun")) return "bun";
|
|
270
|
-
return "npm";
|
|
271
|
-
}
|
|
272
|
-
function getInstallArgs(pm, deps) {
|
|
273
|
-
switch (pm) {
|
|
274
|
-
case "pnpm":
|
|
275
|
-
return ["pnpm", ["add", ...deps]];
|
|
276
|
-
case "yarn":
|
|
277
|
-
return ["yarn", ["add", ...deps]];
|
|
278
|
-
case "bun":
|
|
279
|
-
return ["bun", ["add", ...deps]];
|
|
280
|
-
default:
|
|
281
|
-
return ["npm", ["install", ...deps]];
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
async function installDependencies(deps, cwd) {
|
|
285
|
-
if (deps.length === 0) return;
|
|
286
|
-
const pkgPath = path5.join(cwd, "package.json");
|
|
287
|
-
let existing = /* @__PURE__ */ new Set();
|
|
288
|
-
if (fs4.existsSync(pkgPath)) {
|
|
289
|
-
try {
|
|
290
|
-
const pkg = JSON.parse(fs4.readFileSync(pkgPath, "utf-8"));
|
|
291
|
-
existing = new Set(Object.keys({ ...pkg.dependencies, ...pkg.devDependencies }));
|
|
292
|
-
} catch {
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
const toInstall = deps.filter((dep) => !existing.has(dep));
|
|
296
|
-
if (toInstall.length === 0) return;
|
|
297
|
-
const pm = await detectPackageManager(cwd);
|
|
298
|
-
const [cmd, args] = getInstallArgs(pm, toInstall);
|
|
299
|
-
const spinner = createSpinner(`Installing with ${pm}`);
|
|
300
|
-
try {
|
|
301
|
-
await execa(cmd, args, { cwd });
|
|
302
|
-
spinner.succeed(`Installed with ${pm}`);
|
|
303
|
-
} catch (error) {
|
|
304
|
-
spinner.fail(`Install failed`);
|
|
305
|
-
throw error;
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
// src/utils/write-files.ts
|
|
310
|
-
import fs5 from "fs";
|
|
311
|
-
import path6 from "path";
|
|
312
|
-
import readline from "readline/promises";
|
|
313
|
-
async function confirmOverwrite(relativePath) {
|
|
314
|
-
if (!process.stdin.isTTY) {
|
|
315
|
-
console.log(` Skipping ${relativePath} (already exists, use --overwrite to replace)`);
|
|
316
|
-
return false;
|
|
317
|
-
}
|
|
318
|
-
const rl = readline.createInterface({
|
|
319
|
-
input: process.stdin,
|
|
320
|
-
output: process.stdout
|
|
321
|
-
});
|
|
322
|
-
const answer = await rl.question(` ${relativePath} already exists. Overwrite? (y/N) `);
|
|
323
|
-
rl.close();
|
|
324
|
-
return answer.toLowerCase() === "y";
|
|
325
|
-
}
|
|
326
|
-
async function writeComponentFiles(items, config, projectRoot, options = {}) {
|
|
327
|
-
const written = [];
|
|
328
|
-
const skipped = [];
|
|
329
|
-
for (const item of items) {
|
|
330
|
-
for (const file of item.files) {
|
|
331
|
-
const outputPath = resolveOutputPath(config, projectRoot, file);
|
|
332
|
-
const relativePath = path6.relative(projectRoot, outputPath);
|
|
333
|
-
if (fs5.existsSync(outputPath)) {
|
|
334
|
-
const existing = fs5.readFileSync(outputPath, "utf-8");
|
|
335
|
-
if (existing === file.content) {
|
|
336
|
-
skipped.push(relativePath);
|
|
337
|
-
continue;
|
|
338
|
-
}
|
|
339
|
-
if (!options.overwrite) {
|
|
340
|
-
const confirmed = await confirmOverwrite(relativePath);
|
|
341
|
-
if (!confirmed) {
|
|
342
|
-
skipped.push(relativePath);
|
|
343
|
-
continue;
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
const dir = path6.dirname(outputPath);
|
|
348
|
-
fs5.mkdirSync(dir, { recursive: true });
|
|
349
|
-
fs5.writeFileSync(outputPath, file.content ?? "", "utf-8");
|
|
350
|
-
written.push(relativePath);
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
return { written, skipped };
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
export {
|
|
357
|
-
applyTransforms,
|
|
358
|
-
transformImports,
|
|
359
|
-
resolveOutputPath,
|
|
360
|
-
CONFIG_FILE,
|
|
361
|
-
findConfigPath,
|
|
362
|
-
loadConfig2 as loadConfig,
|
|
363
|
-
detectProject,
|
|
364
|
-
hasGlobalsCss,
|
|
365
|
-
brand,
|
|
366
|
-
dim,
|
|
367
|
-
LOGO,
|
|
368
|
-
CHECK,
|
|
369
|
-
CROSS,
|
|
370
|
-
WARN,
|
|
371
|
-
createSpinner,
|
|
372
|
-
detectPackageManager,
|
|
373
|
-
installDependencies,
|
|
374
|
-
writeComponentFiles
|
|
375
|
-
};
|