fimo 0.7.0-experimental.3 → 0.7.0-experimental.4

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 (389) hide show
  1. package/README.md +2 -3
  2. package/assets/content-templates/hooks-template.eta +27 -73
  3. package/assets/content-templates/types-template.eta +1 -4
  4. package/assets/skills/fimo/SKILL.md +3 -3
  5. package/assets/skills/fimo/references/assets.md +2 -2
  6. package/assets/skills/fimo/references/content.md +43 -47
  7. package/assets/skills/fimo/references/design.md +1 -1
  8. package/assets/skills/fimo/references/locales.md +0 -8
  9. package/assets/skills/fimo/references/setup-react-router.md +2 -2
  10. package/assets/skills/fimo/references/ui.md +1 -1
  11. package/assets/skills/fimo-cli/SKILL.md +1 -1
  12. package/assets/skills/fimo-cli/references/assets.md +24 -7
  13. package/assets/skills/fimo-cli/references/content.md +16 -19
  14. package/assets/skills/fimo-cli/references/domains.md +1 -1
  15. package/assets/skills/fimo-cli/references/locales.md +0 -6
  16. package/assets/skills/fimo-cli/references/media.md +142 -132
  17. package/assets/skills/fimo-migration/SKILL.md +22 -2
  18. package/assets/skills/fimo-migration/references/content.md +8 -0
  19. package/assets/skills/fimo-migration/references/manifest.md +35 -0
  20. package/assets/skills/fimo-migration/references/qa.md +24 -2
  21. package/assets/skills/fimo-migration/references/workflow.md +12 -1
  22. package/assets/skills/fimo-migration/references/wrap.md +582 -0
  23. package/assets/skills/fimo-studio/references/custom-domains.md +1 -1
  24. package/assets/skills/fimo-studio/references/visual-editing.md +5 -3
  25. package/dist/build/vite/index.d.ts.map +1 -0
  26. package/dist/build/vite/plugins/content-sync.d.ts.map +1 -0
  27. package/dist/build/vite/plugins/content-sync.test.d.ts +2 -0
  28. package/dist/build/vite/plugins/content-sync.test.d.ts.map +1 -0
  29. package/dist/build/vite/plugins/content-sync.test.js +64 -0
  30. package/dist/build/vite/plugins/data-id.d.ts.map +1 -0
  31. package/dist/build/vite/plugins/fimo-config.d.ts.map +1 -0
  32. package/dist/build/vite/plugins/fimo-config.test.d.ts +2 -0
  33. package/dist/build/vite/plugins/fimo-config.test.d.ts.map +1 -0
  34. package/dist/build/vite/plugins/fimo-config.test.js +46 -0
  35. package/dist/build/vite/plugins/overlay.d.ts.map +1 -0
  36. package/dist/build/vite/plugins/robots.d.ts.map +1 -0
  37. package/dist/build/vite/plugins/seo.d.ts.map +1 -0
  38. package/dist/build/vite/plugins/server-config.d.ts.map +1 -0
  39. package/dist/build/vite/plugins/sitemap.d.ts.map +1 -0
  40. package/dist/build/vite/plugins/translations.d.ts +2 -8
  41. package/dist/build/vite/plugins/translations.d.ts.map +1 -0
  42. package/dist/build/vite/plugins/translations.js +3 -121
  43. package/dist/build/vite/plugins/translations.test.d.ts +2 -0
  44. package/dist/build/vite/plugins/translations.test.d.ts.map +1 -0
  45. package/dist/build/vite/plugins/translations.test.js +266 -0
  46. package/dist/cli/bundle.json +2 -3
  47. package/dist/cli/index.js +117939 -1186
  48. package/dist/runtime/app/FimoProviders.d.ts +1 -11
  49. package/dist/runtime/app/FimoProviders.d.ts.map +1 -0
  50. package/dist/runtime/app/FimoProviders.js +2 -23
  51. package/dist/runtime/app/FimoScripts.d.ts.map +1 -0
  52. package/dist/runtime/app/index.d.ts.map +1 -0
  53. package/dist/runtime/app/prefetch.d.ts.map +1 -0
  54. package/dist/runtime/astro/index.d.ts +2 -0
  55. package/dist/runtime/astro/index.d.ts.map +1 -0
  56. package/dist/runtime/astro/index.js +3 -0
  57. package/dist/runtime/astro/server.d.ts +3 -0
  58. package/dist/runtime/astro/server.d.ts.map +1 -0
  59. package/dist/runtime/astro/server.js +6 -0
  60. package/dist/runtime/content/DataSourcesProvider.d.ts.map +1 -0
  61. package/dist/runtime/content/RefreshContentProvider.d.ts.map +1 -0
  62. package/dist/runtime/content/RefreshContentProvider.test.d.ts +2 -0
  63. package/dist/runtime/content/RefreshContentProvider.test.d.ts.map +1 -0
  64. package/dist/runtime/content/RefreshContentProvider.test.js +33 -0
  65. package/dist/runtime/content/parseCollectionResponse.d.ts.map +1 -0
  66. package/dist/runtime/content/parseCollectionResponse.test.d.ts +2 -0
  67. package/dist/runtime/content/parseCollectionResponse.test.d.ts.map +1 -0
  68. package/dist/runtime/content/parseCollectionResponse.test.js +20 -0
  69. package/dist/runtime/content/utils/retrieve-data-sources.d.ts +0 -1
  70. package/dist/runtime/content/utils/retrieve-data-sources.d.ts.map +1 -0
  71. package/dist/runtime/content/utils/retrieve-data-sources.js +4 -27
  72. package/dist/runtime/core/AppErrorBoundary.d.ts.map +1 -0
  73. package/dist/runtime/core/ViteLifecycles.d.ts.map +1 -0
  74. package/dist/runtime/i18n/FimoLocaleContext.d.ts.map +1 -0
  75. package/dist/runtime/i18n/FimoLocaleContext.js +1 -0
  76. package/dist/runtime/i18n/locale.d.ts.map +1 -0
  77. package/dist/runtime/i18n/locale.test.d.ts +2 -0
  78. package/dist/runtime/i18n/locale.test.d.ts.map +1 -0
  79. package/dist/runtime/i18n/locale.test.js +58 -0
  80. package/dist/runtime/iframe/ConsoleErrorProvider.d.ts.map +1 -0
  81. package/dist/runtime/iframe/ScreenshotProvider.d.ts.map +1 -0
  82. package/dist/runtime/iframe/runtime/overlay-hmr.d.ts.map +1 -0
  83. package/dist/runtime/iframe/runtime/overlay-hmr.js +0 -3
  84. package/dist/runtime/iframe/runtime/overlay-runtime.d.ts.map +1 -0
  85. package/dist/runtime/index.d.ts +0 -3
  86. package/dist/runtime/index.d.ts.map +1 -0
  87. package/dist/runtime/index.js +0 -2
  88. package/dist/runtime/next/FimoNextProviders.d.ts +24 -0
  89. package/dist/runtime/next/FimoNextProviders.d.ts.map +1 -0
  90. package/dist/runtime/next/FimoNextProviders.js +20 -0
  91. package/dist/runtime/next/FimoNextScripts.d.ts +10 -0
  92. package/dist/runtime/next/FimoNextScripts.d.ts.map +1 -0
  93. package/dist/runtime/next/FimoNextScripts.js +19 -0
  94. package/dist/runtime/next/index.d.ts +14 -0
  95. package/dist/runtime/next/index.d.ts.map +1 -0
  96. package/dist/runtime/next/index.js +14 -0
  97. package/dist/runtime/next/server.d.ts +2 -0
  98. package/dist/runtime/next/server.d.ts.map +1 -0
  99. package/dist/runtime/next/server.js +4 -0
  100. package/dist/runtime/nuxt/composables.d.ts +9 -0
  101. package/dist/runtime/nuxt/composables.d.ts.map +1 -0
  102. package/dist/runtime/nuxt/composables.js +57 -0
  103. package/dist/runtime/nuxt/index.d.ts +3 -0
  104. package/dist/runtime/nuxt/index.d.ts.map +1 -0
  105. package/dist/runtime/nuxt/index.js +6 -0
  106. package/dist/runtime/nuxt/server.d.ts +3 -0
  107. package/dist/runtime/nuxt/server.d.ts.map +1 -0
  108. package/dist/runtime/nuxt/server.js +6 -0
  109. package/dist/runtime/paths/get-fimo-paths.d.ts.map +1 -0
  110. package/dist/runtime/paths/get-fimo-paths.js +5 -15
  111. package/dist/runtime/paths/index.d.ts.map +1 -0
  112. package/dist/runtime/paths/types.d.ts.map +1 -0
  113. package/dist/runtime/primitives/components/Boolean.d.ts.map +1 -0
  114. package/dist/runtime/primitives/components/Date.d.ts.map +1 -0
  115. package/dist/runtime/primitives/components/Image.d.ts.map +1 -0
  116. package/dist/runtime/primitives/components/RichText.d.ts.map +1 -0
  117. package/dist/runtime/primitives/components/StaticImage.d.ts.map +1 -0
  118. package/dist/runtime/primitives/components/Text.d.ts.map +1 -0
  119. package/dist/runtime/primitives/components/Video.d.ts.map +1 -0
  120. package/dist/runtime/primitives/components/index.d.ts.map +1 -0
  121. package/dist/runtime/primitives/index.d.ts.map +1 -0
  122. package/dist/runtime/primitives/labels-hook.d.ts +33 -0
  123. package/dist/runtime/primitives/labels-hook.d.ts.map +1 -0
  124. package/dist/runtime/primitives/labels-hook.js +41 -0
  125. package/dist/runtime/primitives/labels-store.d.ts +12 -0
  126. package/dist/runtime/primitives/labels-store.d.ts.map +1 -0
  127. package/dist/runtime/primitives/labels-store.js +60 -0
  128. package/dist/runtime/primitives/labels-store.test.d.ts +2 -0
  129. package/dist/runtime/primitives/labels-store.test.d.ts.map +1 -0
  130. package/dist/runtime/primitives/labels-store.test.js +66 -0
  131. package/dist/runtime/primitives/lib/image-optimization.d.ts.map +1 -0
  132. package/dist/runtime/primitives/lib/index.d.ts.map +1 -0
  133. package/dist/runtime/primitives/lib/primitives.d.ts +2 -2
  134. package/dist/runtime/primitives/lib/primitives.d.ts.map +1 -0
  135. package/dist/runtime/primitives/lib/query.d.ts +3 -5
  136. package/dist/runtime/primitives/lib/query.d.ts.map +1 -0
  137. package/dist/runtime/primitives/lib/template.d.ts.map +1 -0
  138. package/dist/runtime/primitives/lib/useFimoLiveValue.d.ts +5 -3
  139. package/dist/runtime/primitives/lib/useFimoLiveValue.d.ts.map +1 -0
  140. package/dist/runtime/primitives/lib/useFimoLiveValue.js +11 -4
  141. package/dist/runtime/primitives/public-surface.test.d.ts +2 -0
  142. package/dist/runtime/primitives/public-surface.test.d.ts.map +1 -0
  143. package/dist/runtime/primitives/public-surface.test.js +45 -0
  144. package/dist/runtime/primitives/translations.d.ts +1 -27
  145. package/dist/runtime/primitives/translations.d.ts.map +1 -0
  146. package/dist/runtime/primitives/translations.js +7 -85
  147. package/dist/runtime/react/FimoSpaProviders.d.ts +36 -0
  148. package/dist/runtime/react/FimoSpaProviders.d.ts.map +1 -0
  149. package/dist/runtime/react/FimoSpaProviders.js +63 -0
  150. package/dist/runtime/react/index.d.ts +33 -0
  151. package/dist/runtime/react/index.d.ts.map +1 -0
  152. package/dist/runtime/react/index.js +39 -0
  153. package/dist/runtime/react-router/index.d.ts.map +1 -0
  154. package/dist/runtime/react-router/navigation-utils.d.ts.map +1 -0
  155. package/dist/runtime/react-router/navigation.d.ts.map +1 -0
  156. package/dist/runtime/react-router/navigation.test.d.ts +2 -0
  157. package/dist/runtime/react-router/navigation.test.d.ts.map +1 -0
  158. package/dist/runtime/react-router/navigation.test.js +35 -0
  159. package/dist/runtime/react-router/routes.d.ts.map +1 -0
  160. package/dist/runtime/react-router/routes.test.d.ts +2 -0
  161. package/dist/runtime/react-router/routes.test.d.ts.map +1 -0
  162. package/dist/runtime/react-router/routes.test.js +67 -0
  163. package/dist/runtime/remix/FimoRemixProviders.d.ts +16 -0
  164. package/dist/runtime/remix/FimoRemixProviders.d.ts.map +1 -0
  165. package/dist/runtime/remix/FimoRemixProviders.js +12 -0
  166. package/dist/runtime/remix/FimoRemixScripts.d.ts +10 -0
  167. package/dist/runtime/remix/FimoRemixScripts.d.ts.map +1 -0
  168. package/dist/runtime/remix/FimoRemixScripts.js +19 -0
  169. package/dist/runtime/remix/index.d.ts +12 -0
  170. package/dist/runtime/remix/index.d.ts.map +1 -0
  171. package/dist/runtime/remix/index.js +11 -0
  172. package/dist/runtime/remix/server.d.ts +2 -0
  173. package/dist/runtime/remix/server.d.ts.map +1 -0
  174. package/dist/runtime/remix/server.js +2 -0
  175. package/dist/runtime/routing/AppResetScrollOnNavigate.d.ts.map +1 -0
  176. package/dist/runtime/routing/AppRoutesProvider.d.ts.map +1 -0
  177. package/dist/runtime/seo/buildSeoForPath.d.ts +3 -1
  178. package/dist/runtime/seo/buildSeoForPath.d.ts.map +1 -0
  179. package/dist/runtime/seo/buildSeoForPath.js +1 -4
  180. package/dist/runtime/seo/htmlProps.d.ts.map +1 -0
  181. package/dist/runtime/seo/index.d.ts.map +1 -0
  182. package/dist/runtime/seo/resolver.d.ts.map +1 -0
  183. package/dist/runtime/shared/display-routes.d.ts +14 -0
  184. package/dist/runtime/shared/display-routes.d.ts.map +1 -0
  185. package/dist/runtime/shared/display-routes.js +25 -0
  186. package/dist/runtime/shared/fimo-config.server.d.ts.map +1 -0
  187. package/dist/runtime/shared/fimo-config.server.js +1 -0
  188. package/dist/runtime/shared/fimo-config.types.d.ts +2 -0
  189. package/dist/runtime/shared/fimo-config.types.d.ts.map +1 -0
  190. package/dist/runtime/shared/i18n-messages.d.ts +29 -0
  191. package/dist/runtime/shared/i18n-messages.d.ts.map +1 -0
  192. package/dist/runtime/shared/i18n-messages.js +79 -0
  193. package/dist/runtime/shared/i18n-messages.test.d.ts +2 -0
  194. package/dist/runtime/shared/i18n-messages.test.d.ts.map +1 -0
  195. package/dist/runtime/shared/i18n-messages.test.js +39 -0
  196. package/dist/runtime/shared/labels-fetch.pure.d.ts +17 -0
  197. package/dist/runtime/shared/labels-fetch.pure.d.ts.map +1 -0
  198. package/dist/runtime/shared/labels-fetch.pure.js +71 -0
  199. package/dist/runtime/shared/labels-fetch.server.d.ts +7 -0
  200. package/dist/runtime/shared/labels-fetch.server.d.ts.map +1 -0
  201. package/dist/runtime/shared/labels-fetch.server.js +97 -0
  202. package/dist/runtime/shared/labels-t.pure.d.ts +2 -0
  203. package/dist/runtime/shared/labels-t.pure.d.ts.map +1 -0
  204. package/dist/runtime/shared/labels-t.pure.js +10 -0
  205. package/dist/runtime/svelte/index.d.ts +3 -0
  206. package/dist/runtime/svelte/index.d.ts.map +1 -0
  207. package/dist/runtime/svelte/index.js +7 -0
  208. package/dist/runtime/svelte/server.d.ts +3 -0
  209. package/dist/runtime/svelte/server.d.ts.map +1 -0
  210. package/dist/runtime/svelte/server.js +6 -0
  211. package/dist/runtime/t/OptionalTracking.d.ts.map +1 -0
  212. package/dist/runtime/t/OptionalTracking.test.d.ts +2 -0
  213. package/dist/runtime/t/OptionalTracking.test.d.ts.map +1 -0
  214. package/dist/runtime/t/OptionalTracking.test.js +11 -0
  215. package/dist/runtime/t/Pageview.d.ts.map +1 -0
  216. package/dist/runtime/templates.d.ts.map +1 -0
  217. package/dist/runtime/vue/index.d.ts +3 -0
  218. package/dist/runtime/vue/index.d.ts.map +1 -0
  219. package/dist/runtime/vue/index.js +5 -0
  220. package/dist/runtime/vue/server.d.ts +3 -0
  221. package/dist/runtime/vue/server.d.ts.map +1 -0
  222. package/dist/runtime/vue/server.js +6 -0
  223. package/dist/runtime/wrapped/FimoFileLink.d.ts +17 -0
  224. package/dist/runtime/wrapped/FimoFileLink.d.ts.map +1 -0
  225. package/dist/runtime/wrapped/FimoFileLink.js +19 -0
  226. package/dist/runtime/wrapped/FimoMediaImage.d.ts +14 -0
  227. package/dist/runtime/wrapped/FimoMediaImage.d.ts.map +1 -0
  228. package/dist/runtime/wrapped/FimoMediaImage.js +20 -0
  229. package/dist/runtime/wrapped/FimoMediaVideo.d.ts +14 -0
  230. package/dist/runtime/wrapped/FimoMediaVideo.d.ts.map +1 -0
  231. package/dist/runtime/wrapped/FimoMediaVideo.js +20 -0
  232. package/dist/runtime/wrapped/FimoRichTextBlock.d.ts +23 -0
  233. package/dist/runtime/wrapped/FimoRichTextBlock.d.ts.map +1 -0
  234. package/dist/runtime/wrapped/FimoRichTextBlock.js +22 -0
  235. package/dist/runtime/wrapped/FimoText.d.ts +22 -0
  236. package/dist/runtime/wrapped/FimoText.d.ts.map +1 -0
  237. package/dist/runtime/wrapped/FimoText.js +20 -0
  238. package/dist/runtime/wrapped/WrappedContentContext.d.ts +28 -0
  239. package/dist/runtime/wrapped/WrappedContentContext.d.ts.map +1 -0
  240. package/dist/runtime/wrapped/WrappedContentContext.js +30 -0
  241. package/dist/runtime/wrapped/WrappedProviders.d.ts +33 -0
  242. package/dist/runtime/wrapped/WrappedProviders.d.ts.map +1 -0
  243. package/dist/runtime/wrapped/WrappedProviders.js +101 -0
  244. package/dist/runtime/wrapped/dom.d.ts +4 -0
  245. package/dist/runtime/wrapped/dom.d.ts.map +1 -0
  246. package/dist/runtime/wrapped/dom.js +23 -0
  247. package/dist/runtime/wrapped/dom.test.d.ts +2 -0
  248. package/dist/runtime/wrapped/dom.test.d.ts.map +1 -0
  249. package/dist/runtime/wrapped/dom.test.js +16 -0
  250. package/dist/runtime/wrapped/server.d.ts +77 -0
  251. package/dist/runtime/wrapped/server.d.ts.map +1 -0
  252. package/dist/runtime/wrapped/server.js +237 -0
  253. package/dist/runtime/wrapped/server.test.d.ts +2 -0
  254. package/dist/runtime/wrapped/server.test.d.ts.map +1 -0
  255. package/dist/runtime/wrapped/server.test.js +91 -0
  256. package/dist/scripts/apply-wrap-templates.d.ts +61 -0
  257. package/dist/scripts/apply-wrap-templates.js +132 -0
  258. package/dist/scripts/apply-wrap-templates.test.js +199 -0
  259. package/dist/scripts/apply-wrap.d.ts +46 -0
  260. package/dist/scripts/apply-wrap.js +278 -0
  261. package/dist/scripts/apply-wrap.test.d.ts +1 -0
  262. package/dist/scripts/apply-wrap.test.js +226 -0
  263. package/dist/scripts/cms/discover.d.ts +2 -0
  264. package/dist/scripts/cms/discover.js +17 -0
  265. package/dist/scripts/cms/example-content.d.ts +32 -0
  266. package/dist/scripts/cms/example-content.js +87 -0
  267. package/dist/scripts/cms/example-content.test.d.ts +1 -0
  268. package/dist/scripts/cms/example-content.test.js +57 -0
  269. package/dist/scripts/cms/strapi/detect.d.ts +2 -0
  270. package/dist/scripts/cms/strapi/detect.js +185 -0
  271. package/dist/scripts/cms/strapi/detect.test.d.ts +1 -0
  272. package/dist/scripts/cms/strapi/detect.test.js +56 -0
  273. package/dist/scripts/cms/strapi/index.d.ts +3 -0
  274. package/dist/scripts/cms/strapi/index.js +15 -0
  275. package/dist/scripts/cms/strapi/list-source.d.ts +17 -0
  276. package/dist/scripts/cms/strapi/list-source.js +90 -0
  277. package/dist/scripts/cms/strapi/list-source.test.d.ts +1 -0
  278. package/dist/scripts/cms/strapi/list-source.test.js +33 -0
  279. package/dist/scripts/cms/strapi/schema-map.d.ts +9 -0
  280. package/dist/scripts/cms/strapi/schema-map.js +138 -0
  281. package/dist/scripts/cms/strapi/schema-map.test.d.ts +1 -0
  282. package/dist/scripts/cms/strapi/schema-map.test.js +87 -0
  283. package/dist/scripts/cms/types.d.ts +76 -0
  284. package/dist/scripts/cms/types.js +11 -0
  285. package/dist/scripts/detect-framework.d.ts +39 -0
  286. package/dist/scripts/detect-framework.js +133 -0
  287. package/dist/scripts/detect-framework.test.d.ts +1 -0
  288. package/dist/scripts/detect-framework.test.js +122 -0
  289. package/dist/scripts/draft-rows.d.ts +19 -0
  290. package/dist/scripts/draft-rows.js +135 -0
  291. package/dist/scripts/draft-rows.test.d.ts +1 -0
  292. package/dist/scripts/draft-rows.test.js +113 -0
  293. package/dist/scripts/draft-schemas.d.ts +27 -0
  294. package/dist/scripts/draft-schemas.js +188 -0
  295. package/dist/scripts/draft-schemas.test.d.ts +1 -0
  296. package/dist/scripts/draft-schemas.test.js +152 -0
  297. package/dist/scripts/frameworks/astro/routes.d.ts +3 -0
  298. package/dist/scripts/frameworks/astro/routes.js +55 -0
  299. package/dist/scripts/frameworks/astro/template-style.d.ts +7 -0
  300. package/dist/scripts/frameworks/astro/template-style.js +19 -0
  301. package/dist/scripts/frameworks/discover.d.ts +70 -0
  302. package/dist/scripts/frameworks/discover.js +171 -0
  303. package/dist/scripts/frameworks/next/rewire.d.ts +30 -0
  304. package/dist/scripts/frameworks/next/rewire.js +258 -0
  305. package/dist/scripts/frameworks/next/rewire.test.d.ts +1 -0
  306. package/dist/scripts/frameworks/next/rewire.test.js +134 -0
  307. package/dist/scripts/frameworks/next/routes.d.ts +17 -0
  308. package/dist/scripts/frameworks/next/routes.js +134 -0
  309. package/dist/scripts/frameworks/next/routes.test.d.ts +1 -0
  310. package/dist/scripts/frameworks/next/routes.test.js +64 -0
  311. package/dist/scripts/frameworks/next/wiring.d.ts +26 -0
  312. package/dist/scripts/frameworks/next/wiring.js +163 -0
  313. package/dist/scripts/frameworks/next/wiring.test.d.ts +1 -0
  314. package/dist/scripts/frameworks/next/wiring.test.js +146 -0
  315. package/dist/scripts/frameworks/nuxt/routes.d.ts +3 -0
  316. package/dist/scripts/frameworks/nuxt/routes.js +54 -0
  317. package/dist/scripts/frameworks/nuxt/template-style.d.ts +9 -0
  318. package/dist/scripts/frameworks/nuxt/template-style.js +27 -0
  319. package/dist/scripts/frameworks/remix/routes.d.ts +3 -0
  320. package/dist/scripts/frameworks/remix/routes.js +50 -0
  321. package/dist/scripts/frameworks/sveltekit/routes.d.ts +3 -0
  322. package/dist/scripts/frameworks/sveltekit/routes.js +50 -0
  323. package/dist/scripts/frameworks/sveltekit/template-style.d.ts +9 -0
  324. package/dist/scripts/frameworks/sveltekit/template-style.js +54 -0
  325. package/dist/scripts/frameworks/vite/routes.d.ts +15 -0
  326. package/dist/scripts/frameworks/vite/routes.js +93 -0
  327. package/dist/scripts/frameworks/vite/routes.test.d.ts +1 -0
  328. package/dist/scripts/frameworks/vite/routes.test.js +73 -0
  329. package/dist/scripts/frameworks/vite/wiring.d.ts +10 -0
  330. package/dist/scripts/frameworks/vite/wiring.js +99 -0
  331. package/dist/scripts/frameworks/vite/wiring.test.d.ts +1 -0
  332. package/dist/scripts/frameworks/vite/wiring.test.js +88 -0
  333. package/dist/scripts/generated-types.test.d.ts +1 -0
  334. package/dist/scripts/generated-types.test.js +212 -0
  335. package/dist/scripts/lib/validation-report.d.ts +1 -0
  336. package/dist/scripts/lib/validation-report.js +3 -0
  337. package/dist/scripts/lint-translation-keys.test.d.ts +1 -0
  338. package/dist/scripts/lint-translation-keys.test.js +16 -0
  339. package/dist/scripts/render-parity/capture.d.ts +56 -0
  340. package/dist/scripts/render-parity/capture.js +366 -0
  341. package/dist/scripts/render-parity/capture.test.d.ts +1 -0
  342. package/dist/scripts/render-parity/capture.test.js +306 -0
  343. package/dist/scripts/render-parity/compare.d.ts +59 -0
  344. package/dist/scripts/render-parity/compare.js +0 -0
  345. package/dist/scripts/render-parity/compare.test.d.ts +1 -0
  346. package/dist/scripts/render-parity/compare.test.js +98 -0
  347. package/dist/scripts/render-parity/normalize-html.d.ts +13 -0
  348. package/dist/scripts/render-parity/normalize-html.js +223 -0
  349. package/dist/scripts/render-parity/normalize-html.test.d.ts +1 -0
  350. package/dist/scripts/render-parity/normalize-html.test.js +58 -0
  351. package/dist/scripts/render-parity/types.d.ts +41 -0
  352. package/dist/scripts/render-parity/types.js +1 -0
  353. package/dist/scripts/resolve-routes.js +1 -1
  354. package/dist/scripts/scan-wrappable.d.ts +196 -0
  355. package/dist/scripts/scan-wrappable.js +1221 -0
  356. package/dist/scripts/scan-wrappable.test.d.ts +1 -0
  357. package/dist/scripts/scan-wrappable.test.js +502 -0
  358. package/dist/scripts/sync-schemas.test.d.ts +1 -0
  359. package/dist/scripts/sync-schemas.test.js +124 -0
  360. package/dist/scripts/validate-route-metadata.js +11 -0
  361. package/dist/scripts/validate-route-metadata.test.d.ts +1 -0
  362. package/dist/scripts/validate-route-metadata.test.js +116 -0
  363. package/dist/scripts/validate-schemas.test.d.ts +1 -0
  364. package/dist/scripts/validate-schemas.test.js +263 -0
  365. package/package.json +85 -20
  366. package/scripts/add-ext.mjs +47 -0
  367. package/scripts/bump-version.mjs +58 -0
  368. package/scripts/bundle-cli.mjs +123 -0
  369. package/scripts/install-cli.mjs +36 -0
  370. package/scripts/lib/channels.mjs +70 -0
  371. package/scripts/lib/dev-release-state.mjs +44 -0
  372. package/scripts/lib/dev-release-state.test.ts +36 -0
  373. package/scripts/lib/postinstall-onboarding.test.ts +82 -0
  374. package/scripts/lib/release-core.mjs +225 -0
  375. package/scripts/lib/release-core.test.ts +147 -0
  376. package/scripts/migration-qa-gate.test.ts +155 -0
  377. package/scripts/publish-npm.mjs +180 -0
  378. package/templates/react-router/package.json +7 -10
  379. package/templates/react-router/src/pages/Index.tsx +1 -1
  380. package/dist/runtime/content/client/createContentClient.d.ts +0 -5
  381. package/dist/runtime/content/client/createContentClient.js +0 -300
  382. package/dist/runtime/content/client/createSingletonClient.d.ts +0 -5
  383. package/dist/runtime/content/client/createSingletonClient.js +0 -108
  384. package/dist/runtime/content/client/internal.d.ts +0 -44
  385. package/dist/runtime/content/client/internal.js +0 -236
  386. package/dist/runtime/content/client/types.d.ts +0 -136
  387. package/dist/runtime/content/client/useQueryLocale.d.ts +0 -2
  388. package/dist/runtime/content/client/useQueryLocale.js +0 -6
  389. /package/dist/{runtime/content/client/types.js → scripts/apply-wrap-templates.test.d.ts} +0 -0
