meno-core 1.0.53 → 1.0.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (387) hide show
  1. package/.claude/settings.local.json +1 -3
  2. package/bin/cli.ts +48 -57
  3. package/build-astro.ts +131 -113
  4. package/build-next.ts +109 -96
  5. package/build-static.test.ts +39 -10
  6. package/build-static.ts +120 -122
  7. package/dist/bin/cli.js +34 -38
  8. package/dist/bin/cli.js.map +2 -2
  9. package/dist/build-static.js +12 -11
  10. package/dist/chunks/chunk-2AR55GYH.js +42 -0
  11. package/dist/chunks/chunk-2AR55GYH.js.map +7 -0
  12. package/dist/chunks/{chunk-IGYR22T6.js → chunk-2FN4UOVO.js} +512 -239
  13. package/dist/chunks/chunk-2FN4UOVO.js.map +7 -0
  14. package/dist/chunks/chunk-3XER4E5W.js +168 -0
  15. package/dist/chunks/chunk-3XER4E5W.js.map +7 -0
  16. package/dist/chunks/{chunk-X754AHS5.js → chunk-5ETZFREW.js} +9 -12
  17. package/dist/chunks/chunk-5ETZFREW.js.map +7 -0
  18. package/dist/chunks/{chunk-2MHDV5BF.js → chunk-7E4IF5L7.js} +15 -21
  19. package/dist/chunks/chunk-7E4IF5L7.js.map +7 -0
  20. package/dist/chunks/{chunk-JGWFTO6P.js → chunk-7HWQUVTU.js} +1578 -1349
  21. package/dist/chunks/chunk-7HWQUVTU.js.map +7 -0
  22. package/dist/chunks/{chunk-O3NAGJP4.js → chunk-AE3QK5QW.js} +110 -21
  23. package/dist/chunks/chunk-AE3QK5QW.js.map +7 -0
  24. package/dist/chunks/{chunk-GZHGVVW3.js → chunk-F6KTJYGV.js} +7 -7
  25. package/dist/chunks/chunk-F6KTJYGV.js.map +7 -0
  26. package/dist/chunks/{chunk-WQFG7PAH.js → chunk-FZITJSSS.js} +2 -6
  27. package/dist/chunks/chunk-FZITJSSS.js.map +7 -0
  28. package/dist/chunks/{chunk-QB2LNO4W.js → chunk-GSYYA5GX.js} +2 -2
  29. package/dist/chunks/chunk-GSYYA5GX.js.map +7 -0
  30. package/dist/chunks/{chunk-YBLHKYFF.js → chunk-HIZMY3EP.js} +1 -1
  31. package/dist/chunks/chunk-HIZMY3EP.js.map +7 -0
  32. package/dist/chunks/{chunk-AZQYF6KE.js → chunk-I2WEGYA7.js} +41 -176
  33. package/dist/chunks/chunk-I2WEGYA7.js.map +7 -0
  34. package/dist/chunks/{chunk-I7YIGZXT.js → chunk-JNO3CNLJ.js} +6 -9
  35. package/dist/chunks/chunk-JNO3CNLJ.js.map +7 -0
  36. package/dist/chunks/{chunk-UB44F4Z2.js → chunk-NVRBTSQG.js} +2 -4
  37. package/dist/chunks/chunk-NVRBTSQG.js.map +7 -0
  38. package/dist/chunks/{chunk-JGP5A3Y5.js → chunk-Q4OBWKXG.js} +40 -33
  39. package/dist/chunks/chunk-Q4OBWKXG.js.map +7 -0
  40. package/dist/chunks/{chunk-R6XHAFBF.js → chunk-QTE32Y53.js} +250 -242
  41. package/dist/chunks/chunk-QTE32Y53.js.map +7 -0
  42. package/dist/chunks/{chunk-H3GJ4H2U.js → chunk-STDY3OVM.js} +214 -85
  43. package/dist/chunks/chunk-STDY3OVM.js.map +7 -0
  44. package/dist/chunks/configService-PRJZF7Y6.js +14 -0
  45. package/dist/chunks/{constants-STK2YBIW.js → constants-KIQEYMAM.js} +2 -2
  46. package/dist/chunks/{fs-JGINUXGL.js → fs-ZI5JEU7V.js} +2 -2
  47. package/dist/entries/server-router.js +14 -19
  48. package/dist/entries/server-router.js.map +2 -2
  49. package/dist/lib/client/index.js +638 -332
  50. package/dist/lib/client/index.js.map +2 -2
  51. package/dist/lib/server/index.js +177 -235
  52. package/dist/lib/server/index.js.map +2 -2
  53. package/dist/lib/shared/index.js +80 -44
  54. package/dist/lib/shared/index.js.map +2 -2
  55. package/dist/lib/shared/richtext/index.js +1 -1
  56. package/dist/lib/test-utils/index.js +38 -60
  57. package/dist/lib/test-utils/index.js.map +2 -2
  58. package/entries/client-router.tsx +10 -8
  59. package/entries/server-router.tsx +1 -7
  60. package/lib/client/ClientInitializer.ts +8 -8
  61. package/lib/client/ErrorBoundary.test.tsx +146 -143
  62. package/lib/client/ErrorBoundary.tsx +175 -127
  63. package/lib/client/componentRegistry.test.ts +96 -108
  64. package/lib/client/componentRegistry.ts +1 -2
  65. package/lib/client/contexts/ThemeContext.tsx +3 -2
  66. package/lib/client/core/ComponentBuilder.test.ts +513 -560
  67. package/lib/client/core/ComponentBuilder.ts +318 -146
  68. package/lib/client/core/ComponentRenderer.test.tsx +1 -2
  69. package/lib/client/core/ComponentRenderer.tsx +46 -33
  70. package/lib/client/core/builders/embedBuilder.ts +241 -53
  71. package/lib/client/core/builders/linkBuilder.ts +71 -44
  72. package/lib/client/core/builders/linkNodeBuilder.ts +78 -53
  73. package/lib/client/core/builders/listBuilder.ts +115 -86
  74. package/lib/client/core/builders/localeListBuilder.ts +95 -60
  75. package/lib/client/core/builders/types.ts +5 -5
  76. package/lib/client/core/cmsTemplateProcessor.ts +7 -7
  77. package/lib/client/elementRegistry.ts +3 -3
  78. package/lib/client/fontFamiliesService.test.ts +2 -10
  79. package/lib/client/fontFamiliesService.ts +3 -3
  80. package/lib/client/hmr/HMRManager.tsx +8 -0
  81. package/lib/client/hmrCssReload.ts +14 -8
  82. package/lib/client/hmrWebSocket.ts +9 -14
  83. package/lib/client/hooks/useColorVariables.test.ts +21 -21
  84. package/lib/client/hooks/useColorVariables.ts +12 -10
  85. package/lib/client/hooks/usePropertyAutocomplete.ts +3 -5
  86. package/lib/client/hooks/useVariables.ts +4 -4
  87. package/lib/client/hydration/HydrationUtils.test.ts +24 -25
  88. package/lib/client/hydration/HydrationUtils.ts +3 -4
  89. package/lib/client/i18nConfigService.test.ts +2 -7
  90. package/lib/client/i18nConfigService.ts +2 -2
  91. package/lib/client/meno-filter/MenoFilter.test.ts +19 -21
  92. package/lib/client/meno-filter/MenoFilter.ts +5 -9
  93. package/lib/client/meno-filter/bindings.ts +15 -40
  94. package/lib/client/meno-filter/init.ts +1 -1
  95. package/lib/client/meno-filter/renderer.ts +23 -29
  96. package/lib/client/meno-filter/script.generated.ts +1 -3
  97. package/lib/client/meno-filter/ui.ts +3 -5
  98. package/lib/client/meno-filter/updates.ts +15 -21
  99. package/lib/client/navigation.test.ts +159 -159
  100. package/lib/client/navigation.ts +0 -1
  101. package/lib/client/responsiveStyleResolver.test.ts +230 -228
  102. package/lib/client/responsiveStyleResolver.ts +13 -16
  103. package/lib/client/routing/RouteLoader.test.ts +23 -24
  104. package/lib/client/routing/RouteLoader.ts +22 -35
  105. package/lib/client/routing/Router.tsx +31 -3
  106. package/lib/client/scripts/ScriptExecutor.test.ts +157 -158
  107. package/lib/client/scripts/ScriptExecutor.ts +15 -33
  108. package/lib/client/services/PrefetchService.test.ts +2 -2
  109. package/lib/client/services/PrefetchService.ts +10 -24
  110. package/lib/client/styleProcessor.test.ts +9 -9
  111. package/lib/client/styleProcessor.ts +18 -15
  112. package/lib/client/styles/StyleInjector.test.ts +122 -115
  113. package/lib/client/styles/StyleInjector.ts +9 -6
  114. package/lib/client/styles/UtilityClassCollector.ts +19 -26
  115. package/lib/client/styles/cspNonce.test.ts +2 -5
  116. package/lib/client/templateEngine.test.ts +554 -482
  117. package/lib/client/templateEngine.ts +200 -64
  118. package/lib/client/theme.ts +0 -1
  119. package/lib/client/utils/toast.ts +0 -1
  120. package/lib/server/__integration__/api-routes.test.ts +8 -4
  121. package/lib/server/__integration__/cms-integration.test.ts +1 -4
  122. package/lib/server/__integration__/server-lifecycle.test.ts +2 -5
  123. package/lib/server/__integration__/ssr-rendering.test.ts +47 -37
  124. package/lib/server/__integration__/static-assets.test.ts +1 -1
  125. package/lib/server/__integration__/test-helpers.ts +84 -70
  126. package/lib/server/ab/generateFunctions.ts +12 -10
  127. package/lib/server/astro/cmsPageEmitter.ts +23 -38
  128. package/lib/server/astro/componentEmitter.ts +25 -36
  129. package/lib/server/astro/cssCollector.ts +10 -26
  130. package/lib/server/astro/nodeToAstro.test.ts +1750 -30
  131. package/lib/server/astro/nodeToAstro.ts +198 -187
  132. package/lib/server/astro/normalizeOrphanTemplateProps.test.ts +105 -109
  133. package/lib/server/astro/normalizeOrphanTemplateProps.ts +4 -12
  134. package/lib/server/astro/pageEmitter.ts +9 -13
  135. package/lib/server/astro/tailwindMapper.test.ts +10 -37
  136. package/lib/server/astro/tailwindMapper.ts +33 -40
  137. package/lib/server/astro/templateTransformer.ts +14 -17
  138. package/lib/server/createServer.ts +5 -17
  139. package/lib/server/cssGenerator.test.ts +35 -44
  140. package/lib/server/cssGenerator.ts +6 -17
  141. package/lib/server/fileWatcher.test.ts +124 -10
  142. package/lib/server/fileWatcher.ts +124 -118
  143. package/lib/server/index.ts +7 -1
  144. package/lib/server/jsonLoader.test.ts +39 -2
  145. package/lib/server/jsonLoader.ts +33 -31
  146. package/lib/server/middleware/cors.test.ts +20 -20
  147. package/lib/server/middleware/cors.ts +28 -4
  148. package/lib/server/middleware/errorHandler.test.ts +5 -3
  149. package/lib/server/middleware/errorHandler.ts +3 -8
  150. package/lib/server/middleware/index.ts +0 -1
  151. package/lib/server/middleware/logger.test.ts +7 -5
  152. package/lib/server/middleware/logger.ts +10 -22
  153. package/lib/server/pageCache.test.ts +76 -77
  154. package/lib/server/pageCache.ts +0 -1
  155. package/lib/server/projectContext.ts +4 -3
  156. package/lib/server/providers/fileSystemCMSProvider.test.ts +124 -95
  157. package/lib/server/providers/fileSystemCMSProvider.ts +35 -20
  158. package/lib/server/providers/fileSystemPageProvider.test.ts +84 -0
  159. package/lib/server/providers/fileSystemPageProvider.ts +31 -12
  160. package/lib/server/routes/api/cms.test.ts +26 -14
  161. package/lib/server/routes/api/cms.ts +9 -14
  162. package/lib/server/routes/api/components.ts +30 -34
  163. package/lib/server/routes/api/config.ts +0 -1
  164. package/lib/server/routes/api/core-routes.ts +47 -74
  165. package/lib/server/routes/api/functions.ts +8 -16
  166. package/lib/server/routes/api/index.ts +3 -6
  167. package/lib/server/routes/api/pages.ts +8 -11
  168. package/lib/server/routes/api/shared.test.ts +1 -1
  169. package/lib/server/routes/api/shared.ts +12 -9
  170. package/lib/server/routes/api/variables.test.ts +1 -3
  171. package/lib/server/routes/api/variables.ts +1 -1
  172. package/lib/server/routes/index.ts +23 -26
  173. package/lib/server/routes/pages.ts +34 -29
  174. package/lib/server/routes/static.ts +16 -4
  175. package/lib/server/runtime/bundler.ts +47 -32
  176. package/lib/server/runtime/fs.ts +3 -13
  177. package/lib/server/runtime/httpServer.ts +5 -9
  178. package/lib/server/services/ColorService.ts +32 -27
  179. package/lib/server/services/EnumService.test.ts +2 -6
  180. package/lib/server/services/EnumService.ts +7 -2
  181. package/lib/server/services/VariableService.test.ts +1 -5
  182. package/lib/server/services/VariableService.ts +6 -1
  183. package/lib/server/services/cmsService.test.ts +116 -78
  184. package/lib/server/services/cmsService.ts +24 -54
  185. package/lib/server/services/componentService.test.ts +122 -36
  186. package/lib/server/services/componentService.ts +54 -38
  187. package/lib/server/services/configService.test.ts +9 -31
  188. package/lib/server/services/configService.ts +20 -27
  189. package/lib/server/services/fileWatcherService.ts +40 -6
  190. package/lib/server/services/index.ts +0 -1
  191. package/lib/server/services/pageService.test.ts +1 -3
  192. package/lib/server/services/pageService.ts +14 -13
  193. package/lib/server/ssr/attributeBuilder.ts +16 -6
  194. package/lib/server/ssr/buildErrorOverlay.ts +11 -12
  195. package/lib/server/ssr/clientDataInjector.ts +7 -21
  196. package/lib/server/ssr/cmsSSRProcessor.ts +3 -6
  197. package/lib/server/ssr/cssCollector.ts +1 -1
  198. package/lib/server/ssr/errorOverlay.test.ts +1 -1
  199. package/lib/server/ssr/errorOverlay.ts +3 -9
  200. package/lib/server/ssr/htmlGenerator.nonce.test.ts +3 -9
  201. package/lib/server/ssr/htmlGenerator.test.ts +120 -43
  202. package/lib/server/ssr/htmlGenerator.ts +120 -85
  203. package/lib/server/ssr/imageMetadata.test.ts +3 -1
  204. package/lib/server/ssr/imageMetadata.ts +25 -19
  205. package/lib/server/ssr/jsCollector.test.ts +3 -13
  206. package/lib/server/ssr/jsCollector.ts +3 -8
  207. package/lib/server/ssr/liveReloadIntegration.test.ts +69 -28
  208. package/lib/server/ssr/metaTagGenerator.ts +2 -2
  209. package/lib/server/ssr/ssrRenderer.branches.test.ts +1103 -0
  210. package/lib/server/ssr/ssrRenderer.test.ts +196 -246
  211. package/lib/server/ssr/ssrRenderer.ts +609 -225
  212. package/lib/server/ssrRenderer.test.ts +1044 -950
  213. package/lib/server/utils/jsonLineMapper.test.ts +28 -28
  214. package/lib/server/utils/jsonLineMapper.ts +1 -1
  215. package/lib/server/validateStyleCoverage.ts +18 -20
  216. package/lib/server/webflow/buildWebflow.ts +41 -53
  217. package/lib/server/webflow/nodeToWebflow.test.ts +150 -218
  218. package/lib/server/webflow/nodeToWebflow.ts +195 -258
  219. package/lib/server/webflow/styleMapper.test.ts +15 -56
  220. package/lib/server/webflow/styleMapper.ts +33 -41
  221. package/lib/server/webflow/types.ts +1 -8
  222. package/lib/server/websocketManager.ts +16 -19
  223. package/lib/shared/attributeNodeUtils.test.ts +15 -15
  224. package/lib/shared/attributeNodeUtils.ts +5 -12
  225. package/lib/shared/breakpoints.ts +4 -11
  226. package/lib/shared/cmsQueryParser.test.ts +50 -42
  227. package/lib/shared/cmsQueryParser.ts +49 -31
  228. package/lib/shared/colorVariableUtils.test.ts +5 -5
  229. package/lib/shared/colorVariableUtils.ts +3 -8
  230. package/lib/shared/componentRefs.ts +1 -5
  231. package/lib/shared/constants.test.ts +3 -3
  232. package/lib/shared/constants.ts +4 -8
  233. package/lib/shared/cssGeneration.test.ts +262 -144
  234. package/lib/shared/cssGeneration.ts +189 -516
  235. package/lib/shared/cssNamedColors.ts +152 -30
  236. package/lib/shared/cssProperties.test.ts +5 -6
  237. package/lib/shared/cssProperties.ts +296 -112
  238. package/lib/shared/elementClassName.test.ts +109 -109
  239. package/lib/shared/elementClassName.ts +1 -1
  240. package/lib/shared/elementUtils.ts +12 -16
  241. package/lib/shared/errorLogger.ts +2 -10
  242. package/lib/shared/errors.test.ts +2 -13
  243. package/lib/shared/errors.ts +2 -8
  244. package/lib/shared/expressionEvaluator.test.ts +119 -0
  245. package/lib/shared/expressionEvaluator.ts +43 -24
  246. package/lib/shared/fontLoader.test.ts +19 -5
  247. package/lib/shared/friendlyError.ts +2 -3
  248. package/lib/shared/gradientUtils.test.ts +1 -5
  249. package/lib/shared/gradientUtils.ts +2 -6
  250. package/lib/shared/hrefRefs.ts +2 -10
  251. package/lib/shared/i18n.test.ts +1 -1
  252. package/lib/shared/i18n.ts +13 -34
  253. package/lib/shared/index.ts +4 -0
  254. package/lib/shared/inlineSvgStyleRules.ts +2 -4
  255. package/lib/shared/interactiveStyleMappings.test.ts +11 -33
  256. package/lib/shared/interactiveStyleMappings.ts +9 -16
  257. package/lib/shared/interactiveStyles.test.ts +165 -188
  258. package/lib/shared/interfaces/contentProvider.ts +1 -1
  259. package/lib/shared/itemTemplateUtils.test.ts +6 -12
  260. package/lib/shared/itemTemplateUtils.ts +19 -35
  261. package/lib/shared/jsonRepair.ts +8 -2
  262. package/lib/shared/libraryLoader.test.ts +15 -49
  263. package/lib/shared/libraryLoader.ts +7 -22
  264. package/lib/shared/netlifyLocale404.test.ts +179 -0
  265. package/lib/shared/netlifyLocale404.ts +110 -0
  266. package/lib/shared/nodeUtils.test.ts +24 -16
  267. package/lib/shared/nodeUtils.ts +49 -19
  268. package/lib/shared/pathArrayUtils.test.ts +1 -2
  269. package/lib/shared/pathArrayUtils.ts +1 -1
  270. package/lib/shared/pathSecurity.ts +1 -1
  271. package/lib/shared/pathUtils.test.ts +4 -6
  272. package/lib/shared/pathUtils.ts +42 -48
  273. package/lib/shared/paths/Path.test.ts +2 -2
  274. package/lib/shared/paths/Path.ts +0 -1
  275. package/lib/shared/paths/PathConverter.test.ts +1 -1
  276. package/lib/shared/paths/PathConverter.ts +14 -17
  277. package/lib/shared/paths/PathUtils.ts +9 -10
  278. package/lib/shared/paths/PathValidator.test.ts +2 -15
  279. package/lib/shared/paths/PathValidator.ts +11 -9
  280. package/lib/shared/paths/index.ts +1 -2
  281. package/lib/shared/propResolver.test.ts +240 -244
  282. package/lib/shared/propResolver.ts +14 -25
  283. package/lib/shared/pxToRem.test.ts +7 -6
  284. package/lib/shared/pxToRem.ts +2 -5
  285. package/lib/shared/registry/BaseNodeTypeRegistry.test.ts +9 -5
  286. package/lib/shared/registry/ClientRegistry.ts +0 -1
  287. package/lib/shared/registry/ComponentRegistry.test.ts +43 -29
  288. package/lib/shared/registry/ComponentRegistry.ts +9 -11
  289. package/lib/shared/registry/NodeTypeDefinition.ts +15 -8
  290. package/lib/shared/registry/RegistryManager.ts +1 -2
  291. package/lib/shared/registry/SSRRegistry.ts +0 -1
  292. package/lib/shared/registry/createNodeType.ts +7 -9
  293. package/lib/shared/registry/defineNodeType.ts +2 -6
  294. package/lib/shared/registry/index.ts +0 -1
  295. package/lib/shared/registry/nodeTypes/ComponentInstanceNodeType.ts +14 -15
  296. package/lib/shared/registry/nodeTypes/EmbedNodeType.ts +18 -11
  297. package/lib/shared/registry/nodeTypes/HtmlNodeType.ts +47 -18
  298. package/lib/shared/registry/nodeTypes/LinkNodeType.ts +21 -19
  299. package/lib/shared/registry/nodeTypes/ListNodeType.ts +78 -74
  300. package/lib/shared/registry/nodeTypes/LocaleListNodeType.ts +27 -21
  301. package/lib/shared/registry/nodeTypes/SlotMarkerType.ts +6 -7
  302. package/lib/shared/registry/nodeTypes/index.ts +10 -2
  303. package/lib/shared/responsiveScaling.test.ts +15 -31
  304. package/lib/shared/responsiveScaling.ts +55 -37
  305. package/lib/shared/responsiveStyleUtils.ts +11 -13
  306. package/lib/shared/richtext/htmlToTiptap.test.ts +23 -14
  307. package/lib/shared/richtext/htmlToTiptap.ts +1 -3
  308. package/lib/shared/richtext/tiptapToHtml.test.ts +5 -6
  309. package/lib/shared/richtext/types.ts +1 -8
  310. package/lib/shared/slugTranslator.test.ts +13 -13
  311. package/lib/shared/slugTranslator.ts +12 -16
  312. package/lib/shared/slugify.ts +9 -15
  313. package/lib/shared/styleNodeUtils.test.ts +8 -8
  314. package/lib/shared/styleNodeUtils.ts +5 -10
  315. package/lib/shared/styleUtils.test.ts +87 -61
  316. package/lib/shared/styleUtils.ts +5 -6
  317. package/lib/shared/themeDefaults.test.ts +11 -11
  318. package/lib/shared/themeDefaults.ts +3 -4
  319. package/lib/shared/tree/PathBuilder.test.ts +62 -138
  320. package/lib/shared/tree/PathBuilder.ts +49 -39
  321. package/lib/shared/treePathUtils.test.ts +2 -10
  322. package/lib/shared/treePathUtils.ts +54 -59
  323. package/lib/shared/types/api.ts +1 -2
  324. package/lib/shared/types/cms.ts +25 -21
  325. package/lib/shared/types/comment.ts +49 -16
  326. package/lib/shared/types/components.ts +27 -25
  327. package/lib/shared/types/errors.test.ts +1 -6
  328. package/lib/shared/types/errors.ts +3 -7
  329. package/lib/shared/types/experiments.ts +28 -28
  330. package/lib/shared/types/index.ts +2 -2
  331. package/lib/shared/types/styles.ts +0 -1
  332. package/lib/shared/types/variables.test.ts +4 -13
  333. package/lib/shared/types/variables.ts +48 -27
  334. package/lib/shared/types.ts +1 -2
  335. package/lib/shared/utilityClassConfig.ts +648 -321
  336. package/lib/shared/utilityClassMapper.test.ts +203 -92
  337. package/lib/shared/utilityClassMapper.ts +188 -246
  338. package/lib/shared/utilityClassNames.ts +326 -0
  339. package/lib/shared/utils.test.ts +2 -10
  340. package/lib/shared/utils.ts +19 -10
  341. package/lib/shared/validation/cmsValidators.ts +2 -1
  342. package/lib/shared/validation/commentValidators.test.ts +53 -0
  343. package/lib/shared/validation/commentValidators.ts +12 -1
  344. package/lib/shared/validation/propValidator.test.ts +18 -20
  345. package/lib/shared/validation/propValidator.ts +12 -17
  346. package/lib/shared/validation/schemas.test.ts +24 -33
  347. package/lib/shared/validation/schemas.ts +469 -344
  348. package/lib/shared/validation/validators.test.ts +1 -6
  349. package/lib/shared/validation/validators.ts +89 -68
  350. package/lib/shared/viewportUnits.integration.test.ts +14 -10
  351. package/lib/shared/viewportUnits.test.ts +11 -23
  352. package/lib/test-utils/dom-setup.ts +1 -1
  353. package/lib/test-utils/factories/ConsoleMockFactory.ts +3 -7
  354. package/lib/test-utils/factories/DomMockFactory.ts +7 -19
  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 +5 -9
  358. package/lib/test-utils/factories/StoreMockFactory.ts +14 -25
  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 +12 -18
  365. package/lib/test-utils/mocks.ts +4 -2
  366. package/package.json +1 -1
  367. package/scripts/build-meno-filter.ts +1 -4
  368. package/vite.config.ts +4 -4
  369. package/dist/chunks/chunk-2MHDV5BF.js.map +0 -7
  370. package/dist/chunks/chunk-AZQYF6KE.js.map +0 -7
  371. package/dist/chunks/chunk-GZHGVVW3.js.map +0 -7
  372. package/dist/chunks/chunk-H3GJ4H2U.js.map +0 -7
  373. package/dist/chunks/chunk-I7YIGZXT.js.map +0 -7
  374. package/dist/chunks/chunk-IGYR22T6.js.map +0 -7
  375. package/dist/chunks/chunk-JGP5A3Y5.js.map +0 -7
  376. package/dist/chunks/chunk-JGWFTO6P.js.map +0 -7
  377. package/dist/chunks/chunk-O3NAGJP4.js.map +0 -7
  378. package/dist/chunks/chunk-QB2LNO4W.js.map +0 -7
  379. package/dist/chunks/chunk-R6XHAFBF.js.map +0 -7
  380. package/dist/chunks/chunk-UB44F4Z2.js.map +0 -7
  381. package/dist/chunks/chunk-WQFG7PAH.js.map +0 -7
  382. package/dist/chunks/chunk-X754AHS5.js.map +0 -7
  383. package/dist/chunks/chunk-YBLHKYFF.js.map +0 -7
  384. package/dist/chunks/configService-R3OGU2UD.js +0 -13
  385. /package/dist/chunks/{configService-R3OGU2UD.js.map → configService-PRJZF7Y6.js.map} +0 -0
  386. /package/dist/chunks/{constants-STK2YBIW.js.map → constants-KIQEYMAM.js.map} +0 -0
  387. /package/dist/chunks/{fs-JGINUXGL.js.map → fs-ZI5JEU7V.js.map} +0 -0
