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
|
@@ -5,19 +5,38 @@
|
|
|
5
5
|
* Security: Uses jsep for safe expression parsing instead of eval/new Function()
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import type {
|
|
8
|
+
import type {
|
|
9
|
+
StyleMapping,
|
|
10
|
+
HtmlMapping,
|
|
11
|
+
ComponentNode,
|
|
12
|
+
HtmlNode,
|
|
13
|
+
ComponentInstanceNode,
|
|
14
|
+
SlotMarker,
|
|
15
|
+
StyleObject,
|
|
16
|
+
ResponsiveStyleObject,
|
|
17
|
+
StyleValue,
|
|
18
|
+
TemplateContext,
|
|
19
|
+
} from '../shared/types';
|
|
9
20
|
import { isResponsiveStyle } from '../shared/styleUtils';
|
|
10
|
-
import { normalizeStyle as normalizeStyleShared
|
|
11
|
-
import { DEFAULT_BREAKPOINTS } from '../shared/breakpoints';
|
|
21
|
+
import { normalizeStyle as normalizeStyleShared } from '../shared/responsiveStyleUtils';
|
|
12
22
|
import { NODE_TYPE } from '../shared/constants';
|
|
13
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
isValidNodeType,
|
|
25
|
+
isComponentNode,
|
|
26
|
+
isHtmlNode,
|
|
27
|
+
isSlotMarker,
|
|
28
|
+
isEmbedNode,
|
|
29
|
+
isLocaleListNode,
|
|
30
|
+
isLinkNode,
|
|
31
|
+
isListNode,
|
|
32
|
+
} from '../shared/nodeUtils';
|
|
14
33
|
import { applyStylesToNode } from '../shared/styleNodeUtils';
|
|
15
34
|
import { isRichTextMarker, richTextMarkerToHtml } from '../shared/propResolver';
|
|
16
|
-
import { isTiptapDocument, tiptapToHtml } from '../shared/richtext';
|
|
17
35
|
import { hasItemTemplates } from '../shared/itemTemplateUtils';
|
|
18
36
|
import { safeEvaluate } from '../shared/expressionEvaluator';
|
|
19
37
|
import { RAW_HTML_PREFIX } from '../shared/constants';
|
|
20
38
|
import { getGlobalTemplateContext } from '../shared/globalTemplateContext';
|
|
39
|
+
import { logRuntimeError } from '../shared/errorLogger';
|
|
21
40
|
|
|
22
41
|
// Re-export for backward compatibility
|
|
23
42
|
export { isResponsiveStyle };
|
|
@@ -36,7 +55,7 @@ export function normalizeStyle(style: StyleValue | null | undefined): StyleObjec
|
|
|
36
55
|
*/
|
|
37
56
|
function addProcessedItemToArray(
|
|
38
57
|
item: ComponentNode | (ComponentNode | string)[] | string | number | Record<string, unknown> | null,
|
|
39
|
-
array: Array<ComponentNode | string
|
|
58
|
+
array: Array<ComponentNode | string>,
|
|
40
59
|
): void {
|
|
41
60
|
if (item === null) return;
|
|
42
61
|
|
|
@@ -66,7 +85,11 @@ export function isLinkMapping(value: unknown): value is LinkMapping {
|
|
|
66
85
|
if (!value || typeof value !== 'object') return false;
|
|
67
86
|
const obj = value as Record<string, unknown>;
|
|
68
87
|
// values is optional - when empty/missing, acts as passthrough for link-type props
|
|
69
|
-
return
|
|
88
|
+
return (
|
|
89
|
+
obj._mapping === true &&
|
|
90
|
+
typeof obj.prop === 'string' &&
|
|
91
|
+
(obj.values === undefined || typeof obj.values === 'object')
|
|
92
|
+
);
|
|
70
93
|
}
|
|
71
94
|
|
|
72
95
|
/**
|
|
@@ -95,7 +118,7 @@ export function isLinkMapping(value: unknown): value is LinkMapping {
|
|
|
95
118
|
*/
|
|
96
119
|
export function resolveLinkMapping(
|
|
97
120
|
mappingObj: unknown,
|
|
98
|
-
props: Record<string, unknown> | undefined
|
|
121
|
+
props: Record<string, unknown> | undefined,
|
|
99
122
|
): { href: string; target?: string } | undefined {
|
|
100
123
|
if (!isLinkMapping(mappingObj)) {
|
|
101
124
|
return undefined;
|
|
@@ -147,7 +170,7 @@ export function isHtmlMapping(value: unknown): value is HtmlMapping {
|
|
|
147
170
|
*/
|
|
148
171
|
export function resolveHtmlMapping(
|
|
149
172
|
mappingObj: unknown,
|
|
150
|
-
props: Record<string, unknown> | undefined
|
|
173
|
+
props: Record<string, unknown> | undefined,
|
|
151
174
|
): string | undefined {
|
|
152
175
|
if (!isHtmlMapping(mappingObj)) {
|
|
153
176
|
return undefined;
|
|
@@ -187,14 +210,14 @@ export function resolveHtmlMapping(
|
|
|
187
210
|
*/
|
|
188
211
|
export function resolveStyleMapping(
|
|
189
212
|
mappingObj: unknown,
|
|
190
|
-
props: Record<string, unknown> | undefined
|
|
213
|
+
props: Record<string, unknown> | undefined,
|
|
191
214
|
): string | number | undefined {
|
|
192
215
|
if (!mappingObj || typeof mappingObj !== 'object') {
|
|
193
216
|
return undefined;
|
|
194
217
|
}
|
|
195
218
|
|
|
196
219
|
const mapping = mappingObj as StyleMapping;
|
|
197
|
-
if (!mapping
|
|
220
|
+
if (!mapping?._mapping) {
|
|
198
221
|
return undefined;
|
|
199
222
|
}
|
|
200
223
|
|
|
@@ -227,7 +250,7 @@ export function resolveStyleMapping(
|
|
|
227
250
|
*/
|
|
228
251
|
function processStyleValue(
|
|
229
252
|
styleValue: unknown,
|
|
230
|
-
props: Record<string, unknown> | undefined
|
|
253
|
+
props: Record<string, unknown> | undefined,
|
|
231
254
|
): string | number | undefined {
|
|
232
255
|
// First try style mapping resolution
|
|
233
256
|
const resolved = resolveStyleMapping(styleValue, props);
|
|
@@ -259,10 +282,7 @@ function processStyleValue(
|
|
|
259
282
|
* @param includeItemContext - Whether to include itemContext from the context object
|
|
260
283
|
* @returns A flat object suitable for template evaluation
|
|
261
284
|
*/
|
|
262
|
-
function buildEvalContext(
|
|
263
|
-
context: TemplateContext,
|
|
264
|
-
includeItemContext: boolean = false
|
|
265
|
-
): Record<string, unknown> {
|
|
285
|
+
function buildEvalContext(context: TemplateContext, includeItemContext: boolean = false): Record<string, unknown> {
|
|
266
286
|
// Layer order (lowest → highest precedence): global → parent component
|
|
267
287
|
// props → this component's own props. The middle layer lets a `{{x}}` in
|
|
268
288
|
// a child component's structure cascade to the host's `x` when the child
|
|
@@ -270,7 +290,7 @@ function buildEvalContext(
|
|
|
270
290
|
const evalContext: Record<string, unknown> = {
|
|
271
291
|
...getGlobalTemplateContext(),
|
|
272
292
|
...(context.parentProps ?? {}),
|
|
273
|
-
...context.props
|
|
293
|
+
...context.props,
|
|
274
294
|
};
|
|
275
295
|
|
|
276
296
|
if (context.componentDef && typeof context.componentDef === 'object') {
|
|
@@ -306,30 +326,39 @@ const MAX_RECURSION_DEPTH = 100;
|
|
|
306
326
|
* evaluateTemplate("{{count + 1}}", { count: 5 }) // 6
|
|
307
327
|
* evaluateTemplate("{{undefinedVar}}", {}) // undefined (no error thrown)
|
|
308
328
|
*/
|
|
309
|
-
export function evaluateTemplate(
|
|
310
|
-
template: string,
|
|
311
|
-
context: Record<string, unknown>
|
|
312
|
-
): unknown {
|
|
329
|
+
export function evaluateTemplate(template: string, context: Record<string, unknown>): unknown {
|
|
313
330
|
if (typeof template !== 'string') return template;
|
|
314
331
|
|
|
315
332
|
const templateMatch = template.match(/^\{\{(.+)\}\}$/);
|
|
316
333
|
if (!templateMatch) return template;
|
|
317
334
|
|
|
318
|
-
const expression = templateMatch[1].trim();
|
|
335
|
+
const expression = (templateMatch[1] ?? '').trim();
|
|
319
336
|
|
|
320
337
|
// Security: Expression length limit to prevent DoS
|
|
321
338
|
if (expression.length > MAX_EXPRESSION_LENGTH) {
|
|
322
|
-
console.warn('Template expression too long:', expression.slice(0, 50)
|
|
339
|
+
console.warn('Template expression too long:', `${expression.slice(0, 50)}...`);
|
|
323
340
|
return template;
|
|
324
341
|
}
|
|
325
342
|
|
|
326
343
|
try {
|
|
327
344
|
// Use safe expression evaluator (jsep-based, no eval/new Function)
|
|
328
345
|
const result = safeEvaluate(expression, context);
|
|
329
|
-
//
|
|
330
|
-
|
|
346
|
+
// undefined (unknown identifier) AND NaN (arithmetic over an identifier that isn't
|
|
347
|
+
// in context — e.g. a loop-var stagger like {{0.4+itemIndex*0.2}} evaluated by the
|
|
348
|
+
// props pass before the per-item pass) both mean "can't resolve here": return the
|
|
349
|
+
// template string so a later pass (item/CMS context) can still resolve it, and so
|
|
350
|
+
// React never receives a NaN attribute/prop ("Received NaN for the `fade` attribute").
|
|
351
|
+
if (result === undefined || (typeof result === 'number' && Number.isNaN(result))) {
|
|
352
|
+
return template;
|
|
353
|
+
}
|
|
354
|
+
return result;
|
|
331
355
|
} catch (error) {
|
|
332
|
-
|
|
356
|
+
// Log the expression + context key names only — never the values, which
|
|
357
|
+
// carry props/CMS data. Dev-gated via logRuntimeError so production stays quiet.
|
|
358
|
+
logRuntimeError('templateEngine.evaluateTemplate', error, {
|
|
359
|
+
expression: expression.slice(0, 80),
|
|
360
|
+
contextKeys: context ? Object.keys(context) : [],
|
|
361
|
+
});
|
|
333
362
|
// Return original template string on error for backward compatibility
|
|
334
363
|
return template;
|
|
335
364
|
}
|
|
@@ -346,18 +375,15 @@ export function hasTemplates(code: string): boolean {
|
|
|
346
375
|
/**
|
|
347
376
|
* Processes template strings in JavaScript or CSS code
|
|
348
377
|
* Replaces {{propName}} or {{expression}} with evaluated values
|
|
349
|
-
*
|
|
378
|
+
*
|
|
350
379
|
* @example
|
|
351
380
|
* processCodeTemplates("console.log('{{name}}');", { name: "John" })
|
|
352
381
|
* // "console.log('John');"
|
|
353
|
-
*
|
|
382
|
+
*
|
|
354
383
|
* processCodeTemplates(".card { color: {{color}}; }", { color: "#ff0000" })
|
|
355
384
|
* // ".card { color: #ff0000; }"
|
|
356
385
|
*/
|
|
357
|
-
export function processCodeTemplates(
|
|
358
|
-
code: string,
|
|
359
|
-
context: Record<string, unknown> | undefined
|
|
360
|
-
): string {
|
|
386
|
+
export function processCodeTemplates(code: string, context: Record<string, unknown> | undefined): string {
|
|
361
387
|
if (typeof code !== 'string') return code;
|
|
362
388
|
|
|
363
389
|
// Guard against undefined context
|
|
@@ -371,7 +397,7 @@ export function processCodeTemplates(
|
|
|
371
397
|
|
|
372
398
|
// Security: Expression length limit to prevent DoS
|
|
373
399
|
if (trimmedExpr.length > MAX_EXPRESSION_LENGTH) {
|
|
374
|
-
console.warn('Code template expression too long:', trimmedExpr.slice(0, 50)
|
|
400
|
+
console.warn('Code template expression too long:', `${trimmedExpr.slice(0, 50)}...`);
|
|
375
401
|
return match;
|
|
376
402
|
}
|
|
377
403
|
|
|
@@ -396,7 +422,12 @@ export function processCodeTemplates(
|
|
|
396
422
|
// For objects/arrays, stringify them
|
|
397
423
|
return JSON.stringify(result);
|
|
398
424
|
} catch (error) {
|
|
399
|
-
|
|
425
|
+
// Log the expression + context key names only — never the values, which
|
|
426
|
+
// carry props/CMS data. Dev-gated via logRuntimeError so production stays quiet.
|
|
427
|
+
logRuntimeError('templateEngine.processCodeTemplates', error, {
|
|
428
|
+
expression: trimmedExpr.slice(0, 80),
|
|
429
|
+
contextKeys: context ? Object.keys(context) : [],
|
|
430
|
+
});
|
|
400
431
|
// Return original template if evaluation fails
|
|
401
432
|
return match;
|
|
402
433
|
}
|
|
@@ -417,12 +448,14 @@ export function processStructure(
|
|
|
417
448
|
viewportWidth?: number,
|
|
418
449
|
instanceChildren?: ComponentNode['children'],
|
|
419
450
|
preserveResponsiveStyles: boolean = false,
|
|
420
|
-
depth: number = 0
|
|
451
|
+
depth: number = 0,
|
|
421
452
|
): ComponentNode | (ComponentNode | string)[] | string | number | Record<string, unknown> | null {
|
|
422
453
|
try {
|
|
423
454
|
// Guard against excessive recursion (circular references or very deep structures)
|
|
424
455
|
if (depth > MAX_RECURSION_DEPTH) {
|
|
425
|
-
console.warn(
|
|
456
|
+
console.warn(
|
|
457
|
+
`processStructure: Maximum recursion depth (${MAX_RECURSION_DEPTH}) exceeded. Possible circular reference.`,
|
|
458
|
+
);
|
|
426
459
|
return null;
|
|
427
460
|
}
|
|
428
461
|
|
|
@@ -472,7 +505,7 @@ export function processStructure(
|
|
|
472
505
|
// No templates - return as-is
|
|
473
506
|
return structure;
|
|
474
507
|
}
|
|
475
|
-
|
|
508
|
+
|
|
476
509
|
if (Array.isArray(structure)) {
|
|
477
510
|
const processed: Array<ComponentNode | string> = [];
|
|
478
511
|
for (const item of structure) {
|
|
@@ -482,7 +515,14 @@ export function processStructure(
|
|
|
482
515
|
if (instanceChildren) {
|
|
483
516
|
const childrenArray = Array.isArray(instanceChildren) ? instanceChildren : [instanceChildren];
|
|
484
517
|
for (const child of childrenArray) {
|
|
485
|
-
const processedChild = processStructure(
|
|
518
|
+
const processedChild = processStructure(
|
|
519
|
+
child,
|
|
520
|
+
context,
|
|
521
|
+
viewportWidth,
|
|
522
|
+
instanceChildren,
|
|
523
|
+
preserveResponsiveStyles,
|
|
524
|
+
depth + 1,
|
|
525
|
+
);
|
|
486
526
|
addProcessedItemToArray(processedChild, processed);
|
|
487
527
|
}
|
|
488
528
|
} else if ('default' in item && (item as SlotMarker).default !== undefined) {
|
|
@@ -490,20 +530,34 @@ export function processStructure(
|
|
|
490
530
|
const defaultContent = (item as SlotMarker).default;
|
|
491
531
|
const defaultsArray = Array.isArray(defaultContent) ? defaultContent : [defaultContent];
|
|
492
532
|
for (const defaultChild of defaultsArray) {
|
|
493
|
-
const processedChild = processStructure(
|
|
533
|
+
const processedChild = processStructure(
|
|
534
|
+
defaultChild,
|
|
535
|
+
context,
|
|
536
|
+
viewportWidth,
|
|
537
|
+
undefined,
|
|
538
|
+
preserveResponsiveStyles,
|
|
539
|
+
depth + 1,
|
|
540
|
+
);
|
|
494
541
|
addProcessedItemToArray(processedChild, processed);
|
|
495
542
|
}
|
|
496
543
|
}
|
|
497
544
|
// If no instance children AND no default, marker renders nothing (skip it)
|
|
498
545
|
} else {
|
|
499
546
|
// Regular item - process normally
|
|
500
|
-
const processedItem = processStructure(
|
|
547
|
+
const processedItem = processStructure(
|
|
548
|
+
item,
|
|
549
|
+
context,
|
|
550
|
+
viewportWidth,
|
|
551
|
+
instanceChildren,
|
|
552
|
+
preserveResponsiveStyles,
|
|
553
|
+
depth + 1,
|
|
554
|
+
);
|
|
501
555
|
addProcessedItemToArray(processedItem, processed);
|
|
502
556
|
}
|
|
503
557
|
}
|
|
504
558
|
return processed;
|
|
505
559
|
}
|
|
506
|
-
|
|
560
|
+
|
|
507
561
|
if (typeof structure === 'object' && !Array.isArray(structure) && structure !== null) {
|
|
508
562
|
// Check if this is a slot marker (shouldn't happen here since we handle it in array processing, but guard anyway)
|
|
509
563
|
if (isSlotMarker(structure)) {
|
|
@@ -512,10 +566,17 @@ export function processStructure(
|
|
|
512
566
|
const processed: Array<ComponentNode | string> = [];
|
|
513
567
|
const childrenArray = Array.isArray(instanceChildren) ? instanceChildren : [instanceChildren];
|
|
514
568
|
for (const child of childrenArray) {
|
|
515
|
-
const processedChild = processStructure(
|
|
569
|
+
const processedChild = processStructure(
|
|
570
|
+
child,
|
|
571
|
+
context,
|
|
572
|
+
viewportWidth,
|
|
573
|
+
instanceChildren,
|
|
574
|
+
preserveResponsiveStyles,
|
|
575
|
+
depth + 1,
|
|
576
|
+
);
|
|
516
577
|
addProcessedItemToArray(processedChild, processed);
|
|
517
578
|
}
|
|
518
|
-
return processed.length === 1 ? processed[0] : processed;
|
|
579
|
+
return processed.length === 1 ? (processed[0] ?? processed) : processed;
|
|
519
580
|
}
|
|
520
581
|
// Fallback: use slot's default content
|
|
521
582
|
if ('default' in structure && (structure as SlotMarker).default !== undefined) {
|
|
@@ -523,14 +584,21 @@ export function processStructure(
|
|
|
523
584
|
const processed: Array<ComponentNode | string> = [];
|
|
524
585
|
const defaultsArray = Array.isArray(defaultContent) ? defaultContent : [defaultContent];
|
|
525
586
|
for (const defaultChild of defaultsArray) {
|
|
526
|
-
const processedChild = processStructure(
|
|
587
|
+
const processedChild = processStructure(
|
|
588
|
+
defaultChild,
|
|
589
|
+
context,
|
|
590
|
+
viewportWidth,
|
|
591
|
+
undefined,
|
|
592
|
+
preserveResponsiveStyles,
|
|
593
|
+
depth + 1,
|
|
594
|
+
);
|
|
527
595
|
addProcessedItemToArray(processedChild, processed);
|
|
528
596
|
}
|
|
529
|
-
return processed.length === 1 ? processed[0] : processed;
|
|
597
|
+
return processed.length === 1 ? (processed[0] ?? processed) : processed;
|
|
530
598
|
}
|
|
531
599
|
return null;
|
|
532
600
|
}
|
|
533
|
-
|
|
601
|
+
|
|
534
602
|
// Check if this is a valid node structure or a plain object (like props)
|
|
535
603
|
const inputNode = structure as ComponentNode;
|
|
536
604
|
const hasValidNodeType = inputNode.type && isValidNodeType(inputNode.type);
|
|
@@ -540,7 +608,14 @@ export function processStructure(
|
|
|
540
608
|
if (!hasValidNodeType) {
|
|
541
609
|
const result: Record<string, unknown> = {};
|
|
542
610
|
for (const [key, value] of Object.entries(structure)) {
|
|
543
|
-
const processedValue = processStructure(
|
|
611
|
+
const processedValue = processStructure(
|
|
612
|
+
value as ComponentNode | string | number | null,
|
|
613
|
+
context,
|
|
614
|
+
viewportWidth,
|
|
615
|
+
instanceChildren,
|
|
616
|
+
preserveResponsiveStyles,
|
|
617
|
+
depth + 1,
|
|
618
|
+
);
|
|
544
619
|
if (processedValue !== null && processedValue !== undefined) {
|
|
545
620
|
result[key] = processedValue;
|
|
546
621
|
}
|
|
@@ -557,7 +632,7 @@ export function processStructure(
|
|
|
557
632
|
type: NODE_TYPE.COMPONENT,
|
|
558
633
|
component: '',
|
|
559
634
|
props: {},
|
|
560
|
-
children: [] as Array<ComponentNode | string
|
|
635
|
+
children: [] as Array<ComponentNode | string>,
|
|
561
636
|
} as ComponentInstanceNode;
|
|
562
637
|
} else if (preservedType === NODE_TYPE.EMBED) {
|
|
563
638
|
// Handle embed nodes - they have html content, not children
|
|
@@ -570,7 +645,7 @@ export function processStructure(
|
|
|
570
645
|
processed = {
|
|
571
646
|
type: NODE_TYPE.LINK,
|
|
572
647
|
href: '',
|
|
573
|
-
children: [] as Array<ComponentNode | string
|
|
648
|
+
children: [] as Array<ComponentNode | string>,
|
|
574
649
|
} as unknown as ComponentNode;
|
|
575
650
|
} else if (preservedType === NODE_TYPE.LOCALE_LIST) {
|
|
576
651
|
// Handle locale-list nodes - they have style, itemStyle, activeItemStyle properties
|
|
@@ -583,23 +658,30 @@ export function processStructure(
|
|
|
583
658
|
processed = {
|
|
584
659
|
type: NODE_TYPE.LIST,
|
|
585
660
|
source: '',
|
|
586
|
-
children: [] as Array<ComponentNode | string
|
|
661
|
+
children: [] as Array<ComponentNode | string>,
|
|
587
662
|
} as unknown as ComponentNode;
|
|
588
663
|
} else {
|
|
589
664
|
processed = {
|
|
590
665
|
type: NODE_TYPE.NODE,
|
|
591
666
|
tag: 'div',
|
|
592
|
-
children: [] as Array<ComponentNode | string
|
|
667
|
+
children: [] as Array<ComponentNode | string>,
|
|
593
668
|
} as HtmlNode;
|
|
594
669
|
}
|
|
595
|
-
|
|
670
|
+
|
|
596
671
|
// First pass: process all keys and resolve style mappings
|
|
597
672
|
let resolvedStyle: StyleValue | null = null;
|
|
598
|
-
|
|
673
|
+
|
|
599
674
|
for (const [key, value] of Object.entries(structure)) {
|
|
600
675
|
try {
|
|
601
676
|
if (key === 'children') {
|
|
602
|
-
const processedChildren = processStructure(
|
|
677
|
+
const processedChildren = processStructure(
|
|
678
|
+
value as ComponentNode | ComponentNode[] | string | number | null | undefined,
|
|
679
|
+
context,
|
|
680
|
+
viewportWidth,
|
|
681
|
+
instanceChildren,
|
|
682
|
+
preserveResponsiveStyles,
|
|
683
|
+
depth + 1,
|
|
684
|
+
);
|
|
603
685
|
if (Array.isArray(processedChildren)) {
|
|
604
686
|
processed.children = processedChildren;
|
|
605
687
|
} else if (processedChildren !== null && processedChildren !== undefined) {
|
|
@@ -648,7 +730,11 @@ export function processStructure(
|
|
|
648
730
|
} else {
|
|
649
731
|
processed.html = value;
|
|
650
732
|
}
|
|
651
|
-
} else if (
|
|
733
|
+
} else if (
|
|
734
|
+
typeof value === 'object' &&
|
|
735
|
+
value !== null &&
|
|
736
|
+
(value as Record<string, unknown>)._mapping === true
|
|
737
|
+
) {
|
|
652
738
|
// HtmlMapping object that isHtmlMapping somehow missed — resolve it defensively
|
|
653
739
|
const resolved = resolveHtmlMapping(value, context.props);
|
|
654
740
|
processed.html = resolved ?? '';
|
|
@@ -668,7 +754,7 @@ export function processStructure(
|
|
|
668
754
|
component: '',
|
|
669
755
|
props: (p.props || {}) as ComponentInstanceNode['props'],
|
|
670
756
|
children: p.children as ComponentInstanceNode['children'],
|
|
671
|
-
style: p.style as ComponentInstanceNode['style']
|
|
757
|
+
style: p.style as ComponentInstanceNode['style'],
|
|
672
758
|
};
|
|
673
759
|
processed = newProcessed;
|
|
674
760
|
} else if (value === NODE_TYPE.NODE && !isHtmlNode(processed)) {
|
|
@@ -678,7 +764,7 @@ export function processStructure(
|
|
|
678
764
|
type: NODE_TYPE.NODE,
|
|
679
765
|
tag: (p.component as string) || 'div',
|
|
680
766
|
children: p.children as HtmlNode['children'],
|
|
681
|
-
style: p.style as HtmlNode['style']
|
|
767
|
+
style: p.style as HtmlNode['style'],
|
|
682
768
|
};
|
|
683
769
|
processed = newProcessed;
|
|
684
770
|
}
|
|
@@ -691,9 +777,9 @@ export function processStructure(
|
|
|
691
777
|
if (processedStyle && typeof processedStyle === 'object' && !Array.isArray(processedStyle)) {
|
|
692
778
|
// Check if it's a responsive style object
|
|
693
779
|
const styleEvalContext = buildEvalContext(context, false);
|
|
694
|
-
|
|
780
|
+
if (isResponsiveStyle(processedStyle as StyleValue)) {
|
|
695
781
|
// Preserve responsive styles (for both SSR and editor)
|
|
696
|
-
// responsiveStylesToClasses will generate prefixed classes (
|
|
782
|
+
// responsiveStylesToClasses will generate prefixed classes (tablet:, mobile:)
|
|
697
783
|
// CSS media queries will handle displaying the correct styles based on viewport
|
|
698
784
|
const resolvedResponsive: ResponsiveStyleObject = {};
|
|
699
785
|
for (const [bkeyName, bkeyValue] of Object.entries(processedStyle)) {
|
|
@@ -721,9 +807,21 @@ export function processStructure(
|
|
|
721
807
|
}
|
|
722
808
|
} else if (key === 'props' && typeof value === 'object' && value !== null) {
|
|
723
809
|
// Process non-style props (for instance props only)
|
|
724
|
-
const processedProps = processStructure(
|
|
810
|
+
const processedProps = processStructure(
|
|
811
|
+
value as ComponentNode | ComponentNode[] | string | number | null | undefined,
|
|
812
|
+
context,
|
|
813
|
+
viewportWidth,
|
|
814
|
+
instanceChildren,
|
|
815
|
+
preserveResponsiveStyles,
|
|
816
|
+
depth + 1,
|
|
817
|
+
);
|
|
725
818
|
// Merge non-style props (style is handled separately at top level)
|
|
726
|
-
if (
|
|
819
|
+
if (
|
|
820
|
+
typeof processedProps === 'object' &&
|
|
821
|
+
!Array.isArray(processedProps) &&
|
|
822
|
+
processedProps !== null &&
|
|
823
|
+
processed.props
|
|
824
|
+
) {
|
|
727
825
|
const propsObj = processedProps as unknown as Record<string, unknown>;
|
|
728
826
|
Object.assign(processed.props, propsObj);
|
|
729
827
|
// Remove style from props since we handle it at top level
|
|
@@ -744,7 +842,7 @@ export function processStructure(
|
|
|
744
842
|
if (resolved.target) {
|
|
745
843
|
pLink.attributes = {
|
|
746
844
|
...((pLink.attributes as Record<string, unknown>) || {}),
|
|
747
|
-
target: resolved.target
|
|
845
|
+
target: resolved.target,
|
|
748
846
|
};
|
|
749
847
|
}
|
|
750
848
|
} else {
|
|
@@ -752,13 +850,24 @@ export function processStructure(
|
|
|
752
850
|
}
|
|
753
851
|
} else {
|
|
754
852
|
// Regular href value - process as template
|
|
755
|
-
const processedValue = processStructure(
|
|
853
|
+
const processedValue = processStructure(
|
|
854
|
+
value as ComponentNode | ComponentNode[] | string | number | null | undefined,
|
|
855
|
+
context,
|
|
856
|
+
viewportWidth,
|
|
857
|
+
instanceChildren,
|
|
858
|
+
preserveResponsiveStyles,
|
|
859
|
+
depth + 1,
|
|
860
|
+
);
|
|
756
861
|
if (processedValue !== null && processedValue !== undefined) {
|
|
757
862
|
// Check if result is a link object (from link-type prop like {{link}})
|
|
758
863
|
if (typeof processedValue === 'object' && processedValue !== null && 'href' in processedValue) {
|
|
759
864
|
// Unwrap nested link objects (e.g., {href: {href: "/path"}} from double-wrapped list item templates)
|
|
760
865
|
let linkObj = processedValue as { href: unknown; target?: string };
|
|
761
|
-
while (
|
|
866
|
+
while (
|
|
867
|
+
typeof linkObj.href === 'object' &&
|
|
868
|
+
linkObj.href !== null &&
|
|
869
|
+
'href' in (linkObj.href as Record<string, unknown>)
|
|
870
|
+
) {
|
|
762
871
|
const nested = linkObj.href as { href: unknown; target?: string };
|
|
763
872
|
if (!linkObj.target && nested.target) linkObj = { ...linkObj, target: nested.target };
|
|
764
873
|
linkObj = { ...linkObj, href: nested.href };
|
|
@@ -767,7 +876,7 @@ export function processStructure(
|
|
|
767
876
|
if (linkObj.target) {
|
|
768
877
|
pLink.attributes = {
|
|
769
878
|
...((pLink.attributes as Record<string, unknown>) || {}),
|
|
770
|
-
target: linkObj.target
|
|
879
|
+
target: linkObj.target,
|
|
771
880
|
};
|
|
772
881
|
}
|
|
773
882
|
} else {
|
|
@@ -819,15 +928,31 @@ export function processStructure(
|
|
|
819
928
|
context.props &&
|
|
820
929
|
Array.isArray((context.props as Record<string, unknown>)[value])
|
|
821
930
|
) {
|
|
822
|
-
(processed as unknown as Record<string, unknown>).source = (context.props as Record<string, unknown>)[
|
|
931
|
+
(processed as unknown as Record<string, unknown>).source = (context.props as Record<string, unknown>)[
|
|
932
|
+
value
|
|
933
|
+
];
|
|
823
934
|
} else {
|
|
824
|
-
const processedValue = processStructure(
|
|
935
|
+
const processedValue = processStructure(
|
|
936
|
+
value as ComponentNode | ComponentNode[] | string | number | null | undefined,
|
|
937
|
+
context,
|
|
938
|
+
viewportWidth,
|
|
939
|
+
instanceChildren,
|
|
940
|
+
preserveResponsiveStyles,
|
|
941
|
+
depth + 1,
|
|
942
|
+
);
|
|
825
943
|
if (processedValue !== null && processedValue !== undefined) {
|
|
826
944
|
(processed as unknown as Record<string, unknown>).source = processedValue;
|
|
827
945
|
}
|
|
828
946
|
}
|
|
829
947
|
} else if (key !== 'type' && key !== 'children' && key !== 'style' && key !== 'props') {
|
|
830
|
-
const processedValue = processStructure(
|
|
948
|
+
const processedValue = processStructure(
|
|
949
|
+
value as ComponentNode | ComponentNode[] | string | number | null | undefined,
|
|
950
|
+
context,
|
|
951
|
+
viewportWidth,
|
|
952
|
+
instanceChildren,
|
|
953
|
+
preserveResponsiveStyles,
|
|
954
|
+
depth + 1,
|
|
955
|
+
);
|
|
831
956
|
// Only assign if it's a valid value
|
|
832
957
|
if (processedValue !== null && processedValue !== undefined) {
|
|
833
958
|
// Store extra properties on the node object
|
|
@@ -839,7 +964,7 @@ export function processStructure(
|
|
|
839
964
|
// Continue processing other keys
|
|
840
965
|
}
|
|
841
966
|
}
|
|
842
|
-
|
|
967
|
+
|
|
843
968
|
// Apply resolved styles to the processed node based on its type
|
|
844
969
|
// Both SSR and Editor now preserve responsive styles for proper utility class generation
|
|
845
970
|
if (resolvedStyle && Object.keys(resolvedStyle).length > 0) {
|
|
@@ -847,7 +972,13 @@ export function processStructure(
|
|
|
847
972
|
// Apply responsive styles directly to node.style or props.style
|
|
848
973
|
if (isComponentNode(processed)) {
|
|
849
974
|
(processed as unknown as Record<string, unknown>).style = resolvedStyle as ResponsiveStyleObject;
|
|
850
|
-
} else if (
|
|
975
|
+
} else if (
|
|
976
|
+
isHtmlNode(processed) ||
|
|
977
|
+
isEmbedNode(processed) ||
|
|
978
|
+
isLocaleListNode(processed) ||
|
|
979
|
+
isLinkNode(processed) ||
|
|
980
|
+
isListNode(processed)
|
|
981
|
+
) {
|
|
851
982
|
processed.style = resolvedStyle as ResponsiveStyleObject;
|
|
852
983
|
}
|
|
853
984
|
} else {
|
|
@@ -855,14 +986,13 @@ export function processStructure(
|
|
|
855
986
|
applyStylesToNode(processed, resolvedStyle);
|
|
856
987
|
}
|
|
857
988
|
}
|
|
858
|
-
|
|
989
|
+
|
|
859
990
|
return processed;
|
|
860
991
|
}
|
|
861
|
-
|
|
992
|
+
|
|
862
993
|
return structure;
|
|
863
994
|
} catch (error) {
|
|
864
995
|
console.error('Error in processStructure:', error);
|
|
865
996
|
throw error; // Re-throw so it can be caught by error boundary
|
|
866
997
|
}
|
|
867
998
|
}
|
|
868
|
-
|
package/lib/client/theme.test.ts
CHANGED
package/lib/client/theme.ts
CHANGED
|
@@ -15,10 +15,14 @@ beforeAll(async () => {
|
|
|
15
15
|
ctx = await createTestServer({
|
|
16
16
|
pages: {
|
|
17
17
|
'/': TEST_PAGE_JSON,
|
|
18
|
-
'/about': JSON.stringify(
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
'/about': JSON.stringify(
|
|
19
|
+
{
|
|
20
|
+
meta: { title: 'About', description: 'About page' },
|
|
21
|
+
root: { type: 'node', tag: 'div', children: 'About content' },
|
|
22
|
+
},
|
|
23
|
+
null,
|
|
24
|
+
2,
|
|
25
|
+
),
|
|
22
26
|
},
|
|
23
27
|
components,
|
|
24
28
|
});
|
|
@@ -40,10 +40,7 @@ beforeAll(async () => {
|
|
|
40
40
|
setProjectRoot(tempProject.projectDir);
|
|
41
41
|
|
|
42
42
|
// Create CMS provider and service with real file system
|
|
43
|
-
const cmsProvider = new FileSystemCMSProvider(
|
|
44
|
-
`${tempProject.projectDir}/templates`,
|
|
45
|
-
`${tempProject.projectDir}/cms`
|
|
46
|
-
);
|
|
43
|
+
const cmsProvider = new FileSystemCMSProvider(`${tempProject.projectDir}/templates`, `${tempProject.projectDir}/cms`);
|
|
47
44
|
const cmsService = new CMSService(cmsProvider);
|
|
48
45
|
await cmsService.initialize();
|
|
49
46
|
|