meno-core 1.0.53 → 1.0.54
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 +48 -57
- package/build-astro.ts +131 -113
- package/build-next.ts +109 -96
- package/build-static.test.ts +39 -10
- package/build-static.ts +120 -122
- package/dist/bin/cli.js +34 -38
- package/dist/bin/cli.js.map +2 -2
- package/dist/build-static.js +12 -11
- package/dist/chunks/chunk-2AR55GYH.js +42 -0
- package/dist/chunks/chunk-2AR55GYH.js.map +7 -0
- package/dist/chunks/{chunk-IGYR22T6.js → chunk-2FN4UOVO.js} +512 -239
- package/dist/chunks/chunk-2FN4UOVO.js.map +7 -0
- package/dist/chunks/chunk-3XER4E5W.js +168 -0
- package/dist/chunks/chunk-3XER4E5W.js.map +7 -0
- package/dist/chunks/{chunk-X754AHS5.js → chunk-5ETZFREW.js} +9 -12
- package/dist/chunks/chunk-5ETZFREW.js.map +7 -0
- package/dist/chunks/{chunk-2MHDV5BF.js → chunk-7E4IF5L7.js} +15 -21
- package/dist/chunks/chunk-7E4IF5L7.js.map +7 -0
- package/dist/chunks/{chunk-JGWFTO6P.js → chunk-7HWQUVTU.js} +1578 -1349
- package/dist/chunks/chunk-7HWQUVTU.js.map +7 -0
- package/dist/chunks/{chunk-O3NAGJP4.js → chunk-AE3QK5QW.js} +110 -21
- package/dist/chunks/chunk-AE3QK5QW.js.map +7 -0
- package/dist/chunks/{chunk-GZHGVVW3.js → chunk-F6KTJYGV.js} +7 -7
- package/dist/chunks/chunk-F6KTJYGV.js.map +7 -0
- package/dist/chunks/{chunk-WQFG7PAH.js → chunk-FZITJSSS.js} +2 -6
- package/dist/chunks/chunk-FZITJSSS.js.map +7 -0
- package/dist/chunks/{chunk-QB2LNO4W.js → chunk-GSYYA5GX.js} +2 -2
- package/dist/chunks/chunk-GSYYA5GX.js.map +7 -0
- package/dist/chunks/{chunk-YBLHKYFF.js → chunk-HIZMY3EP.js} +1 -1
- package/dist/chunks/chunk-HIZMY3EP.js.map +7 -0
- package/dist/chunks/{chunk-AZQYF6KE.js → chunk-I2WEGYA7.js} +41 -176
- package/dist/chunks/chunk-I2WEGYA7.js.map +7 -0
- package/dist/chunks/{chunk-I7YIGZXT.js → chunk-JNO3CNLJ.js} +6 -9
- package/dist/chunks/chunk-JNO3CNLJ.js.map +7 -0
- package/dist/chunks/{chunk-UB44F4Z2.js → chunk-NVRBTSQG.js} +2 -4
- package/dist/chunks/chunk-NVRBTSQG.js.map +7 -0
- package/dist/chunks/{chunk-JGP5A3Y5.js → chunk-Q4OBWKXG.js} +40 -33
- package/dist/chunks/chunk-Q4OBWKXG.js.map +7 -0
- package/dist/chunks/{chunk-R6XHAFBF.js → chunk-QTE32Y53.js} +250 -242
- package/dist/chunks/chunk-QTE32Y53.js.map +7 -0
- package/dist/chunks/{chunk-H3GJ4H2U.js → chunk-STDY3OVM.js} +214 -85
- package/dist/chunks/chunk-STDY3OVM.js.map +7 -0
- package/dist/chunks/configService-PRJZF7Y6.js +14 -0
- package/dist/chunks/{constants-STK2YBIW.js → constants-KIQEYMAM.js} +2 -2
- package/dist/chunks/{fs-JGINUXGL.js → fs-ZI5JEU7V.js} +2 -2
- package/dist/entries/server-router.js +14 -19
- package/dist/entries/server-router.js.map +2 -2
- package/dist/lib/client/index.js +638 -332
- package/dist/lib/client/index.js.map +2 -2
- package/dist/lib/server/index.js +177 -235
- package/dist/lib/server/index.js.map +2 -2
- package/dist/lib/shared/index.js +80 -44
- package/dist/lib/shared/index.js.map +2 -2
- package/dist/lib/shared/richtext/index.js +1 -1
- package/dist/lib/test-utils/index.js +38 -60
- package/dist/lib/test-utils/index.js.map +2 -2
- package/entries/client-router.tsx +10 -8
- package/entries/server-router.tsx +1 -7
- package/lib/client/ClientInitializer.ts +8 -8
- package/lib/client/ErrorBoundary.test.tsx +146 -143
- package/lib/client/ErrorBoundary.tsx +175 -127
- package/lib/client/componentRegistry.test.ts +96 -108
- package/lib/client/componentRegistry.ts +1 -2
- package/lib/client/contexts/ThemeContext.tsx +3 -2
- package/lib/client/core/ComponentBuilder.test.ts +513 -560
- package/lib/client/core/ComponentBuilder.ts +318 -146
- package/lib/client/core/ComponentRenderer.test.tsx +1 -2
- package/lib/client/core/ComponentRenderer.tsx +46 -33
- package/lib/client/core/builders/embedBuilder.ts +241 -53
- package/lib/client/core/builders/linkBuilder.ts +71 -44
- package/lib/client/core/builders/linkNodeBuilder.ts +78 -53
- package/lib/client/core/builders/listBuilder.ts +115 -86
- package/lib/client/core/builders/localeListBuilder.ts +95 -60
- package/lib/client/core/builders/types.ts +5 -5
- package/lib/client/core/cmsTemplateProcessor.ts +7 -7
- 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 +8 -0
- package/lib/client/hmrCssReload.ts +14 -8
- package/lib/client/hmrWebSocket.ts +9 -14
- package/lib/client/hooks/useColorVariables.test.ts +21 -21
- package/lib/client/hooks/useColorVariables.ts +12 -10
- package/lib/client/hooks/usePropertyAutocomplete.ts +3 -5
- package/lib/client/hooks/useVariables.ts +4 -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 +19 -21
- package/lib/client/meno-filter/MenoFilter.ts +5 -9
- package/lib/client/meno-filter/bindings.ts +15 -40
- package/lib/client/meno-filter/init.ts +1 -1
- package/lib/client/meno-filter/renderer.ts +23 -29
- package/lib/client/meno-filter/script.generated.ts +1 -3
- package/lib/client/meno-filter/ui.ts +3 -5
- package/lib/client/meno-filter/updates.ts +15 -21
- package/lib/client/navigation.test.ts +159 -159
- package/lib/client/navigation.ts +0 -1
- package/lib/client/responsiveStyleResolver.test.ts +230 -228
- package/lib/client/responsiveStyleResolver.ts +13 -16
- package/lib/client/routing/RouteLoader.test.ts +23 -24
- package/lib/client/routing/RouteLoader.ts +22 -35
- package/lib/client/routing/Router.tsx +31 -3
- package/lib/client/scripts/ScriptExecutor.test.ts +157 -158
- package/lib/client/scripts/ScriptExecutor.ts +15 -33
- package/lib/client/services/PrefetchService.test.ts +2 -2
- package/lib/client/services/PrefetchService.ts +10 -24
- package/lib/client/styleProcessor.test.ts +9 -9
- package/lib/client/styleProcessor.ts +18 -15
- package/lib/client/styles/StyleInjector.test.ts +122 -115
- package/lib/client/styles/StyleInjector.ts +9 -6
- package/lib/client/styles/UtilityClassCollector.ts +19 -26
- package/lib/client/styles/cspNonce.test.ts +2 -5
- package/lib/client/templateEngine.test.ts +554 -482
- package/lib/client/templateEngine.ts +200 -64
- 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 +2 -5
- package/lib/server/__integration__/ssr-rendering.test.ts +47 -37
- package/lib/server/__integration__/static-assets.test.ts +1 -1
- package/lib/server/__integration__/test-helpers.ts +84 -70
- package/lib/server/ab/generateFunctions.ts +12 -10
- package/lib/server/astro/cmsPageEmitter.ts +23 -38
- package/lib/server/astro/componentEmitter.ts +25 -36
- package/lib/server/astro/cssCollector.ts +10 -26
- package/lib/server/astro/nodeToAstro.test.ts +1750 -30
- package/lib/server/astro/nodeToAstro.ts +198 -187
- package/lib/server/astro/normalizeOrphanTemplateProps.test.ts +105 -109
- package/lib/server/astro/normalizeOrphanTemplateProps.ts +4 -12
- 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 +14 -17
- package/lib/server/createServer.ts +5 -17
- package/lib/server/cssGenerator.test.ts +35 -44
- package/lib/server/cssGenerator.ts +6 -17
- package/lib/server/fileWatcher.test.ts +124 -10
- package/lib/server/fileWatcher.ts +124 -118
- package/lib/server/index.ts +7 -1
- package/lib/server/jsonLoader.test.ts +39 -2
- package/lib/server/jsonLoader.ts +33 -31
- package/lib/server/middleware/cors.test.ts +20 -20
- package/lib/server/middleware/cors.ts +28 -4
- package/lib/server/middleware/errorHandler.test.ts +5 -3
- package/lib/server/middleware/errorHandler.ts +3 -8
- package/lib/server/middleware/index.ts +0 -1
- package/lib/server/middleware/logger.test.ts +7 -5
- package/lib/server/middleware/logger.ts +10 -22
- package/lib/server/pageCache.test.ts +76 -77
- package/lib/server/pageCache.ts +0 -1
- package/lib/server/projectContext.ts +4 -3
- package/lib/server/providers/fileSystemCMSProvider.test.ts +124 -95
- package/lib/server/providers/fileSystemCMSProvider.ts +35 -20
- package/lib/server/providers/fileSystemPageProvider.test.ts +84 -0
- package/lib/server/providers/fileSystemPageProvider.ts +31 -12
- package/lib/server/routes/api/cms.test.ts +26 -14
- package/lib/server/routes/api/cms.ts +9 -14
- package/lib/server/routes/api/components.ts +30 -34
- package/lib/server/routes/api/config.ts +0 -1
- package/lib/server/routes/api/core-routes.ts +47 -74
- package/lib/server/routes/api/functions.ts +8 -16
- 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 +1 -3
- package/lib/server/routes/api/variables.ts +1 -1
- package/lib/server/routes/index.ts +23 -26
- package/lib/server/routes/pages.ts +34 -29
- package/lib/server/routes/static.ts +16 -4
- package/lib/server/runtime/bundler.ts +47 -32
- package/lib/server/runtime/fs.ts +3 -13
- package/lib/server/runtime/httpServer.ts +5 -9
- package/lib/server/services/ColorService.ts +32 -27
- package/lib/server/services/EnumService.test.ts +2 -6
- package/lib/server/services/EnumService.ts +7 -2
- package/lib/server/services/VariableService.test.ts +1 -5
- package/lib/server/services/VariableService.ts +6 -1
- package/lib/server/services/cmsService.test.ts +116 -78
- package/lib/server/services/cmsService.ts +24 -54
- package/lib/server/services/componentService.test.ts +122 -36
- package/lib/server/services/componentService.ts +54 -38
- package/lib/server/services/configService.test.ts +9 -31
- package/lib/server/services/configService.ts +20 -27
- package/lib/server/services/fileWatcherService.ts +40 -6
- package/lib/server/services/index.ts +0 -1
- package/lib/server/services/pageService.test.ts +1 -3
- package/lib/server/services/pageService.ts +14 -13
- package/lib/server/ssr/attributeBuilder.ts +16 -6
- package/lib/server/ssr/buildErrorOverlay.ts +11 -12
- package/lib/server/ssr/clientDataInjector.ts +7 -21
- package/lib/server/ssr/cmsSSRProcessor.ts +3 -6
- 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 +3 -9
- package/lib/server/ssr/htmlGenerator.test.ts +120 -43
- package/lib/server/ssr/htmlGenerator.ts +120 -85
- package/lib/server/ssr/imageMetadata.test.ts +3 -1
- package/lib/server/ssr/imageMetadata.ts +25 -19
- package/lib/server/ssr/jsCollector.test.ts +3 -13
- package/lib/server/ssr/jsCollector.ts +3 -8
- package/lib/server/ssr/liveReloadIntegration.test.ts +69 -28
- 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 +196 -246
- package/lib/server/ssr/ssrRenderer.ts +609 -225
- package/lib/server/ssrRenderer.test.ts +1044 -950
- package/lib/server/utils/jsonLineMapper.test.ts +28 -28
- package/lib/server/utils/jsonLineMapper.ts +1 -1
- package/lib/server/validateStyleCoverage.ts +18 -20
- package/lib/server/webflow/buildWebflow.ts +41 -53
- package/lib/server/webflow/nodeToWebflow.test.ts +150 -218
- package/lib/server/webflow/nodeToWebflow.ts +195 -258
- package/lib/server/webflow/styleMapper.test.ts +15 -56
- package/lib/server/webflow/styleMapper.ts +33 -41
- package/lib/server/webflow/types.ts +1 -8
- package/lib/server/websocketManager.ts +16 -19
- package/lib/shared/attributeNodeUtils.test.ts +15 -15
- package/lib/shared/attributeNodeUtils.ts +5 -12
- package/lib/shared/breakpoints.ts +4 -11
- package/lib/shared/cmsQueryParser.test.ts +50 -42
- package/lib/shared/cmsQueryParser.ts +49 -31
- package/lib/shared/colorVariableUtils.test.ts +5 -5
- package/lib/shared/colorVariableUtils.ts +3 -8
- package/lib/shared/componentRefs.ts +1 -5
- package/lib/shared/constants.test.ts +3 -3
- package/lib/shared/constants.ts +4 -8
- package/lib/shared/cssGeneration.test.ts +262 -144
- package/lib/shared/cssGeneration.ts +189 -516
- package/lib/shared/cssNamedColors.ts +152 -30
- package/lib/shared/cssProperties.test.ts +5 -6
- package/lib/shared/cssProperties.ts +296 -112
- package/lib/shared/elementClassName.test.ts +109 -109
- package/lib/shared/elementClassName.ts +1 -1
- package/lib/shared/elementUtils.ts +12 -16
- 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 +119 -0
- package/lib/shared/expressionEvaluator.ts +43 -24
- package/lib/shared/fontLoader.test.ts +19 -5
- package/lib/shared/friendlyError.ts +2 -3
- package/lib/shared/gradientUtils.test.ts +1 -5
- package/lib/shared/gradientUtils.ts +2 -6
- package/lib/shared/hrefRefs.ts +2 -10
- package/lib/shared/i18n.test.ts +1 -1
- package/lib/shared/i18n.ts +13 -34
- package/lib/shared/index.ts +4 -0
- package/lib/shared/inlineSvgStyleRules.ts +2 -4
- package/lib/shared/interactiveStyleMappings.test.ts +11 -33
- package/lib/shared/interactiveStyleMappings.ts +9 -16
- package/lib/shared/interactiveStyles.test.ts +165 -188
- package/lib/shared/interfaces/contentProvider.ts +1 -1
- package/lib/shared/itemTemplateUtils.test.ts +6 -12
- package/lib/shared/itemTemplateUtils.ts +19 -35
- package/lib/shared/jsonRepair.ts +8 -2
- package/lib/shared/libraryLoader.test.ts +15 -49
- package/lib/shared/libraryLoader.ts +7 -22
- package/lib/shared/netlifyLocale404.test.ts +179 -0
- package/lib/shared/netlifyLocale404.ts +110 -0
- package/lib/shared/nodeUtils.test.ts +24 -16
- package/lib/shared/nodeUtils.ts +49 -19
- package/lib/shared/pathArrayUtils.test.ts +1 -2
- package/lib/shared/pathArrayUtils.ts +1 -1
- package/lib/shared/pathSecurity.ts +1 -1
- package/lib/shared/pathUtils.test.ts +4 -6
- package/lib/shared/pathUtils.ts +42 -48
- 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 +14 -17
- package/lib/shared/paths/PathUtils.ts +9 -10
- package/lib/shared/paths/PathValidator.test.ts +2 -15
- package/lib/shared/paths/PathValidator.ts +11 -9
- package/lib/shared/paths/index.ts +1 -2
- package/lib/shared/propResolver.test.ts +240 -244
- package/lib/shared/propResolver.ts +14 -25
- package/lib/shared/pxToRem.test.ts +7 -6
- package/lib/shared/pxToRem.ts +2 -5
- package/lib/shared/registry/BaseNodeTypeRegistry.test.ts +9 -5
- package/lib/shared/registry/ClientRegistry.ts +0 -1
- package/lib/shared/registry/ComponentRegistry.test.ts +43 -29
- package/lib/shared/registry/ComponentRegistry.ts +9 -11
- package/lib/shared/registry/NodeTypeDefinition.ts +15 -8
- package/lib/shared/registry/RegistryManager.ts +1 -2
- package/lib/shared/registry/SSRRegistry.ts +0 -1
- package/lib/shared/registry/createNodeType.ts +7 -9
- package/lib/shared/registry/defineNodeType.ts +2 -6
- package/lib/shared/registry/index.ts +0 -1
- package/lib/shared/registry/nodeTypes/ComponentInstanceNodeType.ts +14 -15
- package/lib/shared/registry/nodeTypes/EmbedNodeType.ts +18 -11
- package/lib/shared/registry/nodeTypes/HtmlNodeType.ts +47 -18
- package/lib/shared/registry/nodeTypes/LinkNodeType.ts +21 -19
- package/lib/shared/registry/nodeTypes/ListNodeType.ts +78 -74
- package/lib/shared/registry/nodeTypes/LocaleListNodeType.ts +27 -21
- package/lib/shared/registry/nodeTypes/SlotMarkerType.ts +6 -7
- package/lib/shared/registry/nodeTypes/index.ts +10 -2
- package/lib/shared/responsiveScaling.test.ts +15 -31
- package/lib/shared/responsiveScaling.ts +55 -37
- package/lib/shared/responsiveStyleUtils.ts +11 -13
- package/lib/shared/richtext/htmlToTiptap.test.ts +23 -14
- package/lib/shared/richtext/htmlToTiptap.ts +1 -3
- 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 +5 -10
- package/lib/shared/styleUtils.test.ts +87 -61
- package/lib/shared/styleUtils.ts +5 -6
- package/lib/shared/themeDefaults.test.ts +11 -11
- package/lib/shared/themeDefaults.ts +3 -4
- package/lib/shared/tree/PathBuilder.test.ts +62 -138
- package/lib/shared/tree/PathBuilder.ts +49 -39
- package/lib/shared/treePathUtils.test.ts +2 -10
- package/lib/shared/treePathUtils.ts +54 -59
- package/lib/shared/types/api.ts +1 -2
- package/lib/shared/types/cms.ts +25 -21
- package/lib/shared/types/comment.ts +49 -16
- package/lib/shared/types/components.ts +27 -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 +2 -2
- package/lib/shared/types/styles.ts +0 -1
- package/lib/shared/types/variables.test.ts +4 -13
- package/lib/shared/types/variables.ts +48 -27
- package/lib/shared/types.ts +1 -2
- package/lib/shared/utilityClassConfig.ts +648 -321
- package/lib/shared/utilityClassMapper.test.ts +203 -92
- package/lib/shared/utilityClassMapper.ts +188 -246
- package/lib/shared/utilityClassNames.ts +326 -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/propValidator.test.ts +18 -20
- package/lib/shared/validation/propValidator.ts +12 -17
- package/lib/shared/validation/schemas.test.ts +24 -33
- package/lib/shared/validation/schemas.ts +469 -344
- package/lib/shared/validation/validators.test.ts +1 -6
- package/lib/shared/validation/validators.ts +89 -68
- package/lib/shared/viewportUnits.integration.test.ts +14 -10
- package/lib/shared/viewportUnits.test.ts +11 -23
- package/lib/test-utils/dom-setup.ts +1 -1
- package/lib/test-utils/factories/ConsoleMockFactory.ts +3 -7
- package/lib/test-utils/factories/DomMockFactory.ts +7 -19
- 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 +5 -9
- package/lib/test-utils/factories/StoreMockFactory.ts +14 -25
- 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 +12 -18
- package/lib/test-utils/mocks.ts +4 -2
- package/package.json +1 -1
- package/scripts/build-meno-filter.ts +1 -4
- package/vite.config.ts +4 -4
- package/dist/chunks/chunk-2MHDV5BF.js.map +0 -7
- package/dist/chunks/chunk-AZQYF6KE.js.map +0 -7
- package/dist/chunks/chunk-GZHGVVW3.js.map +0 -7
- package/dist/chunks/chunk-H3GJ4H2U.js.map +0 -7
- package/dist/chunks/chunk-I7YIGZXT.js.map +0 -7
- package/dist/chunks/chunk-IGYR22T6.js.map +0 -7
- 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.map +0 -7
- 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 → configService-PRJZF7Y6.js.map} +0 -0
- /package/dist/chunks/{constants-STK2YBIW.js.map → constants-KIQEYMAM.js.map} +0 -0
- /package/dist/chunks/{fs-JGINUXGL.js.map → fs-ZI5JEU7V.js.map} +0 -0
package/build-static.ts
CHANGED
|
@@ -4,37 +4,37 @@
|
|
|
4
4
|
* CSP-compliant: Extracts JavaScript to external files
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { existsSync, readdirSync, mkdirSync, rmSync, statSync, copyFileSync, unlinkSync, writeFileSync } from
|
|
8
|
-
import { writeFile, readFile } from
|
|
9
|
-
import { join } from
|
|
10
|
-
import type { BuildError, BuildErrorsData } from
|
|
11
|
-
import { createHash } from
|
|
7
|
+
import { existsSync, readdirSync, mkdirSync, rmSync, statSync, copyFileSync, unlinkSync, writeFileSync } from 'fs';
|
|
8
|
+
import { writeFile, readFile } from 'fs/promises';
|
|
9
|
+
import { join } from 'path';
|
|
10
|
+
import type { BuildError, BuildErrorsData } from './lib/server/ssr/buildErrorOverlay';
|
|
11
|
+
import { createHash } from 'crypto';
|
|
12
12
|
import { inspect, minifyJS as runtimeMinifyJS } from './lib/server/runtime';
|
|
13
13
|
import {
|
|
14
14
|
loadJSONFile,
|
|
15
15
|
loadComponentDirectory,
|
|
16
16
|
mapPageNameToPath,
|
|
17
17
|
parseJSON,
|
|
18
|
-
loadI18nConfig
|
|
19
|
-
} from
|
|
20
|
-
import { generateSSRHTML } from
|
|
21
|
-
import type { SSRHTMLResult } from
|
|
22
|
-
import { prepareClientData, type ClientDataCollection } from
|
|
23
|
-
import { clearJSValidationCache, getJSValidationErrors } from
|
|
24
|
-
import { projectPaths } from
|
|
25
|
-
import { loadProjectConfig } from
|
|
26
|
-
import { FileSystemCMSProvider } from
|
|
27
|
-
import { CMSService } from
|
|
28
|
-
import { isI18nValue, resolveI18nValue } from
|
|
29
|
-
import type { ComponentDefinition, JSONPage, CMSSchema, CMSItem, I18nConfig, Experiment } from
|
|
30
|
-
import { isItemDraftForLocale, isItemFullyPublished } from
|
|
31
|
-
import type { SlugMap } from
|
|
32
|
-
import { buildItemUrl } from
|
|
33
|
-
import { generateMiddleware, generateTrackFunction, generateResultsFunction } from
|
|
34
|
-
import { generateTrackingScript } from
|
|
35
|
-
import { migrateTemplatesDirectory } from
|
|
36
|
-
import { extractLibraryOrigins, collectComponentLibraries, filterLibrariesByContext } from
|
|
37
|
-
import type { LibrariesConfig } from
|
|
18
|
+
loadI18nConfig,
|
|
19
|
+
} from './lib/server/jsonLoader';
|
|
20
|
+
import { generateSSRHTML } from './lib/server/ssrRenderer';
|
|
21
|
+
import type { SSRHTMLResult } from './lib/server/ssr/htmlGenerator';
|
|
22
|
+
import { prepareClientData, type ClientDataCollection } from './lib/server/ssr/clientDataInjector';
|
|
23
|
+
import { clearJSValidationCache, getJSValidationErrors } from './lib/server/ssr/jsCollector';
|
|
24
|
+
import { projectPaths } from './lib/server/projectContext';
|
|
25
|
+
import { loadProjectConfig } from './lib/shared/fontLoader';
|
|
26
|
+
import { FileSystemCMSProvider } from './lib/server/providers/fileSystemCMSProvider';
|
|
27
|
+
import { CMSService } from './lib/server/services/cmsService';
|
|
28
|
+
import { isI18nValue, resolveI18nValue } from './lib/shared/i18n';
|
|
29
|
+
import type { ComponentDefinition, JSONPage, CMSSchema, CMSItem, I18nConfig, Experiment } from './lib/shared/types';
|
|
30
|
+
import { isItemDraftForLocale, isItemFullyPublished } from './lib/shared/types';
|
|
31
|
+
import type { SlugMap } from './lib/shared/slugTranslator';
|
|
32
|
+
import { buildItemUrl } from './lib/shared/itemTemplateUtils';
|
|
33
|
+
import { generateMiddleware, generateTrackFunction, generateResultsFunction } from './lib/server/ab/generateFunctions';
|
|
34
|
+
import { generateTrackingScript } from './lib/server/ab/trackingScript';
|
|
35
|
+
import { migrateTemplatesDirectory } from './lib/server/migrateTemplates';
|
|
36
|
+
import { extractLibraryOrigins, collectComponentLibraries, filterLibrariesByContext } from './lib/shared/libraryLoader';
|
|
37
|
+
import type { LibrariesConfig } from './lib/shared/types/libraries';
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
40
|
* Collect build errors for error overlay
|
|
@@ -157,6 +157,15 @@ function copyDirectory(src: string, dest: string): void {
|
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
+
/**
|
|
161
|
+
* Normalize a slug from meta.slugs to a bare slug (no leading/trailing slashes).
|
|
162
|
+
* Editors/importers sometimes store path-like slugs ("/", "/privacy") — without
|
|
163
|
+
* this, "/" produces a file literally named ".html" instead of "index.html".
|
|
164
|
+
* Mirrors the defensive strip in buildPageUrlForLocale (slugTranslator.ts).
|
|
165
|
+
*/
|
|
166
|
+
function normalizeSlug(slug: string): string {
|
|
167
|
+
return slug.replace(/^\/+|\/+$/g, '');
|
|
168
|
+
}
|
|
160
169
|
|
|
161
170
|
/**
|
|
162
171
|
* Get locale-specific output path for a page with translated slug support
|
|
@@ -168,20 +177,20 @@ export function getLocalizedOutputPath(
|
|
|
168
177
|
locale: string,
|
|
169
178
|
defaultLocale: string,
|
|
170
179
|
distDir: string,
|
|
171
|
-
slugs?: Record<string, string
|
|
180
|
+
slugs?: Record<string, string>,
|
|
172
181
|
): string {
|
|
173
182
|
// Get translated slug for this locale, or fall back to default path
|
|
174
183
|
let slug: string;
|
|
175
184
|
if (slugs && slugs[locale]) {
|
|
176
|
-
slug = slugs[locale];
|
|
177
|
-
} else if (basePath ===
|
|
178
|
-
slug =
|
|
185
|
+
slug = normalizeSlug(slugs[locale]);
|
|
186
|
+
} else if (basePath === '/') {
|
|
187
|
+
slug = '';
|
|
179
188
|
} else {
|
|
180
189
|
slug = basePath.substring(1);
|
|
181
190
|
}
|
|
182
191
|
|
|
183
192
|
// Build filename from slug
|
|
184
|
-
const fileName = slug ===
|
|
193
|
+
const fileName = slug === '' ? 'index.html' : `${slug}.html`;
|
|
185
194
|
|
|
186
195
|
if (locale === defaultLocale) {
|
|
187
196
|
return `${distDir}/${fileName}`;
|
|
@@ -196,22 +205,22 @@ export function getDisplayPath(
|
|
|
196
205
|
basePath: string,
|
|
197
206
|
locale: string,
|
|
198
207
|
defaultLocale: string,
|
|
199
|
-
slugs?: Record<string, string
|
|
208
|
+
slugs?: Record<string, string>,
|
|
200
209
|
): string {
|
|
201
210
|
// Get translated slug for this locale
|
|
202
211
|
let slug: string;
|
|
203
212
|
if (slugs && slugs[locale]) {
|
|
204
|
-
slug = slugs[locale];
|
|
205
|
-
} else if (basePath ===
|
|
206
|
-
slug =
|
|
213
|
+
slug = normalizeSlug(slugs[locale]);
|
|
214
|
+
} else if (basePath === '/') {
|
|
215
|
+
slug = '';
|
|
207
216
|
} else {
|
|
208
217
|
slug = basePath.substring(1);
|
|
209
218
|
}
|
|
210
219
|
|
|
211
220
|
if (locale === defaultLocale) {
|
|
212
|
-
return slug ===
|
|
221
|
+
return slug === '' ? '/' : `/${slug}`;
|
|
213
222
|
}
|
|
214
|
-
return slug ===
|
|
223
|
+
return slug === '' ? `/${locale}` : `/${locale}/${slug}`;
|
|
215
224
|
}
|
|
216
225
|
|
|
217
226
|
/**
|
|
@@ -233,9 +242,7 @@ export async function generateSitemap(urls: string[], siteUrl: string, distDir:
|
|
|
233
242
|
// Sort URLs for deterministic output
|
|
234
243
|
const sortedUrls = [...urls].sort();
|
|
235
244
|
|
|
236
|
-
const urlEntries = sortedUrls
|
|
237
|
-
.map(url => ` <url><loc>${siteUrl}${url}</loc></url>`)
|
|
238
|
-
.join('\n');
|
|
245
|
+
const urlEntries = sortedUrls.map((url) => ` <url><loc>${siteUrl}${url}</loc></url>`).join('\n');
|
|
239
246
|
|
|
240
247
|
const content = `<?xml version="1.0" encoding="UTF-8"?>
|
|
241
248
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
@@ -259,13 +266,7 @@ function cleanDist(distDir: string = projectPaths.dist()): void {
|
|
|
259
266
|
|
|
260
267
|
for (const file of files) {
|
|
261
268
|
// Keep fonts, images, icons, assets, and videos
|
|
262
|
-
if (
|
|
263
|
-
file === "fonts" ||
|
|
264
|
-
file === "images" ||
|
|
265
|
-
file === "icons" ||
|
|
266
|
-
file === "assets" ||
|
|
267
|
-
file === "videos"
|
|
268
|
-
) {
|
|
269
|
+
if (file === 'fonts' || file === 'images' || file === 'icons' || file === 'assets' || file === 'videos') {
|
|
269
270
|
continue;
|
|
270
271
|
}
|
|
271
272
|
|
|
@@ -306,7 +307,7 @@ export function buildCMSItemPath(
|
|
|
306
307
|
item: CMSItem,
|
|
307
308
|
slugField: string,
|
|
308
309
|
locale: string,
|
|
309
|
-
i18nConfig: I18nConfig
|
|
310
|
+
i18nConfig: I18nConfig,
|
|
310
311
|
): string {
|
|
311
312
|
// Get slug from the schema-defined slugField, fall back to _slug or _id
|
|
312
313
|
let slug = item[slugField] ?? item._slug ?? item._id;
|
|
@@ -325,7 +326,7 @@ export function buildCMSItemPath(
|
|
|
325
326
|
*/
|
|
326
327
|
async function generateStaticDataFiles(
|
|
327
328
|
staticCollections: Map<string, ClientDataCollection>,
|
|
328
|
-
distDir: string
|
|
329
|
+
distDir: string,
|
|
329
330
|
): Promise<void> {
|
|
330
331
|
if (staticCollections.size === 0) return;
|
|
331
332
|
|
|
@@ -355,7 +356,7 @@ async function buildCMSTemplates(
|
|
|
355
356
|
generatedUrls: Set<string>,
|
|
356
357
|
staticCollections: Map<string, ClientDataCollection>,
|
|
357
358
|
siteUrl?: string,
|
|
358
|
-
abTrackingScript?: string | null
|
|
359
|
+
abTrackingScript?: string | null,
|
|
359
360
|
): Promise<{ success: number; errors: number }> {
|
|
360
361
|
let successCount = 0;
|
|
361
362
|
let errorCount = 0;
|
|
@@ -364,7 +365,7 @@ async function buildCMSTemplates(
|
|
|
364
365
|
return { success: 0, errors: 0 };
|
|
365
366
|
}
|
|
366
367
|
|
|
367
|
-
const templateFiles = readdirSync(templatesDir).filter(f => f.endsWith('.json'));
|
|
368
|
+
const templateFiles = readdirSync(templatesDir).filter((f) => f.endsWith('.json'));
|
|
368
369
|
|
|
369
370
|
if (templateFiles.length === 0) {
|
|
370
371
|
return { success: 0, errors: 0 };
|
|
@@ -408,17 +409,21 @@ async function buildCMSTemplates(
|
|
|
408
409
|
// Filter out fully-draft items from client data (client data is locale-agnostic)
|
|
409
410
|
let clientDataCollections: Map<string, ClientDataCollection> | undefined;
|
|
410
411
|
if (cmsSchema.clientData?.enabled) {
|
|
411
|
-
const publishedItems = items.filter(item => isItemFullyPublished(item));
|
|
412
|
+
const publishedItems = items.filter((item) => isItemFullyPublished(item));
|
|
412
413
|
const clientData = prepareClientData(cmsSchema.id, publishedItems, cmsSchema.clientData);
|
|
413
414
|
if (clientData) {
|
|
414
415
|
if (clientData.strategy === 'inline') {
|
|
415
416
|
// Inline data embedded in HTML
|
|
416
417
|
clientDataCollections = new Map([[cmsSchema.id, clientData]]);
|
|
417
|
-
console.log(
|
|
418
|
+
console.log(
|
|
419
|
+
` 📦 Client data (inline): ${clientData.items.length} items (${clientData.config.fields?.length || 'all'} fields)`,
|
|
420
|
+
);
|
|
418
421
|
} else if (clientData.strategy === 'static') {
|
|
419
422
|
// Static data written to separate file
|
|
420
423
|
staticCollections.set(cmsSchema.id, clientData);
|
|
421
|
-
console.log(
|
|
424
|
+
console.log(
|
|
425
|
+
` 📦 Client data (static): ${clientData.items.length} items → /data/${cmsSchema.id}/index.json`,
|
|
426
|
+
);
|
|
422
427
|
}
|
|
423
428
|
}
|
|
424
429
|
}
|
|
@@ -434,14 +439,14 @@ async function buildCMSTemplates(
|
|
|
434
439
|
continue;
|
|
435
440
|
}
|
|
436
441
|
|
|
437
|
-
const baseUrl = siteUrl ||
|
|
442
|
+
const baseUrl = siteUrl || '';
|
|
438
443
|
const itemPath = buildCMSItemPath(cmsSchema.urlPattern, item, cmsSchema.slugField, locale, i18nConfig);
|
|
439
444
|
|
|
440
445
|
// Create CMS item with computed _url for {{cms._url}} template access
|
|
441
446
|
const itemWithUrl: CMSItem = { ...item, _url: itemPath };
|
|
442
447
|
|
|
443
448
|
// Generate HTML with JS returned separately (CSP-compliant)
|
|
444
|
-
const result = await generateSSRHTML({
|
|
449
|
+
const result = (await generateSSRHTML({
|
|
445
450
|
pageData,
|
|
446
451
|
globalComponents,
|
|
447
452
|
pagePath: itemPath,
|
|
@@ -456,7 +461,7 @@ async function buildCMSTemplates(
|
|
|
456
461
|
pageCustomCode: pageData.meta?.customCode,
|
|
457
462
|
clientDataCollections,
|
|
458
463
|
isProductionBuild: true,
|
|
459
|
-
}) as SSRHTMLResult;
|
|
464
|
+
})) as SSRHTMLResult;
|
|
460
465
|
|
|
461
466
|
// If there's JavaScript, write to external file and update HTML
|
|
462
467
|
let finalHtml = result.html;
|
|
@@ -470,9 +475,8 @@ async function buildCMSTemplates(
|
|
|
470
475
|
finalHtml = injectTrackingScript(finalHtml, abTrackingScript);
|
|
471
476
|
}
|
|
472
477
|
|
|
473
|
-
const outputPath =
|
|
474
|
-
? `${distDir}${itemPath}.html`
|
|
475
|
-
: `${distDir}/${locale}${itemPath}.html`;
|
|
478
|
+
const outputPath =
|
|
479
|
+
locale === i18nConfig.defaultLocale ? `${distDir}${itemPath}.html` : `${distDir}/${locale}${itemPath}.html`;
|
|
476
480
|
|
|
477
481
|
const outputDir = outputPath.substring(0, outputPath.lastIndexOf('/'));
|
|
478
482
|
if (outputDir && !existsSync(outputDir)) {
|
|
@@ -498,16 +502,14 @@ async function buildCMSTemplates(
|
|
|
498
502
|
}
|
|
499
503
|
// Check for cause chain
|
|
500
504
|
else if (error.cause) {
|
|
501
|
-
const causeMsg =
|
|
502
|
-
?
|
|
503
|
-
: String(error.cause);
|
|
505
|
+
const causeMsg =
|
|
506
|
+
error.cause instanceof Error ? error.cause.stack || error.cause.message : String(error.cause);
|
|
504
507
|
errorMessage = `${error.stack || error.message}\n\nCaused by:\n${causeMsg}`;
|
|
505
508
|
}
|
|
506
509
|
// Bun's BuildMessage has logs array
|
|
507
510
|
else if ('logs' in error && Array.isArray(error.logs)) {
|
|
508
511
|
errorMessage = error.logs.map(formatBunLog).join('\n\n');
|
|
509
|
-
}
|
|
510
|
-
else {
|
|
512
|
+
} else {
|
|
511
513
|
errorMessage = error.stack || error.message;
|
|
512
514
|
}
|
|
513
515
|
} else if (typeof error === 'object' && error !== null) {
|
|
@@ -555,7 +557,7 @@ async function loadRunningExperiments(): Promise<Experiment[]> {
|
|
|
555
557
|
const content = await readFile(experimentsPath, 'utf-8');
|
|
556
558
|
const data = JSON.parse(content);
|
|
557
559
|
const experiments: Experiment[] = data.experiments || [];
|
|
558
|
-
return experiments.filter(e => e.status === 'running');
|
|
560
|
+
return experiments.filter((e) => e.status === 'running');
|
|
559
561
|
} catch {
|
|
560
562
|
return [];
|
|
561
563
|
}
|
|
@@ -601,14 +603,14 @@ async function generateABFunctions(experiments: Experiment[], distDir: string):
|
|
|
601
603
|
* Main build function
|
|
602
604
|
*/
|
|
603
605
|
export async function buildStaticPages(outDir?: string): Promise<void> {
|
|
604
|
-
console.log(
|
|
606
|
+
console.log('🏗️ Building static HTML files...\n');
|
|
605
607
|
|
|
606
608
|
// Clear previous build errors and JS validation cache
|
|
607
609
|
buildErrors.length = 0;
|
|
608
610
|
clearJSValidationCache();
|
|
609
611
|
|
|
610
612
|
// Reset configService to ensure it loads from the correct project directory
|
|
611
|
-
const { configService } = await import(
|
|
613
|
+
const { configService } = await import('./lib/server/services/configService');
|
|
612
614
|
configService.reset();
|
|
613
615
|
|
|
614
616
|
// Load project config first
|
|
@@ -629,7 +631,9 @@ export async function buildStaticPages(outDir?: string): Promise<void> {
|
|
|
629
631
|
|
|
630
632
|
// Load i18n config for multi-locale build
|
|
631
633
|
const i18nConfig = await loadI18nConfig();
|
|
632
|
-
console.log(
|
|
634
|
+
console.log(
|
|
635
|
+
`🌐 Locales: ${i18nConfig.locales.map((l) => l.code).join(', ')} (default: ${i18nConfig.defaultLocale})\n`,
|
|
636
|
+
);
|
|
633
637
|
|
|
634
638
|
// Auto-migrate pages/templates/ → templates/ if needed
|
|
635
639
|
await migrateTemplatesDirectory();
|
|
@@ -646,42 +650,42 @@ export async function buildStaticPages(outDir?: string): Promise<void> {
|
|
|
646
650
|
jsFileCache.clear();
|
|
647
651
|
|
|
648
652
|
// Copy fonts, images, icons, and functions directories to dist
|
|
649
|
-
console.log(
|
|
653
|
+
console.log('📦 Copying assets...');
|
|
650
654
|
|
|
651
655
|
// Delete old _errors.json if it exists (start fresh)
|
|
652
656
|
const errorsPath = join(distDir, '_errors.json');
|
|
653
657
|
if (existsSync(errorsPath)) {
|
|
654
658
|
unlinkSync(errorsPath);
|
|
655
659
|
}
|
|
656
|
-
copyDirectory(projectPaths.fonts(), join(distDir,
|
|
657
|
-
copyDirectory(projectPaths.images(), join(distDir,
|
|
658
|
-
copyDirectory(projectPaths.icons(), join(distDir,
|
|
659
|
-
copyDirectory(projectPaths.assets(), join(distDir,
|
|
660
|
-
copyDirectory(projectPaths.videos(), join(distDir,
|
|
660
|
+
copyDirectory(projectPaths.fonts(), join(distDir, 'fonts'));
|
|
661
|
+
copyDirectory(projectPaths.images(), join(distDir, 'images'));
|
|
662
|
+
copyDirectory(projectPaths.icons(), join(distDir, 'icons'));
|
|
663
|
+
copyDirectory(projectPaths.assets(), join(distDir, 'assets'));
|
|
664
|
+
copyDirectory(projectPaths.videos(), join(distDir, 'videos'));
|
|
661
665
|
|
|
662
666
|
// Copy libraries folder (downloaded external JS/CSS files)
|
|
663
|
-
const librariesDir = join(projectPaths.project,
|
|
667
|
+
const librariesDir = join(projectPaths.project, 'libraries');
|
|
664
668
|
if (existsSync(librariesDir)) {
|
|
665
|
-
copyDirectory(librariesDir, join(distDir,
|
|
669
|
+
copyDirectory(librariesDir, join(distDir, 'libraries'));
|
|
666
670
|
}
|
|
667
671
|
|
|
668
672
|
// Copy functions folder for Cloudflare Pages
|
|
669
673
|
const functionsDir = projectPaths.functions();
|
|
670
674
|
if (existsSync(functionsDir)) {
|
|
671
|
-
copyDirectory(functionsDir, join(distDir,
|
|
675
|
+
copyDirectory(functionsDir, join(distDir, 'functions'));
|
|
672
676
|
}
|
|
673
677
|
|
|
674
678
|
// Copy user-created root files for static hosting
|
|
675
679
|
const hostingFiles: string[] = [];
|
|
676
680
|
const rootFilesToCopy = [
|
|
677
|
-
'_headers',
|
|
678
|
-
'_redirects',
|
|
679
|
-
'llms.txt',
|
|
680
|
-
'humans.txt',
|
|
681
|
-
'ads.txt',
|
|
682
|
-
'security.txt',
|
|
683
|
-
'CNAME',
|
|
684
|
-
'manifest.json',
|
|
681
|
+
'_headers', // Netlify/Cloudflare headers
|
|
682
|
+
'_redirects', // Netlify/Cloudflare redirects
|
|
683
|
+
'llms.txt', // LLM context
|
|
684
|
+
'humans.txt', // Team credits
|
|
685
|
+
'ads.txt', // Ad verification
|
|
686
|
+
'security.txt', // Security contact
|
|
687
|
+
'CNAME', // GitHub Pages domain
|
|
688
|
+
'manifest.json', // PWA manifest
|
|
685
689
|
'site.webmanifest', // PWA manifest (alt)
|
|
686
690
|
];
|
|
687
691
|
|
|
@@ -725,7 +729,7 @@ export async function buildStaticPages(outDir?: string): Promise<void> {
|
|
|
725
729
|
// Load all pages
|
|
726
730
|
const pagesDir = projectPaths.pages();
|
|
727
731
|
if (!existsSync(pagesDir)) {
|
|
728
|
-
console.error(
|
|
732
|
+
console.error('❌ Pages directory not found!');
|
|
729
733
|
process.exit(1);
|
|
730
734
|
}
|
|
731
735
|
|
|
@@ -742,9 +746,9 @@ export async function buildStaticPages(outDir?: string): Promise<void> {
|
|
|
742
746
|
}
|
|
743
747
|
}
|
|
744
748
|
scanPagesDir(pagesDir, '');
|
|
745
|
-
|
|
749
|
+
|
|
746
750
|
if (pageFiles.length === 0) {
|
|
747
|
-
console.warn(
|
|
751
|
+
console.warn('⚠️ No pages found in ./pages directory');
|
|
748
752
|
return;
|
|
749
753
|
}
|
|
750
754
|
|
|
@@ -754,7 +758,7 @@ export async function buildStaticPages(outDir?: string): Promise<void> {
|
|
|
754
758
|
const slugMappings: SlugMap[] = [];
|
|
755
759
|
const allPageLibraries: LibrariesConfig[] = [];
|
|
756
760
|
for (const file of pageFiles) {
|
|
757
|
-
const pageName = file.replace(
|
|
761
|
+
const pageName = file.replace('.json', '');
|
|
758
762
|
const basePath = mapPageNameToPath(pageName);
|
|
759
763
|
const pageContent = await loadJSONFile(join(pagesDir, file));
|
|
760
764
|
if (pageContent) {
|
|
@@ -767,7 +771,9 @@ export async function buildStaticPages(outDir?: string): Promise<void> {
|
|
|
767
771
|
if (pageData.meta?.libraries) {
|
|
768
772
|
allPageLibraries.push(pageData.meta.libraries as LibrariesConfig);
|
|
769
773
|
}
|
|
770
|
-
} catch {
|
|
774
|
+
} catch {
|
|
775
|
+
/* ignore parse errors in first pass */
|
|
776
|
+
}
|
|
771
777
|
}
|
|
772
778
|
}
|
|
773
779
|
|
|
@@ -786,12 +792,12 @@ export async function buildStaticPages(outDir?: string): Promise<void> {
|
|
|
786
792
|
const allJs = [
|
|
787
793
|
...(globalLibraries.js || []),
|
|
788
794
|
...(componentLibraries.js || []),
|
|
789
|
-
...allPageLibraries.flatMap(p => p.js || []),
|
|
795
|
+
...allPageLibraries.flatMap((p) => p.js || []),
|
|
790
796
|
];
|
|
791
797
|
const allCss = [
|
|
792
798
|
...(globalLibraries.css || []),
|
|
793
799
|
...(componentLibraries.css || []),
|
|
794
|
-
...allPageLibraries.flatMap(p => p.css || []),
|
|
800
|
+
...allPageLibraries.flatMap((p) => p.css || []),
|
|
795
801
|
];
|
|
796
802
|
const allLibs: LibrariesConfig = { js: allJs, css: allCss };
|
|
797
803
|
|
|
@@ -801,14 +807,8 @@ export async function buildStaticPages(outDir?: string): Promise<void> {
|
|
|
801
807
|
// Extract CDN origins from all library URLs
|
|
802
808
|
const { scriptOrigins, styleOrigins } = extractLibraryOrigins(buildLibs);
|
|
803
809
|
|
|
804
|
-
const extraScripts = [
|
|
805
|
-
|
|
806
|
-
...Array.from(scriptOrigins),
|
|
807
|
-
].join(' ');
|
|
808
|
-
const extraStyles = [
|
|
809
|
-
...(cspConfig.styleSrc || []),
|
|
810
|
-
...Array.from(styleOrigins),
|
|
811
|
-
].join(' ');
|
|
810
|
+
const extraScripts = [...(cspConfig.scriptSrc || []), ...Array.from(scriptOrigins)].join(' ');
|
|
811
|
+
const extraStyles = [...(cspConfig.styleSrc || []), ...Array.from(styleOrigins)].join(' ');
|
|
812
812
|
const extraConnect = cspConfig.connectSrc?.join(' ') || '';
|
|
813
813
|
const extraFrames = cspConfig.frameSrc?.join(' ') || '';
|
|
814
814
|
const extraFonts = cspConfig.fontSrc?.join(' ') || '';
|
|
@@ -829,12 +829,14 @@ export async function buildStaticPages(outDir?: string): Promise<void> {
|
|
|
829
829
|
`connect-src 'self' https://vimeo.com https://*.vimeocdn.com ${extraConnect}`.trim(),
|
|
830
830
|
`frame-src https://player.vimeo.com https://vimeo.com https://www.youtube.com https://www.youtube-nocookie.com ${extraFrames}`.trim(),
|
|
831
831
|
`font-src 'self' data: ${extraFonts}`.trim(),
|
|
832
|
-
"media-src 'self' https: blob:"
|
|
832
|
+
"media-src 'self' https: blob:",
|
|
833
833
|
].join('; ');
|
|
834
834
|
|
|
835
835
|
const headersContent = `/*\n Content-Security-Policy: ${cspDirectives}\n`;
|
|
836
836
|
writeFileSync(join(distDir, '_headers'), headersContent);
|
|
837
|
-
console.log(
|
|
837
|
+
console.log(
|
|
838
|
+
`✅ Generated _headers with CSP (auto-included ${scriptOrigins.size + styleOrigins.size} library origin(s))\n`,
|
|
839
|
+
);
|
|
838
840
|
}
|
|
839
841
|
}
|
|
840
842
|
|
|
@@ -843,7 +845,7 @@ export async function buildStaticPages(outDir?: string): Promise<void> {
|
|
|
843
845
|
|
|
844
846
|
// Build each page for each locale
|
|
845
847
|
for (const file of pageFiles) {
|
|
846
|
-
const pageName = file.replace(
|
|
848
|
+
const pageName = file.replace('.json', '');
|
|
847
849
|
const basePath = mapPageNameToPath(pageName);
|
|
848
850
|
const pageContent = await loadJSONFile(join(pagesDir, file));
|
|
849
851
|
|
|
@@ -869,13 +871,13 @@ export async function buildStaticPages(outDir?: string): Promise<void> {
|
|
|
869
871
|
// Generate HTML for each locale
|
|
870
872
|
for (const localeConfig of i18nConfig.locales) {
|
|
871
873
|
const locale = localeConfig.code;
|
|
872
|
-
const baseUrl = siteUrl ||
|
|
874
|
+
const baseUrl = siteUrl || '';
|
|
873
875
|
|
|
874
876
|
// Build the URL path that will be used for this locale
|
|
875
877
|
const urlPath = getDisplayPath(basePath, locale, i18nConfig.defaultLocale, slugs);
|
|
876
878
|
|
|
877
879
|
// Generate HTML with JS returned separately (CSP-compliant)
|
|
878
|
-
const result = await generateSSRHTML({
|
|
880
|
+
const result = (await generateSSRHTML({
|
|
879
881
|
pageData,
|
|
880
882
|
globalComponents,
|
|
881
883
|
pagePath: urlPath,
|
|
@@ -888,7 +890,7 @@ export async function buildStaticPages(outDir?: string): Promise<void> {
|
|
|
888
890
|
pageLibraries: pageData.meta?.libraries,
|
|
889
891
|
pageCustomCode: pageData.meta?.customCode,
|
|
890
892
|
isProductionBuild: true,
|
|
891
|
-
}) as SSRHTMLResult;
|
|
893
|
+
})) as SSRHTMLResult;
|
|
892
894
|
|
|
893
895
|
// If there's JavaScript, write to external file and update HTML
|
|
894
896
|
let finalHtml = result.html;
|
|
@@ -907,7 +909,7 @@ export async function buildStaticPages(outDir?: string): Promise<void> {
|
|
|
907
909
|
const outputPath = getLocalizedOutputPath(basePath, locale, i18nConfig.defaultLocale, distDir, slugs);
|
|
908
910
|
|
|
909
911
|
// Ensure directory exists
|
|
910
|
-
const outputDir = outputPath.substring(0, outputPath.lastIndexOf(
|
|
912
|
+
const outputDir = outputPath.substring(0, outputPath.lastIndexOf('/'));
|
|
911
913
|
if (outputDir && !existsSync(outputDir)) {
|
|
912
914
|
mkdirSync(outputDir, { recursive: true });
|
|
913
915
|
}
|
|
@@ -917,13 +919,12 @@ export async function buildStaticPages(outDir?: string): Promise<void> {
|
|
|
917
919
|
console.log('[DEBUG] Last 500 chars of HTML:', finalHtml.slice(-500));
|
|
918
920
|
}
|
|
919
921
|
|
|
920
|
-
await writeFile(outputPath, finalHtml,
|
|
922
|
+
await writeFile(outputPath, finalHtml, 'utf-8');
|
|
921
923
|
|
|
922
924
|
generatedUrls.add(urlPath);
|
|
923
925
|
console.log(`✅ Built: ${urlPath} → ${outputPath}`);
|
|
924
926
|
successCount++;
|
|
925
927
|
}
|
|
926
|
-
|
|
927
928
|
} catch (error: any) {
|
|
928
929
|
// Capture full error with as much detail as possible
|
|
929
930
|
let errorMessage: string;
|
|
@@ -935,16 +936,14 @@ export async function buildStaticPages(outDir?: string): Promise<void> {
|
|
|
935
936
|
}
|
|
936
937
|
// Check for cause chain
|
|
937
938
|
else if (error.cause) {
|
|
938
|
-
const causeMsg =
|
|
939
|
-
?
|
|
940
|
-
: String(error.cause);
|
|
939
|
+
const causeMsg =
|
|
940
|
+
error.cause instanceof Error ? error.cause.stack || error.cause.message : String(error.cause);
|
|
941
941
|
errorMessage = `${error.stack || error.message}\n\nCaused by:\n${causeMsg}`;
|
|
942
942
|
}
|
|
943
943
|
// Bun's BuildMessage has logs array
|
|
944
944
|
else if ('logs' in error && Array.isArray(error.logs)) {
|
|
945
945
|
errorMessage = error.logs.map(formatBunLog).join('\n\n');
|
|
946
|
-
}
|
|
947
|
-
else {
|
|
946
|
+
} else {
|
|
948
947
|
errorMessage = error.stack || error.message;
|
|
949
948
|
}
|
|
950
949
|
} else if (typeof error === 'object' && error !== null) {
|
|
@@ -991,7 +990,7 @@ export async function buildStaticPages(outDir?: string): Promise<void> {
|
|
|
991
990
|
generatedUrls,
|
|
992
991
|
staticCollections,
|
|
993
992
|
siteUrl,
|
|
994
|
-
trackingScript
|
|
993
|
+
trackingScript,
|
|
995
994
|
);
|
|
996
995
|
successCount += cmsResult.success;
|
|
997
996
|
errorCount += cmsResult.errors;
|
|
@@ -1014,7 +1013,7 @@ export async function buildStaticPages(outDir?: string): Promise<void> {
|
|
|
1014
1013
|
console.warn(`\n⚠️ Skipping SEO files: siteUrl not configured in project.config.json`);
|
|
1015
1014
|
}
|
|
1016
1015
|
|
|
1017
|
-
console.log(
|
|
1016
|
+
console.log('\n' + '='.repeat(50));
|
|
1018
1017
|
console.log(`✨ Build complete!`);
|
|
1019
1018
|
console.log(` ✅ Success: ${successCount}`);
|
|
1020
1019
|
if (errorCount > 0) {
|
|
@@ -1053,7 +1052,7 @@ export async function buildStaticPages(outDir?: string): Promise<void> {
|
|
|
1053
1052
|
if (buildErrors.length > 0) {
|
|
1054
1053
|
// Deduplicate errors by message (same error may occur on multiple pages)
|
|
1055
1054
|
const seenMessages = new Set<string>();
|
|
1056
|
-
const uniqueErrors = buildErrors.filter(err => {
|
|
1055
|
+
const uniqueErrors = buildErrors.filter((err) => {
|
|
1057
1056
|
if (seenMessages.has(err.message)) return false;
|
|
1058
1057
|
seenMessages.add(err.message);
|
|
1059
1058
|
return true;
|
|
@@ -1064,11 +1063,10 @@ export async function buildStaticPages(outDir?: string): Promise<void> {
|
|
|
1064
1063
|
timestamp: Date.now(),
|
|
1065
1064
|
};
|
|
1066
1065
|
await writeFile(errorsPath, JSON.stringify(errorsData, null, 2), 'utf-8');
|
|
1067
|
-
const countMsg =
|
|
1068
|
-
|
|
1069
|
-
|
|
1066
|
+
const countMsg =
|
|
1067
|
+
uniqueErrors.length === buildErrors.length
|
|
1068
|
+
? `${uniqueErrors.length} error${uniqueErrors.length === 1 ? '' : 's'}`
|
|
1069
|
+
: `${uniqueErrors.length} unique error${uniqueErrors.length === 1 ? '' : 's'} (affected ${buildErrors.length} files)`;
|
|
1070
1070
|
console.log(`\n⚠️ Build errors written to dist/_errors.json (${countMsg})`);
|
|
1071
1071
|
}
|
|
1072
1072
|
}
|
|
1073
|
-
|
|
1074
|
-
|