meno-core 1.0.52 → 1.0.53
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-astro.ts +183 -13
- package/build-next.ts +1361 -0
- package/build-static.ts +7 -5
- package/dist/bin/cli.js +2 -2
- package/dist/build-static.js +6 -6
- package/dist/chunks/{chunk-HNLUO36W.js → chunk-GZHGVVW3.js} +2 -2
- package/dist/chunks/chunk-GZHGVVW3.js.map +7 -0
- package/dist/chunks/{chunk-LPVETICS.js → chunk-H3GJ4H2U.js} +185 -1
- package/dist/chunks/chunk-H3GJ4H2U.js.map +7 -0
- package/dist/chunks/{chunk-CXCBV2M7.js → chunk-IGYR22T6.js} +76 -270
- package/dist/chunks/chunk-IGYR22T6.js.map +7 -0
- package/dist/chunks/{chunk-LHLHPYSP.js → chunk-JGP5A3Y5.js} +12 -11
- package/dist/chunks/chunk-JGP5A3Y5.js.map +7 -0
- package/dist/chunks/{chunk-7NIC4I3V.js → chunk-JGWFTO6P.js} +167 -21
- package/dist/chunks/chunk-JGWFTO6P.js.map +7 -0
- package/dist/chunks/{chunk-EDQSMAMP.js → chunk-O3NAGJP4.js} +85 -4
- package/dist/chunks/chunk-O3NAGJP4.js.map +7 -0
- package/dist/chunks/{chunk-H4JSCDNW.js → chunk-QB2LNO4W.js} +24 -1
- package/dist/chunks/chunk-QB2LNO4W.js.map +7 -0
- package/dist/chunks/{chunk-A725KYFK.js → chunk-R6XHAFBF.js} +561 -112
- package/dist/chunks/chunk-R6XHAFBF.js.map +7 -0
- package/dist/chunks/{chunk-J23ZX5AP.js → chunk-X754AHS5.js} +277 -1
- package/dist/chunks/chunk-X754AHS5.js.map +7 -0
- package/dist/chunks/{chunk-2QK6U5UK.js → chunk-YBLHKYFF.js} +12 -2
- package/dist/chunks/chunk-YBLHKYFF.js.map +7 -0
- package/dist/chunks/{constants-GWBAD66U.js → constants-STK2YBIW.js} +2 -2
- package/dist/entries/server-router.js +7 -7
- package/dist/lib/client/index.js +354 -59
- package/dist/lib/client/index.js.map +4 -4
- package/dist/lib/server/index.js +1458 -190
- package/dist/lib/server/index.js.map +4 -4
- package/dist/lib/shared/index.js +202 -34
- package/dist/lib/shared/index.js.map +4 -4
- package/dist/lib/test-utils/index.js +1 -1
- package/entries/client-router.tsx +5 -165
- package/lib/client/ErrorBoundary.test.tsx +27 -25
- package/lib/client/ErrorBoundary.tsx +34 -19
- package/lib/client/core/ComponentBuilder.ts +19 -2
- package/lib/client/core/builders/embedBuilder.ts +8 -4
- package/lib/client/core/builders/listBuilder.ts +23 -4
- package/lib/client/fontFamiliesService.test.ts +76 -0
- package/lib/client/fontFamiliesService.ts +69 -0
- package/lib/client/hmrCssReload.ts +160 -0
- package/lib/client/hooks/useColorVariables.ts +2 -0
- package/lib/client/index.ts +4 -0
- package/lib/client/meno-filter/ui.ts +2 -0
- package/lib/client/routing/RouteLoader.test.ts +2 -2
- package/lib/client/routing/RouteLoader.ts +8 -2
- package/lib/client/routing/Router.tsx +81 -15
- package/lib/client/scripts/ScriptExecutor.test.ts +143 -0
- package/lib/client/scripts/ScriptExecutor.ts +56 -2
- package/lib/client/styles/StyleInjector.ts +20 -5
- package/lib/client/styles/UtilityClassCollector.ts +7 -1
- package/lib/client/styles/cspNonce.test.ts +67 -0
- package/lib/client/styles/cspNonce.ts +63 -0
- package/lib/client/templateEngine.test.ts +80 -0
- package/lib/client/templateEngine.ts +5 -0
- package/lib/server/astro/cmsPageEmitter.ts +35 -5
- package/lib/server/astro/componentEmitter.ts +61 -5
- package/lib/server/astro/nodeToAstro.ts +149 -11
- package/lib/server/astro/normalizeOrphanTemplateProps.test.ts +264 -0
- package/lib/server/astro/normalizeOrphanTemplateProps.ts +184 -0
- package/lib/server/createServer.ts +11 -0
- package/lib/server/draftPageStore.ts +49 -0
- package/lib/server/fileWatcher.ts +62 -2
- package/lib/server/index.ts +13 -1
- package/lib/server/providers/fileSystemPageProvider.ts +8 -0
- package/lib/server/routes/api/components.ts +9 -4
- package/lib/server/routes/api/core-routes.ts +2 -2
- package/lib/server/routes/api/pages.ts +14 -22
- package/lib/server/routes/api/shared.ts +56 -0
- package/lib/server/routes/index.ts +90 -0
- package/lib/server/routes/pages.ts +13 -6
- package/lib/server/services/componentService.test.ts +199 -2
- package/lib/server/services/componentService.ts +354 -49
- package/lib/server/services/fileWatcherService.ts +4 -24
- package/lib/server/services/pageService.test.ts +23 -0
- package/lib/server/services/pageService.ts +124 -6
- package/lib/server/ssr/attributeBuilder.ts +8 -2
- package/lib/server/ssr/buildErrorOverlay.ts +1 -1
- package/lib/server/ssr/errorOverlay.test.ts +21 -2
- package/lib/server/ssr/errorOverlay.ts +38 -11
- package/lib/server/ssr/htmlGenerator.test.ts +53 -13
- package/lib/server/ssr/htmlGenerator.ts +71 -27
- package/lib/server/ssr/liveReloadIntegration.test.ts +123 -2
- package/lib/server/ssr/ssrRenderer.test.ts +67 -0
- package/lib/server/ssr/ssrRenderer.ts +94 -9
- package/lib/server/websocketManager.ts +0 -1
- package/lib/shared/componentRefs.ts +45 -0
- package/lib/shared/constants.ts +8 -0
- package/lib/shared/cssGeneration.ts +2 -0
- package/lib/shared/cssProperties.ts +184 -0
- package/lib/shared/expressionEvaluator.ts +54 -0
- package/lib/shared/fontCss.ts +101 -0
- package/lib/shared/fontLoader.ts +8 -86
- package/lib/shared/friendlyError.test.ts +87 -0
- package/lib/shared/friendlyError.ts +121 -0
- package/lib/shared/hrefRefs.test.ts +130 -0
- package/lib/shared/hrefRefs.ts +100 -0
- package/lib/shared/index.ts +52 -0
- package/lib/shared/inlineSvgStyleRules.test.ts +108 -0
- package/lib/shared/inlineSvgStyleRules.ts +134 -0
- package/lib/shared/interfaces/contentProvider.ts +13 -0
- package/lib/shared/itemTemplateUtils.test.ts +14 -0
- package/lib/shared/itemTemplateUtils.ts +4 -1
- package/lib/shared/registry/NodeTypeDefinition.ts +1 -1
- package/lib/shared/registry/nodeTypes/LinkNodeType.ts +1 -1
- package/lib/shared/slugTranslator.test.ts +24 -0
- package/lib/shared/slugTranslator.ts +24 -0
- package/lib/shared/styleNodeUtils.ts +4 -1
- package/lib/shared/tree/PathBuilder.test.ts +128 -1
- package/lib/shared/tree/PathBuilder.ts +83 -31
- package/lib/shared/types/comment.ts +99 -0
- package/lib/shared/types/index.ts +12 -0
- package/lib/shared/types/rendering.ts +8 -0
- package/lib/shared/utilityClassConfig.ts +4 -2
- package/lib/shared/utilityClassMapper.test.ts +24 -0
- package/lib/shared/validation/commentValidators.ts +69 -0
- package/lib/shared/validation/index.ts +1 -0
- package/lib/shared/viewportUnits.integration.test.ts +42 -0
- package/lib/shared/viewportUnits.test.ts +103 -0
- package/lib/shared/viewportUnits.ts +63 -0
- package/lib/test-utils/dom-setup.ts +6 -0
- package/package.json +1 -1
- package/dist/chunks/chunk-2QK6U5UK.js.map +0 -7
- package/dist/chunks/chunk-7NIC4I3V.js.map +0 -7
- package/dist/chunks/chunk-A725KYFK.js.map +0 -7
- package/dist/chunks/chunk-CXCBV2M7.js.map +0 -7
- package/dist/chunks/chunk-EDQSMAMP.js.map +0 -7
- package/dist/chunks/chunk-H4JSCDNW.js.map +0 -7
- package/dist/chunks/chunk-HNLUO36W.js.map +0 -7
- package/dist/chunks/chunk-J23ZX5AP.js.map +0 -7
- package/dist/chunks/chunk-LHLHPYSP.js.map +0 -7
- package/dist/chunks/chunk-LPVETICS.js.map +0 -7
- /package/dist/chunks/{constants-GWBAD66U.js.map → constants-STK2YBIW.js.map} +0 -0
|
@@ -2,9 +2,6 @@ import {
|
|
|
2
2
|
CMSService,
|
|
3
3
|
FileSystemCMSProvider,
|
|
4
4
|
clearJSValidationCache,
|
|
5
|
-
collectComponentLibraries,
|
|
6
|
-
extractLibraryOrigins,
|
|
7
|
-
filterLibrariesByContext,
|
|
8
5
|
generateSSRHTML,
|
|
9
6
|
getJSValidationErrors,
|
|
10
7
|
loadComponentDirectory,
|
|
@@ -15,7 +12,7 @@ import {
|
|
|
15
12
|
migrateTemplatesDirectory,
|
|
16
13
|
parseJSON,
|
|
17
14
|
prepareClientData
|
|
18
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-IGYR22T6.js";
|
|
19
16
|
import {
|
|
20
17
|
minifyJS,
|
|
21
18
|
projectPaths
|
|
@@ -23,10 +20,15 @@ import {
|
|
|
23
20
|
import {
|
|
24
21
|
inspect
|
|
25
22
|
} from "./chunk-WQFG7PAH.js";
|
|
23
|
+
import {
|
|
24
|
+
collectComponentLibraries,
|
|
25
|
+
extractLibraryOrigins,
|
|
26
|
+
filterLibrariesByContext
|
|
27
|
+
} from "./chunk-X754AHS5.js";
|
|
26
28
|
import {
|
|
27
29
|
isItemDraftForLocale,
|
|
28
30
|
isItemFullyPublished
|
|
29
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-JGWFTO6P.js";
|
|
30
32
|
import {
|
|
31
33
|
isI18nValue,
|
|
32
34
|
resolveI18nValue
|
|
@@ -518,8 +520,7 @@ ${urlEntries}
|
|
|
518
520
|
`;
|
|
519
521
|
await writeFile(join(distDir, "sitemap.xml"), content, "utf-8");
|
|
520
522
|
}
|
|
521
|
-
function cleanDist() {
|
|
522
|
-
const distDir = projectPaths.dist();
|
|
523
|
+
function cleanDist(distDir = projectPaths.dist()) {
|
|
523
524
|
if (!existsSync(distDir)) {
|
|
524
525
|
mkdirSync(distDir, { recursive: true });
|
|
525
526
|
return;
|
|
@@ -750,7 +751,7 @@ async function generateABFunctions(experiments, distDir) {
|
|
|
750
751
|
const resultsContent = generateResultsFunction();
|
|
751
752
|
await writeFile(join(trackDir, "ab-results.ts"), resultsContent, "utf-8");
|
|
752
753
|
}
|
|
753
|
-
async function buildStaticPages() {
|
|
754
|
+
async function buildStaticPages(outDir) {
|
|
754
755
|
console.log("\u{1F3D7}\uFE0F Building static HTML files...\n");
|
|
755
756
|
buildErrors.length = 0;
|
|
756
757
|
clearJSValidationCache();
|
|
@@ -771,10 +772,10 @@ async function buildStaticPages() {
|
|
|
771
772
|
console.log(`\u{1F310} Locales: ${i18nConfig.locales.map((l) => l.code).join(", ")} (default: ${i18nConfig.defaultLocale})
|
|
772
773
|
`);
|
|
773
774
|
await migrateTemplatesDirectory();
|
|
774
|
-
|
|
775
|
+
const distDir = outDir || projectPaths.dist();
|
|
776
|
+
cleanDist(distDir);
|
|
775
777
|
jsFileCache.clear();
|
|
776
778
|
console.log("\u{1F4E6} Copying assets...");
|
|
777
|
-
const distDir = projectPaths.dist();
|
|
778
779
|
const errorsPath = join(distDir, "_errors.json");
|
|
779
780
|
if (existsSync(errorsPath)) {
|
|
780
781
|
unlinkSync(errorsPath);
|
|
@@ -1132,4 +1133,4 @@ export {
|
|
|
1132
1133
|
injectTrackingScript,
|
|
1133
1134
|
buildStaticPages
|
|
1134
1135
|
};
|
|
1135
|
-
//# sourceMappingURL=chunk-
|
|
1136
|
+
//# sourceMappingURL=chunk-JGP5A3Y5.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../build-static.ts", "../../lib/server/ab/generateFunctions.ts", "../../lib/server/ab/trackingScript.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Static Site Generation Build Script\n * Pre-generates HTML files for all pages at build time\n * CSP-compliant: Extracts JavaScript to external files\n */\n\nimport { existsSync, readdirSync, mkdirSync, rmSync, statSync, copyFileSync, unlinkSync, writeFileSync } from \"fs\";\nimport { writeFile, readFile } from \"fs/promises\";\nimport { join } from \"path\";\nimport type { BuildError, BuildErrorsData } from \"./lib/server/ssr/buildErrorOverlay\";\nimport { createHash } from \"crypto\";\nimport { inspect, minifyJS as runtimeMinifyJS } from './lib/server/runtime';\nimport {\n loadJSONFile,\n loadComponentDirectory,\n mapPageNameToPath,\n parseJSON,\n loadI18nConfig\n} from \"./lib/server/jsonLoader\";\nimport { generateSSRHTML } from \"./lib/server/ssrRenderer\";\nimport type { SSRHTMLResult } from \"./lib/server/ssr/htmlGenerator\";\nimport { prepareClientData, type ClientDataCollection } from \"./lib/server/ssr/clientDataInjector\";\nimport { clearJSValidationCache, getJSValidationErrors } from \"./lib/server/ssr/jsCollector\";\nimport { projectPaths } from \"./lib/server/projectContext\";\nimport { loadProjectConfig } from \"./lib/shared/fontLoader\";\nimport { FileSystemCMSProvider } from \"./lib/server/providers/fileSystemCMSProvider\";\nimport { CMSService } from \"./lib/server/services/cmsService\";\nimport { isI18nValue, resolveI18nValue } from \"./lib/shared/i18n\";\nimport type { ComponentDefinition, JSONPage, CMSSchema, CMSItem, I18nConfig, Experiment } from \"./lib/shared/types\";\nimport { isItemDraftForLocale, isItemFullyPublished } from \"./lib/shared/types\";\nimport type { SlugMap } from \"./lib/shared/slugTranslator\";\nimport { buildItemUrl } from \"./lib/shared/itemTemplateUtils\";\nimport { generateMiddleware, generateTrackFunction, generateResultsFunction } from \"./lib/server/ab/generateFunctions\";\nimport { generateTrackingScript } from \"./lib/server/ab/trackingScript\";\nimport { migrateTemplatesDirectory } from \"./lib/server/migrateTemplates\";\nimport { extractLibraryOrigins, collectComponentLibraries, filterLibrariesByContext } from \"./lib/shared/libraryLoader\";\nimport type { LibrariesConfig } from \"./lib/shared/types/libraries\";\n\n/**\n * Collect build errors for error overlay\n */\nconst buildErrors: BuildError[] = [];\n\n/**\n * Generate short hash from content for file naming\n */\nexport function hashContent(content: string): string {\n return createHash('sha256').update(content).digest('hex').slice(0, 8);\n}\n\n/**\n * Format a Bun build log entry to a readable string\n */\nexport function formatBunLog(log: any): string {\n const parts: string[] = [];\n\n // Try to get position info\n if (log.position) {\n const pos = log.position;\n if (pos.file) parts.push(`File: ${pos.file}`);\n if (pos.line !== undefined) parts.push(`Line ${pos.line}:${pos.column || 0}`);\n if (pos.lineText) parts.push(` ${pos.lineText}`);\n }\n\n // Get the message\n if (log.message) {\n parts.push(log.message);\n } else if (log.text) {\n parts.push(log.text);\n }\n\n // If we couldn't extract anything useful, stringify the whole thing\n if (parts.length === 0) {\n try {\n return JSON.stringify(log, null, 2);\n } catch {\n return String(log);\n }\n }\n\n return parts.join('\\n');\n}\n\n/**\n * Minify JavaScript code using runtime bundler\n * Throws on error instead of silently failing\n */\nasync function minifyJS(code: string): Promise<string> {\n const result = await runtimeMinifyJS(code);\n if (result.success) {\n return result.code;\n }\n throw new Error(`JavaScript minification failed:\\n${result.errors.join('\\n\\n')}`);\n}\n\n/**\n * Track JavaScript files to avoid duplicates\n * Maps content hash -> script path\n */\nconst jsFileCache = new Map<string, string>();\n\n/**\n * Get or create script file path for given JS content\n * Returns the path to reference in HTML\n */\nasync function getScriptPath(jsContent: string, distDir: string): Promise<string> {\n // Minify JavaScript for production\n const minified = await minifyJS(jsContent);\n const hash = hashContent(minified);\n\n // Check if we already wrote this content\n if (jsFileCache.has(hash)) {\n return jsFileCache.get(hash)!;\n }\n\n // Create scripts directory if needed\n const scriptsDir = join(distDir, '_scripts');\n if (!existsSync(scriptsDir)) {\n mkdirSync(scriptsDir, { recursive: true });\n }\n\n // Write minified script file\n const scriptPath = `/_scripts/${hash}.js`;\n const fullPath = join(distDir, '_scripts', `${hash}.js`);\n await writeFile(fullPath, minified, 'utf-8');\n\n // Cache for reuse\n jsFileCache.set(hash, scriptPath);\n\n return scriptPath;\n}\n\n/**\n * Recursively copy directory contents\n */\nfunction copyDirectory(src: string, dest: string): void {\n if (!existsSync(src)) {\n return;\n }\n\n if (!existsSync(dest)) {\n mkdirSync(dest, { recursive: true });\n }\n\n const files = readdirSync(src);\n\n for (const file of files) {\n const srcPath = join(src, file);\n const destPath = join(dest, file);\n const stat = statSync(srcPath);\n\n if (stat.isDirectory()) {\n copyDirectory(srcPath, destPath);\n } else {\n copyFileSync(srcPath, destPath);\n }\n }\n}\n\n\n/**\n * Get locale-specific output path for a page with translated slug support\n * Default locale files go to root, other locales to subdirectories\n * Uses translated slugs from meta.slugs if available\n */\nexport function getLocalizedOutputPath(\n basePath: string,\n locale: string,\n defaultLocale: string,\n distDir: string,\n slugs?: Record<string, string>\n): string {\n // Get translated slug for this locale, or fall back to default path\n let slug: string;\n if (slugs && slugs[locale]) {\n slug = slugs[locale];\n } else if (basePath === \"/\") {\n slug = \"\";\n } else {\n slug = basePath.substring(1);\n }\n\n // Build filename from slug\n const fileName = slug === \"\" ? \"index.html\" : `${slug}.html`;\n\n if (locale === defaultLocale) {\n return `${distDir}/${fileName}`;\n }\n return `${distDir}/${locale}/${fileName}`;\n}\n\n/**\n * Get display path for logging (the actual URL the user will visit)\n */\nexport function getDisplayPath(\n basePath: string,\n locale: string,\n defaultLocale: string,\n slugs?: Record<string, string>\n): string {\n // Get translated slug for this locale\n let slug: string;\n if (slugs && slugs[locale]) {\n slug = slugs[locale];\n } else if (basePath === \"/\") {\n slug = \"\";\n } else {\n slug = basePath.substring(1);\n }\n\n if (locale === defaultLocale) {\n return slug === \"\" ? \"/\" : `/${slug}`;\n }\n return slug === \"\" ? `/${locale}` : `/${locale}/${slug}`;\n}\n\n/**\n * Generate robots.txt with sensible defaults\n */\nexport async function generateRobotsTxt(siteUrl: string, distDir: string): Promise<void> {\n const content = `User-agent: *\nAllow: /\n\nSitemap: ${siteUrl}/sitemap.xml\n`;\n await writeFile(join(distDir, 'robots.txt'), content, 'utf-8');\n}\n\n/**\n * Generate sitemap.xml from collected URLs\n */\nexport async function generateSitemap(urls: string[], siteUrl: string, distDir: string): Promise<void> {\n // Sort URLs for deterministic output\n const sortedUrls = [...urls].sort();\n\n const urlEntries = sortedUrls\n .map(url => ` <url><loc>${siteUrl}${url}</loc></url>`)\n .join('\\n');\n\n const content = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n${urlEntries}\n</urlset>\n`;\n await writeFile(join(distDir, 'sitemap.xml'), content, 'utf-8');\n}\n\n/**\n * Clean dist directory, keeping only production files\n */\nfunction cleanDist(distDir: string = projectPaths.dist()): void {\n if (!existsSync(distDir)) {\n mkdirSync(distDir, { recursive: true });\n return;\n }\n\n const files = readdirSync(distDir);\n let cleaned = 0;\n\n for (const file of files) {\n // Keep fonts, images, icons, assets, and videos\n if (\n file === \"fonts\" ||\n file === \"images\" ||\n file === \"icons\" ||\n file === \"assets\" ||\n file === \"videos\"\n ) {\n continue;\n }\n\n // Remove everything else (editor files, old HTML, etc.)\n try {\n const filePath = join(distDir, file);\n const stat = statSync(filePath);\n\n if (stat.isDirectory()) {\n rmSync(filePath, { recursive: true, force: true });\n } else {\n rmSync(filePath, { force: true });\n }\n cleaned++;\n } catch (error) {\n console.warn(`\u26A0\uFE0F Could not remove ${file}:`, error);\n }\n }\n\n if (cleaned > 0) {\n console.log(`\uD83E\uDDF9 Cleaned ${cleaned} file(s) from dist\\n`);\n }\n}\n\n/**\n * Check if a page is a CMS template\n */\nexport function isCMSPage(pageData: JSONPage): boolean {\n return pageData.meta?.source === 'cms' && !!pageData.meta?.cms;\n}\n\n/**\n * Build URL path for a CMS item based on the URL pattern\n * Uses schema.slugField to get the slug value, supporting i18n slugs\n */\nexport function buildCMSItemPath(\n urlPattern: string,\n item: CMSItem,\n slugField: string,\n locale: string,\n i18nConfig: I18nConfig\n): string {\n // Get slug from the schema-defined slugField, fall back to _slug or _id\n let slug = item[slugField] ?? item._slug ?? item._id;\n\n // Resolve i18n slug to locale-specific value\n if (isI18nValue(slug)) {\n slug = resolveI18nValue(slug, locale, i18nConfig) as string;\n }\n\n return urlPattern.replace('{{slug}}', String(slug));\n}\n\n/**\n * Generate static JSON data files for collections with 'static' strategy\n * Output: /data/{collection}/index.json\n */\nasync function generateStaticDataFiles(\n staticCollections: Map<string, ClientDataCollection>,\n distDir: string\n): Promise<void> {\n if (staticCollections.size === 0) return;\n\n console.log(`\\n\uD83D\uDCE6 Generating static data files...`);\n\n for (const [collectionId, data] of staticCollections) {\n const dataDir = join(distDir, 'data', collectionId);\n if (!existsSync(dataDir)) {\n mkdirSync(dataDir, { recursive: true });\n }\n const jsonPath = join(dataDir, 'index.json');\n await writeFile(jsonPath, JSON.stringify(data.items), 'utf-8');\n console.log(` \u2705 /data/${collectionId}/index.json (${data.items.length} items)`);\n }\n}\n\n/**\n * Build CMS templates from root templates/ directory\n */\nasync function buildCMSTemplates(\n templatesDir: string,\n globalComponents: Record<string, ComponentDefinition>,\n i18nConfig: I18nConfig,\n slugMappings: SlugMap[],\n distDir: string,\n cmsService: CMSService,\n generatedUrls: Set<string>,\n staticCollections: Map<string, ClientDataCollection>,\n siteUrl?: string,\n abTrackingScript?: string | null\n): Promise<{ success: number; errors: number }> {\n let successCount = 0;\n let errorCount = 0;\n\n if (!existsSync(templatesDir)) {\n return { success: 0, errors: 0 };\n }\n\n const templateFiles = readdirSync(templatesDir).filter(f => f.endsWith('.json'));\n\n if (templateFiles.length === 0) {\n return { success: 0, errors: 0 };\n }\n\n console.log(`\\n\uD83D\uDCDD Processing ${templateFiles.length} CMS template(s)...\\n`);\n\n for (const file of templateFiles) {\n const templateContent = await loadJSONFile(join(templatesDir, file));\n if (!templateContent) continue;\n\n try {\n const pageData = parseJSON<JSONPage>(templateContent);\n\n // Skip draft templates in production (not in dev mode)\n const isDevBuild = process.env.MENO_DEV_BUILD === 'true';\n if (pageData.meta?.draft === true && !isDevBuild) {\n console.log(`\u23ED\uFE0F Skipping draft template: ${file}`);\n continue;\n }\n\n if (!isCMSPage(pageData)) {\n console.warn(`\u26A0\uFE0F ${file} is in templates/ but missing meta.source: \"cms\"`);\n continue;\n }\n\n const cmsSchema = pageData.meta!.cms as CMSSchema;\n console.log(`\uD83D\uDCDD CMS Collection: ${cmsSchema.id}`);\n\n // Use shared cmsService to get items\n const items = await cmsService.queryItems({ collection: cmsSchema.id });\n\n if (items.length === 0) {\n console.log(` \u26A0\uFE0F No items found in cms/${cmsSchema.id}/`);\n continue;\n }\n\n console.log(` Found ${items.length} item(s)`);\n\n // Prepare client data if clientData is enabled\n // Filter out fully-draft items from client data (client data is locale-agnostic)\n let clientDataCollections: Map<string, ClientDataCollection> | undefined;\n if (cmsSchema.clientData?.enabled) {\n const publishedItems = items.filter(item => isItemFullyPublished(item));\n const clientData = prepareClientData(cmsSchema.id, publishedItems, cmsSchema.clientData);\n if (clientData) {\n if (clientData.strategy === 'inline') {\n // Inline data embedded in HTML\n clientDataCollections = new Map([[cmsSchema.id, clientData]]);\n console.log(` \uD83D\uDCE6 Client data (inline): ${clientData.items.length} items (${clientData.config.fields?.length || 'all'} fields)`);\n } else if (clientData.strategy === 'static') {\n // Static data written to separate file\n staticCollections.set(cmsSchema.id, clientData);\n console.log(` \uD83D\uDCE6 Client data (static): ${clientData.items.length} items \u2192 /data/${cmsSchema.id}/index.json`);\n }\n }\n }\n\n for (const item of items) {\n for (const localeConfig of i18nConfig.locales) {\n const locale = localeConfig.code;\n\n // Skip draft items per locale in production builds\n const isDevBuild = process.env.MENO_DEV_BUILD === 'true';\n if (!isDevBuild && isItemDraftForLocale(item, locale)) {\n console.log(` \u23ED\uFE0F Skipping draft: ${item._filename || item._id} [${locale}]`);\n continue;\n }\n\n const baseUrl = siteUrl || \"\";\n const itemPath = buildCMSItemPath(cmsSchema.urlPattern, item, cmsSchema.slugField, locale, i18nConfig);\n\n // Create CMS item with computed _url for {{cms._url}} template access\n const itemWithUrl: CMSItem = { ...item, _url: itemPath };\n\n // Generate HTML with JS returned separately (CSP-compliant)\n const result = await generateSSRHTML({\n pageData,\n globalComponents,\n pagePath: itemPath,\n baseUrl,\n useBuiltBundle: true,\n locale,\n slugMappings,\n cmsContext: { cms: itemWithUrl },\n cmsService,\n returnSeparateJS: true,\n pageLibraries: pageData.meta?.libraries,\n pageCustomCode: pageData.meta?.customCode,\n clientDataCollections,\n isProductionBuild: true,\n }) as SSRHTMLResult;\n\n // If there's JavaScript, write to external file and update HTML\n let finalHtml = result.html;\n if (result.javascript) {\n const scriptPath = await getScriptPath(result.javascript, distDir);\n finalHtml = finalHtml.replace('</body>', ` <script src=\"${scriptPath}\" defer></script>\\n</body>`);\n }\n\n // Inject A/B tracking script if experiments are running\n if (abTrackingScript) {\n finalHtml = injectTrackingScript(finalHtml, abTrackingScript);\n }\n\n const outputPath = locale === i18nConfig.defaultLocale\n ? `${distDir}${itemPath}.html`\n : `${distDir}/${locale}${itemPath}.html`;\n\n const outputDir = outputPath.substring(0, outputPath.lastIndexOf('/'));\n if (outputDir && !existsSync(outputDir)) {\n mkdirSync(outputDir, { recursive: true });\n }\n\n await writeFile(outputPath, finalHtml, 'utf-8');\n\n const displayPath = locale === i18nConfig.defaultLocale ? itemPath : `/${locale}${itemPath}`;\n generatedUrls.add(displayPath);\n console.log(` \u2705 ${displayPath}`);\n successCount++;\n }\n }\n } catch (error: any) {\n // Capture full error with as much detail as possible\n let errorMessage: string;\n\n if (error instanceof Error) {\n // Check for AggregateError (multiple errors)\n if ('errors' in error && Array.isArray(error.errors)) {\n errorMessage = error.errors.map((e: any) => e.stack || e.message || String(e)).join('\\n\\n');\n }\n // Check for cause chain\n else if (error.cause) {\n const causeMsg = error.cause instanceof Error\n ? (error.cause.stack || error.cause.message)\n : String(error.cause);\n errorMessage = `${error.stack || error.message}\\n\\nCaused by:\\n${causeMsg}`;\n }\n // Bun's BuildMessage has logs array\n else if ('logs' in error && Array.isArray(error.logs)) {\n errorMessage = error.logs.map(formatBunLog).join('\\n\\n');\n }\n else {\n errorMessage = error.stack || error.message;\n }\n } else if (typeof error === 'object' && error !== null) {\n // Bun BuildOutput has logs\n if (error.logs && Array.isArray(error.logs)) {\n errorMessage = error.logs.map(formatBunLog).join('\\n\\n');\n } else {\n errorMessage = String(error);\n }\n } else {\n errorMessage = String(error);\n }\n\n // If we still just have \"Bundle failed\", try to get more from inspect\n if (errorMessage === 'Bundle failed' || errorMessage.includes('Bundle failed\\n')) {\n try {\n const inspected = inspect(error);\n if (inspected && inspected !== '[object Object]' && inspected.length > errorMessage.length) {\n errorMessage = inspected;\n }\n } catch {}\n }\n\n console.error(`\u274C Error processing ${file}:`, error);\n buildErrors.push({\n file: `templates/${file}`,\n message: errorMessage,\n type: errorMessage.includes('minification') || errorMessage.includes('minify') ? 'minify' : 'cms',\n });\n errorCount++;\n }\n }\n\n return { success: successCount, errors: errorCount };\n}\n\n/**\n * Load running experiments from experiments.json\n */\nasync function loadRunningExperiments(): Promise<Experiment[]> {\n const experimentsPath = join(projectPaths.project, 'experiments.json');\n if (!existsSync(experimentsPath)) return [];\n\n try {\n const content = await readFile(experimentsPath, 'utf-8');\n const data = JSON.parse(content);\n const experiments: Experiment[] = data.experiments || [];\n return experiments.filter(e => e.status === 'running');\n } catch {\n return [];\n }\n}\n\n/**\n * Inject A/B tracking script into HTML before </head>\n */\nexport function injectTrackingScript(html: string, trackingJs: string): string {\n const scriptTag = `<script>${trackingJs}</script>`;\n return html.replace('</head>', `${scriptTag}\\n</head>`);\n}\n\n/**\n * Generate A/B testing Cloudflare Functions into dist/functions/\n */\nasync function generateABFunctions(experiments: Experiment[], distDir: string): Promise<void> {\n // Generate middleware\n const middlewareContent = generateMiddleware(experiments);\n if (middlewareContent) {\n const middlewarePath = join(distDir, 'functions', '_middleware.ts');\n const middlewareDir = join(distDir, 'functions');\n if (!existsSync(middlewareDir)) {\n mkdirSync(middlewareDir, { recursive: true });\n }\n await writeFile(middlewarePath, middlewareContent, 'utf-8');\n }\n\n // Generate tracking endpoint\n const trackContent = generateTrackFunction();\n const trackDir = join(distDir, 'functions', 'api');\n if (!existsSync(trackDir)) {\n mkdirSync(trackDir, { recursive: true });\n }\n await writeFile(join(trackDir, 'ab-track.ts'), trackContent, 'utf-8');\n\n // Generate results endpoint\n const resultsContent = generateResultsFunction();\n await writeFile(join(trackDir, 'ab-results.ts'), resultsContent, 'utf-8');\n}\n\n/**\n * Main build function\n */\nexport async function buildStaticPages(outDir?: string): Promise<void> {\n console.log(\"\uD83C\uDFD7\uFE0F Building static HTML files...\\n\");\n\n // Clear previous build errors and JS validation cache\n buildErrors.length = 0;\n clearJSValidationCache();\n\n // Reset configService to ensure it loads from the correct project directory\n const { configService } = await import(\"./lib/server/services/configService\");\n configService.reset();\n\n // Load project config first\n const projectConfig = await loadProjectConfig();\n const siteUrl = (projectConfig as { siteUrl?: string }).siteUrl?.replace(/\\/$/, ''); // Remove trailing slash\n\n // Track all generated URLs for sitemap\n const generatedUrls = new Set<string>();\n\n // Load running A/B experiments (if any)\n const runningExperiments = await loadRunningExperiments();\n let trackingScript: string | null = null;\n if (runningExperiments.length > 0) {\n const exp = runningExperiments[0]; // Use first running experiment\n trackingScript = generateTrackingScript(exp.id, exp.conversionGoals);\n console.log(`\uD83E\uDDEA A/B experiment active: \"${exp.name}\" (${exp.variants.length} variant(s))\\n`);\n }\n\n // Load i18n config for multi-locale build\n const i18nConfig = await loadI18nConfig();\n console.log(`\uD83C\uDF10 Locales: ${i18nConfig.locales.map(l => l.code).join(\", \")} (default: ${i18nConfig.defaultLocale})\\n`);\n\n // Auto-migrate pages/templates/ \u2192 templates/ if needed\n await migrateTemplatesDirectory();\n\n // Resolve output directory. Defaults to <project>/dist; callers (e.g. the\n // Cloudflare deploy) may pass a temp dir to avoid leaving a dist/ in the project.\n const distDir = outDir || projectPaths.dist();\n\n // Clean dist directory (removes editor files, old HTML)\n cleanDist(distDir);\n\n // Clear the JS file cache since cleanDist() removed _scripts/\n // Without this, cached entries would skip file creation on subsequent builds\n jsFileCache.clear();\n\n // Copy fonts, images, icons, and functions directories to dist\n console.log(\"\uD83D\uDCE6 Copying assets...\");\n\n // Delete old _errors.json if it exists (start fresh)\n const errorsPath = join(distDir, '_errors.json');\n if (existsSync(errorsPath)) {\n unlinkSync(errorsPath);\n }\n copyDirectory(projectPaths.fonts(), join(distDir, \"fonts\"));\n copyDirectory(projectPaths.images(), join(distDir, \"images\"));\n copyDirectory(projectPaths.icons(), join(distDir, \"icons\"));\n copyDirectory(projectPaths.assets(), join(distDir, \"assets\"));\n copyDirectory(projectPaths.videos(), join(distDir, \"videos\"));\n\n // Copy libraries folder (downloaded external JS/CSS files)\n const librariesDir = join(projectPaths.project, \"libraries\");\n if (existsSync(librariesDir)) {\n copyDirectory(librariesDir, join(distDir, \"libraries\"));\n }\n\n // Copy functions folder for Cloudflare Pages\n const functionsDir = projectPaths.functions();\n if (existsSync(functionsDir)) {\n copyDirectory(functionsDir, join(distDir, \"functions\"));\n }\n\n // Copy user-created root files for static hosting\n const hostingFiles: string[] = [];\n const rootFilesToCopy = [\n '_headers', // Netlify/Cloudflare headers\n '_redirects', // Netlify/Cloudflare redirects\n 'llms.txt', // LLM context\n 'humans.txt', // Team credits\n 'ads.txt', // Ad verification\n 'security.txt', // Security contact\n 'CNAME', // GitHub Pages domain\n 'manifest.json', // PWA manifest\n 'site.webmanifest', // PWA manifest (alt)\n ];\n\n for (const file of rootFilesToCopy) {\n const filePath = join(projectPaths.project, file);\n if (existsSync(filePath)) {\n copyFileSync(filePath, join(distDir, file));\n hostingFiles.push(file);\n }\n }\n\n // Copy .well-known directory if exists\n const wellKnownDir = join(projectPaths.project, '.well-known');\n if (existsSync(wellKnownDir)) {\n copyDirectory(wellKnownDir, join(distDir, '.well-known'));\n hostingFiles.push('.well-known/');\n }\n\n const parts = ['Assets'];\n if (existsSync(functionsDir)) parts.push('functions');\n if (hostingFiles.length > 0) parts.push(hostingFiles.join(', '));\n console.log(`\u2705 ${parts.join(', ')} copied\\n`);\n\n // Load all global components\n const { components, warnings, errors } = await loadComponentDirectory(projectPaths.components());\n const globalComponents: Record<string, ComponentDefinition> = {};\n components.forEach((value, key) => {\n globalComponents[key] = value;\n });\n\n for (const warning of warnings) console.warn(`\u26A0\uFE0F ${warning}`);\n for (const error of errors) console.error(`\u274C ${error}`);\n console.log(`\u2705 Loaded ${components.size} global component(s)\\n`);\n\n // Initialize CMS service for CMSList rendering\n const cmsProvider = new FileSystemCMSProvider(projectPaths.templates(), projectPaths.cms());\n const cmsService = new CMSService(cmsProvider);\n await cmsService.initialize();\n console.log(`\u2705 CMS service initialized\\n`);\n\n // Load all pages\n const pagesDir = projectPaths.pages();\n if (!existsSync(pagesDir)) {\n console.error(\"\u274C Pages directory not found!\");\n process.exit(1);\n }\n\n // Recursively collect all .json page files (supports nested folders like pages/a/b.json)\n const pageFiles: string[] = [];\n function scanPagesDir(dir: string, prefix: string): void {\n const entries = readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isFile() && entry.name.endsWith('.json')) {\n pageFiles.push(prefix ? `${prefix}/${entry.name}` : entry.name);\n } else if (entry.isDirectory()) {\n scanPagesDir(join(dir, entry.name), prefix ? `${prefix}/${entry.name}` : entry.name);\n }\n }\n }\n scanPagesDir(pagesDir, '');\n \n if (pageFiles.length === 0) {\n console.warn(\"\u26A0\uFE0F No pages found in ./pages directory\");\n return;\n }\n\n console.log(`\uD83D\uDCC4 Found ${pageFiles.length} page(s) to build\\n`);\n\n // First pass: collect all slug mappings and page-level libraries\n const slugMappings: SlugMap[] = [];\n const allPageLibraries: LibrariesConfig[] = [];\n for (const file of pageFiles) {\n const pageName = file.replace(\".json\", \"\");\n const basePath = mapPageNameToPath(pageName);\n const pageContent = await loadJSONFile(join(pagesDir, file));\n if (pageContent) {\n try {\n const pageData = parseJSON<JSONPage>(pageContent);\n if (pageData.meta?.slugs) {\n const pageId = basePath === '/' ? 'index' : basePath.substring(1);\n slugMappings.push({ pageId, slugs: pageData.meta.slugs });\n }\n if (pageData.meta?.libraries) {\n allPageLibraries.push(pageData.meta.libraries as LibrariesConfig);\n }\n } catch { /* ignore parse errors in first pass */ }\n }\n }\n\n // Generate _headers from CSP config, auto-including library CDN domains\n // Always regenerate when CSP config exists \u2014 overwrites any stale _headers file\n // that may have been copied from the project root\n {\n await configService.load();\n const cspConfig = configService.getCSP();\n if (cspConfig && Object.keys(cspConfig).length > 0) {\n // Collect all library sources: global + component + page-level\n // Note: we concatenate (not mergeLibraries) because _headers applies globally \u2014\n // we need the union of ALL origins, regardless of per-page merge modes\n const globalLibraries = configService.getLibraries();\n const componentLibraries = collectComponentLibraries(globalComponents);\n const allJs = [\n ...(globalLibraries.js || []),\n ...(componentLibraries.js || []),\n ...allPageLibraries.flatMap(p => p.js || []),\n ];\n const allCss = [\n ...(globalLibraries.css || []),\n ...(componentLibraries.css || []),\n ...allPageLibraries.flatMap(p => p.css || []),\n ];\n const allLibs: LibrariesConfig = { js: allJs, css: allCss };\n\n // Filter out CSS libs disabled for build before extracting CSP origins\n const buildLibs = filterLibrariesByContext(allLibs, 'build');\n\n // Extract CDN origins from all library URLs\n const { scriptOrigins, styleOrigins } = extractLibraryOrigins(buildLibs);\n\n const extraScripts = [\n ...(cspConfig.scriptSrc || []),\n ...Array.from(scriptOrigins),\n ].join(' ');\n const extraStyles = [\n ...(cspConfig.styleSrc || []),\n ...Array.from(styleOrigins),\n ].join(' ');\n const extraConnect = cspConfig.connectSrc?.join(' ') || '';\n const extraFrames = cspConfig.frameSrc?.join(' ') || '';\n const extraFonts = cspConfig.fontSrc?.join(' ') || '';\n const extraImgs = cspConfig.imgSrc?.join(' ') || '';\n\n // Production-built pages have NO executable inline scripts: page config,\n // component JS, form handler, and MenoFilter all live in external\n // /_scripts/{hash}.js files (returnSeparateJS: true), and the Meno\n // badge's hover effect is pure CSS. Only `<script type=\"application/json\">`\n // remains inline (used as a data island for MenoFilter), which CSP\n // ignores because it has no executable code. So we can drop\n // `'unsafe-inline'` entirely from script-src in the generated _headers.\n const cspDirectives = [\n \"default-src 'self'\",\n `script-src 'self' https://f.vimeocdn.com https://player.vimeo.com https://www.youtube.com https://s.ytimg.com ${extraScripts}`.trim(),\n `style-src 'self' 'unsafe-inline' https://f.vimeocdn.com ${extraStyles}`.trim(),\n `img-src 'self' data: https: ${extraImgs}`.trim(),\n `connect-src 'self' https://vimeo.com https://*.vimeocdn.com ${extraConnect}`.trim(),\n `frame-src https://player.vimeo.com https://vimeo.com https://www.youtube.com https://www.youtube-nocookie.com ${extraFrames}`.trim(),\n `font-src 'self' data: ${extraFonts}`.trim(),\n \"media-src 'self' https: blob:\"\n ].join('; ');\n\n const headersContent = `/*\\n Content-Security-Policy: ${cspDirectives}\\n`;\n writeFileSync(join(distDir, '_headers'), headersContent);\n console.log(`\u2705 Generated _headers with CSP (auto-included ${scriptOrigins.size + styleOrigins.size} library origin(s))\\n`);\n }\n }\n\n let successCount = 0;\n let errorCount = 0;\n\n // Build each page for each locale\n for (const file of pageFiles) {\n const pageName = file.replace(\".json\", \"\");\n const basePath = mapPageNameToPath(pageName);\n const pageContent = await loadJSONFile(join(pagesDir, file));\n\n if (!pageContent) {\n console.warn(`\u26A0\uFE0F Skipping ${basePath} (empty file)`);\n errorCount++;\n continue;\n }\n\n try {\n const pageData = parseJSON<JSONPage>(pageContent);\n\n // Skip draft pages in production (not in dev mode)\n const isDevBuild = process.env.MENO_DEV_BUILD === 'true';\n if (pageData.meta?.draft === true && !isDevBuild) {\n console.log(`\u23ED\uFE0F Skipping draft: ${basePath}`);\n continue;\n }\n\n // Get translated slugs from page meta (if available)\n const slugs = pageData.meta?.slugs;\n\n // Generate HTML for each locale\n for (const localeConfig of i18nConfig.locales) {\n const locale = localeConfig.code;\n const baseUrl = siteUrl || \"\";\n\n // Build the URL path that will be used for this locale\n const urlPath = getDisplayPath(basePath, locale, i18nConfig.defaultLocale, slugs);\n\n // Generate HTML with JS returned separately (CSP-compliant)\n const result = await generateSSRHTML({\n pageData,\n globalComponents,\n pagePath: urlPath,\n baseUrl,\n useBuiltBundle: true,\n locale,\n slugMappings,\n cmsService,\n returnSeparateJS: true,\n pageLibraries: pageData.meta?.libraries,\n pageCustomCode: pageData.meta?.customCode,\n isProductionBuild: true,\n }) as SSRHTMLResult;\n\n // If there's JavaScript, write to external file and update HTML\n let finalHtml = result.html;\n if (result.javascript) {\n const scriptPath = await getScriptPath(result.javascript, distDir);\n // Insert script reference before </body>\n finalHtml = finalHtml.replace('</body>', ` <script src=\"${scriptPath}\" defer></script>\\n</body>`);\n }\n\n // Inject A/B tracking script if experiments are running\n if (trackingScript) {\n finalHtml = injectTrackingScript(finalHtml, trackingScript);\n }\n\n // Determine locale-specific output path with translated slug\n const outputPath = getLocalizedOutputPath(basePath, locale, i18nConfig.defaultLocale, distDir, slugs);\n\n // Ensure directory exists\n const outputDir = outputPath.substring(0, outputPath.lastIndexOf(\"/\"));\n if (outputDir && !existsSync(outputDir)) {\n mkdirSync(outputDir, { recursive: true });\n }\n\n // Debug: show end of HTML\n if (urlPath === '/') {\n console.log('[DEBUG] Last 500 chars of HTML:', finalHtml.slice(-500));\n }\n\n await writeFile(outputPath, finalHtml, \"utf-8\");\n\n generatedUrls.add(urlPath);\n console.log(`\u2705 Built: ${urlPath} \u2192 ${outputPath}`);\n successCount++;\n }\n\n } catch (error: any) {\n // Capture full error with as much detail as possible\n let errorMessage: string;\n\n if (error instanceof Error) {\n // Check for AggregateError (multiple errors)\n if ('errors' in error && Array.isArray(error.errors)) {\n errorMessage = error.errors.map((e: any) => e.stack || e.message || String(e)).join('\\n\\n');\n }\n // Check for cause chain\n else if (error.cause) {\n const causeMsg = error.cause instanceof Error\n ? (error.cause.stack || error.cause.message)\n : String(error.cause);\n errorMessage = `${error.stack || error.message}\\n\\nCaused by:\\n${causeMsg}`;\n }\n // Bun's BuildMessage has logs array\n else if ('logs' in error && Array.isArray(error.logs)) {\n errorMessage = error.logs.map(formatBunLog).join('\\n\\n');\n }\n else {\n errorMessage = error.stack || error.message;\n }\n } else if (typeof error === 'object' && error !== null) {\n // Bun BuildOutput has logs\n if (error.logs && Array.isArray(error.logs)) {\n errorMessage = error.logs.map(formatBunLog).join('\\n\\n');\n } else {\n errorMessage = String(error);\n }\n } else {\n errorMessage = String(error);\n }\n\n // If we still just have \"Bundle failed\", try to get more from inspect\n if (errorMessage === 'Bundle failed' || errorMessage.includes('Bundle failed\\n')) {\n try {\n const inspected = inspect(error);\n if (inspected && inspected !== '[object Object]' && inspected.length > errorMessage.length) {\n errorMessage = inspected;\n }\n } catch {}\n }\n\n console.error(`\u274C Error building ${basePath}:`, error);\n buildErrors.push({\n file: `pages/${file}`,\n message: errorMessage,\n type: errorMessage.includes('minification') || errorMessage.includes('minify') ? 'minify' : 'render',\n });\n errorCount++;\n }\n }\n\n // Build CMS templates from root templates/ directory\n const templatesDir = projectPaths.templates();\n const staticCollections = new Map<string, ClientDataCollection>();\n const cmsResult = await buildCMSTemplates(\n templatesDir,\n globalComponents,\n i18nConfig,\n slugMappings,\n distDir,\n cmsService,\n generatedUrls,\n staticCollections,\n siteUrl,\n trackingScript\n );\n successCount += cmsResult.success;\n errorCount += cmsResult.errors;\n\n // Generate static data files for collections with 'static' strategy\n await generateStaticDataFiles(staticCollections, distDir);\n\n // Generate A/B testing functions if experiments are running\n if (runningExperiments.length > 0) {\n await generateABFunctions(runningExperiments, distDir);\n console.log(`\\n\uD83E\uDDEA A/B testing functions generated (middleware, tracker, results API)`);\n }\n\n // Generate SEO files (robots.txt and sitemap.xml)\n if (siteUrl) {\n await generateRobotsTxt(siteUrl, distDir);\n await generateSitemap([...generatedUrls], siteUrl, distDir);\n console.log(`\\n\uD83D\uDD0D SEO files generated (robots.txt, sitemap.xml)`);\n } else {\n console.warn(`\\n\u26A0\uFE0F Skipping SEO files: siteUrl not configured in project.config.json`);\n }\n\n console.log(\"\\n\" + \"=\".repeat(50));\n console.log(`\u2728 Build complete!`);\n console.log(` \u2705 Success: ${successCount}`);\n if (errorCount > 0) {\n console.log(` \u274C Errors: ${errorCount}`);\n }\n console.log(`\\n\uD83D\uDCE6 Production files in /dist:`);\n console.log(` - *.html (Static pages with vanilla JS)`);\n console.log(` - fonts/ (Custom fonts)`);\n console.log(` - images/ (Image assets)`);\n console.log(` - icons/ (Favicon and icons)`);\n if (staticCollections.size > 0) {\n console.log(` - data/ (CMS collection data for client filtering)`);\n }\n if (existsSync(functionsDir)) {\n console.log(` - functions/ (Cloudflare Pages Functions)`);\n }\n if (runningExperiments.length > 0) {\n console.log(` - A/B testing (middleware + tracking injected)`);\n }\n if (siteUrl) {\n console.log(` - robots.txt, sitemap.xml (SEO)`);\n }\n console.log(` - No React, no client-router \u2713`);\n\n // Collect component JS validation errors\n const jsErrors = getJSValidationErrors();\n for (const { component, error } of jsErrors) {\n buildErrors.push({\n file: `components/${component}`,\n message: error,\n type: 'minify',\n });\n }\n\n // Write build errors to _errors.json for static server overlay\n if (buildErrors.length > 0) {\n // Deduplicate errors by message (same error may occur on multiple pages)\n const seenMessages = new Set<string>();\n const uniqueErrors = buildErrors.filter(err => {\n if (seenMessages.has(err.message)) return false;\n seenMessages.add(err.message);\n return true;\n });\n\n const errorsData: BuildErrorsData = {\n errors: uniqueErrors,\n timestamp: Date.now(),\n };\n await writeFile(errorsPath, JSON.stringify(errorsData, null, 2), 'utf-8');\n const countMsg = uniqueErrors.length === buildErrors.length\n ? `${uniqueErrors.length} error${uniqueErrors.length === 1 ? '' : 's'}`\n : `${uniqueErrors.length} unique error${uniqueErrors.length === 1 ? '' : 's'} (affected ${buildErrors.length} files)`;\n console.log(`\\n\u26A0\uFE0F Build errors written to dist/_errors.json (${countMsg})`);\n }\n}\n\n\n", "/**\n * A/B Testing Functions Generator\n * Generates Cloudflare Pages Functions for traffic splitting and event tracking\n * Only called at build time when experiments are running\n */\n\nimport type { Experiment } from '../../shared/types/experiments';\n\n/**\n * Generate the _middleware.ts content for traffic splitting\n */\nexport function generateMiddleware(experiments: Experiment[]): string {\n const running = experiments.filter(e => e.status === 'running');\n if (running.length === 0) return '';\n\n // Embed experiment config as JSON\n const configJSON = JSON.stringify(running.map(e => ({\n id: e.id,\n controlBranch: e.controlBranch,\n controlWeight: e.controlWeight,\n variants: e.variants.map(v => ({\n branch: v.branch,\n weight: v.weight,\n deployUrl: v.deployUrl,\n })),\n })));\n\n return `/**\n * A/B Testing Traffic Splitting Middleware\n * Auto-generated by Meno build - do not edit manually\n */\n\ninterface Env {\n AB_DB?: D1Database;\n}\n\ninterface ExperimentConfig {\n id: string;\n controlBranch: string;\n controlWeight: number;\n variants: Array<{ branch: string; weight: number; deployUrl: string }>;\n}\n\nconst EXPERIMENTS: ExperimentConfig[] = ${configJSON};\n\nfunction getCookie(request: Request, name: string): string | null {\n const cookieHeader = request.headers.get('Cookie');\n if (!cookieHeader) return null;\n const match = cookieHeader.match(new RegExp('(?:^|;\\\\\\\\s*)' + name + '=([^;]*)'));\n return match ? decodeURIComponent(match[1]) : null;\n}\n\nfunction assignVariant(experiment: ExperimentConfig): string {\n const rand = Math.random() * 100;\n let cumulative = experiment.controlWeight;\n if (rand < cumulative) return 'control';\n for (const variant of experiment.variants) {\n cumulative += variant.weight;\n if (rand < cumulative) return variant.branch;\n }\n return 'control';\n}\n\nexport async function onRequest(context: { request: Request; next: () => Promise<Response>; env: Env }) {\n const url = new URL(context.request.url);\n\n // Skip API routes and static assets\n if (url.pathname.startsWith('/api/') || url.pathname.match(/\\\\.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|eot)$/)) {\n return context.next();\n }\n\n // Use first running experiment (single experiment at a time for simplicity)\n const experiment = EXPERIMENTS[0];\n if (!experiment) return context.next();\n\n // Check for existing variant assignment (sticky sessions)\n let variant = getCookie(context.request, 'meno_variant');\n\n // If no cookie, assign a variant\n if (!variant) {\n variant = assignVariant(experiment);\n }\n\n let response: Response;\n\n if (variant === 'control') {\n // Control: serve local assets (pass through)\n response = await context.next();\n } else {\n // Variant: proxy to branch preview deploy\n const variantConfig = experiment.variants.find(v => v.branch === variant);\n if (!variantConfig) {\n response = await context.next();\n } else {\n // Fetch from the variant's deploy URL\n const variantUrl = new URL(url.pathname + url.search, variantConfig.deployUrl);\n try {\n const proxyResponse = await fetch(variantUrl.toString(), {\n method: context.request.method,\n headers: context.request.headers,\n });\n response = new Response(proxyResponse.body, {\n status: proxyResponse.status,\n statusText: proxyResponse.statusText,\n headers: new Headers(proxyResponse.headers),\n });\n } catch {\n // Fallback to control if variant fetch fails\n response = await context.next();\n variant = 'control';\n }\n }\n }\n\n // Set variant cookie (30-day expiry)\n const headers = new Headers(response.headers);\n headers.append(\n 'Set-Cookie',\n \\`meno_variant=\\${encodeURIComponent(variant!)}; Path=/; Max-Age=2592000; SameSite=Lax\\`\n );\n\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n}\n`;\n}\n\n/**\n * Generate the api/ab-track.ts content for event collection\n */\nexport function generateTrackFunction(): string {\n return `/**\n * A/B Testing Event Tracker\n * Auto-generated by Meno build - do not edit manually\n * POST /api/ab-track - stores pageview/conversion events in D1\n */\n\ninterface Env {\n AB_DB: D1Database;\n}\n\ninterface TrackEvent {\n experimentId: string;\n visitorId: string;\n variant: string;\n eventType: 'pageview' | 'conversion';\n goalId?: string;\n url?: string;\n}\n\ninterface PagesContext<E = unknown> {\n request: Request;\n env: E;\n params: Record<string, string>;\n waitUntil: (promise: Promise<unknown>) => void;\n}\n\nexport async function onRequestPost(context: PagesContext<Env>): Promise<Response> {\n try {\n const body: TrackEvent = await context.request.json();\n\n // Validate required fields\n if (!body.experimentId || !body.visitorId || !body.variant || !body.eventType) {\n return new Response(null, { status: 400 });\n }\n\n // Validate event type\n if (body.eventType !== 'pageview' && body.eventType !== 'conversion') {\n return new Response(null, { status: 400 });\n }\n\n // Insert event into D1\n await context.env.AB_DB.prepare(\n 'INSERT INTO ab_events (experiment_id, visitor_id, variant, event_type, goal_id, url, timestamp) VALUES (?, ?, ?, ?, ?, ?, ?)'\n ).bind(\n body.experimentId,\n body.visitorId,\n body.variant,\n body.eventType,\n body.goalId || null,\n body.url || null,\n Date.now()\n ).run();\n\n return new Response(null, { status: 204 });\n } catch {\n return new Response(null, { status: 500 });\n }\n}\n`;\n}\n\n/**\n * Generate the api/ab-results.ts content for results aggregation\n */\nexport function generateResultsFunction(): string {\n return `/**\n * A/B Testing Results API\n * Auto-generated by Meno build - do not edit manually\n * GET /api/ab-results?experiment=<id> - returns aggregated results with significance\n */\n\ninterface Env {\n AB_DB: D1Database;\n}\n\ninterface PagesContext<E = unknown> {\n request: Request;\n env: E;\n params: Record<string, string>;\n}\n\ninterface VariantResult {\n variant: string;\n visitors: number;\n conversions: number;\n conversionRate: number;\n lift?: number;\n pValue?: number;\n isSignificant: boolean;\n}\n\n/**\n * Two-proportion z-test for statistical significance\n */\nfunction zTest(\n conversionsA: number, visitorsA: number,\n conversionsB: number, visitorsB: number\n): number {\n if (visitorsA === 0 || visitorsB === 0) return 1;\n\n const pA = conversionsA / visitorsA;\n const pB = conversionsB / visitorsB;\n const pPool = (conversionsA + conversionsB) / (visitorsA + visitorsB);\n\n if (pPool === 0 || pPool === 1) return 1;\n\n const se = Math.sqrt(pPool * (1 - pPool) * (1 / visitorsA + 1 / visitorsB));\n if (se === 0) return 1;\n\n const z = Math.abs(pA - pB) / se;\n\n // Approximate two-tailed p-value using rational approximation\n const t = 1 / (1 + 0.2316419 * z);\n const d = 0.3989422804014327;\n const p = d * Math.exp(-z * z / 2) * t * (0.3193815 + t * (-0.3565638 + t * (1.781478 + t * (-1.821256 + t * 1.330274))));\n return 2 * p;\n}\n\nexport async function onRequestGet(context: PagesContext<Env>): Promise<Response> {\n const url = new URL(context.request.url);\n const experimentId = url.searchParams.get('experiment');\n\n if (!experimentId) {\n return Response.json({ error: 'Missing experiment parameter' }, { status: 400 });\n }\n\n try {\n // Get unique visitors per variant\n const visitorsResult = await context.env.AB_DB.prepare(\n 'SELECT variant, COUNT(DISTINCT visitor_id) as visitors FROM ab_events WHERE experiment_id = ? AND event_type = \\\\'pageview\\\\' GROUP BY variant'\n ).bind(experimentId).all();\n\n // Get conversions per variant\n const conversionsResult = await context.env.AB_DB.prepare(\n 'SELECT variant, COUNT(DISTINCT visitor_id) as conversions FROM ab_events WHERE experiment_id = ? AND event_type = \\\\'conversion\\\\' GROUP BY variant'\n ).bind(experimentId).all();\n\n // Build results map\n const visitorMap = new Map<string, number>();\n const conversionMap = new Map<string, number>();\n\n for (const row of (visitorsResult.results || [])) {\n visitorMap.set(row.variant as string, row.visitors as number);\n }\n for (const row of (conversionsResult.results || [])) {\n conversionMap.set(row.variant as string, row.conversions as number);\n }\n\n // Get all variant names\n const allVariants = new Set([...visitorMap.keys(), ...conversionMap.keys()]);\n\n // Calculate results\n const variants: VariantResult[] = [];\n let controlVisitors = 0;\n let controlConversions = 0;\n\n for (const variant of allVariants) {\n const visitors = visitorMap.get(variant) || 0;\n const conversions = conversionMap.get(variant) || 0;\n const conversionRate = visitors > 0 ? conversions / visitors : 0;\n\n if (variant === 'control') {\n controlVisitors = visitors;\n controlConversions = conversions;\n }\n\n variants.push({\n variant,\n visitors,\n conversions,\n conversionRate,\n isSignificant: false,\n });\n }\n\n // Calculate lift and significance for non-control variants\n const controlRate = controlVisitors > 0 ? controlConversions / controlVisitors : 0;\n for (const result of variants) {\n if (result.variant !== 'control' && controlVisitors > 0) {\n result.lift = controlRate > 0\n ? ((result.conversionRate - controlRate) / controlRate) * 100\n : 0;\n result.pValue = zTest(\n controlConversions, controlVisitors,\n result.conversions, result.visitors\n );\n result.isSignificant = result.pValue < 0.05;\n }\n }\n\n // Sort: control first, then by variant name\n variants.sort((a, b) => {\n if (a.variant === 'control') return -1;\n if (b.variant === 'control') return 1;\n return a.variant.localeCompare(b.variant);\n });\n\n return Response.json({\n experimentId,\n variants,\n }, {\n headers: {\n 'Access-Control-Allow-Origin': '*',\n 'Cache-Control': 'no-cache',\n }\n });\n } catch (error) {\n return Response.json({ error: 'Failed to query results' }, { status: 500 });\n }\n}\n`;\n}\n", "/**\n * A/B Testing Tracking Script Generator\n * Generates a lightweight client-side tracking script to be injected into HTML\n */\n\nimport type { ConversionGoal } from '../../shared/types/experiments';\n\n/**\n * Generate the tracking script content with embedded experiment config\n */\nexport function generateTrackingScript(experimentId: string, goals: ConversionGoal[]): string {\n const goalsJSON = JSON.stringify(goals);\n\n return `(function(){\nvar EXP_ID=${JSON.stringify(experimentId)};\nvar GOALS=${goalsJSON};\n\nfunction getCookie(n){var m=document.cookie.match(new RegExp('(?:^|;\\\\\\\\s*)'+n+'=([^;]*)'));return m?decodeURIComponent(m[1]):null}\nfunction setCookie(n,v,d){var e=new Date();e.setTime(e.getTime()+d*864e5);document.cookie=n+'='+encodeURIComponent(v)+';path=/;expires='+e.toUTCString()+';SameSite=Lax'}\n\nvar variant=getCookie('meno_variant')||'control';\nvar visitor=getCookie('meno_visitor');\nif(!visitor){visitor=Math.random().toString(36).slice(2)+Date.now().toString(36);setCookie('meno_visitor',visitor,365)}\n\nfunction track(type,goalId){\ntry{navigator.sendBeacon('/api/ab-track',JSON.stringify({experimentId:EXP_ID,visitorId:visitor,variant:variant,eventType:type,goalId:goalId||null,url:location.pathname}))}catch(e){}\n}\n\ntrack('pageview');\n\nGOALS.forEach(function(g){\nif(g.type==='click'&&g.selector){\ndocument.addEventListener('click',function(e){\nif(e.target&&e.target.closest&&e.target.closest(g.selector)){track('conversion',g.id)}\n})\n}\nif(g.type==='navigation'&&g.url){\nif(location.pathname===g.url||location.href.indexOf(g.url)>-1){track('conversion',g.id)}\n}\nif(g.type==='custom'&&g.event){\nwindow.addEventListener(g.event,function(){track('conversion',g.id)})\n}\n});\n})();`;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["minifyJS", "isDevBuild"]
|
|
7
|
+
}
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
import {
|
|
26
26
|
NODE_TYPE,
|
|
27
27
|
init_constants
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-YBLHKYFF.js";
|
|
29
29
|
import {
|
|
30
30
|
__esm,
|
|
31
31
|
__export,
|
|
@@ -1387,7 +1387,7 @@ var init_LinkNodeType = __esm({
|
|
|
1387
1387
|
children: []
|
|
1388
1388
|
},
|
|
1389
1389
|
treeDisplay: {
|
|
1390
|
-
icon: "
|
|
1390
|
+
icon: "LINK",
|
|
1391
1391
|
getLabel: () => "Link"
|
|
1392
1392
|
},
|
|
1393
1393
|
editableFields: [
|
|
@@ -1954,21 +1954,6 @@ function isItemFullyPublished(item) {
|
|
|
1954
1954
|
return !item._draftLocales || item._draftLocales.length === 0;
|
|
1955
1955
|
}
|
|
1956
1956
|
|
|
1957
|
-
// lib/shared/globalTemplateContext.ts
|
|
1958
|
-
var defaultValues = {
|
|
1959
|
-
isEditorMode: false
|
|
1960
|
-
};
|
|
1961
|
-
var globalContext = { ...defaultValues };
|
|
1962
|
-
function setGlobalTemplateContext(values) {
|
|
1963
|
-
globalContext = { ...globalContext, ...values };
|
|
1964
|
-
}
|
|
1965
|
-
function getGlobalTemplateContext() {
|
|
1966
|
-
return globalContext;
|
|
1967
|
-
}
|
|
1968
|
-
function resetGlobalTemplateContext() {
|
|
1969
|
-
globalContext = { ...defaultValues };
|
|
1970
|
-
}
|
|
1971
|
-
|
|
1972
1957
|
// lib/shared/expressionEvaluator.ts
|
|
1973
1958
|
import jsep from "jsep";
|
|
1974
1959
|
function evaluateNode(node, context) {
|
|
@@ -2086,6 +2071,58 @@ function safeEvaluate(expression, context) {
|
|
|
2086
2071
|
function isComplexExpression(expression) {
|
|
2087
2072
|
return /[?:+\-*/%<>=!&|]/.test(expression);
|
|
2088
2073
|
}
|
|
2074
|
+
var SUPPORTED_NODE_TYPES = /* @__PURE__ */ new Set([
|
|
2075
|
+
"Identifier",
|
|
2076
|
+
"Literal",
|
|
2077
|
+
"MemberExpression",
|
|
2078
|
+
"BinaryExpression",
|
|
2079
|
+
"LogicalExpression",
|
|
2080
|
+
"ConditionalExpression",
|
|
2081
|
+
"UnaryExpression",
|
|
2082
|
+
"ArrayExpression"
|
|
2083
|
+
]);
|
|
2084
|
+
var CHILD_KEYS = ["object", "property", "left", "right", "test", "consequent", "alternate", "argument"];
|
|
2085
|
+
function isSupportedNode(node) {
|
|
2086
|
+
if (!node) return true;
|
|
2087
|
+
if (!SUPPORTED_NODE_TYPES.has(node.type)) return false;
|
|
2088
|
+
const n = node;
|
|
2089
|
+
for (const key of CHILD_KEYS) {
|
|
2090
|
+
const child = n[key];
|
|
2091
|
+
if (child && typeof child === "object" && "type" in child) {
|
|
2092
|
+
if (!isSupportedNode(child)) return false;
|
|
2093
|
+
}
|
|
2094
|
+
}
|
|
2095
|
+
if (Array.isArray(n.elements)) {
|
|
2096
|
+
for (const el of n.elements) {
|
|
2097
|
+
if (el && !isSupportedNode(el)) return false;
|
|
2098
|
+
}
|
|
2099
|
+
}
|
|
2100
|
+
return true;
|
|
2101
|
+
}
|
|
2102
|
+
function isSupportedTemplateExpression(expression) {
|
|
2103
|
+
const expr = expression.trim();
|
|
2104
|
+
if (!expr) return false;
|
|
2105
|
+
try {
|
|
2106
|
+
return isSupportedNode(jsep(expr));
|
|
2107
|
+
} catch {
|
|
2108
|
+
return false;
|
|
2109
|
+
}
|
|
2110
|
+
}
|
|
2111
|
+
|
|
2112
|
+
// lib/shared/globalTemplateContext.ts
|
|
2113
|
+
var defaultValues = {
|
|
2114
|
+
isEditorMode: false
|
|
2115
|
+
};
|
|
2116
|
+
var globalContext = { ...defaultValues };
|
|
2117
|
+
function setGlobalTemplateContext(values) {
|
|
2118
|
+
globalContext = { ...globalContext, ...values };
|
|
2119
|
+
}
|
|
2120
|
+
function getGlobalTemplateContext() {
|
|
2121
|
+
return globalContext;
|
|
2122
|
+
}
|
|
2123
|
+
function resetGlobalTemplateContext() {
|
|
2124
|
+
globalContext = { ...defaultValues };
|
|
2125
|
+
}
|
|
2089
2126
|
|
|
2090
2127
|
// lib/shared/itemTemplateUtils.ts
|
|
2091
2128
|
function isTemplateContext(ctx) {
|
|
@@ -2174,7 +2211,7 @@ function resolveCompleteTemplateRaw(template, ctx, resolveValue) {
|
|
|
2174
2211
|
const item = ctx[varName];
|
|
2175
2212
|
if (!item || typeof item !== "object") return void 0;
|
|
2176
2213
|
const value = getNestedValue(item, trimmedField);
|
|
2177
|
-
if (value === void 0) return void 0;
|
|
2214
|
+
if (value === void 0 || value === null) return void 0;
|
|
2178
2215
|
if (resolveValue) {
|
|
2179
2216
|
return resolveValue(value);
|
|
2180
2217
|
}
|
|
@@ -3164,13 +3201,13 @@ var specialValueMappings = {
|
|
|
3164
3201
|
"flex-end": "jc-e",
|
|
3165
3202
|
"space-between": "jc-b",
|
|
3166
3203
|
"space-around": "jc-a",
|
|
3167
|
-
"space-evenly": "jc-
|
|
3204
|
+
"space-evenly": "jc-ev"
|
|
3168
3205
|
},
|
|
3169
3206
|
alignItems: {
|
|
3170
3207
|
center: "ai-c",
|
|
3171
3208
|
"flex-start": "ai-s",
|
|
3172
3209
|
"flex-end": "ai-e",
|
|
3173
|
-
stretch: "ai-
|
|
3210
|
+
stretch: "ai-st",
|
|
3174
3211
|
baseline: "ai-b"
|
|
3175
3212
|
},
|
|
3176
3213
|
overflow: {
|
|
@@ -3219,9 +3256,11 @@ var classToStyleSpecialCases = {
|
|
|
3219
3256
|
"jc-e": { prop: "justifyContent", value: "flex-end" },
|
|
3220
3257
|
"jc-b": { prop: "justifyContent", value: "space-between" },
|
|
3221
3258
|
"jc-a": { prop: "justifyContent", value: "space-around" },
|
|
3259
|
+
"jc-ev": { prop: "justifyContent", value: "space-evenly" },
|
|
3222
3260
|
"ai-c": { prop: "alignItems", value: "center" },
|
|
3223
3261
|
"ai-s": { prop: "alignItems", value: "flex-start" },
|
|
3224
3262
|
"ai-e": { prop: "alignItems", value: "flex-end" },
|
|
3263
|
+
"ai-st": { prop: "alignItems", value: "stretch" },
|
|
3225
3264
|
"ai-b": { prop: "alignItems", value: "baseline" },
|
|
3226
3265
|
"o-h": { prop: "overflow", value: "hidden" },
|
|
3227
3266
|
"o-a": { prop: "overflow", value: "auto" },
|
|
@@ -3960,6 +3999,107 @@ function isCurrentLink(href, currentPagePath) {
|
|
|
3960
3999
|
return normalizePath(href) === normalizePath(currentPagePath);
|
|
3961
4000
|
}
|
|
3962
4001
|
|
|
4002
|
+
// lib/shared/viewportUnits.ts
|
|
4003
|
+
var VIEWPORT_UNIT_RE = /(?<![\w-])(-?\d*\.?\d+)(s|l|d)?(vh|vw)\b/g;
|
|
4004
|
+
function rewriteViewportUnits(input) {
|
|
4005
|
+
if (!input) return input;
|
|
4006
|
+
return input.replace(VIEWPORT_UNIT_RE, (_match, num, sizeKw, axis) => {
|
|
4007
|
+
const unit = `${sizeKw ?? ""}${axis}`;
|
|
4008
|
+
return `calc(var(--design-${unit}, 1${unit}) * ${num})`;
|
|
4009
|
+
});
|
|
4010
|
+
}
|
|
4011
|
+
var DESIGN_VIEWPORT_VARS = [
|
|
4012
|
+
"--design-vh",
|
|
4013
|
+
"--design-svh",
|
|
4014
|
+
"--design-lvh",
|
|
4015
|
+
"--design-dvh",
|
|
4016
|
+
"--design-vw",
|
|
4017
|
+
"--design-svw",
|
|
4018
|
+
"--design-lvw",
|
|
4019
|
+
"--design-dvw"
|
|
4020
|
+
];
|
|
4021
|
+
|
|
4022
|
+
// lib/shared/friendlyError.ts
|
|
4023
|
+
function rawMessageOf(input) {
|
|
4024
|
+
if (input instanceof Error) return input.message;
|
|
4025
|
+
if (typeof input === "string") return input;
|
|
4026
|
+
if (input && typeof input === "object" && "message" in input) {
|
|
4027
|
+
const m = input.message;
|
|
4028
|
+
if (typeof m === "string") return m;
|
|
4029
|
+
}
|
|
4030
|
+
return String(input);
|
|
4031
|
+
}
|
|
4032
|
+
var RULES = [
|
|
4033
|
+
{
|
|
4034
|
+
// Modern V8: "Cannot read properties of null (reading 'length')".
|
|
4035
|
+
// Legacy V8: "Cannot read property 'length' of undefined".
|
|
4036
|
+
test: /Cannot read propert(?:y|ies) (?:of (?:null|undefined)(?: \(reading '([^']+)'\))?|'([^']+)' of (?:null|undefined))/i,
|
|
4037
|
+
build: (m) => {
|
|
4038
|
+
const prop = m[1] || m[2];
|
|
4039
|
+
const target = prop ? `(\`${prop}\`)` : "";
|
|
4040
|
+
return {
|
|
4041
|
+
title: "A section couldn't load its content",
|
|
4042
|
+
friendlyMessage: `Something this section expected ${target} wasn't available \u2014 often a list or field that's empty or not connected yet.`,
|
|
4043
|
+
hint: "Check the data source or list binding for this section."
|
|
4044
|
+
};
|
|
4045
|
+
}
|
|
4046
|
+
},
|
|
4047
|
+
{
|
|
4048
|
+
test: /(\S+) is not a function/i,
|
|
4049
|
+
build: (m) => ({
|
|
4050
|
+
title: "A piece of code didn't run as expected",
|
|
4051
|
+
friendlyMessage: `The site tried to use \`${m[1]}\` as a function, but it isn't one.`,
|
|
4052
|
+
hint: "Check the component's custom JavaScript."
|
|
4053
|
+
})
|
|
4054
|
+
},
|
|
4055
|
+
{
|
|
4056
|
+
test: /(\S+) is not defined/i,
|
|
4057
|
+
build: (m) => ({
|
|
4058
|
+
title: "A piece of code referenced something missing",
|
|
4059
|
+
friendlyMessage: `\`${m[1]}\` was used but never defined.`,
|
|
4060
|
+
hint: "Check for a typo or a missing import in custom code."
|
|
4061
|
+
})
|
|
4062
|
+
},
|
|
4063
|
+
{
|
|
4064
|
+
test: /Failed to fetch|NetworkError|network request failed/i,
|
|
4065
|
+
build: () => ({
|
|
4066
|
+
title: "Couldn't reach the network",
|
|
4067
|
+
friendlyMessage: "A request to load data failed.",
|
|
4068
|
+
hint: "Check your connection or the endpoint URL."
|
|
4069
|
+
})
|
|
4070
|
+
},
|
|
4071
|
+
{
|
|
4072
|
+
test: /Cannot find module|Failed to resolve module|Failed to load module|Error loading dynamically imported module/i,
|
|
4073
|
+
build: () => ({
|
|
4074
|
+
title: "A required file couldn't be loaded",
|
|
4075
|
+
friendlyMessage: "An import or module reference couldn't be found.",
|
|
4076
|
+
hint: "Check the import path."
|
|
4077
|
+
})
|
|
4078
|
+
},
|
|
4079
|
+
{
|
|
4080
|
+
test: /Unexpected token|Unexpected end of (?:JSON|input)|in JSON at position|is not valid JSON/i,
|
|
4081
|
+
build: () => ({
|
|
4082
|
+
title: "Some data was malformed",
|
|
4083
|
+
friendlyMessage: "Content that should be valid JSON couldn't be parsed.",
|
|
4084
|
+
hint: "Check the JSON for a syntax error."
|
|
4085
|
+
})
|
|
4086
|
+
}
|
|
4087
|
+
];
|
|
4088
|
+
function toFriendlyError(input) {
|
|
4089
|
+
const raw = rawMessageOf(input);
|
|
4090
|
+
for (const rule of RULES) {
|
|
4091
|
+
const match = raw.match(rule.test);
|
|
4092
|
+
if (match) {
|
|
4093
|
+
return { ...rule.build(match, raw), raw };
|
|
4094
|
+
}
|
|
4095
|
+
}
|
|
4096
|
+
return {
|
|
4097
|
+
title: "This section ran into a problem",
|
|
4098
|
+
friendlyMessage: "Something went wrong while rendering this part of the page. The rest of the page is fine.",
|
|
4099
|
+
raw
|
|
4100
|
+
};
|
|
4101
|
+
}
|
|
4102
|
+
|
|
3963
4103
|
// lib/shared/cssNamedColors.ts
|
|
3964
4104
|
var CSS_NAMED_COLORS = /* @__PURE__ */ new Set([
|
|
3965
4105
|
// CSS Level 4 named colors
|
|
@@ -4205,10 +4345,12 @@ var utilityClassRules = {
|
|
|
4205
4345
|
"jc-e": "justify-content: flex-end;",
|
|
4206
4346
|
"jc-b": "justify-content: space-between;",
|
|
4207
4347
|
"jc-a": "justify-content: space-around;",
|
|
4348
|
+
"jc-ev": "justify-content: space-evenly;",
|
|
4208
4349
|
// Align Items (short forms)
|
|
4209
4350
|
"ai-c": "align-items: center;",
|
|
4210
4351
|
"ai-s": "align-items: flex-start;",
|
|
4211
4352
|
"ai-e": "align-items: flex-end;",
|
|
4353
|
+
"ai-st": "align-items: stretch;",
|
|
4212
4354
|
"ai-b": "align-items: baseline;",
|
|
4213
4355
|
// Overflow (short forms)
|
|
4214
4356
|
"o-h": "overflow: hidden;",
|
|
@@ -4925,6 +5067,7 @@ export {
|
|
|
4925
5067
|
isItemDraftForLocale,
|
|
4926
5068
|
isItemFullyPublished,
|
|
4927
5069
|
safeEvaluate,
|
|
5070
|
+
isSupportedTemplateExpression,
|
|
4928
5071
|
setGlobalTemplateContext,
|
|
4929
5072
|
getGlobalTemplateContext,
|
|
4930
5073
|
resetGlobalTemplateContext,
|
|
@@ -5057,6 +5200,9 @@ export {
|
|
|
5057
5200
|
createStyleMappingFromProps,
|
|
5058
5201
|
normalizePath,
|
|
5059
5202
|
isCurrentLink,
|
|
5203
|
+
rewriteViewportUnits,
|
|
5204
|
+
DESIGN_VIEWPORT_VARS,
|
|
5205
|
+
toFriendlyError,
|
|
5060
5206
|
CSS_NAMED_COLORS,
|
|
5061
5207
|
isCssNamedColor,
|
|
5062
5208
|
sortClassesByPropertyOrder,
|
|
@@ -5068,4 +5214,4 @@ export {
|
|
|
5068
5214
|
generateInteractiveCSS,
|
|
5069
5215
|
generateAllInteractiveCSS
|
|
5070
5216
|
};
|
|
5071
|
-
//# sourceMappingURL=chunk-
|
|
5217
|
+
//# sourceMappingURL=chunk-JGWFTO6P.js.map
|