@@ -7,7 +7,7 @@ import {
7
7
  parseSortExpression,
8
8
  serializeSortExpression,
9
9
  parseFilterExpression,
10
- serializeFilterExpression
10
+ serializeFilterExpression,
11
11
  } from './cmsQueryParser';
12
12
 
13
13
  describe('parseSortExpression', () => {
@@ -29,11 +29,11 @@ describe('parseSortExpression', () => {
29
29
  test('parses multiple fields', () => {
30
30
  expect(parseSortExpression('date desc, title')).toEqual([
31
31
  { field: 'date', order: 'desc' },
32
- { field: 'title', order: 'asc' }
32
+ { field: 'title', order: 'asc' },
33
33
  ]);
34
34
  expect(parseSortExpression('date desc, title asc')).toEqual([
35
35
  { field: 'date', order: 'desc' },
36
- { field: 'title', order: 'asc' }
36
+ { field: 'title', order: 'asc' },
37
37
  ]);
38
38
  });
39
39
 
@@ -41,7 +41,7 @@ describe('parseSortExpression', () => {
41
41
  expect(parseSortExpression(' date desc ')).toEqual({ field: 'date', order: 'desc' });
42
42
  expect(parseSortExpression('date desc, title asc')).toEqual([
43
43
  { field: 'date', order: 'desc' },
44
- { field: 'title', order: 'asc' }
44
+ { field: 'title', order: 'asc' },
45
45
  ]);
46
46
  });
47
47
  });
@@ -60,10 +60,12 @@ describe('serializeSortExpression', () => {
60
60
  });
61
61
 
62
62
  test('serializes multiple fields', () => {
63
- expect(serializeSortExpression([
64
- { field: 'date', order: 'desc' },
65
- { field: 'title', order: 'asc' }
66
- ])).toBe('date desc, title');
63
+ expect(
64
+ serializeSortExpression([
65
+ { field: 'date', order: 'desc' },
66
+ { field: 'title', order: 'asc' },
67
+ ]),
68
+ ).toBe('date desc, title');
67
69
  });
68
70
  });
