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
|
@@ -52,7 +52,7 @@ export function richTextMarkerToHtml(marker: RichTextMarker): string {
|
|
|
52
52
|
*/
|
|
53
53
|
function wrapRichTextProps(
|
|
54
54
|
props: Record<string, unknown>,
|
|
55
|
-
propDefs: Record<string, PropDefinition
|
|
55
|
+
propDefs: Record<string, PropDefinition>,
|
|
56
56
|
): Record<string, unknown> {
|
|
57
57
|
const result = { ...props };
|
|
58
58
|
|
|
@@ -100,39 +100,35 @@ export interface ResolvePropsOptions {
|
|
|
100
100
|
/**
|
|
101
101
|
* Resolves component props by applying defaults and merging with passed props
|
|
102
102
|
* Now includes validation for type safety
|
|
103
|
-
*
|
|
103
|
+
*
|
|
104
104
|
* @param options - Object containing prop definitions, passed props, and children
|
|
105
105
|
* @returns Resolved props object with defaults applied and validated
|
|
106
106
|
*/
|
|
107
107
|
export function resolveComponentProps(options: ResolvePropsOptions): Record<string, unknown> {
|
|
108
108
|
const { propDefs, passedProps, children = [], locale, i18nConfig } = options;
|
|
109
|
-
|
|
109
|
+
|
|
110
110
|
// Validate props against interface definition
|
|
111
111
|
// This provides runtime type checking while maintaining backward compatibility
|
|
112
112
|
try {
|
|
113
113
|
const validationResult = validateComponentProps(propDefs, passedProps);
|
|
114
|
-
|
|
114
|
+
|
|
115
115
|
if (!validationResult.valid && validationResult.errors.length > 0) {
|
|
116
116
|
// Log validation errors but continue (graceful degradation)
|
|
117
117
|
}
|
|
118
|
-
|
|
118
|
+
|
|
119
119
|
// Use validated props (includes coerced values and defaults)
|
|
120
120
|
const validatedProps = validationResult.props;
|
|
121
|
-
|
|
121
|
+
|
|
122
122
|
// Handle children prop separately (not validated by prop validator)
|
|
123
123
|
const resolvedProps: Record<string, unknown> = { ...validatedProps };
|
|
124
|
-
|
|
124
|
+
|
|
125
125
|
// Apply children handling
|
|
126
126
|
if ('children' in propDefs) {
|
|
127
127
|
const childrenPropDef = propDefs.children;
|
|
128
128
|
if (childrenPropDef && typeof childrenPropDef === 'object' && 'default' in childrenPropDef) {
|
|
129
|
-
resolvedProps.children = Array.isArray(children) && children.length > 0
|
|
130
|
-
? children
|
|
131
|
-
: childrenPropDef.default;
|
|
129
|
+
resolvedProps.children = Array.isArray(children) && children.length > 0 ? children : childrenPropDef.default;
|
|
132
130
|
} else {
|
|
133
|
-
resolvedProps.children = Array.isArray(children) && children.length > 0
|
|
134
|
-
? children
|
|
135
|
-
: undefined;
|
|
131
|
+
resolvedProps.children = Array.isArray(children) && children.length > 0 ? children : undefined;
|
|
136
132
|
}
|
|
137
133
|
} else if (Array.isArray(children) && children.length > 0) {
|
|
138
134
|
// Children passed but not in interface - allow it (backward compatibility)
|
|
@@ -150,27 +146,21 @@ export function resolveComponentProps(options: ResolvePropsOptions): Record<stri
|
|
|
150
146
|
// Wrap rich-text props in marker objects for HTML rendering
|
|
151
147
|
// Must happen AFTER i18n resolution so HTML strings get properly wrapped
|
|
152
148
|
return wrapRichTextProps(result, propDefs);
|
|
153
|
-
} catch (
|
|
149
|
+
} catch (_error) {
|
|
154
150
|
// Fallback to original behavior if validation fails (backward compatibility)
|
|
155
151
|
const resolvedProps: Record<string, unknown> = {};
|
|
156
|
-
|
|
152
|
+
|
|
157
153
|
// Apply defaults and passed props (original logic)
|
|
158
154
|
for (const [propName, propDef] of Object.entries(propDefs)) {
|
|
159
155
|
if (propDef && typeof propDef === 'object' && 'default' in propDef) {
|
|
160
156
|
if (propName === 'children') {
|
|
161
|
-
resolvedProps.children = Array.isArray(children) && children.length > 0
|
|
162
|
-
? children
|
|
163
|
-
: propDef.default;
|
|
157
|
+
resolvedProps.children = Array.isArray(children) && children.length > 0 ? children : propDef.default;
|
|
164
158
|
} else {
|
|
165
|
-
resolvedProps[propName] = passedProps[propName] !== undefined
|
|
166
|
-
? passedProps[propName]
|
|
167
|
-
: propDef.default;
|
|
159
|
+
resolvedProps[propName] = passedProps[propName] !== undefined ? passedProps[propName] : propDef.default;
|
|
168
160
|
}
|
|
169
161
|
} else {
|
|
170
162
|
if (propName === 'children') {
|
|
171
|
-
resolvedProps.children = Array.isArray(children) && children.length > 0
|
|
172
|
-
? children
|
|
173
|
-
: undefined;
|
|
163
|
+
resolvedProps.children = Array.isArray(children) && children.length > 0 ? children : undefined;
|
|
174
164
|
} else {
|
|
175
165
|
resolvedProps[propName] = passedProps[propName];
|
|
176
166
|
}
|
|
@@ -197,7 +187,7 @@ export function resolvePropsFromDefinition(
|
|
|
197
187
|
passedProps: Record<string, unknown> = {},
|
|
198
188
|
children: Array<ComponentNode | string> | string | ComponentNode | null | undefined = [],
|
|
199
189
|
locale?: string,
|
|
200
|
-
i18nConfig?: I18nConfig
|
|
190
|
+
i18nConfig?: I18nConfig,
|
|
201
191
|
): Record<string, unknown> {
|
|
202
192
|
const propDefs = componentDef.interface || {};
|
|
203
193
|
return resolveComponentProps({
|
|
@@ -208,4 +198,3 @@ export function resolvePropsFromDefinition(
|
|
|
208
198
|
i18nConfig,
|
|
209
199
|
});
|
|
210
200
|
}
|
|
211
|
-
|
|
@@ -90,14 +90,14 @@ describe('applyRemConversion', () => {
|
|
|
90
90
|
});
|
|
91
91
|
|
|
92
92
|
test('handles multiple declarations', () => {
|
|
93
|
-
expect(applyRemConversion('padding: 16px; margin: 8px;', enabledConfig))
|
|
94
|
-
.toBe('padding: 1rem; margin: 0.5rem');
|
|
93
|
+
expect(applyRemConversion('padding: 16px; margin: 8px;', enabledConfig)).toBe('padding: 1rem; margin: 0.5rem');
|
|
95
94
|
});
|
|
96
95
|
|
|
97
96
|
test('preserves excluded properties', () => {
|
|
98
97
|
expect(applyRemConversion('border-width: 1px;', enabledConfig)).toBe('border-width: 1px');
|
|
99
|
-
expect(applyRemConversion('box-shadow: 0 1px 2px rgba(0,0,0,0.1);', enabledConfig))
|
|
100
|
-
|
|
98
|
+
expect(applyRemConversion('box-shadow: 0 1px 2px rgba(0,0,0,0.1);', enabledConfig)).toBe(
|
|
99
|
+
'box-shadow: 0 1px 2px rgba(0,0,0,0.1)',
|
|
100
|
+
);
|
|
101
101
|
});
|
|
102
102
|
|
|
103
103
|
test('returns unchanged when disabled', () => {
|
|
@@ -109,7 +109,8 @@ describe('applyRemConversion', () => {
|
|
|
109
109
|
});
|
|
110
110
|
|
|
111
111
|
test('handles mixed convertible and non-convertible', () => {
|
|
112
|
-
expect(applyRemConversion('padding: 16px; border-width: 1px; margin: 8px;', enabledConfig))
|
|
113
|
-
|
|
112
|
+
expect(applyRemConversion('padding: 16px; border-width: 1px; margin: 8px;', enabledConfig)).toBe(
|
|
113
|
+
'padding: 1rem; border-width: 1px; margin: 0.5rem',
|
|
114
|
+
);
|
|
114
115
|
});
|
|
115
116
|
});
|
package/lib/shared/pxToRem.ts
CHANGED
|
@@ -50,15 +50,12 @@ export function shouldConvertProperty(cssProperty: string): boolean {
|
|
|
50
50
|
* Apply rem conversion to a CSS declarations string (e.g. "padding: 16px; font-size: 18px").
|
|
51
51
|
* Checks each property against the exclusion list before converting.
|
|
52
52
|
*/
|
|
53
|
-
export function applyRemConversion(
|
|
54
|
-
declarations: string,
|
|
55
|
-
remConfig?: RemConversionConfig
|
|
56
|
-
): string {
|
|
53
|
+
export function applyRemConversion(declarations: string, remConfig?: RemConversionConfig): string {
|
|
57
54
|
if (!remConfig?.enabled) return declarations;
|
|
58
55
|
|
|
59
56
|
return declarations
|
|
60
57
|
.split(';')
|
|
61
|
-
.map(decl => {
|
|
58
|
+
.map((decl) => {
|
|
62
59
|
const trimmed = decl.trim();
|
|
63
60
|
if (!trimmed) return '';
|
|
64
61
|
const colonIndex = trimmed.indexOf(':');
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
import { describe, it, expect, beforeEach } from 'bun:test';
|
|
6
6
|
import { ClientNodeTypeRegistry } from './ClientNodeTypeRegistry';
|
|
7
|
-
import { SSRNodeTypeRegistry } from './SSRNodeTypeRegistry';
|
|
8
7
|
import { NodeTypeManager, globalNodeTypeManager } from './NodeTypeManager';
|
|
9
8
|
import { defineNodeType } from './defineNodeType';
|
|
10
9
|
import { registerBuiltInNodeTypes, builtInNodeTypes } from './nodeTypes';
|
|
@@ -42,10 +41,11 @@ describe('BaseNodeTypeRegistry', () => {
|
|
|
42
41
|
describe('registerAll', () => {
|
|
43
42
|
it('should register multiple node type definitions', () => {
|
|
44
43
|
registry.registerAll(builtInNodeTypes);
|
|
45
|
-
expect(registry.size).toBe(
|
|
44
|
+
expect(registry.size).toBe(10); // node, component, slot, embed, link, locale-list, list, island, markdown, custom
|
|
46
45
|
expect(registry.has(NODE_TYPE.NODE)).toBe(true);
|
|
47
46
|
expect(registry.has(NODE_TYPE.COMPONENT)).toBe(true);
|
|
48
47
|
expect(registry.has(NODE_TYPE.EMBED)).toBe(true);
|
|
48
|
+
expect(registry.has(NODE_TYPE.ISLAND)).toBe(true);
|
|
49
49
|
});
|
|
50
50
|
});
|
|
51
51
|
|
|
@@ -136,14 +136,18 @@ describe('BaseNodeTypeRegistry', () => {
|
|
|
136
136
|
describe('subscribe', () => {
|
|
137
137
|
it('should notify listeners on registration', () => {
|
|
138
138
|
let called = false;
|
|
139
|
-
registry.subscribe(() => {
|
|
139
|
+
registry.subscribe(() => {
|
|
140
|
+
called = true;
|
|
141
|
+
});
|
|
140
142
|
registry.registerAll(builtInNodeTypes);
|
|
141
143
|
expect(called).toBe(true);
|
|
142
144
|
});
|
|
143
145
|
|
|
144
146
|
it('should allow unsubscribing', () => {
|
|
145
147
|
let callCount = 0;
|
|
146
|
-
const unsubscribe = registry.subscribe(() => {
|
|
148
|
+
const unsubscribe = registry.subscribe(() => {
|
|
149
|
+
callCount++;
|
|
150
|
+
});
|
|
147
151
|
registry.registerAll(builtInNodeTypes);
|
|
148
152
|
expect(callCount).toBe(1);
|
|
149
153
|
|
|
@@ -161,7 +165,7 @@ describe('BaseNodeTypeRegistry', () => {
|
|
|
161
165
|
it('should filter by category', () => {
|
|
162
166
|
const coreTypes = registry.getByCategory('core');
|
|
163
167
|
expect(coreTypes.length).toBeGreaterThan(0);
|
|
164
|
-
expect(coreTypes.every(t => t.category === 'core')).toBe(true);
|
|
168
|
+
expect(coreTypes.every((t) => t.category === 'core')).toBe(true);
|
|
165
169
|
});
|
|
166
170
|
});
|
|
167
171
|
});
|
|
@@ -185,6 +189,8 @@ describe('globalNodeTypeManager', () => {
|
|
|
185
189
|
registerBuiltInNodeTypes();
|
|
186
190
|
expect(globalNodeTypeManager.has(NODE_TYPE.NODE)).toBe(true);
|
|
187
191
|
expect(globalNodeTypeManager.has(NODE_TYPE.EMBED)).toBe(true);
|
|
188
|
-
expect(globalNodeTypeManager.
|
|
192
|
+
expect(globalNodeTypeManager.has(NODE_TYPE.ISLAND)).toBe(true);
|
|
193
|
+
expect(globalNodeTypeManager.has(NODE_TYPE.MARKDOWN)).toBe(true);
|
|
194
|
+
expect(globalNodeTypeManager.getAll().length).toBe(10); // node, component, slot, embed, link, locale-list, list, island, markdown, custom
|
|
189
195
|
});
|
|
190
196
|
});
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { BaseComponentRegistry } from './ComponentRegistry';
|
|
7
|
-
import type { ComponentDefinition } from '../types';
|
|
8
7
|
|
|
9
8
|
export class ClientRegistry extends BaseComponentRegistry {
|
|
10
9
|
/**
|
|
@@ -12,4 +11,3 @@ export class ClientRegistry extends BaseComponentRegistry {
|
|
|
12
11
|
* For now, it's the same as base registry
|
|
13
12
|
*/
|
|
14
13
|
}
|
|
15
|
-
|
|
@@ -15,7 +15,7 @@ describe('BaseComponentRegistry', () => {
|
|
|
15
15
|
describe('register', () => {
|
|
16
16
|
test('registers a component', () => {
|
|
17
17
|
const component: ComponentDefinition = {
|
|
18
|
-
component: { structure: { type: 'node' as const, tag: 'div' } }
|
|
18
|
+
component: { structure: { type: 'node' as const, tag: 'div' } },
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
registry.register('Button', component);
|
|
@@ -26,10 +26,10 @@ describe('BaseComponentRegistry', () => {
|
|
|
26
26
|
|
|
27
27
|
test('overwrites existing component', () => {
|
|
28
28
|
const component1: ComponentDefinition = {
|
|
29
|
-
component: { structure: { type: 'node' as const, tag: 'div' } }
|
|
29
|
+
component: { structure: { type: 'node' as const, tag: 'div' } },
|
|
30
30
|
};
|
|
31
31
|
const component2: ComponentDefinition = {
|
|
32
|
-
component: { structure: { type: 'node' as const, tag: 'span' } }
|
|
32
|
+
component: { structure: { type: 'node' as const, tag: 'span' } },
|
|
33
33
|
};
|
|
34
34
|
|
|
35
35
|
registry.register('Button', component1);
|
|
@@ -42,7 +42,7 @@ describe('BaseComponentRegistry', () => {
|
|
|
42
42
|
describe('get', () => {
|
|
43
43
|
test('returns component by name', () => {
|
|
44
44
|
const component: ComponentDefinition = {
|
|
45
|
-
component: { structure: { type: 'node' as const, tag: 'div' } }
|
|
45
|
+
component: { structure: { type: 'node' as const, tag: 'div' } },
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
registry.register('Button', component);
|
|
@@ -58,7 +58,7 @@ describe('BaseComponentRegistry', () => {
|
|
|
58
58
|
describe('has', () => {
|
|
59
59
|
test('returns true for registered component', () => {
|
|
60
60
|
const component: ComponentDefinition = {
|
|
61
|
-
component: { structure: { type: 'node' as const, tag: 'div' } }
|
|
61
|
+
component: { structure: { type: 'node' as const, tag: 'div' } },
|
|
62
62
|
};
|
|
63
63
|
|
|
64
64
|
registry.register('Button', component);
|
|
@@ -74,10 +74,10 @@ describe('BaseComponentRegistry', () => {
|
|
|
74
74
|
describe('clear', () => {
|
|
75
75
|
test('removes all components', () => {
|
|
76
76
|
const component1: ComponentDefinition = {
|
|
77
|
-
component: { structure: { type: 'node' as const, tag: 'div' } }
|
|
77
|
+
component: { structure: { type: 'node' as const, tag: 'div' } },
|
|
78
78
|
};
|
|
79
79
|
const component2: ComponentDefinition = {
|
|
80
|
-
component: { structure: { type: 'node' as const, tag: 'span' } }
|
|
80
|
+
component: { structure: { type: 'node' as const, tag: 'span' } },
|
|
81
81
|
};
|
|
82
82
|
|
|
83
83
|
registry.register('Button', component1);
|
|
@@ -94,8 +94,8 @@ describe('BaseComponentRegistry', () => {
|
|
|
94
94
|
describe('merge', () => {
|
|
95
95
|
test('merges multiple components', () => {
|
|
96
96
|
const components: Record<string, ComponentDefinition> = {
|
|
97
|
-
|
|
98
|
-
|
|
97
|
+
Button: { component: { structure: { type: 'node' as const, tag: 'button' } } },
|
|
98
|
+
Card: { component: { structure: { type: 'node' as const, tag: 'div' } } },
|
|
99
99
|
};
|
|
100
100
|
|
|
101
101
|
registry.merge(components);
|
|
@@ -106,14 +106,14 @@ describe('BaseComponentRegistry', () => {
|
|
|
106
106
|
|
|
107
107
|
test('overwrites existing components', () => {
|
|
108
108
|
const component1: ComponentDefinition = {
|
|
109
|
-
component: { structure: { type: 'node' as const, tag: 'div' } }
|
|
109
|
+
component: { structure: { type: 'node' as const, tag: 'div' } },
|
|
110
110
|
};
|
|
111
111
|
const component2: ComponentDefinition = {
|
|
112
|
-
component: { structure: { type: 'node' as const, tag: 'button' } }
|
|
112
|
+
component: { structure: { type: 'node' as const, tag: 'button' } },
|
|
113
113
|
};
|
|
114
114
|
|
|
115
115
|
registry.register('Button', component1);
|
|
116
|
-
registry.merge({
|
|
116
|
+
registry.merge({ Button: component2 });
|
|
117
117
|
|
|
118
118
|
expect(registry.get('Button')).toEqual(component2);
|
|
119
119
|
});
|
|
@@ -122,10 +122,10 @@ describe('BaseComponentRegistry', () => {
|
|
|
122
122
|
describe('getAll', () => {
|
|
123
123
|
test('returns all registered components', () => {
|
|
124
124
|
const component1: ComponentDefinition = {
|
|
125
|
-
component: { structure: { type: 'node' as const, tag: 'button' } }
|
|
125
|
+
component: { structure: { type: 'node' as const, tag: 'button' } },
|
|
126
126
|
};
|
|
127
127
|
const component2: ComponentDefinition = {
|
|
128
|
-
component: { structure: { type: 'node' as const, tag: 'div' } }
|
|
128
|
+
component: { structure: { type: 'node' as const, tag: 'div' } },
|
|
129
129
|
};
|
|
130
130
|
|
|
131
131
|
registry.register('Button', component1);
|
|
@@ -133,20 +133,20 @@ describe('BaseComponentRegistry', () => {
|
|
|
133
133
|
|
|
134
134
|
const all = registry.getAll();
|
|
135
135
|
|
|
136
|
-
expect(all
|
|
137
|
-
expect(all
|
|
136
|
+
expect(all.Button).toEqual(component1);
|
|
137
|
+
expect(all.Card).toEqual(component2);
|
|
138
138
|
expect(Object.keys(all).length).toBe(2);
|
|
139
139
|
});
|
|
140
140
|
|
|
141
141
|
test('returns copy of registry', () => {
|
|
142
142
|
const component: ComponentDefinition = {
|
|
143
|
-
component: { structure: { type: 'node' as const, tag: 'button' } }
|
|
143
|
+
component: { structure: { type: 'node' as const, tag: 'button' } },
|
|
144
144
|
};
|
|
145
145
|
|
|
146
146
|
registry.register('Button', component);
|
|
147
147
|
|
|
148
148
|
const all = registry.getAll();
|
|
149
|
-
delete all
|
|
149
|
+
delete all.Button;
|
|
150
150
|
|
|
151
151
|
expect(registry.has('Button')).toBe(true);
|
|
152
152
|
});
|
|
@@ -159,10 +159,10 @@ describe('BaseComponentRegistry', () => {
|
|
|
159
159
|
describe('getNames', () => {
|
|
160
160
|
test('returns list of component names', () => {
|
|
161
161
|
const component1: ComponentDefinition = {
|
|
162
|
-
component: { structure: { type: 'node' as const, tag: 'button' } }
|
|
162
|
+
component: { structure: { type: 'node' as const, tag: 'button' } },
|
|
163
163
|
};
|
|
164
164
|
const component2: ComponentDefinition = {
|
|
165
|
-
component: { structure: { type: 'node' as const, tag: 'div' } }
|
|
165
|
+
component: { structure: { type: 'node' as const, tag: 'div' } },
|
|
166
166
|
};
|
|
167
167
|
|
|
168
168
|
registry.register('Button', component1);
|
|
@@ -183,7 +183,7 @@ describe('BaseComponentRegistry', () => {
|
|
|
183
183
|
describe('remove', () => {
|
|
184
184
|
test('removes component and returns true', () => {
|
|
185
185
|
const component: ComponentDefinition = {
|
|
186
|
-
component: { structure: { type: 'node' as const, tag: 'button' } }
|
|
186
|
+
component: { structure: { type: 'node' as const, tag: 'button' } },
|
|
187
187
|
};
|
|
188
188
|
|
|
189
189
|
registry.register('Button', component);
|
|
@@ -204,12 +204,14 @@ describe('BaseComponentRegistry', () => {
|
|
|
204
204
|
describe('subscribe', () => {
|
|
205
205
|
test('notifies listeners on register', () => {
|
|
206
206
|
let called = false;
|
|
207
|
-
const listener = () => {
|
|
207
|
+
const listener = () => {
|
|
208
|
+
called = true;
|
|
209
|
+
};
|
|
208
210
|
|
|
209
211
|
registry.subscribe(listener);
|
|
210
212
|
|
|
211
213
|
const component: ComponentDefinition = {
|
|
212
|
-
component: { structure: { type: 'node' as const, tag: 'button' } }
|
|
214
|
+
component: { structure: { type: 'node' as const, tag: 'button' } },
|
|
213
215
|
};
|
|
214
216
|
registry.register('Button', component);
|
|
215
217
|
|
|
@@ -218,7 +220,9 @@ describe('BaseComponentRegistry', () => {
|
|
|
218
220
|
|
|
219
221
|
test('notifies listeners on clear', () => {
|
|
220
222
|
let called = false;
|
|
221
|
-
const listener = () => {
|
|
223
|
+
const listener = () => {
|
|
224
|
+
called = true;
|
|
225
|
+
};
|
|
222
226
|
|
|
223
227
|
registry.subscribe(listener);
|
|
224
228
|
|
|
@@ -229,7 +233,9 @@ describe('BaseComponentRegistry', () => {
|
|
|
229
233
|
|
|
230
234
|
test('notifies listeners on merge', () => {
|
|
231
235
|
let called = false;
|
|
232
|
-
const listener = () => {
|
|
236
|
+
const listener = () => {
|
|
237
|
+
called = true;
|
|
238
|
+
};
|
|
233
239
|
|
|
234
240
|
registry.subscribe(listener);
|
|
235
241
|
|
|
@@ -241,12 +247,14 @@ describe('BaseComponentRegistry', () => {
|
|
|
241
247
|
test('notifies listeners on remove', () => {
|
|
242
248
|
let called = false;
|
|
243
249
|
const component: ComponentDefinition = {
|
|
244
|
-
component: { structure: { type: 'node' as const, tag: 'button' } }
|
|
250
|
+
component: { structure: { type: 'node' as const, tag: 'button' } },
|
|
245
251
|
};
|
|
246
252
|
|
|
247
253
|
registry.register('Button', component);
|
|
248
254
|
|
|
249
|
-
const listener = () => {
|
|
255
|
+
const listener = () => {
|
|
256
|
+
called = true;
|
|
257
|
+
};
|
|
250
258
|
registry.subscribe(listener);
|
|
251
259
|
|
|
252
260
|
registry.remove('Button');
|
|
@@ -256,12 +264,14 @@ describe('BaseComponentRegistry', () => {
|
|
|
256
264
|
|
|
257
265
|
test('returns unsubscribe function', () => {
|
|
258
266
|
let callCount = 0;
|
|
259
|
-
const listener = () => {
|
|
267
|
+
const listener = () => {
|
|
268
|
+
callCount++;
|
|
269
|
+
};
|
|
260
270
|
|
|
261
271
|
const unsubscribe = registry.subscribe(listener);
|
|
262
272
|
|
|
263
273
|
const component: ComponentDefinition = {
|
|
264
|
-
component: { structure: { type: 'node' as const, tag: 'button' } }
|
|
274
|
+
component: { structure: { type: 'node' as const, tag: 'button' } },
|
|
265
275
|
};
|
|
266
276
|
registry.register('Button', component);
|
|
267
277
|
|
|
@@ -275,14 +285,18 @@ describe('BaseComponentRegistry', () => {
|
|
|
275
285
|
test('handles multiple listeners', () => {
|
|
276
286
|
let count1 = 0;
|
|
277
287
|
let count2 = 0;
|
|
278
|
-
const listener1 = () => {
|
|
279
|
-
|
|
288
|
+
const listener1 = () => {
|
|
289
|
+
count1++;
|
|
290
|
+
};
|
|
291
|
+
const listener2 = () => {
|
|
292
|
+
count2++;
|
|
293
|
+
};
|
|
280
294
|
|
|
281
295
|
registry.subscribe(listener1);
|
|
282
296
|
registry.subscribe(listener2);
|
|
283
297
|
|
|
284
298
|
const component: ComponentDefinition = {
|
|
285
|
-
component: { structure: { type: 'node' as const, tag: 'button' } }
|
|
299
|
+
component: { structure: { type: 'node' as const, tag: 'button' } },
|
|
286
300
|
};
|
|
287
301
|
registry.register('Button', component);
|
|
288
302
|
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import type { ComponentDefinition } from '../types';
|
|
8
|
+
import { logRuntimeError } from '../errorLogger';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Base registry class with common functionality
|
|
@@ -12,7 +13,7 @@ import type { ComponentDefinition } from '../types';
|
|
|
12
13
|
export abstract class BaseComponentRegistry {
|
|
13
14
|
protected registry: Record<string, ComponentDefinition> = {};
|
|
14
15
|
private listeners: Set<() => void> = new Set();
|
|
15
|
-
|
|
16
|
+
|
|
16
17
|
/**
|
|
17
18
|
* Register a component with the given name
|
|
18
19
|
*/
|
|
@@ -20,21 +21,21 @@ export abstract class BaseComponentRegistry {
|
|
|
20
21
|
this.registry[name] = definition;
|
|
21
22
|
this.notify();
|
|
22
23
|
}
|
|
23
|
-
|
|
24
|
+
|
|
24
25
|
/**
|
|
25
26
|
* Get a component by name
|
|
26
27
|
*/
|
|
27
28
|
get(name: string): ComponentDefinition | undefined {
|
|
28
29
|
return this.registry[name];
|
|
29
30
|
}
|
|
30
|
-
|
|
31
|
+
|
|
31
32
|
/**
|
|
32
33
|
* Check if a component exists
|
|
33
34
|
*/
|
|
34
35
|
has(name: string): boolean {
|
|
35
36
|
return name in this.registry;
|
|
36
37
|
}
|
|
37
|
-
|
|
38
|
+
|
|
38
39
|
/**
|
|
39
40
|
* Clear all registered components
|
|
40
41
|
*/
|
|
@@ -42,7 +43,7 @@ export abstract class BaseComponentRegistry {
|
|
|
42
43
|
this.registry = {};
|
|
43
44
|
this.notify();
|
|
44
45
|
}
|
|
45
|
-
|
|
46
|
+
|
|
46
47
|
/**
|
|
47
48
|
* Merge components into the registry
|
|
48
49
|
* Existing components with the same name will be overwritten
|
|
@@ -51,21 +52,21 @@ export abstract class BaseComponentRegistry {
|
|
|
51
52
|
Object.assign(this.registry, components);
|
|
52
53
|
this.notify();
|
|
53
54
|
}
|
|
54
|
-
|
|
55
|
+
|
|
55
56
|
/**
|
|
56
57
|
* Get all registered components
|
|
57
58
|
*/
|
|
58
59
|
getAll(): Record<string, ComponentDefinition> {
|
|
59
60
|
return { ...this.registry };
|
|
60
61
|
}
|
|
61
|
-
|
|
62
|
+
|
|
62
63
|
/**
|
|
63
64
|
* Get list of registered component names
|
|
64
65
|
*/
|
|
65
66
|
getNames(): string[] {
|
|
66
67
|
return Object.keys(this.registry);
|
|
67
68
|
}
|
|
68
|
-
|
|
69
|
+
|
|
69
70
|
/**
|
|
70
71
|
* Remove a component by name
|
|
71
72
|
*/
|
|
@@ -93,8 +94,10 @@ export abstract class BaseComponentRegistry {
|
|
|
93
94
|
try {
|
|
94
95
|
listener();
|
|
95
96
|
} catch (err) {
|
|
97
|
+
// One throwing subscriber must not stop the rest from being notified, but
|
|
98
|
+
// a swallowed listener error hides real store-update bugs — surface it.
|
|
99
|
+
logRuntimeError('ComponentRegistry.notify', err);
|
|
96
100
|
}
|
|
97
101
|
}
|
|
98
102
|
}
|
|
99
103
|
}
|
|
100
|
-
|
|
@@ -6,12 +6,22 @@
|
|
|
6
6
|
import type { ReactElement } from 'react';
|
|
7
7
|
import type { ZodType } from 'zod';
|
|
8
8
|
import type { ComponentNode } from '../types/nodes';
|
|
9
|
-
import type { StyleValue } from '../types/styles';
|
|
10
9
|
|
|
11
10
|
/**
|
|
12
11
|
* Tree icon types for node display
|
|
13
12
|
*/
|
|
14
|
-
export type TreeIcon =
|
|
13
|
+
export type TreeIcon =
|
|
14
|
+
| 'TEXT'
|
|
15
|
+
| 'COMPONENT'
|
|
16
|
+
| 'HTML_ELEMENT'
|
|
17
|
+
| 'IMAGE'
|
|
18
|
+
| 'OBJECT'
|
|
19
|
+
| 'SLOT_MARKER'
|
|
20
|
+
| 'ARRAY'
|
|
21
|
+
| 'UNKNOWN'
|
|
22
|
+
| 'FORM'
|
|
23
|
+
| 'LINK'
|
|
24
|
+
| 'CODE';
|
|
15
25
|
|
|
16
26
|
/**
|
|
17
27
|
* Node category for grouping in command palette
|
|
@@ -83,13 +93,13 @@ export interface ClientRenderContext {
|
|
|
83
93
|
children: Array<ComponentNode | string> | string | undefined,
|
|
84
94
|
elementPath: (string | number)[],
|
|
85
95
|
parentComponentName?: string | null,
|
|
86
|
-
componentContext?: string | null
|
|
96
|
+
componentContext?: string | null,
|
|
87
97
|
) => ReactElement | ReactElement[] | string | number | null;
|
|
88
98
|
registerElement: (
|
|
89
99
|
path: (string | number)[],
|
|
90
100
|
element: HTMLElement | null,
|
|
91
101
|
parentComponentName?: string | null,
|
|
92
|
-
isComponentRoot?: boolean
|
|
102
|
+
isComponentRoot?: boolean,
|
|
93
103
|
) => void;
|
|
94
104
|
getComponentDefinition: (name: string) => unknown | undefined;
|
|
95
105
|
processI18n: (value: unknown) => string;
|
|
@@ -121,16 +131,13 @@ export interface SSRRenderContext {
|
|
|
121
131
|
*/
|
|
122
132
|
export type ClientNodeRenderer<TNode extends ComponentNode> = (
|
|
123
133
|
node: TNode,
|
|
124
|
-
context: ClientRenderContext
|
|
134
|
+
context: ClientRenderContext,
|
|
125
135
|
) => ReactElement | null;
|
|
126
136
|
|
|
127
137
|
/**
|
|
128
138
|
* SSR renderer function type
|
|
129
139
|
*/
|
|
130
|
-
export type SSRNodeRenderer<TNode extends ComponentNode> = (
|
|
131
|
-
node: TNode,
|
|
132
|
-
context: SSRRenderContext
|
|
133
|
-
) => string;
|
|
140
|
+
export type SSRNodeRenderer<TNode extends ComponentNode> = (node: TNode, context: SSRRenderContext) => string;
|
|
134
141
|
|
|
135
142
|
/**
|
|
136
143
|
* Props editor component props
|
|
@@ -36,7 +36,7 @@ export class RegistryManager {
|
|
|
36
36
|
sync(from: 'client' | 'ssr', to: 'client' | 'ssr'): void {
|
|
37
37
|
const source = from === 'client' ? this.clientRegistry : this.ssrRegistry;
|
|
38
38
|
const target = to === 'client' ? this.clientRegistry : this.ssrRegistry;
|
|
39
|
-
|
|
39
|
+
|
|
40
40
|
const components = source.getAll();
|
|
41
41
|
target.merge(components);
|
|
42
42
|
}
|
|
@@ -57,4 +57,3 @@ export class RegistryManager {
|
|
|
57
57
|
this.ssrRegistry.clear();
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
|
-
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { BaseComponentRegistry } from './ComponentRegistry';
|
|
7
|
-
import type { ComponentDefinition } from '../types';
|
|
8
7
|
|
|
9
8
|
export class SSRRegistry extends BaseComponentRegistry {
|
|
10
9
|
/**
|
|
@@ -12,4 +11,3 @@ export class SSRRegistry extends BaseComponentRegistry {
|
|
|
12
11
|
* For now, it's the same as base registry
|
|
13
12
|
*/
|
|
14
13
|
}
|
|
15
|
-
|
|
@@ -33,10 +33,7 @@ const DEFAULT_CAPABILITIES: NodeCapabilities = {
|
|
|
33
33
|
*/
|
|
34
34
|
function createTypeGuard<T>(typeValue: string) {
|
|
35
35
|
return (node: unknown): node is T =>
|
|
36
|
-
node !== null &&
|
|
37
|
-
typeof node === 'object' &&
|
|
38
|
-
'type' in node &&
|
|
39
|
-
(node as { type: unknown }).type === typeValue;
|
|
36
|
+
node !== null && typeof node === 'object' && 'type' in node && (node as { type: unknown }).type === typeValue;
|
|
40
37
|
}
|
|
41
38
|
|
|
42
39
|
/**
|
|
@@ -118,7 +115,7 @@ export interface CreateNodeTypeInput<TSchema extends ZodType> {
|
|
|
118
115
|
* ```
|
|
119
116
|
*/
|
|
120
117
|
export function createNodeType<TSchema extends ZodType>(
|
|
121
|
-
input: CreateNodeTypeInput<TSchema
|
|
118
|
+
input: CreateNodeTypeInput<TSchema>,
|
|
122
119
|
): NodeTypeDefinition<z.infer<TSchema>> {
|
|
123
120
|
type TNode = z.infer<TSchema>;
|
|
124
121
|
|
|
@@ -152,10 +149,11 @@ export function createNodeType<TSchema extends ZodType>(
|
|
|
152
149
|
typeGuard: createTypeGuard<TNode>(input.type),
|
|
153
150
|
|
|
154
151
|
// Auto-generated default factory
|
|
155
|
-
defaultFactory: (): TNode =>
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
152
|
+
defaultFactory: (): TNode =>
|
|
153
|
+
({
|
|
154
|
+
type: input.type,
|
|
155
|
+
...input.defaultValues,
|
|
156
|
+
}) as TNode,
|
|
159
157
|
|
|
160
158
|
treeDisplay: {
|
|
161
159
|
icon: input.treeDisplay.icon,
|