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
|
@@ -3,25 +3,29 @@
|
|
|
3
3
|
* Handles rendering of locale/language switcher nodes
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { createElement as h } from
|
|
7
|
-
import type { ReactElement } from
|
|
8
|
-
import type { LocaleListNode, StyleObject, ResponsiveStyleObject, InteractiveStyles } from
|
|
9
|
-
import { extractAttributesFromNode } from
|
|
10
|
-
import { responsiveStylesToClasses } from
|
|
11
|
-
import { getCachedResponsiveScalesConfig } from
|
|
12
|
-
import { pathToString } from
|
|
13
|
-
import { generateElementClassName, type ElementClassContext } from
|
|
14
|
-
import { InteractiveStylesRegistry } from
|
|
15
|
-
import {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
6
|
+
import { createElement as h } from 'react';
|
|
7
|
+
import type { ReactElement } from 'react';
|
|
8
|
+
import type { LocaleListNode, StyleObject, ResponsiveStyleObject, InteractiveStyles } from '../../../shared/types';
|
|
9
|
+
import { extractAttributesFromNode } from '../../../shared/attributeNodeUtils';
|
|
10
|
+
import { responsiveStylesToClasses } from '../../../shared/utilityClassMapper';
|
|
11
|
+
import { getCachedResponsiveScalesConfig } from '../../responsiveStyleResolver';
|
|
12
|
+
import { pathToString } from '../../../shared/pathArrayUtils';
|
|
13
|
+
import { generateElementClassName, type ElementClassContext } from '../../../shared/elementClassName';
|
|
14
|
+
import { InteractiveStylesRegistry } from '../../InteractiveStylesRegistry';
|
|
15
|
+
import {
|
|
16
|
+
hasInteractiveStyleMappings,
|
|
17
|
+
extractInteractiveStyleMappings,
|
|
18
|
+
resolveExtractedMappings,
|
|
19
|
+
} from '../../../shared/interactiveStyleMappings';
|
|
20
|
+
import { UtilityClassCollector } from '../../styles/UtilityClassCollector';
|
|
21
|
+
import type { ElementRegistry } from '../../elementRegistry';
|
|
22
|
+
import type { BuilderContext } from './types';
|
|
19
23
|
|
|
20
24
|
export interface LocaleListBuilderDeps {
|
|
21
25
|
elementRegistry: ElementRegistry;
|
|
22
26
|
getEffectiveParentComponentName: (
|
|
23
27
|
componentContext: string | null,
|
|
24
|
-
parentComponentName: string | null
|
|
28
|
+
parentComponentName: string | null,
|
|
25
29
|
) => string | null;
|
|
26
30
|
/** Optional getter for current page name (for interactive styles class generation) */
|
|
27
31
|
getCurrentPageName?: () => string;
|
|
@@ -32,14 +36,16 @@ export interface LocaleListBuilderDeps {
|
|
|
32
36
|
/**
|
|
33
37
|
* Build a locale list node (language switcher)
|
|
34
38
|
*/
|
|
35
|
-
export function buildLocaleList(
|
|
36
|
-
node: LocaleListNode,
|
|
37
|
-
ctx: BuilderContext,
|
|
38
|
-
deps: LocaleListBuilderDeps
|
|
39
|
-
): ReactElement {
|
|
39
|
+
export function buildLocaleList(node: LocaleListNode, ctx: BuilderContext, deps: LocaleListBuilderDeps): ReactElement {
|
|
40
40
|
const {
|
|
41
|
-
key,
|
|
42
|
-
|
|
41
|
+
key,
|
|
42
|
+
elementPath,
|
|
43
|
+
parentComponentName,
|
|
44
|
+
componentContext,
|
|
45
|
+
componentRootPath,
|
|
46
|
+
locale,
|
|
47
|
+
i18nConfig,
|
|
48
|
+
cmsItemIndexPath,
|
|
43
49
|
} = ctx;
|
|
44
50
|
|
|
45
51
|
const effectiveParentComponentName = deps.getEffectiveParentComponentName(componentContext, parentComponentName);
|
|
@@ -48,7 +54,7 @@ export function buildLocaleList(
|
|
|
48
54
|
const extractedAttributes = extractAttributesFromNode(node as any);
|
|
49
55
|
|
|
50
56
|
// Build locale list props
|
|
51
|
-
const localeListProps: Record<string,
|
|
57
|
+
const localeListProps: Record<string, unknown> = {
|
|
52
58
|
key,
|
|
53
59
|
'data-element-path': pathToString(elementPath),
|
|
54
60
|
'data-locale-list': 'true',
|
|
@@ -63,7 +69,7 @@ export function buildLocaleList(
|
|
|
63
69
|
}
|
|
64
70
|
}
|
|
65
71
|
}
|
|
66
|
-
}
|
|
72
|
+
},
|
|
67
73
|
};
|
|
68
74
|
|
|
69
75
|
// Add CMS item index path for elements inside CMS lists
|
|
@@ -72,7 +78,7 @@ export function buildLocaleList(
|
|
|
72
78
|
}
|
|
73
79
|
|
|
74
80
|
// Start building className
|
|
75
|
-
|
|
81
|
+
const classNames: string[] = [];
|
|
76
82
|
|
|
77
83
|
// Resolve fluid mode once for all conversions in this builder
|
|
78
84
|
const scales = getCachedResponsiveScalesConfig();
|
|
@@ -80,10 +86,10 @@ export function buildLocaleList(
|
|
|
80
86
|
|
|
81
87
|
// Convert container styles to utility classes
|
|
82
88
|
if (node.style) {
|
|
83
|
-
const utilityClasses = responsiveStylesToClasses(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
);
|
|
89
|
+
const utilityClasses = responsiveStylesToClasses(node.style as StyleObject | ResponsiveStyleObject, {
|
|
90
|
+
fluidActive,
|
|
91
|
+
responsiveScales: scales ?? undefined,
|
|
92
|
+
});
|
|
87
93
|
UtilityClassCollector.collect(utilityClasses);
|
|
88
94
|
classNames.push(...utilityClasses);
|
|
89
95
|
}
|
|
@@ -96,11 +102,10 @@ export function buildLocaleList(
|
|
|
96
102
|
if ((nodeInteractiveStyles && nodeInteractiveStyles.length > 0) || nodeGenerateElementClass) {
|
|
97
103
|
// Determine file type and name for element class generation
|
|
98
104
|
const useComponentContext = Boolean(componentContext);
|
|
99
|
-
const fileType = useComponentContext ? 'component' :
|
|
100
|
-
const fileName = useComponentContext ? componentContext! :
|
|
101
|
-
const pathForClass =
|
|
102
|
-
? elementPath.slice(componentRootPath.length)
|
|
103
|
-
: elementPath;
|
|
105
|
+
const fileType = useComponentContext ? 'component' : deps.getCurrentFileType?.() || 'page';
|
|
106
|
+
const fileName = useComponentContext ? componentContext! : deps.getCurrentPageName?.() || 'page';
|
|
107
|
+
const pathForClass =
|
|
108
|
+
useComponentContext && componentRootPath ? elementPath.slice(componentRootPath.length) : elementPath;
|
|
104
109
|
|
|
105
110
|
const elementClassCtx: ElementClassContext = {
|
|
106
111
|
fileType,
|
|
@@ -131,10 +136,10 @@ export function buildLocaleList(
|
|
|
131
136
|
const previewClasses: string[] = [];
|
|
132
137
|
for (const rule of nodeInteractiveStyles) {
|
|
133
138
|
if (rule.previewProp && ctx.componentResolvedProps[rule.previewProp] === true) {
|
|
134
|
-
const styleClasses = responsiveStylesToClasses(
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
);
|
|
139
|
+
const styleClasses = responsiveStylesToClasses(rule.style as StyleObject | ResponsiveStyleObject, {
|
|
140
|
+
fluidActive,
|
|
141
|
+
responsiveScales: scales ?? undefined,
|
|
142
|
+
});
|
|
138
143
|
UtilityClassCollector.collect(styleClasses);
|
|
139
144
|
previewClasses.push(...styleClasses);
|
|
140
145
|
}
|
|
@@ -151,9 +156,9 @@ export function buildLocaleList(
|
|
|
151
156
|
// would be spread onto the React element below and override the className that
|
|
152
157
|
// holds the utility classes derived from node.style.
|
|
153
158
|
if ('class' in extractedAttributes || 'className' in extractedAttributes) {
|
|
154
|
-
const attrClass = ((extractedAttributes as Record<string, unknown>).class
|
|
155
|
-
|
|
156
|
-
|
|
159
|
+
const attrClass = ((extractedAttributes as Record<string, unknown>).class ??
|
|
160
|
+
(extractedAttributes as Record<string, unknown>).className ??
|
|
161
|
+
'') as string;
|
|
157
162
|
if (attrClass) {
|
|
158
163
|
classNames.push(...attrClass.split(/\s+/));
|
|
159
164
|
}
|
|
@@ -188,10 +193,30 @@ export function buildLocaleList(
|
|
|
188
193
|
const currentLocaleCode = locale || i18nConfig?.defaultLocale || 'en';
|
|
189
194
|
|
|
190
195
|
// Convert item styles, active item styles, separator styles, and flag styles to utility classes
|
|
191
|
-
const itemClasses = node.itemStyle
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
196
|
+
const itemClasses = node.itemStyle
|
|
197
|
+
? responsiveStylesToClasses(node.itemStyle as StyleObject | ResponsiveStyleObject, {
|
|
198
|
+
fluidActive,
|
|
199
|
+
responsiveScales: scales ?? undefined,
|
|
200
|
+
})
|
|
201
|
+
: [];
|
|
202
|
+
const activeItemClasses = node.activeItemStyle
|
|
203
|
+
? responsiveStylesToClasses(node.activeItemStyle as StyleObject | ResponsiveStyleObject, {
|
|
204
|
+
fluidActive,
|
|
205
|
+
responsiveScales: scales ?? undefined,
|
|
206
|
+
})
|
|
207
|
+
: [];
|
|
208
|
+
const separatorClasses = node.separatorStyle
|
|
209
|
+
? responsiveStylesToClasses(node.separatorStyle as StyleObject | ResponsiveStyleObject, {
|
|
210
|
+
fluidActive,
|
|
211
|
+
responsiveScales: scales ?? undefined,
|
|
212
|
+
})
|
|
213
|
+
: [];
|
|
214
|
+
const flagClasses = node.flagStyle
|
|
215
|
+
? responsiveStylesToClasses(node.flagStyle as StyleObject | ResponsiveStyleObject, {
|
|
216
|
+
fluidActive,
|
|
217
|
+
responsiveScales: scales ?? undefined,
|
|
218
|
+
})
|
|
219
|
+
: [];
|
|
195
220
|
UtilityClassCollector.collect(itemClasses);
|
|
196
221
|
UtilityClassCollector.collect(activeItemClasses);
|
|
197
222
|
UtilityClassCollector.collect(separatorClasses);
|
|
@@ -201,26 +226,31 @@ export function buildLocaleList(
|
|
|
201
226
|
const linkElements: ReactElement[] = [];
|
|
202
227
|
for (let i = 0; i < configLocales.length; i++) {
|
|
203
228
|
const localeConfig = configLocales[i];
|
|
229
|
+
if (!localeConfig) continue;
|
|
204
230
|
const isCurrent = localeConfig.code === currentLocaleCode;
|
|
205
231
|
if (!showCurrent && isCurrent) continue;
|
|
206
232
|
|
|
207
233
|
// Add separator between links (empty span styled via separatorStyle)
|
|
208
234
|
if (showSeparator && linkElements.length > 0) {
|
|
209
|
-
linkElements.push(
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
235
|
+
linkElements.push(
|
|
236
|
+
h('span', {
|
|
237
|
+
key: `sep-${i}`,
|
|
238
|
+
className: separatorClasses.length > 0 ? separatorClasses.join(' ') : undefined,
|
|
239
|
+
}),
|
|
240
|
+
);
|
|
213
241
|
}
|
|
214
242
|
|
|
215
243
|
// Build link element content - flag icon (if enabled and exists) + nativeName in span
|
|
216
244
|
const linkContent: (ReactElement | string)[] = [];
|
|
217
245
|
if (showFlag && localeConfig.icon) {
|
|
218
|
-
linkContent.push(
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
246
|
+
linkContent.push(
|
|
247
|
+
h('img', {
|
|
248
|
+
key: 'flag',
|
|
249
|
+
src: localeConfig.icon,
|
|
250
|
+
alt: `${localeConfig.name} flag`,
|
|
251
|
+
className: flagClasses.length > 0 ? flagClasses.join(' ') : undefined,
|
|
252
|
+
}),
|
|
253
|
+
);
|
|
224
254
|
}
|
|
225
255
|
// Get display text based on displayType (mirrors SSR logic)
|
|
226
256
|
const displayType = node.displayType || 'nativeName';
|
|
@@ -232,7 +262,6 @@ export function buildLocaleList(
|
|
|
232
262
|
case 'name':
|
|
233
263
|
displayText = localeConfig.name;
|
|
234
264
|
break;
|
|
235
|
-
case 'nativeName':
|
|
236
265
|
default:
|
|
237
266
|
displayText = localeConfig.nativeName;
|
|
238
267
|
break;
|
|
@@ -241,13 +270,19 @@ export function buildLocaleList(
|
|
|
241
270
|
|
|
242
271
|
// Current item gets both itemClasses + activeItemClasses (additive/override)
|
|
243
272
|
const linkClasses = isCurrent ? [...itemClasses, ...activeItemClasses] : itemClasses;
|
|
244
|
-
linkElements.push(
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
273
|
+
linkElements.push(
|
|
274
|
+
h(
|
|
275
|
+
'div',
|
|
276
|
+
{
|
|
277
|
+
key: `locale-${localeConfig.code}`,
|
|
278
|
+
'data-current': isCurrent ? 'true' : 'false',
|
|
279
|
+
'data-locale': localeConfig.code,
|
|
280
|
+
className: linkClasses.length > 0 ? linkClasses.join(' ') : undefined,
|
|
281
|
+
style: { cursor: 'pointer' },
|
|
282
|
+
},
|
|
283
|
+
...linkContent,
|
|
284
|
+
),
|
|
285
|
+
);
|
|
251
286
|
}
|
|
252
287
|
|
|
253
288
|
return h('div', localeListProps, linkElements);
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
* Shared types for ComponentBuilder modules
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import type { ReactElement } from
|
|
6
|
-
import type { ComponentNode } from
|
|
7
|
-
import type { Path } from
|
|
8
|
-
import type { I18nConfig } from
|
|
9
|
-
import type { CMSItem, ItemContext, TemplateContext } from
|
|
5
|
+
import type { ReactElement } from 'react';
|
|
6
|
+
import type { ComponentNode } from '../../../shared/types';
|
|
7
|
+
import type { Path } from '../../../shared/pathArrayUtils';
|
|
8
|
+
import type { I18nConfig } from '../../../shared/types/components';
|
|
9
|
+
import type { CMSItem, ItemContext, TemplateContext } from '../../../shared/types/cms';
|
|
10
10
|
|
|
11
11
|
export type ComponentProps = Record<string, unknown>;
|
|
12
12
|
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
|
|
8
8
|
import type { I18nValue, I18nConfig } from '../../shared/types';
|
|
9
9
|
import { getI18nConfig } from '../i18nConfigService';
|
|
10
|
-
import { isRichTextMarker, richTextMarkerToHtml } from '../../shared/propResolver';
|
|
11
10
|
import { tiptapToHtml } from '../../shared/richtext/tiptapToHtml';
|
|
12
11
|
import { isTiptapDocument } from '../../shared/richtext/types';
|
|
13
12
|
import { RAW_HTML_PREFIX } from '../../shared/constants';
|
|
@@ -60,15 +59,11 @@ function resolveI18nValue(value: I18nValue, locale: string, config: I18nConfig):
|
|
|
60
59
|
* @param locale - Optional locale for i18n resolution (defaults to config's defaultLocale)
|
|
61
60
|
* @returns Processed string with values filled in
|
|
62
61
|
*/
|
|
63
|
-
export function processCMSTemplate(
|
|
64
|
-
template: string,
|
|
65
|
-
cmsItem: Record<string, unknown>,
|
|
66
|
-
locale?: string
|
|
67
|
-
): string {
|
|
62
|
+
export function processCMSTemplate(template: string, cmsItem: Record<string, unknown>, locale?: string): string {
|
|
68
63
|
const config = getI18nConfig();
|
|
69
64
|
const effectiveLocale = locale || config.defaultLocale;
|
|
70
65
|
|
|
71
|
-
return template.replace(/\{\{cms\.([^}]+)\}\}/g, (
|
|
66
|
+
return template.replace(/\{\{cms\.([^}]+)\}\}/g, (_match, fieldPath) => {
|
|
72
67
|
// Support nested paths like cms.author.name
|
|
73
68
|
const parts = fieldPath.trim().split('.');
|
|
74
69
|
let value: unknown = cmsItem;
|
|
@@ -94,7 +89,11 @@ export function processCMSTemplate(
|
|
|
94
89
|
}
|
|
95
90
|
// Handle rich-text markers - extract HTML content for interpolation
|
|
96
91
|
// Mark with RAW_HTML_PREFIX so renderer knows not to escape
|
|
97
|
-
if (
|
|
92
|
+
if (
|
|
93
|
+
typeof value === 'object' &&
|
|
94
|
+
'__richtext__' in value &&
|
|
95
|
+
typeof (value as unknown as { html: string }).html === 'string'
|
|
96
|
+
) {
|
|
98
97
|
return RAW_HTML_PREFIX + (value as unknown as { html: string }).html;
|
|
99
98
|
}
|
|
100
99
|
// Handle raw TipTap documents (fallback if not preprocessed)
|
|
@@ -118,7 +117,7 @@ export function processCMSTemplate(
|
|
|
118
117
|
export function processCMSPropsTemplate(
|
|
119
118
|
props: Record<string, unknown>,
|
|
120
119
|
cmsItem: Record<string, unknown>,
|
|
121
|
-
locale?: string
|
|
120
|
+
locale?: string,
|
|
122
121
|
): Record<string, unknown> {
|
|
123
122
|
const result: Record<string, unknown> = {};
|
|
124
123
|
|
|
@@ -27,7 +27,7 @@ export class ElementRegistry {
|
|
|
27
27
|
_componentName?: string | null,
|
|
28
28
|
_isComponentRoot?: boolean,
|
|
29
29
|
_props?: Record<string, unknown>,
|
|
30
|
-
_metadata?: Partial<ElementMetadata
|
|
30
|
+
_metadata?: Partial<ElementMetadata>,
|
|
31
31
|
): void {
|
|
32
32
|
// No-op in core - element tracking is editor-only
|
|
33
33
|
}
|
|
@@ -81,7 +81,7 @@ export class ElementRegistry {
|
|
|
81
81
|
_path: Path | string,
|
|
82
82
|
_itemIndex: number,
|
|
83
83
|
_element: HTMLElement | null,
|
|
84
|
-
_metadata?: Partial<ElementMetadata
|
|
84
|
+
_metadata?: Partial<ElementMetadata>,
|
|
85
85
|
): void {
|
|
86
86
|
// No-op in core - element tracking is editor-only
|
|
87
87
|
}
|
|
@@ -105,7 +105,7 @@ let _elementRegistry: ElementRegistry = new ElementRegistry();
|
|
|
105
105
|
export const elementRegistry: ElementRegistry = new Proxy({} as ElementRegistry, {
|
|
106
106
|
get(_target, prop) {
|
|
107
107
|
return (_elementRegistry as any)[prop];
|
|
108
|
-
}
|
|
108
|
+
},
|
|
109
109
|
});
|
|
110
110
|
|
|
111
111
|
/**
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import { describe, test, expect, beforeEach, afterEach, mock } from 'bun:test';
|
|
2
|
-
import {
|
|
3
|
-
fetchFontFamilies,
|
|
4
|
-
getCachedFontFamilies,
|
|
5
|
-
invalidateFontFamilies,
|
|
6
|
-
} from './fontFamiliesService';
|
|
2
|
+
import { fetchFontFamilies, getCachedFontFamilies, invalidateFontFamilies } from './fontFamiliesService';
|
|
7
3
|
|
|
8
4
|
const realFetch = globalThis.fetch;
|
|
9
5
|
|
|
@@ -36,11 +32,7 @@ describe('fontFamiliesService', () => {
|
|
|
36
32
|
|
|
37
33
|
test('fetchFontFamilies dedupes families that repeat across weights/unicode-ranges', async () => {
|
|
38
34
|
mockFetchOnce({
|
|
39
|
-
fonts: [
|
|
40
|
-
{ family: 'Fraunces', weight: 400 },
|
|
41
|
-
{ family: 'Fraunces', weight: 700 },
|
|
42
|
-
{ family: 'Inter' },
|
|
43
|
-
],
|
|
35
|
+
fonts: [{ family: 'Fraunces', weight: 400 }, { family: 'Fraunces', weight: 700 }, { family: 'Inter' }],
|
|
44
36
|
});
|
|
45
37
|
const families = await fetchFontFamilies();
|
|
46
38
|
expect(families).toEqual(['Fraunces', 'Inter']);
|
|
@@ -15,7 +15,7 @@ function extractFamilyFromPath(path: string): string {
|
|
|
15
15
|
const name = filename.replace(/\.(ttf|woff2?|otf)$/i, '');
|
|
16
16
|
return name
|
|
17
17
|
.split('-')
|
|
18
|
-
.map(part => part.charAt(0).toUpperCase() + part.slice(1))
|
|
18
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
19
19
|
.join(' ');
|
|
20
20
|
}
|
|
21
21
|
|
|
@@ -38,8 +38,8 @@ export async function fetchFontFamilies(): Promise<string[]> {
|
|
|
38
38
|
if (inFlight) return inFlight;
|
|
39
39
|
|
|
40
40
|
inFlight = fetch('/api/config')
|
|
41
|
-
.then(res => (res.ok ? res.json() : { fonts: [] }))
|
|
42
|
-
.then(config => {
|
|
41
|
+
.then((res) => (res.ok ? res.json() : { fonts: [] }))
|
|
42
|
+
.then((config) => {
|
|
43
43
|
cachedFamilies = extractFamilies(config.fonts);
|
|
44
44
|
return cachedFamilies;
|
|
45
45
|
})
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
* Manages Hot Module Replacement WebSocket connection, status tracking, and visual indicators.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { createElement as h, useState, useEffect, useRef } from
|
|
7
|
-
import type { ReactElement } from
|
|
8
|
-
import { HMRWebSocket } from
|
|
6
|
+
import { createElement as h, useState, useEffect, useRef } from 'react';
|
|
7
|
+
import type { ReactElement } from 'react';
|
|
8
|
+
import { HMRWebSocket } from '../hmrWebSocket';
|
|
9
9
|
|
|
10
10
|
export interface HMRManagerProps {
|
|
11
11
|
/**
|
|
@@ -46,7 +46,7 @@ export function HMRManager({
|
|
|
46
46
|
onStatusChange,
|
|
47
47
|
currentPath = typeof window !== 'undefined' ? window.location.pathname : '/',
|
|
48
48
|
onReload,
|
|
49
|
-
onCMSUpdate
|
|
49
|
+
onCMSUpdate,
|
|
50
50
|
}: HMRManagerProps): ReactElement | null {
|
|
51
51
|
const [status, setStatus] = useState<'connecting' | 'connected' | 'disconnected' | 'error'>('connecting');
|
|
52
52
|
|
|
@@ -63,7 +63,9 @@ export function HMRManager({
|
|
|
63
63
|
onCMSUpdateRef.current = onCMSUpdate;
|
|
64
64
|
}, [onCMSUpdate]);
|
|
65
65
|
|
|
66
|
-
useEffect(() => {
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
onReloadRef.current = onReload;
|
|
68
|
+
}, [onReload]);
|
|
67
69
|
|
|
68
70
|
// Define message handler - reads from refs to always get latest values
|
|
69
71
|
const createMessageHandler = () => (data: any) => {
|
|
@@ -95,6 +97,19 @@ export function HMRManager({
|
|
|
95
97
|
} else if (data.type === 'hmr:libraries-update') {
|
|
96
98
|
// Dispatch custom event to trigger full page reload for library changes
|
|
97
99
|
document.dispatchEvent(new CustomEvent('hmr-libraries-update'));
|
|
100
|
+
} else if (data.type === 'hmr:config-update') {
|
|
101
|
+
// project.config.json changed (e.g. a locale was added in the editor).
|
|
102
|
+
// Dispatch custom event so the Router refetches the i18n config and
|
|
103
|
+
// re-resolves the current route — without this, the canvas keeps the
|
|
104
|
+
// stale locale set and a freshly added locale's paths (/pl) 404 with
|
|
105
|
+
// "Page not found" until a full canvas reload. The studio frame has its
|
|
106
|
+
// own handler for the same WS message (editor.tsx); this is the canvas's.
|
|
107
|
+
document.dispatchEvent(new CustomEvent('hmr-config-update'));
|
|
108
|
+
} else if (data.type === 'hmr:stylesheet-update') {
|
|
109
|
+
// An external project stylesheet changed (e.g. a mirror-import class edit
|
|
110
|
+
// via /api/element-styles/update — outside the file watcher's categories).
|
|
111
|
+
// Dispatch so the canvas cache-busts its <link> stylesheets and repaints.
|
|
112
|
+
document.dispatchEvent(new CustomEvent('hmr-stylesheet-update'));
|
|
98
113
|
}
|
|
99
114
|
};
|
|
100
115
|
|
|
@@ -150,17 +165,16 @@ export function HMRManager({
|
|
|
150
165
|
useEffect(() => {
|
|
151
166
|
if (import.meta.hot) {
|
|
152
167
|
import.meta.hot.accept();
|
|
153
|
-
|
|
168
|
+
|
|
154
169
|
import.meta.hot.on('bun:beforeUpdate', () => {
|
|
155
170
|
// HMR update starting
|
|
156
171
|
});
|
|
157
|
-
|
|
172
|
+
|
|
158
173
|
import.meta.hot.on('bun:afterUpdate', () => {
|
|
159
174
|
// HMR update complete
|
|
160
175
|
});
|
|
161
|
-
|
|
162
|
-
import.meta.hot.on('bun:error', () => {
|
|
163
|
-
});
|
|
176
|
+
|
|
177
|
+
import.meta.hot.on('bun:error', () => {});
|
|
164
178
|
}
|
|
165
179
|
}, []);
|
|
166
180
|
|
|
@@ -182,24 +196,27 @@ export function HMRIndicator({ status }: { status: 'connecting' | 'connected' |
|
|
|
182
196
|
|
|
183
197
|
const config = statusConfig[status];
|
|
184
198
|
|
|
185
|
-
return h(
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
199
|
+
return h(
|
|
200
|
+
'div',
|
|
201
|
+
{
|
|
202
|
+
id: 'hmr-indicator',
|
|
203
|
+
style: {
|
|
204
|
+
position: 'fixed',
|
|
205
|
+
top: '20px',
|
|
206
|
+
right: '20px',
|
|
207
|
+
background: config.bg,
|
|
208
|
+
color: 'white',
|
|
209
|
+
padding: '12px 20px',
|
|
210
|
+
borderRadius: '8px',
|
|
211
|
+
fontSize: '14px',
|
|
212
|
+
fontWeight: '600',
|
|
213
|
+
display: config.show ? 'block' : 'none',
|
|
214
|
+
boxShadow: `0 4px 12px ${config.bg}40`,
|
|
215
|
+
animation: 'slideIn 0.3s ease-out',
|
|
216
|
+
zIndex: 9999,
|
|
217
|
+
transition: 'all 0.3s ease',
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
config.text,
|
|
221
|
+
);
|
|
204
222
|
}
|
|
205
|
-
|
|
@@ -23,6 +23,27 @@ declare global {
|
|
|
23
23
|
__hmrVariablesCSSInitialized?: boolean;
|
|
24
24
|
__hmrFontsCSSInitialized?: boolean;
|
|
25
25
|
__hmrLibrariesInitialized?: boolean;
|
|
26
|
+
__hmrStylesheetInitialized?: boolean;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Cache-bust same-origin `<link rel="stylesheet">` hrefs so the canvas repaints
|
|
31
|
+
// after a project CSS file changes (e.g. a mirror-import class edit). The old
|
|
32
|
+
// stylesheet stays applied until the new one loads, so there's no flash. Skips
|
|
33
|
+
// cross-origin (CDN) links and data: URIs.
|
|
34
|
+
function reloadExternalStylesheets(): void {
|
|
35
|
+
const links = document.querySelectorAll<HTMLLinkElement>('link[rel="stylesheet"]');
|
|
36
|
+
for (const link of links) {
|
|
37
|
+
const href = link.getAttribute('href');
|
|
38
|
+
if (!href || href.startsWith('data:')) continue;
|
|
39
|
+
try {
|
|
40
|
+
const url = new URL(href, location.href);
|
|
41
|
+
if (url.origin !== location.origin) continue;
|
|
42
|
+
url.searchParams.set('hmr', String(Date.now()));
|
|
43
|
+
link.href = url.href;
|
|
44
|
+
} catch {
|
|
45
|
+
// ignore unparseable href
|
|
46
|
+
}
|
|
26
47
|
}
|
|
27
48
|
}
|
|
28
49
|
|
|
@@ -32,17 +53,15 @@ async function injectUpdatedThemeCSS(): Promise<void> {
|
|
|
32
53
|
const themesResponse = await fetch('/api/themes');
|
|
33
54
|
if (!themesResponse.ok) return;
|
|
34
55
|
|
|
35
|
-
const themesData = await themesResponse.json() as {
|
|
56
|
+
const themesData = (await themesResponse.json()) as {
|
|
36
57
|
themes: Array<{ name: string; label: string }>;
|
|
37
58
|
default: string;
|
|
38
59
|
};
|
|
39
60
|
|
|
40
61
|
// Fetch colors for each theme
|
|
41
|
-
const themeColors: Record<string,
|
|
62
|
+
const themeColors: Record<string, Record<string, string>> = {};
|
|
42
63
|
for (const theme of themesData.themes) {
|
|
43
|
-
const colorResponse = await fetch(
|
|
44
|
-
`/api/colors?theme=${encodeURIComponent(theme.name)}`
|
|
45
|
-
);
|
|
64
|
+
const colorResponse = await fetch(`/api/colors?theme=${encodeURIComponent(theme.name)}`);
|
|
46
65
|
if (colorResponse.ok) {
|
|
47
66
|
themeColors[theme.name] = (await colorResponse.json()).colors;
|
|
48
67
|
}
|
|
@@ -51,20 +70,21 @@ async function injectUpdatedThemeCSS(): Promise<void> {
|
|
|
51
70
|
// Also get default theme colors
|
|
52
71
|
const defaultResponse = await fetch('/api/colors');
|
|
53
72
|
if (defaultResponse.ok) {
|
|
54
|
-
themeColors
|
|
73
|
+
themeColors.default = (await defaultResponse.json()).colors;
|
|
55
74
|
}
|
|
56
75
|
|
|
57
76
|
// Generate CSS — default theme in :root, each named theme in [theme="..."]
|
|
58
77
|
let css = '';
|
|
59
|
-
if (themeColors
|
|
60
|
-
const vars = Object.entries(themeColors
|
|
78
|
+
if (themeColors.default) {
|
|
79
|
+
const vars = Object.entries(themeColors.default)
|
|
61
80
|
.map(([name, value]) => ` --${name}: ${value};`)
|
|
62
81
|
.join('\n');
|
|
63
82
|
css += `:root {\n${vars}\n}\n\n`;
|
|
64
83
|
}
|
|
65
84
|
for (const theme of themesData.themes) {
|
|
66
|
-
|
|
67
|
-
|
|
85
|
+
const themeVars = themeColors[theme.name];
|
|
86
|
+
if (themeVars) {
|
|
87
|
+
const vars = Object.entries(themeVars)
|
|
68
88
|
.map(([name, value]) => ` --${name}: ${value};`)
|
|
69
89
|
.join('\n');
|
|
70
90
|
css += `[theme="${theme.name}"] {\n${vars}\n}\n\n`;
|
|
@@ -140,21 +160,36 @@ export function setupCssHmrListeners(): void {
|
|
|
140
160
|
|
|
141
161
|
if (!window.__hmrColorsInitialized) {
|
|
142
162
|
window.__hmrColorsInitialized = true;
|
|
143
|
-
document.addEventListener('hmr-colors-update', () => {
|
|
163
|
+
document.addEventListener('hmr-colors-update', () => {
|
|
164
|
+
void injectUpdatedThemeCSS();
|
|
165
|
+
});
|
|
144
166
|
}
|
|
145
167
|
|
|
146
168
|
if (!window.__hmrVariablesCSSInitialized) {
|
|
147
169
|
window.__hmrVariablesCSSInitialized = true;
|
|
148
|
-
document.addEventListener('hmr-variables-update', () => {
|
|
170
|
+
document.addEventListener('hmr-variables-update', () => {
|
|
171
|
+
void injectUpdatedVariablesCSS();
|
|
172
|
+
});
|
|
149
173
|
}
|
|
150
174
|
|
|
151
175
|
if (!window.__hmrFontsCSSInitialized) {
|
|
152
176
|
window.__hmrFontsCSSInitialized = true;
|
|
153
|
-
document.addEventListener('hmr-fonts-update', () => {
|
|
177
|
+
document.addEventListener('hmr-fonts-update', () => {
|
|
178
|
+
void injectUpdatedFontsCSS();
|
|
179
|
+
});
|
|
154
180
|
}
|
|
155
181
|
|
|
156
182
|
if (!window.__hmrLibrariesInitialized) {
|
|
157
183
|
window.__hmrLibrariesInitialized = true;
|
|
158
|
-
document.addEventListener('hmr-libraries-update', () => {
|
|
184
|
+
document.addEventListener('hmr-libraries-update', () => {
|
|
185
|
+
location.reload();
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (!window.__hmrStylesheetInitialized) {
|
|
190
|
+
window.__hmrStylesheetInitialized = true;
|
|
191
|
+
document.addEventListener('hmr-stylesheet-update', () => {
|
|
192
|
+
reloadExternalStylesheets();
|
|
193
|
+
});
|
|
159
194
|
}
|
|
160
195
|
}
|