69
71
 
@@ -98,32 +100,32 @@ describe('parseFilterExpression', () => {
98
100
  expect(parseFilterExpression('price > 100')).toEqual({
99
101
  field: 'price',
100
102
  operator: 'gt',
101
- value: 100
103
+ value: 100,
102
104
  });
103
105
  expect(parseFilterExpression('price >= 100')).toEqual({
104
106
  field: 'price',
105
107
  operator: 'gte',
106
- value: 100
108
+ value: 100,
107
109
  });
108
110
  expect(parseFilterExpression('price < 100')).toEqual({
109
111
  field: 'price',
110
112
  operator: 'lt',
111
- value: 100
113
+ value: 100,
112
114
  });
113
115
  expect(parseFilterExpression('price <= 100')).toEqual({
114
116
  field: 'price',
115
117
  operator: 'lte',
116
- value: 100
118
+ value: 100,
117
119
  });
118
120
  expect(parseFilterExpression('status != draft')).toEqual({
119
121
  field: 'status',
120
122
  operator: 'neq',
121
- value: 'draft'
123
+ value: 'draft',
122
124
  });
123
125
  expect(parseFilterExpression('status <> draft')).toEqual({
124
126
  field: 'status',
125
127
  operator: 'neq',
126
- value: 'draft'
128
+ value: 'draft',
127
129
  });
128
130
  });
