meno-core 1.0.53 → 1.1.0
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 +66 -261
- package/build-astro.ts +150 -128
- package/dist/bin/cli.js +42 -185
- package/dist/bin/cli.js.map +2 -2
- package/dist/chunks/chunk-2AR55GYH.js +42 -0
- package/dist/chunks/chunk-2AR55GYH.js.map +7 -0
- package/dist/chunks/{chunk-JGWFTO6P.js → chunk-2IIQK7T3.js} +2624 -1389
- package/dist/chunks/chunk-2IIQK7T3.js.map +7 -0
- package/dist/chunks/chunk-4ZRU52J2.js +169 -0
- package/dist/chunks/chunk-4ZRU52J2.js.map +7 -0
- package/dist/chunks/{chunk-UB44F4Z2.js → chunk-5X4HCN7J.js} +5 -7
- package/dist/chunks/chunk-5X4HCN7J.js.map +7 -0
- package/dist/chunks/{chunk-WQFG7PAH.js → chunk-7CCVOL5M.js} +15 -19
- package/dist/chunks/chunk-7CCVOL5M.js.map +7 -0
- package/dist/chunks/{chunk-YBLHKYFF.js → chunk-AR7LHIFY.js} +8 -2
- package/dist/chunks/chunk-AR7LHIFY.js.map +7 -0
- package/dist/chunks/{chunk-O3NAGJP4.js → chunk-NUP7H7D3.js} +135 -41
- package/dist/chunks/chunk-NUP7H7D3.js.map +7 -0
- package/dist/chunks/{chunk-X754AHS5.js → chunk-QWTQZHG3.js} +194 -90
- package/dist/chunks/chunk-QWTQZHG3.js.map +7 -0
- package/dist/chunks/{chunk-H3GJ4H2U.js → chunk-XTKNX4FW.js} +216 -87
- package/dist/chunks/chunk-XTKNX4FW.js.map +7 -0
- package/dist/chunks/{fs-JGINUXGL.js → fs-G3ANWEFP.js} +2 -2
- package/dist/lib/client/index.js +1003 -475
- package/dist/lib/client/index.js.map +3 -3
- package/dist/lib/server/index.js +14393 -6371
- package/dist/lib/server/index.js.map +4 -4
- package/dist/lib/shared/index.js +342 -101
- 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 +64 -80
- package/dist/lib/test-utils/index.js.map +2 -2
- package/entries/client-router.tsx +10 -8
- package/lib/client/ClientInitializer.ts +8 -8
- package/lib/client/ErrorBoundary.test.tsx +246 -186
- package/lib/client/ErrorBoundary.tsx +183 -132
- package/lib/client/componentRegistry.test.ts +96 -108
- package/lib/client/componentRegistry.ts +1 -3
- package/lib/client/contexts/ThemeContext.tsx +3 -2
- package/lib/client/core/ComponentBuilder.test.ts +663 -560
- package/lib/client/core/ComponentBuilder.ts +427 -155
- package/lib/client/core/ComponentRenderer.test.tsx +2 -4
- package/lib/client/core/ComponentRenderer.tsx +46 -33
- package/lib/client/core/builders/embedBuilder.ts +242 -54
- package/lib/client/core/builders/linkBuilder.ts +72 -45
- package/lib/client/core/builders/linkNodeBuilder.ts +79 -54
- package/lib/client/core/builders/listBuilder.ts +155 -89
- package/lib/client/core/builders/localeListBuilder.ts +97 -62
- package/lib/client/core/builders/types.ts +5 -5
- package/lib/client/core/cmsTemplateProcessor.ts +8 -9
- package/lib/client/elementRegistry.ts +3 -3
- package/lib/client/fontFamiliesService.test.ts +2 -10
- package/lib/client/fontFamiliesService.ts +3 -3
- package/lib/client/hmr/HMRManager.tsx +47 -30
- package/lib/client/hmrCssReload.ts +49 -14
- package/lib/client/hmrWebSocket.ts +14 -19
- package/lib/client/hooks/useColorVariables.test.ts +21 -21
- package/lib/client/hooks/useColorVariables.ts +23 -18
- package/lib/client/hooks/usePropertyAutocomplete.ts +4 -6
- package/lib/client/hooks/useVariables.ts +6 -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/meno-filter/MenoFilter.test.ts +47 -49
- package/lib/client/meno-filter/MenoFilter.ts +14 -15
- package/lib/client/meno-filter/bindings.ts +18 -43
- package/lib/client/meno-filter/init.ts +4 -4
- package/lib/client/meno-filter/renderer.ts +30 -32
- package/lib/client/meno-filter/script.generated.ts +1 -3
- package/lib/client/meno-filter/ui.ts +4 -6
- package/lib/client/meno-filter/updates.ts +18 -23
- package/lib/client/meno-filter/utils.ts +1 -1
- package/lib/client/navigation.test.ts +174 -178
- package/lib/client/navigation.ts +0 -1
- package/lib/client/responsiveStyleResolver.knownTokens.test.ts +71 -0
- package/lib/client/responsiveStyleResolver.test.ts +234 -232
- package/lib/client/responsiveStyleResolver.ts +74 -20
- package/lib/client/routing/RouteLoader.test.ts +24 -25
- package/lib/client/routing/RouteLoader.ts +27 -35
- package/lib/client/routing/Router.tsx +210 -153
- package/lib/client/scripts/ScriptExecutor.test.ts +157 -158
- package/lib/client/scripts/ScriptExecutor.ts +18 -36
- package/lib/client/services/PrefetchService.test.ts +3 -3
- package/lib/client/services/PrefetchService.ts +23 -29
- package/lib/client/styleProcessor.test.ts +9 -9
- package/lib/client/styleProcessor.ts +24 -15
- package/lib/client/styles/StyleInjector.test.ts +122 -115
- package/lib/client/styles/StyleInjector.ts +10 -7
- package/lib/client/styles/UtilityClassCollector.ts +62 -28
- package/lib/client/styles/cspNonce.test.ts +2 -5
- package/lib/client/templateEngine.test.ts +554 -488
- package/lib/client/templateEngine.ts +203 -73
- package/lib/client/theme.test.ts +1 -1
- 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 +4 -5
- package/lib/server/__integration__/ssr-rendering.test.ts +47 -37
- package/lib/server/__integration__/static-assets.test.ts +3 -3
- package/lib/server/__integration__/test-helpers.ts +87 -74
- package/lib/server/ab/generateFunctions.ts +12 -10
- package/lib/server/astro/cmsPageEmitter.ts +26 -42
- package/lib/server/astro/componentEmitter.ts +35 -43
- package/lib/server/astro/cssCollector.ts +10 -26
- package/lib/server/astro/nodeToAstro.test.ts +1754 -34
- package/lib/server/astro/nodeToAstro.ts +232 -216
- package/lib/server/astro/normalizeOrphanTemplateProps.test.ts +115 -119
- package/lib/server/astro/normalizeOrphanTemplateProps.ts +11 -18
- 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 +17 -20
- package/lib/server/createServer.ts +7 -19
- package/lib/server/cssGenerator.test.ts +35 -44
- package/lib/server/cssGenerator.ts +8 -19
- package/lib/server/fileWatcher.test.ts +164 -13
- package/lib/server/fileWatcher.ts +209 -124
- package/lib/server/index.ts +14 -17
- package/lib/server/jsonLoader.test.ts +39 -2
- package/lib/server/jsonLoader.ts +39 -34
- package/lib/server/middleware/cors.test.ts +21 -21
- package/lib/server/middleware/cors.ts +28 -4
- package/lib/server/middleware/errorHandler.test.ts +7 -5
- package/lib/server/middleware/errorHandler.ts +3 -8
- package/lib/server/middleware/index.ts +0 -1
- package/lib/server/middleware/logger.test.ts +10 -8
- package/lib/server/middleware/logger.ts +17 -29
- package/lib/server/migrateTemplates.ts +3 -3
- package/lib/server/pageCache.test.ts +76 -77
- package/lib/server/pageCache.ts +0 -1
- package/lib/server/projectContext.ts +5 -4
- package/lib/server/providers/fileSystemCMSProvider.test.ts +142 -99
- package/lib/server/providers/fileSystemCMSProvider.ts +62 -38
- package/lib/server/routes/api/cms.test.ts +26 -14
- package/lib/server/routes/api/cms.ts +9 -14
- package/lib/server/routes/api/colors.test.ts +2 -2
- package/lib/server/routes/api/components.ts +31 -35
- package/lib/server/routes/api/config.ts +3 -4
- package/lib/server/routes/api/core-routes.ts +49 -76
- package/lib/server/routes/api/enums.test.ts +2 -2
- package/lib/server/routes/api/functions.ts +9 -17
- package/lib/server/routes/api/index.ts +3 -6
- package/lib/server/routes/api/pages.ts +8 -11
- package/lib/server/routes/api/shared.test.ts +1 -1
- package/lib/server/routes/api/shared.ts +12 -9
- package/lib/server/routes/api/variables.test.ts +3 -5
- package/lib/server/routes/api/variables.ts +1 -1
- package/lib/server/routes/index.ts +25 -28
- package/lib/server/routes/pages.ts +35 -31
- package/lib/server/routes/static.ts +17 -6
- package/lib/server/runtime/bundler.ts +98 -61
- package/lib/server/runtime/fs.ts +16 -26
- package/lib/server/runtime/httpServer.ts +8 -12
- package/lib/server/services/ColorService.test.ts +3 -3
- package/lib/server/services/ColorService.ts +37 -29
- package/lib/server/services/EnumService.test.ts +4 -8
- package/lib/server/services/EnumService.ts +11 -3
- package/lib/server/services/VariableService.test.ts +8 -12
- package/lib/server/services/VariableService.ts +11 -3
- package/lib/server/services/cmsService.test.ts +158 -120
- package/lib/server/services/cmsService.ts +36 -146
- package/lib/server/services/componentService.test.ts +125 -45
- package/lib/server/services/componentService.ts +70 -46
- package/lib/server/services/configService.test.ts +22 -45
- package/lib/server/services/configService.ts +50 -27
- package/lib/server/services/fileWatcherService.ts +42 -8
- package/lib/server/services/index.ts +0 -1
- package/lib/server/services/pageService.test.ts +8 -10
- package/lib/server/services/pageService.ts +32 -18
- package/lib/server/ssr/attributeBuilder.ts +18 -8
- package/lib/server/ssr/buildErrorOverlay.ts +11 -12
- package/lib/server/ssr/clientDataInjector.ts +7 -21
- package/lib/server/ssr/cmsSSRProcessor.ts +4 -8
- package/lib/server/ssr/cssCollector.ts +1 -1
- package/lib/server/ssr/errorOverlay.test.ts +1 -1
- package/lib/server/ssr/errorOverlay.ts +3 -9
- package/lib/server/ssr/htmlGenerator.nonce.test.ts +9 -14
- package/lib/server/ssr/htmlGenerator.test.ts +120 -44
- package/lib/server/ssr/htmlGenerator.ts +126 -91
- package/lib/server/ssr/imageMetadata.test.ts +3 -1
- package/lib/server/ssr/imageMetadata.ts +27 -21
- package/lib/server/ssr/jsCollector.test.ts +8 -18
- package/lib/server/ssr/jsCollector.ts +3 -8
- package/lib/server/ssr/liveReloadIntegration.test.ts +76 -36
- 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 +316 -256
- package/lib/server/ssr/ssrRenderer.ts +795 -243
- package/lib/server/ssrRenderer.test.ts +1048 -954
- package/lib/server/utils/jsonLineMapper.test.ts +28 -28
- package/lib/server/utils/jsonLineMapper.ts +7 -7
- package/lib/server/validateStyleCoverage.ts +18 -21
- package/lib/server/websocketManager.ts +28 -19
- package/lib/shared/attributeNodeUtils.test.ts +15 -15
- package/lib/shared/attributeNodeUtils.ts +5 -12
- package/lib/shared/breakpoints.test.ts +5 -5
- package/lib/shared/breakpoints.ts +4 -11
- package/lib/shared/cmsQuery.test.ts +81 -0
- package/lib/shared/cmsQuery.ts +92 -0
- package/lib/shared/cmsQueryParser.test.ts +50 -42
- package/lib/shared/cmsQueryParser.ts +60 -38
- package/lib/shared/colorConversions.ts +9 -9
- package/lib/shared/colorVariableUtils.test.ts +27 -5
- package/lib/shared/colorVariableUtils.ts +21 -12
- package/lib/shared/componentRefs.ts +1 -5
- package/lib/shared/constants.test.ts +3 -3
- package/lib/shared/constants.ts +8 -8
- package/lib/shared/cssGeneration.test.ts +285 -144
- package/lib/shared/cssGeneration.ts +217 -531
- package/lib/shared/cssNamedColors.ts +152 -30
- package/lib/shared/cssProperties.test.ts +69 -70
- package/lib/shared/cssProperties.ts +298 -114
- package/lib/shared/elementClassName.test.ts +109 -109
- package/lib/shared/elementClassName.ts +3 -3
- package/lib/shared/elementUtils.ts +12 -16
- package/lib/shared/errorLogger.test.ts +12 -12
- 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 +145 -0
- package/lib/shared/expressionEvaluator.ts +52 -24
- package/lib/shared/fontLoader.test.ts +32 -18
- package/lib/shared/fontLoader.ts +2 -2
- package/lib/shared/friendlyError.ts +2 -3
- package/lib/shared/gradientUtils.test.ts +3 -7
- package/lib/shared/gradientUtils.ts +17 -14
- package/lib/shared/hrefRefs.test.ts +2 -2
- package/lib/shared/hrefRefs.ts +2 -10
- package/lib/shared/i18n.test.ts +4 -4
- package/lib/shared/i18n.ts +18 -38
- package/lib/shared/index.ts +27 -0
- package/lib/shared/inlineSvgStyleRules.ts +14 -13
- package/lib/shared/interactiveStyleMappings.test.ts +32 -54
- package/lib/shared/interactiveStyleMappings.ts +11 -24
- package/lib/shared/interactiveStyles.test.ts +165 -188
- package/lib/shared/interfaces/contentProvider.ts +1 -1
- package/lib/shared/itemTemplateUtils.test.ts +11 -17
- package/lib/shared/itemTemplateUtils.ts +27 -39
- package/lib/shared/jsonRepair.ts +16 -10
- package/lib/shared/libraryLoader.test.ts +21 -55
- package/lib/shared/libraryLoader.ts +7 -22
- package/lib/shared/linkUtils.ts +1 -1
- package/lib/shared/logger.test.ts +66 -0
- package/lib/shared/logger.ts +94 -0
- package/lib/shared/markdown.ts +25 -0
- package/lib/shared/netlifyLocale404.test.ts +179 -0
- package/lib/shared/netlifyLocale404.ts +110 -0
- package/lib/shared/nodeUtils.test.ts +28 -16
- package/lib/shared/nodeUtils.ts +76 -23
- package/lib/shared/pathArrayUtils.test.ts +1 -2
- package/lib/shared/pathArrayUtils.ts +1 -1
- package/lib/shared/pathSecurity.ts +2 -2
- package/lib/shared/pathUtils.test.ts +4 -6
- package/lib/shared/pathUtils.ts +42 -49
- 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 +17 -20
- package/lib/shared/paths/PathUtils.ts +13 -13
- package/lib/shared/paths/PathValidator.test.ts +2 -15
- package/lib/shared/paths/PathValidator.ts +12 -10
- package/lib/shared/paths/index.ts +1 -2
- package/lib/shared/permissions.test.ts +168 -0
- package/lib/shared/permissions.ts +162 -0
- package/lib/shared/propResolver.test.ts +240 -244
- package/lib/shared/propResolver.ts +15 -26
- package/lib/shared/pxToRem.test.ts +7 -6
- package/lib/shared/pxToRem.ts +2 -5
- package/lib/shared/registry/BaseNodeTypeRegistry.test.ts +12 -6
- package/lib/shared/registry/ClientRegistry.ts +0 -2
- package/lib/shared/registry/ComponentRegistry.test.ts +46 -32
- package/lib/shared/registry/ComponentRegistry.ts +12 -9
- package/lib/shared/registry/NodeTypeDefinition.ts +16 -9
- package/lib/shared/registry/RegistryManager.ts +1 -2
- package/lib/shared/registry/SSRRegistry.ts +0 -2
- package/lib/shared/registry/createNodeType.ts +7 -9
- package/lib/shared/registry/defineNodeType.ts +2 -6
- package/lib/shared/registry/fieldPresets.ts +3 -1
- package/lib/shared/registry/index.ts +0 -1
- package/lib/shared/registry/nodeTypes/ComponentInstanceNodeType.ts +14 -15
- package/lib/shared/registry/nodeTypes/CustomNodeType.ts +103 -0
- package/lib/shared/registry/nodeTypes/EmbedNodeType.ts +18 -11
- package/lib/shared/registry/nodeTypes/HtmlNodeType.ts +48 -19
- package/lib/shared/registry/nodeTypes/IslandNodeType.ts +129 -0
- package/lib/shared/registry/nodeTypes/LinkNodeType.ts +21 -19
- package/lib/shared/registry/nodeTypes/ListNodeType.ts +117 -77
- package/lib/shared/registry/nodeTypes/LocaleListNodeType.ts +27 -21
- package/lib/shared/registry/nodeTypes/MarkdownNodeType.ts +78 -0
- package/lib/shared/registry/nodeTypes/SlotMarkerType.ts +12 -8
- package/lib/shared/registry/nodeTypes/index.ts +26 -3
- package/lib/shared/responsiveScaling.test.ts +16 -34
- package/lib/shared/responsiveScaling.ts +61 -42
- package/lib/shared/responsiveStyleUtils.test.ts +0 -1
- package/lib/shared/responsiveStyleUtils.ts +11 -13
- package/lib/shared/richtext/htmlToTiptap.test.ts +139 -130
- package/lib/shared/richtext/htmlToTiptap.ts +2 -4
- package/lib/shared/richtext/tiptapToHtml.test.ts +5 -6
- package/lib/shared/richtext/types.ts +1 -8
- package/lib/shared/slugTranslator.test.ts +13 -13
- package/lib/shared/slugTranslator.ts +12 -16
- package/lib/shared/slugify.ts +9 -15
- package/lib/shared/styleNodeUtils.test.ts +8 -8
- package/lib/shared/styleNodeUtils.ts +18 -20
- package/lib/shared/styleUtils.test.ts +87 -61
- package/lib/shared/styleUtils.ts +5 -6
- package/lib/shared/themeDefaults.test.ts +11 -14
- package/lib/shared/themeDefaults.ts +3 -4
- package/lib/shared/tree/PathBuilder.test.ts +63 -145
- package/lib/shared/tree/PathBuilder.ts +59 -47
- package/lib/shared/treePathUtils.test.ts +51 -12
- package/lib/shared/treePathUtils.ts +91 -60
- package/lib/shared/types/api.ts +105 -8
- package/lib/shared/types/cms.test.ts +34 -0
- package/lib/shared/types/cms.ts +90 -34
- package/lib/shared/types/comment.ts +49 -16
- package/lib/shared/types/components.ts +51 -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 +25 -2
- package/lib/shared/types/permissions.ts +139 -0
- package/lib/shared/types/styles.ts +0 -1
- package/lib/shared/types/variables.test.ts +4 -13
- package/lib/shared/types/variables.ts +51 -30
- package/lib/shared/types.ts +1 -2
- package/lib/shared/utilityClassConfig.ts +751 -321
- package/lib/shared/utilityClassMapper.durability.test.ts +117 -0
- package/lib/shared/utilityClassMapper.test.ts +433 -95
- package/lib/shared/utilityClassMapper.ts +322 -249
- package/lib/shared/utilityClassNames.test.ts +38 -0
- package/lib/shared/utilityClassNames.ts +458 -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 +12 -1
- package/lib/shared/validation/index.ts +1 -0
- package/lib/shared/validation/permissionsValidators.test.ts +49 -0
- package/lib/shared/validation/permissionsValidators.ts +49 -0
- package/lib/shared/validation/propValidator.test.ts +19 -21
- package/lib/shared/validation/propValidator.ts +13 -18
- package/lib/shared/validation/schemas.test.ts +64 -32
- package/lib/shared/validation/schemas.ts +616 -345
- package/lib/shared/validation/validators.test.ts +3 -8
- package/lib/shared/validation/validators.ts +89 -68
- package/lib/shared/viewportUnits.integration.test.ts +14 -10
- package/lib/shared/viewportUnits.test.ts +24 -23
- package/lib/shared/viewportUnits.ts +12 -5
- package/lib/test-utils/dom-setup.ts +1 -1
- package/lib/test-utils/factories/ConsoleMockFactory.ts +10 -14
- package/lib/test-utils/factories/DomMockFactory.ts +17 -23
- 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 +6 -10
- package/lib/test-utils/factories/StoreMockFactory.ts +18 -29
- 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 +13 -19
- package/lib/test-utils/mocks.ts +6 -4
- package/package.json +3 -5
- package/scripts/build-for-publish.mjs +2 -4
- package/scripts/build-meno-filter.ts +4 -7
- package/tsconfig.json +1 -0
- package/vite.config.ts +4 -4
- package/build-next.ts +0 -1361
- package/build-static.test.ts +0 -424
- package/build-static.ts +0 -1074
- package/dist/build-static.js +0 -36
- package/dist/chunks/chunk-2MHDV5BF.js +0 -251
- package/dist/chunks/chunk-2MHDV5BF.js.map +0 -7
- package/dist/chunks/chunk-AZQYF6KE.js +0 -559
- package/dist/chunks/chunk-AZQYF6KE.js.map +0 -7
- package/dist/chunks/chunk-GZHGVVW3.js +0 -322
- package/dist/chunks/chunk-GZHGVVW3.js.map +0 -7
- package/dist/chunks/chunk-H3GJ4H2U.js.map +0 -7
- package/dist/chunks/chunk-I7YIGZXT.js +0 -467
- package/dist/chunks/chunk-I7YIGZXT.js.map +0 -7
- package/dist/chunks/chunk-IGYR22T6.js +0 -6192
- package/dist/chunks/chunk-IGYR22T6.js.map +0 -7
- package/dist/chunks/chunk-JGP5A3Y5.js +0 -1136
- package/dist/chunks/chunk-JGP5A3Y5.js.map +0 -7
- package/dist/chunks/chunk-JGWFTO6P.js.map +0 -7
- package/dist/chunks/chunk-O3NAGJP4.js.map +0 -7
- package/dist/chunks/chunk-QB2LNO4W.js +0 -77
- package/dist/chunks/chunk-QB2LNO4W.js.map +0 -7
- package/dist/chunks/chunk-R6XHAFBF.js +0 -3821
- package/dist/chunks/chunk-R6XHAFBF.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/chunk-X754AHS5.js.map +0 -7
- package/dist/chunks/chunk-YBLHKYFF.js.map +0 -7
- package/dist/chunks/configService-R3OGU2UD.js +0 -13
- package/dist/chunks/configService-R3OGU2UD.js.map +0 -7
- package/dist/chunks/constants-STK2YBIW.js +0 -46
- package/dist/chunks/constants-STK2YBIW.js.map +0 -7
- package/dist/chunks/fs-JGINUXGL.js.map +0 -7
- package/dist/entries/server-router.js +0 -67
- package/dist/entries/server-router.js.map +0 -7
- package/entries/server-router.tsx +0 -81
- package/lib/server/providers/fileSystemPageProvider.ts +0 -160
- package/lib/server/webflow/buildWebflow.ts +0 -635
- package/lib/server/webflow/index.ts +0 -23
- package/lib/server/webflow/nodeToWebflow.test.ts +0 -3170
- package/lib/server/webflow/nodeToWebflow.ts +0 -2435
- package/lib/server/webflow/styleMapper.test.ts +0 -389
- package/lib/server/webflow/styleMapper.ts +0 -695
- package/lib/server/webflow/templateWrapper.ts +0 -49
- package/lib/server/webflow/types.ts +0 -396
- /package/dist/{build-static.js.map → chunks/fs-G3ANWEFP.js.map} +0 -0
|
@@ -13,13 +13,22 @@ import { generateFontCSS, generateFontPreloadTags, loadProjectConfig } from '../
|
|
|
13
13
|
import { colorService } from '../services/ColorService';
|
|
14
14
|
import { generateThemeColorVariablesCSS, generateVariablesCSS } from '../cssGenerator';
|
|
15
15
|
import { variableService } from '../services/VariableService';
|
|
16
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
generateUtilityCSS,
|
|
18
|
+
extractUtilityClassesFromHTML,
|
|
19
|
+
generateAllInteractiveCSS,
|
|
20
|
+
} from '../../shared/cssGeneration';
|
|
17
21
|
import { rewriteViewportUnits } from '../../shared/viewportUnits';
|
|
18
22
|
import { printMissingStyleWarnings } from '../validateStyleCoverage';
|
|
19
23
|
import { formHandlerScript, needsFormHandler } from '../../client/scripts/formHandler';
|
|
20
24
|
import { menoFilterScript, needsMenoFilter } from '../../client/meno-filter/script.generated';
|
|
21
25
|
import { generateAllInlineDataScripts, prepareClientData, type ClientDataCollection } from './clientDataInjector';
|
|
22
|
-
import {
|
|
26
|
+
import {
|
|
27
|
+
mergeLibraries,
|
|
28
|
+
generateLibraryTags,
|
|
29
|
+
collectComponentLibraries,
|
|
30
|
+
filterLibrariesByContext,
|
|
31
|
+
} from '../../shared/libraryLoader';
|
|
23
32
|
import { escapeHtml } from './attributeBuilder';
|
|
24
33
|
import { renderPageSSR, type PreloadImage } from './ssrRenderer';
|
|
25
34
|
import type { CMSContext } from './cmsSSRProcessor';
|
|
@@ -34,7 +43,10 @@ function generateImagePreloadTags(preloadImages: PreloadImage[]): string {
|
|
|
34
43
|
if (preloadImages.length === 0) return '';
|
|
35
44
|
|
|
36
45
|
return preloadImages
|
|
37
|
-
.map(
|
|
46
|
+
.map(
|
|
47
|
+
(img) =>
|
|
48
|
+
`<link rel="preload" as="image" type="${img.type}" imagesrcset="${escapeHtml(img.srcset)}" imagesizes="${escapeHtml(img.sizes)}" fetchpriority="high">`,
|
|
49
|
+
)
|
|
38
50
|
.join('\n ');
|
|
39
51
|
}
|
|
40
52
|
|
|
@@ -45,29 +57,31 @@ function generateImagePreloadTags(preloadImages: PreloadImage[]): string {
|
|
|
45
57
|
function minifyCSS(code: string): string {
|
|
46
58
|
if (!code.trim()) return code;
|
|
47
59
|
|
|
48
|
-
return
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
60
|
+
return (
|
|
61
|
+
code
|
|
62
|
+
// Remove CSS comments
|
|
63
|
+
.replace(/\/\*[\s\S]*?\*\//g, '')
|
|
64
|
+
// Remove whitespace around block / declaration delimiters and selector
|
|
65
|
+
// combinators. We deliberately exclude `+` and `-` from this set: they
|
|
66
|
+
// are selector combinators (e.g. `a + b`, but `~` is also rare; siblings)
|
|
67
|
+
// AND arithmetic operators inside `calc()` / `clamp()` / `min()` / `max()`,
|
|
68
|
+
// where they REQUIRE surrounding spaces. Stripping there produces invalid
|
|
69
|
+
// CSS like `padding-top: clamp(.5*16px,((.5 - .5)/(90 - 20))*16px+(...))`,
|
|
70
|
+
// which the browser silently drops, collapsing paddings/margins to 0.
|
|
71
|
+
// The cost of leaving spaces around `+` selectors is a few extra bytes;
|
|
72
|
+
// the cost of stripping them is broken layout.
|
|
73
|
+
.replace(/\s*([{};:,>~])\s*/g, '$1')
|
|
74
|
+
// Collapse multiple spaces/newlines into single space
|
|
75
|
+
.replace(/\s+/g, ' ')
|
|
76
|
+
// Remove space after opening brace
|
|
77
|
+
.replace(/\{\s+/g, '{')
|
|
78
|
+
// Remove space before closing brace
|
|
79
|
+
.replace(/\s+\}/g, '}')
|
|
80
|
+
// Remove trailing semicolons before closing braces
|
|
81
|
+
.replace(/;}/g, '}')
|
|
82
|
+
// Remove leading/trailing whitespace
|
|
83
|
+
.trim()
|
|
84
|
+
);
|
|
71
85
|
}
|
|
72
86
|
|
|
73
87
|
/**
|
|
@@ -172,22 +186,20 @@ export async function generateSSRHTML(
|
|
|
172
186
|
slugMappings?: SlugMap[],
|
|
173
187
|
cmsContext?: CMSContext,
|
|
174
188
|
cmsService?: CMSService,
|
|
175
|
-
externalScriptPath?: string
|
|
189
|
+
externalScriptPath?: string,
|
|
176
190
|
): Promise<string>;
|
|
177
191
|
|
|
178
192
|
/**
|
|
179
193
|
* Generate complete HTML document with SSR content (options object, returns separate JS for CSP)
|
|
180
194
|
*/
|
|
181
195
|
export async function generateSSRHTML(
|
|
182
|
-
options: GenerateSSRHTMLOptions & { returnSeparateJS: true }
|
|
196
|
+
options: GenerateSSRHTMLOptions & { returnSeparateJS: true },
|
|
183
197
|
): Promise<SSRHTMLResult>;
|
|
184
198
|
|
|
185
199
|
/**
|
|
186
200
|
* Generate complete HTML document with SSR content (options object)
|
|
187
201
|
*/
|
|
188
|
-
export async function generateSSRHTML(
|
|
189
|
-
options: GenerateSSRHTMLOptions & { returnSeparateJS?: false }
|
|
190
|
-
): Promise<string>;
|
|
202
|
+
export async function generateSSRHTML(options: GenerateSSRHTMLOptions & { returnSeparateJS?: false }): Promise<string>;
|
|
191
203
|
|
|
192
204
|
/**
|
|
193
205
|
* Generate complete HTML document with SSR content
|
|
@@ -202,7 +214,7 @@ export async function generateSSRHTML(
|
|
|
202
214
|
slugMappings?: SlugMap[],
|
|
203
215
|
cmsContext?: CMSContext,
|
|
204
216
|
cmsService?: CMSService,
|
|
205
|
-
externalScriptPath?: string
|
|
217
|
+
externalScriptPath?: string,
|
|
206
218
|
): Promise<string | SSRHTMLResult> {
|
|
207
219
|
// Handle options object vs legacy positional args
|
|
208
220
|
let options: GenerateSSRHTMLOptions & { returnSeparateJS?: boolean };
|
|
@@ -255,16 +267,26 @@ export async function generateSSRHTML(
|
|
|
255
267
|
// on injectEditorAttrs — set ONLY when the request comes from the editor preview iframe
|
|
256
268
|
// via the studio's /__static__/ proxy (which sends an `x-meno-editor` header).
|
|
257
269
|
// Direct hits to the SSR preview server (e.g., http://localhost:8082/) get clean output.
|
|
258
|
-
const rendered = await renderPageSSR(
|
|
270
|
+
const rendered = await renderPageSSR(
|
|
271
|
+
pageData,
|
|
272
|
+
components,
|
|
273
|
+
path,
|
|
274
|
+
base,
|
|
275
|
+
loc,
|
|
276
|
+
undefined,
|
|
277
|
+
slugs,
|
|
278
|
+
cms,
|
|
279
|
+
cmsServ,
|
|
280
|
+
isProductionBuild,
|
|
281
|
+
injectEditorAttrs,
|
|
282
|
+
);
|
|
259
283
|
|
|
260
284
|
// Auto-inject data for nested collections (detected during SSR)
|
|
261
285
|
// This enables client-side hydration for nested cms-list placeholders
|
|
262
286
|
let finalClientDataCollections = clientDataCollections;
|
|
263
287
|
if (rendered.neededCollections.size > 0 && cmsServ) {
|
|
264
288
|
// Create a mutable copy if we need to add collections
|
|
265
|
-
finalClientDataCollections = clientDataCollections
|
|
266
|
-
? new Map(clientDataCollections)
|
|
267
|
-
: new Map();
|
|
289
|
+
finalClientDataCollections = clientDataCollections ? new Map(clientDataCollections) : new Map();
|
|
268
290
|
|
|
269
291
|
for (const collectionId of rendered.neededCollections) {
|
|
270
292
|
// Skip if already provided
|
|
@@ -273,9 +295,7 @@ export async function generateSSRHTML(
|
|
|
273
295
|
// Get schema to check if clientData is enabled
|
|
274
296
|
const schema = cmsServ.getSchema(collectionId);
|
|
275
297
|
if (!schema?.clientData?.enabled) {
|
|
276
|
-
console.warn(
|
|
277
|
-
`[SSR] Nested collection "${collectionId}" needs clientData.enabled for client-side hydration`
|
|
278
|
-
);
|
|
298
|
+
console.warn(`[SSR] Nested collection "${collectionId}" needs clientData.enabled for client-side hydration`);
|
|
279
299
|
continue;
|
|
280
300
|
}
|
|
281
301
|
|
|
@@ -322,31 +342,33 @@ export async function generateSSRHTML(
|
|
|
322
342
|
const seenJS = new Set<string>();
|
|
323
343
|
const seenCSS = new Set<string>();
|
|
324
344
|
const mergedLibraries = {
|
|
325
|
-
js: (mergedRaw.js || []).filter(lib => {
|
|
345
|
+
js: (mergedRaw.js || []).filter((lib) => {
|
|
326
346
|
if (seenJS.has(lib.url)) return false;
|
|
327
347
|
seenJS.add(lib.url);
|
|
328
348
|
return true;
|
|
329
349
|
}),
|
|
330
|
-
css: (mergedRaw.css || []).filter(lib => {
|
|
350
|
+
css: (mergedRaw.css || []).filter((lib) => {
|
|
331
351
|
if (seenCSS.has(lib.url)) return false;
|
|
332
352
|
seenCSS.add(lib.url);
|
|
333
353
|
return true;
|
|
334
354
|
}),
|
|
335
355
|
};
|
|
336
|
-
const libraryContext = isEditor ? 'editor' :
|
|
356
|
+
const libraryContext = isEditor ? 'editor' : useBundled && !injectLiveReload ? 'build' : 'preview';
|
|
337
357
|
const filteredLibraries = filterLibrariesByContext(mergedLibraries, libraryContext);
|
|
338
358
|
|
|
339
359
|
// Cache-bust local library URLs in dev/preview to avoid stale browser cache
|
|
340
360
|
const devMode = !useBundled || injectLiveReload;
|
|
341
361
|
const bustCache = devMode ? `?v=${Date.now()}` : '';
|
|
342
|
-
const finalLibraries = bustCache
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
362
|
+
const finalLibraries = bustCache
|
|
363
|
+
? {
|
|
364
|
+
js: (filteredLibraries.js || []).map((lib) =>
|
|
365
|
+
lib.url.startsWith('/') ? { ...lib, url: lib.url + bustCache } : lib,
|
|
366
|
+
),
|
|
367
|
+
css: (filteredLibraries.css || []).map((lib) =>
|
|
368
|
+
lib.url.startsWith('/') ? { ...lib, url: lib.url + bustCache } : lib,
|
|
369
|
+
),
|
|
370
|
+
}
|
|
371
|
+
: filteredLibraries;
|
|
350
372
|
|
|
351
373
|
// Read local CSS files for inline embedding
|
|
352
374
|
const inlineContents = new Map<string, string>();
|
|
@@ -355,7 +377,7 @@ export async function generateSSRHTML(
|
|
|
355
377
|
const shouldInline = css.inline !== false && css.url.startsWith('/');
|
|
356
378
|
if (shouldInline) {
|
|
357
379
|
try {
|
|
358
|
-
const cleanUrl = css.url.split('?')[0]; // Strip cache-bust query param
|
|
380
|
+
const cleanUrl = css.url.split('?')[0] ?? css.url; // Strip cache-bust query param
|
|
359
381
|
const filePath = resolveProjectPath(cleanUrl.slice(1));
|
|
360
382
|
const content = await readTextFile(filePath);
|
|
361
383
|
inlineContents.set(css.url, content);
|
|
@@ -375,12 +397,15 @@ export async function generateSSRHTML(
|
|
|
375
397
|
// Collect all JavaScript (component JS + form handler + meno filter if needed)
|
|
376
398
|
const needsForm = needsFormHandler(rendered.html);
|
|
377
399
|
// Include MenoFilter if: inline clientData exists OR page has cms-list nodes (for static strategy)
|
|
378
|
-
const needsFilter =
|
|
400
|
+
const needsFilter =
|
|
401
|
+
(finalClientDataCollections && finalClientDataCollections.size > 0) || needsMenoFilter(rendered.html);
|
|
379
402
|
const allJavaScript = [
|
|
380
403
|
rendered.javascript || '',
|
|
381
404
|
needsForm ? formHandlerScript : '',
|
|
382
|
-
needsFilter ? menoFilterScript : ''
|
|
383
|
-
]
|
|
405
|
+
needsFilter ? menoFilterScript : '',
|
|
406
|
+
]
|
|
407
|
+
.filter(Boolean)
|
|
408
|
+
.join('\n\n');
|
|
384
409
|
|
|
385
410
|
// Determine script output based on mode
|
|
386
411
|
let componentScript = '';
|
|
@@ -426,12 +451,23 @@ export async function generateSSRHTML(
|
|
|
426
451
|
const variablesConfig = await variableService.loadConfig();
|
|
427
452
|
const variablesCSS = generateVariablesCSS(variablesConfig, breakpointConfig, responsiveScalesConfig);
|
|
428
453
|
const remConversionConfig = configService.getRemConversion();
|
|
429
|
-
const utilityCSS = generateUtilityCSS(
|
|
454
|
+
const utilityCSS = generateUtilityCSS(
|
|
455
|
+
usedUtilityClasses,
|
|
456
|
+
breakpointConfig,
|
|
457
|
+
responsiveScalesConfig,
|
|
458
|
+
remConversionConfig,
|
|
459
|
+
);
|
|
430
460
|
|
|
431
461
|
// Generate interactive styles CSS from map collected during render
|
|
432
|
-
const interactiveCSS =
|
|
433
|
-
|
|
434
|
-
|
|
462
|
+
const interactiveCSS =
|
|
463
|
+
rendered.interactiveStylesMap.size > 0
|
|
464
|
+
? generateAllInteractiveCSS(
|
|
465
|
+
rendered.interactiveStylesMap,
|
|
466
|
+
breakpointConfig,
|
|
467
|
+
remConversionConfig,
|
|
468
|
+
responsiveScalesConfig,
|
|
469
|
+
)
|
|
470
|
+
: '';
|
|
435
471
|
|
|
436
472
|
// Print warnings for any unmapped styles found during build
|
|
437
473
|
printMissingStyleWarnings(false);
|
|
@@ -469,18 +505,20 @@ picture {
|
|
|
469
505
|
display: inline-block;
|
|
470
506
|
vertical-align: top;
|
|
471
507
|
line-height: 0;
|
|
508
|
+
}
|
|
509
|
+
/* line-height:0 above kills the inline-block descender gap (inline SVG/icon
|
|
510
|
+
embeds), but line-height inherits — so block rich-text inside an <Embed>
|
|
511
|
+
(CMS content: <p>/<li>/…) would collapse its text lines onto each other.
|
|
512
|
+
Restore a normal line-height on the embed's children. Astro play renders
|
|
513
|
+
rich-text bare (no .oem), which is why it looked correct only there. */
|
|
514
|
+
.oem > * {
|
|
515
|
+
line-height: normal;
|
|
472
516
|
}`;
|
|
473
517
|
|
|
474
518
|
// Combine all CSS
|
|
475
|
-
const combinedCSS = [
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
variablesCSS,
|
|
479
|
-
baseCSS,
|
|
480
|
-
componentCSS,
|
|
481
|
-
utilityCSS,
|
|
482
|
-
interactiveCSS
|
|
483
|
-
].filter(Boolean).join('\n');
|
|
519
|
+
const combinedCSS = [fontCSS, themeColorVariablesCSS, variablesCSS, baseCSS, componentCSS, utilityCSS, interactiveCSS]
|
|
520
|
+
.filter(Boolean)
|
|
521
|
+
.join('\n');
|
|
484
522
|
|
|
485
523
|
// Rewrite vh/vw to calc(var(--design-vh, 1vh) * N) so the studio's design
|
|
486
524
|
// canvas can pin viewport units to a stable height (avoids the
|
|
@@ -497,24 +535,27 @@ picture {
|
|
|
497
535
|
const menoConfig = prefetchConfig.enabled ? { prefetch: prefetchConfig } : {};
|
|
498
536
|
// Config script - inline for dev, include in external JS for static build
|
|
499
537
|
const hasConfig = Object.keys(menoConfig).length > 0;
|
|
500
|
-
const configInlineScript =
|
|
501
|
-
|
|
502
|
-
|
|
538
|
+
const configInlineScript =
|
|
539
|
+
hasConfig && !extScriptPath && !returnSeparateJS
|
|
540
|
+
? `<script${nonceAttr}>window.__MENO_CONFIG__=${JSON.stringify(menoConfig)}</script>\n `
|
|
541
|
+
: '';
|
|
503
542
|
// Add config to external JS if using external scripts
|
|
504
543
|
if (hasConfig && externalJavaScript !== null) {
|
|
505
|
-
externalJavaScript = `window.__MENO_CONFIG__=${JSON.stringify(menoConfig)};\n\n
|
|
544
|
+
externalJavaScript = `window.__MENO_CONFIG__=${JSON.stringify(menoConfig)};\n\n${externalJavaScript}`;
|
|
506
545
|
}
|
|
507
546
|
|
|
508
547
|
// CMS context script - needed when a client-side Router is present (dev mode or studio preview)
|
|
509
548
|
// Production builds are pure HTML with no client routing, so excluded
|
|
510
|
-
const cmsInlineScript =
|
|
511
|
-
|
|
512
|
-
|
|
549
|
+
const cmsInlineScript =
|
|
550
|
+
cmsTemplatePath && cms && (!useBundled || injectLiveReload)
|
|
551
|
+
? `<script${nonceAttr}>window.__MENO_CMS__=${JSON.stringify({ item: cms.cms, templatePath: cmsTemplatePath })}</script>\n `
|
|
552
|
+
: '';
|
|
513
553
|
|
|
514
554
|
// Client data scripts - inline JSON for MenoFilter (production builds only)
|
|
515
|
-
const clientDataScripts =
|
|
516
|
-
|
|
517
|
-
|
|
555
|
+
const clientDataScripts =
|
|
556
|
+
finalClientDataCollections && finalClientDataCollections.size > 0
|
|
557
|
+
? `${generateAllInlineDataScripts(finalClientDataCollections)}\n `
|
|
558
|
+
: '';
|
|
518
559
|
|
|
519
560
|
// Generate favicon and apple touch icon link tags.
|
|
520
561
|
// When a dark-mode favicon is configured alongside the default, scope the
|
|
@@ -534,17 +575,13 @@ picture {
|
|
|
534
575
|
const iconTags = [faviconTag, faviconDarkTag, appleTouchIconTag].filter(Boolean).join('\n ');
|
|
535
576
|
|
|
536
577
|
// Script preload tag - eliminates critical request chain by discovering script early
|
|
537
|
-
const scriptPreloadTag = extScriptPath
|
|
538
|
-
? `<link rel="preload" href="${extScriptPath}" as="script">`
|
|
539
|
-
: '';
|
|
578
|
+
const scriptPreloadTag = extScriptPath ? `<link rel="preload" href="${extScriptPath}" as="script">` : '';
|
|
540
579
|
|
|
541
580
|
// Image preload tags for high-priority images (LCP optimization)
|
|
542
581
|
const imagePreloadTags = generateImagePreloadTags(rendered.preloadImages);
|
|
543
582
|
|
|
544
583
|
// Live reload script for on-demand SSR preview mode (in-place DOM update, no white flash)
|
|
545
|
-
const wsUrl = serverPort
|
|
546
|
-
? `'ws://localhost:${serverPort}/hmr'`
|
|
547
|
-
: `location.origin.replace('http','ws')+'/hmr'`;
|
|
584
|
+
const wsUrl = serverPort ? `'ws://localhost:${serverPort}/hmr'` : `location.origin.replace('http','ws')+'/hmr'`;
|
|
548
585
|
// True hot reload for the studio's static preview iframe.
|
|
549
586
|
//
|
|
550
587
|
// The central question on every edit is: did the EDITOR change page
|
|
@@ -617,23 +654,21 @@ picture {
|
|
|
617
654
|
: '';
|
|
618
655
|
|
|
619
656
|
// In production, output minified CSS on single line; in dev, preserve formatting
|
|
620
|
-
const styleContent = useBundled
|
|
621
|
-
? finalCSS
|
|
622
|
-
: `\n ${combinedCSS.split('\n').join('\n ')}\n `;
|
|
657
|
+
const styleContent = useBundled ? finalCSS : `\n ${combinedCSS.split('\n').join('\n ')}\n `;
|
|
623
658
|
|
|
624
659
|
const htmlDocument = `<!DOCTYPE html>
|
|
625
660
|
<html lang="${rendered.locale}" theme="${themeConfig.default}">
|
|
626
661
|
<head>
|
|
627
662
|
<meta charset="UTF-8">
|
|
628
663
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
629
|
-
${cspNonce ? `<meta name="csp-nonce" content="${cspNonce}">\n ` : ''}${iconTags ? iconTags
|
|
630
|
-
${configInlineScript}${cmsInlineScript}${clientDataScripts}<style id="meno-styles"${nonceAttr}>${styleContent}</style>${mergedCustomCode.head ?
|
|
664
|
+
${cspNonce ? `<meta name="csp-nonce" content="${cspNonce}">\n ` : ''}${iconTags ? `${iconTags}\n ` : ''}${scriptPreloadTag ? `${scriptPreloadTag}\n ` : ''}${imagePreloadTags ? `${imagePreloadTags}\n ` : ''}${fontPreloadTags ? `${fontPreloadTags}\n ` : ''}${libraryTags.headCSS ? `${libraryTags.headCSS}\n ` : ''}${libraryTags.headJS ? `${libraryTags.headJS}\n ` : ''}${rendered.meta}
|
|
665
|
+
${configInlineScript}${cmsInlineScript}${clientDataScripts}<style id="meno-styles"${nonceAttr}>${styleContent}</style>${mergedCustomCode.head ? `\n ${mergedCustomCode.head}` : ''}
|
|
631
666
|
</head>
|
|
632
|
-
<body>${mergedCustomCode.bodyStart ?
|
|
667
|
+
<body>${mergedCustomCode.bodyStart ? `\n ${mergedCustomCode.bodyStart}` : ''}
|
|
633
668
|
<div id="root">
|
|
634
669
|
${rendered.html}
|
|
635
670
|
</div>
|
|
636
|
-
${clientScript}${componentScript}${libraryTags.bodyEndJS ?
|
|
671
|
+
${clientScript}${componentScript}${libraryTags.bodyEndJS ? `\n ${libraryTags.bodyEndJS}` : ''}${liveReloadScript ? `\n ${liveReloadScript}` : ''}${scrollHandlerScript ? `\n ${scrollHandlerScript}` : ''}${mergedCustomCode.bodyEnd ? `\n ${mergedCustomCode.bodyEnd}` : ''}
|
|
637
672
|
</body>
|
|
638
673
|
</html>`;
|
|
639
674
|
|
|
@@ -641,7 +676,7 @@ picture {
|
|
|
641
676
|
if (returnSeparateJS) {
|
|
642
677
|
return {
|
|
643
678
|
html: htmlDocument,
|
|
644
|
-
javascript: externalJavaScript
|
|
679
|
+
javascript: externalJavaScript,
|
|
645
680
|
};
|
|
646
681
|
}
|
|
647
682
|
|
|
@@ -20,7 +20,9 @@ describe('extractImgSrc', () => {
|
|
|
20
20
|
});
|
|
21
21
|
|
|
22
22
|
describe('rewriteRichTextImages', () => {
|
|
23
|
-
function buildMap(
|
|
23
|
+
function buildMap(
|
|
24
|
+
entries: Record<string, { srcset: string; avifSrcset?: string; width?: number; height?: number }>,
|
|
25
|
+
): ImageMetadataMap {
|
|
24
26
|
const map = new Map() as ImageMetadataMap;
|
|
25
27
|
for (const [key, value] of Object.entries(entries)) {
|
|
26
28
|
map.set(key, value);
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { projectPaths } from '../projectContext';
|
|
7
|
-
import * as path from 'path';
|
|
7
|
+
import * as path from 'node:path';
|
|
8
8
|
import { escapeHtml } from './attributeBuilder';
|
|
9
9
|
import { readTextFile, fileExists } from '../runtime';
|
|
10
10
|
|
|
@@ -58,14 +58,17 @@ export async function buildImageMetadataMap(): Promise<ImageMetadataMap> {
|
|
|
58
58
|
const manifestContent = await readTextFile(manifestPath);
|
|
59
59
|
const manifest = JSON.parse(manifestContent) as {
|
|
60
60
|
version: number;
|
|
61
|
-
images: Record<
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
61
|
+
images: Record<
|
|
62
|
+
string,
|
|
63
|
+
{
|
|
64
|
+
filename: string;
|
|
65
|
+
width: number;
|
|
66
|
+
height: number;
|
|
67
|
+
blurHash: string;
|
|
68
|
+
formats: { avif: boolean; webp: boolean };
|
|
69
|
+
variants: { width: number; webpFilename: string; avifFilename: string }[];
|
|
70
|
+
}
|
|
71
|
+
>;
|
|
69
72
|
};
|
|
70
73
|
|
|
71
74
|
// Build metadata for each image
|
|
@@ -78,13 +81,9 @@ export async function buildImageMetadataMap(): Promise<ImageMetadataMap> {
|
|
|
78
81
|
|
|
79
82
|
// Add variants
|
|
80
83
|
for (const variant of entry.variants) {
|
|
81
|
-
webpSrcsetParts.push(
|
|
82
|
-
`/images/${encodeURIComponent(variant.webpFilename)} ${variant.width}w`
|
|
83
|
-
);
|
|
84
|
+
webpSrcsetParts.push(`/images/${encodeURIComponent(variant.webpFilename)} ${variant.width}w`);
|
|
84
85
|
if (variant.avifFilename) {
|
|
85
|
-
avifSrcsetParts.push(
|
|
86
|
-
`/images/${encodeURIComponent(variant.avifFilename)} ${variant.width}w`
|
|
87
|
-
);
|
|
86
|
+
avifSrcsetParts.push(`/images/${encodeURIComponent(variant.avifFilename)} ${variant.width}w`);
|
|
88
87
|
}
|
|
89
88
|
}
|
|
90
89
|
|
|
@@ -133,7 +132,7 @@ export async function buildImageMetadataMap(): Promise<ImageMetadataMap> {
|
|
|
133
132
|
*/
|
|
134
133
|
export function extractImgSrc(imgTag: string): string | null {
|
|
135
134
|
const match = imgTag.match(/src=["']([^"']+)["']/i);
|
|
136
|
-
return match ? match[1] : null;
|
|
135
|
+
return match ? (match[1] ?? null) : null;
|
|
137
136
|
}
|
|
138
137
|
|
|
139
138
|
/**
|
|
@@ -141,7 +140,11 @@ export function extractImgSrc(imgTag: string): string | null {
|
|
|
141
140
|
* Only rewrites images that exist in the metadata map (project images with generated variants).
|
|
142
141
|
* External/unrecognized images are left unchanged.
|
|
143
142
|
*/
|
|
144
|
-
export function rewriteRichTextImages(
|
|
143
|
+
export function rewriteRichTextImages(
|
|
144
|
+
html: string,
|
|
145
|
+
metadataMap: ImageMetadataMap,
|
|
146
|
+
imageFormat?: 'webp' | 'avif',
|
|
147
|
+
): string {
|
|
145
148
|
return html.replace(/<img\b([^>]*)\/?>/gi, (fullMatch, innerAttrs: string) => {
|
|
146
149
|
const src = extractImgSrc(fullMatch);
|
|
147
150
|
if (!src) return fullMatch;
|
|
@@ -166,17 +169,20 @@ export function rewriteRichTextImages(html: string, metadataMap: ImageMetadataMa
|
|
|
166
169
|
|
|
167
170
|
// Render as <picture> with AVIF + WebP sources when AVIF is available and format allows
|
|
168
171
|
if (metadata.avifSrcset && imageFormat !== 'webp') {
|
|
169
|
-
return
|
|
172
|
+
return (
|
|
173
|
+
`<picture>` +
|
|
170
174
|
`<source type="image/avif" srcset="${escapeHtml(metadata.avifSrcset)}" sizes="${escapeHtml(sizes)}" />` +
|
|
171
175
|
`<source type="image/webp" srcset="${escapeHtml(metadata.srcset)}" sizes="${escapeHtml(sizes)}" />` +
|
|
172
176
|
enhancedTag +
|
|
173
|
-
`</picture
|
|
177
|
+
`</picture>`
|
|
178
|
+
);
|
|
174
179
|
}
|
|
175
180
|
|
|
176
181
|
// WebP only: add srcset and sizes to existing <img>
|
|
177
182
|
if (metadata.srcset) {
|
|
178
|
-
enhancedTag = enhancedTag.replace(
|
|
179
|
-
|
|
183
|
+
enhancedTag = enhancedTag.replace(
|
|
184
|
+
/<img\b/i,
|
|
185
|
+
`<img srcset="${escapeHtml(metadata.srcset)}" sizes="${escapeHtml(sizes)}"`,
|
|
180
186
|
);
|
|
181
187
|
}
|
|
182
188
|
|
|
@@ -67,9 +67,9 @@ describe('jsCollector', () => {
|
|
|
67
67
|
|
|
68
68
|
const errors = getJSValidationErrors();
|
|
69
69
|
expect(errors).toHaveLength(1);
|
|
70
|
-
expect(errors[0]
|
|
71
|
-
expect(typeof errors[0]
|
|
72
|
-
expect(errors[0]
|
|
70
|
+
expect(errors[0]!.component).toBe('myBadComp');
|
|
71
|
+
expect(typeof errors[0]!.error).toBe('string');
|
|
72
|
+
expect(errors[0]!.error.length).toBeGreaterThan(0);
|
|
73
73
|
});
|
|
74
74
|
});
|
|
75
75
|
|
|
@@ -154,10 +154,7 @@ describe('jsCollector', () => {
|
|
|
154
154
|
const globalComp = makeComponent({ javascript: 'console.log("global");' });
|
|
155
155
|
const pageComp = makeComponent({ javascript: 'console.log("page");' });
|
|
156
156
|
|
|
157
|
-
const result = await collectComponentJavaScript(
|
|
158
|
-
{ header: globalComp },
|
|
159
|
-
{ footer: pageComp }
|
|
160
|
-
);
|
|
157
|
+
const result = await collectComponentJavaScript({ header: globalComp }, { footer: pageComp });
|
|
161
158
|
|
|
162
159
|
expect(result).toContain('// Component: header');
|
|
163
160
|
expect(result).toContain('console.log("global");');
|
|
@@ -169,10 +166,7 @@ describe('jsCollector', () => {
|
|
|
169
166
|
const globalComp = makeComponent({ javascript: 'console.log("global version");' });
|
|
170
167
|
const pageComp = makeComponent({ javascript: 'console.log("page version");' });
|
|
171
168
|
|
|
172
|
-
const result = await collectComponentJavaScript(
|
|
173
|
-
{ shared: globalComp },
|
|
174
|
-
{ shared: pageComp }
|
|
175
|
-
);
|
|
169
|
+
const result = await collectComponentJavaScript({ shared: globalComp }, { shared: pageComp });
|
|
176
170
|
|
|
177
171
|
expect(result).toContain('console.log("global version");');
|
|
178
172
|
expect(result).not.toContain('console.log("page version");');
|
|
@@ -187,11 +181,7 @@ describe('jsCollector', () => {
|
|
|
187
181
|
const badComp = makeComponent({ javascript: '%%%INVALID%%%' });
|
|
188
182
|
const goodComp = makeComponent({ javascript: 'console.log("valid");' });
|
|
189
183
|
|
|
190
|
-
const result = await collectComponentJavaScript(
|
|
191
|
-
{ bad: badComp, good: goodComp },
|
|
192
|
-
{},
|
|
193
|
-
onError
|
|
194
|
-
);
|
|
184
|
+
const result = await collectComponentJavaScript({ bad: badComp, good: goodComp }, {}, onError);
|
|
195
185
|
|
|
196
186
|
// The bad component should be skipped
|
|
197
187
|
expect(result).not.toContain('%%%INVALID%%%');
|
|
@@ -200,8 +190,8 @@ describe('jsCollector', () => {
|
|
|
200
190
|
|
|
201
191
|
// onError should have been called for the bad component
|
|
202
192
|
expect(errors).toHaveLength(1);
|
|
203
|
-
expect(errors[0]
|
|
204
|
-
expect(errors[0]
|
|
193
|
+
expect(errors[0]!.name).toBe('bad');
|
|
194
|
+
expect(errors[0]!.error.length).toBeGreaterThan(0);
|
|
205
195
|
});
|
|
206
196
|
|
|
207
197
|
test('should use validation cache on repeated calls for same component', async () => {
|
|
@@ -34,13 +34,8 @@ const DEFINE_VARS_RUNTIME = `(function() {
|
|
|
34
34
|
/**
|
|
35
35
|
* Generate destructure statement for defineVars
|
|
36
36
|
*/
|
|
37
|
-
function generateDestructure(
|
|
38
|
-
defineVars
|
|
39
|
-
interfaceDef?: Record<string, unknown>
|
|
40
|
-
): string {
|
|
41
|
-
const vars = defineVars === true
|
|
42
|
-
? Object.keys(interfaceDef || {})
|
|
43
|
-
: defineVars;
|
|
37
|
+
function generateDestructure(defineVars: true | string[], interfaceDef?: Record<string, unknown>): string {
|
|
38
|
+
const vars = defineVars === true ? Object.keys(interfaceDef || {}) : defineVars;
|
|
44
39
|
if (vars.length === 0) return '';
|
|
45
40
|
return `var {${vars.join(', ')}} = props;`;
|
|
46
41
|
}
|
|
@@ -89,7 +84,7 @@ export function getJSValidationErrors(): Array<{ component: string; error: strin
|
|
|
89
84
|
export async function collectComponentJavaScript(
|
|
90
85
|
globalComponents: Record<string, ComponentDefinition> = {},
|
|
91
86
|
pageComponents: Record<string, ComponentDefinition> = {},
|
|
92
|
-
onError?: JSErrorCallback
|
|
87
|
+
onError?: JSErrorCallback,
|
|
93
88
|
): Promise<string> {
|
|
94
89
|
const jsCodeBlocks: string[] = [];
|
|
95
90
|
let hasDefineVars = false;
|