meno-core 1.0.52 → 1.0.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (399) hide show
  1. package/.claude/settings.local.json +1 -3
  2. package/bin/cli.ts +48 -57
  3. package/build-astro.ts +296 -108
  4. package/build-next.ts +1374 -0
  5. package/build-static.test.ts +39 -10
  6. package/build-static.ts +127 -127
  7. package/dist/bin/cli.js +34 -38
  8. package/dist/bin/cli.js.map +2 -2
  9. package/dist/build-static.js +12 -11
  10. package/dist/chunks/chunk-2AR55GYH.js +42 -0
  11. package/dist/chunks/chunk-2AR55GYH.js.map +7 -0
  12. package/dist/chunks/{chunk-CXCBV2M7.js → chunk-2FN4UOVO.js} +581 -502
  13. package/dist/chunks/chunk-2FN4UOVO.js.map +7 -0
  14. package/dist/chunks/chunk-3XER4E5W.js +168 -0
  15. package/dist/chunks/chunk-3XER4E5W.js.map +7 -0
  16. package/dist/chunks/chunk-5ETZFREW.js +514 -0
  17. package/dist/chunks/chunk-5ETZFREW.js.map +7 -0
  18. package/dist/chunks/{chunk-2MHDV5BF.js → chunk-7E4IF5L7.js} +15 -21
  19. package/dist/chunks/chunk-7E4IF5L7.js.map +7 -0
  20. package/dist/chunks/{chunk-7NIC4I3V.js → chunk-7HWQUVTU.js} +1691 -1316
  21. package/dist/chunks/chunk-7HWQUVTU.js.map +7 -0
  22. package/dist/chunks/{chunk-EDQSMAMP.js → chunk-AE3QK5QW.js} +189 -19
  23. package/dist/chunks/chunk-AE3QK5QW.js.map +7 -0
  24. package/dist/chunks/{chunk-HNLUO36W.js → chunk-F6KTJYGV.js} +8 -8
  25. package/dist/chunks/chunk-F6KTJYGV.js.map +7 -0
  26. package/dist/chunks/{chunk-WQFG7PAH.js → chunk-FZITJSSS.js} +2 -6
  27. package/dist/chunks/chunk-FZITJSSS.js.map +7 -0
  28. package/dist/chunks/{chunk-H4JSCDNW.js → chunk-GSYYA5GX.js} +25 -2
  29. package/dist/chunks/chunk-GSYYA5GX.js.map +7 -0
  30. package/dist/chunks/{chunk-2QK6U5UK.js → chunk-HIZMY3EP.js} +12 -2
  31. package/dist/chunks/chunk-HIZMY3EP.js.map +7 -0
  32. package/dist/chunks/{chunk-AZQYF6KE.js → chunk-I2WEGYA7.js} +41 -176
  33. package/dist/chunks/chunk-I2WEGYA7.js.map +7 -0
  34. package/dist/chunks/{chunk-I7YIGZXT.js → chunk-JNO3CNLJ.js} +6 -9
  35. package/dist/chunks/chunk-JNO3CNLJ.js.map +7 -0
  36. package/dist/chunks/{chunk-UB44F4Z2.js → chunk-NVRBTSQG.js} +2 -4
  37. package/dist/chunks/chunk-NVRBTSQG.js.map +7 -0
  38. package/dist/chunks/{chunk-LHLHPYSP.js → chunk-Q4OBWKXG.js} +48 -40
  39. package/dist/chunks/chunk-Q4OBWKXG.js.map +7 -0
  40. package/dist/chunks/{chunk-A725KYFK.js → chunk-QTE32Y53.js} +780 -323
  41. package/dist/chunks/chunk-QTE32Y53.js.map +7 -0
  42. package/dist/chunks/{chunk-LPVETICS.js → chunk-STDY3OVM.js} +397 -84
  43. package/dist/chunks/chunk-STDY3OVM.js.map +7 -0
  44. package/dist/chunks/configService-PRJZF7Y6.js +14 -0
  45. package/dist/chunks/{constants-GWBAD66U.js → constants-KIQEYMAM.js} +2 -2
  46. package/dist/chunks/{fs-JGINUXGL.js → fs-ZI5JEU7V.js} +2 -2
  47. package/dist/entries/server-router.js +14 -19
  48. package/dist/entries/server-router.js.map +2 -2
  49. package/dist/lib/client/index.js +957 -356
  50. package/dist/lib/client/index.js.map +4 -4
  51. package/dist/lib/server/index.js +1538 -328
  52. package/dist/lib/server/index.js.map +4 -4
  53. package/dist/lib/shared/index.js +277 -73
  54. package/dist/lib/shared/index.js.map +4 -4
  55. package/dist/lib/shared/richtext/index.js +1 -1
  56. package/dist/lib/test-utils/index.js +38 -60
  57. package/dist/lib/test-utils/index.js.map +2 -2
  58. package/entries/client-router.tsx +14 -172
  59. package/entries/server-router.tsx +1 -7
  60. package/lib/client/ClientInitializer.ts +8 -8
  61. package/lib/client/ErrorBoundary.test.tsx +156 -151
  62. package/lib/client/ErrorBoundary.tsx +184 -121
  63. package/lib/client/componentRegistry.test.ts +96 -108
  64. package/lib/client/componentRegistry.ts +1 -2
  65. package/lib/client/contexts/ThemeContext.tsx +3 -2
  66. package/lib/client/core/ComponentBuilder.test.ts +513 -560
  67. package/lib/client/core/ComponentBuilder.ts +335 -146
  68. package/lib/client/core/ComponentRenderer.test.tsx +1 -2
  69. package/lib/client/core/ComponentRenderer.tsx +46 -33
  70. package/lib/client/core/builders/embedBuilder.ts +246 -54
  71. package/lib/client/core/builders/linkBuilder.ts +71 -44
  72. package/lib/client/core/builders/linkNodeBuilder.ts +78 -53
  73. package/lib/client/core/builders/listBuilder.ts +137 -89
  74. package/lib/client/core/builders/localeListBuilder.ts +95 -60
  75. package/lib/client/core/builders/types.ts +5 -5
  76. package/lib/client/core/cmsTemplateProcessor.ts +7 -7
  77. package/lib/client/elementRegistry.ts +3 -3
  78. package/lib/client/fontFamiliesService.test.ts +68 -0
  79. package/lib/client/fontFamiliesService.ts +69 -0
  80. package/lib/client/hmr/HMRManager.tsx +8 -0
  81. package/lib/client/hmrCssReload.ts +166 -0
  82. package/lib/client/hmrWebSocket.ts +9 -14
  83. package/lib/client/hooks/useColorVariables.test.ts +21 -21
  84. package/lib/client/hooks/useColorVariables.ts +14 -10
  85. package/lib/client/hooks/usePropertyAutocomplete.ts +3 -5
  86. package/lib/client/hooks/useVariables.ts +4 -4
  87. package/lib/client/hydration/HydrationUtils.test.ts +24 -25
  88. package/lib/client/hydration/HydrationUtils.ts +3 -4
  89. package/lib/client/i18nConfigService.test.ts +2 -7
  90. package/lib/client/i18nConfigService.ts +2 -2
  91. package/lib/client/index.ts +4 -0
  92. package/lib/client/meno-filter/MenoFilter.test.ts +19 -21
  93. package/lib/client/meno-filter/MenoFilter.ts +5 -9
  94. package/lib/client/meno-filter/bindings.ts +15 -40
  95. package/lib/client/meno-filter/init.ts +1 -1
  96. package/lib/client/meno-filter/renderer.ts +23 -29
  97. package/lib/client/meno-filter/script.generated.ts +1 -3
  98. package/lib/client/meno-filter/ui.ts +5 -5
  99. package/lib/client/meno-filter/updates.ts +15 -21
  100. package/lib/client/navigation.test.ts +159 -159
  101. package/lib/client/navigation.ts +0 -1
  102. package/lib/client/responsiveStyleResolver.test.ts +230 -228
  103. package/lib/client/responsiveStyleResolver.ts +13 -16
  104. package/lib/client/routing/RouteLoader.test.ts +25 -26
  105. package/lib/client/routing/RouteLoader.ts +30 -37
  106. package/lib/client/routing/Router.tsx +112 -18
  107. package/lib/client/scripts/ScriptExecutor.test.ts +270 -128
  108. package/lib/client/scripts/ScriptExecutor.ts +69 -33
  109. package/lib/client/services/PrefetchService.test.ts +2 -2
  110. package/lib/client/services/PrefetchService.ts +10 -24
  111. package/lib/client/styleProcessor.test.ts +9 -9
  112. package/lib/client/styleProcessor.ts +18 -15
  113. package/lib/client/styles/StyleInjector.test.ts +122 -115
  114. package/lib/client/styles/StyleInjector.ts +25 -7
  115. package/lib/client/styles/UtilityClassCollector.ts +26 -27
  116. package/lib/client/styles/cspNonce.test.ts +64 -0
  117. package/lib/client/styles/cspNonce.ts +63 -0
  118. package/lib/client/templateEngine.test.ts +600 -448
  119. package/lib/client/templateEngine.ts +205 -64
  120. package/lib/client/theme.ts +0 -1
  121. package/lib/client/utils/toast.ts +0 -1
  122. package/lib/server/__integration__/api-routes.test.ts +8 -4
  123. package/lib/server/__integration__/cms-integration.test.ts +1 -4
  124. package/lib/server/__integration__/server-lifecycle.test.ts +2 -5
  125. package/lib/server/__integration__/ssr-rendering.test.ts +47 -37
  126. package/lib/server/__integration__/static-assets.test.ts +1 -1
  127. package/lib/server/__integration__/test-helpers.ts +84 -70
  128. package/lib/server/ab/generateFunctions.ts +12 -10
  129. package/lib/server/astro/cmsPageEmitter.ts +47 -32
  130. package/lib/server/astro/componentEmitter.ts +82 -37
  131. package/lib/server/astro/cssCollector.ts +10 -26
  132. package/lib/server/astro/nodeToAstro.test.ts +1750 -30
  133. package/lib/server/astro/nodeToAstro.ts +327 -178
  134. package/lib/server/astro/normalizeOrphanTemplateProps.test.ts +260 -0
  135. package/lib/server/astro/normalizeOrphanTemplateProps.ts +176 -0
  136. package/lib/server/astro/pageEmitter.ts +9 -13
  137. package/lib/server/astro/tailwindMapper.test.ts +10 -37
  138. package/lib/server/astro/tailwindMapper.ts +33 -40
  139. package/lib/server/astro/templateTransformer.ts +14 -17
  140. package/lib/server/createServer.ts +16 -17
  141. package/lib/server/cssGenerator.test.ts +35 -44
  142. package/lib/server/cssGenerator.ts +6 -17
  143. package/lib/server/draftPageStore.ts +49 -0
  144. package/lib/server/fileWatcher.test.ts +124 -10
  145. package/lib/server/fileWatcher.ts +164 -98
  146. package/lib/server/index.ts +20 -2
  147. package/lib/server/jsonLoader.test.ts +39 -2
  148. package/lib/server/jsonLoader.ts +33 -31
  149. package/lib/server/middleware/cors.test.ts +20 -20
  150. package/lib/server/middleware/cors.ts +28 -4
  151. package/lib/server/middleware/errorHandler.test.ts +5 -3
  152. package/lib/server/middleware/errorHandler.ts +3 -8
  153. package/lib/server/middleware/index.ts +0 -1
  154. package/lib/server/middleware/logger.test.ts +7 -5
  155. package/lib/server/middleware/logger.ts +10 -22
  156. package/lib/server/pageCache.test.ts +76 -77
  157. package/lib/server/pageCache.ts +0 -1
  158. package/lib/server/projectContext.ts +4 -3
  159. package/lib/server/providers/fileSystemCMSProvider.test.ts +124 -95
  160. package/lib/server/providers/fileSystemCMSProvider.ts +35 -20
  161. package/lib/server/providers/fileSystemPageProvider.test.ts +84 -0
  162. package/lib/server/providers/fileSystemPageProvider.ts +39 -12
  163. package/lib/server/routes/api/cms.test.ts +26 -14
  164. package/lib/server/routes/api/cms.ts +9 -14
  165. package/lib/server/routes/api/components.ts +35 -34
  166. package/lib/server/routes/api/config.ts +0 -1
  167. package/lib/server/routes/api/core-routes.ts +49 -76
  168. package/lib/server/routes/api/functions.ts +8 -16
  169. package/lib/server/routes/api/index.ts +3 -6
  170. package/lib/server/routes/api/pages.ts +21 -32
  171. package/lib/server/routes/api/shared.test.ts +1 -1
  172. package/lib/server/routes/api/shared.ts +65 -6
  173. package/lib/server/routes/api/variables.test.ts +1 -3
  174. package/lib/server/routes/api/variables.ts +1 -1
  175. package/lib/server/routes/index.ts +106 -19
  176. package/lib/server/routes/pages.ts +47 -35
  177. package/lib/server/routes/static.ts +16 -4
  178. package/lib/server/runtime/bundler.ts +47 -32
  179. package/lib/server/runtime/fs.ts +3 -13
  180. package/lib/server/runtime/httpServer.ts +5 -9
  181. package/lib/server/services/ColorService.ts +32 -27
  182. package/lib/server/services/EnumService.test.ts +2 -6
  183. package/lib/server/services/EnumService.ts +7 -2
  184. package/lib/server/services/VariableService.test.ts +1 -5
  185. package/lib/server/services/VariableService.ts +6 -1
  186. package/lib/server/services/cmsService.test.ts +116 -78
  187. package/lib/server/services/cmsService.ts +24 -54
  188. package/lib/server/services/componentService.test.ts +303 -20
  189. package/lib/server/services/componentService.ts +397 -76
  190. package/lib/server/services/configService.test.ts +9 -31
  191. package/lib/server/services/configService.ts +20 -27
  192. package/lib/server/services/fileWatcherService.ts +44 -30
  193. package/lib/server/services/index.ts +0 -1
  194. package/lib/server/services/pageService.test.ts +24 -3
  195. package/lib/server/services/pageService.ts +135 -16
  196. package/lib/server/ssr/attributeBuilder.ts +24 -8
  197. package/lib/server/ssr/buildErrorOverlay.ts +12 -13
  198. package/lib/server/ssr/clientDataInjector.ts +7 -21
  199. package/lib/server/ssr/cmsSSRProcessor.ts +3 -6
  200. package/lib/server/ssr/cssCollector.ts +1 -1
  201. package/lib/server/ssr/errorOverlay.test.ts +21 -2
  202. package/lib/server/ssr/errorOverlay.ts +39 -18
  203. package/lib/server/ssr/htmlGenerator.nonce.test.ts +3 -9
  204. package/lib/server/ssr/htmlGenerator.test.ts +173 -56
  205. package/lib/server/ssr/htmlGenerator.ts +191 -112
  206. package/lib/server/ssr/imageMetadata.test.ts +3 -1
  207. package/lib/server/ssr/imageMetadata.ts +25 -19
  208. package/lib/server/ssr/jsCollector.test.ts +3 -13
  209. package/lib/server/ssr/jsCollector.ts +3 -8
  210. package/lib/server/ssr/liveReloadIntegration.test.ts +184 -22
  211. package/lib/server/ssr/metaTagGenerator.ts +2 -2
  212. package/lib/server/ssr/ssrRenderer.branches.test.ts +1103 -0
  213. package/lib/server/ssr/ssrRenderer.test.ts +263 -246
  214. package/lib/server/ssr/ssrRenderer.ts +700 -231
  215. package/lib/server/ssrRenderer.test.ts +1044 -950
  216. package/lib/server/utils/jsonLineMapper.test.ts +28 -28
  217. package/lib/server/utils/jsonLineMapper.ts +1 -1
  218. package/lib/server/validateStyleCoverage.ts +18 -20
  219. package/lib/server/webflow/buildWebflow.ts +41 -53
  220. package/lib/server/webflow/nodeToWebflow.test.ts +150 -218
  221. package/lib/server/webflow/nodeToWebflow.ts +195 -258
  222. package/lib/server/webflow/styleMapper.test.ts +15 -56
  223. package/lib/server/webflow/styleMapper.ts +33 -41
  224. package/lib/server/webflow/types.ts +1 -8
  225. package/lib/server/websocketManager.ts +16 -20
  226. package/lib/shared/attributeNodeUtils.test.ts +15 -15
  227. package/lib/shared/attributeNodeUtils.ts +5 -12
  228. package/lib/shared/breakpoints.ts +4 -11
  229. package/lib/shared/cmsQueryParser.test.ts +50 -42
  230. package/lib/shared/cmsQueryParser.ts +49 -31
  231. package/lib/shared/colorVariableUtils.test.ts +5 -5
  232. package/lib/shared/colorVariableUtils.ts +3 -8
  233. package/lib/shared/componentRefs.ts +41 -0
  234. package/lib/shared/constants.test.ts +3 -3
  235. package/lib/shared/constants.ts +12 -8
  236. package/lib/shared/cssGeneration.test.ts +262 -144
  237. package/lib/shared/cssGeneration.ts +189 -514
  238. package/lib/shared/cssNamedColors.ts +152 -30
  239. package/lib/shared/cssProperties.test.ts +5 -6
  240. package/lib/shared/cssProperties.ts +479 -111
  241. package/lib/shared/elementClassName.test.ts +109 -109
  242. package/lib/shared/elementClassName.ts +1 -1
  243. package/lib/shared/elementUtils.ts +12 -16
  244. package/lib/shared/errorLogger.ts +2 -10
  245. package/lib/shared/errors.test.ts +2 -13
  246. package/lib/shared/errors.ts +2 -8
  247. package/lib/shared/expressionEvaluator.test.ts +119 -0
  248. package/lib/shared/expressionEvaluator.ts +95 -22
  249. package/lib/shared/fontCss.ts +101 -0
  250. package/lib/shared/fontLoader.test.ts +19 -5
  251. package/lib/shared/fontLoader.ts +8 -86
  252. package/lib/shared/friendlyError.test.ts +87 -0
  253. package/lib/shared/friendlyError.ts +120 -0
  254. package/lib/shared/gradientUtils.test.ts +1 -5
  255. package/lib/shared/gradientUtils.ts +2 -6
  256. package/lib/shared/hrefRefs.test.ts +130 -0
  257. package/lib/shared/hrefRefs.ts +92 -0
  258. package/lib/shared/i18n.test.ts +1 -1
  259. package/lib/shared/i18n.ts +13 -34
  260. package/lib/shared/index.ts +56 -0
  261. package/lib/shared/inlineSvgStyleRules.test.ts +108 -0
  262. package/lib/shared/inlineSvgStyleRules.ts +132 -0
  263. package/lib/shared/interactiveStyleMappings.test.ts +11 -33
  264. package/lib/shared/interactiveStyleMappings.ts +9 -16
  265. package/lib/shared/interactiveStyles.test.ts +165 -188
  266. package/lib/shared/interfaces/contentProvider.ts +14 -1
  267. package/lib/shared/itemTemplateUtils.test.ts +20 -12
  268. package/lib/shared/itemTemplateUtils.ts +23 -36
  269. package/lib/shared/jsonRepair.ts +8 -2
  270. package/lib/shared/libraryLoader.test.ts +15 -49
  271. package/lib/shared/libraryLoader.ts +7 -22
  272. package/lib/shared/netlifyLocale404.test.ts +179 -0
  273. package/lib/shared/netlifyLocale404.ts +110 -0
  274. package/lib/shared/nodeUtils.test.ts +24 -16
  275. package/lib/shared/nodeUtils.ts +49 -19
  276. package/lib/shared/pathArrayUtils.test.ts +1 -2
  277. package/lib/shared/pathArrayUtils.ts +1 -1
  278. package/lib/shared/pathSecurity.ts +1 -1
  279. package/lib/shared/pathUtils.test.ts +4 -6
  280. package/lib/shared/pathUtils.ts +42 -48
  281. package/lib/shared/paths/Path.test.ts +2 -2
  282. package/lib/shared/paths/Path.ts +0 -1
  283. package/lib/shared/paths/PathConverter.test.ts +1 -1
  284. package/lib/shared/paths/PathConverter.ts +14 -17
  285. package/lib/shared/paths/PathUtils.ts +9 -10
  286. package/lib/shared/paths/PathValidator.test.ts +2 -15
  287. package/lib/shared/paths/PathValidator.ts +11 -9
  288. package/lib/shared/paths/index.ts +1 -2
  289. package/lib/shared/propResolver.test.ts +240 -244
  290. package/lib/shared/propResolver.ts +14 -25
  291. package/lib/shared/pxToRem.test.ts +7 -6
  292. package/lib/shared/pxToRem.ts +2 -5
  293. package/lib/shared/registry/BaseNodeTypeRegistry.test.ts +9 -5
  294. package/lib/shared/registry/ClientRegistry.ts +0 -1
  295. package/lib/shared/registry/ComponentRegistry.test.ts +43 -29
  296. package/lib/shared/registry/ComponentRegistry.ts +9 -11
  297. package/lib/shared/registry/NodeTypeDefinition.ts +15 -8
  298. package/lib/shared/registry/RegistryManager.ts +1 -2
  299. package/lib/shared/registry/SSRRegistry.ts +0 -1
  300. package/lib/shared/registry/createNodeType.ts +7 -9
  301. package/lib/shared/registry/defineNodeType.ts +2 -6
  302. package/lib/shared/registry/index.ts +0 -1
  303. package/lib/shared/registry/nodeTypes/ComponentInstanceNodeType.ts +14 -15
  304. package/lib/shared/registry/nodeTypes/EmbedNodeType.ts +18 -11
  305. package/lib/shared/registry/nodeTypes/HtmlNodeType.ts +47 -18
  306. package/lib/shared/registry/nodeTypes/LinkNodeType.ts +22 -20
  307. package/lib/shared/registry/nodeTypes/ListNodeType.ts +78 -74
  308. package/lib/shared/registry/nodeTypes/LocaleListNodeType.ts +27 -21
  309. package/lib/shared/registry/nodeTypes/SlotMarkerType.ts +6 -7
  310. package/lib/shared/registry/nodeTypes/index.ts +10 -2
  311. package/lib/shared/responsiveScaling.test.ts +15 -31
  312. package/lib/shared/responsiveScaling.ts +55 -37
  313. package/lib/shared/responsiveStyleUtils.ts +11 -13
  314. package/lib/shared/richtext/htmlToTiptap.test.ts +23 -14
  315. package/lib/shared/richtext/htmlToTiptap.ts +1 -3
  316. package/lib/shared/richtext/tiptapToHtml.test.ts +5 -6
  317. package/lib/shared/richtext/types.ts +1 -8
  318. package/lib/shared/slugTranslator.test.ts +37 -13
  319. package/lib/shared/slugTranslator.ts +31 -11
  320. package/lib/shared/slugify.ts +9 -15
  321. package/lib/shared/styleNodeUtils.test.ts +8 -8
  322. package/lib/shared/styleNodeUtils.ts +9 -11
  323. package/lib/shared/styleUtils.test.ts +87 -61
  324. package/lib/shared/styleUtils.ts +5 -6
  325. package/lib/shared/themeDefaults.test.ts +11 -11
  326. package/lib/shared/themeDefaults.ts +3 -4
  327. package/lib/shared/tree/PathBuilder.test.ts +160 -109
  328. package/lib/shared/tree/PathBuilder.ts +121 -59
  329. package/lib/shared/treePathUtils.test.ts +2 -10
  330. package/lib/shared/treePathUtils.ts +54 -59
  331. package/lib/shared/types/api.ts +1 -2
  332. package/lib/shared/types/cms.ts +25 -21
  333. package/lib/shared/types/comment.ts +132 -0
  334. package/lib/shared/types/components.ts +27 -25
  335. package/lib/shared/types/errors.test.ts +1 -6
  336. package/lib/shared/types/errors.ts +3 -7
  337. package/lib/shared/types/experiments.ts +28 -28
  338. package/lib/shared/types/index.ts +14 -2
  339. package/lib/shared/types/rendering.ts +8 -0
  340. package/lib/shared/types/styles.ts +0 -1
  341. package/lib/shared/types/variables.test.ts +4 -13
  342. package/lib/shared/types/variables.ts +48 -27
  343. package/lib/shared/types.ts +1 -2
  344. package/lib/shared/utilityClassConfig.ts +648 -319
  345. package/lib/shared/utilityClassMapper.test.ts +213 -78
  346. package/lib/shared/utilityClassMapper.ts +188 -246
  347. package/lib/shared/utilityClassNames.ts +326 -0
  348. package/lib/shared/utils.test.ts +2 -10
  349. package/lib/shared/utils.ts +19 -10
  350. package/lib/shared/validation/cmsValidators.ts +2 -1
  351. package/lib/shared/validation/commentValidators.test.ts +53 -0
  352. package/lib/shared/validation/commentValidators.ts +80 -0
  353. package/lib/shared/validation/index.ts +1 -0
  354. package/lib/shared/validation/propValidator.test.ts +18 -20
  355. package/lib/shared/validation/propValidator.ts +12 -17
  356. package/lib/shared/validation/schemas.test.ts +24 -33
  357. package/lib/shared/validation/schemas.ts +469 -344
  358. package/lib/shared/validation/validators.test.ts +1 -6
  359. package/lib/shared/validation/validators.ts +89 -68
  360. package/lib/shared/viewportUnits.integration.test.ts +46 -0
  361. package/lib/shared/viewportUnits.test.ts +91 -0
  362. package/lib/shared/viewportUnits.ts +63 -0
  363. package/lib/test-utils/dom-setup.ts +7 -1
  364. package/lib/test-utils/factories/ConsoleMockFactory.ts +3 -7
  365. package/lib/test-utils/factories/DomMockFactory.ts +7 -19
  366. package/lib/test-utils/factories/EventMockFactory.ts +7 -13
  367. package/lib/test-utils/factories/FetchMockFactory.ts +39 -57
  368. package/lib/test-utils/factories/ServerMockFactory.ts +5 -9
  369. package/lib/test-utils/factories/StoreMockFactory.ts +14 -25
  370. package/lib/test-utils/fixtures.ts +45 -45
  371. package/lib/test-utils/helpers/asyncHelpers.test.ts +15 -18
  372. package/lib/test-utils/helpers/asyncHelpers.ts +11 -20
  373. package/lib/test-utils/helpers.ts +1 -5
  374. package/lib/test-utils/index.ts +0 -4
  375. package/lib/test-utils/mockFactories.ts +12 -18
  376. package/lib/test-utils/mocks.ts +4 -2
  377. package/package.json +1 -1
  378. package/scripts/build-meno-filter.ts +1 -4
  379. package/vite.config.ts +4 -4
  380. package/dist/chunks/chunk-2MHDV5BF.js.map +0 -7
  381. package/dist/chunks/chunk-2QK6U5UK.js.map +0 -7
  382. package/dist/chunks/chunk-7NIC4I3V.js.map +0 -7
  383. package/dist/chunks/chunk-A725KYFK.js.map +0 -7
  384. package/dist/chunks/chunk-AZQYF6KE.js.map +0 -7
  385. package/dist/chunks/chunk-CXCBV2M7.js.map +0 -7
  386. package/dist/chunks/chunk-EDQSMAMP.js.map +0 -7
  387. package/dist/chunks/chunk-H4JSCDNW.js.map +0 -7
  388. package/dist/chunks/chunk-HNLUO36W.js.map +0 -7
  389. package/dist/chunks/chunk-I7YIGZXT.js.map +0 -7
  390. package/dist/chunks/chunk-J23ZX5AP.js +0 -241
  391. package/dist/chunks/chunk-J23ZX5AP.js.map +0 -7
  392. package/dist/chunks/chunk-LHLHPYSP.js.map +0 -7
  393. package/dist/chunks/chunk-LPVETICS.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/configService-R3OGU2UD.js +0 -13
  397. /package/dist/chunks/{configService-R3OGU2UD.js.map → configService-PRJZF7Y6.js.map} +0 -0
  398. /package/dist/chunks/{constants-GWBAD66U.js.map → constants-KIQEYMAM.js.map} +0 -0
  399. /package/dist/chunks/{fs-JGINUXGL.js.map → fs-ZI5JEU7V.js.map} +0 -0
