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
|
@@ -108,8 +108,11 @@ var init_constants = __esm({
|
|
|
108
108
|
// Enums API routes
|
|
109
109
|
ENUMS: "/api/enums",
|
|
110
110
|
// Get enums config
|
|
111
|
-
SAVE_ENUMS: "/api/save-enums"
|
|
111
|
+
SAVE_ENUMS: "/api/save-enums",
|
|
112
112
|
// Save enums config
|
|
113
|
+
// Component usage
|
|
114
|
+
COMPONENT_USAGE: "/api/component-usage"
|
|
115
|
+
// Get component usage across project
|
|
113
116
|
};
|
|
114
117
|
HMR_ROUTE = "/hmr";
|
|
115
118
|
FILE_PATTERNS = {
|
|
@@ -163,8 +166,10 @@ var init_constants = __esm({
|
|
|
163
166
|
// Editor → Iframe to revert preview
|
|
164
167
|
PAGE_DATA_COMMITTED: "PAGE_DATA_COMMITTED",
|
|
165
168
|
// Editor → Iframe for committed mutations
|
|
166
|
-
COMPONENT_DEFINITION_COMMITTED: "COMPONENT_DEFINITION_COMMITTED"
|
|
169
|
+
COMPONENT_DEFINITION_COMMITTED: "COMPONENT_DEFINITION_COMMITTED",
|
|
167
170
|
// Editor → Iframe for component definition updates
|
|
171
|
+
CSS_VARIABLE_UPDATE: "CSS_VARIABLE_UPDATE"
|
|
172
|
+
// Editor → Iframe for instant CSS variable preview
|
|
168
173
|
};
|
|
169
174
|
NODE_TYPE = {
|
|
170
175
|
NODE: "node",
|
|
@@ -180,6 +185,7 @@ var init_constants = __esm({
|
|
|
180
185
|
COMPONENT_JAVASCRIPT: "component_javascript",
|
|
181
186
|
COMPONENT_CSS: "component_css",
|
|
182
187
|
COMPONENT_LIBRARIES: "component_libraries",
|
|
188
|
+
COMPONENT_ACCEPTS_STYLES: "component_acceptsStyles",
|
|
183
189
|
STRUCTURE_STYLE: "structure_style"
|
|
184
190
|
};
|
|
185
191
|
DEFAULT_COMPONENT_TYPES = [
|
|
@@ -214,4 +220,4 @@ export {
|
|
|
214
220
|
RAW_HTML_PREFIX,
|
|
215
221
|
init_constants
|
|
216
222
|
};
|
|
217
|
-
//# sourceMappingURL=chunk-
|
|
223
|
+
//# sourceMappingURL=chunk-LBWIHPN7.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../lib/shared/constants.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Shared constants used across the application\n */\n\n// Read PORT from environment variable, fallback to 3000\n// Safe for browser environments where process is not defined\nexport const SERVER_PORT = typeof process !== 'undefined' && process.env?.PORT\n ? parseInt(process.env.PORT, 10)\n : 3000;\n\n// Port for serving built static files\nexport const SERVE_PORT = 8080;\n\nexport const API_ROUTES = {\n PAGES: '/api/pages',\n COMPONENTS: '/api/components',\n PAGE_CONTENT: '/api/page-content', // Returns raw JSON text for a page\n PAGE_DATA: '/api/page-data', // Returns parsed JSON for a specific page\n COMPONENT_DATA: '/api/component-data', // Returns parsed JSON for a specific component\n SAVE_PAGE: '/api/save-page',\n SAVE_COMPONENT: '/api/save-component',\n SAVE_COMPONENT_JS: '/api/save-component-js', // Save JavaScript to .js file\n SAVE_COMPONENT_CSS: '/api/save-component-css', // Save CSS to .css file\n COMPONENT_CATEGORY: '/api/component-category', // Move component to category folder\n COMPONENT_FOLDER: '/api/component-folder', // Create component folder\n COMPONENT_FOLDERS: '/api/component-folders', // List all component folders\n COMPONENT_JS: '/api/component-js', // Get JavaScript from .js file\n CONFIG: '/api/config', // Get project config\n SAVE_CONFIG: '/api/save-config', // Save project config\n COMPONENTS_CONFIG: '/api/components-config', // Get components config\n SAVE_COMPONENTS_CONFIG: '/api/save-components-config', // Save components config\n SELECTION: '/api/selection', // Editor selection state (for AI integration)\n // CMS API routes\n CMS_COLLECTIONS: '/api/cms/collections', // List all CMS collections\n CMS_BASE: '/api/cms', // Base path for CMS item operations\n // Colors API routes\n COLORS_CONFIG: '/api/colors-config', // Get full colors config\n SAVE_COLORS: '/api/save-colors', // Save colors config\n // Page deletion\n DELETE_PAGE: '/api/delete-page', // Delete a page\n // Page folder management\n PAGE_FOLDER: '/api/page-folder', // Create page folder\n PAGE_FOLDERS: '/api/page-folders', // List all page folders\n MOVE_PAGE: '/api/move-page', // Move page to folder\n // Component preview\n COMPONENT_PREVIEW: '/api/component-preview', // Render component preview HTML\n // Website import\n IMPORT_WEBSITE: '/api/import-website', // Import external website for reference\n IMPORTED_WEBSITES: '/api/imported-websites', // List imported website folders\n ANALYZE_WEBSITE: '/api/analyze-website', // Analyze imported website into section map\n CONVERT_TO_MENO: '/api/convert-to-meno', // Convert imported HTML to flat Meno page JSON\n EXTRACT_CONTENT: '/api/extract-content', // Extract content from imported website for template mapping\n GENERATE_WIREFRAME_PROMPT: '/api/generate-wireframe-prompt', // Generate wireframe conversion prompt from extraction\n GENERATE_DESIGN_TOKEN_PROMPT: '/api/generate-design-token-prompt', // Generate design token extraction prompt\n GENERATE_CONTENT_PROMPT: '/api/generate-content-prompt', // Generate content conversion prompt using existing components\n GENERATE_SIMPLIFIED_PROMPT: '/api/generate-simplified-prompt', // Generate simplified prompt for Claude Code with Chrome extension\n // Multi-page import routes\n FETCH_SITEMAP: '/api/fetch-sitemap', // Fetch & parse sitemap.xml\n IMPORT_PAGE: '/api/import-page', // Import a single subpage\n ANALYZE_PAGE: '/api/analyze-page', // Analyze a subpage\n EXTRACT_PAGE_CONTENT: '/api/extract-page-content', // Extract content from a subpage\n GENERATE_HOMEPAGE_PROMPT: '/api/generate-homepage-prompt', // Homepage prompt with site structure\n GENERATE_PAGE_PROMPT: '/api/generate-page-prompt', // Per-page/template prompt\n LOAD_WEBSITE_IMPORT: '/api/load-website-import', // Load saved website import data from disk\n // Variables API routes\n VARIABLES_STATUS: '/api/variables-status', // Get variables config with status\n VARIABLES_CSS: '/api/variables-css', // Get generated CSS custom properties\n SAVE_VARIABLES: '/api/save-variables', // Save variables config\n // Enums API routes\n ENUMS: '/api/enums', // Get enums config\n SAVE_ENUMS: '/api/save-enums', // Save enums config\n // Component usage\n COMPONENT_USAGE: '/api/component-usage', // Get component usage across project\n} as const;\n\nexport const HMR_ROUTE = '/hmr';\n\nexport const FILE_PATTERNS = {\n PAGES: './pages',\n COMPONENTS: './components',\n} as const;\n\nexport const DEFAULT_TIMEOUT = 5000;\n\nexport const WEBSOCKET_STATES = {\n CONNECTING: 0,\n OPEN: 1,\n CLOSING: 2,\n CLOSED: 3,\n} as const;\n\n// Timeout constants\nexport const NOT_FOUND_TIMEOUT_MS = 300;\nexport const TAB_SWITCH_DELAY_MS = 100;\nexport const IFRAME_HIGHLIGHT_DELAY_MS = 100;\nexport const TREE_SCROLL_DELAY_MS = 200;\nexport const HOVER_HIGHLIGHT_DELAY_MS = 50; // Delay before highlighting tree item after expansion\n\n// Server configuration\nexport const MAX_PORT_ATTEMPTS = 10;\n\n// Message types for iframe-parent communication\nexport const IFRAME_MESSAGE_TYPES = {\n DELETE_ELEMENT: 'DELETE_ELEMENT',\n TOGGLE_SELECTING_MODE: 'TOGGLE_SELECTING_MODE',\n SET_TAB: 'SET_TAB',\n COPY_ELEMENT: 'COPY_ELEMENT',\n PASTE_ELEMENT: 'PASTE_ELEMENT',\n ARROW_UP: 'ARROW_UP',\n ARROW_DOWN: 'ARROW_DOWN',\n ARROW_LEFT: 'ARROW_LEFT',\n ARROW_RIGHT: 'ARROW_RIGHT',\n OPEN_COMMAND_PALETTE: 'OPEN_COMMAND_PALETTE',\n EDIT_COMPONENT: 'EDIT_COMPONENT',\n NAVIGATE_BACK: 'NAVIGATE_BACK',\n TOGGLE_ADDING_STYLE: 'TOGGLE_ADDING_STYLE',\n MOVE_ELEMENT_UP: 'MOVE_ELEMENT_UP',\n MOVE_ELEMENT_DOWN: 'MOVE_ELEMENT_DOWN',\n NEST_INTO_PREVIOUS_SIBLING: 'NEST_INTO_PREVIOUS_SIBLING',\n NEST_INTO_NEXT_SIBLING: 'NEST_INTO_NEXT_SIBLING',\n SELECTION_CHANGED: 'SELECTION_CHANGED',\n CMS_CONTEXT_UPDATE: 'CMS_CONTEXT_UPDATE',\n CMS_CONTEXT_REQUEST: 'CMS_CONTEXT_REQUEST',\n INTERACTIVE_CSS_UPDATE: 'INTERACTIVE_CSS_UPDATE',\n INTERACTIVE_STYLES_UPDATE: 'INTERACTIVE_STYLES_UPDATE', // Registry data from iframe to editor\n UNDO_REQUEST: 'UNDO_REQUEST',\n REDO_REQUEST: 'REDO_REQUEST',\n TOGGLE_INTERACTIVITY_EDITOR: 'TOGGLE_INTERACTIVITY_EDITOR',\n SET_BREAKPOINT: 'SET_BREAKPOINT',\n PAGE_DATA_PREVIEW: 'PAGE_DATA_PREVIEW', // Editor \u2192 Iframe for component hover preview\n PAGE_DATA_PREVIEW_REVERT: 'PAGE_DATA_PREVIEW_REVERT', // Editor \u2192 Iframe to revert preview\n PAGE_DATA_COMMITTED: 'PAGE_DATA_COMMITTED', // Editor \u2192 Iframe for committed mutations\n COMPONENT_DEFINITION_COMMITTED: 'COMPONENT_DEFINITION_COMMITTED', // Editor \u2192 Iframe for component definition updates\n CSS_VARIABLE_UPDATE: 'CSS_VARIABLE_UPDATE', // Editor \u2192 Iframe for instant CSS variable preview\n} as const;\n\n// Component node type constants\nexport const NODE_TYPE = {\n NODE: 'node',\n COMPONENT: 'component',\n SLOT: 'slot',\n EMBED: 'embed',\n LINK: 'link',\n LOCALE_LIST: 'locale-list',\n LIST: 'list',\n} as const;\n\nexport type NodeType = typeof NODE_TYPE[keyof typeof NODE_TYPE];\n\n// Special path identifiers for component editing\nexport const SPECIAL_PATHS = {\n COMPONENT_INTERFACE: 'component_interface',\n COMPONENT_JAVASCRIPT: 'component_javascript',\n COMPONENT_CSS: 'component_css',\n COMPONENT_LIBRARIES: 'component_libraries',\n COMPONENT_ACCEPTS_STYLES: 'component_acceptsStyles',\n STRUCTURE_STYLE: 'structure_style',\n} as const;\n\n// Component type configuration\nexport interface ComponentTypeConfig {\n id: string;\n label: string;\n color: string;\n description?: string;\n}\n\nexport const DEFAULT_COMPONENT_TYPES: ComponentTypeConfig[] = [\n { id: 'ui', label: 'UI', color: '#3b82f6' },\n { id: 'layout', label: 'Layout', color: '#10b981' },\n { id: 'content', label: 'Content', color: '#f59e0b' },\n];\n\nexport const DEFAULT_ICON_COLOR = '#6b7280';\n\n/**\n * Marker for raw HTML content that should not be escaped\n * Used by rich-text fields to signal that content should render as HTML\n */\nexport const RAW_HTML_PREFIX = '<!--MENO_RAW_HTML-->';\n\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -181,6 +181,14 @@ var ConfigService = class {
|
|
|
181
181
|
}
|
|
182
182
|
return this.config.baseComponent;
|
|
183
183
|
}
|
|
184
|
+
/**
|
|
185
|
+
* Get image format setting
|
|
186
|
+
* Returns 'webp' (default) or 'avif'
|
|
187
|
+
*/
|
|
188
|
+
getImageFormat() {
|
|
189
|
+
if (this.config?.imageFormat === "avif") return "avif";
|
|
190
|
+
return "webp";
|
|
191
|
+
}
|
|
184
192
|
/**
|
|
185
193
|
* Get raw config value by key (for extension)
|
|
186
194
|
*/
|
|
@@ -197,4 +205,4 @@ export {
|
|
|
197
205
|
ConfigService,
|
|
198
206
|
configService
|
|
199
207
|
};
|
|
200
|
-
//# sourceMappingURL=chunk-
|
|
208
|
+
//# sourceMappingURL=chunk-MKB2J6AD.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../lib/server/services/configService.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Config Service\n * Centralized configuration loading and access\n *\n * Consolidates multiple config loaders into a single service that loads\n * the project.config.json file once and exposes typed sections.\n */\n\nimport type { BreakpointConfig, BreakpointConfigInput, BreakpointEntry } from '../../shared/breakpoints';\nimport { DEFAULT_BREAKPOINTS, normalizeBreakpointConfig } from '../../shared/breakpoints';\nimport type { ResponsiveScales, BreakpointScales } from '../../shared/responsiveScaling';\nimport { DEFAULT_RESPONSIVE_SCALES } from '../../shared/responsiveScaling';\nimport type { I18nConfig } from '../../shared/types/components';\nimport type { LibrariesConfig, JSLibraryConfig, CSSLibraryConfig } from '../../shared/types/libraries';\nimport type { CSPConfig } from '../../shared/types/config';\nimport { DEFAULT_I18N_CONFIG, migrateI18nConfig } from '../../shared/i18n';\nimport { projectPaths } from '../projectContext';\nimport { readTextFile, fileExists } from '../runtime';\n\n/**\n * Icons configuration\n */\nexport interface IconsConfig {\n favicon?: string;\n appleTouchIcon?: string;\n}\n\n/**\n * Raw project config structure from project.config.json\n */\nexport type ImageFormat = 'webp' | 'avif';\n\ninterface RawProjectConfig {\n breakpoints?: BreakpointConfigInput;\n responsiveScales?: Partial<ResponsiveScales>;\n i18n?: unknown;\n icons?: IconsConfig;\n libraries?: LibrariesConfig;\n csp?: CSPConfig;\n baseComponent?: string;\n imageFormat?: ImageFormat;\n}\n\n/**\n * ConfigService\n * Loads project configuration once and provides typed access to sections\n */\nexport class ConfigService {\n private config: RawProjectConfig | null = null;\n private loaded = false;\n\n /**\n * Load configuration from project.config.json\n * Safe to call multiple times - only loads once\n */\n async load(): Promise<void> {\n if (this.loaded) {\n return;\n }\n\n try {\n if (await fileExists(projectPaths.config())) {\n const content = await readTextFile(projectPaths.config());\n this.config = JSON.parse(content);\n }\n } catch {\n // Fall through to defaults\n this.config = null;\n }\n\n this.loaded = true;\n }\n\n /**\n * Check if configuration has been loaded\n */\n isLoaded(): boolean {\n return this.loaded;\n }\n\n /**\n * Reset the service (for testing)\n */\n reset(): void {\n this.config = null;\n this.loaded = false;\n }\n\n /**\n * Get breakpoint configuration\n * Returns validated and normalized breakpoints (always object format)\n * Supports both legacy format { tablet: 1024 } and new format { tablet: { breakpoint: 1024, previewPoint: 768 } }\n */\n getBreakpoints(): BreakpointConfig {\n if (!this.config?.breakpoints || typeof this.config.breakpoints !== 'object') {\n return { ...DEFAULT_BREAKPOINTS };\n }\n\n // Validate breakpoint values before normalization\n const validInput: BreakpointConfigInput = {};\n for (const [key, value] of Object.entries(this.config.breakpoints)) {\n if (typeof value === 'number' && value > 0) {\n // Legacy format: number\n validInput[key] = value;\n } else if (typeof value === 'object' && value !== null) {\n // New format: object with breakpoint and optional previewPoint\n const entry = value as BreakpointEntry;\n if (typeof entry.breakpoint === 'number' && entry.breakpoint > 0) {\n validInput[key] = {\n breakpoint: entry.breakpoint,\n previewPoint: typeof entry.previewPoint === 'number' && entry.previewPoint > 0\n ? entry.previewPoint\n : entry.breakpoint,\n };\n }\n }\n }\n\n // Return normalized breakpoints or defaults if none valid\n if (Object.keys(validInput).length === 0) {\n return { ...DEFAULT_BREAKPOINTS };\n }\n\n return normalizeBreakpointConfig(validInput);\n }\n\n /**\n * Get i18n configuration\n * Automatically migrates old string[] format to LocaleConfig[] format\n */\n getI18n(): I18nConfig {\n if (!this.config?.i18n) {\n return { ...DEFAULT_I18N_CONFIG };\n }\n\n return migrateI18nConfig(this.config.i18n);\n }\n\n /**\n * Deep merge scale categories, preserving user-defined breakpoints\n * while filling in missing values from defaults\n */\n private mergeScaleCategory(\n userScales: BreakpointScales | undefined,\n defaultScales: BreakpointScales | undefined\n ): BreakpointScales | undefined {\n if (!userScales && !defaultScales) return undefined;\n if (!userScales) return defaultScales ? { ...defaultScales } : undefined;\n if (!defaultScales) return { ...userScales };\n\n // User scales take precedence, but include defaults for breakpoints not specified\n return {\n ...defaultScales,\n ...userScales,\n };\n }\n\n /**\n * Get responsive scales configuration\n * Supports dynamic breakpoints - scales are keyed by breakpoint name\n * Deep merges scale categories to preserve user breakpoint definitions\n */\n getResponsiveScales(): ResponsiveScales {\n if (!this.config?.responsiveScales || typeof this.config.responsiveScales !== 'object') {\n return { ...DEFAULT_RESPONSIVE_SCALES };\n }\n\n const userScales = this.config.responsiveScales;\n\n return {\n enabled: userScales.enabled ?? DEFAULT_RESPONSIVE_SCALES.enabled,\n baseReference: userScales.baseReference ?? DEFAULT_RESPONSIVE_SCALES.baseReference,\n fontSize: this.mergeScaleCategory(\n userScales.fontSize as BreakpointScales | undefined,\n DEFAULT_RESPONSIVE_SCALES.fontSize\n ),\n padding: this.mergeScaleCategory(\n userScales.padding as BreakpointScales | undefined,\n DEFAULT_RESPONSIVE_SCALES.padding\n ),\n margin: this.mergeScaleCategory(\n userScales.margin as BreakpointScales | undefined,\n DEFAULT_RESPONSIVE_SCALES.margin\n ),\n gap: this.mergeScaleCategory(\n userScales.gap as BreakpointScales | undefined,\n DEFAULT_RESPONSIVE_SCALES.gap\n ),\n };\n }\n\n /**\n * Get icons configuration\n * Returns empty object if not configured\n */\n getIcons(): IconsConfig {\n if (!this.config?.icons || typeof this.config.icons !== 'object') {\n return {};\n }\n\n return this.config.icons;\n }\n\n /**\n * Get libraries configuration\n * Returns empty arrays if not configured\n * Normalizes string URLs to object format for backwards compatibility\n */\n getLibraries(): LibrariesConfig {\n if (!this.config?.libraries || typeof this.config.libraries !== 'object') {\n return { js: [], css: [] };\n }\n\n const libs = this.config.libraries;\n\n // Normalize JS libraries: support both string URLs and object format\n const normalizedJs = Array.isArray(libs.js)\n ? libs.js.map((lib) =>\n typeof lib === 'string' ? { url: lib } : lib\n ) as JSLibraryConfig[]\n : [];\n\n // Normalize CSS libraries: support both string URLs and object format\n const normalizedCss = Array.isArray(libs.css)\n ? libs.css.map((lib) =>\n typeof lib === 'string' ? { url: lib } : lib\n ) as CSSLibraryConfig[]\n : [];\n\n return {\n js: normalizedJs,\n css: normalizedCss,\n };\n }\n\n /**\n * Get CSP configuration\n * Returns empty object if not configured\n */\n getCSP(): CSPConfig {\n if (!this.config?.csp || typeof this.config.csp !== 'object') {\n return {};\n }\n\n return this.config.csp;\n }\n\n /**\n * Get base component name for new pages\n * Returns undefined if not configured\n */\n getBaseComponent(): string | undefined {\n if (!this.config?.baseComponent || typeof this.config.baseComponent !== 'string') {\n return undefined;\n }\n return this.config.baseComponent;\n }\n\n /**\n * Get image format setting\n * Returns 'webp' (default) or 'avif'\n */\n getImageFormat(): ImageFormat {\n if (this.config?.imageFormat === 'avif') return 'avif';\n return 'webp';\n }\n\n /**\n * Get raw config value by key (for extension)\n */\n getRaw<T>(key: string): T | undefined {\n if (!this.config) {\n return undefined;\n }\n return (this.config as Record<string, unknown>)[key] as T | undefined;\n }\n}\n\n/**\n * Singleton instance for global access\n * Use this for convenience, or create your own instance for testing\n */\nexport const configService = new ConfigService();\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../lib/shared/types/components.ts", "../../lib/shared/types/errors.ts", "../../lib/shared/types/colors.ts", "../../lib/shared/types/variables.ts", "../../lib/shared/pathSecurity.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Component Definition Types\n * Improved type safety with stricter types\n */\n\nimport type { ComponentNode } from './nodes';\nimport type { LibrariesConfig } from './libraries';\n\n/**\n * Prop type definitions\n */\nexport type PropType = 'string' | 'select' | 'boolean' | 'number' | 'link' | 'file' | 'rich-text' | 'list';\n\n/**\n * Project-level enum configuration\n * Keys are enum names, values are arrays of options\n */\nexport type EnumsConfig = Record<string, readonly string[]>;\n\n/**\n * Internationalization (i18n) value object\n * Keys are locale codes (e.g., 'en', 'pl', 'de')\n * Values can be strings (for string props) or arrays (for list props)\n */\nexport interface I18nValue {\n _i18n: true;\n [locale: string]: string | unknown[] | true; // true is for the _i18n marker, arrays for list props\n}\n\n/**\n * Locale configuration with metadata\n */\nexport interface LocaleConfig {\n code: string; // URL prefix & translation key (e.g., \"en\", \"pl\")\n name: string; // English name for admin UI (e.g., \"Polish\")\n nativeName: string; // Native name for public UI (e.g., \"Polski\")\n langTag: string; // BCP 47 language tag for SEO (e.g., \"pl-PL\")\n icon?: string; // Optional flag icon path (e.g., \"/icons/flag-en.svg\")\n}\n\n/**\n * Internationalization configuration\n */\nexport interface I18nConfig {\n defaultLocale: string;\n locales: LocaleConfig[];\n}\n\n/**\n * Value resolver function type\n * Used for transforming field values (e.g., i18n resolution)\n */\nexport type ValueResolver = (value: unknown) => unknown;\n\n/**\n * Link prop value type\n */\nexport interface LinkPropValue {\n href: string;\n target?: '_blank';\n}\n\n/**\n * Base prop definition without list-specific fields\n */\nexport interface BasePropDefinition {\n type: Exclude<PropType, 'list'>;\n default?: string | number | boolean | I18nValue | LinkPropValue;\n options?: readonly string[]; // Required for \"select\" type (inline options)\n enumName?: string; // For \"select\" type: reference to project-level enum\n accept?: string; // For \"file\" type: MIME pattern like \"image/*\", \"video/*\"\n editor?: 'basic' | 'extended'; // For 'rich-text' type: which editor to use\n}\n\n/**\n * List item schema - defines the structure of each item in a list prop\n * Uses the same prop types as component interfaces (except nested lists)\n */\nexport type ListItemSchema = Record<string, BasePropDefinition>;\n\n/**\n * List item value type\n * Supports i18n values for localized string fields\n */\nexport type ListItemValue = Record<string, string | number | boolean | LinkPropValue | I18nValue | null>;\n\n/**\n * List prop definition - for array/list data\n */\nexport interface ListPropDefinition {\n type: 'list';\n /** Schema defining the structure of each list item */\n itemSchema: ListItemSchema;\n /** Default value is an array of items */\n default?: ListItemValue[];\n}\n\n/**\n * Prop definition with improved type safety\n */\nexport type PropDefinition = BasePropDefinition | ListPropDefinition;\n\n/**\n * Type guard to check if a prop definition is a list type\n */\nexport function isListPropDefinition(def: PropDefinition): def is ListPropDefinition {\n return def.type === 'list';\n}\n\n/**\n * Type guard to check if a prop definition is a base (non-list) type\n */\nexport function isBasePropDefinition(def: PropDefinition): def is BasePropDefinition {\n return def.type !== 'list';\n}\n\n/**\n * Structured component definition\n */\nexport interface StructuredComponentDefinition {\n interface?: Record<string, PropDefinition>;\n structure?: ComponentNode;\n javascript?: string; // Vanilla JS code to be rendered at end of HTML\n css?: string; // CSS code to be rendered in <style> tag in <head>\n category?: string; // Component category for organization\n /**\n * Define which props are available as JavaScript variables (Astro-style define:vars)\n * - true: all props from interface are exposed\n * - string[]: only specified props are exposed\n * - undefined: no automatic prop injection (backward compatible)\n */\n defineVars?: true | string[];\n /** External JS/CSS libraries required by this component */\n libraries?: LibrariesConfig;\n /** Whether instances of this component can have styles applied to the wrapper */\n acceptsStyles?: boolean;\n}\n\n/**\n * Component definition\n * Supports both new format (just component) and legacy format (type/props/children/component)\n */\nexport interface ComponentDefinition {\n type?: string; // Legacy format\n props?: Record<string, unknown>; // Legacy format\n children?: unknown[]; // Legacy format\n component: StructuredComponentDefinition;\n}\n\n/**\n * Line range for element line number tracking\n */\nexport interface LineRange {\n startLine: number;\n endLine: number;\n}\n\n/**\n * JSON page structure\n */\nexport interface JSONPage {\n meta?: import('./api').PageMetaData;\n components?: Record<string, ComponentDefinition>;\n root?: ComponentNode;\n _lineMap?: Record<string, LineRange>;\n}\n\n/**\n * Page data type that can be either a JSONPage or a component definition structure\n */\nexport type PageData = JSONPage | {\n component: {\n structure?: ComponentNode;\n interface?: Record<string, PropDefinition>;\n javascript?: string;\n css?: string;\n acceptsStyles?: boolean;\n }\n};\n\n/**\n * Page data with component structure (for type narrowing)\n */\nexport interface PageDataWithComponent {\n component: {\n structure?: ComponentNode;\n interface?: Record<string, PropDefinition>;\n javascript?: string;\n css?: string;\n libraries?: LibrariesConfig;\n acceptsStyles?: boolean;\n };\n}\n", "/**\n * Error Types\n * Structured error types for validation and type safety\n */\n\n/**\n * Validation error with context\n */\nexport interface ValidationError {\n path?: string;\n message: string;\n receivedValue?: unknown;\n expectedType?: string;\n}\n\n/**\n * Type safety error\n * Errors from type mismatches or invalid data structures\n */\nexport interface TypeSafetyError extends Error {\n readonly path?: string;\n readonly receivedValue?: unknown;\n readonly expectedType?: string;\n}\n\n/**\n * Result type for operations that can fail\n * Replaces null returns with explicit success/failure\n */\nexport type Result<T> =\n | { success: true; data: T }\n | { success: false; error: ValidationError };\n\n/**\n * Create a validation error\n */\nexport function createValidationError(\n message: string,\n options?: {\n path?: string;\n receivedValue?: unknown;\n expectedType?: string;\n }\n): ValidationError {\n return {\n message,\n ...options,\n };\n}\n\n/**\n * Create a type safety error\n */\nexport function createTypeSafetyError(\n message: string,\n options?: {\n path?: string;\n receivedValue?: unknown;\n expectedType?: string;\n }\n): TypeSafetyError {\n const error = new Error(message) as TypeSafetyError;\n Object.defineProperty(error, 'path', { value: options?.path, writable: false });\n Object.defineProperty(error, 'receivedValue', { value: options?.receivedValue, writable: false });\n Object.defineProperty(error, 'expectedType', { value: options?.expectedType, writable: false });\n return error;\n}\n\n\n", "/**\n * Color Variables Types\n * Handles color variable definitions and configuration\n */\n\n/**\n * Color variables configuration\n * Maps semantic color names to their hex/rgb values\n */\nexport interface ColorVariables {\n colors: Record<string, string>;\n}\n\n/**\n * Theme configuration with color set and metadata\n */\nexport interface Theme {\n label: string;\n colors: Record<string, string>;\n}\n\n/**\n * Theme configuration file structure\n * Supports multiple named themes with a default theme\n */\nexport interface ThemeConfig {\n default: string;\n palette?: Record<string, string>;\n themes: Record<string, Theme>;\n}\n\n/**\n * Resolve a color value through the palette.\n * If value matches a palette key, returns the palette hex; otherwise returns value as-is.\n */\nexport function resolvePaletteColor(value: string, palette?: Record<string, string>): string {\n if (!palette) return value;\n return palette[value] ?? value;\n}\n\n/**\n * Color variable entry for editor display\n */\nexport interface ColorVariableEntry {\n name: string;\n value: string;\n}\n\n/**\n * Theme entry for theme selector\n */\nexport interface ThemeEntry {\n name: string;\n label: string;\n}\n", "/**\n * CSS Variables Types\n * Defines types for the variables.json configuration file\n */\n\n/**\n * Category type for a CSS variable\n * Maps to responsiveScales categories for automatic responsive scaling\n * 'none' means no responsive scaling is applied\n */\nexport type VariableType = 'fontSize' | 'padding' | 'margin' | 'gap' | 'none';\n\n/**\n * UI filtering group for a CSS variable.\n * Controls which variables appear in the picker based on the CSS property being edited.\n */\nexport type VariableGroup =\n | 'font-family' | 'font-size' | 'font-weight'\n | 'line-height' | 'letter-spacing'\n | 'margin' | 'padding' | 'gap'\n | 'size'\n | 'border-radius' | 'border-width'\n | 'opacity' | 'z-index'\n | 'text-align'\n | 'other';\n\n/** Predefined variable groups for UI dropdowns */\nexport const VARIABLE_GROUPS: { value: VariableGroup; label: string }[] = [\n { value: 'font-family', label: 'Font Family' },\n { value: 'font-size', label: 'Font Size' },\n { value: 'font-weight', label: 'Font Weight' },\n { value: 'line-height', label: 'Line Height' },\n { value: 'letter-spacing', label: 'Letter Spacing' },\n { value: 'margin', label: 'Margin' },\n { value: 'padding', label: 'Padding' },\n { value: 'gap', label: 'Gap' },\n { value: 'size', label: 'Size' },\n { value: 'border-radius', label: 'Border Radius' },\n { value: 'border-width', label: 'Border Width' },\n { value: 'opacity', label: 'Opacity' },\n { value: 'z-index', label: 'Z-Index' },\n { value: 'text-align', label: 'Text Align' },\n { value: 'other', label: 'Other' },\n];\n\n/** All valid group string values */\nexport const VARIABLE_GROUP_VALUES: VariableGroup[] = VARIABLE_GROUPS.map(g => g.value);\n\n/** Maps CSS property names to variable groups */\nconst CSS_PROPERTY_TO_GROUP: Record<string, VariableGroup> = {\n 'font-family': 'font-family',\n 'font-size': 'font-size',\n 'font-weight': 'font-weight',\n 'line-height': 'line-height',\n 'letter-spacing': 'letter-spacing',\n 'text-align': 'text-align',\n 'opacity': 'opacity',\n 'z-index': 'z-index',\n};\n\n/** Prefix-based mappings for CSS properties */\nconst CSS_PROPERTY_PREFIX_GROUPS: { prefix: string; group: VariableGroup }[] = [\n { prefix: 'margin', group: 'margin' },\n { prefix: 'padding', group: 'padding' },\n { prefix: 'gap', group: 'gap' },\n { prefix: 'row-gap', group: 'gap' },\n { prefix: 'column-gap', group: 'gap' },\n { prefix: 'width', group: 'size' },\n { prefix: 'height', group: 'size' },\n { prefix: 'min-width', group: 'size' },\n { prefix: 'max-width', group: 'size' },\n { prefix: 'min-height', group: 'size' },\n { prefix: 'max-height', group: 'size' },\n { prefix: 'border-radius', group: 'border-radius' },\n { prefix: 'border-top-left-radius', group: 'border-radius' },\n { prefix: 'border-top-right-radius', group: 'border-radius' },\n { prefix: 'border-bottom-left-radius', group: 'border-radius' },\n { prefix: 'border-bottom-right-radius', group: 'border-radius' },\n { prefix: 'border-width', group: 'border-width' },\n { prefix: 'border-top-width', group: 'border-width' },\n { prefix: 'border-right-width', group: 'border-width' },\n { prefix: 'border-bottom-width', group: 'border-width' },\n { prefix: 'border-left-width', group: 'border-width' },\n];\n\n/**\n * Determines which variable group a CSS property belongs to.\n * Returns null if no group matches (show all variables).\n */\nexport function getGroupForProperty(prop: string): VariableGroup | null {\n // Normalize camelCase to kebab-case (e.g., \"fontFamily\" \u2192 \"font-family\")\n const normalized = prop.replace(/[A-Z]/g, letter => `-${letter.toLowerCase()}`);\n\n // Exact match first\n if (normalized in CSS_PROPERTY_TO_GROUP) {\n return CSS_PROPERTY_TO_GROUP[normalized];\n }\n // Prefix-based match (handles margin-top, padding-left, etc.)\n for (const { prefix, group } of CSS_PROPERTY_PREFIX_GROUPS) {\n if (normalized === prefix || normalized.startsWith(prefix + '-')) {\n return group;\n }\n }\n return null;\n}\n\n/**\n * A single CSS custom property definition\n */\nexport interface CSSVariable {\n /** Display name (e.g., \"H1 Font Size\") */\n name: string;\n /** Optional prop name alias for organizational purposes */\n prop_name?: string;\n /** CSS custom property name (e.g., \"--h1-fs\") */\n cssVar: string;\n /** Base value (e.g., \"48px\") */\n value: string;\n /** Category for responsive scaling */\n type: VariableType;\n /** Optional per-variable breakpoint scale overrides */\n scales?: Record<string, string>;\n /** Optional UI filtering group for the variable picker */\n group?: VariableGroup;\n}\n\n/**\n * Variables configuration file structure (variables.json)\n */\nexport interface VariablesConfig {\n variables: CSSVariable[];\n}\n\n/** Predefined variable scaling types for UI dropdowns */\nexport const VARIABLE_TYPES: { value: VariableType; label: string }[] = [\n { value: 'fontSize', label: 'Font Size' },\n { value: 'padding', label: 'Padding' },\n { value: 'margin', label: 'Margin' },\n { value: 'gap', label: 'Gap' },\n { value: 'none', label: 'None' },\n];\n\n/**\n * Returns an abbreviation for a variable group by taking the first letter of each word.\n * e.g. 'letter-spacing' -> 'ls', 'font-size' -> 'fs', 'spacing' -> 's'\n */\nexport function getGroupAbbreviation(group: string): string {\n return group.split('-').map(w => w[0] || '').join('');\n}\n\n/**\n * Infers a default scaling type from a variable group and optional CSS property.\n */\nexport function getDefaultScalingType(group: string, cssProperty?: string): VariableType {\n if (group === 'font-size') return 'fontSize';\n if (group === 'margin') return 'margin';\n if (group === 'padding') return 'padding';\n if (group === 'gap') return 'gap';\n return 'none';\n}\n\n/**\n * Generates a short CSS variable name with collision detection.\n * e.g. name=\"Heading\", group=\"letter-spacing\" -> \"--h-ls\"\n * If taken, extends prefix: \"--he-ls\", \"--hea-ls\", etc.\n */\nexport function generateShortCssVar(\n name: string,\n group: string,\n existingVariables: CSSVariable[]\n): string {\n const trimmed = name.trim();\n if (!trimmed) return '--';\n if (!group) {\n // No group: just kebab-case the name\n const base = '--' + trimmed.toLowerCase().replace(/\\s+/g, '-').replace(/[^a-z0-9-]/g, '');\n return ensureUnique(base, existingVariables);\n }\n\n const groupAbbr = getGroupAbbreviation(group);\n const kebabName = trimmed.toLowerCase().replace(/\\s+/g, '-').replace(/[^a-z0-9-]/g, '');\n const words = kebabName.split('-').filter(Boolean);\n const existingNames = new Set(existingVariables.map(v => v.cssVar));\n\n // Try progressively longer prefixes from the name\n // Start with first letter of each word, then extend first word\n const initials = words.map(w => w[0] || '').join('');\n const initialCandidate = `--${initials}-${groupAbbr}`;\n if (!existingNames.has(initialCandidate)) return initialCandidate;\n\n // Extend first word progressively\n const firstWord = words[0] || '';\n for (let len = 2; len <= firstWord.length; len++) {\n const prefix = firstWord.slice(0, len) + (words.length > 1 ? words.slice(1).map(w => w[0] || '').join('') : '');\n const candidate = `--${prefix}-${groupAbbr}`;\n if (!existingNames.has(candidate)) return candidate;\n }\n\n // Full kebab name with group abbreviation\n const fullCandidate = `--${kebabName}-${groupAbbr}`;\n if (!existingNames.has(fullCandidate)) return fullCandidate;\n\n // Numeric suffix fallback\n let i = 2;\n while (existingNames.has(`${fullCandidate}-${i}`)) i++;\n return `${fullCandidate}-${i}`;\n}\n\nfunction ensureUnique(base: string, existingVariables: CSSVariable[]): string {\n const existingNames = new Set(existingVariables.map(v => v.cssVar));\n if (!existingNames.has(base)) return base;\n let i = 2;\n while (existingNames.has(`${base}-${i}`)) i++;\n return `${base}-${i}`;\n}\n", "/**\n * Path Security Utilities\n * Provides path traversal protection for file system operations\n */\n\nimport { resolve, sep } from 'path';\n\n/**\n * Error thrown when a path traversal attack is detected\n */\nexport class PathTraversalError extends Error {\n constructor(\n public readonly requestedPath: string,\n public readonly rootPath: string\n ) {\n super(`Path traversal detected: \"${requestedPath}\" escapes root \"${rootPath}\"`);\n this.name = 'PathTraversalError';\n }\n}\n\n/**\n * Check if a resolved path is within the allowed root directory\n * Uses path.resolve() to normalize and handle .. sequences\n *\n * @param requestedPath - The path to validate (can be relative or absolute)\n * @param rootPath - The root directory that paths must be within\n * @returns true if the path is within root, false otherwise\n */\nexport function isPathWithinRoot(requestedPath: string, rootPath: string): boolean {\n const normalizedRoot = resolve(rootPath);\n const normalizedPath = resolve(rootPath, requestedPath);\n\n // Check that normalized path starts with root + separator\n // Adding separator prevents /project-backup from matching /project\n return normalizedPath === normalizedRoot || normalizedPath.startsWith(normalizedRoot + sep);\n}\n\n/**\n * Resolve a path safely, throwing if it would escape the root\n *\n * @param rootPath - The root directory\n * @param segments - Path segments to join\n * @returns The resolved path\n * @throws PathTraversalError if path escapes root\n */\nexport function resolveSafePath(rootPath: string, ...segments: string[]): string {\n const normalizedRoot = resolve(rootPath);\n const normalizedPath = resolve(normalizedRoot, ...segments);\n\n if (!normalizedPath.startsWith(normalizedRoot + sep) && normalizedPath !== normalizedRoot) {\n throw new PathTraversalError(segments.join(sep), rootPath);\n }\n\n return normalizedPath;\n}\n\n/**\n * Validate that a filename/identifier contains no path traversal sequences\n * Use for collection names, filenames, etc.\n *\n * @param name - The name to validate\n * @returns true if safe, false if contains traversal sequences\n */\nexport function isSafePathSegment(name: string): boolean {\n // Reject empty names\n if (!name || name.trim() === '') return false;\n\n // Reject names with path separators\n if (name.includes('/') || name.includes('\\\\')) return false;\n\n // Reject . and ..\n if (name === '.' || name === '..') return false;\n\n // Reject names starting with .. (e.g., \"..foo\")\n if (name.startsWith('..')) return false;\n\n // Reject null bytes (used in some attacks)\n if (name.includes('\\0')) return false;\n\n return true;\n}\n\n/**\n * Regex for valid CMS identifiers (collection names, filenames)\n * Allows alphanumeric, underscore, hyphen\n */\nexport const SAFE_IDENTIFIER_REGEX = /^[a-zA-Z0-9_-]+$/;\n\n/**\n * Validate a CMS identifier (stricter than isSafePathSegment)\n * Use for collection IDs and filenames that should only contain safe chars\n */\nexport function isValidIdentifier(name: string): boolean {\n return SAFE_IDENTIFIER_REGEX.test(name);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
configService
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-MKB2J6AD.js";
|
|
4
4
|
import {
|
|
5
5
|
projectPaths,
|
|
6
6
|
resolveProjectPath,
|
|
@@ -16,14 +16,14 @@ import {
|
|
|
16
16
|
isSafePathSegment,
|
|
17
17
|
isValidIdentifier,
|
|
18
18
|
resolvePaletteColor
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-S2HXJTAF.js";
|
|
20
20
|
import {
|
|
21
21
|
extractAttributesFromNode,
|
|
22
22
|
isHtmlMapping,
|
|
23
23
|
processStructure,
|
|
24
24
|
resolveHtmlMapping,
|
|
25
25
|
skipEmptyTemplateAttributes
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-IBR2F4IL.js";
|
|
27
27
|
import {
|
|
28
28
|
DEFAULT_PREFETCH_CONFIG,
|
|
29
29
|
SSRRegistry,
|
|
@@ -60,7 +60,7 @@ import {
|
|
|
60
60
|
singularize,
|
|
61
61
|
validateCMSItem,
|
|
62
62
|
validateComponentDefinition
|
|
63
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-IGVQF5GY.js";
|
|
64
64
|
import {
|
|
65
65
|
DEFAULT_BREAKPOINTS,
|
|
66
66
|
DEFAULT_I18N_CONFIG,
|
|
@@ -81,7 +81,7 @@ import {
|
|
|
81
81
|
NODE_TYPE,
|
|
82
82
|
RAW_HTML_PREFIX,
|
|
83
83
|
init_constants
|
|
84
|
-
} from "./chunk-
|
|
84
|
+
} from "./chunk-LBWIHPN7.js";
|
|
85
85
|
import {
|
|
86
86
|
__require
|
|
87
87
|
} from "./chunk-KSBZ2L7C.js";
|
|
@@ -1303,6 +1303,82 @@ function generateFontPreloadTags() {
|
|
|
1303
1303
|
}).join("\n ");
|
|
1304
1304
|
}
|
|
1305
1305
|
|
|
1306
|
+
// lib/server/cssGenerator.ts
|
|
1307
|
+
function generateThemeColorVariablesCSS(themeConfig) {
|
|
1308
|
+
const cssBlocks = [];
|
|
1309
|
+
const palette = themeConfig.palette;
|
|
1310
|
+
for (const [themeName, theme] of Object.entries(themeConfig.themes)) {
|
|
1311
|
+
const cssVars = [];
|
|
1312
|
+
for (const [name, value] of Object.entries(theme.colors)) {
|
|
1313
|
+
const resolved = resolvePaletteColor(value, palette);
|
|
1314
|
+
cssVars.push(` --${name}: ${resolved};`);
|
|
1315
|
+
}
|
|
1316
|
+
if (cssVars.length > 0) {
|
|
1317
|
+
cssBlocks.push(`[theme="${themeName}"] {
|
|
1318
|
+
${cssVars.join("\n")}
|
|
1319
|
+
}`);
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
const defaultTheme = themeConfig.themes[themeConfig.default];
|
|
1323
|
+
if (defaultTheme) {
|
|
1324
|
+
const cssVars = [];
|
|
1325
|
+
for (const [name, value] of Object.entries(defaultTheme.colors)) {
|
|
1326
|
+
const resolved = resolvePaletteColor(value, palette);
|
|
1327
|
+
cssVars.push(` --${name}: ${resolved};`);
|
|
1328
|
+
}
|
|
1329
|
+
if (cssVars.length > 0) {
|
|
1330
|
+
cssBlocks.unshift(`:root {
|
|
1331
|
+
${cssVars.join("\n")}
|
|
1332
|
+
}`);
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
return cssBlocks.join("\n\n");
|
|
1336
|
+
}
|
|
1337
|
+
function generateVariablesCSS(config, breakpoints, responsiveScales) {
|
|
1338
|
+
if (!config.variables || config.variables.length === 0) {
|
|
1339
|
+
return "";
|
|
1340
|
+
}
|
|
1341
|
+
const cssBlocks = [];
|
|
1342
|
+
const baseVars = config.variables.map((v) => ` ${v.cssVar}: ${v.value};`);
|
|
1343
|
+
cssBlocks.push(`:root {
|
|
1344
|
+
${baseVars.join("\n")}
|
|
1345
|
+
}`);
|
|
1346
|
+
if (breakpoints && responsiveScales?.enabled) {
|
|
1347
|
+
const baseRef = responsiveScales.baseReference || 16;
|
|
1348
|
+
const sortedBreakpoints = Object.entries(breakpoints).sort((a, b) => b[1].breakpoint - a[1].breakpoint);
|
|
1349
|
+
for (const [bpName, bpEntry] of sortedBreakpoints) {
|
|
1350
|
+
const scaledVars = [];
|
|
1351
|
+
for (const variable of config.variables) {
|
|
1352
|
+
if (variable.scales && variable.scales[bpName]) {
|
|
1353
|
+
const overrideValue = variable.scales[bpName];
|
|
1354
|
+
if (overrideValue !== variable.value) {
|
|
1355
|
+
scaledVars.push(` ${variable.cssVar}: ${overrideValue};`);
|
|
1356
|
+
}
|
|
1357
|
+
continue;
|
|
1358
|
+
}
|
|
1359
|
+
if (variable.type === "none") continue;
|
|
1360
|
+
const categoryScales = responsiveScales[variable.type];
|
|
1361
|
+
const scale = categoryScales?.[bpName] ?? null;
|
|
1362
|
+
if (scale === null) continue;
|
|
1363
|
+
const scaled = scalePropertyValue(variable.value, baseRef, scale);
|
|
1364
|
+
if (scaled !== null && scaled !== variable.value) {
|
|
1365
|
+
scaledVars.push(` ${variable.cssVar}: ${scaled};`);
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
if (scaledVars.length > 0) {
|
|
1369
|
+
cssBlocks.push(
|
|
1370
|
+
`@media (max-width: ${bpEntry.breakpoint}px) {
|
|
1371
|
+
:root {
|
|
1372
|
+
${scaledVars.join("\n")}
|
|
1373
|
+
}
|
|
1374
|
+
}`
|
|
1375
|
+
);
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
return cssBlocks.join("\n");
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1306
1382
|
// lib/server/ssr/attributeBuilder.ts
|
|
1307
1383
|
function escapeHtml(unsafe) {
|
|
1308
1384
|
if (typeof unsafe !== "string") {
|
|
@@ -1711,7 +1787,7 @@ function extractImgSrc(imgTag) {
|
|
|
1711
1787
|
const match = imgTag.match(/src=["']([^"']+)["']/i);
|
|
1712
1788
|
return match ? match[1] : null;
|
|
1713
1789
|
}
|
|
1714
|
-
function rewriteRichTextImages(html, metadataMap) {
|
|
1790
|
+
function rewriteRichTextImages(html, metadataMap, imageFormat) {
|
|
1715
1791
|
return html.replace(/<img\b([^>]*)\/?>/gi, (fullMatch, innerAttrs) => {
|
|
1716
1792
|
const src = extractImgSrc(fullMatch);
|
|
1717
1793
|
if (!src) return fullMatch;
|
|
@@ -1727,7 +1803,7 @@ function rewriteRichTextImages(html, metadataMap) {
|
|
|
1727
1803
|
enhancedTag = enhancedTag.replace(/<img\b/i, `<img height="${escapeHtml(String(metadata.height))}"`);
|
|
1728
1804
|
}
|
|
1729
1805
|
const sizes = DEFAULT_SIZES;
|
|
1730
|
-
if (metadata.avifSrcset) {
|
|
1806
|
+
if (metadata.avifSrcset && imageFormat !== "webp") {
|
|
1731
1807
|
return `<picture><source type="image/avif" srcset="${escapeHtml(metadata.avifSrcset)}" sizes="${escapeHtml(sizes)}" /><source type="image/webp" srcset="${escapeHtml(metadata.srcset)}" sizes="${escapeHtml(sizes)}" />` + enhancedTag + `</picture>`;
|
|
1732
1808
|
}
|
|
1733
1809
|
if (metadata.srcset) {
|
|
@@ -1992,7 +2068,8 @@ async function buildComponentHTML(node, globalComponents = {}, pageComponents =
|
|
|
1992
2068
|
const interactiveStylesMap = /* @__PURE__ */ new Map();
|
|
1993
2069
|
const preloadImages = [];
|
|
1994
2070
|
const neededCollections = /* @__PURE__ */ new Set();
|
|
1995
|
-
|
|
2071
|
+
const ssrFallbackCollector = /* @__PURE__ */ new Map();
|
|
2072
|
+
if (!node) return { html: "", interactiveStylesMap, preloadImages, neededCollections, ssrFallbackCollector };
|
|
1996
2073
|
ssrComponentRegistry.merge(globalComponents);
|
|
1997
2074
|
ssrComponentRegistry.merge(pageComponents);
|
|
1998
2075
|
const breakpoints = await loadBreakpointConfig();
|
|
@@ -2016,10 +2093,13 @@ async function buildComponentHTML(node, globalComponents = {}, pageComponents =
|
|
|
2016
2093
|
// Collect high-priority images for preloading
|
|
2017
2094
|
neededCollections,
|
|
2018
2095
|
// Track collections that need client-side data
|
|
2019
|
-
isProductionBuild
|
|
2096
|
+
isProductionBuild,
|
|
2097
|
+
ssrFallbackCollector,
|
|
2098
|
+
// Collect SSR fallback HTML for complex nodes
|
|
2099
|
+
imageFormat: configService.getImageFormat()
|
|
2020
2100
|
};
|
|
2021
2101
|
const html = await renderNode(node, ctx);
|
|
2022
|
-
return { html, interactiveStylesMap, preloadImages, neededCollections };
|
|
2102
|
+
return { html, interactiveStylesMap, preloadImages, neededCollections, ssrFallbackCollector };
|
|
2023
2103
|
}
|
|
2024
2104
|
async function renderNestedListPlaceholder(node, ctx) {
|
|
2025
2105
|
const sourceValue = node.source || node.collection;
|
|
@@ -2123,7 +2203,11 @@ async function processList(node, ctx) {
|
|
|
2123
2203
|
const templateContent = await renderChildrenAsync(node.children, templateCtx);
|
|
2124
2204
|
templateHtml = `<template data-meno-item>${templateContent}</template>`;
|
|
2125
2205
|
}
|
|
2126
|
-
|
|
2206
|
+
const listResult = childrenHTML + templateHtml;
|
|
2207
|
+
if (ctx.ssrFallbackCollector && ctx.elementPath) {
|
|
2208
|
+
ctx.ssrFallbackCollector.set(ctx.elementPath.join("."), listResult);
|
|
2209
|
+
}
|
|
2210
|
+
return listResult;
|
|
2127
2211
|
}
|
|
2128
2212
|
async function getCollectionItems(node, source, ctx) {
|
|
2129
2213
|
if (!ctx.cmsService) return [];
|
|
@@ -2254,7 +2338,7 @@ async function renderNode(node, ctx) {
|
|
|
2254
2338
|
}
|
|
2255
2339
|
if (text.startsWith(RAW_HTML_PREFIX)) {
|
|
2256
2340
|
let rawHtml = text.slice(RAW_HTML_PREFIX.length);
|
|
2257
|
-
if (ctx.imageMetadataMap) rawHtml = rewriteRichTextImages(rawHtml, ctx.imageMetadataMap);
|
|
2341
|
+
if (ctx.imageMetadataMap) rawHtml = rewriteRichTextImages(rawHtml, ctx.imageMetadataMap, ctx.imageFormat);
|
|
2258
2342
|
rawHtml = await expandRichTextComponents(rawHtml, ctx);
|
|
2259
2343
|
rawHtml = localizeRichTextLinks(rawHtml, ctx);
|
|
2260
2344
|
return rawHtml;
|
|
@@ -2270,7 +2354,7 @@ async function renderNode(node, ctx) {
|
|
|
2270
2354
|
}
|
|
2271
2355
|
if (text.startsWith(RAW_HTML_PREFIX)) {
|
|
2272
2356
|
let rawHtml = text.slice(RAW_HTML_PREFIX.length);
|
|
2273
|
-
if (ctx.imageMetadataMap) rawHtml = rewriteRichTextImages(rawHtml, ctx.imageMetadataMap);
|
|
2357
|
+
if (ctx.imageMetadataMap) rawHtml = rewriteRichTextImages(rawHtml, ctx.imageMetadataMap, ctx.imageFormat);
|
|
2274
2358
|
rawHtml = await expandRichTextComponents(rawHtml, ctx);
|
|
2275
2359
|
rawHtml = localizeRichTextLinks(rawHtml, ctx);
|
|
2276
2360
|
return rawHtml;
|
|
@@ -2318,11 +2402,11 @@ async function renderNode(node, ctx) {
|
|
|
2318
2402
|
}
|
|
2319
2403
|
const purify = getDOMPurify();
|
|
2320
2404
|
const sanitizedHtml = purify ? purify.sanitize(htmlContent, {
|
|
2321
|
-
ALLOWED_TAGS: ["svg", "path", "circle", "rect", "line", "polyline", "polygon", "g", "text", "tspan", "image", "defs", "use", "linearGradient", "radialGradient", "stop", "clipPath", "mask", "pattern", "marker", "symbol", "a", "div", "span", "p", "br", "button", "img", "iframe", "video", "audio", "source", "canvas", "b", "i", "u", "strong", "em", "sub", "sup", "mark", "s", "small", "del", "ins", "q", "abbr", "code", "pre", "blockquote", "ul", "ol", "li", "h1", "h2", "h3", "h4", "h5", "h6"],
|
|
2322
|
-
ALLOWED_ATTR: ["class", "id", "style", "width", "height", "viewBox", "xmlns", "fill", "stroke", "stroke-width", "stroke-linecap", "stroke-linejoin", "stroke-dasharray", "stroke-dashoffset", "d", "cx", "cy", "r", "x", "y", "x1", "y1", "x2", "y2", "points", "href", "src", "alt", "target", "rel", "data-*", "aria-*", "transform", "opacity", "fill-opacity", "stroke-opacity", "font-size", "font-family", "text-anchor", "dominant-baseline", "offset", "stop-color", "stop-opacity", "frameborder", "allowfullscreen", "allow", "title"],
|
|
2405
|
+
ALLOWED_TAGS: ["svg", "path", "circle", "rect", "line", "polyline", "polygon", "g", "text", "tspan", "image", "defs", "use", "linearGradient", "radialGradient", "stop", "clipPath", "mask", "pattern", "marker", "symbol", "a", "div", "span", "p", "br", "button", "img", "iframe", "video", "audio", "source", "canvas", "b", "i", "u", "strong", "em", "sub", "sup", "mark", "s", "small", "del", "ins", "q", "abbr", "code", "pre", "blockquote", "ul", "ol", "li", "h1", "h2", "h3", "h4", "h5", "h6", "style", "animate", "animateTransform", "animateMotion", "set"],
|
|
2406
|
+
ALLOWED_ATTR: ["class", "id", "style", "width", "height", "viewBox", "xmlns", "fill", "stroke", "stroke-width", "stroke-linecap", "stroke-linejoin", "stroke-dasharray", "stroke-dashoffset", "d", "cx", "cy", "r", "x", "y", "x1", "y1", "x2", "y2", "points", "href", "src", "alt", "target", "rel", "data-*", "aria-*", "transform", "opacity", "fill-opacity", "stroke-opacity", "font-size", "font-family", "text-anchor", "dominant-baseline", "offset", "stop-color", "stop-opacity", "frameborder", "allowfullscreen", "allow", "title", "attributeName", "values", "dur", "begin", "end", "repeatCount", "repeatDur", "keyTimes", "keySplines", "calcMode", "from", "to", "by", "additive", "accumulate", "type", "rotate", "keyPoints", "path"],
|
|
2323
2407
|
KEEP_CONTENT: true
|
|
2324
2408
|
}) : htmlContent;
|
|
2325
|
-
const optimizedHtml = ctx.imageMetadataMap ? rewriteRichTextImages(sanitizedHtml, ctx.imageMetadataMap) : sanitizedHtml;
|
|
2409
|
+
const optimizedHtml = ctx.imageMetadataMap ? rewriteRichTextImages(sanitizedHtml, ctx.imageMetadataMap, ctx.imageFormat) : sanitizedHtml;
|
|
2326
2410
|
const nodeAttributes2 = extractAttributesFromNode(node);
|
|
2327
2411
|
const classNames = ["oem"];
|
|
2328
2412
|
if (nodeStyle) {
|
|
@@ -2533,17 +2617,37 @@ async function renderComponent(componentName, propsWithStyleAndAttrs, children,
|
|
|
2533
2617
|
if (!rootNode.props) {
|
|
2534
2618
|
rootNode.props = {};
|
|
2535
2619
|
}
|
|
2536
|
-
if (rootNode
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2620
|
+
if (isHtmlNode(rootNode)) {
|
|
2621
|
+
if (propsWithStyleAndAttrs.style) {
|
|
2622
|
+
const existingStyle = rootNode.style;
|
|
2623
|
+
if (existingStyle && typeof existingStyle === "object") {
|
|
2624
|
+
rootNode.style = {
|
|
2625
|
+
...existingStyle,
|
|
2626
|
+
...propsWithStyleAndAttrs.style
|
|
2627
|
+
};
|
|
2628
|
+
} else {
|
|
2629
|
+
rootNode.style = propsWithStyleAndAttrs.style;
|
|
2630
|
+
}
|
|
2631
|
+
}
|
|
2632
|
+
} else {
|
|
2633
|
+
if (rootNode.props.style && typeof rootNode.props.style === "object") {
|
|
2634
|
+
rootNode.props.style = {
|
|
2635
|
+
...rootNode.props.style,
|
|
2636
|
+
...propsWithStyleAndAttrs.style || {}
|
|
2637
|
+
};
|
|
2638
|
+
} else if (propsWithStyleAndAttrs.style) {
|
|
2639
|
+
rootNode.props.style = propsWithStyleAndAttrs.style;
|
|
2640
|
+
}
|
|
2543
2641
|
}
|
|
2544
2642
|
if (propsWithStyleAndAttrs.className) {
|
|
2545
|
-
|
|
2546
|
-
|
|
2643
|
+
if (isHtmlNode(rootNode)) {
|
|
2644
|
+
if (!rootNode.attributes) rootNode.attributes = {};
|
|
2645
|
+
const existingClass = rootNode.attributes.class || "";
|
|
2646
|
+
rootNode.attributes.class = existingClass ? `${existingClass} ${propsWithStyleAndAttrs.className}` : propsWithStyleAndAttrs.className;
|
|
2647
|
+
} else {
|
|
2648
|
+
const existingClassName = rootNode.props.className || "";
|
|
2649
|
+
rootNode.props.className = existingClassName ? `${existingClassName} ${propsWithStyleAndAttrs.className}` : propsWithStyleAndAttrs.className;
|
|
2650
|
+
}
|
|
2547
2651
|
}
|
|
2548
2652
|
Object.assign(rootNode.props, nodeAttributes);
|
|
2549
2653
|
if (isHtmlNode(rootNode) && Object.keys(nodeAttributes).length > 0) {
|
|
@@ -2657,7 +2761,7 @@ function renderImageElement(propsWithStyleAndAttrs, classAttr, attrs, ctx) {
|
|
|
2657
2761
|
}
|
|
2658
2762
|
const sizesAttr = sizes || DEFAULT_SIZES;
|
|
2659
2763
|
if (fetchpriority === "high" && metadata && ctx.preloadImages) {
|
|
2660
|
-
if (metadata.avifSrcset) {
|
|
2764
|
+
if (metadata.avifSrcset && ctx.imageFormat !== "webp") {
|
|
2661
2765
|
ctx.preloadImages.push({
|
|
2662
2766
|
srcset: metadata.avifSrcset,
|
|
2663
2767
|
type: "image/avif",
|
|
@@ -2682,7 +2786,7 @@ function renderImageElement(propsWithStyleAndAttrs, classAttr, attrs, ctx) {
|
|
|
2682
2786
|
if (metadata?.blurHash) {
|
|
2683
2787
|
blurStyle = ` style="background-image: url(${escapeHtml(metadata.blurHash)}); background-size: cover;" onload="this.style.backgroundImage=''"`;
|
|
2684
2788
|
}
|
|
2685
|
-
if (metadata?.avifSrcset) {
|
|
2789
|
+
if (metadata?.avifSrcset && ctx.imageFormat !== "webp") {
|
|
2686
2790
|
const imgClassPrefixes = [
|
|
2687
2791
|
"objf-",
|
|
2688
2792
|
"objp-",
|
|
@@ -2803,7 +2907,11 @@ function renderLocaleList(node, ctx) {
|
|
|
2803
2907
|
const linksHTML = showSeparator ? links.join(`<span${separatorClassAttr}></span>`) : links.join("");
|
|
2804
2908
|
const nodeAttributes = extractAttributesFromNode(node);
|
|
2805
2909
|
const attrsStr = buildAttributes(nodeAttributes);
|
|
2806
|
-
|
|
2910
|
+
const localeListResult = `<div data-locale-list="true"${containerClassAttr}${localeListStyleAttr}${attrsStr}>${linksHTML}</div>`;
|
|
2911
|
+
if (ctx.ssrFallbackCollector && ctx.elementPath) {
|
|
2912
|
+
ctx.ssrFallbackCollector.set(ctx.elementPath.join("."), localeListResult);
|
|
2913
|
+
}
|
|
2914
|
+
return localeListResult;
|
|
2807
2915
|
}
|
|
2808
2916
|
return '<div data-locale-list="true"></div>';
|
|
2809
2917
|
}
|
|
@@ -2831,7 +2939,7 @@ async function renderPageSSR(pageData, globalComponents = {}, pagePath = "/", ba
|
|
|
2831
2939
|
}
|
|
2832
2940
|
}
|
|
2833
2941
|
const pageComponents = pageData?.components || {};
|
|
2834
|
-
const { html: contentHTML, interactiveStylesMap, preloadImages, neededCollections } = rootNode ? await buildComponentHTML(rootNode, globalComponents, pageComponents, effectiveLocale, config, slugMappings, pagePath, cmsContext, cmsService, isProductionBuild) : { html: "", interactiveStylesMap: /* @__PURE__ */ new Map(), preloadImages: [], neededCollections: /* @__PURE__ */ new Set() };
|
|
2942
|
+
const { html: contentHTML, interactiveStylesMap, preloadImages, neededCollections, ssrFallbackCollector } = rootNode ? await buildComponentHTML(rootNode, globalComponents, pageComponents, effectiveLocale, config, slugMappings, pagePath, cmsContext, cmsService, isProductionBuild) : { html: "", interactiveStylesMap: /* @__PURE__ */ new Map(), preloadImages: [], neededCollections: /* @__PURE__ */ new Set(), ssrFallbackCollector: /* @__PURE__ */ new Map() };
|
|
2835
2943
|
const javascript = await collectComponentJavaScript(globalComponents, pageComponents);
|
|
2836
2944
|
const componentCSS = collectComponentCSS(globalComponents, pageComponents);
|
|
2837
2945
|
const fullUrl = baseUrl ? `${baseUrl}${pagePath}` : pagePath;
|
|
@@ -2851,7 +2959,8 @@ async function renderPageSSR(pageData, globalComponents = {}, pagePath = "/", ba
|
|
|
2851
2959
|
locale: effectiveLocale,
|
|
2852
2960
|
interactiveStylesMap,
|
|
2853
2961
|
preloadImages,
|
|
2854
|
-
neededCollections
|
|
2962
|
+
neededCollections,
|
|
2963
|
+
ssrFallbackCollector
|
|
2855
2964
|
};
|
|
2856
2965
|
}
|
|
2857
2966
|
|
|
@@ -3036,82 +3145,6 @@ function safeOrigin(url) {
|
|
|
3036
3145
|
}
|
|
3037
3146
|
}
|
|
3038
3147
|
|
|
3039
|
-
// lib/server/cssGenerator.ts
|
|
3040
|
-
function generateThemeColorVariablesCSS(themeConfig) {
|
|
3041
|
-
const cssBlocks = [];
|
|
3042
|
-
const palette = themeConfig.palette;
|
|
3043
|
-
for (const [themeName, theme] of Object.entries(themeConfig.themes)) {
|
|
3044
|
-
const cssVars = [];
|
|
3045
|
-
for (const [name, value] of Object.entries(theme.colors)) {
|
|
3046
|
-
const resolved = resolvePaletteColor(value, palette);
|
|
3047
|
-
cssVars.push(` --${name}: ${resolved};`);
|
|
3048
|
-
}
|
|
3049
|
-
if (cssVars.length > 0) {
|
|
3050
|
-
cssBlocks.push(`[theme="${themeName}"] {
|
|
3051
|
-
${cssVars.join("\n")}
|
|
3052
|
-
}`);
|
|
3053
|
-
}
|
|
3054
|
-
}
|
|
3055
|
-
const defaultTheme = themeConfig.themes[themeConfig.default];
|
|
3056
|
-
if (defaultTheme) {
|
|
3057
|
-
const cssVars = [];
|
|
3058
|
-
for (const [name, value] of Object.entries(defaultTheme.colors)) {
|
|
3059
|
-
const resolved = resolvePaletteColor(value, palette);
|
|
3060
|
-
cssVars.push(` --${name}: ${resolved};`);
|
|
3061
|
-
}
|
|
3062
|
-
if (cssVars.length > 0) {
|
|
3063
|
-
cssBlocks.unshift(`:root {
|
|
3064
|
-
${cssVars.join("\n")}
|
|
3065
|
-
}`);
|
|
3066
|
-
}
|
|
3067
|
-
}
|
|
3068
|
-
return cssBlocks.join("\n\n");
|
|
3069
|
-
}
|
|
3070
|
-
function generateVariablesCSS(config, breakpoints, responsiveScales) {
|
|
3071
|
-
if (!config.variables || config.variables.length === 0) {
|
|
3072
|
-
return "";
|
|
3073
|
-
}
|
|
3074
|
-
const cssBlocks = [];
|
|
3075
|
-
const baseVars = config.variables.map((v) => ` ${v.cssVar}: ${v.value};`);
|
|
3076
|
-
cssBlocks.push(`:root {
|
|
3077
|
-
${baseVars.join("\n")}
|
|
3078
|
-
}`);
|
|
3079
|
-
if (breakpoints && responsiveScales?.enabled) {
|
|
3080
|
-
const baseRef = responsiveScales.baseReference || 16;
|
|
3081
|
-
const sortedBreakpoints = Object.entries(breakpoints).sort((a, b) => b[1].breakpoint - a[1].breakpoint);
|
|
3082
|
-
for (const [bpName, bpEntry] of sortedBreakpoints) {
|
|
3083
|
-
const scaledVars = [];
|
|
3084
|
-
for (const variable of config.variables) {
|
|
3085
|
-
if (variable.scales && variable.scales[bpName]) {
|
|
3086
|
-
const overrideValue = variable.scales[bpName];
|
|
3087
|
-
if (overrideValue !== variable.value) {
|
|
3088
|
-
scaledVars.push(` ${variable.cssVar}: ${overrideValue};`);
|
|
3089
|
-
}
|
|
3090
|
-
continue;
|
|
3091
|
-
}
|
|
3092
|
-
if (variable.type === "none") continue;
|
|
3093
|
-
const categoryScales = responsiveScales[variable.type];
|
|
3094
|
-
const scale = categoryScales?.[bpName] ?? null;
|
|
3095
|
-
if (scale === null) continue;
|
|
3096
|
-
const scaled = scalePropertyValue(variable.value, baseRef, scale);
|
|
3097
|
-
if (scaled !== null && scaled !== variable.value) {
|
|
3098
|
-
scaledVars.push(` ${variable.cssVar}: ${scaled};`);
|
|
3099
|
-
}
|
|
3100
|
-
}
|
|
3101
|
-
if (scaledVars.length > 0) {
|
|
3102
|
-
cssBlocks.push(
|
|
3103
|
-
`@media (max-width: ${bpEntry.breakpoint}px) {
|
|
3104
|
-
:root {
|
|
3105
|
-
${scaledVars.join("\n")}
|
|
3106
|
-
}
|
|
3107
|
-
}`
|
|
3108
|
-
);
|
|
3109
|
-
}
|
|
3110
|
-
}
|
|
3111
|
-
}
|
|
3112
|
-
return cssBlocks.join("\n");
|
|
3113
|
-
}
|
|
3114
|
-
|
|
3115
3148
|
// lib/client/scripts/formHandler.ts
|
|
3116
3149
|
var formHandlerScript = `
|
|
3117
3150
|
(function() {
|
|
@@ -3397,11 +3430,6 @@ button {
|
|
|
3397
3430
|
cursor: pointer;
|
|
3398
3431
|
outline: inherit;
|
|
3399
3432
|
}
|
|
3400
|
-
img {
|
|
3401
|
-
display: block;
|
|
3402
|
-
width: 100%;
|
|
3403
|
-
height: 100%;
|
|
3404
|
-
}
|
|
3405
3433
|
picture {
|
|
3406
3434
|
display: block;
|
|
3407
3435
|
}
|
|
@@ -3768,8 +3796,6 @@ export {
|
|
|
3768
3796
|
buildComponentHTML,
|
|
3769
3797
|
renderPageSSR,
|
|
3770
3798
|
prepareClientData,
|
|
3771
|
-
mergeLibraries,
|
|
3772
|
-
generateLibraryTags,
|
|
3773
3799
|
collectComponentLibraries,
|
|
3774
3800
|
extractLibraryOrigins,
|
|
3775
3801
|
filterLibrariesByContext,
|
|
@@ -3777,4 +3803,4 @@ export {
|
|
|
3777
3803
|
FileSystemCMSProvider,
|
|
3778
3804
|
migrateTemplatesDirectory
|
|
3779
3805
|
};
|
|
3780
|
-
//# sourceMappingURL=chunk-
|
|
3806
|
+
//# sourceMappingURL=chunk-SK3TLNUP.js.map
|