cus-base-ui 0.2.7 → 0.2.8
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/ui-cli.cjs +191 -2
- package/package.json +1 -1
- package/scripts/ui-cli.ts +5 -1
package/dist/ui-cli.cjs
CHANGED
|
@@ -68,7 +68,7 @@ var getRegistry = async (isLocal) => {
|
|
|
68
68
|
process.exit(1);
|
|
69
69
|
}
|
|
70
70
|
};
|
|
71
|
-
var installNpmPackages = (packages, cwd) => {
|
|
71
|
+
var installNpmPackages = (packages, cwd, dev = false) => {
|
|
72
72
|
if (packages.length === 0) return;
|
|
73
73
|
const pkgJsonPath = import_path.default.join(cwd, "package.json");
|
|
74
74
|
let toInstall = packages;
|
|
@@ -79,12 +79,189 @@ var installNpmPackages = (packages, cwd) => {
|
|
|
79
79
|
}
|
|
80
80
|
if (toInstall.length === 0) return;
|
|
81
81
|
log(`Installing: ${toInstall.join(", ")}...`);
|
|
82
|
+
const flag = dev ? "--save-dev" : "--save";
|
|
82
83
|
try {
|
|
83
|
-
(0, import_child_process.execSync)(`npm install ${toInstall.join(" ")}
|
|
84
|
+
(0, import_child_process.execSync)(`npm install ${toInstall.join(" ")} ${flag}`, { stdio: "inherit", cwd });
|
|
84
85
|
} catch (err) {
|
|
85
86
|
error(`Failed to install packages: ${toInstall.join(", ")}. ${err instanceof Error ? err.message : ""}`);
|
|
86
87
|
}
|
|
87
88
|
};
|
|
89
|
+
var VITE_DEV_PACKAGES = ["tailwindcss", "@tailwindcss/vite", "@vitejs/plugin-react", "vite-plugin-babel", "babel-plugin-react-compiler", "@types/node"];
|
|
90
|
+
var RUNTIME_PACKAGES = ["@base-ui/react", "tailwind-variants", "clsx", "tailwind-merge", "tailwindcss-animate"];
|
|
91
|
+
var VITE_CONFIG_TEMPLATE = `import { defineConfig } from 'vite';
|
|
92
|
+
import tailwindcss from '@tailwindcss/vite';
|
|
93
|
+
import react from '@vitejs/plugin-react';
|
|
94
|
+
import babel from 'vite-plugin-babel';
|
|
95
|
+
import { reactCompilerPreset } from 'babel-plugin-react-compiler';
|
|
96
|
+
import path from 'path';
|
|
97
|
+
|
|
98
|
+
// https://vite.dev/config/
|
|
99
|
+
export default defineConfig({
|
|
100
|
+
plugins: [
|
|
101
|
+
tailwindcss(),
|
|
102
|
+
react(),
|
|
103
|
+
babel({ presets: [reactCompilerPreset()] }),
|
|
104
|
+
],
|
|
105
|
+
resolve: {
|
|
106
|
+
alias: {
|
|
107
|
+
'@': path.resolve(__dirname, './src'),
|
|
108
|
+
'@lib': path.resolve(__dirname, './src/lib'),
|
|
109
|
+
'@components': path.resolve(__dirname, './src/components'),
|
|
110
|
+
'@assets': path.resolve(__dirname, './src/assets'),
|
|
111
|
+
'@pages': path.resolve(__dirname, './src/pages'),
|
|
112
|
+
'@styles': path.resolve(__dirname, './src/styles'),
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
`;
|
|
117
|
+
var TSCONFIG_PATHS = {
|
|
118
|
+
"@/*": ["./src/*"],
|
|
119
|
+
"@lib/*": ["./src/lib/*"],
|
|
120
|
+
"@components/*": ["./src/components/*"],
|
|
121
|
+
"@assets/*": ["./src/assets/*"],
|
|
122
|
+
"@pages/*": ["./src/pages/*"],
|
|
123
|
+
"@styles/*": ["./src/styles/*"]
|
|
124
|
+
};
|
|
125
|
+
var setupViteConfig = (cwd) => {
|
|
126
|
+
installNpmPackages(VITE_DEV_PACKAGES, cwd, true);
|
|
127
|
+
const configTs = import_path.default.join(cwd, "vite.config.ts");
|
|
128
|
+
const configJs = import_path.default.join(cwd, "vite.config.js");
|
|
129
|
+
if (!import_fs.default.existsSync(configTs) && !import_fs.default.existsSync(configJs)) {
|
|
130
|
+
import_fs.default.writeFileSync(configTs, VITE_CONFIG_TEMPLATE);
|
|
131
|
+
log("Created vite.config.ts with Tailwind + React Compiler setup.");
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const existingPath = import_fs.default.existsSync(configTs) ? configTs : configJs;
|
|
135
|
+
let content = import_fs.default.readFileSync(existingPath, "utf-8");
|
|
136
|
+
const missingImports = [];
|
|
137
|
+
if (!content.includes("@tailwindcss/vite")) missingImports.push("import tailwindcss from '@tailwindcss/vite';");
|
|
138
|
+
if (!content.includes("@vitejs/plugin-react")) missingImports.push("import react from '@vitejs/plugin-react';");
|
|
139
|
+
if (!content.includes("vite-plugin-babel")) missingImports.push("import babel from 'vite-plugin-babel';");
|
|
140
|
+
if (!content.includes("babel-plugin-react-compiler")) missingImports.push("import { reactCompilerPreset } from 'babel-plugin-react-compiler';");
|
|
141
|
+
if (!content.includes("from 'path'") && !content.includes('from "path"')) missingImports.push("import path from 'path';");
|
|
142
|
+
const missingPlugins = [];
|
|
143
|
+
if (!content.includes("tailwindcss()")) missingPlugins.push("tailwindcss()");
|
|
144
|
+
if (!content.includes("react()") && !content.includes("react({")) missingPlugins.push("react()");
|
|
145
|
+
if (!content.includes("reactCompilerPreset")) missingPlugins.push("babel({ presets: [reactCompilerPreset()] })");
|
|
146
|
+
const hasAlias = content.includes("alias:") || content.includes("alias(") || content.includes("'@'") || content.includes('"@"');
|
|
147
|
+
if (missingImports.length === 0 && missingPlugins.length === 0 && hasAlias) {
|
|
148
|
+
log("vite.config already configured \u2014 skipping.");
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
if (missingImports.length > 0) {
|
|
152
|
+
const importBlock = missingImports.join("\n");
|
|
153
|
+
const allImports = [...content.matchAll(/^import\s.+$/gm)];
|
|
154
|
+
if (allImports.length > 0) {
|
|
155
|
+
const last = allImports[allImports.length - 1];
|
|
156
|
+
const pos = last.index + last[0].length;
|
|
157
|
+
content = content.slice(0, pos) + "\n" + importBlock + content.slice(pos);
|
|
158
|
+
} else {
|
|
159
|
+
content = importBlock + "\n" + content;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (missingPlugins.length > 0) {
|
|
163
|
+
const match = content.match(/plugins:\s*\[/);
|
|
164
|
+
if (match && match.index !== void 0) {
|
|
165
|
+
const pos = match.index + match[0].length;
|
|
166
|
+
const after = content.slice(pos);
|
|
167
|
+
const pluginLines = missingPlugins.map((p) => `
|
|
168
|
+
${p},`).join("");
|
|
169
|
+
const needsNewline = after.length > 0 && after[0] !== "\n" && after[0] !== "\r";
|
|
170
|
+
content = content.slice(0, pos) + pluginLines + (needsNewline ? "\n " : "") + after;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
if (!hasAlias) {
|
|
174
|
+
const aliasBlock = [
|
|
175
|
+
" resolve: {",
|
|
176
|
+
" alias: {",
|
|
177
|
+
" '@': path.resolve(__dirname, './src'),",
|
|
178
|
+
" '@lib': path.resolve(__dirname, './src/lib'),",
|
|
179
|
+
" '@components': path.resolve(__dirname, './src/components'),",
|
|
180
|
+
" '@assets': path.resolve(__dirname, './src/assets'),",
|
|
181
|
+
" '@pages': path.resolve(__dirname, './src/pages'),",
|
|
182
|
+
" '@styles': path.resolve(__dirname, './src/styles'),",
|
|
183
|
+
" },",
|
|
184
|
+
" },"
|
|
185
|
+
].join("\n");
|
|
186
|
+
const pluginsStart = content.search(/plugins:\s*\[/);
|
|
187
|
+
if (pluginsStart !== -1) {
|
|
188
|
+
let depth = 0;
|
|
189
|
+
let foundStart = false;
|
|
190
|
+
for (let i = pluginsStart; i < content.length; i++) {
|
|
191
|
+
if (content[i] === "[") {
|
|
192
|
+
depth++;
|
|
193
|
+
foundStart = true;
|
|
194
|
+
}
|
|
195
|
+
if (content[i] === "]") depth--;
|
|
196
|
+
if (foundStart && depth === 0) {
|
|
197
|
+
let lineEnd = content.indexOf("\n", i);
|
|
198
|
+
if (lineEnd === -1) lineEnd = content.length;
|
|
199
|
+
content = content.slice(0, lineEnd + 1) + aliasBlock + "\n" + content.slice(lineEnd + 1);
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
import_fs.default.writeFileSync(existingPath, content);
|
|
206
|
+
log(`Updated ${import_path.default.basename(existingPath)} with Tailwind + React Compiler + path aliases.`);
|
|
207
|
+
};
|
|
208
|
+
var ensureTailwindCss = (cwd) => {
|
|
209
|
+
const candidates = ["src/index.css", "src/App.css", "src/main.css"];
|
|
210
|
+
for (const cssFile of candidates) {
|
|
211
|
+
const cssPath = import_path.default.join(cwd, cssFile);
|
|
212
|
+
if (import_fs.default.existsSync(cssPath)) {
|
|
213
|
+
const content = import_fs.default.readFileSync(cssPath, "utf-8");
|
|
214
|
+
if (!content.includes('@import "tailwindcss"') && !content.includes("@import 'tailwindcss'")) {
|
|
215
|
+
import_fs.default.writeFileSync(cssPath, `@import "tailwindcss";
|
|
216
|
+
|
|
217
|
+
${content}`);
|
|
218
|
+
log(`Added @import "tailwindcss" to ${cssFile}`);
|
|
219
|
+
} else {
|
|
220
|
+
log(`${cssFile} already imports Tailwind \u2014 skipping.`);
|
|
221
|
+
}
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
const srcDir = import_path.default.join(cwd, "src");
|
|
226
|
+
if (!import_fs.default.existsSync(srcDir)) import_fs.default.mkdirSync(srcDir, { recursive: true });
|
|
227
|
+
import_fs.default.writeFileSync(import_path.default.join(srcDir, "index.css"), '@import "tailwindcss";\n');
|
|
228
|
+
log('Created src/index.css with @import "tailwindcss"');
|
|
229
|
+
};
|
|
230
|
+
var setupTsConfig = (cwd) => {
|
|
231
|
+
const candidates = ["tsconfig.app.json", "tsconfig.json"];
|
|
232
|
+
for (const candidate of candidates) {
|
|
233
|
+
const configPath = import_path.default.join(cwd, candidate);
|
|
234
|
+
if (!import_fs.default.existsSync(configPath)) continue;
|
|
235
|
+
const raw = import_fs.default.readFileSync(configPath, "utf-8");
|
|
236
|
+
if (raw.includes('"@/*"') || raw.includes("'@/*'")) {
|
|
237
|
+
log(`${candidate} already has path aliases \u2014 skipping.`);
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
try {
|
|
241
|
+
const stripped = raw.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[\s,{[\]])\/\/[^\n]*/g, "$1");
|
|
242
|
+
const parsed = JSON.parse(stripped);
|
|
243
|
+
if (!parsed.compilerOptions) parsed.compilerOptions = {};
|
|
244
|
+
parsed.compilerOptions.baseUrl = ".";
|
|
245
|
+
parsed.compilerOptions.paths = TSCONFIG_PATHS;
|
|
246
|
+
import_fs.default.writeFileSync(configPath, JSON.stringify(parsed, null, 2));
|
|
247
|
+
log(`Added path aliases to ${candidate}.`);
|
|
248
|
+
} catch (err) {
|
|
249
|
+
warn(`Could not auto-patch ${candidate}: ${err instanceof Error ? err.message : err}`);
|
|
250
|
+
warn("Add these to compilerOptions manually:");
|
|
251
|
+
console.log('\n "baseUrl": ".",');
|
|
252
|
+
console.log(' "paths": {');
|
|
253
|
+
for (const [alias, targets] of Object.entries(TSCONFIG_PATHS)) {
|
|
254
|
+
console.log(` "${alias}": ["${targets[0]}"],`);
|
|
255
|
+
}
|
|
256
|
+
console.log(" }");
|
|
257
|
+
console.log("");
|
|
258
|
+
}
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
const newConfig = { compilerOptions: { baseUrl: ".", paths: TSCONFIG_PATHS } };
|
|
262
|
+
import_fs.default.writeFileSync(import_path.default.join(cwd, "tsconfig.json"), JSON.stringify(newConfig, null, 2));
|
|
263
|
+
log("Created tsconfig.json with path aliases.");
|
|
264
|
+
};
|
|
88
265
|
var ensureCore = (registry, cwd) => {
|
|
89
266
|
const core = registry.core;
|
|
90
267
|
if (!core) return;
|
|
@@ -174,6 +351,14 @@ var main = async () => {
|
|
|
174
351
|
error("Usage: npx cus-base-ui add <component-name> [--force]");
|
|
175
352
|
return;
|
|
176
353
|
}
|
|
354
|
+
const cnPath = import_path.default.join(cwd, "src/lib/utils/cn.ts");
|
|
355
|
+
if (!import_fs.default.existsSync(cnPath)) {
|
|
356
|
+
log("Project not initialized \u2014 running init first...");
|
|
357
|
+
setupViteConfig(cwd);
|
|
358
|
+
setupTsConfig(cwd);
|
|
359
|
+
ensureTailwindCss(cwd);
|
|
360
|
+
installNpmPackages(RUNTIME_PACKAGES, cwd);
|
|
361
|
+
}
|
|
177
362
|
for (const name of componentNames) {
|
|
178
363
|
addComponent(name, registry, cwd, { force: isForce });
|
|
179
364
|
}
|
|
@@ -202,6 +387,10 @@ var main = async () => {
|
|
|
202
387
|
break;
|
|
203
388
|
}
|
|
204
389
|
case "init": {
|
|
390
|
+
setupViteConfig(cwd);
|
|
391
|
+
setupTsConfig(cwd);
|
|
392
|
+
ensureTailwindCss(cwd);
|
|
393
|
+
installNpmPackages(RUNTIME_PACKAGES, cwd);
|
|
205
394
|
ensureCore(registry, cwd);
|
|
206
395
|
log("Initialization complete.");
|
|
207
396
|
break;
|
package/package.json
CHANGED
package/scripts/ui-cli.ts
CHANGED
|
@@ -175,8 +175,12 @@ const setupViteConfig = (cwd: string) => {
|
|
|
175
175
|
const match = content.match(/plugins:\s*\[/);
|
|
176
176
|
if (match && match.index !== undefined) {
|
|
177
177
|
const pos = match.index + match[0].length;
|
|
178
|
+
const after = content.slice(pos);
|
|
178
179
|
const pluginLines = missingPlugins.map((p) => `\n ${p},`).join('');
|
|
179
|
-
|
|
180
|
+
// If existing content continues on the same line (e.g. `plugins: [react()],`),
|
|
181
|
+
// push it to a new line so formatting stays clean
|
|
182
|
+
const needsNewline = after.length > 0 && after[0] !== '\n' && after[0] !== '\r';
|
|
183
|
+
content = content.slice(0, pos) + pluginLines + (needsNewline ? '\n ' : '') + after;
|
|
180
184
|
}
|
|
181
185
|
}
|
|
182
186
|
|