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
@@ -25,67 +25,91 @@ const CMSSortConfigSchema = z.union([
25
25
  field: z.string(),
26
26
  order: z.enum(['asc', 'desc']).optional(),
27
27
  }),
28
- z.array(z.object({
29
- field: z.string(),
30
- order: z.enum(['asc', 'desc']).optional(),
31
- })),
28
+ z.array(
29
+ z.object({
30
+ field: z.string(),
31
+ order: z.enum(['asc', 'desc']).optional(),
32
+ }),
33
+ ),
32
34
  ]);
33
35
 
34
36
  // Schema is the SINGLE source of truth
35
- const ListNodeSchemaInternal = z.object({
36
- type: z.literal('list'),
37
- /**
38
- * Data source type:
39
- * - 'prop': Read items from component props (default)
40
- * - 'collection': Query items from CMS collection
41
- */
42
- sourceType: z.enum(['prop', 'collection']).default('prop'),
43
- /**
44
- * Source identifier:
45
- * - For sourceType 'prop': Prop name (e.g., "items") or template expression (e.g., "{{category.items}}")
46
- * - For sourceType 'collection': Collection name (e.g., "posts", "authors")
47
- */
48
- source: z.string(),
49
- label: z.string().optional(), // Custom label displayed in structure tree
50
- if: IfConditionSchema.optional(), // Conditional rendering - skip node when false
51
- /**
52
- * Variable name for item in templates.
53
- * - For sourceType 'prop': defaults to 'item'
54
- * - For sourceType 'collection': defaults to singularized collection name
55
- */
56
- itemAs: z.string().optional(),
57
-
58
- // Collection-only options (ignored when sourceType: 'prop')
59
- /** Direct item IDs or template expression for referenced items (e.g., "{{post.authorId}}") */
60
- items: z.union([z.string(), z.array(z.string())]).optional(),
61
- /** Filter conditions */
62
- filter: z.union([
63
- CMSFilterConditionSchema,
64
- z.array(CMSFilterConditionSchema),
65
- z.record(z.unknown()),
66
- ]).optional(),
67
- /** Sort configuration */
68
- sort: CMSSortConfigSchema.optional(),
69
- /** Exclude the current CMS item from the list (useful for "related items" sections) */
70
- excludeCurrentItem: z.boolean().optional(),
71
- /**
72
- * Emit item template for dynamic client-side rendering.
73
- * When true, SSR emits a `<template data-meno-item>` element with unprocessed
74
- * {{item.field}} placeholders. MenoFilter uses this to render items beyond
75
- * the SSR'd limit dynamically.
76
- */
77
- emitTemplate: z.boolean().optional(),
78
-
79
- // Shared options
80
- /** Maximum number of items to return */
81
- limit: z.number().optional(),
82
- /** Number of items to skip */
83
- offset: z.number().optional(),
84
- /** Children are repeated for each item */
85
- children: z.array(z.unknown()).optional(),
86
- /** @deprecated Legacy property - use source + sourceType instead */
87
- collection: z.union([z.string(), z.array(z.any())]).optional(),
88
- }).passthrough();
37
+ const ListNodeSchemaInternal = z
38
+ .object({
39
+ type: z.literal('list'),
40
+ /**
41
+ * Data source type:
42
+ * - 'prop': Read items from component props (default)
43
+ * - 'collection': Query items from CMS collection
44
+ * - 'remote': Fetch items from a public HTTP/JSON endpoint at build/SSR time
45
+ * - 'sanity': Fetch a Sanity document type via GROQ at build/SSR time (read-only, public dataset)
46
+ * - 'expression': Iterate a verbatim JS expression (`source`) that yields an array — a
47
+ * `.map()` over arbitrary frontmatter data (e.g. an Astro Action / supabase query) the
48
+ * dialect can't model as a prop/collection. The item template (`children` + `itemAs`) IS
49
+ * editable; the source itself is a read-only black box (edit it in the .astro frontmatter).
50
+ * The editor has no data for it, so it renders empty in the design canvas (real Astro play
51
+ * renders it for real at build/SSR).
52
+ */
53
+ sourceType: z.enum(['prop', 'collection', 'remote', 'sanity', 'expression']).default('prop'),
54
+ /**
55
+ * Source identifier (sourceType 'prop'/'collection'/'expression'; 'remote' uses `url`):
56
+ * - For sourceType 'prop': Prop name (e.g., "items") or template expression (e.g., "{{category.items}}")
57
+ * - For sourceType 'collection': Collection name (e.g., "posts", "authors")
58
+ * - For sourceType 'expression': the verbatim JS expression iterated by `.map()` (e.g. "notes?")
59
+ */
60
+ source: z.string().optional(),
61
+
62
+ // Remote-only options (sourceType: 'remote')
63
+ /** HTTP(S) endpoint returning JSON, fetched at build/SSR time (e.g. a public REST API). */
64
+ url: z.string().optional(),
65
+ /**
66
+ * Dot-path into the JSON response to reach the items array (e.g. "data.items").
67
+ * Empty/absent = the response body is itself the array.
68
+ */
69
+ path: z.string().optional(),
70
+
71
+ // Sanity-only options (sourceType: 'sanity')
72
+ /** Sanity document `_type` to fetch (`*[_type == "<documentType>"]`). projectId/dataset come from project config. */
73
+ documentType: z.string().optional(),
74
+ /** Field used as the URL slug (for synthesizing item links); defaults to 'slug'. */
75
+ slugField: z.string().optional(),
76
+ label: z.string().optional(), // Custom label displayed in structure tree
77
+ if: IfConditionSchema.optional(), // Conditional rendering - skip node when false
78
+ /**
79
+ * Variable name for item in templates.
80
+ * - For sourceType 'prop': defaults to 'item'
81
+ * - For sourceType 'collection': defaults to singularized collection name
82
+ */
83
+ itemAs: z.string().optional(),
84
+
85
+ // Collection-only options (ignored when sourceType: 'prop')
86
+ /** Direct item IDs or template expression for referenced items (e.g., "{{post.authorId}}") */
87
+ items: z.union([z.string(), z.array(z.string())]).optional(),
88
+ /** Filter conditions */
89
+ filter: z.union([CMSFilterConditionSchema, z.array(CMSFilterConditionSchema), z.record(z.unknown())]).optional(),
90
+ /** Sort configuration */
91
+ sort: CMSSortConfigSchema.optional(),
92
+ /** Exclude the current CMS item from the list (useful for "related items" sections) */
93
+ excludeCurrentItem: z.boolean().optional(),
94
+ /**
95
+ * Emit item template for dynamic client-side rendering.
96
+ * When true, SSR emits a `<template data-meno-item>` element with unprocessed
97
+ * {{item.field}} placeholders. MenoFilter uses this to render items beyond
98
+ * the SSR'd limit dynamically.
99
+ */
100
+ emitTemplate: z.boolean().optional(),
101
+
102
+ // Shared options
103
+ /** Maximum number of items to return */
104
+ limit: z.number().optional(),
105
+ /** Number of items to skip */
106
+ offset: z.number().optional(),
107
+ /** Children are repeated for each item */
108
+ children: z.array(z.unknown()).optional(),
109
+ /** @deprecated Legacy property - use source + sourceType instead */
110
+ collection: z.union([z.string(), z.array(z.any())]).optional(),
111
+ })
112
+ .passthrough();
89
113
 