@@ -5,15 +5,15 @@
5
5
 
6
6
  /** Field types supported by CMS */
7
7
  export type CMSFieldType =
8
- | 'string' // Single-line text (auto-localizable when project has multiple locales)
9
- | 'text' // Multi-line text (auto-localizable when project has multiple locales)
10
- | 'rich-text' // Rich text with formatting (auto-localizable when project has multiple locales)
11
- | 'number' // Numeric value
12
- | 'boolean' // True/false
13
- | 'image' // Image URL/path
14
- | 'file' // File URL/path (any file type)
15
- | 'date' // ISO date string
16
- | 'select' // Single selection from options
8
+ | 'string' // Single-line text (auto-localizable when project has multiple locales)
9
+ | 'text' // Multi-line text (auto-localizable when project has multiple locales)
10
+ | 'rich-text' // Rich text with formatting (auto-localizable when project has multiple locales)
11
+ | 'number' // Numeric value
12
+ | 'boolean' // True/false
13
+ | 'image' // Image URL/path
14
+ | 'file' // File URL/path (any file type)
15
+ | 'date' // ISO date string
16
+ | 'select' // Single selection from options
17
17
  | 'reference'; // Reference to another collection item
18
18
 
19
19
  /** Single field definition in a schema */
@@ -21,12 +21,12 @@ export interface CMSFieldDefinition {
21
21
  type: CMSFieldType;
22
22
  required?: boolean;
23
23
  default?: unknown;
24
- label?: string; // Display label in editor
25
- description?: string; // Help text
26
- options?: string[]; // For 'select' type
27
- accept?: string; // For 'file' type - MIME filter (e.g. "application/pdf", "*/*")
28
- collection?: string; // For 'reference' type - target collection ID
29
- multiple?: boolean; // For 'reference' type - allows array of IDs
24
+ label?: string; // Display label in editor
25
+ description?: string; // Help text
26
+ options?: string[]; // For 'select' type
27
+ accept?: string; // For 'file' type - MIME filter (e.g. "application/pdf", "*/*")
28
+ collection?: string; // For 'reference' type - target collection ID
29
+ multiple?: boolean; // For 'reference' type - allows array of IDs
30
30
  }
