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
@@ -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 */
@@ -62,14 +62,37 @@ export interface CMSSchema {
62
62
  id: string;
63
63
  /** Display name for the collection */
64
64
  name: string;
65
- /** Which field to use for URL slug */
66
- slugField: string;
67
- /** URL pattern, e.g., "/blog/{{slug}}" */
68
- urlPattern: string;
65
+ /**
66
+ * Backing store for the collection's items. `'cms'` (default/omitted) = file-backed items
67
+ * under `cms/<id>/` (editable in Meno). `'sanity'` = read-only items fetched from a public
68
+ * Sanity dataset at build/SSR (authored in Sanity Studio, never written by Meno); the template
69
+ * page's `getStaticPaths` calls `getSanityData(documentType)` instead of `getCollection`.
70
+ */
71
+ source?: 'cms' | 'sanity';
72
+ /** Sanity document `_type` to fetch (only when `source === 'sanity'`). */
73
+ documentType?: string;
74
+ /**
75
+ * Which field to use for the URL slug. Omitted for a **data-only collection** — one
76
+ * with no per-item route (structured data bound to lists/cards, e.g. Team, Testimonials,
77
+ * Settings). When present, the collection has a template route.
78
+ */
79
+ slugField?: string;
80
+ /**
81
+ * URL pattern, e.g. `"/blog/{{slug}}"`. Omitted for a **data-only collection** (no
82
+ * per-item route is emitted). Its absence is what marks a collection as data-only.
83
+ */
84
+ urlPattern?: string;
69
85
  /** Field definitions */
70
86
  fields: Record<string, CMSFieldDefinition>;
71
87
  /** Client-side data configuration for dynamic filtering */
72
88
  clientData?: CMSClientDataConfig;
89
+ /**
90
+ * Generate an RSS 2.0 feed for this collection at `<route-prefix>/rss.xml`
91
+ * (e.g. a `/blog/{{slug}}` collection → `/blog/rss.xml`). Item title/description/date
92
+ * are auto-detected from the schema fields by convention; the item link uses its
93
+ * synthesized `_url`. Only meaningful for a routed collection (one with a `urlPattern`).
94
+ */
95
+ rss?: boolean;
73
96
  }
74
97
 
75
98
  /**
@@ -156,7 +179,7 @@ export interface CMSRouteMatch {
156
179
  collection: string;
157
180
  slug: string;
158
181
  item: CMSItem;
159
- pagePath: string; // Path to the template page file
182
+ pagePath: string; // Path to the template page file
160
183
  }
161
184
 
162
185
  /** Filter operators for CMS queries */
@@ -165,14 +188,14 @@ export type CMSFilterOperator = 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'co
165
188
  /** Single filter condition */
166
189
  export interface CMSFilterCondition {
167
190
  field: string;
168
- operator?: CMSFilterOperator; // defaults to 'eq'
191
+ operator?: CMSFilterOperator; // defaults to 'eq'
169
192
  value: unknown;
170
193
  }
171
194
 
172
195
  /** Sort configuration */
173
196
  export interface CMSSortConfig {
174
197
  field: string;
175
- order?: 'asc' | 'desc'; // defaults to 'asc'
198
+ order?: 'asc' | 'desc'; // defaults to 'asc'
176
199
  }
177
200
 
178
201
  /** CMSList query configuration */
@@ -286,33 +309,66 @@ const IRREGULAR_PLURALS: Record<string, string> = {
286
309
  };
287
310
 
288
311
  /**
289
- * Convert a collection name to its singular form for use as item variable name.
290
- * Used when itemAs is not explicitly specified.
291
- *
292
- * @example
293
- * singularize('posts') // 'post'
294
- * singularize('categories') // 'category'
295
- * singularize('author') // 'author'
312
+ * Coerce a name into a valid JS identifier for use as a `.map` loop variable / forwarded
313
+ * prop name. Collection names allow `-`, `.` and spaces (e.g. "case-study"), none of which
314
+ * are legal in an identifier — emitted raw they produce `list.map((case-study) => …)`, a
315
+ * SyntaxError. Kebab/space/dot separators camelCase together; a leading digit is prefixed.
316
+ * Already-valid names pass through unchanged (no behavior change for typical collections).
296
317
  */
