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
@@ -9,7 +9,7 @@ import { applyNonce } from '../styles/cspNonce';
9
9
  let cachedColors: Record<string, ColorVariables> = {};
10
10
  let cachedThemes: ThemeEntry[] | null = null;
11
11
  let cachedDefaultTheme: string | null = null;
12
- let hmrCallbacks: Set<() => void> = new Set();
12
+ const hmrCallbacks: Set<() => void> = new Set();
13
13
 
14
14
  // Setup HMR listener immediately when module loads
15
15
  function initializeHMRListener() {
@@ -30,7 +30,7 @@ function initializeHMRListener() {
30
30
  await injectUpdatedThemeCSS();
31
31
 
32
32
  // Notify all listeners to refresh their data
33
- hmrCallbacks.forEach(callback => callback());
33
+ hmrCallbacks.forEach((callback) => callback());
34
34
  });
35
35
  }
36
36
 
@@ -48,7 +48,7 @@ async function injectUpdatedThemeCSS() {
48
48
  const response = await fetch('/api/themes');
49
49
  if (!response.ok) return;
50
50
 
51
- const data = await response.json() as { themes: Array<{ name: string; label: string }>; default: string };
51
+ const data = (await response.json()) as { themes: Array<{ name: string; label: string }>; default: string };
52
52
 
53
53
  // Fetch all theme colors
54
54
  const themeColors: Record<string, any> = {};
@@ -109,7 +109,9 @@ async function injectUpdatedThemeCSS() {
109
109
  }
110
110
 
111
111
  export function useColorVariables(themeName?: string) {
112
- const [colors, setColors] = useState<ColorVariables | null>(themeName && cachedColors[themeName] ? cachedColors[themeName] : null);
112
+ const [colors, setColors] = useState<ColorVariables | null>(
113
+ themeName && cachedColors[themeName] ? cachedColors[themeName] : null,
114
+ );
113
115
  const [loading, setLoading] = useState(!cachedColors[themeName || 'default']);
114
116
  const [error, setError] = useState<Error | null>(null);
115
117
  const callbackRef = useRef<(() => void) | null>(null);
@@ -125,7 +127,7 @@ export function useColorVariables(themeName?: string) {
125
127
  if (!response.ok) {
126
128
  throw new Error('Failed to fetch colors');
127
129
  }
128
- const data = await response.json() as ColorVariables;
130
+ const data = (await response.json()) as ColorVariables;
129
131
  cachedColors[theme] = data;
130
132
  setColors(data);
131
133
  setError(null);
@@ -157,7 +159,7 @@ export function useColorVariables(themeName?: string) {
157
159
  if (!response.ok) {
158
160
  throw new Error('Failed to fetch colors');
159
161
  }
160
- const data = await response.json() as ColorVariables;
162
+ const data = (await response.json()) as ColorVariables;
161
163
  cachedColors[theme] = data;
162
164
  setColors(data);
163
165
  setError(null);
@@ -206,7 +208,7 @@ export function useThemes() {
206
208
  if (!response.ok) {
207
209
  throw new Error('Failed to fetch themes');
208
210
  }
209
- const data = await response.json() as { themes: ThemeEntry[]; default: string };
211
+ const data = (await response.json()) as { themes: ThemeEntry[]; default: string };
210
212
  cachedThemes = data.themes;
211
213
  cachedDefaultTheme = data.default;
212
214
  setThemes(data.themes);
@@ -234,13 +236,13 @@ export function getColorVariableSuggestions(colors: ColorVariables | null, input
234
236
 
235
237
  const normalizedInput = input.trim().toLowerCase();
236
238
  if (!normalizedInput) {
237
- return Object.keys(colors.colors).map(name => `var(--${name})`);
239
+ return Object.keys(colors.colors).map((name) => `var(--${name})`);
238
240
  }
239
241
 
240
242
  // Filter color variable names that match the input
241
243
  return Object.keys(colors.colors)
242
- .filter(name => name.toLowerCase().includes(normalizedInput) || normalizedInput.includes(name.toLowerCase()))
243
- .map(name => `var(--${name})`);
244
+ .filter((name) => name.toLowerCase().includes(normalizedInput) || normalizedInput.includes(name.toLowerCase()))
245
+ .map((name) => `var(--${name})`);
244
246
  }
245
247
 
246
248
  /**
@@ -17,12 +17,10 @@ export function usePropertyAutocomplete(initialProperty: string = '') {
17
17
  const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
18
18
  if (e.key === 'ArrowDown') {
19
19
  e.preventDefault();
20
- setSelectedIndex(prev =>
21
- prev < suggestions.length - 1 ? prev + 1 : prev
22
- );
20
+ setSelectedIndex((prev) => (prev < suggestions.length - 1 ? prev + 1 : prev));
23
21
  } else if (e.key === 'ArrowUp') {
24
22
  e.preventDefault();
25
- setSelectedIndex(prev => prev > 0 ? prev - 1 : -1);
23
+ setSelectedIndex((prev) => (prev > 0 ? prev - 1 : -1));
26
24
  }
27
25
  };
28
26
 
@@ -35,6 +33,6 @@ export function usePropertyAutocomplete(initialProperty: string = '') {
35
33
  setSelectedIndex,
36
34
  suggestions,
37
35
  inputRef,
38
- handleKeyDown
36
+ handleKeyDown,
39
37
  };
40
38
  }
@@ -6,7 +6,7 @@ import { useState, useEffect, useRef } from 'react';
6
6
  import type { CSSVariable } from '../../shared/types/variables';
7
7
 
8
8
  let cachedVariables: CSSVariable[] | null = null;
9
- let hmrCallbacks: Set<() => void> = new Set();
9
+ const hmrCallbacks: Set<() => void> = new Set();
10
10
 
11
11
  // Setup HMR listener immediately when module loads
12
12
  function initializeHMRListener() {
@@ -22,7 +22,7 @@ function initializeHMRListener() {
22
22
  cachedVariables = null;
23
23
 
24
24
  // Notify all listeners to refresh their data
25
- hmrCallbacks.forEach(callback => callback());
25
+ hmrCallbacks.forEach((callback) => callback());
26
26
  });
27
27
  }
28
28
 
@@ -45,7 +45,7 @@ export function useVariables() {
45
45
  if (!response.ok) {
46
46
  throw new Error('Failed to fetch variables');
47
47
  }
48
- const data = await response.json() as { status: string; config: { variables: CSSVariable[] } };
48
+ const data = (await response.json()) as { status: string; config: { variables: CSSVariable[] } };
49
49
  cachedVariables = data.config.variables;
50
50
  setVariables(cachedVariables);
51
51
  setError(null);
@@ -76,7 +76,7 @@ export function useVariables() {
76
76
  if (!response.ok) {
77
77
  throw new Error('Failed to fetch variables');
78
78
  }
79
- const data = await response.json() as { status: string; config: { variables: CSSVariable[] } };
79
+ const data = (await response.json()) as { status: string; config: { variables: CSSVariable[] } };
80
80
  cachedVariables = data.config.variables;
81
81
  setVariables(cachedVariables);
82
82
  setError(null);
@@ -1,7 +1,7 @@
1
- import { test, expect, describe, beforeEach, afterEach, mock } from "bun:test";
2
- import { detectSSRContent, getInitialLoadingState } from "./HydrationUtils";
1
+ import { test, expect, describe, beforeEach, afterEach, mock } from 'bun:test';
2
+ import { detectSSRContent, getInitialLoadingState } from './HydrationUtils';
3
3
 
4
- describe("HydrationUtils", () => {
4
+ describe('HydrationUtils', () => {
5
5
  let originalDocument: Document | undefined;
6
6
  let originalWindow: (Window & typeof globalThis) | undefined;
7
7
  let mockGetElementById: ReturnType<typeof mock>;
@@ -22,11 +22,11 @@ describe("HydrationUtils", () => {
22
22
  }
23
23
  });
24
24
 
25
- describe("detectSSRContent", () => {
26
- test("should return true when root element exists with children", () => {
25
+ describe('detectSSRContent', () => {
26
+ test('should return true when root element exists with children', () => {
27
27
  // Create a mock root element with children
28
28
  const mockRoot = {
29
- id: "root",
29
+ id: 'root',
30
30
  children: {
31
31
  length: 1,
32
32
  },
@@ -40,13 +40,13 @@ describe("HydrationUtils", () => {
40
40
 
41
41
  const result = detectSSRContent();
42
42
  expect(result).toBe(true);
43
- expect(mockGetElementById).toHaveBeenCalledWith("root");
43
+ expect(mockGetElementById).toHaveBeenCalledWith('root');
44
44
  });
45
45
 
46
- test("should return false when root element exists without children", () => {
46
+ test('should return false when root element exists without children', () => {
47
47
  // Create a mock root element without children
48
48
  const mockRoot = {
49
- id: "root",
49
+ id: 'root',
50
50
  children: {
51
51
  length: 0,
52
52
  },
@@ -60,10 +60,10 @@ describe("HydrationUtils", () => {
60
60
 
61
61
  const result = detectSSRContent();
62
62
  expect(result).toBe(false);
63
- expect(mockGetElementById).toHaveBeenCalledWith("root");
63
+ expect(mockGetElementById).toHaveBeenCalledWith('root');
64
64
  });
65
65
 
66
- test("should return false when root element does not exist", () => {
66
+ test('should return false when root element does not exist', () => {
67
67
  // Mock getElementById to return null
68
68
  mockGetElementById = mock(() => null);
69
69
  global.window = {} as any;
@@ -73,14 +73,14 @@ describe("HydrationUtils", () => {
73
73
 
74
74
  const result = detectSSRContent();
75
75
  expect(result).toBe(false);
76
- expect(mockGetElementById).toHaveBeenCalledWith("root");
76
+ expect(mockGetElementById).toHaveBeenCalledWith('root');
77
77
  });
78
78
 
79
- test("should return false when window is undefined (SSR environment)", () => {
79
+ test('should return false when window is undefined (SSR environment)', () => {
80
80
  // Mock SSR environment
81
81
  const originalWindow = globalThis.window;
82
82
  const originalDocument = globalThis.document;
83
-
83
+
84
84
  // @ts-expect-error - intentionally removing window for SSR test
85
85
  delete globalThis.window;
86
86
  // @ts-expect-error - intentionally removing document for SSR test
@@ -94,10 +94,10 @@ describe("HydrationUtils", () => {
94
94
  globalThis.document = originalDocument;
95
95
  });
96
96
 
97
- test("should return false when document is undefined", () => {
97
+ test('should return false when document is undefined', () => {
98
98
  // Mock environment without document
99
99
  const originalDocument = globalThis.document;
100
-
100
+
101
101
  // @ts-expect-error - intentionally removing document for test
102
102
  delete globalThis.document;
103
103
 
@@ -108,10 +108,10 @@ describe("HydrationUtils", () => {
108
108
  globalThis.document = originalDocument;
109
109
  });
110
110
 
111
- test("should handle root element with multiple children", () => {
111
+ test('should handle root element with multiple children', () => {
112
112
  // Create a mock root element with multiple children
113
113
  const mockRoot = {
114
- id: "root",
114
+ id: 'root',
115
115
  children: {
116
116
  length: 3,
117
117
  },
@@ -125,30 +125,29 @@ describe("HydrationUtils", () => {
125
125
 
126
126
  const result = detectSSRContent();
127
127
  expect(result).toBe(true);
128
- expect(mockGetElementById).toHaveBeenCalledWith("root");
128
+ expect(mockGetElementById).toHaveBeenCalledWith('root');
129
129
  });
130
130
  });
131
131
 
132
- describe("getInitialLoadingState", () => {
133
- test("should return false when SSR content exists (smooth hydration)", () => {
132
+ describe('getInitialLoadingState', () => {
133
+ test('should return false when SSR content exists (smooth hydration)', () => {
134
134
  const result = getInitialLoadingState(true);
135
135
  expect(result).toBe(false);
136
136
  });
137
137
 
138
- test("should return true when no SSR content exists (show loading)", () => {
138
+ test('should return true when no SSR content exists (show loading)', () => {
139
139
  const result = getInitialLoadingState(false);
140
140
  expect(result).toBe(true);
141
141
  });
142
142
 
143
- test("should handle edge case with explicit false", () => {
143
+ test('should handle edge case with explicit false', () => {
144
144
  const result = getInitialLoadingState(false);
145
145
  expect(result).toBe(true);
146
146
  });
147
147
 
148
- test("should handle edge case with explicit true", () => {
148
+ test('should handle edge case with explicit true', () => {
149
149
  const result = getInitialLoadingState(true);
150
150
  expect(result).toBe(false);
151
151
  });
152
152
  });
153
153
  });
154
-
@@ -6,7 +6,7 @@
6
6
  /**
7
7
  * Detects if server-side rendered content exists in the DOM.
8
8
  * Checks if the root element has children, which indicates SSR rendered content.
9
- *
9
+ *
10
10
  * @returns true if SSR content is detected, false otherwise
11
11
  */
12
12
  export function detectSSRContent(): boolean {
@@ -16,14 +16,14 @@ export function detectSSRContent(): boolean {
16
16
  }
17
17
 
18
18
  const rootElement = document.getElementById('root');
19
-
19
+
20
20
  // SSR content exists if root element has children
21
21
  return rootElement !== null && rootElement.children.length > 0;
22
22
  }
23
23
 
24
24
  /**
25
25
  * Determines the initial loading state based on SSR content presence.
26
- *
26
+ *
27
27
  * @param hasSSRContent - Whether SSR content was detected
28
28
  * @returns false if SSR content exists (for smooth hydration), true otherwise
29
29
  */
@@ -32,4 +32,3 @@ export function getInitialLoadingState(hasSSRContent: boolean): boolean {
32
32
  // If no SSR content, start with loading=true to show loading state
33
33
  return !hasSSRContent;
34
34
  }
35
-
@@ -1,10 +1,5 @@
1
1
  import { describe, test, expect, beforeEach } from 'bun:test';
2
- import {
3
- getI18nConfig,
4
- isI18nConfigLoaded,
5
- invalidateI18nConfig,
6
- setI18nConfig,
7
- } from './i18nConfigService';
2
+ import { getI18nConfig, isI18nConfigLoaded, invalidateI18nConfig, setI18nConfig } from './i18nConfigService';
8
3
  import { DEFAULT_I18N_CONFIG } from '../shared/i18n';
9
4
 
10
5
  describe('i18nConfigService', () => {
@@ -51,7 +46,7 @@ describe('i18nConfigService', () => {
51
46
  test('sets config that can be retrieved', () => {
52
47
  const customConfig = {
53
48
  defaultLocale: 'de',
54
- locales: [{ code: 'de', name: 'German', nativeName: 'Deutsch', langTag: 'de-DE' }]
49
+ locales: [{ code: 'de', name: 'German', nativeName: 'Deutsch', langTag: 'de-DE' }],
55
50
  };
56
51
  setI18nConfig(customConfig);
57
52
  const config = getI18nConfig();
@@ -26,13 +26,13 @@ export async function fetchI18nConfig(): Promise<I18nConfig> {
26
26
 
27
27
  // Create new request
28
28
  configPromise = fetch('/api/config')
29
- .then(response => {
29
+ .then((response) => {
30
30
  if (!response.ok) {
31
31
  throw new Error('Failed to fetch config');
32
32
  }
33
33
  return response.json();
34
34
  })
35
- .then(config => {
35
+ .then((config) => {
36
36
  cachedConfig = migrateI18nConfig(config.i18n);
37
37
  return cachedConfig;
38
38
  })
@@ -83,7 +83,7 @@ describe('MenoFilter', () => {
83
83
  Promise.resolve({
84
84
  ok: true,
85
85
  json: () => Promise.resolve(sampleItems),
86
- })
86
+ }),
87
87
  );
88
88
  const originalFetch = (globalThis as any).fetch;
89
89
  (globalThis as any).fetch = mockFetch;
@@ -127,7 +127,7 @@ describe('MenoFilter', () => {
127
127
  Promise.resolve({
128
128
  ok: false,
129
129
  status: 404,
130
- })
130
+ }),
131
131
  );
132
132
  const originalFetch = (globalThis as any).fetch;
133
133
  (globalThis as any).fetch = mockFetch;
@@ -157,7 +157,7 @@ describe('MenoFilter', () => {
157
157
  Promise.resolve({
158
158
  ok: true,
159
159
  json: () => Promise.resolve([{ _id: 'fetch', title: 'Fetch Data' }]),
160
- })
160
+ }),
161
161
  );
162
162
  const originalFetch = (globalThis as any).fetch;
163
163
  (globalThis as any).fetch = mockFetch;
@@ -193,7 +193,7 @@ describe('MenoFilter', () => {
193
193
  const result = filter.filter({ category: 'tech' });
194
194
 
195
195
  expect(result).toHaveLength(3);
196
- expect(result.every(item => item.category === 'tech')).toBe(true);
196
+ expect(result.every((item) => item.category === 'tech')).toBe(true);
197
197
  });
198
198
 
199
199
  test('should filter by multiple criteria (AND logic)', () => {
@@ -217,7 +217,7 @@ describe('MenoFilter', () => {
217
217
 
218
218
  test('should emit to subscribers on filter', () => {
219
219
  let emittedItems: CMSItemClient[] = [];
220
- filter.subscribe(items => {
220
+ filter.subscribe((items) => {
221
221
  emittedItems = items;
222
222
  });
223
223
 
@@ -245,8 +245,8 @@ describe('MenoFilter', () => {
245
245
  const result = filter.search('world');
246
246
 
247
247
  expect(result).toHaveLength(2);
248
- expect(result.map(i => i.title)).toContain('Hello World');
249
- expect(result.map(i => i.title)).toContain('Goodbye World');
248
+ expect(result.map((i) => i.title)).toContain('Hello World');
249
+ expect(result.map((i) => i.title)).toContain('Goodbye World');
250
250
  });
251
251
 
252
252
  test('should search specified fields only', () => {
@@ -337,9 +337,7 @@ describe('MenoFilter', () => {
337
337
  });
338
338
 
339
339
  test('should find item by _filename', () => {
340
- const itemsWithFilename = [
341
- { _id: '1', _filename: 'hello-world', title: 'Hello' },
342
- ];
340
+ const itemsWithFilename = [{ _id: '1', _filename: 'hello-world', title: 'Hello' }];
343
341
  const mockElement = {
344
342
  textContent: JSON.stringify(itemsWithFilename),
345
343
  };
@@ -424,7 +422,7 @@ describe('MenoFilter', () => {
424
422
  await filter.init();
425
423
 
426
424
  let receivedItems: CMSItemClient[] = [];
427
- filter.subscribe(items => {
425
+ filter.subscribe((items) => {
428
426
  receivedItems = items;
429
427
  });
430
428
 
@@ -648,7 +646,7 @@ describe('MenoFilter', () => {
648
646
  await filter.init();
649
647
 
650
648
  let receivedItems: CMSItemClient[] = [];
651
- filter.subscribe(items => {
649
+ filter.subscribe((items) => {
652
650
  receivedItems = items;
653
651
  });
654
652
 
@@ -701,7 +699,7 @@ describe('MenoFilter', () => {
701
699
  const result = filter.filter({ price: { $gt: 100 } });
702
700
 
703
701
  expect(result).toHaveLength(2);
704
- expect(result.map(i => i.price)).toEqual([200, 150]);
702
+ expect(result.map((i) => i.price)).toEqual([200, 150]);
705
703
  });
706
704
 
707
705
  test('should filter numbers from string criteria', async () => {
@@ -718,7 +716,7 @@ describe('MenoFilter', () => {
718
716
  const result = filter.filter({ price: { $gte: '100', $lte: '150' } });
719
717
 
720
718
  expect(result).toHaveLength(2);
721
- expect(result.map(i => i.price)).toEqual([100, 150]);
719
+ expect(result.map((i) => i.price)).toEqual([100, 150]);
722
720
  });
723
721
 
724
722
  test('should filter dates with type coercion', async () => {
@@ -735,7 +733,7 @@ describe('MenoFilter', () => {
735
733
  const result = filter.filter({ date: { $gt: '2024-01-31' } });
736
734
 
737
735
  expect(result).toHaveLength(2);
738
- expect(result.map(i => i.date)).toEqual(['2024-02-15', '2024-03-15']);
736
+ expect(result.map((i) => i.date)).toEqual(['2024-02-15', '2024-03-15']);
739
737
  });
740
738
 
741
739
  test('should filter booleans with type coercion', async () => {
@@ -752,7 +750,7 @@ describe('MenoFilter', () => {
752
750
  const result = filter.filter({ featured: 'true' });
753
751
 
754
752
  expect(result).toHaveLength(2);
755
- expect(result.every(i => i.featured === true)).toBe(true);
753
+ expect(result.every((i) => i.featured === true)).toBe(true);
756
754
  });
757
755
 
758
756
  test('setFieldType() should update field types', async () => {
@@ -773,7 +771,7 @@ describe('MenoFilter', () => {
773
771
  result = filter.filter({ price: { $gt: 100 } });
774
772
 
775
773
  expect(result).toHaveLength(2);
776
- expect(result.map(i => i.price)).toEqual([200, 150]);
774
+ expect(result.map((i) => i.price)).toEqual([200, 150]);
777
775
  });
778
776
 
779
777
  test('setFieldTypes() should set multiple types', async () => {
@@ -820,7 +818,7 @@ describe('MenoFilter', () => {
820
818
  const result = filter.filterRange('price', { min: 100, max: 200 });
821
819
 
822
820
  expect(result).toHaveLength(3);
823
- expect(result.map(i => i.price).sort((a, b) => (a as number) - (b as number))).toEqual([100, 150, 200]);
821
+ expect(result.map((i) => i.price).sort((a, b) => (a as number) - (b as number))).toEqual([100, 150, 200]);
824
822
  });
825
823
 
826
824
  test('should filter with only min', async () => {
@@ -836,7 +834,7 @@ describe('MenoFilter', () => {
836
834
  const result = filter.filterRange('price', { min: 150 });
837
835
 
838
836
  expect(result).toHaveLength(3);
839
- expect(result.every(i => (i.price as number) >= 150)).toBe(true);
837
+ expect(result.every((i) => (i.price as number) >= 150)).toBe(true);
840
838
  });
841
839
 
842
840
  test('should filter with only max', async () => {
@@ -852,7 +850,7 @@ describe('MenoFilter', () => {
852
850
  const result = filter.filterRange('price', { max: 100 });
853
851
 
854
852
  expect(result).toHaveLength(2);
855
- expect(result.every(i => (i.price as number) <= 100)).toBe(true);
853
+ expect(result.every((i) => (i.price as number) <= 100)).toBe(true);
856
854
  });
857
855
 
858
856
  test('should clear filter when both min and max are empty', async () => {
@@ -956,7 +954,7 @@ describe('MenoFilter', () => {
956
954
  const result = filter.search('recat', ['title']);
957
955
 
958
956
  expect(result.length).toBeGreaterThanOrEqual(1);
959
- expect(result.some(i => i.title === 'React')).toBe(true);
957
+ expect(result.some((i) => i.title === 'React')).toBe(true);
960
958
  });
961
959
 
962
960
  test('should use exact match for short queries (< 3 chars)', async () => {
@@ -797,9 +797,7 @@ export class MenoFilter {
797
797
  }
798
798
 
799
799
  const queryString = params.toString();
800
- const url = queryString
801
- ? `${window.location.pathname}?${queryString}`
802
- : window.location.pathname;
800
+ const url = queryString ? `${window.location.pathname}?${queryString}` : window.location.pathname;
803
801
 
804
802
  if (this.urlMode === 'push') {
805
803
  history.pushState(null, '', url);
@@ -1082,17 +1080,14 @@ export class MenoFilter {
1082
1080
 
1083
1081
  // Apply OR criteria
1084
1082
  if (this.orCriteria.length > 0) {
1085
- result = result.filter((item) =>
1086
- this.orCriteria.some((criteria) => this.matchesCriteria(item, criteria))
1087
- );
1083
+ result = result.filter((item) => this.orCriteria.some((criteria) => this.matchesCriteria(item, criteria)));
1088
1084
  }
1089
1085
 
1090
1086
  // Apply search
1091
1087
  if (this.searchQuery) {
1092
1088
  const query = this.searchQuery;
1093
1089
  result = result.filter((item) => {
1094
- const fieldsToSearch =
1095
- this.searchFields.length > 0 ? this.searchFields : Object.keys(item);
1090
+ const fieldsToSearch = this.searchFields.length > 0 ? this.searchFields : Object.keys(item);
1096
1091
  return fieldsToSearch.some((field) => {
1097
1092
  const value = item[field];
1098
1093
  if (typeof value !== 'string') return false;
@@ -1259,13 +1254,14 @@ export class MenoFilter {
1259
1254
  case '$nin':
1260
1255
  return Array.isArray(opValue) ? !opValue.includes(itemValue) : true;
1261
1256
 
1262
- case '$empty':
1257
+ case '$empty': {
1263
1258
  const isEmpty =
1264
1259
  itemValue === undefined ||
1265
1260
  itemValue === null ||
1266
1261
  itemValue === '' ||
1267
1262
  (Array.isArray(itemValue) && itemValue.length === 0);
1268
1263
  return opValue ? isEmpty : !isEmpty;
1264
+ }
1269
1265
 
1270
1266
  default:
1271
1267
  console.warn(`MenoFilter: Unknown operator "${op}"`);