31
31
 
32
32
  /** Data delivery strategy for client-side CMS data */
@@ -156,7 +156,7 @@ export interface CMSRouteMatch {
156
156
  collection: string;
157
157
  slug: string;
158
158
  item: CMSItem;
159
- pagePath: string; // Path to the template page file
159
+ pagePath: string; // Path to the template page file
160
160
  }
161
161
 
162
162
  /** Filter operators for CMS queries */
@@ -165,14 +165,14 @@ export type CMSFilterOperator = 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'co
165
165
  /** Single filter condition */
166
166
  export interface CMSFilterCondition {
167
167
  field: string;
168
- operator?: CMSFilterOperator; // defaults to 'eq'
168
+ operator?: CMSFilterOperator; // defaults to 'eq'
169
169
  value: unknown;
170
170
  }
171
171
 
172
172
  /** Sort configuration */
173
173
  export interface CMSSortConfig {
174
174
  field: string;
175
- order?: 'asc' | 'desc'; // defaults to 'asc'
175
+ order?: 'asc' | 'desc'; // defaults to 'asc'
176
176
  }
177
177
 
178
178
  /** CMSList query configuration */
@@ -304,9 +304,13 @@ export function singularize(collection: string): string {
304
304
  return collection.slice(0, -3) + 'y';
305
305
  }