129
131
 
@@ -131,12 +133,12 @@ describe('parseFilterExpression', () => {
131
133
  expect(parseFilterExpression('title contains hello')).toEqual({
132
134
  field: 'title',
133
135
  operator: 'contains',
134
- value: 'hello'
136
+ value: 'hello',
135
137
  });
136
138
  expect(parseFilterExpression('title ~ hello')).toEqual({
137
139
  field: 'title',
138
140
  operator: 'contains',
139
- value: 'hello'
141
+ value: 'hello',
140
142
  });
141
143
  });
142
144
 
@@ -144,35 +146,35 @@ describe('parseFilterExpression', () => {
144
146
  expect(parseFilterExpression('category in news, blog')).toEqual({
145
147
  field: 'category',
146
148
  operator: 'in',
147
- value: ['news', 'blog']
149
+ value: ['news', 'blog'],
148
150
  });
149
151
  expect(parseFilterExpression('status in draft, published, archived')).toEqual({
150
152
  field: 'status',
151
153
  operator: 'in',
152
- value: ['draft', 'published', 'archived']
154
+ value: ['draft', 'published', 'archived'],
153
155
  });
154
156
  });
155
157
 
156
158
  test('parses template values', () => {
157
159
  expect(parseFilterExpression('category = {{cms.category}}')).toEqual({
158
- category: '{{cms.category}}'
160
+ category: '{{cms.category}}',
159
161
  });
160
162
  expect(parseFilterExpression('author = {{cms.authorId}}')).toEqual({
161
- author: '{{cms.authorId}}'
163
+ author: '{{cms.authorId}}',
162
164
  });
163
165
  });