297
- export function singularize(collection: string): string {
318
+ function toIdentifier(name: string): string {
319
+ if (/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name)) return name;
320
+ const parts = name.split(/[^A-Za-z0-9]+/).filter(Boolean);
321
+ if (parts.length === 0) return 'item';
322
+ const camel =
323
+ parts[0] +
324
+ parts
325
+ .slice(1)
326
+ .map((p) => p[0]!.toUpperCase() + p.slice(1))
327
+ .join('');
328
+ return /^[0-9]/.test(camel) ? `_${camel}` : camel;
329
+ }
330
+
331
+ /** Apply English plural→singular rules (caller-facing identifier sanitization happens in {@link singularize}). */
332
+ function singularizeRaw(collection: string): string {
298
333
  // Check irregular plurals first
299
334
  if (IRREGULAR_PLURALS[collection]) {
300
335
  return IRREGULAR_PLURALS[collection];
301
336
  }
302
337
  // Handle -ies -> -y (e.g., "stories" -> "story")
303
338
  if (collection.endsWith('ies')) {
304
- return collection.slice(0, -3) + 'y';
339
+ return `${collection.slice(0, -3)}y`;
305
340
  }
306
341
  // 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')) {
342
+ if (
343
+ collection.endsWith('ses') ||
344
+ collection.endsWith('xes') ||
345
+ collection.endsWith('zes') ||
346
+ collection.endsWith('ches') ||
347
+ collection.endsWith('shes')
348
+ ) {
310
349
  return collection.slice(0, -2);
311
350
  }
312
351
  // Simple rule: remove trailing 's' if present
313
352
  return collection.endsWith('s') ? collection.slice(0, -1) : collection;
314
353
  }
315
354
 
355
+ /**
356
+ * Convert a collection name to its singular form for use as item variable name.
357
+ * Used when itemAs is not explicitly specified. The result is always a valid JS
358
+ * identifier (the value is emitted as a `.map` loop variable), and a non-string/empty
359
+ * input degrades to the generic `'item'` rather than throwing.
360
+ *
361
+ * @example
362
+ * singularize('posts') // 'post'
363
+ * singularize('categories') // 'category'
364
+ * singularize('author') // 'author'
365
+ * singularize('case-study') // 'caseStudy' (sanitized to a valid identifier)
366
+ */
367
+ export function singularize(collection: string): string {
368
+ if (typeof collection !== 'string' || collection === '') return 'item';
369
+ return toIdentifier(singularizeRaw(collection));
370
+ }
371
+
316
372
  /**
317
373
  * Describes a location where a CMS item is referenced.
318
374
  * Used for delete warnings and reference tracking.
@@ -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
@@ -134,6 +134,14 @@ export interface StructuredComponentDefinition {
134
134
  libraries?: LibrariesConfig;
135
135
  /** Whether instances of this component can have styles applied to the wrapper */
136
136
  acceptsStyles?: boolean;
137
+ /**
138
+ * Verbatim frontmatter passthrough — hand-authored `.astro` frontmatter statements the
139
+ * codec can't model (foreign `import`s, helper `const`/`function`s, `import.meta.env`
140
+ * access, etc.). Captured byte-for-byte on parse and re-emitted unchanged so a component
141
+ * carrying arbitrary frontmatter round-trips. Emit-side it is appended after the
142
+ * generated frontmatter consts. See the dialect spec §10 (escape hatches).
143
+ */
144
+ _frontmatter?: string;
137
145
  }
138
146
 
139
147
  /**
@@ -141,9 +149,9 @@ export interface StructuredComponentDefinition {
141
149
  * Supports both new format (just component) and legacy format (type/props/children/component)
142
150
  */
