meno-core 1.0.53 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +1 -3
- package/bin/cli.ts +66 -261
- package/build-astro.ts +150 -128
- package/dist/bin/cli.js +42 -185
- package/dist/bin/cli.js.map +2 -2
- package/dist/chunks/chunk-2AR55GYH.js +42 -0
- package/dist/chunks/chunk-2AR55GYH.js.map +7 -0
- package/dist/chunks/{chunk-JGWFTO6P.js → chunk-2IIQK7T3.js} +2624 -1389
- package/dist/chunks/chunk-2IIQK7T3.js.map +7 -0
- package/dist/chunks/chunk-4ZRU52J2.js +169 -0
- package/dist/chunks/chunk-4ZRU52J2.js.map +7 -0
- package/dist/chunks/{chunk-UB44F4Z2.js → chunk-5X4HCN7J.js} +5 -7
- package/dist/chunks/chunk-5X4HCN7J.js.map +7 -0
- package/dist/chunks/{chunk-WQFG7PAH.js → chunk-7CCVOL5M.js} +15 -19
- package/dist/chunks/chunk-7CCVOL5M.js.map +7 -0
- package/dist/chunks/{chunk-YBLHKYFF.js → chunk-AR7LHIFY.js} +8 -2
- package/dist/chunks/chunk-AR7LHIFY.js.map +7 -0
- package/dist/chunks/{chunk-O3NAGJP4.js → chunk-NUP7H7D3.js} +135 -41
- package/dist/chunks/chunk-NUP7H7D3.js.map +7 -0
- package/dist/chunks/{chunk-X754AHS5.js → chunk-QWTQZHG3.js} +194 -90
- package/dist/chunks/chunk-QWTQZHG3.js.map +7 -0
- package/dist/chunks/{chunk-H3GJ4H2U.js → chunk-XTKNX4FW.js} +216 -87
- package/dist/chunks/chunk-XTKNX4FW.js.map +7 -0
- package/dist/chunks/{fs-JGINUXGL.js → fs-G3ANWEFP.js} +2 -2
- package/dist/lib/client/index.js +1003 -475
- package/dist/lib/client/index.js.map +3 -3
- package/dist/lib/server/index.js +14393 -6371
- package/dist/lib/server/index.js.map +4 -4
- package/dist/lib/shared/index.js +342 -101
- package/dist/lib/shared/index.js.map +4 -4
- package/dist/lib/shared/richtext/index.js +1 -1
- package/dist/lib/test-utils/index.js +64 -80
- package/dist/lib/test-utils/index.js.map +2 -2
- package/entries/client-router.tsx +10 -8
- package/lib/client/ClientInitializer.ts +8 -8
- package/lib/client/ErrorBoundary.test.tsx +246 -186
- package/lib/client/ErrorBoundary.tsx +183 -132
- package/lib/client/componentRegistry.test.ts +96 -108
- package/lib/client/componentRegistry.ts +1 -3
- package/lib/client/contexts/ThemeContext.tsx +3 -2
- package/lib/client/core/ComponentBuilder.test.ts +663 -560
- package/lib/client/core/ComponentBuilder.ts +427 -155
- package/lib/client/core/ComponentRenderer.test.tsx +2 -4
- package/lib/client/core/ComponentRenderer.tsx +46 -33
- package/lib/client/core/builders/embedBuilder.ts +242 -54
- package/lib/client/core/builders/linkBuilder.ts +72 -45
- package/lib/client/core/builders/linkNodeBuilder.ts +79 -54
- package/lib/client/core/builders/listBuilder.ts +155 -89
- package/lib/client/core/builders/localeListBuilder.ts +97 -62
- package/lib/client/core/builders/types.ts +5 -5
- package/lib/client/core/cmsTemplateProcessor.ts +8 -9
- package/lib/client/elementRegistry.ts +3 -3
- package/lib/client/fontFamiliesService.test.ts +2 -10
- package/lib/client/fontFamiliesService.ts +3 -3
- package/lib/client/hmr/HMRManager.tsx +47 -30
- package/lib/client/hmrCssReload.ts +49 -14
- package/lib/client/hmrWebSocket.ts +14 -19
- package/lib/client/hooks/useColorVariables.test.ts +21 -21
- package/lib/client/hooks/useColorVariables.ts +23 -18
- package/lib/client/hooks/usePropertyAutocomplete.ts +4 -6
- package/lib/client/hooks/useVariables.ts +6 -4
- package/lib/client/hydration/HydrationUtils.test.ts +24 -25
- package/lib/client/hydration/HydrationUtils.ts +3 -4
- package/lib/client/i18nConfigService.test.ts +2 -7
- package/lib/client/i18nConfigService.ts +2 -2
- package/lib/client/meno-filter/MenoFilter.test.ts +47 -49
- package/lib/client/meno-filter/MenoFilter.ts +14 -15
- package/lib/client/meno-filter/bindings.ts +18 -43
- package/lib/client/meno-filter/init.ts +4 -4
- package/lib/client/meno-filter/renderer.ts +30 -32
- package/lib/client/meno-filter/script.generated.ts +1 -3
- package/lib/client/meno-filter/ui.ts +4 -6
- package/lib/client/meno-filter/updates.ts +18 -23
- package/lib/client/meno-filter/utils.ts +1 -1
- package/lib/client/navigation.test.ts +174 -178
- package/lib/client/navigation.ts +0 -1
- package/lib/client/responsiveStyleResolver.knownTokens.test.ts +71 -0
- package/lib/client/responsiveStyleResolver.test.ts +234 -232
- package/lib/client/responsiveStyleResolver.ts +74 -20
- package/lib/client/routing/RouteLoader.test.ts +24 -25
- package/lib/client/routing/RouteLoader.ts +27 -35
- package/lib/client/routing/Router.tsx +210 -153
- package/lib/client/scripts/ScriptExecutor.test.ts +157 -158
- package/lib/client/scripts/ScriptExecutor.ts +18 -36
- package/lib/client/services/PrefetchService.test.ts +3 -3
- package/lib/client/services/PrefetchService.ts +23 -29
- package/lib/client/styleProcessor.test.ts +9 -9
- package/lib/client/styleProcessor.ts +24 -15
- package/lib/client/styles/StyleInjector.test.ts +122 -115
- package/lib/client/styles/StyleInjector.ts +10 -7
- package/lib/client/styles/UtilityClassCollector.ts +62 -28
- package/lib/client/styles/cspNonce.test.ts +2 -5
- package/lib/client/templateEngine.test.ts +554 -488
- package/lib/client/templateEngine.ts +203 -73
- package/lib/client/theme.test.ts +1 -1
- package/lib/client/theme.ts +0 -1
- package/lib/client/utils/toast.ts +0 -1
- package/lib/server/__integration__/api-routes.test.ts +8 -4
- package/lib/server/__integration__/cms-integration.test.ts +1 -4
- package/lib/server/__integration__/server-lifecycle.test.ts +4 -5
- package/lib/server/__integration__/ssr-rendering.test.ts +47 -37
- package/lib/server/__integration__/static-assets.test.ts +3 -3
- package/lib/server/__integration__/test-helpers.ts +87 -74
- package/lib/server/ab/generateFunctions.ts +12 -10
- package/lib/server/astro/cmsPageEmitter.ts +26 -42
- package/lib/server/astro/componentEmitter.ts +35 -43
- package/lib/server/astro/cssCollector.ts +10 -26
- package/lib/server/astro/nodeToAstro.test.ts +1754 -34
- package/lib/server/astro/nodeToAstro.ts +232 -216
- package/lib/server/astro/normalizeOrphanTemplateProps.test.ts +115 -119
- package/lib/server/astro/normalizeOrphanTemplateProps.ts +11 -18
- package/lib/server/astro/pageEmitter.ts +9 -13
- package/lib/server/astro/tailwindMapper.test.ts +10 -37
- package/lib/server/astro/tailwindMapper.ts +33 -40
- package/lib/server/astro/templateTransformer.ts +17 -20
- package/lib/server/createServer.ts +7 -19
- package/lib/server/cssGenerator.test.ts +35 -44
- package/lib/server/cssGenerator.ts +8 -19
- package/lib/server/fileWatcher.test.ts +164 -13
- package/lib/server/fileWatcher.ts +209 -124
- package/lib/server/index.ts +14 -17
- package/lib/server/jsonLoader.test.ts +39 -2
- package/lib/server/jsonLoader.ts +39 -34
- package/lib/server/middleware/cors.test.ts +21 -21
- package/lib/server/middleware/cors.ts +28 -4
- package/lib/server/middleware/errorHandler.test.ts +7 -5
- package/lib/server/middleware/errorHandler.ts +3 -8
- package/lib/server/middleware/index.ts +0 -1
- package/lib/server/middleware/logger.test.ts +10 -8
- package/lib/server/middleware/logger.ts +17 -29
- package/lib/server/migrateTemplates.ts +3 -3
- package/lib/server/pageCache.test.ts +76 -77
- package/lib/server/pageCache.ts +0 -1
- package/lib/server/projectContext.ts +5 -4
- package/lib/server/providers/fileSystemCMSProvider.test.ts +142 -99
- package/lib/server/providers/fileSystemCMSProvider.ts +62 -38
- package/lib/server/routes/api/cms.test.ts +26 -14
- package/lib/server/routes/api/cms.ts +9 -14
- package/lib/server/routes/api/colors.test.ts +2 -2
- package/lib/server/routes/api/components.ts +31 -35
- package/lib/server/routes/api/config.ts +3 -4
- package/lib/server/routes/api/core-routes.ts +49 -76
- package/lib/server/routes/api/enums.test.ts +2 -2
- package/lib/server/routes/api/functions.ts +9 -17
- package/lib/server/routes/api/index.ts +3 -6
- package/lib/server/routes/api/pages.ts +8 -11
- package/lib/server/routes/api/shared.test.ts +1 -1
- package/lib/server/routes/api/shared.ts +12 -9
- package/lib/server/routes/api/variables.test.ts +3 -5
- package/lib/server/routes/api/variables.ts +1 -1
- package/lib/server/routes/index.ts +25 -28
- package/lib/server/routes/pages.ts +35 -31
- package/lib/server/routes/static.ts +17 -6
- package/lib/server/runtime/bundler.ts +98 -61
- package/lib/server/runtime/fs.ts +16 -26
- package/lib/server/runtime/httpServer.ts +8 -12
- package/lib/server/services/ColorService.test.ts +3 -3
- package/lib/server/services/ColorService.ts +37 -29
- package/lib/server/services/EnumService.test.ts +4 -8
- package/lib/server/services/EnumService.ts +11 -3
- package/lib/server/services/VariableService.test.ts +8 -12
- package/lib/server/services/VariableService.ts +11 -3
- package/lib/server/services/cmsService.test.ts +158 -120
- package/lib/server/services/cmsService.ts +36 -146
- package/lib/server/services/componentService.test.ts +125 -45
- package/lib/server/services/componentService.ts +70 -46
- package/lib/server/services/configService.test.ts +22 -45
- package/lib/server/services/configService.ts +50 -27
- package/lib/server/services/fileWatcherService.ts +42 -8
- package/lib/server/services/index.ts +0 -1
- package/lib/server/services/pageService.test.ts +8 -10
- package/lib/server/services/pageService.ts +32 -18
- package/lib/server/ssr/attributeBuilder.ts +18 -8
- package/lib/server/ssr/buildErrorOverlay.ts +11 -12
- package/lib/server/ssr/clientDataInjector.ts +7 -21
- package/lib/server/ssr/cmsSSRProcessor.ts +4 -8
- package/lib/server/ssr/cssCollector.ts +1 -1
- package/lib/server/ssr/errorOverlay.test.ts +1 -1
- package/lib/server/ssr/errorOverlay.ts +3 -9
- package/lib/server/ssr/htmlGenerator.nonce.test.ts +9 -14
- package/lib/server/ssr/htmlGenerator.test.ts +120 -44
- package/lib/server/ssr/htmlGenerator.ts +126 -91
- package/lib/server/ssr/imageMetadata.test.ts +3 -1
- package/lib/server/ssr/imageMetadata.ts +27 -21
- package/lib/server/ssr/jsCollector.test.ts +8 -18
- package/lib/server/ssr/jsCollector.ts +3 -8
- package/lib/server/ssr/liveReloadIntegration.test.ts +76 -36
- package/lib/server/ssr/metaTagGenerator.ts +2 -2
- package/lib/server/ssr/ssrRenderer.branches.test.ts +1103 -0
- package/lib/server/ssr/ssrRenderer.test.ts +316 -256
- package/lib/server/ssr/ssrRenderer.ts +795 -243
- package/lib/server/ssrRenderer.test.ts +1048 -954
- package/lib/server/utils/jsonLineMapper.test.ts +28 -28
- package/lib/server/utils/jsonLineMapper.ts +7 -7
- package/lib/server/validateStyleCoverage.ts +18 -21
- package/lib/server/websocketManager.ts +28 -19
- package/lib/shared/attributeNodeUtils.test.ts +15 -15
- package/lib/shared/attributeNodeUtils.ts +5 -12
- package/lib/shared/breakpoints.test.ts +5 -5
- package/lib/shared/breakpoints.ts +4 -11
- package/lib/shared/cmsQuery.test.ts +81 -0
- package/lib/shared/cmsQuery.ts +92 -0
- package/lib/shared/cmsQueryParser.test.ts +50 -42
- package/lib/shared/cmsQueryParser.ts +60 -38
- package/lib/shared/colorConversions.ts +9 -9
- package/lib/shared/colorVariableUtils.test.ts +27 -5
- package/lib/shared/colorVariableUtils.ts +21 -12
- package/lib/shared/componentRefs.ts +1 -5
- package/lib/shared/constants.test.ts +3 -3
- package/lib/shared/constants.ts +8 -8
- package/lib/shared/cssGeneration.test.ts +285 -144
- package/lib/shared/cssGeneration.ts +217 -531
- package/lib/shared/cssNamedColors.ts +152 -30
- package/lib/shared/cssProperties.test.ts +69 -70
- package/lib/shared/cssProperties.ts +298 -114
- package/lib/shared/elementClassName.test.ts +109 -109
- package/lib/shared/elementClassName.ts +3 -3
- package/lib/shared/elementUtils.ts +12 -16
- package/lib/shared/errorLogger.test.ts +12 -12
- package/lib/shared/errorLogger.ts +2 -10
- package/lib/shared/errors.test.ts +2 -13
- package/lib/shared/errors.ts +2 -8
- package/lib/shared/expressionEvaluator.test.ts +145 -0
- package/lib/shared/expressionEvaluator.ts +52 -24
- package/lib/shared/fontLoader.test.ts +32 -18
- package/lib/shared/fontLoader.ts +2 -2
- package/lib/shared/friendlyError.ts +2 -3
- package/lib/shared/gradientUtils.test.ts +3 -7
- package/lib/shared/gradientUtils.ts +17 -14
- package/lib/shared/hrefRefs.test.ts +2 -2
- package/lib/shared/hrefRefs.ts +2 -10
- package/lib/shared/i18n.test.ts +4 -4
- package/lib/shared/i18n.ts +18 -38
- package/lib/shared/index.ts +27 -0
- package/lib/shared/inlineSvgStyleRules.ts +14 -13
- package/lib/shared/interactiveStyleMappings.test.ts +32 -54
- package/lib/shared/interactiveStyleMappings.ts +11 -24
- package/lib/shared/interactiveStyles.test.ts +165 -188
- package/lib/shared/interfaces/contentProvider.ts +1 -1
- package/lib/shared/itemTemplateUtils.test.ts +11 -17
- package/lib/shared/itemTemplateUtils.ts +27 -39
- package/lib/shared/jsonRepair.ts +16 -10
- package/lib/shared/libraryLoader.test.ts +21 -55
- package/lib/shared/libraryLoader.ts +7 -22
- package/lib/shared/linkUtils.ts +1 -1
- package/lib/shared/logger.test.ts +66 -0
- package/lib/shared/logger.ts +94 -0
- package/lib/shared/markdown.ts +25 -0
- package/lib/shared/netlifyLocale404.test.ts +179 -0
- package/lib/shared/netlifyLocale404.ts +110 -0
- package/lib/shared/nodeUtils.test.ts +28 -16
- package/lib/shared/nodeUtils.ts +76 -23
- package/lib/shared/pathArrayUtils.test.ts +1 -2
- package/lib/shared/pathArrayUtils.ts +1 -1
- package/lib/shared/pathSecurity.ts +2 -2
- package/lib/shared/pathUtils.test.ts +4 -6
- package/lib/shared/pathUtils.ts +42 -49
- package/lib/shared/paths/Path.test.ts +2 -2
- package/lib/shared/paths/Path.ts +0 -1
- package/lib/shared/paths/PathConverter.test.ts +1 -1
- package/lib/shared/paths/PathConverter.ts +17 -20
- package/lib/shared/paths/PathUtils.ts +13 -13
- package/lib/shared/paths/PathValidator.test.ts +2 -15
- package/lib/shared/paths/PathValidator.ts +12 -10
- package/lib/shared/paths/index.ts +1 -2
- package/lib/shared/permissions.test.ts +168 -0
- package/lib/shared/permissions.ts +162 -0
- package/lib/shared/propResolver.test.ts +240 -244
- package/lib/shared/propResolver.ts +15 -26
- package/lib/shared/pxToRem.test.ts +7 -6
- package/lib/shared/pxToRem.ts +2 -5
- package/lib/shared/registry/BaseNodeTypeRegistry.test.ts +12 -6
- package/lib/shared/registry/ClientRegistry.ts +0 -2
- package/lib/shared/registry/ComponentRegistry.test.ts +46 -32
- package/lib/shared/registry/ComponentRegistry.ts +12 -9
- package/lib/shared/registry/NodeTypeDefinition.ts +16 -9
- package/lib/shared/registry/RegistryManager.ts +1 -2
- package/lib/shared/registry/SSRRegistry.ts +0 -2
- package/lib/shared/registry/createNodeType.ts +7 -9
- package/lib/shared/registry/defineNodeType.ts +2 -6
- package/lib/shared/registry/fieldPresets.ts +3 -1
- package/lib/shared/registry/index.ts +0 -1
- package/lib/shared/registry/nodeTypes/ComponentInstanceNodeType.ts +14 -15
- package/lib/shared/registry/nodeTypes/CustomNodeType.ts +103 -0
- package/lib/shared/registry/nodeTypes/EmbedNodeType.ts +18 -11
- package/lib/shared/registry/nodeTypes/HtmlNodeType.ts +48 -19
- package/lib/shared/registry/nodeTypes/IslandNodeType.ts +129 -0
- package/lib/shared/registry/nodeTypes/LinkNodeType.ts +21 -19
- package/lib/shared/registry/nodeTypes/ListNodeType.ts +117 -77
- package/lib/shared/registry/nodeTypes/LocaleListNodeType.ts +27 -21
- package/lib/shared/registry/nodeTypes/MarkdownNodeType.ts +78 -0
- package/lib/shared/registry/nodeTypes/SlotMarkerType.ts +12 -8
- package/lib/shared/registry/nodeTypes/index.ts +26 -3
- package/lib/shared/responsiveScaling.test.ts +16 -34
- package/lib/shared/responsiveScaling.ts +61 -42
- package/lib/shared/responsiveStyleUtils.test.ts +0 -1
- package/lib/shared/responsiveStyleUtils.ts +11 -13
- package/lib/shared/richtext/htmlToTiptap.test.ts +139 -130
- package/lib/shared/richtext/htmlToTiptap.ts +2 -4
- package/lib/shared/richtext/tiptapToHtml.test.ts +5 -6
- package/lib/shared/richtext/types.ts +1 -8
- package/lib/shared/slugTranslator.test.ts +13 -13
- package/lib/shared/slugTranslator.ts +12 -16
- package/lib/shared/slugify.ts +9 -15
- package/lib/shared/styleNodeUtils.test.ts +8 -8
- package/lib/shared/styleNodeUtils.ts +18 -20
- package/lib/shared/styleUtils.test.ts +87 -61
- package/lib/shared/styleUtils.ts +5 -6
- package/lib/shared/themeDefaults.test.ts +11 -14
- package/lib/shared/themeDefaults.ts +3 -4
- package/lib/shared/tree/PathBuilder.test.ts +63 -145
- package/lib/shared/tree/PathBuilder.ts +59 -47
- package/lib/shared/treePathUtils.test.ts +51 -12
- package/lib/shared/treePathUtils.ts +91 -60
- package/lib/shared/types/api.ts +105 -8
- package/lib/shared/types/cms.test.ts +34 -0
- package/lib/shared/types/cms.ts +90 -34
- package/lib/shared/types/comment.ts +49 -16
- package/lib/shared/types/components.ts +51 -25
- package/lib/shared/types/errors.test.ts +1 -6
- package/lib/shared/types/errors.ts +3 -7
- package/lib/shared/types/experiments.ts +28 -28
- package/lib/shared/types/index.ts +25 -2
- package/lib/shared/types/permissions.ts +139 -0
- package/lib/shared/types/styles.ts +0 -1
- package/lib/shared/types/variables.test.ts +4 -13
- package/lib/shared/types/variables.ts +51 -30
- package/lib/shared/types.ts +1 -2
- package/lib/shared/utilityClassConfig.ts +751 -321
- package/lib/shared/utilityClassMapper.durability.test.ts +117 -0
- package/lib/shared/utilityClassMapper.test.ts +433 -95
- package/lib/shared/utilityClassMapper.ts +322 -249
- package/lib/shared/utilityClassNames.test.ts +38 -0
- package/lib/shared/utilityClassNames.ts +458 -0
- package/lib/shared/utils.test.ts +2 -10
- package/lib/shared/utils.ts +19 -10
- package/lib/shared/validation/cmsValidators.ts +2 -1
- package/lib/shared/validation/commentValidators.test.ts +53 -0
- package/lib/shared/validation/commentValidators.ts +12 -1
- package/lib/shared/validation/index.ts +1 -0
- package/lib/shared/validation/permissionsValidators.test.ts +49 -0
- package/lib/shared/validation/permissionsValidators.ts +49 -0
- package/lib/shared/validation/propValidator.test.ts +19 -21
- package/lib/shared/validation/propValidator.ts +13 -18
- package/lib/shared/validation/schemas.test.ts +64 -32
- package/lib/shared/validation/schemas.ts +616 -345
- package/lib/shared/validation/validators.test.ts +3 -8
- package/lib/shared/validation/validators.ts +89 -68
- package/lib/shared/viewportUnits.integration.test.ts +14 -10
- package/lib/shared/viewportUnits.test.ts +24 -23
- package/lib/shared/viewportUnits.ts +12 -5
- package/lib/test-utils/dom-setup.ts +1 -1
- package/lib/test-utils/factories/ConsoleMockFactory.ts +10 -14
- package/lib/test-utils/factories/DomMockFactory.ts +17 -23
- package/lib/test-utils/factories/EventMockFactory.ts +7 -13
- package/lib/test-utils/factories/FetchMockFactory.ts +39 -57
- package/lib/test-utils/factories/ServerMockFactory.ts +6 -10
- package/lib/test-utils/factories/StoreMockFactory.ts +18 -29
- package/lib/test-utils/fixtures.ts +45 -45
- package/lib/test-utils/helpers/asyncHelpers.test.ts +15 -18
- package/lib/test-utils/helpers/asyncHelpers.ts +11 -20
- package/lib/test-utils/helpers.ts +1 -5
- package/lib/test-utils/index.ts +0 -4
- package/lib/test-utils/mockFactories.ts +13 -19
- package/lib/test-utils/mocks.ts +6 -4
- package/package.json +3 -5
- package/scripts/build-for-publish.mjs +2 -4
- package/scripts/build-meno-filter.ts +4 -7
- package/tsconfig.json +1 -0
- package/vite.config.ts +4 -4
- package/build-next.ts +0 -1361
- package/build-static.test.ts +0 -424
- package/build-static.ts +0 -1074
- package/dist/build-static.js +0 -36
- package/dist/chunks/chunk-2MHDV5BF.js +0 -251
- package/dist/chunks/chunk-2MHDV5BF.js.map +0 -7
- package/dist/chunks/chunk-AZQYF6KE.js +0 -559
- package/dist/chunks/chunk-AZQYF6KE.js.map +0 -7
- package/dist/chunks/chunk-GZHGVVW3.js +0 -322
- package/dist/chunks/chunk-GZHGVVW3.js.map +0 -7
- package/dist/chunks/chunk-H3GJ4H2U.js.map +0 -7
- package/dist/chunks/chunk-I7YIGZXT.js +0 -467
- package/dist/chunks/chunk-I7YIGZXT.js.map +0 -7
- package/dist/chunks/chunk-IGYR22T6.js +0 -6192
- package/dist/chunks/chunk-IGYR22T6.js.map +0 -7
- package/dist/chunks/chunk-JGP5A3Y5.js +0 -1136
- package/dist/chunks/chunk-JGP5A3Y5.js.map +0 -7
- package/dist/chunks/chunk-JGWFTO6P.js.map +0 -7
- package/dist/chunks/chunk-O3NAGJP4.js.map +0 -7
- package/dist/chunks/chunk-QB2LNO4W.js +0 -77
- package/dist/chunks/chunk-QB2LNO4W.js.map +0 -7
- package/dist/chunks/chunk-R6XHAFBF.js +0 -3821
- package/dist/chunks/chunk-R6XHAFBF.js.map +0 -7
- package/dist/chunks/chunk-UB44F4Z2.js.map +0 -7
- package/dist/chunks/chunk-WQFG7PAH.js.map +0 -7
- package/dist/chunks/chunk-X754AHS5.js.map +0 -7
- package/dist/chunks/chunk-YBLHKYFF.js.map +0 -7
- package/dist/chunks/configService-R3OGU2UD.js +0 -13
- package/dist/chunks/configService-R3OGU2UD.js.map +0 -7
- package/dist/chunks/constants-STK2YBIW.js +0 -46
- package/dist/chunks/constants-STK2YBIW.js.map +0 -7
- package/dist/chunks/fs-JGINUXGL.js.map +0 -7
- package/dist/entries/server-router.js +0 -67
- package/dist/entries/server-router.js.map +0 -7
- package/entries/server-router.tsx +0 -81
- package/lib/server/providers/fileSystemPageProvider.ts +0 -160
- package/lib/server/webflow/buildWebflow.ts +0 -635
- package/lib/server/webflow/index.ts +0 -23
- package/lib/server/webflow/nodeToWebflow.test.ts +0 -3170
- package/lib/server/webflow/nodeToWebflow.ts +0 -2435
- package/lib/server/webflow/styleMapper.test.ts +0 -389
- package/lib/server/webflow/styleMapper.ts +0 -695
- package/lib/server/webflow/templateWrapper.ts +0 -49
- package/lib/server/webflow/types.ts +0 -396
- /package/dist/{build-static.js.map → chunks/fs-G3ANWEFP.js.map} +0 -0
|
@@ -3,12 +3,91 @@
|
|
|
3
3
|
* Watches for changes in JSON files and triggers callbacks
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { watch, existsSync } from 'fs';
|
|
7
|
-
import { basename, dirname, join } from 'path';
|
|
8
|
-
import type { FSWatcher } from 'fs';
|
|
6
|
+
import { watch, existsSync, statSync, readdirSync } from 'node:fs';
|
|
7
|
+
import { basename, dirname, join, relative } from 'node:path';
|
|
8
|
+
import type { FSWatcher } from 'node:fs';
|
|
9
9
|
import { mapPageNameToPath } from './jsonLoader';
|
|
10
10
|
import { projectPaths, getProjectRoot } from './projectContext';
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Recursive directory watcher that also covers subdirectories created AFTER the
|
|
14
|
+
* watch began. Node's `fs.watch({recursive:true})` does this natively, but Bun's
|
|
15
|
+
* does NOT — it reports the new subdir's creation event yet never the files
|
|
16
|
+
* created inside it (verified on Bun 1.3). Since the studio server can run under
|
|
17
|
+
* Bun, relying on the native behavior silently breaks live-reload / cache
|
|
18
|
+
* invalidation for any collection or page added at runtime (e.g. a new
|
|
19
|
+
* `src/pages/<col>/[slug].astro` or `src/content/<col>/*.json`).
|
|
20
|
+
*
|
|
21
|
+
* We attach the native recursive watcher (covering the depth present at start),
|
|
22
|
+
* then, whenever a directory appears, attach a nested watcher to it AND replay
|
|
23
|
+
* its current contents as synthetic `rename` events — closing the
|
|
24
|
+
* mkdir-then-write race where a file lands before the nested watcher is live.
|
|
25
|
+
* The listener receives paths relative to `root` (matching `fs.watch`'s relative
|
|
26
|
+
* `filename`). Idempotent callbacks tolerate the occasional duplicate event this
|
|
27
|
+
* can produce under Node (where the native watcher already recurses).
|
|
28
|
+
*/
|
|
29
|
+
export function watchRecursive(root: string, listener: (event: string, relPath: string) => void): FSWatcher {
|
|
30
|
+
const nested: FSWatcher[] = [];
|
|
31
|
+
const watchedDirs = new Set<string>();
|
|
32
|
+
let rootWatcher: FSWatcher | null = null;
|
|
33
|
+
|
|
34
|
+
const coverNewDir = (abs: string): void => {
|
|
35
|
+
let isDir = false;
|
|
36
|
+
try {
|
|
37
|
+
isDir = statSync(abs).isDirectory();
|
|
38
|
+
} catch {
|
|
39
|
+
return; // vanished (or unreadable) between event and stat — nothing to do
|
|
40
|
+
}
|
|
41
|
+
if (!isDir || watchedDirs.has(abs)) return;
|
|
42
|
+
attachDir(abs);
|
|
43
|
+
// Replay what's already inside (created before the nested watcher went live).
|
|
44
|
+
try {
|
|
45
|
+
for (const e of readdirSync(abs, { withFileTypes: true })) {
|
|
46
|
+
const child = join(abs, e.name);
|
|
47
|
+
if (e.isDirectory()) coverNewDir(child);
|
|
48
|
+
else listener('rename', relative(root, child));
|
|
49
|
+
}
|
|
50
|
+
} catch {
|
|
51
|
+
/* dir vanished / unreadable — nothing to replay */
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
function attachDir(absDir: string): void {
|
|
56
|
+
if (watchedDirs.has(absDir)) return;
|
|
57
|
+
watchedDirs.add(absDir);
|
|
58
|
+
let w: FSWatcher;
|
|
59
|
+
try {
|
|
60
|
+
w = watch(absDir, { recursive: true }, (event, filename) => {
|
|
61
|
+
if (!filename) return;
|
|
62
|
+
const abs = join(absDir, filename);
|
|
63
|
+
listener(event, relative(root, abs));
|
|
64
|
+
coverNewDir(abs); // a newly-created subdir — Bun won't recurse into it on its own
|
|
65
|
+
});
|
|
66
|
+
} catch {
|
|
67
|
+
return; // dir vanished mid-attach
|
|
68
|
+
}
|
|
69
|
+
if (absDir === root) rootWatcher = w;
|
|
70
|
+
else nested.push(w);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
attachDir(root);
|
|
74
|
+
|
|
75
|
+
// Composite handle: closing it tears down the root + every nested watcher.
|
|
76
|
+
const handle = (rootWatcher ?? { close() {} }) as FSWatcher;
|
|
77
|
+
const baseClose = handle.close.bind(handle);
|
|
78
|
+
handle.close = () => {
|
|
79
|
+
baseClose();
|
|
80
|
+
for (const w of nested) {
|
|
81
|
+
try {
|
|
82
|
+
w.close();
|
|
83
|
+
} catch {
|
|
84
|
+
/* already closed */
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
return handle;
|
|
89
|
+
}
|
|
90
|
+
|
|
12
91
|
/**
|
|
13
92
|
* Attach a recursive watcher to `dirPath`. If the directory doesn't exist
|
|
14
93
|
* yet, watch the parent directory and defer the attach until the target is
|
|
@@ -21,7 +100,7 @@ import { projectPaths, getProjectRoot } from './projectContext';
|
|
|
21
100
|
function attachWhenDirExists(
|
|
22
101
|
dirPath: string,
|
|
23
102
|
attach: () => FSWatcher | null,
|
|
24
|
-
setWatcher: (w: FSWatcher | null) => void
|
|
103
|
+
setWatcher: (w: FSWatcher | null) => void,
|
|
25
104
|
): void {
|
|
26
105
|
if (existsSync(dirPath)) {
|
|
27
106
|
setWatcher(attach());
|
|
@@ -50,6 +129,13 @@ function attachWhenDirExists(
|
|
|
50
129
|
export interface FileWatchCallbacks {
|
|
51
130
|
onComponentChange?: () => Promise<void>;
|
|
52
131
|
onPageChange?: (pagePath: string) => Promise<void>;
|
|
132
|
+
/**
|
|
133
|
+
* Fires when an astro CMS template page (`src/pages/<col>/[slug].astro`) is
|
|
134
|
+
* added, edited, or removed. Distinct from onPageChange because this changes
|
|
135
|
+
* the set of collections (not just one page's content), so the handler must
|
|
136
|
+
* refresh the CMS schema cache + the `/templates/<id>` page-cache entries.
|
|
137
|
+
*/
|
|
138
|
+
onCMSTemplateChange?: () => Promise<void>;
|
|
53
139
|
onColorsChange?: () => Promise<void>;
|
|
54
140
|
onVariablesChange?: () => Promise<void>;
|
|
55
141
|
onEnumsChange?: () => Promise<void>;
|
|
@@ -76,7 +162,7 @@ export class FileWatcher {
|
|
|
76
162
|
private astroContentWatcher: FSWatcher | null = null;
|
|
77
163
|
|
|
78
164
|
constructor(private callbacks: FileWatchCallbacks) {}
|
|
79
|
-
|
|
165
|
+
|
|
80
166
|
/**
|
|
81
167
|
* Start watching components directory
|
|
82
168
|
* Watches both .json and .js files to detect component definition and JavaScript changes
|
|
@@ -85,24 +171,19 @@ export class FileWatcher {
|
|
|
85
171
|
if (!existsSync(dirPath)) {
|
|
86
172
|
return;
|
|
87
173
|
}
|
|
88
|
-
|
|
89
|
-
this.componentsWatcher =
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
if (
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
if (this.callbacks.onComponentChange) {
|
|
98
|
-
await this.callbacks.onComponentChange();
|
|
99
|
-
}
|
|
174
|
+
|
|
175
|
+
this.componentsWatcher = watchRecursive(dirPath, async (_event, filename) => {
|
|
176
|
+
// Watch .json (component definitions), .js (component JavaScript), and .css (component CSS) files
|
|
177
|
+
if (filename && (filename.endsWith('.json') || filename.endsWith('.js') || filename.endsWith('.css'))) {
|
|
178
|
+
const _fileType = filename.endsWith('.js') ? 'JavaScript' : filename.endsWith('.css') ? 'CSS' : 'component';
|
|
179
|
+
|
|
180
|
+
if (this.callbacks.onComponentChange) {
|
|
181
|
+
await this.callbacks.onComponentChange();
|
|
100
182
|
}
|
|
101
183
|
}
|
|
102
|
-
);
|
|
103
|
-
|
|
184
|
+
});
|
|
104
185
|
}
|
|
105
|
-
|
|
186
|
+
|
|
106
187
|
/**
|
|
107
188
|
* Start watching pages directory
|
|
108
189
|
*/
|
|
@@ -111,21 +192,16 @@ export class FileWatcher {
|
|
|
111
192
|
return;
|
|
112
193
|
}
|
|
113
194
|
|
|
114
|
-
this.pagesWatcher =
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
if (this.callbacks.onPageChange) {
|
|
123
|
-
await this.callbacks.onPageChange(pagePath);
|
|
124
|
-
}
|
|
195
|
+
this.pagesWatcher = watchRecursive(dirPath, async (_event, filename) => {
|
|
196
|
+
if (filename?.endsWith('.json')) {
|
|
197
|
+
const pageName = filename.replace('.json', '');
|
|
198
|
+
const pagePath = mapPageNameToPath(pageName);
|
|
199
|
+
|
|
200
|
+
if (this.callbacks.onPageChange) {
|
|
201
|
+
await this.callbacks.onPageChange(pagePath);
|
|
125
202
|
}
|
|
126
203
|
}
|
|
127
|
-
);
|
|
128
|
-
|
|
204
|
+
});
|
|
129
205
|
}
|
|
130
206
|
|
|
131
207
|
/**
|
|
@@ -137,11 +213,9 @@ export class FileWatcher {
|
|
|
137
213
|
watchTemplates(dirPath: string = projectPaths.templates()): void {
|
|
138
214
|
attachWhenDirExists(
|
|
139
215
|
dirPath,
|
|
140
|
-
() =>
|
|
141
|
-
dirPath,
|
|
142
|
-
|
|
143
|
-
async (event, filename) => {
|
|
144
|
-
if (filename && filename.endsWith('.json')) {
|
|
216
|
+
() =>
|
|
217
|
+
watchRecursive(dirPath, async (_event, filename) => {
|
|
218
|
+
if (filename?.endsWith('.json')) {
|
|
145
219
|
// Prefix with templates/ so the path is /templates/...
|
|
146
220
|
const pageName = `templates/${filename.replace('.json', '')}`;
|
|
147
221
|
const pagePath = mapPageNameToPath(pageName);
|
|
@@ -150,12 +224,13 @@ export class FileWatcher {
|
|
|
150
224
|
await this.callbacks.onPageChange(pagePath);
|
|
151
225
|
}
|
|
152
226
|
}
|
|
153
|
-
}
|
|
154
|
-
)
|
|
155
|
-
|
|
227
|
+
}),
|
|
228
|
+
(w) => {
|
|
229
|
+
this.templatesWatcher = w;
|
|
230
|
+
},
|
|
156
231
|
);
|
|
157
232
|
}
|
|
158
|
-
|
|
233
|
+
|
|
159
234
|
/**
|
|
160
235
|
* Start watching colors.json file
|
|
161
236
|
*/
|
|
@@ -166,15 +241,11 @@ export class FileWatcher {
|
|
|
166
241
|
|
|
167
242
|
// Watch the file's directory for changes
|
|
168
243
|
const dirPath = getProjectRoot();
|
|
169
|
-
this.colorsWatcher = watch(
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
async (event, filename) => {
|
|
173
|
-
if (filename === 'colors.json' && this.callbacks.onColorsChange) {
|
|
174
|
-
await this.callbacks.onColorsChange();
|
|
175
|
-
}
|
|
244
|
+
this.colorsWatcher = watch(dirPath, { recursive: false }, async (_event, filename) => {
|
|
245
|
+
if (filename === 'colors.json' && this.callbacks.onColorsChange) {
|
|
246
|
+
await this.callbacks.onColorsChange();
|
|
176
247
|
}
|
|
177
|
-
);
|
|
248
|
+
});
|
|
178
249
|
}
|
|
179
250
|
|
|
180
251
|
/**
|
|
@@ -182,15 +253,11 @@ export class FileWatcher {
|
|
|
182
253
|
*/
|
|
183
254
|
watchVariables(): void {
|
|
184
255
|
const dirPath = getProjectRoot();
|
|
185
|
-
this.variablesWatcher = watch(
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
async (event, filename) => {
|
|
189
|
-
if (filename === 'variables.json' && this.callbacks.onVariablesChange) {
|
|
190
|
-
await this.callbacks.onVariablesChange();
|
|
191
|
-
}
|
|
256
|
+
this.variablesWatcher = watch(dirPath, { recursive: false }, async (_event, filename) => {
|
|
257
|
+
if (filename === 'variables.json' && this.callbacks.onVariablesChange) {
|
|
258
|
+
await this.callbacks.onVariablesChange();
|
|
192
259
|
}
|
|
193
|
-
);
|
|
260
|
+
});
|
|
194
261
|
}
|
|
195
262
|
|
|
196
263
|
/**
|
|
@@ -198,15 +265,11 @@ export class FileWatcher {
|
|
|
198
265
|
*/
|
|
199
266
|
watchEnums(): void {
|
|
200
267
|
const dirPath = getProjectRoot();
|
|
201
|
-
this.enumsWatcher = watch(
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
async (event, filename) => {
|
|
205
|
-
if (filename === 'enums.json' && this.callbacks.onEnumsChange) {
|
|
206
|
-
await this.callbacks.onEnumsChange();
|
|
207
|
-
}
|
|
268
|
+
this.enumsWatcher = watch(dirPath, { recursive: false }, async (_event, filename) => {
|
|
269
|
+
if (filename === 'enums.json' && this.callbacks.onEnumsChange) {
|
|
270
|
+
await this.callbacks.onEnumsChange();
|
|
208
271
|
}
|
|
209
|
-
);
|
|
272
|
+
});
|
|
210
273
|
}
|
|
211
274
|
|
|
212
275
|
/**
|
|
@@ -217,20 +280,19 @@ export class FileWatcher {
|
|
|
217
280
|
watchCMS(dirPath: string = projectPaths.cms()): void {
|
|
218
281
|
attachWhenDirExists(
|
|
219
282
|
dirPath,
|
|
220
|
-
() =>
|
|
221
|
-
dirPath,
|
|
222
|
-
|
|
223
|
-
async (event, filename) => {
|
|
224
|
-
if (filename && filename.endsWith('.json')) {
|
|
283
|
+
() =>
|
|
284
|
+
watchRecursive(dirPath, async (_event, filename) => {
|
|
285
|
+
if (filename?.endsWith('.json')) {
|
|
225
286
|
// Extract collection from path: "blog/my-post.json" -> "blog"
|
|
226
|
-
const collection = filename.split('/')[0];
|
|
287
|
+
const collection = filename.split('/')[0] ?? filename;
|
|
227
288
|
if (this.callbacks.onCMSChange) {
|
|
228
289
|
await this.callbacks.onCMSChange(collection);
|
|
229
290
|
}
|
|
230
291
|
}
|
|
231
|
-
}
|
|
232
|
-
)
|
|
233
|
-
|
|
292
|
+
}),
|
|
293
|
+
(w) => {
|
|
294
|
+
this.cmsWatcher = w;
|
|
295
|
+
},
|
|
234
296
|
);
|
|
235
297
|
}
|
|
236
298
|
|
|
@@ -242,15 +304,11 @@ export class FileWatcher {
|
|
|
242
304
|
return;
|
|
243
305
|
}
|
|
244
306
|
|
|
245
|
-
this.imagesWatcher = watch(
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
async (event, filename) => {
|
|
249
|
-
if (event === 'rename' && filename && this.callbacks.onImageAdded) {
|
|
250
|
-
await this.callbacks.onImageAdded(filename);
|
|
251
|
-
}
|
|
307
|
+
this.imagesWatcher = watch(dirPath, { recursive: false }, async (event, filename) => {
|
|
308
|
+
if (event === 'rename' && filename && this.callbacks.onImageAdded) {
|
|
309
|
+
await this.callbacks.onImageAdded(filename);
|
|
252
310
|
}
|
|
253
|
-
);
|
|
311
|
+
});
|
|
254
312
|
}
|
|
255
313
|
|
|
256
314
|
/**
|
|
@@ -261,15 +319,11 @@ export class FileWatcher {
|
|
|
261
319
|
*/
|
|
262
320
|
watchProjectConfig(): void {
|
|
263
321
|
const dirPath = getProjectRoot();
|
|
264
|
-
this.projectConfigWatcher = watch(
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
async (_event, filename) => {
|
|
268
|
-
if (filename === 'project.config.json' && this.callbacks.onProjectConfigChange) {
|
|
269
|
-
await this.callbacks.onProjectConfigChange();
|
|
270
|
-
}
|
|
322
|
+
this.projectConfigWatcher = watch(dirPath, { recursive: false }, async (_event, filename) => {
|
|
323
|
+
if (filename === 'project.config.json' && this.callbacks.onProjectConfigChange) {
|
|
324
|
+
await this.callbacks.onProjectConfigChange();
|
|
271
325
|
}
|
|
272
|
-
);
|
|
326
|
+
});
|
|
273
327
|
}
|
|
274
328
|
|
|
275
329
|
/**
|
|
@@ -280,17 +334,13 @@ export class FileWatcher {
|
|
|
280
334
|
return;
|
|
281
335
|
}
|
|
282
336
|
|
|
283
|
-
this.librariesWatcher =
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
if (filename && (filename.endsWith('.css') || filename.endsWith('.js'))) {
|
|
288
|
-
if (this.callbacks.onLibraryChange) {
|
|
289
|
-
await this.callbacks.onLibraryChange();
|
|
290
|
-
}
|
|
337
|
+
this.librariesWatcher = watchRecursive(dirPath, async (_event, filename) => {
|
|
338
|
+
if (filename && (filename.endsWith('.css') || filename.endsWith('.js'))) {
|
|
339
|
+
if (this.callbacks.onLibraryChange) {
|
|
340
|
+
await this.callbacks.onLibraryChange();
|
|
291
341
|
}
|
|
292
342
|
}
|
|
293
|
-
);
|
|
343
|
+
});
|
|
294
344
|
}
|
|
295
345
|
|
|
296
346
|
/**
|
|
@@ -299,35 +349,66 @@ export class FileWatcher {
|
|
|
299
349
|
* (reload goes through the active provider), so file→editor live reload works
|
|
300
350
|
* for `.astro` the same way it does for JSON. These are no-ops in JSON projects
|
|
301
351
|
* (the src/ dirs don't exist).
|
|
352
|
+
*
|
|
353
|
+
* All three use deferred attach (like watchTemplates/watchCMS): `src/content`
|
|
354
|
+
* (and occasionally `src/components`) may not exist at startup — e.g. a project
|
|
355
|
+
* with no CMS collections yet. Without deferral the watcher would silently
|
|
356
|
+
* early-out and the first collection's item edits wouldn't live-reload until a
|
|
357
|
+
* dev-server restart.
|
|
302
358
|
*/
|
|
303
359
|
watchAstroPages(dirPath: string = join(getProjectRoot(), 'src', 'pages')): void {
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
360
|
+
attachWhenDirExists(
|
|
361
|
+
dirPath,
|
|
362
|
+
() =>
|
|
363
|
+
watchRecursive(dirPath, async (_event, filename) => {
|
|
364
|
+
if (!filename?.endsWith('.astro')) return;
|
|
365
|
+
// Dynamic CMS routes ([slug].astro) are CMS template pages, not regular pages.
|
|
366
|
+
// A change there means a collection was added/edited/removed — route it to the
|
|
367
|
+
// CMS-template refresh (schema cache + /templates/<id> page cache). Mapping its
|
|
368
|
+
// on-disk name ([slug]) as a page path would be wrong, and skipping it (as before)
|
|
369
|
+
// left new collections + their template pages invisible until a dev-server restart.
|
|
370
|
+
if (filename.includes('[')) {
|
|
371
|
+
if (this.callbacks.onCMSTemplateChange) await this.callbacks.onCMSTemplateChange();
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
const pagePath = mapPageNameToPath(filename.replace(/\.astro$/, ''));
|
|
375
|
+
if (this.callbacks.onPageChange) await this.callbacks.onPageChange(pagePath);
|
|
376
|
+
}),
|
|
377
|
+
(w) => {
|
|
378
|
+
this.astroPagesWatcher = w;
|
|
379
|
+
},
|
|
380
|
+
);
|
|
312
381
|
}
|
|
313
382
|
|
|
314
383
|
watchAstroComponents(dirPath: string = join(getProjectRoot(), 'src', 'components')): void {
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
384
|
+
attachWhenDirExists(
|
|
385
|
+
dirPath,
|
|
386
|
+
() =>
|
|
387
|
+
watchRecursive(dirPath, async (_event, filename) => {
|
|
388
|
+
if (filename?.endsWith('.astro') && this.callbacks.onComponentChange) {
|
|
389
|
+
await this.callbacks.onComponentChange();
|
|
390
|
+
}
|
|
391
|
+
}),
|
|
392
|
+
(w) => {
|
|
393
|
+
this.astroComponentsWatcher = w;
|
|
394
|
+
},
|
|
395
|
+
);
|
|
321
396
|
}
|
|
322
397
|
|
|
323
398
|
watchAstroContent(dirPath: string = join(getProjectRoot(), 'src', 'content')): void {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
399
|
+
attachWhenDirExists(
|
|
400
|
+
dirPath,
|
|
401
|
+
() =>
|
|
402
|
+
watchRecursive(dirPath, async (_event, filename) => {
|
|
403
|
+
if (filename?.endsWith('.json') && this.callbacks.onCMSChange) {
|
|
404
|
+
const collection = filename.split('/')[0] ?? filename;
|
|
405
|
+
await this.callbacks.onCMSChange(collection);
|
|
406
|
+
}
|
|
407
|
+
}),
|
|
408
|
+
(w) => {
|
|
409
|
+
this.astroContentWatcher = w;
|
|
410
|
+
},
|
|
411
|
+
);
|
|
331
412
|
}
|
|
332
413
|
|
|
333
414
|
/**
|
|
@@ -349,7 +430,7 @@ export class FileWatcher {
|
|
|
349
430
|
this.watchAstroComponents();
|
|
350
431
|
this.watchAstroContent();
|
|
351
432
|
}
|
|
352
|
-
|
|
433
|
+
|
|
353
434
|
/**
|
|
354
435
|
* Stop watching all directories
|
|
355
436
|
*/
|
|
@@ -424,7 +505,11 @@ export class FileWatcher {
|
|
|
424
505
|
* Check if watchers are active
|
|
425
506
|
*/
|
|
426
507
|
isWatching(): boolean {
|
|
427
|
-
return
|
|
508
|
+
return (
|
|
509
|
+
this.componentsWatcher !== null ||
|
|
510
|
+
this.pagesWatcher !== null ||
|
|
511
|
+
this.cmsWatcher !== null ||
|
|
512
|
+
this.imagesWatcher !== null
|
|
513
|
+
);
|
|
428
514
|
}
|
|
429
515
|
}
|
|
430
|
-
|
package/lib/server/index.ts
CHANGED
|
@@ -29,7 +29,9 @@ export { VariableService, variableService } from './services/VariableService';
|
|
|
29
29
|
export { EnumService, enumService } from './services/EnumService';
|
|
30
30
|
|
|
31
31
|
// Providers
|
|
32
|
-
|
|
32
|
+
// FileSystemPageProvider was retired with the bespoke JSON renderer (the editor is
|
|
33
|
+
// meno-astro-only; AstroPageProvider is the live page provider). FileSystemCMSProvider
|
|
34
|
+
// remains: the JSON→astro export (build-astro.ts) still reads JSON CMS items through it.
|
|
33
35
|
export { FileSystemCMSProvider } from './providers/fileSystemCMSProvider';
|
|
34
36
|
|
|
35
37
|
// CMS interfaces
|
|
@@ -39,10 +41,16 @@ export type { CMSProvider, CMSSchemaInfo } from '../shared/interfaces/contentPro
|
|
|
39
41
|
export { handleCoreApiRoutes, type CoreRouteContext } from './routes/api/core-routes';
|
|
40
42
|
|
|
41
43
|
// CMS read routes (GET handlers)
|
|
42
|
-
export {
|
|
44
|
+
export {
|
|
45
|
+
handleCollectionsRoute,
|
|
46
|
+
handleCollectionSchemaRoute,
|
|
47
|
+
handleItemsRoute,
|
|
48
|
+
handleItemRoute,
|
|
49
|
+
} from './routes/api/cms';
|
|
43
50
|
|
|
44
51
|
// Route utilities
|
|
45
52
|
export { jsonResponse, errorResponse } from './routes/api/shared';
|
|
53
|
+
export { createCorsHeaders, handleCorsPreflight } from './middleware/cors';
|
|
46
54
|
|
|
47
55
|
// Note: Write route handlers moved to @meno/studio:
|
|
48
56
|
// - handleSavePageRoute
|
|
@@ -64,28 +72,17 @@ export * from './projectContext';
|
|
|
64
72
|
|
|
65
73
|
// File watcher
|
|
66
74
|
export { FileWatcherService } from './services/fileWatcherService';
|
|
75
|
+
// Recursive watch shim that also covers subdirs created AFTER the watch began (Bun's native
|
|
76
|
+
// `fs.watch({recursive:true})` does not — see fileWatcher.ts). Reused by the studio Astro
|
|
77
|
+
// dev-server's workdir mirror so a new collection/page dir live-syncs under Bun.
|
|
78
|
+
export { watchRecursive } from './fileWatcher';
|
|
67
79
|
|
|
68
80
|
// Migration
|
|
69
81
|
export { migrateTemplatesDirectory } from './migrateTemplates';
|
|
70
82
|
|
|
71
|
-
// Static build
|
|
72
|
-
export { buildStaticPages } from '../../build-static';
|
|
73
|
-
|
|
74
83
|
// Astro export
|
|
75
84
|
export { buildAstroProject } from '../../build-astro';
|
|
76
85
|
|
|
77
|
-
// Next.js export
|
|
78
|
-
export { buildNextProject } from '../../build-next';
|
|
79
|
-
|
|
80
|
-
// Webflow export
|
|
81
|
-
export { buildWebflowPayload, wrapInWebflowTemplate } from './webflow';
|
|
82
|
-
export type {
|
|
83
|
-
WebflowExportPayload,
|
|
84
|
-
WebflowPage,
|
|
85
|
-
WebflowElement,
|
|
86
|
-
WebflowStyleClass,
|
|
87
|
-
} from './webflow';
|
|
88
|
-
|
|
89
86
|
// Utilities
|
|
90
87
|
export * from './utils';
|
|
91
88
|
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import { describe, test, expect } from 'bun:test';
|
|
1
|
+
import { describe, test, expect, afterEach } from 'bun:test';
|
|
2
|
+
import { writeFileSync, mkdtempSync, rmSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { tmpdir } from 'node:os';
|
|
2
5
|
import {
|
|
3
6
|
parseJSON,
|
|
7
|
+
loadAndParseJSON,
|
|
8
|
+
loadJSONFile,
|
|
4
9
|
mapPageNameToPath,
|
|
5
10
|
mapPathToPageName,
|
|
6
11
|
getBreakpointConfig,
|
|
@@ -8,6 +13,7 @@ import {
|
|
|
8
13
|
getI18nConfig,
|
|
9
14
|
setI18nConfig,
|
|
10
15
|
} from './jsonLoader';
|
|
16
|
+
import { setErrorHandler } from '../shared/errorLogger';
|
|
11
17
|
import { DEFAULT_BREAKPOINTS } from '../shared/breakpoints';
|
|
12
18
|
import { DEFAULT_I18N_CONFIG } from '../shared/i18n';
|
|
13
19
|
|
|
@@ -56,6 +62,37 @@ describe('jsonLoader', () => {
|
|
|
56
62
|
});
|
|
57
63
|
});
|
|
58
64
|
|
|
65
|
+
describe('file-load error observability', () => {
|
|
66
|
+
afterEach(() => setErrorHandler(null));
|
|
67
|
+
|
|
68
|
+
test('loadAndParseJSON surfaces corrupt JSON via the error handler but still returns null', async () => {
|
|
69
|
+
const dir = mkdtempSync(join(tmpdir(), 'jsonloader-'));
|
|
70
|
+
const filePath = join(dir, 'broken.json');
|
|
71
|
+
writeFileSync(filePath, '{ not valid json ', 'utf8');
|
|
72
|
+
|
|
73
|
+
const entries: string[] = [];
|
|
74
|
+
setErrorHandler((entry) => entries.push(entry.location));
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
const result = await loadAndParseJSON(filePath);
|
|
78
|
+
expect(result).toBeNull();
|
|
79
|
+
expect(entries).toContain('jsonLoader.loadAndParseJSON');
|
|
80
|
+
} finally {
|
|
81
|
+
rmSync(dir, { recursive: true, force: true });
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
test('loadJSONFile returns null without logging for a missing file', async () => {
|
|
86
|
+
const entries: string[] = [];
|
|
87
|
+
setErrorHandler((entry) => entries.push(entry.location));
|
|
88
|
+
|
|
89
|
+
const result = await loadJSONFile(join(tmpdir(), 'definitely-does-not-exist-xyz.json'));
|
|
90
|
+
expect(result).toBeNull();
|
|
91
|
+
// Missing file is gated by fileExists() — no error should be logged.
|
|
92
|
+
expect(entries).toHaveLength(0);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
59
96
|
describe('breakpoint config cache', () => {
|
|
60
97
|
test('returns default config initially', () => {
|
|
61
98
|
const config = getBreakpointConfig();
|
|
@@ -65,7 +102,7 @@ describe('jsonLoader', () => {
|
|
|
65
102
|
test('returns cached config after set', () => {
|
|
66
103
|
const customConfig = {
|
|
67
104
|
mobile: { breakpoint: 500, previewPoint: 375 },
|
|
68
|
-
tablet: { breakpoint: 900, previewPoint: 768 }
|
|
105
|
+
tablet: { breakpoint: 900, previewPoint: 768 },
|
|
69
106
|
};
|
|
70
107
|
setBreakpointConfig(customConfig);
|
|
71
108
|
const config = getBreakpointConfig();
|