306
306
  // Handle -es for words ending in s, x, z, ch, sh
307
- if (collection.endsWith('ses') || collection.endsWith('xes') ||
308
- collection.endsWith('zes') || collection.endsWith('ches') ||
309
- collection.endsWith('shes')) {
307
+ if (
308
+ collection.endsWith('ses') ||
309
+ collection.endsWith('xes') ||
310
+ collection.endsWith('zes') ||
311
+ collection.endsWith('ches') ||
312
+ collection.endsWith('shes')
313
+ ) {
310
314
  return collection.slice(0, -2);
311
315
  }
312
316
  // Simple rule: remove trailing 's' if present
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Comment / Pin Types
3
+ *
4
+ * Comments are Figma-style pins placed on components in the studio canvas.
5
+ * One file per pin (thread embedded). Storage layout (status as top folder):
6
+ * {projectRoot}/comments/<status>/<pageSlug>--<seq>--<titleSlug>.json
7
+ * e.g. comments/open/blog__post--3--hero-is-too-dark.json
8
+ *
9
+ * Pins are an authoring-time concept — they live in studio only.
10
+ */
11
+
12
+ /** Workflow status. No custom statuses for MVP. */
13
+ export type CommentStatus = 'open' | 'in-progress' | 'ready-for-review' | 'resolved' | 'closed';
14
+
15
+ export const COMMENT_STATUSES: readonly CommentStatus[] = [
16
+ 'open',
17
+ 'in-progress',
18
+ 'ready-for-review',
19
+ 'resolved',
20
+ 'closed',
21
+ ] as const;
22
+
23
+ /** Identifies the GitHub user who authored a thread entry. */
24
+ export interface CommentAuthor {
25
+ /** GitHub login. `"local"` for non-electron / unauthenticated runs. */
26
+ login: string;
27
+ name?: string;
28
+ avatarUrl?: string;
29
+ }
30
+
31
+ /**
32
+ * Identity fingerprint for the anchored node — used to detect orphan pins
33
+ * when the tree shifts. Mirrors the shape of `nodesMatch()` in NodeStore.
34
+ */
35
+ export interface CommentNodeIdentity {
36
+ /** `'component'` or `'node'` (HTML). */
37
+ kind: 'component' | 'node';
38
+ /** Component name (when kind=component) or HTML tag (when kind=node). */
39
+ name: string;
40
+ /** Editor-set label, used to disambiguate same-type siblings. */
41
+ label?: string;
42
+ }
43
+
44
+ /**
45
+ * One step of a {@link CommentAnchor.nodeRef}: a node addressed by its TYPE and
46
+ * its occurrence among same-type siblings, rather than its raw child index. E.g.
47
+ * `{ kind:'component', name:'HomeProducts', nth:0 }` = "the first HomeProducts
48
+ * under this parent". Move-invariant: reordering/inserting/deleting siblings of
49
+ * OTHER types doesn't change it (only reordering same-type instances does).
50
+ */
51
+ export interface CommentNodeRefSegment {
52
+ kind: 'component' | 'node';
53
+ /** Component name (kind=component) or HTML tag / node type (kind=node). */
54
+ name: string;
55
+ /** 0-based occurrence among same-(kind,name) siblings under the same parent. */
56
+ nth: number;
57
+ }
58
+
59
+ /**
60
+ * Where the pin sits. Pins are ELEMENT-ANCHORED: a comment attaches to the
61
+ * specific node/component the user picked (exactly like a selection), not to a
62
+ * spot on the page. The anchor's source of truth is `nodeRef` — a type +
63
+ * occurrence path from the page root (e.g. `HomeProducts[0]` →
64
+ * `Section[2] > Heading[4]`) — so a pin survives the section being moved,
65
+ * inserted before, or its differently-typed siblings being deleted. `nodePath`
66
+ * is a create-time positional snapshot kept only as a fallback for legacy pins
67
+ * (no `nodeRef`). `cmsItemIndexPath` disambiguates which CMS-list copy was
68
+ * clicked. The pin is drawn over the resolved element's rect;
69
+ * `offsetXPercent`/`offsetYPercent` place it WITHIN that rect.
70
+ *
71
+ * The identity resolves to a DOM element in both the same-origin SSR canvas and
72
+ * the cross-origin Astro play DOM (nodeRef → live nodePath → existing x-ray
73
+ * pipeline), and survives the JSON→.astro migration. When the node can no longer
74
+ * be resolved the comment is "detached".
75
+ */
76
+ export interface CommentAnchor {
77
+ /**
78
+ * Type + occurrence path from the page root — the move-resilient source of
79
+ * truth for the anchored node. Absent only on legacy pins (fall back to
80
+ * `nodePath`).
81
+ */
82
+ nodeRef?: CommentNodeRefSegment[];
83
+ /** Create-time positional snapshot of the anchored node (fallback for legacy pins). */
84
+ nodePath: number[];
85
+ /**
86
+ * CMS-list item path disambiguating which list copy the anchored element
87
+ * belongs to (parallel to SelectionStore's `selectedCMSItemIndexPath`).
88
+ * Absent when the element is not inside a CMS list.
89
+ */
90
+ cmsItemIndexPath?: number[];
91
+ /** Identity fingerprint of the anchored node, used to detect orphan pins. */
92
+ nodeIdentity: CommentNodeIdentity;
93
+ /** Horizontal position WITHIN the anchored element's rect, 0..1 (default 0.5). */
94
+ offsetXPercent: number;
95
+ /** Vertical position WITHIN the anchored element's rect, 0..1 (default 0.5). */
96
+ offsetYPercent: number;
97
+ /**
98
+ * Breakpoint frame this pin was placed on (e.g. `'base'`, `'tablet'`,
99
+ * `'mobile'`). A pin is only shown on the frame where it was pinned. When
100
+ * unset, the pin renders on every frame (or pins created before this field).
101
+ */
102
+ breakpoint?: string;
103
+ }
104
+
105
+ /** One message in a comment's thread (initial + replies). */
106
+ export interface CommentThreadEntry {
107
+ id: string;
108
+ author: CommentAuthor;
109
+ /** ISO timestamp. */
110
+ createdAt: string;
111
+ text: string;
112
+ /** When this entry transitioned the comment status, the target status. */
113
+ statusChange: CommentStatus | null;
114
+ }
115
+
116
+ /** A pinned comment. */
117
+ export interface Comment {
118
+ _id: string;
119
+ _filename: string;
120
+ /** Page path the pin lives on (e.g. `"blog/post"`). */
121
+ _pagePath: string;
122
+ /** Stable per-page badge number. Server assigns at create time. */
123
+ _seq: number;
124
+ /** ISO timestamps. */
125
+ _createdAt: string;
126
+ _updatedAt: string;
127
+ /** Git HEAD SHA captured at create time, or null when unavailable. */
128
+ _commitSha: string | null;
129
+ anchor: CommentAnchor;
130
+ status: CommentStatus;
131
+ thread: CommentThreadEntry[];
132
+ }
@@ -24,18 +24,18 @@ export type EnumsConfig = Record<string, readonly string[]>;
24
24
  */
25
25
  export interface I18nValue {
26
26
  _i18n: true;
27
- [locale: string]: string | unknown[] | true; // true is for the _i18n marker, arrays for list props
27
+ [locale: string]: string | unknown[] | true; // true is for the _i18n marker, arrays for list props
28
28
  }
29
29
 
30
30
  /**
31
31
  * Locale configuration with metadata
32
32
  */
33
33
  export interface LocaleConfig {
34
- code: string; // URL prefix & translation key (e.g., "en", "pl")
35
- name: string; // English name for admin UI (e.g., "Polish")
36
- nativeName: string; // Native name for public UI (e.g., "Polski")
37
- langTag: string; // BCP 47 language tag for SEO (e.g., "pl-PL")
38
- icon?: string; // Optional flag icon path (e.g., "/icons/flag-en.svg")
34
+ code: string; // URL prefix & translation key (e.g., "en", "pl")
35
+ name: string; // English name for admin UI (e.g., "Polish")
36
+ nativeName: string; // Native name for public UI (e.g., "Polski")
37
+ langTag: string; // BCP 47 language tag for SEO (e.g., "pl-PL")
38
+ icon?: string; // Optional flag icon path (e.g., "/icons/flag-en.svg")
39
39
  }
40
40
 
41
41
  /**
@@ -66,10 +66,10 @@ export interface LinkPropValue {
66
66
  export interface BasePropDefinition {
67
67
  type: Exclude<PropType, 'list'>;
68
68
  default?: string | number | boolean | I18nValue | LinkPropValue;
69
- options?: readonly string[]; // Required for "select" type (inline options)
70
- enumName?: string; // For "select" type: reference to project-level enum
71
- accept?: string; // For "file" type: MIME pattern like "image/*", "video/*"
72
- editor?: 'basic' | 'extended'; // For 'rich-text' type: which editor to use
69
+ options?: readonly string[]; // Required for "select" type (inline options)
70
+ enumName?: string; // For "select" type: reference to project-level enum
71
+ accept?: string; // For "file" type: MIME pattern like "image/*", "video/*"
72
+ editor?: 'basic' | 'extended'; // For 'rich-text' type: which editor to use
73
73
  }
74
74
 
75
75
  /**
@@ -120,9 +120,9 @@ export function isBasePropDefinition(def: PropDefinition): def is BasePropDefini
120
120
  export interface StructuredComponentDefinition {
121
121
  interface?: Record<string, PropDefinition>;
122
122
  structure?: ComponentNode;
123
- javascript?: string; // Vanilla JS code to be rendered at end of HTML
124
- css?: string; // CSS code to be rendered in <style> tag in <head>
125
- category?: string; // Component category for organization
123
+ javascript?: string; // Vanilla JS code to be rendered at end of HTML
124
+ css?: string; // CSS code to be rendered in <style> tag in <head>
125
+ category?: string; // Component category for organization
126
126
  /**
127
127
  * Define which props are available as JavaScript variables (Astro-style define:vars)
128
128
  * - true: all props from interface are exposed
@@ -141,9 +141,9 @@ export interface StructuredComponentDefinition {
141
141
  * Supports both new format (just component) and legacy format (type/props/children/component)
142
142
  */
143
143
  export interface ComponentDefinition {
144
- type?: string; // Legacy format
145
- props?: Record<string, unknown>; // Legacy format
146
- children?: unknown[]; // Legacy format
144
+ type?: string; // Legacy format
145
+ props?: Record<string, unknown>; // Legacy format
146
+ children?: unknown[]; // Legacy format
147
147
  component: StructuredComponentDefinition;
148
148
  }
149
149
 
@@ -168,15 +168,17 @@ export interface JSONPage {
168
168
  /**
169
169
  * Page data type that can be either a JSONPage or a component definition structure
170
170
  */
171
- export type PageData = JSONPage | {
172
- component: {
173
- structure?: ComponentNode;
174
- interface?: Record<string, PropDefinition>;
175
- javascript?: string;
176
- css?: string;
177
- acceptsStyles?: boolean;
178
- }
179
- };
171
+ export type PageData =
172
+ | JSONPage
173
+ | {
174
+ component: {
175
+ structure?: ComponentNode;
176
+ interface?: Record<string, PropDefinition>;
177
+ javascript?: string;
178
+ css?: string;
179
+ acceptsStyles?: boolean;
180
+ };
181
+ };
180
182
 
181
183
  /**
182
184
  * Page data with component structure (for type narrowing)
@@ -1,10 +1,5 @@
1
1
  import { describe, test, expect } from 'bun:test';
2
- import {
3
- createValidationError,
4
- createTypeSafetyError,
5
- type ValidationError,
6
- type TypeSafetyError,
7
- } from './errors';
2
+ import { createValidationError, createTypeSafetyError, type ValidationError, type TypeSafetyError } from './errors';
8
3
 
9
4
  describe('error types', () => {
10
5
  describe('createValidationError', () => {
@@ -27,9 +27,7 @@ export interface TypeSafetyError extends Error {
27
27
  * Result type for operations that can fail
28
28
  * Replaces null returns with explicit success/failure
29
29
  */
30
- export type Result<T> =
31
- | { success: true; data: T }
32
- | { success: false; error: ValidationError };
30
+ export type Result<T> = { success: true; data: T } | { success: false; error: ValidationError };
33
31
 
34
32
  /**
35
33
  * Create a validation error
@@ -40,7 +38,7 @@ export function createValidationError(
40
38
  path?: string;
41
39
  receivedValue?: unknown;
42
40
  expectedType?: string;
43
- }
41
+ },
44
42
  ): ValidationError {
45
43
  return {
46
44
  message,
@@ -57,7 +55,7 @@ export function createTypeSafetyError(
57
55
  path?: string;
58
56
  receivedValue?: unknown;
59
57
  expectedType?: string;
60
- }
58
+ },
61
59
  ): TypeSafetyError {
62
60
  const error = new Error(message) as TypeSafetyError;
63
61
  Object.defineProperty(error, 'path', { value: options?.path, writable: false });
@@ -65,5 +63,3 @@ export function createTypeSafetyError(
65
63
  Object.defineProperty(error, 'expectedType', { value: options?.expectedType, writable: false });
66
64
  return error;
67
65
  }
68
-
69
-
@@ -4,52 +4,52 @@
4
4
  */
5
5
 
6
6
  export interface ConversionGoal {
7
- id: string
8
- name: string
9
- type: 'click' | 'navigation' | 'custom'
7
+ id: string;
8
+ name: string;
9
+ type: 'click' | 'navigation' | 'custom';
10
10
  /** CSS selector for click goals */
11
- selector?: string
11
+ selector?: string;
12
12
  /** URL pattern for navigation goals */
13
- url?: string
13
+ url?: string;
14
14
  /** Custom event name */
15
- event?: string
15
+ event?: string;
16
16
  }
17
17
 
18
18
  export interface ExperimentVariant {
19
- branch: string
19
+ branch: string;
20
20
  /** Percentage of traffic (0-100) */
21
- weight: number
21
+ weight: number;
22
22
  /** Cloudflare Pages preview deploy URL, e.g. "https://variant-blue.project.pages.dev" */
23
- deployUrl: string
23
+ deployUrl: string;
24
24
  }
25
25
 
26
26
  export interface Experiment {
27
- id: string
28
- name: string
29
- status: 'draft' | 'running' | 'paused' | 'completed'
30
- controlBranch: string
31
- variants: ExperimentVariant[]
27
+ id: string;
28
+ name: string;
29
+ status: 'draft' | 'running' | 'paused' | 'completed';
30
+ controlBranch: string;
31
+ variants: ExperimentVariant[];
32
32
  /** Percentage of traffic for control (0-100) */
33
- controlWeight: number
34
- conversionGoals: ConversionGoal[]
35
- createdAt: string
36
- startedAt?: string
37
- endedAt?: string
33
+ controlWeight: number;
34
+ conversionGoals: ConversionGoal[];
35
+ createdAt: string;
36
+ startedAt?: string;
37
+ endedAt?: string;
38
38
  }
39
39
 
40
40
  export interface ExperimentResults {
41
- experimentId: string
42
- variants: VariantResult[]
41
+ experimentId: string;
42
+ variants: VariantResult[];
43
43
  }
44
44
 
45
45
  export interface VariantResult {
46
- variant: string
47
- visitors: number
48
- conversions: number
49
- conversionRate: number
46
+ variant: string;
47
+ visitors: number;
48
+ conversions: number;
49
+ conversionRate: number;
50
50
  /** Lift percentage compared to control */
51
- lift?: number
51
+ lift?: number;
52
52
  /** p-value from z-test */
53
- pValue?: number
54
- isSignificant: boolean
53
+ pValue?: number;
54
+ isSignificant: boolean;
55
55
  }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Shared TypeScript types and interfaces
3
3
  * Used by both client and server code
4
- *
4
+ *
5
5
  * This is the main entry point for all shared types.
6
6
  * Types are organized into separate files for better maintainability.
7
7
  */
@@ -173,5 +173,17 @@ export type {
173
173
  VariantResult,
174
174
  } from './experiments';
175
175
 
176
- // Note: Path types are exported from ../paths/index.ts, not from here
176
+ // Comment / Pin types
177
+ export type {
178
+ CommentStatus,
179
+ CommentAuthor,
180
+ CommentNodeIdentity,
181
+ CommentNodeRefSegment,
182
+ CommentAnchor,
183
+ CommentThreadEntry,
184
+ Comment,
185
+ } from './comment';
177
186
 
187
+ export { COMMENT_STATUSES } from './comment';
188
+
189
+ // Note: Path types are exported from ../paths/index.ts, not from here
@@ -57,6 +57,14 @@ export interface TemplateContext {
57
57
  props: Record<string, unknown>;
58
58
  /** Component definition (for variants, defaults) */
59
59
  componentDef?: ComponentDefinition | StructuredComponentDefinition;
60
+ /**
61
+ * Resolved props of the component that hosts this one (one level up).
62
+ * Layered into template evaluation at lower precedence than `props`, so a
63
+ * `{{x}}` in a child component's structure falls back to the parent's `x`
64
+ * when the child doesn't declare it. Aligned with `buildListResolutionScope`
65
+ * for list `items` / `filter` templates.
66
+ */
67
+ parentProps?: Record<string, unknown>;
60
68
  /** Future extension points (cms, page, etc.) */
61
69
  [namespace: string]: unknown;
62
70
  }
@@ -80,4 +80,3 @@ export interface InteractiveStyleRule {
80
80
  * Each rule has a selector and associated styles
81
81
  */
82
82
  export type InteractiveStyles = InteractiveStyleRule[];
83
-
@@ -1,15 +1,10 @@
1
1
  import { describe, expect, it } from 'bun:test';
2
- import {
3
- getGroupAbbreviation,
4
- getDefaultScalingType,
5
- generateShortCssVar,
6
- VARIABLE_TYPES,
7
- } from './variables';
2
+ import { getGroupAbbreviation, getDefaultScalingType, generateShortCssVar, VARIABLE_TYPES } from './variables';
8
3
  import type { CSSVariable } from './variables';
9
4
 
10
5
  describe('VARIABLE_TYPES', () => {
11
6
  it('has all expected scaling types', () => {
12
- const values = VARIABLE_TYPES.map(t => t.value);
7
+ const values = VARIABLE_TYPES.map((t) => t.value);
13
8
  expect(values).toEqual(['fontSize', 'padding', 'margin', 'gap', 'borderRadius', 'size', 'none']);
14
9
  });
15
10
  });
@@ -97,9 +92,7 @@ describe('generateShortCssVar', () => {
97
92
  });
98
93
 
99
94
  it('extends prefix on collision', () => {
100
- const existing: CSSVariable[] = [
101
- { name: 'H', cssVar: '--h-ls', value: '1px', type: 'none' },
102
- ];
95
+ const existing: CSSVariable[] = [{ name: 'H', cssVar: '--h-ls', value: '1px', type: 'none' }];
103
96
  const result = generateShortCssVar('Heading', 'letter-spacing', existing);
104
97
  expect(result).toBe('--he-ls');
105
98
  });
@@ -130,9 +123,7 @@ describe('generateShortCssVar', () => {
130
123
  });
131
124
 
132
125
  it('adds numeric suffix for no-group collisions', () => {
133
- const existing: CSSVariable[] = [
134
- { name: '', cssVar: '--my-var', value: '1px', type: 'none' },
135
- ];
126
+ const existing: CSSVariable[] = [{ name: '', cssVar: '--my-var', value: '1px', type: 'none' }];
136
127
  const result = generateShortCssVar('My Var', '', existing);
137
128
  expect(result).toBe('--my-var-2');
138
129
  });