bertui 0.3.7 → 0.3.9

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.
Files changed (3) hide show
  1. package/index.js +1 -1
  2. package/package.json +1 -1
  3. package/src/build.js +37 -25
package/index.js CHANGED
@@ -32,5 +32,5 @@ export default {
32
32
  buildCSS,
33
33
  copyCSS,
34
34
  program,
35
- version: "0.2.5"
35
+ version: "0.3.9"
36
36
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bertui",
3
- "version": "0.3.7",
3
+ "version": "0.3.9",
4
4
  "description": "Lightning-fast React dev server powered by Bun and Elysia",
5
5
  "type": "module",
6
6
  "main": "./index.js",
package/src/build.js CHANGED
@@ -3,6 +3,7 @@ import { existsSync, mkdirSync, rmSync, cpSync, readdirSync, statSync } from 'fs
3
3
  import { extname, dirname } from 'path';
4
4
  import logger from './logger/logger.js';
5
5
  import { buildCSS } from './build/css-builder.js';
6
+ import { loadEnvVariables, replaceEnvInCode } from './utils/env.js'; // ✅ IMPORT THIS!
6
7
 
7
8
  export async function buildProduction(options = {}) {
8
9
  const root = options.root || process.cwd();
@@ -25,8 +26,15 @@ export async function buildProduction(options = {}) {
25
26
  const startTime = Date.now();
26
27
 
27
28
  try {
29
+ // ✅ LOAD ENV VARS BEFORE COMPILATION!
30
+ logger.info('Step 0: Loading environment variables...');
31
+ const envVars = loadEnvVariables(root);
32
+ if (Object.keys(envVars).length > 0) {
33
+ logger.info(`Loaded ${Object.keys(envVars).length} environment variables`);
34
+ }
35
+
28
36
  logger.info('Step 1: Compiling for production...');
29
- const { routes } = await compileForBuild(root, buildDir);
37
+ const { routes } = await compileForBuild(root, buildDir, envVars); // ✅ PASS ENV VARS!
30
38
  logger.success('Production compilation complete');
31
39
 
32
40
  logger.info('Step 2: Building CSS with Lightning CSS...');
@@ -68,7 +76,21 @@ export async function buildProduction(options = {}) {
68
76
  chunk: 'chunks/[name]-[hash].js',
69
77
  asset: '[name]-[hash].[ext]'
70
78
  },
71
- external: ['react', 'react-dom', 'react-dom/client', 'react/jsx-runtime']
79
+ external: ['react', 'react-dom', 'react-dom/client', 'react/jsx-runtime'],
80
+ // ✅ CRITICAL: Add define to replace process.env at bundle time!
81
+ define: {
82
+ 'process.env.NODE_ENV': '"production"',
83
+ 'process.env.PUBLIC_APP_NAME': JSON.stringify(envVars.PUBLIC_APP_NAME || 'BertUI App'),
84
+ 'process.env.PUBLIC_API_URL': JSON.stringify(envVars.PUBLIC_API_URL || ''),
85
+ 'process.env.PUBLIC_USERNAME': JSON.stringify(envVars.PUBLIC_USERNAME || ''),
86
+ // Add all other env vars dynamically
87
+ ...Object.fromEntries(
88
+ Object.entries(envVars).map(([key, value]) => [
89
+ `process.env.${key}`,
90
+ JSON.stringify(value)
91
+ ])
92
+ )
93
+ }
72
94
  });
73
95
 
74
96
  if (!result.success) {
@@ -131,7 +153,8 @@ async function buildAllCSS(root, outDir) {
131
153
  }
132
154
  }
133
155
 
134
- async function compileForBuild(root, buildDir) {
156
+ // ACCEPT ENV VARS PARAMETER
157
+ async function compileForBuild(root, buildDir, envVars) {
135
158
  const srcDir = join(root, 'src');
136
159
  const pagesDir = join(srcDir, 'pages');
137
160
 
@@ -145,7 +168,8 @@ async function compileForBuild(root, buildDir) {
145
168
  logger.info(`Found ${routes.length} routes`);
146
169
  }
147
170
 
148
- await compileBuildDirectory(srcDir, buildDir, root);
171
+ // PASS ENV VARS TO COMPILATION
172
+ await compileBuildDirectory(srcDir, buildDir, root, envVars);
149
173
 
150
174
  if (routes.length > 0) {
151
175
  await generateBuildRouter(routes, buildDir);
@@ -343,7 +367,8 @@ ${routeConfigs}
343
367
  await Bun.write(join(buildDir, 'router.js'), routerCode);
344
368
  }
345
369
 
346
- async function compileBuildDirectory(srcDir, buildDir, root) {
370
+ // ACCEPT ENV VARS PARAMETER
371
+ async function compileBuildDirectory(srcDir, buildDir, root, envVars) {
347
372
  const files = readdirSync(srcDir);
348
373
 
349
374
  for (const file of files) {
@@ -353,19 +378,20 @@ async function compileBuildDirectory(srcDir, buildDir, root) {
353
378
  if (stat.isDirectory()) {
354
379
  const subBuildDir = join(buildDir, file);
355
380
  mkdirSync(subBuildDir, { recursive: true });
356
- await compileBuildDirectory(srcPath, subBuildDir, root);
381
+ await compileBuildDirectory(srcPath, subBuildDir, root, envVars); // ✅ PASS IT DOWN
357
382
  } else {
358
383
  const ext = extname(file);
359
384
 
360
385
  if (ext === '.css') continue;
361
386
 
362
387
  if (['.jsx', '.tsx', '.ts'].includes(ext)) {
363
- await compileBuildFile(srcPath, buildDir, file, root);
388
+ await compileBuildFile(srcPath, buildDir, file, root, envVars); // ✅ PASS IT HERE
364
389
  } else if (ext === '.js') {
365
390
  const outPath = join(buildDir, file);
366
391
  let code = await Bun.file(srcPath).text();
367
392
 
368
393
  code = removeCSSImports(code);
394
+ code = replaceEnvInCode(code, envVars); // ✅ REPLACE ENV VARS!
369
395
  code = fixBuildImports(code, srcPath, outPath, root);
370
396
 
371
397
  await Bun.write(outPath, code);
@@ -374,7 +400,8 @@ async function compileBuildDirectory(srcDir, buildDir, root) {
374
400
  }
375
401
  }
376
402
 
377
- async function compileBuildFile(srcPath, buildDir, filename, root) {
403
+ // ACCEPT ENV VARS PARAMETER
404
+ async function compileBuildFile(srcPath, buildDir, filename, root, envVars) {
378
405
  const ext = extname(filename);
379
406
  const loader = ext === '.tsx' ? 'tsx' : ext === '.ts' ? 'ts' : 'jsx';
380
407
 
@@ -382,6 +409,7 @@ async function compileBuildFile(srcPath, buildDir, filename, root) {
382
409
  let code = await Bun.file(srcPath).text();
383
410
 
384
411
  code = removeCSSImports(code);
412
+ code = replaceEnvInCode(code, envVars); // ✅ REPLACE ENV VARS BEFORE TRANSPILATION!
385
413
 
386
414
  const outFilename = filename.replace(/\.(jsx|tsx|ts)$/, '.js');
387
415
  const outPath = join(buildDir, outFilename);
@@ -448,18 +476,15 @@ function fixRelativeImports(code) {
448
476
  return code;
449
477
  }
450
478
 
451
- // ✅ FIXED: Better meta extraction that handles multi-line objects
452
479
  function extractMetaFromSource(code) {
453
480
  try {
454
- // Match export const meta = { ... } with proper brace counting
455
481
  const metaMatch = code.match(/export\s+const\s+meta\s*=\s*\{/);
456
482
  if (!metaMatch) return null;
457
483
 
458
- const startIndex = metaMatch.index + metaMatch[0].length - 1; // Start at opening brace
484
+ const startIndex = metaMatch.index + metaMatch[0].length - 1;
459
485
  let braceCount = 0;
460
486
  let endIndex = startIndex;
461
487
 
462
- // Count braces to find the closing brace
463
488
  for (let i = startIndex; i < code.length; i++) {
464
489
  if (code[i] === '{') braceCount++;
465
490
  if (code[i] === '}') {
@@ -474,11 +499,7 @@ function extractMetaFromSource(code) {
474
499
  if (endIndex === startIndex) return null;
475
500
 
476
501
  const metaString = code.substring(startIndex, endIndex + 1);
477
-
478
- // Parse the meta object safely
479
502
  const meta = {};
480
-
481
- // Extract key-value pairs (handles strings with quotes)
482
503
  const pairRegex = /(\w+)\s*:\s*(['"`])((?:(?!\2).)*)\2/g;
483
504
  let match;
484
505
 
@@ -495,7 +516,6 @@ function extractMetaFromSource(code) {
495
516
  }
496
517
  }
497
518
 
498
- // ✅ FIXED: Correct bundle path and proper hydration
499
519
  async function generateProductionHTML(root, outDir, buildResult, routes) {
500
520
  const mainBundle = buildResult.outputs.find(o =>
501
521
  o.path.includes('main') && o.kind === 'entry-point'
@@ -505,9 +525,7 @@ async function generateProductionHTML(root, outDir, buildResult, routes) {
505
525
  throw new Error('Could not find main bundle in build output');
506
526
  }
507
527
 
508
- // ✅ FIX 1: Get ONLY the relative path from dist/
509
528
  const bundlePath = relative(outDir, mainBundle.path).replace(/\\/g, '/');
510
-
511
529
  logger.info(`Main bundle path: ${bundlePath}`);
512
530
 
513
531
  const srcStylesDir = join(root, 'src', 'styles');
@@ -520,7 +538,6 @@ async function generateProductionHTML(root, outDir, buildResult, routes) {
520
538
  ).join('\n');
521
539
  }
522
540
 
523
- // Load config for default meta
524
541
  const { loadConfig } = await import('./config/loadConfig.js');
525
542
  const config = await loadConfig(root);
526
543
  const defaultMeta = config.meta || {};
@@ -533,18 +550,14 @@ async function generateProductionHTML(root, outDir, buildResult, routes) {
533
550
  continue;
534
551
  }
535
552
 
536
- // Read source file and extract meta
537
553
  const sourceCode = await Bun.file(route.path).text();
538
554
  const pageMeta = extractMetaFromSource(sourceCode);
539
-
540
- // Merge page meta with default meta
541
555
  const meta = { ...defaultMeta, ...pageMeta };
542
556
 
543
557
  if (pageMeta) {
544
558
  logger.info(`Extracted meta for ${route.route}: ${JSON.stringify(pageMeta)}`);
545
559
  }
546
560
 
547
- // ✅ FIX 2: Generate proper HTML with correct script path
548
561
  const html = `<!DOCTYPE html>
549
562
  <html lang="${meta.lang || 'en'}">
550
563
  <head>
@@ -590,7 +603,6 @@ ${userStylesheets}
590
603
  </body>
591
604
  </html>`;
592
605
 
593
- // Determine output path
594
606
  let htmlPath;
595
607
  if (route.route === '/') {
596
608
  htmlPath = join(outDir, 'index.html');