164
166
 
165
167
  test('parses multiple conditions (newline)', () => {
166
168
  expect(parseFilterExpression('featured = true\nprice > 100')).toEqual([
167
169
  { field: 'featured', value: true },
168
- { field: 'price', operator: 'gt', value: 100 }
170
+ { field: 'price', operator: 'gt', value: 100 },
169
171
  ]);
170
172
  });
171
173
 
172
174
  test('parses multiple conditions (semicolon)', () => {
173
175
  expect(parseFilterExpression('featured = true; price > 100')).toEqual([
174
176
  { field: 'featured', value: true },
175
- { field: 'price', operator: 'gt', value: 100 }
177
+ { field: 'price', operator: 'gt', value: 100 },
176
178
  ]);
177
179
  });
178
180
 
@@ -198,20 +200,20 @@ describe('parseFilterExpression', () => {
198
200
  expect(parseFilterExpression('price gt 100')).toEqual({
199
201
  field: 'price',
200
202
  operator: 'gt',
201
- value: 100
203
+ value: 100,
202
204
  });
203
205
  expect(parseFilterExpression('price gte 100')).toEqual({
204
206
  field: 'price',
205
207
  operator: 'gte',
206
- value: 100
208
+ value: 100,
207
209
  });
208
210
  expect(parseFilterExpression('status eq active')).toEqual({
209
- status: 'active'
211
+ status: 'active',
210
212
  });
211
213
  expect(parseFilterExpression('status neq draft')).toEqual({
212
214
  field: 'status',
213
215
  operator: 'neq',
214
- value: 'draft'
216
+ value: 'draft',
215
217
  });
216
218
  });