90
114
  // TypeScript type inferred from schema
91
115
  export type ListNode = z.infer<typeof ListNodeSchemaInternal>;
@@ -111,8 +135,19 @@ export const ListNodeType = createNodeType({
111
135
  getLabel: (node) => {
112
136
  const listNode = node as ListNode;
113
137
  const sourceType = listNode.sourceType || 'prop';
114
- const prefix = sourceType === 'collection' ? 'CMS List' : 'List';
115
- return listNode.source ? `${prefix}: ${listNode.source}` : prefix;
138
+ const prefix =
139
+ sourceType === 'collection'
140
+ ? 'CMS List'
141
+ : sourceType === 'remote'
142
+ ? 'Remote List'
143
+ : sourceType === 'sanity'
144
+ ? 'Sanity List'
145
+ : sourceType === 'expression'
146
+ ? 'Loop'
147
+ : 'List';
148
+ const src =
149
+ sourceType === 'remote' ? listNode.url : sourceType === 'sanity' ? listNode.documentType : listNode.source;
150
+ return src ? `${prefix}: ${src}` : prefix;
116
151
  },
117
152
  },
118
153
 
@@ -126,20 +161,25 @@ export const ListNodeType = createNodeType({
126
161
  const textColor = isCollection ? '#8b5cf6' : '#3b82f6';
127
162
  const label = isCollection ? 'CMS List' : 'List';
128
163
 
129
- return h('div', {
130
- key: context.key,
131
- 'data-list': 'true',
132
- 'data-source-type': sourceType,
133
- 'data-source': listNode.source,
134
- style: {
135
- padding: '8px 12px',
136
- background: bgColor,
137
- border: `1px dashed ${borderColor}`,
138
- borderRadius: '4px',
139
- color: textColor,
140
- fontSize: '12px',
164
+ return h(
165
+ 'div',
166
+ {
167
+ key: context.key,
168
+ 'data-list': 'true',
169
+ 'data-source-type': sourceType,
170
+ 'data-source':
171
+ sourceType === 'remote' ? listNode.url : sourceType === 'sanity' ? listNode.documentType : listNode.source,
172
+ style: {
173
+ padding: '8px 12px',
174
+ background: bgColor,
175
+ border: `1px dashed ${borderColor}`,
176
+ borderRadius: '4px',
177
+ color: textColor,
178
+ fontSize: '12px',
179
+ },
141
180
  },
142
- }, `[${label}: ${listNode.source || 'No source'}]`);
181
+ `[${label}: ${listNode.source || 'No source'}]`,
182
+ );
143
183
  },
144
184
 
145
185
  ssrRenderer: (_node, _context) => {
@@ -158,21 +198,21 @@ export const ListNodeType = createNodeType({
158
198
  label: 'Source Type',
159
199
  type: 'select',
160
200
  required: false,
161
- options: ['prop', 'collection'],
201
+ options: ['prop', 'collection', 'remote', 'sanity'],
162
202
  },
163
203
  {
164
204
  name: 'source',
165
205
  label: 'Source',
166
206
  type: 'string',
167
207
  required: true,
168
- placeholder: 'e.g., items or posts'
208
+ placeholder: 'e.g., items or posts',
169
209
  },
170
210
  {
171
211
  name: 'itemAs',
172
212
  label: 'Item Variable',
173
213
  type: 'string',
174
214
  required: false,
175
- placeholder: 'default: item (prop) or singular (collection)'
176
- }
215
+ placeholder: 'default: item (prop) or singular (collection)',
216
+ },
177
217
  ],
178
218
  });
@@ -9,23 +9,25 @@ import { StyleValueSchema, InteractiveStylesSchema, IfConditionSchema } from '..
9
9
  import { createNodeType } from '../createNodeType';
10
10
 
11
11
  // Schema is the SINGLE source of truth
12
- const LocaleListNodeSchemaInternal = z.object({
13
- type: z.literal('locale-list'),
14
- label: z.string().optional(), // Custom label displayed in structure tree
15
- if: IfConditionSchema.optional(), // Conditional rendering - skip node when false
16
- style: StyleValueSchema.optional(),
17
- itemStyle: StyleValueSchema.optional(),
18
- activeItemStyle: StyleValueSchema.optional(),
19
- separatorStyle: StyleValueSchema.optional(),
20
- showCurrent: z.boolean().optional(),
21
- showSeparator: z.boolean().optional(),
22
- showFlag: z.boolean().optional(),
23
- flagStyle: StyleValueSchema.optional(),
24
- interactiveStyles: InteractiveStylesSchema.optional(), // Interactive CSS rules (hover, active, etc.)
25
- generateElementClass: z.boolean().optional(), // Generate element class without styles (for custom CSS)
26
- displayType: z.enum(['code', 'name', 'nativeName']).optional(), // How to display locale text
27
- attributes: z.record(z.string(), z.union([z.string(), z.number(), z.boolean()])).optional(),
28
- }).passthrough();
12
+ const LocaleListNodeSchemaInternal = z
13
+ .object({
14
+ type: z.literal('locale-list'),
15
+ label: z.string().optional(), // Custom label displayed in structure tree
16
+ if: IfConditionSchema.optional(), // Conditional rendering - skip node when false
17
+ style: StyleValueSchema.optional(),
18
+ itemStyle: StyleValueSchema.optional(),
19
+ activeItemStyle: StyleValueSchema.optional(),
20
+ separatorStyle: StyleValueSchema.optional(),
21
+ showCurrent: z.boolean().optional(),
22
+ showSeparator: z.boolean().optional(),
23
+ showFlag: z.boolean().optional(),
24
+ flagStyle: StyleValueSchema.optional(),
25
+ interactiveStyles: InteractiveStylesSchema.optional(), // Interactive CSS rules (hover, active, etc.)
26
+ generateElementClass: z.boolean().optional(), // Generate element class without styles (for custom CSS)
27
+ displayType: z.enum(['code', 'name', 'nativeName']).optional(), // How to display locale text
28
+ attributes: z.record(z.string(), z.union([z.string(), z.number(), z.boolean()])).optional(),
29
+ })
30
+ .passthrough();
29
31
 
30
32
  // TypeScript type inferred from schema
31
33
  export type LocaleListNode = z.infer<typeof LocaleListNodeSchemaInternal>;
@@ -54,10 +56,14 @@ export const LocaleListNodeType = createNodeType({
54
56
 
55
57
  clientRenderer: (_node, context) => {
56
58
  // In editor, shows placeholder
57
- return h('div', {
58
- key: context.key,
59
- 'data-locale-list': 'true',
60
- }, '[Locale List]');
59
+ return h(
60
+ 'div',
61
+ {
62
+ key: context.key,
63
+ 'data-locale-list': 'true',
64
+ },
65
+ '[Locale List]',
66
+ );
61
67
  },
62
68
 
63
69
  ssrRenderer: (_node, _context) => {
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Markdown Node Type Definition
3
+ * Renders a verbatim Markdown source string as HTML (Astro `.md`-style authoring).
4
+ *
5
+ * The body is stored byte-exact in `node.source` (whitespace-significant Markdown). meno-core
6
+ * renders it via `renderMarkdown` for the canvas + SSR; the meno-astro codec hoists the source
7
+ * to a backtick const and renders it through the runtime `renderMarkdown` at build (see
8
+ * dialect/emit/emitNode.ts:renderMarkdown). Modeled on the Embed node (verbatim payload).
9
+ */
10
+
11
+ import { z } from 'zod';
12
+ import { createElement as h } from 'react';
13
+ import { renderMarkdown } from '../../markdown';
14
+ import { StyleValueSchema, InteractiveStylesSchema, IfConditionSchema } from '../../validation/schemas';
15
+ import { createNodeType } from '../createNodeType';
16
+ import { textareaField } from '../fieldPresets';
17
+
18
+ // Schema is the SINGLE source of truth
19
+ const MarkdownNodeSchemaInternal = z
20
+ .object({
21
+ type: z.literal('markdown'),
22
+ source: z.string(), // verbatim Markdown source (whitespace-significant)
23
+ label: z.string().optional(), // Custom label displayed in structure tree
24
+ if: IfConditionSchema.optional(), // Conditional rendering - skip node when false
25
+ style: StyleValueSchema.optional(),
26
+ interactiveStyles: InteractiveStylesSchema.optional(),
27
+ generateElementClass: z.boolean().optional(),
28
+ attributes: z.record(z.string(), z.union([z.string(), z.number(), z.boolean()])).optional(),
29
+ })
30
+ .passthrough();
31
+
32
+ // TypeScript type inferred from schema
33
+ export type MarkdownNode = z.infer<typeof MarkdownNodeSchemaInternal>;
34
+
35
+ // Export schema for validation/schemas.ts
36
+ export const MarkdownNodeSchema = MarkdownNodeSchemaInternal;
37
+
38
+ export const MarkdownNodeType = createNodeType({
39
+ type: 'markdown',
40
+ displayName: 'Markdown',
41
+ category: 'content',
42
+ schema: MarkdownNodeSchemaInternal,
43
+
44
+ defaultValues: {
45
+ source: '',
46
+ style: { base: {} },
47
+ },
48
+
49
+ treeDisplay: {
50
+ icon: 'HTML_ELEMENT',
51
+ getLabel: () => 'Markdown',
52
+ },
53
+
54
+ editableFields: [
55
+ textareaField({
56
+ name: 'source',
57
+ label: 'Markdown',
58
+ required: true,
59
+ placeholder: '# Heading\n\nWrite **markdown** here…',
60
+ }),
61
+ ],
62
+
63
+ clientRenderer: (node, context) => {
64
+ return h('div', {
65
+ key: context.key,
66
+ dangerouslySetInnerHTML: { __html: renderMarkdown((node as { source?: unknown }).source) },
67
+ });
68
+ },
69
+
70
+ ssrRenderer: (node, _context) => {
71
+ return `<div>${renderMarkdown((node as { source?: unknown }).source)}</div>`;
72
+ },
73
+
74
+ capabilities: {
75
+ canHaveChildren: false,
76
+ requiresProps: ['source'],
77
+ },
78
+ });
@@ -9,13 +9,12 @@ import { createNodeType } from '../createNodeType';
9
9
  // Schema is the SINGLE source of truth
10
10
  // Note: default uses z.any() to avoid circular reference with ComponentNodeSchema
11
11
  // Full validation is done via the schema in validation/schemas.ts
12
- const SlotMarkerSchemaInternal = z.object({
13
- type: z.literal('slot'),
14
- default: z.union([
15
- z.array(z.any()),
16
- z.string(),
17
- ]).optional(),
18
- }).passthrough();
12
+ const SlotMarkerSchemaInternal = z
13
+ .object({
14
+ type: z.literal('slot'),
15
+ default: z.union([z.array(z.any()), z.string()]).optional(),
16
+ })
17
+ .passthrough();
19
18
 
20
19
  // TypeScript type inferred from schema
21
20
  export type SlotMarker = z.infer<typeof SlotMarkerSchemaInternal>;
@@ -33,7 +32,12 @@ export const SlotMarkerType = createNodeType({
33
32
 
34
33
  treeDisplay: {
35
34
  icon: 'SLOT_MARKER',
36
- getLabel: () => 'slot',
35
+ // Show the slot's name so multiple named slots in a component are distinguishable
36
+ // (e.g. `slot: header`). Unnamed (default) slots stay just `slot`.
37
+ getLabel: (node) => {
38
+ const name = (node as { name?: unknown }).name;
39
+ return typeof name === 'string' && name ? `slot: ${name}` : 'slot';
40
+ },
37
41
  },
38
42
 
39
43
  clientRenderer: (_node, _context) => {
@@ -11,12 +11,19 @@ import type { NodeTypeDefinition } from '../NodeTypeDefinition';
11
11
 
12
12
  // Import all node type definitions (each file exports type, schema, and definition)
13
13
  import { HtmlNodeType, HtmlNodeSchema, type HtmlNode } from './HtmlNodeType';
14
- import { ComponentInstanceNodeType, ComponentInstanceNodeSchema, type ComponentInstanceNode } from './ComponentInstanceNodeType';
14
+ import {
15
+ ComponentInstanceNodeType,
16
+ ComponentInstanceNodeSchema,
17
+ type ComponentInstanceNode,
18
+ } from './ComponentInstanceNodeType';
15
19
  import { SlotMarkerType, SlotMarkerSchema, type SlotMarker } from './SlotMarkerType';
16
20
  import { EmbedNodeType, EmbedNodeSchema, type EmbedNode } from './EmbedNodeType';
17
21
  import { LinkNodeType, LinkNodeSchema, type LinkNode } from './LinkNodeType';
18
22
  import { LocaleListNodeType, LocaleListNodeSchema, type LocaleListNode } from './LocaleListNodeType';
19
23
  import { ListNodeType, ListNodeSchema, type ListNode } from './ListNodeType';
24
+ import { IslandNodeType, IslandNodeSchema, type IslandNode } from './IslandNodeType';
25
+ import { MarkdownNodeType, MarkdownNodeSchema, type MarkdownNode } from './MarkdownNodeType';
26
+ import { CustomNodeType, CustomNodeSchema, type CustomNode } from './CustomNodeType';
20
27
 
21
28
  /**
22
29
  * All built-in node type definitions
@@ -30,6 +37,9 @@ export const builtInNodeTypes: NodeTypeDefinition[] = [
30
37
  LinkNodeType as NodeTypeDefinition,
31
38
  LocaleListNodeType as NodeTypeDefinition,
32
39
  ListNodeType as NodeTypeDefinition,
40
+ IslandNodeType as NodeTypeDefinition,
41
+ MarkdownNodeType as NodeTypeDefinition,
42
+ CustomNodeType as NodeTypeDefinition,
33
43
  ];
34
44
 
35
45
  /**
@@ -43,6 +53,9 @@ export const nodeSchemas = {
43
53
  link: LinkNodeSchema,
44
54
  localeList: LocaleListNodeSchema,
45
55
  list: ListNodeSchema,
56
+ island: IslandNodeSchema,
57
+ markdown: MarkdownNodeSchema,
58
+ custom: CustomNodeSchema,
46
59
  };
47
60
 
48
61
  /**
@@ -55,12 +68,19 @@ export function registerBuiltInNodeTypes(): void {
55
68
 
56
69
  // Re-export individual node types for direct access
57
70
  export { HtmlNodeType, HtmlNodeSchema, type HtmlNode } from './HtmlNodeType';
58
- export { ComponentInstanceNodeType, ComponentInstanceNodeSchema, type ComponentInstanceNode } from './ComponentInstanceNodeType';
71
+ export {
72
+ ComponentInstanceNodeType,
73
+ ComponentInstanceNodeSchema,
74
+ type ComponentInstanceNode,
75
+ } from './ComponentInstanceNodeType';
59
76
  export { SlotMarkerType, SlotMarkerSchema, type SlotMarker } from './SlotMarkerType';
60
77
  export { EmbedNodeType, EmbedNodeSchema, type EmbedNode } from './EmbedNodeType';
61
78
  export { LinkNodeType, LinkNodeSchema, type LinkNode } from './LinkNodeType';
62
79
  export { LocaleListNodeType, LocaleListNodeSchema, type LocaleListNode } from './LocaleListNodeType';
63
80
  export { ListNodeType, ListNodeSchema, type ListNode } from './ListNodeType';
81
+ export { IslandNodeType, IslandNodeSchema, type IslandNode } from './IslandNodeType';
82
+ export { MarkdownNodeType, MarkdownNodeSchema, type MarkdownNode } from './MarkdownNodeType';
83
+ export { CustomNodeType, CustomNodeSchema, type CustomNode } from './CustomNodeType';
64
84
 
65
85
  /**
66
86
  * Discriminated union of all component node types
@@ -73,4 +93,7 @@ export type ComponentNode =
73
93
  | EmbedNode
74
94
  | LinkNode
75
95
  | LocaleListNode
76
- | ListNode;
96
+ | ListNode
97
+ | IslandNode
98
+ | MarkdownNode
99
+ | CustomNode;
@@ -15,8 +15,6 @@ import {
15
15
  buildSiteMarginClamp,
16
16
  getSmallestBreakpointName,
17
17
  type ResponsiveScales,
18
- type CSSPropertyType,
19
- type BreakpointScales,
20
18
  } from './responsiveScaling';
21
19
 
22
20
  describe('responsiveScaling', () => {
@@ -95,7 +93,7 @@ describe('responsiveScaling', () => {
95
93
  const scales: ResponsiveScales = {
96
94
  enabled: true,
97
95
  baseReference: 16,
98
- fontSize: { tablet: 0.88 }
96
+ fontSize: { tablet: 0.88 },
99
97
  };
100
98
  const scale = getScaleMultiplier(scales, 'fontSize', 'mobile');
101
99
  expect(scale).toBeNull();
@@ -105,7 +103,7 @@ describe('responsiveScaling', () => {
105
103
  const scales: ResponsiveScales = {
106
104
  enabled: true,
107
105
  baseReference: 16,
108
- fontSize: { large: 0.95, tablet: 0.88, small: 0.82, mobile: 0.75 }
106
+ fontSize: { large: 0.95, tablet: 0.88, small: 0.82, mobile: 0.75 },
109
107
  };
110
108
  expect(getScaleMultiplier(scales, 'fontSize', 'large')).toBe(0.95);
111
109
  expect(getScaleMultiplier(scales, 'fontSize', 'small')).toBe(0.82);
@@ -115,7 +113,7 @@ describe('responsiveScaling', () => {
115
113
  const scales: ResponsiveScales = {
116
114
  enabled: true,
117
115
  baseReference: 16,
118
- fontSize: { tablet: 0.88, mobile: 0.75 }
116
+ fontSize: { tablet: 0.88, mobile: 0.75 },
119
117
  };
120
118
  expect(getScaleMultiplier(scales, 'fontSize', 'large')).toBeNull();
121
119
  expect(getScaleMultiplier(scales, 'fontSize', 'small')).toBeNull();
@@ -277,7 +275,7 @@ describe('responsiveScaling', () => {
277
275
  const scales: ResponsiveScales = {
278
276
  enabled: true,
279
277
  baseReference: 16,
280
- fontSize: { tablet: 0.88 }
278
+ fontSize: { tablet: 0.88 },
281
279
  };
282
280
  const result = getResponsiveValues('20px', 'fontSize', scales);
283
281
  expect(result.base).toBe('20px');
@@ -289,18 +287,13 @@ describe('responsiveScaling', () => {
289
287
  const scales: ResponsiveScales = {
290
288
  enabled: true,
291
289
  baseReference: 16,
292
- fontSize: { large: 0.95, tablet: 0.88, small: 0.82, mobile: 0.75 }
290
+ fontSize: { large: 0.95, tablet: 0.88, small: 0.82, mobile: 0.75 },
293
291
  };
294
- const result = getResponsiveValues(
295
- '67px',
296
- 'fontSize',
297
- scales,
298
- ['large', 'tablet', 'small', 'mobile']
299
- );
292
+ const result = getResponsiveValues('67px', 'fontSize', scales, ['large', 'tablet', 'small', 'mobile']);
300
293
  expect(result.base).toBe('67px');
301
- expect(result.large).toBe('64px'); // 67 + (67-16) * (0.95-1) = 67 - 2.55 ≈ 64
294
+ expect(result.large).toBe('64px'); // 67 + (67-16) * (0.95-1) = 67 - 2.55 ≈ 64
302
295
  expect(result.tablet).toBe('61px'); // 0.88 scale
303
- expect(result.small).toBe('58px'); // 67 + (67-16) * (0.82-1) = 67 - 9.18 ≈ 58
296
+ expect(result.small).toBe('58px'); // 67 + (67-16) * (0.82-1) = 67 - 9.18 ≈ 58
304
297
  expect(result.mobile).toBe('54px'); // 0.75 scale
305
298
  });
306
299
 
@@ -308,15 +301,10 @@ describe('responsiveScaling', () => {
308
301
  const scales: ResponsiveScales = {
309
302
  enabled: true,
310
303
  baseReference: 16,
311
- fontSize: { large: 0.95, tablet: 0.88, small: 0.82, mobile: 0.75 }
304
+ fontSize: { large: 0.95, tablet: 0.88, small: 0.82, mobile: 0.75 },
312
305
  };
313
306
  // Only request large and small breakpoints
314
- const result = getResponsiveValues(
315
- '67px',
316
- 'fontSize',
317
- scales,
318
- ['large', 'small']
319
- );
307
+ const result = getResponsiveValues('67px', 'fontSize', scales, ['large', 'small']);
320
308
  expect(result.base).toBe('67px');
321
309
  expect(result.large).toBe('64px');
322
310
  expect(result.small).toBe('58px');
@@ -328,19 +316,14 @@ describe('responsiveScaling', () => {
328
316
  const scales: ResponsiveScales = {
329
317
  enabled: true,
330
318
  baseReference: 16,
331
- fontSize: { tablet: 0.88, mobile: 0.75 }
319
+ fontSize: { tablet: 0.88, mobile: 0.75 },
332
320
  };
333
321
  // Request breakpoints that don't have scales configured
334
- const result = getResponsiveValues(
335
- '67px',
336
- 'fontSize',
337
- scales,
338
- ['large', 'tablet', 'small', 'mobile']
339
- );
322
+ const result = getResponsiveValues('67px', 'fontSize', scales, ['large', 'tablet', 'small', 'mobile']);
340
323
  expect(result.base).toBe('67px');
341
- expect(result.large).toBeUndefined(); // No scale configured
324
+ expect(result.large).toBeUndefined(); // No scale configured
342
325
  expect(result.tablet).toBe('61px');
343
- expect(result.small).toBeUndefined(); // No scale configured
326
+ expect(result.small).toBeUndefined(); // No scale configured
344
327
  expect(result.mobile).toBe('54px');
345
328
  });
346
329
 
@@ -469,7 +452,7 @@ describe('responsiveScaling', () => {
469
452
  test('multi-value padding "20px 40px" → both tokens scaled', () => {
470
453
  const out = buildFluidPropertyValue('20px 40px', 0.5, 320, 1440);
471
454
  expect(out).not.toBeNull();
472
- const parts = out!.split(' ');
455
+ const _parts = out!.split(' ');
473
456
  // The two tokens get joined by space — but each clamp() also has spaces inside.
474
457
  // Check both clamp(...) substrings present.
475
458
  expect((out!.match(/clamp\(/g) ?? []).length).toBe(2);
@@ -501,8 +484,7 @@ describe('responsiveScaling', () => {
501
484
  });
502
485
 
503
486
  test('returns plain px when min === max', () => {
504
- expect(buildSiteMarginClamp({ min: 16, max: 16 }, { min: 320, max: 1440 }))
505
- .toBe('16px');
487
+ expect(buildSiteMarginClamp({ min: 16, max: 16 }, { min: 320, max: 1440 })).toBe('16px');
506
488
  });
507
489
 
508
490
  test('default DEFAULT_SITE_MARGIN is 16/32', () => {