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
|
@@ -1,496 +1,498 @@
|
|
|
1
|
-
import { test, expect, describe,
|
|
1
|
+
import { test, expect, describe, afterEach } from 'bun:test';
|
|
2
2
|
|
|
3
3
|
// Save original fetch before any test can modify it
|
|
4
4
|
const _originalFetch = globalThis.fetch;
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
import type { ResponsiveStyleObject, StyleObject } from "../shared/types";
|
|
12
|
-
|
|
13
|
-
describe("Responsive Style Resolver - getBreakpointName", () => {
|
|
14
|
-
describe("Breakpoint detection", () => {
|
|
5
|
+
import { resolveResponsiveStyleSync, resolveResponsiveStyle, initializeBreakpoints } from './responsiveStyleResolver';
|
|
6
|
+
import { getBreakpointName, DEFAULT_BREAKPOINTS } from '../shared/breakpoints';
|
|
7
|
+
import type { ResponsiveStyleObject, StyleObject } from '../shared/types';
|
|
8
|
+
|
|
9
|
+
describe('Responsive Style Resolver - getBreakpointName', () => {
|
|
10
|
+
describe('Breakpoint detection', () => {
|
|
15
11
|
test("should return 'base' for large viewport", () => {
|
|
16
12
|
const viewportWidth = 1920;
|
|
17
13
|
const result = getBreakpointName(viewportWidth);
|
|
18
|
-
expect(result).toBe(
|
|
14
|
+
expect(result).toBe('base');
|
|
19
15
|
});
|
|
20
16
|
|
|
21
17
|
test("should return 'base' for viewport wider than tablet", () => {
|
|
22
18
|
const viewportWidth = 1025;
|
|
23
19
|
const result = getBreakpointName(viewportWidth);
|
|
24
|
-
expect(result).toBe(
|
|
20
|
+
expect(result).toBe('base');
|
|
25
21
|
});
|
|
26
22
|
|
|
27
23
|
test("should return 'tablet' for viewport at tablet breakpoint", () => {
|
|
28
24
|
const viewportWidth = 1024;
|
|
29
25
|
const result = getBreakpointName(viewportWidth);
|
|
30
|
-
expect(result).toBe(
|
|
26
|
+
expect(result).toBe('tablet');
|
|
31
27
|
});
|
|
32
28
|
|
|
33
29
|
test("should return 'tablet' for viewport between mobile and tablet", () => {
|
|
34
30
|
const viewportWidth = 768;
|
|
35
31
|
const result = getBreakpointName(viewportWidth);
|
|
36
|
-
expect(result).toBe(
|
|
32
|
+
expect(result).toBe('tablet');
|
|
37
33
|
});
|
|
38
34
|
|
|
39
35
|
test("should return 'tablet' for viewport just above mobile breakpoint", () => {
|
|
40
36
|
const viewportWidth = 541;
|
|
41
37
|
const result = getBreakpointName(viewportWidth);
|
|
42
|
-
expect(result).toBe(
|
|
38
|
+
expect(result).toBe('tablet');
|
|
43
39
|
});
|
|
44
40
|
|
|
45
41
|
test("should return 'mobile' for viewport at mobile breakpoint", () => {
|
|
46
42
|
const viewportWidth = 540;
|
|
47
43
|
const result = getBreakpointName(viewportWidth);
|
|
48
|
-
expect(result).toBe(
|
|
44
|
+
expect(result).toBe('mobile');
|
|
49
45
|
});
|
|
50
46
|
|
|
51
47
|
test("should return 'mobile' for viewport smaller than mobile breakpoint", () => {
|
|
52
48
|
const viewportWidth = 320;
|
|
53
49
|
const result = getBreakpointName(viewportWidth);
|
|
54
|
-
expect(result).toBe(
|
|
50
|
+
expect(result).toBe('mobile');
|
|
55
51
|
});
|
|
56
52
|
|
|
57
|
-
test(
|
|
53
|
+
test('should use custom breakpoints when provided', () => {
|
|
58
54
|
const viewportWidth = 800;
|
|
59
55
|
const customBreakpoints = {
|
|
60
56
|
tablet: { breakpoint: 900, previewPoint: 768 },
|
|
61
|
-
mobile: { breakpoint: 400, previewPoint: 375 }
|
|
57
|
+
mobile: { breakpoint: 400, previewPoint: 375 },
|
|
62
58
|
};
|
|
63
59
|
const result = getBreakpointName(viewportWidth, customBreakpoints);
|
|
64
|
-
expect(result).toBe(
|
|
60
|
+
expect(result).toBe('tablet');
|
|
65
61
|
});
|
|
66
62
|
});
|
|
67
63
|
|
|
68
|
-
describe(
|
|
69
|
-
test(
|
|
70
|
-
const tabletWidth = DEFAULT_BREAKPOINTS.tablet
|
|
71
|
-
const mobileWidth = DEFAULT_BREAKPOINTS.mobile
|
|
64
|
+
describe('Edge cases', () => {
|
|
65
|
+
test('should handle exact breakpoint boundaries', () => {
|
|
66
|
+
const tabletWidth = DEFAULT_BREAKPOINTS.tablet!.breakpoint;
|
|
67
|
+
const mobileWidth = DEFAULT_BREAKPOINTS.mobile!.breakpoint;
|
|
72
68
|
|
|
73
|
-
expect(getBreakpointName(tabletWidth)).toBe(
|
|
74
|
-
expect(getBreakpointName(tabletWidth - 1)).toBe(
|
|
75
|
-
expect(getBreakpointName(tabletWidth + 1)).toBe(
|
|
69
|
+
expect(getBreakpointName(tabletWidth)).toBe('tablet');
|
|
70
|
+
expect(getBreakpointName(tabletWidth - 1)).toBe('tablet');
|
|
71
|
+
expect(getBreakpointName(tabletWidth + 1)).toBe('base');
|
|
76
72
|
|
|
77
|
-
expect(getBreakpointName(mobileWidth)).toBe(
|
|
78
|
-
expect(getBreakpointName(mobileWidth - 1)).toBe(
|
|
79
|
-
expect(getBreakpointName(mobileWidth + 1)).toBe(
|
|
73
|
+
expect(getBreakpointName(mobileWidth)).toBe('mobile');
|
|
74
|
+
expect(getBreakpointName(mobileWidth - 1)).toBe('mobile');
|
|
75
|
+
expect(getBreakpointName(mobileWidth + 1)).toBe('tablet');
|
|
80
76
|
});
|
|
81
77
|
|
|
82
|
-
test(
|
|
78
|
+
test('should handle zero viewport width', () => {
|
|
83
79
|
const result = getBreakpointName(0);
|
|
84
|
-
expect(result).toBe(
|
|
80
|
+
expect(result).toBe('mobile');
|
|
85
81
|
});
|
|
86
82
|
|
|
87
|
-
test(
|
|
83
|
+
test('should handle very large viewport width', () => {
|
|
88
84
|
const result = getBreakpointName(10000);
|
|
89
|
-
expect(result).toBe(
|
|
85
|
+
expect(result).toBe('base');
|
|
90
86
|
});
|
|
91
87
|
});
|
|
92
88
|
});
|
|
93
89
|
|
|
94
|
-
describe(
|
|
95
|
-
describe(
|
|
96
|
-
test(
|
|
90
|
+
describe('Responsive Style Resolver - resolveResponsiveStyleSync', () => {
|
|
91
|
+
describe('Non-responsive styles', () => {
|
|
92
|
+
test('should pass through flat style objects', () => {
|
|
97
93
|
const style: StyleObject = {
|
|
98
|
-
color:
|
|
99
|
-
fontSize:
|
|
94
|
+
color: 'red',
|
|
95
|
+
fontSize: '16px',
|
|
100
96
|
};
|
|
101
|
-
|
|
97
|
+
|
|
102
98
|
const result = resolveResponsiveStyleSync(style);
|
|
103
99
|
expect(result).toEqual(style);
|
|
104
|
-
expect(result.color).toBe(
|
|
105
|
-
expect(result.fontSize).toBe(
|
|
100
|
+
expect(result.color).toBe('red');
|
|
101
|
+
expect(result.fontSize).toBe('16px');
|
|
106
102
|
});
|
|
107
103
|
|
|
108
|
-
test(
|
|
104
|
+
test('should return same object for non-responsive styles', () => {
|
|
109
105
|
const style: StyleObject = {
|
|
110
|
-
padding:
|
|
111
|
-
margin:
|
|
106
|
+
padding: '10px',
|
|
107
|
+
margin: '20px',
|
|
112
108
|
};
|
|
113
|
-
|
|
109
|
+
|
|
114
110
|
const result = resolveResponsiveStyleSync(style);
|
|
115
111
|
expect(result).toBe(style); // Should return same reference for flat styles
|
|
116
112
|
});
|
|
117
113
|
});
|
|
118
114
|
|
|
119
|
-
describe(
|
|
120
|
-
test(
|
|
115
|
+
describe('Responsive styles - viewport strategy', () => {
|
|
116
|
+
test('should merge base only styles at base breakpoint', () => {
|
|
121
117
|
const style: ResponsiveStyleObject = {
|
|
122
118
|
base: {
|
|
123
|
-
color:
|
|
124
|
-
fontSize:
|
|
125
|
-
}
|
|
119
|
+
color: 'red',
|
|
120
|
+
fontSize: '16px',
|
|
121
|
+
},
|
|
126
122
|
};
|
|
127
123
|
const viewportWidth = 1920;
|
|
128
|
-
|
|
124
|
+
|
|
129
125
|
const result = resolveResponsiveStyleSync(style, viewportWidth);
|
|
130
|
-
|
|
131
|
-
expect(result.color).toBe(
|
|
132
|
-
expect(result.fontSize).toBe(
|
|
126
|
+
|
|
127
|
+
expect(result.color).toBe('red');
|
|
128
|
+
expect(result.fontSize).toBe('16px');
|
|
133
129
|
});
|
|
134
130
|
|
|
135
|
-
test(
|
|
131
|
+
test('should merge base and tablet styles at tablet breakpoint', () => {
|
|
136
132
|
const style: ResponsiveStyleObject = {
|
|
137
133
|
base: {
|
|
138
|
-
color:
|
|
139
|
-
fontSize:
|
|
134
|
+
color: 'red',
|
|
135
|
+
fontSize: '16px',
|
|
140
136
|
},
|
|
141
137
|
tablet: {
|
|
142
|
-
fontSize:
|
|
143
|
-
padding:
|
|
144
|
-
}
|
|
138
|
+
fontSize: '14px',
|
|
139
|
+
padding: '10px',
|
|
140
|
+
},
|
|
145
141
|
};
|
|
146
142
|
const viewportWidth = 768;
|
|
147
|
-
|
|
143
|
+
|
|
148
144
|
const result = resolveResponsiveStyleSync(style, viewportWidth);
|
|
149
|
-
|
|
150
|
-
expect(result.color).toBe(
|
|
151
|
-
expect(result.fontSize).toBe(
|
|
152
|
-
expect(result.padding).toBe(
|
|
145
|
+
|
|
146
|
+
expect(result.color).toBe('red'); // From base
|
|
147
|
+
expect(result.fontSize).toBe('14px'); // Overridden by tablet
|
|
148
|
+
expect(result.padding).toBe('10px'); // From tablet
|
|
153
149
|
});
|
|
154
150
|
|
|
155
|
-
test(
|
|
151
|
+
test('should merge all breakpoints at mobile breakpoint', () => {
|
|
156
152
|
const style: ResponsiveStyleObject = {
|
|
157
153
|
base: {
|
|
158
|
-
color:
|
|
159
|
-
fontSize:
|
|
154
|
+
color: 'red',
|
|
155
|
+
fontSize: '16px',
|
|
160
156
|
},
|
|
161
157
|
tablet: {
|
|
162
|
-
fontSize:
|
|
158
|
+
fontSize: '14px',
|
|
163
159
|
},
|
|
164
160
|
mobile: {
|
|
165
|
-
fontSize:
|
|
166
|
-
color:
|
|
167
|
-
}
|
|
161
|
+
fontSize: '12px',
|
|
162
|
+
color: 'blue',
|
|
163
|
+
},
|
|
168
164
|
};
|
|
169
165
|
const viewportWidth = 320;
|
|
170
|
-
|
|
166
|
+
|
|
171
167
|
const result = resolveResponsiveStyleSync(style, viewportWidth);
|
|
172
|
-
|
|
173
|
-
expect(result.color).toBe(
|
|
174
|
-
expect(result.fontSize).toBe(
|
|
168
|
+
|
|
169
|
+
expect(result.color).toBe('blue'); // Overridden by mobile
|
|
170
|
+
expect(result.fontSize).toBe('12px'); // Overridden by mobile
|
|
175
171
|
});
|
|
176
172
|
|
|
177
|
-
test(
|
|
173
|
+
test('should apply tablet styles at tablet viewport', () => {
|
|
178
174
|
const style: ResponsiveStyleObject = {
|
|
179
175
|
base: {
|
|
180
|
-
padding:
|
|
176
|
+
padding: '20px',
|
|
181
177
|
},
|
|
182
178
|
tablet: {
|
|
183
|
-
padding:
|
|
184
|
-
}
|
|
179
|
+
padding: '15px',
|
|
180
|
+
},
|
|
185
181
|
};
|
|
186
182
|
const viewportWidth = 1024;
|
|
187
|
-
|
|
183
|
+
|
|
188
184
|
const result = resolveResponsiveStyleSync(style, viewportWidth);
|
|
189
|
-
|
|
190
|
-
expect(result.padding).toBe(
|
|
185
|
+
|
|
186
|
+
expect(result.padding).toBe('15px');
|
|
191
187
|
});
|
|
192
188
|
|
|
193
|
-
test(
|
|
189
|
+
test('should apply mobile styles at mobile viewport', () => {
|
|
194
190
|
const style: ResponsiveStyleObject = {
|
|
195
191
|
base: {
|
|
196
|
-
padding:
|
|
192
|
+
padding: '20px',
|
|
197
193
|
},
|
|
198
194
|
tablet: {
|
|
199
|
-
padding:
|
|
195
|
+
padding: '15px',
|
|
200
196
|
},
|
|
201
197
|
mobile: {
|
|
202
|
-
padding:
|
|
203
|
-
}
|
|
198
|
+
padding: '10px',
|
|
199
|
+
},
|
|
204
200
|
};
|
|
205
201
|
const viewportWidth = 540;
|
|
206
|
-
|
|
202
|
+
|
|
207
203
|
const result = resolveResponsiveStyleSync(style, viewportWidth);
|
|
208
|
-
|
|
209
|
-
expect(result.padding).toBe(
|
|
204
|
+
|
|
205
|
+
expect(result.padding).toBe('10px');
|
|
210
206
|
});
|
|
211
207
|
});
|
|
212
208
|
|
|
213
|
-
describe(
|
|
214
|
-
test(
|
|
209
|
+
describe('Responsive styles - style object variations', () => {
|
|
210
|
+
test('should handle styles with base only', () => {
|
|
215
211
|
const style: ResponsiveStyleObject = {
|
|
216
212
|
base: {
|
|
217
|
-
color:
|
|
218
|
-
backgroundColor:
|
|
219
|
-
}
|
|
213
|
+
color: 'black',
|
|
214
|
+
backgroundColor: 'white',
|
|
215
|
+
},
|
|
220
216
|
};
|
|
221
|
-
|
|
217
|
+
|
|
222
218
|
const result = resolveResponsiveStyleSync(style, 1920);
|
|
223
|
-
|
|
224
|
-
expect(result.color).toBe(
|
|
225
|
-
expect(result.backgroundColor).toBe(
|
|
219
|
+
|
|
220
|
+
expect(result.color).toBe('black');
|
|
221
|
+
expect(result.backgroundColor).toBe('white');
|
|
226
222
|
});
|
|
227
223
|
|
|
228
|
-
test(
|
|
224
|
+
test('should handle styles with base and tablet', () => {
|
|
229
225
|
const style: ResponsiveStyleObject = {
|
|
230
226
|
base: {
|
|
231
|
-
fontSize:
|
|
227
|
+
fontSize: '16px',
|
|
232
228
|
},
|
|
233
229
|
tablet: {
|
|
234
|
-
fontSize:
|
|
235
|
-
}
|
|
230
|
+
fontSize: '14px',
|
|
231
|
+
},
|
|
236
232
|
};
|
|
237
|
-
|
|
233
|
+
|
|
238
234
|
const result = resolveResponsiveStyleSync(style, 768);
|
|
239
|
-
|
|
240
|
-
expect(result.fontSize).toBe(
|
|
235
|
+
|
|
236
|
+
expect(result.fontSize).toBe('14px');
|
|
241
237
|
});
|
|
242
238
|
|
|
243
|
-
test(
|
|
239
|
+
test('should handle styles with all breakpoints', () => {
|
|
244
240
|
const style: ResponsiveStyleObject = {
|
|
245
241
|
base: {
|
|
246
|
-
fontSize:
|
|
247
|
-
color:
|
|
242
|
+
fontSize: '18px',
|
|
243
|
+
color: 'black',
|
|
248
244
|
},
|
|
249
245
|
tablet: {
|
|
250
|
-
fontSize:
|
|
246
|
+
fontSize: '16px',
|
|
251
247
|
},
|
|
252
248
|
mobile: {
|
|
253
|
-
fontSize:
|
|
254
|
-
color:
|
|
255
|
-
}
|
|
249
|
+
fontSize: '14px',
|
|
250
|
+
color: 'gray',
|
|
251
|
+
},
|
|
256
252
|
};
|
|
257
|
-
|
|
253
|
+
|
|
258
254
|
const result = resolveResponsiveStyleSync(style, 320);
|
|
259
|
-
|
|
260
|
-
expect(result.fontSize).toBe(
|
|
261
|
-
expect(result.color).toBe(
|
|
255
|
+
|
|
256
|
+
expect(result.fontSize).toBe('14px');
|
|
257
|
+
expect(result.color).toBe('gray');
|
|
262
258
|
});
|
|
263
259
|
|
|
264
|
-
test(
|
|
260
|
+
test('should handle missing breakpoint styles', () => {
|
|
265
261
|
const style: ResponsiveStyleObject = {
|
|
266
262
|
base: {
|
|
267
|
-
color:
|
|
268
|
-
}
|
|
263
|
+
color: 'red',
|
|
264
|
+
},
|
|
269
265
|
// No tablet or mobile
|
|
270
266
|
};
|
|
271
|
-
|
|
267
|
+
|
|
272
268
|
const result = resolveResponsiveStyleSync(style, 320);
|
|
273
|
-
|
|
274
|
-
expect(result.color).toBe(
|
|
269
|
+
|
|
270
|
+
expect(result.color).toBe('red'); // Should still have base styles
|
|
275
271
|
});
|
|
276
272
|
|
|
277
|
-
test(
|
|
273
|
+
test('should handle empty base styles', () => {
|
|
278
274
|
const style: ResponsiveStyleObject = {
|
|
279
275
|
base: {},
|
|
280
276
|
tablet: {
|
|
281
|
-
fontSize:
|
|
282
|
-
}
|
|
277
|
+
fontSize: '14px',
|
|
278
|
+
},
|
|
283
279
|
};
|
|
284
|
-
|
|
280
|
+
|
|
285
281
|
const result = resolveResponsiveStyleSync(style, 768);
|
|
286
|
-
|
|
287
|
-
expect(result.fontSize).toBe(
|
|
282
|
+
|
|
283
|
+
expect(result.fontSize).toBe('14px');
|
|
288
284
|
});
|
|
289
285
|
});
|
|
290
286
|
|
|
291
|
-
describe(
|
|
292
|
-
test(
|
|
287
|
+
describe('Edge cases', () => {
|
|
288
|
+
test('should handle empty responsive style object', () => {
|
|
293
289
|
const style: ResponsiveStyleObject = {
|
|
294
|
-
base: {}
|
|
290
|
+
base: {},
|
|
295
291
|
};
|
|
296
|
-
|
|
292
|
+
|
|
297
293
|
const result = resolveResponsiveStyleSync(style, 1920);
|
|
298
|
-
|
|
294
|
+
|
|
299
295
|
expect(Object.keys(result).length).toBe(0);
|
|
300
296
|
});
|
|
301
297
|
|
|
302
|
-
test(
|
|
298
|
+
test('should handle viewport width at exact tablet boundary', () => {
|
|
303
299
|
const style: ResponsiveStyleObject = {
|
|
304
|
-
base: { fontSize:
|
|
305
|
-
tablet: { fontSize:
|
|
300
|
+
base: { fontSize: '16px' },
|
|
301
|
+
tablet: { fontSize: '14px' },
|
|
306
302
|
};
|
|
307
303
|
|
|
308
|
-
const result = resolveResponsiveStyleSync(style, DEFAULT_BREAKPOINTS.tablet
|
|
304
|
+
const result = resolveResponsiveStyleSync(style, DEFAULT_BREAKPOINTS.tablet!.breakpoint);
|
|
309
305
|
|
|
310
|
-
expect(result.fontSize).toBe(
|
|
306
|
+
expect(result.fontSize).toBe('14px');
|
|
311
307
|
});
|
|
312
308
|
|
|
313
|
-
test(
|
|
309
|
+
test('should handle viewport width at exact mobile boundary', () => {
|
|
314
310
|
const style: ResponsiveStyleObject = {
|
|
315
|
-
base: { fontSize:
|
|
316
|
-
tablet: { fontSize:
|
|
317
|
-
mobile: { fontSize:
|
|
311
|
+
base: { fontSize: '16px' },
|
|
312
|
+
tablet: { fontSize: '14px' },
|
|
313
|
+
mobile: { fontSize: '12px' },
|
|
318
314
|
};
|
|
319
315
|
|
|
320
|
-
const result = resolveResponsiveStyleSync(style, DEFAULT_BREAKPOINTS.mobile
|
|
316
|
+
const result = resolveResponsiveStyleSync(style, DEFAULT_BREAKPOINTS.mobile!.breakpoint);
|
|
321
317
|
|
|
322
|
-
expect(result.fontSize).toBe(
|
|
318
|
+
expect(result.fontSize).toBe('12px');
|
|
323
319
|
});
|
|
324
320
|
|
|
325
|
-
test(
|
|
321
|
+
test('should use default viewport width when not provided', () => {
|
|
326
322
|
const style: ResponsiveStyleObject = {
|
|
327
|
-
base: { fontSize:
|
|
323
|
+
base: { fontSize: '16px' },
|
|
328
324
|
};
|
|
329
|
-
|
|
325
|
+
|
|
330
326
|
// Should use window.innerWidth or 1920 as default
|
|
331
327
|
const result = resolveResponsiveStyleSync(style);
|
|
332
|
-
|
|
333
|
-
expect(result.fontSize).toBe(
|
|
328
|
+
|
|
329
|
+
expect(result.fontSize).toBe('16px');
|
|
334
330
|
// Note: Can't reliably test the exact default without window object in test env
|
|
335
331
|
});
|
|
336
332
|
});
|
|
337
333
|
});
|
|
338
334
|
|
|
339
|
-
describe(
|
|
335
|
+
describe('Responsive Style Resolver - resolveResponsiveStyle (async)', () => {
|
|
340
336
|
afterEach(() => {
|
|
341
337
|
globalThis.fetch = _originalFetch;
|
|
342
338
|
});
|
|
343
339
|
|
|
344
|
-
test(
|
|
340
|
+
test('should resolve non-responsive styles asynchronously', async () => {
|
|
345
341
|
const style: StyleObject = {
|
|
346
|
-
color:
|
|
342
|
+
color: 'red',
|
|
347
343
|
};
|
|
348
|
-
|
|
344
|
+
|
|
349
345
|
const result = await resolveResponsiveStyle(style);
|
|
350
|
-
|
|
346
|
+
|
|
351
347
|
expect(result).toEqual(style);
|
|
352
348
|
});
|
|
353
349
|
|
|
354
|
-
test(
|
|
350
|
+
test('should resolve responsive styles with default breakpoints on fetch error', async () => {
|
|
355
351
|
// Mock fetch to fail
|
|
356
352
|
globalThis.fetch = (() => Promise.reject(new Error('Network error'))) as unknown as typeof fetch;
|
|
357
|
-
|
|
353
|
+
|
|
358
354
|
const style: ResponsiveStyleObject = {
|
|
359
355
|
base: {
|
|
360
|
-
fontSize:
|
|
356
|
+
fontSize: '16px',
|
|
361
357
|
},
|
|
362
358
|
tablet: {
|
|
363
|
-
fontSize:
|
|
364
|
-
}
|
|
359
|
+
fontSize: '14px',
|
|
360
|
+
},
|
|
365
361
|
};
|
|
366
|
-
|
|
362
|
+
|
|
367
363
|
const result = await resolveResponsiveStyle(style);
|
|
368
|
-
|
|
364
|
+
|
|
369
365
|
// Should use default breakpoints and resolve based on window.innerWidth or 1920
|
|
370
366
|
expect(result.fontSize).toBeDefined();
|
|
371
367
|
});
|
|
372
368
|
|
|
373
|
-
test(
|
|
369
|
+
test('should handle async breakpoint config loading', async () => {
|
|
374
370
|
// Mock successful fetch
|
|
375
|
-
globalThis.fetch = (() =>
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
371
|
+
globalThis.fetch = (() =>
|
|
372
|
+
Promise.resolve({
|
|
373
|
+
json: () =>
|
|
374
|
+
Promise.resolve({
|
|
375
|
+
breakpoints: {
|
|
376
|
+
tablet: 900,
|
|
377
|
+
mobile: 400,
|
|
378
|
+
},
|
|
379
|
+
}),
|
|
380
|
+
})) as unknown as typeof fetch;
|
|
381
|
+
|
|
384
382
|
const style: ResponsiveStyleObject = {
|
|
385
|
-
base: { fontSize:
|
|
386
|
-
tablet: { fontSize:
|
|
383
|
+
base: { fontSize: '16px' },
|
|
384
|
+
tablet: { fontSize: '14px' },
|
|
387
385
|
};
|
|
388
|
-
|
|
386
|
+
|
|
389
387
|
// First call should trigger config load
|
|
390
388
|
await resolveResponsiveStyle(style);
|
|
391
|
-
|
|
389
|
+
|
|
392
390
|
// Second call should use cached config
|
|
393
391
|
const result = await resolveResponsiveStyle(style);
|
|
394
|
-
|
|
392
|
+
|
|
395
393
|
expect(result.fontSize).toBeDefined();
|
|
396
394
|
});
|
|
397
395
|
});
|
|
398
396
|
|
|
399
|
-
describe(
|
|
397
|
+
describe('Responsive Style Resolver - initializeBreakpoints', () => {
|
|
400
398
|
afterEach(() => {
|
|
401
399
|
globalThis.fetch = _originalFetch;
|
|
402
400
|
});
|
|
403
401
|
|
|
404
|
-
test(
|
|
402
|
+
test('should initialize breakpoint config', async () => {
|
|
405
403
|
// Mock successful fetch
|
|
406
|
-
globalThis.fetch = (() =>
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
404
|
+
globalThis.fetch = (() =>
|
|
405
|
+
Promise.resolve({
|
|
406
|
+
json: () =>
|
|
407
|
+
Promise.resolve({
|
|
408
|
+
breakpoints: {
|
|
409
|
+
tablet: 900,
|
|
410
|
+
mobile: 400,
|
|
411
|
+
},
|
|
412
|
+
}),
|
|
413
|
+
})) as unknown as typeof fetch;
|
|
414
|
+
|
|
415
415
|
await initializeBreakpoints();
|
|
416
|
-
|
|
416
|
+
|
|
417
417
|
// If initialization succeeds, subsequent resolveResponsiveStyleSync should use cached config
|
|
418
418
|
const style: ResponsiveStyleObject = {
|
|
419
|
-
base: { fontSize:
|
|
419
|
+
base: { fontSize: '16px' },
|
|
420
420
|
};
|
|
421
|
-
|
|
421
|
+
|
|
422
422
|
const result = resolveResponsiveStyleSync(style);
|
|
423
|
-
expect(result.fontSize).toBe(
|
|
423
|
+
expect(result.fontSize).toBe('16px');
|
|
424
424
|
});
|
|
425
425
|
|
|
426
|
-
test(
|
|
426
|
+
test('should handle initialization error gracefully', async () => {
|
|
427
427
|
// Mock fetch to fail
|
|
428
428
|
globalThis.fetch = (() => Promise.reject(new Error('Network error'))) as unknown as typeof fetch;
|
|
429
|
-
|
|
429
|
+
|
|
430
430
|
// Should not throw
|
|
431
431
|
await expect(initializeBreakpoints()).resolves.toBeUndefined();
|
|
432
432
|
});
|
|
433
433
|
});
|
|
434
434
|
|
|
435
|
-
describe(
|
|
436
|
-
test(
|
|
435
|
+
describe('Responsive Style Resolver - Real-world examples', () => {
|
|
436
|
+
test('should handle complex responsive style from index.json example', () => {
|
|
437
437
|
// Based on pages/index.json - h1 with responsive fontSize
|
|
438
438
|
const style: ResponsiveStyleObject = {
|
|
439
439
|
base: {
|
|
440
|
-
fontSize:
|
|
441
|
-
fontWeight:
|
|
442
|
-
marginBottom:
|
|
443
|
-
color:
|
|
444
|
-
letterSpacing:
|
|
440
|
+
fontSize: '89px',
|
|
441
|
+
fontWeight: '600',
|
|
442
|
+
marginBottom: '16px',
|
|
443
|
+
color: '#1f2937',
|
|
444
|
+
letterSpacing: '-0.02em',
|
|
445
445
|
},
|
|
446
446
|
tablet: {
|
|
447
|
-
fontSize:
|
|
447
|
+
fontSize: '32px',
|
|
448
448
|
},
|
|
449
|
-
mobile: {}
|
|
449
|
+
mobile: {},
|
|
450
450
|
};
|
|
451
|
-
|
|
451
|
+
|
|
452
452
|
// Test at base viewport
|
|
453
453
|
const resultBase = resolveResponsiveStyleSync(style, 1920);
|
|
454
|
-
expect(resultBase.fontSize).toBe(
|
|
455
|
-
expect(resultBase.fontWeight).toBe(
|
|
456
|
-
|
|
454
|
+
expect(resultBase.fontSize).toBe('89px');
|
|
455
|
+
expect(resultBase.fontWeight).toBe('600');
|
|
456
|
+
|
|
457
457
|
// Test at tablet viewport
|
|
458
458
|
const resultTablet = resolveResponsiveStyleSync(style, 768);
|
|
459
|
-
expect(resultTablet.fontSize).toBe(
|
|
460
|
-
expect(resultTablet.fontWeight).toBe(
|
|
461
|
-
|
|
459
|
+
expect(resultTablet.fontSize).toBe('32px');
|
|
460
|
+
expect(resultTablet.fontWeight).toBe('600'); // From base
|
|
461
|
+
|
|
462
462
|
// Test at mobile viewport
|
|
463
|
-
// Implementation note: viewport strategy
|
|
464
|
-
//
|
|
463
|
+
// Implementation note: viewport strategy mirrors the CSS max-width cascade —
|
|
464
|
+
// every breakpoint whose range includes the viewport applies, larger first.
|
|
465
|
+
// At 320px both tablet and mobile ranges include the viewport, so tablet's
|
|
466
|
+
// fontSize applies (mobile is empty and overrides nothing).
|
|
465
467
|
const resultMobile = resolveResponsiveStyleSync(style, 320);
|
|
466
|
-
expect(resultMobile.fontSize).toBe(
|
|
467
|
-
expect(resultMobile.fontWeight).toBe(
|
|
468
|
+
expect(resultMobile.fontSize).toBe('32px'); // Tablet cascades to mobile (CSS max-width semantics)
|
|
469
|
+
expect(resultMobile.fontWeight).toBe('600'); // From base
|
|
468
470
|
});
|
|
469
471
|
|
|
470
|
-
test(
|
|
471
|
-
// Implementation note: viewport strategy
|
|
472
|
-
//
|
|
472
|
+
test('should apply base + cascading breakpoint styles', () => {
|
|
473
|
+
// Implementation note: viewport strategy mirrors the CSS max-width cascade —
|
|
474
|
+
// at a mobile viewport, tablet styles apply first, then mobile overrides.
|
|
473
475
|
const style: ResponsiveStyleObject = {
|
|
474
476
|
base: {
|
|
475
|
-
padding:
|
|
476
|
-
margin:
|
|
477
|
-
color:
|
|
477
|
+
padding: '20px',
|
|
478
|
+
margin: '10px',
|
|
479
|
+
color: 'black',
|
|
478
480
|
},
|
|
479
481
|
tablet: {
|
|
480
|
-
padding:
|
|
481
|
-
fontSize:
|
|
482
|
+
padding: '15px',
|
|
483
|
+
fontSize: '14px',
|
|
482
484
|
},
|
|
483
485
|
mobile: {
|
|
484
|
-
padding:
|
|
485
|
-
color:
|
|
486
|
-
}
|
|
486
|
+
padding: '10px',
|
|
487
|
+
color: 'gray',
|
|
488
|
+
},
|
|
487
489
|
};
|
|
488
490
|
|
|
489
491
|
const result = resolveResponsiveStyleSync(style, 320);
|
|
490
492
|
|
|
491
|
-
expect(result.padding).toBe(
|
|
492
|
-
expect(result.margin).toBe(
|
|
493
|
-
expect(result.color).toBe(
|
|
494
|
-
expect(result.fontSize).
|
|
493
|
+
expect(result.padding).toBe('10px'); // Mobile overrides tablet's 15px
|
|
494
|
+
expect(result.margin).toBe('10px'); // From base
|
|
495
|
+
expect(result.color).toBe('gray'); // Mobile overrides
|
|
496
|
+
expect(result.fontSize).toBe('14px'); // Tablet cascades to mobile (CSS max-width semantics)
|
|
495
497
|
});
|
|
496
498
|
});
|