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.
Files changed (415) hide show
  1. package/.claude/settings.local.json +1 -3
  2. package/bin/cli.ts +66 -261
  3. package/build-astro.ts +150 -128
  4. package/dist/bin/cli.js +42 -185
  5. package/dist/bin/cli.js.map +2 -2
  6. package/dist/chunks/chunk-2AR55GYH.js +42 -0
  7. package/dist/chunks/chunk-2AR55GYH.js.map +7 -0
  8. package/dist/chunks/{chunk-JGWFTO6P.js → chunk-2IIQK7T3.js} +2624 -1389
  9. package/dist/chunks/chunk-2IIQK7T3.js.map +7 -0
  10. package/dist/chunks/chunk-4ZRU52J2.js +169 -0
  11. package/dist/chunks/chunk-4ZRU52J2.js.map +7 -0
  12. package/dist/chunks/{chunk-UB44F4Z2.js → chunk-5X4HCN7J.js} +5 -7
  13. package/dist/chunks/chunk-5X4HCN7J.js.map +7 -0
  14. package/dist/chunks/{chunk-WQFG7PAH.js → chunk-7CCVOL5M.js} +15 -19
  15. package/dist/chunks/chunk-7CCVOL5M.js.map +7 -0
  16. package/dist/chunks/{chunk-YBLHKYFF.js → chunk-AR7LHIFY.js} +8 -2
  17. package/dist/chunks/chunk-AR7LHIFY.js.map +7 -0
  18. package/dist/chunks/{chunk-O3NAGJP4.js → chunk-NUP7H7D3.js} +135 -41
  19. package/dist/chunks/chunk-NUP7H7D3.js.map +7 -0
  20. package/dist/chunks/{chunk-X754AHS5.js → chunk-QWTQZHG3.js} +194 -90
  21. package/dist/chunks/chunk-QWTQZHG3.js.map +7 -0
  22. package/dist/chunks/{chunk-H3GJ4H2U.js → chunk-XTKNX4FW.js} +216 -87
  23. package/dist/chunks/chunk-XTKNX4FW.js.map +7 -0
  24. package/dist/chunks/{fs-JGINUXGL.js → fs-G3ANWEFP.js} +2 -2
  25. package/dist/lib/client/index.js +1003 -475
  26. package/dist/lib/client/index.js.map +3 -3
  27. package/dist/lib/server/index.js +14393 -6371
  28. package/dist/lib/server/index.js.map +4 -4
  29. package/dist/lib/shared/index.js +342 -101
  30. package/dist/lib/shared/index.js.map +4 -4
  31. package/dist/lib/shared/richtext/index.js +1 -1
  32. package/dist/lib/test-utils/index.js +64 -80
  33. package/dist/lib/test-utils/index.js.map +2 -2
  34. package/entries/client-router.tsx +10 -8
  35. package/lib/client/ClientInitializer.ts +8 -8
  36. package/lib/client/ErrorBoundary.test.tsx +246 -186
  37. package/lib/client/ErrorBoundary.tsx +183 -132
  38. package/lib/client/componentRegistry.test.ts +96 -108
  39. package/lib/client/componentRegistry.ts +1 -3
  40. package/lib/client/contexts/ThemeContext.tsx +3 -2
  41. package/lib/client/core/ComponentBuilder.test.ts +663 -560
  42. package/lib/client/core/ComponentBuilder.ts +427 -155
  43. package/lib/client/core/ComponentRenderer.test.tsx +2 -4
  44. package/lib/client/core/ComponentRenderer.tsx +46 -33
  45. package/lib/client/core/builders/embedBuilder.ts +242 -54
  46. package/lib/client/core/builders/linkBuilder.ts +72 -45
  47. package/lib/client/core/builders/linkNodeBuilder.ts +79 -54
  48. package/lib/client/core/builders/listBuilder.ts +155 -89
  49. package/lib/client/core/builders/localeListBuilder.ts +97 -62
  50. package/lib/client/core/builders/types.ts +5 -5
  51. package/lib/client/core/cmsTemplateProcessor.ts +8 -9
  52. package/lib/client/elementRegistry.ts +3 -3
  53. package/lib/client/fontFamiliesService.test.ts +2 -10
  54. package/lib/client/fontFamiliesService.ts +3 -3
  55. package/lib/client/hmr/HMRManager.tsx +47 -30
  56. package/lib/client/hmrCssReload.ts +49 -14
  57. package/lib/client/hmrWebSocket.ts +14 -19
  58. package/lib/client/hooks/useColorVariables.test.ts +21 -21
  59. package/lib/client/hooks/useColorVariables.ts +23 -18
  60. package/lib/client/hooks/usePropertyAutocomplete.ts +4 -6
  61. package/lib/client/hooks/useVariables.ts +6 -4
  62. package/lib/client/hydration/HydrationUtils.test.ts +24 -25
  63. package/lib/client/hydration/HydrationUtils.ts +3 -4
  64. package/lib/client/i18nConfigService.test.ts +2 -7
  65. package/lib/client/i18nConfigService.ts +2 -2
  66. package/lib/client/meno-filter/MenoFilter.test.ts +47 -49
  67. package/lib/client/meno-filter/MenoFilter.ts +14 -15
  68. package/lib/client/meno-filter/bindings.ts +18 -43
  69. package/lib/client/meno-filter/init.ts +4 -4
  70. package/lib/client/meno-filter/renderer.ts +30 -32
  71. package/lib/client/meno-filter/script.generated.ts +1 -3
  72. package/lib/client/meno-filter/ui.ts +4 -6
  73. package/lib/client/meno-filter/updates.ts +18 -23
  74. package/lib/client/meno-filter/utils.ts +1 -1
  75. package/lib/client/navigation.test.ts +174 -178
  76. package/lib/client/navigation.ts +0 -1
  77. package/lib/client/responsiveStyleResolver.knownTokens.test.ts +71 -0
  78. package/lib/client/responsiveStyleResolver.test.ts +234 -232
  79. package/lib/client/responsiveStyleResolver.ts +74 -20
  80. package/lib/client/routing/RouteLoader.test.ts +24 -25
  81. package/lib/client/routing/RouteLoader.ts +27 -35
  82. package/lib/client/routing/Router.tsx +210 -153
  83. package/lib/client/scripts/ScriptExecutor.test.ts +157 -158
  84. package/lib/client/scripts/ScriptExecutor.ts +18 -36
  85. package/lib/client/services/PrefetchService.test.ts +3 -3
  86. package/lib/client/services/PrefetchService.ts +23 -29
  87. package/lib/client/styleProcessor.test.ts +9 -9
  88. package/lib/client/styleProcessor.ts +24 -15
  89. package/lib/client/styles/StyleInjector.test.ts +122 -115
  90. package/lib/client/styles/StyleInjector.ts +10 -7
  91. package/lib/client/styles/UtilityClassCollector.ts +62 -28
  92. package/lib/client/styles/cspNonce.test.ts +2 -5
  93. package/lib/client/templateEngine.test.ts +554 -488
  94. package/lib/client/templateEngine.ts +203 -73
  95. package/lib/client/theme.test.ts +1 -1
  96. package/lib/client/theme.ts +0 -1
  97. package/lib/client/utils/toast.ts +0 -1
  98. package/lib/server/__integration__/api-routes.test.ts +8 -4
  99. package/lib/server/__integration__/cms-integration.test.ts +1 -4
  100. package/lib/server/__integration__/server-lifecycle.test.ts +4 -5
  101. package/lib/server/__integration__/ssr-rendering.test.ts +47 -37
  102. package/lib/server/__integration__/static-assets.test.ts +3 -3
  103. package/lib/server/__integration__/test-helpers.ts +87 -74
  104. package/lib/server/ab/generateFunctions.ts +12 -10
  105. package/lib/server/astro/cmsPageEmitter.ts +26 -42
  106. package/lib/server/astro/componentEmitter.ts +35 -43
  107. package/lib/server/astro/cssCollector.ts +10 -26
  108. package/lib/server/astro/nodeToAstro.test.ts +1754 -34
  109. package/lib/server/astro/nodeToAstro.ts +232 -216
  110. package/lib/server/astro/normalizeOrphanTemplateProps.test.ts +115 -119
  111. package/lib/server/astro/normalizeOrphanTemplateProps.ts +11 -18
  112. package/lib/server/astro/pageEmitter.ts +9 -13
  113. package/lib/server/astro/tailwindMapper.test.ts +10 -37
  114. package/lib/server/astro/tailwindMapper.ts +33 -40
  115. package/lib/server/astro/templateTransformer.ts +17 -20
  116. package/lib/server/createServer.ts +7 -19
  117. package/lib/server/cssGenerator.test.ts +35 -44
  118. package/lib/server/cssGenerator.ts +8 -19
  119. package/lib/server/fileWatcher.test.ts +164 -13
  120. package/lib/server/fileWatcher.ts +209 -124
  121. package/lib/server/index.ts +14 -17
  122. package/lib/server/jsonLoader.test.ts +39 -2
  123. package/lib/server/jsonLoader.ts +39 -34
  124. package/lib/server/middleware/cors.test.ts +21 -21
  125. package/lib/server/middleware/cors.ts +28 -4
  126. package/lib/server/middleware/errorHandler.test.ts +7 -5
  127. package/lib/server/middleware/errorHandler.ts +3 -8
  128. package/lib/server/middleware/index.ts +0 -1
  129. package/lib/server/middleware/logger.test.ts +10 -8
  130. package/lib/server/middleware/logger.ts +17 -29
  131. package/lib/server/migrateTemplates.ts +3 -3
  132. package/lib/server/pageCache.test.ts +76 -77
  133. package/lib/server/pageCache.ts +0 -1
  134. package/lib/server/projectContext.ts +5 -4
  135. package/lib/server/providers/fileSystemCMSProvider.test.ts +142 -99
  136. package/lib/server/providers/fileSystemCMSProvider.ts +62 -38
  137. package/lib/server/routes/api/cms.test.ts +26 -14
  138. package/lib/server/routes/api/cms.ts +9 -14
  139. package/lib/server/routes/api/colors.test.ts +2 -2
  140. package/lib/server/routes/api/components.ts +31 -35
  141. package/lib/server/routes/api/config.ts +3 -4
  142. package/lib/server/routes/api/core-routes.ts +49 -76
  143. package/lib/server/routes/api/enums.test.ts +2 -2
  144. package/lib/server/routes/api/functions.ts +9 -17
  145. package/lib/server/routes/api/index.ts +3 -6
  146. package/lib/server/routes/api/pages.ts +8 -11
  147. package/lib/server/routes/api/shared.test.ts +1 -1
  148. package/lib/server/routes/api/shared.ts +12 -9
  149. package/lib/server/routes/api/variables.test.ts +3 -5
  150. package/lib/server/routes/api/variables.ts +1 -1
  151. package/lib/server/routes/index.ts +25 -28
  152. package/lib/server/routes/pages.ts +35 -31
  153. package/lib/server/routes/static.ts +17 -6
  154. package/lib/server/runtime/bundler.ts +98 -61
  155. package/lib/server/runtime/fs.ts +16 -26
  156. package/lib/server/runtime/httpServer.ts +8 -12
  157. package/lib/server/services/ColorService.test.ts +3 -3
  158. package/lib/server/services/ColorService.ts +37 -29
  159. package/lib/server/services/EnumService.test.ts +4 -8
  160. package/lib/server/services/EnumService.ts +11 -3
  161. package/lib/server/services/VariableService.test.ts +8 -12
  162. package/lib/server/services/VariableService.ts +11 -3
  163. package/lib/server/services/cmsService.test.ts +158 -120
  164. package/lib/server/services/cmsService.ts +36 -146
  165. package/lib/server/services/componentService.test.ts +125 -45
  166. package/lib/server/services/componentService.ts +70 -46
  167. package/lib/server/services/configService.test.ts +22 -45
  168. package/lib/server/services/configService.ts +50 -27
  169. package/lib/server/services/fileWatcherService.ts +42 -8
  170. package/lib/server/services/index.ts +0 -1
  171. package/lib/server/services/pageService.test.ts +8 -10
  172. package/lib/server/services/pageService.ts +32 -18
  173. package/lib/server/ssr/attributeBuilder.ts +18 -8
  174. package/lib/server/ssr/buildErrorOverlay.ts +11 -12
  175. package/lib/server/ssr/clientDataInjector.ts +7 -21
  176. package/lib/server/ssr/cmsSSRProcessor.ts +4 -8
  177. package/lib/server/ssr/cssCollector.ts +1 -1
  178. package/lib/server/ssr/errorOverlay.test.ts +1 -1
  179. package/lib/server/ssr/errorOverlay.ts +3 -9
  180. package/lib/server/ssr/htmlGenerator.nonce.test.ts +9 -14
  181. package/lib/server/ssr/htmlGenerator.test.ts +120 -44
  182. package/lib/server/ssr/htmlGenerator.ts +126 -91
  183. package/lib/server/ssr/imageMetadata.test.ts +3 -1
  184. package/lib/server/ssr/imageMetadata.ts +27 -21
  185. package/lib/server/ssr/jsCollector.test.ts +8 -18
  186. package/lib/server/ssr/jsCollector.ts +3 -8
  187. package/lib/server/ssr/liveReloadIntegration.test.ts +76 -36
  188. package/lib/server/ssr/metaTagGenerator.ts +2 -2
  189. package/lib/server/ssr/ssrRenderer.branches.test.ts +1103 -0
  190. package/lib/server/ssr/ssrRenderer.test.ts +316 -256
  191. package/lib/server/ssr/ssrRenderer.ts +795 -243
  192. package/lib/server/ssrRenderer.test.ts +1048 -954
  193. package/lib/server/utils/jsonLineMapper.test.ts +28 -28
  194. package/lib/server/utils/jsonLineMapper.ts +7 -7
  195. package/lib/server/validateStyleCoverage.ts +18 -21
  196. package/lib/server/websocketManager.ts +28 -19
  197. package/lib/shared/attributeNodeUtils.test.ts +15 -15
  198. package/lib/shared/attributeNodeUtils.ts +5 -12
  199. package/lib/shared/breakpoints.test.ts +5 -5
  200. package/lib/shared/breakpoints.ts +4 -11
  201. package/lib/shared/cmsQuery.test.ts +81 -0
  202. package/lib/shared/cmsQuery.ts +92 -0
  203. package/lib/shared/cmsQueryParser.test.ts +50 -42
  204. package/lib/shared/cmsQueryParser.ts +60 -38
  205. package/lib/shared/colorConversions.ts +9 -9
  206. package/lib/shared/colorVariableUtils.test.ts +27 -5
  207. package/lib/shared/colorVariableUtils.ts +21 -12
  208. package/lib/shared/componentRefs.ts +1 -5
  209. package/lib/shared/constants.test.ts +3 -3
  210. package/lib/shared/constants.ts +8 -8
  211. package/lib/shared/cssGeneration.test.ts +285 -144
  212. package/lib/shared/cssGeneration.ts +217 -531
  213. package/lib/shared/cssNamedColors.ts +152 -30
  214. package/lib/shared/cssProperties.test.ts +69 -70
  215. package/lib/shared/cssProperties.ts +298 -114
  216. package/lib/shared/elementClassName.test.ts +109 -109
  217. package/lib/shared/elementClassName.ts +3 -3
  218. package/lib/shared/elementUtils.ts +12 -16
  219. package/lib/shared/errorLogger.test.ts +12 -12
  220. package/lib/shared/errorLogger.ts +2 -10
  221. package/lib/shared/errors.test.ts +2 -13
  222. package/lib/shared/errors.ts +2 -8
  223. package/lib/shared/expressionEvaluator.test.ts +145 -0
  224. package/lib/shared/expressionEvaluator.ts +52 -24
  225. package/lib/shared/fontLoader.test.ts +32 -18
  226. package/lib/shared/fontLoader.ts +2 -2
  227. package/lib/shared/friendlyError.ts +2 -3
  228. package/lib/shared/gradientUtils.test.ts +3 -7
  229. package/lib/shared/gradientUtils.ts +17 -14
  230. package/lib/shared/hrefRefs.test.ts +2 -2
  231. package/lib/shared/hrefRefs.ts +2 -10
  232. package/lib/shared/i18n.test.ts +4 -4
  233. package/lib/shared/i18n.ts +18 -38
  234. package/lib/shared/index.ts +27 -0
  235. package/lib/shared/inlineSvgStyleRules.ts +14 -13
  236. package/lib/shared/interactiveStyleMappings.test.ts +32 -54
  237. package/lib/shared/interactiveStyleMappings.ts +11 -24
  238. package/lib/shared/interactiveStyles.test.ts +165 -188
  239. package/lib/shared/interfaces/contentProvider.ts +1 -1
  240. package/lib/shared/itemTemplateUtils.test.ts +11 -17
  241. package/lib/shared/itemTemplateUtils.ts +27 -39
  242. package/lib/shared/jsonRepair.ts +16 -10
  243. package/lib/shared/libraryLoader.test.ts +21 -55
  244. package/lib/shared/libraryLoader.ts +7 -22
  245. package/lib/shared/linkUtils.ts +1 -1
  246. package/lib/shared/logger.test.ts +66 -0
  247. package/lib/shared/logger.ts +94 -0
  248. package/lib/shared/markdown.ts +25 -0
  249. package/lib/shared/netlifyLocale404.test.ts +179 -0
  250. package/lib/shared/netlifyLocale404.ts +110 -0
  251. package/lib/shared/nodeUtils.test.ts +28 -16
  252. package/lib/shared/nodeUtils.ts +76 -23
  253. package/lib/shared/pathArrayUtils.test.ts +1 -2
  254. package/lib/shared/pathArrayUtils.ts +1 -1
  255. package/lib/shared/pathSecurity.ts +2 -2
  256. package/lib/shared/pathUtils.test.ts +4 -6
  257. package/lib/shared/pathUtils.ts +42 -49
  258. package/lib/shared/paths/Path.test.ts +2 -2
  259. package/lib/shared/paths/Path.ts +0 -1
  260. package/lib/shared/paths/PathConverter.test.ts +1 -1
  261. package/lib/shared/paths/PathConverter.ts +17 -20
  262. package/lib/shared/paths/PathUtils.ts +13 -13
  263. package/lib/shared/paths/PathValidator.test.ts +2 -15
  264. package/lib/shared/paths/PathValidator.ts +12 -10
  265. package/lib/shared/paths/index.ts +1 -2
  266. package/lib/shared/permissions.test.ts +168 -0
  267. package/lib/shared/permissions.ts +162 -0
  268. package/lib/shared/propResolver.test.ts +240 -244
  269. package/lib/shared/propResolver.ts +15 -26
  270. package/lib/shared/pxToRem.test.ts +7 -6
  271. package/lib/shared/pxToRem.ts +2 -5
  272. package/lib/shared/registry/BaseNodeTypeRegistry.test.ts +12 -6
  273. package/lib/shared/registry/ClientRegistry.ts +0 -2
  274. package/lib/shared/registry/ComponentRegistry.test.ts +46 -32
  275. package/lib/shared/registry/ComponentRegistry.ts +12 -9
  276. package/lib/shared/registry/NodeTypeDefinition.ts +16 -9
  277. package/lib/shared/registry/RegistryManager.ts +1 -2
  278. package/lib/shared/registry/SSRRegistry.ts +0 -2
  279. package/lib/shared/registry/createNodeType.ts +7 -9
  280. package/lib/shared/registry/defineNodeType.ts +2 -6
  281. package/lib/shared/registry/fieldPresets.ts +3 -1
  282. package/lib/shared/registry/index.ts +0 -1
  283. package/lib/shared/registry/nodeTypes/ComponentInstanceNodeType.ts +14 -15
  284. package/lib/shared/registry/nodeTypes/CustomNodeType.ts +103 -0
  285. package/lib/shared/registry/nodeTypes/EmbedNodeType.ts +18 -11
  286. package/lib/shared/registry/nodeTypes/HtmlNodeType.ts +48 -19
  287. package/lib/shared/registry/nodeTypes/IslandNodeType.ts +129 -0
  288. package/lib/shared/registry/nodeTypes/LinkNodeType.ts +21 -19
  289. package/lib/shared/registry/nodeTypes/ListNodeType.ts +117 -77
  290. package/lib/shared/registry/nodeTypes/LocaleListNodeType.ts +27 -21
  291. package/lib/shared/registry/nodeTypes/MarkdownNodeType.ts +78 -0
  292. package/lib/shared/registry/nodeTypes/SlotMarkerType.ts +12 -8
  293. package/lib/shared/registry/nodeTypes/index.ts +26 -3
  294. package/lib/shared/responsiveScaling.test.ts +16 -34
  295. package/lib/shared/responsiveScaling.ts +61 -42
  296. package/lib/shared/responsiveStyleUtils.test.ts +0 -1
  297. package/lib/shared/responsiveStyleUtils.ts +11 -13
  298. package/lib/shared/richtext/htmlToTiptap.test.ts +139 -130
  299. package/lib/shared/richtext/htmlToTiptap.ts +2 -4
  300. package/lib/shared/richtext/tiptapToHtml.test.ts +5 -6
  301. package/lib/shared/richtext/types.ts +1 -8
  302. package/lib/shared/slugTranslator.test.ts +13 -13
  303. package/lib/shared/slugTranslator.ts +12 -16
  304. package/lib/shared/slugify.ts +9 -15
  305. package/lib/shared/styleNodeUtils.test.ts +8 -8
  306. package/lib/shared/styleNodeUtils.ts +18 -20
  307. package/lib/shared/styleUtils.test.ts +87 -61
  308. package/lib/shared/styleUtils.ts +5 -6
  309. package/lib/shared/themeDefaults.test.ts +11 -14
  310. package/lib/shared/themeDefaults.ts +3 -4
  311. package/lib/shared/tree/PathBuilder.test.ts +63 -145
  312. package/lib/shared/tree/PathBuilder.ts +59 -47
  313. package/lib/shared/treePathUtils.test.ts +51 -12
  314. package/lib/shared/treePathUtils.ts +91 -60
  315. package/lib/shared/types/api.ts +105 -8
  316. package/lib/shared/types/cms.test.ts +34 -0
  317. package/lib/shared/types/cms.ts +90 -34
  318. package/lib/shared/types/comment.ts +49 -16
  319. package/lib/shared/types/components.ts +51 -25
  320. package/lib/shared/types/errors.test.ts +1 -6
  321. package/lib/shared/types/errors.ts +3 -7
  322. package/lib/shared/types/experiments.ts +28 -28
  323. package/lib/shared/types/index.ts +25 -2
  324. package/lib/shared/types/permissions.ts +139 -0
  325. package/lib/shared/types/styles.ts +0 -1
  326. package/lib/shared/types/variables.test.ts +4 -13
  327. package/lib/shared/types/variables.ts +51 -30
  328. package/lib/shared/types.ts +1 -2
  329. package/lib/shared/utilityClassConfig.ts +751 -321
  330. package/lib/shared/utilityClassMapper.durability.test.ts +117 -0
  331. package/lib/shared/utilityClassMapper.test.ts +433 -95
  332. package/lib/shared/utilityClassMapper.ts +322 -249
  333. package/lib/shared/utilityClassNames.test.ts +38 -0
  334. package/lib/shared/utilityClassNames.ts +458 -0
  335. package/lib/shared/utils.test.ts +2 -10
  336. package/lib/shared/utils.ts +19 -10
  337. package/lib/shared/validation/cmsValidators.ts +2 -1
  338. package/lib/shared/validation/commentValidators.test.ts +53 -0
  339. package/lib/shared/validation/commentValidators.ts +12 -1
  340. package/lib/shared/validation/index.ts +1 -0
  341. package/lib/shared/validation/permissionsValidators.test.ts +49 -0
  342. package/lib/shared/validation/permissionsValidators.ts +49 -0
  343. package/lib/shared/validation/propValidator.test.ts +19 -21
  344. package/lib/shared/validation/propValidator.ts +13 -18
  345. package/lib/shared/validation/schemas.test.ts +64 -32
  346. package/lib/shared/validation/schemas.ts +616 -345
  347. package/lib/shared/validation/validators.test.ts +3 -8
  348. package/lib/shared/validation/validators.ts +89 -68
  349. package/lib/shared/viewportUnits.integration.test.ts +14 -10
  350. package/lib/shared/viewportUnits.test.ts +24 -23
  351. package/lib/shared/viewportUnits.ts +12 -5
  352. package/lib/test-utils/dom-setup.ts +1 -1
  353. package/lib/test-utils/factories/ConsoleMockFactory.ts +10 -14
  354. package/lib/test-utils/factories/DomMockFactory.ts +17 -23
  355. package/lib/test-utils/factories/EventMockFactory.ts +7 -13
  356. package/lib/test-utils/factories/FetchMockFactory.ts +39 -57
  357. package/lib/test-utils/factories/ServerMockFactory.ts +6 -10
  358. package/lib/test-utils/factories/StoreMockFactory.ts +18 -29
  359. package/lib/test-utils/fixtures.ts +45 -45
  360. package/lib/test-utils/helpers/asyncHelpers.test.ts +15 -18
  361. package/lib/test-utils/helpers/asyncHelpers.ts +11 -20
  362. package/lib/test-utils/helpers.ts +1 -5
  363. package/lib/test-utils/index.ts +0 -4
  364. package/lib/test-utils/mockFactories.ts +13 -19
  365. package/lib/test-utils/mocks.ts +6 -4
  366. package/package.json +3 -5
  367. package/scripts/build-for-publish.mjs +2 -4
  368. package/scripts/build-meno-filter.ts +4 -7
  369. package/tsconfig.json +1 -0
  370. package/vite.config.ts +4 -4
  371. package/build-next.ts +0 -1361
  372. package/build-static.test.ts +0 -424
  373. package/build-static.ts +0 -1074
  374. package/dist/build-static.js +0 -36
  375. package/dist/chunks/chunk-2MHDV5BF.js +0 -251
  376. package/dist/chunks/chunk-2MHDV5BF.js.map +0 -7
  377. package/dist/chunks/chunk-AZQYF6KE.js +0 -559
  378. package/dist/chunks/chunk-AZQYF6KE.js.map +0 -7
  379. package/dist/chunks/chunk-GZHGVVW3.js +0 -322
  380. package/dist/chunks/chunk-GZHGVVW3.js.map +0 -7
  381. package/dist/chunks/chunk-H3GJ4H2U.js.map +0 -7
  382. package/dist/chunks/chunk-I7YIGZXT.js +0 -467
  383. package/dist/chunks/chunk-I7YIGZXT.js.map +0 -7
  384. package/dist/chunks/chunk-IGYR22T6.js +0 -6192
  385. package/dist/chunks/chunk-IGYR22T6.js.map +0 -7
  386. package/dist/chunks/chunk-JGP5A3Y5.js +0 -1136
  387. package/dist/chunks/chunk-JGP5A3Y5.js.map +0 -7
  388. package/dist/chunks/chunk-JGWFTO6P.js.map +0 -7
  389. package/dist/chunks/chunk-O3NAGJP4.js.map +0 -7
  390. package/dist/chunks/chunk-QB2LNO4W.js +0 -77
  391. package/dist/chunks/chunk-QB2LNO4W.js.map +0 -7
  392. package/dist/chunks/chunk-R6XHAFBF.js +0 -3821
  393. package/dist/chunks/chunk-R6XHAFBF.js.map +0 -7
  394. package/dist/chunks/chunk-UB44F4Z2.js.map +0 -7
  395. package/dist/chunks/chunk-WQFG7PAH.js.map +0 -7
  396. package/dist/chunks/chunk-X754AHS5.js.map +0 -7
  397. package/dist/chunks/chunk-YBLHKYFF.js.map +0 -7
  398. package/dist/chunks/configService-R3OGU2UD.js +0 -13
  399. package/dist/chunks/configService-R3OGU2UD.js.map +0 -7
  400. package/dist/chunks/constants-STK2YBIW.js +0 -46
  401. package/dist/chunks/constants-STK2YBIW.js.map +0 -7
  402. package/dist/chunks/fs-JGINUXGL.js.map +0 -7
  403. package/dist/entries/server-router.js +0 -67
  404. package/dist/entries/server-router.js.map +0 -7
  405. package/entries/server-router.tsx +0 -81
  406. package/lib/server/providers/fileSystemPageProvider.ts +0 -160
  407. package/lib/server/webflow/buildWebflow.ts +0 -635
  408. package/lib/server/webflow/index.ts +0 -23
  409. package/lib/server/webflow/nodeToWebflow.test.ts +0 -3170
  410. package/lib/server/webflow/nodeToWebflow.ts +0 -2435
  411. package/lib/server/webflow/styleMapper.test.ts +0 -389
  412. package/lib/server/webflow/styleMapper.ts +0 -695
  413. package/lib/server/webflow/templateWrapper.ts +0 -49
  414. package/lib/server/webflow/types.ts +0 -396
  415. /package/dist/{build-static.js.map → chunks/fs-G3ANWEFP.js.map} +0 -0
