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,9 +1,9 @@
1
- import { test, expect, describe } from "bun:test";
2
- import { buildLineMap, lineMapToObject } from "./jsonLineMapper";
1
+ import { test, expect, describe } from 'bun:test';
2
+ import { buildLineMap, lineMapToObject } from './jsonLineMapper';
3
3
 
4
- describe("jsonLineMapper", () => {
5
- describe("buildLineMap", () => {
6
- test("should track line numbers for children array elements", () => {
4
+ describe('jsonLineMapper', () => {
5
+ describe('buildLineMap', () => {
6
+ test('should track line numbers for children array elements', () => {
7
7
  const json = `{
8
8
  "root": {
9
9
  "type": "node",
@@ -23,15 +23,15 @@ describe("jsonLineMapper", () => {
23
23
  const lineMap = buildLineMap(json);
24
24
 
25
25
  // First child starts at line 5, ends at line 8
26
- expect(lineMap.get("0")).toBeDefined();
27
- expect(lineMap.get("0")?.startLine).toBe(5);
26
+ expect(lineMap.get('0')).toBeDefined();
27
+ expect(lineMap.get('0')?.startLine).toBe(5);
28
28
 
29
29
  // Second child starts at line 9, ends at line 12
30
- expect(lineMap.get("1")).toBeDefined();
31
- expect(lineMap.get("1")?.startLine).toBe(9);
30
+ expect(lineMap.get('1')).toBeDefined();
31
+ expect(lineMap.get('1')?.startLine).toBe(9);
32
32
  });
33
33
 
34
- test("should handle nested children", () => {
34
+ test('should handle nested children', () => {
35
35
  const json = `{
36
36
  "root": {
37
37
  "type": "node",
@@ -53,15 +53,15 @@ describe("jsonLineMapper", () => {
53
53
  const lineMap = buildLineMap(json);
54
54
 
55
55
  // First child of root - uses comma-separated format to match pathToString
56
- expect(lineMap.get("0")).toBeDefined();
57
- expect(lineMap.get("0")?.startLine).toBe(5);
56
+ expect(lineMap.get('0')).toBeDefined();
57
+ expect(lineMap.get('0')?.startLine).toBe(5);
58
58
 
59
59
  // First child of first child - comma-separated format
60
- expect(lineMap.get("0,0")).toBeDefined();
61
- expect(lineMap.get("0,0")?.startLine).toBe(9);
60
+ expect(lineMap.get('0,0')).toBeDefined();
61
+ expect(lineMap.get('0,0')?.startLine).toBe(9);
62
62
  });
63
63
 
64
- test("should handle empty children array", () => {
64
+ test('should handle empty children array', () => {
65
65
  const json = `{
66
66
  "root": {
67
67
  "type": "node",
@@ -72,7 +72,7 @@ describe("jsonLineMapper", () => {
72
72
  const lineMap = buildLineMap(json);
73
73
  // Only the root entry (empty-string key) is recorded; no children.
74
74
  expect(lineMap.size).toBe(1);
75
- expect(lineMap.get("")).toBeDefined();
75
+ expect(lineMap.get('')).toBeDefined();
76
76
  });
77
77
 
78
78
  test("records the root's own line range under the empty-string key", () => {
@@ -90,10 +90,10 @@ describe("jsonLineMapper", () => {
90
90
 
91
91
  const lineMap = buildLineMap(json);
92
92
  // Root value starts at line 2 and closes at line 10.
93
- expect(lineMap.get("")).toEqual({ startLine: 2, endLine: 10 });
93
+ expect(lineMap.get('')).toEqual({ startLine: 2, endLine: 10 });
94
94
  });
95
95
 
96
- test("should handle JSON without root", () => {
96
+ test('should handle JSON without root', () => {
97
97
  const json = `{
98
98
  "meta": {
99
99
  "title": "Test"
@@ -104,7 +104,7 @@ describe("jsonLineMapper", () => {
104
104
  expect(lineMap.size).toBe(0);
105
105
  });
106
106
 
107
- test("tracks component format via component.structure", () => {
107
+ test('tracks component format via component.structure', () => {
108
108
  const json = `{
109
109
  "component": {
110
110
  "interface": {
@@ -129,24 +129,24 @@ describe("jsonLineMapper", () => {
129
129
 
130
130
  const lineMap = buildLineMap(json);
131
131
  // Structure spans from its opening `{` (line 6) to its closing `}` (line 19).
132
- expect(lineMap.get("")).toEqual({ startLine: 6, endLine: 19 });
132
+ expect(lineMap.get('')).toEqual({ startLine: 6, endLine: 19 });
133
133
  // First child: the <span>.
134
- expect(lineMap.get("0")?.startLine).toBe(10);
134
+ expect(lineMap.get('0')?.startLine).toBe(10);
135
135
  // Second child: the Icon component instance.
136
- expect(lineMap.get("1")?.startLine).toBe(14);
136
+ expect(lineMap.get('1')?.startLine).toBe(14);
137
137
  });
138
138
  });
139
139
 
140
- describe("lineMapToObject", () => {
141
- test("should convert Map to plain object", () => {
140
+ describe('lineMapToObject', () => {
141
+ test('should convert Map to plain object', () => {
142
142
  const lineMap = new Map();
143
- lineMap.set("0", { startLine: 5, endLine: 10 });
144
- lineMap.set("0,1", { startLine: 7, endLine: 9 });
143
+ lineMap.set('0', { startLine: 5, endLine: 10 });
144
+ lineMap.set('0,1', { startLine: 7, endLine: 9 });
145
145
 
146
146
  const obj = lineMapToObject(lineMap);
147
147
 
148
- expect(obj["0"]).toEqual({ startLine: 5, endLine: 10 });
149
- expect(obj["0,1"]).toEqual({ startLine: 7, endLine: 9 });
148
+ expect(obj['0']).toEqual({ startLine: 5, endLine: 10 });
149
+ expect(obj['0,1']).toEqual({ startLine: 7, endLine: 9 });
150
150
  });
151
151
  });
152
152
  });
@@ -16,7 +16,7 @@ export type LineMap = Map<string, LineRange>;
16
16
  */
17
17
  export function buildLineMap(jsonText: string): LineMap {
18
18
  const lineMap = new Map<string, LineRange>();
19
- const lines = jsonText.split('\n');
19
+ const _lines = jsonText.split('\n');
20
20
 
21
21
  // Build character offset to line number lookup
22
22
  const charToLine: number[] = [];
@@ -32,7 +32,7 @@ export function buildLineMap(jsonText: string): LineMap {
32
32
  let pos = 0;
33
33
 
34
34
  function skipWhitespace(): void {
35
- while (pos < jsonText.length && /\s/.test(jsonText[pos])) {
35
+ while (pos < jsonText.length && /\s/.test(jsonText[pos] ?? '')) {
36
36
  pos++;
37
37
  }
38
38
  }
@@ -58,7 +58,7 @@ export function buildLineMap(jsonText: string): LineMap {
58
58
  }
59
59
 
60
60
  function parseNumber(): void {
61
- while (pos < jsonText.length && /[\d.eE\-+]/.test(jsonText[pos])) {
61
+ while (pos < jsonText.length && /[\d.eE\-+]/.test(jsonText[pos] ?? '')) {
62
62
  pos++;
63
63
  }
64
64
  }
@@ -91,8 +91,8 @@ export function buildLineMap(jsonText: string): LineMap {
91
91
  // under the empty-string key, so callers can resolve the root selection itself.
92
92
  const { start, end } = parseValue(path, true);
93
93
  lineMap.set('', {
94
- startLine: charToLine[start],
95
- endLine: charToLine[end - 1] || charToLine[start],
94
+ startLine: charToLine[start] ?? 0,
95
+ endLine: charToLine[end - 1] || charToLine[start] || 0,
96
96
  });
97
97
  }
98
98
 
@@ -169,8 +169,8 @@ export function buildLineMap(jsonText: string): LineMap {
169
169
  if (trackChildren) {
170
170
  const pathStr = childPath.join(',');
171
171
  lineMap.set(pathStr, {
172
- startLine: charToLine[start],
173
- endLine: charToLine[end - 1] || charToLine[start]
172
+ startLine: charToLine[start] ?? 0,
173
+ endLine: charToLine[end - 1] || charToLine[start] || 0,
174
174
  });
175
175
  }
176
176
 
@@ -3,7 +3,6 @@
3
3
  * Scans all rendered HTML and warns about styles that don't generate utility classes
4
4
  */
5
5
 
6
- import { propertyMap } from '../shared/utilityClassConfig';
7
6
  import type { StyleObject, ResponsiveStyleObject } from '../shared/types';
8
7
 
9
8
  interface MissingStyleReport {
@@ -26,8 +25,17 @@ const missingStylesMap = new Map<string, MissingStyleReport>();
26
25
  function canGenerateClass(property: string, value: unknown): boolean {
27
26
  // Skip internal component properties that shouldn't be styles
28
27
  const internalProps = new Set([
29
- 'type', 'tag', 'props', 'component', 'children', 'id', 'key',
30
- 'ref', 'className', 'style', 'node'
28
+ 'type',
29
+ 'tag',
30
+ 'props',
31
+ 'component',
32
+ 'children',
33
+ 'id',
34
+ 'key',
35
+ 'ref',
36
+ 'className',
37
+ 'style',
38
+ 'node',
31
39
  ]);
32
40
 
33
41
  if (internalProps.has(property)) {
@@ -36,7 +44,7 @@ function canGenerateClass(property: string, value: unknown): boolean {
36
44
 
37
45
  // Skip if value is null, undefined, or empty - these don't need utility classes
38
46
  if (value === null || value === undefined || value === '') {
39
- return true; // Skip reporting - nothing to convert
47
+ return true; // Skip reporting - nothing to convert
40
48
  }
41
49
 
42
50
  // Try to convert to string and check
@@ -60,10 +68,7 @@ function canGenerateClass(property: string, value: unknown): boolean {
60
68
  /**
61
69
  * Validate a style object and report missing utility class coverage
62
70
  */
63
- export function validateStyleCoverage(
64
- styles: StyleObject | ResponsiveStyleObject | undefined,
65
- location: string
66
- ): void {
71
+ export function validateStyleCoverage(styles: StyleObject | ResponsiveStyleObject | undefined, location: string): void {
67
72
  if (!styles || typeof styles !== 'object') {
68
73
  return;
69
74
  }
@@ -111,21 +116,15 @@ export function printMissingStyleWarnings(verbose = false): void {
111
116
  }
112
117
 
113
118
  const warnings: string[] = [];
114
- warnings.push(
115
- '\n⚠️ WARNING: Found styles that cannot be converted to utility classes\n'
116
- );
117
- warnings.push(
118
- 'These styles use object values which cannot be serialized to class names:\n'
119
- );
119
+ warnings.push('\n⚠️ WARNING: Found styles that cannot be converted to utility classes\n');
120
+ warnings.push('These styles use object values which cannot be serialized to class names:\n');
120
121
 
121
122
  // Sort by frequency
122
- const sorted = Array.from(missingStylesMap.values()).sort(
123
- (a, b) => b.count - a.count
124
- );
123
+ const sorted = Array.from(missingStylesMap.values()).sort((a, b) => b.count - a.count);
125
124
 
126
125
  for (const report of sorted) {
127
126
  warnings.push(
128
- ` • ${report.property}: "${report.value}" (used ${report.count} time${report.count > 1 ? 's' : ''})`
127
+ ` • ${report.property}: "${report.value}" (used ${report.count} time${report.count > 1 ? 's' : ''})`,
129
128
  );
130
129
 
131
130
  if (verbose && report.locations.length > 0) {
@@ -133,9 +132,7 @@ export function printMissingStyleWarnings(verbose = false): void {
133
132
  warnings.push(` └─ ${location}`);
134
133
  }
135
134
  if (report.locations.length > 3) {
136
- warnings.push(
137
- ` └─ ... and ${report.locations.length - 3} more locations`
138
- );
135
+ warnings.push(` └─ ... and ${report.locations.length - 3} more locations`);
139
136
  }
140
137
  }
141
138
  }
@@ -23,29 +23,27 @@ export class WebSocketManager {
23
23
  removeClient(ws: RuntimeWSClient): void {
24
24
  this.clients.delete(ws);
25
25
  }
26
-
26
+
27
27
  /**
28
28
  * Broadcast message to all connected clients
29
29
  */
30
30
  broadcast(message: HMRMessage | string): void {
31
- const messageStr = typeof message === 'string'
32
- ? message
33
- : JSON.stringify(message);
34
-
31
+ const messageStr = typeof message === 'string' ? message : JSON.stringify(message);
32
+
35
33
  for (const ws of this.clients) {
36
34
  if (ws.readyState === WEBSOCKET_STATES.OPEN) {
37
35
  ws.send(messageStr);
38
36
  }
39
37
  }
40
38
  }
41
-
39
+
42
40
  /**
43
41
  * Broadcast update notification
44
42
  */
45
43
  broadcastUpdate(path?: string): void {
46
44
  this.broadcast({
47
45
  type: 'hmr:update',
48
- path: path || 'all'
46
+ path: path || 'all',
49
47
  });
50
48
  }
51
49
 
@@ -54,7 +52,7 @@ export class WebSocketManager {
54
52
  */
55
53
  broadcastColorsUpdate(): void {
56
54
  this.broadcast({
57
- type: 'hmr:colors-update'
55
+ type: 'hmr:colors-update',
58
56
  });
59
57
  }
60
58
 
@@ -63,7 +61,7 @@ export class WebSocketManager {
63
61
  */
64
62
  broadcastVariablesUpdate(): void {
65
63
  this.broadcast({
66
- type: 'hmr:variables-update'
64
+ type: 'hmr:variables-update',
67
65
  });
68
66
  }
69
67
 
@@ -72,7 +70,7 @@ export class WebSocketManager {
72
70
  */
73
71
  broadcastFontsUpdate(): void {
74
72
  this.broadcast({
75
- type: 'hmr:fonts-update'
73
+ type: 'hmr:fonts-update',
76
74
  });
77
75
  }
78
76
 
@@ -81,7 +79,7 @@ export class WebSocketManager {
81
79
  */
82
80
  broadcastLibrariesUpdate(): void {
83
81
  this.broadcast({
84
- type: 'hmr:libraries-update'
82
+ type: 'hmr:libraries-update',
85
83
  });
86
84
  }
87
85
 
@@ -90,7 +88,7 @@ export class WebSocketManager {
90
88
  */
91
89
  broadcastEnumsUpdate(): void {
92
90
  this.broadcast({
93
- type: 'hmr:enums-update'
91
+ type: 'hmr:enums-update',
94
92
  });
95
93
  }
96
94
 
@@ -100,7 +98,7 @@ export class WebSocketManager {
100
98
  broadcastCMSUpdate(collection: string): void {
101
99
  this.broadcast({
102
100
  type: 'hmr:cms-update',
103
- collection
101
+ collection,
104
102
  });
105
103
  }
106
104
 
@@ -111,7 +109,7 @@ export class WebSocketManager {
111
109
  */
112
110
  broadcastCollectionsUpdate(): void {
113
111
  this.broadcast({
114
- type: 'hmr:cms-collections-update'
112
+ type: 'hmr:cms-collections-update',
115
113
  });
116
114
  }
117
115
 
@@ -123,7 +121,19 @@ export class WebSocketManager {
123
121
  */
124
122
  broadcastConfigUpdate(): void {
125
123
  this.broadcast({
126
- type: 'hmr:config-update'
124
+ type: 'hmr:config-update',
125
+ });
126
+ }
127
+
128
+ /**
129
+ * Broadcast external-stylesheet update notification. Emitted when a project CSS
130
+ * file outside the watched categories changes (e.g. a mirror-import class edit
131
+ * via /api/element-styles/update) — tells the canvas to cache-bust its `<link>`
132
+ * stylesheets and repaint, since the file watcher doesn't cover public/ CSS.
133
+ */
134
+ broadcastStylesheetUpdate(): void {
135
+ this.broadcast({
136
+ type: 'hmr:stylesheet-update',
127
137
  });
128
138
  }
129
139
 
@@ -133,21 +143,21 @@ export class WebSocketManager {
133
143
  getClientCount(): number {
134
144
  return this.clients.size;
135
145
  }
136
-
146
+
137
147
  /**
138
148
  * Clear all clients
139
149
  */
140
150
  clear(): void {
141
151
  this.clients.clear();
142
152
  }
143
-
153
+
144
154
  /**
145
155
  * Get all clients
146
156
  */
147
157
  getClients(): Set<RuntimeWSClient> {
148
158
  return new Set(this.clients);
149
159
  }
150
-
160
+
151
161
  /**
152
162
  * Check if any clients are connected
153
163
  */
@@ -155,4 +165,3 @@ export class WebSocketManager {
155
165
  return this.clients.size > 0;
156
166
  }
157
167
  }
158
-
@@ -18,12 +18,12 @@ describe('attributeNodeUtils', () => {
18
18
  const node: ComponentNode = {
19
19
  type: 'node' as const,
20
20
  tag: 'div',
21
- attributes: { id: 'test', disabled: true, tabIndex: 0 }
21
+ attributes: { id: 'test', disabled: true, tabIndex: 0 },
22
22
  };
23
23
  expect(extractAttributesFromNode(node)).toEqual({
24
24
  id: 'test',
25
25
  disabled: true,
26
- tabIndex: 0
26
+ tabIndex: 0,
27
27
  });
28
28
  });
29
29
 
@@ -31,7 +31,7 @@ describe('attributeNodeUtils', () => {
31
31
  const node: ComponentNode = {
32
32
  type: 'node' as const,
33
33
  tag: 'div',
34
- attributes: {}
34
+ attributes: {},
35
35
  };
36
36
  expect(extractAttributesFromNode(node)).toEqual({});
37
37
  });
@@ -44,14 +44,14 @@ describe('attributeNodeUtils', () => {
44
44
  type: 'text',
45
45
  required: true,
46
46
  maxLength: 100,
47
- placeholder: 'Enter text'
48
- }
47
+ placeholder: 'Enter text',
48
+ },
49
49
  };
50
50
  expect(extractAttributesFromNode(node)).toEqual({
51
51
  type: 'text',
52
52
  required: true,
53
53
  maxLength: 100,
54
- placeholder: 'Enter text'
54
+ placeholder: 'Enter text',
55
55
  });
56
56
  });
57
57
 
@@ -83,7 +83,7 @@ describe('attributeNodeUtils', () => {
83
83
  expect(result).toEqual({
84
84
  type: 'node',
85
85
  tag: 'div',
86
- attributes: { id: 'test', className: 'btn' }
86
+ attributes: { id: 'test', className: 'btn' },
87
87
  });
88
88
  });
89
89
 
@@ -91,7 +91,7 @@ describe('attributeNodeUtils', () => {
91
91
  const node: ComponentNode = {
92
92
  type: 'node',
93
93
  tag: 'div',
94
- attributes: { id: 'original', disabled: true }
94
+ attributes: { id: 'original', disabled: true },
95
95
  };
96
96
  const result = applyAttributesToNode(node, { className: 'new', tabIndex: 0 });
97
97
  expect(result).toEqual({
@@ -101,8 +101,8 @@ describe('attributeNodeUtils', () => {
101
101
  id: 'original',
102
102
  disabled: true,
103
103
  className: 'new',
104
- tabIndex: 0
105
- }
104
+ tabIndex: 0,
105
+ },
106
106
  });
107
107
  });
108
108
 
@@ -110,25 +110,25 @@ describe('attributeNodeUtils', () => {
110
110
  const node: ComponentNode = {
111
111
  type: 'node',
112
112
  tag: 'div',
113
- attributes: { id: 'original', className: 'old' }
113
+ attributes: { id: 'original', className: 'old' },
114
114
  };
115
115
  const result = applyAttributesToNode(node, { className: 'new' });
116
116
  expect(result.attributes).toEqual({
117
117
  id: 'original',
118
- className: 'new'
118
+ className: 'new',
119
119
  });
120
120
  });
121
121
 
122
122
  test('works with component nodes', () => {
123
123
  const node: ComponentNode = {
124
124
  type: 'component' as const,
125
- component: 'Button'
125
+ component: 'Button',
126
126
  };
127
127
  const result = applyAttributesToNode(node, { disabled: true });
128
128
  expect(result).toEqual({
129
129
  type: 'component',
130
130
  component: 'Button',
131
- attributes: { disabled: true }
131
+ attributes: { disabled: true },
132
132
  });
133
133
  });
134
134
 
@@ -142,7 +142,7 @@ describe('attributeNodeUtils', () => {
142
142
  const node: ComponentNode = {
143
143
  type: 'node',
144
144
  tag: 'div',
145
- attributes: { id: 'original' }
145
+ attributes: { id: 'original' },
146
146
  };
147
147
  const original = JSON.stringify(node);
148
148
  applyAttributesToNode(node, { className: 'new' });
@@ -11,9 +11,7 @@ import { isComponentNode, isHtmlNode } from './nodeUtils';
11
11
  * Attributes are stored at the top level of the node (like styles)
12
12
  * Returns a record of attributes ready for React props
13
13
  */
14
- export function extractAttributesFromNode(
15
- node: ComponentNode
16
- ): Record<string, string | number | boolean> {
14
+ export function extractAttributesFromNode(node: ComponentNode): Record<string, string | number | boolean> {
17
15
  if (!node || typeof node !== 'object') {
18
16
  return {};
19
17
  }
@@ -32,16 +30,12 @@ export function extractAttributesFromNode(
32
30
  */
33
31
  export function skipEmptyTemplateAttributes(
34
32
  original: Record<string, unknown>,
35
- resolved: Record<string, unknown>
33
+ resolved: Record<string, unknown>,
36
34
  ): Record<string, unknown> {
37
35
  const result: Record<string, unknown> = {};
38
36
  for (const [key, value] of Object.entries(resolved)) {
39
37
  const orig = original[key];
40
- if (
41
- typeof orig === 'string' &&
42
- /^\{\{.+\}\}$/.test(orig) &&
43
- value === ''
44
- ) {
38
+ if (typeof orig === 'string' && /^\{\{.+\}\}$/.test(orig) && value === '') {
45
39
  continue;
46
40
  }
47
41
  result[key] = value;
@@ -55,7 +49,7 @@ export function skipEmptyTemplateAttributes(
55
49
  */
56
50
  export function applyAttributesToNode(
57
51
  node: ComponentNode,
58
- attributes: Record<string, string | number | boolean> | null | undefined
52
+ attributes: Record<string, string | number | boolean> | null | undefined,
59
53
  ): ComponentNode {
60
54
  if (!attributes || Object.keys(attributes).length === 0) {
61
55
  return node;
@@ -64,10 +58,9 @@ export function applyAttributesToNode(
64
58
  if (isComponentNode(node) || isHtmlNode(node)) {
65
59
  return {
66
60
  ...node,
67
- attributes: { ...(node.attributes || {}), ...attributes }
61
+ attributes: { ...(node.attributes || {}), ...attributes },
68
62
  };
69
63
  }
70
64
 
71
65
  return node;
72
66
  }
73
-
@@ -18,10 +18,10 @@ import type { BreakpointConfig, BreakpointConfigInput } from './breakpoints';
18
18
  describe('breakpoints', () => {
19
19
  describe('DEFAULT_BREAKPOINTS', () => {
20
20
  test('should have tablet and mobile breakpoints with new format', () => {
21
- expect(DEFAULT_BREAKPOINTS.tablet.breakpoint).toBe(1024);
22
- expect(DEFAULT_BREAKPOINTS.tablet.previewPoint).toBe(768);
23
- expect(DEFAULT_BREAKPOINTS.mobile.breakpoint).toBe(540);
24
- expect(DEFAULT_BREAKPOINTS.mobile.previewPoint).toBe(375);
21
+ expect(DEFAULT_BREAKPOINTS.tablet!.breakpoint).toBe(1024);
22
+ expect(DEFAULT_BREAKPOINTS.tablet!.previewPoint).toBe(768);
23
+ expect(DEFAULT_BREAKPOINTS.mobile!.breakpoint).toBe(540);
24
+ expect(DEFAULT_BREAKPOINTS.mobile!.previewPoint).toBe(375);
25
25
  });
26
26
  });
27
27
 
@@ -102,7 +102,7 @@ describe('breakpoints', () => {
102
102
  };
103
103
  const result = normalizeBreakpointConfig(input);
104
104
 
105
- expect(result.tabletLandscape.label).toBe('Tablet Landscape');
105
+ expect(result.tabletLandscape!.label).toBe('Tablet Landscape');
106
106
  expect(result.tabletPortrait).not.toHaveProperty('label');
107
107
  expect(result.mobile).not.toHaveProperty('label');
108
108
  });
@@ -46,9 +46,7 @@ export const DEFAULT_BREAKPOINTS: BreakpointConfig = {
46
46
  * Converts legacy number format to object format
47
47
  * If previewPoint is not specified, defaults to breakpoint value
48
48
  */
49
- export function normalizeBreakpointConfig(
50
- input: BreakpointConfigInput | LegacyBreakpointConfig
51
- ): BreakpointConfig {
49
+ export function normalizeBreakpointConfig(input: BreakpointConfigInput | LegacyBreakpointConfig): BreakpointConfig {
52
50
  const result: BreakpointConfig = {};
53
51
 
54
52
  for (const [name, value] of Object.entries(input)) {
@@ -97,9 +95,7 @@ export function getPreviewPointValues(config: BreakpointConfig): LegacyBreakpoin
97
95
  * Always includes 'base' plus all keys from the config
98
96
  * Order: base (desktop) -> breakpoints sorted by value descending (largest to smallest viewport)
99
97
  */
100
- export function getAllBreakpointNames(
101
- breakpoints: BreakpointConfig = DEFAULT_BREAKPOINTS
102
- ): BreakpointName[] {
98
+ export function getAllBreakpointNames(breakpoints: BreakpointConfig = DEFAULT_BREAKPOINTS): BreakpointName[] {
103
99
  // Base is always included first
104
100
  const names: BreakpointName[] = ['base'];
105
101
 
@@ -124,7 +120,7 @@ export function getAllBreakpointNames(
124
120
  */
125
121
  export function getBreakpointName(
126
122
  viewportWidth: number,
127
- breakpoints: BreakpointConfig = DEFAULT_BREAKPOINTS
123
+ breakpoints: BreakpointConfig = DEFAULT_BREAKPOINTS,
128
124
  ): BreakpointName {
129
125
  // Sort breakpoints by breakpoint value (ascending) to find the smallest one that matches
130
126
  const breakpointEntries = Object.entries(breakpoints);
@@ -148,10 +144,7 @@ export function getBreakpointName(
148
144
  * 2. "Desktop" for 'base'
149
145
  * 3. Auto-capitalized name (camelCase -> Title Case)
150
146
  */
151
- export function getBreakpointLabel(
152
- name: BreakpointName,
153
- breakpoints: BreakpointConfig = DEFAULT_BREAKPOINTS
154
- ): string {
147
+ export function getBreakpointLabel(name: BreakpointName, breakpoints: BreakpointConfig = DEFAULT_BREAKPOINTS): string {
155
148
  // Base always returns "Desktop"
156
149
  if (name === 'base') {
157
150
  return 'Desktop';