bertui 1.1.5 → 1.1.6

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bertui",
3
- "version": "1.1.5",
3
+ "version": "1.1.6",
4
4
  "description": "Lightning-fast React dev server powered by Bun and Elysia - Now with TypeScript support!",
5
5
  "type": "module",
6
6
  "main": "./index.js",
package/src/build.js CHANGED
@@ -1,9 +1,8 @@
1
- // bertui/src/build.js - FORCE PRODUCTION MODE
1
+ // bertui/src/build.js - CLEANED (No PageBuilder)
2
2
  import { join } from 'path';
3
- import { existsSync, mkdirSync, rmSync, writeFileSync } from 'fs';
3
+ import { existsSync, mkdirSync, rmSync } from 'fs';
4
4
  import logger from './logger/logger.js';
5
5
  import { loadEnvVariables } from './utils/env.js';
6
- import { runPageBuilder } from './pagebuilder/core.js';
7
6
 
8
7
  import { compileForBuild } from './build/compiler/index.js';
9
8
  import { buildAllCSS } from './build/processors/css-builder.js';
@@ -37,11 +36,6 @@ export async function buildProduction(options = {}) {
37
36
  const { loadConfig } = await import('./config/loadConfig.js');
38
37
  const config = await loadConfig(root);
39
38
 
40
- if (config.pageBuilder) {
41
- logger.info('Step 0.5: Running Page Builder...');
42
- await runPageBuilder(root, config);
43
- }
44
-
45
39
  logger.info('Step 1: Compiling and detecting Server Islands...');
46
40
  const { routes, serverIslands, clientRoutes } = await compileForBuild(root, buildDir, envVars);
47
41
 
@@ -94,7 +88,6 @@ export async function buildProduction(options = {}) {
94
88
 
95
89
  async function bundleJavaScript(buildEntry, outDir, envVars, buildDir) {
96
90
  try {
97
- // Change to build directory where bunfig.toml is
98
91
  const originalCwd = process.cwd();
99
92
  process.chdir(buildDir);
100
93
 
@@ -172,4 +165,4 @@ function showBuildSummary(routes, serverIslands, clientRoutes, duration) {
172
165
  }
173
166
 
174
167
  logger.bigLog('READY TO DEPLOY 🚀', { color: 'green' });
175
- }
168
+ }
@@ -1,4 +1,7 @@
1
- // bertui/src/client/compiler.js - FIXED: jsxDEV error
1
+ // ============================================
2
+ // FILE: bertui/src/client/compiler.js (UPDATED - Skip templates/)
3
+ // ============================================
4
+
2
5
  import { existsSync, mkdirSync, readdirSync, statSync } from 'fs';
3
6
  import { join, extname, relative, dirname } from 'path';
4
7
  import logger from '../logger/logger.js';
@@ -127,9 +130,7 @@ const RouterContext = createContext(null);
127
130
 
128
131
  export function useRouter() {
129
132
  const context = useContext(RouterContext);
130
- if (!context) {
131
- throw new Error('useRouter must be used within a Router component');
132
- }
133
+ if (!context) throw new Error('useRouter must be used within a Router');
133
134
  return context;
134
135
  }
135
136
 
@@ -194,24 +195,13 @@ export function Link({ to, children, ...props }) {
194
195
  }
195
196
 
196
197
  function NotFound() {
197
- return React.createElement(
198
- 'div',
199
- {
200
- style: {
201
- display: 'flex',
202
- flexDirection: 'column',
203
- alignItems: 'center',
204
- justifyContent: 'center',
205
- minHeight: '100vh',
206
- fontFamily: 'system-ui'
207
- }
208
- },
198
+ return React.createElement('div', {
199
+ style: { display: 'flex', flexDirection: 'column', alignItems: 'center',
200
+ justifyContent: 'center', minHeight: '100vh', fontFamily: 'system-ui' }
201
+ },
209
202
  React.createElement('h1', { style: { fontSize: '6rem', margin: 0 } }, '404'),
210
203
  React.createElement('p', { style: { fontSize: '1.5rem', color: '#666' } }, 'Page not found'),
211
- React.createElement('a', {
212
- href: '/',
213
- style: { color: '#10b981', textDecoration: 'none', fontSize: '1.2rem' }
214
- }, 'Go home')
204
+ React.createElement('a', { href: '/', style: { color: '#10b981', textDecoration: 'none' } }, 'Go home')
215
205
  );
216
206
  }
217
207
 
@@ -219,11 +209,9 @@ ${imports}
219
209
 
220
210
  export const routes = [
221
211
  ${routeConfigs}
222
- ];
223
- `;
212
+ ];`;
224
213
 
225
- const routerPath = join(outDir, 'router.js');
226
- await Bun.write(routerPath, routerComponentCode);
214
+ await Bun.write(join(outDir, 'router.js'), routerComponentCode);
227
215
  }
228
216
 
229
217
  async function compileDirectory(srcDir, outDir, root, envVars) {
@@ -235,6 +223,12 @@ async function compileDirectory(srcDir, outDir, root, envVars) {
235
223
  const stat = statSync(srcPath);
236
224
 
237
225
  if (stat.isDirectory()) {
226
+ // ✅ NEW: Skip templates directory
227
+ if (file === 'templates') {
228
+ logger.debug('⏭️ Skipping src/templates/ (PageBuilder templates only)');
229
+ continue;
230
+ }
231
+
238
232
  const subOutDir = join(outDir, file);
239
233
  mkdirSync(subOutDir, { recursive: true });
240
234
  const subStats = await compileDirectory(srcPath, subOutDir, root, envVars);
@@ -295,12 +289,11 @@ async function compileFile(srcPath, outDir, filename, relativePath, root, envVar
295
289
  const outPath = join(outDir, filename.replace(/\.(jsx|tsx|ts)$/, '.js'));
296
290
  code = fixRouterImports(code, outPath, root);
297
291
 
298
- // ✅ CRITICAL FIX: Force React.createElement instead of jsxDEV
299
292
  const transpiler = new Bun.Transpiler({
300
293
  loader,
301
294
  tsconfig: {
302
295
  compilerOptions: {
303
- jsx: 'react', // ✅ Use 'react' instead of 'react-jsx'
296
+ jsx: 'react',
304
297
  jsxFactory: 'React.createElement',
305
298
  jsxFragmentFactory: 'React.Fragment'
306
299
  }
@@ -369,4 +362,4 @@ function fixRelativeImports(code) {
369
362
  });
370
363
 
371
364
  return code;
372
- }
365
+ }
@@ -1,12 +1,8 @@
1
- // bertui/src/config/defaultConfig.js
2
- // Default configuration used when bertui.config.js is not present
3
-
1
+ // bertui/src/config/defaultConfig.js - CLEANED
4
2
  export const defaultConfig = {
5
- // Site information (used for sitemap generation)
6
3
  siteName: "BertUI App",
7
- baseUrl: "http://localhost:3000", // Default to localhost
4
+ baseUrl: "http://localhost:3000",
8
5
 
9
- // HTML Meta Tags (SEO)
10
6
  meta: {
11
7
  title: "BertUI - Lightning Fast React",
12
8
  description: "Build lightning-fast React applications with file-based routing powered by Bun",
@@ -14,23 +10,19 @@ export const defaultConfig = {
14
10
  author: "Pease Ernest",
15
11
  themeColor: "#667eea",
16
12
  lang: "en",
17
-
18
- // Open Graph for social sharing
19
13
  ogTitle: "BertUI - Lightning Fast React Framework",
20
14
  ogDescription: "Build lightning-fast React apps with zero config",
21
15
  ogImage: "/og-image.png"
22
16
  },
23
17
 
24
- // App Shell Configuration
25
18
  appShell: {
26
19
  loading: true,
27
20
  loadingText: "Loading...",
28
21
  backgroundColor: "#ffffff"
29
22
  },
30
23
 
31
- // robots.txt Configuration
32
24
  robots: {
33
- disallow: [], // No paths blocked by default
34
- crawlDelay: null // No crawl delay by default
25
+ disallow: [],
26
+ crawlDelay: null
35
27
  }
36
28
  };
package/src/dev.js CHANGED
@@ -1,13 +1,16 @@
1
- // src/dev.js
1
+ // bertui/src/dev.js - CLEANED (No PageBuilder)
2
2
  import { compileProject } from './client/compiler.js';
3
3
  import { startDevServer } from './server/dev-server.js';
4
4
  import logger from './logger/logger.js';
5
+ import { loadConfig } from './config/loadConfig.js';
5
6
 
6
7
  export async function startDev(options = {}) {
7
8
  const root = options.root || process.cwd();
8
9
  const port = options.port || 3000;
9
10
 
10
11
  try {
12
+ const config = await loadConfig(root);
13
+
11
14
  // Step 1: Compile project
12
15
  logger.info('Step 1: Compiling project...');
13
16
  await compileProject(root);
package/types/config.d.ts CHANGED
@@ -1,80 +1,33 @@
1
- // bertui/types/config.d.ts
1
+ // bertui/types/config.d.ts - CLEANED
2
2
  declare module 'bertui/config' {
3
- /**
4
- * BertUI Configuration
5
- */
6
3
  export interface BertuiConfig {
7
- /** Site name for SEO */
8
4
  siteName?: string;
9
-
10
- /** Base URL for sitemap generation (e.g., "https://example.com") */
11
5
  baseUrl?: string;
12
6
 
13
- /** HTML meta tags configuration */
14
7
  meta?: {
15
- /** Page title */
16
8
  title?: string;
17
- /** Meta description */
18
9
  description?: string;
19
- /** Meta keywords */
20
10
  keywords?: string;
21
- /** Author name */
22
11
  author?: string;
23
- /** Open Graph image URL */
24
12
  ogImage?: string;
25
- /** Open Graph title */
26
13
  ogTitle?: string;
27
- /** Open Graph description */
28
14
  ogDescription?: string;
29
- /** Theme color */
30
15
  themeColor?: string;
31
- /** Language code (e.g., "en") */
32
16
  lang?: string;
33
17
  };
34
18
 
35
- /** App shell configuration */
36
19
  appShell?: {
37
- /** Show loading indicator */
38
20
  loading?: boolean;
39
- /** Loading text */
40
21
  loadingText?: string;
41
- /** Background color */
42
22
  backgroundColor?: string;
43
23
  };
44
24
 
45
- /** robots.txt configuration */
46
25
  robots?: {
47
- /** Paths to disallow in robots.txt */
48
26
  disallow?: string[];
49
- /** Crawl delay in seconds */
50
27
  crawlDelay?: number;
51
28
  };
52
29
  }
53
30
 
54
- /**
55
- * Page meta configuration (exported from page files)
56
- */
57
- export interface PageMeta {
58
- title?: string;
59
- description?: string;
60
- keywords?: string;
61
- author?: string;
62
- ogTitle?: string;
63
- ogDescription?: string;
64
- ogImage?: string;
65
- themeColor?: string;
66
- lang?: string;
67
- publishedDate?: string;
68
- updatedDate?: string;
69
- }
70
-
71
- /**
72
- * Default BertUI configuration
73
- */
74
31
  export const defaultConfig: BertuiConfig;
75
-
76
- /**
77
- * Load BertUI configuration from bertui.config.js
78
- */
79
32
  export function loadConfig(root: string): Promise<BertuiConfig>;
80
33
  }
@@ -1,191 +0,0 @@
1
- // bertui/src/pagebuilder/core.js
2
- import { join } from 'path';
3
- import { existsSync, mkdirSync } from 'fs';
4
- import logger from '../logger/logger.js';
5
-
6
- /**
7
- * Run page builder to generate pages from config
8
- * @param {string} root - Project root directory
9
- * @param {Object} config - BertUI configuration
10
- */
11
- export async function runPageBuilder(root, config) {
12
- const pagesDir = join(root, 'src', 'pages');
13
-
14
- if (!config.pageBuilder || typeof config.pageBuilder !== 'object') {
15
- logger.debug('No page builder configuration found');
16
- return;
17
- }
18
-
19
- const { pages } = config.pageBuilder;
20
-
21
- if (!pages || !Array.isArray(pages) || pages.length === 0) {
22
- logger.debug('No pages defined in page builder');
23
- return;
24
- }
25
-
26
- logger.info(`📄 Page Builder: Generating ${pages.length} page(s)...`);
27
-
28
- // Ensure pages directory exists
29
- const generatedDir = join(pagesDir, 'generated');
30
- if (!existsSync(generatedDir)) {
31
- mkdirSync(generatedDir, { recursive: true });
32
- }
33
-
34
- for (const page of pages) {
35
- try {
36
- await generatePage(page, generatedDir);
37
- logger.success(`✅ Generated: ${page.name}`);
38
- } catch (error) {
39
- logger.error(`❌ Failed to generate ${page.name}: ${error.message}`);
40
- }
41
- }
42
- }
43
-
44
- /**
45
- * Generate a single page from configuration
46
- * @param {Object} pageConfig - Page configuration
47
- * @param {string} outputDir - Output directory
48
- */
49
- async function generatePage(pageConfig, outputDir) {
50
- const { name, type, data } = pageConfig;
51
-
52
- if (!name) {
53
- throw new Error('Page name is required');
54
- }
55
-
56
- let pageContent = '';
57
-
58
- switch (type) {
59
- case 'markdown':
60
- pageContent = generateMarkdownPage(name, data);
61
- break;
62
-
63
- case 'json':
64
- pageContent = generateJsonPage(name, data);
65
- break;
66
-
67
- case 'custom':
68
- pageContent = data.template || generateDefaultPage(name, data);
69
- break;
70
-
71
- default:
72
- pageContent = generateDefaultPage(name, data);
73
- }
74
-
75
- // Write the generated page
76
- const filename = name.toLowerCase().replace(/\s+/g, '-') + '.jsx';
77
- const filepath = join(outputDir, filename);
78
-
79
- await Bun.write(filepath, pageContent);
80
- }
81
-
82
- /**
83
- * Generate a default React page
84
- */
85
- function generateDefaultPage(name, data) {
86
- const title = data?.title || name;
87
- const content = data?.content || `<p>Welcome to ${name}</p>`;
88
-
89
- return `// Auto-generated page: ${name}
90
- import React from 'react';
91
-
92
- export const title = "${title}";
93
- export const description = "${data?.description || `${name} page`}";
94
-
95
- export default function ${sanitizeComponentName(name)}() {
96
- return (
97
- <div>
98
- <h1>${title}</h1>
99
- ${content}
100
- </div>
101
- );
102
- }
103
- `;
104
- }
105
-
106
- /**
107
- * Generate a page from Markdown data
108
- */
109
- function generateMarkdownPage(name, data) {
110
- const title = data?.title || name;
111
- const markdown = data?.markdown || '';
112
-
113
- // Simple markdown to JSX conversion
114
- const jsxContent = convertMarkdownToJSX(markdown);
115
-
116
- return `// Auto-generated markdown page: ${name}
117
- import React from 'react';
118
-
119
- export const title = "${title}";
120
- export const description = "${data?.description || `${name} page`}";
121
-
122
- export default function ${sanitizeComponentName(name)}() {
123
- return (
124
- <div className="markdown-content">
125
- ${jsxContent}
126
- </div>
127
- );
128
- }
129
- `;
130
- }
131
-
132
- /**
133
- * Generate a page from JSON data
134
- */
135
- function generateJsonPage(name, data) {
136
- const title = data?.title || name;
137
- const items = data?.items || [];
138
-
139
- return `// Auto-generated JSON page: ${name}
140
- import React from 'react';
141
-
142
- export const title = "${title}";
143
- export const description = "${data?.description || `${name} page`}";
144
-
145
- const items = ${JSON.stringify(items, null, 2)};
146
-
147
- export default function ${sanitizeComponentName(name)}() {
148
- return (
149
- <div>
150
- <h1>${title}</h1>
151
- <ul>
152
- {items.map((item, index) => (
153
- <li key={index}>{item.title || item.name || item}</li>
154
- ))}
155
- </ul>
156
- </div>
157
- );
158
- }
159
- `;
160
- }
161
-
162
- /**
163
- * Convert markdown to JSX (basic implementation)
164
- */
165
- function convertMarkdownToJSX(markdown) {
166
- let jsx = markdown
167
- // Headers
168
- .replace(/^### (.*$)/gm, '<h3>$1</h3>')
169
- .replace(/^## (.*$)/gm, '<h2>$1</h2>')
170
- .replace(/^# (.*$)/gm, '<h1>$1</h1>')
171
- // Bold
172
- .replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
173
- // Italic
174
- .replace(/\*(.+?)\*/g, '<em>$1</em>')
175
- // Paragraphs
176
- .split('\n\n')
177
- .map(para => para.trim() ? `<p>${para}</p>` : '')
178
- .join('\n ');
179
-
180
- return jsx;
181
- }
182
-
183
- /**
184
- * Sanitize component name (must be valid React component name)
185
- */
186
- function sanitizeComponentName(name) {
187
- return name
188
- .replace(/[^a-zA-Z0-9]/g, '')
189
- .replace(/^[0-9]/, 'Page$&')
190
- .replace(/^./, c => c.toUpperCase());
191
- }