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,5 +1,5 @@
1
- import { test, expect, describe, beforeEach, afterEach, mock } from "bun:test";
2
- import { navigateTo, createNavigationHandler } from "./navigation";
1
+ import { test, expect, describe, beforeEach, afterEach, mock } from 'bun:test';
2
+ import { navigateTo, createNavigationHandler } from './navigation';
3
3
 
4
4
  // Setup browser-like environment
5
5
  function setupWindowMock() {
@@ -13,15 +13,11 @@ function setupWindowMock() {
13
13
  }
14
14
  // Add PopStateEvent if not defined
15
15
  if (typeof globalThis.PopStateEvent === 'undefined') {
16
- globalThis.PopStateEvent = class PopStateEvent extends Event {
17
- constructor(type: string, eventInitDict?: PopStateEventInit) {
18
- super(type, eventInitDict);
19
- }
20
- } as any;
16
+ globalThis.PopStateEvent = class PopStateEvent extends Event {} as any;
21
17
  }
22
18
  }
23
19
 
24
- describe("Navigation - navigateTo", () => {
20
+ describe('Navigation - navigateTo', () => {
25
21
  let originalPushState: any;
26
22
  let originalDispatchEvent: any;
27
23
  let pushStateCalls: Array<{ state: any; title: string; url: string }>;
@@ -29,20 +25,20 @@ describe("Navigation - navigateTo", () => {
29
25
 
30
26
  beforeEach(() => {
31
27
  setupWindowMock();
32
-
28
+
33
29
  // Save originals
34
30
  originalPushState = (globalThis as any).window.history.pushState;
35
31
  originalDispatchEvent = (globalThis as any).window.dispatchEvent;
36
-
32
+
37
33
  // Track calls
38
34
  pushStateCalls = [];
39
35
  dispatchedEvents = [];
40
-
36
+
41
37
  // Mock pushState
42
38
  (globalThis as any).window.history.pushState = mock((state: any, title: string, url: string) => {
43
39
  pushStateCalls.push({ state, title, url });
44
40
  }) as any;
45
-
41
+
46
42
  // Mock dispatchEvent
47
43
  (globalThis as any).window.dispatchEvent = mock((event: Event) => {
48
44
  dispatchedEvents.push(event);
@@ -58,57 +54,57 @@ describe("Navigation - navigateTo", () => {
58
54
  }
59
55
  });
60
56
 
61
- test("should navigate to root path", () => {
62
- navigateTo("/");
63
-
57
+ test('should navigate to root path', () => {
58
+ navigateTo('/');
59
+
64
60
  expect(pushStateCalls.length).toBe(1);
65
- expect(pushStateCalls[0].url).toBe("/");
61
+ expect(pushStateCalls[0]!.url).toBe('/');
66
62
  expect(dispatchedEvents.length).toBe(1);
67
- expect(dispatchedEvents[0].type).toBe("popstate");
63
+ expect(dispatchedEvents[0]!.type).toBe('popstate');
68
64
  });
69
65
 
70
- test("should navigate to nested path", () => {
71
- navigateTo("/about");
72
-
66
+ test('should navigate to nested path', () => {
67
+ navigateTo('/about');
68
+
73
69
  expect(pushStateCalls.length).toBe(1);
74
- expect(pushStateCalls[0].url).toBe("/about");
75
- expect(dispatchedEvents[0].type).toBe("popstate");
70
+ expect(pushStateCalls[0]!.url).toBe('/about');
71
+ expect(dispatchedEvents[0]!.type).toBe('popstate');
76
72
  });
77
73
 
78
- test("should navigate to deeply nested path", () => {
79
- navigateTo("/blog/post-1");
80
-
81
- expect(pushStateCalls[0].url).toBe("/blog/post-1");
74
+ test('should navigate to deeply nested path', () => {
75
+ navigateTo('/blog/post-1');
76
+
77
+ expect(pushStateCalls[0]!.url).toBe('/blog/post-1');
82
78
  });
83
79
 
84
- test("should call pushState with empty state object", () => {
85
- navigateTo("/test");
86
-
87
- expect(pushStateCalls[0].state).toEqual({});
88
- expect(pushStateCalls[0].title).toBe("");
80
+ test('should call pushState with empty state object', () => {
81
+ navigateTo('/test');
82
+
83
+ expect(pushStateCalls[0]!.state).toEqual({});
84
+ expect(pushStateCalls[0]!.title).toBe('');
89
85
  });
90
86
 
91
- test("should dispatch PopStateEvent", () => {
92
- navigateTo("/test");
93
-
87
+ test('should dispatch PopStateEvent', () => {
88
+ navigateTo('/test');
89
+
94
90
  expect(dispatchedEvents.length).toBe(1);
95
91
  expect(dispatchedEvents[0]).toBeInstanceOf(PopStateEvent);
96
92
  });
97
93
 
98
- test("should handle path with query string", () => {
99
- navigateTo("/search?q=test");
100
-
101
- expect(pushStateCalls[0].url).toBe("/search?q=test");
94
+ test('should handle path with query string', () => {
95
+ navigateTo('/search?q=test');
96
+
97
+ expect(pushStateCalls[0]!.url).toBe('/search?q=test');
102
98
  });
103
99
 
104
- test("should handle path with hash", () => {
105
- navigateTo("/page#section");
106
-
107
- expect(pushStateCalls[0].url).toBe("/page#section");
100
+ test('should handle path with hash', () => {
101
+ navigateTo('/page#section');
102
+
103
+ expect(pushStateCalls[0]!.url).toBe('/page#section');
108
104
  });
109
105
  });
110
106
 
111
- describe("Navigation - createNavigationHandler", () => {
107
+ describe('Navigation - createNavigationHandler', () => {
112
108
  let originalPushState: any;
113
109
  let originalDispatchEvent: any;
114
110
  let pushStateCalls: Array<{ url: string }>;
@@ -118,14 +114,14 @@ describe("Navigation - createNavigationHandler", () => {
118
114
  setupWindowMock();
119
115
  originalPushState = (globalThis as any).window.history.pushState;
120
116
  originalDispatchEvent = (globalThis as any).window.dispatchEvent;
121
-
117
+
122
118
  pushStateCalls = [];
123
119
  preventDefaultCalled = false;
124
-
125
- (globalThis as any).window.history.pushState = mock((state: any, title: string, url: string) => {
120
+
121
+ (globalThis as any).window.history.pushState = mock((_state: any, _title: string, url: string) => {
126
122
  pushStateCalls.push({ url });
127
123
  }) as any;
128
-
124
+
129
125
  (globalThis as any).window.dispatchEvent = mock(() => true);
130
126
  });
131
127
 
@@ -136,78 +132,78 @@ describe("Navigation - createNavigationHandler", () => {
136
132
  }
137
133
  });
138
134
 
139
- test("should create handler that prevents default", () => {
140
- const handler = createNavigationHandler("/test");
135
+ test('should create handler that prevents default', () => {
136
+ const handler = createNavigationHandler('/test');
141
137
  const mockEvent = {
142
138
  preventDefault: mock(() => {
143
139
  preventDefaultCalled = true;
144
- })
140
+ }),
145
141
  } as any;
146
-
142
+
147
143
  handler(mockEvent);
148
-
144
+
149
145
  expect(preventDefaultCalled).toBe(true);
150
146
  expect(mockEvent.preventDefault).toHaveBeenCalled();
151
147
  });
152
148
 
153
- test("should create handler that navigates to path", () => {
154
- const handler = createNavigationHandler("/about");
149
+ test('should create handler that navigates to path', () => {
150
+ const handler = createNavigationHandler('/about');
155
151
  const mockEvent = {
156
- preventDefault: mock(() => {})
152
+ preventDefault: mock(() => {}),
157
153
  } as any;
158
-
154
+
159
155
  handler(mockEvent);
160
-
156
+
161
157
  expect(pushStateCalls.length).toBe(1);
162
- expect(pushStateCalls[0].url).toBe("/about");
158
+ expect(pushStateCalls[0]!.url).toBe('/about');
163
159
  });
164
160
 
165
- test("should prevent default before navigating", () => {
166
- const handler = createNavigationHandler("/test");
161
+ test('should prevent default before navigating', () => {
162
+ const handler = createNavigationHandler('/test');
167
163
  let preventDefaultCalledFirst = false;
168
164
  let navigationCalledFirst = false;
169
-
165
+
170
166
  const mockEvent = {
171
167
  preventDefault: mock(() => {
172
168
  preventDefaultCalledFirst = !navigationCalledFirst;
173
- })
169
+ }),
174
170
  } as any;
175
-
176
- const originalPushState = (globalThis as any).window.history.pushState;
171
+
172
+ const _originalPushState = (globalThis as any).window.history.pushState;
177
173
  (globalThis as any).window.history.pushState = mock(() => {
178
174
  navigationCalledFirst = !preventDefaultCalledFirst;
179
175
  }) as any;
180
-
176
+
181
177
  handler(mockEvent);
182
-
178
+
183
179
  // preventDefault should be called before navigation
184
180
  expect(preventDefaultCalledFirst).toBe(true);
185
181
  });
186
182
 
187
- test("should handle root path in handler", () => {
188
- const handler = createNavigationHandler("/");
183
+ test('should handle root path in handler', () => {
184
+ const handler = createNavigationHandler('/');
189
185
  const mockEvent = {
190
- preventDefault: mock(() => {})
186
+ preventDefault: mock(() => {}),
191
187
  } as any;
192
-
188
+
193
189
  handler(mockEvent);
194
-
195
- expect(pushStateCalls[0].url).toBe("/");
190
+
191
+ expect(pushStateCalls[0]!.url).toBe('/');
196
192
  });
197
193
 
198
- test("should handle nested paths in handler", () => {
199
- const handler = createNavigationHandler("/blog/post-1");
194
+ test('should handle nested paths in handler', () => {
195
+ const handler = createNavigationHandler('/blog/post-1');
200
196
  const mockEvent = {
201
- preventDefault: mock(() => {})
197
+ preventDefault: mock(() => {}),
202
198
  } as any;
203
-
199
+
204
200
  handler(mockEvent);
205
-
206
- expect(pushStateCalls[0].url).toBe("/blog/post-1");
201
+
202
+ expect(pushStateCalls[0]!.url).toBe('/blog/post-1');
207
203
  });
208
204
  });
209
205
 
210
- describe("Navigation - Path handling", () => {
206
+ describe('Navigation - Path handling', () => {
211
207
  let originalPushState: any;
212
208
  let originalDispatchEvent: any;
213
209
 
@@ -215,7 +211,7 @@ describe("Navigation - Path handling", () => {
215
211
  setupWindowMock();
216
212
  originalPushState = (globalThis as any).window.history.pushState;
217
213
  originalDispatchEvent = (globalThis as any).window.dispatchEvent;
218
-
214
+
219
215
  (globalThis as any).window.history.pushState = mock(() => {}) as any;
220
216
  (globalThis as any).window.dispatchEvent = mock(() => true);
221
217
  });
@@ -227,151 +223,151 @@ describe("Navigation - Path handling", () => {
227
223
  }
228
224
  });
229
225
 
230
- describe("Root path handling", () => {
231
- test("should navigate to root path correctly", () => {
226
+ describe('Root path handling', () => {
227
+ test('should navigate to root path correctly', () => {
232
228
  const pushStateCalls: Array<{ url: string }> = [];
233
- (globalThis as any).window.history.pushState = mock((state: any, title: string, url: string) => {
229
+ (globalThis as any).window.history.pushState = mock((_state: any, _title: string, url: string) => {
234
230
  pushStateCalls.push({ url });
235
231
  }) as any;
236
-
237
- navigateTo("/");
238
-
239
- expect(pushStateCalls[0].url).toBe("/");
232
+
233
+ navigateTo('/');
234
+
235
+ expect(pushStateCalls[0]!.url).toBe('/');
240
236
  });
241
237
 
242
- test("should handle root path with handler", () => {
243
- const handler = createNavigationHandler("/");
238
+ test('should handle root path with handler', () => {
239
+ const handler = createNavigationHandler('/');
244
240
  const pushStateCalls: Array<{ url: string }> = [];
245
- (globalThis as any).window.history.pushState = mock((state: any, title: string, url: string) => {
241
+ (globalThis as any).window.history.pushState = mock((_state: any, _title: string, url: string) => {
246
242
  pushStateCalls.push({ url });
247
243
  }) as any;
248
-
244
+
249
245
  const mockEvent = {
250
- preventDefault: mock(() => {})
246
+ preventDefault: mock(() => {}),
251
247
  } as any;
252
-
248
+
253
249
  handler(mockEvent);
254
-
255
- expect(pushStateCalls[0].url).toBe("/");
250
+
251
+ expect(pushStateCalls[0]!.url).toBe('/');
256
252
  });
257
253
  });
258
254
 
259
- describe("Nested paths handling", () => {
260
- test("should handle single level nested path", () => {
255
+ describe('Nested paths handling', () => {
256
+ test('should handle single level nested path', () => {
261
257
  const pushStateCalls: Array<{ url: string }> = [];
262
- (globalThis as any).window.history.pushState = mock((state: any, title: string, url: string) => {
258
+ (globalThis as any).window.history.pushState = mock((_state: any, _title: string, url: string) => {
263
259
  pushStateCalls.push({ url });
264
260
  }) as any;
265
-
266
- navigateTo("/about");
267
-
268
- expect(pushStateCalls[0].url).toBe("/about");
261
+
262
+ navigateTo('/about');
263
+
264
+ expect(pushStateCalls[0]!.url).toBe('/about');
269
265
  });
270
266
 
271
- test("should handle multi-level nested paths", () => {
267
+ test('should handle multi-level nested paths', () => {
272
268
  const pushStateCalls: Array<{ url: string }> = [];
273
- (globalThis as any).window.history.pushState = mock((state: any, title: string, url: string) => {
269
+ (globalThis as any).window.history.pushState = mock((_state: any, _title: string, url: string) => {
274
270
  pushStateCalls.push({ url });
275
271
  }) as any;
276
-
277
- navigateTo("/blog/category/post-1");
278
-
279
- expect(pushStateCalls[0].url).toBe("/blog/category/post-1");
272
+
273
+ navigateTo('/blog/category/post-1');
274
+
275
+ expect(pushStateCalls[0]!.url).toBe('/blog/category/post-1');
280
276
  });
281
277
 
282
- test("should handle paths with trailing slash", () => {
278
+ test('should handle paths with trailing slash', () => {
283
279
  const pushStateCalls: Array<{ url: string }> = [];
284
- (globalThis as any).window.history.pushState = mock((state: any, title: string, url: string) => {
280
+ (globalThis as any).window.history.pushState = mock((_state: any, _title: string, url: string) => {
285
281
  pushStateCalls.push({ url });
286
282
  }) as any;
287
-
288
- navigateTo("/about/");
289
-
290
- expect(pushStateCalls[0].url).toBe("/about/");
283
+
284
+ navigateTo('/about/');
285
+
286
+ expect(pushStateCalls[0]!.url).toBe('/about/');
291
287
  });
292
288
  });
293
289
 
294
- describe("Special path handling", () => {
295
- test("should handle paths with query parameters", () => {
290
+ describe('Special path handling', () => {
291
+ test('should handle paths with query parameters', () => {
296
292
  const pushStateCalls: Array<{ url: string }> = [];
297
- (globalThis as any).window.history.pushState = mock((state: any, title: string, url: string) => {
293
+ (globalThis as any).window.history.pushState = mock((_state: any, _title: string, url: string) => {
298
294
  pushStateCalls.push({ url });
299
295
  }) as any;
300
-
301
- navigateTo("/search?q=test&page=1");
302
-
303
- expect(pushStateCalls[0].url).toBe("/search?q=test&page=1");
296
+
297
+ navigateTo('/search?q=test&page=1');
298
+
299
+ expect(pushStateCalls[0]!.url).toBe('/search?q=test&page=1');
304
300
  });
305
301
 
306
- test("should handle paths with hash fragments", () => {
302
+ test('should handle paths with hash fragments', () => {
307
303
  const pushStateCalls: Array<{ url: string }> = [];
308
- (globalThis as any).window.history.pushState = mock((state: any, title: string, url: string) => {
304
+ (globalThis as any).window.history.pushState = mock((_state: any, _title: string, url: string) => {
309
305
  pushStateCalls.push({ url });
310
306
  }) as any;
311
-
312
- navigateTo("/page#section");
313
-
314
- expect(pushStateCalls[0].url).toBe("/page#section");
307
+
308
+ navigateTo('/page#section');
309
+
310
+ expect(pushStateCalls[0]!.url).toBe('/page#section');
315
311
  });
316
312
 
317
- test("should handle paths with both query and hash", () => {
313
+ test('should handle paths with both query and hash', () => {
318
314
  const pushStateCalls: Array<{ url: string }> = [];
319
- (globalThis as any).window.history.pushState = mock((state: any, title: string, url: string) => {
315
+ (globalThis as any).window.history.pushState = mock((_state: any, _title: string, url: string) => {
320
316
  pushStateCalls.push({ url });
321
317
  }) as any;
322
-
323
- navigateTo("/page?param=value#section");
324
-
325
- expect(pushStateCalls[0].url).toBe("/page?param=value#section");
318
+
319
+ navigateTo('/page?param=value#section');
320
+
321
+ expect(pushStateCalls[0]!.url).toBe('/page?param=value#section');
326
322
  });
327
323
  });
328
324
 
329
- describe("Link component behavior simulation", () => {
330
- test("should simulate Link component click behavior", () => {
331
- const handler = createNavigationHandler("/link-target");
325
+ describe('Link component behavior simulation', () => {
326
+ test('should simulate Link component click behavior', () => {
327
+ const handler = createNavigationHandler('/link-target');
332
328
  const mockEvent = {
333
329
  preventDefault: mock(() => {}),
334
- type: "click",
335
- target: {}
330
+ type: 'click',
331
+ target: {},
336
332
  } as any;
337
-
333
+
338
334
  const pushStateCalls: Array<{ url: string }> = [];
339
- (globalThis as any).window.history.pushState = mock((state: any, title: string, url: string) => {
335
+ (globalThis as any).window.history.pushState = mock((_state: any, _title: string, url: string) => {
340
336
  pushStateCalls.push({ url });
341
337
  }) as any;
342
-
338
+
343
339
  handler(mockEvent);
344
-
340
+
345
341
  // Should prevent default (no page reload)
346
342
  expect(mockEvent.preventDefault).toHaveBeenCalled();
347
343
  // Should navigate using history API
348
344
  expect(pushStateCalls.length).toBe(1);
349
- expect(pushStateCalls[0].url).toBe("/link-target");
345
+ expect(pushStateCalls[0]!.url).toBe('/link-target');
350
346
  });
351
347
 
352
- test("should handle multiple Link clicks", () => {
353
- const handler1 = createNavigationHandler("/page1");
354
- const handler2 = createNavigationHandler("/page2");
355
-
348
+ test('should handle multiple Link clicks', () => {
349
+ const handler1 = createNavigationHandler('/page1');
350
+ const handler2 = createNavigationHandler('/page2');
351
+
356
352
  const pushStateCalls: Array<{ url: string }> = [];
357
- (globalThis as any).window.history.pushState = mock((state: any, title: string, url: string) => {
353
+ (globalThis as any).window.history.pushState = mock((_state: any, _title: string, url: string) => {
358
354
  pushStateCalls.push({ url });
359
355
  }) as any;
360
-
356
+
361
357
  const mockEvent1 = { preventDefault: mock(() => {}) } as any;
362
358
  const mockEvent2 = { preventDefault: mock(() => {}) } as any;
363
-
359
+
364
360
  handler1(mockEvent1);
365
361
  handler2(mockEvent2);
366
-
362
+
367
363
  expect(pushStateCalls.length).toBe(2);
368
- expect(pushStateCalls[0].url).toBe("/page1");
369
- expect(pushStateCalls[1].url).toBe("/page2");
364
+ expect(pushStateCalls[0]!.url).toBe('/page1');
365
+ expect(pushStateCalls[1]!.url).toBe('/page2');
370
366
  });
371
367
  });
372
368
  });
373
369
 
374
- describe("Navigation - Integration scenarios", () => {
370
+ describe('Navigation - Integration scenarios', () => {
375
371
  let originalPushState: any;
376
372
  let originalDispatchEvent: any;
377
373
  let pushStateCalls: Array<{ url: string }>;
@@ -381,14 +377,14 @@ describe("Navigation - Integration scenarios", () => {
381
377
  setupWindowMock();
382
378
  originalPushState = (globalThis as any).window.history.pushState;
383
379
  originalDispatchEvent = (globalThis as any).window.dispatchEvent;
384
-
380
+
385
381
  pushStateCalls = [];
386
382
  dispatchedEvents = [];
387
-
388
- (globalThis as any).window.history.pushState = mock((state: any, title: string, url: string) => {
383
+
384
+ (globalThis as any).window.history.pushState = mock((_state: any, _title: string, url: string) => {
389
385
  pushStateCalls.push({ url });
390
386
  }) as any;
391
-
387
+
392
388
  (globalThis as any).window.dispatchEvent = mock((event: Event) => {
393
389
  dispatchedEvents.push(event);
394
390
  return true;
@@ -402,38 +398,38 @@ describe("Navigation - Integration scenarios", () => {
402
398
  }
403
399
  });
404
400
 
405
- test("should handle navigation sequence", () => {
406
- navigateTo("/");
407
- navigateTo("/about");
408
- navigateTo("/contact");
409
-
401
+ test('should handle navigation sequence', () => {
402
+ navigateTo('/');
403
+ navigateTo('/about');
404
+ navigateTo('/contact');
405
+
410
406
  expect(pushStateCalls.length).toBe(3);
411
- expect(pushStateCalls[0].url).toBe("/");
412
- expect(pushStateCalls[1].url).toBe("/about");
413
- expect(pushStateCalls[2].url).toBe("/contact");
407
+ expect(pushStateCalls[0]!.url).toBe('/');
408
+ expect(pushStateCalls[1]!.url).toBe('/about');
409
+ expect(pushStateCalls[2]!.url).toBe('/contact');
414
410
  expect(dispatchedEvents.length).toBe(3);
415
411
  });
416
412
 
417
- test("should work with navigation handler in sequence", () => {
418
- const handler1 = createNavigationHandler("/page1");
419
- const handler2 = createNavigationHandler("/page2");
420
-
413
+ test('should work with navigation handler in sequence', () => {
414
+ const handler1 = createNavigationHandler('/page1');
415
+ const handler2 = createNavigationHandler('/page2');
416
+
421
417
  const mockEvent = {
422
- preventDefault: mock(() => {})
418
+ preventDefault: mock(() => {}),
423
419
  } as any;
424
-
420
+
425
421
  handler1(mockEvent);
426
422
  handler2(mockEvent);
427
-
423
+
428
424
  expect(pushStateCalls.length).toBe(2);
429
425
  });
430
426
 
431
- test("should handle back/forward navigation simulation", () => {
427
+ test('should handle back/forward navigation simulation', () => {
432
428
  // Navigate forward
433
- navigateTo("/page1");
434
- navigateTo("/page2");
435
- navigateTo("/page3");
436
-
429
+ navigateTo('/page1');
430
+ navigateTo('/page2');
431
+ navigateTo('/page3');
432
+
437
433
  // Simulate back button (this would normally be handled by popstate listener)
438
434
  // The navigateTo function doesn't handle back/forward, but the router does
439
435
  expect(pushStateCalls.length).toBe(3);
@@ -20,4 +20,3 @@ export function createNavigationHandler(path: string): (e: Event) => void {
20
20
  navigateTo(path);
21
21
  };
22
22
  }
23
-
@@ -0,0 +1,71 @@
1
+ import { describe, test, expect, afterEach } from 'bun:test';
2
+ import { loadKnownTokens, getCachedKnownTokens, clearKnownTokensCache } from './responsiveStyleResolver';
3
+
4
+ /**
5
+ * The design-canvas token cache: it feeds `knownTokens` into the utility-CSS generator so bare
6
+ * color-token classes (`bg-muted`) expand to `background-color: var(--muted)` in select/design mode.
7
+ * Mirrors meno-astro's `readKnownTokensSync` — color names across every theme + variable cssVars.
8
+ */
9
+
10
+ const realFetch = globalThis.fetch;
11
+
12
+ function stubFetch(routes: Record<string, unknown>) {
13
+ globalThis.fetch = (async (input: RequestInfo | URL) => {
14
+ const url = String(input);
15
+ const path = url.startsWith('/') ? url : new URL(url).pathname;
16
+ if (path in routes) {
17
+ return new Response(JSON.stringify(routes[path]), { status: 200 });
18
+ }
19
+ return new Response('not found', { status: 404 });
20
+ }) as typeof fetch;
21
+ }
22
+
23
+ afterEach(() => {
24
+ globalThis.fetch = realFetch;
25
+ clearKnownTokensCache();
26
+ });
27
+
28
+ describe('loadKnownTokens (design-canvas token cache)', () => {
29
+ test('collects color names across every theme + variable cssVars (minus --)', async () => {
30
+ stubFetch({
31
+ '/api/colors-config': {
32
+ themes: {
33
+ light: { colors: { text: '#1f2937', bg: '#ffffff', muted: '#6b7280', border: '#e5e7eb' } },
34
+ dark: { colors: { text: '#fff', accentDark: '#111' } }, // a name only in another theme
35
+ },
36
+ },
37
+ '/api/variables-status': { config: { variables: [{ cssVar: '--bs' }, { cssVar: '--fs-fs' }] } },
38
+ });
39
+
40
+ const tokens = await loadKnownTokens();
41
+ for (const name of ['text', 'bg', 'muted', 'border', 'accentDark', 'bs', 'fs-fs']) {
42
+ expect(tokens.has(name)).toBe(true);
43
+ }
44
+ expect(tokens.has('colors')).toBe(false); // not the wrapper key
45
+ // Cached synchronously after load.
46
+ expect(getCachedKnownTokens()?.has('muted')).toBe(true);
47
+ });
48
+
49
+ test('is null before load, deduped across concurrent calls', async () => {
50
+ let colorsHits = 0;
51
+ globalThis.fetch = (async (input: RequestInfo | URL) => {
52
+ const path = String(input);
53
+ if (path === '/api/colors-config') {
54
+ colorsHits++;
55
+ return new Response(JSON.stringify({ themes: { light: { colors: { muted: '#6b7280' } } } }), { status: 200 });
56
+ }
57
+ return new Response(JSON.stringify({ config: { variables: [] } }), { status: 200 });
58
+ }) as typeof fetch;
59
+
60
+ expect(getCachedKnownTokens()).toBeNull();
61
+ const [a, b] = await Promise.all([loadKnownTokens(), loadKnownTokens()]);
62
+ expect(a).toBe(b); // same cached set
63
+ expect(colorsHits).toBe(1); // deduped — only fetched once
64
+ });
65
+
66
+ test('survives a failed fetch (empty set, no throw)', async () => {
67
+ globalThis.fetch = (async () => new Response('boom', { status: 500 })) as typeof fetch;
68
+ const tokens = await loadKnownTokens();
69
+ expect(tokens.size).toBe(0);
70
+ });
71
+ });