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
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { describe, test, expect } from 'bun:test';
|
|
2
|
+
import { validatePermissionsPolicy } from './permissionsValidators';
|
|
3
|
+
|
|
4
|
+
describe('validatePermissionsPolicy', () => {
|
|
5
|
+
test('accepts a minimal policy', () => {
|
|
6
|
+
const result = validatePermissionsPolicy({ version: 1 });
|
|
7
|
+
expect(result.valid).toBe(true);
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
test('accepts a full policy with members, teams, roles and allow-lists', () => {
|
|
11
|
+
const result = validatePermissionsPolicy({
|
|
12
|
+
version: 1,
|
|
13
|
+
defaultRole: 'viewer',
|
|
14
|
+
members: {
|
|
15
|
+
alice: { allow: { pages: ['blog/*'], cms: ['posts'] } },
|
|
16
|
+
carol: { role: 'admin' },
|
|
17
|
+
},
|
|
18
|
+
teams: { content: { allow: { cms: ['*'] } } },
|
|
19
|
+
});
|
|
20
|
+
expect(result.valid).toBe(true);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test('rejects a missing version', () => {
|
|
24
|
+
expect(validatePermissionsPolicy({ defaultRole: 'viewer' }).valid).toBe(false);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test('rejects a version below 1', () => {
|
|
28
|
+
expect(validatePermissionsPolicy({ version: 0 }).valid).toBe(false);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test('rejects an unknown role', () => {
|
|
32
|
+
const result = validatePermissionsPolicy({ version: 1, members: { a: { role: 'superuser' } } });
|
|
33
|
+
expect(result.valid).toBe(false);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test('rejects a non-array allow-list', () => {
|
|
37
|
+
const result = validatePermissionsPolicy({ version: 1, members: { a: { allow: { pages: 'blog/*' } } } });
|
|
38
|
+
expect(result.valid).toBe(false);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test('reports a structured error path on failure', () => {
|
|
42
|
+
const result = validatePermissionsPolicy({ version: 1, members: { a: { role: 'nope' } } });
|
|
43
|
+
expect(result.valid).toBe(false);
|
|
44
|
+
if (!result.valid) {
|
|
45
|
+
expect(result.errors.length).toBeGreaterThan(0);
|
|
46
|
+
expect(result.errors[0]!.path).toContain('members');
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
});
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Permissions Policy Validators
|
|
3
|
+
* Zod schema + validator for `.meno/permissions.json`.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import type { ZodError } from 'zod';
|
|
8
|
+
import type { PermissionsPolicy } from '../types/permissions';
|
|
9
|
+
import { PERMISSION_ROLES } from '../types/permissions';
|
|
10
|
+
import type { ValidationResult, ValidationError } from './validators';
|
|
11
|
+
|
|
12
|
+
// PERMISSION_ROLES is a precise `as const` tuple, so z.enum consumes it directly.
|
|
13
|
+
export const PermissionRoleSchema = z.enum(PERMISSION_ROLES);
|
|
14
|
+
|
|
15
|
+
export const PermissionRuleSchema = z.object({
|
|
16
|
+
pages: z.array(z.string()).optional(),
|
|
17
|
+
components: z.array(z.string()).optional(),
|
|
18
|
+
cms: z.array(z.string()).optional(),
|
|
19
|
+
config: z.array(z.string()).optional(),
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
export const PermissionGrantSchema = z.object({
|
|
23
|
+
role: PermissionRoleSchema.optional(),
|
|
24
|
+
allow: PermissionRuleSchema.optional(),
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
export const PermissionsPolicySchema = z.object({
|
|
28
|
+
// Forward-tolerant: accept any positive version; the resolver only knows v1.
|
|
29
|
+
version: z.number().int().min(1),
|
|
30
|
+
defaultRole: PermissionRoleSchema.optional(),
|
|
31
|
+
members: z.record(z.string(), PermissionGrantSchema).optional(),
|
|
32
|
+
teams: z.record(z.string(), PermissionGrantSchema).optional(),
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
function zodToValidationErrors(zodError: ZodError): ValidationError[] {
|
|
36
|
+
return zodError.errors.map((err) => ({
|
|
37
|
+
path: err.path.join('.') || 'root',
|
|
38
|
+
message: err.message,
|
|
39
|
+
code: 'INVALID_TYPE' as const,
|
|
40
|
+
}));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function validatePermissionsPolicy(data: unknown): ValidationResult<PermissionsPolicy> {
|
|
44
|
+
const result = PermissionsPolicySchema.safeParse(data);
|
|
45
|
+
if (result.success) {
|
|
46
|
+
return { valid: true, data: result.data as PermissionsPolicy };
|
|
47
|
+
}
|
|
48
|
+
return { valid: false, errors: zodToValidationErrors(result.error) };
|
|
49
|
+
}
|
|
@@ -14,9 +14,9 @@ describe('Prop Validator', () => {
|
|
|
14
14
|
title: { type: 'string', default: 'Hello' },
|
|
15
15
|
};
|
|
16
16
|
const passedProps = { title: 'World' };
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
const result = validateComponentProps(propDefs, passedProps);
|
|
19
|
-
|
|
19
|
+
|
|
20
20
|
expect(result.valid).toBe(true);
|
|
21
21
|
expect(result.props.title).toBe('World');
|
|
22
22
|
});
|
|
@@ -26,9 +26,9 @@ describe('Prop Validator', () => {
|
|
|
26
26
|
count: { type: 'number', default: 0 },
|
|
27
27
|
};
|
|
28
28
|
const passedProps = { count: 42 };
|
|
29
|
-
|
|
29
|
+
|
|
30
30
|
const result = validateComponentProps(propDefs, passedProps);
|
|
31
|
-
|
|
31
|
+
|
|
32
32
|
expect(result.valid).toBe(true);
|
|
33
33
|
expect(result.props.count).toBe(42);
|
|
34
34
|
});
|
|
@@ -38,9 +38,9 @@ describe('Prop Validator', () => {
|
|
|
38
38
|
enabled: { type: 'boolean', default: false },
|
|
39
39
|
};
|
|
40
40
|
const passedProps = { enabled: true };
|
|
41
|
-
|
|
41
|
+
|
|
42
42
|
const result = validateComponentProps(propDefs, passedProps);
|
|
43
|
-
|
|
43
|
+
|
|
44
44
|
expect(result.valid).toBe(true);
|
|
45
45
|
expect(result.props.enabled).toBe(true);
|
|
46
46
|
});
|
|
@@ -54,9 +54,9 @@ describe('Prop Validator', () => {
|
|
|
54
54
|
},
|
|
55
55
|
};
|
|
56
56
|
const passedProps = { variant: 'secondary' };
|
|
57
|
-
|
|
57
|
+
|
|
58
58
|
const result = validateComponentProps(propDefs, passedProps);
|
|
59
|
-
|
|
59
|
+
|
|
60
60
|
expect(result.valid).toBe(true);
|
|
61
61
|
expect(result.props.variant).toBe('secondary');
|
|
62
62
|
});
|
|
@@ -68,9 +68,9 @@ describe('Prop Validator', () => {
|
|
|
68
68
|
title: { type: 'string', default: 'Hello' },
|
|
69
69
|
};
|
|
70
70
|
const passedProps = { title: 123 };
|
|
71
|
-
|
|
71
|
+
|
|
72
72
|
const result = validateComponentProps(propDefs, passedProps);
|
|
73
|
-
|
|
73
|
+
|
|
74
74
|
// Coercion makes this valid (123 -> "123")
|
|
75
75
|
expect(result.valid).toBe(true);
|
|
76
76
|
expect(result.props.title).toBe('123');
|
|
@@ -108,7 +108,7 @@ describe('Prop Validator', () => {
|
|
|
108
108
|
expect(result.valid).toBe(false);
|
|
109
109
|
if (!result.valid) {
|
|
110
110
|
expect(result.errors.length).toBeGreaterThan(0);
|
|
111
|
-
expect(result.errors[0]
|
|
111
|
+
expect(result.errors[0]!.message).toContain('not in allowed options');
|
|
112
112
|
}
|
|
113
113
|
// Should fall back to default
|
|
114
114
|
expect(result.props.variant).toBe('primary');
|
|
@@ -121,9 +121,9 @@ describe('Prop Validator', () => {
|
|
|
121
121
|
count: { type: 'number', default: 0 },
|
|
122
122
|
};
|
|
123
123
|
const passedProps = { count: '123' };
|
|
124
|
-
|
|
124
|
+
|
|
125
125
|
const result = validateComponentProps(propDefs, passedProps);
|
|
126
|
-
|
|
126
|
+
|
|
127
127
|
expect(result.valid).toBe(true);
|
|
128
128
|
expect(result.props.count).toBe(123);
|
|
129
129
|
expect(typeof result.props.count).toBe('number');
|
|
@@ -134,9 +134,9 @@ describe('Prop Validator', () => {
|
|
|
134
134
|
enabled: { type: 'boolean', default: false },
|
|
135
135
|
};
|
|
136
136
|
const passedProps = { enabled: 'true' };
|
|
137
|
-
|
|
137
|
+
|
|
138
138
|
const result = validateComponentProps(propDefs, passedProps);
|
|
139
|
-
|
|
139
|
+
|
|
140
140
|
expect(result.valid).toBe(true);
|
|
141
141
|
expect(result.props.enabled).toBe(true);
|
|
142
142
|
expect(typeof result.props.enabled).toBe('boolean');
|
|
@@ -243,9 +243,9 @@ describe('Prop Validator', () => {
|
|
|
243
243
|
unknownProp: 'allowed',
|
|
244
244
|
anotherUnknown: 123,
|
|
245
245
|
};
|
|
246
|
-
|
|
246
|
+
|
|
247
247
|
const result = validateComponentProps(propDefs, passedProps);
|
|
248
|
-
|
|
248
|
+
|
|
249
249
|
// Should be valid (unknown props don't fail validation)
|
|
250
250
|
expect(result.valid).toBe(true);
|
|
251
251
|
// Unknown props should be preserved
|
|
@@ -259,14 +259,12 @@ describe('Prop Validator', () => {
|
|
|
259
259
|
count: { type: 'number', default: 42 },
|
|
260
260
|
};
|
|
261
261
|
const passedProps = {};
|
|
262
|
-
|
|
262
|
+
|
|
263
263
|
const result = validateComponentProps(propDefs, passedProps);
|
|
264
|
-
|
|
264
|
+
|
|
265
265
|
expect(result.valid).toBe(true);
|
|
266
266
|
expect(result.props.title).toBe('Hello');
|
|
267
267
|
expect(result.props.count).toBe(42);
|
|
268
268
|
});
|
|
269
269
|
});
|
|
270
270
|
});
|
|
271
|
-
|
|
272
|
-
|
|
@@ -43,19 +43,19 @@ function coerceValue(value: unknown, expectedType: PropDefinition['type']): unkn
|
|
|
43
43
|
switch (expectedType) {
|
|
44
44
|
case 'string':
|
|
45
45
|
return String(value);
|
|
46
|
-
|
|
46
|
+
|
|
47
47
|
case 'number':
|
|
48
48
|
if (typeof value === 'number') {
|
|
49
49
|
return value;
|
|
50
50
|
}
|
|
51
51
|
if (typeof value === 'string') {
|
|
52
52
|
const num = Number(value);
|
|
53
|
-
if (!isNaN(num) && isFinite(num)) {
|
|
53
|
+
if (!Number.isNaN(num) && Number.isFinite(num)) {
|
|
54
54
|
return num;
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
return undefined;
|
|
58
|
-
|
|
58
|
+
|
|
59
59
|
case 'boolean':
|
|
60
60
|
if (typeof value === 'boolean') {
|
|
61
61
|
return value;
|
|
@@ -73,10 +73,10 @@ function coerceValue(value: unknown, expectedType: PropDefinition['type']): unkn
|
|
|
73
73
|
return value !== 0;
|
|
74
74
|
}
|
|
75
75
|
return undefined;
|
|
76
|
-
|
|
76
|
+
|
|
77
77
|
case 'select':
|
|
78
78
|
return String(value);
|
|
79
|
-
|
|
79
|
+
|
|
80
80
|
default:
|
|
81
81
|
return value;
|
|
82
82
|
}
|
|
@@ -88,7 +88,7 @@ function coerceValue(value: unknown, expectedType: PropDefinition['type']): unkn
|
|
|
88
88
|
function validateSingleProp(
|
|
89
89
|
propName: string,
|
|
90
90
|
propDef: PropDefinition,
|
|
91
|
-
value: unknown
|
|
91
|
+
value: unknown,
|
|
92
92
|
): { valid: boolean; error?: PropValidationError; coercedValue?: unknown } {
|
|
93
93
|
// If value is undefined, it's valid (will use default)
|
|
94
94
|
if (value === undefined) {
|
|
@@ -158,7 +158,7 @@ function validateSingleProp(
|
|
|
158
158
|
case 'rich-text':
|
|
159
159
|
// Rich-text accepts both strings and i18n values (i18n values will be resolved later)
|
|
160
160
|
// Coerce numbers/booleans to strings (e.g. from CMS template resolution like {{item.value}})
|
|
161
|
-
coercedValue =
|
|
161
|
+
coercedValue = typeof value === 'number' || typeof value === 'boolean' ? String(value) : value;
|
|
162
162
|
typeValid = typeof coercedValue === 'string' || isI18nValue(coercedValue) || isTiptapDocument(coercedValue);
|
|
163
163
|
break;
|
|
164
164
|
|
|
@@ -209,11 +209,11 @@ function validateSingleProp(
|
|
|
209
209
|
|
|
210
210
|
/**
|
|
211
211
|
* Validate component props against their interface definition
|
|
212
|
-
*
|
|
212
|
+
*
|
|
213
213
|
* @param propDefs - Component interface definition (prop name -> PropDefinition)
|
|
214
214
|
* @param passedProps - Props passed to the component instance
|
|
215
215
|
* @returns Validation result with validated/coerced props and any errors
|
|
216
|
-
*
|
|
216
|
+
*
|
|
217
217
|
* @example
|
|
218
218
|
* ```typescript
|
|
219
219
|
* const result = validateComponentProps(
|
|
@@ -227,7 +227,7 @@ function validateSingleProp(
|
|
|
227
227
|
*/
|
|
228
228
|
export function validateComponentProps(
|
|
229
229
|
propDefs: Record<string, PropDefinition>,
|
|
230
|
-
passedProps: Record<string, unknown
|
|
230
|
+
passedProps: Record<string, unknown>,
|
|
231
231
|
): PropValidationResult {
|
|
232
232
|
const errors: PropValidationError[] = [];
|
|
233
233
|
const validatedProps: Record<string, unknown> = {};
|
|
@@ -239,18 +239,15 @@ export function validateComponentProps(
|
|
|
239
239
|
|
|
240
240
|
if (validation.valid) {
|
|
241
241
|
// Use coerced value if available, otherwise use original or default
|
|
242
|
-
validatedProps[propName] =
|
|
243
|
-
? validation.coercedValue
|
|
244
|
-
: (value !== undefined ? value : propDef.default);
|
|
242
|
+
validatedProps[propName] =
|
|
243
|
+
validation.coercedValue !== undefined ? validation.coercedValue : value !== undefined ? value : propDef.default;
|
|
245
244
|
} else {
|
|
246
245
|
// Validation failed - log error but use default if available (backward compatibility)
|
|
247
246
|
if (validation.error) {
|
|
248
247
|
errors.push(validation.error);
|
|
249
248
|
}
|
|
250
249
|
// Use default value if available, otherwise use original value (graceful degradation)
|
|
251
|
-
validatedProps[propName] = propDef.default !== undefined
|
|
252
|
-
? propDef.default
|
|
253
|
-
: value;
|
|
250
|
+
validatedProps[propName] = propDef.default !== undefined ? propDef.default : value;
|
|
254
251
|
}
|
|
255
252
|
}
|
|
256
253
|
|
|
@@ -268,5 +265,3 @@ export function validateComponentProps(
|
|
|
268
265
|
|
|
269
266
|
return { valid: true, props: validatedProps };
|
|
270
267
|
}
|
|
271
|
-
|
|
272
|
-
|
|
@@ -4,12 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { describe, test, expect } from 'bun:test';
|
|
7
|
-
import {
|
|
8
|
-
PropDefinitionSchema,
|
|
9
|
-
ComponentNodeSchema,
|
|
10
|
-
ComponentDefinitionSchema,
|
|
11
|
-
PageDataSchema,
|
|
12
|
-
} from './schemas';
|
|
7
|
+
import { PropDefinitionSchema, ComponentNodeSchema, ComponentDefinitionSchema, PageDataSchema } from './schemas';
|
|
13
8
|
|
|
14
9
|
describe('Schema Validation', () => {
|
|
15
10
|
describe('Valid component definitions pass', () => {
|
|
@@ -18,9 +13,9 @@ describe('Schema Validation', () => {
|
|
|
18
13
|
type: 'string',
|
|
19
14
|
default: 'Hello',
|
|
20
15
|
};
|
|
21
|
-
|
|
16
|
+
|
|
22
17
|
const result = PropDefinitionSchema.safeParse(propDef);
|
|
23
|
-
|
|
18
|
+
|
|
24
19
|
expect(result.success).toBe(true);
|
|
25
20
|
if (result.success) {
|
|
26
21
|
expect(result.data.type).toBe('string');
|
|
@@ -46,9 +41,7 @@ describe('Schema Validation', () => {
|
|
|
46
41
|
const propDef = {
|
|
47
42
|
type: 'list',
|
|
48
43
|
itemSchema: { title: { type: 'string' } },
|
|
49
|
-
default: [
|
|
50
|
-
{ title: { _i18n: true, en: 'Hello', pl: 'Cześć' } },
|
|
51
|
-
],
|
|
44
|
+
default: [{ title: { _i18n: true, en: 'Hello', pl: 'Cześć' } }],
|
|
52
45
|
};
|
|
53
46
|
|
|
54
47
|
const result = PropDefinitionSchema.safeParse(propDef);
|
|
@@ -127,9 +120,9 @@ describe('Schema Validation', () => {
|
|
|
127
120
|
default: 'primary',
|
|
128
121
|
options: ['primary', 'secondary'],
|
|
129
122
|
};
|
|
130
|
-
|
|
123
|
+
|
|
131
124
|
const result = PropDefinitionSchema.safeParse(propDef);
|
|
132
|
-
|
|
125
|
+
|
|
133
126
|
expect(result.success).toBe(true);
|
|
134
127
|
if (result.success) {
|
|
135
128
|
expect(result.data.type).toBe('select');
|
|
@@ -143,9 +136,9 @@ describe('Schema Validation', () => {
|
|
|
143
136
|
tag: 'div',
|
|
144
137
|
children: [],
|
|
145
138
|
};
|
|
146
|
-
|
|
139
|
+
|
|
147
140
|
const result = ComponentNodeSchema.safeParse(node);
|
|
148
|
-
|
|
141
|
+
|
|
149
142
|
expect(result.success).toBe(true);
|
|
150
143
|
});
|
|
151
144
|
|
|
@@ -163,9 +156,9 @@ describe('Schema Validation', () => {
|
|
|
163
156
|
},
|
|
164
157
|
},
|
|
165
158
|
};
|
|
166
|
-
|
|
159
|
+
|
|
167
160
|
const result = ComponentDefinitionSchema.safeParse(def);
|
|
168
|
-
|
|
161
|
+
|
|
169
162
|
expect(result.success).toBe(true);
|
|
170
163
|
});
|
|
171
164
|
});
|
|
@@ -176,9 +169,9 @@ describe('Schema Validation', () => {
|
|
|
176
169
|
type: 'invalid-type',
|
|
177
170
|
default: 'Hello',
|
|
178
171
|
};
|
|
179
|
-
|
|
172
|
+
|
|
180
173
|
const result = PropDefinitionSchema.safeParse(propDef);
|
|
181
|
-
|
|
174
|
+
|
|
182
175
|
expect(result.success).toBe(false);
|
|
183
176
|
});
|
|
184
177
|
|
|
@@ -187,9 +180,9 @@ describe('Schema Validation', () => {
|
|
|
187
180
|
tag: 'div',
|
|
188
181
|
children: [],
|
|
189
182
|
};
|
|
190
|
-
|
|
183
|
+
|
|
191
184
|
const result = ComponentNodeSchema.safeParse(node);
|
|
192
|
-
|
|
185
|
+
|
|
193
186
|
expect(result.success).toBe(false);
|
|
194
187
|
});
|
|
195
188
|
|
|
@@ -199,9 +192,9 @@ describe('Schema Validation', () => {
|
|
|
199
192
|
// Missing required structure
|
|
200
193
|
},
|
|
201
194
|
};
|
|
202
|
-
|
|
195
|
+
|
|
203
196
|
const result = ComponentDefinitionSchema.safeParse(def);
|
|
204
|
-
|
|
197
|
+
|
|
205
198
|
// Should fail or pass with passthrough (backward compatibility)
|
|
206
199
|
// The schema uses passthrough, so it might pass but log warnings
|
|
207
200
|
expect(result).toBeDefined();
|
|
@@ -213,9 +206,9 @@ describe('Schema Validation', () => {
|
|
|
213
206
|
const propDef = {
|
|
214
207
|
type: 'string',
|
|
215
208
|
};
|
|
216
|
-
|
|
209
|
+
|
|
217
210
|
const result = PropDefinitionSchema.safeParse(propDef);
|
|
218
|
-
|
|
211
|
+
|
|
219
212
|
// Should pass (default is optional)
|
|
220
213
|
expect(result.success).toBe(true);
|
|
221
214
|
});
|
|
@@ -225,9 +218,9 @@ describe('Schema Validation', () => {
|
|
|
225
218
|
type: 'node',
|
|
226
219
|
tag: 'div',
|
|
227
220
|
};
|
|
228
|
-
|
|
221
|
+
|
|
229
222
|
const result = ComponentNodeSchema.safeParse(node);
|
|
230
|
-
|
|
223
|
+
|
|
231
224
|
// Should pass (children is optional)
|
|
232
225
|
expect(result.success).toBe(true);
|
|
233
226
|
});
|
|
@@ -240,9 +233,9 @@ describe('Schema Validation', () => {
|
|
|
240
233
|
default: 'Hello',
|
|
241
234
|
unknownField: 'preserved',
|
|
242
235
|
};
|
|
243
|
-
|
|
236
|
+
|
|
244
237
|
const result = PropDefinitionSchema.safeParse(propDef);
|
|
245
|
-
|
|
238
|
+
|
|
246
239
|
expect(result.success).toBe(true);
|
|
247
240
|
if (result.success) {
|
|
248
241
|
// Passthrough should preserve unknown fields
|
|
@@ -257,14 +250,53 @@ describe('Schema Validation', () => {
|
|
|
257
250
|
unknownField: 'preserved',
|
|
258
251
|
children: [],
|
|
259
252
|
};
|
|
260
|
-
|
|
253
|
+
|
|
261
254
|
const result = ComponentNodeSchema.safeParse(node);
|
|
262
|
-
|
|
255
|
+
|
|
263
256
|
expect(result.success).toBe(true);
|
|
264
257
|
// Passthrough preserves unknown fields
|
|
265
258
|
expect((node as any).unknownField).toBe('preserved');
|
|
266
259
|
});
|
|
267
260
|
});
|
|
268
|
-
});
|
|
269
261
|
|
|
262
|
+
describe('meno-astro verbatim-code markers ({ _code, expr }) validate', () => {
|
|
263
|
+
test('a _code child node is accepted (renders natively at build; nothing in preview)', () => {
|
|
264
|
+
const node = {
|
|
265
|
+
type: 'node',
|
|
266
|
+
tag: 'div',
|
|
267
|
+
// The shape a promoted custom component produces: `{updateResult && <p>…</p>}`.
|
|
268
|
+
children: [{ _code: true, expr: 'updateResult && <p class="alert">Saved.</p>' }],
|
|
269
|
+
};
|
|
270
|
+
expect(ComponentNodeSchema.safeParse(node).success).toBe(true);
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
test('a _code value is accepted as an `if` condition and as an attribute value', () => {
|
|
274
|
+
const node = {
|
|
275
|
+
type: 'node',
|
|
276
|
+
tag: 'input',
|
|
277
|
+
if: { _code: true, expr: 'user?.isAdmin' },
|
|
278
|
+
attributes: { value: { _code: true, expr: "profile?.name ?? ''" } },
|
|
279
|
+
};
|
|
280
|
+
expect(ComponentNodeSchema.safeParse(node).success).toBe(true);
|
|
281
|
+
});
|
|
270
282
|
|
|
283
|
+
test('a full component definition whose structure carries _code children + a _frontmatter passthrough opens', () => {
|
|
284
|
+
const def = {
|
|
285
|
+
component: {
|
|
286
|
+
structure: {
|
|
287
|
+
type: 'node',
|
|
288
|
+
tag: 'div',
|
|
289
|
+
children: [{ _code: true, expr: 'error && <p>{error}</p>' }],
|
|
290
|
+
},
|
|
291
|
+
_frontmatter: "const error = Astro.url.searchParams.get('error');",
|
|
292
|
+
},
|
|
293
|
+
};
|
|
294
|
+
expect(ComponentDefinitionSchema.safeParse(def).success).toBe(true);
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
test('a bogus marker (missing expr) is still rejected as a child', () => {
|
|
298
|
+
const node = { type: 'node', tag: 'div', children: [{ _code: true }] };
|
|
299
|
+
expect(ComponentNodeSchema.safeParse(node).success).toBe(false);
|
|
300
|
+
});
|
|
301
|
+
});
|
|
302
|
+
});
|