cus-base-ui 0.2.6 → 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 +71 -24
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
|
@@ -126,6 +126,7 @@ const setupViteConfig = (cwd: string) => {
|
|
|
126
126
|
const configTs = path.join(cwd, 'vite.config.ts');
|
|
127
127
|
const configJs = path.join(cwd, 'vite.config.js');
|
|
128
128
|
|
|
129
|
+
// No config exists — create from template
|
|
129
130
|
if (!fs.existsSync(configTs) && !fs.existsSync(configJs)) {
|
|
130
131
|
fs.writeFileSync(configTs, VITE_CONFIG_TEMPLATE);
|
|
131
132
|
log('Created vite.config.ts with Tailwind + React Compiler setup.');
|
|
@@ -133,49 +134,91 @@ const setupViteConfig = (cwd: string) => {
|
|
|
133
134
|
}
|
|
134
135
|
|
|
135
136
|
const existingPath = fs.existsSync(configTs) ? configTs : configJs;
|
|
136
|
-
|
|
137
|
+
let content = fs.readFileSync(existingPath, 'utf-8');
|
|
137
138
|
|
|
138
139
|
const missingImports: string[] = [];
|
|
139
140
|
if (!content.includes('@tailwindcss/vite')) missingImports.push("import tailwindcss from '@tailwindcss/vite';");
|
|
140
141
|
if (!content.includes('@vitejs/plugin-react')) missingImports.push("import react from '@vitejs/plugin-react';");
|
|
141
142
|
if (!content.includes('vite-plugin-babel')) missingImports.push("import babel from 'vite-plugin-babel';");
|
|
142
143
|
if (!content.includes('babel-plugin-react-compiler')) missingImports.push("import { reactCompilerPreset } from 'babel-plugin-react-compiler';");
|
|
144
|
+
if (!content.includes("from 'path'") && !content.includes('from "path"')) missingImports.push("import path from 'path';");
|
|
143
145
|
|
|
144
146
|
const missingPlugins: string[] = [];
|
|
145
147
|
if (!content.includes('tailwindcss()')) missingPlugins.push('tailwindcss()');
|
|
146
148
|
if (!content.includes('react()') && !content.includes('react({')) missingPlugins.push('react()');
|
|
147
|
-
if (!content.includes('reactCompilerPreset')) missingPlugins.push(
|
|
149
|
+
if (!content.includes('reactCompilerPreset')) missingPlugins.push("babel({ presets: [reactCompilerPreset()] })");
|
|
148
150
|
|
|
149
|
-
const hasAlias = content.includes('alias:') || content.includes("'@'") || content.includes('"@"');
|
|
151
|
+
const hasAlias = content.includes('alias:') || content.includes('alias(') || content.includes("'@'") || content.includes('"@"');
|
|
150
152
|
|
|
151
153
|
if (missingImports.length === 0 && missingPlugins.length === 0 && hasAlias) {
|
|
152
154
|
log('vite.config already configured — skipping.');
|
|
153
155
|
return;
|
|
154
156
|
}
|
|
155
157
|
|
|
156
|
-
|
|
158
|
+
// --- Auto-patch the file ---
|
|
159
|
+
|
|
160
|
+
// 1. Insert missing imports after the last import statement
|
|
157
161
|
if (missingImports.length > 0) {
|
|
158
|
-
|
|
159
|
-
|
|
162
|
+
const importBlock = missingImports.join('\n');
|
|
163
|
+
const allImports = [...content.matchAll(/^import\s.+$/gm)];
|
|
164
|
+
if (allImports.length > 0) {
|
|
165
|
+
const last = allImports[allImports.length - 1];
|
|
166
|
+
const pos = last.index! + last[0].length;
|
|
167
|
+
content = content.slice(0, pos) + '\n' + importBlock + content.slice(pos);
|
|
168
|
+
} else {
|
|
169
|
+
content = importBlock + '\n' + content;
|
|
170
|
+
}
|
|
160
171
|
}
|
|
172
|
+
|
|
173
|
+
// 2. Insert missing plugins into plugins: [...]
|
|
161
174
|
if (missingPlugins.length > 0) {
|
|
162
|
-
|
|
163
|
-
|
|
175
|
+
const match = content.match(/plugins:\s*\[/);
|
|
176
|
+
if (match && match.index !== undefined) {
|
|
177
|
+
const pos = match.index + match[0].length;
|
|
178
|
+
const after = content.slice(pos);
|
|
179
|
+
const pluginLines = missingPlugins.map((p) => `\n ${p},`).join('');
|
|
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;
|
|
184
|
+
}
|
|
164
185
|
}
|
|
186
|
+
|
|
187
|
+
// 3. Insert resolve.alias block if missing
|
|
165
188
|
if (!hasAlias) {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
189
|
+
const aliasBlock = [
|
|
190
|
+
' resolve: {',
|
|
191
|
+
' alias: {',
|
|
192
|
+
" '@': path.resolve(__dirname, './src'),",
|
|
193
|
+
" '@lib': path.resolve(__dirname, './src/lib'),",
|
|
194
|
+
" '@components': path.resolve(__dirname, './src/components'),",
|
|
195
|
+
" '@assets': path.resolve(__dirname, './src/assets'),",
|
|
196
|
+
" '@pages': path.resolve(__dirname, './src/pages'),",
|
|
197
|
+
" '@styles': path.resolve(__dirname, './src/styles'),",
|
|
198
|
+
' },',
|
|
199
|
+
' },',
|
|
200
|
+
].join('\n');
|
|
201
|
+
|
|
202
|
+
// Find end of plugins array, then insert after that line
|
|
203
|
+
const pluginsStart = content.search(/plugins:\s*\[/);
|
|
204
|
+
if (pluginsStart !== -1) {
|
|
205
|
+
let depth = 0;
|
|
206
|
+
let foundStart = false;
|
|
207
|
+
for (let i = pluginsStart; i < content.length; i++) {
|
|
208
|
+
if (content[i] === '[') { depth++; foundStart = true; }
|
|
209
|
+
if (content[i] === ']') depth--;
|
|
210
|
+
if (foundStart && depth === 0) {
|
|
211
|
+
let lineEnd = content.indexOf('\n', i);
|
|
212
|
+
if (lineEnd === -1) lineEnd = content.length;
|
|
213
|
+
content = content.slice(0, lineEnd + 1) + aliasBlock + '\n' + content.slice(lineEnd + 1);
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
177
218
|
}
|
|
178
|
-
|
|
219
|
+
|
|
220
|
+
fs.writeFileSync(existingPath, content);
|
|
221
|
+
log(`Updated ${path.basename(existingPath)} with Tailwind + React Compiler + path aliases.`);
|
|
179
222
|
};
|
|
180
223
|
|
|
181
224
|
const ensureTailwindCss = (cwd: string) => {
|
|
@@ -215,16 +258,20 @@ const setupTsConfig = (cwd: string) => {
|
|
|
215
258
|
}
|
|
216
259
|
|
|
217
260
|
try {
|
|
218
|
-
// Strip
|
|
219
|
-
|
|
261
|
+
// Strip comments safely: block comments first, then single-line comments
|
|
262
|
+
// only when they appear outside of string values (preceded by whitespace or line start)
|
|
263
|
+
const stripped = raw
|
|
264
|
+
.replace(/\/\*[\s\S]*?\*\//g, '')
|
|
265
|
+
.replace(/(^|[\s,{[\]])\/\/[^\n]*/g, '$1');
|
|
220
266
|
const parsed = JSON.parse(stripped) as { compilerOptions?: Record<string, unknown> };
|
|
221
267
|
if (!parsed.compilerOptions) parsed.compilerOptions = {};
|
|
222
268
|
parsed.compilerOptions.baseUrl = '.';
|
|
223
269
|
parsed.compilerOptions.paths = TSCONFIG_PATHS;
|
|
224
270
|
fs.writeFileSync(configPath, JSON.stringify(parsed, null, 2));
|
|
225
271
|
log(`Added path aliases to ${candidate}.`);
|
|
226
|
-
} catch {
|
|
227
|
-
warn(`Could not auto-patch ${candidate}
|
|
272
|
+
} catch (err) {
|
|
273
|
+
warn(`Could not auto-patch ${candidate}: ${err instanceof Error ? err.message : err}`);
|
|
274
|
+
warn('Add these to compilerOptions manually:');
|
|
228
275
|
console.log('\n "baseUrl": ".",');
|
|
229
276
|
console.log(' "paths": {');
|
|
230
277
|
for (const [alias, targets] of Object.entries(TSCONFIG_PATHS)) {
|