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,32 +3,33 @@
|
|
|
3
3
|
* Handles rendering of link nodes (links rendered as div in editor)
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { createElement as h } from
|
|
7
|
-
import type { ReactElement } from
|
|
8
|
-
import type { LinkNode, 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
|
-
|
|
19
|
-
|
|
20
|
-
import type
|
|
21
|
-
import
|
|
6
|
+
import { createElement as h } from 'react';
|
|
7
|
+
import type { ReactElement } from 'react';
|
|
8
|
+
import type { LinkNode, 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 { processItemPropsTemplate, type ValueResolver } from '../../../shared/itemTemplateUtils';
|
|
21
|
+
import { UtilityClassCollector } from '../../styles/UtilityClassCollector';
|
|
22
|
+
import { resolveI18nValue, DEFAULT_I18N_CONFIG } from '../../../shared/i18n';
|
|
23
|
+
import { isCurrentLink } from '../../../shared/linkUtils';
|
|
24
|
+
import type { ElementRegistry } from '../../elementRegistry';
|
|
25
|
+
import type { BuilderContext, BuildResult, BuildChildrenContext } from './types';
|
|
22
26
|
|
|
23
27
|
export interface LinkNodeBuilderDeps {
|
|
24
28
|
elementRegistry: ElementRegistry;
|
|
25
|
-
buildChildren: (
|
|
26
|
-
children: unknown,
|
|
27
|
-
ctx: BuildChildrenContext
|
|
28
|
-
) => BuildResult;
|
|
29
|
+
buildChildren: (children: unknown, ctx: BuildChildrenContext) => BuildResult;
|
|
29
30
|
getEffectiveParentComponentName: (
|
|
30
31
|
componentContext: string | null,
|
|
31
|
-
parentComponentName: string | null
|
|
32
|
+
parentComponentName: string | null,
|
|
32
33
|
) => string | null;
|
|
33
34
|
/** Optional getter for current page name (for interactive styles class generation) */
|
|
34
35
|
getCurrentPageName?: () => string;
|
|
@@ -45,12 +46,25 @@ export function buildLinkNode(
|
|
|
45
46
|
node: LinkNode,
|
|
46
47
|
children: unknown,
|
|
47
48
|
ctx: BuilderContext,
|
|
48
|
-
deps: LinkNodeBuilderDeps
|
|
49
|
+
deps: LinkNodeBuilderDeps,
|
|
49
50
|
): ReactElement {
|
|
50
51
|
const {
|
|
51
|
-
key,
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
key,
|
|
53
|
+
elementPath,
|
|
54
|
+
parentComponentName,
|
|
55
|
+
viewportWidth,
|
|
56
|
+
componentContext,
|
|
57
|
+
componentRootPath,
|
|
58
|
+
locale,
|
|
59
|
+
i18nConfig,
|
|
60
|
+
cmsContext,
|
|
61
|
+
cmsLocale,
|
|
62
|
+
collectionItemsMap,
|
|
63
|
+
itemContext,
|
|
64
|
+
cmsItemIndexPath,
|
|
65
|
+
cmsListPaths,
|
|
66
|
+
templateContext,
|
|
67
|
+
componentResolvedProps,
|
|
54
68
|
} = ctx;
|
|
55
69
|
|
|
56
70
|
const effectiveParentComponentName = deps.getEffectiveParentComponentName(componentContext, parentComponentName);
|
|
@@ -59,7 +73,7 @@ export function buildLinkNode(
|
|
|
59
73
|
const extractedAttributes = extractAttributesFromNode(node as any);
|
|
60
74
|
|
|
61
75
|
// Build link node props (renders as div in editor)
|
|
62
|
-
const linkNodeProps: Record<string,
|
|
76
|
+
const linkNodeProps: Record<string, unknown> = {
|
|
63
77
|
key,
|
|
64
78
|
'data-element-path': pathToString(elementPath),
|
|
65
79
|
'data-link-node': 'true',
|
|
@@ -74,7 +88,7 @@ export function buildLinkNode(
|
|
|
74
88
|
}
|
|
75
89
|
}
|
|
76
90
|
}
|
|
77
|
-
}
|
|
91
|
+
},
|
|
78
92
|
};
|
|
79
93
|
|
|
80
94
|
// Add CMS item index path for elements inside CMS lists
|
|
@@ -83,7 +97,7 @@ export function buildLinkNode(
|
|
|
83
97
|
}
|
|
84
98
|
|
|
85
99
|
// Start building className
|
|
86
|
-
|
|
100
|
+
const classNames: string[] = [];
|
|
87
101
|
|
|
88
102
|
// Convert link node styles to utility classes
|
|
89
103
|
if (node.style) {
|
|
@@ -99,16 +113,15 @@ export function buildLinkNode(
|
|
|
99
113
|
processedStyle = processItemPropsTemplate(
|
|
100
114
|
node.style as Record<string, unknown>,
|
|
101
115
|
ctx.templateContext,
|
|
102
|
-
i18nResolver
|
|
116
|
+
i18nResolver,
|
|
103
117
|
) as StyleObject | ResponsiveStyleObject;
|
|
104
118
|
}
|
|
105
119
|
const scales = getCachedResponsiveScalesConfig();
|
|
106
|
-
const fluidActive =
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
);
|
|
120
|
+
const fluidActive = scales?.enabled === true && scales?.mode === 'fluid';
|
|
121
|
+
const utilityClasses = responsiveStylesToClasses(processedStyle as StyleObject | ResponsiveStyleObject, {
|
|
122
|
+
fluidActive,
|
|
123
|
+
responsiveScales: scales ?? undefined,
|
|
124
|
+
});
|
|
112
125
|
UtilityClassCollector.collect(utilityClasses);
|
|
113
126
|
classNames.push(...utilityClasses);
|
|
114
127
|
}
|
|
@@ -121,11 +134,10 @@ export function buildLinkNode(
|
|
|
121
134
|
if ((nodeInteractiveStyles && nodeInteractiveStyles.length > 0) || nodeGenerateElementClass) {
|
|
122
135
|
// Determine file type and name for element class generation
|
|
123
136
|
const useComponentContext = Boolean(componentContext);
|
|
124
|
-
const fileType = useComponentContext ? 'component' :
|
|
125
|
-
const fileName = useComponentContext ? componentContext! :
|
|
126
|
-
const pathForClass =
|
|
127
|
-
? elementPath.slice(componentRootPath.length)
|
|
128
|
-
: elementPath;
|
|
137
|
+
const fileType = useComponentContext ? 'component' : deps.getCurrentFileType?.() || 'page';
|
|
138
|
+
const fileName = useComponentContext ? componentContext! : deps.getCurrentPageName?.() || 'page';
|
|
139
|
+
const pathForClass =
|
|
140
|
+
useComponentContext && componentRootPath ? elementPath.slice(componentRootPath.length) : elementPath;
|
|
129
141
|
|
|
130
142
|
const elementClassCtx: ElementClassContext = {
|
|
131
143
|
fileType,
|
|
@@ -157,12 +169,11 @@ export function buildLinkNode(
|
|
|
157
169
|
for (const rule of nodeInteractiveStyles) {
|
|
158
170
|
if (rule.previewProp && ctx.componentResolvedProps[rule.previewProp] === true) {
|
|
159
171
|
const previewScales = getCachedResponsiveScalesConfig();
|
|
160
|
-
const previewFluidActive =
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
);
|
|
172
|
+
const previewFluidActive = previewScales?.enabled === true && previewScales?.mode === 'fluid';
|
|
173
|
+
const styleClasses = responsiveStylesToClasses(rule.style as StyleObject | ResponsiveStyleObject, {
|
|
174
|
+
fluidActive: previewFluidActive,
|
|
175
|
+
responsiveScales: previewScales ?? undefined,
|
|
176
|
+
});
|
|
166
177
|
UtilityClassCollector.collect(styleClasses);
|
|
167
178
|
previewClasses.push(...styleClasses);
|
|
168
179
|
}
|
|
@@ -179,9 +190,9 @@ export function buildLinkNode(
|
|
|
179
190
|
// would be spread onto the React element below and override the className that
|
|
180
191
|
// holds the utility classes derived from node.style.
|
|
181
192
|
if ('class' in extractedAttributes || 'className' in extractedAttributes) {
|
|
182
|
-
const attrClass = ((extractedAttributes as Record<string, unknown>).class
|
|
183
|
-
|
|
184
|
-
|
|
193
|
+
const attrClass = ((extractedAttributes as Record<string, unknown>).class ??
|
|
194
|
+
(extractedAttributes as Record<string, unknown>).className ??
|
|
195
|
+
'') as string;
|
|
185
196
|
if (attrClass) {
|
|
186
197
|
classNames.push(...attrClass.split(/\s+/));
|
|
187
198
|
}
|
|
@@ -209,9 +220,10 @@ export function buildLinkNode(
|
|
|
209
220
|
const i18nResolver: ValueResolver | undefined = effectiveLocale
|
|
210
221
|
? (value: unknown) => resolveI18nValue(value, effectiveLocale, config)
|
|
211
222
|
: undefined;
|
|
212
|
-
processedAttributes = processItemPropsTemplate(
|
|
213
|
-
|
|
214
|
-
|
|
223
|
+
processedAttributes = processItemPropsTemplate(extractedAttributes, ctx.templateContext, i18nResolver) as Record<
|
|
224
|
+
string,
|
|
225
|
+
string | number | boolean
|
|
226
|
+
>;
|
|
215
227
|
}
|
|
216
228
|
|
|
217
229
|
// Add extracted attributes (like class, id, data-*, aria-*, etc.)
|
|
@@ -229,8 +241,21 @@ export function buildLinkNode(
|
|
|
229
241
|
|
|
230
242
|
// Build children recursively
|
|
231
243
|
const linkNodeChildren = deps.buildChildren(children, {
|
|
232
|
-
elementPath,
|
|
233
|
-
|
|
244
|
+
elementPath,
|
|
245
|
+
parentComponentName: effectiveParentComponentName,
|
|
246
|
+
viewportWidth,
|
|
247
|
+
componentContext,
|
|
248
|
+
componentRootPath,
|
|
249
|
+
locale,
|
|
250
|
+
i18nConfig,
|
|
251
|
+
cmsContext,
|
|
252
|
+
cmsLocale,
|
|
253
|
+
collectionItemsMap,
|
|
254
|
+
itemContext,
|
|
255
|
+
cmsItemIndexPath,
|
|
256
|
+
cmsListPaths,
|
|
257
|
+
templateContext,
|
|
258
|
+
componentResolvedProps,
|
|
234
259
|
});
|
|
235
260
|
|
|
236
261
|
return h('div', linkNodeProps, linkNodeChildren);
|
|
@@ -5,56 +5,76 @@
|
|
|
5
5
|
* - CMS collections (sourceType: 'collection')
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { createElement as h, Fragment } from
|
|
9
|
-
import type { ReactElement } from
|
|
10
|
-
import type { ListNode } from
|
|
11
|
-
import type { CMSItem, CMSFilterCondition, CMSSortConfig, CMSFilterOperator } from
|
|
12
|
-
import { singularize, isItemDraftForLocale } from
|
|
13
|
-
import { buildTemplateContext, resolveItemsTemplate, getNestedValue } from
|
|
14
|
-
import type { TemplateContext } from
|
|
15
|
-
import { pathToString } from
|
|
16
|
-
import { extractAttributesFromNode } from
|
|
17
|
-
import type { ElementRegistry } from
|
|
18
|
-
import type { BuilderContext, BuildResult, BuildChildrenContext } from
|
|
8
|
+
import { createElement as h, Fragment } from 'react';
|
|
9
|
+
import type { ReactElement } from 'react';
|
|
10
|
+
import type { ListNode } from '../../../shared/registry/nodeTypes/ListNodeType';
|
|
11
|
+
import type { CMSItem, CMSFilterCondition, CMSSortConfig, CMSFilterOperator } from '../../../shared/types/cms';
|
|
12
|
+
import { singularize, isItemDraftForLocale } from '../../../shared/types/cms';
|
|
13
|
+
import { buildTemplateContext, resolveItemsTemplate, getNestedValue } from '../../../shared/itemTemplateUtils';
|
|
14
|
+
import type { TemplateContext } from '../../../shared/types/cms';
|
|
15
|
+
import { pathToString } from '../../../shared/pathArrayUtils';
|
|
16
|
+
import { extractAttributesFromNode } from '../../../shared/attributeNodeUtils';
|
|
17
|
+
import type { ElementRegistry } from '../../elementRegistry';
|
|
18
|
+
import type { BuilderContext, BuildResult, BuildChildrenContext } from './types';
|
|
19
19
|
|
|
20
20
|
export interface ListBuilderDeps {
|
|
21
21
|
elementRegistry: ElementRegistry;
|
|
22
|
-
buildChildren: (
|
|
23
|
-
children: unknown,
|
|
24
|
-
ctx: BuildChildrenContext
|
|
25
|
-
) => BuildResult;
|
|
22
|
+
buildChildren: (children: unknown, ctx: BuildChildrenContext) => BuildResult;
|
|
26
23
|
getEffectiveParentComponentName: (
|
|
27
24
|
componentContext: string | null,
|
|
28
|
-
parentComponentName: string | null
|
|
25
|
+
parentComponentName: string | null,
|
|
29
26
|
) => string | null;
|
|
30
27
|
}
|
|
31
28
|
|
|
32
29
|
/**
|
|
33
30
|
* Build a unified list node - handles both prop and collection source types
|
|
34
31
|
*/
|
|
35
|
-
export function buildList(
|
|
36
|
-
node: ListNode,
|
|
37
|
-
children: unknown,
|
|
38
|
-
ctx: BuilderContext,
|
|
39
|
-
deps: ListBuilderDeps
|
|
40
|
-
): ReactElement {
|
|
32
|
+
export function buildList(node: ListNode, children: unknown, ctx: BuilderContext, deps: ListBuilderDeps): ReactElement {
|
|
41
33
|
const {
|
|
42
|
-
key,
|
|
43
|
-
|
|
44
|
-
|
|
34
|
+
key,
|
|
35
|
+
elementPath,
|
|
36
|
+
parentComponentName,
|
|
37
|
+
viewportWidth,
|
|
38
|
+
componentContext,
|
|
39
|
+
componentRootPath,
|
|
40
|
+
locale,
|
|
41
|
+
i18nConfig,
|
|
42
|
+
cmsContext,
|
|
43
|
+
cmsLocale,
|
|
44
|
+
collectionItemsMap = {},
|
|
45
|
+
cmsItemIndexPath,
|
|
46
|
+
cmsListPaths,
|
|
47
|
+
templateContext,
|
|
48
|
+
componentResolvedProps,
|
|
45
49
|
} = ctx;
|
|
46
50
|
|
|
47
51
|
// Determine source type (default to 'prop', but handle legacy 'cms-list' type)
|
|
48
52
|
const nodeType = (node as any).type;
|
|
49
53
|
const isLegacyCMSList = nodeType === 'cms-list';
|
|
50
|
-
const sourceType = isLegacyCMSList ? 'collection' :
|
|
54
|
+
const sourceType = isLegacyCMSList ? 'collection' : node.sourceType || 'prop';
|
|
51
55
|
const isCollectionMode = sourceType === 'collection';
|
|
56
|
+
// Remote lists (sourceType: 'remote') are fetched by the meno-astro runtime (getRemoteData)
|
|
57
|
+
// at build/SSR. In the editor canvas there's no Astro runtime, so the studio pre-fetches the
|
|
58
|
+
// endpoint's items and injects them into `collectionItemsMap` keyed by the endpoint URL — the
|
|
59
|
+
// same channel CMS collections use. We then reuse the collection query path (filter/sort/
|
|
60
|
+
// offset/limit) so the canvas matches what the real build renders.
|
|
61
|
+
const isRemoteMode = sourceType === 'remote';
|
|
62
|
+
const remoteUrl = isRemoteMode && typeof node.url === 'string' ? node.url : '';
|
|
63
|
+
// Sanity lists (sourceType: 'sanity') are fetched by the meno-astro runtime (getSanityData)
|
|
64
|
+
// at build/SSR. Like remote lists, the editor canvas has no Astro runtime, so the studio
|
|
65
|
+
// pre-fetches sample items (via /api/sanity-sample) and injects them into `collectionItemsMap`
|
|
66
|
+
// keyed by the document type — the same channel CMS/remote lists use.
|
|
67
|
+
const isSanityMode = sourceType === 'sanity';
|
|
68
|
+
const sanityKey = isSanityMode && typeof node.documentType === 'string' ? node.documentType : '';
|
|
52
69
|
|
|
53
70
|
// Get source - handle both new 'source' and legacy 'collection' property
|
|
54
71
|
// Source can be a string (prop name) or array (pre-resolved by processStructure)
|
|
55
72
|
const rawSource = node.source || (node as any).collection;
|
|
56
73
|
const source = typeof rawSource === 'string' ? rawSource : '';
|
|
57
74
|
const sourceIsResolved = Array.isArray(rawSource);
|
|
75
|
+
// Unified "do we have something to render from?" flag (remote keys off its URL, sanity off its type).
|
|
76
|
+
const hasSource =
|
|
77
|
+
sourceIsResolved || Boolean(source) || (isRemoteMode && Boolean(remoteUrl)) || (isSanityMode && Boolean(sanityKey));
|
|
58
78
|
|
|
59
79
|
const effectiveParentComponentName = deps.getEffectiveParentComponentName(componentContext, parentComponentName);
|
|
60
80
|
|
|
@@ -62,12 +82,12 @@ export function buildList(
|
|
|
62
82
|
const extractedAttributes = extractAttributesFromNode(node as any);
|
|
63
83
|
|
|
64
84
|
// Build container props with appropriate data attributes
|
|
65
|
-
const containerProps: Record<string,
|
|
85
|
+
const containerProps: Record<string, unknown> = {
|
|
66
86
|
key,
|
|
67
87
|
'data-element-path': pathToString(elementPath),
|
|
68
88
|
ref: (el: HTMLElement | null) => {
|
|
69
89
|
deps.elementRegistry.register(elementPath, el, effectiveParentComponentName, false);
|
|
70
|
-
}
|
|
90
|
+
},
|
|
71
91
|
};
|
|
72
92
|
|
|
73
93
|
// Set data attributes based on source type
|
|
@@ -75,6 +95,14 @@ export function buildList(
|
|
|
75
95
|
containerProps['data-cms-list'] = 'true';
|
|
76
96
|
if (isCollectionMode) {
|
|
77
97
|
containerProps['data-collection'] = source || '';
|
|
98
|
+
} else if (isRemoteMode) {
|
|
99
|
+
containerProps['data-list'] = 'true';
|
|
100
|
+
containerProps['data-source-type'] = 'remote';
|
|
101
|
+
containerProps['data-source'] = remoteUrl;
|
|
102
|
+
} else if (isSanityMode) {
|
|
103
|
+
containerProps['data-list'] = 'true';
|
|
104
|
+
containerProps['data-source-type'] = 'sanity';
|
|
105
|
+
containerProps['data-source'] = sanityKey;
|
|
78
106
|
} else {
|
|
79
107
|
containerProps['data-list'] = 'true';
|
|
80
108
|
containerProps['data-source'] = source || (sourceIsResolved ? 'resolved' : '');
|
|
@@ -112,6 +140,19 @@ export function buildList(
|
|
|
112
140
|
|
|
113
141
|
if (isCollectionMode) {
|
|
114
142
|
itemsToRender = getCollectionItems(node, source, ctx);
|
|
143
|
+
} else if (isRemoteMode) {
|
|
144
|
+
// Remote items are injected into collectionItemsMap keyed by URL; reuse the collection
|
|
145
|
+
// query path so filter/sort/offset/limit behave identically to the Astro runtime.
|
|
146
|
+
itemsToRender = getCollectionItems(node, remoteUrl, ctx);
|
|
147
|
+
} else if (isSanityMode) {
|
|
148
|
+
// Sanity sample items are injected into collectionItemsMap keyed by document type; reuse
|
|
149
|
+
// the collection query path so filter/sort/offset/limit match the Astro runtime.
|
|
150
|
+
itemsToRender = getCollectionItems(node, sanityKey, ctx);
|
|
151
|
+
} else if (sourceType === 'expression') {
|
|
152
|
+
// Expression mode: the source is a verbatim JS expression (an Astro Action / supabase result,
|
|
153
|
+
// …) with no data in the editor — it resolves only in the real Astro build/play. Render empty
|
|
154
|
+
// here; the item template is still editable. (Mirrors ssrRenderer's expression branch.)
|
|
155
|
+
itemsToRender = [];
|
|
115
156
|
} else {
|
|
116
157
|
// Prop mode: Read from component props or template context
|
|
117
158
|
// If source was already resolved to an array by processStructure (e.g., from {{features}}),
|
|
@@ -139,26 +180,30 @@ export function buildList(
|
|
|
139
180
|
const bgColor = isCollectionMode ? 'rgba(139, 92, 246, 0.05)' : 'rgba(59, 130, 246, 0.05)';
|
|
140
181
|
const borderColor = isCollectionMode ? 'rgba(139, 92, 246, 0.3)' : 'rgba(59, 130, 246, 0.3)';
|
|
141
182
|
const textColor = isCollectionMode ? '#8b5cf6' : '#3b82f6';
|
|
142
|
-
const label = isCollectionMode ? 'CMS List' : 'List';
|
|
183
|
+
const label = isCollectionMode ? 'CMS List' : isRemoteMode ? 'Remote List' : isSanityMode ? 'Sanity List' : 'List';
|
|
143
184
|
|
|
144
185
|
// Use configurable tag (defaults to 'div') - null means fragment mode (no wrapper)
|
|
145
186
|
const tag = typeof node.tag === 'string' ? node.tag : null;
|
|
146
187
|
|
|
147
|
-
if (!
|
|
188
|
+
if (!hasSource) {
|
|
148
189
|
// No source - render empty container with placeholder
|
|
149
|
-
const emptyState = h(
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
190
|
+
const emptyState = h(
|
|
191
|
+
'div',
|
|
192
|
+
{
|
|
193
|
+
key: 'list-empty',
|
|
194
|
+
style: {
|
|
195
|
+
padding: '12px',
|
|
196
|
+
background: bgColor,
|
|
197
|
+
border: `1px dashed ${borderColor}`,
|
|
198
|
+
borderRadius: '4px',
|
|
199
|
+
color: textColor,
|
|
200
|
+
fontSize: '12px',
|
|
201
|
+
fontFamily: 'system-ui, sans-serif',
|
|
202
|
+
textAlign: 'center',
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
`${label}: No source - No items`,
|
|
206
|
+
);
|
|
162
207
|
if (tag === null) {
|
|
163
208
|
return emptyState;
|
|
164
209
|
}
|
|
@@ -167,19 +212,23 @@ export function buildList(
|
|
|
167
212
|
|
|
168
213
|
if (itemsToRender.length === 0) {
|
|
169
214
|
// No items - render empty container with placeholder
|
|
170
|
-
const emptyState = h(
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
215
|
+
const emptyState = h(
|
|
216
|
+
'div',
|
|
217
|
+
{
|
|
218
|
+
key: 'list-empty',
|
|
219
|
+
style: {
|
|
220
|
+
padding: '12px',
|
|
221
|
+
background: bgColor,
|
|
222
|
+
border: `1px dashed ${borderColor}`,
|
|
223
|
+
borderRadius: '4px',
|
|
224
|
+
color: textColor,
|
|
225
|
+
fontSize: '12px',
|
|
226
|
+
fontFamily: 'system-ui, sans-serif',
|
|
227
|
+
textAlign: 'center',
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
`${label}: ${source || remoteUrl || sanityKey || 'resolved'} - No items`,
|
|
231
|
+
);
|
|
183
232
|
if (tag === null) {
|
|
184
233
|
return emptyState;
|
|
185
234
|
}
|
|
@@ -197,7 +246,7 @@ export function buildList(
|
|
|
197
246
|
item as CMSItem,
|
|
198
247
|
index,
|
|
199
248
|
itemsToRender.length,
|
|
200
|
-
templateContext || undefined
|
|
249
|
+
templateContext || undefined,
|
|
201
250
|
);
|
|
202
251
|
|
|
203
252
|
// Build children with item context
|
|
@@ -220,7 +269,7 @@ export function buildList(
|
|
|
220
269
|
cmsItemIndexPath: newIndexPath,
|
|
221
270
|
cmsListPaths: newListPaths,
|
|
222
271
|
templateContext: itemTemplateContext,
|
|
223
|
-
componentResolvedProps
|
|
272
|
+
componentResolvedProps,
|
|
224
273
|
});
|
|
225
274
|
|
|
226
275
|
// Add children directly (no wrapper div).
|
|
@@ -241,7 +290,10 @@ export function buildList(
|
|
|
241
290
|
}
|
|
242
291
|
} else if (typeof itemChildren === 'object' && itemChildren !== null && 'key' in itemChildren) {
|
|
243
292
|
// Single child - ensure unique key
|
|
244
|
-
renderedItems.push({
|
|
293
|
+
renderedItems.push({
|
|
294
|
+
...itemChildren,
|
|
295
|
+
key: `${(itemChildren as ReactElement).key}-item-${itemKey}`,
|
|
296
|
+
} as ReactElement);
|
|
245
297
|
} else {
|
|
246
298
|
renderedItems.push(itemChildren);
|
|
247
299
|
}
|
|
@@ -262,15 +314,15 @@ export function buildList(
|
|
|
262
314
|
*/
|
|
263
315
|
function getCollectionItems(node: ListNode, source: string, ctx: BuilderContext): CMSItem[] {
|
|
264
316
|
const { collectionItemsMap = {}, cmsContext, templateContext } = ctx;
|
|
265
|
-
const collectionItems = source ?
|
|
317
|
+
const collectionItems = source ? collectionItemsMap[source] || [] : [];
|
|
266
318
|
|
|
267
319
|
// Helper to lookup items by ID or filename
|
|
268
320
|
const lookupItemsByIds = (ids: string[], items: CMSItem[]): CMSItem[] => {
|
|
269
|
-
const itemMap = new Map(items.map(item => [item._id, item]));
|
|
270
|
-
const filenameMap = new Map(items.map(item => [item._filename, item]));
|
|
321
|
+
const itemMap = new Map(items.map((item) => [item._id, item]));
|
|
322
|
+
const filenameMap = new Map(items.map((item) => [item._filename, item]));
|
|
271
323
|
return ids
|
|
272
324
|
.filter(Boolean)
|
|
273
|
-
.map(id => itemMap.get(id) || filenameMap.get(id))
|
|
325
|
+
.map((id) => itemMap.get(id) || filenameMap.get(id))
|
|
274
326
|
.filter((item): item is CMSItem => item !== undefined);
|
|
275
327
|
};
|
|
276
328
|
|
|
@@ -295,7 +347,7 @@ function getCollectionItems(node: ListNode, source: string, ctx: BuilderContext)
|
|
|
295
347
|
}
|
|
296
348
|
}
|
|
297
349
|
if (value !== null && value !== undefined) {
|
|
298
|
-
resolvedIds = Array.isArray(value) ? value.map(v => String(v)) : String(value);
|
|
350
|
+
resolvedIds = Array.isArray(value) ? value.map((v) => String(v)) : String(value);
|
|
299
351
|
}
|
|
300
352
|
} else {
|
|
301
353
|
// Otherwise resolve from template context (for nested lists)
|
|
@@ -315,7 +367,12 @@ function getCollectionItems(node: ListNode, source: string, ctx: BuilderContext)
|
|
|
315
367
|
|
|
316
368
|
// Apply filters and sorting to referenced items
|
|
317
369
|
if (node.filter) {
|
|
318
|
-
itemsToRender = applyClientFilters(
|
|
370
|
+
itemsToRender = applyClientFilters(
|
|
371
|
+
itemsToRender,
|
|
372
|
+
node.filter as CMSFilterCondition | CMSFilterCondition[] | Record<string, unknown>,
|
|
373
|
+
cmsContext ?? undefined,
|
|
374
|
+
templateContext ?? undefined,
|
|
375
|
+
);
|
|
319
376
|
}
|
|
320
377
|
if (node.sort) {
|
|
321
378
|
itemsToRender = applyClientSorting(itemsToRender, node.sort);
|
|
@@ -326,7 +383,12 @@ function getCollectionItems(node: ListNode, source: string, ctx: BuilderContext)
|
|
|
326
383
|
|
|
327
384
|
// Apply filters (BEFORE offset/limit)
|
|
328
385
|
if (node.filter) {
|
|
329
|
-
itemsToRender = applyClientFilters(
|
|
386
|
+
itemsToRender = applyClientFilters(
|
|
387
|
+
itemsToRender,
|
|
388
|
+
node.filter as CMSFilterCondition | CMSFilterCondition[] | Record<string, unknown>,
|
|
389
|
+
cmsContext ?? undefined,
|
|
390
|
+
templateContext ?? undefined,
|
|
391
|
+
);
|
|
330
392
|
}
|
|
331
393
|
|
|
332
394
|
// Apply sorting (BEFORE offset/limit)
|
|
@@ -346,13 +408,13 @@ function getCollectionItems(node: ListNode, source: string, ctx: BuilderContext)
|
|
|
346
408
|
// Filter draft items for the current locale
|
|
347
409
|
const locale = ctx.locale || ctx.cmsLocale;
|
|
348
410
|
if (locale) {
|
|
349
|
-
itemsToRender = itemsToRender.filter(item => !isItemDraftForLocale(item, locale));
|
|
411
|
+
itemsToRender = itemsToRender.filter((item) => !isItemDraftForLocale(item, locale));
|
|
350
412
|
}
|
|
351
413
|
|
|
352
414
|
// Exclude current item if option is set and we have a current CMS context
|
|
353
415
|
if (node.excludeCurrentItem && cmsContext && (cmsContext as any)._id) {
|
|
354
416
|
const currentId = (cmsContext as any)._id as string;
|
|
355
|
-
itemsToRender = itemsToRender.filter(item => item._id !== currentId);
|
|
417
|
+
itemsToRender = itemsToRender.filter((item) => item._id !== currentId);
|
|
356
418
|
}
|
|
357
419
|
|
|
358
420
|
return itemsToRender;
|
|
@@ -408,23 +470,21 @@ function applyClientFilters(
|
|
|
408
470
|
items: CMSItem[],
|
|
409
471
|
filter: CMSFilterCondition | CMSFilterCondition[] | Record<string, unknown>,
|
|
410
472
|
cmsContext?: Record<string, unknown>,
|
|
411
|
-
templateContext?: TemplateContext
|
|
473
|
+
templateContext?: TemplateContext,
|
|
412
474
|
): CMSItem[] {
|
|
413
475
|
// Handle simple object filter: { featured: true }
|
|
414
476
|
if (!Array.isArray(filter) && !isFilterCondition(filter)) {
|
|
415
|
-
return items.filter(item =>
|
|
477
|
+
return items.filter((item) =>
|
|
416
478
|
Object.entries(filter).every(([key, value]) => {
|
|
417
479
|
const resolvedValue = resolveTemplateValue(value, cmsContext, templateContext);
|
|
418
480
|
return item[key] === resolvedValue;
|
|
419
|
-
})
|
|
481
|
+
}),
|
|
420
482
|
);
|
|
421
483
|
}
|
|
422
484
|
|
|
423
485
|
// Handle array of conditions or single condition
|
|
424
486
|
const conditions = Array.isArray(filter) ? filter : [filter as CMSFilterCondition];
|
|
425
|
-
return items.filter(item =>
|
|
426
|
-
conditions.every(cond => matchCondition(item, cond, cmsContext, templateContext))
|
|
427
|
-
);
|
|
487
|
+
return items.filter((item) => conditions.every((cond) => matchCondition(item, cond, cmsContext, templateContext)));
|
|
428
488
|
}
|
|
429
489
|
|
|
430
490
|
function isFilterCondition(obj: unknown): obj is CMSFilterCondition {
|
|
@@ -437,7 +497,7 @@ function isFilterCondition(obj: unknown): obj is CMSFilterCondition {
|
|
|
437
497
|
function resolveTemplateValue(
|
|
438
498
|
value: unknown,
|
|
439
499
|
cmsContext?: Record<string, unknown>,
|
|
440
|
-
templateContext?: TemplateContext
|
|
500
|
+
templateContext?: TemplateContext,
|
|
441
501
|
): unknown {
|
|
442
502
|
if (typeof value !== 'string' || !value.startsWith('{{') || !value.endsWith('}}')) {
|
|
443
503
|
return value;
|
|
@@ -474,32 +534,38 @@ function matchCondition(
|
|
|
474
534
|
item: CMSItem,
|
|
475
535
|
condition: CMSFilterCondition,
|
|
476
536
|
cmsContext?: Record<string, unknown>,
|
|
477
|
-
templateContext?: TemplateContext
|
|
537
|
+
templateContext?: TemplateContext,
|
|
478
538
|
): boolean {
|
|
479
539
|
const value = item[condition.field];
|
|
480
540
|
const target = resolveTemplateValue(condition.value, cmsContext, templateContext);
|
|
481
541
|
const op: CMSFilterOperator = condition.operator || 'eq';
|
|
482
542
|
|
|
483
543
|
switch (op) {
|
|
484
|
-
case 'eq':
|
|
485
|
-
|
|
486
|
-
case '
|
|
487
|
-
|
|
488
|
-
case '
|
|
489
|
-
|
|
490
|
-
case '
|
|
491
|
-
|
|
492
|
-
|
|
544
|
+
case 'eq':
|
|
545
|
+
return value === target;
|
|
546
|
+
case 'neq':
|
|
547
|
+
return value !== target;
|
|
548
|
+
case 'gt':
|
|
549
|
+
return typeof value === 'number' && typeof target === 'number' && value > target;
|
|
550
|
+
case 'gte':
|
|
551
|
+
return typeof value === 'number' && typeof target === 'number' && value >= target;
|
|
552
|
+
case 'lt':
|
|
553
|
+
return typeof value === 'number' && typeof target === 'number' && value < target;
|
|
554
|
+
case 'lte':
|
|
555
|
+
return typeof value === 'number' && typeof target === 'number' && value <= target;
|
|
556
|
+
case 'contains':
|
|
557
|
+
return typeof value === 'string' && typeof target === 'string' && value.includes(target);
|
|
558
|
+
case 'in':
|
|
559
|
+
return Array.isArray(target) && target.includes(value);
|
|
560
|
+
default:
|
|
561
|
+
return false;
|
|
493
562
|
}
|
|
494
563
|
}
|
|
495
564
|
|
|
496
565
|
/**
|
|
497
566
|
* Apply sorting to items (client-side)
|
|
498
567
|
*/
|
|
499
|
-
function applyClientSorting(
|
|
500
|
-
items: CMSItem[],
|
|
501
|
-
sort: CMSSortConfig | CMSSortConfig[]
|
|
502
|
-
): CMSItem[] {
|
|
568
|
+
function applyClientSorting(items: CMSItem[], sort: CMSSortConfig | CMSSortConfig[]): CMSItem[] {
|
|
503
569
|
const sorts = Array.isArray(sort) ? sort : [sort];
|
|
504
570
|
|
|
505
571
|
return [...items].sort((a, b) => {
|