bertui 0.3.2 ā 0.3.4
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/package.json +1 -1
- package/src/build.js +26 -29
- package/src/client/compiler.js +58 -23
- package/src/utils/env.js +57 -0
package/package.json
CHANGED
package/src/build.js
CHANGED
|
@@ -11,7 +11,6 @@ export async function buildProduction(options = {}) {
|
|
|
11
11
|
|
|
12
12
|
logger.bigLog('BUILDING FOR PRODUCTION', { color: 'green' });
|
|
13
13
|
|
|
14
|
-
// Clean folders
|
|
15
14
|
if (existsSync(buildDir)) {
|
|
16
15
|
rmSync(buildDir, { recursive: true });
|
|
17
16
|
}
|
|
@@ -26,16 +25,13 @@ export async function buildProduction(options = {}) {
|
|
|
26
25
|
const startTime = Date.now();
|
|
27
26
|
|
|
28
27
|
try {
|
|
29
|
-
// Step 1: Compile for production
|
|
30
28
|
logger.info('Step 1: Compiling for production...');
|
|
31
29
|
await compileForBuild(root, buildDir);
|
|
32
30
|
logger.success('Production compilation complete');
|
|
33
31
|
|
|
34
|
-
// Step 2: Build CSS with Lightning CSS
|
|
35
32
|
logger.info('Step 2: Building CSS with Lightning CSS...');
|
|
36
33
|
await buildAllCSS(root, outDir);
|
|
37
34
|
|
|
38
|
-
// Step 3: Copy public assets if they exist
|
|
39
35
|
const publicDir = join(root, 'public');
|
|
40
36
|
if (existsSync(publicDir)) {
|
|
41
37
|
logger.info('Step 3: Copying public assets...');
|
|
@@ -45,7 +41,6 @@ export async function buildProduction(options = {}) {
|
|
|
45
41
|
logger.info('Step 3: No public directory found, skipping...');
|
|
46
42
|
}
|
|
47
43
|
|
|
48
|
-
// Step 4: Build JavaScript with Bun's bundler
|
|
49
44
|
logger.info('Step 4: Bundling JavaScript with Bun...');
|
|
50
45
|
const buildEntry = join(buildDir, 'main.js');
|
|
51
46
|
|
|
@@ -54,7 +49,6 @@ export async function buildProduction(options = {}) {
|
|
|
54
49
|
process.exit(1);
|
|
55
50
|
}
|
|
56
51
|
|
|
57
|
-
// FIXED: Let Bun handle ALL imports with proper externals
|
|
58
52
|
const result = await Bun.build({
|
|
59
53
|
entrypoints: [buildEntry],
|
|
60
54
|
outdir: join(outDir, 'assets'),
|
|
@@ -67,7 +61,6 @@ export async function buildProduction(options = {}) {
|
|
|
67
61
|
chunk: 'chunks/[name]-[hash].js',
|
|
68
62
|
asset: '[name]-[hash].[ext]'
|
|
69
63
|
},
|
|
70
|
-
// FIXED: Use CDN externals - Bun handles tree shaking automatically
|
|
71
64
|
external: ['react', 'react-dom', 'react-dom/client', 'react/jsx-runtime']
|
|
72
65
|
});
|
|
73
66
|
|
|
@@ -79,11 +72,9 @@ export async function buildProduction(options = {}) {
|
|
|
79
72
|
|
|
80
73
|
logger.success('JavaScript bundled with tree-shaking');
|
|
81
74
|
|
|
82
|
-
// Step 5: Generate index.html
|
|
83
75
|
logger.info('Step 5: Generating index.html...');
|
|
84
76
|
await generateProductionHTML(root, outDir, result);
|
|
85
77
|
|
|
86
|
-
// Step 6: Clean up build folder
|
|
87
78
|
rmSync(buildDir, { recursive: true });
|
|
88
79
|
logger.info('Cleaned up .bertuibuild/');
|
|
89
80
|
|
|
@@ -91,13 +82,11 @@ export async function buildProduction(options = {}) {
|
|
|
91
82
|
logger.success(`⨠Build complete in ${duration}ms`);
|
|
92
83
|
logger.info(`š¦ Output: ${outDir}`);
|
|
93
84
|
|
|
94
|
-
// Display build stats
|
|
95
85
|
logger.table(result.outputs.map(o => ({
|
|
96
86
|
file: o.path.replace(outDir, ''),
|
|
97
87
|
size: `${(o.size / 1024).toFixed(2)} KB`
|
|
98
88
|
})));
|
|
99
89
|
|
|
100
|
-
// Show deployment instructions
|
|
101
90
|
logger.bigLog('READY TO DEPLOY', { color: 'green' });
|
|
102
91
|
console.log('\nš¤ Deploy your app:\n');
|
|
103
92
|
console.log(' Vercel: bunx vercel');
|
|
@@ -111,7 +100,6 @@ export async function buildProduction(options = {}) {
|
|
|
111
100
|
logger.error(error.stack);
|
|
112
101
|
}
|
|
113
102
|
|
|
114
|
-
// Clean up on error
|
|
115
103
|
if (existsSync(buildDir)) {
|
|
116
104
|
rmSync(buildDir, { recursive: true });
|
|
117
105
|
}
|
|
@@ -122,15 +110,10 @@ export async function buildProduction(options = {}) {
|
|
|
122
110
|
|
|
123
111
|
async function buildAllCSS(root, outDir) {
|
|
124
112
|
const srcStylesDir = join(root, 'src', 'styles');
|
|
125
|
-
const bertuiCssSource = join(import.meta.dir, 'styles/bertui.css');
|
|
126
113
|
const stylesOutDir = join(outDir, 'styles');
|
|
127
114
|
|
|
128
115
|
mkdirSync(stylesOutDir, { recursive: true });
|
|
129
116
|
|
|
130
|
-
// Build BertUI's built-in CSS
|
|
131
|
-
await buildCSS(bertuiCssSource, join(stylesOutDir, 'bertui.min.css'));
|
|
132
|
-
|
|
133
|
-
// Build user's CSS files if they exist
|
|
134
117
|
if (existsSync(srcStylesDir)) {
|
|
135
118
|
const cssFiles = readdirSync(srcStylesDir).filter(f => f.endsWith('.css'));
|
|
136
119
|
for (const cssFile of cssFiles) {
|
|
@@ -149,17 +132,14 @@ async function compileForBuild(root, buildDir) {
|
|
|
149
132
|
throw new Error('src/ directory not found!');
|
|
150
133
|
}
|
|
151
134
|
|
|
152
|
-
// Discover routes
|
|
153
135
|
let routes = [];
|
|
154
136
|
if (existsSync(pagesDir)) {
|
|
155
137
|
routes = await discoverRoutes(pagesDir);
|
|
156
138
|
logger.info(`Found ${routes.length} routes`);
|
|
157
139
|
}
|
|
158
140
|
|
|
159
|
-
// Compile all source files
|
|
160
141
|
await compileBuildDirectory(srcDir, buildDir, root);
|
|
161
142
|
|
|
162
|
-
// Generate router if we have routes
|
|
163
143
|
if (routes.length > 0) {
|
|
164
144
|
await generateBuildRouter(routes, buildDir);
|
|
165
145
|
logger.info('Generated router for build');
|
|
@@ -181,7 +161,6 @@ async function discoverRoutes(pagesDir) {
|
|
|
181
161
|
} else if (entry.isFile()) {
|
|
182
162
|
const ext = extname(entry.name);
|
|
183
163
|
|
|
184
|
-
// FIXED: Ignore CSS files
|
|
185
164
|
if (ext === '.css') continue;
|
|
186
165
|
|
|
187
166
|
if (['.jsx', '.tsx', '.js', '.ts'].includes(ext)) {
|
|
@@ -369,7 +348,6 @@ async function compileBuildDirectory(srcDir, buildDir, root) {
|
|
|
369
348
|
} else {
|
|
370
349
|
const ext = extname(file);
|
|
371
350
|
|
|
372
|
-
// FIXED: Skip CSS files in build
|
|
373
351
|
if (ext === '.css') continue;
|
|
374
352
|
|
|
375
353
|
if (['.jsx', '.tsx', '.ts'].includes(ext)) {
|
|
@@ -377,7 +355,11 @@ async function compileBuildDirectory(srcDir, buildDir, root) {
|
|
|
377
355
|
} else if (ext === '.js') {
|
|
378
356
|
const outPath = join(buildDir, file);
|
|
379
357
|
let code = await Bun.file(srcPath).text();
|
|
358
|
+
|
|
359
|
+
// CRITICAL FIX: Remove CSS imports
|
|
360
|
+
code = removeCSSImports(code);
|
|
380
361
|
code = fixBuildImports(code, srcPath, outPath, root);
|
|
362
|
+
|
|
381
363
|
await Bun.write(outPath, code);
|
|
382
364
|
}
|
|
383
365
|
}
|
|
@@ -391,6 +373,9 @@ async function compileBuildFile(srcPath, buildDir, filename, root) {
|
|
|
391
373
|
try {
|
|
392
374
|
let code = await Bun.file(srcPath).text();
|
|
393
375
|
|
|
376
|
+
// CRITICAL FIX: Remove CSS imports before transpilation
|
|
377
|
+
code = removeCSSImports(code);
|
|
378
|
+
|
|
394
379
|
const outFilename = filename.replace(/\.(jsx|tsx|ts)$/, '.js');
|
|
395
380
|
const outPath = join(buildDir, outFilename);
|
|
396
381
|
|
|
@@ -422,19 +407,20 @@ async function compileBuildFile(srcPath, buildDir, filename, root) {
|
|
|
422
407
|
}
|
|
423
408
|
}
|
|
424
409
|
|
|
425
|
-
//
|
|
426
|
-
function
|
|
427
|
-
|
|
410
|
+
// NEW FUNCTION: Remove all CSS imports
|
|
411
|
+
function removeCSSImports(code) {
|
|
412
|
+
code = code.replace(/import\s+['"][^'"]*\.css['"];?\s*/g, '');
|
|
428
413
|
code = code.replace(/import\s+['"]bertui\/styles['"]\s*;?\s*/g, '');
|
|
429
|
-
|
|
414
|
+
return code;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
function fixBuildImports(code, srcPath, outPath, root) {
|
|
430
418
|
const buildDir = join(root, '.bertuibuild');
|
|
431
419
|
const routerPath = join(buildDir, 'router.js');
|
|
432
420
|
|
|
433
|
-
// Calculate relative path from output file to router.js
|
|
434
421
|
const relativeToRouter = relative(dirname(outPath), routerPath).replace(/\\/g, '/');
|
|
435
422
|
const routerImport = relativeToRouter.startsWith('.') ? relativeToRouter : './' + relativeToRouter;
|
|
436
423
|
|
|
437
|
-
// ONLY replace bertui/router imports
|
|
438
424
|
code = code.replace(
|
|
439
425
|
/from\s+['"]bertui\/router['"]/g,
|
|
440
426
|
`from '${routerImport}'`
|
|
@@ -467,6 +453,17 @@ async function generateProductionHTML(root, outDir, buildResult) {
|
|
|
467
453
|
|
|
468
454
|
const bundlePath = mainBundle.path.replace(outDir, '').replace(/^\//, '');
|
|
469
455
|
|
|
456
|
+
// Find user CSS files
|
|
457
|
+
const srcStylesDir = join(root, 'src', 'styles');
|
|
458
|
+
let userStylesheets = '';
|
|
459
|
+
|
|
460
|
+
if (existsSync(srcStylesDir)) {
|
|
461
|
+
const cssFiles = readdirSync(srcStylesDir).filter(f => f.endsWith('.css'));
|
|
462
|
+
userStylesheets = cssFiles.map(f =>
|
|
463
|
+
` <link rel="stylesheet" href="/styles/${f.replace('.css', '.min.css')}">`
|
|
464
|
+
).join('\n');
|
|
465
|
+
}
|
|
466
|
+
|
|
470
467
|
const html = `<!DOCTYPE html>
|
|
471
468
|
<html lang="en">
|
|
472
469
|
<head>
|
|
@@ -474,7 +471,7 @@ async function generateProductionHTML(root, outDir, buildResult) {
|
|
|
474
471
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
475
472
|
<meta name="description" content="Built with BertUI - Lightning fast React development">
|
|
476
473
|
<title>BertUI App</title>
|
|
477
|
-
|
|
474
|
+
${userStylesheets}
|
|
478
475
|
<script type="importmap">
|
|
479
476
|
{
|
|
480
477
|
"imports": {
|
package/src/client/compiler.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readdirSync, statSync } from 'fs';
|
|
2
2
|
import { join, extname, relative, dirname } from 'path';
|
|
3
3
|
import logger from '../logger/logger.js';
|
|
4
|
+
import { loadEnvVariables, generateEnvCode, replaceEnvInCode } from '../utils/env.js';
|
|
4
5
|
|
|
5
6
|
export async function compileProject(root) {
|
|
6
7
|
logger.bigLog('COMPILING PROJECT', { color: 'blue' });
|
|
@@ -19,6 +20,16 @@ export async function compileProject(root) {
|
|
|
19
20
|
logger.info('Created .bertui/compiled/');
|
|
20
21
|
}
|
|
21
22
|
|
|
23
|
+
// Load environment variables
|
|
24
|
+
const envVars = loadEnvVariables(root);
|
|
25
|
+
if (Object.keys(envVars).length > 0) {
|
|
26
|
+
logger.info(`Loaded ${Object.keys(envVars).length} environment variables`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Generate env.js file
|
|
30
|
+
const envCode = generateEnvCode(envVars);
|
|
31
|
+
await Bun.write(join(outDir, 'env.js'), envCode);
|
|
32
|
+
|
|
22
33
|
let routes = [];
|
|
23
34
|
if (existsSync(pagesDir)) {
|
|
24
35
|
routes = await discoverRoutes(pagesDir);
|
|
@@ -36,7 +47,7 @@ export async function compileProject(root) {
|
|
|
36
47
|
}
|
|
37
48
|
|
|
38
49
|
const startTime = Date.now();
|
|
39
|
-
const stats = await compileDirectory(srcDir, outDir, root);
|
|
50
|
+
const stats = await compileDirectory(srcDir, outDir, root, envVars);
|
|
40
51
|
const duration = Date.now() - startTime;
|
|
41
52
|
|
|
42
53
|
if (routes.length > 0) {
|
|
@@ -65,13 +76,8 @@ async function discoverRoutes(pagesDir) {
|
|
|
65
76
|
} else if (entry.isFile()) {
|
|
66
77
|
const ext = extname(entry.name);
|
|
67
78
|
|
|
68
|
-
|
|
69
|
-
if (ext === '.css') {
|
|
70
|
-
logger.debug(`Skipping CSS file: ${relativePath}`);
|
|
71
|
-
continue;
|
|
72
|
-
}
|
|
79
|
+
if (ext === '.css') continue;
|
|
73
80
|
|
|
74
|
-
// Only process valid page files
|
|
75
81
|
if (['.jsx', '.tsx', '.js', '.ts'].includes(ext)) {
|
|
76
82
|
const fileName = entry.name.replace(ext, '');
|
|
77
83
|
|
|
@@ -244,7 +250,7 @@ ${routeConfigs}
|
|
|
244
250
|
await Bun.write(routerPath, routerComponentCode);
|
|
245
251
|
}
|
|
246
252
|
|
|
247
|
-
async function compileDirectory(srcDir, outDir, root) {
|
|
253
|
+
async function compileDirectory(srcDir, outDir, root, envVars) {
|
|
248
254
|
const stats = { files: 0, skipped: 0 };
|
|
249
255
|
|
|
250
256
|
const files = readdirSync(srcDir);
|
|
@@ -256,14 +262,13 @@ async function compileDirectory(srcDir, outDir, root) {
|
|
|
256
262
|
if (stat.isDirectory()) {
|
|
257
263
|
const subOutDir = join(outDir, file);
|
|
258
264
|
mkdirSync(subOutDir, { recursive: true });
|
|
259
|
-
const subStats = await compileDirectory(srcPath, subOutDir, root);
|
|
265
|
+
const subStats = await compileDirectory(srcPath, subOutDir, root, envVars);
|
|
260
266
|
stats.files += subStats.files;
|
|
261
267
|
stats.skipped += subStats.skipped;
|
|
262
268
|
} else {
|
|
263
269
|
const ext = extname(file);
|
|
264
270
|
const relativePath = relative(join(root, 'src'), srcPath);
|
|
265
271
|
|
|
266
|
-
// FIXED: Handle CSS files properly - copy to styles output
|
|
267
272
|
if (ext === '.css') {
|
|
268
273
|
const stylesOutDir = join(root, '.bertui', 'styles');
|
|
269
274
|
if (!existsSync(stylesOutDir)) {
|
|
@@ -274,14 +279,17 @@ async function compileDirectory(srcDir, outDir, root) {
|
|
|
274
279
|
logger.debug(`Copied CSS: ${relativePath}`);
|
|
275
280
|
stats.files++;
|
|
276
281
|
} else if (['.jsx', '.tsx', '.ts'].includes(ext)) {
|
|
277
|
-
await compileFile(srcPath, outDir, file, relativePath);
|
|
282
|
+
await compileFile(srcPath, outDir, file, relativePath, root, envVars);
|
|
278
283
|
stats.files++;
|
|
279
284
|
} else if (ext === '.js') {
|
|
280
285
|
const outPath = join(outDir, file);
|
|
281
286
|
let code = await Bun.file(srcPath).text();
|
|
282
287
|
|
|
283
|
-
//
|
|
284
|
-
|
|
288
|
+
// Remove ALL CSS imports
|
|
289
|
+
code = removeCSSImports(code);
|
|
290
|
+
// Inject environment variables
|
|
291
|
+
code = replaceEnvInCode(code, envVars);
|
|
292
|
+
// Fix router imports
|
|
285
293
|
code = fixRouterImports(code, outPath, root);
|
|
286
294
|
|
|
287
295
|
await Bun.write(outPath, code);
|
|
@@ -297,17 +305,24 @@ async function compileDirectory(srcDir, outDir, root) {
|
|
|
297
305
|
return stats;
|
|
298
306
|
}
|
|
299
307
|
|
|
300
|
-
async function compileFile(srcPath, outDir, filename, relativePath) {
|
|
308
|
+
async function compileFile(srcPath, outDir, filename, relativePath, root, envVars) {
|
|
301
309
|
const ext = extname(filename);
|
|
302
310
|
const loader = ext === '.tsx' ? 'tsx' : ext === '.ts' ? 'ts' : 'jsx';
|
|
303
311
|
|
|
304
312
|
try {
|
|
305
313
|
let code = await Bun.file(srcPath).text();
|
|
306
314
|
|
|
307
|
-
//
|
|
308
|
-
|
|
315
|
+
// CRITICAL FIX: Remove ALL CSS imports before transpilation
|
|
316
|
+
code = removeCSSImports(code);
|
|
317
|
+
|
|
318
|
+
// Remove dotenv imports (not needed in browser)
|
|
319
|
+
code = removeDotenvImports(code);
|
|
320
|
+
|
|
321
|
+
// Inject environment variables
|
|
322
|
+
code = replaceEnvInCode(code, envVars);
|
|
323
|
+
|
|
309
324
|
const outPath = join(outDir, filename.replace(/\.(jsx|tsx|ts)$/, '.js'));
|
|
310
|
-
code = fixRouterImports(code, outPath,
|
|
325
|
+
code = fixRouterImports(code, outPath, root);
|
|
311
326
|
|
|
312
327
|
const transpiler = new Bun.Transpiler({
|
|
313
328
|
loader,
|
|
@@ -335,24 +350,44 @@ async function compileFile(srcPath, outDir, filename, relativePath) {
|
|
|
335
350
|
}
|
|
336
351
|
}
|
|
337
352
|
|
|
338
|
-
//
|
|
353
|
+
// NEW FUNCTION: Remove all CSS imports
|
|
354
|
+
function removeCSSImports(code) {
|
|
355
|
+
// Remove CSS imports (with or without quotes, single or double)
|
|
356
|
+
// Matches: import './styles.css', import "./styles.css", import "styles.css", import 'styles.css'
|
|
357
|
+
code = code.replace(/import\s+['"][^'"]*\.css['"];?\s*/g, '');
|
|
358
|
+
|
|
359
|
+
// Also remove bertui/styles imports
|
|
360
|
+
code = code.replace(/import\s+['"]bertui\/styles['"]\s*;?\s*/g, '');
|
|
361
|
+
|
|
362
|
+
return code;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// NEW FUNCTION: Remove dotenv imports and dotenv.config() calls
|
|
366
|
+
function removeDotenvImports(code) {
|
|
367
|
+
// Remove: import dotenv from 'dotenv'
|
|
368
|
+
code = code.replace(/import\s+\w+\s+from\s+['"]dotenv['"]\s*;?\s*/g, '');
|
|
369
|
+
|
|
370
|
+
// Remove: import { config } from 'dotenv'
|
|
371
|
+
code = code.replace(/import\s+\{[^}]+\}\s+from\s+['"]dotenv['"]\s*;?\s*/g, '');
|
|
372
|
+
|
|
373
|
+
// Remove: dotenv.config()
|
|
374
|
+
code = code.replace(/\w+\.config\(\s*\)\s*;?\s*/g, '');
|
|
375
|
+
|
|
376
|
+
return code;
|
|
377
|
+
}
|
|
378
|
+
|
|
339
379
|
function fixRouterImports(code, outPath, root) {
|
|
340
380
|
const buildDir = join(root, '.bertui', 'compiled');
|
|
341
381
|
const routerPath = join(buildDir, 'router.js');
|
|
342
382
|
|
|
343
|
-
// Calculate relative path from output file to router.js
|
|
344
383
|
const relativeToRouter = relative(dirname(outPath), routerPath).replace(/\\/g, '/');
|
|
345
384
|
const routerImport = relativeToRouter.startsWith('.') ? relativeToRouter : './' + relativeToRouter;
|
|
346
385
|
|
|
347
|
-
// ONLY replace bertui/router imports
|
|
348
386
|
code = code.replace(
|
|
349
387
|
/from\s+['"]bertui\/router['"]/g,
|
|
350
388
|
`from '${routerImport}'`
|
|
351
389
|
);
|
|
352
390
|
|
|
353
|
-
// Remove bertui/styles imports (CSS handled separately)
|
|
354
|
-
code = code.replace(/import\s+['"]bertui\/styles['"]\s*;?\s*/g, '');
|
|
355
|
-
|
|
356
391
|
return code;
|
|
357
392
|
}
|
|
358
393
|
|
package/src/utils/env.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// bertui/src/utils/env.js
|
|
2
|
+
import { existsSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Load environment variables for BertUI
|
|
7
|
+
* This runs at BUILD TIME (Node.js), not in the browser
|
|
8
|
+
*/
|
|
9
|
+
export function loadEnvVariables(root) {
|
|
10
|
+
const envVars = {};
|
|
11
|
+
|
|
12
|
+
// Load from process.env (already loaded by Bun/Node)
|
|
13
|
+
for (const [key, value] of Object.entries(process.env)) {
|
|
14
|
+
// Only expose variables that start with VITE_ or PUBLIC_
|
|
15
|
+
if (key.startsWith('BERTUI_') || key.startsWith('PUBLIC_')) {
|
|
16
|
+
envVars[key] = value;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return envVars;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Generate code to inject env variables into the browser
|
|
25
|
+
*/
|
|
26
|
+
export function generateEnvCode(envVars) {
|
|
27
|
+
const envObject = Object.entries(envVars)
|
|
28
|
+
.map(([key, value]) => ` "${key}": ${JSON.stringify(value)}`)
|
|
29
|
+
.join(',\n');
|
|
30
|
+
|
|
31
|
+
return `
|
|
32
|
+
// Environment variables injected at build time
|
|
33
|
+
export const env = {
|
|
34
|
+
${envObject}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
Make it available globally (optional)
|
|
38
|
+
if (typeof window !== 'undefined') {
|
|
39
|
+
window.__BERTUI_ENV__ = env;
|
|
40
|
+
}
|
|
41
|
+
`;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Replace process.env references in code with actual values
|
|
46
|
+
*/
|
|
47
|
+
export function replaceEnvInCode(code, envVars) {
|
|
48
|
+
let result = code;
|
|
49
|
+
|
|
50
|
+
// Replace process.env.VARIABLE_NAME with actual values
|
|
51
|
+
for (const [key, value] of Object.entries(envVars)) {
|
|
52
|
+
const regex = new RegExp(`process\\.env\\.${key}`, 'g');
|
|
53
|
+
result = result.replace(regex, JSON.stringify(value));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return result;
|
|
57
|
+
}
|