meno-core 1.0.39 → 1.0.41
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/bin/cli.ts +33 -0
- package/build-astro.ts +172 -69
- package/dist/bin/cli.js +30 -2
- package/dist/bin/cli.js.map +2 -2
- package/dist/build-static.js +7 -7
- package/dist/chunks/{chunk-WK5XLASY.js → chunk-EQOSDQS2.js} +4 -4
- package/dist/chunks/{chunk-AIXKUVNG.js → chunk-IBR2F4IL.js} +4 -5
- package/dist/chunks/{chunk-AIXKUVNG.js.map → chunk-IBR2F4IL.js.map} +2 -2
- package/dist/chunks/{chunk-NV25WXCA.js → chunk-IGVQF5GY.js} +11 -7
- package/dist/chunks/chunk-IGVQF5GY.js.map +7 -0
- package/dist/chunks/{chunk-KULPBDC7.js → chunk-LBWIHPN7.js} +9 -3
- package/dist/chunks/chunk-LBWIHPN7.js.map +7 -0
- package/dist/chunks/{chunk-A6KWUEA6.js → chunk-MKB2J6AD.js} +9 -1
- package/dist/chunks/chunk-MKB2J6AD.js.map +7 -0
- package/dist/chunks/{chunk-P3FX5HJM.js → chunk-S2HXJTAF.js} +1 -1
- package/dist/chunks/chunk-S2HXJTAF.js.map +7 -0
- package/dist/chunks/{chunk-W6HDII4T.js → chunk-SK3TLNUP.js} +140 -114
- package/dist/chunks/chunk-SK3TLNUP.js.map +7 -0
- package/dist/chunks/{chunk-HNAS6BSS.js → chunk-SNUROC7E.js} +56 -6
- package/dist/chunks/{chunk-HNAS6BSS.js.map → chunk-SNUROC7E.js.map} +3 -3
- package/dist/chunks/{configService-TXBNUBBL.js → configService-MICL4S2L.js} +2 -2
- package/dist/chunks/{constants-5CRJRQNR.js → constants-ZEU4TZCA.js} +2 -2
- package/dist/entries/server-router.js +7 -7
- package/dist/lib/client/index.js +11 -6
- package/dist/lib/client/index.js.map +2 -2
- package/dist/lib/server/index.js +507 -1587
- package/dist/lib/server/index.js.map +4 -4
- package/dist/lib/shared/index.js +3 -3
- package/dist/lib/test-utils/index.js +1 -1
- package/lib/client/core/ComponentBuilder.ts +1 -1
- package/lib/client/core/builders/embedBuilder.ts +2 -2
- package/lib/client/routing/Router.tsx +6 -0
- package/lib/client/templateEngine.test.ts +178 -0
- package/lib/client/templateEngine.ts +1 -2
- package/lib/server/astro/cmsPageEmitter.ts +420 -0
- package/lib/server/astro/componentEmitter.ts +150 -17
- package/lib/server/astro/nodeToAstro.test.ts +1101 -0
- package/lib/server/astro/nodeToAstro.ts +869 -37
- package/lib/server/astro/pageEmitter.ts +43 -3
- package/lib/server/astro/tailwindMapper.ts +69 -8
- package/lib/server/astro/templateTransformer.ts +107 -0
- package/lib/server/index.ts +26 -3
- package/lib/server/routes/api/components.ts +62 -0
- package/lib/server/routes/api/core-routes.ts +8 -0
- package/lib/server/services/configService.ts +12 -0
- package/lib/server/ssr/htmlGenerator.ts +0 -5
- package/lib/server/ssr/imageMetadata.ts +3 -3
- package/lib/server/ssr/ssrRenderer.ts +78 -29
- package/lib/server/webflow/buildWebflow.ts +415 -0
- package/lib/server/webflow/index.ts +22 -0
- package/lib/server/webflow/nodeToWebflow.ts +423 -0
- package/lib/server/webflow/styleMapper.ts +241 -0
- package/lib/server/webflow/types.ts +196 -0
- package/lib/shared/constants.ts +4 -0
- package/lib/shared/types/components.ts +9 -4
- package/lib/shared/validation/propValidator.ts +2 -1
- package/lib/shared/validation/schemas.ts +4 -1
- package/package.json +1 -1
- package/templates/index-router.html +0 -5
- package/dist/chunks/chunk-A6KWUEA6.js.map +0 -7
- package/dist/chunks/chunk-KULPBDC7.js.map +0 -7
- package/dist/chunks/chunk-NV25WXCA.js.map +0 -7
- package/dist/chunks/chunk-P3FX5HJM.js.map +0 -7
- package/dist/chunks/chunk-W6HDII4T.js.map +0 -7
- /package/dist/chunks/{chunk-WK5XLASY.js.map → chunk-EQOSDQS2.js.map} +0 -0
- /package/dist/chunks/{configService-TXBNUBBL.js.map → configService-MICL4S2L.js.map} +0 -0
- /package/dist/chunks/{constants-5CRJRQNR.js.map → constants-ZEU4TZCA.js.map} +0 -0
package/bin/cli.ts
CHANGED
|
@@ -296,6 +296,35 @@ async function runInit(projectName?: string) {
|
|
|
296
296
|
JSON.stringify(packageJson, null, 2)
|
|
297
297
|
);
|
|
298
298
|
|
|
299
|
+
// Create .claude/tools/ with screenshot tool
|
|
300
|
+
mkdirSync(join(projectPath, '.claude', 'tools'), { recursive: true });
|
|
301
|
+
|
|
302
|
+
const screenshotToolSrc = join(import.meta.dirname, '..', '..', '..', 'example', '.claude', 'tools', 'screenshot.mjs');
|
|
303
|
+
if (existsSync(screenshotToolSrc)) {
|
|
304
|
+
cpSync(screenshotToolSrc, join(projectPath, '.claude', 'tools', 'screenshot.mjs'));
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Create CLAUDE.md with project instructions
|
|
308
|
+
const claudeMd = `# ${projectName}
|
|
309
|
+
|
|
310
|
+
A Meno project - visual editor that generates websites from JSON files.
|
|
311
|
+
|
|
312
|
+
## Dev Server
|
|
313
|
+
|
|
314
|
+
\`\`\`bash
|
|
315
|
+
bun run dev # Start dev server on port 3000
|
|
316
|
+
\`\`\`
|
|
317
|
+
|
|
318
|
+
## Screenshot Tool
|
|
319
|
+
|
|
320
|
+
Take a screenshot of any element by its node ID:
|
|
321
|
+
\`\`\`bash
|
|
322
|
+
npx puppeteer browsers install chrome && node .claude/tools/screenshot.mjs <nodeId> --page /about
|
|
323
|
+
\`\`\`
|
|
324
|
+
Node IDs can be found in the page JSON files under the \`id\` field of each node.
|
|
325
|
+
`;
|
|
326
|
+
writeFileSync(join(projectPath, 'CLAUDE.md'), claudeMd);
|
|
327
|
+
|
|
299
328
|
// Create .gitignore
|
|
300
329
|
const gitignore = `# Dependencies
|
|
301
330
|
node_modules/
|
|
@@ -387,6 +416,9 @@ command = "bun install && bun run build"
|
|
|
387
416
|
|
|
388
417
|
console.log('✅ Created project structure:');
|
|
389
418
|
console.log(` ${projectName}/`);
|
|
419
|
+
console.log(' ├── .claude/');
|
|
420
|
+
console.log(' │ └── tools/');
|
|
421
|
+
console.log(' │ └── screenshot.mjs');
|
|
390
422
|
console.log(' ├── pages/');
|
|
391
423
|
console.log(' │ └── index.json');
|
|
392
424
|
console.log(' ├── components/');
|
|
@@ -395,6 +427,7 @@ command = "bun install && bun run build"
|
|
|
395
427
|
console.log(' ├── colors.json');
|
|
396
428
|
console.log(' ├── project.config.json');
|
|
397
429
|
console.log(' ├── package.json');
|
|
430
|
+
console.log(' ├── CLAUDE.md');
|
|
398
431
|
console.log(' ├── netlify.toml');
|
|
399
432
|
console.log(' ├── vercel.json');
|
|
400
433
|
console.log(' ├── wrangler.toml');
|
package/build-astro.ts
CHANGED
|
@@ -39,7 +39,10 @@ import { collectComponentLibraries, filterLibrariesByContext, mergeLibraries, ge
|
|
|
39
39
|
import { migrateTemplatesDirectory } from "./lib/server/migrateTemplates";
|
|
40
40
|
import { emitAstroComponent } from "./lib/server/astro/componentEmitter";
|
|
41
41
|
import { emitAstroPage } from "./lib/server/astro/pageEmitter";
|
|
42
|
+
import { emitCMSPage } from './lib/server/astro/cmsPageEmitter';
|
|
42
43
|
import { collectAllMappingClasses } from "./lib/server/astro/cssCollector";
|
|
44
|
+
import { buildImageMetadataMap } from "./lib/server/ssr/imageMetadata";
|
|
45
|
+
|
|
43
46
|
|
|
44
47
|
// ---------------------------------------------------------------------------
|
|
45
48
|
// Helpers
|
|
@@ -118,6 +121,28 @@ function escapeTemplateLiteral(s: string): string {
|
|
|
118
121
|
return s.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\$\{/g, '\\${');
|
|
119
122
|
}
|
|
120
123
|
|
|
124
|
+
/**
|
|
125
|
+
* Compute locale → URL path map for a page's slug translations.
|
|
126
|
+
* Used by locale list rendering to generate correct links.
|
|
127
|
+
*/
|
|
128
|
+
function computePageSlugMap(
|
|
129
|
+
slugs: Record<string, string>,
|
|
130
|
+
i18nConfig: I18nConfig
|
|
131
|
+
): Record<string, string> {
|
|
132
|
+
const map: Record<string, string> = {};
|
|
133
|
+
for (const localeConfig of i18nConfig.locales) {
|
|
134
|
+
const code = localeConfig.code;
|
|
135
|
+
const isDefault = code === i18nConfig.defaultLocale;
|
|
136
|
+
const slug = slugs[code] || '';
|
|
137
|
+
if (isDefault) {
|
|
138
|
+
map[code] = slug === '' ? '/' : `/${slug}`;
|
|
139
|
+
} else {
|
|
140
|
+
map[code] = slug === '' ? `/${code}` : `/${code}/${slug}`;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return map;
|
|
144
|
+
}
|
|
145
|
+
|
|
121
146
|
/**
|
|
122
147
|
* Map a CMS field type to a Zod schema string for the Astro content config.
|
|
123
148
|
*/
|
|
@@ -126,7 +151,8 @@ function cmsFieldToZod(field: CMSFieldDefinition): string {
|
|
|
126
151
|
case 'string':
|
|
127
152
|
case 'text':
|
|
128
153
|
case 'rich-text':
|
|
129
|
-
|
|
154
|
+
// Support both plain strings and i18n objects { _i18n: true, en: "...", pl: "..." }
|
|
155
|
+
return 'z.union([z.string(), z.object({ _i18n: z.literal(true) }).passthrough()])';
|
|
130
156
|
case 'number':
|
|
131
157
|
return 'z.number()';
|
|
132
158
|
case 'boolean':
|
|
@@ -180,6 +206,8 @@ interface PageRenderResult {
|
|
|
180
206
|
pageName?: string;
|
|
181
207
|
/** Whether this is a CMS template page */
|
|
182
208
|
isCMSPage?: boolean;
|
|
209
|
+
/** SSR fallback HTML for complex nodes (list, locale-list) keyed by element path */
|
|
210
|
+
ssrFallbackCollector?: Map<string, string>;
|
|
183
211
|
}
|
|
184
212
|
|
|
185
213
|
interface AstroBuildStats {
|
|
@@ -275,6 +303,12 @@ export async function buildAstroProject(
|
|
|
275
303
|
const globalLibraries = configService.getLibraries();
|
|
276
304
|
const componentLibraries = collectComponentLibraries(globalComponents);
|
|
277
305
|
|
|
306
|
+
// Build image metadata map for responsive image generation
|
|
307
|
+
const imageMetadataMap = await buildImageMetadataMap();
|
|
308
|
+
if (imageMetadataMap.size > 0) {
|
|
309
|
+
console.log(`Loaded image metadata for ${imageMetadataMap.size} image(s)\n`);
|
|
310
|
+
}
|
|
311
|
+
|
|
278
312
|
// ----------------------------------------------------------
|
|
279
313
|
// 2. Clean and create output directory
|
|
280
314
|
// ----------------------------------------------------------
|
|
@@ -350,7 +384,7 @@ export async function buildAstroProject(
|
|
|
350
384
|
|
|
351
385
|
// Helper to process a render result
|
|
352
386
|
function processRenderResult(
|
|
353
|
-
result: { html: string; meta: string; title: string; javascript: string; componentCSS?: string; locale: string; interactiveStylesMap: Map<string, InteractiveStyles>; preloadImages: any[]; neededCollections: Set<string> },
|
|
387
|
+
result: { html: string; meta: string; title: string; javascript: string; componentCSS?: string; locale: string; interactiveStylesMap: Map<string, InteractiveStyles>; preloadImages: any[]; neededCollections: Set<string>; ssrFallbackCollector?: Map<string, string> },
|
|
354
388
|
urlPath: string,
|
|
355
389
|
astroFilePath: string,
|
|
356
390
|
fileDepth: number,
|
|
@@ -388,6 +422,7 @@ export async function buildAstroProject(
|
|
|
388
422
|
pageData,
|
|
389
423
|
pageName,
|
|
390
424
|
isCMSPage,
|
|
425
|
+
ssrFallbackCollector: result.ssrFallbackCollector,
|
|
391
426
|
});
|
|
392
427
|
}
|
|
393
428
|
|
|
@@ -460,6 +495,13 @@ export async function buildAstroProject(
|
|
|
460
495
|
}
|
|
461
496
|
}
|
|
462
497
|
|
|
498
|
+
// Pre-compute layout dependencies needed by both CMS and regular page emission
|
|
499
|
+
const fontPreloads = generateFontPreloadTags();
|
|
500
|
+
const mergedLibraries = mergeLibraries(globalLibraries, componentLibraries);
|
|
501
|
+
const buildLibraries = filterLibrariesByContext(mergedLibraries, 'build');
|
|
502
|
+
const libraryTags = generateLibraryTags(buildLibraries);
|
|
503
|
+
const defaultTheme = themeConfig.default || 'light';
|
|
504
|
+
|
|
463
505
|
// ---------- CMS template pages ----------
|
|
464
506
|
const templatesDir = projectPaths.templates();
|
|
465
507
|
const templateSchemas: CMSSchema[] = [];
|
|
@@ -494,54 +536,115 @@ export async function buildAstroProject(
|
|
|
494
536
|
templateSchemas.push(cmsSchema);
|
|
495
537
|
console.log(` CMS Collection: ${cmsSchema.id}`);
|
|
496
538
|
|
|
539
|
+
// Count items for stats
|
|
497
540
|
const items = await cmsService.queryItems({ collection: cmsSchema.id });
|
|
498
|
-
|
|
541
|
+
const itemCount = items.length;
|
|
542
|
+
|
|
543
|
+
if (itemCount === 0) {
|
|
499
544
|
console.log(` No items found in cms/${cmsSchema.id}/`);
|
|
500
|
-
|
|
545
|
+
} else {
|
|
546
|
+
console.log(` Found ${itemCount} item(s)`);
|
|
501
547
|
}
|
|
502
548
|
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
pageData,
|
|
520
|
-
globalComponents,
|
|
521
|
-
itemPath,
|
|
522
|
-
siteUrl,
|
|
523
|
-
locale,
|
|
524
|
-
i18nConfig,
|
|
525
|
-
slugMappings,
|
|
526
|
-
{ cms: itemWithUrl },
|
|
527
|
-
cmsService,
|
|
528
|
-
true
|
|
529
|
-
);
|
|
549
|
+
// Render SSR once for metadata collection (interactive styles, component CSS, JS)
|
|
550
|
+
const defaultLocale = i18nConfig.defaultLocale;
|
|
551
|
+
const dummyPath = cmsSchema.urlPattern.replace('{{slug}}', '__placeholder__');
|
|
552
|
+
|
|
553
|
+
const metaResult = await renderPageSSR(
|
|
554
|
+
pageData,
|
|
555
|
+
globalComponents,
|
|
556
|
+
dummyPath,
|
|
557
|
+
siteUrl,
|
|
558
|
+
defaultLocale,
|
|
559
|
+
i18nConfig,
|
|
560
|
+
slugMappings,
|
|
561
|
+
undefined, // no CMS context - just collecting metadata
|
|
562
|
+
cmsService,
|
|
563
|
+
true
|
|
564
|
+
);
|
|
530
565
|
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
const fileDepth = astroFilePath.split('/').length - 1;
|
|
566
|
+
// Collect interactive styles and component CSS
|
|
567
|
+
mergeInteractiveStyles(metaResult.interactiveStylesMap);
|
|
568
|
+
if (metaResult.componentCSS) {
|
|
569
|
+
allComponentCSS.add(metaResult.componentCSS);
|
|
570
|
+
}
|
|
537
571
|
|
|
538
|
-
|
|
572
|
+
// Deduplicate JavaScript by content hash
|
|
573
|
+
const scriptPaths: string[] = [];
|
|
574
|
+
if (metaResult.javascript) {
|
|
575
|
+
const hash = hashContent(metaResult.javascript);
|
|
576
|
+
if (!jsContents.has(hash)) {
|
|
577
|
+
jsContents.set(hash, metaResult.javascript);
|
|
578
|
+
}
|
|
579
|
+
scriptPaths.push(`/_scripts/${hash}.js`);
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
// Determine route file path from urlPattern
|
|
583
|
+
const isMultiLocale = i18nConfig.locales.length > 1;
|
|
584
|
+
const urlPatternWithoutSlash = cmsSchema.urlPattern.replace(/^\//, '');
|
|
585
|
+
const slugPlaceholderIdx = urlPatternWithoutSlash.indexOf('{{');
|
|
586
|
+
const pathPrefix = slugPlaceholderIdx > 0 ? urlPatternWithoutSlash.substring(0, slugPlaceholderIdx) : '';
|
|
587
|
+
|
|
588
|
+
// Generate CMS page with getStaticPaths()
|
|
589
|
+
const ssrFallbacks = metaResult.ssrFallbackCollector ?? new Map<string, string>();
|
|
590
|
+
|
|
591
|
+
// For each locale (or just default), generate a route file
|
|
592
|
+
const localesToEmit = isMultiLocale ? i18nConfig.locales : [{ code: i18nConfig.defaultLocale }];
|
|
593
|
+
|
|
594
|
+
for (const localeEntry of localesToEmit) {
|
|
595
|
+
const localeCode = localeEntry.code;
|
|
596
|
+
const isDefault = localeCode === i18nConfig.defaultLocale;
|
|
597
|
+
|
|
598
|
+
// Route file path: blog/[slug].astro for default, pl/blog/[slug].astro for non-default
|
|
599
|
+
let astroFilePath: string;
|
|
600
|
+
if (pathPrefix) {
|
|
601
|
+
astroFilePath = isDefault
|
|
602
|
+
? `${pathPrefix}[slug].astro`
|
|
603
|
+
: `${localeCode}/${pathPrefix}[slug].astro`;
|
|
604
|
+
} else {
|
|
605
|
+
astroFilePath = isDefault
|
|
606
|
+
? '[slug].astro'
|
|
607
|
+
: `${localeCode}/[slug].astro`;
|
|
608
|
+
}
|
|
539
609
|
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
610
|
+
const fileDepth = astroFilePath.split('/').length - 1;
|
|
611
|
+
const importPath = layoutImportPath(fileDepth);
|
|
612
|
+
|
|
613
|
+
const astroContent = emitCMSPage({
|
|
614
|
+
pageData,
|
|
615
|
+
globalComponents,
|
|
616
|
+
cmsSchema,
|
|
617
|
+
title: String(pageData.meta?.title || cmsSchema.name),
|
|
618
|
+
meta: metaResult.meta,
|
|
619
|
+
locale: localeCode,
|
|
620
|
+
theme: defaultTheme,
|
|
621
|
+
fontPreloads,
|
|
622
|
+
libraryTags,
|
|
623
|
+
scriptPaths,
|
|
624
|
+
layoutImportPath: importPath,
|
|
625
|
+
fileDepth,
|
|
626
|
+
ssrFallbacks,
|
|
627
|
+
pageName: file.replace('.json', ''),
|
|
628
|
+
breakpoints,
|
|
629
|
+
imageMetadataMap,
|
|
630
|
+
i18nConfig,
|
|
631
|
+
isMultiLocale: false, // Each file handles one locale
|
|
632
|
+
slugMappings,
|
|
633
|
+
imageFormat: configService.getImageFormat(),
|
|
634
|
+
});
|
|
635
|
+
|
|
636
|
+
const astroFileFull = join(pagesOutDir, astroFilePath);
|
|
637
|
+
const astroFileDir = astroFileFull.substring(0, astroFileFull.lastIndexOf('/'));
|
|
638
|
+
if (!existsSync(astroFileDir)) {
|
|
639
|
+
mkdirSync(astroFileDir, { recursive: true });
|
|
543
640
|
}
|
|
641
|
+
|
|
642
|
+
await writeFile(astroFileFull, astroContent, 'utf-8');
|
|
544
643
|
}
|
|
644
|
+
|
|
645
|
+
console.log(` Generated: ${pathPrefix}[slug].astro (${itemCount} items × ${localesToEmit.length} locale(s))`);
|
|
646
|
+
|
|
647
|
+
cmsPageCount += itemCount * i18nConfig.locales.length;
|
|
545
648
|
} catch (error: any) {
|
|
546
649
|
console.error(` Error processing template ${file}:`, error?.message || error);
|
|
547
650
|
errorCount++;
|
|
@@ -585,13 +688,6 @@ export async function buildAstroProject(
|
|
|
585
688
|
// ----------------------------------------------------------
|
|
586
689
|
// 7. Generate BaseLayout.astro
|
|
587
690
|
// ----------------------------------------------------------
|
|
588
|
-
const fontPreloads = generateFontPreloadTags();
|
|
589
|
-
|
|
590
|
-
// Merge global + component libraries for the layout
|
|
591
|
-
const mergedLibraries = mergeLibraries(globalLibraries, componentLibraries);
|
|
592
|
-
const buildLibraries = filterLibrariesByContext(mergedLibraries, 'build');
|
|
593
|
-
const libraryTags = generateLibraryTags(buildLibraries);
|
|
594
|
-
|
|
595
691
|
const baseLayoutContent = `---
|
|
596
692
|
import '../styles/global.css';
|
|
597
693
|
|
|
@@ -635,7 +731,7 @@ const { title, meta = '', scripts = [], locale = 'en', theme = '${themeConfig.de
|
|
|
635
731
|
let componentFileCount = 0;
|
|
636
732
|
for (const [compName, compDef] of Object.entries(globalComponents)) {
|
|
637
733
|
try {
|
|
638
|
-
const astroContent = emitAstroComponent(compName, compDef, globalComponents, breakpoints);
|
|
734
|
+
const astroContent = emitAstroComponent(compName, compDef, globalComponents, breakpoints, i18nConfig.defaultLocale);
|
|
639
735
|
await writeFile(join(componentsOutDir, `${compName}.astro`), astroContent, 'utf-8');
|
|
640
736
|
componentFileCount++;
|
|
641
737
|
} catch (error: any) {
|
|
@@ -647,8 +743,6 @@ const { title, meta = '', scripts = [], locale = 'en', theme = '${themeConfig.de
|
|
|
647
743
|
// ----------------------------------------------------------
|
|
648
744
|
// 8. Generate .astro page files (component-structured)
|
|
649
745
|
// ----------------------------------------------------------
|
|
650
|
-
const defaultTheme = themeConfig.default || 'light';
|
|
651
|
-
|
|
652
746
|
for (const result of allResults) {
|
|
653
747
|
const importPath = layoutImportPath(result.fileDepth);
|
|
654
748
|
|
|
@@ -672,10 +766,18 @@ const { title, meta = '', scripts = [], locale = 'en', theme = '${themeConfig.de
|
|
|
672
766
|
|
|
673
767
|
let astroContent: string;
|
|
674
768
|
|
|
675
|
-
// Use component-structured emission for
|
|
676
|
-
|
|
677
|
-
if (result.pageData && !result.isCMSPage) {
|
|
769
|
+
// Use component-structured emission for pages with page data
|
|
770
|
+
if (result.pageData) {
|
|
678
771
|
try {
|
|
772
|
+
// Use SSR fallback collector from the initial render (paths already match nodeToAstro convention)
|
|
773
|
+
const ssrFallbacks = result.ssrFallbackCollector ?? new Map<string, string>();
|
|
774
|
+
|
|
775
|
+
// Compute slug map for locale list rendering
|
|
776
|
+
const pageSlugMap: Record<string, string> | undefined =
|
|
777
|
+
result.pageData.meta?.slugs
|
|
778
|
+
? computePageSlugMap(result.pageData.meta.slugs, i18nConfig)
|
|
779
|
+
: undefined;
|
|
780
|
+
|
|
679
781
|
astroContent = emitAstroPage({
|
|
680
782
|
pageData: result.pageData,
|
|
681
783
|
globalComponents,
|
|
@@ -688,9 +790,14 @@ const { title, meta = '', scripts = [], locale = 'en', theme = '${themeConfig.de
|
|
|
688
790
|
scriptPaths,
|
|
689
791
|
layoutImportPath: importPath,
|
|
690
792
|
fileDepth: result.fileDepth,
|
|
691
|
-
ssrFallbacks
|
|
793
|
+
ssrFallbacks,
|
|
692
794
|
pageName: result.pageName || 'index',
|
|
693
795
|
breakpoints,
|
|
796
|
+
imageMetadataMap,
|
|
797
|
+
i18nConfig: i18nConfig.locales.length > 1 ? i18nConfig : undefined,
|
|
798
|
+
currentPageSlugMap: pageSlugMap,
|
|
799
|
+
slugMappings: i18nConfig.locales.length > 1 ? slugMappings : undefined,
|
|
800
|
+
imageFormat: configService.getImageFormat(),
|
|
694
801
|
});
|
|
695
802
|
} catch (error: any) {
|
|
696
803
|
// Fallback to SSR HTML if component emission fails
|
|
@@ -698,7 +805,7 @@ const { title, meta = '', scripts = [], locale = 'en', theme = '${themeConfig.de
|
|
|
698
805
|
astroContent = buildSSRFallbackPage(result, importPath, fontPreloads, libraryTags, defaultTheme, scriptPaths);
|
|
699
806
|
}
|
|
700
807
|
} else {
|
|
701
|
-
//
|
|
808
|
+
// Pages without pageData: use SSR fallback
|
|
702
809
|
astroContent = buildSSRFallbackPage(result, importPath, fontPreloads, libraryTags, defaultTheme, scriptPaths);
|
|
703
810
|
}
|
|
704
811
|
|
|
@@ -738,15 +845,8 @@ const { title, meta = '', scripts = [], locale = 'en', theme = '${themeConfig.de
|
|
|
738
845
|
const rawContent = await readFile(join(cmsItemsDir, itemFile), 'utf-8');
|
|
739
846
|
const item = JSON.parse(rawContent) as CMSItem;
|
|
740
847
|
|
|
741
|
-
//
|
|
742
|
-
const resolved: Record<string, unknown> = {};
|
|
743
|
-
for (const [key, value] of Object.entries(item)) {
|
|
744
|
-
if (isI18nValue(value)) {
|
|
745
|
-
resolved[key] = resolveI18nValue(value, i18nConfig.defaultLocale, i18nConfig);
|
|
746
|
-
} else {
|
|
747
|
-
resolved[key] = value;
|
|
748
|
-
}
|
|
749
|
-
}
|
|
848
|
+
// Keep i18n values as-is so getStaticPaths() can resolve per-locale
|
|
849
|
+
const resolved: Record<string, unknown> = { ...item };
|
|
750
850
|
|
|
751
851
|
await writeFile(
|
|
752
852
|
join(collectionDir, itemFile),
|
|
@@ -836,7 +936,6 @@ export { collections };
|
|
|
836
936
|
},
|
|
837
937
|
dependencies: {
|
|
838
938
|
'astro': '^4.0.0',
|
|
839
|
-
'@astrojs/sitemap': '^3.0.0',
|
|
840
939
|
'@astrojs/tailwind': '^5.0.0',
|
|
841
940
|
'tailwindcss': '^3.4.0',
|
|
842
941
|
},
|
|
@@ -845,12 +944,16 @@ export { collections };
|
|
|
845
944
|
await writeFile(join(outDir, 'package.json'), JSON.stringify(packageJson, null, 2), 'utf-8');
|
|
846
945
|
|
|
847
946
|
// astro.config.mjs
|
|
947
|
+
const localeCodes = i18nConfig.locales.map(l => l.code);
|
|
948
|
+
const i18nBlock = i18nConfig.locales.length > 1
|
|
949
|
+
? `\n i18n: {\n defaultLocale: '${i18nConfig.defaultLocale}',\n locales: [${localeCodes.map(c => `'${c}'`).join(', ')}],\n routing: { prefixDefaultLocale: false },\n },`
|
|
950
|
+
: '';
|
|
951
|
+
|
|
848
952
|
const astroConfig = `import { defineConfig } from 'astro/config';
|
|
849
|
-
import sitemap from '@astrojs/sitemap';
|
|
850
953
|
import tailwind from '@astrojs/tailwind';
|
|
851
954
|
|
|
852
|
-
export default defineConfig({${siteUrl ? `\n site: '${siteUrl}',` : ''}
|
|
853
|
-
integrations: [
|
|
955
|
+
export default defineConfig({${siteUrl ? `\n site: '${siteUrl}',` : ''}${i18nBlock}
|
|
956
|
+
integrations: [tailwind({ applyBaseStyles: false })],
|
|
854
957
|
});
|
|
855
958
|
`;
|
|
856
959
|
|
package/dist/bin/cli.js
CHANGED
|
@@ -14,7 +14,7 @@ import "../chunks/chunk-KSBZ2L7C.js";
|
|
|
14
14
|
|
|
15
15
|
// bin/cli.ts
|
|
16
16
|
import { resolve, join } from "path";
|
|
17
|
-
import { existsSync, mkdirSync, writeFileSync, readFileSync } from "fs";
|
|
17
|
+
import { existsSync, mkdirSync, writeFileSync, cpSync, readFileSync } from "fs";
|
|
18
18
|
var args = process.argv.slice(2);
|
|
19
19
|
var command = args[0];
|
|
20
20
|
function printHelp() {
|
|
@@ -82,7 +82,7 @@ function getMatchingHeaders(pathname, headersMap) {
|
|
|
82
82
|
return result;
|
|
83
83
|
}
|
|
84
84
|
async function startStaticServer(distPath) {
|
|
85
|
-
const { SERVE_PORT } = await import("../chunks/constants-
|
|
85
|
+
const { SERVE_PORT } = await import("../chunks/constants-ZEU4TZCA.js");
|
|
86
86
|
const headersMap = parseHeadersFile(distPath);
|
|
87
87
|
const server = await createRuntimeServer({
|
|
88
88
|
port: SERVE_PORT,
|
|
@@ -226,6 +226,30 @@ async function runInit(projectName) {
|
|
|
226
226
|
join(projectPath, "package.json"),
|
|
227
227
|
JSON.stringify(packageJson, null, 2)
|
|
228
228
|
);
|
|
229
|
+
mkdirSync(join(projectPath, ".claude", "tools"), { recursive: true });
|
|
230
|
+
const screenshotToolSrc = join(import.meta.dirname, "..", "..", "..", "example", ".claude", "tools", "screenshot.mjs");
|
|
231
|
+
if (existsSync(screenshotToolSrc)) {
|
|
232
|
+
cpSync(screenshotToolSrc, join(projectPath, ".claude", "tools", "screenshot.mjs"));
|
|
233
|
+
}
|
|
234
|
+
const claudeMd = `# ${projectName}
|
|
235
|
+
|
|
236
|
+
A Meno project - visual editor that generates websites from JSON files.
|
|
237
|
+
|
|
238
|
+
## Dev Server
|
|
239
|
+
|
|
240
|
+
\`\`\`bash
|
|
241
|
+
bun run dev # Start dev server on port 3000
|
|
242
|
+
\`\`\`
|
|
243
|
+
|
|
244
|
+
## Screenshot Tool
|
|
245
|
+
|
|
246
|
+
Take a screenshot of any element by its node ID:
|
|
247
|
+
\`\`\`bash
|
|
248
|
+
npx puppeteer browsers install chrome && node .claude/tools/screenshot.mjs <nodeId> --page /about
|
|
249
|
+
\`\`\`
|
|
250
|
+
Node IDs can be found in the page JSON files under the \`id\` field of each node.
|
|
251
|
+
`;
|
|
252
|
+
writeFileSync(join(projectPath, "CLAUDE.md"), claudeMd);
|
|
229
253
|
const gitignore = `# Dependencies
|
|
230
254
|
node_modules/
|
|
231
255
|
|
|
@@ -307,6 +331,9 @@ command = "bun install && bun run build"
|
|
|
307
331
|
);
|
|
308
332
|
console.log("\u2705 Created project structure:");
|
|
309
333
|
console.log(` ${projectName}/`);
|
|
334
|
+
console.log(" \u251C\u2500\u2500 .claude/");
|
|
335
|
+
console.log(" \u2502 \u2514\u2500\u2500 tools/");
|
|
336
|
+
console.log(" \u2502 \u2514\u2500\u2500 screenshot.mjs");
|
|
310
337
|
console.log(" \u251C\u2500\u2500 pages/");
|
|
311
338
|
console.log(" \u2502 \u2514\u2500\u2500 index.json");
|
|
312
339
|
console.log(" \u251C\u2500\u2500 components/");
|
|
@@ -315,6 +342,7 @@ command = "bun install && bun run build"
|
|
|
315
342
|
console.log(" \u251C\u2500\u2500 colors.json");
|
|
316
343
|
console.log(" \u251C\u2500\u2500 project.config.json");
|
|
317
344
|
console.log(" \u251C\u2500\u2500 package.json");
|
|
345
|
+
console.log(" \u251C\u2500\u2500 CLAUDE.md");
|
|
318
346
|
console.log(" \u251C\u2500\u2500 netlify.toml");
|
|
319
347
|
console.log(" \u251C\u2500\u2500 vercel.json");
|
|
320
348
|
console.log(" \u251C\u2500\u2500 wrangler.toml");
|
package/dist/bin/cli.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../bin/cli.ts"],
|
|
4
|
-
"sourcesContent": ["#!/usr/bin/env node\n/**\n * meno CLI\n * Commands: dev, build, init\n */\n\nimport { resolve, join } from 'path';\nimport { existsSync, mkdirSync, writeFileSync, cpSync, readFileSync } from 'fs';\nimport { setProjectRoot } from '../lib/server/projectContext';\nimport { generateBuildErrorPage, type BuildErrorsData } from '../lib/server/ssr/buildErrorOverlay';\nimport { createRuntimeServer, serveFile, fileExists as runtimeFileExists } from '../lib/server/runtime';\n\nconst args = process.argv.slice(2);\nconst command = args[0];\n\nfunction printHelp() {\n console.log(`\nmeno - Visual editor for JSON-based pages\n\nRequirements:\n - Bun or Node.js 18+\n\nUsage:\n meno <command> [options]\n\nCommands:\n dev Start development server with hot reload\n build Build static HTML files for production\n serve Serve built files from ./dist on port 8080\n init Initialize a new project\n\nOptions:\n build --dev Include draft pages in build (for local preview)\n\nExamples:\n meno dev Start dev server in current directory\n meno build Build static files to ./dist (excludes drafts)\n meno build --dev Build including draft pages\n meno serve Serve built files on port 8080\n meno init my-project Create new project in ./my-project\n`);\n}\n\n// Parse _headers file (Netlify/Cloudflare format)\nfunction parseHeadersFile(distPath: string): Map<string, Record<string, string>> {\n const headersPath = join(distPath, '_headers');\n const headers = new Map<string, Record<string, string>>();\n\n if (!existsSync(headersPath)) return headers;\n\n const content = readFileSync(headersPath, 'utf-8');\n let currentPath = '';\n\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n\n if (!line.startsWith(' ') && !line.startsWith('\\t')) {\n // Path line\n currentPath = trimmed;\n if (!headers.has(currentPath)) {\n headers.set(currentPath, {});\n }\n } else if (currentPath && trimmed.includes(':')) {\n // Header line\n const colonIndex = trimmed.indexOf(':');\n const name = trimmed.substring(0, colonIndex).trim();\n const value = trimmed.substring(colonIndex + 1).trim();\n headers.get(currentPath)![name] = value;\n }\n }\n\n return headers;\n}\n\n// Get headers matching a pathname\nfunction getMatchingHeaders(\n pathname: string,\n headersMap: Map<string, Record<string, string>>\n): Record<string, string> {\n const result: Record<string, string> = {};\n\n headersMap.forEach((headers, pattern) => {\n if (pattern === pathname || pattern === '/*') {\n Object.assign(result, headers);\n } else if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -1);\n if (pathname.startsWith(prefix)) {\n Object.assign(result, headers);\n }\n }\n });\n\n return result;\n}\n\n// Start static file server on port 8080 (non-blocking)\nasync function startStaticServer(distPath: string) {\n const { SERVE_PORT } = await import('../lib/shared/constants');\n\n // Parse _headers file once on startup\n const headersMap = parseHeadersFile(distPath);\n\n const server = await createRuntimeServer({\n port: SERVE_PORT,\n hostname: 'localhost',\n async fetch(req: Request) {\n const url = new URL(req.url);\n let pathname = url.pathname;\n\n // Check for build errors and show overlay (except for _errors.json itself)\n if (pathname !== '/_errors.json') {\n const errorsPath = join(distPath, '_errors.json');\n if (existsSync(errorsPath)) {\n try {\n const errorsData: BuildErrorsData = JSON.parse(readFileSync(errorsPath, 'utf-8'));\n return new Response(generateBuildErrorPage(errorsData), {\n headers: { 'Content-Type': 'text/html; charset=utf-8' },\n });\n } catch {\n // If we can't parse errors file, continue normally\n }\n }\n }\n\n // Default to index.html for root\n if (pathname === '/') {\n pathname = '/index.html';\n }\n\n // Get custom headers for this path\n const customHeaders = getMatchingHeaders(pathname, headersMap);\n\n // Try to serve the file\n const filePath = join(distPath, pathname);\n\n // Check if file exists and serve it\n if (await runtimeFileExists(filePath)) {\n return await serveFile(filePath, customHeaders);\n }\n\n // Try with .html extension for clean URLs\n const htmlPath = filePath.endsWith('.html') ? filePath : `${filePath}.html`;\n if (await runtimeFileExists(htmlPath)) {\n return await serveFile(htmlPath, customHeaders);\n }\n\n // Try index.html in directory\n const indexPath = join(filePath, 'index.html');\n if (await runtimeFileExists(indexPath)) {\n return await serveFile(indexPath, customHeaders);\n }\n\n return new Response('Not Found', { status: 404 });\n },\n });\n\n return server;\n}\n\nasync function runDev() {\n const projectRoot = process.cwd();\n\n // Validate project structure\n if (!existsSync(join(projectRoot, 'pages'))) {\n console.error('\u274C No pages directory found. Are you in a valid project directory?');\n console.error(' Run \"meno init <project-name>\" to create a new project.');\n process.exit(1);\n }\n\n // Set project root for path resolution\n setProjectRoot(projectRoot);\n\n console.log(`\uD83D\uDCC1 Project root: ${projectRoot}`);\n\n // Start static server on 8080 if dist exists\n const distPath = join(projectRoot, 'dist');\n if (existsSync(distPath)) {\n const staticServer = await startStaticServer(distPath);\n console.log(`\uD83D\uDE80 Static server running at http://localhost:${staticServer.port}`);\n }\n\n // Import and run the dev server (it handles all initialization internally)\n await import('../entries/server-router');\n}\n\nasync function runBuild(isDev: boolean = false) {\n const projectRoot = process.cwd();\n\n // Validate project structure\n if (!existsSync(join(projectRoot, 'pages'))) {\n console.error('\u274C No pages directory found. Are you in a valid project directory?');\n process.exit(1);\n }\n\n // Set project root for path resolution\n setProjectRoot(projectRoot);\n\n // Set dev mode environment variable (drafts are built in dev mode)\n if (isDev) {\n process.env.MENO_DEV_BUILD = 'true';\n }\n\n console.log(`\uD83D\uDCC1 Building project: ${projectRoot}${isDev ? ' (dev mode - including drafts)' : ''}`);\n\n // Import and run build\n const { buildStaticPages } = await import('../build-static.ts');\n await buildStaticPages();\n}\n\nasync function runServe() {\n const projectRoot = process.cwd();\n const distPath = join(projectRoot, 'dist');\n\n // Validate dist directory exists\n if (!existsSync(distPath)) {\n console.error('\u274C No dist directory found. Run \"meno build\" first.');\n process.exit(1);\n }\n\n console.log(`\uD83D\uDCC1 Serving built files from: ${distPath}`);\n const server = await startStaticServer(distPath);\n console.log(`\uD83D\uDE80 Static server running at http://localhost:${server.port}`);\n\n // Keep the process alive\n await new Promise(() => {});\n}\n\nasync function runInit(projectName?: string) {\n if (!projectName) {\n console.error('\u274C Please provide a project name: meno init <project-name>');\n process.exit(1);\n }\n\n const projectPath = resolve(process.cwd(), projectName);\n\n if (existsSync(projectPath)) {\n console.error(`\u274C Directory \"${projectName}\" already exists.`);\n process.exit(1);\n }\n\n console.log(`\\n\uD83D\uDE80 Creating new meno project: ${projectName}\\n`);\n\n // Create project structure\n mkdirSync(projectPath, { recursive: true });\n mkdirSync(join(projectPath, 'pages'));\n mkdirSync(join(projectPath, 'components'));\n mkdirSync(join(projectPath, 'fonts'));\n mkdirSync(join(projectPath, 'images'));\n\n // Create default project.config.json\n const defaultConfig = {\n fonts: [],\n editor: {\n theme: 'dark'\n }\n };\n writeFileSync(\n join(projectPath, 'project.config.json'),\n JSON.stringify(defaultConfig, null, 2)\n );\n\n // Create default colors.json\n const defaultColors = {\n default: 'light',\n themes: {\n light: {\n label: 'Light',\n colors: {\n text: '#1f2937',\n bg: '#ffffff'\n }\n }\n }\n };\n writeFileSync(\n join(projectPath, 'colors.json'),\n JSON.stringify(defaultColors, null, 2)\n );\n\n // Create package.json for deployment\n const packageJson = {\n name: projectName,\n version: '1.0.0',\n private: true,\n scripts: {\n dev: 'meno dev',\n build: 'meno build',\n },\n dependencies: {\n 'meno-core': '^1.0.0'\n }\n };\n writeFileSync(\n join(projectPath, 'package.json'),\n JSON.stringify(packageJson, null, 2)\n );\n\n // Create .gitignore\n const gitignore = `# Dependencies\nnode_modules/\n\n# Build output\ndist/\n\n# OS files\n.DS_Store\n`;\n writeFileSync(\n join(projectPath, '.gitignore'),\n gitignore\n );\n\n // Create netlify.toml\n const netlifyConfig = `[build]\n command = \"bun install && bun run build\"\n publish = \"dist\"\n\n[build.environment]\n BUN_VERSION = \"1\"\n`;\n writeFileSync(\n join(projectPath, 'netlify.toml'),\n netlifyConfig\n );\n\n // Create vercel.json\n const vercelConfig = {\n buildCommand: 'bun run build',\n outputDirectory: 'dist',\n installCommand: 'bun install'\n };\n writeFileSync(\n join(projectPath, 'vercel.json'),\n JSON.stringify(vercelConfig, null, 2)\n );\n\n // Create wrangler.toml for Cloudflare Pages\n const cloudflareConfig = `name = \"${projectName}\"\ncompatibility_date = \"2024-01-01\"\npages_build_output_dir = \"dist\"\n\n[build]\ncommand = \"bun install && bun run build\"\n`;\n writeFileSync(\n join(projectPath, 'wrangler.toml'),\n cloudflareConfig\n );\n\n // Create default index page\n const defaultPage = {\n meta: {\n title: 'Your Project Title',\n description: 'Your Project Description',\n keywords: '',\n ogTitle: 'Your Project Title',\n ogDescription: 'Your Project Description',\n ogType: 'website'\n },\n root: {\n type: 'node',\n tag: 'div',\n style: {\n base: {\n padding: '40px'\n },\n tablet: {},\n mobile: {}\n },\n children: [\n {\n type: 'node',\n tag: 'h1',\n style: {\n base: {}\n },\n children: 'Hello'\n }\n ]\n }\n };\n writeFileSync(\n join(projectPath, 'pages', 'index.json'),\n JSON.stringify(defaultPage, null, 2)\n );\n\n console.log('\u2705 Created project structure:');\n console.log(` ${projectName}/`);\n console.log(' \u251C\u2500\u2500 pages/');\n console.log(' \u2502 \u2514\u2500\u2500 index.json');\n console.log(' \u251C\u2500\u2500 components/');\n console.log(' \u251C\u2500\u2500 fonts/');\n console.log(' \u251C\u2500\u2500 images/');\n console.log(' \u251C\u2500\u2500 colors.json');\n console.log(' \u251C\u2500\u2500 project.config.json');\n console.log(' \u251C\u2500\u2500 package.json');\n console.log(' \u251C\u2500\u2500 netlify.toml');\n console.log(' \u251C\u2500\u2500 vercel.json');\n console.log(' \u251C\u2500\u2500 wrangler.toml');\n console.log(' \u2514\u2500\u2500 .gitignore');\n console.log('\\n\uD83C\uDF89 Project created successfully!\\n');\n console.log('Requirements:');\n console.log(' Bun - https://bun.sh');\n console.log('');\n console.log('Next steps:');\n console.log(` cd ${projectName}`);\n console.log(' bun install # Install dependencies');\n console.log(' bun run dev # Start dev server');\n console.log('');\n console.log('Deploy:');\n console.log(' Push to GitHub and connect to Netlify/Vercel/Cloudflare');\n console.log(' Config files included - auto-detected!');\n console.log('');\n}\n\n// Main\nswitch (command) {\n case 'dev':\n runDev();\n break;\n case 'build':\n runBuild(args.includes('--dev'));\n break;\n case 'serve':\n runServe();\n break;\n case 'init':\n runInit(args[1]);\n break;\n case '--help':\n case '-h':\n case undefined:\n printHelp();\n break;\n default:\n console.error(`Unknown command: ${command}`);\n printHelp();\n process.exit(1);\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;AAMA,SAAS,SAAS,YAAY;AAC9B,SAAS,YAAY,WAAW,
|
|
4
|
+
"sourcesContent": ["#!/usr/bin/env node\n/**\n * meno CLI\n * Commands: dev, build, init\n */\n\nimport { resolve, join } from 'path';\nimport { existsSync, mkdirSync, writeFileSync, cpSync, readFileSync } from 'fs';\nimport { setProjectRoot } from '../lib/server/projectContext';\nimport { generateBuildErrorPage, type BuildErrorsData } from '../lib/server/ssr/buildErrorOverlay';\nimport { createRuntimeServer, serveFile, fileExists as runtimeFileExists } from '../lib/server/runtime';\n\nconst args = process.argv.slice(2);\nconst command = args[0];\n\nfunction printHelp() {\n console.log(`\nmeno - Visual editor for JSON-based pages\n\nRequirements:\n - Bun or Node.js 18+\n\nUsage:\n meno <command> [options]\n\nCommands:\n dev Start development server with hot reload\n build Build static HTML files for production\n serve Serve built files from ./dist on port 8080\n init Initialize a new project\n\nOptions:\n build --dev Include draft pages in build (for local preview)\n\nExamples:\n meno dev Start dev server in current directory\n meno build Build static files to ./dist (excludes drafts)\n meno build --dev Build including draft pages\n meno serve Serve built files on port 8080\n meno init my-project Create new project in ./my-project\n`);\n}\n\n// Parse _headers file (Netlify/Cloudflare format)\nfunction parseHeadersFile(distPath: string): Map<string, Record<string, string>> {\n const headersPath = join(distPath, '_headers');\n const headers = new Map<string, Record<string, string>>();\n\n if (!existsSync(headersPath)) return headers;\n\n const content = readFileSync(headersPath, 'utf-8');\n let currentPath = '';\n\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n\n if (!line.startsWith(' ') && !line.startsWith('\\t')) {\n // Path line\n currentPath = trimmed;\n if (!headers.has(currentPath)) {\n headers.set(currentPath, {});\n }\n } else if (currentPath && trimmed.includes(':')) {\n // Header line\n const colonIndex = trimmed.indexOf(':');\n const name = trimmed.substring(0, colonIndex).trim();\n const value = trimmed.substring(colonIndex + 1).trim();\n headers.get(currentPath)![name] = value;\n }\n }\n\n return headers;\n}\n\n// Get headers matching a pathname\nfunction getMatchingHeaders(\n pathname: string,\n headersMap: Map<string, Record<string, string>>\n): Record<string, string> {\n const result: Record<string, string> = {};\n\n headersMap.forEach((headers, pattern) => {\n if (pattern === pathname || pattern === '/*') {\n Object.assign(result, headers);\n } else if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -1);\n if (pathname.startsWith(prefix)) {\n Object.assign(result, headers);\n }\n }\n });\n\n return result;\n}\n\n// Start static file server on port 8080 (non-blocking)\nasync function startStaticServer(distPath: string) {\n const { SERVE_PORT } = await import('../lib/shared/constants');\n\n // Parse _headers file once on startup\n const headersMap = parseHeadersFile(distPath);\n\n const server = await createRuntimeServer({\n port: SERVE_PORT,\n hostname: 'localhost',\n async fetch(req: Request) {\n const url = new URL(req.url);\n let pathname = url.pathname;\n\n // Check for build errors and show overlay (except for _errors.json itself)\n if (pathname !== '/_errors.json') {\n const errorsPath = join(distPath, '_errors.json');\n if (existsSync(errorsPath)) {\n try {\n const errorsData: BuildErrorsData = JSON.parse(readFileSync(errorsPath, 'utf-8'));\n return new Response(generateBuildErrorPage(errorsData), {\n headers: { 'Content-Type': 'text/html; charset=utf-8' },\n });\n } catch {\n // If we can't parse errors file, continue normally\n }\n }\n }\n\n // Default to index.html for root\n if (pathname === '/') {\n pathname = '/index.html';\n }\n\n // Get custom headers for this path\n const customHeaders = getMatchingHeaders(pathname, headersMap);\n\n // Try to serve the file\n const filePath = join(distPath, pathname);\n\n // Check if file exists and serve it\n if (await runtimeFileExists(filePath)) {\n return await serveFile(filePath, customHeaders);\n }\n\n // Try with .html extension for clean URLs\n const htmlPath = filePath.endsWith('.html') ? filePath : `${filePath}.html`;\n if (await runtimeFileExists(htmlPath)) {\n return await serveFile(htmlPath, customHeaders);\n }\n\n // Try index.html in directory\n const indexPath = join(filePath, 'index.html');\n if (await runtimeFileExists(indexPath)) {\n return await serveFile(indexPath, customHeaders);\n }\n\n return new Response('Not Found', { status: 404 });\n },\n });\n\n return server;\n}\n\nasync function runDev() {\n const projectRoot = process.cwd();\n\n // Validate project structure\n if (!existsSync(join(projectRoot, 'pages'))) {\n console.error('\u274C No pages directory found. Are you in a valid project directory?');\n console.error(' Run \"meno init <project-name>\" to create a new project.');\n process.exit(1);\n }\n\n // Set project root for path resolution\n setProjectRoot(projectRoot);\n\n console.log(`\uD83D\uDCC1 Project root: ${projectRoot}`);\n\n // Start static server on 8080 if dist exists\n const distPath = join(projectRoot, 'dist');\n if (existsSync(distPath)) {\n const staticServer = await startStaticServer(distPath);\n console.log(`\uD83D\uDE80 Static server running at http://localhost:${staticServer.port}`);\n }\n\n // Import and run the dev server (it handles all initialization internally)\n await import('../entries/server-router');\n}\n\nasync function runBuild(isDev: boolean = false) {\n const projectRoot = process.cwd();\n\n // Validate project structure\n if (!existsSync(join(projectRoot, 'pages'))) {\n console.error('\u274C No pages directory found. Are you in a valid project directory?');\n process.exit(1);\n }\n\n // Set project root for path resolution\n setProjectRoot(projectRoot);\n\n // Set dev mode environment variable (drafts are built in dev mode)\n if (isDev) {\n process.env.MENO_DEV_BUILD = 'true';\n }\n\n console.log(`\uD83D\uDCC1 Building project: ${projectRoot}${isDev ? ' (dev mode - including drafts)' : ''}`);\n\n // Import and run build\n const { buildStaticPages } = await import('../build-static.ts');\n await buildStaticPages();\n}\n\nasync function runServe() {\n const projectRoot = process.cwd();\n const distPath = join(projectRoot, 'dist');\n\n // Validate dist directory exists\n if (!existsSync(distPath)) {\n console.error('\u274C No dist directory found. Run \"meno build\" first.');\n process.exit(1);\n }\n\n console.log(`\uD83D\uDCC1 Serving built files from: ${distPath}`);\n const server = await startStaticServer(distPath);\n console.log(`\uD83D\uDE80 Static server running at http://localhost:${server.port}`);\n\n // Keep the process alive\n await new Promise(() => {});\n}\n\nasync function runInit(projectName?: string) {\n if (!projectName) {\n console.error('\u274C Please provide a project name: meno init <project-name>');\n process.exit(1);\n }\n\n const projectPath = resolve(process.cwd(), projectName);\n\n if (existsSync(projectPath)) {\n console.error(`\u274C Directory \"${projectName}\" already exists.`);\n process.exit(1);\n }\n\n console.log(`\\n\uD83D\uDE80 Creating new meno project: ${projectName}\\n`);\n\n // Create project structure\n mkdirSync(projectPath, { recursive: true });\n mkdirSync(join(projectPath, 'pages'));\n mkdirSync(join(projectPath, 'components'));\n mkdirSync(join(projectPath, 'fonts'));\n mkdirSync(join(projectPath, 'images'));\n\n // Create default project.config.json\n const defaultConfig = {\n fonts: [],\n editor: {\n theme: 'dark'\n }\n };\n writeFileSync(\n join(projectPath, 'project.config.json'),\n JSON.stringify(defaultConfig, null, 2)\n );\n\n // Create default colors.json\n const defaultColors = {\n default: 'light',\n themes: {\n light: {\n label: 'Light',\n colors: {\n text: '#1f2937',\n bg: '#ffffff'\n }\n }\n }\n };\n writeFileSync(\n join(projectPath, 'colors.json'),\n JSON.stringify(defaultColors, null, 2)\n );\n\n // Create package.json for deployment\n const packageJson = {\n name: projectName,\n version: '1.0.0',\n private: true,\n scripts: {\n dev: 'meno dev',\n build: 'meno build',\n },\n dependencies: {\n 'meno-core': '^1.0.0'\n }\n };\n writeFileSync(\n join(projectPath, 'package.json'),\n JSON.stringify(packageJson, null, 2)\n );\n\n // Create .claude/tools/ with screenshot tool\n mkdirSync(join(projectPath, '.claude', 'tools'), { recursive: true });\n\n const screenshotToolSrc = join(import.meta.dirname, '..', '..', '..', 'example', '.claude', 'tools', 'screenshot.mjs');\n if (existsSync(screenshotToolSrc)) {\n cpSync(screenshotToolSrc, join(projectPath, '.claude', 'tools', 'screenshot.mjs'));\n }\n\n // Create CLAUDE.md with project instructions\n const claudeMd = `# ${projectName}\n\nA Meno project - visual editor that generates websites from JSON files.\n\n## Dev Server\n\n\\`\\`\\`bash\nbun run dev # Start dev server on port 3000\n\\`\\`\\`\n\n## Screenshot Tool\n\nTake a screenshot of any element by its node ID:\n\\`\\`\\`bash\nnpx puppeteer browsers install chrome && node .claude/tools/screenshot.mjs <nodeId> --page /about\n\\`\\`\\`\nNode IDs can be found in the page JSON files under the \\`id\\` field of each node.\n`;\n writeFileSync(join(projectPath, 'CLAUDE.md'), claudeMd);\n\n // Create .gitignore\n const gitignore = `# Dependencies\nnode_modules/\n\n# Build output\ndist/\n\n# OS files\n.DS_Store\n`;\n writeFileSync(\n join(projectPath, '.gitignore'),\n gitignore\n );\n\n // Create netlify.toml\n const netlifyConfig = `[build]\n command = \"bun install && bun run build\"\n publish = \"dist\"\n\n[build.environment]\n BUN_VERSION = \"1\"\n`;\n writeFileSync(\n join(projectPath, 'netlify.toml'),\n netlifyConfig\n );\n\n // Create vercel.json\n const vercelConfig = {\n buildCommand: 'bun run build',\n outputDirectory: 'dist',\n installCommand: 'bun install'\n };\n writeFileSync(\n join(projectPath, 'vercel.json'),\n JSON.stringify(vercelConfig, null, 2)\n );\n\n // Create wrangler.toml for Cloudflare Pages\n const cloudflareConfig = `name = \"${projectName}\"\ncompatibility_date = \"2024-01-01\"\npages_build_output_dir = \"dist\"\n\n[build]\ncommand = \"bun install && bun run build\"\n`;\n writeFileSync(\n join(projectPath, 'wrangler.toml'),\n cloudflareConfig\n );\n\n // Create default index page\n const defaultPage = {\n meta: {\n title: 'Your Project Title',\n description: 'Your Project Description',\n keywords: '',\n ogTitle: 'Your Project Title',\n ogDescription: 'Your Project Description',\n ogType: 'website'\n },\n root: {\n type: 'node',\n tag: 'div',\n style: {\n base: {\n padding: '40px'\n },\n tablet: {},\n mobile: {}\n },\n children: [\n {\n type: 'node',\n tag: 'h1',\n style: {\n base: {}\n },\n children: 'Hello'\n }\n ]\n }\n };\n writeFileSync(\n join(projectPath, 'pages', 'index.json'),\n JSON.stringify(defaultPage, null, 2)\n );\n\n console.log('\u2705 Created project structure:');\n console.log(` ${projectName}/`);\n console.log(' \u251C\u2500\u2500 .claude/');\n console.log(' \u2502 \u2514\u2500\u2500 tools/');\n console.log(' \u2502 \u2514\u2500\u2500 screenshot.mjs');\n console.log(' \u251C\u2500\u2500 pages/');\n console.log(' \u2502 \u2514\u2500\u2500 index.json');\n console.log(' \u251C\u2500\u2500 components/');\n console.log(' \u251C\u2500\u2500 fonts/');\n console.log(' \u251C\u2500\u2500 images/');\n console.log(' \u251C\u2500\u2500 colors.json');\n console.log(' \u251C\u2500\u2500 project.config.json');\n console.log(' \u251C\u2500\u2500 package.json');\n console.log(' \u251C\u2500\u2500 CLAUDE.md');\n console.log(' \u251C\u2500\u2500 netlify.toml');\n console.log(' \u251C\u2500\u2500 vercel.json');\n console.log(' \u251C\u2500\u2500 wrangler.toml');\n console.log(' \u2514\u2500\u2500 .gitignore');\n console.log('\\n\uD83C\uDF89 Project created successfully!\\n');\n console.log('Requirements:');\n console.log(' Bun - https://bun.sh');\n console.log('');\n console.log('Next steps:');\n console.log(` cd ${projectName}`);\n console.log(' bun install # Install dependencies');\n console.log(' bun run dev # Start dev server');\n console.log('');\n console.log('Deploy:');\n console.log(' Push to GitHub and connect to Netlify/Vercel/Cloudflare');\n console.log(' Config files included - auto-detected!');\n console.log('');\n}\n\n// Main\nswitch (command) {\n case 'dev':\n runDev();\n break;\n case 'build':\n runBuild(args.includes('--dev'));\n break;\n case 'serve':\n runServe();\n break;\n case 'init':\n runInit(args[1]);\n break;\n case '--help':\n case '-h':\n case undefined:\n printHelp();\n break;\n default:\n console.error(`Unknown command: ${command}`);\n printHelp();\n process.exit(1);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/build-static.js
CHANGED
|
@@ -9,17 +9,17 @@ import {
|
|
|
9
9
|
hashContent,
|
|
10
10
|
injectTrackingScript,
|
|
11
11
|
isCMSPage
|
|
12
|
-
} from "./chunks/chunk-
|
|
13
|
-
import "./chunks/chunk-
|
|
14
|
-
import "./chunks/chunk-
|
|
12
|
+
} from "./chunks/chunk-EQOSDQS2.js";
|
|
13
|
+
import "./chunks/chunk-SK3TLNUP.js";
|
|
14
|
+
import "./chunks/chunk-MKB2J6AD.js";
|
|
15
15
|
import "./chunks/chunk-YSZ5IUFM.js";
|
|
16
16
|
import "./chunks/chunk-WQFG7PAH.js";
|
|
17
|
-
import "./chunks/chunk-
|
|
18
|
-
import "./chunks/chunk-
|
|
19
|
-
import "./chunks/chunk-
|
|
17
|
+
import "./chunks/chunk-S2HXJTAF.js";
|
|
18
|
+
import "./chunks/chunk-IBR2F4IL.js";
|
|
19
|
+
import "./chunks/chunk-IGVQF5GY.js";
|
|
20
20
|
import "./chunks/chunk-PGH3ATYI.js";
|
|
21
21
|
import "./chunks/chunk-UB44F4Z2.js";
|
|
22
|
-
import "./chunks/chunk-
|
|
22
|
+
import "./chunks/chunk-LBWIHPN7.js";
|
|
23
23
|
import "./chunks/chunk-KSBZ2L7C.js";
|
|
24
24
|
export {
|
|
25
25
|
buildCMSItemPath,
|