meno-core 1.0.53 → 1.0.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (387) hide show
  1. package/.claude/settings.local.json +1 -3
  2. package/bin/cli.ts +48 -57
  3. package/build-astro.ts +131 -113
  4. package/build-next.ts +109 -96
  5. package/build-static.test.ts +39 -10
  6. package/build-static.ts +120 -122
  7. package/dist/bin/cli.js +34 -38
  8. package/dist/bin/cli.js.map +2 -2
  9. package/dist/build-static.js +12 -11
  10. package/dist/chunks/chunk-2AR55GYH.js +42 -0
  11. package/dist/chunks/chunk-2AR55GYH.js.map +7 -0
  12. package/dist/chunks/{chunk-IGYR22T6.js → chunk-2FN4UOVO.js} +512 -239
  13. package/dist/chunks/chunk-2FN4UOVO.js.map +7 -0
  14. package/dist/chunks/chunk-3XER4E5W.js +168 -0
  15. package/dist/chunks/chunk-3XER4E5W.js.map +7 -0
  16. package/dist/chunks/{chunk-X754AHS5.js → chunk-5ETZFREW.js} +9 -12
  17. package/dist/chunks/chunk-5ETZFREW.js.map +7 -0
  18. package/dist/chunks/{chunk-2MHDV5BF.js → chunk-7E4IF5L7.js} +15 -21
  19. package/dist/chunks/chunk-7E4IF5L7.js.map +7 -0
  20. package/dist/chunks/{chunk-JGWFTO6P.js → chunk-7HWQUVTU.js} +1578 -1349
  21. package/dist/chunks/chunk-7HWQUVTU.js.map +7 -0
  22. package/dist/chunks/{chunk-O3NAGJP4.js → chunk-AE3QK5QW.js} +110 -21
  23. package/dist/chunks/chunk-AE3QK5QW.js.map +7 -0
  24. package/dist/chunks/{chunk-GZHGVVW3.js → chunk-F6KTJYGV.js} +7 -7
  25. package/dist/chunks/chunk-F6KTJYGV.js.map +7 -0
  26. package/dist/chunks/{chunk-WQFG7PAH.js → chunk-FZITJSSS.js} +2 -6
  27. package/dist/chunks/chunk-FZITJSSS.js.map +7 -0
  28. package/dist/chunks/{chunk-QB2LNO4W.js → chunk-GSYYA5GX.js} +2 -2
  29. package/dist/chunks/chunk-GSYYA5GX.js.map +7 -0
  30. package/dist/chunks/{chunk-YBLHKYFF.js → chunk-HIZMY3EP.js} +1 -1
  31. package/dist/chunks/chunk-HIZMY3EP.js.map +7 -0
  32. package/dist/chunks/{chunk-AZQYF6KE.js → chunk-I2WEGYA7.js} +41 -176
  33. package/dist/chunks/chunk-I2WEGYA7.js.map +7 -0
  34. package/dist/chunks/{chunk-I7YIGZXT.js → chunk-JNO3CNLJ.js} +6 -9
  35. package/dist/chunks/chunk-JNO3CNLJ.js.map +7 -0
  36. package/dist/chunks/{chunk-UB44F4Z2.js → chunk-NVRBTSQG.js} +2 -4
  37. package/dist/chunks/chunk-NVRBTSQG.js.map +7 -0
  38. package/dist/chunks/{chunk-JGP5A3Y5.js → chunk-Q4OBWKXG.js} +40 -33
  39. package/dist/chunks/chunk-Q4OBWKXG.js.map +7 -0
  40. package/dist/chunks/{chunk-R6XHAFBF.js → chunk-QTE32Y53.js} +250 -242
  41. package/dist/chunks/chunk-QTE32Y53.js.map +7 -0
  42. package/dist/chunks/{chunk-H3GJ4H2U.js → chunk-STDY3OVM.js} +214 -85
  43. package/dist/chunks/chunk-STDY3OVM.js.map +7 -0
  44. package/dist/chunks/configService-PRJZF7Y6.js +14 -0
  45. package/dist/chunks/{constants-STK2YBIW.js → constants-KIQEYMAM.js} +2 -2
  46. package/dist/chunks/{fs-JGINUXGL.js → fs-ZI5JEU7V.js} +2 -2
  47. package/dist/entries/server-router.js +14 -19
  48. package/dist/entries/server-router.js.map +2 -2
  49. package/dist/lib/client/index.js +638 -332
  50. package/dist/lib/client/index.js.map +2 -2
  51. package/dist/lib/server/index.js +177 -235
  52. package/dist/lib/server/index.js.map +2 -2
  53. package/dist/lib/shared/index.js +80 -44
  54. package/dist/lib/shared/index.js.map +2 -2
  55. package/dist/lib/shared/richtext/index.js +1 -1
  56. package/dist/lib/test-utils/index.js +38 -60
  57. package/dist/lib/test-utils/index.js.map +2 -2
  58. package/entries/client-router.tsx +10 -8
  59. package/entries/server-router.tsx +1 -7
  60. package/lib/client/ClientInitializer.ts +8 -8
  61. package/lib/client/ErrorBoundary.test.tsx +146 -143
  62. package/lib/client/ErrorBoundary.tsx +175 -127
  63. package/lib/client/componentRegistry.test.ts +96 -108
  64. package/lib/client/componentRegistry.ts +1 -2
  65. package/lib/client/contexts/ThemeContext.tsx +3 -2
  66. package/lib/client/core/ComponentBuilder.test.ts +513 -560
  67. package/lib/client/core/ComponentBuilder.ts +318 -146
  68. package/lib/client/core/ComponentRenderer.test.tsx +1 -2
  69. package/lib/client/core/ComponentRenderer.tsx +46 -33
  70. package/lib/client/core/builders/embedBuilder.ts +241 -53
  71. package/lib/client/core/builders/linkBuilder.ts +71 -44
  72. package/lib/client/core/builders/linkNodeBuilder.ts +78 -53
  73. package/lib/client/core/builders/listBuilder.ts +115 -86
  74. package/lib/client/core/builders/localeListBuilder.ts +95 -60
  75. package/lib/client/core/builders/types.ts +5 -5
  76. package/lib/client/core/cmsTemplateProcessor.ts +7 -7
  77. package/lib/client/elementRegistry.ts +3 -3
  78. package/lib/client/fontFamiliesService.test.ts +2 -10
  79. package/lib/client/fontFamiliesService.ts +3 -3
  80. package/lib/client/hmr/HMRManager.tsx +8 -0
  81. package/lib/client/hmrCssReload.ts +14 -8
  82. package/lib/client/hmrWebSocket.ts +9 -14
  83. package/lib/client/hooks/useColorVariables.test.ts +21 -21
  84. package/lib/client/hooks/useColorVariables.ts +12 -10
  85. package/lib/client/hooks/usePropertyAutocomplete.ts +3 -5
  86. package/lib/client/hooks/useVariables.ts +4 -4
  87. package/lib/client/hydration/HydrationUtils.test.ts +24 -25
  88. package/lib/client/hydration/HydrationUtils.ts +3 -4
  89. package/lib/client/i18nConfigService.test.ts +2 -7
  90. package/lib/client/i18nConfigService.ts +2 -2
  91. package/lib/client/meno-filter/MenoFilter.test.ts +19 -21
  92. package/lib/client/meno-filter/MenoFilter.ts +5 -9
  93. package/lib/client/meno-filter/bindings.ts +15 -40
  94. package/lib/client/meno-filter/init.ts +1 -1
  95. package/lib/client/meno-filter/renderer.ts +23 -29
  96. package/lib/client/meno-filter/script.generated.ts +1 -3
  97. package/lib/client/meno-filter/ui.ts +3 -5
  98. package/lib/client/meno-filter/updates.ts +15 -21
  99. package/lib/client/navigation.test.ts +159 -159
  100. package/lib/client/navigation.ts +0 -1
  101. package/lib/client/responsiveStyleResolver.test.ts +230 -228
  102. package/lib/client/responsiveStyleResolver.ts +13 -16
  103. package/lib/client/routing/RouteLoader.test.ts +23 -24
  104. package/lib/client/routing/RouteLoader.ts +22 -35
  105. package/lib/client/routing/Router.tsx +31 -3
  106. package/lib/client/scripts/ScriptExecutor.test.ts +157 -158
  107. package/lib/client/scripts/ScriptExecutor.ts +15 -33
  108. package/lib/client/services/PrefetchService.test.ts +2 -2
  109. package/lib/client/services/PrefetchService.ts +10 -24
  110. package/lib/client/styleProcessor.test.ts +9 -9
  111. package/lib/client/styleProcessor.ts +18 -15
  112. package/lib/client/styles/StyleInjector.test.ts +122 -115
  113. package/lib/client/styles/StyleInjector.ts +9 -6
  114. package/lib/client/styles/UtilityClassCollector.ts +19 -26
  115. package/lib/client/styles/cspNonce.test.ts +2 -5
  116. package/lib/client/templateEngine.test.ts +554 -482
  117. package/lib/client/templateEngine.ts +200 -64
  118. package/lib/client/theme.ts +0 -1
  119. package/lib/client/utils/toast.ts +0 -1
  120. package/lib/server/__integration__/api-routes.test.ts +8 -4
  121. package/lib/server/__integration__/cms-integration.test.ts +1 -4
  122. package/lib/server/__integration__/server-lifecycle.test.ts +2 -5
  123. package/lib/server/__integration__/ssr-rendering.test.ts +47 -37
  124. package/lib/server/__integration__/static-assets.test.ts +1 -1
  125. package/lib/server/__integration__/test-helpers.ts +84 -70
  126. package/lib/server/ab/generateFunctions.ts +12 -10
  127. package/lib/server/astro/cmsPageEmitter.ts +23 -38
  128. package/lib/server/astro/componentEmitter.ts +25 -36
  129. package/lib/server/astro/cssCollector.ts +10 -26
  130. package/lib/server/astro/nodeToAstro.test.ts +1750 -30
  131. package/lib/server/astro/nodeToAstro.ts +198 -187
  132. package/lib/server/astro/normalizeOrphanTemplateProps.test.ts +105 -109
  133. package/lib/server/astro/normalizeOrphanTemplateProps.ts +4 -12
  134. package/lib/server/astro/pageEmitter.ts +9 -13
  135. package/lib/server/astro/tailwindMapper.test.ts +10 -37
  136. package/lib/server/astro/tailwindMapper.ts +33 -40
  137. package/lib/server/astro/templateTransformer.ts +14 -17
  138. package/lib/server/createServer.ts +5 -17
  139. package/lib/server/cssGenerator.test.ts +35 -44
  140. package/lib/server/cssGenerator.ts +6 -17
  141. package/lib/server/fileWatcher.test.ts +124 -10
  142. package/lib/server/fileWatcher.ts +124 -118
  143. package/lib/server/index.ts +7 -1
  144. package/lib/server/jsonLoader.test.ts +39 -2
  145. package/lib/server/jsonLoader.ts +33 -31
  146. package/lib/server/middleware/cors.test.ts +20 -20
  147. package/lib/server/middleware/cors.ts +28 -4
  148. package/lib/server/middleware/errorHandler.test.ts +5 -3
  149. package/lib/server/middleware/errorHandler.ts +3 -8
  150. package/lib/server/middleware/index.ts +0 -1
  151. package/lib/server/middleware/logger.test.ts +7 -5
  152. package/lib/server/middleware/logger.ts +10 -22
  153. package/lib/server/pageCache.test.ts +76 -77
  154. package/lib/server/pageCache.ts +0 -1
  155. package/lib/server/projectContext.ts +4 -3
  156. package/lib/server/providers/fileSystemCMSProvider.test.ts +124 -95
  157. package/lib/server/providers/fileSystemCMSProvider.ts +35 -20
  158. package/lib/server/providers/fileSystemPageProvider.test.ts +84 -0
  159. package/lib/server/providers/fileSystemPageProvider.ts +31 -12
  160. package/lib/server/routes/api/cms.test.ts +26 -14
  161. package/lib/server/routes/api/cms.ts +9 -14
  162. package/lib/server/routes/api/components.ts +30 -34
  163. package/lib/server/routes/api/config.ts +0 -1
  164. package/lib/server/routes/api/core-routes.ts +47 -74
  165. package/lib/server/routes/api/functions.ts +8 -16
  166. package/lib/server/routes/api/index.ts +3 -6
  167. package/lib/server/routes/api/pages.ts +8 -11
  168. package/lib/server/routes/api/shared.test.ts +1 -1
  169. package/lib/server/routes/api/shared.ts +12 -9
  170. package/lib/server/routes/api/variables.test.ts +1 -3
  171. package/lib/server/routes/api/variables.ts +1 -1
  172. package/lib/server/routes/index.ts +23 -26
  173. package/lib/server/routes/pages.ts +34 -29
  174. package/lib/server/routes/static.ts +16 -4
  175. package/lib/server/runtime/bundler.ts +47 -32
  176. package/lib/server/runtime/fs.ts +3 -13
  177. package/lib/server/runtime/httpServer.ts +5 -9
  178. package/lib/server/services/ColorService.ts +32 -27
  179. package/lib/server/services/EnumService.test.ts +2 -6
  180. package/lib/server/services/EnumService.ts +7 -2
  181. package/lib/server/services/VariableService.test.ts +1 -5
  182. package/lib/server/services/VariableService.ts +6 -1
  183. package/lib/server/services/cmsService.test.ts +116 -78
  184. package/lib/server/services/cmsService.ts +24 -54
  185. package/lib/server/services/componentService.test.ts +122 -36
  186. package/lib/server/services/componentService.ts +54 -38
  187. package/lib/server/services/configService.test.ts +9 -31
  188. package/lib/server/services/configService.ts +20 -27
  189. package/lib/server/services/fileWatcherService.ts +40 -6
  190. package/lib/server/services/index.ts +0 -1
  191. package/lib/server/services/pageService.test.ts +1 -3
  192. package/lib/server/services/pageService.ts +14 -13
  193. package/lib/server/ssr/attributeBuilder.ts +16 -6
  194. package/lib/server/ssr/buildErrorOverlay.ts +11 -12
  195. package/lib/server/ssr/clientDataInjector.ts +7 -21
  196. package/lib/server/ssr/cmsSSRProcessor.ts +3 -6
  197. package/lib/server/ssr/cssCollector.ts +1 -1
  198. package/lib/server/ssr/errorOverlay.test.ts +1 -1
  199. package/lib/server/ssr/errorOverlay.ts +3 -9
  200. package/lib/server/ssr/htmlGenerator.nonce.test.ts +3 -9
  201. package/lib/server/ssr/htmlGenerator.test.ts +120 -43
  202. package/lib/server/ssr/htmlGenerator.ts +120 -85
  203. package/lib/server/ssr/imageMetadata.test.ts +3 -1
  204. package/lib/server/ssr/imageMetadata.ts +25 -19
  205. package/lib/server/ssr/jsCollector.test.ts +3 -13
  206. package/lib/server/ssr/jsCollector.ts +3 -8
  207. package/lib/server/ssr/liveReloadIntegration.test.ts +69 -28
  208. package/lib/server/ssr/metaTagGenerator.ts +2 -2
  209. package/lib/server/ssr/ssrRenderer.branches.test.ts +1103 -0
  210. package/lib/server/ssr/ssrRenderer.test.ts +196 -246
  211. package/lib/server/ssr/ssrRenderer.ts +609 -225
  212. package/lib/server/ssrRenderer.test.ts +1044 -950
  213. package/lib/server/utils/jsonLineMapper.test.ts +28 -28
  214. package/lib/server/utils/jsonLineMapper.ts +1 -1
  215. package/lib/server/validateStyleCoverage.ts +18 -20
  216. package/lib/server/webflow/buildWebflow.ts +41 -53
  217. package/lib/server/webflow/nodeToWebflow.test.ts +150 -218
  218. package/lib/server/webflow/nodeToWebflow.ts +195 -258
  219. package/lib/server/webflow/styleMapper.test.ts +15 -56
  220. package/lib/server/webflow/styleMapper.ts +33 -41
  221. package/lib/server/webflow/types.ts +1 -8
  222. package/lib/server/websocketManager.ts +16 -19
  223. package/lib/shared/attributeNodeUtils.test.ts +15 -15
  224. package/lib/shared/attributeNodeUtils.ts +5 -12
  225. package/lib/shared/breakpoints.ts +4 -11
  226. package/lib/shared/cmsQueryParser.test.ts +50 -42
  227. package/lib/shared/cmsQueryParser.ts +49 -31
  228. package/lib/shared/colorVariableUtils.test.ts +5 -5
  229. package/lib/shared/colorVariableUtils.ts +3 -8
  230. package/lib/shared/componentRefs.ts +1 -5
  231. package/lib/shared/constants.test.ts +3 -3
  232. package/lib/shared/constants.ts +4 -8
  233. package/lib/shared/cssGeneration.test.ts +262 -144
  234. package/lib/shared/cssGeneration.ts +189 -516
  235. package/lib/shared/cssNamedColors.ts +152 -30
  236. package/lib/shared/cssProperties.test.ts +5 -6
  237. package/lib/shared/cssProperties.ts +296 -112
  238. package/lib/shared/elementClassName.test.ts +109 -109
  239. package/lib/shared/elementClassName.ts +1 -1
  240. package/lib/shared/elementUtils.ts +12 -16
  241. package/lib/shared/errorLogger.ts +2 -10
  242. package/lib/shared/errors.test.ts +2 -13
  243. package/lib/shared/errors.ts +2 -8
  244. package/lib/shared/expressionEvaluator.test.ts +119 -0
  245. package/lib/shared/expressionEvaluator.ts +43 -24
  246. package/lib/shared/fontLoader.test.ts +19 -5
  247. package/lib/shared/friendlyError.ts +2 -3
  248. package/lib/shared/gradientUtils.test.ts +1 -5
  249. package/lib/shared/gradientUtils.ts +2 -6
  250. package/lib/shared/hrefRefs.ts +2 -10
  251. package/lib/shared/i18n.test.ts +1 -1
  252. package/lib/shared/i18n.ts +13 -34
  253. package/lib/shared/index.ts +4 -0
  254. package/lib/shared/inlineSvgStyleRules.ts +2 -4
  255. package/lib/shared/interactiveStyleMappings.test.ts +11 -33
  256. package/lib/shared/interactiveStyleMappings.ts +9 -16
  257. package/lib/shared/interactiveStyles.test.ts +165 -188
  258. package/lib/shared/interfaces/contentProvider.ts +1 -1
  259. package/lib/shared/itemTemplateUtils.test.ts +6 -12
  260. package/lib/shared/itemTemplateUtils.ts +19 -35
  261. package/lib/shared/jsonRepair.ts +8 -2
  262. package/lib/shared/libraryLoader.test.ts +15 -49
  263. package/lib/shared/libraryLoader.ts +7 -22
  264. package/lib/shared/netlifyLocale404.test.ts +179 -0
  265. package/lib/shared/netlifyLocale404.ts +110 -0
  266. package/lib/shared/nodeUtils.test.ts +24 -16
  267. package/lib/shared/nodeUtils.ts +49 -19
  268. package/lib/shared/pathArrayUtils.test.ts +1 -2
  269. package/lib/shared/pathArrayUtils.ts +1 -1
  270. package/lib/shared/pathSecurity.ts +1 -1
  271. package/lib/shared/pathUtils.test.ts +4 -6
  272. package/lib/shared/pathUtils.ts +42 -48
  273. package/lib/shared/paths/Path.test.ts +2 -2
  274. package/lib/shared/paths/Path.ts +0 -1
  275. package/lib/shared/paths/PathConverter.test.ts +1 -1
  276. package/lib/shared/paths/PathConverter.ts +14 -17
  277. package/lib/shared/paths/PathUtils.ts +9 -10
  278. package/lib/shared/paths/PathValidator.test.ts +2 -15
  279. package/lib/shared/paths/PathValidator.ts +11 -9
  280. package/lib/shared/paths/index.ts +1 -2
  281. package/lib/shared/propResolver.test.ts +240 -244
  282. package/lib/shared/propResolver.ts +14 -25
  283. package/lib/shared/pxToRem.test.ts +7 -6
  284. package/lib/shared/pxToRem.ts +2 -5
  285. package/lib/shared/registry/BaseNodeTypeRegistry.test.ts +9 -5
  286. package/lib/shared/registry/ClientRegistry.ts +0 -1
  287. package/lib/shared/registry/ComponentRegistry.test.ts +43 -29
  288. package/lib/shared/registry/ComponentRegistry.ts +9 -11
  289. package/lib/shared/registry/NodeTypeDefinition.ts +15 -8
  290. package/lib/shared/registry/RegistryManager.ts +1 -2
  291. package/lib/shared/registry/SSRRegistry.ts +0 -1
  292. package/lib/shared/registry/createNodeType.ts +7 -9
  293. package/lib/shared/registry/defineNodeType.ts +2 -6
  294. package/lib/shared/registry/index.ts +0 -1
  295. package/lib/shared/registry/nodeTypes/ComponentInstanceNodeType.ts +14 -15
  296. package/lib/shared/registry/nodeTypes/EmbedNodeType.ts +18 -11
  297. package/lib/shared/registry/nodeTypes/HtmlNodeType.ts +47 -18
  298. package/lib/shared/registry/nodeTypes/LinkNodeType.ts +21 -19
  299. package/lib/shared/registry/nodeTypes/ListNodeType.ts +78 -74
  300. package/lib/shared/registry/nodeTypes/LocaleListNodeType.ts +27 -21
  301. package/lib/shared/registry/nodeTypes/SlotMarkerType.ts +6 -7
  302. package/lib/shared/registry/nodeTypes/index.ts +10 -2
  303. package/lib/shared/responsiveScaling.test.ts +15 -31
  304. package/lib/shared/responsiveScaling.ts +55 -37
  305. package/lib/shared/responsiveStyleUtils.ts +11 -13
  306. package/lib/shared/richtext/htmlToTiptap.test.ts +23 -14
  307. package/lib/shared/richtext/htmlToTiptap.ts +1 -3
  308. package/lib/shared/richtext/tiptapToHtml.test.ts +5 -6
  309. package/lib/shared/richtext/types.ts +1 -8
  310. package/lib/shared/slugTranslator.test.ts +13 -13
  311. package/lib/shared/slugTranslator.ts +12 -16
  312. package/lib/shared/slugify.ts +9 -15
  313. package/lib/shared/styleNodeUtils.test.ts +8 -8
  314. package/lib/shared/styleNodeUtils.ts +5 -10
  315. package/lib/shared/styleUtils.test.ts +87 -61
  316. package/lib/shared/styleUtils.ts +5 -6
  317. package/lib/shared/themeDefaults.test.ts +11 -11
  318. package/lib/shared/themeDefaults.ts +3 -4
  319. package/lib/shared/tree/PathBuilder.test.ts +62 -138
  320. package/lib/shared/tree/PathBuilder.ts +49 -39
  321. package/lib/shared/treePathUtils.test.ts +2 -10
  322. package/lib/shared/treePathUtils.ts +54 -59
  323. package/lib/shared/types/api.ts +1 -2
  324. package/lib/shared/types/cms.ts +25 -21
  325. package/lib/shared/types/comment.ts +49 -16
  326. package/lib/shared/types/components.ts +27 -25
  327. package/lib/shared/types/errors.test.ts +1 -6
  328. package/lib/shared/types/errors.ts +3 -7
  329. package/lib/shared/types/experiments.ts +28 -28
  330. package/lib/shared/types/index.ts +2 -2
  331. package/lib/shared/types/styles.ts +0 -1
  332. package/lib/shared/types/variables.test.ts +4 -13
  333. package/lib/shared/types/variables.ts +48 -27
  334. package/lib/shared/types.ts +1 -2
  335. package/lib/shared/utilityClassConfig.ts +648 -321
  336. package/lib/shared/utilityClassMapper.test.ts +203 -92
  337. package/lib/shared/utilityClassMapper.ts +188 -246
  338. package/lib/shared/utilityClassNames.ts +326 -0
  339. package/lib/shared/utils.test.ts +2 -10
  340. package/lib/shared/utils.ts +19 -10
  341. package/lib/shared/validation/cmsValidators.ts +2 -1
  342. package/lib/shared/validation/commentValidators.test.ts +53 -0
  343. package/lib/shared/validation/commentValidators.ts +12 -1
  344. package/lib/shared/validation/propValidator.test.ts +18 -20
  345. package/lib/shared/validation/propValidator.ts +12 -17
  346. package/lib/shared/validation/schemas.test.ts +24 -33
  347. package/lib/shared/validation/schemas.ts +469 -344
  348. package/lib/shared/validation/validators.test.ts +1 -6
  349. package/lib/shared/validation/validators.ts +89 -68
  350. package/lib/shared/viewportUnits.integration.test.ts +14 -10
  351. package/lib/shared/viewportUnits.test.ts +11 -23
  352. package/lib/test-utils/dom-setup.ts +1 -1
  353. package/lib/test-utils/factories/ConsoleMockFactory.ts +3 -7
  354. package/lib/test-utils/factories/DomMockFactory.ts +7 -19
  355. package/lib/test-utils/factories/EventMockFactory.ts +7 -13
  356. package/lib/test-utils/factories/FetchMockFactory.ts +39 -57
  357. package/lib/test-utils/factories/ServerMockFactory.ts +5 -9
  358. package/lib/test-utils/factories/StoreMockFactory.ts +14 -25
  359. package/lib/test-utils/fixtures.ts +45 -45
  360. package/lib/test-utils/helpers/asyncHelpers.test.ts +15 -18
  361. package/lib/test-utils/helpers/asyncHelpers.ts +11 -20
  362. package/lib/test-utils/helpers.ts +1 -5
  363. package/lib/test-utils/index.ts +0 -4
  364. package/lib/test-utils/mockFactories.ts +12 -18
  365. package/lib/test-utils/mocks.ts +4 -2
  366. package/package.json +1 -1
  367. package/scripts/build-meno-filter.ts +1 -4
  368. package/vite.config.ts +4 -4
  369. package/dist/chunks/chunk-2MHDV5BF.js.map +0 -7
  370. package/dist/chunks/chunk-AZQYF6KE.js.map +0 -7
  371. package/dist/chunks/chunk-GZHGVVW3.js.map +0 -7
  372. package/dist/chunks/chunk-H3GJ4H2U.js.map +0 -7
  373. package/dist/chunks/chunk-I7YIGZXT.js.map +0 -7
  374. package/dist/chunks/chunk-IGYR22T6.js.map +0 -7
  375. package/dist/chunks/chunk-JGP5A3Y5.js.map +0 -7
  376. package/dist/chunks/chunk-JGWFTO6P.js.map +0 -7
  377. package/dist/chunks/chunk-O3NAGJP4.js.map +0 -7
  378. package/dist/chunks/chunk-QB2LNO4W.js.map +0 -7
  379. package/dist/chunks/chunk-R6XHAFBF.js.map +0 -7
  380. package/dist/chunks/chunk-UB44F4Z2.js.map +0 -7
  381. package/dist/chunks/chunk-WQFG7PAH.js.map +0 -7
  382. package/dist/chunks/chunk-X754AHS5.js.map +0 -7
  383. package/dist/chunks/chunk-YBLHKYFF.js.map +0 -7
  384. package/dist/chunks/configService-R3OGU2UD.js +0 -13
  385. /package/dist/chunks/{configService-R3OGU2UD.js.map → configService-PRJZF7Y6.js.map} +0 -0
  386. /package/dist/chunks/{constants-STK2YBIW.js.map → constants-KIQEYMAM.js.map} +0 -0
  387. /package/dist/chunks/{fs-JGINUXGL.js.map → fs-ZI5JEU7V.js.map} +0 -0
