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
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../lib/shared/richtext/types.ts", "../../lib/shared/richtext/htmlToTiptap.ts", "../../lib/shared/richtext/tiptapToHtml.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Tiptap Rich Text Type Definitions\n * Defines the JSON structure used by Tiptap for rich text content\n */\n\n/**\n * Mark applied to text (bold, italic, link, etc.)\n */\nexport interface TiptapMark {\n type: string;\n attrs?: Record<string, unknown>;\n}\n\n/**\n * A node in the Tiptap document tree\n */\nexport interface TiptapNode {\n type: string;\n attrs?: Record<string, unknown>;\n content?: TiptapNode[];\n marks?: TiptapMark[];\n text?: string;\n}\n\n/**\n * Root document structure for Tiptap content\n */\nexport interface TiptapDocument {\n type: 'doc';\n content: TiptapNode[];\n}\n\n/**\n * Type guard to check if a value is a Tiptap document\n */\nexport function isTiptapDocument(value: unknown): value is TiptapDocument {\n if (!value || typeof value !== 'object') return false;\n const doc = value as Record<string, unknown>;\n return doc.type === 'doc' && Array.isArray(doc.content);\n}\n\n/**\n * Detect the format of rich text content\n */\nexport function detectRichTextFormat(value: unknown): 'html' | 'tiptap' | 'empty' {\n if (!value) return 'empty';\n if (typeof value === 'string') return value.length > 0 ? 'html' : 'empty';\n if (isTiptapDocument(value)) return 'tiptap';\n return 'empty';\n}\n\n/**\n * Known Tiptap node types\n */\nexport type TiptapNodeType =\n | 'doc'\n | 'paragraph'\n | 'text'\n | 'heading'\n | 'bulletList'\n | 'orderedList'\n | 'listItem'\n | 'blockquote'\n | 'codeBlock'\n | 'hardBreak'\n | 'horizontalRule'\n | 'image'\n | 'table'\n | 'tableRow'\n | 'tableCell'\n | 'tableHeader'\n | 'iframe'\n | 'rawHtml'\n | 'menoComponent';\n\n/**\n * Known Tiptap mark types\n */\nexport type TiptapMarkType =\n | 'bold'\n | 'italic'\n | 'underline'\n | 'strike'\n | 'code'\n | 'link'\n | 'textStyle';\n", "/**\n * HTML to Tiptap JSON Converter\n * Converts legacy HTML rich text content to Tiptap document format\n */\n\nimport type { TiptapDocument, TiptapNode, TiptapMark } from './types';\n\n/**\n * Parse HTML string and convert to Tiptap document\n */\nexport function htmlToTiptap(html: string): TiptapDocument {\n if (!html || typeof html !== 'string') {\n return { type: 'doc', content: [] };\n }\n\n // Use DOMParser if available (browser), otherwise use a simple regex-based approach\n if (typeof DOMParser !== 'undefined') {\n return parseWithDOM(html);\n }\n\n // Fallback for server-side: wrap in paragraph\n return {\n type: 'doc',\n content: [{ type: 'paragraph', content: [{ type: 'text', text: stripHtml(html) }] }],\n };\n}\n\n/**\n * Strip HTML tags for fallback text extraction\n */\nfunction stripHtml(html: string): string {\n return html.replace(/<[^>]*>/g, '').trim();\n}\n\n/**\n * Parse HTML using DOMParser (browser environment)\n */\nfunction parseWithDOM(html: string): TiptapDocument {\n const parser = new DOMParser();\n const doc = parser.parseFromString(`<div>${html}</div>`, 'text/html');\n const container = doc.body.firstChild as HTMLElement;\n\n if (!container) {\n return { type: 'doc', content: [] };\n }\n\n const content = parseChildren(container);\n\n // If content is empty or only has inline content, wrap in paragraph\n if (content.length === 0) {\n return { type: 'doc', content: [] };\n }\n\n // Ensure top-level nodes are block-level\n const blockContent = wrapInlineContent(content);\n\n return { type: 'doc', content: blockContent };\n}\n\n/**\n * Wrap consecutive inline nodes in paragraphs\n */\nfunction wrapInlineContent(nodes: TiptapNode[]): TiptapNode[] {\n const result: TiptapNode[] = [];\n let inlineBuffer: TiptapNode[] = [];\n\n const flushInline = () => {\n if (inlineBuffer.length > 0) {\n result.push({ type: 'paragraph', content: inlineBuffer });\n inlineBuffer = [];\n }\n };\n\n for (const node of nodes) {\n if (isBlockNode(node.type)) {\n flushInline();\n result.push(node);\n } else {\n inlineBuffer.push(node);\n }\n }\n\n flushInline();\n return result;\n}\n\n/**\n * Check if a node type is block-level\n */\nfunction isBlockNode(type: string): boolean {\n return [\n 'paragraph',\n 'heading',\n 'bulletList',\n 'orderedList',\n 'listItem',\n 'blockquote',\n 'codeBlock',\n 'horizontalRule',\n 'image',\n 'table',\n 'tableRow',\n 'tableCell',\n 'tableHeader',\n 'iframe',\n 'rawHtml',\n 'menoComponent',\n ].includes(type);\n}\n\n/**\n * Parse child nodes of an element\n */\nfunction parseChildren(element: HTMLElement): TiptapNode[] {\n const nodes: TiptapNode[] = [];\n\n for (const child of Array.from(element.childNodes)) {\n const parsed = parseNode(child);\n if (parsed) {\n if (Array.isArray(parsed)) {\n nodes.push(...parsed);\n } else {\n nodes.push(parsed);\n }\n }\n }\n\n return nodes;\n}\n\n/**\n * Parse a single DOM node\n */\nfunction parseNode(node: Node): TiptapNode | TiptapNode[] | null {\n if (node.nodeType === Node.TEXT_NODE) {\n const text = node.textContent;\n if (!text) return null;\n return { type: 'text', text };\n }\n\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return null;\n }\n\n const element = node as HTMLElement;\n const tagName = element.tagName.toLowerCase();\n\n switch (tagName) {\n // Block elements\n case 'p':\n return parseParagraph(element);\n case 'h1':\n case 'h2':\n case 'h3':\n case 'h4':\n case 'h5':\n case 'h6':\n return parseHeading(element);\n case 'ul':\n return parseBulletList(element);\n case 'ol':\n return parseOrderedList(element);\n case 'li':\n return parseListItem(element);\n case 'blockquote':\n return parseBlockquote(element);\n case 'pre':\n return parseCodeBlock(element);\n case 'hr':\n return { type: 'horizontalRule' };\n case 'br':\n return { type: 'hardBreak' };\n case 'img':\n return parseImage(element);\n case 'iframe':\n return parseIframe(element);\n case 'table':\n return parseTable(element);\n\n // Inline elements - return text with marks\n case 'b':\n case 'strong':\n return parseInlineWithMark(element, 'bold');\n case 'i':\n case 'em':\n return parseInlineWithMark(element, 'italic');\n case 'u':\n return parseInlineWithMark(element, 'underline');\n case 's':\n case 'strike':\n case 'del':\n return parseInlineWithMark(element, 'strike');\n case 'code':\n return parseInlineWithMark(element, 'code');\n case 'a':\n return parseLink(element);\n case 'span':\n return parseSpan(element);\n\n // Container elements - check for special data attributes first\n case 'div': {\n // Raw HTML block\n if (element.hasAttribute('data-raw-html')) {\n return { type: 'rawHtml', attrs: { content: element.innerHTML } };\n }\n // Meno component embed\n if (element.hasAttribute('data-meno-component')) {\n return parseMenoComponent(element);\n }\n // Regular div - parse children\n return parseChildren(element);\n }\n case 'article':\n case 'section':\n case 'main':\n case 'header':\n case 'footer':\n case 'thead':\n case 'tbody':\n case 'tfoot':\n return parseChildren(element);\n\n case 'tr':\n return parseTableRow(element);\n case 'td':\n return parseTableCell(element, 'tableCell');\n case 'th':\n return parseTableCell(element, 'tableHeader');\n\n default:\n // Unknown elements - try to parse children\n return parseChildren(element);\n }\n}\n\nfunction parseParagraph(element: HTMLElement): TiptapNode {\n const content = parseInlineChildren(element);\n const node: TiptapNode = { type: 'paragraph' };\n if (content.length > 0) {\n node.content = content;\n }\n\n // Handle text alignment\n const align = element.style.textAlign;\n if (align && ['left', 'center', 'right', 'justify'].includes(align)) {\n node.attrs = { textAlign: align };\n }\n\n return node;\n}\n\nfunction parseHeading(element: HTMLElement): TiptapNode {\n const level = parseInt(element.tagName[1], 10);\n const content = parseInlineChildren(element);\n const node: TiptapNode = {\n type: 'heading',\n attrs: { level },\n };\n if (content.length > 0) {\n node.content = content;\n }\n\n // Handle text alignment\n const align = element.style.textAlign;\n if (align && ['left', 'center', 'right', 'justify'].includes(align)) {\n node.attrs = { ...node.attrs, textAlign: align };\n }\n\n return node;\n}\n\nfunction parseBulletList(element: HTMLElement): TiptapNode {\n const items = Array.from(element.children)\n .filter((child) => child.tagName.toLowerCase() === 'li')\n .map((li) => parseListItem(li as HTMLElement));\n return { type: 'bulletList', content: items };\n}\n\nfunction parseOrderedList(element: HTMLElement): TiptapNode {\n const items = Array.from(element.children)\n .filter((child) => child.tagName.toLowerCase() === 'li')\n .map((li) => parseListItem(li as HTMLElement));\n const node: TiptapNode = { type: 'orderedList', content: items };\n\n // Preserve start attribute\n const start = element.getAttribute('start');\n if (start) {\n node.attrs = { start: parseInt(start, 10) };\n }\n\n return node;\n}\n\nfunction parseListItem(element: HTMLElement): TiptapNode {\n // List items can contain block content or inline content\n const children = parseChildren(element);\n\n // If children are all inline, wrap in paragraph\n const hasBlockContent = children.some((child) => isBlockNode(child.type));\n\n if (hasBlockContent) {\n return { type: 'listItem', content: wrapInlineContent(children) };\n }\n\n // Wrap inline content in paragraph\n if (children.length > 0) {\n return { type: 'listItem', content: [{ type: 'paragraph', content: children }] };\n }\n\n return { type: 'listItem', content: [{ type: 'paragraph' }] };\n}\n\nfunction parseBlockquote(element: HTMLElement): TiptapNode {\n const children = parseChildren(element);\n const content = wrapInlineContent(children);\n return { type: 'blockquote', content: content.length > 0 ? content : [{ type: 'paragraph' }] };\n}\n\nfunction parseCodeBlock(element: HTMLElement): TiptapNode {\n // Get language from class (e.g., \"language-javascript\")\n const codeElement = element.querySelector('code');\n const targetElement = codeElement || element;\n\n let language: string | null = null;\n const classList = targetElement.className.split(' ');\n for (const cls of classList) {\n if (cls.startsWith('language-')) {\n language = cls.replace('language-', '');\n break;\n }\n }\n\n const text = targetElement.textContent || '';\n const node: TiptapNode = {\n type: 'codeBlock',\n content: text ? [{ type: 'text', text }] : [],\n };\n\n if (language) {\n node.attrs = { language };\n }\n\n return node;\n}\n\nfunction parseImage(element: HTMLElement): TiptapNode {\n const src = element.getAttribute('src') || '';\n const alt = element.getAttribute('alt') || undefined;\n const title = element.getAttribute('title') || undefined;\n const width = element.getAttribute('width');\n const height = element.getAttribute('height');\n\n const attrs: Record<string, unknown> = { src };\n if (alt) attrs.alt = alt;\n if (title) attrs.title = title;\n if (width) attrs.width = parseInt(width, 10);\n if (height) attrs.height = parseInt(height, 10);\n\n return { type: 'image', attrs };\n}\n\nfunction parseIframe(element: HTMLElement): TiptapNode {\n const src = element.getAttribute('src') || '';\n const width = element.getAttribute('width') || '100%';\n const height = element.getAttribute('height') || '315';\n\n return {\n type: 'iframe',\n attrs: { src, width, height },\n };\n}\n\nfunction parseMenoComponent(element: HTMLElement): TiptapNode {\n const component = element.getAttribute('data-meno-component') || '';\n let props: Record<string, unknown> = {};\n const propsStr = element.getAttribute('data-meno-props');\n if (propsStr) {\n try {\n props = JSON.parse(propsStr);\n } catch {\n // ignore parse errors\n }\n }\n return {\n type: 'menoComponent',\n attrs: { component, props },\n };\n}\n\nfunction parseTable(element: HTMLElement): TiptapNode {\n const rows: TiptapNode[] = [];\n\n // Parse thead, tbody, tfoot\n for (const section of ['thead', 'tbody', 'tfoot']) {\n const sectionEl = element.querySelector(section);\n if (sectionEl) {\n const sectionRows = Array.from(sectionEl.querySelectorAll('tr'));\n for (const tr of sectionRows) {\n const row = parseTableRow(tr as HTMLElement, section === 'thead');\n if (row) rows.push(row);\n }\n }\n }\n\n // Also check direct tr children\n const directRows = Array.from(element.children).filter(\n (child) => child.tagName.toLowerCase() === 'tr'\n );\n for (const tr of directRows) {\n const row = parseTableRow(tr as HTMLElement);\n if (row) rows.push(row);\n }\n\n return { type: 'table', content: rows };\n}\n\nfunction parseTableRow(element: HTMLElement, isHeader = false): TiptapNode {\n const cells: TiptapNode[] = [];\n\n for (const child of Array.from(element.children)) {\n const tagName = child.tagName.toLowerCase();\n if (tagName === 'td' || tagName === 'th') {\n const cellType = tagName === 'th' || isHeader ? 'tableHeader' : 'tableCell';\n const cell = parseTableCell(child as HTMLElement, cellType);\n cells.push(cell);\n }\n }\n\n return { type: 'tableRow', content: cells };\n}\n\nfunction parseTableCell(element: HTMLElement, type: 'tableCell' | 'tableHeader'): TiptapNode {\n const children = parseChildren(element);\n const content = wrapInlineContent(children);\n\n const attrs: Record<string, unknown> = {};\n const colspan = element.getAttribute('colspan');\n const rowspan = element.getAttribute('rowspan');\n if (colspan) attrs.colspan = parseInt(colspan, 10);\n if (rowspan) attrs.rowspan = parseInt(rowspan, 10);\n\n const node: TiptapNode = {\n type,\n content: content.length > 0 ? content : [{ type: 'paragraph' }],\n };\n\n if (Object.keys(attrs).length > 0) {\n node.attrs = attrs;\n }\n\n return node;\n}\n\n/**\n * Parse inline children, returning text nodes with marks\n */\nfunction parseInlineChildren(element: HTMLElement): TiptapNode[] {\n const nodes: TiptapNode[] = [];\n\n for (const child of Array.from(element.childNodes)) {\n if (child.nodeType === Node.TEXT_NODE) {\n const text = child.textContent;\n if (text) {\n nodes.push({ type: 'text', text });\n }\n } else if (child.nodeType === Node.ELEMENT_NODE) {\n const parsed = parseNode(child);\n if (parsed) {\n if (Array.isArray(parsed)) {\n nodes.push(...parsed);\n } else {\n nodes.push(parsed);\n }\n }\n }\n }\n\n return nodes;\n}\n\n/**\n * Parse inline element with a specific mark\n */\nfunction parseInlineWithMark(element: HTMLElement, markType: string): TiptapNode[] {\n const children = parseInlineChildren(element);\n return addMarkToNodes(children, { type: markType });\n}\n\n/**\n * Parse a link element\n */\nfunction parseLink(element: HTMLElement): TiptapNode[] {\n const href = element.getAttribute('href') || '';\n const target = element.getAttribute('target');\n const rel = element.getAttribute('rel');\n\n const attrs: Record<string, unknown> = { href };\n if (target) attrs.target = target;\n if (rel) attrs.rel = rel;\n\n const children = parseInlineChildren(element);\n return addMarkToNodes(children, { type: 'link', attrs });\n}\n\n/**\n * Parse a span element (may have custom class)\n */\nfunction parseSpan(element: HTMLElement): TiptapNode[] {\n const children = parseInlineChildren(element);\n\n // Check for data-meno-span attribute (custom styling)\n const menoSpan = element.getAttribute('data-meno-span');\n if (menoSpan) {\n return addMarkToNodes(children, { type: 'textStyle', attrs: { class: menoSpan } });\n }\n\n // Check for inline styles\n const style = element.getAttribute('style');\n if (style) {\n // Could add textStyle mark with color, background, etc.\n // For now, just return children\n }\n\n return children;\n}\n\n/**\n * Add a mark to all text nodes in a list\n */\nfunction addMarkToNodes(nodes: TiptapNode[], mark: TiptapMark): TiptapNode[] {\n return nodes.map((node) => {\n if (node.type === 'text') {\n const existingMarks = node.marks || [];\n return { ...node, marks: [...existingMarks, mark] };\n }\n // For non-text nodes, recursively add mark to content\n if (node.content) {\n return { ...node, content: addMarkToNodes(node.content, mark) };\n }\n return node;\n });\n}\n", "/**\n * Tiptap JSON to HTML Converter\n * Converts Tiptap document format to sanitized HTML for rendering\n */\n\nimport type { TiptapDocument, TiptapNode, TiptapMark } from './types';\nimport { isTiptapDocument } from './types';\n\n/**\n * DOMPurify-compatible sanitization config for rich text output\n */\nexport const RICH_TEXT_ALLOWED_TAGS = [\n 'b',\n 'i',\n 'u',\n 'strong',\n 'em',\n 'a',\n 'span',\n 'p',\n 'br',\n 'sub',\n 'sup',\n 'mark',\n 's',\n 'small',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'ul',\n 'ol',\n 'li',\n 'blockquote',\n // Extended features\n 'table',\n 'thead',\n 'tbody',\n 'tr',\n 'th',\n 'td',\n 'img',\n 'pre',\n 'code',\n 'hr',\n 'figure',\n 'figcaption',\n // Embeds\n 'iframe',\n 'div',\n];\n\nexport const RICH_TEXT_ALLOWED_ATTRS = [\n 'class',\n 'href',\n 'target',\n 'rel',\n 'data-meno-span',\n // Table attributes\n 'colspan',\n 'rowspan',\n // Image attributes\n 'src',\n 'alt',\n 'width',\n 'height',\n 'title',\n // Code block attributes\n 'data-language',\n // Alignment (via style)\n 'style',\n // Iframe attributes\n 'frameborder',\n 'allowfullscreen',\n 'allow',\n // Raw HTML / Component attributes\n 'data-raw-html',\n 'data-meno-component',\n 'data-meno-props',\n];\n\n/**\n * Allowed URL protocols for links\n */\nconst ALLOWED_URL_PROTOCOLS = ['http:', 'https:', 'mailto:', 'tel:'];\n\n/**\n * Validate URL protocol for security\n */\nfunction isValidUrl(url: string): boolean {\n if (!url || typeof url !== 'string') return false;\n if (url.startsWith('/') || url.startsWith('#')) return true;\n\n try {\n const parsed = new URL(url, 'https://example.com');\n return ALLOWED_URL_PROTOCOLS.includes(parsed.protocol);\n } catch {\n return !url.includes(':');\n }\n}\n\n/**\n * Escape HTML special characters\n */\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\n/**\n * Escape attribute value\n */\nfunction escapeAttr(value: string): string {\n return value.replace(/\"/g, '"').replace(/'/g, ''');\n}\n\n/**\n * Convert Tiptap document to HTML string\n */\nexport function tiptapToHtml(doc: TiptapDocument | unknown): string {\n if (!isTiptapDocument(doc)) {\n // If it's already HTML string, return as-is\n if (typeof doc === 'string') {\n return doc;\n }\n return '';\n }\n\n return renderNodes(doc.content);\n}\n\n/**\n * Render an array of nodes to HTML\n */\nfunction renderNodes(nodes: TiptapNode[]): string {\n return nodes.map(renderNode).join('');\n}\n\n/**\n * Render a single node to HTML\n */\nfunction renderNode(node: TiptapNode): string {\n switch (node.type) {\n case 'doc':\n return node.content ? renderNodes(node.content) : '';\n\n case 'paragraph':\n return renderParagraph(node);\n\n case 'heading':\n return renderHeading(node);\n\n case 'text':\n return renderText(node);\n\n case 'hardBreak':\n return '<br>';\n\n case 'horizontalRule':\n return '<hr>';\n\n case 'bulletList':\n return `<ul>${node.content ? renderNodes(node.content) : ''}</ul>`;\n\n case 'orderedList':\n return renderOrderedList(node);\n\n case 'listItem':\n return `<li>${node.content ? renderNodes(node.content) : ''}</li>`;\n\n case 'blockquote':\n return `<blockquote>${node.content ? renderNodes(node.content) : ''}</blockquote>`;\n\n case 'codeBlock':\n return renderCodeBlock(node);\n\n case 'image':\n return renderImage(node);\n\n case 'table':\n return `<table>${node.content ? renderNodes(node.content) : ''}</table>`;\n\n case 'tableRow':\n return `<tr>${node.content ? renderNodes(node.content) : ''}</tr>`;\n\n case 'tableCell':\n return renderTableCell(node, 'td');\n\n case 'tableHeader':\n return renderTableCell(node, 'th');\n\n case 'iframe':\n return renderIframe(node);\n\n case 'rawHtml':\n return renderRawHtml(node);\n\n case 'menoComponent':\n return renderMenoComponent(node);\n\n default:\n // Unknown node type - try to render content\n if (node.content) {\n return renderNodes(node.content);\n }\n return '';\n }\n}\n\n/**\n * Render paragraph with optional text alignment\n */\nfunction renderParagraph(node: TiptapNode): string {\n const content = node.content ? renderNodes(node.content) : '';\n const align = node.attrs?.textAlign as string | undefined;\n\n if (align && ['left', 'center', 'right', 'justify'].includes(align)) {\n return `<p style=\"text-align: ${align}\">${content}</p>`;\n }\n\n return `<p>${content}</p>`;\n}\n\n/**\n * Render heading with level and optional text alignment\n */\nfunction renderHeading(node: TiptapNode): string {\n const level = (node.attrs?.level as number) || 1;\n const tag = `h${Math.min(Math.max(level, 1), 6)}`;\n const content = node.content ? renderNodes(node.content) : '';\n const align = node.attrs?.textAlign as string | undefined;\n\n if (align && ['left', 'center', 'right', 'justify'].includes(align)) {\n return `<${tag} style=\"text-align: ${align}\">${content}</${tag}>`;\n }\n\n return `<${tag}>${content}</${tag}>`;\n}\n\n/**\n * Render ordered list with optional start attribute\n */\nfunction renderOrderedList(node: TiptapNode): string {\n const content = node.content ? renderNodes(node.content) : '';\n const start = node.attrs?.start as number | undefined;\n\n if (start && start !== 1) {\n return `<ol start=\"${start}\">${content}</ol>`;\n }\n\n return `<ol>${content}</ol>`;\n}\n\n/**\n * Render code block with optional language\n */\nfunction renderCodeBlock(node: TiptapNode): string {\n const language = node.attrs?.language as string | undefined;\n const content = node.content\n ? node.content.map((n) => (n.type === 'text' ? escapeHtml(n.text || '') : '')).join('')\n : '';\n\n if (language) {\n return `<pre><code class=\"language-${escapeAttr(language)}\" data-language=\"${escapeAttr(language)}\">${content}</code></pre>`;\n }\n\n return `<pre><code>${content}</code></pre>`;\n}\n\n/**\n * Render image with attributes\n */\nfunction renderImage(node: TiptapNode): string {\n const src = node.attrs?.src as string | undefined;\n if (!src) return '';\n\n // Validate image src for security\n if (!isValidUrl(src) && !src.startsWith('data:image/')) {\n return '';\n }\n\n const attrs: string[] = [`src=\"${escapeAttr(src)}\"`];\n\n const alt = node.attrs?.alt as string | undefined;\n if (alt) attrs.push(`alt=\"${escapeAttr(alt)}\"`);\n\n const title = node.attrs?.title as string | undefined;\n if (title) attrs.push(`title=\"${escapeAttr(title)}\"`);\n\n const width = node.attrs?.width as number | undefined;\n if (width) attrs.push(`width=\"${width}\"`);\n\n const height = node.attrs?.height as number | undefined;\n if (height) attrs.push(`height=\"${height}\"`);\n\n return `<img ${attrs.join(' ')}>`;\n}\n\n/**\n * Render table cell (td or th)\n */\nfunction renderTableCell(node: TiptapNode, tag: 'td' | 'th'): string {\n const content = node.content ? renderNodes(node.content) : '';\n const attrs: string[] = [];\n\n const colspan = node.attrs?.colspan as number | undefined;\n if (colspan && colspan > 1) attrs.push(`colspan=\"${colspan}\"`);\n\n const rowspan = node.attrs?.rowspan as number | undefined;\n if (rowspan && rowspan > 1) attrs.push(`rowspan=\"${rowspan}\"`);\n\n const attrStr = attrs.length > 0 ? ` ${attrs.join(' ')}` : '';\n return `<${tag}${attrStr}>${content}</${tag}>`;\n}\n\n/**\n * Render iframe embed\n */\nfunction renderIframe(node: TiptapNode): string {\n const src = node.attrs?.src as string | undefined;\n if (!src) return '';\n\n // Only allow https:// URLs for security\n if (!src.startsWith('https://')) return '';\n\n const width = (node.attrs?.width as string | undefined) || '100%';\n const height = (node.attrs?.height as string | undefined) || '315';\n\n return `<iframe src=\"${escapeAttr(src)}\" width=\"${escapeAttr(String(width))}\" height=\"${escapeAttr(String(height))}\" frameborder=\"0\" allowfullscreen></iframe>`;\n}\n\n/**\n * Render raw HTML block\n */\nfunction renderRawHtml(node: TiptapNode): string {\n const content = node.attrs?.content as string | undefined;\n if (!content) return '';\n\n // Strip script tags and event handlers for safety\n const sanitized = content\n .replace(/<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi, '')\n .replace(/\\son\\w+\\s*=\\s*(['\"])[^'\"]*\\1/gi, '')\n .replace(/\\son\\w+\\s*=\\s*[^\\s>]*/gi, '');\n\n return `<div data-raw-html=\"true\">${sanitized}</div>`;\n}\n\n/**\n * Render Meno component marker for SSR expansion\n */\nfunction renderMenoComponent(node: TiptapNode): string {\n const component = node.attrs?.component as string | undefined;\n if (!component) return '';\n\n const props = node.attrs?.props as Record<string, unknown> | undefined;\n const propsJson = props ? escapeAttr(JSON.stringify(props)) : '{}';\n\n return `<div data-meno-component=\"${escapeAttr(component)}\" data-meno-props=\"${propsJson}\"></div>`;\n}\n\n/**\n * Render text node with marks\n */\nfunction renderText(node: TiptapNode): string {\n const text = escapeHtml(node.text || '');\n\n if (!node.marks || node.marks.length === 0) {\n return text;\n }\n\n // Apply marks from innermost to outermost\n let result = text;\n for (const mark of node.marks) {\n result = applyMark(result, mark);\n }\n\n return result;\n}\n\n/**\n * Apply a mark to text content\n */\nfunction applyMark(content: string, mark: TiptapMark): string {\n switch (mark.type) {\n case 'bold':\n return `<strong>${content}</strong>`;\n\n case 'italic':\n return `<em>${content}</em>`;\n\n case 'underline':\n return `<u>${content}</u>`;\n\n case 'strike':\n return `<s>${content}</s>`;\n\n case 'code':\n return `<code>${content}</code>`;\n\n case 'link': {\n const href = mark.attrs?.href as string | undefined;\n if (!href || !isValidUrl(href)) {\n return content;\n }\n\n const attrs: string[] = [`href=\"${escapeAttr(href)}\"`];\n\n const target = mark.attrs?.target as string | undefined;\n if (target) attrs.push(`target=\"${escapeAttr(target)}\"`);\n\n // Add rel for external links\n if (target === '_blank') {\n attrs.push('rel=\"noopener noreferrer\"');\n } else {\n const rel = mark.attrs?.rel as string | undefined;\n if (rel) attrs.push(`rel=\"${escapeAttr(rel)}\"`);\n }\n\n return `<a ${attrs.join(' ')}>${content}</a>`;\n }\n\n case 'textStyle': {\n const className = mark.attrs?.class as string | undefined;\n if (className) {\n return `<span class=\"${escapeAttr(className)}\" data-meno-span=\"${escapeAttr(className)}\">${content}</span>`;\n }\n return content;\n }\n\n case 'subscript':\n return `<sub>${content}</sub>`;\n\n case 'superscript':\n return `<sup>${content}</sup>`;\n\n case 'highlight':\n return `<mark>${content}</mark>`;\n\n default:\n return content;\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../lib/server/runtime/fs.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Runtime-agnostic file I/O and utilities.\n * Uses Bun APIs when available, falls back to Node.js APIs.\n */\n\nimport { dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\nconst isBun = typeof globalThis.Bun !== 'undefined';\n\n// \u2500\u2500 File reading \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport async function readTextFile(path: string): Promise<string> {\n if (isBun) {\n return Bun.file(path).text();\n }\n const { readFile } = await import('fs/promises');\n return readFile(path, 'utf-8');\n}\n\nexport async function readJsonFile<T = unknown>(path: string): Promise<T> {\n if (isBun) {\n return Bun.file(path).json() as Promise<T>;\n }\n const { readFile } = await import('fs/promises');\n const text = await readFile(path, 'utf-8');\n return JSON.parse(text) as T;\n}\n\n// \u2500\u2500 File existence \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport async function fileExists(path: string): Promise<boolean> {\n if (isBun) {\n return Bun.file(path).exists();\n }\n const { access } = await import('fs/promises');\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\n// \u2500\u2500 File writing \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport async function writeFile(\n path: string,\n content: string | Uint8Array | ArrayBuffer,\n): Promise<void> {\n if (isBun) {\n await Bun.write(path, content);\n return;\n }\n const { writeFile: fsWrite } = await import('fs/promises');\n if (typeof content === 'string') {\n await fsWrite(path, content, 'utf-8');\n } else if (content instanceof ArrayBuffer) {\n await fsWrite(path, new Uint8Array(content));\n } else {\n await fsWrite(path, content);\n }\n}\n\n// \u2500\u2500 Serve file as HTTP Response \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** MIME type lookup by extension */\nconst MIME_MAP: Record<string, string> = {\n '.html': 'text/html',\n '.css': 'text/css',\n '.js': 'application/javascript',\n '.mjs': 'application/javascript',\n '.json': 'application/json',\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.gif': 'image/gif',\n '.webp': 'image/webp',\n '.avif': 'image/avif',\n '.svg': 'image/svg+xml',\n '.ico': 'image/x-icon',\n '.bmp': 'image/bmp',\n '.tiff': 'image/tiff',\n '.tif': 'image/tiff',\n '.woff': 'font/woff',\n '.woff2': 'font/woff2',\n '.ttf': 'font/ttf',\n '.otf': 'font/otf',\n '.eot': 'application/vnd.ms-fontobject',\n '.xml': 'application/xml',\n '.txt': 'text/plain',\n '.mp4': 'video/mp4',\n '.webm': 'video/webm',\n '.mov': 'video/quicktime',\n '.mp3': 'audio/mpeg',\n '.wav': 'audio/wav',\n '.pdf': 'application/pdf',\n '.zip': 'application/zip',\n};\n\nexport function getMimeType(filePath: string): string {\n const ext = filePath.slice(filePath.lastIndexOf('.')).toLowerCase();\n return MIME_MAP[ext] || 'application/octet-stream';\n}\n\nexport async function serveFile(\n path: string,\n headers?: Record<string, string>,\n): Promise<Response> {\n if (isBun) {\n return new Response(Bun.file(path), { headers });\n }\n\n // Node.js path: stream the file via Web ReadableStream\n const { createReadStream } = await import('fs');\n const { Readable } = await import('stream');\n const nodeStream = createReadStream(path);\n const webStream = Readable.toWeb(nodeStream) as unknown as ReadableStream;\n\n const contentType = getMimeType(path);\n return new Response(webStream, {\n headers: {\n 'Content-Type': contentType,\n ...headers,\n },\n });\n}\n\n// \u2500\u2500 Hashing \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function hashContent(content: string): string {\n if (isBun) {\n return Bun.hash(content).toString(16).slice(0, 8);\n }\n const { createHash } = require('crypto') as typeof import('crypto');\n return createHash('sha256').update(content).digest('hex').slice(0, 8);\n}\n\n// \u2500\u2500 Inspect (debug formatting) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function inspect(value: unknown): string {\n if (isBun) {\n return Bun.inspect(value);\n }\n const { inspect: nodeInspect } = require('util') as typeof import('util');\n return nodeInspect(value, { depth: 4 });\n}\n\n// \u2500\u2500 Directory helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport async function ensureDir(path: string): Promise<void> {\n const { mkdir } = await import('fs/promises');\n await mkdir(path, { recursive: true });\n}\n\n/**\n * Get the directory of the calling module.\n * Replaces Bun-only `import.meta.dir`.\n * Pass `import.meta.url` from the call site.\n */\nexport function getModuleDir(importMetaUrl: string): string {\n return dirname(fileURLToPath(importMetaUrl));\n}\n\n// \u2500\u2500 Process spawning \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface SpawnResult {\n exitCode: number;\n stdout?: string;\n stderr?: string;\n}\n\nexport async function spawnProcess(\n cmd: string,\n args: string[],\n opts?: {\n cwd?: string;\n stdout?: 'inherit' | 'pipe';\n stderr?: 'inherit' | 'pipe';\n },\n): Promise<SpawnResult> {\n if (isBun) {\n const proc = Bun.spawn([cmd, ...args], {\n cwd: opts?.cwd,\n stdout: opts?.stdout === 'pipe' ? 'pipe' : 'inherit',\n stderr: opts?.stderr === 'pipe' ? 'pipe' : 'inherit',\n });\n const exitCode = await proc.exited;\n return { exitCode };\n }\n\n const { spawn } = await import('child_process');\n return new Promise((resolve, reject) => {\n const child = spawn(cmd, args, {\n cwd: opts?.cwd,\n stdio: [\n 'ignore',\n opts?.stdout === 'pipe' ? 'pipe' : 'inherit',\n opts?.stderr === 'pipe' ? 'pipe' : 'inherit',\n ],\n });\n\n let stdout = '';\n let stderr = '';\n\n child.stdout?.on('data', (data: Buffer) => {\n stdout += data.toString();\n });\n child.stderr?.on('data', (data: Buffer) => {\n stderr += data.toString();\n });\n\n child.on('error', reject);\n child.on('close', (code) => {\n resolve({\n exitCode: code ?? 1,\n stdout: opts?.stdout === 'pipe' ? stdout : undefined,\n stderr: opts?.stderr === 'pipe' ? stderr : undefined,\n });\n });\n });\n}\n\n// \u2500\u2500 File size (for image processing service) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport async function getFileSize(path: string): Promise<number> {\n if (isBun) {\n return Bun.file(path).size;\n }\n const { stat } = await import('fs/promises');\n const stats = await stat(path);\n return stats.size;\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../lib/shared/types/components.ts", "../../lib/shared/types/errors.ts", "../../lib/shared/types/colors.ts", "../../lib/shared/types/variables.ts", "../../lib/shared/types/comment.ts", "../../lib/shared/fontCss.ts", "../../lib/shared/slugTranslator.ts", "../../lib/shared/libraryLoader.ts", "../../lib/shared/pathSecurity.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Component Definition Types\n * Improved type safety with stricter types\n */\n\nimport type { ComponentNode } from './nodes';\nimport type { LibrariesConfig } from './libraries';\n\n/**\n * Prop type definitions\n */\nexport type PropType = 'string' | 'select' | 'boolean' | 'number' | 'link' | 'file' | 'rich-text' | 'embed' | 'list';\n\n/**\n * Project-level enum configuration\n * Keys are enum names, values are arrays of options\n */\nexport type EnumsConfig = Record<string, readonly string[]>;\n\n/**\n * Internationalization (i18n) value object\n * Keys are locale codes (e.g., 'en', 'pl', 'de')\n * Values can be strings (for string props) or arrays (for list props)\n */\nexport interface I18nValue {\n _i18n: true;\n [locale: string]: string | unknown[] | true; // true is for the _i18n marker, arrays for list props\n}\n\n/**\n * Locale configuration with metadata\n */\nexport interface LocaleConfig {\n code: string; // URL prefix & translation key (e.g., \"en\", \"pl\")\n name: string; // English name for admin UI (e.g., \"Polish\")\n nativeName: string; // Native name for public UI (e.g., \"Polski\")\n langTag: string; // BCP 47 language tag for SEO (e.g., \"pl-PL\")\n icon?: string; // Optional flag icon path (e.g., \"/icons/flag-en.svg\")\n}\n\n/**\n * Internationalization configuration\n */\nexport interface I18nConfig {\n defaultLocale: string;\n locales: LocaleConfig[];\n}\n\n/**\n * Value resolver function type\n * Used for transforming field values (e.g., i18n resolution)\n */\nexport type ValueResolver = (value: unknown) => unknown;\n\n/**\n * Link prop value type\n */\nexport interface LinkPropValue {\n href: string;\n target?: '_blank';\n}\n\n/**\n * Base prop definition without list-specific fields\n */\nexport interface BasePropDefinition {\n type: Exclude<PropType, 'list'>;\n default?: string | number | boolean | I18nValue | LinkPropValue;\n options?: readonly string[]; // Required for \"select\" type (inline options)\n enumName?: string; // For \"select\" type: reference to project-level enum\n accept?: string; // For \"file\" type: MIME pattern like \"image/*\", \"video/*\"\n editor?: 'basic' | 'extended'; // For 'rich-text' type: which editor to use\n}\n\n/**\n * List item schema - defines the structure of each item in a list prop\n * Uses the same prop types as component interfaces (except nested lists)\n */\nexport type ListItemSchema = Record<string, BasePropDefinition>;\n\n/**\n * List item value type\n * Supports i18n values for localized string fields\n */\nexport type ListItemValue = Record<string, string | number | boolean | LinkPropValue | I18nValue | null>;\n\n/**\n * List prop definition - for array/list data\n */\nexport interface ListPropDefinition {\n type: 'list';\n /** Schema defining the structure of each list item */\n itemSchema: ListItemSchema;\n /** Default value is an array of items */\n default?: ListItemValue[];\n}\n\n/**\n * Prop definition with improved type safety\n */\nexport type PropDefinition = BasePropDefinition | ListPropDefinition;\n\n/**\n * Type guard to check if a prop definition is a list type\n */\nexport function isListPropDefinition(def: PropDefinition): def is ListPropDefinition {\n return def.type === 'list';\n}\n\n/**\n * Type guard to check if a prop definition is a base (non-list) type\n */\nexport function isBasePropDefinition(def: PropDefinition): def is BasePropDefinition {\n return def.type !== 'list';\n}\n\n/**\n * Structured component definition\n */\nexport interface StructuredComponentDefinition {\n interface?: Record<string, PropDefinition>;\n structure?: ComponentNode;\n javascript?: string; // Vanilla JS code to be rendered at end of HTML\n css?: string; // CSS code to be rendered in <style> tag in <head>\n category?: string; // Component category for organization\n /**\n * Define which props are available as JavaScript variables (Astro-style define:vars)\n * - true: all props from interface are exposed\n * - string[]: only specified props are exposed\n * - undefined: no automatic prop injection (backward compatible)\n */\n defineVars?: true | string[];\n /** External JS/CSS libraries required by this component */\n libraries?: LibrariesConfig;\n /** Whether instances of this component can have styles applied to the wrapper */\n acceptsStyles?: boolean;\n}\n\n/**\n * Component definition\n * Supports both new format (just component) and legacy format (type/props/children/component)\n */\nexport interface ComponentDefinition {\n type?: string; // Legacy format\n props?: Record<string, unknown>; // Legacy format\n children?: unknown[]; // Legacy format\n component: StructuredComponentDefinition;\n}\n\n/**\n * Line range for element line number tracking\n */\nexport interface LineRange {\n startLine: number;\n endLine: number;\n}\n\n/**\n * JSON page structure\n */\nexport interface JSONPage {\n meta?: import('./api').PageMetaData;\n components?: Record<string, ComponentDefinition>;\n root?: ComponentNode;\n _lineMap?: Record<string, LineRange>;\n}\n\n/**\n * Page data type that can be either a JSONPage or a component definition structure\n */\nexport type PageData = JSONPage | {\n component: {\n structure?: ComponentNode;\n interface?: Record<string, PropDefinition>;\n javascript?: string;\n css?: string;\n acceptsStyles?: boolean;\n }\n};\n\n/**\n * Page data with component structure (for type narrowing)\n */\nexport interface PageDataWithComponent {\n component: {\n structure?: ComponentNode;\n interface?: Record<string, PropDefinition>;\n javascript?: string;\n css?: string;\n libraries?: LibrariesConfig;\n acceptsStyles?: boolean;\n };\n}\n", "/**\n * Error Types\n * Structured error types for validation and type safety\n */\n\n/**\n * Validation error with context\n */\nexport interface ValidationError {\n path?: string;\n message: string;\n receivedValue?: unknown;\n expectedType?: string;\n}\n\n/**\n * Type safety error\n * Errors from type mismatches or invalid data structures\n */\nexport interface TypeSafetyError extends Error {\n readonly path?: string;\n readonly receivedValue?: unknown;\n readonly expectedType?: string;\n}\n\n/**\n * Result type for operations that can fail\n * Replaces null returns with explicit success/failure\n */\nexport type Result<T> =\n | { success: true; data: T }\n | { success: false; error: ValidationError };\n\n/**\n * Create a validation error\n */\nexport function createValidationError(\n message: string,\n options?: {\n path?: string;\n receivedValue?: unknown;\n expectedType?: string;\n }\n): ValidationError {\n return {\n message,\n ...options,\n };\n}\n\n/**\n * Create a type safety error\n */\nexport function createTypeSafetyError(\n message: string,\n options?: {\n path?: string;\n receivedValue?: unknown;\n expectedType?: string;\n }\n): TypeSafetyError {\n const error = new Error(message) as TypeSafetyError;\n Object.defineProperty(error, 'path', { value: options?.path, writable: false });\n Object.defineProperty(error, 'receivedValue', { value: options?.receivedValue, writable: false });\n Object.defineProperty(error, 'expectedType', { value: options?.expectedType, writable: false });\n return error;\n}\n\n\n", "/**\n * Color Variables Types\n * Handles color variable definitions and configuration\n */\n\n/**\n * Color variables configuration\n * Maps semantic color names to their hex/rgb values\n */\nexport interface ColorVariables {\n colors: Record<string, string>;\n}\n\n/**\n * Theme configuration with color set and metadata\n */\nexport interface Theme {\n label: string;\n colors: Record<string, string>;\n}\n\n/**\n * Theme configuration file structure\n * Supports multiple named themes with a default theme\n */\nexport interface ThemeConfig {\n default: string;\n palette?: Record<string, string>;\n themes: Record<string, Theme>;\n}\n\n/**\n * Resolve a color value through the palette.\n * If value matches a palette key, returns the palette hex; otherwise returns value as-is.\n */\nexport function resolvePaletteColor(value: string, palette?: Record<string, string>): string {\n if (!palette) return value;\n return palette[value] ?? value;\n}\n\n/**\n * Color variable entry for editor display\n */\nexport interface ColorVariableEntry {\n name: string;\n value: string;\n}\n\n/**\n * Theme entry for theme selector\n */\nexport interface ThemeEntry {\n name: string;\n label: string;\n}\n", "/**\n * CSS Variables Types\n * Defines types for the variables.json configuration file\n */\n\n/**\n * Category type for a CSS variable\n * Maps to responsiveScales categories for automatic responsive scaling\n * 'none' means no responsive scaling is applied\n */\nexport type VariableType = 'fontSize' | 'padding' | 'margin' | 'gap' | 'borderRadius' | 'size' | 'none';\n\n/**\n * UI filtering group for a CSS variable.\n * Controls which variables appear in the picker based on the CSS property being edited.\n */\nexport type VariableGroup =\n | 'font-family' | 'font-size' | 'font-weight'\n | 'line-height' | 'letter-spacing'\n | 'margin' | 'padding' | 'gap'\n | 'size'\n | 'position'\n | 'border-radius' | 'border-width'\n | 'outline'\n | 'shadow'\n | 'filter'\n | 'duration'\n | 'aspect-ratio'\n | 'opacity' | 'z-index'\n | 'text-align'\n | 'other';\n\n/** Predefined variable groups for UI dropdowns */\nexport const VARIABLE_GROUPS: { value: VariableGroup; label: string }[] = [\n { value: 'font-family', label: 'Font Family' },\n { value: 'font-size', label: 'Font Size' },\n { value: 'font-weight', label: 'Font Weight' },\n { value: 'line-height', label: 'Line Height' },\n { value: 'letter-spacing', label: 'Letter Spacing' },\n { value: 'margin', label: 'Margin' },\n { value: 'padding', label: 'Padding' },\n { value: 'gap', label: 'Gap' },\n { value: 'size', label: 'Size' },\n { value: 'position', label: 'Position' },\n { value: 'border-radius', label: 'Border Radius' },\n { value: 'border-width', label: 'Border Width' },\n { value: 'outline', label: 'Outline' },\n { value: 'shadow', label: 'Shadow' },\n { value: 'filter', label: 'Filter' },\n { value: 'duration', label: 'Duration' },\n { value: 'aspect-ratio', label: 'Aspect Ratio' },\n { value: 'opacity', label: 'Opacity' },\n { value: 'z-index', label: 'Z-Index' },\n { value: 'text-align', label: 'Text Align' },\n { value: 'other', label: 'Other' },\n];\n\n/** All valid group string values */\nexport const VARIABLE_GROUP_VALUES: VariableGroup[] = VARIABLE_GROUPS.map(g => g.value);\n\n/** Maps CSS property names to variable groups */\nconst CSS_PROPERTY_TO_GROUP: Record<string, VariableGroup> = {\n 'font-family': 'font-family',\n 'font-size': 'font-size',\n 'font-weight': 'font-weight',\n 'line-height': 'line-height',\n 'letter-spacing': 'letter-spacing',\n 'text-align': 'text-align',\n 'opacity': 'opacity',\n 'z-index': 'z-index',\n 'top': 'position',\n 'right': 'position',\n 'bottom': 'position',\n 'left': 'position',\n 'inset': 'position',\n 'inset-block': 'position',\n 'inset-inline': 'position',\n 'inset-block-start': 'position',\n 'inset-block-end': 'position',\n 'inset-inline-start': 'position',\n 'inset-inline-end': 'position',\n 'box-shadow': 'shadow',\n 'text-shadow': 'shadow',\n 'filter': 'filter',\n 'backdrop-filter': 'filter',\n 'aspect-ratio': 'aspect-ratio',\n 'transition-duration': 'duration',\n 'animation-duration': 'duration',\n 'transition-delay': 'duration',\n 'animation-delay': 'duration',\n};\n\n/** Prefix-based mappings for CSS properties */\nconst CSS_PROPERTY_PREFIX_GROUPS: { prefix: string; group: VariableGroup }[] = [\n { prefix: 'margin', group: 'margin' },\n { prefix: 'padding', group: 'padding' },\n { prefix: 'gap', group: 'gap' },\n { prefix: 'row-gap', group: 'gap' },\n { prefix: 'column-gap', group: 'gap' },\n { prefix: 'width', group: 'size' },\n { prefix: 'height', group: 'size' },\n { prefix: 'min-width', group: 'size' },\n { prefix: 'max-width', group: 'size' },\n { prefix: 'min-height', group: 'size' },\n { prefix: 'max-height', group: 'size' },\n { prefix: 'border-radius', group: 'border-radius' },\n { prefix: 'border-top-left-radius', group: 'border-radius' },\n { prefix: 'border-top-right-radius', group: 'border-radius' },\n { prefix: 'border-bottom-left-radius', group: 'border-radius' },\n { prefix: 'border-bottom-right-radius', group: 'border-radius' },\n { prefix: 'border-width', group: 'border-width' },\n { prefix: 'border-top-width', group: 'border-width' },\n { prefix: 'border-right-width', group: 'border-width' },\n { prefix: 'border-bottom-width', group: 'border-width' },\n { prefix: 'border-left-width', group: 'border-width' },\n { prefix: 'outline-width', group: 'outline' },\n { prefix: 'outline-offset', group: 'outline' },\n];\n\n/**\n * Determines which variable group a CSS property belongs to.\n * Returns null if no group matches (show all variables).\n */\nexport function getGroupForProperty(prop: string): VariableGroup | null {\n // Normalize camelCase to kebab-case (e.g., \"fontFamily\" \u2192 \"font-family\")\n const normalized = prop.replace(/[A-Z]/g, letter => `-${letter.toLowerCase()}`);\n\n // Exact match first\n if (normalized in CSS_PROPERTY_TO_GROUP) {\n return CSS_PROPERTY_TO_GROUP[normalized];\n }\n // Prefix-based match (handles margin-top, padding-left, etc.)\n for (const { prefix, group } of CSS_PROPERTY_PREFIX_GROUPS) {\n if (normalized === prefix || normalized.startsWith(prefix + '-')) {\n return group;\n }\n }\n return null;\n}\n\n/**\n * A single CSS custom property definition\n */\nexport interface CSSVariable {\n /** Display name (e.g., \"H1 Font Size\") */\n name: string;\n /** Optional prop name alias for organizational purposes */\n prop_name?: string;\n /** CSS custom property name (e.g., \"--h1-fs\") */\n cssVar: string;\n /** Base value (e.g., \"48px\") */\n value: string;\n /** Category for responsive scaling */\n type: VariableType;\n /** Optional per-variable breakpoint scale overrides */\n scales?: Record<string, string>;\n /** Optional UI filtering group for the variable picker */\n group?: VariableGroup;\n}\n\n/**\n * Variables configuration file structure (variables.json)\n */\nexport interface VariablesConfig {\n variables: CSSVariable[];\n}\n\n/** Predefined variable scaling types for UI dropdowns */\nexport const VARIABLE_TYPES: { value: VariableType; label: string }[] = [\n { value: 'fontSize', label: 'Font Size' },\n { value: 'padding', label: 'Padding' },\n { value: 'margin', label: 'Margin' },\n { value: 'gap', label: 'Gap' },\n { value: 'borderRadius', label: 'Border Radius' },\n { value: 'size', label: 'Width / Height' },\n { value: 'none', label: 'None' },\n];\n\n/** All valid variable scaling type values */\nexport const VARIABLE_TYPE_VALUES: VariableType[] = VARIABLE_TYPES.map(t => t.value);\n\n/**\n * Returns an abbreviation for a variable group by taking the first letter of each word.\n * e.g. 'letter-spacing' -> 'ls', 'font-size' -> 'fs', 'spacing' -> 's'\n */\nexport function getGroupAbbreviation(group: string): string {\n return group.split('-').map(w => w[0] || '').join('');\n}\n\n/**\n * Infers a default scaling type from a variable group and optional CSS property.\n */\nexport function getDefaultScalingType(group: string, cssProperty?: string): VariableType {\n if (group === 'font-size') return 'fontSize';\n if (group === 'margin') return 'margin';\n if (group === 'padding') return 'padding';\n if (group === 'gap') return 'gap';\n if (group === 'border-radius') return 'borderRadius';\n if (group === 'size') return 'size';\n return 'none';\n}\n\n/**\n * Generates a short CSS variable name with collision detection.\n * e.g. name=\"Heading\", group=\"letter-spacing\" -> \"--h-ls\"\n * If taken, extends prefix: \"--he-ls\", \"--hea-ls\", etc.\n */\nexport function generateShortCssVar(\n name: string,\n group: string,\n existingVariables: CSSVariable[]\n): string {\n const trimmed = name.trim();\n if (!trimmed) return '--';\n if (!group) {\n // No group: just kebab-case the name\n const base = '--' + trimmed.toLowerCase().replace(/\\s+/g, '-').replace(/[^a-z0-9-]/g, '');\n return ensureUnique(base, existingVariables);\n }\n\n const groupAbbr = getGroupAbbreviation(group);\n const kebabName = trimmed.toLowerCase().replace(/\\s+/g, '-').replace(/[^a-z0-9-]/g, '');\n const words = kebabName.split('-').filter(Boolean);\n const existingNames = new Set(existingVariables.map(v => v.cssVar));\n\n // Try progressively longer prefixes from the name\n // Start with first letter of each word, then extend first word\n const initials = words.map(w => w[0] || '').join('');\n const initialCandidate = `--${initials}-${groupAbbr}`;\n if (!existingNames.has(initialCandidate)) return initialCandidate;\n\n // Extend first word progressively\n const firstWord = words[0] || '';\n for (let len = 2; len <= firstWord.length; len++) {\n const prefix = firstWord.slice(0, len) + (words.length > 1 ? words.slice(1).map(w => w[0] || '').join('') : '');\n const candidate = `--${prefix}-${groupAbbr}`;\n if (!existingNames.has(candidate)) return candidate;\n }\n\n // Full kebab name with group abbreviation\n const fullCandidate = `--${kebabName}-${groupAbbr}`;\n if (!existingNames.has(fullCandidate)) return fullCandidate;\n\n // Numeric suffix fallback\n let i = 2;\n while (existingNames.has(`${fullCandidate}-${i}`)) i++;\n return `${fullCandidate}-${i}`;\n}\n\nfunction ensureUnique(base: string, existingVariables: CSSVariable[]): string {\n const existingNames = new Set(existingVariables.map(v => v.cssVar));\n if (!existingNames.has(base)) return base;\n let i = 2;\n while (existingNames.has(`${base}-${i}`)) i++;\n return `${base}-${i}`;\n}\n", "/**\n * Comment / Pin Types\n *\n * Comments are Figma-style pins placed on components in the studio canvas.\n * One file per pin (thread embedded). Storage layout (status as top folder):\n * {projectRoot}/comments/<status>/<pageSlug>--<seq>--<titleSlug>.json\n * e.g. comments/open/blog__post--3--hero-is-too-dark.json\n *\n * Pins are an authoring-time concept \u2014 they live in studio only.\n */\n\n/** Workflow status. No custom statuses for MVP. */\nexport type CommentStatus =\n | 'open'\n | 'in-progress'\n | 'ready-for-review'\n | 'resolved'\n | 'closed';\n\nexport const COMMENT_STATUSES: readonly CommentStatus[] = [\n 'open',\n 'in-progress',\n 'ready-for-review',\n 'resolved',\n 'closed',\n] as const;\n\n/** Identifies the GitHub user who authored a thread entry. */\nexport interface CommentAuthor {\n /** GitHub login. `\"local\"` for non-electron / unauthenticated runs. */\n login: string;\n name?: string;\n avatarUrl?: string;\n}\n\n/**\n * Identity fingerprint for the anchored node \u2014 used to detect orphan pins\n * when the tree shifts. Mirrors the shape of `nodesMatch()` in NodeStore.\n */\nexport interface CommentNodeIdentity {\n /** `'component'` or `'node'` (HTML). */\n kind: 'component' | 'node';\n /** Component name (when kind=component) or HTML tag (when kind=node). */\n name: string;\n /** Editor-set label, used to disambiguate same-type siblings. */\n label?: string;\n}\n\n/**\n * Where the pin attaches on the page. nodePath is positional; nodeIdentity\n * is used at render time to detect that the pin has been orphaned (Phase 4).\n */\nexport interface CommentAnchor {\n /** Path array into the page tree, e.g. [0, 1, 2]. */\n nodePath: number[];\n /** Identity fingerprint for orphan detection. */\n nodeIdentity: CommentNodeIdentity;\n /** Horizontal offset inside the component's bounding box, 0..1. */\n offsetXPercent: number;\n /** Vertical offset inside the component's bounding box, 0..1. */\n offsetYPercent: number;\n /**\n * Breakpoint frame this pin was placed on (e.g. `'base'`, `'tablet'`,\n * `'mobile'`). Only set for pins created in Design Mode's multi-frame\n * canvas, so the pin is only shown on the frame where it was pinned.\n * When unset, the pin renders on every frame (single-frame / page mode,\n * or pins created before this field existed).\n */\n breakpoint?: string;\n}\n\n/** One message in a comment's thread (initial + replies). */\nexport interface CommentThreadEntry {\n id: string;\n author: CommentAuthor;\n /** ISO timestamp. */\n createdAt: string;\n text: string;\n /** When this entry transitioned the comment status, the target status. */\n statusChange: CommentStatus | null;\n}\n\n/** A pinned comment. */\nexport interface Comment {\n _id: string;\n _filename: string;\n /** Page path the pin lives on (e.g. `\"blog/post\"`). */\n _pagePath: string;\n /** Stable per-page badge number. Server assigns at create time. */\n _seq: number;\n /** ISO timestamps. */\n _createdAt: string;\n _updatedAt: string;\n /** Git HEAD SHA captured at create time, or null when unavailable. */\n _commitSha: string | null;\n anchor: CommentAnchor;\n status: CommentStatus;\n thread: CommentThreadEntry[];\n}\n", "/**\n * Pure `@font-face` / preload generation from a list of font configs.\n *\n * No filesystem or project-context coupling \u2014 the caller passes the `fonts`\n * array (read however it likes). This is the single source of truth for font\n * CSS formatting, shared by every renderer:\n * - meno-core SSR \u2192 via {@link ../shared/fontLoader} (cached config)\n * - meno-core JSON\u2192Astro \u2192 build-astro.ts\n * - meno-astro dialect twin \u2192 meno-astro/server `loadFontCss` \u2192 BaseLayout.astro\n *\n * Keeping it server-free means the Astro `BaseLayout` can import it without\n * dragging meno-core's server runtime into the build.\n */\n\nexport interface FontConfig {\n path: string;\n family?: string;\n weight?: number;\n weightMax?: number; // If set, font is variable with weight range [weight, weightMax]\n style?: 'normal' | 'italic';\n fontDisplay?: 'auto' | 'block' | 'swap' | 'fallback' | 'optional';\n unicodeRange?: string;\n /** Legacy alias for `path` (emitted by the website-import flow). */\n src?: string;\n}\n\n/** Detect the `@font-face` `format()` value from a file extension. */\nfunction getFontFormat(path: string): string {\n if (path.endsWith('.woff2')) return 'woff2';\n if (path.endsWith('.woff')) return 'woff';\n if (path.endsWith('.ttf')) return 'truetype';\n if (path.endsWith('.otf')) return 'opentype';\n return 'truetype';\n}\n\n/** Font `type` attribute for a `<link rel=\"preload\">`. */\nfunction getFontMimeType(path: string): string {\n if (path.endsWith('.woff2')) return 'font/woff2';\n if (path.endsWith('.woff')) return 'font/woff';\n if (path.endsWith('.ttf')) return 'font/ttf';\n if (path.endsWith('.otf')) return 'font/otf';\n return 'font/ttf';\n}\n\n/**\n * Derive a family name from a path when none is configured.\n * Example: \"/fonts/geomanist-regular.ttf\" -> \"Geomanist Regular\".\n */\nexport function extractFamilyName(path: string): string {\n const filename = path.split('/').pop() || 'Font';\n const name = filename.replace(/\\.(ttf|woff2?|otf)$/i, '');\n return name\n .split('-')\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(' ');\n}\n\n/** Build the `@font-face` rules for the given fonts (empty string for none). */\nexport function fontFaceCss(fonts: FontConfig[]): string {\n return (fonts || [])\n .filter((font) => font.path || font.src)\n .map((font) => {\n // Support both \"path\" (standard) and \"src\" (legacy from website import)\n const fontPath = (font.path || font.src) as string;\n const format = getFontFormat(fontPath);\n const family = font.family || extractFamilyName(fontPath);\n const weight = font.weight ?? 400;\n const weightMax = font.weightMax;\n const style = font.style ?? 'normal';\n const fontDisplay = font.fontDisplay;\n\n // Variable fonts use weight range syntax: \"100 900\"\n const fontWeight = weightMax != null ? `${weight} ${weightMax}` : weight;\n const unicodeRange = font.unicodeRange;\n\n return `@font-face {\n font-family: '${family}';\n src: url('${fontPath}') format('${format}');\n font-weight: ${fontWeight};\n font-style: ${style};${fontDisplay ? `\\n font-display: ${fontDisplay};` : ''}${unicodeRange ? `\\n unicode-range: ${unicodeRange};` : ''}\n}`;\n })\n .join('\\n\\n');\n}\n\n/**\n * Build `<link rel=\"preload\">` tags for the given fonts (empty string for none).\n * `crossorigin` is required for the preloaded font to be reused by the CSS.\n */\nexport function fontPreloadLinks(fonts: FontConfig[]): string {\n if (!fonts || fonts.length === 0) return '';\n\n return fonts\n .filter((font) => font.path || font.src)\n .map((font) => {\n const fontPath = (font.path || font.src) as string;\n const mimeType = getFontMimeType(fontPath);\n return `<link rel=\"preload\" href=\"${fontPath}\" as=\"font\" type=\"${mimeType}\" crossorigin>`;\n })\n .join('\\n ');\n}\n", "/**\n * Slug Translation Service\n * Handles translation of URL slugs between locales\n */\n\nimport type { I18nConfig } from './types';\n\n/**\n * Slug mapping for a single page\n */\nexport interface SlugMap {\n pageId: string;\n slugs: Record<string, string>;\n}\n\n/**\n * Index entry for reverse lookup (slug+locale \u2192 pageId)\n */\ninterface SlugIndexEntry {\n pageId: string;\n slugs: Record<string, string>;\n}\n\n/**\n * Build reverse lookup index: \"locale:slug\" \u2192 SlugIndexEntry\n * This allows quick lookup of pageId from any locale's slug\n */\nexport function buildSlugIndex(mappings: SlugMap[]): Map<string, SlugIndexEntry> {\n const index = new Map<string, SlugIndexEntry>();\n\n for (const mapping of mappings) {\n for (const [locale, slug] of Object.entries(mapping.slugs)) {\n // Key format: \"locale:slug\" (e.g., \"pl:o-nas\" or \"en:about\")\n const key = `${locale}:${slug}`;\n index.set(key, {\n pageId: mapping.pageId,\n slugs: mapping.slugs,\n });\n }\n }\n\n return index;\n}\n\n/**\n * Find page by slug and locale\n * @returns The SlugIndexEntry if found, undefined otherwise\n */\nexport function findPageBySlug(\n slug: string,\n locale: string,\n index: Map<string, SlugIndexEntry>\n): SlugIndexEntry | undefined {\n const key = `${locale}:${slug}`;\n return index.get(key);\n}\n\n/**\n * Translate a path to another locale\n *\n * @param currentPath - Current URL path (e.g., \"/pl/o-nas\" or \"/about\")\n * @param targetLocale - Target locale (e.g., \"en\")\n * @param currentLocale - Current locale (e.g., \"pl\")\n * @param defaultLocale - Default locale that doesn't use prefix (e.g., \"en\")\n * @param index - Slug index from buildSlugIndex()\n * @returns Translated path (e.g., \"/about\" for en default, \"/de/uber\" for de)\n */\nexport function translatePath(\n currentPath: string,\n targetLocale: string,\n currentLocale: string,\n defaultLocale: string,\n index: Map<string, SlugIndexEntry>\n): string {\n // Extract slug from current path (remove locale prefix if present)\n let slug = currentPath;\n\n // Remove leading slash\n if (slug.startsWith('/')) {\n slug = slug.substring(1);\n }\n\n // Remove locale prefix if present (e.g., \"pl/o-nas\" \u2192 \"o-nas\")\n // Also handle case where slug IS the locale (e.g., \"pl\" for Polish homepage)\n if (currentLocale !== defaultLocale) {\n if (slug.startsWith(`${currentLocale}/`)) {\n slug = slug.substring(currentLocale.length + 1);\n } else if (slug === currentLocale) {\n // Path is just the locale prefix (e.g., \"/pl\" \u2192 index page)\n slug = '';\n }\n }\n\n // Handle root path\n if (slug === '' || slug === '/') {\n slug = '';\n }\n\n // Look up page by current slug and locale\n let entry = findPageBySlug(slug, currentLocale, index);\n\n // If not found for current locale, try default locale\n // This handles cases like /de/about where German uses the English slug\n if (!entry && currentLocale !== defaultLocale) {\n entry = findPageBySlug(slug, defaultLocale, index);\n }\n\n if (!entry) {\n // No translation found - return path with just locale prefix change\n if (targetLocale === defaultLocale) {\n return slug === '' ? '/' : `/${slug}`;\n }\n return slug === '' ? `/${targetLocale}` : `/${targetLocale}/${slug}`;\n }\n\n // Get translated slug for target locale\n const targetSlug = entry.slugs[targetLocale] ?? entry.slugs[defaultLocale] ?? slug;\n\n // Build target path\n if (targetLocale === defaultLocale) {\n return targetSlug === '' ? '/' : `/${targetSlug}`;\n }\n return targetSlug === '' ? `/${targetLocale}` : `/${targetLocale}/${targetSlug}`;\n}\n\n/**\n * Locale link information for locale switcher\n */\nexport interface LocaleLink {\n locale: string; // Locale code (e.g., \"pl\")\n langTag: string; // BCP 47 language tag (e.g., \"pl-PL\")\n name: string; // English name (e.g., \"Polish\")\n nativeName: string; // Display name in native language (e.g., \"Polski\")\n path: string; // Translated path for this locale\n isCurrent: boolean; // Whether this is the current locale\n}\n\n/**\n * Get all available locales with their translated paths for the current page\n * Useful for rendering locale switcher\n *\n * @param currentPath - Current URL path\n * @param currentLocale - Current locale\n * @param i18nConfig - i18n configuration with locales\n * @param index - Slug index\n * @returns Array of LocaleLink objects\n */\nexport function getLocaleLinks(\n currentPath: string,\n currentLocale: string,\n i18nConfig: I18nConfig,\n index: Map<string, SlugIndexEntry>\n): LocaleLink[] {\n return i18nConfig.locales.map(localeConfig => ({\n locale: localeConfig.code,\n langTag: localeConfig.langTag,\n name: localeConfig.name,\n nativeName: localeConfig.nativeName,\n path: translatePath(currentPath, localeConfig.code, currentLocale, i18nConfig.defaultLocale, index),\n isCurrent: localeConfig.code === currentLocale,\n }));\n}\n\n/**\n * Build the URL a page is served at for a given locale.\n *\n * Conventions (match what `translatePath` / the routing layer at\n * packages/core/lib/server/routes/pages.ts produces):\n * - Default locale paths are bare: \"/\" or \"/{slug}\"\n * - Non-default locale paths are locale-prefixed: \"/{locale}\" or \"/{locale}/{slug}\"\n * - An empty slug (e.g. for the index page) collapses to the root.\n *\n * Used by the slug/page-rename flow to compute the (old, new) href pair\n * for cascade rewrites in incoming links.\n */\nexport function buildPageUrlForLocale(\n slug: string,\n locale: string,\n defaultLocale: string,\n): string {\n const cleanSlug = slug.replace(/^\\/+/, '');\n if (locale === defaultLocale) {\n return cleanSlug === '' ? '/' : `/${cleanSlug}`;\n }\n return cleanSlug === '' ? `/${locale}` : `/${locale}/${cleanSlug}`;\n}\n\n/**\n * Resolve a slug to its pageId (for server-side page loading)\n *\n * @param slug - URL slug (e.g., \"o-nas\")\n * @param locale - Current locale (e.g., \"pl\")\n * @param index - Slug index\n * @returns pageId if found (e.g., \"about\"), undefined otherwise\n */\nexport function resolveSlugToPageId(\n slug: string,\n locale: string,\n index: Map<string, SlugIndexEntry>\n): string | undefined {\n const entry = findPageBySlug(slug, locale, index);\n return entry?.pageId;\n}\n", "/**\n * Library Loader\n * Generates HTML tags for external JS/CSS libraries\n */\n\nimport type {\n JSLibraryConfig,\n CSSLibraryConfig,\n LibrariesConfig,\n PageLibrariesConfig,\n} from './types/libraries';\nimport type { ComponentDefinition } from './types/components';\n\n/**\n * Escape HTML special characters in attribute values\n */\nfunction escapeAttr(str: string): string {\n return str\n .replace(/&/g, '&')\n .replace(/\"/g, '"')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n}\n\n/**\n * Merge global and page-level library configurations\n * @param global Global libraries from project.config.json\n * @param page Page-level libraries from page meta\n * @returns Merged library configuration\n */\nexport function mergeLibraries(\n global: LibrariesConfig,\n page?: PageLibrariesConfig\n): LibrariesConfig {\n if (!page) {\n return global;\n }\n\n if (page.mode === 'replace') {\n return {\n js: page.js || [],\n css: page.css || [],\n };\n }\n\n // Default: extend\n return {\n js: [...(global.js || []), ...(page.js || [])],\n css: [...(global.css || []), ...(page.css || [])],\n };\n}\n\n/**\n * Generate <script> tag for a JS library\n * @param lib JavaScript library configuration\n * @returns HTML script tag string\n */\nexport function generateScriptTag(lib: JSLibraryConfig): string {\n const attrs: string[] = [`src=\"${escapeAttr(lib.url)}\"`];\n\n if (lib.type === 'module') {\n attrs.push('type=\"module\"');\n } else {\n // Default to defer for better performance\n const mode = lib.mode || 'defer';\n attrs.push(mode);\n }\n\n return `<script ${attrs.join(' ')}></script>`;\n}\n\n/**\n * Generate inline <style> tag with CSS content\n * @param content CSS content to embed\n * @param media Optional media query attribute\n * @returns HTML style tag string\n */\nexport function generateInlineStyleTag(content: string, media?: string): string {\n const attrs = media ? ` media=\"${escapeAttr(media)}\"` : '';\n return `<style${attrs}>${content}</style>`;\n}\n\n/**\n * Generate <link> tag for a CSS library\n * @param lib CSS library configuration\n * @returns HTML link tag string\n */\nexport function generateStylesheetTag(lib: CSSLibraryConfig): string {\n const attrs: string[] = [\n 'rel=\"stylesheet\"',\n `href=\"${escapeAttr(lib.url)}\"`,\n ];\n\n if (lib.media) {\n attrs.push(`media=\"${escapeAttr(lib.media)}\"`);\n }\n\n return `<link ${attrs.join(' ')}>`;\n}\n\n/**\n * Generated library tags grouped by position\n */\nexport interface LibraryTags {\n /** CSS tags for <head> */\n headCSS: string;\n /** JS tags for <head> */\n headJS: string;\n /** JS tags for before </body> */\n bodyEndJS: string;\n}\n\n/**\n * Generate all library tags grouped by position\n * @param libs Library configuration\n * @param inlineContents Optional map of URL \u2192 CSS content for inline embedding\n * @returns Object with tags grouped by position\n */\nexport function generateLibraryTags(libs: LibrariesConfig, inlineContents?: Map<string, string>): LibraryTags {\n const headCSS: string[] = [];\n const headJS: string[] = [];\n const bodyEndJS: string[] = [];\n\n // CSS always goes in head\n for (const css of libs.css || []) {\n const inlineContent = inlineContents?.get(css.url);\n if (inlineContent !== undefined) {\n headCSS.push(generateInlineStyleTag(inlineContent, css.media));\n } else {\n headCSS.push(generateStylesheetTag(css));\n }\n }\n\n // JS can go in head or body-end\n for (const js of libs.js || []) {\n const tag = generateScriptTag(js);\n if (js.position === 'head') {\n headJS.push(tag);\n } else {\n // Default to body-end\n bodyEndJS.push(tag);\n }\n }\n\n return {\n headCSS: headCSS.join('\\n '),\n headJS: headJS.join('\\n '),\n bodyEndJS: bodyEndJS.join('\\n '),\n };\n}\n\n/**\n * Collect library configurations from all component definitions, deduplicated by URL\n * @param globalComponents Global component definitions\n * @param pageComponents Page-specific component definitions\n * @returns Combined library configuration from all components\n */\nexport function collectComponentLibraries(\n globalComponents: Record<string, ComponentDefinition> = {},\n pageComponents: Record<string, ComponentDefinition> = {}\n): LibrariesConfig {\n const seenJS = new Set<string>();\n const seenCSS = new Set<string>();\n const jsLibs: JSLibraryConfig[] = [];\n const cssLibs: CSSLibraryConfig[] = [];\n\n const collect = (components: Record<string, ComponentDefinition>) => {\n for (const component of Object.values(components)) {\n const libs = component?.component?.libraries;\n if (!libs) continue;\n\n for (const js of libs.js || []) {\n if (!seenJS.has(js.url)) {\n seenJS.add(js.url);\n jsLibs.push(js);\n }\n }\n for (const css of libs.css || []) {\n if (!seenCSS.has(css.url)) {\n seenCSS.add(css.url);\n cssLibs.push(css);\n }\n }\n }\n };\n\n collect(globalComponents);\n collect(pageComponents);\n\n return { js: jsLibs, css: cssLibs };\n}\n\n/**\n * Origins extracted from library URLs, grouped by resource type\n */\nexport interface LibraryOrigins {\n /** Origins for script-src (from JS library URLs) */\n scriptOrigins: Set<string>;\n /** Origins for style-src (from CSS library URLs) */\n styleOrigins: Set<string>;\n}\n\n/**\n * Extract unique origin domains from library URLs for CSP headers.\n * Skips relative URLs (/, ./, ../) since they're covered by 'self'.\n * Silently skips malformed URLs.\n */\nexport function extractLibraryOrigins(libs: LibrariesConfig): LibraryOrigins {\n const scriptOrigins = new Set<string>();\n const styleOrigins = new Set<string>();\n\n for (const js of libs.js || []) {\n const origin = safeOrigin(js.url);\n if (origin) scriptOrigins.add(origin);\n }\n\n for (const css of libs.css || []) {\n const origin = safeOrigin(css.url);\n if (origin) styleOrigins.add(origin);\n }\n\n return { scriptOrigins, styleOrigins };\n}\n\n/**\n * Filter libraries based on context (editor, build, or preview).\n * Removes CSS libraries that have the corresponding disable flag set.\n * JS libraries pass through unchanged.\n * Preview context (dev server on port 8080) returns all libraries unfiltered.\n */\nexport function filterLibrariesByContext(\n libs: LibrariesConfig,\n context: 'editor' | 'build' | 'preview'\n): LibrariesConfig {\n if (context === 'preview') return libs;\n const key = context === 'editor' ? 'disableEditor' : 'disableBuild';\n return {\n js: libs.js,\n css: (libs.css || []).filter(css => !css[key]),\n };\n}\n\nfunction safeOrigin(url: string): string | null {\n if (!url || url.startsWith('/') || url.startsWith('./') || url.startsWith('../')) {\n return null;\n }\n try {\n return new URL(url).origin;\n } catch {\n return null;\n }\n}\n", "/**\n * Path Security Utilities\n * Provides path traversal protection for file system operations\n */\n\nimport { resolve, sep } from 'path';\n\n/**\n * Error thrown when a path traversal attack is detected\n */\nexport class PathTraversalError extends Error {\n constructor(\n public readonly requestedPath: string,\n public readonly rootPath: string\n ) {\n super(`Path traversal detected: \"${requestedPath}\" escapes root \"${rootPath}\"`);\n this.name = 'PathTraversalError';\n }\n}\n\n/**\n * Check if a resolved path is within the allowed root directory\n * Uses path.resolve() to normalize and handle .. sequences\n *\n * @param requestedPath - The path to validate (can be relative or absolute)\n * @param rootPath - The root directory that paths must be within\n * @returns true if the path is within root, false otherwise\n */\nexport function isPathWithinRoot(requestedPath: string, rootPath: string): boolean {\n const normalizedRoot = resolve(rootPath);\n const normalizedPath = resolve(rootPath, requestedPath);\n\n // Check that normalized path starts with root + separator\n // Adding separator prevents /project-backup from matching /project\n return normalizedPath === normalizedRoot || normalizedPath.startsWith(normalizedRoot + sep);\n}\n\n/**\n * Resolve a path safely, throwing if it would escape the root\n *\n * @param rootPath - The root directory\n * @param segments - Path segments to join\n * @returns The resolved path\n * @throws PathTraversalError if path escapes root\n */\nexport function resolveSafePath(rootPath: string, ...segments: string[]): string {\n const normalizedRoot = resolve(rootPath);\n const normalizedPath = resolve(normalizedRoot, ...segments);\n\n if (!normalizedPath.startsWith(normalizedRoot + sep) && normalizedPath !== normalizedRoot) {\n throw new PathTraversalError(segments.join(sep), rootPath);\n }\n\n return normalizedPath;\n}\n\n/**\n * Validate that a filename/identifier contains no path traversal sequences\n * Use for collection names, filenames, etc.\n *\n * @param name - The name to validate\n * @returns true if safe, false if contains traversal sequences\n */\nexport function isSafePathSegment(name: string): boolean {\n // Reject empty names\n if (!name || name.trim() === '') return false;\n\n // Reject names with path separators\n if (name.includes('/') || name.includes('\\\\')) return false;\n\n // Reject . and ..\n if (name === '.' || name === '..') return false;\n\n // Reject names starting with .. (e.g., \"..foo\")\n if (name.startsWith('..')) return false;\n\n // Reject null bytes (used in some attacks)\n if (name.includes('\\0')) return false;\n\n return true;\n}\n\n/**\n * Regex for valid CMS identifiers (collection names, filenames)\n * Allows alphanumeric, underscore, hyphen\n */\nexport const SAFE_IDENTIFIER_REGEX = /^[a-zA-Z0-9_-]+$/;\n\n/**\n * Validate a CMS identifier (stricter than isSafePathSegment)\n * Use for collection IDs and filenames that should only contain safe chars\n */\nexport function isValidIdentifier(name: string): boolean {\n return SAFE_IDENTIFIER_REGEX.test(name);\n}\n\n/**\n * Suffix used for CMS draft files: `{filename}.draft.json`. The provider must\n * never accept user-supplied filenames ending in `.draft`, because that would\n * clash with the draft-suffix convention and let a user shadow another item's\n * draft file.\n */\nexport const CMS_DRAFT_SUFFIX = '.draft';\n\n/**\n * True when a user-supplied CMS filename collides with the reserved `.draft`\n * suffix. Use as a hard reject in CMS provider write paths.\n */\nexport function isReservedDraftFilename(filename: string): boolean {\n return filename.endsWith(CMS_DRAFT_SUFFIX);\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../lib/shared/constants.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Shared constants used across the application\n */\n\n// Read PORT from environment variable, fallback to 3000\n// Safe for browser environments where process is not defined\nexport const SERVER_PORT = typeof process !== 'undefined' && process.env?.PORT\n ? parseInt(process.env.PORT, 10)\n : 3000;\n\n// Port for serving built static files (SSR preview)\n// Reads MENO_SERVE_PORT env var so each project instance can get its own port\nexport const SERVE_PORT = typeof process !== 'undefined' && process.env?.MENO_SERVE_PORT\n ? parseInt(process.env.MENO_SERVE_PORT, 10)\n : 8080;\n\nexport const API_ROUTES = {\n PAGES: '/api/pages',\n COMPONENTS: '/api/components',\n PAGE_CONTENT: '/api/page-content', // Returns raw JSON text for a page\n PAGE_DATA: '/api/page-data', // Returns parsed JSON for a specific page\n COMPONENT_DATA: '/api/component-data', // Returns parsed JSON for a specific component\n SAVE_PAGE: '/api/save-page',\n SAVE_COMPONENT: '/api/save-component',\n SAVE_COMPONENT_JS: '/api/save-component-js', // Save JavaScript to .js file\n SAVE_COMPONENT_CSS: '/api/save-component-css', // Save CSS to .css file\n COMPONENT_CATEGORY: '/api/component-category', // Move component to category folder\n COMPONENT_FOLDER: '/api/component-folder', // Create component folder\n COMPONENT_FOLDERS: '/api/component-folders', // List all component folders\n COMPONENT_JS: '/api/component-js', // Get JavaScript from .js file\n CONFIG: '/api/config', // Get project config\n SAVE_CONFIG: '/api/save-config', // Save project config\n COMPONENTS_CONFIG: '/api/components-config', // Get components config\n SAVE_COMPONENTS_CONFIG: '/api/save-components-config', // Save components config\n SELECTION: '/api/selection', // Editor selection state (for AI integration)\n // CMS API routes\n CMS_COLLECTIONS: '/api/cms/collections', // List all CMS collections\n CMS_BASE: '/api/cms', // Base path for CMS item operations\n // Colors API routes\n COLORS_CONFIG: '/api/colors-config', // Get full colors config\n SAVE_COLORS: '/api/save-colors', // Save colors config\n // Page deletion\n DELETE_PAGE: '/api/delete-page', // Delete a page\n // Page folder management\n PAGE_FOLDER: '/api/page-folder', // Create page folder\n PAGE_FOLDERS: '/api/page-folders', // List all page folders\n MOVE_PAGE: '/api/move-page', // Move page to folder\n // Component preview\n COMPONENT_PREVIEW: '/api/component-preview', // Render component preview HTML\n // Website import\n IMPORT_WEBSITE: '/api/import-website', // Import external website for reference\n IMPORTED_WEBSITES: '/api/imported-websites', // List imported website folders\n ANALYZE_WEBSITE: '/api/analyze-website', // Analyze imported website into section map\n CONVERT_TO_MENO: '/api/convert-to-meno', // Convert imported HTML to flat Meno page JSON\n EXTRACT_CONTENT: '/api/extract-content', // Extract content from imported website for template mapping\n GENERATE_WIREFRAME_PROMPT: '/api/generate-wireframe-prompt', // Generate wireframe conversion prompt from extraction\n GENERATE_DESIGN_TOKEN_PROMPT: '/api/generate-design-token-prompt', // Generate design token extraction prompt\n GENERATE_CONTENT_PROMPT: '/api/generate-content-prompt', // Generate content conversion prompt using existing components\n GENERATE_SIMPLIFIED_PROMPT: '/api/generate-simplified-prompt', // Generate simplified prompt for Claude Code with Chrome extension\n // Multi-page import routes\n FETCH_SITEMAP: '/api/fetch-sitemap', // Fetch & parse sitemap.xml\n IMPORT_PAGE: '/api/import-page', // Import a single subpage\n ANALYZE_PAGE: '/api/analyze-page', // Analyze a subpage\n EXTRACT_PAGE_CONTENT: '/api/extract-page-content', // Extract content from a subpage\n GENERATE_HOMEPAGE_PROMPT: '/api/generate-homepage-prompt', // Homepage prompt with site structure\n GENERATE_PAGE_PROMPT: '/api/generate-page-prompt', // Per-page/template prompt\n LOAD_WEBSITE_IMPORT: '/api/load-website-import', // Load saved website import data from disk\n // Variables API routes\n VARIABLES_STATUS: '/api/variables-status', // Get variables config with status\n VARIABLES_CSS: '/api/variables-css', // Get generated CSS custom properties\n SAVE_VARIABLES: '/api/save-variables', // Save variables config\n // Enums API routes\n ENUMS: '/api/enums', // Get enums config\n SAVE_ENUMS: '/api/save-enums', // Save enums config\n // Component usage\n COMPONENT_USAGE: '/api/component-usage', // Get component usage across project\n // Rename component across the project (files + all references)\n RENAME_COMPONENT: '/api/rename-component',\n // Rename a page (single-locale: file rename + cascade href rewrite)\n RENAME_PAGE: '/api/rename-page',\n // Rename a page's locale-specific slug (multi-locale: meta.slugs + cascade hrefs)\n RENAME_PAGE_SLUG: '/api/rename-page-slug',\n} as const;\n\nexport const HMR_ROUTE = '/hmr';\n\nexport const FILE_PATTERNS = {\n PAGES: './pages',\n COMPONENTS: './components',\n} as const;\n\nexport const DEFAULT_TIMEOUT = 5000;\n\nexport const WEBSOCKET_STATES = {\n CONNECTING: 0,\n OPEN: 1,\n CLOSING: 2,\n CLOSED: 3,\n} as const;\n\n// Timeout constants\nexport const NOT_FOUND_TIMEOUT_MS = 300;\nexport const TAB_SWITCH_DELAY_MS = 100;\nexport const IFRAME_HIGHLIGHT_DELAY_MS = 100;\nexport const TREE_SCROLL_DELAY_MS = 200;\nexport const HOVER_HIGHLIGHT_DELAY_MS = 50; // Delay before highlighting tree item after expansion\n\n// Server configuration\nexport const MAX_PORT_ATTEMPTS = 10;\n\n// Message types for iframe-parent communication\nexport const IFRAME_MESSAGE_TYPES = {\n DELETE_ELEMENT: 'DELETE_ELEMENT',\n TOGGLE_SELECTING_MODE: 'TOGGLE_SELECTING_MODE',\n SET_TAB: 'SET_TAB',\n COPY_ELEMENT: 'COPY_ELEMENT',\n PASTE_ELEMENT: 'PASTE_ELEMENT',\n PASTE_ELEMENT_AFTER: 'PASTE_ELEMENT_AFTER',\n ARROW_UP: 'ARROW_UP',\n ARROW_DOWN: 'ARROW_DOWN',\n ARROW_LEFT: 'ARROW_LEFT',\n ARROW_RIGHT: 'ARROW_RIGHT',\n OPEN_COMMAND_PALETTE: 'OPEN_COMMAND_PALETTE',\n EDIT_COMPONENT: 'EDIT_COMPONENT',\n NAVIGATE_BACK: 'NAVIGATE_BACK',\n TOGGLE_ADDING_STYLE: 'TOGGLE_ADDING_STYLE',\n MOVE_ELEMENT_UP: 'MOVE_ELEMENT_UP',\n MOVE_ELEMENT_DOWN: 'MOVE_ELEMENT_DOWN',\n NEST_INTO_PREVIOUS_SIBLING: 'NEST_INTO_PREVIOUS_SIBLING',\n NEST_INTO_NEXT_SIBLING: 'NEST_INTO_NEXT_SIBLING',\n SELECTION_CHANGED: 'SELECTION_CHANGED',\n CMS_CONTEXT_UPDATE: 'CMS_CONTEXT_UPDATE',\n CMS_CONTEXT_REQUEST: 'CMS_CONTEXT_REQUEST',\n INTERACTIVE_CSS_UPDATE: 'INTERACTIVE_CSS_UPDATE',\n INTERACTIVE_STYLES_UPDATE: 'INTERACTIVE_STYLES_UPDATE', // Registry data from iframe to editor\n UNDO_REQUEST: 'UNDO_REQUEST',\n REDO_REQUEST: 'REDO_REQUEST',\n TOGGLE_INTERACTIVITY_EDITOR: 'TOGGLE_INTERACTIVITY_EDITOR',\n SET_BREAKPOINT: 'SET_BREAKPOINT',\n PAGE_DATA_PREVIEW: 'PAGE_DATA_PREVIEW', // Editor \u2192 Iframe for component hover preview\n PAGE_DATA_PREVIEW_REVERT: 'PAGE_DATA_PREVIEW_REVERT', // Editor \u2192 Iframe to revert preview\n PAGE_DATA_COMMITTED: 'PAGE_DATA_COMMITTED', // Editor \u2192 Iframe for committed mutations\n COMPONENT_DEFINITION_COMMITTED: 'COMPONENT_DEFINITION_COMMITTED', // Editor \u2192 Iframe for component definition updates\n CSS_VARIABLE_UPDATE: 'CSS_VARIABLE_UPDATE', // Editor \u2192 Iframe for instant CSS variable preview\n CSS_VARIABLE_SCOPED_UPDATE: 'CSS_VARIABLE_SCOPED_UPDATE', // Editor \u2192 Iframe for instant per-breakpoint CSS variable preview (scoped via @media)\n CSS_VARIABLE_SCOPED_CLEAR: 'CSS_VARIABLE_SCOPED_CLEAR', // Editor \u2192 Iframe to drop the scrub-preview <style> tag\n DUPLICATE_ELEMENT: 'DUPLICATE_ELEMENT',\n MAKE_COMPONENT: 'MAKE_COMPONENT',\n SWAP_TO_COMPONENT: 'SWAP_TO_COMPONENT',\n SMART_CONNECT: 'SMART_CONNECT',\n} as const;\n\n// Component node type constants\nexport const NODE_TYPE = {\n NODE: 'node',\n COMPONENT: 'component',\n SLOT: 'slot',\n EMBED: 'embed',\n LINK: 'link',\n LOCALE_LIST: 'locale-list',\n LIST: 'list',\n} as const;\n\nexport type NodeType = typeof NODE_TYPE[keyof typeof NODE_TYPE];\n\n// Special path identifiers for component editing\nexport const SPECIAL_PATHS = {\n COMPONENT_INTERFACE: 'component_interface',\n COMPONENT_JAVASCRIPT: 'component_javascript',\n COMPONENT_CSS: 'component_css',\n COMPONENT_LIBRARIES: 'component_libraries',\n COMPONENT_ACCEPTS_STYLES: 'component_acceptsStyles',\n STRUCTURE_STYLE: 'structure_style',\n} as const;\n\n// Component type configuration\nexport interface ComponentTypeConfig {\n id: string;\n label: string;\n color: string;\n description?: string;\n}\n\nexport const DEFAULT_COMPONENT_TYPES: ComponentTypeConfig[] = [\n { id: 'ui', label: 'UI', color: '#3b82f6' },\n { id: 'layout', label: 'Layout', color: '#10b981' },\n { id: 'content', label: 'Content', color: '#f59e0b' },\n];\n\nexport const DEFAULT_ICON_COLOR = '#6b7280';\n\n/**\n * Marker for raw HTML content that should not be escaped\n * Used by rich-text fields to signal that content should render as HTML\n */\nexport const RAW_HTML_PREFIX = '<!--MENO_RAW_HTML-->';\n\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ConfigService,
|
|
3
|
-
configService
|
|
4
|
-
} from "./chunk-2MHDV5BF.js";
|
|
5
|
-
import "./chunk-I7YIGZXT.js";
|
|
6
|
-
import "./chunk-WQFG7PAH.js";
|
|
7
|
-
import "./chunk-AZQYF6KE.js";
|
|
8
|
-
import "./chunk-KSBZ2L7C.js";
|
|
9
|
-
export {
|
|
10
|
-
ConfigService,
|
|
11
|
-
configService
|
|
12
|
-
};
|
|
13
|
-
//# sourceMappingURL=configService-R3OGU2UD.js.map
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
API_ROUTES,
|
|
3
|
-
DEFAULT_COMPONENT_TYPES,
|
|
4
|
-
DEFAULT_ICON_COLOR,
|
|
5
|
-
DEFAULT_TIMEOUT,
|
|
6
|
-
FILE_PATTERNS,
|
|
7
|
-
HMR_ROUTE,
|
|
8
|
-
HOVER_HIGHLIGHT_DELAY_MS,
|
|
9
|
-
IFRAME_HIGHLIGHT_DELAY_MS,
|
|
10
|
-
IFRAME_MESSAGE_TYPES,
|
|
11
|
-
MAX_PORT_ATTEMPTS,
|
|
12
|
-
NODE_TYPE,
|
|
13
|
-
NOT_FOUND_TIMEOUT_MS,
|
|
14
|
-
RAW_HTML_PREFIX,
|
|
15
|
-
SERVER_PORT,
|
|
16
|
-
SERVE_PORT,
|
|
17
|
-
SPECIAL_PATHS,
|
|
18
|
-
TAB_SWITCH_DELAY_MS,
|
|
19
|
-
TREE_SCROLL_DELAY_MS,
|
|
20
|
-
WEBSOCKET_STATES,
|
|
21
|
-
init_constants
|
|
22
|
-
} from "./chunk-YBLHKYFF.js";
|
|
23
|
-
import "./chunk-KSBZ2L7C.js";
|
|
24
|
-
init_constants();
|
|
25
|
-
export {
|
|
26
|
-
API_ROUTES,
|
|
27
|
-
DEFAULT_COMPONENT_TYPES,
|
|
28
|
-
DEFAULT_ICON_COLOR,
|
|
29
|
-
DEFAULT_TIMEOUT,
|
|
30
|
-
FILE_PATTERNS,
|
|
31
|
-
HMR_ROUTE,
|
|
32
|
-
HOVER_HIGHLIGHT_DELAY_MS,
|
|
33
|
-
IFRAME_HIGHLIGHT_DELAY_MS,
|
|
34
|
-
IFRAME_MESSAGE_TYPES,
|
|
35
|
-
MAX_PORT_ATTEMPTS,
|
|
36
|
-
NODE_TYPE,
|
|
37
|
-
NOT_FOUND_TIMEOUT_MS,
|
|
38
|
-
RAW_HTML_PREFIX,
|
|
39
|
-
SERVER_PORT,
|
|
40
|
-
SERVE_PORT,
|
|
41
|
-
SPECIAL_PATHS,
|
|
42
|
-
TAB_SWITCH_DELAY_MS,
|
|
43
|
-
TREE_SCROLL_DELAY_MS,
|
|
44
|
-
WEBSOCKET_STATES
|
|
45
|
-
};
|
|
46
|
-
//# sourceMappingURL=constants-STK2YBIW.js.map
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ComponentService,
|
|
3
|
-
FileSystemPageProvider,
|
|
4
|
-
FileWatcherService,
|
|
5
|
-
PageCache,
|
|
6
|
-
PageService,
|
|
7
|
-
WebSocketManager,
|
|
8
|
-
createServer
|
|
9
|
-
} from "../chunks/chunk-R6XHAFBF.js";
|
|
10
|
-
import {
|
|
11
|
-
CMSService,
|
|
12
|
-
FileSystemCMSProvider,
|
|
13
|
-
loadProjectConfig,
|
|
14
|
-
migrateTemplatesDirectory
|
|
15
|
-
} from "../chunks/chunk-IGYR22T6.js";
|
|
16
|
-
import {
|
|
17
|
-
configService
|
|
18
|
-
} from "../chunks/chunk-2MHDV5BF.js";
|
|
19
|
-
import {
|
|
20
|
-
projectPaths
|
|
21
|
-
} from "../chunks/chunk-I7YIGZXT.js";
|
|
22
|
-
import "../chunks/chunk-WQFG7PAH.js";
|
|
23
|
-
import "../chunks/chunk-QB2LNO4W.js";
|
|
24
|
-
import "../chunks/chunk-X754AHS5.js";
|
|
25
|
-
import "../chunks/chunk-O3NAGJP4.js";
|
|
26
|
-
import "../chunks/chunk-JGWFTO6P.js";
|
|
27
|
-
import "../chunks/chunk-AZQYF6KE.js";
|
|
28
|
-
import "../chunks/chunk-UB44F4Z2.js";
|
|
29
|
-
import "../chunks/chunk-YBLHKYFF.js";
|
|
30
|
-
import "../chunks/chunk-KSBZ2L7C.js";
|
|
31
|
-
|
|
32
|
-
// entries/server-router.tsx
|
|
33
|
-
await migrateTemplatesDirectory();
|
|
34
|
-
var pageCache = new PageCache();
|
|
35
|
-
var pageProvider = new FileSystemPageProvider(projectPaths.pages(), projectPaths.templates());
|
|
36
|
-
var pageService = new PageService(pageCache, pageProvider);
|
|
37
|
-
var componentService = new ComponentService();
|
|
38
|
-
var wsManager = new WebSocketManager();
|
|
39
|
-
var cmsProvider = new FileSystemCMSProvider(projectPaths.templates(), projectPaths.cms());
|
|
40
|
-
var cmsService = new CMSService(cmsProvider, { previewMode: true });
|
|
41
|
-
var fileWatcherService = new FileWatcherService(
|
|
42
|
-
componentService,
|
|
43
|
-
pageService,
|
|
44
|
-
pageCache,
|
|
45
|
-
wsManager,
|
|
46
|
-
cmsService
|
|
47
|
-
);
|
|
48
|
-
async function initialize() {
|
|
49
|
-
await configService.load();
|
|
50
|
-
await loadProjectConfig();
|
|
51
|
-
await componentService.loadAllComponents();
|
|
52
|
-
await pageService.loadAllPages();
|
|
53
|
-
await cmsService.initialize();
|
|
54
|
-
fileWatcherService.initialize();
|
|
55
|
-
}
|
|
56
|
-
await initialize();
|
|
57
|
-
var { server, port } = await createServer({
|
|
58
|
-
pageService,
|
|
59
|
-
componentService,
|
|
60
|
-
wsManager,
|
|
61
|
-
cmsService,
|
|
62
|
-
cmsProvider
|
|
63
|
-
});
|
|
64
|
-
console.log(`Server with routing and HMR running at http://localhost:${port}`);
|
|
65
|
-
console.log(`Available pages:`, pageService.getAllPagePaths());
|
|
66
|
-
console.log(`Edit any JSON file to see instant hot reloading!`);
|
|
67
|
-
//# sourceMappingURL=server-router.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../entries/server-router.tsx"],
|
|
4
|
-
"sourcesContent": ["/**\n * Server Router\n * Main entry point for the development server\n * Uses the createServer factory with all services initialized\n */\n\nimport { PageCache } from '../lib/server/pageCache';\nimport { WebSocketManager } from '../lib/server/websocketManager';\nimport { PageService, ComponentService, FileWatcherService } from '../lib/server/services';\nimport { CMSService } from '../lib/server/services/cmsService';\nimport { createServer } from '../lib/server/createServer';\nimport { loadProjectConfig } from '../lib/shared/fontLoader';\nimport { FileSystemPageProvider } from '../lib/server/providers/fileSystemPageProvider';\nimport { FileSystemCMSProvider } from '../lib/server/providers/fileSystemCMSProvider';\nimport { configService } from '../lib/server/services/configService';\nimport { projectPaths } from '../lib/server/projectContext';\nimport { migrateTemplatesDirectory } from '../lib/server/migrateTemplates';\n\n// Auto-migrate pages/templates/ \u2192 templates/ if needed\nawait migrateTemplatesDirectory();\n\n// Initialize services\nconst pageCache = new PageCache();\nconst pageProvider = new FileSystemPageProvider(projectPaths.pages(), projectPaths.templates());\nconst pageService = new PageService(pageCache, pageProvider);\nconst componentService = new ComponentService();\nconst wsManager = new WebSocketManager();\n\n// Initialize CMS services. The service runs in preview mode so SSR-facing\n// reads merge drafts over published content \u2014 the localhost dev runtime\n// reflects unpublished edits. Production builds (build-static / build-astro\n// / Webflow export) construct the service without the flag and only ever\n// serve published content.\nconst cmsProvider = new FileSystemCMSProvider(projectPaths.templates(), projectPaths.cms());\nconst cmsService = new CMSService(cmsProvider, { previewMode: true });\n\n// Initialize file watcher with CMS service for template change detection\nconst fileWatcherService = new FileWatcherService(\n componentService,\n pageService,\n pageCache,\n wsManager,\n cmsService\n);\n\n// Initialize server data\nasync function initialize() {\n // Load centralized config first\n await configService.load();\n\n // Load project config for fonts (uses legacy loader for now)\n await loadProjectConfig();\n\n // Load global components first\n await componentService.loadAllComponents();\n\n // Load all pages\n await pageService.loadAllPages();\n\n // Initialize CMS service (extract schemas from pages)\n await cmsService.initialize();\n\n // Setup file watchers\n fileWatcherService.initialize();\n}\n\n// Initialize before starting server\nawait initialize();\n\n// Create and start server using the factory\nconst { server, port } = await createServer({\n pageService,\n componentService,\n wsManager,\n cmsService,\n cmsProvider,\n});\n\nconsole.log(`Server with routing and HMR running at http://localhost:${port}`);\nconsole.log(`Available pages:`, pageService.getAllPagePaths());\nconsole.log(`Edit any JSON file to see instant hot reloading!`);\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmBA,MAAM,0BAA0B;AAGhC,IAAM,YAAY,IAAI,UAAU;AAChC,IAAM,eAAe,IAAI,uBAAuB,aAAa,MAAM,GAAG,aAAa,UAAU,CAAC;AAC9F,IAAM,cAAc,IAAI,YAAY,WAAW,YAAY;AAC3D,IAAM,mBAAmB,IAAI,iBAAiB;AAC9C,IAAM,YAAY,IAAI,iBAAiB;AAOvC,IAAM,cAAc,IAAI,sBAAsB,aAAa,UAAU,GAAG,aAAa,IAAI,CAAC;AAC1F,IAAM,aAAa,IAAI,WAAW,aAAa,EAAE,aAAa,KAAK,CAAC;AAGpE,IAAM,qBAAqB,IAAI;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGA,eAAe,aAAa;AAE1B,QAAM,cAAc,KAAK;AAGzB,QAAM,kBAAkB;AAGxB,QAAM,iBAAiB,kBAAkB;AAGzC,QAAM,YAAY,aAAa;AAG/B,QAAM,WAAW,WAAW;AAG5B,qBAAmB,WAAW;AAChC;AAGA,MAAM,WAAW;AAGjB,IAAM,EAAE,QAAQ,KAAK,IAAI,MAAM,aAAa;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,QAAQ,IAAI,2DAA2D,IAAI,EAAE;AAC7E,QAAQ,IAAI,oBAAoB,YAAY,gBAAgB,CAAC;AAC7D,QAAQ,IAAI,kDAAkD;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Server Router
|
|
3
|
-
* Main entry point for the development server
|
|
4
|
-
* Uses the createServer factory with all services initialized
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { PageCache } from '../lib/server/pageCache';
|
|
8
|
-
import { WebSocketManager } from '../lib/server/websocketManager';
|
|
9
|
-
import { PageService, ComponentService, FileWatcherService } from '../lib/server/services';
|
|
10
|
-
import { CMSService } from '../lib/server/services/cmsService';
|
|
11
|
-
import { createServer } from '../lib/server/createServer';
|
|
12
|
-
import { loadProjectConfig } from '../lib/shared/fontLoader';
|
|
13
|
-
import { FileSystemPageProvider } from '../lib/server/providers/fileSystemPageProvider';
|
|
14
|
-
import { FileSystemCMSProvider } from '../lib/server/providers/fileSystemCMSProvider';
|
|
15
|
-
import { configService } from '../lib/server/services/configService';
|
|
16
|
-
import { projectPaths } from '../lib/server/projectContext';
|
|
17
|
-
import { migrateTemplatesDirectory } from '../lib/server/migrateTemplates';
|
|
18
|
-
|
|
19
|
-
// Auto-migrate pages/templates/ → templates/ if needed
|
|
20
|
-
await migrateTemplatesDirectory();
|
|
21
|
-
|
|
22
|
-
// Initialize services
|
|
23
|
-
const pageCache = new PageCache();
|
|
24
|
-
const pageProvider = new FileSystemPageProvider(projectPaths.pages(), projectPaths.templates());
|
|
25
|
-
const pageService = new PageService(pageCache, pageProvider);
|
|
26
|
-
const componentService = new ComponentService();
|
|
27
|
-
const wsManager = new WebSocketManager();
|
|
28
|
-
|
|
29
|
-
// Initialize CMS services. The service runs in preview mode so SSR-facing
|
|
30
|
-
// reads merge drafts over published content — the localhost dev runtime
|
|
31
|
-
// reflects unpublished edits. Production builds (build-static / build-astro
|
|
32
|
-
// / Webflow export) construct the service without the flag and only ever
|
|
33
|
-
// serve published content.
|
|
34
|
-
const cmsProvider = new FileSystemCMSProvider(projectPaths.templates(), projectPaths.cms());
|
|
35
|
-
const cmsService = new CMSService(cmsProvider, { previewMode: true });
|
|
36
|
-
|
|
37
|
-
// Initialize file watcher with CMS service for template change detection
|
|
38
|
-
const fileWatcherService = new FileWatcherService(
|
|
39
|
-
componentService,
|
|
40
|
-
pageService,
|
|
41
|
-
pageCache,
|
|
42
|
-
wsManager,
|
|
43
|
-
cmsService
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
// Initialize server data
|
|
47
|
-
async function initialize() {
|
|
48
|
-
// Load centralized config first
|
|
49
|
-
await configService.load();
|
|
50
|
-
|
|
51
|
-
// Load project config for fonts (uses legacy loader for now)
|
|
52
|
-
await loadProjectConfig();
|
|
53
|
-
|
|
54
|
-
// Load global components first
|
|
55
|
-
await componentService.loadAllComponents();
|
|
56
|
-
|
|
57
|
-
// Load all pages
|
|
58
|
-
await pageService.loadAllPages();
|
|
59
|
-
|
|
60
|
-
// Initialize CMS service (extract schemas from pages)
|
|
61
|
-
await cmsService.initialize();
|
|
62
|
-
|
|
63
|
-
// Setup file watchers
|
|
64
|
-
fileWatcherService.initialize();
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Initialize before starting server
|
|
68
|
-
await initialize();
|
|
69
|
-
|
|
70
|
-
// Create and start server using the factory
|
|
71
|
-
const { server, port } = await createServer({
|
|
72
|
-
pageService,
|
|
73
|
-
componentService,
|
|
74
|
-
wsManager,
|
|
75
|
-
cmsService,
|
|
76
|
-
cmsProvider,
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
console.log(`Server with routing and HMR running at http://localhost:${port}`);
|
|
80
|
-
console.log(`Available pages:`, pageService.getAllPagePaths());
|
|
81
|
-
console.log(`Edit any JSON file to see instant hot reloading!`);
|