meno-core 1.0.52 → 1.0.54
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/.claude/settings.local.json +1 -3
- package/bin/cli.ts +48 -57
- package/build-astro.ts +296 -108
- package/build-next.ts +1374 -0
- package/build-static.test.ts +39 -10
- package/build-static.ts +127 -127
- package/dist/bin/cli.js +34 -38
- package/dist/bin/cli.js.map +2 -2
- package/dist/build-static.js +12 -11
- package/dist/chunks/chunk-2AR55GYH.js +42 -0
- package/dist/chunks/chunk-2AR55GYH.js.map +7 -0
- package/dist/chunks/{chunk-CXCBV2M7.js → chunk-2FN4UOVO.js} +581 -502
- package/dist/chunks/chunk-2FN4UOVO.js.map +7 -0
- package/dist/chunks/chunk-3XER4E5W.js +168 -0
- package/dist/chunks/chunk-3XER4E5W.js.map +7 -0
- package/dist/chunks/chunk-5ETZFREW.js +514 -0
- package/dist/chunks/chunk-5ETZFREW.js.map +7 -0
- package/dist/chunks/{chunk-2MHDV5BF.js → chunk-7E4IF5L7.js} +15 -21
- package/dist/chunks/chunk-7E4IF5L7.js.map +7 -0
- package/dist/chunks/{chunk-7NIC4I3V.js → chunk-7HWQUVTU.js} +1691 -1316
- package/dist/chunks/chunk-7HWQUVTU.js.map +7 -0
- package/dist/chunks/{chunk-EDQSMAMP.js → chunk-AE3QK5QW.js} +189 -19
- package/dist/chunks/chunk-AE3QK5QW.js.map +7 -0
- package/dist/chunks/{chunk-HNLUO36W.js → chunk-F6KTJYGV.js} +8 -8
- package/dist/chunks/chunk-F6KTJYGV.js.map +7 -0
- package/dist/chunks/{chunk-WQFG7PAH.js → chunk-FZITJSSS.js} +2 -6
- package/dist/chunks/chunk-FZITJSSS.js.map +7 -0
- package/dist/chunks/{chunk-H4JSCDNW.js → chunk-GSYYA5GX.js} +25 -2
- package/dist/chunks/chunk-GSYYA5GX.js.map +7 -0
- package/dist/chunks/{chunk-2QK6U5UK.js → chunk-HIZMY3EP.js} +12 -2
- package/dist/chunks/chunk-HIZMY3EP.js.map +7 -0
- package/dist/chunks/{chunk-AZQYF6KE.js → chunk-I2WEGYA7.js} +41 -176
- package/dist/chunks/chunk-I2WEGYA7.js.map +7 -0
- package/dist/chunks/{chunk-I7YIGZXT.js → chunk-JNO3CNLJ.js} +6 -9
- package/dist/chunks/chunk-JNO3CNLJ.js.map +7 -0
- package/dist/chunks/{chunk-UB44F4Z2.js → chunk-NVRBTSQG.js} +2 -4
- package/dist/chunks/chunk-NVRBTSQG.js.map +7 -0
- package/dist/chunks/{chunk-LHLHPYSP.js → chunk-Q4OBWKXG.js} +48 -40
- package/dist/chunks/chunk-Q4OBWKXG.js.map +7 -0
- package/dist/chunks/{chunk-A725KYFK.js → chunk-QTE32Y53.js} +780 -323
- package/dist/chunks/chunk-QTE32Y53.js.map +7 -0
- package/dist/chunks/{chunk-LPVETICS.js → chunk-STDY3OVM.js} +397 -84
- package/dist/chunks/chunk-STDY3OVM.js.map +7 -0
- package/dist/chunks/configService-PRJZF7Y6.js +14 -0
- package/dist/chunks/{constants-GWBAD66U.js → constants-KIQEYMAM.js} +2 -2
- package/dist/chunks/{fs-JGINUXGL.js → fs-ZI5JEU7V.js} +2 -2
- package/dist/entries/server-router.js +14 -19
- package/dist/entries/server-router.js.map +2 -2
- package/dist/lib/client/index.js +957 -356
- package/dist/lib/client/index.js.map +4 -4
- package/dist/lib/server/index.js +1538 -328
- package/dist/lib/server/index.js.map +4 -4
- package/dist/lib/shared/index.js +277 -73
- package/dist/lib/shared/index.js.map +4 -4
- package/dist/lib/shared/richtext/index.js +1 -1
- package/dist/lib/test-utils/index.js +38 -60
- package/dist/lib/test-utils/index.js.map +2 -2
- package/entries/client-router.tsx +14 -172
- package/entries/server-router.tsx +1 -7
- package/lib/client/ClientInitializer.ts +8 -8
- package/lib/client/ErrorBoundary.test.tsx +156 -151
- package/lib/client/ErrorBoundary.tsx +184 -121
- package/lib/client/componentRegistry.test.ts +96 -108
- package/lib/client/componentRegistry.ts +1 -2
- package/lib/client/contexts/ThemeContext.tsx +3 -2
- package/lib/client/core/ComponentBuilder.test.ts +513 -560
- package/lib/client/core/ComponentBuilder.ts +335 -146
- package/lib/client/core/ComponentRenderer.test.tsx +1 -2
- package/lib/client/core/ComponentRenderer.tsx +46 -33
- package/lib/client/core/builders/embedBuilder.ts +246 -54
- package/lib/client/core/builders/linkBuilder.ts +71 -44
- package/lib/client/core/builders/linkNodeBuilder.ts +78 -53
- package/lib/client/core/builders/listBuilder.ts +137 -89
- package/lib/client/core/builders/localeListBuilder.ts +95 -60
- package/lib/client/core/builders/types.ts +5 -5
- package/lib/client/core/cmsTemplateProcessor.ts +7 -7
- package/lib/client/elementRegistry.ts +3 -3
- package/lib/client/fontFamiliesService.test.ts +68 -0
- package/lib/client/fontFamiliesService.ts +69 -0
- package/lib/client/hmr/HMRManager.tsx +8 -0
- package/lib/client/hmrCssReload.ts +166 -0
- package/lib/client/hmrWebSocket.ts +9 -14
- package/lib/client/hooks/useColorVariables.test.ts +21 -21
- package/lib/client/hooks/useColorVariables.ts +14 -10
- package/lib/client/hooks/usePropertyAutocomplete.ts +3 -5
- package/lib/client/hooks/useVariables.ts +4 -4
- package/lib/client/hydration/HydrationUtils.test.ts +24 -25
- package/lib/client/hydration/HydrationUtils.ts +3 -4
- package/lib/client/i18nConfigService.test.ts +2 -7
- package/lib/client/i18nConfigService.ts +2 -2
- package/lib/client/index.ts +4 -0
- package/lib/client/meno-filter/MenoFilter.test.ts +19 -21
- package/lib/client/meno-filter/MenoFilter.ts +5 -9
- package/lib/client/meno-filter/bindings.ts +15 -40
- package/lib/client/meno-filter/init.ts +1 -1
- package/lib/client/meno-filter/renderer.ts +23 -29
- package/lib/client/meno-filter/script.generated.ts +1 -3
- package/lib/client/meno-filter/ui.ts +5 -5
- package/lib/client/meno-filter/updates.ts +15 -21
- package/lib/client/navigation.test.ts +159 -159
- package/lib/client/navigation.ts +0 -1
- package/lib/client/responsiveStyleResolver.test.ts +230 -228
- package/lib/client/responsiveStyleResolver.ts +13 -16
- package/lib/client/routing/RouteLoader.test.ts +25 -26
- package/lib/client/routing/RouteLoader.ts +30 -37
- package/lib/client/routing/Router.tsx +112 -18
- package/lib/client/scripts/ScriptExecutor.test.ts +270 -128
- package/lib/client/scripts/ScriptExecutor.ts +69 -33
- package/lib/client/services/PrefetchService.test.ts +2 -2
- package/lib/client/services/PrefetchService.ts +10 -24
- package/lib/client/styleProcessor.test.ts +9 -9
- package/lib/client/styleProcessor.ts +18 -15
- package/lib/client/styles/StyleInjector.test.ts +122 -115
- package/lib/client/styles/StyleInjector.ts +25 -7
- package/lib/client/styles/UtilityClassCollector.ts +26 -27
- package/lib/client/styles/cspNonce.test.ts +64 -0
- package/lib/client/styles/cspNonce.ts +63 -0
- package/lib/client/templateEngine.test.ts +600 -448
- package/lib/client/templateEngine.ts +205 -64
- package/lib/client/theme.ts +0 -1
- package/lib/client/utils/toast.ts +0 -1
- package/lib/server/__integration__/api-routes.test.ts +8 -4
- package/lib/server/__integration__/cms-integration.test.ts +1 -4
- package/lib/server/__integration__/server-lifecycle.test.ts +2 -5
- package/lib/server/__integration__/ssr-rendering.test.ts +47 -37
- package/lib/server/__integration__/static-assets.test.ts +1 -1
- package/lib/server/__integration__/test-helpers.ts +84 -70
- package/lib/server/ab/generateFunctions.ts +12 -10
- package/lib/server/astro/cmsPageEmitter.ts +47 -32
- package/lib/server/astro/componentEmitter.ts +82 -37
- package/lib/server/astro/cssCollector.ts +10 -26
- package/lib/server/astro/nodeToAstro.test.ts +1750 -30
- package/lib/server/astro/nodeToAstro.ts +327 -178
- package/lib/server/astro/normalizeOrphanTemplateProps.test.ts +260 -0
- package/lib/server/astro/normalizeOrphanTemplateProps.ts +176 -0
- package/lib/server/astro/pageEmitter.ts +9 -13
- package/lib/server/astro/tailwindMapper.test.ts +10 -37
- package/lib/server/astro/tailwindMapper.ts +33 -40
- package/lib/server/astro/templateTransformer.ts +14 -17
- package/lib/server/createServer.ts +16 -17
- package/lib/server/cssGenerator.test.ts +35 -44
- package/lib/server/cssGenerator.ts +6 -17
- package/lib/server/draftPageStore.ts +49 -0
- package/lib/server/fileWatcher.test.ts +124 -10
- package/lib/server/fileWatcher.ts +164 -98
- package/lib/server/index.ts +20 -2
- package/lib/server/jsonLoader.test.ts +39 -2
- package/lib/server/jsonLoader.ts +33 -31
- package/lib/server/middleware/cors.test.ts +20 -20
- package/lib/server/middleware/cors.ts +28 -4
- package/lib/server/middleware/errorHandler.test.ts +5 -3
- package/lib/server/middleware/errorHandler.ts +3 -8
- package/lib/server/middleware/index.ts +0 -1
- package/lib/server/middleware/logger.test.ts +7 -5
- package/lib/server/middleware/logger.ts +10 -22
- package/lib/server/pageCache.test.ts +76 -77
- package/lib/server/pageCache.ts +0 -1
- package/lib/server/projectContext.ts +4 -3
- package/lib/server/providers/fileSystemCMSProvider.test.ts +124 -95
- package/lib/server/providers/fileSystemCMSProvider.ts +35 -20
- package/lib/server/providers/fileSystemPageProvider.test.ts +84 -0
- package/lib/server/providers/fileSystemPageProvider.ts +39 -12
- package/lib/server/routes/api/cms.test.ts +26 -14
- package/lib/server/routes/api/cms.ts +9 -14
- package/lib/server/routes/api/components.ts +35 -34
- package/lib/server/routes/api/config.ts +0 -1
- package/lib/server/routes/api/core-routes.ts +49 -76
- package/lib/server/routes/api/functions.ts +8 -16
- package/lib/server/routes/api/index.ts +3 -6
- package/lib/server/routes/api/pages.ts +21 -32
- package/lib/server/routes/api/shared.test.ts +1 -1
- package/lib/server/routes/api/shared.ts +65 -6
- package/lib/server/routes/api/variables.test.ts +1 -3
- package/lib/server/routes/api/variables.ts +1 -1
- package/lib/server/routes/index.ts +106 -19
- package/lib/server/routes/pages.ts +47 -35
- package/lib/server/routes/static.ts +16 -4
- package/lib/server/runtime/bundler.ts +47 -32
- package/lib/server/runtime/fs.ts +3 -13
- package/lib/server/runtime/httpServer.ts +5 -9
- package/lib/server/services/ColorService.ts +32 -27
- package/lib/server/services/EnumService.test.ts +2 -6
- package/lib/server/services/EnumService.ts +7 -2
- package/lib/server/services/VariableService.test.ts +1 -5
- package/lib/server/services/VariableService.ts +6 -1
- package/lib/server/services/cmsService.test.ts +116 -78
- package/lib/server/services/cmsService.ts +24 -54
- package/lib/server/services/componentService.test.ts +303 -20
- package/lib/server/services/componentService.ts +397 -76
- package/lib/server/services/configService.test.ts +9 -31
- package/lib/server/services/configService.ts +20 -27
- package/lib/server/services/fileWatcherService.ts +44 -30
- package/lib/server/services/index.ts +0 -1
- package/lib/server/services/pageService.test.ts +24 -3
- package/lib/server/services/pageService.ts +135 -16
- package/lib/server/ssr/attributeBuilder.ts +24 -8
- package/lib/server/ssr/buildErrorOverlay.ts +12 -13
- package/lib/server/ssr/clientDataInjector.ts +7 -21
- package/lib/server/ssr/cmsSSRProcessor.ts +3 -6
- package/lib/server/ssr/cssCollector.ts +1 -1
- package/lib/server/ssr/errorOverlay.test.ts +21 -2
- package/lib/server/ssr/errorOverlay.ts +39 -18
- package/lib/server/ssr/htmlGenerator.nonce.test.ts +3 -9
- package/lib/server/ssr/htmlGenerator.test.ts +173 -56
- package/lib/server/ssr/htmlGenerator.ts +191 -112
- package/lib/server/ssr/imageMetadata.test.ts +3 -1
- package/lib/server/ssr/imageMetadata.ts +25 -19
- package/lib/server/ssr/jsCollector.test.ts +3 -13
- package/lib/server/ssr/jsCollector.ts +3 -8
- package/lib/server/ssr/liveReloadIntegration.test.ts +184 -22
- package/lib/server/ssr/metaTagGenerator.ts +2 -2
- package/lib/server/ssr/ssrRenderer.branches.test.ts +1103 -0
- package/lib/server/ssr/ssrRenderer.test.ts +263 -246
- package/lib/server/ssr/ssrRenderer.ts +700 -231
- package/lib/server/ssrRenderer.test.ts +1044 -950
- package/lib/server/utils/jsonLineMapper.test.ts +28 -28
- package/lib/server/utils/jsonLineMapper.ts +1 -1
- package/lib/server/validateStyleCoverage.ts +18 -20
- package/lib/server/webflow/buildWebflow.ts +41 -53
- package/lib/server/webflow/nodeToWebflow.test.ts +150 -218
- package/lib/server/webflow/nodeToWebflow.ts +195 -258
- package/lib/server/webflow/styleMapper.test.ts +15 -56
- package/lib/server/webflow/styleMapper.ts +33 -41
- package/lib/server/webflow/types.ts +1 -8
- package/lib/server/websocketManager.ts +16 -20
- package/lib/shared/attributeNodeUtils.test.ts +15 -15
- package/lib/shared/attributeNodeUtils.ts +5 -12
- package/lib/shared/breakpoints.ts +4 -11
- package/lib/shared/cmsQueryParser.test.ts +50 -42
- package/lib/shared/cmsQueryParser.ts +49 -31
- package/lib/shared/colorVariableUtils.test.ts +5 -5
- package/lib/shared/colorVariableUtils.ts +3 -8
- package/lib/shared/componentRefs.ts +41 -0
- package/lib/shared/constants.test.ts +3 -3
- package/lib/shared/constants.ts +12 -8
- package/lib/shared/cssGeneration.test.ts +262 -144
- package/lib/shared/cssGeneration.ts +189 -514
- package/lib/shared/cssNamedColors.ts +152 -30
- package/lib/shared/cssProperties.test.ts +5 -6
- package/lib/shared/cssProperties.ts +479 -111
- package/lib/shared/elementClassName.test.ts +109 -109
- package/lib/shared/elementClassName.ts +1 -1
- package/lib/shared/elementUtils.ts +12 -16
- package/lib/shared/errorLogger.ts +2 -10
- package/lib/shared/errors.test.ts +2 -13
- package/lib/shared/errors.ts +2 -8
- package/lib/shared/expressionEvaluator.test.ts +119 -0
- package/lib/shared/expressionEvaluator.ts +95 -22
- package/lib/shared/fontCss.ts +101 -0
- package/lib/shared/fontLoader.test.ts +19 -5
- package/lib/shared/fontLoader.ts +8 -86
- package/lib/shared/friendlyError.test.ts +87 -0
- package/lib/shared/friendlyError.ts +120 -0
- package/lib/shared/gradientUtils.test.ts +1 -5
- package/lib/shared/gradientUtils.ts +2 -6
- package/lib/shared/hrefRefs.test.ts +130 -0
- package/lib/shared/hrefRefs.ts +92 -0
- package/lib/shared/i18n.test.ts +1 -1
- package/lib/shared/i18n.ts +13 -34
- package/lib/shared/index.ts +56 -0
- package/lib/shared/inlineSvgStyleRules.test.ts +108 -0
- package/lib/shared/inlineSvgStyleRules.ts +132 -0
- package/lib/shared/interactiveStyleMappings.test.ts +11 -33
- package/lib/shared/interactiveStyleMappings.ts +9 -16
- package/lib/shared/interactiveStyles.test.ts +165 -188
- package/lib/shared/interfaces/contentProvider.ts +14 -1
- package/lib/shared/itemTemplateUtils.test.ts +20 -12
- package/lib/shared/itemTemplateUtils.ts +23 -36
- package/lib/shared/jsonRepair.ts +8 -2
- package/lib/shared/libraryLoader.test.ts +15 -49
- package/lib/shared/libraryLoader.ts +7 -22
- package/lib/shared/netlifyLocale404.test.ts +179 -0
- package/lib/shared/netlifyLocale404.ts +110 -0
- package/lib/shared/nodeUtils.test.ts +24 -16
- package/lib/shared/nodeUtils.ts +49 -19
- package/lib/shared/pathArrayUtils.test.ts +1 -2
- package/lib/shared/pathArrayUtils.ts +1 -1
- package/lib/shared/pathSecurity.ts +1 -1
- package/lib/shared/pathUtils.test.ts +4 -6
- package/lib/shared/pathUtils.ts +42 -48
- package/lib/shared/paths/Path.test.ts +2 -2
- package/lib/shared/paths/Path.ts +0 -1
- package/lib/shared/paths/PathConverter.test.ts +1 -1
- package/lib/shared/paths/PathConverter.ts +14 -17
- package/lib/shared/paths/PathUtils.ts +9 -10
- package/lib/shared/paths/PathValidator.test.ts +2 -15
- package/lib/shared/paths/PathValidator.ts +11 -9
- package/lib/shared/paths/index.ts +1 -2
- package/lib/shared/propResolver.test.ts +240 -244
- package/lib/shared/propResolver.ts +14 -25
- package/lib/shared/pxToRem.test.ts +7 -6
- package/lib/shared/pxToRem.ts +2 -5
- package/lib/shared/registry/BaseNodeTypeRegistry.test.ts +9 -5
- package/lib/shared/registry/ClientRegistry.ts +0 -1
- package/lib/shared/registry/ComponentRegistry.test.ts +43 -29
- package/lib/shared/registry/ComponentRegistry.ts +9 -11
- package/lib/shared/registry/NodeTypeDefinition.ts +15 -8
- package/lib/shared/registry/RegistryManager.ts +1 -2
- package/lib/shared/registry/SSRRegistry.ts +0 -1
- package/lib/shared/registry/createNodeType.ts +7 -9
- package/lib/shared/registry/defineNodeType.ts +2 -6
- package/lib/shared/registry/index.ts +0 -1
- package/lib/shared/registry/nodeTypes/ComponentInstanceNodeType.ts +14 -15
- package/lib/shared/registry/nodeTypes/EmbedNodeType.ts +18 -11
- package/lib/shared/registry/nodeTypes/HtmlNodeType.ts +47 -18
- package/lib/shared/registry/nodeTypes/LinkNodeType.ts +22 -20
- package/lib/shared/registry/nodeTypes/ListNodeType.ts +78 -74
- package/lib/shared/registry/nodeTypes/LocaleListNodeType.ts +27 -21
- package/lib/shared/registry/nodeTypes/SlotMarkerType.ts +6 -7
- package/lib/shared/registry/nodeTypes/index.ts +10 -2
- package/lib/shared/responsiveScaling.test.ts +15 -31
- package/lib/shared/responsiveScaling.ts +55 -37
- package/lib/shared/responsiveStyleUtils.ts +11 -13
- package/lib/shared/richtext/htmlToTiptap.test.ts +23 -14
- package/lib/shared/richtext/htmlToTiptap.ts +1 -3
- package/lib/shared/richtext/tiptapToHtml.test.ts +5 -6
- package/lib/shared/richtext/types.ts +1 -8
- package/lib/shared/slugTranslator.test.ts +37 -13
- package/lib/shared/slugTranslator.ts +31 -11
- package/lib/shared/slugify.ts +9 -15
- package/lib/shared/styleNodeUtils.test.ts +8 -8
- package/lib/shared/styleNodeUtils.ts +9 -11
- package/lib/shared/styleUtils.test.ts +87 -61
- package/lib/shared/styleUtils.ts +5 -6
- package/lib/shared/themeDefaults.test.ts +11 -11
- package/lib/shared/themeDefaults.ts +3 -4
- package/lib/shared/tree/PathBuilder.test.ts +160 -109
- package/lib/shared/tree/PathBuilder.ts +121 -59
- package/lib/shared/treePathUtils.test.ts +2 -10
- package/lib/shared/treePathUtils.ts +54 -59
- package/lib/shared/types/api.ts +1 -2
- package/lib/shared/types/cms.ts +25 -21
- package/lib/shared/types/comment.ts +132 -0
- package/lib/shared/types/components.ts +27 -25
- package/lib/shared/types/errors.test.ts +1 -6
- package/lib/shared/types/errors.ts +3 -7
- package/lib/shared/types/experiments.ts +28 -28
- package/lib/shared/types/index.ts +14 -2
- package/lib/shared/types/rendering.ts +8 -0
- package/lib/shared/types/styles.ts +0 -1
- package/lib/shared/types/variables.test.ts +4 -13
- package/lib/shared/types/variables.ts +48 -27
- package/lib/shared/types.ts +1 -2
- package/lib/shared/utilityClassConfig.ts +648 -319
- package/lib/shared/utilityClassMapper.test.ts +213 -78
- package/lib/shared/utilityClassMapper.ts +188 -246
- package/lib/shared/utilityClassNames.ts +326 -0
- package/lib/shared/utils.test.ts +2 -10
- package/lib/shared/utils.ts +19 -10
- package/lib/shared/validation/cmsValidators.ts +2 -1
- package/lib/shared/validation/commentValidators.test.ts +53 -0
- package/lib/shared/validation/commentValidators.ts +80 -0
- package/lib/shared/validation/index.ts +1 -0
- package/lib/shared/validation/propValidator.test.ts +18 -20
- package/lib/shared/validation/propValidator.ts +12 -17
- package/lib/shared/validation/schemas.test.ts +24 -33
- package/lib/shared/validation/schemas.ts +469 -344
- package/lib/shared/validation/validators.test.ts +1 -6
- package/lib/shared/validation/validators.ts +89 -68
- package/lib/shared/viewportUnits.integration.test.ts +46 -0
- package/lib/shared/viewportUnits.test.ts +91 -0
- package/lib/shared/viewportUnits.ts +63 -0
- package/lib/test-utils/dom-setup.ts +7 -1
- package/lib/test-utils/factories/ConsoleMockFactory.ts +3 -7
- package/lib/test-utils/factories/DomMockFactory.ts +7 -19
- package/lib/test-utils/factories/EventMockFactory.ts +7 -13
- package/lib/test-utils/factories/FetchMockFactory.ts +39 -57
- package/lib/test-utils/factories/ServerMockFactory.ts +5 -9
- package/lib/test-utils/factories/StoreMockFactory.ts +14 -25
- package/lib/test-utils/fixtures.ts +45 -45
- package/lib/test-utils/helpers/asyncHelpers.test.ts +15 -18
- package/lib/test-utils/helpers/asyncHelpers.ts +11 -20
- package/lib/test-utils/helpers.ts +1 -5
- package/lib/test-utils/index.ts +0 -4
- package/lib/test-utils/mockFactories.ts +12 -18
- package/lib/test-utils/mocks.ts +4 -2
- package/package.json +1 -1
- package/scripts/build-meno-filter.ts +1 -4
- package/vite.config.ts +4 -4
- package/dist/chunks/chunk-2MHDV5BF.js.map +0 -7
- 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-AZQYF6KE.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-I7YIGZXT.js.map +0 -7
- package/dist/chunks/chunk-J23ZX5AP.js +0 -241
- 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/chunk-UB44F4Z2.js.map +0 -7
- package/dist/chunks/chunk-WQFG7PAH.js.map +0 -7
- package/dist/chunks/configService-R3OGU2UD.js +0 -13
- /package/dist/chunks/{configService-R3OGU2UD.js.map → configService-PRJZF7Y6.js.map} +0 -0
- /package/dist/chunks/{constants-GWBAD66U.js.map → constants-KIQEYMAM.js.map} +0 -0
- /package/dist/chunks/{fs-JGINUXGL.js.map → fs-ZI5JEU7V.js.map} +0 -0
|
@@ -1,32 +1,42 @@
|
|
|
1
1
|
import {
|
|
2
2
|
configService
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-7E4IF5L7.js";
|
|
4
4
|
import {
|
|
5
5
|
projectPaths,
|
|
6
6
|
resolveProjectPath,
|
|
7
7
|
validateJS
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-JNO3CNLJ.js";
|
|
9
9
|
import {
|
|
10
10
|
fileExists,
|
|
11
11
|
readJsonFile,
|
|
12
12
|
readTextFile,
|
|
13
13
|
writeFile
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-FZITJSSS.js";
|
|
15
15
|
import {
|
|
16
16
|
CMS_DRAFT_SUFFIX,
|
|
17
|
+
buildSlugIndex,
|
|
18
|
+
collectComponentLibraries,
|
|
19
|
+
filterLibrariesByContext,
|
|
20
|
+
fontFaceCss,
|
|
21
|
+
fontPreloadLinks,
|
|
22
|
+
generateLibraryTags,
|
|
23
|
+
getLocaleLinks,
|
|
17
24
|
isReservedDraftFilename,
|
|
18
25
|
isSafePathSegment,
|
|
19
26
|
isValidIdentifier,
|
|
20
|
-
|
|
21
|
-
|
|
27
|
+
mergeLibraries,
|
|
28
|
+
resolvePaletteColor,
|
|
29
|
+
translatePath
|
|
30
|
+
} from "./chunk-5ETZFREW.js";
|
|
22
31
|
import {
|
|
23
32
|
extractAttributesFromNode,
|
|
33
|
+
inlineSvgStyleRules,
|
|
24
34
|
isHtmlMapping,
|
|
25
35
|
mergeNodeStyles,
|
|
26
36
|
processStructure,
|
|
27
37
|
resolveHtmlMapping,
|
|
28
38
|
skipEmptyTemplateAttributes
|
|
29
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-AE3QK5QW.js";
|
|
30
40
|
import {
|
|
31
41
|
DEFAULT_PREFETCH_CONFIG,
|
|
32
42
|
SSRRegistry,
|
|
@@ -62,36 +72,41 @@ import {
|
|
|
62
72
|
resolvePropsFromDefinition,
|
|
63
73
|
resolveTemplateRawValue,
|
|
64
74
|
responsiveStylesToClasses,
|
|
75
|
+
rewriteViewportUnits,
|
|
65
76
|
singularize,
|
|
77
|
+
toFriendlyError,
|
|
66
78
|
validateCMSDraftItem,
|
|
67
79
|
validateCMSItem,
|
|
68
80
|
validateComponentDefinition
|
|
69
|
-
} from "./chunk-
|
|
81
|
+
} from "./chunk-7HWQUVTU.js";
|
|
70
82
|
import {
|
|
71
83
|
DEFAULT_BREAKPOINTS,
|
|
72
84
|
DEFAULT_FLUID_RANGE,
|
|
73
|
-
DEFAULT_I18N_CONFIG,
|
|
74
85
|
DEFAULT_SITE_MARGIN,
|
|
75
86
|
buildFluidPropertyValue,
|
|
76
|
-
buildLocalizedPath,
|
|
77
87
|
buildSiteMarginClamp,
|
|
78
|
-
extractLocaleFromPath,
|
|
79
88
|
getSmallestBreakpointName,
|
|
80
|
-
|
|
81
|
-
migrateI18nConfig,
|
|
89
|
+
logRuntimeError,
|
|
82
90
|
normalizeBreakpointConfig,
|
|
83
|
-
resolveI18nValue,
|
|
84
91
|
scalePropertyValue
|
|
85
|
-
} from "./chunk-
|
|
92
|
+
} from "./chunk-I2WEGYA7.js";
|
|
93
|
+
import {
|
|
94
|
+
DEFAULT_I18N_CONFIG,
|
|
95
|
+
buildLocalizedPath,
|
|
96
|
+
extractLocaleFromPath,
|
|
97
|
+
isI18nValue,
|
|
98
|
+
migrateI18nConfig,
|
|
99
|
+
resolveI18nValue
|
|
100
|
+
} from "./chunk-3XER4E5W.js";
|
|
86
101
|
import {
|
|
87
102
|
isTiptapDocument,
|
|
88
103
|
tiptapToHtml
|
|
89
|
-
} from "./chunk-
|
|
104
|
+
} from "./chunk-NVRBTSQG.js";
|
|
90
105
|
import {
|
|
91
106
|
NODE_TYPE,
|
|
92
107
|
RAW_HTML_PREFIX,
|
|
93
108
|
init_constants
|
|
94
|
-
} from "./chunk-
|
|
109
|
+
} from "./chunk-HIZMY3EP.js";
|
|
95
110
|
import {
|
|
96
111
|
__require
|
|
97
112
|
} from "./chunk-KSBZ2L7C.js";
|
|
@@ -167,7 +182,7 @@ function attemptJsonRepair(content) {
|
|
|
167
182
|
const nextLine = i + 1 < lines.length ? lines[i + 1] : null;
|
|
168
183
|
if (nextLine !== null) {
|
|
169
184
|
const nextTrimmed = nextLine.trimStart();
|
|
170
|
-
const needsComma = /["\d\w\]}
|
|
185
|
+
const needsComma = /["\d\w\]}-]$/.test(trimmed) && !trimmed.endsWith(",") && !trimmed.endsWith("{") && !trimmed.endsWith("[") && !trimmed.endsWith(":") && (nextTrimmed.startsWith('"') || nextTrimmed.startsWith("{") || nextTrimmed.startsWith("[") || /^\d/.test(nextTrimmed) || nextTrimmed === "true" || nextTrimmed === "false" || nextTrimmed === "null");
|
|
171
186
|
if (needsComma) {
|
|
172
187
|
fixed += trimmed + ",\n";
|
|
173
188
|
if (repairLine === 0) repairLine = i + 1;
|
|
@@ -212,6 +227,7 @@ async function loadJSONFile(filePath) {
|
|
|
212
227
|
}
|
|
213
228
|
return null;
|
|
214
229
|
} catch (error) {
|
|
230
|
+
logRuntimeError("jsonLoader.loadJSONFile", error, { filePath });
|
|
215
231
|
return null;
|
|
216
232
|
}
|
|
217
233
|
}
|
|
@@ -225,6 +241,7 @@ async function loadFileAsText(filePath) {
|
|
|
225
241
|
}
|
|
226
242
|
return null;
|
|
227
243
|
} catch (error) {
|
|
244
|
+
logRuntimeError("jsonLoader.loadFileAsText", error, { filePath });
|
|
228
245
|
return null;
|
|
229
246
|
}
|
|
230
247
|
}
|
|
@@ -263,10 +280,7 @@ async function loadSingleComponent(filePath, componentName, category) {
|
|
|
263
280
|
const dirPath = filePath.substring(0, filePath.lastIndexOf("/"));
|
|
264
281
|
const jsFilePath = `${dirPath}/${componentName}.js`;
|
|
265
282
|
const cssFilePath = `${dirPath}/${componentName}.css`;
|
|
266
|
-
const [jsContent, cssContent] = await Promise.all([
|
|
267
|
-
loadFileAsText(jsFilePath),
|
|
268
|
-
loadFileAsText(cssFilePath)
|
|
269
|
-
]);
|
|
283
|
+
const [jsContent, cssContent] = await Promise.all([loadFileAsText(jsFilePath), loadFileAsText(cssFilePath)]);
|
|
270
284
|
if (!componentDef.component) {
|
|
271
285
|
componentDef.component = {};
|
|
272
286
|
}
|
|
@@ -285,6 +299,7 @@ async function loadSingleComponent(filePath, componentName, category) {
|
|
|
285
299
|
}
|
|
286
300
|
return { component: componentDef, warning };
|
|
287
301
|
} catch (error) {
|
|
302
|
+
logRuntimeError("jsonLoader.loadSingleComponent", error, { filePath, componentName });
|
|
288
303
|
return { component: null };
|
|
289
304
|
}
|
|
290
305
|
}
|
|
@@ -366,6 +381,7 @@ async function loadBreakpointConfig() {
|
|
|
366
381
|
}
|
|
367
382
|
}
|
|
368
383
|
} catch (error) {
|
|
384
|
+
logRuntimeError("jsonLoader.loadBreakpointConfig", error, { filePath: projectPaths.config() });
|
|
369
385
|
}
|
|
370
386
|
return { ...DEFAULT_BREAKPOINTS };
|
|
371
387
|
}
|
|
@@ -377,6 +393,7 @@ async function loadI18nConfig() {
|
|
|
377
393
|
return migrateI18nConfig(config.i18n);
|
|
378
394
|
}
|
|
379
395
|
} catch (error) {
|
|
396
|
+
logRuntimeError("jsonLoader.loadI18nConfig", error, { filePath: projectPaths.config() });
|
|
380
397
|
}
|
|
381
398
|
return { ...DEFAULT_I18N_CONFIG };
|
|
382
399
|
}
|
|
@@ -390,6 +407,7 @@ async function loadIconsConfig() {
|
|
|
390
407
|
}
|
|
391
408
|
}
|
|
392
409
|
} catch (error) {
|
|
410
|
+
logRuntimeError("jsonLoader.loadIconsConfig", error, { filePath: projectPaths.config() });
|
|
393
411
|
}
|
|
394
412
|
return {};
|
|
395
413
|
}
|
|
@@ -406,6 +424,7 @@ async function loadPrefetchConfig() {
|
|
|
406
424
|
}
|
|
407
425
|
}
|
|
408
426
|
} catch (error) {
|
|
427
|
+
logRuntimeError("jsonLoader.loadPrefetchConfig", error, { filePath: projectPaths.config() });
|
|
409
428
|
}
|
|
410
429
|
return { ...DEFAULT_PREFETCH_CONFIG };
|
|
411
430
|
}
|
|
@@ -485,44 +504,44 @@ var ColorService = class extends CachedConfigLoader {
|
|
|
485
504
|
dark: {
|
|
486
505
|
label: "Dark",
|
|
487
506
|
colors: {
|
|
488
|
-
|
|
507
|
+
primary: "#007acc",
|
|
489
508
|
"primary-light": "#0099ff",
|
|
490
509
|
"primary-dark": "#005a99",
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
510
|
+
secondary: "#6c757d",
|
|
511
|
+
success: "#28a745",
|
|
512
|
+
warning: "#ffc107",
|
|
513
|
+
danger: "#dc3545",
|
|
514
|
+
error: "#d32f2f",
|
|
515
|
+
info: "#17a2b8",
|
|
516
|
+
light: "#f8f9fa",
|
|
517
|
+
dark: "#343a40",
|
|
518
|
+
text: "#cccccc",
|
|
500
519
|
"text-dark": "#1e1e1e",
|
|
501
|
-
|
|
520
|
+
background: "#1e1e1e",
|
|
502
521
|
"background-light": "#252526",
|
|
503
|
-
|
|
522
|
+
border: "#444444",
|
|
504
523
|
"border-light": "#d0d0d0"
|
|
505
524
|
}
|
|
506
525
|
},
|
|
507
526
|
light: {
|
|
508
527
|
label: "Light",
|
|
509
528
|
colors: {
|
|
510
|
-
|
|
529
|
+
primary: "#0066ff",
|
|
511
530
|
"primary-light": "#3385ff",
|
|
512
531
|
"primary-dark": "#0052cc",
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
532
|
+
secondary: "#888888",
|
|
533
|
+
success: "#22c55e",
|
|
534
|
+
warning: "#f59e0b",
|
|
535
|
+
danger: "#ef4444",
|
|
536
|
+
error: "#dc2626",
|
|
537
|
+
info: "#06b6d4",
|
|
538
|
+
light: "#f8f9fa",
|
|
539
|
+
dark: "#1f2937",
|
|
540
|
+
text: "#1f2937",
|
|
522
541
|
"text-dark": "#ffffff",
|
|
523
|
-
|
|
542
|
+
background: "#ffffff",
|
|
524
543
|
"background-light": "#f3f4f6",
|
|
525
|
-
|
|
544
|
+
border: "#d1d5db",
|
|
526
545
|
"border-light": "#e5e7eb"
|
|
527
546
|
}
|
|
528
547
|
}
|
|
@@ -539,8 +558,8 @@ var ColorService = class extends CachedConfigLoader {
|
|
|
539
558
|
default: {
|
|
540
559
|
label: "Default",
|
|
541
560
|
colors: {
|
|
542
|
-
|
|
543
|
-
|
|
561
|
+
background: "#1e1e1e",
|
|
562
|
+
text: "#cccccc"
|
|
544
563
|
}
|
|
545
564
|
}
|
|
546
565
|
}
|
|
@@ -561,7 +580,12 @@ var ColorService = class extends CachedConfigLoader {
|
|
|
561
580
|
if (data && typeof data === "object" && "themes" in data && "default" in data) {
|
|
562
581
|
return { status: "valid", config: data, filePath };
|
|
563
582
|
}
|
|
564
|
-
return {
|
|
583
|
+
return {
|
|
584
|
+
status: "invalid",
|
|
585
|
+
config: this.getMinimalConfig(),
|
|
586
|
+
error: 'Invalid structure: missing "themes" or "default" property',
|
|
587
|
+
filePath
|
|
588
|
+
};
|
|
565
589
|
} catch (error) {
|
|
566
590
|
return {
|
|
567
591
|
status: "invalid",
|
|
@@ -698,7 +722,12 @@ var VariableService = class extends CachedConfigLoader {
|
|
|
698
722
|
if (data && typeof data === "object" && "variables" in data && Array.isArray(data.variables)) {
|
|
699
723
|
return { status: "valid", config: this.migrateConfig(data), filePath };
|
|
700
724
|
}
|
|
701
|
-
return {
|
|
725
|
+
return {
|
|
726
|
+
status: "invalid",
|
|
727
|
+
config: this.getDefaultConfig(),
|
|
728
|
+
error: 'Invalid structure: missing "variables" array',
|
|
729
|
+
filePath
|
|
730
|
+
};
|
|
702
731
|
} catch (error) {
|
|
703
732
|
return {
|
|
704
733
|
status: "invalid",
|
|
@@ -966,9 +995,7 @@ var CMSService = class {
|
|
|
966
995
|
const slugValue = item[schemaInfo.schema.slugField];
|
|
967
996
|
if (typeof slugValue === "string") {
|
|
968
997
|
if (options?.excludeDrafts && defaultLocale && isItemDraftForLocale(item, defaultLocale)) continue;
|
|
969
|
-
urls.push(
|
|
970
|
-
schemaInfo.schema.urlPattern.replace("{{slug}}", slugValue)
|
|
971
|
-
);
|
|
998
|
+
urls.push(schemaInfo.schema.urlPattern.replace("{{slug}}", slugValue));
|
|
972
999
|
} else if (isI18nValue(slugValue) && locales) {
|
|
973
1000
|
for (const locale of locales) {
|
|
974
1001
|
if (options?.excludeDrafts && isItemDraftForLocale(item, locale)) continue;
|
|
@@ -985,9 +1012,7 @@ var CMSService = class {
|
|
|
985
1012
|
} else if (isI18nValue(slugValue)) {
|
|
986
1013
|
for (const key of Object.keys(slugValue)) {
|
|
987
1014
|
if (key !== "_i18n" && typeof slugValue[key] === "string") {
|
|
988
|
-
urls.push(
|
|
989
|
-
schemaInfo.schema.urlPattern.replace("{{slug}}", slugValue[key])
|
|
990
|
-
);
|
|
1015
|
+
urls.push(schemaInfo.schema.urlPattern.replace("{{slug}}", slugValue[key]));
|
|
991
1016
|
break;
|
|
992
1017
|
}
|
|
993
1018
|
}
|
|
@@ -1142,14 +1167,10 @@ var CMSService = class {
|
|
|
1142
1167
|
*/
|
|
1143
1168
|
applyFilters(items, filter) {
|
|
1144
1169
|
if (!Array.isArray(filter) && !this.isFilterCondition(filter)) {
|
|
1145
|
-
return items.filter(
|
|
1146
|
-
(item) => Object.entries(filter).every(([key, value]) => item[key] === value)
|
|
1147
|
-
);
|
|
1170
|
+
return items.filter((item) => Object.entries(filter).every(([key, value]) => item[key] === value));
|
|
1148
1171
|
}
|
|
1149
1172
|
const conditions = Array.isArray(filter) ? filter : [filter];
|
|
1150
|
-
return items.filter(
|
|
1151
|
-
(item) => conditions.every((cond) => this.matchCondition(item, cond))
|
|
1152
|
-
);
|
|
1173
|
+
return items.filter((item) => conditions.every((cond) => this.matchCondition(item, cond)));
|
|
1153
1174
|
}
|
|
1154
1175
|
/**
|
|
1155
1176
|
* Check if object is a CMSFilterCondition
|
|
@@ -1199,9 +1220,7 @@ var CMSService = class {
|
|
|
1199
1220
|
}
|
|
1200
1221
|
const allItems = await this.getCachedItems(collection);
|
|
1201
1222
|
const itemMap = new Map(allItems.map((item) => [item._id, item]));
|
|
1202
|
-
const filenameMap = new Map(
|
|
1203
|
-
allItems.filter((item) => item._filename).map((item) => [item._filename, item])
|
|
1204
|
-
);
|
|
1223
|
+
const filenameMap = new Map(allItems.filter((item) => item._filename).map((item) => [item._filename, item]));
|
|
1205
1224
|
return ids.filter(Boolean).map((id) => itemMap.get(id) || filenameMap.get(id)).filter((item) => item !== void 0);
|
|
1206
1225
|
}
|
|
1207
1226
|
/**
|
|
@@ -1248,7 +1267,9 @@ var CMSService = class {
|
|
|
1248
1267
|
const allSchemas = this.getAllSchemas();
|
|
1249
1268
|
for (const [collectionId, schemaInfo] of allSchemas) {
|
|
1250
1269
|
const { schema } = schemaInfo;
|
|
1251
|
-
const refFields = Object.entries(schema.fields).filter(
|
|
1270
|
+
const refFields = Object.entries(schema.fields).filter(
|
|
1271
|
+
([_, def]) => def.type === "reference" && def.collection === targetCollection
|
|
1272
|
+
);
|
|
1252
1273
|
if (refFields.length === 0) continue;
|
|
1253
1274
|
const items = await this.getCachedItems(collectionId);
|
|
1254
1275
|
for (const item of items) {
|
|
@@ -1323,57 +1344,11 @@ async function loadProjectConfig() {
|
|
|
1323
1344
|
function getProjectConfig() {
|
|
1324
1345
|
return cachedConfig || { fonts: [] };
|
|
1325
1346
|
}
|
|
1326
|
-
function getFontFormat(path2) {
|
|
1327
|
-
if (path2.endsWith(".woff2")) return "woff2";
|
|
1328
|
-
if (path2.endsWith(".woff")) return "woff";
|
|
1329
|
-
if (path2.endsWith(".ttf")) return "truetype";
|
|
1330
|
-
if (path2.endsWith(".otf")) return "opentype";
|
|
1331
|
-
return "truetype";
|
|
1332
|
-
}
|
|
1333
|
-
function extractFamilyName(path2) {
|
|
1334
|
-
const filename = path2.split("/").pop() || "Font";
|
|
1335
|
-
const name = filename.replace(/\.(ttf|woff2?|otf)$/i, "");
|
|
1336
|
-
return name.split("-").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
|
|
1337
|
-
}
|
|
1338
1347
|
function generateFontCSS() {
|
|
1339
|
-
|
|
1340
|
-
const fonts = config.fonts || [];
|
|
1341
|
-
return fonts.filter((font) => font.path || font.src).map((font) => {
|
|
1342
|
-
const fontPath = font.path || font.src;
|
|
1343
|
-
const format = getFontFormat(fontPath);
|
|
1344
|
-
const family = font.family || extractFamilyName(fontPath);
|
|
1345
|
-
const weight = font.weight ?? 400;
|
|
1346
|
-
const weightMax = font.weightMax;
|
|
1347
|
-
const style = font.style ?? "normal";
|
|
1348
|
-
const fontDisplay = font.fontDisplay;
|
|
1349
|
-
const fontWeight = weightMax != null ? `${weight} ${weightMax}` : weight;
|
|
1350
|
-
const unicodeRange = font.unicodeRange;
|
|
1351
|
-
return `@font-face {
|
|
1352
|
-
font-family: '${family}';
|
|
1353
|
-
src: url('${fontPath}') format('${format}');
|
|
1354
|
-
font-weight: ${fontWeight};
|
|
1355
|
-
font-style: ${style};${fontDisplay ? `
|
|
1356
|
-
font-display: ${fontDisplay};` : ""}${unicodeRange ? `
|
|
1357
|
-
unicode-range: ${unicodeRange};` : ""}
|
|
1358
|
-
}`;
|
|
1359
|
-
}).join("\n\n");
|
|
1360
|
-
}
|
|
1361
|
-
function getFontMimeType(path2) {
|
|
1362
|
-
if (path2.endsWith(".woff2")) return "font/woff2";
|
|
1363
|
-
if (path2.endsWith(".woff")) return "font/woff";
|
|
1364
|
-
if (path2.endsWith(".ttf")) return "font/ttf";
|
|
1365
|
-
if (path2.endsWith(".otf")) return "font/otf";
|
|
1366
|
-
return "font/ttf";
|
|
1348
|
+
return fontFaceCss(getProjectConfig().fonts || []);
|
|
1367
1349
|
}
|
|
1368
1350
|
function generateFontPreloadTags() {
|
|
1369
|
-
|
|
1370
|
-
const fonts = config.fonts || [];
|
|
1371
|
-
if (fonts.length === 0) return "";
|
|
1372
|
-
return fonts.filter((font) => font.path || font.src).map((font) => {
|
|
1373
|
-
const fontPath = font.path || font.src;
|
|
1374
|
-
const mimeType = getFontMimeType(fontPath);
|
|
1375
|
-
return `<link rel="preload" href="${fontPath}" as="font" type="${mimeType}" crossorigin>`;
|
|
1376
|
-
}).join("\n ");
|
|
1351
|
+
return fontPreloadLinks(getProjectConfig().fonts || []);
|
|
1377
1352
|
}
|
|
1378
1353
|
|
|
1379
1354
|
// lib/server/cssGenerator.ts
|
|
@@ -1418,13 +1393,7 @@ function generateVariablesCSS(config, breakpoints, responsiveScales) {
|
|
|
1418
1393
|
const categoryScales = responsiveScales?.[v.type];
|
|
1419
1394
|
const scale = categoryScales?.[smallestBp];
|
|
1420
1395
|
if (scale != null && scale !== 1) {
|
|
1421
|
-
const fluid = buildFluidPropertyValue(
|
|
1422
|
-
v.value,
|
|
1423
|
-
scale,
|
|
1424
|
-
fluidRange.min,
|
|
1425
|
-
fluidRange.max,
|
|
1426
|
-
fluidBaseRef
|
|
1427
|
-
);
|
|
1396
|
+
const fluid = buildFluidPropertyValue(v.value, scale, fluidRange.min, fluidRange.max, fluidBaseRef);
|
|
1428
1397
|
if (fluid) return ` ${v.cssVar}: ${fluid};`;
|
|
1429
1398
|
}
|
|
1430
1399
|
}
|
|
@@ -1464,13 +1433,11 @@ ${baseVars.join("\n")}
|
|
|
1464
1433
|
}
|
|
1465
1434
|
}
|
|
1466
1435
|
if (scaledVars.length > 0) {
|
|
1467
|
-
cssBlocks.push(
|
|
1468
|
-
`@media (max-width: ${bpEntry.breakpoint}px) {
|
|
1436
|
+
cssBlocks.push(`@media (max-width: ${bpEntry.breakpoint}px) {
|
|
1469
1437
|
:root {
|
|
1470
1438
|
${scaledVars.join("\n")}
|
|
1471
1439
|
}
|
|
1472
|
-
}`
|
|
1473
|
-
);
|
|
1440
|
+
}`);
|
|
1474
1441
|
}
|
|
1475
1442
|
}
|
|
1476
1443
|
}
|
|
@@ -1553,80 +1520,17 @@ function styleToString(style) {
|
|
|
1553
1520
|
const declarations = [];
|
|
1554
1521
|
for (const [key, value] of Object.entries(style)) {
|
|
1555
1522
|
if (value === null || value === void 0) continue;
|
|
1523
|
+
const rewritten = rewriteViewportUnits(String(value));
|
|
1556
1524
|
if (key.startsWith("--")) {
|
|
1557
|
-
declarations.push(`${key}: ${escapeHtml(
|
|
1525
|
+
declarations.push(`${key}: ${escapeHtml(rewritten)}`);
|
|
1558
1526
|
} else {
|
|
1559
1527
|
const cssProperty = key.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
1560
|
-
declarations.push(`${cssProperty}: ${escapeHtml(
|
|
1528
|
+
declarations.push(`${cssProperty}: ${escapeHtml(rewritten)}`);
|
|
1561
1529
|
}
|
|
1562
1530
|
}
|
|
1563
1531
|
return declarations.length > 0 ? declarations.join("; ") : "";
|
|
1564
1532
|
}
|
|
1565
1533
|
|
|
1566
|
-
// lib/shared/slugTranslator.ts
|
|
1567
|
-
function buildSlugIndex(mappings) {
|
|
1568
|
-
const index = /* @__PURE__ */ new Map();
|
|
1569
|
-
for (const mapping of mappings) {
|
|
1570
|
-
for (const [locale, slug] of Object.entries(mapping.slugs)) {
|
|
1571
|
-
const key = `${locale}:${slug}`;
|
|
1572
|
-
index.set(key, {
|
|
1573
|
-
pageId: mapping.pageId,
|
|
1574
|
-
slugs: mapping.slugs
|
|
1575
|
-
});
|
|
1576
|
-
}
|
|
1577
|
-
}
|
|
1578
|
-
return index;
|
|
1579
|
-
}
|
|
1580
|
-
function findPageBySlug(slug, locale, index) {
|
|
1581
|
-
const key = `${locale}:${slug}`;
|
|
1582
|
-
return index.get(key);
|
|
1583
|
-
}
|
|
1584
|
-
function translatePath(currentPath, targetLocale, currentLocale, defaultLocale, index) {
|
|
1585
|
-
let slug = currentPath;
|
|
1586
|
-
if (slug.startsWith("/")) {
|
|
1587
|
-
slug = slug.substring(1);
|
|
1588
|
-
}
|
|
1589
|
-
if (currentLocale !== defaultLocale) {
|
|
1590
|
-
if (slug.startsWith(`${currentLocale}/`)) {
|
|
1591
|
-
slug = slug.substring(currentLocale.length + 1);
|
|
1592
|
-
} else if (slug === currentLocale) {
|
|
1593
|
-
slug = "";
|
|
1594
|
-
}
|
|
1595
|
-
}
|
|
1596
|
-
if (slug === "" || slug === "/") {
|
|
1597
|
-
slug = "";
|
|
1598
|
-
}
|
|
1599
|
-
let entry = findPageBySlug(slug, currentLocale, index);
|
|
1600
|
-
if (!entry && currentLocale !== defaultLocale) {
|
|
1601
|
-
entry = findPageBySlug(slug, defaultLocale, index);
|
|
1602
|
-
}
|
|
1603
|
-
if (!entry) {
|
|
1604
|
-
if (targetLocale === defaultLocale) {
|
|
1605
|
-
return slug === "" ? "/" : `/${slug}`;
|
|
1606
|
-
}
|
|
1607
|
-
return slug === "" ? `/${targetLocale}` : `/${targetLocale}/${slug}`;
|
|
1608
|
-
}
|
|
1609
|
-
const targetSlug = entry.slugs[targetLocale] ?? entry.slugs[defaultLocale] ?? slug;
|
|
1610
|
-
if (targetLocale === defaultLocale) {
|
|
1611
|
-
return targetSlug === "" ? "/" : `/${targetSlug}`;
|
|
1612
|
-
}
|
|
1613
|
-
return targetSlug === "" ? `/${targetLocale}` : `/${targetLocale}/${targetSlug}`;
|
|
1614
|
-
}
|
|
1615
|
-
function getLocaleLinks(currentPath, currentLocale, i18nConfig, index) {
|
|
1616
|
-
return i18nConfig.locales.map((localeConfig) => ({
|
|
1617
|
-
locale: localeConfig.code,
|
|
1618
|
-
langTag: localeConfig.langTag,
|
|
1619
|
-
name: localeConfig.name,
|
|
1620
|
-
nativeName: localeConfig.nativeName,
|
|
1621
|
-
path: translatePath(currentPath, localeConfig.code, currentLocale, i18nConfig.defaultLocale, index),
|
|
1622
|
-
isCurrent: localeConfig.code === currentLocale
|
|
1623
|
-
}));
|
|
1624
|
-
}
|
|
1625
|
-
function resolveSlugToPageId(slug, locale, index) {
|
|
1626
|
-
const entry = findPageBySlug(slug, locale, index);
|
|
1627
|
-
return entry?.pageId;
|
|
1628
|
-
}
|
|
1629
|
-
|
|
1630
1534
|
// lib/server/ssr/metaTagGenerator.ts
|
|
1631
1535
|
function extractPageMeta(pageData) {
|
|
1632
1536
|
const meta = {};
|
|
@@ -1898,13 +1802,9 @@ async function buildImageMetadataMap() {
|
|
|
1898
1802
|
const webpSrcsetParts = [];
|
|
1899
1803
|
const avifSrcsetParts = [];
|
|
1900
1804
|
for (const variant of entry.variants) {
|
|
1901
|
-
webpSrcsetParts.push(
|
|
1902
|
-
`/images/${encodeURIComponent(variant.webpFilename)} ${variant.width}w`
|
|
1903
|
-
);
|
|
1805
|
+
webpSrcsetParts.push(`/images/${encodeURIComponent(variant.webpFilename)} ${variant.width}w`);
|
|
1904
1806
|
if (variant.avifFilename) {
|
|
1905
|
-
avifSrcsetParts.push(
|
|
1906
|
-
`/images/${encodeURIComponent(variant.avifFilename)} ${variant.width}w`
|
|
1907
|
-
);
|
|
1807
|
+
avifSrcsetParts.push(`/images/${encodeURIComponent(variant.avifFilename)} ${variant.width}w`);
|
|
1908
1808
|
}
|
|
1909
1809
|
}
|
|
1910
1810
|
const hasVariants = entry.variants.length > 0;
|
|
@@ -2041,15 +1941,9 @@ function printMissingStyleWarnings(verbose = false) {
|
|
|
2041
1941
|
return;
|
|
2042
1942
|
}
|
|
2043
1943
|
const warnings = [];
|
|
2044
|
-
warnings.push(
|
|
2045
|
-
|
|
2046
|
-
);
|
|
2047
|
-
warnings.push(
|
|
2048
|
-
"These styles use object values which cannot be serialized to class names:\n"
|
|
2049
|
-
);
|
|
2050
|
-
const sorted = Array.from(missingStylesMap.values()).sort(
|
|
2051
|
-
(a, b) => b.count - a.count
|
|
2052
|
-
);
|
|
1944
|
+
warnings.push("\n\u26A0\uFE0F WARNING: Found styles that cannot be converted to utility classes\n");
|
|
1945
|
+
warnings.push("These styles use object values which cannot be serialized to class names:\n");
|
|
1946
|
+
const sorted = Array.from(missingStylesMap.values()).sort((a, b) => b.count - a.count);
|
|
2053
1947
|
for (const report of sorted) {
|
|
2054
1948
|
warnings.push(
|
|
2055
1949
|
` \u2022 ${report.property}: "${report.value}" (used ${report.count} time${report.count > 1 ? "s" : ""})`
|
|
@@ -2059,9 +1953,7 @@ function printMissingStyleWarnings(verbose = false) {
|
|
|
2059
1953
|
warnings.push(` \u2514\u2500 ${location}`);
|
|
2060
1954
|
}
|
|
2061
1955
|
if (report.locations.length > 3) {
|
|
2062
|
-
warnings.push(
|
|
2063
|
-
` \u2514\u2500 ... and ${report.locations.length - 3} more locations`
|
|
2064
|
-
);
|
|
1956
|
+
warnings.push(` \u2514\u2500 ... and ${report.locations.length - 3} more locations`);
|
|
2065
1957
|
}
|
|
2066
1958
|
}
|
|
2067
1959
|
}
|
|
@@ -2125,31 +2017,24 @@ function localizeHref(href, ctx) {
|
|
|
2125
2017
|
}
|
|
2126
2018
|
function localizeRichTextLinks(html, ctx) {
|
|
2127
2019
|
if (ctx.templateMode || !ctx.locale || !ctx.i18nConfig) return html;
|
|
2128
|
-
return html.replace(
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
return localized === href ? match : `<a${before}href=${quote}${localized}${quote}${after}>`;
|
|
2134
|
-
}
|
|
2135
|
-
);
|
|
2020
|
+
return html.replace(/<a\b([^>]*?)href=(["'])([^"']*?)\2([^>]*?)>/gi, (match, before, quote, href, after) => {
|
|
2021
|
+
if (!href.startsWith("/") || href.startsWith("//")) return match;
|
|
2022
|
+
const localized = localizeHref(href, ctx);
|
|
2023
|
+
return localized === href ? match : `<a${before}href=${quote}${localized}${quote}${after}>`;
|
|
2024
|
+
});
|
|
2136
2025
|
}
|
|
2137
2026
|
function processStyleToClasses(style, ctx) {
|
|
2138
2027
|
if (!style) return [];
|
|
2139
2028
|
let processedStyle = style;
|
|
2140
2029
|
const templateCtx = getTemplateContext(ctx);
|
|
2141
2030
|
if (templateCtx && !ctx.templateMode) {
|
|
2142
|
-
processedStyle = processItemPropsTemplate(
|
|
2143
|
-
style,
|
|
2144
|
-
templateCtx,
|
|
2145
|
-
getI18nResolver(ctx)
|
|
2146
|
-
);
|
|
2031
|
+
processedStyle = processItemPropsTemplate(style, templateCtx, getI18nResolver(ctx));
|
|
2147
2032
|
}
|
|
2148
2033
|
const fluidActive = ctx.responsiveScales?.enabled === true && ctx.responsiveScales?.mode === "fluid";
|
|
2149
|
-
return responsiveStylesToClasses(
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
);
|
|
2034
|
+
return responsiveStylesToClasses(processedStyle, {
|
|
2035
|
+
fluidActive,
|
|
2036
|
+
responsiveScales: ctx.responsiveScales
|
|
2037
|
+
});
|
|
2153
2038
|
}
|
|
2154
2039
|
function evaluateIfCondition(node, ctx) {
|
|
2155
2040
|
const ifValue = hasIf(node) ? node.if : void 0;
|
|
@@ -2181,31 +2066,53 @@ function evaluateIfCondition(node, ctx) {
|
|
|
2181
2066
|
}
|
|
2182
2067
|
return true;
|
|
2183
2068
|
}
|
|
2069
|
+
var UNRESOLVED_FILTER_VALUE = Symbol("unresolved-filter-value");
|
|
2184
2070
|
function resolveFilterValue(value, scope) {
|
|
2185
|
-
if (
|
|
2071
|
+
if (typeof value !== "string" || !value.startsWith("{{") || !value.endsWith("}}")) {
|
|
2186
2072
|
return value;
|
|
2187
2073
|
}
|
|
2188
2074
|
const path2 = value.slice(2, -2).trim();
|
|
2189
|
-
const resolved = getNestedValue(scope, path2);
|
|
2190
|
-
return resolved !== void 0 ? resolved :
|
|
2191
|
-
}
|
|
2192
|
-
function resolveFilterTemplates(filter, scope) {
|
|
2193
|
-
if (!filter
|
|
2075
|
+
const resolved = scope ? getNestedValue(scope, path2) : void 0;
|
|
2076
|
+
return resolved !== void 0 ? resolved : UNRESOLVED_FILTER_VALUE;
|
|
2077
|
+
}
|
|
2078
|
+
function resolveFilterTemplates(filter, scope, collection) {
|
|
2079
|
+
if (!filter) return filter;
|
|
2080
|
+
const reportDropped = (field, template) => {
|
|
2081
|
+
logRuntimeError(
|
|
2082
|
+
"ssrRenderer.resolveFilterTemplates",
|
|
2083
|
+
new Error(`Unresolved filter template ${String(template)} \u2014 condition dropped from "${collection}" query`),
|
|
2084
|
+
{ collection, field: String(field), template: String(template) }
|
|
2085
|
+
);
|
|
2086
|
+
};
|
|
2194
2087
|
if (Array.isArray(filter)) {
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
value
|
|
2198
|
-
|
|
2088
|
+
const conditions = [];
|
|
2089
|
+
for (const cond of filter) {
|
|
2090
|
+
const value = resolveFilterValue(cond.value, scope);
|
|
2091
|
+
if (value === UNRESOLVED_FILTER_VALUE) {
|
|
2092
|
+
reportDropped(cond.field, cond.value);
|
|
2093
|
+
continue;
|
|
2094
|
+
}
|
|
2095
|
+
conditions.push({ ...cond, value });
|
|
2096
|
+
}
|
|
2097
|
+
return conditions;
|
|
2199
2098
|
}
|
|
2200
2099
|
if ("field" in filter && "value" in filter) {
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2100
|
+
const cond = filter;
|
|
2101
|
+
const value = resolveFilterValue(cond.value, scope);
|
|
2102
|
+
if (value === UNRESOLVED_FILTER_VALUE) {
|
|
2103
|
+
reportDropped(cond.field, cond.value);
|
|
2104
|
+
return void 0;
|
|
2105
|
+
}
|
|
2106
|
+
return { ...cond, value };
|
|
2205
2107
|
}
|
|
2206
2108
|
const resolved = {};
|
|
2207
2109
|
for (const [key, value] of Object.entries(filter)) {
|
|
2208
|
-
|
|
2110
|
+
const resolvedValue = resolveFilterValue(value, scope);
|
|
2111
|
+
if (resolvedValue === UNRESOLVED_FILTER_VALUE) {
|
|
2112
|
+
reportDropped(key, value);
|
|
2113
|
+
continue;
|
|
2114
|
+
}
|
|
2115
|
+
resolved[key] = resolvedValue;
|
|
2209
2116
|
}
|
|
2210
2117
|
return resolved;
|
|
2211
2118
|
}
|
|
@@ -2224,12 +2131,11 @@ async function expandRichTextComponents(html, ctx) {
|
|
|
2224
2131
|
try {
|
|
2225
2132
|
const propsStr = match[2].replace(/"/g, '"').replace(/'/g, "'").replace(/&/g, "&");
|
|
2226
2133
|
props = JSON.parse(propsStr);
|
|
2227
|
-
} catch {
|
|
2134
|
+
} catch (error) {
|
|
2135
|
+
logRuntimeError("ssrRenderer.expandRichTextComponents", error, { component: componentName });
|
|
2228
2136
|
}
|
|
2229
2137
|
if (ssrComponentRegistry.has(componentName)) {
|
|
2230
|
-
parts.push(
|
|
2231
|
-
renderComponent(componentName, props, [], {}, ctx)
|
|
2232
|
-
);
|
|
2138
|
+
parts.push(renderComponent(componentName, props, [], {}, ctx));
|
|
2233
2139
|
} else {
|
|
2234
2140
|
parts.push(match[0]);
|
|
2235
2141
|
}
|
|
@@ -2248,7 +2154,15 @@ async function buildComponentHTML(node, globalComponents = {}, pageComponents =
|
|
|
2248
2154
|
const neededCollections = /* @__PURE__ */ new Set();
|
|
2249
2155
|
const ssrFallbackCollector = /* @__PURE__ */ new Map();
|
|
2250
2156
|
const processedRawHtmlCollector = /* @__PURE__ */ new Map();
|
|
2251
|
-
if (!node)
|
|
2157
|
+
if (!node)
|
|
2158
|
+
return {
|
|
2159
|
+
html: "",
|
|
2160
|
+
interactiveStylesMap,
|
|
2161
|
+
preloadImages,
|
|
2162
|
+
neededCollections,
|
|
2163
|
+
ssrFallbackCollector,
|
|
2164
|
+
processedRawHtmlCollector
|
|
2165
|
+
};
|
|
2252
2166
|
ssrComponentRegistry.merge(globalComponents);
|
|
2253
2167
|
ssrComponentRegistry.merge(pageComponents);
|
|
2254
2168
|
const breakpoints = await loadBreakpointConfig();
|
|
@@ -2282,7 +2196,14 @@ async function buildComponentHTML(node, globalComponents = {}, pageComponents =
|
|
|
2282
2196
|
responsiveScales: configService.getResponsiveScales()
|
|
2283
2197
|
};
|
|
2284
2198
|
const html = await renderNode(node, ctx);
|
|
2285
|
-
return {
|
|
2199
|
+
return {
|
|
2200
|
+
html,
|
|
2201
|
+
interactiveStylesMap,
|
|
2202
|
+
preloadImages,
|
|
2203
|
+
neededCollections,
|
|
2204
|
+
ssrFallbackCollector,
|
|
2205
|
+
processedRawHtmlCollector
|
|
2206
|
+
};
|
|
2286
2207
|
}
|
|
2287
2208
|
async function renderNestedListPlaceholder(node, ctx) {
|
|
2288
2209
|
const sourceValue = node.source || node.collection;
|
|
@@ -2312,6 +2233,13 @@ async function renderNestedListPlaceholder(node, ctx) {
|
|
|
2312
2233
|
const configJson = escapeHtml(JSON.stringify(config));
|
|
2313
2234
|
return `<div data-cms-list-nested="true" data-collection="${escapeHtml(sourceStr)}" data-cms-config="${configJson}"${editorAttrs(ctx, { isCMSListContainer: true })}><template data-nested-template>${templateContent}</template></div>`;
|
|
2314
2235
|
}
|
|
2236
|
+
function renderNodeFallback(ctx, error, label) {
|
|
2237
|
+
console.error(`\u274C SSR render error in ${label}:`, error);
|
|
2238
|
+
if (!ctx.injectEditorAttrs) return "";
|
|
2239
|
+
const friendly = toFriendlyError(error);
|
|
2240
|
+
const text = `${friendly.title} \u2014 ${friendly.friendlyMessage}`;
|
|
2241
|
+
return `<div data-meno-render-error style="margin:8px 0;padding:12px 14px;border:1px dashed #e0a3a3;border-radius:6px;background:#fdf3f3;color:#9a3b3b;font:13px/1.5 -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;">\u26A0\uFE0F ${escapeHtml(text)}</div>`;
|
|
2242
|
+
}
|
|
2315
2243
|
async function processList(node, ctx) {
|
|
2316
2244
|
const nodeType = node.type;
|
|
2317
2245
|
const isLegacyCMSList = nodeType === "cms-list";
|
|
@@ -2346,6 +2274,7 @@ async function processList(node, ctx) {
|
|
|
2346
2274
|
items = [];
|
|
2347
2275
|
}
|
|
2348
2276
|
}
|
|
2277
|
+
if (!Array.isArray(items)) items = [];
|
|
2349
2278
|
if (node.offset && sourceType === "prop") {
|
|
2350
2279
|
items = items.slice(node.offset);
|
|
2351
2280
|
}
|
|
@@ -2360,13 +2289,7 @@ async function processList(node, ctx) {
|
|
|
2360
2289
|
for (let i = 0; i < items.length; i++) {
|
|
2361
2290
|
const rawItem = items[i];
|
|
2362
2291
|
const item = schema ? addItemUrl(rawItem, schema, ctx.locale, ctx.i18nConfig) : rawItem;
|
|
2363
|
-
const templateContext = buildTemplateContext(
|
|
2364
|
-
variableName,
|
|
2365
|
-
item,
|
|
2366
|
-
i,
|
|
2367
|
-
items.length,
|
|
2368
|
-
ctx.templateContext
|
|
2369
|
-
);
|
|
2292
|
+
const templateContext = buildTemplateContext(variableName, item, i, items.length, ctx.templateContext);
|
|
2370
2293
|
const itemCtx = {
|
|
2371
2294
|
...ctx,
|
|
2372
2295
|
templateContext,
|
|
@@ -2434,7 +2357,11 @@ async function getCollectionItems(node, source, ctx) {
|
|
|
2434
2357
|
} else {
|
|
2435
2358
|
const query = {
|
|
2436
2359
|
collection: source,
|
|
2437
|
-
filter: resolveFilterTemplates(
|
|
2360
|
+
filter: resolveFilterTemplates(
|
|
2361
|
+
node.filter,
|
|
2362
|
+
buildListResolutionScope(ctx),
|
|
2363
|
+
source
|
|
2364
|
+
),
|
|
2438
2365
|
sort: node.sort,
|
|
2439
2366
|
limit: node.limit,
|
|
2440
2367
|
offset: node.offset,
|
|
@@ -2512,7 +2439,7 @@ function registerInteractiveStyles(ctx, elementClass, interactiveStyles) {
|
|
|
2512
2439
|
}
|
|
2513
2440
|
function buildCssVariableStyleAttr(cssVariables) {
|
|
2514
2441
|
if (Object.keys(cssVariables).length === 0) return "";
|
|
2515
|
-
const styleString = Object.entries(cssVariables).map(([k, v]) => `${k}: ${v}`).join("; ");
|
|
2442
|
+
const styleString = Object.entries(cssVariables).map(([k, v]) => `${k}: ${rewriteViewportUnits(v)}`).join("; ");
|
|
2516
2443
|
return ` style="${escapeHtml(styleString)}"`;
|
|
2517
2444
|
}
|
|
2518
2445
|
function arraysEqual(a, b) {
|
|
@@ -2538,6 +2465,9 @@ function editorAttrs(ctx, opts = {}) {
|
|
|
2538
2465
|
async function renderNode(node, ctx) {
|
|
2539
2466
|
const { breakpoints, viewportWidth, locale, i18nConfig, slugMappings, pagePath } = ctx;
|
|
2540
2467
|
if (node === null || node === void 0) return "";
|
|
2468
|
+
if (typeof node === "object" && !Array.isArray(node) && node._code === true) {
|
|
2469
|
+
return "";
|
|
2470
|
+
}
|
|
2541
2471
|
if (typeof node === "string" || typeof node === "number") {
|
|
2542
2472
|
let text = String(node);
|
|
2543
2473
|
if (ctx.templateMode) {
|
|
@@ -2574,26 +2504,29 @@ async function renderNode(node, ctx) {
|
|
|
2574
2504
|
return escapeHtml(text);
|
|
2575
2505
|
}
|
|
2576
2506
|
if (Array.isArray(node)) {
|
|
2577
|
-
return (await Promise.all(
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2507
|
+
return (await Promise.all(
|
|
2508
|
+
node.map((child, index) => {
|
|
2509
|
+
const childPath = ctx.elementPath ? [...ctx.elementPath.slice(0, -1), index] : [index];
|
|
2510
|
+
return renderNode(child, { ...ctx, elementPath: childPath });
|
|
2511
|
+
})
|
|
2512
|
+
)).join("");
|
|
2581
2513
|
}
|
|
2582
2514
|
if (typeof node !== "object") return "";
|
|
2583
2515
|
if (isI18nValue(node)) {
|
|
2584
2516
|
const i18nResolveConfig = i18nConfig ?? DEFAULT_I18N_CONFIG;
|
|
2585
2517
|
const i18nEffectiveLocale = locale || i18nResolveConfig.defaultLocale;
|
|
2586
2518
|
const resolved = resolveI18nValue(node, i18nEffectiveLocale, i18nResolveConfig);
|
|
2587
|
-
return renderNode(
|
|
2588
|
-
resolved,
|
|
2589
|
-
ctx
|
|
2590
|
-
);
|
|
2519
|
+
return renderNode(resolved, ctx);
|
|
2591
2520
|
}
|
|
2592
2521
|
if (!evaluateIfCondition(node, ctx)) {
|
|
2593
2522
|
return "";
|
|
2594
2523
|
}
|
|
2595
2524
|
if (isListNode(node)) {
|
|
2596
|
-
|
|
2525
|
+
try {
|
|
2526
|
+
return await processList(node, ctx);
|
|
2527
|
+
} catch (error) {
|
|
2528
|
+
return renderNodeFallback(ctx, error, "list");
|
|
2529
|
+
}
|
|
2597
2530
|
}
|
|
2598
2531
|
const nodeType = "type" in node ? node.type : void 0;
|
|
2599
2532
|
const nodeStyle = "style" in node ? node.style : void 0;
|
|
@@ -2622,11 +2555,197 @@ async function renderNode(node, ctx) {
|
|
|
2622
2555
|
}
|
|
2623
2556
|
}
|
|
2624
2557
|
const purify = getDOMPurify();
|
|
2625
|
-
const
|
|
2626
|
-
ALLOWED_TAGS: [
|
|
2627
|
-
|
|
2558
|
+
const purifiedHtml = purify ? purify.sanitize(htmlContent, {
|
|
2559
|
+
ALLOWED_TAGS: [
|
|
2560
|
+
"svg",
|
|
2561
|
+
"path",
|
|
2562
|
+
"circle",
|
|
2563
|
+
"rect",
|
|
2564
|
+
"line",
|
|
2565
|
+
"polyline",
|
|
2566
|
+
"polygon",
|
|
2567
|
+
"g",
|
|
2568
|
+
"text",
|
|
2569
|
+
"tspan",
|
|
2570
|
+
"image",
|
|
2571
|
+
"defs",
|
|
2572
|
+
"use",
|
|
2573
|
+
"linearGradient",
|
|
2574
|
+
"radialGradient",
|
|
2575
|
+
"stop",
|
|
2576
|
+
"clipPath",
|
|
2577
|
+
"mask",
|
|
2578
|
+
"pattern",
|
|
2579
|
+
"marker",
|
|
2580
|
+
"symbol",
|
|
2581
|
+
"a",
|
|
2582
|
+
"div",
|
|
2583
|
+
"span",
|
|
2584
|
+
"p",
|
|
2585
|
+
"br",
|
|
2586
|
+
"button",
|
|
2587
|
+
"img",
|
|
2588
|
+
"iframe",
|
|
2589
|
+
"video",
|
|
2590
|
+
"audio",
|
|
2591
|
+
"source",
|
|
2592
|
+
"canvas",
|
|
2593
|
+
"b",
|
|
2594
|
+
"i",
|
|
2595
|
+
"u",
|
|
2596
|
+
"strong",
|
|
2597
|
+
"em",
|
|
2598
|
+
"sub",
|
|
2599
|
+
"sup",
|
|
2600
|
+
"mark",
|
|
2601
|
+
"s",
|
|
2602
|
+
"small",
|
|
2603
|
+
"del",
|
|
2604
|
+
"ins",
|
|
2605
|
+
"q",
|
|
2606
|
+
"abbr",
|
|
2607
|
+
"code",
|
|
2608
|
+
"pre",
|
|
2609
|
+
"blockquote",
|
|
2610
|
+
"ul",
|
|
2611
|
+
"ol",
|
|
2612
|
+
"li",
|
|
2613
|
+
"h1",
|
|
2614
|
+
"h2",
|
|
2615
|
+
"h3",
|
|
2616
|
+
"h4",
|
|
2617
|
+
"h5",
|
|
2618
|
+
"h6",
|
|
2619
|
+
"style",
|
|
2620
|
+
"animate",
|
|
2621
|
+
"animateTransform",
|
|
2622
|
+
"animateMotion",
|
|
2623
|
+
"set",
|
|
2624
|
+
"filter",
|
|
2625
|
+
"feGaussianBlur",
|
|
2626
|
+
"feOffset",
|
|
2627
|
+
"feMerge",
|
|
2628
|
+
"feMergeNode",
|
|
2629
|
+
"feColorMatrix",
|
|
2630
|
+
"feComposite",
|
|
2631
|
+
"feFlood",
|
|
2632
|
+
"feMorphology",
|
|
2633
|
+
"feBlend",
|
|
2634
|
+
"feDropShadow",
|
|
2635
|
+
"feTurbulence",
|
|
2636
|
+
"feDisplacementMap",
|
|
2637
|
+
"foreignObject"
|
|
2638
|
+
],
|
|
2639
|
+
ALLOWED_ATTR: [
|
|
2640
|
+
"class",
|
|
2641
|
+
"id",
|
|
2642
|
+
"style",
|
|
2643
|
+
"width",
|
|
2644
|
+
"height",
|
|
2645
|
+
"viewBox",
|
|
2646
|
+
"xmlns",
|
|
2647
|
+
"xmlns:xlink",
|
|
2648
|
+
"xlink:href",
|
|
2649
|
+
"fill",
|
|
2650
|
+
"stroke",
|
|
2651
|
+
"stroke-width",
|
|
2652
|
+
"stroke-linecap",
|
|
2653
|
+
"stroke-linejoin",
|
|
2654
|
+
"stroke-dasharray",
|
|
2655
|
+
"stroke-dashoffset",
|
|
2656
|
+
"d",
|
|
2657
|
+
"cx",
|
|
2658
|
+
"cy",
|
|
2659
|
+
"r",
|
|
2660
|
+
"x",
|
|
2661
|
+
"y",
|
|
2662
|
+
"x1",
|
|
2663
|
+
"y1",
|
|
2664
|
+
"x2",
|
|
2665
|
+
"y2",
|
|
2666
|
+
"points",
|
|
2667
|
+
"href",
|
|
2668
|
+
"src",
|
|
2669
|
+
"alt",
|
|
2670
|
+
"target",
|
|
2671
|
+
"rel",
|
|
2672
|
+
"data-*",
|
|
2673
|
+
"aria-*",
|
|
2674
|
+
"transform",
|
|
2675
|
+
"opacity",
|
|
2676
|
+
"fill-opacity",
|
|
2677
|
+
"fill-rule",
|
|
2678
|
+
"clip-rule",
|
|
2679
|
+
"clip-path",
|
|
2680
|
+
"clipPathUnits",
|
|
2681
|
+
"mask",
|
|
2682
|
+
"mask-type",
|
|
2683
|
+
"maskUnits",
|
|
2684
|
+
"maskContentUnits",
|
|
2685
|
+
"patternUnits",
|
|
2686
|
+
"patternContentUnits",
|
|
2687
|
+
"patternTransform",
|
|
2688
|
+
"gradientUnits",
|
|
2689
|
+
"gradientTransform",
|
|
2690
|
+
"spreadMethod",
|
|
2691
|
+
"preserveAspectRatio",
|
|
2692
|
+
"marker-start",
|
|
2693
|
+
"marker-mid",
|
|
2694
|
+
"marker-end",
|
|
2695
|
+
"markerUnits",
|
|
2696
|
+
"markerWidth",
|
|
2697
|
+
"markerHeight",
|
|
2698
|
+
"refX",
|
|
2699
|
+
"refY",
|
|
2700
|
+
"orient",
|
|
2701
|
+
"paint-order",
|
|
2702
|
+
"vector-effect",
|
|
2703
|
+
"filter",
|
|
2704
|
+
"filterUnits",
|
|
2705
|
+
"primitiveUnits",
|
|
2706
|
+
"in",
|
|
2707
|
+
"in2",
|
|
2708
|
+
"result",
|
|
2709
|
+
"stdDeviation",
|
|
2710
|
+
"flood-color",
|
|
2711
|
+
"flood-opacity",
|
|
2712
|
+
"stroke-opacity",
|
|
2713
|
+
"font-size",
|
|
2714
|
+
"font-family",
|
|
2715
|
+
"font-weight",
|
|
2716
|
+
"font-style",
|
|
2717
|
+
"text-anchor",
|
|
2718
|
+
"dominant-baseline",
|
|
2719
|
+
"offset",
|
|
2720
|
+
"stop-color",
|
|
2721
|
+
"stop-opacity",
|
|
2722
|
+
"frameborder",
|
|
2723
|
+
"allowfullscreen",
|
|
2724
|
+
"allow",
|
|
2725
|
+
"title",
|
|
2726
|
+
"attributeName",
|
|
2727
|
+
"values",
|
|
2728
|
+
"dur",
|
|
2729
|
+
"begin",
|
|
2730
|
+
"end",
|
|
2731
|
+
"repeatCount",
|
|
2732
|
+
"repeatDur",
|
|
2733
|
+
"keyTimes",
|
|
2734
|
+
"keySplines",
|
|
2735
|
+
"calcMode",
|
|
2736
|
+
"from",
|
|
2737
|
+
"to",
|
|
2738
|
+
"by",
|
|
2739
|
+
"additive",
|
|
2740
|
+
"accumulate",
|
|
2741
|
+
"type",
|
|
2742
|
+
"rotate",
|
|
2743
|
+
"keyPoints",
|
|
2744
|
+
"path"
|
|
2745
|
+
],
|
|
2628
2746
|
KEEP_CONTENT: true
|
|
2629
2747
|
}) : htmlContent;
|
|
2748
|
+
const sanitizedHtml = inlineSvgStyleRules(purifiedHtml);
|
|
2630
2749
|
const optimizedHtml = ctx.imageMetadataMap ? rewriteRichTextImages(sanitizedHtml, ctx.imageMetadataMap, ctx.imageFormat) : sanitizedHtml;
|
|
2631
2750
|
const nodeAttributes2 = resolveI18nAttrs(extractAttributesFromNode(node), locale, i18nConfig);
|
|
2632
2751
|
const classNames = ["oem"];
|
|
@@ -2643,7 +2762,7 @@ async function renderNode(node, ctx) {
|
|
|
2643
2762
|
if (embedInteractiveStyles && embedInteractiveStyles.length > 0) {
|
|
2644
2763
|
embedCssVariables = registerInteractiveStyles(ctx, elementClass2, embedInteractiveStyles);
|
|
2645
2764
|
}
|
|
2646
|
-
|
|
2765
|
+
const embedStyleAttr = buildCssVariableStyleAttr(embedCssVariables);
|
|
2647
2766
|
const attrClassName3 = nodeAttributes2.className || nodeAttributes2.class || "";
|
|
2648
2767
|
if (attrClassName3) {
|
|
2649
2768
|
classNames.push(attrClassName3);
|
|
@@ -2719,16 +2838,21 @@ async function renderNode(node, ctx) {
|
|
|
2719
2838
|
}
|
|
2720
2839
|
const attrs = buildAttributes(nodeAttributes2, ["href"]);
|
|
2721
2840
|
const classAttr = ` class="${escapeHtml(classNames.filter(Boolean).join(" "))}"`;
|
|
2722
|
-
const childrenHTML = Array.isArray(children) ? (await Promise.all(
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2841
|
+
const childrenHTML = Array.isArray(children) ? (await Promise.all(
|
|
2842
|
+
children.map((child, index) => {
|
|
2843
|
+
const childPath = ctx.elementPath ? [...ctx.elementPath, index] : [index];
|
|
2844
|
+
return renderNode(child, { ...ctx, elementPath: childPath });
|
|
2845
|
+
})
|
|
2846
|
+
)).join("") : await renderNode(children, {
|
|
2847
|
+
...ctx,
|
|
2848
|
+
elementPath: ctx.elementPath ? [...ctx.elementPath, 0] : [0]
|
|
2849
|
+
});
|
|
2726
2850
|
return `<a href="${escapeHtml(String(href))}"${classAttr}${olinkStyleAttr}${attrs}${editorAttrs(ctx, { isSlotContent: isSlotContent(node) })}>${childrenHTML}</a>`;
|
|
2727
2851
|
}
|
|
2728
2852
|
if (isLocaleListNode(node)) {
|
|
2729
2853
|
return renderLocaleList(node, ctx);
|
|
2730
2854
|
}
|
|
2731
|
-
|
|
2855
|
+
const tag = isHtmlNode(node) ? node.tag : void 0;
|
|
2732
2856
|
const componentName = isComponentNode(node) ? node.component : void 0;
|
|
2733
2857
|
let nodeProps = isComponentNode(node) ? node.props || {} : {};
|
|
2734
2858
|
if (ctx.cmsContext?.cms && Object.keys(nodeProps).length > 0) {
|
|
@@ -2742,7 +2866,12 @@ async function renderNode(node, ctx) {
|
|
|
2742
2866
|
let nodeAttributes = resolveI18nAttrs(extractAttributesFromNode(node), locale, i18nConfig);
|
|
2743
2867
|
const originalAttributes = { ...nodeAttributes };
|
|
2744
2868
|
if (ctx.cmsContext?.cms && Object.keys(nodeAttributes).length > 0) {
|
|
2745
|
-
nodeAttributes = processCMSPropsTemplate(
|
|
2869
|
+
nodeAttributes = processCMSPropsTemplate(
|
|
2870
|
+
nodeAttributes,
|
|
2871
|
+
ctx.cmsContext.cms,
|
|
2872
|
+
locale,
|
|
2873
|
+
i18nConfig
|
|
2874
|
+
);
|
|
2746
2875
|
}
|
|
2747
2876
|
if (!ctx.templateMode && templateCtx && Object.keys(nodeAttributes).length > 0) {
|
|
2748
2877
|
nodeAttributes = processItemPropsTemplate(nodeAttributes, templateCtx, i18nResolver);
|
|
@@ -2764,7 +2893,12 @@ async function renderNode(node, ctx) {
|
|
|
2764
2893
|
}
|
|
2765
2894
|
} else if (nodeProps.style) {
|
|
2766
2895
|
if (isResponsiveStyle(nodeProps.style) && breakpoints && viewportWidth) {
|
|
2767
|
-
resolvedStyle = mergeResponsiveStyles(
|
|
2896
|
+
resolvedStyle = mergeResponsiveStyles(
|
|
2897
|
+
nodeProps.style,
|
|
2898
|
+
"viewport",
|
|
2899
|
+
viewportWidth,
|
|
2900
|
+
breakpoints
|
|
2901
|
+
);
|
|
2768
2902
|
} else {
|
|
2769
2903
|
resolvedStyle = nodeProps.style;
|
|
2770
2904
|
}
|
|
@@ -2807,10 +2941,6 @@ async function renderNode(node, ctx) {
|
|
|
2807
2941
|
if (tag === "Link") {
|
|
2808
2942
|
return renderLinkNode(propsWithStyleAndAttrs, children, ctx);
|
|
2809
2943
|
}
|
|
2810
|
-
if (!tag) {
|
|
2811
|
-
console.error("Missing tag for HTML element in SSR");
|
|
2812
|
-
return "";
|
|
2813
|
-
}
|
|
2814
2944
|
return renderHtmlElement(tag, propsWithStyleAndAttrs, children, ctx);
|
|
2815
2945
|
}
|
|
2816
2946
|
async function renderComponent(componentName, propsWithStyleAndAttrs, children, nodeAttributes, ctx) {
|
|
@@ -2830,7 +2960,17 @@ async function renderComponent(componentName, propsWithStyleAndAttrs, children,
|
|
|
2830
2960
|
const markedChildren = children ? markAsSlotContent(children) : void 0;
|
|
2831
2961
|
const processedStructure = processStructure(
|
|
2832
2962
|
structuredComponentDef.structure,
|
|
2833
|
-
{
|
|
2963
|
+
{
|
|
2964
|
+
props: resolvedProps,
|
|
2965
|
+
componentDef: structuredComponentDef,
|
|
2966
|
+
itemContext: ctx.templateContext,
|
|
2967
|
+
// Host (outer) component's resolved props — used as fallback scope
|
|
2968
|
+
// for `{{x}}` templates the child's interface doesn't declare. At
|
|
2969
|
+
// this point `ctx.componentResolvedProps` still belongs to the
|
|
2970
|
+
// outer component; it's only swapped to `resolvedProps` below when
|
|
2971
|
+
// we recurse via `renderNode`.
|
|
2972
|
+
parentProps: ctx.componentResolvedProps
|
|
2973
|
+
},
|
|
2834
2974
|
void 0,
|
|
2835
2975
|
markedChildren,
|
|
2836
2976
|
true
|
|
@@ -2894,6 +3034,16 @@ async function renderComponent(componentName, propsWithStyleAndAttrs, children,
|
|
|
2894
3034
|
existingPropsMap[componentName] = propsForJS;
|
|
2895
3035
|
processedRoot.attributes["data-props"] = JSON.stringify(existingPropsMap);
|
|
2896
3036
|
}
|
|
3037
|
+
if (componentName && (isHtmlNode(rootNode) || isLinkNode(rootNode))) {
|
|
3038
|
+
if (!rootNode.attributes) rootNode.attributes = {};
|
|
3039
|
+
if (!ctx.componentInstanceCounter) {
|
|
3040
|
+
ctx.componentInstanceCounter = /* @__PURE__ */ new Map();
|
|
3041
|
+
}
|
|
3042
|
+
const instanceIndex = ctx.componentInstanceCounter.get(componentName) ?? 0;
|
|
3043
|
+
ctx.componentInstanceCounter.set(componentName, instanceIndex + 1);
|
|
3044
|
+
rootNode.attributes["data-meno-component"] = componentName;
|
|
3045
|
+
rootNode.attributes["data-meno-component-instance"] = String(instanceIndex);
|
|
3046
|
+
}
|
|
2897
3047
|
}
|
|
2898
3048
|
return await renderNode(processedStructure, {
|
|
2899
3049
|
...ctx,
|
|
@@ -2904,8 +3054,7 @@ async function renderComponent(componentName, propsWithStyleAndAttrs, children,
|
|
|
2904
3054
|
componentResolvedProps: resolvedProps
|
|
2905
3055
|
});
|
|
2906
3056
|
} catch (error) {
|
|
2907
|
-
|
|
2908
|
-
return "";
|
|
3057
|
+
return renderNodeFallback(ctx, error, `component ${componentName}`);
|
|
2909
3058
|
}
|
|
2910
3059
|
}
|
|
2911
3060
|
async function renderLinkNode(propsWithStyleAndAttrs, children, ctx) {
|
|
@@ -2916,10 +3065,15 @@ async function renderLinkNode(propsWithStyleAndAttrs, children, ctx) {
|
|
|
2916
3065
|
const href = localizeHref(rawHref, ctx);
|
|
2917
3066
|
const linkClassAttr = restProps.className ? ` class="${escapeHtml(String(restProps.className))}"` : "";
|
|
2918
3067
|
const attrs = buildAttributes(restProps, ["style", "className", "to"]);
|
|
2919
|
-
const childrenHTML = Array.isArray(children) ? (await Promise.all(
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
3068
|
+
const childrenHTML = Array.isArray(children) ? (await Promise.all(
|
|
3069
|
+
children.map((child, index) => {
|
|
3070
|
+
const childPath = ctx.elementPath ? [...ctx.elementPath, index] : [index];
|
|
3071
|
+
return renderNode(child, { ...ctx, elementPath: childPath });
|
|
3072
|
+
})
|
|
3073
|
+
)).join("") : await renderNode(children, {
|
|
3074
|
+
...ctx,
|
|
3075
|
+
elementPath: ctx.elementPath ? [...ctx.elementPath, 0] : [0]
|
|
3076
|
+
});
|
|
2923
3077
|
return `<a href="${escapeHtml(String(href))}"${linkClassAttr}${attrs}${editorAttrs(ctx)}>${childrenHTML}</a>`;
|
|
2924
3078
|
}
|
|
2925
3079
|
async function renderHtmlElement(tag, propsWithStyleAndAttrs, children, ctx) {
|
|
@@ -2950,17 +3104,42 @@ async function renderHtmlElement(tag, propsWithStyleAndAttrs, children, ctx) {
|
|
|
2950
3104
|
if (typeof node === "string") return node;
|
|
2951
3105
|
if (typeof node === "number") return String(node);
|
|
2952
3106
|
if (Array.isArray(node)) return node.map(flatten).join("");
|
|
3107
|
+
if (node._code === true) return "";
|
|
3108
|
+
logRuntimeError(
|
|
3109
|
+
"ssrRenderer.renderHtmlElement",
|
|
3110
|
+
new Error(`Element child dropped inside <${tag}> \u2014 raw-text elements render only string content`),
|
|
3111
|
+
{ tag, droppedNodeType: String(node.type ?? typeof node) }
|
|
3112
|
+
);
|
|
2953
3113
|
return "";
|
|
2954
3114
|
};
|
|
2955
3115
|
childrenHTML = flatten(children);
|
|
2956
3116
|
} else {
|
|
2957
|
-
childrenHTML = Array.isArray(children) ? (await Promise.all(
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
3117
|
+
childrenHTML = Array.isArray(children) ? (await Promise.all(
|
|
3118
|
+
children.map((child, index) => {
|
|
3119
|
+
const childPath = ctx.elementPath ? [...ctx.elementPath, index] : [index];
|
|
3120
|
+
return renderNode(child, { ...ctx, elementPath: childPath });
|
|
3121
|
+
})
|
|
3122
|
+
)).join("") : await renderNode(children, {
|
|
3123
|
+
...ctx,
|
|
3124
|
+
elementPath: ctx.elementPath ? [...ctx.elementPath, 0] : [0]
|
|
3125
|
+
});
|
|
2961
3126
|
}
|
|
2962
3127
|
const ea = editorAttrs(ctx);
|
|
2963
|
-
const voidElements = [
|
|
3128
|
+
const voidElements = [
|
|
3129
|
+
"img",
|
|
3130
|
+
"input",
|
|
3131
|
+
"br",
|
|
3132
|
+
"hr",
|
|
3133
|
+
"meta",
|
|
3134
|
+
"link",
|
|
3135
|
+
"area",
|
|
3136
|
+
"base",
|
|
3137
|
+
"col",
|
|
3138
|
+
"embed",
|
|
3139
|
+
"source",
|
|
3140
|
+
"track",
|
|
3141
|
+
"wbr"
|
|
3142
|
+
];
|
|
2964
3143
|
if (voidElements.includes(tag.toLowerCase())) {
|
|
2965
3144
|
if (tag.toLowerCase() === "img") {
|
|
2966
3145
|
return renderImageElement(propsWithStyleAndAttrs, classAttr, styleAttr, attrs + ea, ctx);
|
|
@@ -2976,8 +3155,8 @@ function renderImageElement(propsWithStyleAndAttrs, classAttr, styleAttr, attrs,
|
|
|
2976
3155
|
const loading = imgProps.loading;
|
|
2977
3156
|
const sizes = imgProps.sizes;
|
|
2978
3157
|
const fetchpriority = imgProps.fetchpriority;
|
|
2979
|
-
|
|
2980
|
-
|
|
3158
|
+
const width = imgProps.width;
|
|
3159
|
+
const height = imgProps.height;
|
|
2981
3160
|
const metadata = src ? ctx.imageMetadataMap?.get(src) : void 0;
|
|
2982
3161
|
const sizesAttr = sizes || DEFAULT_SIZES;
|
|
2983
3162
|
if (fetchpriority === "high" && metadata && ctx.preloadImages) {
|
|
@@ -3122,7 +3301,9 @@ function renderLocaleList(node, ctx) {
|
|
|
3122
3301
|
break;
|
|
3123
3302
|
}
|
|
3124
3303
|
linkContent += `<div>${escapeHtml(displayText)}</div>`;
|
|
3125
|
-
links.push(
|
|
3304
|
+
links.push(
|
|
3305
|
+
`<a href="${escapeHtml(link.path)}"${hreflangAttr}${currentAttr} data-locale="${escapeHtml(link.locale)}"${classAttrForLink}>${linkContent}</a>`
|
|
3306
|
+
);
|
|
3126
3307
|
}
|
|
3127
3308
|
const linksHTML = showSeparator ? links.join(`<span${separatorClassAttr}></span>`) : links.join("");
|
|
3128
3309
|
const nodeAttributes = resolveI18nAttrs(extractAttributesFromNode(node), locale, i18nConfig);
|
|
@@ -3155,11 +3336,36 @@ async function renderPageSSR(pageData, globalComponents = {}, pagePath = "/", ba
|
|
|
3155
3336
|
meta = { ...meta, ogTitle: processCMSTemplate(meta.ogTitle, cmsContext.cms, effectiveLocale, config) };
|
|
3156
3337
|
}
|
|
3157
3338
|
if (typeof meta.ogDescription === "string") {
|
|
3158
|
-
meta = {
|
|
3339
|
+
meta = {
|
|
3340
|
+
...meta,
|
|
3341
|
+
ogDescription: processCMSTemplate(meta.ogDescription, cmsContext.cms, effectiveLocale, config)
|
|
3342
|
+
};
|
|
3343
|
+
}
|
|
3344
|
+
if (typeof meta.ogImage === "string") {
|
|
3345
|
+
meta = { ...meta, ogImage: processCMSTemplate(meta.ogImage, cmsContext.cms, effectiveLocale, config) };
|
|
3159
3346
|
}
|
|
3160
3347
|
}
|
|
3161
3348
|
const pageComponents = pageData?.components || {};
|
|
3162
|
-
const {
|
|
3349
|
+
const {
|
|
3350
|
+
html: contentHTML,
|
|
3351
|
+
interactiveStylesMap,
|
|
3352
|
+
preloadImages,
|
|
3353
|
+
neededCollections,
|
|
3354
|
+
ssrFallbackCollector,
|
|
3355
|
+
processedRawHtmlCollector
|
|
3356
|
+
} = await buildComponentHTML(
|
|
3357
|
+
rootNode,
|
|
3358
|
+
globalComponents,
|
|
3359
|
+
pageComponents,
|
|
3360
|
+
effectiveLocale,
|
|
3361
|
+
config,
|
|
3362
|
+
slugMappings,
|
|
3363
|
+
pagePath,
|
|
3364
|
+
cmsContext,
|
|
3365
|
+
cmsService,
|
|
3366
|
+
isProductionBuild,
|
|
3367
|
+
injectEditorAttrs
|
|
3368
|
+
);
|
|
3163
3369
|
const javascript = await collectComponentJavaScript(globalComponents, pageComponents);
|
|
3164
3370
|
const componentCSS = collectComponentCSS(globalComponents, pageComponents);
|
|
3165
3371
|
const fullUrl = baseUrl ? `${baseUrl}${pagePath}` : pagePath;
|
|
@@ -3349,138 +3555,12 @@ function generateAllInlineDataScripts(collections) {
|
|
|
3349
3555
|
return scripts.join("\n ");
|
|
3350
3556
|
}
|
|
3351
3557
|
|
|
3352
|
-
// lib/shared/libraryLoader.ts
|
|
3353
|
-
function escapeAttr2(str) {
|
|
3354
|
-
return str.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
3355
|
-
}
|
|
3356
|
-
function mergeLibraries(global, page) {
|
|
3357
|
-
if (!page) {
|
|
3358
|
-
return global;
|
|
3359
|
-
}
|
|
3360
|
-
if (page.mode === "replace") {
|
|
3361
|
-
return {
|
|
3362
|
-
js: page.js || [],
|
|
3363
|
-
css: page.css || []
|
|
3364
|
-
};
|
|
3365
|
-
}
|
|
3366
|
-
return {
|
|
3367
|
-
js: [...global.js || [], ...page.js || []],
|
|
3368
|
-
css: [...global.css || [], ...page.css || []]
|
|
3369
|
-
};
|
|
3370
|
-
}
|
|
3371
|
-
function generateScriptTag(lib) {
|
|
3372
|
-
const attrs = [`src="${escapeAttr2(lib.url)}"`];
|
|
3373
|
-
if (lib.type === "module") {
|
|
3374
|
-
attrs.push('type="module"');
|
|
3375
|
-
} else {
|
|
3376
|
-
const mode = lib.mode || "defer";
|
|
3377
|
-
attrs.push(mode);
|
|
3378
|
-
}
|
|
3379
|
-
return `<script ${attrs.join(" ")}></script>`;
|
|
3380
|
-
}
|
|
3381
|
-
function generateInlineStyleTag(content, media) {
|
|
3382
|
-
const attrs = media ? ` media="${escapeAttr2(media)}"` : "";
|
|
3383
|
-
return `<style${attrs}>${content}</style>`;
|
|
3384
|
-
}
|
|
3385
|
-
function generateStylesheetTag(lib) {
|
|
3386
|
-
const attrs = [
|
|
3387
|
-
'rel="stylesheet"',
|
|
3388
|
-
`href="${escapeAttr2(lib.url)}"`
|
|
3389
|
-
];
|
|
3390
|
-
if (lib.media) {
|
|
3391
|
-
attrs.push(`media="${escapeAttr2(lib.media)}"`);
|
|
3392
|
-
}
|
|
3393
|
-
return `<link ${attrs.join(" ")}>`;
|
|
3394
|
-
}
|
|
3395
|
-
function generateLibraryTags(libs, inlineContents) {
|
|
3396
|
-
const headCSS = [];
|
|
3397
|
-
const headJS = [];
|
|
3398
|
-
const bodyEndJS = [];
|
|
3399
|
-
for (const css of libs.css || []) {
|
|
3400
|
-
const inlineContent = inlineContents?.get(css.url);
|
|
3401
|
-
if (inlineContent !== void 0) {
|
|
3402
|
-
headCSS.push(generateInlineStyleTag(inlineContent, css.media));
|
|
3403
|
-
} else {
|
|
3404
|
-
headCSS.push(generateStylesheetTag(css));
|
|
3405
|
-
}
|
|
3406
|
-
}
|
|
3407
|
-
for (const js of libs.js || []) {
|
|
3408
|
-
const tag = generateScriptTag(js);
|
|
3409
|
-
if (js.position === "head") {
|
|
3410
|
-
headJS.push(tag);
|
|
3411
|
-
} else {
|
|
3412
|
-
bodyEndJS.push(tag);
|
|
3413
|
-
}
|
|
3414
|
-
}
|
|
3415
|
-
return {
|
|
3416
|
-
headCSS: headCSS.join("\n "),
|
|
3417
|
-
headJS: headJS.join("\n "),
|
|
3418
|
-
bodyEndJS: bodyEndJS.join("\n ")
|
|
3419
|
-
};
|
|
3420
|
-
}
|
|
3421
|
-
function collectComponentLibraries(globalComponents = {}, pageComponents = {}) {
|
|
3422
|
-
const seenJS = /* @__PURE__ */ new Set();
|
|
3423
|
-
const seenCSS = /* @__PURE__ */ new Set();
|
|
3424
|
-
const jsLibs = [];
|
|
3425
|
-
const cssLibs = [];
|
|
3426
|
-
const collect = (components) => {
|
|
3427
|
-
for (const component of Object.values(components)) {
|
|
3428
|
-
const libs = component?.component?.libraries;
|
|
3429
|
-
if (!libs) continue;
|
|
3430
|
-
for (const js of libs.js || []) {
|
|
3431
|
-
if (!seenJS.has(js.url)) {
|
|
3432
|
-
seenJS.add(js.url);
|
|
3433
|
-
jsLibs.push(js);
|
|
3434
|
-
}
|
|
3435
|
-
}
|
|
3436
|
-
for (const css of libs.css || []) {
|
|
3437
|
-
if (!seenCSS.has(css.url)) {
|
|
3438
|
-
seenCSS.add(css.url);
|
|
3439
|
-
cssLibs.push(css);
|
|
3440
|
-
}
|
|
3441
|
-
}
|
|
3442
|
-
}
|
|
3443
|
-
};
|
|
3444
|
-
collect(globalComponents);
|
|
3445
|
-
collect(pageComponents);
|
|
3446
|
-
return { js: jsLibs, css: cssLibs };
|
|
3447
|
-
}
|
|
3448
|
-
function extractLibraryOrigins(libs) {
|
|
3449
|
-
const scriptOrigins = /* @__PURE__ */ new Set();
|
|
3450
|
-
const styleOrigins = /* @__PURE__ */ new Set();
|
|
3451
|
-
for (const js of libs.js || []) {
|
|
3452
|
-
const origin = safeOrigin(js.url);
|
|
3453
|
-
if (origin) scriptOrigins.add(origin);
|
|
3454
|
-
}
|
|
3455
|
-
for (const css of libs.css || []) {
|
|
3456
|
-
const origin = safeOrigin(css.url);
|
|
3457
|
-
if (origin) styleOrigins.add(origin);
|
|
3458
|
-
}
|
|
3459
|
-
return { scriptOrigins, styleOrigins };
|
|
3460
|
-
}
|
|
3461
|
-
function filterLibrariesByContext(libs, context) {
|
|
3462
|
-
if (context === "preview") return libs;
|
|
3463
|
-
const key = context === "editor" ? "disableEditor" : "disableBuild";
|
|
3464
|
-
return {
|
|
3465
|
-
js: libs.js,
|
|
3466
|
-
css: (libs.css || []).filter((css) => !css[key])
|
|
3467
|
-
};
|
|
3468
|
-
}
|
|
3469
|
-
function safeOrigin(url) {
|
|
3470
|
-
if (!url || url.startsWith("/") || url.startsWith("./") || url.startsWith("../")) {
|
|
3471
|
-
return null;
|
|
3472
|
-
}
|
|
3473
|
-
try {
|
|
3474
|
-
return new URL(url).origin;
|
|
3475
|
-
} catch {
|
|
3476
|
-
return null;
|
|
3477
|
-
}
|
|
3478
|
-
}
|
|
3479
|
-
|
|
3480
3558
|
// lib/server/ssr/htmlGenerator.ts
|
|
3481
3559
|
function generateImagePreloadTags(preloadImages) {
|
|
3482
3560
|
if (preloadImages.length === 0) return "";
|
|
3483
|
-
return preloadImages.map(
|
|
3561
|
+
return preloadImages.map(
|
|
3562
|
+
(img) => `<link rel="preload" as="image" type="${img.type}" imagesrcset="${escapeHtml(img.srcset)}" imagesizes="${escapeHtml(img.sizes)}" fetchpriority="high">`
|
|
3563
|
+
).join("\n ");
|
|
3484
3564
|
}
|
|
3485
3565
|
function minifyCSS(code) {
|
|
3486
3566
|
if (!code.trim()) return code;
|
|
@@ -3528,7 +3608,19 @@ async function generateSSRHTML(pageDataOrOptions, globalComponents = {}, pagePat
|
|
|
3528
3608
|
cspNonce
|
|
3529
3609
|
} = options;
|
|
3530
3610
|
const nonceAttr = cspNonce ? ` nonce="${cspNonce}"` : "";
|
|
3531
|
-
const rendered = await renderPageSSR(
|
|
3611
|
+
const rendered = await renderPageSSR(
|
|
3612
|
+
pageData,
|
|
3613
|
+
components,
|
|
3614
|
+
path2,
|
|
3615
|
+
base,
|
|
3616
|
+
loc,
|
|
3617
|
+
void 0,
|
|
3618
|
+
slugs,
|
|
3619
|
+
cms,
|
|
3620
|
+
cmsServ,
|
|
3621
|
+
isProductionBuild,
|
|
3622
|
+
injectEditorAttrs
|
|
3623
|
+
);
|
|
3532
3624
|
let finalClientDataCollections = clientDataCollections;
|
|
3533
3625
|
if (rendered.neededCollections.size > 0 && cmsServ) {
|
|
3534
3626
|
finalClientDataCollections = clientDataCollections ? new Map(clientDataCollections) : /* @__PURE__ */ new Map();
|
|
@@ -3536,9 +3628,7 @@ async function generateSSRHTML(pageDataOrOptions, globalComponents = {}, pagePat
|
|
|
3536
3628
|
if (finalClientDataCollections.has(collectionId)) continue;
|
|
3537
3629
|
const schema = cmsServ.getSchema(collectionId);
|
|
3538
3630
|
if (!schema?.clientData?.enabled) {
|
|
3539
|
-
console.warn(
|
|
3540
|
-
`[SSR] Nested collection "${collectionId}" needs clientData.enabled for client-side hydration`
|
|
3541
|
-
);
|
|
3631
|
+
console.warn(`[SSR] Nested collection "${collectionId}" needs clientData.enabled for client-side hydration`);
|
|
3542
3632
|
continue;
|
|
3543
3633
|
}
|
|
3544
3634
|
const items = await cmsServ.queryItems({
|
|
@@ -3558,7 +3648,7 @@ async function generateSSRHTML(pageDataOrOptions, globalComponents = {}, pagePat
|
|
|
3558
3648
|
await configService.load();
|
|
3559
3649
|
const globalLibraries = configService.getLibraries() || { js: [], css: [] };
|
|
3560
3650
|
const globalCustomCode = configService.getCustomCode();
|
|
3561
|
-
const menoBadgeHtml = configService.getShowMenoBadge() ? `<style>.meno-badge{position:fixed;bottom:12px;left:12px;z-index:9999;background:#000;color:#fff;padding:4px 10px;border-radius:6px;font-size:12px;font-family:system-ui,sans-serif;text-decoration:none;opacity:0.8;transition:opacity 0.2s}.meno-badge:hover,.meno-badge:focus{opacity:1}</style><a class="meno-badge" href="https://meno.so" target="_blank" rel="noopener">Made in Meno</a>` : "";
|
|
3651
|
+
const menoBadgeHtml = configService.getShowMenoBadge() ? `<style${nonceAttr}>.meno-badge{position:fixed;bottom:12px;left:12px;z-index:9999;background:#000;color:#fff;padding:4px 10px;border-radius:6px;font-size:12px;font-family:system-ui,sans-serif;text-decoration:none;opacity:0.8;transition:opacity 0.2s}.meno-badge:hover,.meno-badge:focus{opacity:1}</style><a class="meno-badge" href="https://meno.so" target="_blank" rel="noopener">Made in Meno</a>` : "";
|
|
3562
3652
|
const mergedCustomCode = {
|
|
3563
3653
|
head: [globalCustomCode.head, pageCustomCode?.head].filter(Boolean).join("\n"),
|
|
3564
3654
|
bodyStart: [globalCustomCode.bodyStart, pageCustomCode?.bodyStart].filter(Boolean).join("\n"),
|
|
@@ -3645,8 +3735,18 @@ ${escapedJavaScript}
|
|
|
3645
3735
|
const variablesConfig = await variableService.loadConfig();
|
|
3646
3736
|
const variablesCSS = generateVariablesCSS(variablesConfig, breakpointConfig, responsiveScalesConfig);
|
|
3647
3737
|
const remConversionConfig = configService.getRemConversion();
|
|
3648
|
-
const utilityCSS = generateUtilityCSS(
|
|
3649
|
-
|
|
3738
|
+
const utilityCSS = generateUtilityCSS(
|
|
3739
|
+
usedUtilityClasses,
|
|
3740
|
+
breakpointConfig,
|
|
3741
|
+
responsiveScalesConfig,
|
|
3742
|
+
remConversionConfig
|
|
3743
|
+
);
|
|
3744
|
+
const interactiveCSS = rendered.interactiveStylesMap.size > 0 ? generateAllInteractiveCSS(
|
|
3745
|
+
rendered.interactiveStylesMap,
|
|
3746
|
+
breakpointConfig,
|
|
3747
|
+
remConversionConfig,
|
|
3748
|
+
responsiveScalesConfig
|
|
3749
|
+
) : "";
|
|
3650
3750
|
printMissingStyleWarnings(false);
|
|
3651
3751
|
const baseCSS = `* {
|
|
3652
3752
|
margin: 0;
|
|
@@ -3680,17 +3780,18 @@ picture {
|
|
|
3680
3780
|
display: inline-block;
|
|
3681
3781
|
vertical-align: top;
|
|
3682
3782
|
line-height: 0;
|
|
3783
|
+
}
|
|
3784
|
+
/* line-height:0 above kills the inline-block descender gap (inline SVG/icon
|
|
3785
|
+
embeds), but line-height inherits \u2014 so block rich-text inside an <Embed>
|
|
3786
|
+
(CMS content: <p>/<li>/\u2026) would collapse its text lines onto each other.
|
|
3787
|
+
Restore a normal line-height on the embed's children. Astro play renders
|
|
3788
|
+
rich-text bare (no .oem), which is why it looked correct only there. */
|
|
3789
|
+
.oem > * {
|
|
3790
|
+
line-height: normal;
|
|
3683
3791
|
}`;
|
|
3684
|
-
const combinedCSS = [
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
variablesCSS,
|
|
3688
|
-
baseCSS,
|
|
3689
|
-
componentCSS,
|
|
3690
|
-
utilityCSS,
|
|
3691
|
-
interactiveCSS
|
|
3692
|
-
].filter(Boolean).join("\n");
|
|
3693
|
-
const finalCSS = useBundled ? minifyCSS(combinedCSS) : combinedCSS;
|
|
3792
|
+
const combinedCSS = [fontCSS, themeColorVariablesCSS, variablesCSS, baseCSS, componentCSS, utilityCSS, interactiveCSS].filter(Boolean).join("\n");
|
|
3793
|
+
const cssWithStableViewport = rewriteViewportUnits(combinedCSS);
|
|
3794
|
+
const finalCSS = useBundled ? minifyCSS(cssWithStableViewport) : cssWithStableViewport;
|
|
3694
3795
|
const prefetchConfig = await loadPrefetchConfig();
|
|
3695
3796
|
const menoConfig = prefetchConfig.enabled ? { prefetch: prefetchConfig } : {};
|
|
3696
3797
|
const hasConfig = Object.keys(menoConfig).length > 0;
|
|
@@ -3712,7 +3813,7 @@ picture {
|
|
|
3712
3813
|
const scriptPreloadTag = extScriptPath ? `<link rel="preload" href="${extScriptPath}" as="script">` : "";
|
|
3713
3814
|
const imagePreloadTags = generateImagePreloadTags(rendered.preloadImages);
|
|
3714
3815
|
const wsUrl = serverPort ? `'ws://localhost:${serverPort}/hmr'` : `location.origin.replace('http','ws')+'/hmr'`;
|
|
3715
|
-
const liveReloadScript = injectLiveReload ? `<script${nonceAttr}>(function(){var ws,timer,gen=0,lastSrvRoot=null;function strip(s){return s?s.replace(/[?&]_r=\\d+/,''):''}function classList(el){return (el.getAttribute('class')||'').split(/\\s+/).filter(Boolean)}function syncEl(cur,srv,old){var cc=classList(cur),sc=classList(srv),oc=old?new Set(classList(old)):new Set();var rt=cc.filter(function(c){return !oc.has(c)});var seen=new Set(),fin=[];sc.concat(rt).forEach(function(c){if(!seen.has(c)){seen.add(c);fin.push(c)}});var fs=fin.join(' ');if((cur.getAttribute('class')||'')!==fs){if(fs)cur.setAttribute('class',fs);else cur.removeAttribute('class')}for(var i=0;i<srv.attributes.length;i++){var a=srv.attributes[i];if(a.name==='class')continue;if(cur.getAttribute(a.name)!==a.value)cur.setAttribute(a.name,a.value)}if(old){for(var i=0;i<old.attributes.length;i++){var a=old.attributes[i];if(a.name==='class')continue;if(!srv.hasAttribute(a.name)&&cur.hasAttribute(a.name))cur.removeAttribute(a.name)}}}function syncText(cur,srv){var cc=cur.childNodes,sc=srv.childNodes;for(var i=0;i<sc.length;i++){var s=sc[i],c=cc[i];if(s.nodeType===3&&c&&c.nodeType===3){if(c.textContent!==s.textContent)c.textContent=s.textContent}}}function
|
|
3816
|
+
const liveReloadScript = injectLiveReload ? `<script${nonceAttr}>(function(){var ws,timer,gen=0,lastSrvRoot=null,dn=document.querySelector('meta[name="csp-nonce"]'),docNonce=dn?dn.getAttribute('content'):'';function strip(s){return s?s.replace(/[?&]_r=\\d+/,''):''}function classList(el){return (el.getAttribute('class')||'').split(/\\s+/).filter(Boolean)}function syncEl(cur,srv,old){var cc=classList(cur),sc=classList(srv),oc=old?new Set(classList(old)):new Set();var rt=cc.filter(function(c){return !oc.has(c)});var seen=new Set(),fin=[];sc.concat(rt).forEach(function(c){if(!seen.has(c)){seen.add(c);fin.push(c)}});var fs=fin.join(' ');if((cur.getAttribute('class')||'')!==fs){if(fs)cur.setAttribute('class',fs);else cur.removeAttribute('class')}for(var i=0;i<srv.attributes.length;i++){var a=srv.attributes[i];if(a.name==='class')continue;var ov=old?old.getAttribute(a.name):null;if(a.value!==ov){if(cur.getAttribute(a.name)!==a.value)cur.setAttribute(a.name,a.value)}}if(old){for(var i=0;i<old.attributes.length;i++){var a=old.attributes[i];if(a.name==='class')continue;if(!srv.hasAttribute(a.name)&&cur.hasAttribute(a.name))cur.removeAttribute(a.name)}}}function syncText(cur,srv){var cc=cur.childNodes,sc=srv.childNodes;for(var i=0;i<sc.length;i++){var s=sc[i],c=cc[i];if(s.nodeType===3&&c&&c.nodeType===3){if(c.textContent!==s.textContent)c.textContent=s.textContent}}}function ek(el){var p=el.getAttribute('data-element-path'),ci=el.getAttribute('data-cms-item-index');return ci?p+'|'+ci:p}function structKey(root){var e=root.querySelectorAll('[data-element-path]'),k=[];for(var i=0;i<e.length;i++)k.push(ek(e[i]));return k.sort().join('~')}function softSync(curR,srvR,oldR){var ce=curR.querySelectorAll('[data-element-path]');var sbp={},se=srvR.querySelectorAll('[data-element-path]');for(var i=0;i<se.length;i++)sbp[ek(se[i])]=se[i];var obp={};if(oldR){var oe=oldR.querySelectorAll('[data-element-path]');for(var i=0;i<oe.length;i++)obp[ek(oe[i])]=oe[i]}for(var i=0;i<ce.length;i++){var c=ce[i],p=ek(c),s=sbp[p];if(!s)continue;syncEl(c,s,obp[p]);syncText(c,s)}syncText(curR,srvR)}function connect(){ws=new WebSocket(${wsUrl});ws.onmessage=function(e){var d=JSON.parse(e.data);if(d.type==='hmr:libraries-update'){location.reload()}else if(d.type==='hmr:update'||d.type==='hmr:cms-update'||d.type==='hmr:colors-update'||d.type==='hmr:variables-update')hotReload()};ws.onclose=function(){clearTimeout(timer);timer=setTimeout(connect,1000)}}function hotReload(){var g=++gen;var sx=window.scrollX,sy=window.scrollY;fetch(location.href,{cache:'no-store'}).then(function(r){return r.text()}).then(function(html){if(g!==gen)return;var p=new DOMParser();var d=p.parseFromString(html,'text/html');var or=document.getElementById('root'),nr=d.getElementById('root');var oscr=document.querySelector('script[src^="/_scripts/"]'),nscr=d.querySelector('script[src^="/_scripts/"]');var oss=oscr?strip(oscr.getAttribute('src')):'',nss=nscr?strip(nscr.getAttribute('src')):'';var hardReset=(oss!==nss)||!lastSrvRoot||!or||!nr||structKey(lastSrvRoot)!==structKey(nr);if(or&&nr){if(hardReset){if(or.innerHTML!==nr.innerHTML)or.innerHTML=nr.innerHTML}else{softSync(or,nr,lastSrvRoot)}}if(nr)lastSrvRoot=nr.cloneNode(true);var os=document.getElementById('meno-styles'),ns=d.getElementById('meno-styles');if(os&&ns&&os.textContent!==ns.textContent)os.textContent=ns.textContent;var nh=d.documentElement;if(nh){var nl=nh.getAttribute('lang')||'en',nt=nh.getAttribute('theme')||'light';if(document.documentElement.getAttribute('lang')!==nl)document.documentElement.setAttribute('lang',nl);if(document.documentElement.getAttribute('theme')!==nt)document.documentElement.setAttribute('theme',nt)}var ocms=document.querySelectorAll('script[id^="meno-cms-"]'),ncms=d.querySelectorAll('script[id^="meno-cms-"]');var ock=JSON.stringify(Array.prototype.map.call(ocms,function(s){return [s.id,s.textContent]}));var nck=JSON.stringify(Array.prototype.map.call(ncms,function(s){return [s.id,s.textContent]}));if(ock!==nck){ocms.forEach(function(s){s.remove()});ncms.forEach(function(s){var c=document.createElement('script');c.type=s.type;c.id=s.id;if(docNonce)c.nonce=docNonce;c.textContent=s.textContent;document.head.appendChild(c)})}window.__menoHotReload=true;var olib=document.querySelectorAll('body > script[src^="/libraries/"]'),nlib=d.querySelectorAll('body > script[src^="/libraries/"]');var olk=JSON.stringify(Array.prototype.map.call(olib,function(s){return strip(s.getAttribute('src'))}).sort());var nlk=JSON.stringify(Array.prototype.map.call(nlib,function(s){return strip(s.getAttribute('src'))}).sort());if(olk!==nlk){olib.forEach(function(o){o.remove()});nlib.forEach(function(n){var src=n.getAttribute('src');var ls=document.createElement('script');ls.src=src+(src.indexOf('?')>-1?'&':'?')+'_r='+Date.now();document.body.appendChild(ls)})}if(!hardReset){window.scrollTo(sx,sy)}else{if(oscr)oscr.remove();if(nscr){var src=nscr.getAttribute('src');var s=document.createElement('script');s.src=src+(src.indexOf('?')>-1?'&':'?')+'_r='+Date.now();s.onload=function(){document.dispatchEvent(new Event('DOMContentLoaded'));window.scrollTo(sx,sy)};s.onerror=function(){window.scrollTo(sx,sy)};document.body.appendChild(s)}else{document.dispatchEvent(new Event('DOMContentLoaded'));window.scrollTo(sx,sy)}}}).catch(function(){location.reload()})}var iR=document.getElementById('root');if(iR)lastSrvRoot=iR.cloneNode(true);connect()})()</script>` : "";
|
|
3716
3817
|
const scrollHandlerScript = injectLiveReload ? `<script${nonceAttr}>(function(){window.addEventListener('message',function(e){if(e.data.type==='GET_SCROLL_POSITION'){window.parent.postMessage({type:'SCROLL_POSITION_RESPONSE',scrollX:window.scrollX,scrollY:window.scrollY},'*')}else if(e.data.type==='SET_SCROLL_POSITION'){window.scrollTo(e.data.scrollX,e.data.scrollY)}})})()</script>` : "";
|
|
3717
3818
|
const styleContent = useBundled ? finalCSS : `
|
|
3718
3819
|
${combinedCSS.split("\n").join("\n ")}
|
|
@@ -3722,8 +3823,9 @@ picture {
|
|
|
3722
3823
|
<head>
|
|
3723
3824
|
<meta charset="UTF-8">
|
|
3724
3825
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
3725
|
-
${
|
|
3726
|
-
${
|
|
3826
|
+
${cspNonce ? `<meta name="csp-nonce" content="${cspNonce}">
|
|
3827
|
+
` : ""}${iconTags ? iconTags + "\n " : ""}${scriptPreloadTag ? scriptPreloadTag + "\n " : ""}${imagePreloadTags ? imagePreloadTags + "\n " : ""}${fontPreloadTags ? fontPreloadTags + "\n " : ""}${libraryTags.headCSS ? libraryTags.headCSS + "\n " : ""}${libraryTags.headJS ? libraryTags.headJS + "\n " : ""}${rendered.meta}
|
|
3828
|
+
${configInlineScript}${cmsInlineScript}${clientDataScripts}<style id="meno-styles"${nonceAttr}>${styleContent}</style>${mergedCustomCode.head ? "\n " + mergedCustomCode.head : ""}
|
|
3727
3829
|
</head>
|
|
3728
3830
|
<body>${mergedCustomCode.bodyStart ? "\n " + mergedCustomCode.bodyStart : ""}
|
|
3729
3831
|
<div id="root">
|
|
@@ -4605,9 +4707,7 @@ var MenoFilter = class _MenoFilter {
|
|
|
4605
4707
|
result = result.filter((item) => this.matchesCriteria(item, this.criteria));
|
|
4606
4708
|
}
|
|
4607
4709
|
if (this.orCriteria.length > 0) {
|
|
4608
|
-
result = result.filter(
|
|
4609
|
-
(item) => this.orCriteria.some((criteria) => this.matchesCriteria(item, criteria))
|
|
4610
|
-
);
|
|
4710
|
+
result = result.filter((item) => this.orCriteria.some((criteria) => this.matchesCriteria(item, criteria)));
|
|
4611
4711
|
}
|
|
4612
4712
|
if (this.searchQuery) {
|
|
4613
4713
|
const query = this.searchQuery;
|
|
@@ -4721,9 +4821,10 @@ var MenoFilter = class _MenoFilter {
|
|
|
4721
4821
|
return Array.isArray(opValue) ? opValue.includes(itemValue) : false;
|
|
4722
4822
|
case "$nin":
|
|
4723
4823
|
return Array.isArray(opValue) ? !opValue.includes(itemValue) : true;
|
|
4724
|
-
case "$empty":
|
|
4824
|
+
case "$empty": {
|
|
4725
4825
|
const isEmpty = itemValue === void 0 || itemValue === null || itemValue === "" || Array.isArray(itemValue) && itemValue.length === 0;
|
|
4726
4826
|
return opValue ? isEmpty : !isEmpty;
|
|
4827
|
+
}
|
|
4727
4828
|
default:
|
|
4728
4829
|
console.warn(`MenoFilter: Unknown operator "${op}"`);
|
|
4729
4830
|
return true;
|
|
@@ -4829,9 +4930,7 @@ function handleMultiButtonClick(filter, field, value, currentValue) {
|
|
|
4829
4930
|
}
|
|
4830
4931
|
function bindFilterControls(instance) {
|
|
4831
4932
|
const { wrapper, filter, cleanup } = instance;
|
|
4832
|
-
const filterButtons = wrapper.querySelectorAll(
|
|
4833
|
-
`[${ATTR.FILTER_FIELD}][${ATTR.FILTER_VALUE}]`
|
|
4834
|
-
);
|
|
4933
|
+
const filterButtons = wrapper.querySelectorAll(`[${ATTR.FILTER_FIELD}][${ATTR.FILTER_VALUE}]`);
|
|
4835
4934
|
for (const btn of filterButtons) {
|
|
4836
4935
|
if (btn.tagName === "INPUT") continue;
|
|
4837
4936
|
const field = btn.getAttribute(ATTR.FILTER_FIELD);
|
|
@@ -4857,9 +4956,7 @@ function bindFilterControls(instance) {
|
|
|
4857
4956
|
btn.addEventListener("click", handler);
|
|
4858
4957
|
cleanup.push(() => btn.removeEventListener("click", handler));
|
|
4859
4958
|
}
|
|
4860
|
-
const filterCheckboxes = wrapper.querySelectorAll(
|
|
4861
|
-
`input[type="checkbox"][${ATTR.FILTER_FIELD}]`
|
|
4862
|
-
);
|
|
4959
|
+
const filterCheckboxes = wrapper.querySelectorAll(`input[type="checkbox"][${ATTR.FILTER_FIELD}]`);
|
|
4863
4960
|
for (const checkbox of filterCheckboxes) {
|
|
4864
4961
|
const field = checkbox.getAttribute(ATTR.FILTER_FIELD);
|
|
4865
4962
|
const handler = () => {
|
|
@@ -4879,9 +4976,7 @@ function bindFilterControls(instance) {
|
|
|
4879
4976
|
checkbox.addEventListener("change", handler);
|
|
4880
4977
|
cleanup.push(() => checkbox.removeEventListener("change", handler));
|
|
4881
4978
|
}
|
|
4882
|
-
const filterSelects = wrapper.querySelectorAll(
|
|
4883
|
-
`select[${ATTR.FILTER_FIELD}]`
|
|
4884
|
-
);
|
|
4979
|
+
const filterSelects = wrapper.querySelectorAll(`select[${ATTR.FILTER_FIELD}]`);
|
|
4885
4980
|
for (const select of filterSelects) {
|
|
4886
4981
|
const field = select.getAttribute(ATTR.FILTER_FIELD);
|
|
4887
4982
|
const handler = () => {
|
|
@@ -4895,9 +4990,7 @@ function bindFilterControls(instance) {
|
|
|
4895
4990
|
select.addEventListener("change", handler);
|
|
4896
4991
|
cleanup.push(() => select.removeEventListener("change", handler));
|
|
4897
4992
|
}
|
|
4898
|
-
const filterRadios = wrapper.querySelectorAll(
|
|
4899
|
-
`input[type="radio"][${ATTR.FILTER_FIELD}]`
|
|
4900
|
-
);
|
|
4993
|
+
const filterRadios = wrapper.querySelectorAll(`input[type="radio"][${ATTR.FILTER_FIELD}]`);
|
|
4901
4994
|
for (const radio of filterRadios) {
|
|
4902
4995
|
const field = radio.getAttribute(ATTR.FILTER_FIELD);
|
|
4903
4996
|
const value = radio.getAttribute(ATTR.FILTER_VALUE) || radio.value;
|
|
@@ -4918,9 +5011,7 @@ function updateCheckboxFilters(wrapper, filter, field) {
|
|
|
4918
5011
|
const checkboxes = wrapper.querySelectorAll(
|
|
4919
5012
|
`input[type="checkbox"][${ATTR.FILTER_FIELD}="${field}"]:checked`
|
|
4920
5013
|
);
|
|
4921
|
-
const values = Array.from(checkboxes).map(
|
|
4922
|
-
(cb) => cb.getAttribute(ATTR.FILTER_VALUE) || cb.value
|
|
4923
|
-
);
|
|
5014
|
+
const values = Array.from(checkboxes).map((cb) => cb.getAttribute(ATTR.FILTER_VALUE) || cb.value);
|
|
4924
5015
|
if (values.length === 0) {
|
|
4925
5016
|
filter.removeFilter(field);
|
|
4926
5017
|
} else if (values.length === 1) {
|
|
@@ -5008,15 +5099,11 @@ function bindActionControls(instance) {
|
|
|
5008
5099
|
}
|
|
5009
5100
|
}
|
|
5010
5101
|
function resetFormControls(wrapper) {
|
|
5011
|
-
const checkboxes = wrapper.querySelectorAll(
|
|
5012
|
-
`input[type="checkbox"][${ATTR.FILTER_FIELD}]`
|
|
5013
|
-
);
|
|
5102
|
+
const checkboxes = wrapper.querySelectorAll(`input[type="checkbox"][${ATTR.FILTER_FIELD}]`);
|
|
5014
5103
|
for (const cb of checkboxes) {
|
|
5015
5104
|
cb.checked = false;
|
|
5016
5105
|
}
|
|
5017
|
-
const selects = wrapper.querySelectorAll(
|
|
5018
|
-
`select[${ATTR.FILTER_FIELD}]`
|
|
5019
|
-
);
|
|
5106
|
+
const selects = wrapper.querySelectorAll(`select[${ATTR.FILTER_FIELD}]`);
|
|
5020
5107
|
for (const select of selects) {
|
|
5021
5108
|
select.selectedIndex = 0;
|
|
5022
5109
|
}
|
|
@@ -5048,19 +5135,18 @@ function bindPaginationControls(instance) {
|
|
|
5048
5135
|
case "last":
|
|
5049
5136
|
filter.setPage(filter.getPageInfo().total);
|
|
5050
5137
|
break;
|
|
5051
|
-
default:
|
|
5138
|
+
default: {
|
|
5052
5139
|
const page = parseInt(action || "1", 10);
|
|
5053
5140
|
if (!isNaN(page)) {
|
|
5054
5141
|
filter.setPage(page);
|
|
5055
5142
|
}
|
|
5143
|
+
}
|
|
5056
5144
|
}
|
|
5057
5145
|
};
|
|
5058
5146
|
btn.addEventListener("click", handler);
|
|
5059
5147
|
cleanup.push(() => btn.removeEventListener("click", handler));
|
|
5060
5148
|
}
|
|
5061
|
-
const perPageSelects = wrapper.querySelectorAll(
|
|
5062
|
-
`[${ATTR.PER_PAGE_SELECT}]`
|
|
5063
|
-
);
|
|
5149
|
+
const perPageSelects = wrapper.querySelectorAll(`[${ATTR.PER_PAGE_SELECT}]`);
|
|
5064
5150
|
for (const select of perPageSelects) {
|
|
5065
5151
|
const handler = () => {
|
|
5066
5152
|
const perPage = parseInt(select.value, 10);
|
|
@@ -5208,9 +5294,7 @@ function renderNestedItemFromTemplate(template, item, itemAs, index, total, pare
|
|
|
5208
5294
|
return element;
|
|
5209
5295
|
}
|
|
5210
5296
|
function hydrateNestedCMSLists(element, parentItem, parentItemAs) {
|
|
5211
|
-
const placeholders = element.querySelectorAll(
|
|
5212
|
-
'[data-cms-list-nested="true"]'
|
|
5213
|
-
);
|
|
5297
|
+
const placeholders = element.querySelectorAll('[data-cms-list-nested="true"]');
|
|
5214
5298
|
for (const placeholder of placeholders) {
|
|
5215
5299
|
hydrateNestedCMSList(placeholder, parentItem, parentItemAs);
|
|
5216
5300
|
}
|
|
@@ -5225,15 +5309,15 @@ function hydrateNestedCMSList(placeholder, parentItem, parentItemAs) {
|
|
|
5225
5309
|
return;
|
|
5226
5310
|
}
|
|
5227
5311
|
const collection = config.collection;
|
|
5228
|
-
const templateEl = placeholder.querySelector(
|
|
5229
|
-
"template[data-nested-template]"
|
|
5230
|
-
);
|
|
5312
|
+
const templateEl = placeholder.querySelector("template[data-nested-template]");
|
|
5231
5313
|
if (!templateEl) return;
|
|
5232
5314
|
const childTemplate = templateEl.innerHTML.trim();
|
|
5233
5315
|
const nestedItemAs = config.itemAs || singularizeWord(collection);
|
|
5234
5316
|
const collectionData = getCollectionData(collection);
|
|
5235
5317
|
if (!collectionData) {
|
|
5236
|
-
console.warn(
|
|
5318
|
+
console.warn(
|
|
5319
|
+
`MenoFilter: No data for nested collection "${collection}". Ensure clientData.enabled is true in schema.`
|
|
5320
|
+
);
|
|
5237
5321
|
return;
|
|
5238
5322
|
}
|
|
5239
5323
|
let items;
|
|
@@ -5440,7 +5524,7 @@ function filterDOMOnly(instance, listEl) {
|
|
|
5440
5524
|
const sortConfig = filter.getSort();
|
|
5441
5525
|
const perPage = filter.getPageInfo().perPage;
|
|
5442
5526
|
const currentPage = filter.getPageInfo().current;
|
|
5443
|
-
|
|
5527
|
+
const filteredItems = items.filter((item) => {
|
|
5444
5528
|
for (const [field, value] of Object.entries(filters)) {
|
|
5445
5529
|
const itemValue = getItemFieldValue(item, field);
|
|
5446
5530
|
if (!matchesFilter(itemValue, value)) {
|
|
@@ -5569,9 +5653,7 @@ function updateFacets(wrapper, filter) {
|
|
|
5569
5653
|
function updateActiveFilters(wrapper, filter, instance) {
|
|
5570
5654
|
const container = wrapper.querySelector(`[${ATTR.ACTIVE_FILTERS}]`);
|
|
5571
5655
|
if (!container) return;
|
|
5572
|
-
const template = wrapper.querySelector(
|
|
5573
|
-
`template[${ATTR.ACTIVE_FILTER_TEMPLATE}]`
|
|
5574
|
-
);
|
|
5656
|
+
const template = wrapper.querySelector(`template[${ATTR.ACTIVE_FILTER_TEMPLATE}]`);
|
|
5575
5657
|
const filters = filter.getFilters();
|
|
5576
5658
|
const entries = Object.entries(filters);
|
|
5577
5659
|
container.innerHTML = "";
|
|
@@ -5702,9 +5784,7 @@ function updateLoadMoreUI(wrapper, filter) {
|
|
|
5702
5784
|
function updateActiveStates(wrapper, filter) {
|
|
5703
5785
|
const filters = filter.getFilters();
|
|
5704
5786
|
const activeClass = wrapper.getAttribute(ATTR.ACTIVE_CLASS) || "active";
|
|
5705
|
-
const filterButtons = wrapper.querySelectorAll(
|
|
5706
|
-
`[${ATTR.FILTER_FIELD}][${ATTR.FILTER_VALUE}]`
|
|
5707
|
-
);
|
|
5787
|
+
const filterButtons = wrapper.querySelectorAll(`[${ATTR.FILTER_FIELD}][${ATTR.FILTER_VALUE}]`);
|
|
5708
5788
|
for (const btn of filterButtons) {
|
|
5709
5789
|
if (btn.tagName === "INPUT") continue;
|
|
5710
5790
|
const field = btn.getAttribute(ATTR.FILTER_FIELD);
|
|
@@ -5937,7 +6017,9 @@ var FileSystemCMSProvider = class {
|
|
|
5937
6017
|
*/
|
|
5938
6018
|
validateCollection(collection) {
|
|
5939
6019
|
if (!isValidIdentifier(collection)) {
|
|
5940
|
-
throw new Error(
|
|
6020
|
+
throw new Error(
|
|
6021
|
+
`Invalid collection name: "${collection}". Collection names must contain only letters, numbers, hyphens, and underscores.`
|
|
6022
|
+
);
|
|
5941
6023
|
}
|
|
5942
6024
|
}
|
|
5943
6025
|
/**
|
|
@@ -5946,7 +6028,9 @@ var FileSystemCMSProvider = class {
|
|
|
5946
6028
|
*/
|
|
5947
6029
|
validateFilename(filename) {
|
|
5948
6030
|
if (!isSafePathSegment(filename)) {
|
|
5949
|
-
throw new Error(
|
|
6031
|
+
throw new Error(
|
|
6032
|
+
`Invalid filename: "${filename}". Filenames cannot contain path separators or traversal sequences.`
|
|
6033
|
+
);
|
|
5950
6034
|
}
|
|
5951
6035
|
if (isReservedDraftFilename(filename)) {
|
|
5952
6036
|
throw new Error(`Invalid filename: "${filename}". The "${CMS_DRAFT_SUFFIX}" suffix is reserved for draft files.`);
|
|
@@ -6271,7 +6355,9 @@ var FileSystemCMSProvider = class {
|
|
|
6271
6355
|
*/
|
|
6272
6356
|
async saveSchema(collectionId, pageData) {
|
|
6273
6357
|
if (!isValidIdentifier(collectionId)) {
|
|
6274
|
-
throw new Error(
|
|
6358
|
+
throw new Error(
|
|
6359
|
+
`Invalid collection ID: "${collectionId}". Collection IDs must contain only letters, numbers, hyphens, and underscores.`
|
|
6360
|
+
);
|
|
6275
6361
|
}
|
|
6276
6362
|
const { writeFile: writeFile2, mkdir } = await import("fs/promises");
|
|
6277
6363
|
if (!existsSync2(this.templatesDir)) {
|
|
@@ -6294,7 +6380,9 @@ var FileSystemCMSProvider = class {
|
|
|
6294
6380
|
*/
|
|
6295
6381
|
async updateSchema(collectionId, updates) {
|
|
6296
6382
|
if (!isValidIdentifier(collectionId)) {
|
|
6297
|
-
throw new Error(
|
|
6383
|
+
throw new Error(
|
|
6384
|
+
`Invalid collection ID: "${collectionId}". Collection IDs must contain only letters, numbers, hyphens, and underscores.`
|
|
6385
|
+
);
|
|
6298
6386
|
}
|
|
6299
6387
|
const { readFile, writeFile: writeFile2 } = await import("fs/promises");
|
|
6300
6388
|
const pageFilePath = join2(this.templatesDir, `${collectionId}.json`);
|
|
@@ -6348,10 +6436,6 @@ export {
|
|
|
6348
6436
|
generateFontPreloadTags,
|
|
6349
6437
|
generateThemeColorVariablesCSS,
|
|
6350
6438
|
generateVariablesCSS,
|
|
6351
|
-
buildSlugIndex,
|
|
6352
|
-
translatePath,
|
|
6353
|
-
getLocaleLinks,
|
|
6354
|
-
resolveSlugToPageId,
|
|
6355
6439
|
escapeHtml,
|
|
6356
6440
|
buildAttributes,
|
|
6357
6441
|
styleToString,
|
|
@@ -6374,13 +6458,8 @@ export {
|
|
|
6374
6458
|
menoFilterScript,
|
|
6375
6459
|
needsMenoFilter,
|
|
6376
6460
|
prepareClientData,
|
|
6377
|
-
mergeLibraries,
|
|
6378
|
-
generateLibraryTags,
|
|
6379
|
-
collectComponentLibraries,
|
|
6380
|
-
extractLibraryOrigins,
|
|
6381
|
-
filterLibrariesByContext,
|
|
6382
6461
|
generateSSRHTML,
|
|
6383
6462
|
FileSystemCMSProvider,
|
|
6384
6463
|
migrateTemplatesDirectory
|
|
6385
6464
|
};
|
|
6386
|
-
//# sourceMappingURL=chunk-
|
|
6465
|
+
//# sourceMappingURL=chunk-2FN4UOVO.js.map
|