143
151
  export interface ComponentDefinition {
144
- type?: string; // Legacy format
145
- props?: Record<string, unknown>; // Legacy format
146
- children?: unknown[]; // Legacy format
152
+ type?: string; // Legacy format
153
+ props?: Record<string, unknown>; // Legacy format
154
+ children?: unknown[]; // Legacy format
147
155
  component: StructuredComponentDefinition;
148
156
  }
149
157
 
@@ -163,20 +171,38 @@ export interface JSONPage {
163
171
  components?: Record<string, ComponentDefinition>;
164
172
  root?: ComponentNode;
165
173
  _lineMap?: Record<string, LineRange>;
174
+ /**
175
+ * Verbatim frontmatter passthrough — hand-authored `.astro` frontmatter statements the
176
+ * codec can't model (foreign `import`s, top-level `const`/`function`s, `getStaticPaths`
177
+ * helpers, `import.meta.env` access, etc.). Captured byte-for-byte on parse and re-emitted
178
+ * unchanged so a page carrying arbitrary frontmatter round-trips instead of being flagged
179
+ * read-only. Emit-side it is appended after the generated `const meta`/frontmatter consts.
180
+ * See the dialect spec §10 (escape hatches).
181
+ */
182
+ _frontmatter?: string;
183
+ /**
184
+ * Set when the source file renders under Astro but is outside the meno-astro dialect
185
+ * (can't be modeled into a node tree) — e.g. a hand-authored SSR page with arbitrary
186
+ * frontmatter. The editor shows a read-only info state instead of a (lossy) tree, and the
187
+ * Astro page provider's save() no-ops to protect the hand-authored source from clobber.
188
+ */
189
+ _unsupported?: { reason: string };
166
190
  }
167
191
 
168
192
  /**
169
193
  * Page data type that can be either a JSONPage or a component definition structure
170
194
  */
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
- };
195
+ export type PageData =
196
+ | JSONPage
197
+ | {
198
+ component: {
199
+ structure?: ComponentNode;
200
+ interface?: Record<string, PropDefinition>;
201
+ javascript?: string;
202
+ css?: string;
203
+ acceptsStyles?: boolean;
204
+ };
205
+ };
180
206
 
181
207
  /**
182
208
  * 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 } from './errors';
8
3
 
9
4
  describe('error types', () => {
10
5
  describe('createValidationError', () => {
@@ -27,9 +27,7 @@ export interface TypeSafetyError extends Error {
27
27
  * Result type for operations that can fail
28
28
  * Replaces null returns with explicit success/failure
29
29
  */
30
- export type Result<T> =
31
- | { success: true; data: T }
32
- | { success: false; error: ValidationError };
30
+ export type Result<T> = { success: true; data: T } | { success: false; error: ValidationError };
33
31
 
34
32
  /**
35
33
  * Create a validation error
@@ -40,7 +38,7 @@ export function createValidationError(
40
38
  path?: string;
41
39
  receivedValue?: unknown;
42
40
  expectedType?: string;
43
- }
41
+ },
44
42
  ): ValidationError {
45
43
  return {
46
44
  message,
@@ -57,7 +55,7 @@ export function createTypeSafetyError(
57
55
  path?: string;
58
56
  receivedValue?: unknown;
59
57
  expectedType?: string;
60
- }
58
+ },
61
59
  ): TypeSafetyError {
62
60
  const error = new Error(message) as TypeSafetyError;
63
61
  Object.defineProperty(error, 'path', { value: options?.path, writable: false });
@@ -65,5 +63,3 @@ export function createTypeSafetyError(
65
63
  Object.defineProperty(error, 'expectedType', { value: options?.expectedType, writable: false });
66
64
  return error;
67
65
  }
68
-
69
-
@@ -4,52 +4,52 @@
4
4
  */
5
5
 
6
6
  export interface ConversionGoal {
7
- id: string
8
- name: string
9
- type: 'click' | 'navigation' | 'custom'
7
+ id: string;
8
+ name: string;
9
+ type: 'click' | 'navigation' | 'custom';
10
10
  /** CSS selector for click goals */
11
- selector?: string
11
+ selector?: string;
12
12
  /** URL pattern for navigation goals */
13
- url?: string
13
+ url?: string;
14
14
  /** Custom event name */
15
- event?: string
15
+ event?: string;
16
16
  }