@@ -1,1136 +0,0 @@
1
- import {
2
- CMSService,
3
- FileSystemCMSProvider,
4
- clearJSValidationCache,
5
- generateSSRHTML,
6
- getJSValidationErrors,
7
- loadComponentDirectory,
8
- loadI18nConfig,
9
- loadJSONFile,
10
- loadProjectConfig,
11
- mapPageNameToPath,
12
- migrateTemplatesDirectory,
13
- parseJSON,
14
- prepareClientData
15
- } from "./chunk-IGYR22T6.js";
16
- import {
17
- minifyJS,
18
- projectPaths
19
- } from "./chunk-I7YIGZXT.js";
20
- import {
21
- inspect
22
- } from "./chunk-WQFG7PAH.js";
23
- import {
24
- collectComponentLibraries,
25
- extractLibraryOrigins,
26
- filterLibrariesByContext
27
- } from "./chunk-X754AHS5.js";
28
- import {
29
- isItemDraftForLocale,
30
- isItemFullyPublished
31
- } from "./chunk-JGWFTO6P.js";
32
- import {
33
- isI18nValue,
34
- resolveI18nValue
35
- } from "./chunk-AZQYF6KE.js";
36
-
37
- // build-static.ts
38
- import { existsSync, readdirSync, mkdirSync, rmSync, statSync, copyFileSync, unlinkSync, writeFileSync } from "fs";
39
- import { writeFile, readFile } from "fs/promises";
40
- import { join } from "path";
41
- import { createHash } from "crypto";
42
-
43
- // lib/server/ab/generateFunctions.ts
44
- function generateMiddleware(experiments) {
45
- const running = experiments.filter((e) => e.status === "running");
46
- if (running.length === 0) return "";
47
- const configJSON = JSON.stringify(running.map((e) => ({
48
- id: e.id,
49
- controlBranch: e.controlBranch,
50
- controlWeight: e.controlWeight,
51
- variants: e.variants.map((v) => ({
52
- branch: v.branch,
53
- weight: v.weight,
54
- deployUrl: v.deployUrl
55
- }))
56
- })));
57
- return `/**
58
- * A/B Testing Traffic Splitting Middleware
59
- * Auto-generated by Meno build - do not edit manually
60
- */
61
-
62
- interface Env {
63
- AB_DB?: D1Database;
64
- }
65
-
66
- interface ExperimentConfig {
67
- id: string;
68
- controlBranch: string;
69
- controlWeight: number;
70
- variants: Array<{ branch: string; weight: number; deployUrl: string }>;
71
- }
72
-
73
- const EXPERIMENTS: ExperimentConfig[] = ${configJSON};
74
-
75
- function getCookie(request: Request, name: string): string | null {
76
- const cookieHeader = request.headers.get('Cookie');
77
- if (!cookieHeader) return null;
78
- const match = cookieHeader.match(new RegExp('(?:^|;\\\\s*)' + name + '=([^;]*)'));
79
- return match ? decodeURIComponent(match[1]) : null;
80
- }
81
-
82
- function assignVariant(experiment: ExperimentConfig): string {
83
- const rand = Math.random() * 100;
84
- let cumulative = experiment.controlWeight;
85
- if (rand < cumulative) return 'control';
86
- for (const variant of experiment.variants) {
87
- cumulative += variant.weight;
88
- if (rand < cumulative) return variant.branch;
89
- }
90
- return 'control';
91
- }
92
-
93
- export async function onRequest(context: { request: Request; next: () => Promise<Response>; env: Env }) {
94
- const url = new URL(context.request.url);
95
-
96
- // Skip API routes and static assets
97
- if (url.pathname.startsWith('/api/') || url.pathname.match(/\\.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|eot)$/)) {
98
- return context.next();
99
- }
100
-
101
- // Use first running experiment (single experiment at a time for simplicity)
102
- const experiment = EXPERIMENTS[0];
103
- if (!experiment) return context.next();
104
-
105
- // Check for existing variant assignment (sticky sessions)
106
- let variant = getCookie(context.request, 'meno_variant');
107
-
108
- // If no cookie, assign a variant
109
- if (!variant) {
110
- variant = assignVariant(experiment);
111
- }
112
-
113
- let response: Response;
114
-
115
- if (variant === 'control') {
116
- // Control: serve local assets (pass through)
117
- response = await context.next();
118
- } else {
119
- // Variant: proxy to branch preview deploy
120
- const variantConfig = experiment.variants.find(v => v.branch === variant);
121
- if (!variantConfig) {
122
- response = await context.next();
123
- } else {
124
- // Fetch from the variant's deploy URL
125
- const variantUrl = new URL(url.pathname + url.search, variantConfig.deployUrl);
126
- try {
127
- const proxyResponse = await fetch(variantUrl.toString(), {
128
- method: context.request.method,
129
- headers: context.request.headers,
130
- });
131
- response = new Response(proxyResponse.body, {
132
- status: proxyResponse.status,
133
- statusText: proxyResponse.statusText,
134
- headers: new Headers(proxyResponse.headers),
135
- });
136
- } catch {
137
- // Fallback to control if variant fetch fails
138
- response = await context.next();
139
- variant = 'control';
140
- }
141
- }
142
- }
143
-
144
- // Set variant cookie (30-day expiry)
145
- const headers = new Headers(response.headers);
146
- headers.append(
147
- 'Set-Cookie',
148
- \`meno_variant=\${encodeURIComponent(variant!)}; Path=/; Max-Age=2592000; SameSite=Lax\`
149
- );
150
-
151
- return new Response(response.body, {
152
- status: response.status,
153
- statusText: response.statusText,
154
- headers,
155
- });
156
- }
157
- `;
158
- }
159
- function generateTrackFunction() {
160
- return `/**
161
- * A/B Testing Event Tracker
162
- * Auto-generated by Meno build - do not edit manually
163
- * POST /api/ab-track - stores pageview/conversion events in D1
164
- */
165
-
166
- interface Env {
167
- AB_DB: D1Database;
168
- }
169
-
170
- interface TrackEvent {
171
- experimentId: string;
172
- visitorId: string;
173
- variant: string;
174
- eventType: 'pageview' | 'conversion';
175
- goalId?: string;
176
- url?: string;
177
- }
178
-
179
- interface PagesContext<E = unknown> {
180
- request: Request;
181
- env: E;
182
- params: Record<string, string>;
183
- waitUntil: (promise: Promise<unknown>) => void;
184
- }
185
-
186
- export async function onRequestPost(context: PagesContext<Env>): Promise<Response> {
187
- try {
188
- const body: TrackEvent = await context.request.json();
189
-
190
- // Validate required fields
191
- if (!body.experimentId || !body.visitorId || !body.variant || !body.eventType) {
192
- return new Response(null, { status: 400 });
193
- }
194
-
195
- // Validate event type
196
- if (body.eventType !== 'pageview' && body.eventType !== 'conversion') {
197
- return new Response(null, { status: 400 });
198
- }
199
-
200
- // Insert event into D1
201
- await context.env.AB_DB.prepare(
202
- 'INSERT INTO ab_events (experiment_id, visitor_id, variant, event_type, goal_id, url, timestamp) VALUES (?, ?, ?, ?, ?, ?, ?)'
203
- ).bind(
204
- body.experimentId,
205
- body.visitorId,
206
- body.variant,
207
- body.eventType,
208
- body.goalId || null,
209
- body.url || null,
210
- Date.now()
211
- ).run();
212
-
213
- return new Response(null, { status: 204 });
214
- } catch {
215
- return new Response(null, { status: 500 });
216
- }
217
- }
218
- `;
219
- }
220
- function generateResultsFunction() {
221
- return `/**
222
- * A/B Testing Results API
223
- * Auto-generated by Meno build - do not edit manually
224
- * GET /api/ab-results?experiment=<id> - returns aggregated results with significance
225
- */
226
-
227
- interface Env {
228
- AB_DB: D1Database;
229
- }
230
-
231
- interface PagesContext<E = unknown> {
232
- request: Request;
233
- env: E;
234
- params: Record<string, string>;
235
- }
236
-
237
- interface VariantResult {
238
- variant: string;
239
- visitors: number;
240
- conversions: number;
241
- conversionRate: number;
242
- lift?: number;
243
- pValue?: number;
244
- isSignificant: boolean;
245
- }
246
-
247
- /**
248
- * Two-proportion z-test for statistical significance
249
- */
250
- function zTest(
251
- conversionsA: number, visitorsA: number,
252
- conversionsB: number, visitorsB: number
253
- ): number {
254
- if (visitorsA === 0 || visitorsB === 0) return 1;
255
-
256
- const pA = conversionsA / visitorsA;
257
- const pB = conversionsB / visitorsB;
258
- const pPool = (conversionsA + conversionsB) / (visitorsA + visitorsB);
259
-
260
- if (pPool === 0 || pPool === 1) return 1;
261
-
262
- const se = Math.sqrt(pPool * (1 - pPool) * (1 / visitorsA + 1 / visitorsB));
263
- if (se === 0) return 1;
264
-
265
- const z = Math.abs(pA - pB) / se;
266
-
267
- // Approximate two-tailed p-value using rational approximation
268
- const t = 1 / (1 + 0.2316419 * z);
269
- const d = 0.3989422804014327;
270
- const p = d * Math.exp(-z * z / 2) * t * (0.3193815 + t * (-0.3565638 + t * (1.781478 + t * (-1.821256 + t * 1.330274))));
271
- return 2 * p;
272
- }
273
-
274
- export async function onRequestGet(context: PagesContext<Env>): Promise<Response> {
275
- const url = new URL(context.request.url);
276
- const experimentId = url.searchParams.get('experiment');
277
-
278
- if (!experimentId) {
279
- return Response.json({ error: 'Missing experiment parameter' }, { status: 400 });
280
- }
281
-
282
- try {
283
- // Get unique visitors per variant
284
- const visitorsResult = await context.env.AB_DB.prepare(
285
- 'SELECT variant, COUNT(DISTINCT visitor_id) as visitors FROM ab_events WHERE experiment_id = ? AND event_type = \\'pageview\\' GROUP BY variant'
286
- ).bind(experimentId).all();
287
-
288
- // Get conversions per variant
289
- const conversionsResult = await context.env.AB_DB.prepare(
290
- 'SELECT variant, COUNT(DISTINCT visitor_id) as conversions FROM ab_events WHERE experiment_id = ? AND event_type = \\'conversion\\' GROUP BY variant'
291
- ).bind(experimentId).all();
292
-
293
- // Build results map
294
- const visitorMap = new Map<string, number>();
295
- const conversionMap = new Map<string, number>();
296
-
297
- for (const row of (visitorsResult.results || [])) {
298
- visitorMap.set(row.variant as string, row.visitors as number);
299
- }
300
- for (const row of (conversionsResult.results || [])) {
301
- conversionMap.set(row.variant as string, row.conversions as number);
302
- }
303
-
304
- // Get all variant names
305
- const allVariants = new Set([...visitorMap.keys(), ...conversionMap.keys()]);
306
-
307
- // Calculate results
308
- const variants: VariantResult[] = [];
309
- let controlVisitors = 0;
310
- let controlConversions = 0;
311
-
312
- for (const variant of allVariants) {
313
- const visitors = visitorMap.get(variant) || 0;
314
- const conversions = conversionMap.get(variant) || 0;
315
- const conversionRate = visitors > 0 ? conversions / visitors : 0;
316
-
317
- if (variant === 'control') {
318
- controlVisitors = visitors;
319
- controlConversions = conversions;
320
- }
321
-
322
- variants.push({
323
- variant,
324
- visitors,
325
- conversions,
326
- conversionRate,
327
- isSignificant: false,
328
- });
329
- }
330
-
331
- // Calculate lift and significance for non-control variants
332
- const controlRate = controlVisitors > 0 ? controlConversions / controlVisitors : 0;
333
- for (const result of variants) {
334
- if (result.variant !== 'control' && controlVisitors > 0) {
335
- result.lift = controlRate > 0
336
- ? ((result.conversionRate - controlRate) / controlRate) * 100
337
- : 0;
338
- result.pValue = zTest(
339
- controlConversions, controlVisitors,
340
- result.conversions, result.visitors
341
- );
342
- result.isSignificant = result.pValue < 0.05;
343
- }
344
- }
345
-
346
- // Sort: control first, then by variant name
347
- variants.sort((a, b) => {
348
- if (a.variant === 'control') return -1;
349
- if (b.variant === 'control') return 1;
350
- return a.variant.localeCompare(b.variant);
351
- });
352
-
353
- return Response.json({
354
- experimentId,
355
- variants,
356
- }, {
357
- headers: {
358
- 'Access-Control-Allow-Origin': '*',
359
- 'Cache-Control': 'no-cache',
360
- }
361
- });
362
- } catch (error) {
363
- return Response.json({ error: 'Failed to query results' }, { status: 500 });
364
- }
365
- }
366
- `;
367
- }
368
-
369
- // lib/server/ab/trackingScript.ts
370
- function generateTrackingScript(experimentId, goals) {
371
- const goalsJSON = JSON.stringify(goals);
372
- return `(function(){
373
- var EXP_ID=${JSON.stringify(experimentId)};
374
- var GOALS=${goalsJSON};
375
-
376
- function getCookie(n){var m=document.cookie.match(new RegExp('(?:^|;\\\\s*)'+n+'=([^;]*)'));return m?decodeURIComponent(m[1]):null}
377
- function setCookie(n,v,d){var e=new Date();e.setTime(e.getTime()+d*864e5);document.cookie=n+'='+encodeURIComponent(v)+';path=/;expires='+e.toUTCString()+';SameSite=Lax'}
378
-
379
- var variant=getCookie('meno_variant')||'control';
380
- var visitor=getCookie('meno_visitor');
381
- if(!visitor){visitor=Math.random().toString(36).slice(2)+Date.now().toString(36);setCookie('meno_visitor',visitor,365)}
382
-
383
- function track(type,goalId){
384
- try{navigator.sendBeacon('/api/ab-track',JSON.stringify({experimentId:EXP_ID,visitorId:visitor,variant:variant,eventType:type,goalId:goalId||null,url:location.pathname}))}catch(e){}
385
- }
386
-
387
- track('pageview');
388
-
389
- GOALS.forEach(function(g){
390
- if(g.type==='click'&&g.selector){
391
- document.addEventListener('click',function(e){
392
- if(e.target&&e.target.closest&&e.target.closest(g.selector)){track('conversion',g.id)}
393
- })
394
- }
395
- if(g.type==='navigation'&&g.url){
396
- if(location.pathname===g.url||location.href.indexOf(g.url)>-1){track('conversion',g.id)}
397
- }
398
- if(g.type==='custom'&&g.event){
399
- window.addEventListener(g.event,function(){track('conversion',g.id)})
400
- }
401
- });
402
- })();`;
403
- }
404
-
405
- // build-static.ts
406
- var buildErrors = [];
407
- function hashContent(content) {
408
- return createHash("sha256").update(content).digest("hex").slice(0, 8);
409
- }
410
- function formatBunLog(log) {
411
- const parts = [];
412
- if (log.position) {
413
- const pos = log.position;
414
- if (pos.file) parts.push(`File: ${pos.file}`);
415
- if (pos.line !== void 0) parts.push(`Line ${pos.line}:${pos.column || 0}`);
416
- if (pos.lineText) parts.push(` ${pos.lineText}`);
417
- }
418
- if (log.message) {
419
- parts.push(log.message);
420
- } else if (log.text) {
421
- parts.push(log.text);
422
- }
423
- if (parts.length === 0) {
424
- try {
425
- return JSON.stringify(log, null, 2);
426
- } catch {
427
- return String(log);
428
- }
429
- }
430
- return parts.join("\n");
431
- }
432
- async function minifyJS2(code) {
433
- const result = await minifyJS(code);
434
- if (result.success) {
435
- return result.code;
436
- }
437
- throw new Error(`JavaScript minification failed:
438
- ${result.errors.join("\n\n")}`);
439
- }
440
- var jsFileCache = /* @__PURE__ */ new Map();
441
- async function getScriptPath(jsContent, distDir) {
442
- const minified = await minifyJS2(jsContent);
443
- const hash = hashContent(minified);
444
- if (jsFileCache.has(hash)) {
445
- return jsFileCache.get(hash);
446
- }
447
- const scriptsDir = join(distDir, "_scripts");
448
- if (!existsSync(scriptsDir)) {
449
- mkdirSync(scriptsDir, { recursive: true });
450
- }
451
- const scriptPath = `/_scripts/${hash}.js`;
452
- const fullPath = join(distDir, "_scripts", `${hash}.js`);
453
- await writeFile(fullPath, minified, "utf-8");
454
- jsFileCache.set(hash, scriptPath);
455
- return scriptPath;
456
- }
457
- function copyDirectory(src, dest) {
458
- if (!existsSync(src)) {
459
- return;
460
- }
461
- if (!existsSync(dest)) {
462
- mkdirSync(dest, { recursive: true });
463
- }
464
- const files = readdirSync(src);
465
- for (const file of files) {
466
- const srcPath = join(src, file);
467
- const destPath = join(dest, file);
468
- const stat = statSync(srcPath);
469
- if (stat.isDirectory()) {
470
- copyDirectory(srcPath, destPath);
471
- } else {
472
- copyFileSync(srcPath, destPath);
473
- }
474
- }
475
- }
476
- function getLocalizedOutputPath(basePath, locale, defaultLocale, distDir, slugs) {
477
- let slug;
478
- if (slugs && slugs[locale]) {
479
- slug = slugs[locale];
480
- } else if (basePath === "/") {
481
- slug = "";
482
- } else {
483
- slug = basePath.substring(1);
484
- }
485
- const fileName = slug === "" ? "index.html" : `${slug}.html`;
486
- if (locale === defaultLocale) {
487
- return `${distDir}/${fileName}`;
488
- }
489
- return `${distDir}/${locale}/${fileName}`;
490
- }
491
- function getDisplayPath(basePath, locale, defaultLocale, slugs) {
492
- let slug;
493
- if (slugs && slugs[locale]) {
494
- slug = slugs[locale];
495
- } else if (basePath === "/") {
496
- slug = "";
497
- } else {
498
- slug = basePath.substring(1);
499
- }
500
- if (locale === defaultLocale) {
501
- return slug === "" ? "/" : `/${slug}`;
502
- }
503
- return slug === "" ? `/${locale}` : `/${locale}/${slug}`;
504
- }
505
- async function generateRobotsTxt(siteUrl, distDir) {
506
- const content = `User-agent: *
507
- Allow: /
508
-
509
- Sitemap: ${siteUrl}/sitemap.xml
510
- `;
511
- await writeFile(join(distDir, "robots.txt"), content, "utf-8");
512
- }
513
- async function generateSitemap(urls, siteUrl, distDir) {
514
- const sortedUrls = [...urls].sort();
515
- const urlEntries = sortedUrls.map((url) => ` <url><loc>${siteUrl}${url}</loc></url>`).join("\n");
516
- const content = `<?xml version="1.0" encoding="UTF-8"?>
517
- <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
518
- ${urlEntries}
519
- </urlset>
520
- `;
521
- await writeFile(join(distDir, "sitemap.xml"), content, "utf-8");
522
- }
523
- function cleanDist(distDir = projectPaths.dist()) {
524
- if (!existsSync(distDir)) {
525
- mkdirSync(distDir, { recursive: true });
526
- return;
527
- }
528
- const files = readdirSync(distDir);
529
- let cleaned = 0;
530
- for (const file of files) {
531
- if (file === "fonts" || file === "images" || file === "icons" || file === "assets" || file === "videos") {
532
- continue;
533
- }
534
- try {
535
- const filePath = join(distDir, file);
536
- const stat = statSync(filePath);
537
- if (stat.isDirectory()) {
538
- rmSync(filePath, { recursive: true, force: true });
539
- } else {
540
- rmSync(filePath, { force: true });
541
- }
542
- cleaned++;
543
- } catch (error) {
544
- console.warn(`\u26A0\uFE0F Could not remove ${file}:`, error);
545
- }
546
- }
547
- if (cleaned > 0) {
548
- console.log(`\u{1F9F9} Cleaned ${cleaned} file(s) from dist
549
- `);
550
- }
551
- }
552
- function isCMSPage(pageData) {
553
- return pageData.meta?.source === "cms" && !!pageData.meta?.cms;
554
- }
555
- function buildCMSItemPath(urlPattern, item, slugField, locale, i18nConfig) {
556
- let slug = item[slugField] ?? item._slug ?? item._id;
557
- if (isI18nValue(slug)) {
558
- slug = resolveI18nValue(slug, locale, i18nConfig);
559
- }
560
- return urlPattern.replace("{{slug}}", String(slug));
561
- }
562
- async function generateStaticDataFiles(staticCollections, distDir) {
563
- if (staticCollections.size === 0) return;
564
- console.log(`
565
- \u{1F4E6} Generating static data files...`);
566
- for (const [collectionId, data] of staticCollections) {
567
- const dataDir = join(distDir, "data", collectionId);
568
- if (!existsSync(dataDir)) {
569
- mkdirSync(dataDir, { recursive: true });
570
- }
571
- const jsonPath = join(dataDir, "index.json");
572
- await writeFile(jsonPath, JSON.stringify(data.items), "utf-8");
573
- console.log(` \u2705 /data/${collectionId}/index.json (${data.items.length} items)`);
574
- }
575
- }
576
- async function buildCMSTemplates(templatesDir, globalComponents, i18nConfig, slugMappings, distDir, cmsService, generatedUrls, staticCollections, siteUrl, abTrackingScript) {
577
- let successCount = 0;
578
- let errorCount = 0;
579
- if (!existsSync(templatesDir)) {
580
- return { success: 0, errors: 0 };
581
- }
582
- const templateFiles = readdirSync(templatesDir).filter((f) => f.endsWith(".json"));
583
- if (templateFiles.length === 0) {
584
- return { success: 0, errors: 0 };
585
- }
586
- console.log(`
587
- \u{1F4DD} Processing ${templateFiles.length} CMS template(s)...
588
- `);
589
- for (const file of templateFiles) {
590
- const templateContent = await loadJSONFile(join(templatesDir, file));
591
- if (!templateContent) continue;
592
- try {
593
- const pageData = parseJSON(templateContent);
594
- const isDevBuild = process.env.MENO_DEV_BUILD === "true";
595
- if (pageData.meta?.draft === true && !isDevBuild) {
596
- console.log(`\u23ED\uFE0F Skipping draft template: ${file}`);
597
- continue;
598
- }
599
- if (!isCMSPage(pageData)) {
600
- console.warn(`\u26A0\uFE0F ${file} is in templates/ but missing meta.source: "cms"`);
601
- continue;
602
- }
603
- const cmsSchema = pageData.meta.cms;
604
- console.log(`\u{1F4DD} CMS Collection: ${cmsSchema.id}`);
605
- const items = await cmsService.queryItems({ collection: cmsSchema.id });
606
- if (items.length === 0) {
607
- console.log(` \u26A0\uFE0F No items found in cms/${cmsSchema.id}/`);
608
- continue;
609
- }
610
- console.log(` Found ${items.length} item(s)`);
611
- let clientDataCollections;
612
- if (cmsSchema.clientData?.enabled) {
613
- const publishedItems = items.filter((item) => isItemFullyPublished(item));
614
- const clientData = prepareClientData(cmsSchema.id, publishedItems, cmsSchema.clientData);
615
- if (clientData) {
616
- if (clientData.strategy === "inline") {
617
- clientDataCollections = /* @__PURE__ */ new Map([[cmsSchema.id, clientData]]);
618
- console.log(` \u{1F4E6} Client data (inline): ${clientData.items.length} items (${clientData.config.fields?.length || "all"} fields)`);
619
- } else if (clientData.strategy === "static") {
620
- staticCollections.set(cmsSchema.id, clientData);
621
- console.log(` \u{1F4E6} Client data (static): ${clientData.items.length} items \u2192 /data/${cmsSchema.id}/index.json`);
622
- }
623
- }
624
- }
625
- for (const item of items) {
626
- for (const localeConfig of i18nConfig.locales) {
627
- const locale = localeConfig.code;
628
- const isDevBuild2 = process.env.MENO_DEV_BUILD === "true";
629
- if (!isDevBuild2 && isItemDraftForLocale(item, locale)) {
630
- console.log(` \u23ED\uFE0F Skipping draft: ${item._filename || item._id} [${locale}]`);
631
- continue;
632
- }
633
- const baseUrl = siteUrl || "";
634
- const itemPath = buildCMSItemPath(cmsSchema.urlPattern, item, cmsSchema.slugField, locale, i18nConfig);
635
- const itemWithUrl = { ...item, _url: itemPath };
636
- const result = await generateSSRHTML({
637
- pageData,
638
- globalComponents,
639
- pagePath: itemPath,
640
- baseUrl,
641
- useBuiltBundle: true,
642
- locale,
643
- slugMappings,
644
- cmsContext: { cms: itemWithUrl },
645
- cmsService,
646
- returnSeparateJS: true,
647
- pageLibraries: pageData.meta?.libraries,
648
- pageCustomCode: pageData.meta?.customCode,
649
- clientDataCollections,
650
- isProductionBuild: true
651
- });
652
- let finalHtml = result.html;
653
- if (result.javascript) {
654
- const scriptPath = await getScriptPath(result.javascript, distDir);
655
- finalHtml = finalHtml.replace("</body>", ` <script src="${scriptPath}" defer></script>
656
- </body>`);
657
- }
658
- if (abTrackingScript) {
659
- finalHtml = injectTrackingScript(finalHtml, abTrackingScript);
660
- }
661
- const outputPath = locale === i18nConfig.defaultLocale ? `${distDir}${itemPath}.html` : `${distDir}/${locale}${itemPath}.html`;
662
- const outputDir = outputPath.substring(0, outputPath.lastIndexOf("/"));
663
- if (outputDir && !existsSync(outputDir)) {
664
- mkdirSync(outputDir, { recursive: true });
665
- }
666
- await writeFile(outputPath, finalHtml, "utf-8");
667
- const displayPath = locale === i18nConfig.defaultLocale ? itemPath : `/${locale}${itemPath}`;
668
- generatedUrls.add(displayPath);
669
- console.log(` \u2705 ${displayPath}`);
670
- successCount++;
671
- }
672
- }
673
- } catch (error) {
674
- let errorMessage;
675
- if (error instanceof Error) {
676
- if ("errors" in error && Array.isArray(error.errors)) {
677
- errorMessage = error.errors.map((e) => e.stack || e.message || String(e)).join("\n\n");
678
- } else if (error.cause) {
679
- const causeMsg = error.cause instanceof Error ? error.cause.stack || error.cause.message : String(error.cause);
680
- errorMessage = `${error.stack || error.message}
681
-
682
- Caused by:
683
- ${causeMsg}`;
684
- } else if ("logs" in error && Array.isArray(error.logs)) {
685
- errorMessage = error.logs.map(formatBunLog).join("\n\n");
686
- } else {
687
- errorMessage = error.stack || error.message;
688
- }
689
- } else if (typeof error === "object" && error !== null) {
690
- if (error.logs && Array.isArray(error.logs)) {
691
- errorMessage = error.logs.map(formatBunLog).join("\n\n");
692
- } else {
693
- errorMessage = String(error);
694
- }
695
- } else {
696
- errorMessage = String(error);
697
- }
698
- if (errorMessage === "Bundle failed" || errorMessage.includes("Bundle failed\n")) {
699
- try {
700
- const inspected = inspect(error);
701
- if (inspected && inspected !== "[object Object]" && inspected.length > errorMessage.length) {
702
- errorMessage = inspected;
703
- }
704
- } catch {
705
- }
706
- }
707
- console.error(`\u274C Error processing ${file}:`, error);
708
- buildErrors.push({
709
- file: `templates/${file}`,
710
- message: errorMessage,
711
- type: errorMessage.includes("minification") || errorMessage.includes("minify") ? "minify" : "cms"
712
- });
713
- errorCount++;
714
- }
715
- }
716
- return { success: successCount, errors: errorCount };
717
- }
718
- async function loadRunningExperiments() {
719
- const experimentsPath = join(projectPaths.project, "experiments.json");
720
- if (!existsSync(experimentsPath)) return [];
721
- try {
722
- const content = await readFile(experimentsPath, "utf-8");
723
- const data = JSON.parse(content);
724
- const experiments = data.experiments || [];
725
- return experiments.filter((e) => e.status === "running");
726
- } catch {
727
- return [];
728
- }
729
- }
730
- function injectTrackingScript(html, trackingJs) {
731
- const scriptTag = `<script>${trackingJs}</script>`;
732
- return html.replace("</head>", `${scriptTag}
733
- </head>`);
734
- }
735
- async function generateABFunctions(experiments, distDir) {
736
- const middlewareContent = generateMiddleware(experiments);
737
- if (middlewareContent) {
738
- const middlewarePath = join(distDir, "functions", "_middleware.ts");
739
- const middlewareDir = join(distDir, "functions");
740
- if (!existsSync(middlewareDir)) {
741
- mkdirSync(middlewareDir, { recursive: true });
742
- }
743
- await writeFile(middlewarePath, middlewareContent, "utf-8");
744
- }
745
- const trackContent = generateTrackFunction();
746
- const trackDir = join(distDir, "functions", "api");
747
- if (!existsSync(trackDir)) {
748
- mkdirSync(trackDir, { recursive: true });
749
- }
750
- await writeFile(join(trackDir, "ab-track.ts"), trackContent, "utf-8");
751
- const resultsContent = generateResultsFunction();
752
- await writeFile(join(trackDir, "ab-results.ts"), resultsContent, "utf-8");
753
- }
754
- async function buildStaticPages(outDir) {
755
- console.log("\u{1F3D7}\uFE0F Building static HTML files...\n");
756
- buildErrors.length = 0;
757
- clearJSValidationCache();
758
- const { configService } = await import("./configService-R3OGU2UD.js");
759
- configService.reset();
760
- const projectConfig = await loadProjectConfig();
761
- const siteUrl = projectConfig.siteUrl?.replace(/\/$/, "");
762
- const generatedUrls = /* @__PURE__ */ new Set();
763
- const runningExperiments = await loadRunningExperiments();
764
- let trackingScript = null;
765
- if (runningExperiments.length > 0) {
766
- const exp = runningExperiments[0];
767
- trackingScript = generateTrackingScript(exp.id, exp.conversionGoals);
768
- console.log(`\u{1F9EA} A/B experiment active: "${exp.name}" (${exp.variants.length} variant(s))
769
- `);
770
- }
771
- const i18nConfig = await loadI18nConfig();
772
- console.log(`\u{1F310} Locales: ${i18nConfig.locales.map((l) => l.code).join(", ")} (default: ${i18nConfig.defaultLocale})
773
- `);
774
- await migrateTemplatesDirectory();
775
- const distDir = outDir || projectPaths.dist();
776
- cleanDist(distDir);
777
- jsFileCache.clear();
778
- console.log("\u{1F4E6} Copying assets...");
779
- const errorsPath = join(distDir, "_errors.json");
780
- if (existsSync(errorsPath)) {
781
- unlinkSync(errorsPath);
782
- }
783
- copyDirectory(projectPaths.fonts(), join(distDir, "fonts"));
784
- copyDirectory(projectPaths.images(), join(distDir, "images"));
785
- copyDirectory(projectPaths.icons(), join(distDir, "icons"));
786
- copyDirectory(projectPaths.assets(), join(distDir, "assets"));
787
- copyDirectory(projectPaths.videos(), join(distDir, "videos"));
788
- const librariesDir = join(projectPaths.project, "libraries");
789
- if (existsSync(librariesDir)) {
790
- copyDirectory(librariesDir, join(distDir, "libraries"));
791
- }
792
- const functionsDir = projectPaths.functions();
793
- if (existsSync(functionsDir)) {
794
- copyDirectory(functionsDir, join(distDir, "functions"));
795
- }
796
- const hostingFiles = [];
797
- const rootFilesToCopy = [
798
- "_headers",
799
- // Netlify/Cloudflare headers
800
- "_redirects",
801
- // Netlify/Cloudflare redirects
802
- "llms.txt",
803
- // LLM context
804
- "humans.txt",
805
- // Team credits
806
- "ads.txt",
807
- // Ad verification
808
- "security.txt",
809
- // Security contact
810
- "CNAME",
811
- // GitHub Pages domain
812
- "manifest.json",
813
- // PWA manifest
814
- "site.webmanifest"
815
- // PWA manifest (alt)
816
- ];
817
- for (const file of rootFilesToCopy) {
818
- const filePath = join(projectPaths.project, file);
819
- if (existsSync(filePath)) {
820
- copyFileSync(filePath, join(distDir, file));
821
- hostingFiles.push(file);
822
- }
823
- }
824
- const wellKnownDir = join(projectPaths.project, ".well-known");
825
- if (existsSync(wellKnownDir)) {
826
- copyDirectory(wellKnownDir, join(distDir, ".well-known"));
827
- hostingFiles.push(".well-known/");
828
- }
829
- const parts = ["Assets"];
830
- if (existsSync(functionsDir)) parts.push("functions");
831
- if (hostingFiles.length > 0) parts.push(hostingFiles.join(", "));
832
- console.log(`\u2705 ${parts.join(", ")} copied
833
- `);
834
- const { components, warnings, errors } = await loadComponentDirectory(projectPaths.components());
835
- const globalComponents = {};
836
- components.forEach((value, key) => {
837
- globalComponents[key] = value;
838
- });
839
- for (const warning of warnings) console.warn(`\u26A0\uFE0F ${warning}`);
840
- for (const error of errors) console.error(`\u274C ${error}`);
841
- console.log(`\u2705 Loaded ${components.size} global component(s)
842
- `);
843
- const cmsProvider = new FileSystemCMSProvider(projectPaths.templates(), projectPaths.cms());
844
- const cmsService = new CMSService(cmsProvider);
845
- await cmsService.initialize();
846
- console.log(`\u2705 CMS service initialized
847
- `);
848
- const pagesDir = projectPaths.pages();
849
- if (!existsSync(pagesDir)) {
850
- console.error("\u274C Pages directory not found!");
851
- process.exit(1);
852
- }
853
- const pageFiles = [];
854
- function scanPagesDir(dir, prefix) {
855
- const entries = readdirSync(dir, { withFileTypes: true });
856
- for (const entry of entries) {
857
- if (entry.isFile() && entry.name.endsWith(".json")) {
858
- pageFiles.push(prefix ? `${prefix}/${entry.name}` : entry.name);
859
- } else if (entry.isDirectory()) {
860
- scanPagesDir(join(dir, entry.name), prefix ? `${prefix}/${entry.name}` : entry.name);
861
- }
862
- }
863
- }
864
- scanPagesDir(pagesDir, "");
865
- if (pageFiles.length === 0) {
866
- console.warn("\u26A0\uFE0F No pages found in ./pages directory");
867
- return;
868
- }
869
- console.log(`\u{1F4C4} Found ${pageFiles.length} page(s) to build
870
- `);
871
- const slugMappings = [];
872
- const allPageLibraries = [];
873
- for (const file of pageFiles) {
874
- const pageName = file.replace(".json", "");
875
- const basePath = mapPageNameToPath(pageName);
876
- const pageContent = await loadJSONFile(join(pagesDir, file));
877
- if (pageContent) {
878
- try {
879
- const pageData = parseJSON(pageContent);
880
- if (pageData.meta?.slugs) {
881
- const pageId = basePath === "/" ? "index" : basePath.substring(1);
882
- slugMappings.push({ pageId, slugs: pageData.meta.slugs });
883
- }
884
- if (pageData.meta?.libraries) {
885
- allPageLibraries.push(pageData.meta.libraries);
886
- }
887
- } catch {
888
- }
889
- }
890
- }
891
- {
892
- await configService.load();
893
- const cspConfig = configService.getCSP();
894
- if (cspConfig && Object.keys(cspConfig).length > 0) {
895
- const globalLibraries = configService.getLibraries();
896
- const componentLibraries = collectComponentLibraries(globalComponents);
897
- const allJs = [
898
- ...globalLibraries.js || [],
899
- ...componentLibraries.js || [],
900
- ...allPageLibraries.flatMap((p) => p.js || [])
901
- ];
902
- const allCss = [
903
- ...globalLibraries.css || [],
904
- ...componentLibraries.css || [],
905
- ...allPageLibraries.flatMap((p) => p.css || [])
906
- ];
907
- const allLibs = { js: allJs, css: allCss };
908
- const buildLibs = filterLibrariesByContext(allLibs, "build");
909
- const { scriptOrigins, styleOrigins } = extractLibraryOrigins(buildLibs);
910
- const extraScripts = [
911
- ...cspConfig.scriptSrc || [],
912
- ...Array.from(scriptOrigins)
913
- ].join(" ");
914
- const extraStyles = [
915
- ...cspConfig.styleSrc || [],
916
- ...Array.from(styleOrigins)
917
- ].join(" ");
918
- const extraConnect = cspConfig.connectSrc?.join(" ") || "";
919
- const extraFrames = cspConfig.frameSrc?.join(" ") || "";
920
- const extraFonts = cspConfig.fontSrc?.join(" ") || "";
921
- const extraImgs = cspConfig.imgSrc?.join(" ") || "";
922
- const cspDirectives = [
923
- "default-src 'self'",
924
- `script-src 'self' https://f.vimeocdn.com https://player.vimeo.com https://www.youtube.com https://s.ytimg.com ${extraScripts}`.trim(),
925
- `style-src 'self' 'unsafe-inline' https://f.vimeocdn.com ${extraStyles}`.trim(),
926
- `img-src 'self' data: https: ${extraImgs}`.trim(),
927
- `connect-src 'self' https://vimeo.com https://*.vimeocdn.com ${extraConnect}`.trim(),
928
- `frame-src https://player.vimeo.com https://vimeo.com https://www.youtube.com https://www.youtube-nocookie.com ${extraFrames}`.trim(),
929
- `font-src 'self' data: ${extraFonts}`.trim(),
930
- "media-src 'self' https: blob:"
931
- ].join("; ");
932
- const headersContent = `/*
933
- Content-Security-Policy: ${cspDirectives}
934
- `;
935
- writeFileSync(join(distDir, "_headers"), headersContent);
936
- console.log(`\u2705 Generated _headers with CSP (auto-included ${scriptOrigins.size + styleOrigins.size} library origin(s))
937
- `);
938
- }
939
- }
940
- let successCount = 0;
941
- let errorCount = 0;
942
- for (const file of pageFiles) {
943
- const pageName = file.replace(".json", "");
944
- const basePath = mapPageNameToPath(pageName);
945
- const pageContent = await loadJSONFile(join(pagesDir, file));
946
- if (!pageContent) {
947
- console.warn(`\u26A0\uFE0F Skipping ${basePath} (empty file)`);
948
- errorCount++;
949
- continue;
950
- }
951
- try {
952
- const pageData = parseJSON(pageContent);
953
- const isDevBuild = process.env.MENO_DEV_BUILD === "true";
954
- if (pageData.meta?.draft === true && !isDevBuild) {
955
- console.log(`\u23ED\uFE0F Skipping draft: ${basePath}`);
956
- continue;
957
- }
958
- const slugs = pageData.meta?.slugs;
959
- for (const localeConfig of i18nConfig.locales) {
960
- const locale = localeConfig.code;
961
- const baseUrl = siteUrl || "";
962
- const urlPath = getDisplayPath(basePath, locale, i18nConfig.defaultLocale, slugs);
963
- const result = await generateSSRHTML({
964
- pageData,
965
- globalComponents,
966
- pagePath: urlPath,
967
- baseUrl,
968
- useBuiltBundle: true,
969
- locale,
970
- slugMappings,
971
- cmsService,
972
- returnSeparateJS: true,
973
- pageLibraries: pageData.meta?.libraries,
974
- pageCustomCode: pageData.meta?.customCode,
975
- isProductionBuild: true
976
- });
977
- let finalHtml = result.html;
978
- if (result.javascript) {
979
- const scriptPath = await getScriptPath(result.javascript, distDir);
980
- finalHtml = finalHtml.replace("</body>", ` <script src="${scriptPath}" defer></script>
981
- </body>`);
982
- }
983
- if (trackingScript) {
984
- finalHtml = injectTrackingScript(finalHtml, trackingScript);
985
- }
986
- const outputPath = getLocalizedOutputPath(basePath, locale, i18nConfig.defaultLocale, distDir, slugs);
987
- const outputDir = outputPath.substring(0, outputPath.lastIndexOf("/"));
988
- if (outputDir && !existsSync(outputDir)) {
989
- mkdirSync(outputDir, { recursive: true });
990
- }
991
- if (urlPath === "/") {
992
- console.log("[DEBUG] Last 500 chars of HTML:", finalHtml.slice(-500));
993
- }
994
- await writeFile(outputPath, finalHtml, "utf-8");
995
- generatedUrls.add(urlPath);
996
- console.log(`\u2705 Built: ${urlPath} \u2192 ${outputPath}`);
997
- successCount++;
998
- }
999
- } catch (error) {
1000
- let errorMessage;
1001
- if (error instanceof Error) {
1002
- if ("errors" in error && Array.isArray(error.errors)) {
1003
- errorMessage = error.errors.map((e) => e.stack || e.message || String(e)).join("\n\n");
1004
- } else if (error.cause) {
1005
- const causeMsg = error.cause instanceof Error ? error.cause.stack || error.cause.message : String(error.cause);
1006
- errorMessage = `${error.stack || error.message}
1007
-
1008
- Caused by:
1009
- ${causeMsg}`;
1010
- } else if ("logs" in error && Array.isArray(error.logs)) {
1011
- errorMessage = error.logs.map(formatBunLog).join("\n\n");
1012
- } else {
1013
- errorMessage = error.stack || error.message;
1014
- }
1015
- } else if (typeof error === "object" && error !== null) {
1016
- if (error.logs && Array.isArray(error.logs)) {
1017
- errorMessage = error.logs.map(formatBunLog).join("\n\n");
1018
- } else {
1019
- errorMessage = String(error);
1020
- }
1021
- } else {
1022
- errorMessage = String(error);
1023
- }
1024
- if (errorMessage === "Bundle failed" || errorMessage.includes("Bundle failed\n")) {
1025
- try {
1026
- const inspected = inspect(error);
1027
- if (inspected && inspected !== "[object Object]" && inspected.length > errorMessage.length) {
1028
- errorMessage = inspected;
1029
- }
1030
- } catch {
1031
- }
1032
- }
1033
- console.error(`\u274C Error building ${basePath}:`, error);
1034
- buildErrors.push({
1035
- file: `pages/${file}`,
1036
- message: errorMessage,
1037
- type: errorMessage.includes("minification") || errorMessage.includes("minify") ? "minify" : "render"
1038
- });
1039
- errorCount++;
1040
- }
1041
- }
1042
- const templatesDir = projectPaths.templates();
1043
- const staticCollections = /* @__PURE__ */ new Map();
1044
- const cmsResult = await buildCMSTemplates(
1045
- templatesDir,
1046
- globalComponents,
1047
- i18nConfig,
1048
- slugMappings,
1049
- distDir,
1050
- cmsService,
1051
- generatedUrls,
1052
- staticCollections,
1053
- siteUrl,
1054
- trackingScript
1055
- );
1056
- successCount += cmsResult.success;
1057
- errorCount += cmsResult.errors;
1058
- await generateStaticDataFiles(staticCollections, distDir);
1059
- if (runningExperiments.length > 0) {
1060
- await generateABFunctions(runningExperiments, distDir);
1061
- console.log(`
1062
- \u{1F9EA} A/B testing functions generated (middleware, tracker, results API)`);
1063
- }
1064
- if (siteUrl) {
1065
- await generateRobotsTxt(siteUrl, distDir);
1066
- await generateSitemap([...generatedUrls], siteUrl, distDir);
1067
- console.log(`
1068
- \u{1F50D} SEO files generated (robots.txt, sitemap.xml)`);
1069
- } else {
1070
- console.warn(`
1071
- \u26A0\uFE0F Skipping SEO files: siteUrl not configured in project.config.json`);
1072
- }
1073
- console.log("\n" + "=".repeat(50));
1074
- console.log(`\u2728 Build complete!`);
1075
- console.log(` \u2705 Success: ${successCount}`);
1076
- if (errorCount > 0) {
1077
- console.log(` \u274C Errors: ${errorCount}`);
1078
- }
1079
- console.log(`
1080
- \u{1F4E6} Production files in /dist:`);
1081
- console.log(` - *.html (Static pages with vanilla JS)`);
1082
- console.log(` - fonts/ (Custom fonts)`);
1083
- console.log(` - images/ (Image assets)`);
1084
- console.log(` - icons/ (Favicon and icons)`);
1085
- if (staticCollections.size > 0) {
1086
- console.log(` - data/ (CMS collection data for client filtering)`);
1087
- }
1088
- if (existsSync(functionsDir)) {
1089
- console.log(` - functions/ (Cloudflare Pages Functions)`);
1090
- }
1091
- if (runningExperiments.length > 0) {
1092
- console.log(` - A/B testing (middleware + tracking injected)`);
1093
- }
1094
- if (siteUrl) {
1095
- console.log(` - robots.txt, sitemap.xml (SEO)`);
1096
- }
1097
- console.log(` - No React, no client-router \u2713`);
1098
- const jsErrors = getJSValidationErrors();
1099
- for (const { component, error } of jsErrors) {
1100
- buildErrors.push({
1101
- file: `components/${component}`,
1102
- message: error,
1103
- type: "minify"
1104
- });
1105
- }
1106
- if (buildErrors.length > 0) {
1107
- const seenMessages = /* @__PURE__ */ new Set();
1108
- const uniqueErrors = buildErrors.filter((err) => {
1109
- if (seenMessages.has(err.message)) return false;
1110
- seenMessages.add(err.message);
1111
- return true;
1112
- });
1113
- const errorsData = {
1114
- errors: uniqueErrors,
1115
- timestamp: Date.now()
1116
- };
1117
- await writeFile(errorsPath, JSON.stringify(errorsData, null, 2), "utf-8");
1118
- const countMsg = uniqueErrors.length === buildErrors.length ? `${uniqueErrors.length} error${uniqueErrors.length === 1 ? "" : "s"}` : `${uniqueErrors.length} unique error${uniqueErrors.length === 1 ? "" : "s"} (affected ${buildErrors.length} files)`;
1119
- console.log(`
1120
- \u26A0\uFE0F Build errors written to dist/_errors.json (${countMsg})`);
1121
- }
1122
- }
1123
-
1124
- export {
1125
- hashContent,
1126
- formatBunLog,
1127
- getLocalizedOutputPath,
1128
- getDisplayPath,
1129
- generateRobotsTxt,
1130
- generateSitemap,
1131
- isCMSPage,
1132
- buildCMSItemPath,
1133
- injectTrackingScript,
1134
- buildStaticPages
1135
- };
1136
- //# sourceMappingURL=chunk-JGP5A3Y5.js.map