@@ -2,7 +2,7 @@
2
2
  * Tree path utilities for parsing and navigating tree structure paths
3
3
  */
4
4
 
5
- import { ComponentNode, PageData, JSONPage } from './types';
5
+ import { type ComponentNode, type PageData, JSONPage } from './types';
6
6
  import type { PropDefinition } from './types';
7
7
  import type { Path } from './pathArrayUtils';
8
8
  import { stringToPath } from './pathArrayUtils';
@@ -28,12 +28,12 @@ export interface NodeLocation {
28
28
  */
29
29
  export function validateComponentStructure(pageData: PageData | null): boolean {
30
30
  if (!pageData) return false;
31
-
31
+
32
32
  // Check for page format (has root property)
33
33
  if ('root' in pageData && pageData.root) {
34
34
  return true;
35
35
  }
36
-
36
+
37
37
  // Check for component format (has component.structure property)
38
38
  if ('component' in pageData && pageData.component) {
39
39
  if ('structure' in pageData.component && pageData.component.structure) {
@@ -42,7 +42,7 @@ export function validateComponentStructure(pageData: PageData | null): boolean {
42
42
  // Component exists but structure is missing
43
43
  return false;
44
44
  }
45
-
45
+
46
46
  return false;
47
47
  }
48
48
 
@@ -52,12 +52,12 @@ export function validateComponentStructure(pageData: PageData | null): boolean {
52
52
  */
53
53
  export function getRootData(pageData: PageData | null): ComponentNode | null {
54
54
  if (!pageData) return null;
55
-
55
+
56
56
  // Check for page format (has root property)
57
57
  if ('root' in pageData && pageData.root) {
58
58
  return pageData.root;
59
59
  }
60
-
60
+
61
61
  // Check for component format (has component.structure property)
62
62
  if ('component' in pageData && pageData.component) {
63
63
  if ('structure' in pageData.component) {
@@ -70,7 +70,7 @@ export function getRootData(pageData: PageData | null): ComponentNode | null {
70
70
  // Component exists but structure field is missing
71
71
  }
72
72
  }
73
-
73
+
74
74
  return null;
75
75
  }
76
76
 
@@ -79,10 +79,7 @@ export function getRootData(pageData: PageData | null): ComponentNode | null {
79
79
  * Handles paths like: root_0, root_0_children_0, root_0_children_0_children_1
80
80
  * Also accepts array paths: [0], [0,0], [0,0,1]
81
81
  */
82
- export function getParentAndIndexFromPath(
83
- path: Path | string,
84
- pageData: PageData
85
- ): NodeLocation | null {
82
+ export function getParentAndIndexFromPath(path: Path | string, pageData: PageData): NodeLocation | null {
86
83
  const rootData = getRootData(pageData);
87
84
  if (!rootData) return null;
88
85
 
@@ -94,7 +91,7 @@ export function getParentAndIndexFromPath(
94
91
  return {
95
92
  parent: pageData,
96
93
  index: 0,
97
- node: rootData
94
+ node: rootData,
98
95
  };
99
96
  }
100
97
 
@@ -107,25 +104,25 @@ export function getParentAndIndexFromPath(
107
104
  for (let i = 1; i < pathArray.length; i++) {
108
105
  const childIndex = pathArray[i];
109
106
 
110
- if (!current || !('children' in current) || !Array.isArray(current.children)) {
111
- return null;
112
- }
113
-
114
- if (isNaN(childIndex) || childIndex < 0 || childIndex >= current.children.length) {
115
- return null;
116
- }
107
+ if (!current || !('children' in current) || !Array.isArray(current.children)) {
108
+ return null;
109
+ }
110
+
111
+ if (isNaN(childIndex) || childIndex < 0 || childIndex >= current.children.length) {
112
+ return null;
113
+ }
117
114
 
118
115
  parent = current;
119
- const child = current.children[childIndex];
120
- if (typeof child === 'string') {
121
- return null;
122
- }
123
- current = child;
124
- lastIndex = childIndex;
116
+ const child = current.children[childIndex];
117
+ if (typeof child === 'string') {
118
+ return null;
119
+ }
120
+ current = child;
121
+ lastIndex = childIndex;
125
122
 
126
- // If this is the last navigation step, we found our node
123
+ // If this is the last navigation step, we found our node
127
124
  if (i === pathArray.length - 1) {
128
- return { parent, index: childIndex, node: current };
125
+ return { parent, index: childIndex, node: current };
129
126
  }
130
127
  }
131
128
 
@@ -141,7 +138,9 @@ export function getParentAndIndexFromPath(
141
138
  * Extract structure without styles/props for tree comparison
142
139
  * This allows tree to only regenerate when structure changes, not styles
143
140
  */
144
- export function extractStructureWithoutStyles(node: ComponentNode | string | null | undefined): ComponentNode | string | null | undefined {
141
+ export function extractStructureWithoutStyles(
142
+ node: ComponentNode | string | null | undefined,
143
+ ): ComponentNode | string | null | undefined {
145
144
  if (!node || typeof node === 'string') {
146
145
  return node;
147
146
  }
@@ -157,13 +156,13 @@ export function extractStructureWithoutStyles(node: ComponentNode | string | nul
157
156
  const component = 'component' in node ? (node as any).component : undefined;
158
157
  const ifCondition = 'if' in node ? node.if : undefined;
159
158
  const children = 'children' in node ? node.children : undefined;
160
-
159
+
161
160
  // Recursively process children
162
161
  let processedChildren: ComponentNode | (ComponentNode | string)[] | string | undefined;
163
162
  if (children) {
164
163
  if (Array.isArray(children)) {
165
164
  processedChildren = children.map((child: ComponentNode | string) =>
166
- typeof child === 'string' ? child : extractStructureWithoutStyles(child) as ComponentNode
165
+ typeof child === 'string' ? child : (extractStructureWithoutStyles(child) as ComponentNode),
167
166
  );
168
167
  } else if (typeof children === 'string') {
169
168
  processedChildren = children;
@@ -202,7 +201,7 @@ export function calculateInsertionIndex(
202
201
  linearIndex?: number;
203
202
  },
204
203
  parentChildren: Array<ComponentNode | string>,
205
- nodeDataMap: Map<string, ComponentNode | string>
204
+ nodeDataMap: Map<string, ComponentNode | string>,
206
205
  ): number {
207
206
  if (target.childIndex !== undefined && target.childIndex >= 0) {
208
207
  // Most reliable: use childIndex directly
@@ -250,13 +249,13 @@ export function isValidNodeLocation(location: unknown): location is NodeLocation
250
249
  if (!location || typeof location !== 'object') {
251
250
  return false;
252
251
  }
253
-
252
+
254
253
  // Use proper type narrowing instead of assertion
255
254
  const loc = location as Record<string, unknown>;
256
255
  const hasParent = 'parent' in loc && (loc.parent === null || typeof loc.parent === 'object');
257
256
  const hasIndex = 'index' in loc && typeof loc.index === 'number' && loc.index >= 0;
258
257
  const hasNode = 'node' in loc && (loc.node === null || typeof loc.node === 'object');
259
-
258
+
260
259
  return hasParent && hasIndex && hasNode;
261
260
  }
262
261
 
@@ -267,7 +266,7 @@ export function isValidPath(path: unknown): path is Path {
267
266
  if (!Array.isArray(path)) {
268
267
  return false;
269
268
  }
270
-
269
+
271
270
  // Path is an array of numbers
272
271
  return path.every((item): item is number => typeof item === 'number' && item >= 0);
273
272
  }
@@ -275,28 +274,24 @@ export function isValidPath(path: unknown): path is Path {
275
274
  /**
276
275
  * Type guard to check if parent is PageData
277
276
  */
278
- export function isPageDataParent(
279
- parent: ComponentNode | PageData | null
280
- ): parent is PageData {
277
+ export function isPageDataParent(parent: ComponentNode | PageData | null): parent is PageData {
281
278
  if (!parent) return false;
282
-
279
+
283
280
  // Check for JSONPage format (has root property)
284
281
  if ('root' in parent) return true;
285
-
282
+
286
283
  // Check for component format - component must be an object, not a string
287
284
  if ('component' in parent) {
288
285
  return typeof parent.component === 'object' && parent.component !== null;
289
286
  }
290
-
287
+
291
288
  return false;
292
289
  }
293
290
 
294
291
  /**
295
292
  * Type guard to check if parent is ComponentNode
296
293
  */
297
- export function isComponentNodeParent(
298
- parent: ComponentNode | PageData | null
299
- ): parent is ComponentNode {
294
+ export function isComponentNodeParent(parent: ComponentNode | PageData | null): parent is ComponentNode {
300
295
  if (!parent) return false;
301
296
  // Check for 'type' property (all ComponentNodes have it)
302
297
  // Then check for specific node types that can have children:
@@ -307,28 +302,29 @@ export function isComponentNodeParent(
307
302
  // - EmbedNode: type === 'embed'
308
303
  // - ListNode: type === 'list' (also handles legacy 'cms-list' for migration)
309
304
  const nodeType = (parent as any).type;
310
- return 'type' in parent && (
311
- 'tag' in parent ||
312
- 'component' in parent ||
313
- nodeType === 'slot' ||
314
- nodeType === 'link' ||
315
- nodeType === 'embed' ||
316
- nodeType === 'cms-list' || // Legacy support for migration
317
- nodeType === 'list'
305
+ return (
306
+ 'type' in parent &&
307
+ ('tag' in parent ||
308
+ 'component' in parent ||
309
+ nodeType === 'slot' ||
310
+ nodeType === 'link' ||
311
+ nodeType === 'embed' ||
312
+ nodeType === 'cms-list' || // Legacy support for migration
313
+ nodeType === 'list')
318
314
  );
319
315
  }
320
316
 
321
317
  /**
322
318
  * Get children array from parent (handles both PageData and ComponentNode)
323
319
  */
324
- export function getParentChildren(
325
- parent: ComponentNode | PageData | null
326
- ): Array<ComponentNode | string> | null {
320
+ export function getParentChildren(parent: ComponentNode | PageData | null): Array<ComponentNode | string> | null {
327
321
  if (!parent) return null;
328
-
322
+
329
323
  if (isPageDataParent(parent)) {
330
324
  const rootData = getRootData(parent);
331
- return rootData && 'children' in rootData ? (rootData.children as Array<ComponentNode | string> | undefined) || null : null;
325
+ return rootData && 'children' in rootData
326
+ ? (rootData.children as Array<ComponentNode | string> | undefined) || null
327
+ : null;
332
328
  }
333
329
 
334
330
  if (isComponentNodeParent(parent)) {
@@ -343,10 +339,10 @@ export function getParentChildren(
343
339
  */
344
340
  export function setParentChildren(
345
341
  parent: ComponentNode | PageData | null,
346
- children: Array<ComponentNode | string>
342
+ children: Array<ComponentNode | string>,
347
343
  ): void {
348
344
  if (!parent) return;
349
-
345
+
350
346
  if (isPageDataParent(parent)) {
351
347
  const rootData = getRootData(parent);
352
348
  if (rootData && 'children' in rootData) {
@@ -358,4 +354,3 @@ export function setParentChildren(
358
354
  }
359
355
  }
360
356
  }
361
-
@@ -18,7 +18,7 @@ export interface HMRMessage {
18
18
  | 'hmr:cms-collections-update'
19
19
  | 'hmr:config-update';
20
20
  path?: string;
21
- collection?: string; // For CMS updates
21
+ collection?: string; // For CMS updates
22
22
  }
23
23
 
24
24
  export interface PageListResponse {
@@ -84,4 +84,3 @@ export interface PageMetaData {
84
84
  /** Custom code injected into head/body for this page */
85
85
  customCode?: CustomCodeConfig;
86
86
  }
87
-
@@ -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
@@ -10,12 +10,7 @@
10
10
  */
11
11
 
12
12
  /** Workflow status. No custom statuses for MVP. */
13
- export type CommentStatus =
14
- | 'open'
15
- | 'in-progress'
16
- | 'ready-for-review'
17
- | 'resolved'
18
- | 'closed';
13
+ export type CommentStatus = 'open' | 'in-progress' | 'ready-for-review' | 'resolved' | 'closed';
19
14
 
20
15
  export const COMMENT_STATUSES: readonly CommentStatus[] = [
21
16
  'open',
@@ -47,24 +42,62 @@ export interface CommentNodeIdentity {
47
42
  }
48
43
 
49
44
  /**
50
- * Where the pin attaches on the page. nodePath is positional; nodeIdentity
51
- * is used at render time to detect that the pin has been orphaned (Phase 4).
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".
52
75
  */
53
76
  export interface CommentAnchor {
54
- /** Path array into the page tree, e.g. [0, 1, 2]. */
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). */
55
84
  nodePath: number[];
56
- /** Identity fingerprint for orphan detection. */
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. */
57
92
  nodeIdentity: CommentNodeIdentity;
58
- /** Horizontal offset inside the component's bounding box, 0..1. */
93
+ /** Horizontal position WITHIN the anchored element's rect, 0..1 (default 0.5). */
59
94
  offsetXPercent: number;
60
- /** Vertical offset inside the component's bounding box, 0..1. */
95
+ /** Vertical position WITHIN the anchored element's rect, 0..1 (default 0.5). */
61
96
  offsetYPercent: number;
62
97
  /**
63
98
  * Breakpoint frame this pin was placed on (e.g. `'base'`, `'tablet'`,
64
- * `'mobile'`). Only set for pins created in Design Mode's multi-frame
65
- * canvas, so the pin is only shown on the frame where it was pinned.
66
- * When unset, the pin renders on every frame (single-frame / page mode,
67
- * or pins created before this field existed).
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).
68
101
  */
69
102
  breakpoint?: string;
70
103
  }
@@ -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
-