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
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
* Tree path utilities for parsing and navigating tree structure paths
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { ComponentNode, PageData
|
|
5
|
+
import type { ComponentNode, PageData } from './types';
|
|
6
6
|
import type { PropDefinition } from './types';
|
|
7
7
|
import type { Path } from './pathArrayUtils';
|
|
8
8
|
import { stringToPath } from './pathArrayUtils';
|
|
9
9
|
|
|
10
10
|
// Type for page data that can have component structure
|
|
11
|
-
type
|
|
11
|
+
type _PageDataWithComponent = PageData & {
|
|
12
12
|
component?: {
|
|
13
13
|
structure?: ComponentNode;
|
|
14
14
|
interface?: Record<string, PropDefinition>;
|
|
@@ -28,12 +28,12 @@ export interface NodeLocation {
|
|
|
28
28
|
*/
|
|
29
29
|
export function validateComponentStructure(pageData: PageData | null): boolean {
|
|
30
30
|
if (!pageData) return false;
|
|
31
|
-
|
|
31
|
+
|
|
32
32
|
// Check for page format (has root property)
|
|
33
33
|
if ('root' in pageData && pageData.root) {
|
|
34
34
|
return true;
|
|
35
35
|
}
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
// Check for component format (has component.structure property)
|
|
38
38
|
if ('component' in pageData && pageData.component) {
|
|
39
39
|
if ('structure' in pageData.component && pageData.component.structure) {
|
|
@@ -42,7 +42,7 @@ export function validateComponentStructure(pageData: PageData | null): boolean {
|
|
|
42
42
|
// Component exists but structure is missing
|
|
43
43
|
return false;
|
|
44
44
|
}
|
|
45
|
-
|
|
45
|
+
|
|
46
46
|
return false;
|
|
47
47
|
}
|
|
48
48
|
|
|
@@ -52,12 +52,12 @@ export function validateComponentStructure(pageData: PageData | null): boolean {
|
|
|
52
52
|
*/
|
|
53
53
|
export function getRootData(pageData: PageData | null): ComponentNode | null {
|
|
54
54
|
if (!pageData) return null;
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
// Check for page format (has root property)
|
|
57
57
|
if ('root' in pageData && pageData.root) {
|
|
58
58
|
return pageData.root;
|
|
59
59
|
}
|
|
60
|
-
|
|
60
|
+
|
|
61
61
|
// Check for component format (has component.structure property)
|
|
62
62
|
if ('component' in pageData && pageData.component) {
|
|
63
63
|
if ('structure' in pageData.component) {
|
|
@@ -70,7 +70,7 @@ export function getRootData(pageData: PageData | null): ComponentNode | null {
|
|
|
70
70
|
// Component exists but structure field is missing
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
|
-
|
|
73
|
+
|
|
74
74
|
return null;
|
|
75
75
|
}
|
|
76
76
|
|
|
@@ -79,10 +79,7 @@ export function getRootData(pageData: PageData | null): ComponentNode | null {
|
|
|
79
79
|
* Handles paths like: root_0, root_0_children_0, root_0_children_0_children_1
|
|
80
80
|
* Also accepts array paths: [0], [0,0], [0,0,1]
|
|
81
81
|
*/
|
|
82
|
-
export function getParentAndIndexFromPath(
|
|
83
|
-
path: Path | string,
|
|
84
|
-
pageData: PageData
|
|
85
|
-
): NodeLocation | null {
|
|
82
|
+
export function getParentAndIndexFromPath(path: Path | string, pageData: PageData): NodeLocation | null {
|
|
86
83
|
const rootData = getRootData(pageData);
|
|
87
84
|
if (!rootData) return null;
|
|
88
85
|
|
|
@@ -94,7 +91,7 @@ export function getParentAndIndexFromPath(
|
|
|
94
91
|
return {
|
|
95
92
|
parent: pageData,
|
|
96
93
|
index: 0,
|
|
97
|
-
node: rootData
|
|
94
|
+
node: rootData,
|
|
98
95
|
};
|
|
99
96
|
}
|
|
100
97
|
|
|
@@ -106,26 +103,27 @@ export function getParentAndIndexFromPath(
|
|
|
106
103
|
// Skip first element (root index 0), navigate through rest
|
|
107
104
|
for (let i = 1; i < pathArray.length; i++) {
|
|
108
105
|
const childIndex = pathArray[i];
|
|
106
|
+
if (childIndex === undefined) return null;
|
|
109
107
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
108
|
+
if (!current || !('children' in current) || !Array.isArray(current.children)) {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (Number.isNaN(childIndex) || childIndex < 0 || childIndex >= current.children.length) {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
117
115
|
|
|
118
116
|
parent = current;
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
117
|
+
const child = current.children[childIndex];
|
|
118
|
+
if (child === undefined || typeof child === 'string') {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
current = child;
|
|
122
|
+
lastIndex = childIndex;
|
|
125
123
|
|
|
126
|
-
|
|
124
|
+
// If this is the last navigation step, we found our node
|
|
127
125
|
if (i === pathArray.length - 1) {
|
|
128
|
-
|
|
126
|
+
return { parent, index: childIndex, node: current };
|
|
129
127
|
}
|
|
130
128
|
}
|
|
131
129
|
|
|
@@ -137,11 +135,44 @@ export function getParentAndIndexFromPath(
|
|
|
137
135
|
return null;
|
|
138
136
|
}
|
|
139
137
|
|
|
138
|
+
/**
|
|
139
|
+
* Find the path to a node by reference identity (===) within the page tree.
|
|
140
|
+
*
|
|
141
|
+
* Used to recover the correct tree path when a stored selection path has drifted
|
|
142
|
+
* out of sync with the current pageData (e.g. a play-mode reload re-parsed the
|
|
143
|
+
* tree) but the selected node object is still present in the tree. Returns a path
|
|
144
|
+
* in the same `[0, ...childIndices]` form that {@link getParentAndIndexFromPath}
|
|
145
|
+
* consumes, or null if the node isn't reachable from the root by reference.
|
|
146
|
+
*/
|
|
147
|
+
export function findPathToNodeByReference(pageData: PageData, target: ComponentNode): Path | null {
|
|
148
|
+
const root = getRootData(pageData);
|
|
149
|
+
if (!root) return null;
|
|
150
|
+
|
|
151
|
+
// DFS from the root (path [0]); the children of a node at `path` are `[...path, i]`.
|
|
152
|
+
const stack: { node: ComponentNode; path: Path }[] = [{ node: root, path: [0] }];
|
|
153
|
+
while (stack.length > 0) {
|
|
154
|
+
const { node, path } = stack.pop()!;
|
|
155
|
+
if (node === target) return path;
|
|
156
|
+
const children = 'children' in node ? node.children : undefined;
|
|
157
|
+
if (Array.isArray(children)) {
|
|
158
|
+
for (let i = 0; i < children.length; i++) {
|
|
159
|
+
const child = children[i];
|
|
160
|
+
if (child && typeof child === 'object') {
|
|
161
|
+
stack.push({ node: child as ComponentNode, path: [...path, i] });
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
|
|
140
169
|
/**
|
|
141
170
|
* Extract structure without styles/props for tree comparison
|
|
142
171
|
* This allows tree to only regenerate when structure changes, not styles
|
|
143
172
|
*/
|
|
144
|
-
export function extractStructureWithoutStyles(
|
|
173
|
+
export function extractStructureWithoutStyles(
|
|
174
|
+
node: ComponentNode | string | null | undefined,
|
|
175
|
+
): ComponentNode | string | null | undefined {
|
|
145
176
|
if (!node || typeof node === 'string') {
|
|
146
177
|
return node;
|
|
147
178
|
}
|
|
@@ -157,13 +188,13 @@ export function extractStructureWithoutStyles(node: ComponentNode | string | nul
|
|
|
157
188
|
const component = 'component' in node ? (node as any).component : undefined;
|
|
158
189
|
const ifCondition = 'if' in node ? node.if : undefined;
|
|
159
190
|
const children = 'children' in node ? node.children : undefined;
|
|
160
|
-
|
|
191
|
+
|
|
161
192
|
// Recursively process children
|
|
162
193
|
let processedChildren: ComponentNode | (ComponentNode | string)[] | string | undefined;
|
|
163
194
|
if (children) {
|
|
164
195
|
if (Array.isArray(children)) {
|
|
165
196
|
processedChildren = children.map((child: ComponentNode | string) =>
|
|
166
|
-
typeof child === 'string' ? child : extractStructureWithoutStyles(child) as ComponentNode
|
|
197
|
+
typeof child === 'string' ? child : (extractStructureWithoutStyles(child) as ComponentNode),
|
|
167
198
|
);
|
|
168
199
|
} else if (typeof children === 'string') {
|
|
169
200
|
processedChildren = children;
|
|
@@ -202,7 +233,7 @@ export function calculateInsertionIndex(
|
|
|
202
233
|
linearIndex?: number;
|
|
203
234
|
},
|
|
204
235
|
parentChildren: Array<ComponentNode | string>,
|
|
205
|
-
nodeDataMap: Map<string, ComponentNode | string
|
|
236
|
+
nodeDataMap: Map<string, ComponentNode | string>,
|
|
206
237
|
): number {
|
|
207
238
|
if (target.childIndex !== undefined && target.childIndex >= 0) {
|
|
208
239
|
// Most reliable: use childIndex directly
|
|
@@ -250,13 +281,13 @@ export function isValidNodeLocation(location: unknown): location is NodeLocation
|
|
|
250
281
|
if (!location || typeof location !== 'object') {
|
|
251
282
|
return false;
|
|
252
283
|
}
|
|
253
|
-
|
|
284
|
+
|
|
254
285
|
// Use proper type narrowing instead of assertion
|
|
255
286
|
const loc = location as Record<string, unknown>;
|
|
256
287
|
const hasParent = 'parent' in loc && (loc.parent === null || typeof loc.parent === 'object');
|
|
257
288
|
const hasIndex = 'index' in loc && typeof loc.index === 'number' && loc.index >= 0;
|
|
258
289
|
const hasNode = 'node' in loc && (loc.node === null || typeof loc.node === 'object');
|
|
259
|
-
|
|
290
|
+
|
|
260
291
|
return hasParent && hasIndex && hasNode;
|
|
261
292
|
}
|
|
262
293
|
|
|
@@ -267,7 +298,7 @@ export function isValidPath(path: unknown): path is Path {
|
|
|
267
298
|
if (!Array.isArray(path)) {
|
|
268
299
|
return false;
|
|
269
300
|
}
|
|
270
|
-
|
|
301
|
+
|
|
271
302
|
// Path is an array of numbers
|
|
272
303
|
return path.every((item): item is number => typeof item === 'number' && item >= 0);
|
|
273
304
|
}
|
|
@@ -275,28 +306,24 @@ export function isValidPath(path: unknown): path is Path {
|
|
|
275
306
|
/**
|
|
276
307
|
* Type guard to check if parent is PageData
|
|
277
308
|
*/
|
|
278
|
-
export function isPageDataParent(
|
|
279
|
-
parent: ComponentNode | PageData | null
|
|
280
|
-
): parent is PageData {
|
|
309
|
+
export function isPageDataParent(parent: ComponentNode | PageData | null): parent is PageData {
|
|
281
310
|
if (!parent) return false;
|
|
282
|
-
|
|
311
|
+
|
|
283
312
|
// Check for JSONPage format (has root property)
|
|
284
313
|
if ('root' in parent) return true;
|
|
285
|
-
|
|
314
|
+
|
|
286
315
|
// Check for component format - component must be an object, not a string
|
|
287
316
|
if ('component' in parent) {
|
|
288
317
|
return typeof parent.component === 'object' && parent.component !== null;
|
|
289
318
|
}
|
|
290
|
-
|
|
319
|
+
|
|
291
320
|
return false;
|
|
292
321
|
}
|
|
293
322
|
|
|
294
323
|
/**
|
|
295
324
|
* Type guard to check if parent is ComponentNode
|
|
296
325
|
*/
|
|
297
|
-
export function isComponentNodeParent(
|
|
298
|
-
parent: ComponentNode | PageData | null
|
|
299
|
-
): parent is ComponentNode {
|
|
326
|
+
export function isComponentNodeParent(parent: ComponentNode | PageData | null): parent is ComponentNode {
|
|
300
327
|
if (!parent) return false;
|
|
301
328
|
// Check for 'type' property (all ComponentNodes have it)
|
|
302
329
|
// Then check for specific node types that can have children:
|
|
@@ -306,29 +333,34 @@ export function isComponentNodeParent(
|
|
|
306
333
|
// - LinkNode: type === 'link'
|
|
307
334
|
// - EmbedNode: type === 'embed'
|
|
308
335
|
// - ListNode: type === 'list' (also handles legacy 'cms-list' for migration)
|
|
336
|
+
// - CustomNode: type === 'custom' (opaque .astro, accepts slotted children)
|
|
337
|
+
// - IslandNode: type === 'island' (BYO framework island, accepts slotted children)
|
|
309
338
|
const nodeType = (parent as any).type;
|
|
310
|
-
return
|
|
311
|
-
'
|
|
312
|
-
'
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
339
|
+
return (
|
|
340
|
+
'type' in parent &&
|
|
341
|
+
('tag' in parent ||
|
|
342
|
+
'component' in parent ||
|
|
343
|
+
nodeType === 'slot' ||
|
|
344
|
+
nodeType === 'link' ||
|
|
345
|
+
nodeType === 'embed' ||
|
|
346
|
+
nodeType === 'custom' ||
|
|
347
|
+
nodeType === 'island' ||
|
|
348
|
+
nodeType === 'cms-list' || // Legacy support for migration
|
|
349
|
+
nodeType === 'list')
|
|
318
350
|
);
|
|
319
351
|
}
|
|
320
352
|
|
|
321
353
|
/**
|
|
322
354
|
* Get children array from parent (handles both PageData and ComponentNode)
|
|
323
355
|
*/
|
|
324
|
-
export function getParentChildren(
|
|
325
|
-
parent: ComponentNode | PageData | null
|
|
326
|
-
): Array<ComponentNode | string> | null {
|
|
356
|
+
export function getParentChildren(parent: ComponentNode | PageData | null): Array<ComponentNode | string> | null {
|
|
327
357
|
if (!parent) return null;
|
|
328
|
-
|
|
358
|
+
|
|
329
359
|
if (isPageDataParent(parent)) {
|
|
330
360
|
const rootData = getRootData(parent);
|
|
331
|
-
return rootData && 'children' in rootData
|
|
361
|
+
return rootData && 'children' in rootData
|
|
362
|
+
? (rootData.children as Array<ComponentNode | string> | undefined) || null
|
|
363
|
+
: null;
|
|
332
364
|
}
|
|
333
365
|
|
|
334
366
|
if (isComponentNodeParent(parent)) {
|
|
@@ -343,10 +375,10 @@ export function getParentChildren(
|
|
|
343
375
|
*/
|
|
344
376
|
export function setParentChildren(
|
|
345
377
|
parent: ComponentNode | PageData | null,
|
|
346
|
-
children: Array<ComponentNode | string
|
|
378
|
+
children: Array<ComponentNode | string>,
|
|
347
379
|
): void {
|
|
348
380
|
if (!parent) return;
|
|
349
|
-
|
|
381
|
+
|
|
350
382
|
if (isPageDataParent(parent)) {
|
|
351
383
|
const rootData = getRootData(parent);
|
|
352
384
|
if (rootData && 'children' in rootData) {
|
|
@@ -358,4 +390,3 @@ export function setParentChildren(
|
|
|
358
390
|
}
|
|
359
391
|
}
|
|
360
392
|
}
|
|
361
|
-
|
package/lib/shared/types/api.ts
CHANGED
|
@@ -16,9 +16,10 @@ export interface HMRMessage {
|
|
|
16
16
|
| 'hmr:libraries-update'
|
|
17
17
|
| 'hmr:cms-update'
|
|
18
18
|
| 'hmr:cms-collections-update'
|
|
19
|
-
| 'hmr:config-update'
|
|
19
|
+
| 'hmr:config-update'
|
|
20
|
+
| 'hmr:stylesheet-update';
|
|
20
21
|
path?: string;
|
|
21
|
-
collection?: string;
|
|
22
|
+
collection?: string; // For CMS updates
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
export interface PageListResponse {
|
|
@@ -39,12 +40,57 @@ export interface PageCmsConfig {
|
|
|
39
40
|
id: string;
|
|
40
41
|
/** Display name for the collection */
|
|
41
42
|
name: string;
|
|
42
|
-
/** Which field to use for URL slug */
|
|
43
|
-
slugField
|
|
44
|
-
/** URL pattern, e.g., "/blog/{{slug}}" */
|
|
45
|
-
urlPattern
|
|
43
|
+
/** Which field to use for URL slug. Omitted for a data-only collection (no per-item route). */
|
|
44
|
+
slugField?: string;
|
|
45
|
+
/** URL pattern, e.g., "/blog/{{slug}}". Omitted for a data-only collection (no per-item route). */
|
|
46
|
+
urlPattern?: string;
|
|
46
47
|
/** Field definitions */
|
|
47
48
|
fields: Record<string, CMSFieldDefinition>;
|
|
49
|
+
/** Generate an RSS 2.0 feed at `<route-prefix>/rss.xml` (routed collections only). */
|
|
50
|
+
rss?: boolean;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Field type discovered for one SSR data-source result (drives binding autocomplete). */
|
|
54
|
+
export type DataFieldType = 'string' | 'number' | 'boolean' | 'date' | 'image' | 'object';
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* A single declarative data source on an SSR page (`meta.source === 'ssr'`). v1 supports a
|
|
58
|
+
* declarative HTTP `GET` whose response is bound into the page body. The fetch runs per
|
|
59
|
+
* request via the `loadPageData` runtime helper. Anything beyond "GET → bind fields"
|
|
60
|
+
* (multi-step fetches, mutations, custom transforms) stays a hand-authored escape-hatch page.
|
|
61
|
+
*/
|
|
62
|
+
export interface PageDataSource {
|
|
63
|
+
/** Source kind. Only declarative HTTP fetch in v1. */
|
|
64
|
+
type: 'fetch';
|
|
65
|
+
/**
|
|
66
|
+
* Endpoint URL. May interpolate request inputs and env secrets via `{{…}}`
|
|
67
|
+
* (e.g. `https://api…/repos/{{params.owner}}?q={{query.q}}`,
|
|
68
|
+
* `headers: { authorization: "Bearer {{env.TOKEN}}" }`). The origin is author-fixed —
|
|
69
|
+
* only path/query segments interpolate (SSRF guard).
|
|
70
|
+
*/
|
|
71
|
+
url: string;
|
|
72
|
+
/** HTTP method. GET only in v1 (no modeled mutations). */
|
|
73
|
+
method?: 'GET';
|
|
74
|
+
/** Header map; values may interpolate `{{env.SECRET}}` (resolved server-side, never in markup). */
|
|
75
|
+
headers?: Record<string, string>;
|
|
76
|
+
/** Dot-path into the JSON response to the payload (e.g. "data.items"); empty = whole response. */
|
|
77
|
+
path?: string;
|
|
78
|
+
/** Shape of ONE result, discovered via /api/remote-sample. Drives binding autocomplete. */
|
|
79
|
+
fields?: Record<string, DataFieldType>;
|
|
80
|
+
/** 'object' (bind `{{name.field}}`) or 'list' (drives a list node). Default 'object'. */
|
|
81
|
+
cardinality?: 'object' | 'list';
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* SSR page data configuration embedded in page meta (`meta.data`, required when
|
|
86
|
+
* `meta.source === 'ssr'`). Each source key becomes a binding scope in the page body
|
|
87
|
+
* (`{{repo.stargazers_count}}`). The `getStaticPaths`-equivalent boilerplate
|
|
88
|
+
* (`const { … } = await loadPageData(meta.data, Astro)`) is derived by the emitter and
|
|
89
|
+
* skipped by the parser — `meta.data` is authoritative. See docs/meno-astro-ssr-page-type.md.
|
|
90
|
+
*/
|
|
91
|
+
export interface PageDataConfig {
|
|
92
|
+
/** Named data sources. The key becomes a binding scope in the body. */
|
|
93
|
+
sources: Record<string, PageDataSource>;
|
|
48
94
|
}
|
|
49
95
|
|
|
50
96
|
/**
|
|
@@ -73,15 +119,66 @@ export interface PageMetaData {
|
|
|
73
119
|
ogType?: string;
|
|
74
120
|
/** Translated slugs for each locale, e.g., { "en": "about", "pl": "o-nas" } */
|
|
75
121
|
slugs?: Record<string, string>;
|
|
76
|
-
/** Data source: 'static' (default) or '
|
|
77
|
-
source?: 'static' | 'cms';
|
|
122
|
+
/** Data source: 'static' (default), 'cms' (content collection), or 'ssr' (live per-request fetch) */
|
|
123
|
+
source?: 'static' | 'cms' | 'ssr';
|
|
78
124
|
/** CMS configuration with embedded schema (required when source: 'cms') */
|
|
79
125
|
cms?: PageCmsConfig;
|
|
126
|
+
/** SSR data-source configuration (required when source: 'ssr') */
|
|
127
|
+
data?: PageDataConfig;
|
|
128
|
+
/**
|
|
129
|
+
* Dynamic-route param names for an SSR page that lives at a `[param]` path
|
|
130
|
+
* (e.g. `["slug"]` for `src/pages/repo/[slug].astro`). When set on an `source: 'ssr'`
|
|
131
|
+
* page, the emitter exposes `const params = Astro.params` so the body can bind
|
|
132
|
+
* `{{params.<name>}}` and data-source URLs can interpolate `{{params.<name>}}`. The route
|
|
133
|
+
* is served on demand (no getStaticPaths) under `output: 'server'`.
|
|
134
|
+
*/
|
|
135
|
+
routeParams?: string[];
|
|
136
|
+
/**
|
|
137
|
+
* Sample param values used ONLY to preview a dynamic `[param]` route in the editor — the
|
|
138
|
+
* editor loads e.g. `/repo/astro` instead of the un-matchable `/repo/[slug]`
|
|
139
|
+
* (`{ slug: "astro" }`). Editor-only hint; ignored at build/runtime.
|
|
140
|
+
*/
|
|
141
|
+
routePreview?: Record<string, string>;
|
|
80
142
|
/** Draft pages are excluded from static build, sitemap, and robots.txt */
|
|
81
143
|
draft?: boolean;
|
|
82
144
|
/** External libraries for this page (extends or replaces global) */
|
|
83
145
|
libraries?: PageLibrariesConfig;
|
|
84
146
|
/** Custom code injected into head/body for this page */
|
|
85
147
|
customCode?: CustomCodeConfig;
|
|
148
|
+
/**
|
|
149
|
+
* Verbatim attributes of the source document's `<html>` element, preserved by the
|
|
150
|
+
* faithful-mirror importer (e.g. Webflow's `data-wf-page` / `data-wf-site`, which its
|
|
151
|
+
* client interaction engine reads to arm a page's interactions). BaseLayout spreads them
|
|
152
|
+
* onto its own `<html>` so a mirrored site boots its runtime exactly as the original —
|
|
153
|
+
* without them, e.g. a Webflow preloader never animates out. `lang` is excluded (BaseLayout
|
|
154
|
+
* owns it via locale routing).
|
|
155
|
+
*/
|
|
156
|
+
htmlAttributes?: Record<string, string>;
|
|
157
|
+
/** Opt this page into Astro View Transitions (renders `<ClientRouter>` in the head) */
|
|
158
|
+
viewTransitions?: boolean;
|
|
159
|
+
/** Discourage search indexing (renders `<meta name="robots" content="noindex">`) */
|
|
160
|
+
noindex?: boolean;
|
|
161
|
+
/** Per-page sitemap settings (priority/changefreq/exclude) */
|
|
162
|
+
sitemap?: SitemapPageConfig;
|
|
163
|
+
/**
|
|
164
|
+
* Per-page static/SSR override, emitted as Astro's own top-level
|
|
165
|
+
* `export const prerender = <value>`. `true` forces this route to be statically
|
|
166
|
+
* generated, `false` makes it server-rendered on demand (requires SSR `output: 'server'`
|
|
167
|
+
* + an adapter). Omitted (undefined) → the route inherits the project's `output` default.
|
|
168
|
+
* CMS template routes always prerender (they depend on `getStaticPaths`), so this override
|
|
169
|
+
* applies only to regular pages.
|
|
170
|
+
*/
|
|
171
|
+
prerender?: boolean;
|
|
86
172
|
}
|
|
87
173
|
|
|
174
|
+
/**
|
|
175
|
+
* Per-page sitemap settings (surfaced in the page SEO panel).
|
|
176
|
+
*/
|
|
177
|
+
export interface SitemapPageConfig {
|
|
178
|
+
/** Relative importance, 0.0–1.0 (sitemap `<priority>`). */
|
|
179
|
+
priority?: number;
|
|
180
|
+
/** Expected update cadence (sitemap `<changefreq>`). */
|
|
181
|
+
changefreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never';
|
|
182
|
+
/** Omit this page (and all locale variants) from the generated sitemap. */
|
|
183
|
+
exclude?: boolean;
|
|
184
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { describe, expect, it } from 'bun:test';
|
|
2
|
+
import { singularize } from './cms';
|
|
3
|
+
|
|
4
|
+
describe('singularize', () => {
|
|
5
|
+
it('applies English plural→singular rules', () => {
|
|
6
|
+
expect(singularize('posts')).toBe('post');
|
|
7
|
+
expect(singularize('categories')).toBe('category'); // -ies → -y
|
|
8
|
+
expect(singularize('boxes')).toBe('box'); // -xes → -x
|
|
9
|
+
expect(singularize('classes')).toBe('class'); // -ses → -s
|
|
10
|
+
expect(singularize('people')).toBe('person'); // irregular
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('leaves an already-singular name unchanged', () => {
|
|
14
|
+
expect(singularize('author')).toBe('author');
|
|
15
|
+
expect(singularize('category')).toBe('category');
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('coerces a non-identifier collection name into a valid JS identifier', () => {
|
|
19
|
+
// The result is emitted as a `.map` loop variable, so it must be a legal identifier —
|
|
20
|
+
// a hyphenated/spaced/dotted collection name would otherwise emit `.map((case-study) => …)`.
|
|
21
|
+
expect(singularize('case-study')).toBe('caseStudy');
|
|
22
|
+
expect(singularize('case-study-category')).toBe('caseStudyCategory');
|
|
23
|
+
expect(singularize('blog posts')).toBe('blogPost'); // space-separated + pluralized last word
|
|
24
|
+
expect(singularize('2024-items')).toBe('_2024Item'); // leading digit gets prefixed
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('degrades a non-string / empty input to the generic `item` rather than throwing', () => {
|
|
28
|
+
expect(singularize('')).toBe('item');
|
|
29
|
+
// @ts-expect-error — defensive guard against undefined (was a hard crash: collection.endsWith)
|
|
30
|
+
expect(singularize(undefined)).toBe('item');
|
|
31
|
+
// @ts-expect-error — defensive guard against null
|
|
32
|
+
expect(singularize(null)).toBe('item');
|
|
33
|
+
});
|
|
34
|
+
});
|