@@ -12,7 +12,9 @@ For text elements, the side panel shows editable fields where you can change the
12
12
 
13
13
  ### Editing Styles
14
14
 
15
- The side panel organizes style controls into these categories:
15
+ Style controls are only available on projects created before July 2026. Newer projects edit styles through the AI chat instead (for example: "make the hero title larger and dark blue"). If the user does not see the style controls described below, their project is a newer one -- point them to the chat.
16
+
17
+ On projects that have them, the side panel organizes style controls into these categories:
16
18
 
17
19
  - **Typography** -- Font family, font size, font weight, line height, letter spacing, text alignment, and bold/italic/underline/strikethrough toggles.
18
20
  - **Color** -- Text and foreground colors.
@@ -31,5 +33,5 @@ Click the **Edit mode** toggle again or close the side panel. The side editor cl
31
33
 
32
34
  ## When to Use Edit Mode vs. Chat
33
35
 
34
- - **Edit mode** is best for quick visual tweaks -- changing a color, adjusting spacing, updating text, or trying a different font.
35
- - **Chat** is better for bigger changes -- adding new sections, restructuring a page layout, or building new functionality.
36
+ - **Edit mode** is best for content changes -- updating text (including bold, italic, underline, and links), and replacing images. On older projects it also covers quick style tweaks like colors and spacing.
37
+ - **Chat** is better for style and structural changes -- changing colors or spacing (on newer projects), adding new sections, restructuring a page layout, or building new functionality.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/build/vite/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAU,YAAY,EAAE,MAAM,MAAM,CAAC;AAmFjD,MAAM,WAAW,eAAe;IAC9B;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;;;;;;;;OAUG;IACH,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAGD,wBAAgB,IAAI,CAAC,IAAI,GAAE,eAAoB,GAAG,YAAY,EAAE,CAsB/D"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-sync.d.ts","sourceRoot":"","sources":["../../../../src/build/vite/plugins/content-sync.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAC;AAKlD;;;;;;;GAOG;AACH,MAAM,CAAC,OAAO,UAAU,iBAAiB,IAAI,MAAM,CAkClD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=content-sync.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-sync.test.d.ts","sourceRoot":"","sources":["../../../../src/build/vite/plugins/content-sync.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,64 @@
1
+ import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
2
+ import { tmpdir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import { afterEach, describe, expect, it, vi } from 'vitest';
5
+ import contentSyncPlugin from './content-sync';
6
+ let scratch = null;
7
+ const pluginContext = {
8
+ addWatchFile: vi.fn(),
9
+ meta: {},
10
+ error: (error) => {
11
+ throw error;
12
+ },
13
+ info: () => undefined,
14
+ warn: () => undefined,
15
+ debug: () => undefined,
16
+ };
17
+ afterEach(() => {
18
+ if (scratch) {
19
+ rmSync(scratch, { recursive: true, force: true });
20
+ scratch = null;
21
+ }
22
+ vi.clearAllMocks();
23
+ });
24
+ function createProjectRoot() {
25
+ scratch = mkdtempSync(join(tmpdir(), 'fimo-content-sync-plugin-'));
26
+ mkdirSync(join(scratch, 'src/schemas'), { recursive: true });
27
+ return scratch;
28
+ }
29
+ function configurePlugin(plugin, root) {
30
+ if (typeof plugin.configResolved === 'function') {
31
+ plugin.configResolved.call(pluginContext, { root });
32
+ }
33
+ }
34
+ describe('contentSyncPlugin', () => {
35
+ it('does not mutate generated files during a production build', () => {
36
+ const plugin = contentSyncPlugin();
37
+ expect(plugin.buildStart).toBeUndefined();
38
+ expect(plugin.generateBundle).toBeUndefined();
39
+ expect(plugin.writeBundle).toBeUndefined();
40
+ });
41
+ it('regenerates schema clients after a schema changes in dev', () => {
42
+ const root = createProjectRoot();
43
+ const schemaPath = join(root, 'src/schemas/Post.json');
44
+ writeFileSync(schemaPath, JSON.stringify({ uid: 'Post', name: 'Posts', fields: { title: { type: 'string' } } }, null, 2));
45
+ const listeners = new Map();
46
+ const server = {
47
+ watcher: {
48
+ add: vi.fn(),
49
+ on: vi.fn((event, listener) => {
50
+ listeners.set(event, listener);
51
+ }),
52
+ },
53
+ };
54
+ const plugin = contentSyncPlugin();
55
+ configurePlugin(plugin, root);
56
+ if (typeof plugin.configureServer !== 'function') {
57
+ throw new Error('Expected configureServer hook');
58
+ }
59
+ plugin.configureServer.call(pluginContext, server);
60
+ listeners.get('change')?.(schemaPath);
61
+ expect(readFileSync(join(root, 'src/schemas/Post.ts'), 'utf8')).toContain('from "./Post.types";');
62
+ expect(readFileSync(join(root, 'src/schemas/Post.types.ts'), 'utf8')).toContain('export interface Post');
63
+ });
64
+ });
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-id.d.ts","sourceRoot":"","sources":["../../../../src/build/vite/plugins/data-id.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAOnC,MAAM,CAAC,OAAO,UAAU,YAAY,IAAI,MAAM,CA2F7C"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fimo-config.d.ts","sourceRoot":"","sources":["../../../../src/build/vite/plugins/fimo-config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAKnC;;;;;;;;GAQG;AACH,MAAM,CAAC,OAAO,UAAU,gBAAgB,IAAI,MAAM,CA6CjD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=fimo-config.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fimo-config.test.d.ts","sourceRoot":"","sources":["../../../../src/build/vite/plugins/fimo-config.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,46 @@
1
+ import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
2
+ import { tmpdir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import { afterEach, describe, expect, it } from 'vitest';
5
+ import fimoConfigPlugin from './fimo-config';
6
+ let scratch = null;
7
+ const pluginContext = {
8
+ meta: {},
9
+ error: (error) => {
10
+ throw error;
11
+ },
12
+ info: () => undefined,
13
+ warn: () => undefined,
14
+ debug: () => undefined,
15
+ };
16
+ afterEach(() => {
17
+ if (scratch) {
18
+ rmSync(scratch, { recursive: true, force: true });
19
+ scratch = null;
20
+ }
21
+ });
22
+ function createPluginWithConfig(config) {
23
+ scratch = mkdtempSync(join(tmpdir(), 'fimo-config-plugin-'));
24
+ writeFileSync(join(scratch, 'fimo-config.json'), JSON.stringify(config, null, 2));
25
+ const plugin = fimoConfigPlugin();
26
+ if (typeof plugin.config === 'function') {
27
+ plugin.config.call(pluginContext, { root: scratch }, { command: 'build', mode: 'production' });
28
+ }
29
+ return plugin;
30
+ }
31
+ function transformHtml(plugin, html) {
32
+ if (typeof plugin.transformIndexHtml !== 'function') {
33
+ throw new Error('Expected transformIndexHtml function');
34
+ }
35
+ return plugin.transformIndexHtml.call(pluginContext, html, {});
36
+ }
37
+ describe('fimoConfigPlugin', () => {
38
+ it('sets html lang from i18n.defaultLocale', () => {
39
+ const plugin = createPluginWithConfig({ seo: { locale: 'es_ES' }, i18n: { defaultLocale: 'fr' } });
40
+ expect(transformHtml(plugin, '<html><head></head><body></body></html>')).toContain('<html lang="fr">');
41
+ });
42
+ it('falls back to en when i18n.defaultLocale is absent', () => {
43
+ const plugin = createPluginWithConfig({ seo: { locale: 'es_ES' } });
44
+ expect(transformHtml(plugin, '<html lang="fr"><head></head><body></body></html>')).toContain('<html lang="en">');
45
+ });
46
+ });
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../../../../src/build/vite/plugins/overlay.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAoEnC,MAAM,CAAC,OAAO,UAAU,aAAa,IAAI,MAAM,CA+E9C"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"robots.d.ts","sourceRoot":"","sources":["../../../../src/build/vite/plugins/robots.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AA6BnC;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,YAAY,IAAI,MAAM,CAuB7C"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seo.d.ts","sourceRoot":"","sources":["../../../../src/build/vite/plugins/seo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AA2BnC,MAAM,CAAC,OAAO,UAAU,SAAS,IAAI,MAAM,CA2G1C"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-config.d.ts","sourceRoot":"","sources":["../../../../src/build/vite/plugins/server-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,MAAM,CAAC,OAAO,UAAU,kBAAkB,IAAI,MAAM,CAsBnD"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sitemap.d.ts","sourceRoot":"","sources":["../../../../src/build/vite/plugins/sitemap.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAkDnC,MAAM,CAAC,OAAO,UAAU,aAAa,IAAI,MAAM,CA8B9C"}
@@ -1,11 +1,5 @@
1
1
  import type { Plugin } from 'vite';
2
- interface LabelBundle {
3
- dictionaries: Record<string, Record<string, string>>;
4
- defaultLocale: string;
5
- locales: string[];
6
- updatedAt: string | null;
7
- }
2
+ import { loadLabelBundle } from '../../../runtime/shared/labels-fetch.server.js';
8
3
  export default function translationsPlugin(): Plugin;
9
- export declare function loadLabelBundle(rootDir: string): Promise<LabelBundle>;
10
- export {};
4
+ export { loadLabelBundle };
11
5
  //# sourceMappingURL=translations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translations.d.ts","sourceRoot":"","sources":["../../../../src/build/vite/plugins/translations.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAC;AAElD,OAAO,EAIL,eAAe,EAIhB,MAAM,gDAAgD,CAAC;AA2CxD,MAAM,CAAC,OAAO,UAAU,kBAAkB,IAAI,MAAM,CAmOnD;AA4CD,OAAO,EAAE,eAAe,EAAE,CAAC"}
@@ -1,10 +1,8 @@
1
1
  import { createHash } from 'node:crypto';
2
- import { Buffer } from 'node:buffer';
3
2
  import { readFile } from 'node:fs/promises';
4
3
  import { homedir } from 'node:os';
5
4
  import { join } from 'node:path';
6
- import { getFimoDefaultLocale, getFimoLocales } from '../../../runtime/i18n/locale.js';
7
- import { getConfigServer } from '../../../runtime/shared/fimo-config.server.js';
5
+ import { emptyLabelBundle, labelSignature, loadLabelBundle, readProjectEnv, resolveTenantApiUrl, serializeBundle, } from '../../../runtime/shared/labels-fetch.server.js';
8
6
  const VIRTUAL_ID = 'virtual:translations';
9
7
  const RESOLVED_ID = '\0' + VIRTUAL_ID;
10
8
  export default function translationsPlugin() {
@@ -145,7 +143,7 @@ export default function translationsPlugin() {
145
143
  };
146
144
  async function connectLabelEvents(root, onLabelsChanged) {
147
145
  const env = await readProjectEnv(root);
148
- const apiUrl = env.VITE_API_URL;
146
+ const apiUrl = resolveTenantApiUrl(env);
149
147
  if (!apiUrl) {
150
148
  return [];
151
149
  }
@@ -229,24 +227,6 @@ function parseContentChangePayload(payload) {
229
227
  updatedAt: typeof source.updatedAt === 'string' ? source.updatedAt : undefined,
230
228
  };
231
229
  }
232
- function serializeBundle(bundle) {
233
- return JSON.stringify({
234
- dictionaries: bundle.dictionaries,
235
- defaultLocale: bundle.defaultLocale,
236
- locales: bundle.locales,
237
- });
238
- }
239
- function emptyLabelBundle(rootDir) {
240
- const config = getConfigServer(rootDir);
241
- const defaultLocale = getFimoDefaultLocale(config);
242
- const locales = getFimoLocales(config);
243
- return {
244
- dictionaries: Object.fromEntries(locales.map((locale) => [locale, {}])),
245
- defaultLocale,
246
- locales,
247
- updatedAt: null,
248
- };
249
- }
250
230
  function findVirtualTranslationModules(server) {
251
231
  const direct = server.moduleGraph.getModuleById(RESOLVED_ID);
252
232
  const matches = new Set(direct ? [direct] : []);
@@ -257,73 +237,13 @@ function findVirtualTranslationModules(server) {
257
237
  }
258
238
  return [...matches];
259
239
  }
260
- function labelSignature(bundle) {
261
- return Buffer.from(serializeBundle(bundle)).toString('base64');
262
- }
263
240
  function labelUpdatePayload(bundle) {
264
241
  return {
265
242
  ...bundle,
266
243
  signature: labelSignature(bundle),
267
244
  };
268
245
  }
269
- export async function loadLabelBundle(rootDir) {
270
- const config = getConfigServer(rootDir);
271
- const defaultLocale = getFimoDefaultLocale(config);
272
- const locales = getFimoLocales(config);
273
- const env = await readProjectEnv(rootDir);
274
- const apiUrl = env.VITE_API_URL;
275
- if (!apiUrl) {
276
- return {
277
- dictionaries: Object.fromEntries(locales.map((locale) => [locale, {}])),
278
- defaultLocale,
279
- locales,
280
- updatedAt: null,
281
- };
282
- }
283
- try {
284
- const loaded = await Promise.all(locales.map((locale) => fetchLabelDictionary(apiUrl, locale).catch(() => ({ locale, labels: {}, updatedAt: null }))));
285
- const updatedAt = loaded
286
- .map((entry) => entry.updatedAt)
287
- .filter((value) => typeof value === 'string')
288
- .sort()
289
- .at(-1);
290
- return {
291
- dictionaries: Object.fromEntries(loaded.map((entry) => [entry.locale, entry.labels])),
292
- defaultLocale,
293
- locales,
294
- updatedAt: updatedAt ?? null,
295
- };
296
- }
297
- catch {
298
- return {
299
- dictionaries: Object.fromEntries(locales.map((locale) => [locale, {}])),
300
- defaultLocale,
301
- locales,
302
- updatedAt: null,
303
- };
304
- }
305
- }
306
- async function fetchLabelDictionary(apiUrl, locale) {
307
- const url = new URL('/labels', apiUrl);
308
- url.searchParams.set('locale', locale);
309
- const response = await fetchWithTimeout(url, 4000);
310
- if (!response.ok) {
311
- return { locale, labels: {}, updatedAt: null };
312
- }
313
- const body = (await response.json());
314
- if (Array.isArray(body.data)) {
315
- return {
316
- locale,
317
- labels: Object.fromEntries(body.data.map((row) => [row.key, row.value ?? row.defaultValue ?? ''])),
318
- updatedAt: null,
319
- };
320
- }
321
- return {
322
- locale,
323
- labels: body.data?.labels ?? {},
324
- updatedAt: body.data?.updatedAt ?? null,
325
- };
326
- }
246
+ export { loadLabelBundle };
327
247
  async function loadRuntimeConfig(apiUrl) {
328
248
  try {
329
249
  const response = await fetchWithTimeout(new URL('/runtime-config', apiUrl), 2000);
@@ -358,44 +278,6 @@ async function fetchWithTimeout(url, timeoutMs) {
358
278
  clearTimeout(timeout);
359
279
  }
360
280
  }
361
- async function readProjectEnv(rootDir) {
362
- const values = {
363
- ...(await readEnvFile(join(rootDir, '.env'))),
364
- ...(await readEnvFile(join(rootDir, '.env.local'))),
365
- };
366
- for (const key of ['VITE_API_URL']) {
367
- if (process.env[key]) {
368
- values[key] = process.env[key];
369
- }
370
- }
371
- return values;
372
- }
373
- async function readEnvFile(filePath) {
374
- try {
375
- const content = await readFile(filePath, 'utf8');
376
- const values = {};
377
- for (const line of content.split(/\r?\n/)) {
378
- const trimmed = line.trim();
379
- if (!trimmed || trimmed.startsWith('#')) {
380
- continue;
381
- }
382
- const index = trimmed.indexOf('=');
383
- if (index === -1) {
384
- continue;
385
- }
386
- const key = trimmed.slice(0, index).trim();
387
- const value = trimmed
388
- .slice(index + 1)
389
- .trim()
390
- .replace(/^['"]|['"]$/g, '');
391
- values[key] = value;
392
- }
393
- return values;
394
- }
395
- catch {
396
- return {};
397
- }
398
- }
399
281
  async function readProjectSettings(rootDir) {
400
282
  try {
401
283
  const raw = await readFile(join(rootDir, '.fimo.settings.json'), 'utf8');
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=translations.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translations.test.d.ts","sourceRoot":"","sources":["../../../../src/build/vite/plugins/translations.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,266 @@
1
+ import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
2
+ import { tmpdir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import { afterEach, describe, expect, it, vi } from 'vitest';
5
+ import translationsPlugin from './translations';
6
+ let scratch = null;
7
+ let activePlugin = null;
8
+ const originalFimoApiToken = process.env.FIMO_API_TOKEN;
9
+ const pluginContext = {
10
+ addWatchFile: vi.fn(),
11
+ meta: {},
12
+ error: (error) => {
13
+ throw error;
14
+ },
15
+ info: () => undefined,
16
+ warn: () => undefined,
17
+ debug: () => undefined,
18
+ };
19
+ afterEach(() => {
20
+ if (activePlugin && typeof activePlugin.closeBundle === 'function') {
21
+ activePlugin.closeBundle.call(pluginContext);
22
+ activePlugin = null;
23
+ }
24
+ if (scratch) {
25
+ rmSync(scratch, { recursive: true, force: true });
26
+ scratch = null;
27
+ }
28
+ if (originalFimoApiToken === undefined) {
29
+ delete process.env.FIMO_API_TOKEN;
30
+ }
31
+ else {
32
+ process.env.FIMO_API_TOKEN = originalFimoApiToken;
33
+ }
34
+ vi.unstubAllGlobals();
35
+ vi.clearAllMocks();
36
+ });
37
+ function createProjectRoot() {
38
+ scratch = mkdtempSync(join(tmpdir(), 'fimo-translations-plugin-'));
39
+ writeFileSync(join(scratch, 'fimo-config.json'), JSON.stringify({ i18n: { defaultLocale: 'es', locales: ['es'] } }, null, 2));
40
+ writeFileSync(join(scratch, '.env'), 'VITE_API_URL=https://tenant.example.test\n');
41
+ return scratch;
42
+ }
43
+ function createPlugin(root, command) {
44
+ const plugin = translationsPlugin();
45
+ activePlugin = plugin;
46
+ if (typeof plugin.configResolved === 'function') {
47
+ plugin.configResolved.call(pluginContext, { root, command });
48
+ }
49
+ return plugin;
50
+ }
51
+ async function buildStart(plugin) {
52
+ if (typeof plugin.buildStart !== 'function') {
53
+ throw new Error('Expected buildStart hook');
54
+ }
55
+ await plugin.buildStart.call(pluginContext, {});
56
+ }
57
+ async function loadTranslations(plugin) {
58
+ if (typeof plugin.resolveId !== 'function' || typeof plugin.load !== 'function') {
59
+ throw new Error('Expected resolveId/load hooks');
60
+ }
61
+ const id = await plugin.resolveId.call(pluginContext, 'virtual:translations', undefined, {});
62
+ if (typeof id !== 'string') {
63
+ throw new Error('Expected virtual translations module id');
64
+ }
65
+ const result = await plugin.load.call(pluginContext, id, {});
66
+ if (typeof result !== 'string') {
67
+ throw new Error('Expected virtual translations source');
68
+ }
69
+ return result;
70
+ }
71
+ function createDevServer() {
72
+ return {
73
+ watcher: { add: vi.fn() },
74
+ moduleGraph: {
75
+ getModuleById: vi.fn(() => null),
76
+ idToModuleMap: new Map(),
77
+ },
78
+ ws: { send: vi.fn() },
79
+ };
80
+ }
81
+ function mockLabels(labels) {
82
+ const fetchMock = vi.fn(async () => jsonResponse({ data: { labels, updatedAt: '2026-06-24T00:00:00.000Z' } }));
83
+ vi.stubGlobal('fetch', fetchMock);
84
+ return fetchMock;
85
+ }
86
+ function jsonResponse(body) {
87
+ return {
88
+ ok: true,
89
+ json: async () => body,
90
+ };
91
+ }
92
+ async function waitFor(condition) {
93
+ const deadline = Date.now() + 1000;
94
+ while (Date.now() < deadline) {
95
+ if (condition()) {
96
+ return;
97
+ }
98
+ await new Promise((resolve) => setTimeout(resolve, 10));
99
+ }
100
+ throw new Error('Timed out waiting for condition');
101
+ }
102
+ describe('translationsPlugin', () => {
103
+ it('does not block dev startup on the initial label fetch', async () => {
104
+ const root = createProjectRoot();
105
+ const fetchMock = mockLabels({ headline: 'Hola' });
106
+ const plugin = createPlugin(root, 'serve');
107
+ await buildStart(plugin);
108
+ expect(fetchMock).not.toHaveBeenCalled();
109
+ const source = await loadTranslations(plugin);
110
+ expect(source).toContain('export const translations = {};');
111
+ expect(source).toContain('export const defaultLocale = "es";');
112
+ });
113
+ it('pushes updated labels over custom HMR without a full page reload', async () => {
114
+ const root = createProjectRoot();
115
+ mockLabels({ headline: 'Hola' });
116
+ const plugin = createPlugin(root, 'serve');
117
+ await buildStart(plugin);
118
+ const server = createDevServer();
119
+ if (typeof plugin.configureServer !== 'function') {
120
+ throw new Error('Expected configureServer hook');
121
+ }
122
+ plugin.configureServer.call(pluginContext, server);
123
+ await waitFor(() => server.ws.send.mock.calls.length > 0);
124
+ expect(server.ws.send).toHaveBeenCalledWith({
125
+ type: 'custom',
126
+ event: 'fimo:labels-updated',
127
+ data: expect.objectContaining({
128
+ defaultLocale: 'es',
129
+ dictionaries: { es: { headline: 'Hola' } },
130
+ locales: ['es'],
131
+ signature: expect.any(String),
132
+ updatedAt: '2026-06-24T00:00:00.000Z',
133
+ }),
134
+ });
135
+ expect(server.ws.send).not.toHaveBeenCalledWith({ type: 'full-reload', path: '*' });
136
+ const source = await loadTranslations(plugin);
137
+ expect(source).toContain('"headline":"Hola"');
138
+ });
139
+ it('discovers the events URL from tenant runtime config when env is absent', async () => {
140
+ const root = createProjectRoot();
141
+ const projectId = '11111111-1111-4111-8111-111111111111';
142
+ writeFileSync(join(root, '.fimo.settings.json'), JSON.stringify({ projectId, apiUrl: 'https://api.example.test' }));
143
+ process.env.FIMO_API_TOKEN = 'test-api-token';
144
+ const socketUrls = [];
145
+ vi.stubGlobal('WebSocket', class {
146
+ onopen = null;
147
+ onmessage = null;
148
+ onclose = null;
149
+ onerror = null;
150
+ constructor(url) {
151
+ socketUrls.push(url);
152
+ }
153
+ close() { }
154
+ });
155
+ const fetchMock = vi.fn(async (input, init) => {
156
+ const url = new URL(input.toString());
157
+ if (url.pathname === '/labels') {
158
+ return jsonResponse({ data: { labels: {}, updatedAt: null } });
159
+ }
160
+ if (url.pathname === '/runtime-config') {
161
+ return jsonResponse({ data: { eventsServerUrl: 'https://events.example.test' } });
162
+ }
163
+ if (url.pathname === '/api/auth/one-time-token/generate') {
164
+ expect(init?.method).toBe('GET');
165
+ return jsonResponse({ token: 'event-token' });
166
+ }
167
+ return { ok: false, json: async () => ({}) };
168
+ });
169
+ vi.stubGlobal('fetch', fetchMock);
170
+ const plugin = createPlugin(root, 'serve');
171
+ await buildStart(plugin);
172
+ const server = createDevServer();
173
+ if (typeof plugin.configureServer !== 'function') {
174
+ throw new Error('Expected configureServer hook');
175
+ }
176
+ plugin.configureServer.call(pluginContext, server);
177
+ await waitFor(() => socketUrls.length > 0);
178
+ expect(socketUrls[0]).toContain(`wss://events.example.test/parties/events/${projectId}`);
179
+ expect(socketUrls[0]).toContain('authToken=event-token');
180
+ });
181
+ it('forwards content changes over custom HMR without a full page reload', async () => {
182
+ const root = createProjectRoot();
183
+ const projectId = '11111111-1111-4111-8111-111111111111';
184
+ writeFileSync(join(root, '.fimo.settings.json'), JSON.stringify({ projectId, apiUrl: 'https://api.example.test' }));
185
+ process.env.FIMO_API_TOKEN = 'test-api-token';
186
+ const sockets = [];
187
+ vi.stubGlobal('WebSocket', class {
188
+ onopen = null;
189
+ onmessage = null;
190
+ onclose = null;
191
+ onerror = null;
192
+ constructor(_url) {
193
+ sockets.push(this);
194
+ }
195
+ close() { }
196
+ });
197
+ vi.stubGlobal('fetch', vi.fn(async (input) => {
198
+ const url = new URL(input.toString());
199
+ if (url.pathname === '/labels') {
200
+ return jsonResponse({ data: { labels: {}, updatedAt: null } });
201
+ }
202
+ if (url.pathname === '/runtime-config') {
203
+ return jsonResponse({ data: { eventsServerUrl: 'https://events.example.test' } });
204
+ }
205
+ if (url.pathname === '/api/auth/one-time-token/generate') {
206
+ return jsonResponse({ data: { token: 'event-token' } });
207
+ }
208
+ return { ok: false, json: async () => ({}) };
209
+ }));
210
+ const plugin = createPlugin(root, 'serve');
211
+ await buildStart(plugin);
212
+ const server = createDevServer();
213
+ if (typeof plugin.configureServer !== 'function') {
214
+ throw new Error('Expected configureServer hook');
215
+ }
216
+ plugin.configureServer.call(pluginContext, server);
217
+ await waitFor(() => sockets.length > 0);
218
+ sockets[0].onmessage?.({
219
+ data: JSON.stringify({
220
+ type: 'content:changed',
221
+ payload: {
222
+ changes: [{ action: 'update', contentType: 'LiveNote', id: 'entry-1', locale: 'en' }],
223
+ updatedAt: '2026-06-24T00:00:00.000Z',
224
+ },
225
+ }),
226
+ });
227
+ expect(server.ws.send).toHaveBeenCalledWith({
228
+ type: 'custom',
229
+ event: 'fimo:content-updated',
230
+ data: {
231
+ changes: [{ action: 'update', contentType: 'LiveNote', id: 'entry-1', locale: 'en' }],
232
+ updatedAt: '2026-06-24T00:00:00.000Z',
233
+ },
234
+ });
235
+ expect(server.ws.send).not.toHaveBeenCalledWith({ type: 'full-reload', path: '*' });
236
+ });
237
+ it('still waits for labels during production builds', async () => {
238
+ const root = createProjectRoot();
239
+ const fetchMock = mockLabels({ headline: 'Hola' });
240
+ const plugin = createPlugin(root, 'build');
241
+ await buildStart(plugin);
242
+ expect(fetchMock).toHaveBeenCalled();
243
+ const source = await loadTranslations(plugin);
244
+ expect(source).toContain('"headline":"Hola"');
245
+ });
246
+ it('loads one dictionary per configured locale', async () => {
247
+ const root = createProjectRoot();
248
+ writeFileSync(join(root, 'fimo-config.json'), JSON.stringify({ i18n: { defaultLocale: 'en', locales: ['en', 'es'] } }, null, 2));
249
+ vi.stubGlobal('fetch', vi.fn(async (input) => {
250
+ const url = new URL(input.toString());
251
+ const locale = url.searchParams.get('locale');
252
+ return jsonResponse({
253
+ data: {
254
+ labels: locale === 'es' ? { headline: 'Hola' } : { headline: 'Hello' },
255
+ updatedAt: `2026-06-24T00:00:0${locale === 'es' ? '2' : '1'}.000Z`,
256
+ },
257
+ });
258
+ }));
259
+ const plugin = createPlugin(root, 'build');
260
+ await buildStart(plugin);
261
+ const source = await loadTranslations(plugin);
262
+ expect(source).toContain('export const dictionaries = {"en":{"headline":"Hello"},"es":{"headline":"Hola"}};');
263
+ expect(source).toContain('export const translations = {"headline":"Hello"};');
264
+ expect(source).toContain('export const updatedAt = "2026-06-24T00:00:02.000Z";');
265
+ });
266
+ });
@@ -1,11 +1,10 @@
1
1
  {
2
2
  "bundled": true,
3
3
  "bundler": "esbuild",
4
- "bundledAt": "2026-07-17T15:57:36.106Z",
4
+ "bundledAt": "2026-07-21T08:12:39.698Z",
5
5
  "cliVersion": "0.6.0",
6
6
  "external": [
7
7
  "oxc-parser",
8
- "fsevents",
9
- "zod"
8
+ "fsevents"
10
9
  ]
11
10
  }