17
17
 
18
18
  export interface ExperimentVariant {
19
- branch: string
19
+ branch: string;
20
20
  /** Percentage of traffic (0-100) */
21
- weight: number
21
+ weight: number;
22
22
  /** Cloudflare Pages preview deploy URL, e.g. "https://variant-blue.project.pages.dev" */
23
- deployUrl: string
23
+ deployUrl: string;
24
24
  }
25
25
 
26
26
  export interface Experiment {
27
- id: string
28
- name: string
29
- status: 'draft' | 'running' | 'paused' | 'completed'
30
- controlBranch: string
31
- variants: ExperimentVariant[]
27
+ id: string;
28
+ name: string;
29
+ status: 'draft' | 'running' | 'paused' | 'completed';
30
+ controlBranch: string;
31
+ variants: ExperimentVariant[];
32
32
  /** Percentage of traffic for control (0-100) */
33
- controlWeight: number
34
- conversionGoals: ConversionGoal[]
35
- createdAt: string
36
- startedAt?: string
37
- endedAt?: string
33
+ controlWeight: number;
34
+ conversionGoals: ConversionGoal[];
35
+ createdAt: string;
36
+ startedAt?: string;
37
+ endedAt?: string;
38
38
  }
39
39
 
40
40
  export interface ExperimentResults {
41
- experimentId: string
42
- variants: VariantResult[]
41
+ experimentId: string;
42
+ variants: VariantResult[];
43
43
  }
44
44
 
45
45
  export interface VariantResult {
46
- variant: string
47
- visitors: number
48
- conversions: number
49
- conversionRate: number
46
+ variant: string;
47
+ visitors: number;
48
+ conversions: number;
49
+ conversionRate: number;
50
50
  /** Lift percentage compared to control */
51
- lift?: number
51
+ lift?: number;
52
52
  /** p-value from z-test */
53
- pValue?: number
54
- isSignificant: boolean
53
+ pValue?: number;
54
+ isSignificant: boolean;
55
55
  }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Shared TypeScript types and interfaces
3
3
  * Used by both client and server code
4
- *
4
+ *
5
5
  * This is the main entry point for all shared types.
6
6
  * Types are organized into separate files for better maintainability.
7
7
  */
@@ -60,6 +60,9 @@ export type {
60
60
  RouteHandler,
61
61
  PageMetaData,
62
62
  PageCmsConfig,
63
+ PageDataConfig,
64
+ PageDataSource,
65
+ DataFieldType,
63
66
  CustomCodeConfig,
64
67
  } from './api';
65
68
 
@@ -178,6 +181,7 @@ export type {
178
181
  CommentStatus,
179
182
  CommentAuthor,
180
183
  CommentNodeIdentity,
184
+ CommentNodeRefSegment,
181
185
  CommentAnchor,
182
186
  CommentThreadEntry,
183
187
  Comment,
@@ -185,5 +189,24 @@ export type {
185
189
 
186
190
  export { COMMENT_STATUSES } from './comment';
187
191
 
188
- // Note: Path types are exported from ../paths/index.ts, not from here
192
+ // Permission types
193
+ export type {
194
+ PermissionRole,
195
+ ResourceKind,
196
+ ConfigArea,
197
+ ResourceRef,
198
+ PermissionRule,
199
+ PermissionGrant,
200
+ PermissionsPolicy,
201
+ PermissionIdentity,
202
+ ResolvedPermissions,
203
+ } from './permissions';
189
204
 
205
+ export {
206
+ PERMISSION_ROLES,
207
+ RESOURCE_KINDS,
208
+ CONFIG_AREAS,
209
+ CURRENT_PERMISSIONS_VERSION,
210
+ } from './permissions';
211
+
212
+ // Note: Path types are exported from ../paths/index.ts, not from here