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
package/dist/bin/cli.js
CHANGED
|
@@ -1,25 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
} from "../chunks/chunk-
|
|
3
|
+
syncNetlifyLocale404Block
|
|
4
|
+
} from "../chunks/chunk-2AR55GYH.js";
|
|
5
5
|
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
} from "../chunks/chunk-I7YIGZXT.js";
|
|
9
|
-
import {
|
|
10
|
-
fileExists,
|
|
11
|
-
serveFile
|
|
12
|
-
} from "../chunks/chunk-WQFG7PAH.js";
|
|
6
|
+
migrateI18nConfig
|
|
7
|
+
} from "../chunks/chunk-4ZRU52J2.js";
|
|
13
8
|
import "../chunks/chunk-KSBZ2L7C.js";
|
|
14
9
|
|
|
15
10
|
// bin/cli.ts
|
|
16
|
-
import { resolve, join } from "path";
|
|
17
|
-
import { existsSync, mkdirSync, writeFileSync, cpSync
|
|
11
|
+
import { resolve, join } from "node:path";
|
|
12
|
+
import { existsSync, mkdirSync, writeFileSync, cpSync } from "node:fs";
|
|
18
13
|
var args = process.argv.slice(2);
|
|
19
14
|
var command = args[0];
|
|
20
15
|
function printHelp() {
|
|
21
16
|
console.log(`
|
|
22
|
-
meno - Visual editor for
|
|
17
|
+
meno - Visual editor for websites (meno-astro)
|
|
23
18
|
|
|
24
19
|
Requirements:
|
|
25
20
|
- Bun or Node.js 18+
|
|
@@ -28,144 +23,19 @@ Usage:
|
|
|
28
23
|
meno <command> [options]
|
|
29
24
|
|
|
30
25
|
Commands:
|
|
31
|
-
dev Start development server with hot reload
|
|
32
|
-
build Build static HTML files for production
|
|
33
|
-
serve Serve built files from ./dist on port 8080
|
|
34
26
|
init Initialize a new project
|
|
35
27
|
|
|
36
|
-
|
|
37
|
-
|
|
28
|
+
Note:
|
|
29
|
+
The legacy JSON runtime (dev/build/serve) has been retired. Convert a JSON
|
|
30
|
+
project to meno-astro and use the Astro toolchain instead.
|
|
38
31
|
|
|
39
32
|
Examples:
|
|
40
|
-
meno dev Start dev server in current directory
|
|
41
|
-
meno build Build static files to ./dist (excludes drafts)
|
|
42
|
-
meno build --dev Build including draft pages
|
|
43
|
-
meno serve Serve built files on port 8080
|
|
44
33
|
meno init my-project Create new project in ./my-project
|
|
45
34
|
`);
|
|
46
35
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (!existsSync(headersPath)) return headers;
|
|
51
|
-
const content = readFileSync(headersPath, "utf-8");
|
|
52
|
-
let currentPath = "";
|
|
53
|
-
for (const line of content.split("\n")) {
|
|
54
|
-
const trimmed = line.trim();
|
|
55
|
-
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
56
|
-
if (!line.startsWith(" ") && !line.startsWith(" ")) {
|
|
57
|
-
currentPath = trimmed;
|
|
58
|
-
if (!headers.has(currentPath)) {
|
|
59
|
-
headers.set(currentPath, {});
|
|
60
|
-
}
|
|
61
|
-
} else if (currentPath && trimmed.includes(":")) {
|
|
62
|
-
const colonIndex = trimmed.indexOf(":");
|
|
63
|
-
const name = trimmed.substring(0, colonIndex).trim();
|
|
64
|
-
const value = trimmed.substring(colonIndex + 1).trim();
|
|
65
|
-
headers.get(currentPath)[name] = value;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
return headers;
|
|
69
|
-
}
|
|
70
|
-
function getMatchingHeaders(pathname, headersMap) {
|
|
71
|
-
const result = {};
|
|
72
|
-
headersMap.forEach((headers, pattern) => {
|
|
73
|
-
if (pattern === pathname || pattern === "/*") {
|
|
74
|
-
Object.assign(result, headers);
|
|
75
|
-
} else if (pattern.endsWith("/*")) {
|
|
76
|
-
const prefix = pattern.slice(0, -1);
|
|
77
|
-
if (pathname.startsWith(prefix)) {
|
|
78
|
-
Object.assign(result, headers);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
return result;
|
|
83
|
-
}
|
|
84
|
-
async function startStaticServer(distPath) {
|
|
85
|
-
const { SERVE_PORT } = await import("../chunks/constants-STK2YBIW.js");
|
|
86
|
-
const headersMap = parseHeadersFile(distPath);
|
|
87
|
-
const server = await createRuntimeServer({
|
|
88
|
-
port: SERVE_PORT,
|
|
89
|
-
hostname: "localhost",
|
|
90
|
-
async fetch(req) {
|
|
91
|
-
const url = new URL(req.url);
|
|
92
|
-
let pathname = url.pathname;
|
|
93
|
-
if (pathname !== "/_errors.json") {
|
|
94
|
-
const errorsPath = join(distPath, "_errors.json");
|
|
95
|
-
if (existsSync(errorsPath)) {
|
|
96
|
-
try {
|
|
97
|
-
const errorsData = JSON.parse(readFileSync(errorsPath, "utf-8"));
|
|
98
|
-
return new Response(generateBuildErrorPage(errorsData), {
|
|
99
|
-
headers: { "Content-Type": "text/html; charset=utf-8" }
|
|
100
|
-
});
|
|
101
|
-
} catch {
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
if (pathname === "/") {
|
|
106
|
-
pathname = "/index.html";
|
|
107
|
-
}
|
|
108
|
-
const customHeaders = getMatchingHeaders(pathname, headersMap);
|
|
109
|
-
const filePath = join(distPath, pathname);
|
|
110
|
-
if (await fileExists(filePath)) {
|
|
111
|
-
return await serveFile(filePath, customHeaders);
|
|
112
|
-
}
|
|
113
|
-
const htmlPath = filePath.endsWith(".html") ? filePath : `${filePath}.html`;
|
|
114
|
-
if (await fileExists(htmlPath)) {
|
|
115
|
-
return await serveFile(htmlPath, customHeaders);
|
|
116
|
-
}
|
|
117
|
-
const indexPath = join(filePath, "index.html");
|
|
118
|
-
if (await fileExists(indexPath)) {
|
|
119
|
-
return await serveFile(indexPath, customHeaders);
|
|
120
|
-
}
|
|
121
|
-
return new Response("Not Found", { status: 404 });
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
return server;
|
|
125
|
-
}
|
|
126
|
-
async function runDev() {
|
|
127
|
-
const projectRoot = process.cwd();
|
|
128
|
-
if (!existsSync(join(projectRoot, "pages"))) {
|
|
129
|
-
console.error("\u274C No pages directory found. Are you in a valid project directory?");
|
|
130
|
-
console.error(' Run "meno init <project-name>" to create a new project.');
|
|
131
|
-
process.exit(1);
|
|
132
|
-
}
|
|
133
|
-
setProjectRoot(projectRoot);
|
|
134
|
-
console.log(`\u{1F4C1} Project root: ${projectRoot}`);
|
|
135
|
-
const distPath = join(projectRoot, "dist");
|
|
136
|
-
if (existsSync(distPath)) {
|
|
137
|
-
const staticServer = await startStaticServer(distPath);
|
|
138
|
-
console.log(`\u{1F680} Static server running at http://localhost:${staticServer.port}`);
|
|
139
|
-
}
|
|
140
|
-
await import("../entries/server-router.js");
|
|
141
|
-
}
|
|
142
|
-
async function runBuild(isDev = false) {
|
|
143
|
-
const projectRoot = process.cwd();
|
|
144
|
-
if (!existsSync(join(projectRoot, "pages"))) {
|
|
145
|
-
console.error("\u274C No pages directory found. Are you in a valid project directory?");
|
|
146
|
-
process.exit(1);
|
|
147
|
-
}
|
|
148
|
-
setProjectRoot(projectRoot);
|
|
149
|
-
if (isDev) {
|
|
150
|
-
process.env.MENO_DEV_BUILD = "true";
|
|
151
|
-
}
|
|
152
|
-
console.log(`\u{1F4C1} Building project: ${projectRoot}${isDev ? " (dev mode - including drafts)" : ""}`);
|
|
153
|
-
const { buildStaticPages } = await import("../build-static.js");
|
|
154
|
-
await buildStaticPages();
|
|
155
|
-
}
|
|
156
|
-
async function runServe() {
|
|
157
|
-
const projectRoot = process.cwd();
|
|
158
|
-
const distPath = join(projectRoot, "dist");
|
|
159
|
-
if (!existsSync(distPath)) {
|
|
160
|
-
console.error('\u274C No dist directory found. Run "meno build" first.');
|
|
161
|
-
process.exit(1);
|
|
162
|
-
}
|
|
163
|
-
console.log(`\u{1F4C1} Serving built files from: ${distPath}`);
|
|
164
|
-
const server = await startStaticServer(distPath);
|
|
165
|
-
console.log(`\u{1F680} Static server running at http://localhost:${server.port}`);
|
|
166
|
-
await new Promise(() => {
|
|
167
|
-
});
|
|
168
|
-
}
|
|
36
|
+
var RETIRED_NOTICE = `The legacy JSON "${command}" command has been retired.
|
|
37
|
+
Meno targets Astro exclusively now. Convert this project to meno-astro and use the
|
|
38
|
+
Astro toolchain instead (open it in @meno/studio, or run "astro dev" / "astro build").`;
|
|
169
39
|
async function runInit(projectName) {
|
|
170
40
|
if (!projectName) {
|
|
171
41
|
console.error("\u274C Please provide a project name: meno init <project-name>");
|
|
@@ -190,10 +60,7 @@ async function runInit(projectName) {
|
|
|
190
60
|
theme: "dark"
|
|
191
61
|
}
|
|
192
62
|
};
|
|
193
|
-
writeFileSync(
|
|
194
|
-
join(projectPath, "project.config.json"),
|
|
195
|
-
JSON.stringify(defaultConfig, null, 2)
|
|
196
|
-
);
|
|
63
|
+
writeFileSync(join(projectPath, "project.config.json"), JSON.stringify(defaultConfig, null, 2));
|
|
197
64
|
const defaultColors = {
|
|
198
65
|
default: "light",
|
|
199
66
|
themes: {
|
|
@@ -206,10 +73,7 @@ async function runInit(projectName) {
|
|
|
206
73
|
}
|
|
207
74
|
}
|
|
208
75
|
};
|
|
209
|
-
writeFileSync(
|
|
210
|
-
join(projectPath, "colors.json"),
|
|
211
|
-
JSON.stringify(defaultColors, null, 2)
|
|
212
|
-
);
|
|
76
|
+
writeFileSync(join(projectPath, "colors.json"), JSON.stringify(defaultColors, null, 2));
|
|
213
77
|
const packageJson = {
|
|
214
78
|
name: projectName,
|
|
215
79
|
version: "1.0.0",
|
|
@@ -222,12 +86,18 @@ async function runInit(projectName) {
|
|
|
222
86
|
"meno-core": "^1.0.0"
|
|
223
87
|
}
|
|
224
88
|
};
|
|
225
|
-
writeFileSync(
|
|
226
|
-
join(projectPath, "package.json"),
|
|
227
|
-
JSON.stringify(packageJson, null, 2)
|
|
228
|
-
);
|
|
89
|
+
writeFileSync(join(projectPath, "package.json"), JSON.stringify(packageJson, null, 2));
|
|
229
90
|
mkdirSync(join(projectPath, ".claude", "tools"), { recursive: true });
|
|
230
|
-
const screenshotToolSrc = join(
|
|
91
|
+
const screenshotToolSrc = join(
|
|
92
|
+
import.meta.dirname,
|
|
93
|
+
"..",
|
|
94
|
+
"..",
|
|
95
|
+
"..",
|
|
96
|
+
"example",
|
|
97
|
+
".claude",
|
|
98
|
+
"tools",
|
|
99
|
+
"screenshot.mjs"
|
|
100
|
+
);
|
|
231
101
|
if (existsSync(screenshotToolSrc)) {
|
|
232
102
|
cpSync(screenshotToolSrc, join(projectPath, ".claude", "tools", "screenshot.mjs"));
|
|
233
103
|
}
|
|
@@ -259,30 +129,26 @@ dist/
|
|
|
259
129
|
# OS files
|
|
260
130
|
.DS_Store
|
|
261
131
|
`;
|
|
262
|
-
writeFileSync(
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
);
|
|
266
|
-
const netlifyConfig = `[build]
|
|
132
|
+
writeFileSync(join(projectPath, ".gitignore"), gitignore);
|
|
133
|
+
const netlifyConfig = syncNetlifyLocale404Block(
|
|
134
|
+
`[build]
|
|
267
135
|
command = "bun install && bun run build"
|
|
268
136
|
publish = "dist"
|
|
269
137
|
|
|
270
138
|
[build.environment]
|
|
271
139
|
BUN_VERSION = "1"
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
140
|
+
`,
|
|
141
|
+
migrateI18nConfig(defaultConfig.i18n),
|
|
142
|
+
false
|
|
143
|
+
// the scaffold ships pages/index.json only — no 404 page
|
|
276
144
|
);
|
|
145
|
+
writeFileSync(join(projectPath, "netlify.toml"), netlifyConfig);
|
|
277
146
|
const vercelConfig = {
|
|
278
147
|
buildCommand: "bun run build",
|
|
279
148
|
outputDirectory: "dist",
|
|
280
149
|
installCommand: "bun install"
|
|
281
150
|
};
|
|
282
|
-
writeFileSync(
|
|
283
|
-
join(projectPath, "vercel.json"),
|
|
284
|
-
JSON.stringify(vercelConfig, null, 2)
|
|
285
|
-
);
|
|
151
|
+
writeFileSync(join(projectPath, "vercel.json"), JSON.stringify(vercelConfig, null, 2));
|
|
286
152
|
const cloudflareConfig = `name = "${projectName}"
|
|
287
153
|
compatibility_date = "2024-01-01"
|
|
288
154
|
pages_build_output_dir = "dist"
|
|
@@ -290,10 +156,7 @@ pages_build_output_dir = "dist"
|
|
|
290
156
|
[build]
|
|
291
157
|
command = "bun install && bun run build"
|
|
292
158
|
`;
|
|
293
|
-
writeFileSync(
|
|
294
|
-
join(projectPath, "wrangler.toml"),
|
|
295
|
-
cloudflareConfig
|
|
296
|
-
);
|
|
159
|
+
writeFileSync(join(projectPath, "wrangler.toml"), cloudflareConfig);
|
|
297
160
|
const defaultPage = {
|
|
298
161
|
meta: {
|
|
299
162
|
title: "Your Project Title",
|
|
@@ -325,10 +188,7 @@ command = "bun install && bun run build"
|
|
|
325
188
|
]
|
|
326
189
|
}
|
|
327
190
|
};
|
|
328
|
-
writeFileSync(
|
|
329
|
-
join(projectPath, "pages", "index.json"),
|
|
330
|
-
JSON.stringify(defaultPage, null, 2)
|
|
331
|
-
);
|
|
191
|
+
writeFileSync(join(projectPath, "pages", "index.json"), JSON.stringify(defaultPage, null, 2));
|
|
332
192
|
console.log("\u2705 Created project structure:");
|
|
333
193
|
console.log(` ${projectName}/`);
|
|
334
194
|
console.log(" \u251C\u2500\u2500 .claude/");
|
|
@@ -362,17 +222,14 @@ command = "bun install && bun run build"
|
|
|
362
222
|
console.log("");
|
|
363
223
|
}
|
|
364
224
|
switch (command) {
|
|
365
|
-
case "
|
|
366
|
-
|
|
225
|
+
case "init":
|
|
226
|
+
runInit(args[1]);
|
|
367
227
|
break;
|
|
228
|
+
case "dev":
|
|
368
229
|
case "build":
|
|
369
|
-
runBuild(args.includes("--dev"));
|
|
370
|
-
break;
|
|
371
230
|
case "serve":
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
case "init":
|
|
375
|
-
runInit(args[1]);
|
|
231
|
+
console.error(RETIRED_NOTICE);
|
|
232
|
+
process.exit(1);
|
|
376
233
|
break;
|
|
377
234
|
case "--help":
|
|
378
235
|
case "-h":
|
package/dist/bin/cli.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../bin/cli.ts"],
|
|
4
|
-
"sourcesContent": ["#!/usr/bin/env node\n/**\n * meno CLI\n * Commands: dev, build, init\n */\n\nimport { resolve, join } from 'path';\nimport { existsSync, mkdirSync, writeFileSync, cpSync, readFileSync } from 'fs';\nimport { setProjectRoot } from '../lib/server/projectContext';\nimport { generateBuildErrorPage, type BuildErrorsData } from '../lib/server/ssr/buildErrorOverlay';\nimport { createRuntimeServer, serveFile, fileExists as runtimeFileExists } from '../lib/server/runtime';\n\nconst args = process.argv.slice(2);\nconst command = args[0];\n\nfunction printHelp() {\n console.log(`\nmeno - Visual editor for JSON-based pages\n\nRequirements:\n - Bun or Node.js 18+\n\nUsage:\n meno <command> [options]\n\nCommands:\n dev Start development server with hot reload\n build Build static HTML files for production\n serve Serve built files from ./dist on port 8080\n init Initialize a new project\n\nOptions:\n build --dev Include draft pages in build (for local preview)\n\nExamples:\n meno dev Start dev server in current directory\n meno build Build static files to ./dist (excludes drafts)\n meno build --dev Build including draft pages\n meno serve Serve built files on port 8080\n meno init my-project Create new project in ./my-project\n`);\n}\n\n// Parse _headers file (Netlify/Cloudflare format)\nfunction parseHeadersFile(distPath: string): Map<string, Record<string, string>> {\n const headersPath = join(distPath, '_headers');\n const headers = new Map<string, Record<string, string>>();\n\n if (!existsSync(headersPath)) return headers;\n\n const content = readFileSync(headersPath, 'utf-8');\n let currentPath = '';\n\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n\n if (!line.startsWith(' ') && !line.startsWith('\\t')) {\n // Path line\n currentPath = trimmed;\n if (!headers.has(currentPath)) {\n headers.set(currentPath, {});\n }\n } else if (currentPath && trimmed.includes(':')) {\n // Header line\n const colonIndex = trimmed.indexOf(':');\n const name = trimmed.substring(0, colonIndex).trim();\n const value = trimmed.substring(colonIndex + 1).trim();\n headers.get(currentPath)![name] = value;\n }\n }\n\n return headers;\n}\n\n// Get headers matching a pathname\nfunction getMatchingHeaders(\n pathname: string,\n headersMap: Map<string, Record<string, string>>\n): Record<string, string> {\n const result: Record<string, string> = {};\n\n headersMap.forEach((headers, pattern) => {\n if (pattern === pathname || pattern === '/*') {\n Object.assign(result, headers);\n } else if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -1);\n if (pathname.startsWith(prefix)) {\n Object.assign(result, headers);\n }\n }\n });\n\n return result;\n}\n\n// Start static file server on port 8080 (non-blocking)\nasync function startStaticServer(distPath: string) {\n const { SERVE_PORT } = await import('../lib/shared/constants');\n\n // Parse _headers file once on startup\n const headersMap = parseHeadersFile(distPath);\n\n const server = await createRuntimeServer({\n port: SERVE_PORT,\n hostname: 'localhost',\n async fetch(req: Request) {\n const url = new URL(req.url);\n let pathname = url.pathname;\n\n // Check for build errors and show overlay (except for _errors.json itself)\n if (pathname !== '/_errors.json') {\n const errorsPath = join(distPath, '_errors.json');\n if (existsSync(errorsPath)) {\n try {\n const errorsData: BuildErrorsData = JSON.parse(readFileSync(errorsPath, 'utf-8'));\n return new Response(generateBuildErrorPage(errorsData), {\n headers: { 'Content-Type': 'text/html; charset=utf-8' },\n });\n } catch {\n // If we can't parse errors file, continue normally\n }\n }\n }\n\n // Default to index.html for root\n if (pathname === '/') {\n pathname = '/index.html';\n }\n\n // Get custom headers for this path\n const customHeaders = getMatchingHeaders(pathname, headersMap);\n\n // Try to serve the file\n const filePath = join(distPath, pathname);\n\n // Check if file exists and serve it\n if (await runtimeFileExists(filePath)) {\n return await serveFile(filePath, customHeaders);\n }\n\n // Try with .html extension for clean URLs\n const htmlPath = filePath.endsWith('.html') ? filePath : `${filePath}.html`;\n if (await runtimeFileExists(htmlPath)) {\n return await serveFile(htmlPath, customHeaders);\n }\n\n // Try index.html in directory\n const indexPath = join(filePath, 'index.html');\n if (await runtimeFileExists(indexPath)) {\n return await serveFile(indexPath, customHeaders);\n }\n\n return new Response('Not Found', { status: 404 });\n },\n });\n\n return server;\n}\n\nasync function runDev() {\n const projectRoot = process.cwd();\n\n // Validate project structure\n if (!existsSync(join(projectRoot, 'pages'))) {\n console.error('\u274C No pages directory found. Are you in a valid project directory?');\n console.error(' Run \"meno init <project-name>\" to create a new project.');\n process.exit(1);\n }\n\n // Set project root for path resolution\n setProjectRoot(projectRoot);\n\n console.log(`\uD83D\uDCC1 Project root: ${projectRoot}`);\n\n // Start static server on 8080 if dist exists\n const distPath = join(projectRoot, 'dist');\n if (existsSync(distPath)) {\n const staticServer = await startStaticServer(distPath);\n console.log(`\uD83D\uDE80 Static server running at http://localhost:${staticServer.port}`);\n }\n\n // Import and run the dev server (it handles all initialization internally)\n await import('../entries/server-router');\n}\n\nasync function runBuild(isDev: boolean = false) {\n const projectRoot = process.cwd();\n\n // Validate project structure\n if (!existsSync(join(projectRoot, 'pages'))) {\n console.error('\u274C No pages directory found. Are you in a valid project directory?');\n process.exit(1);\n }\n\n // Set project root for path resolution\n setProjectRoot(projectRoot);\n\n // Set dev mode environment variable (drafts are built in dev mode)\n if (isDev) {\n process.env.MENO_DEV_BUILD = 'true';\n }\n\n console.log(`\uD83D\uDCC1 Building project: ${projectRoot}${isDev ? ' (dev mode - including drafts)' : ''}`);\n\n // Import and run build\n const { buildStaticPages } = await import('../build-static.ts');\n await buildStaticPages();\n}\n\nasync function runServe() {\n const projectRoot = process.cwd();\n const distPath = join(projectRoot, 'dist');\n\n // Validate dist directory exists\n if (!existsSync(distPath)) {\n console.error('\u274C No dist directory found. Run \"meno build\" first.');\n process.exit(1);\n }\n\n console.log(`\uD83D\uDCC1 Serving built files from: ${distPath}`);\n const server = await startStaticServer(distPath);\n console.log(`\uD83D\uDE80 Static server running at http://localhost:${server.port}`);\n\n // Keep the process alive\n await new Promise(() => {});\n}\n\nasync function runInit(projectName?: string) {\n if (!projectName) {\n console.error('\u274C Please provide a project name: meno init <project-name>');\n process.exit(1);\n }\n\n const projectPath = resolve(process.cwd(), projectName);\n\n if (existsSync(projectPath)) {\n console.error(`\u274C Directory \"${projectName}\" already exists.`);\n process.exit(1);\n }\n\n console.log(`\\n\uD83D\uDE80 Creating new meno project: ${projectName}\\n`);\n\n // Create project structure\n mkdirSync(projectPath, { recursive: true });\n mkdirSync(join(projectPath, 'pages'));\n mkdirSync(join(projectPath, 'components'));\n mkdirSync(join(projectPath, 'fonts'));\n mkdirSync(join(projectPath, 'images'));\n\n // Create default project.config.json\n const defaultConfig = {\n fonts: [],\n editor: {\n theme: 'dark'\n }\n };\n writeFileSync(\n join(projectPath, 'project.config.json'),\n JSON.stringify(defaultConfig, null, 2)\n );\n\n // Create default colors.json\n const defaultColors = {\n default: 'light',\n themes: {\n light: {\n label: 'Light',\n colors: {\n text: '#1f2937',\n bg: '#ffffff'\n }\n }\n }\n };\n writeFileSync(\n join(projectPath, 'colors.json'),\n JSON.stringify(defaultColors, null, 2)\n );\n\n // Create package.json for deployment\n const packageJson = {\n name: projectName,\n version: '1.0.0',\n private: true,\n scripts: {\n dev: 'meno dev',\n build: 'meno build',\n },\n dependencies: {\n 'meno-core': '^1.0.0'\n }\n };\n writeFileSync(\n join(projectPath, 'package.json'),\n JSON.stringify(packageJson, null, 2)\n );\n\n // Create .claude/tools/ with screenshot tool\n mkdirSync(join(projectPath, '.claude', 'tools'), { recursive: true });\n\n const screenshotToolSrc = join(import.meta.dirname, '..', '..', '..', 'example', '.claude', 'tools', 'screenshot.mjs');\n if (existsSync(screenshotToolSrc)) {\n cpSync(screenshotToolSrc, join(projectPath, '.claude', 'tools', 'screenshot.mjs'));\n }\n\n // Create CLAUDE.md with project instructions\n const claudeMd = `# ${projectName}\n\nA Meno project - visual editor that generates websites from JSON files.\n\n## Dev Server\n\n\\`\\`\\`bash\nbun run dev # Start dev server on port 3000\n\\`\\`\\`\n\n## Screenshot Tool\n\nTake a screenshot of any element by its node ID:\n\\`\\`\\`bash\nnpx puppeteer browsers install chrome && node .claude/tools/screenshot.mjs <nodeId> --page /about\n\\`\\`\\`\nNode IDs can be found in the page JSON files under the \\`id\\` field of each node.\n`;\n writeFileSync(join(projectPath, 'CLAUDE.md'), claudeMd);\n\n // Create .gitignore\n const gitignore = `# Dependencies\nnode_modules/\n\n# Build output\ndist/\n\n# OS files\n.DS_Store\n`;\n writeFileSync(\n join(projectPath, '.gitignore'),\n gitignore\n );\n\n // Create netlify.toml\n const netlifyConfig = `[build]\n command = \"bun install && bun run build\"\n publish = \"dist\"\n\n[build.environment]\n BUN_VERSION = \"1\"\n`;\n writeFileSync(\n join(projectPath, 'netlify.toml'),\n netlifyConfig\n );\n\n // Create vercel.json\n const vercelConfig = {\n buildCommand: 'bun run build',\n outputDirectory: 'dist',\n installCommand: 'bun install'\n };\n writeFileSync(\n join(projectPath, 'vercel.json'),\n JSON.stringify(vercelConfig, null, 2)\n );\n\n // Create wrangler.toml for Cloudflare Pages\n const cloudflareConfig = `name = \"${projectName}\"\ncompatibility_date = \"2024-01-01\"\npages_build_output_dir = \"dist\"\n\n[build]\ncommand = \"bun install && bun run build\"\n`;\n writeFileSync(\n join(projectPath, 'wrangler.toml'),\n cloudflareConfig\n );\n\n // Create default index page\n const defaultPage = {\n meta: {\n title: 'Your Project Title',\n description: 'Your Project Description',\n keywords: '',\n ogTitle: 'Your Project Title',\n ogDescription: 'Your Project Description',\n ogType: 'website'\n },\n root: {\n type: 'node',\n tag: 'div',\n style: {\n base: {\n padding: '40px'\n },\n tablet: {},\n mobile: {}\n },\n children: [\n {\n type: 'node',\n tag: 'h1',\n style: {\n base: {}\n },\n children: 'Hello'\n }\n ]\n }\n };\n writeFileSync(\n join(projectPath, 'pages', 'index.json'),\n JSON.stringify(defaultPage, null, 2)\n );\n\n console.log('\u2705 Created project structure:');\n console.log(` ${projectName}/`);\n console.log(' \u251C\u2500\u2500 .claude/');\n console.log(' \u2502 \u2514\u2500\u2500 tools/');\n console.log(' \u2502 \u2514\u2500\u2500 screenshot.mjs');\n console.log(' \u251C\u2500\u2500 pages/');\n console.log(' \u2502 \u2514\u2500\u2500 index.json');\n console.log(' \u251C\u2500\u2500 components/');\n console.log(' \u251C\u2500\u2500 fonts/');\n console.log(' \u251C\u2500\u2500 images/');\n console.log(' \u251C\u2500\u2500 colors.json');\n console.log(' \u251C\u2500\u2500 project.config.json');\n console.log(' \u251C\u2500\u2500 package.json');\n console.log(' \u251C\u2500\u2500 CLAUDE.md');\n console.log(' \u251C\u2500\u2500 netlify.toml');\n console.log(' \u251C\u2500\u2500 vercel.json');\n console.log(' \u251C\u2500\u2500 wrangler.toml');\n console.log(' \u2514\u2500\u2500 .gitignore');\n console.log('\\n\uD83C\uDF89 Project created successfully!\\n');\n console.log('Requirements:');\n console.log(' Bun - https://bun.sh');\n console.log('');\n console.log('Next steps:');\n console.log(` cd ${projectName}`);\n console.log(' bun install # Install dependencies');\n console.log(' bun run dev # Start dev server');\n console.log('');\n console.log('Deploy:');\n console.log(' Push to GitHub and connect to Netlify/Vercel/Cloudflare');\n console.log(' Config files included - auto-detected!');\n console.log('');\n}\n\n// Main\nswitch (command) {\n case 'dev':\n runDev();\n break;\n case 'build':\n runBuild(args.includes('--dev'));\n break;\n case 'serve':\n runServe();\n break;\n case 'init':\n runInit(args[1]);\n break;\n case '--help':\n case '-h':\n case undefined:\n printHelp();\n break;\n default:\n console.error(`Unknown command: ${command}`);\n printHelp();\n process.exit(1);\n}\n"],
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["#!/usr/bin/env node\n/**\n * meno CLI\n *\n * The bespoke JSON renderer (`meno dev`/`build`/`serve`) has been retired \u2014 Meno\n * targets Astro exclusively now. The only remaining command is `init` (scaffold a\n * project). To run/build a project, convert it to meno-astro and use the Astro\n * toolchain (`@meno/studio` in the editor, or `astro dev`/`astro build`).\n */\n\nimport { resolve, join } from 'node:path';\nimport { existsSync, mkdirSync, writeFileSync, cpSync } from 'node:fs';\nimport { migrateI18nConfig } from '../lib/shared/i18n';\nimport { syncNetlifyLocale404Block } from '../lib/shared/netlifyLocale404';\n\nconst args = process.argv.slice(2);\nconst command = args[0];\n\nfunction printHelp() {\n console.log(`\nmeno - Visual editor for websites (meno-astro)\n\nRequirements:\n - Bun or Node.js 18+\n\nUsage:\n meno <command> [options]\n\nCommands:\n init Initialize a new project\n\nNote:\n The legacy JSON runtime (dev/build/serve) has been retired. Convert a JSON\n project to meno-astro and use the Astro toolchain instead.\n\nExamples:\n meno init my-project Create new project in ./my-project\n`);\n}\n\nconst RETIRED_NOTICE = `The legacy JSON \"${command}\" command has been retired.\nMeno targets Astro exclusively now. Convert this project to meno-astro and use the\nAstro toolchain instead (open it in @meno/studio, or run \"astro dev\" / \"astro build\").`;\n\nasync function runInit(projectName?: string) {\n if (!projectName) {\n console.error('\u274C Please provide a project name: meno init <project-name>');\n process.exit(1);\n }\n\n const projectPath = resolve(process.cwd(), projectName);\n\n if (existsSync(projectPath)) {\n console.error(`\u274C Directory \"${projectName}\" already exists.`);\n process.exit(1);\n }\n\n console.log(`\\n\uD83D\uDE80 Creating new meno project: ${projectName}\\n`);\n\n // Create project structure\n mkdirSync(projectPath, { recursive: true });\n mkdirSync(join(projectPath, 'pages'));\n mkdirSync(join(projectPath, 'components'));\n mkdirSync(join(projectPath, 'fonts'));\n mkdirSync(join(projectPath, 'images'));\n\n // Create default project.config.json\n const defaultConfig = {\n fonts: [],\n editor: {\n theme: 'dark',\n },\n };\n writeFileSync(join(projectPath, 'project.config.json'), JSON.stringify(defaultConfig, null, 2));\n\n // Create default colors.json\n const defaultColors = {\n default: 'light',\n themes: {\n light: {\n label: 'Light',\n colors: {\n text: '#1f2937',\n bg: '#ffffff',\n },\n },\n },\n };\n writeFileSync(join(projectPath, 'colors.json'), JSON.stringify(defaultColors, null, 2));\n\n // Create package.json for deployment\n const packageJson = {\n name: projectName,\n version: '1.0.0',\n private: true,\n scripts: {\n dev: 'meno dev',\n build: 'meno build',\n },\n dependencies: {\n 'meno-core': '^1.0.0',\n },\n };\n writeFileSync(join(projectPath, 'package.json'), JSON.stringify(packageJson, null, 2));\n\n // Create .claude/tools/ with screenshot tool\n mkdirSync(join(projectPath, '.claude', 'tools'), { recursive: true });\n\n const screenshotToolSrc = join(\n import.meta.dirname,\n '..',\n '..',\n '..',\n 'example',\n '.claude',\n 'tools',\n 'screenshot.mjs',\n );\n if (existsSync(screenshotToolSrc)) {\n cpSync(screenshotToolSrc, join(projectPath, '.claude', 'tools', 'screenshot.mjs'));\n }\n\n // Create CLAUDE.md with project instructions\n const claudeMd = `# ${projectName}\n\nA Meno project - visual editor that generates websites from JSON files.\n\n## Dev Server\n\n\\`\\`\\`bash\nbun run dev # Start dev server on port 3000\n\\`\\`\\`\n\n## Screenshot Tool\n\nTake a screenshot of any element by its node ID:\n\\`\\`\\`bash\nnpx puppeteer browsers install chrome && node .claude/tools/screenshot.mjs <nodeId> --page /about\n\\`\\`\\`\nNode IDs can be found in the page JSON files under the \\`id\\` field of each node.\n`;\n writeFileSync(join(projectPath, 'CLAUDE.md'), claudeMd);\n\n // Create .gitignore\n const gitignore = `# Dependencies\nnode_modules/\n\n# Build output\ndist/\n\n# OS files\n.DS_Store\n`;\n writeFileSync(join(projectPath, '.gitignore'), gitignore);\n\n // Create netlify.toml. Routed through the shared locale-404 sync for uniformity\n // with the other netlify.toml producers \u2014 a no-op here (new projects are\n // single-locale with no 404 page), but the managed block appears automatically\n // if this scaffold ever grows locales/404 defaults.\n const netlifyConfig = syncNetlifyLocale404Block(\n `[build]\n command = \"bun install && bun run build\"\n publish = \"dist\"\n\n[build.environment]\n BUN_VERSION = \"1\"\n`,\n migrateI18nConfig((defaultConfig as { i18n?: unknown }).i18n),\n false, // the scaffold ships pages/index.json only \u2014 no 404 page\n );\n writeFileSync(join(projectPath, 'netlify.toml'), netlifyConfig);\n\n // Create vercel.json\n const vercelConfig = {\n buildCommand: 'bun run build',\n outputDirectory: 'dist',\n installCommand: 'bun install',\n };\n writeFileSync(join(projectPath, 'vercel.json'), JSON.stringify(vercelConfig, null, 2));\n\n // Create wrangler.toml for Cloudflare Pages\n const cloudflareConfig = `name = \"${projectName}\"\ncompatibility_date = \"2024-01-01\"\npages_build_output_dir = \"dist\"\n\n[build]\ncommand = \"bun install && bun run build\"\n`;\n writeFileSync(join(projectPath, 'wrangler.toml'), cloudflareConfig);\n\n // Create default index page\n const defaultPage = {\n meta: {\n title: 'Your Project Title',\n description: 'Your Project Description',\n keywords: '',\n ogTitle: 'Your Project Title',\n ogDescription: 'Your Project Description',\n ogType: 'website',\n },\n root: {\n type: 'node',\n tag: 'div',\n style: {\n base: {\n padding: '40px',\n },\n tablet: {},\n mobile: {},\n },\n children: [\n {\n type: 'node',\n tag: 'h1',\n style: {\n base: {},\n },\n children: 'Hello',\n },\n ],\n },\n };\n writeFileSync(join(projectPath, 'pages', 'index.json'), JSON.stringify(defaultPage, null, 2));\n\n console.log('\u2705 Created project structure:');\n console.log(` ${projectName}/`);\n console.log(' \u251C\u2500\u2500 .claude/');\n console.log(' \u2502 \u2514\u2500\u2500 tools/');\n console.log(' \u2502 \u2514\u2500\u2500 screenshot.mjs');\n console.log(' \u251C\u2500\u2500 pages/');\n console.log(' \u2502 \u2514\u2500\u2500 index.json');\n console.log(' \u251C\u2500\u2500 components/');\n console.log(' \u251C\u2500\u2500 fonts/');\n console.log(' \u251C\u2500\u2500 images/');\n console.log(' \u251C\u2500\u2500 colors.json');\n console.log(' \u251C\u2500\u2500 project.config.json');\n console.log(' \u251C\u2500\u2500 package.json');\n console.log(' \u251C\u2500\u2500 CLAUDE.md');\n console.log(' \u251C\u2500\u2500 netlify.toml');\n console.log(' \u251C\u2500\u2500 vercel.json');\n console.log(' \u251C\u2500\u2500 wrangler.toml');\n console.log(' \u2514\u2500\u2500 .gitignore');\n console.log('\\n\uD83C\uDF89 Project created successfully!\\n');\n console.log('Requirements:');\n console.log(' Bun - https://bun.sh');\n console.log('');\n console.log('Next steps:');\n console.log(` cd ${projectName}`);\n console.log(' bun install # Install dependencies');\n console.log(' bun run dev # Start dev server');\n console.log('');\n console.log('Deploy:');\n console.log(' Push to GitHub and connect to Netlify/Vercel/Cloudflare');\n console.log(' Config files included - auto-detected!');\n console.log('');\n}\n\n// Main\nswitch (command) {\n case 'init':\n runInit(args[1]);\n break;\n case 'dev':\n case 'build':\n case 'serve':\n console.error(RETIRED_NOTICE);\n process.exit(1);\n break;\n case '--help':\n case '-h':\n case undefined:\n printHelp();\n break;\n default:\n console.error(`Unknown command: ${command}`);\n printHelp();\n process.exit(1);\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;AAUA,SAAS,SAAS,YAAY;AAC9B,SAAS,YAAY,WAAW,eAAe,cAAc;AAI7D,IAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;AACjC,IAAM,UAAU,KAAK,CAAC;AAEtB,SAAS,YAAY;AACnB,UAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAkBb;AACD;AAEA,IAAM,iBAAiB,oBAAoB,OAAO;AAAA;AAAA;AAIlD,eAAe,QAAQ,aAAsB;AAC3C,MAAI,CAAC,aAAa;AAChB,YAAQ,MAAM,gEAA2D;AACzE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,cAAc,QAAQ,QAAQ,IAAI,GAAG,WAAW;AAEtD,MAAI,WAAW,WAAW,GAAG;AAC3B,YAAQ,MAAM,qBAAgB,WAAW,mBAAmB;AAC5D,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,IAAI;AAAA,uCAAmC,WAAW;AAAA,CAAI;AAG9D,YAAU,aAAa,EAAE,WAAW,KAAK,CAAC;AAC1C,YAAU,KAAK,aAAa,OAAO,CAAC;AACpC,YAAU,KAAK,aAAa,YAAY,CAAC;AACzC,YAAU,KAAK,aAAa,OAAO,CAAC;AACpC,YAAU,KAAK,aAAa,QAAQ,CAAC;AAGrC,QAAM,gBAAgB;AAAA,IACpB,OAAO,CAAC;AAAA,IACR,QAAQ;AAAA,MACN,OAAO;AAAA,IACT;AAAA,EACF;AACA,gBAAc,KAAK,aAAa,qBAAqB,GAAG,KAAK,UAAU,eAAe,MAAM,CAAC,CAAC;AAG9F,QAAM,gBAAgB;AAAA,IACpB,SAAS;AAAA,IACT,QAAQ;AAAA,MACN,OAAO;AAAA,QACL,OAAO;AAAA,QACP,QAAQ;AAAA,UACN,MAAM;AAAA,UACN,IAAI;AAAA,QACN;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,gBAAc,KAAK,aAAa,aAAa,GAAG,KAAK,UAAU,eAAe,MAAM,CAAC,CAAC;AAGtF,QAAM,cAAc;AAAA,IAClB,MAAM;AAAA,IACN,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,MACP,KAAK;AAAA,MACL,OAAO;AAAA,IACT;AAAA,IACA,cAAc;AAAA,MACZ,aAAa;AAAA,IACf;AAAA,EACF;AACA,gBAAc,KAAK,aAAa,cAAc,GAAG,KAAK,UAAU,aAAa,MAAM,CAAC,CAAC;AAGrF,YAAU,KAAK,aAAa,WAAW,OAAO,GAAG,EAAE,WAAW,KAAK,CAAC;AAEpE,QAAM,oBAAoB;AAAA,IACxB,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,WAAW,iBAAiB,GAAG;AACjC,WAAO,mBAAmB,KAAK,aAAa,WAAW,SAAS,gBAAgB,CAAC;AAAA,EACnF;AAGA,QAAM,WAAW,KAAK,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBjC,gBAAc,KAAK,aAAa,WAAW,GAAG,QAAQ;AAGtD,QAAM,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASlB,gBAAc,KAAK,aAAa,YAAY,GAAG,SAAS;AAMxD,QAAM,gBAAgB;AAAA,IACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA,kBAAmB,cAAqC,IAAI;AAAA,IAC5D;AAAA;AAAA,EACF;AACA,gBAAc,KAAK,aAAa,cAAc,GAAG,aAAa;AAG9D,QAAM,eAAe;AAAA,IACnB,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,EAClB;AACA,gBAAc,KAAK,aAAa,aAAa,GAAG,KAAK,UAAU,cAAc,MAAM,CAAC,CAAC;AAGrF,QAAM,mBAAmB,WAAW,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAO/C,gBAAc,KAAK,aAAa,eAAe,GAAG,gBAAgB;AAGlE,QAAM,cAAc;AAAA,IAClB,MAAM;AAAA,MACJ,OAAO;AAAA,MACP,aAAa;AAAA,MACb,UAAU;AAAA,MACV,SAAS;AAAA,MACT,eAAe;AAAA,MACf,QAAQ;AAAA,IACV;AAAA,IACA,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,KAAK;AAAA,MACL,OAAO;AAAA,QACL,MAAM;AAAA,UACJ,SAAS;AAAA,QACX;AAAA,QACA,QAAQ,CAAC;AAAA,QACT,QAAQ,CAAC;AAAA,MACX;AAAA,MACA,UAAU;AAAA,QACR;AAAA,UACE,MAAM;AAAA,UACN,KAAK;AAAA,UACL,OAAO;AAAA,YACL,MAAM,CAAC;AAAA,UACT;AAAA,UACA,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,gBAAc,KAAK,aAAa,SAAS,YAAY,GAAG,KAAK,UAAU,aAAa,MAAM,CAAC,CAAC;AAE5F,UAAQ,IAAI,mCAA8B;AAC1C,UAAQ,IAAI,MAAM,WAAW,GAAG;AAChC,UAAQ,IAAI,gCAAiB;AAC7B,UAAQ,IAAI,uCAAmB;AAC/B,UAAQ,IAAI,mDAA+B;AAC3C,UAAQ,IAAI,8BAAe;AAC3B,UAAQ,IAAI,2CAAuB;AACnC,UAAQ,IAAI,mCAAoB;AAChC,UAAQ,IAAI,8BAAe;AAC3B,UAAQ,IAAI,+BAAgB;AAC5B,UAAQ,IAAI,mCAAoB;AAChC,UAAQ,IAAI,2CAA4B;AACxC,UAAQ,IAAI,oCAAqB;AACjC,UAAQ,IAAI,iCAAkB;AAC9B,UAAQ,IAAI,oCAAqB;AACjC,UAAQ,IAAI,mCAAoB;AAChC,UAAQ,IAAI,qCAAsB;AAClC,UAAQ,IAAI,kCAAmB;AAC/B,UAAQ,IAAI,6CAAsC;AAClD,UAAQ,IAAI,eAAe;AAC3B,UAAQ,IAAI,yBAAyB;AACrC,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,aAAa;AACzB,UAAQ,IAAI,SAAS,WAAW,EAAE;AAClC,UAAQ,IAAI,8CAA8C;AAC1D,UAAQ,IAAI,0CAA0C;AACtD,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,SAAS;AACrB,UAAQ,IAAI,4DAA4D;AACxE,UAAQ,IAAI,2CAA2C;AACvD,UAAQ,IAAI,EAAE;AAChB;AAGA,QAAQ,SAAS;AAAA,EACf,KAAK;AACH,YAAQ,KAAK,CAAC,CAAC;AACf;AAAA,EACF,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACH,YAAQ,MAAM,cAAc;AAC5B,YAAQ,KAAK,CAAC;AACd;AAAA,EACF,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACH,cAAU;AACV;AAAA,EACF;AACE,YAAQ,MAAM,oBAAoB,OAAO,EAAE;AAC3C,cAAU;AACV,YAAQ,KAAK,CAAC;AAClB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// lib/shared/netlifyLocale404.ts
|
|
2
|
+
var NETLIFY_LOCALE_404_BEGIN = "# BEGIN meno locale-404 redirects (generated \u2014 do not edit between markers)";
|
|
3
|
+
var NETLIFY_LOCALE_404_END = "# END meno locale-404 redirects";
|
|
4
|
+
function netlifyLocale404Redirects(config) {
|
|
5
|
+
if (!config.locales || config.locales.length <= 1) return "";
|
|
6
|
+
const codes = config.locales.map((l) => l.code).filter((code) => code !== config.defaultLocale && /^[A-Za-z0-9_-]+$/.test(code));
|
|
7
|
+
if (codes.length === 0) return "";
|
|
8
|
+
const header = "\n# Locale-scoped 404s \u2014 an unmatched /<locale>/* URL serves that locale's own\n# prerendered 404 page WITH a 404 status (non-shadowing: real pages still win).\n# Unmatched URLs outside these prefixes fall through to the default /404.html.\n";
|
|
9
|
+
const rules = codes.map((code) => `[[redirects]]
|
|
10
|
+
from = "/${code}/*"
|
|
11
|
+
to = "/${code}/404/index.html"
|
|
12
|
+
status = 404
|
|
13
|
+
`).join("\n");
|
|
14
|
+
return header + rules;
|
|
15
|
+
}
|
|
16
|
+
function syncNetlifyLocale404Block(content, config, has404) {
|
|
17
|
+
const rules = has404 ? netlifyLocale404Redirects(config) : "";
|
|
18
|
+
const block = rules ? `${NETLIFY_LOCALE_404_BEGIN}${rules}${NETLIFY_LOCALE_404_END}
|
|
19
|
+
` : "";
|
|
20
|
+
const beginIdx = content.indexOf(NETLIFY_LOCALE_404_BEGIN);
|
|
21
|
+
if (beginIdx === -1) {
|
|
22
|
+
if (!block) return content;
|
|
23
|
+
const base = content === "" || content.endsWith("\n") ? content : `${content}
|
|
24
|
+
`;
|
|
25
|
+
return base + block;
|
|
26
|
+
}
|
|
27
|
+
const endMarkerIdx = content.indexOf(NETLIFY_LOCALE_404_END, beginIdx);
|
|
28
|
+
if (endMarkerIdx === -1) return content;
|
|
29
|
+
let endIdx = endMarkerIdx + NETLIFY_LOCALE_404_END.length;
|
|
30
|
+
if (content[endIdx] === "\n") endIdx += 1;
|
|
31
|
+
const before = content.slice(0, beginIdx);
|
|
32
|
+
const after = content.slice(endIdx);
|
|
33
|
+
return before + block + after;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export {
|
|
37
|
+
NETLIFY_LOCALE_404_BEGIN,
|
|
38
|
+
NETLIFY_LOCALE_404_END,
|
|
39
|
+
netlifyLocale404Redirects,
|
|
40
|
+
syncNetlifyLocale404Block
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=chunk-2AR55GYH.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../lib/shared/netlifyLocale404.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Locale-scoped Netlify 404 rules + the managed netlify.toml block that carries them.\n *\n * Why: a multi-locale static build emits a localized 404 per non-default locale\n * (`dist/pl/404/index.html`), but a static host serves exactly ONE catch-all 404\n * page unless told otherwise \u2014 so `/pl/<missing>` would get the default-locale\n * `404.html`. These rules scope the 404 per locale prefix.\n *\n * Shared by every netlify.toml producer \u2014 meno-astro's `convertProject` scaffold,\n * the JSON\u2192Astro export (`build-astro.ts`), the CLI new-project scaffold \u2014 and by\n * the studio save-config route, which re-syncs the managed block when the locale\n * set changes AFTER the file was first written (so a project that adds a locale\n * later still gets its rules). It lives in meno-core because the dependency\n * direction is astro\u2192core: meno-core must never import from meno-astro.\n */\n\nimport type { I18nConfig } from './types';\n\n/**\n * First line of the managed block. Everything between the markers (inclusive) is\n * generated and may be rewritten wholesale by `syncNetlifyLocale404Block`; user\n * content outside the markers is never touched.\n */\nexport const NETLIFY_LOCALE_404_BEGIN = '# BEGIN meno locale-404 redirects (generated \u2014 do not edit between markers)';\n\n/** Last line of the managed block. */\nexport const NETLIFY_LOCALE_404_END = '# END meno locale-404 redirects';\n\n/**\n * Locale-scoped 404 rules for a netlify.toml \u2014 one `[[redirects]]` block per\n * non-default locale (`''` for single-locale configs):\n *\n * [[redirects]]\n * from = \"/pl/*\"\n * to = \"/pl/404/index.html\"\n * status = 404\n *\n * Netlify semantics (verified against Netlify's \"redirect options\" docs, the\n * documented \"localized custom 404\" pattern): a redirect with `status = 404` and no\n * `force` is a NON-SHADOWING rewrite \u2014 a request that matches an existing file is\n * served normally (real `/pl/...` pages always win), and only an unmatched `/pl/*`\n * URL serves the `to` file's CONTENT with an HTTP 404 status (the URL stays put; no\n * 3xx). Everything the rules don't cover falls through to Netlify's root convention:\n * a top-level `404.html` (which Astro builds from `src/pages/404.astro`) is served\n * automatically for any other unmatched URL \u2014 no explicit catch-all rule needed.\n *\n * Locale codes are sanity-checked (`/^[A-Za-z0-9_-]+$/`): a malformed code would\n * corrupt the TOML / redirect syntax, and such a locale cannot produce a route anyway.\n *\n * Pure (config in, TOML fragment out) so it is directly unit-testable; callers own\n * the existence gates (404 page present, netlify.toml ownership). Most callers\n * should go through `syncNetlifyLocale404Block`, which wraps the rules in the\n * managed marker block so later config saves can update them in place.\n */\nexport function netlifyLocale404Redirects(config: I18nConfig): string {\n if (!config.locales || config.locales.length <= 1) return '';\n const codes = config.locales\n .map((l) => l.code)\n .filter((code) => code !== config.defaultLocale && /^[A-Za-z0-9_-]+$/.test(code));\n if (codes.length === 0) return '';\n const header =\n \"\\n# Locale-scoped 404s \u2014 an unmatched /<locale>/* URL serves that locale's own\\n\" +\n '# prerendered 404 page WITH a 404 status (non-shadowing: real pages still win).\\n' +\n '# Unmatched URLs outside these prefixes fall through to the default /404.html.\\n';\n const rules = codes\n .map((code) => `[[redirects]]\\n from = \"/${code}/*\"\\n to = \"/${code}/404/index.html\"\\n status = 404\\n`)\n .join('\\n');\n return header + rules;\n}\n\n/**\n * Insert / refresh / remove the managed locale-404 block in netlify.toml content.\n * Pure (string in, string out) \u2014 callers own reading/writing the file.\n *\n * - Rules applicable (multi-locale config AND `has404`) + no block yet \u2192 the block\n * is APPENDED (a trailing newline is added to the existing content first if it\n * lacks one).\n * - Rules applicable + block present \u2192 the block's contents are REPLACED in place\n * (idempotent: re-syncing identical state is a no-op).\n * - Rules no longer applicable (single-locale, or no 404 page) + block present \u2192\n * the whole block is REMOVED; everything outside the markers stays byte-identical.\n * - Nothing applicable + no block \u2192 the content is returned unchanged.\n *\n * A corrupted block (BEGIN marker without its END) is left untouched \u2014 rewriting up\n * to an unknown boundary could eat user content, and a hand-damaged block is the\n * user taking ownership.\n */\nexport function syncNetlifyLocale404Block(content: string, config: I18nConfig, has404: boolean): string {\n const rules = has404 ? netlifyLocale404Redirects(config) : '';\n // `rules` starts with '\\n' (terminating the BEGIN line) and ends with '\\n'\n // (putting END at line start), so the block is exactly BEGIN\u2026rules\u2026END lines.\n const block = rules ? `${NETLIFY_LOCALE_404_BEGIN}${rules}${NETLIFY_LOCALE_404_END}\\n` : '';\n\n const beginIdx = content.indexOf(NETLIFY_LOCALE_404_BEGIN);\n if (beginIdx === -1) {\n if (!block) return content;\n const base = content === '' || content.endsWith('\\n') ? content : `${content}\\n`;\n return base + block;\n }\n\n const endMarkerIdx = content.indexOf(NETLIFY_LOCALE_404_END, beginIdx);\n if (endMarkerIdx === -1) return content; // corrupted block \u2014 refuse to guess its extent\n\n let endIdx = endMarkerIdx + NETLIFY_LOCALE_404_END.length;\n if (content[endIdx] === '\\n') endIdx += 1; // the END line's own newline belongs to the block\n\n const before = content.slice(0, beginIdx);\n const after = content.slice(endIdx);\n return before + block + after;\n}\n"],
|
|
5
|
+
"mappings": ";AAuBO,IAAM,2BAA2B;AAGjC,IAAM,yBAAyB;AA4B/B,SAAS,0BAA0B,QAA4B;AACpE,MAAI,CAAC,OAAO,WAAW,OAAO,QAAQ,UAAU,EAAG,QAAO;AAC1D,QAAM,QAAQ,OAAO,QAClB,IAAI,CAAC,MAAM,EAAE,IAAI,EACjB,OAAO,CAAC,SAAS,SAAS,OAAO,iBAAiB,mBAAmB,KAAK,IAAI,CAAC;AAClF,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,QAAM,SACJ;AAGF,QAAM,QAAQ,MACX,IAAI,CAAC,SAAS;AAAA,aAA6B,IAAI;AAAA,WAAiB,IAAI;AAAA;AAAA,CAAoC,EACxG,KAAK,IAAI;AACZ,SAAO,SAAS;AAClB;AAmBO,SAAS,0BAA0B,SAAiB,QAAoB,QAAyB;AACtG,QAAM,QAAQ,SAAS,0BAA0B,MAAM,IAAI;AAG3D,QAAM,QAAQ,QAAQ,GAAG,wBAAwB,GAAG,KAAK,GAAG,sBAAsB;AAAA,IAAO;AAEzF,QAAM,WAAW,QAAQ,QAAQ,wBAAwB;AACzD,MAAI,aAAa,IAAI;AACnB,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,OAAO,YAAY,MAAM,QAAQ,SAAS,IAAI,IAAI,UAAU,GAAG,OAAO;AAAA;AAC5E,WAAO,OAAO;AAAA,EAChB;AAEA,QAAM,eAAe,QAAQ,QAAQ,wBAAwB,QAAQ;AACrE,MAAI,iBAAiB,GAAI,QAAO;AAEhC,MAAI,SAAS,eAAe,uBAAuB;AACnD,MAAI,QAAQ,MAAM,MAAM,KAAM,WAAU;AAExC,QAAM,SAAS,QAAQ,MAAM,GAAG,QAAQ;AACxC,QAAM,QAAQ,QAAQ,MAAM,MAAM;AAClC,SAAO,SAAS,QAAQ;AAC1B;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|