meno-core 1.0.7 → 1.0.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/build-static.ts CHANGED
@@ -150,6 +150,37 @@ function getDisplayPath(
150
150
  return slug === "" ? `/${locale}` : `/${locale}/${slug}`;
151
151
  }
152
152
 
153
+ /**
154
+ * Generate robots.txt with sensible defaults
155
+ */
156
+ async function generateRobotsTxt(siteUrl: string, distDir: string): Promise<void> {
157
+ const content = `User-agent: *
158
+ Allow: /
159
+
160
+ Sitemap: ${siteUrl}/sitemap.xml
161
+ `;
162
+ await writeFile(join(distDir, 'robots.txt'), content, 'utf-8');
163
+ }
164
+
165
+ /**
166
+ * Generate sitemap.xml from collected URLs
167
+ */
168
+ async function generateSitemap(urls: string[], siteUrl: string, distDir: string): Promise<void> {
169
+ // Sort URLs for deterministic output
170
+ const sortedUrls = [...urls].sort();
171
+
172
+ const urlEntries = sortedUrls
173
+ .map(url => ` <url><loc>${siteUrl}${url}</loc></url>`)
174
+ .join('\n');
175
+
176
+ const content = `<?xml version="1.0" encoding="UTF-8"?>
177
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
178
+ ${urlEntries}
179
+ </urlset>
180
+ `;
181
+ await writeFile(join(distDir, 'sitemap.xml'), content, 'utf-8');
182
+ }
183
+
153
184
  /**
154
185
  * Clean dist directory, keeping only production files
155
186
  */
@@ -232,7 +263,8 @@ async function buildCMSTemplates(
232
263
  i18nConfig: I18nConfig,
233
264
  slugMappings: SlugMap[],
234
265
  distDir: string,
235
- cmsService: CMSService
266
+ cmsService: CMSService,
267
+ generatedUrls: Set<string>
236
268
  ): Promise<{ success: number; errors: number }> {
237
269
  let successCount = 0;
238
270
  let errorCount = 0;
@@ -313,6 +345,7 @@ async function buildCMSTemplates(
313
345
  await writeFile(outputPath, finalHtml, 'utf-8');
314
346
 
315
347
  const displayPath = locale === i18nConfig.defaultLocale ? itemPath : `/${locale}${itemPath}`;
348
+ generatedUrls.add(displayPath);
316
349
  console.log(` āœ… ${displayPath}`);
317
350
  successCount++;
318
351
  }
@@ -333,7 +366,11 @@ async function buildStaticPages(): Promise<void> {
333
366
  console.log("šŸ—ļø Building static HTML files...\n");
334
367
 
335
368
  // Load project config first
336
- await loadProjectConfig();
369
+ const projectConfig = await loadProjectConfig();
370
+ const siteUrl = (projectConfig as { siteUrl?: string }).siteUrl?.replace(/\/$/, ''); // Remove trailing slash
371
+
372
+ // Track all generated URLs for sitemap
373
+ const generatedUrls = new Set<string>();
337
374
 
338
375
  // Load i18n config for multi-locale build
339
376
  const i18nConfig = await loadI18nConfig();
@@ -483,6 +520,7 @@ async function buildStaticPages(): Promise<void> {
483
520
 
484
521
  await writeFile(outputPath, finalHtml, "utf-8");
485
522
 
523
+ generatedUrls.add(urlPath);
486
524
  console.log(`āœ… Built: ${urlPath} → ${outputPath}`);
487
525
  successCount++;
488
526
  }
@@ -501,11 +539,21 @@ async function buildStaticPages(): Promise<void> {
501
539
  i18nConfig,
502
540
  slugMappings,
503
541
  distDir,
504
- cmsService
542
+ cmsService,
543
+ generatedUrls
505
544
  );
506
545
  successCount += cmsResult.success;
507
546
  errorCount += cmsResult.errors;
508
547
 
548
+ // Generate SEO files (robots.txt and sitemap.xml)
549
+ if (siteUrl) {
550
+ await generateRobotsTxt(siteUrl, distDir);
551
+ await generateSitemap([...generatedUrls], siteUrl, distDir);
552
+ console.log(`\nšŸ” SEO files generated (robots.txt, sitemap.xml)`);
553
+ } else {
554
+ console.warn(`\nāš ļø Skipping SEO files: siteUrl not configured in project.config.json`);
555
+ }
556
+
509
557
  console.log("\n" + "=".repeat(50));
510
558
  console.log(`✨ Build complete!`);
511
559
  console.log(` āœ… Success: ${successCount}`);
@@ -520,6 +568,9 @@ async function buildStaticPages(): Promise<void> {
520
568
  if (existsSync(functionsDir)) {
521
569
  console.log(` - functions/ (Cloudflare Pages Functions)`);
522
570
  }
571
+ if (siteUrl) {
572
+ console.log(` - robots.txt, sitemap.xml (SEO)`);
573
+ }
523
574
  console.log(` - No React, no client-router āœ“`);
524
575
  }
525
576
 
@@ -10,6 +10,7 @@ export interface FontConfig {
10
10
 
11
11
  interface ProjectConfig {
12
12
  fonts?: FontConfig[];
13
+ siteUrl?: string;
13
14
  [key: string]: unknown;
14
15
  }
15
16
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "meno-core",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "meno": "./bin/cli.ts"