217
219
  });
@@ -227,32 +229,38 @@ describe('serializeFilterExpression', () => {
227
229
  });
228
230
 
229
231
  test('serializes condition with operator', () => {
230
- expect(serializeFilterExpression({
231
- field: 'price',
232
- operator: 'gt',
233
- value: 100
234
- })).toBe('price > 100');
235
- expect(serializeFilterExpression({
236
- field: 'status',
237
- operator: 'neq',
238
- value: 'draft'
239
- })).toBe('status != draft');
232
+ expect(
233
+ serializeFilterExpression({
234
+ field: 'price',
235
+ operator: 'gt',
236
+ value: 100,
237
+ }),
238
+ ).toBe('price > 100');
239
+ expect(
240
+ serializeFilterExpression({
241
+ field: 'status',
242
+ operator: 'neq',
243
+ value: 'draft',
244
+ }),
245
+ ).toBe('status != draft');
240
246
  });
241
247
 
242
248
  test('serializes multiple conditions', () => {
243
249
  const result = serializeFilterExpression([
244
250
  { field: 'featured', value: true },
245
- { field: 'price', operator: 'gt', value: 100 }
251
+ { field: 'price', operator: 'gt', value: 100 },
246
252
  ]);
247
253
  expect(result).toBe('featured = true\nprice > 100');
248
254
  });
249
255
 
250
256
  test('serializes in operator', () => {
251
- expect(serializeFilterExpression({
252
- field: 'category',
253
- operator: 'in',
254
- value: ['news', 'blog']
255
- })).toBe('category in news, blog');
257
+ expect(
258
+ serializeFilterExpression({
259
+ field: 'category',
260
+ operator: 'in',
261
+ value: ['news', 'blog'],
262
+ }),
263
+ ).toBe('category in news, blog');
256
264
  });
257
265
 
