bertui 1.1.0 β 1.1.1
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 +26 -6
- package/src/build/compiler/file-transpiler.js +171 -0
- package/src/build/compiler/index.js +45 -0
- package/src/build/compiler/route-discoverer.js +46 -0
- package/src/build/compiler/router-generator.js +104 -0
- package/src/build/generators/html-generator.js +259 -0
- package/src/build/generators/robots-generator.js +58 -0
- package/src/build/generators/sitemap-generator.js +63 -0
- package/src/build/processors/asset-processor.js +19 -0
- package/src/build/processors/css-builder.js +35 -0
- package/src/build.js +75 -697
- package/src/config/defaultConfig.js +26 -6
- package/src/config/loadConfig.js +21 -5
- package/src/utils/meta-extractor.js +61 -0
- package/types/config.d.ts +80 -0
- package/types/index.d.ts +116 -0
- package/types/react.d.ts +13 -0
- package/types/router.d.ts +79 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// bertui/src/build/robots-generator.js
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import logger from '../../logger/logger.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Generate robots.txt from sitemap data
|
|
7
|
+
* @param {Object} config - BertUI config with baseUrl
|
|
8
|
+
* @param {string} outDir - Output directory (dist/)
|
|
9
|
+
* @param {Array} routes - Optional: routes to disallow (e.g., admin pages)
|
|
10
|
+
*/
|
|
11
|
+
export async function generateRobots(config, outDir, routes = []) {
|
|
12
|
+
logger.info('π€ Generating robots.txt...');
|
|
13
|
+
|
|
14
|
+
// β
FIX: Check if baseUrl exists, then remove trailing slash
|
|
15
|
+
if (!config?.baseUrl) {
|
|
16
|
+
logger.error('β baseUrl is required in bertui.config.js for robots.txt generation!');
|
|
17
|
+
logger.error(' Add: baseUrl: "https://your-domain.com" to your config');
|
|
18
|
+
throw new Error('Missing baseUrl in config - robots.txt generation failed');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const baseUrl = config.baseUrl.replace(/\/$/, ''); // Remove trailing slash
|
|
22
|
+
const sitemapUrl = `${baseUrl}/sitemap.xml`;
|
|
23
|
+
|
|
24
|
+
logger.info(` Sitemap URL: ${sitemapUrl}`);
|
|
25
|
+
|
|
26
|
+
// Default robots.txt - Allow all
|
|
27
|
+
let robotsTxt = `# BertUI Generated robots.txt
|
|
28
|
+
User-agent: *
|
|
29
|
+
Allow: /
|
|
30
|
+
|
|
31
|
+
# Sitemap
|
|
32
|
+
Sitemap: ${sitemapUrl}
|
|
33
|
+
`;
|
|
34
|
+
|
|
35
|
+
// Add custom disallow rules if specified in config
|
|
36
|
+
if (config?.robots?.disallow && Array.isArray(config.robots.disallow) && config.robots.disallow.length > 0) {
|
|
37
|
+
robotsTxt += '\n# Custom Disallow Rules\n';
|
|
38
|
+
config.robots.disallow.forEach(path => {
|
|
39
|
+
robotsTxt += `Disallow: ${path}\n`;
|
|
40
|
+
});
|
|
41
|
+
logger.info(` Blocked ${config.robots.disallow.length} path(s)`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Add crawl delay if specified
|
|
45
|
+
if (config?.robots?.crawlDelay && typeof config.robots.crawlDelay === 'number') {
|
|
46
|
+
robotsTxt += `\nCrawl-delay: ${config.robots.crawlDelay}\n`;
|
|
47
|
+
logger.info(` Crawl delay: ${config.robots.crawlDelay}s`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Write to dist/robots.txt
|
|
51
|
+
const robotsPath = join(outDir, 'robots.txt');
|
|
52
|
+
await Bun.write(robotsPath, robotsTxt);
|
|
53
|
+
|
|
54
|
+
logger.success('β
robots.txt generated');
|
|
55
|
+
logger.info(` Location: ${robotsPath}`);
|
|
56
|
+
|
|
57
|
+
return { path: robotsPath, content: robotsTxt };
|
|
58
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// bertui/src/build/sitemap-generator.js - SIMPLIFIED
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import logger from '../../logger/logger';
|
|
4
|
+
|
|
5
|
+
function calculatePriority(route) {
|
|
6
|
+
if (route === '/') return 1.0;
|
|
7
|
+
if (route.includes(':')) return 0.6;
|
|
8
|
+
const depth = route.split('/').filter(Boolean).length;
|
|
9
|
+
if (depth === 1) return 0.8;
|
|
10
|
+
if (depth === 2) return 0.7;
|
|
11
|
+
return 0.6;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function generateSitemapXML(routes, baseUrl) {
|
|
15
|
+
const urls = routes.map(route => {
|
|
16
|
+
const url = `${baseUrl}${route.route}`;
|
|
17
|
+
return ` <url>
|
|
18
|
+
<loc>${url}</loc>
|
|
19
|
+
<lastmod>${route.lastmod}</lastmod>
|
|
20
|
+
<changefreq>weekly</changefreq>
|
|
21
|
+
<priority>${route.priority}</priority>
|
|
22
|
+
</url>`;
|
|
23
|
+
}).join('\n');
|
|
24
|
+
|
|
25
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
26
|
+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
27
|
+
${urls}
|
|
28
|
+
</urlset>`;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export async function generateSitemap(routes, config, outDir) {
|
|
32
|
+
logger.info('πΊοΈ Generating sitemap.xml...');
|
|
33
|
+
|
|
34
|
+
if (!config?.baseUrl) {
|
|
35
|
+
logger.error('β baseUrl is required in bertui.config.js for sitemap generation!');
|
|
36
|
+
logger.error(' Add: baseUrl: "https://your-domain.com" to your config');
|
|
37
|
+
throw new Error('Missing baseUrl in config - sitemap generation failed');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const baseUrl = config.baseUrl.replace(/\/$/, '');
|
|
41
|
+
const currentDate = new Date().toISOString().split('T')[0];
|
|
42
|
+
|
|
43
|
+
logger.info(` Base URL: ${baseUrl}`);
|
|
44
|
+
|
|
45
|
+
const staticRoutes = routes.filter(r => r.type === 'static');
|
|
46
|
+
logger.info(` ${staticRoutes.length} static routes will be included in sitemap`);
|
|
47
|
+
|
|
48
|
+
// SIMPLE: No file reading, just route processing
|
|
49
|
+
const sitemapRoutes = staticRoutes.map(route => ({
|
|
50
|
+
route: route.route,
|
|
51
|
+
lastmod: currentDate,
|
|
52
|
+
priority: calculatePriority(route.route)
|
|
53
|
+
}));
|
|
54
|
+
|
|
55
|
+
const xml = generateSitemapXML(sitemapRoutes, baseUrl);
|
|
56
|
+
const sitemapPath = join(outDir, 'sitemap.xml');
|
|
57
|
+
await Bun.write(sitemapPath, xml);
|
|
58
|
+
|
|
59
|
+
logger.success(`β
Sitemap generated: ${sitemapRoutes.length} URLs`);
|
|
60
|
+
logger.info(` Location: ${sitemapPath}`);
|
|
61
|
+
|
|
62
|
+
return { routes: sitemapRoutes, path: sitemapPath };
|
|
63
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// bertui/src/build/processors/asset-processor.js
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { existsSync, mkdirSync } from 'fs'; // β
ADD THIS IMPORT
|
|
4
|
+
import { copyImages } from '../image-optimizer.js';
|
|
5
|
+
|
|
6
|
+
export async function copyAllStaticAssets(root, outDir) {
|
|
7
|
+
const publicDir = join(root, 'public');
|
|
8
|
+
const srcImagesDir = join(root, 'src', 'images');
|
|
9
|
+
|
|
10
|
+
if (existsSync(publicDir)) {
|
|
11
|
+
copyImages(publicDir, outDir);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (existsSync(srcImagesDir)) {
|
|
15
|
+
const distImagesDir = join(outDir, 'images');
|
|
16
|
+
mkdirSync(distImagesDir, { recursive: true });
|
|
17
|
+
copyImages(srcImagesDir, distImagesDir);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// bertui/src/build/processors/css-builder.js
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { existsSync, readdirSync, mkdirSync } from 'fs';
|
|
4
|
+
import logger from '../../logger/logger.js';
|
|
5
|
+
import { buildCSS } from '../css-builder.js';
|
|
6
|
+
|
|
7
|
+
export async function buildAllCSS(root, outDir) {
|
|
8
|
+
const srcStylesDir = join(root, 'src', 'styles');
|
|
9
|
+
const stylesOutDir = join(outDir, 'styles');
|
|
10
|
+
|
|
11
|
+
mkdirSync(stylesOutDir, { recursive: true });
|
|
12
|
+
|
|
13
|
+
if (existsSync(srcStylesDir)) {
|
|
14
|
+
const cssFiles = readdirSync(srcStylesDir).filter(f => f.endsWith('.css'));
|
|
15
|
+
|
|
16
|
+
if (cssFiles.length === 0) {
|
|
17
|
+
await Bun.write(join(stylesOutDir, 'bertui.min.css'), '/* No CSS */');
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
let combinedCSS = '';
|
|
22
|
+
for (const cssFile of cssFiles) {
|
|
23
|
+
const srcPath = join(srcStylesDir, cssFile);
|
|
24
|
+
const file = Bun.file(srcPath);
|
|
25
|
+
const cssContent = await file.text();
|
|
26
|
+
combinedCSS += `/* ${cssFile} */\n${cssContent}\n\n`;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const combinedPath = join(stylesOutDir, 'bertui.min.css');
|
|
30
|
+
await Bun.write(combinedPath, combinedCSS);
|
|
31
|
+
await buildCSS(combinedPath, combinedPath);
|
|
32
|
+
|
|
33
|
+
logger.success(`β
Combined ${cssFiles.length} CSS files`);
|
|
34
|
+
}
|
|
35
|
+
}
|