258
266
  test('serializes template values', () => {
@@ -22,8 +22,11 @@ import type { CMSFilterCondition, CMSSortConfig, CMSFilterOperator } from './typ
22
22
  export function parseSortExpression(expr: string): CMSSortConfig | CMSSortConfig[] | undefined {
23
23
  if (!expr.trim()) return undefined;
24
24
 
25
- const parts = expr.split(',').map(p => p.trim()).filter(Boolean);
26
- const sorts: CMSSortConfig[] = parts.map(part => {
25
+ const parts = expr
26
+ .split(',')
27
+ .map((p) => p.trim())
28
+ .filter(Boolean);
29
+ const sorts: CMSSortConfig[] = parts.map((part) => {
27
30
  const tokens = part.split(/\s+/);
28
31
  const field = tokens[0];
29
32
  const order = tokens[1]?.toLowerCase() === 'desc' ? 'desc' : 'asc';
@@ -39,19 +42,22 @@ export function parseSortExpression(expr: string): CMSSortConfig | CMSSortConfig
39
42
  export function serializeSortExpression(sort: CMSSortConfig | CMSSortConfig[] | undefined): string {
40
43
  if (!sort) return '';
41
44
  const sorts = Array.isArray(sort) ? sort : [sort];
42
- return sorts.map(s => `${s.field}${s.order === 'desc' ? ' desc' : ''}`).join(', ');
45
+ return sorts.map((s) => `${s.field}${s.order === 'desc' ? ' desc' : ''}`).join(', ');
43
46
  }
44
47
 
45
48
  /**
46
49
  * Parse filter expression: "featured = true; price > 100"
47
50
  */
48
51
  export function parseFilterExpression(
49
- expr: string
52
+ expr: string,
50
53
  ): CMSFilterCondition | CMSFilterCondition[] | Record<string, unknown> | undefined {
51
54
  if (!expr.trim()) return undefined;
52
55
 
53
56
  // Split by newline or semicolon
54
- const lines = expr.split(/[;\n]/).map(l => l.trim()).filter(Boolean);
57
+ const lines = expr
58
+ .split(/[;\n]/)
59
+ .map((l) => l.trim())
60
+ .filter(Boolean);
55
61
  const conditions: CMSFilterCondition[] = [];
56
62
 
57
63
  for (const line of lines) {
@@ -90,14 +96,23 @@ function parseFilterLine(line: string): CMSFilterCondition | null {
90
96
  function normalizeOperator(op: string): CMSFilterOperator {
91
97
  const normalized = op.toLowerCase();
92
98
  const map: Record<string, CMSFilterOperator> = {
93
- '=': 'eq', '==': 'eq', 'eq': 'eq',
94
- '!=': 'neq', '<>': 'neq', 'neq': 'neq',
95
- '>': 'gt', 'gt': 'gt',
96
- '>=': 'gte', 'gte': 'gte',
97
- '<': 'lt', 'lt': 'lt',
98
- '<=': 'lte', 'lte': 'lte',
99
- 'contains': 'contains', '~': 'contains',
100
- 'in': 'in'
99
+ '=': 'eq',
100
+ '==': 'eq',
101
+ eq: 'eq',
102
+ '!=': 'neq',
103
+ '<>': 'neq',
104
+ neq: 'neq',
105
+ '>': 'gt',
106
+ gt: 'gt',
107
+ '>=': 'gte',
108
+ gte: 'gte',
109
+ '<': 'lt',
110
+ lt: 'lt',
111
+ '<=': 'lte',
112
+ lte: 'lte',
113
+ contains: 'contains',
114
+ '~': 'contains',
115
+ in: 'in',
101
116
  };
102
117
  return map[normalized] || 'eq';
103
118
  }
@@ -110,7 +125,7 @@ function parseValue(raw: string, operator: CMSFilterOperator): unknown {
110
125
 
111
126
  // Handle 'in' operator - comma separated list
112
127
  if (operator === 'in') {
113
- return raw.split(',').map(v => parseScalarValue(v.trim()));
128
+ return raw.split(',').map((v) => parseScalarValue(v.trim()));
114
129
  }
115
130
 
116
131
  return parseScalarValue(raw);
@@ -137,7 +152,7 @@ function parseScalarValue(raw: string): unknown {
137
152
  * Serialize filter config back to expression
138
153
  */
139
154
  export function serializeFilterExpression(
140
- filter: CMSFilterCondition | CMSFilterCondition[] | Record<string, unknown> | undefined
155
+ filter: CMSFilterCondition | CMSFilterCondition[] | Record<string, unknown> | undefined,
141
156
  ): string {
142
157
  if (!filter) return '';
143
158
 
@@ -150,26 +165,29 @@ export function serializeFilterExpression(
150
165
 
151
166
  // Array or single condition
152
167
  const conditions = Array.isArray(filter) ? filter : [filter as CMSFilterCondition];
153
- return conditions.map(c => {
154
- const op = c.operator || 'eq';
155
- const opStr = operatorToString(op);
156
- const valStr = op === 'in' && Array.isArray(c.value)
157
- ? c.value.map(v => serializeValue(v)).join(', ')
158
- : serializeValue(c.value);
159
- return `${c.field} ${opStr} ${valStr}`;
160
- }).join('\n');
168
+ return conditions
169
+ .map((c) => {
170
+ const op = c.operator || 'eq';
171
+ const opStr = operatorToString(op);
172
+ const valStr =
173
+ op === 'in' && Array.isArray(c.value)
174
+ ? c.value.map((v) => serializeValue(v)).join(', ')
175
+ : serializeValue(c.value);
176
+ return `${c.field} ${opStr} ${valStr}`;
177
+ })
178
+ .join('\n');
161
179
  }
162
180
 
163
181
  function operatorToString(op: CMSFilterOperator): string {
164
182
  const map: Record<CMSFilterOperator, string> = {
165
- 'eq': '=',
166
- 'neq': '!=',
167
- 'gt': '>',
168
- 'gte': '>=',
169
- 'lt': '<',
170
- 'lte': '<=',
171
- 'contains': 'contains',
172
- 'in': 'in'
183
+ eq: '=',
184
+ neq: '!=',
185
+ gt: '>',
186
+ gte: '>=',
187
+ lt: '<',
188
+ lte: '<=',
189
+ contains: 'contains',
190
+ in: 'in',
173
191
  };
174
192
  return map[op] || '=';
175
193
  }
@@ -105,9 +105,9 @@ describe('colorVariableUtils', () => {
105
105
  describe('resolveColorVariable', () => {
106
106
  const colorMap = {
107
107
  'primary-color': '#3b82f6',
108
- 'background': '#ffffff',
108
+ background: '#ffffff',
109
109
  'text-dark': '#1f2937',
110
- 'accent': 'rgb(239, 68, 68)',
110
+ accent: 'rgb(239, 68, 68)',
111
111
  };
112
112
 
113
113
  test('should resolve valid variable to color value', () => {
@@ -142,9 +142,9 @@ describe('colorVariableUtils', () => {
142
142
 
143
143
  describe('resolveColorVariablesInStyles', () => {
144
144
  const colorMap = {
145
- 'primary': '#3b82f6',
146
- 'background': '#ffffff',
147
- 'text': '#1f2937',
145
+ primary: '#3b82f6',
146
+ background: '#ffffff',
147
+ text: '#1f2937',
148
148
  };
149
149
 
150
150
  test('should resolve all color variables in styles', () => {
@@ -35,10 +35,7 @@ export function createVariableReference(variableName: string): string {
35
35
  * @param colorMap - Map of variable names to color values
36
36
  * @returns Resolved color value or original value if not a variable
37
37
  */
38
- export function resolveColorVariable(
39
- value: string | unknown,
40
- colorMap: Record<string, string>
41
- ): string {
38
+ export function resolveColorVariable(value: string | unknown, colorMap: Record<string, string>): string {
42
39
  if (!isColorVariable(value)) {
43
40
  return String(value);
44
41
  }
@@ -59,7 +56,7 @@ export function resolveColorVariable(
59
56
  */
60
57
  export function resolveColorVariablesInStyles(
61
58
  styles: Record<string, any>,
62
- colorMap: Record<string, string>
59
+ colorMap: Record<string, string>,
63
60
  ): Record<string, any> {
64
61
  const resolved: Record<string, any> = {};
65
62
 
@@ -79,9 +76,7 @@ export function resolveColorVariablesInStyles(
79
76
  * @param styles - Style object to search
80
77
  * @returns Array of variable names found in styles
81
78
  */
82
- export function getColorVariablesFromStyles(
83
- styles: Record<string, any>
84
- ): string[] {
79
+ export function getColorVariablesFromStyles(styles: Record<string, any>): string[] {
85
80
  const variables = new Set<string>();
86
81
 
87
82
  for (const value of Object.values(styles)) {
@@ -16,11 +16,7 @@
16
16
  * like "Button" will never collide with HTML tags, CSS classes, prop strings,
17
17
  * embedded SVG/HTML, or any user copy that happens to contain the word.
18
18
  */
19
- export function rewriteComponentRefs(
20
- node: unknown,
21
- oldName: string,
22
- newName: string,
23
- ): boolean {
19
+ export function rewriteComponentRefs(node: unknown, oldName: string, newName: string): boolean {
24
20
  if (!node || typeof node !== 'object') return false;
25
21
  let changed = false;
26
22
 
@@ -48,7 +48,7 @@ describe('constants', () => {
48
48
  });
49
49
 
50
50
  test('all routes are strings starting with /api/', () => {
51
- Object.values(API_ROUTES).forEach(route => {
51
+ Object.values(API_ROUTES).forEach((route) => {
52
52
  expect(typeof route).toBe('string');
53
53
  expect(route.startsWith('/api/')).toBe(true);
54
54
  });
@@ -150,14 +150,14 @@ describe('constants', () => {
150
150
  });
151
151
 
152
152
  test('contains ui, layout, and content types', () => {
153
- const ids = DEFAULT_COMPONENT_TYPES.map(t => t.id);
153
+ const ids = DEFAULT_COMPONENT_TYPES.map((t) => t.id);
154
154
  expect(ids).toContain('ui');
155
155
  expect(ids).toContain('layout');
156
156
  expect(ids).toContain('content');
157
157
  });
158
158
 
159
159
  test('each type has id, label, and color', () => {
160
- DEFAULT_COMPONENT_TYPES.forEach(type => {
160
+ DEFAULT_COMPONENT_TYPES.forEach((type) => {
161
161
  expect(typeof type.id).toBe('string');
162
162
  expect(typeof type.label).toBe('string');
163
163
  expect(typeof type.color).toBe('string');
@@ -4,15 +4,12 @@
4
4
 
5
5
  // Read PORT from environment variable, fallback to 3000
6
6
  // Safe for browser environments where process is not defined
7
- export const SERVER_PORT = typeof process !== 'undefined' && process.env?.PORT
8
- ? parseInt(process.env.PORT, 10)
9
- : 3000;
7
+ export const SERVER_PORT = typeof process !== 'undefined' && process.env?.PORT ? parseInt(process.env.PORT, 10) : 3000;
10
8
 
11
9
  // Port for serving built static files (SSR preview)
12
10
  // Reads MENO_SERVE_PORT env var so each project instance can get its own port
13
- export const SERVE_PORT = typeof process !== 'undefined' && process.env?.MENO_SERVE_PORT
14
- ? parseInt(process.env.MENO_SERVE_PORT, 10)
15
- : 8080;
11
+ export const SERVE_PORT =
12
+ typeof process !== 'undefined' && process.env?.MENO_SERVE_PORT ? parseInt(process.env.MENO_SERVE_PORT, 10) : 8080;
16
13
 
17
14
  export const API_ROUTES = {
18
15
  PAGES: '/api/pages',
@@ -161,7 +158,7 @@ export const NODE_TYPE = {
161
158
  LIST: 'list',
162
159
  } as const;
163
160
 
164
- export type NodeType = typeof NODE_TYPE[keyof typeof NODE_TYPE];
161
+ export type NodeType = (typeof NODE_TYPE)[keyof typeof NODE_TYPE];
165
162
 
166
163
  // Special path identifiers for component editing
167
164
  export const SPECIAL_PATHS = {
@@ -194,4 +191,3 @@ export const DEFAULT_ICON_COLOR = '#6b7280';
194
191
  * Used by rich-text fields to signal that content should render as HTML
195
192
  */
196
193
  export const RAW_HTML_PREFIX = '<!--MENO_RAW_HTML-->';
197
-