@lingo.dev/compiler 0.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 (300) hide show
  1. package/LICENSE.md +201 -0
  2. package/README.md +192 -0
  3. package/build/_virtual/rolldown_runtime.cjs +29 -0
  4. package/build/_virtual/rolldown_runtime.mjs +7 -0
  5. package/build/index.cjs +0 -0
  6. package/build/index.d.cts +2 -0
  7. package/build/index.d.mts +2 -0
  8. package/build/index.mjs +1 -0
  9. package/build/metadata/manager.cjs +131 -0
  10. package/build/metadata/manager.mjs +123 -0
  11. package/build/metadata/manager.mjs.map +1 -0
  12. package/build/plugin/build-translator.cjs +198 -0
  13. package/build/plugin/build-translator.mjs +196 -0
  14. package/build/plugin/build-translator.mjs.map +1 -0
  15. package/build/plugin/cleanup.cjs +20 -0
  16. package/build/plugin/cleanup.mjs +20 -0
  17. package/build/plugin/cleanup.mjs.map +1 -0
  18. package/build/plugin/next-compiler-loader.cjs +41 -0
  19. package/build/plugin/next-compiler-loader.d.cts +12 -0
  20. package/build/plugin/next-compiler-loader.d.cts.map +1 -0
  21. package/build/plugin/next-compiler-loader.d.mts +13 -0
  22. package/build/plugin/next-compiler-loader.d.mts.map +1 -0
  23. package/build/plugin/next-compiler-loader.mjs +42 -0
  24. package/build/plugin/next-compiler-loader.mjs.map +1 -0
  25. package/build/plugin/next-config-loader.cjs +13 -0
  26. package/build/plugin/next-config-loader.d.cts +8 -0
  27. package/build/plugin/next-config-loader.d.cts.map +1 -0
  28. package/build/plugin/next-config-loader.d.mts +9 -0
  29. package/build/plugin/next-config-loader.d.mts.map +1 -0
  30. package/build/plugin/next-config-loader.mjs +14 -0
  31. package/build/plugin/next-config-loader.mjs.map +1 -0
  32. package/build/plugin/next-locale-client-loader.cjs +9 -0
  33. package/build/plugin/next-locale-client-loader.d.cts +8 -0
  34. package/build/plugin/next-locale-client-loader.d.cts.map +1 -0
  35. package/build/plugin/next-locale-client-loader.d.mts +9 -0
  36. package/build/plugin/next-locale-client-loader.d.mts.map +1 -0
  37. package/build/plugin/next-locale-client-loader.mjs +10 -0
  38. package/build/plugin/next-locale-client-loader.mjs.map +1 -0
  39. package/build/plugin/next-locale-server-loader.cjs +9 -0
  40. package/build/plugin/next-locale-server-loader.d.cts +8 -0
  41. package/build/plugin/next-locale-server-loader.d.cts.map +1 -0
  42. package/build/plugin/next-locale-server-loader.d.mts +9 -0
  43. package/build/plugin/next-locale-server-loader.d.mts.map +1 -0
  44. package/build/plugin/next-locale-server-loader.mjs +10 -0
  45. package/build/plugin/next-locale-server-loader.mjs.map +1 -0
  46. package/build/plugin/next.cjs +220 -0
  47. package/build/plugin/next.d.cts +9 -0
  48. package/build/plugin/next.d.cts.map +1 -0
  49. package/build/plugin/next.d.mts +9 -0
  50. package/build/plugin/next.d.mts.map +1 -0
  51. package/build/plugin/next.mjs +222 -0
  52. package/build/plugin/next.mjs.map +1 -0
  53. package/build/plugin/transform/babel-compat.cjs +13 -0
  54. package/build/plugin/transform/babel-compat.mjs +10 -0
  55. package/build/plugin/transform/babel-compat.mjs.map +1 -0
  56. package/build/plugin/transform/index.cjs +44 -0
  57. package/build/plugin/transform/index.mjs +42 -0
  58. package/build/plugin/transform/index.mjs.map +1 -0
  59. package/build/plugin/transform/metadata.cjs +142 -0
  60. package/build/plugin/transform/metadata.mjs +141 -0
  61. package/build/plugin/transform/metadata.mjs.map +1 -0
  62. package/build/plugin/transform/parse-override.cjs +145 -0
  63. package/build/plugin/transform/parse-override.mjs +144 -0
  64. package/build/plugin/transform/parse-override.mjs.map +1 -0
  65. package/build/plugin/transform/process-file.cjs +391 -0
  66. package/build/plugin/transform/process-file.mjs +390 -0
  67. package/build/plugin/transform/process-file.mjs.map +1 -0
  68. package/build/plugin/transform/use-i18n.cjs +8 -0
  69. package/build/plugin/transform/use-i18n.mjs +7 -0
  70. package/build/plugin/transform/use-i18n.mjs.map +1 -0
  71. package/build/plugin/transform/utils.cjs +205 -0
  72. package/build/plugin/transform/utils.mjs +192 -0
  73. package/build/plugin/transform/utils.mjs.map +1 -0
  74. package/build/plugin/unplugin.cjs +188 -0
  75. package/build/plugin/unplugin.d.cts +8 -0
  76. package/build/plugin/unplugin.d.cts.map +1 -0
  77. package/build/plugin/unplugin.d.mts +8 -0
  78. package/build/plugin/unplugin.d.mts.map +1 -0
  79. package/build/plugin/unplugin.mjs +186 -0
  80. package/build/plugin/unplugin.mjs.map +1 -0
  81. package/build/plugin/vite.cjs +28 -0
  82. package/build/plugin/vite.d.cts +9 -0
  83. package/build/plugin/vite.d.cts.map +1 -0
  84. package/build/plugin/vite.d.mts +9 -0
  85. package/build/plugin/vite.d.mts.map +1 -0
  86. package/build/plugin/vite.mjs +29 -0
  87. package/build/plugin/vite.mjs.map +1 -0
  88. package/build/plugin/webpack.cjs +27 -0
  89. package/build/plugin/webpack.d.cts +8 -0
  90. package/build/plugin/webpack.d.cts.map +1 -0
  91. package/build/plugin/webpack.d.mts +8 -0
  92. package/build/plugin/webpack.d.mts.map +1 -0
  93. package/build/plugin/webpack.mjs +28 -0
  94. package/build/plugin/webpack.mjs.map +1 -0
  95. package/build/react/client/index.cjs +9 -0
  96. package/build/react/client/index.d.cts +5 -0
  97. package/build/react/client/index.d.mts +5 -0
  98. package/build/react/client/index.mjs +6 -0
  99. package/build/react/client/useTranslation.cjs +71 -0
  100. package/build/react/client/useTranslation.d.cts +42 -0
  101. package/build/react/client/useTranslation.d.cts.map +1 -0
  102. package/build/react/client/useTranslation.d.mts +42 -0
  103. package/build/react/client/useTranslation.d.mts.map +1 -0
  104. package/build/react/client/useTranslation.mjs +71 -0
  105. package/build/react/client/useTranslation.mjs.map +1 -0
  106. package/build/react/next/client.cjs +25 -0
  107. package/build/react/next/client.d.cts +9 -0
  108. package/build/react/next/client.d.cts.map +1 -0
  109. package/build/react/next/client.d.mts +9 -0
  110. package/build/react/next/client.d.mts.map +1 -0
  111. package/build/react/next/client.mjs +24 -0
  112. package/build/react/next/client.mjs.map +1 -0
  113. package/build/react/next/cookie-locale-resolver.cjs +29 -0
  114. package/build/react/next/cookie-locale-resolver.d.cts +33 -0
  115. package/build/react/next/cookie-locale-resolver.d.cts.map +1 -0
  116. package/build/react/next/cookie-locale-resolver.d.mts +33 -0
  117. package/build/react/next/cookie-locale-resolver.d.mts.map +1 -0
  118. package/build/react/next/cookie-locale-resolver.mjs +29 -0
  119. package/build/react/next/cookie-locale-resolver.mjs.map +1 -0
  120. package/build/react/next/server.cjs +21 -0
  121. package/build/react/next/server.d.cts +13 -0
  122. package/build/react/next/server.d.cts.map +1 -0
  123. package/build/react/next/server.d.mts +14 -0
  124. package/build/react/next/server.d.mts.map +1 -0
  125. package/build/react/next/server.mjs +20 -0
  126. package/build/react/next/server.mjs.map +1 -0
  127. package/build/react/server/ServerLingoProvider.cjs +19 -0
  128. package/build/react/server/ServerLingoProvider.d.cts +12 -0
  129. package/build/react/server/ServerLingoProvider.d.cts.map +1 -0
  130. package/build/react/server/ServerLingoProvider.d.mts +12 -0
  131. package/build/react/server/ServerLingoProvider.d.mts.map +1 -0
  132. package/build/react/server/ServerLingoProvider.mjs +19 -0
  133. package/build/react/server/ServerLingoProvider.mjs.map +1 -0
  134. package/build/react/server/index.cjs +7 -0
  135. package/build/react/server/index.d.cts +4 -0
  136. package/build/react/server/index.d.mts +4 -0
  137. package/build/react/server/index.mjs +5 -0
  138. package/build/react/server/useTranslation.cjs +60 -0
  139. package/build/react/server/useTranslation.d.cts +36 -0
  140. package/build/react/server/useTranslation.d.cts.map +1 -0
  141. package/build/react/server/useTranslation.d.mts +36 -0
  142. package/build/react/server/useTranslation.d.mts.map +1 -0
  143. package/build/react/server/useTranslation.mjs +60 -0
  144. package/build/react/server/useTranslation.mjs.map +1 -0
  145. package/build/react/server-only/index.cjs +42 -0
  146. package/build/react/server-only/index.d.cts +38 -0
  147. package/build/react/server-only/index.d.cts.map +1 -0
  148. package/build/react/server-only/index.d.mts +38 -0
  149. package/build/react/server-only/index.d.mts.map +1 -0
  150. package/build/react/server-only/index.mjs +42 -0
  151. package/build/react/server-only/index.mjs.map +1 -0
  152. package/build/react/server-only/translations.cjs +85 -0
  153. package/build/react/server-only/translations.mjs +85 -0
  154. package/build/react/server-only/translations.mjs.map +1 -0
  155. package/build/react/shared/LingoContext.cjs +14 -0
  156. package/build/react/shared/LingoContext.d.cts +41 -0
  157. package/build/react/shared/LingoContext.d.cts.map +1 -0
  158. package/build/react/shared/LingoContext.d.mts +41 -0
  159. package/build/react/shared/LingoContext.d.mts.map +1 -0
  160. package/build/react/shared/LingoContext.mjs +13 -0
  161. package/build/react/shared/LingoContext.mjs.map +1 -0
  162. package/build/react/shared/LingoProvider.cjs +274 -0
  163. package/build/react/shared/LingoProvider.d.cts +76 -0
  164. package/build/react/shared/LingoProvider.d.cts.map +1 -0
  165. package/build/react/shared/LingoProvider.d.mts +76 -0
  166. package/build/react/shared/LingoProvider.d.mts.map +1 -0
  167. package/build/react/shared/LingoProvider.mjs +274 -0
  168. package/build/react/shared/LingoProvider.mjs.map +1 -0
  169. package/build/react/shared/LocaleSwitcher.cjs +61 -0
  170. package/build/react/shared/LocaleSwitcher.d.cts +71 -0
  171. package/build/react/shared/LocaleSwitcher.d.cts.map +1 -0
  172. package/build/react/shared/LocaleSwitcher.d.mts +71 -0
  173. package/build/react/shared/LocaleSwitcher.d.mts.map +1 -0
  174. package/build/react/shared/LocaleSwitcher.mjs +61 -0
  175. package/build/react/shared/LocaleSwitcher.mjs.map +1 -0
  176. package/build/react/shared/render-rich-text.cjs +55 -0
  177. package/build/react/shared/render-rich-text.d.cts +17 -0
  178. package/build/react/shared/render-rich-text.d.cts.map +1 -0
  179. package/build/react/shared/render-rich-text.d.mts +17 -0
  180. package/build/react/shared/render-rich-text.d.mts.map +1 -0
  181. package/build/react/shared/render-rich-text.mjs +54 -0
  182. package/build/react/shared/render-rich-text.mjs.map +1 -0
  183. package/build/react/shared/utils.cjs +34 -0
  184. package/build/react/shared/utils.mjs +35 -0
  185. package/build/react/shared/utils.mjs.map +1 -0
  186. package/build/react/types.d.cts +16 -0
  187. package/build/react/types.d.cts.map +1 -0
  188. package/build/react/types.d.mts +16 -0
  189. package/build/react/types.d.mts.map +1 -0
  190. package/build/translation-server/logger.cjs +37 -0
  191. package/build/translation-server/logger.mjs +37 -0
  192. package/build/translation-server/logger.mjs.map +1 -0
  193. package/build/translation-server/translation-server.cjs +547 -0
  194. package/build/translation-server/translation-server.mjs +544 -0
  195. package/build/translation-server/translation-server.mjs.map +1 -0
  196. package/build/translation-server/ws-events.cjs +15 -0
  197. package/build/translation-server/ws-events.mjs +15 -0
  198. package/build/translation-server/ws-events.mjs.map +1 -0
  199. package/build/translators/api.cjs +12 -0
  200. package/build/translators/api.mjs +12 -0
  201. package/build/translators/api.mjs.map +1 -0
  202. package/build/translators/cache-factory.cjs +26 -0
  203. package/build/translators/cache-factory.mjs +27 -0
  204. package/build/translators/cache-factory.mjs.map +1 -0
  205. package/build/translators/lingo/model-factory.cjs +179 -0
  206. package/build/translators/lingo/model-factory.mjs +174 -0
  207. package/build/translators/lingo/model-factory.mjs.map +1 -0
  208. package/build/translators/lingo/prompt.cjs +43 -0
  209. package/build/translators/lingo/prompt.mjs +43 -0
  210. package/build/translators/lingo/prompt.mjs.map +1 -0
  211. package/build/translators/lingo/service.cjs +152 -0
  212. package/build/translators/lingo/service.mjs +152 -0
  213. package/build/translators/lingo/service.mjs.map +1 -0
  214. package/build/translators/lingo/shots.cjs +28 -0
  215. package/build/translators/lingo/shots.mjs +28 -0
  216. package/build/translators/lingo/shots.mjs.map +1 -0
  217. package/build/translators/local-cache.cjs +115 -0
  218. package/build/translators/local-cache.mjs +113 -0
  219. package/build/translators/local-cache.mjs.map +1 -0
  220. package/build/translators/parse-xml.cjs +109 -0
  221. package/build/translators/parse-xml.mjs +108 -0
  222. package/build/translators/parse-xml.mjs.map +1 -0
  223. package/build/translators/pluralization/icu-validator.cjs +36 -0
  224. package/build/translators/pluralization/icu-validator.mjs +36 -0
  225. package/build/translators/pluralization/icu-validator.mjs.map +1 -0
  226. package/build/translators/pluralization/pattern-detector.cjs +25 -0
  227. package/build/translators/pluralization/pattern-detector.mjs +25 -0
  228. package/build/translators/pluralization/pattern-detector.mjs.map +1 -0
  229. package/build/translators/pluralization/prompt.cjs +98 -0
  230. package/build/translators/pluralization/prompt.mjs +98 -0
  231. package/build/translators/pluralization/prompt.mjs.map +1 -0
  232. package/build/translators/pluralization/service.cjs +247 -0
  233. package/build/translators/pluralization/service.mjs +247 -0
  234. package/build/translators/pluralization/service.mjs.map +1 -0
  235. package/build/translators/pluralization/shots.cjs +53 -0
  236. package/build/translators/pluralization/shots.mjs +53 -0
  237. package/build/translators/pluralization/shots.mjs.map +1 -0
  238. package/build/translators/pluralization/types.d.cts +17 -0
  239. package/build/translators/pluralization/types.d.cts.map +1 -0
  240. package/build/translators/pluralization/types.d.mts +17 -0
  241. package/build/translators/pluralization/types.d.mts.map +1 -0
  242. package/build/translators/pseudotranslator/index.cjs +129 -0
  243. package/build/translators/pseudotranslator/index.mjs +129 -0
  244. package/build/translators/pseudotranslator/index.mjs.map +1 -0
  245. package/build/translators/translation-service.cjs +182 -0
  246. package/build/translators/translation-service.mjs +183 -0
  247. package/build/translators/translation-service.mjs.map +1 -0
  248. package/build/translators/translator-factory.cjs +49 -0
  249. package/build/translators/translator-factory.mjs +50 -0
  250. package/build/translators/translator-factory.mjs.map +1 -0
  251. package/build/types.d.cts +161 -0
  252. package/build/types.d.cts.map +1 -0
  253. package/build/types.d.mts +161 -0
  254. package/build/types.d.mts.map +1 -0
  255. package/build/utils/config-factory.cjs +58 -0
  256. package/build/utils/config-factory.mjs +58 -0
  257. package/build/utils/config-factory.mjs.map +1 -0
  258. package/build/utils/hash.cjs +17 -0
  259. package/build/utils/hash.mjs +16 -0
  260. package/build/utils/hash.mjs.map +1 -0
  261. package/build/utils/is-valid-locale.cjs +14 -0
  262. package/build/utils/is-valid-locale.mjs +14 -0
  263. package/build/utils/is-valid-locale.mjs.map +1 -0
  264. package/build/utils/logger.cjs +51 -0
  265. package/build/utils/logger.mjs +50 -0
  266. package/build/utils/logger.mjs.map +1 -0
  267. package/build/utils/path-helpers.cjs +49 -0
  268. package/build/utils/path-helpers.mjs +47 -0
  269. package/build/utils/path-helpers.mjs.map +1 -0
  270. package/build/utils/timeout.cjs +42 -0
  271. package/build/utils/timeout.mjs +41 -0
  272. package/build/utils/timeout.mjs.map +1 -0
  273. package/build/virtual/code-generator.cjs +54 -0
  274. package/build/virtual/code-generator.mjs +53 -0
  275. package/build/virtual/code-generator.mjs.map +1 -0
  276. package/build/virtual/config.cjs +10 -0
  277. package/build/virtual/config.d.cts +9 -0
  278. package/build/virtual/config.d.cts.map +1 -0
  279. package/build/virtual/config.d.mts +9 -0
  280. package/build/virtual/config.d.mts.map +1 -0
  281. package/build/virtual/config.mjs +8 -0
  282. package/build/virtual/config.mjs.map +1 -0
  283. package/build/virtual/locale/client.cjs +23 -0
  284. package/build/virtual/locale/client.d.cts +19 -0
  285. package/build/virtual/locale/client.d.cts.map +1 -0
  286. package/build/virtual/locale/client.d.mts +19 -0
  287. package/build/virtual/locale/client.d.mts.map +1 -0
  288. package/build/virtual/locale/client.mjs +22 -0
  289. package/build/virtual/locale/client.mjs.map +1 -0
  290. package/build/virtual/locale/server.cjs +13 -0
  291. package/build/virtual/locale/server.d.cts +13 -0
  292. package/build/virtual/locale/server.d.cts.map +1 -0
  293. package/build/virtual/locale/server.d.mts +13 -0
  294. package/build/virtual/locale/server.d.mts.map +1 -0
  295. package/build/virtual/locale/server.mjs +13 -0
  296. package/build/virtual/locale/server.mjs.map +1 -0
  297. package/build/widget/lingo-dev-widget.cjs +228 -0
  298. package/build/widget/lingo-dev-widget.mjs +229 -0
  299. package/build/widget/lingo-dev-widget.mjs.map +1 -0
  300. package/package.json +189 -0
@@ -0,0 +1,17 @@
1
+ import { ReactNode } from "react";
2
+ import { FormatXMLElementFn } from "intl-messageformat";
3
+ import { LocaleCode } from "lingo.dev/spec";
4
+
5
+ //#region src/react/shared/render-rich-text.d.ts
6
+
7
+ /**
8
+ * Component renderer function for rich text translation
9
+ */
10
+ type ComponentRenderer = FormatXMLElementFn<ReactNode>;
11
+ /**
12
+ * Rich text parameters for translation
13
+ */
14
+ type RichTextParams = Record<string, ReactNode | ComponentRenderer>;
15
+ //#endregion
16
+ export { RichTextParams };
17
+ //# sourceMappingURL=render-rich-text.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-rich-text.d.mts","names":[],"sources":["../../../src/react/shared/render-rich-text.tsx"],"sourcesContent":[],"mappings":";;;;;;;;AAQA;AAKY,KALA,iBAAA,GAAoB,kBAKN,CALyB,SAKzB,CAAA;;;;AAAS,KAAvB,cAAA,GAAiB,MAAM,CAAA,MAAA,EAAS,SAAT,GAAqB,iBAArB,CAAA"}
@@ -0,0 +1,54 @@
1
+ import { logger } from "../../utils/logger.mjs";
2
+ import { Fragment } from "react";
3
+ import { jsx } from "react/jsx-runtime";
4
+ import IntlMessageFormat from "intl-messageformat";
5
+
6
+ //#region src/react/shared/render-rich-text.tsx
7
+ /**
8
+ * Wraps a FormatXMLElementFn to automatically assign keys to parts
9
+ */
10
+ function assignUniqueKeysToParts(formatXMLElementFn) {
11
+ return function(parts) {
12
+ return formatXMLElementFn(parts);
13
+ };
14
+ }
15
+ /**
16
+ * Wraps all FormatXMLElementFn values in params with key assignment
17
+ */
18
+ function assignUniqueKeysToParams(params) {
19
+ const result = {};
20
+ for (const [key, value] of Object.entries(params)) if (typeof value === "function") result[key] = assignUniqueKeysToParts(value);
21
+ else result[key] = value;
22
+ return result;
23
+ }
24
+ /**
25
+ * Parse rich text translation string with placeholders (server-side version)
26
+ *
27
+ * Supports:
28
+ * - ICU MessageFormat: {count, plural, one {# item} other {# items}}
29
+ * - Variable placeholders: {name}
30
+ * - Component placeholders: <tag0>content</tag0>
31
+ *
32
+ * @param text - The translation string with placeholders
33
+ * @param params - Object with variable values and component renderers
34
+ * @param locale
35
+ * @returns React nodes or string
36
+ */
37
+ function renderRichText(text, params, locale) {
38
+ try {
39
+ const formatter = new IntlMessageFormat(text, locale);
40
+ const keyedParams = assignUniqueKeysToParams(params);
41
+ const result = formatter.format(keyedParams);
42
+ if (Array.isArray(result)) return result.map((item, index) => {
43
+ return /* @__PURE__ */ jsx(Fragment, { children: item }, index);
44
+ });
45
+ return result;
46
+ } catch (error) {
47
+ logger.warn(`Error rendering rich text (${text}): ${error}`);
48
+ return text;
49
+ }
50
+ }
51
+
52
+ //#endregion
53
+ export { renderRichText };
54
+ //# sourceMappingURL=render-rich-text.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-rich-text.mjs","names":["result: RichTextParams"],"sources":["../../../src/react/shared/render-rich-text.tsx"],"sourcesContent":["import { Fragment, type ReactNode } from \"react\";\nimport IntlMessageFormat, { type FormatXMLElementFn } from \"intl-messageformat\";\nimport { logger } from \"../../utils/logger\";\nimport type { LocaleCode } from \"lingo.dev/spec\";\n\n/**\n * Component renderer function for rich text translation\n */\nexport type ComponentRenderer = FormatXMLElementFn<ReactNode>;\n\n/**\n * Rich text parameters for translation\n */\nexport type RichTextParams = Record<string, ReactNode | ComponentRenderer>;\n\n/**\n * Wraps a FormatXMLElementFn to automatically assign keys to parts\n */\nfunction assignUniqueKeysToParts(\n formatXMLElementFn: FormatXMLElementFn<ReactNode>,\n): FormatXMLElementFn<ReactNode> {\n return function (parts: Array<ReactNode>) {\n return formatXMLElementFn(parts);\n };\n}\n\n/**\n * Wraps all FormatXMLElementFn values in params with key assignment\n */\nfunction assignUniqueKeysToParams(params: RichTextParams): RichTextParams {\n const result: RichTextParams = {};\n\n for (const [key, value] of Object.entries(params)) {\n // Check if value is a FormatXMLElementFn (function that's not a React component)\n if (typeof value === \"function\") {\n result[key] = assignUniqueKeysToParts(value);\n } else {\n result[key] = value;\n }\n }\n\n return result;\n}\n//\n\n/**\n * Parse rich text translation string with placeholders (server-side version)\n *\n * Supports:\n * - ICU MessageFormat: {count, plural, one {# item} other {# items}}\n * - Variable placeholders: {name}\n * - Component placeholders: <tag0>content</tag0>\n *\n * @param text - The translation string with placeholders\n * @param params - Object with variable values and component renderers\n * @param locale\n * @returns React nodes or string\n */\nexport function renderRichText(\n text: string,\n params: RichTextParams,\n locale: LocaleCode,\n): ReactNode {\n try {\n const formatter = new IntlMessageFormat(text, locale);\n const keyedParams = assignUniqueKeysToParams(params);\n const result = formatter.format<ReactNode>(keyedParams);\n\n if (Array.isArray(result)) {\n // Making all elements keyed here somehow fixes all the things. Maybe I also need to key everything in toKeyedReactNodeArray and I just don't get the error because I don't have a corner case for it? Need to investigate\n return result.map((item, index) => {\n // Each item gets wrapped in Fragment with unique key\n // This handles strings, React elements (like <>text</>), everything\n return <Fragment key={index}>{item}</Fragment>;\n });\n }\n\n return result;\n } catch (error) {\n // It's better to render at least something than break the whole app.\n logger.warn(`Error rendering rich text (${text}): ${error}`);\n return text;\n }\n}\n"],"mappings":";;;;;;;;;AAkBA,SAAS,wBACP,oBAC+B;AAC/B,QAAO,SAAU,OAAyB;AACxC,SAAO,mBAAmB,MAAM;;;;;;AAOpC,SAAS,yBAAyB,QAAwC;CACxE,MAAMA,SAAyB,EAAE;AAEjC,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,CAE/C,KAAI,OAAO,UAAU,WACnB,QAAO,OAAO,wBAAwB,MAAM;KAE5C,QAAO,OAAO;AAIlB,QAAO;;;;;;;;;;;;;;;AAiBT,SAAgB,eACd,MACA,QACA,QACW;AACX,KAAI;EACF,MAAM,YAAY,IAAI,kBAAkB,MAAM,OAAO;EACrD,MAAM,cAAc,yBAAyB,OAAO;EACpD,MAAM,SAAS,UAAU,OAAkB,YAAY;AAEvD,MAAI,MAAM,QAAQ,OAAO,CAEvB,QAAO,OAAO,KAAK,MAAM,UAAU;AAGjC,UAAO,oBAAC,sBAAsB,QAAR,MAAwB;IAC9C;AAGJ,SAAO;UACA,OAAO;AAEd,SAAO,KAAK,8BAA8B,KAAK,KAAK,QAAQ;AAC5D,SAAO"}
@@ -0,0 +1,34 @@
1
+ const require_logger = require('../../utils/logger.cjs');
2
+
3
+ //#region src/react/shared/utils.ts
4
+ /**
5
+ * Fetch translations from translation server
6
+ * Times out after 30 seconds to prevent indefinite hangs
7
+ */
8
+ async function fetchTranslations(targetLocale, hashes, serverUrl) {
9
+ if (!serverUrl) return {};
10
+ if (!hashes || hashes.length === 0) return {};
11
+ const url = `${serverUrl}/translations/${targetLocale}`;
12
+ const controller = new AbortController();
13
+ const timeoutId = setTimeout(() => controller.abort(), 3e4);
14
+ try {
15
+ let response = await fetch(url, {
16
+ method: "POST",
17
+ headers: { "Content-Type": "application/json" },
18
+ body: JSON.stringify({ hashes }),
19
+ signal: controller.signal
20
+ });
21
+ if (!response.ok) throw new Error(`Translation API error: ${response.statusText}`);
22
+ const result = await response.json();
23
+ require_logger.logger.debug(`Fetched translations for ${targetLocale}: ${JSON.stringify(result)}`);
24
+ return result.translations || {};
25
+ } catch (error) {
26
+ if (error instanceof Error && error.name === "AbortError") throw new Error(`Translation request to ${targetLocale} timed out after 30 seconds`);
27
+ throw error;
28
+ } finally {
29
+ clearTimeout(timeoutId);
30
+ }
31
+ }
32
+
33
+ //#endregion
34
+ exports.fetchTranslations = fetchTranslations;
@@ -0,0 +1,35 @@
1
+ import { logger } from "../../utils/logger.mjs";
2
+
3
+ //#region src/react/shared/utils.ts
4
+ /**
5
+ * Fetch translations from translation server
6
+ * Times out after 30 seconds to prevent indefinite hangs
7
+ */
8
+ async function fetchTranslations(targetLocale, hashes, serverUrl) {
9
+ if (!serverUrl) return {};
10
+ if (!hashes || hashes.length === 0) return {};
11
+ const url = `${serverUrl}/translations/${targetLocale}`;
12
+ const controller = new AbortController();
13
+ const timeoutId = setTimeout(() => controller.abort(), 3e4);
14
+ try {
15
+ let response = await fetch(url, {
16
+ method: "POST",
17
+ headers: { "Content-Type": "application/json" },
18
+ body: JSON.stringify({ hashes }),
19
+ signal: controller.signal
20
+ });
21
+ if (!response.ok) throw new Error(`Translation API error: ${response.statusText}`);
22
+ const result = await response.json();
23
+ logger.debug(`Fetched translations for ${targetLocale}: ${JSON.stringify(result)}`);
24
+ return result.translations || {};
25
+ } catch (error) {
26
+ if (error instanceof Error && error.name === "AbortError") throw new Error(`Translation request to ${targetLocale} timed out after 30 seconds`);
27
+ throw error;
28
+ } finally {
29
+ clearTimeout(timeoutId);
30
+ }
31
+ }
32
+
33
+ //#endregion
34
+ export { fetchTranslations };
35
+ //# sourceMappingURL=utils.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.mjs","names":[],"sources":["../../../src/react/shared/utils.ts"],"sourcesContent":["import { logger } from \"../../utils/logger\";\n\n/**\n * Fetch translations from translation server\n * Times out after 30 seconds to prevent indefinite hangs\n */\nexport async function fetchTranslations(\n targetLocale: string,\n hashes: string[],\n serverUrl?: string,\n): Promise<Record<string, string>> {\n if (!serverUrl) {\n return {};\n }\n if (!hashes || hashes.length === 0) {\n // This function is only called in dev mode and there is no need to fetch all the translations at once in dev mode\n return {};\n }\n const url = `${serverUrl}/translations/${targetLocale}`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 30000); // 30 second timeout\n\n try {\n let response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ hashes }),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n throw new Error(`Translation API error: ${response.statusText}`);\n }\n\n // TODO (AleksandrSl 02/12/2025): Handle errors in the context.\n const result = await response.json();\n\n logger.debug(\n `Fetched translations for ${targetLocale}: ${JSON.stringify(result)}`,\n );\n\n // Server returns { locale, translations, errors }\n // Extract just the translations dictionary\n return result.translations || {};\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new Error(\n `Translation request to ${targetLocale} timed out after 30 seconds`,\n );\n }\n throw error;\n } finally {\n clearTimeout(timeoutId);\n }\n}\n"],"mappings":";;;;;;;AAMA,eAAsB,kBACpB,cACA,QACA,WACiC;AACjC,KAAI,CAAC,UACH,QAAO,EAAE;AAEX,KAAI,CAAC,UAAU,OAAO,WAAW,EAE/B,QAAO,EAAE;CAEX,MAAM,MAAM,GAAG,UAAU,gBAAgB;CAEzC,MAAM,aAAa,IAAI,iBAAiB;CACxC,MAAM,YAAY,iBAAiB,WAAW,OAAO,EAAE,IAAM;AAE7D,KAAI;EACF,IAAI,WAAW,MAAM,MAAM,KAAK;GAC9B,QAAQ;GACR,SAAS,EACP,gBAAgB,oBACjB;GACD,MAAM,KAAK,UAAU,EAAE,QAAQ,CAAC;GAChC,QAAQ,WAAW;GACpB,CAAC;AAEF,MAAI,CAAC,SAAS,GACZ,OAAM,IAAI,MAAM,0BAA0B,SAAS,aAAa;EAIlE,MAAM,SAAS,MAAM,SAAS,MAAM;AAEpC,SAAO,MACL,4BAA4B,aAAa,IAAI,KAAK,UAAU,OAAO,GACpE;AAID,SAAO,OAAO,gBAAgB,EAAE;UACzB,OAAO;AACd,MAAI,iBAAiB,SAAS,MAAM,SAAS,aAC3C,OAAM,IAAI,MACR,0BAA0B,aAAa,6BACxC;AAEH,QAAM;WACE;AACR,eAAa,UAAU"}
@@ -0,0 +1,16 @@
1
+ import { RichTextParams } from "./shared/render-rich-text.cjs";
2
+ import { LocaleCode } from "lingo.dev/spec";
3
+ import { ReactNode } from "react";
4
+
5
+ //#region src/react/types.d.ts
6
+ type TranslationHook = (hashes: string[]) => {
7
+ t: TranslationFunction;
8
+ locale: LocaleCode;
9
+ };
10
+ /**
11
+ * Translation function type
12
+ */
13
+ type TranslationFunction = (hash: string, source: string, params?: RichTextParams) => string | ReactNode;
14
+ //#endregion
15
+ export { TranslationHook };
16
+ //# sourceMappingURL=types.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.cts","names":[],"sources":["../../src/react/types.ts"],"sourcesContent":[],"mappings":";;;;;KAIY,eAAA;KACP;EADO,MAAA,EAEF,UAFiB;AAQ3B,CAAA;;;;KAAY,mBAAA,2CAGD,4BACG"}
@@ -0,0 +1,16 @@
1
+ import { RichTextParams } from "./shared/render-rich-text.mjs";
2
+ import { ReactNode } from "react";
3
+ import { LocaleCode } from "lingo.dev/spec";
4
+
5
+ //#region src/react/types.d.ts
6
+ type TranslationHook = (hashes: string[]) => {
7
+ t: TranslationFunction;
8
+ locale: LocaleCode;
9
+ };
10
+ /**
11
+ * Translation function type
12
+ */
13
+ type TranslationFunction = (hash: string, source: string, params?: RichTextParams) => string | ReactNode;
14
+ //#endregion
15
+ export { TranslationHook };
16
+ //# sourceMappingURL=types.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.mts","names":[],"sources":["../../src/react/types.ts"],"sourcesContent":[],"mappings":";;;;;KAIY,eAAA;KACP;EADO,MAAA,EAEF,UAFiB;AAQ3B,CAAA;;;;KAAY,mBAAA,2CAGD,4BACG"}
@@ -0,0 +1,37 @@
1
+ const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
2
+ const require_logger = require('../utils/logger.cjs');
3
+ let fs_promises = require("fs/promises");
4
+ let path = require("path");
5
+
6
+ //#region src/translation-server/logger.ts
7
+ /**
8
+ * Such weird separation of file writer from logger
9
+ * is needed to avoid leaking node deps to the client build in next,
10
+ * but still keep the main logger logic in one place.
11
+ */
12
+ /**
13
+ * Create a file writer function for a specific log file
14
+ */
15
+ function createFileWriter(filePath, plainPrefix = "[Lingo.dev]") {
16
+ let writeQueue = Promise.resolve();
17
+ return (level, message) => {
18
+ writeQueue = writeQueue.then(async () => {
19
+ try {
20
+ const logLine = `${(/* @__PURE__ */ new Date()).toISOString()} [${level.toUpperCase()}] ${plainPrefix} ${message}\n`;
21
+ await Promise.race([(0, fs_promises.appendFile)(filePath, logLine, "utf-8"), new Promise((_, reject) => setTimeout(() => reject(/* @__PURE__ */ new Error("File write timeout")), 1e3))]);
22
+ } catch (error) {}
23
+ }).catch(() => {});
24
+ };
25
+ }
26
+ let logger = void 0;
27
+ function getLogger(config) {
28
+ if (!logger) logger = new require_logger.Logger({
29
+ enableConsole: false,
30
+ enableDebug: true,
31
+ writeToFile: createFileWriter((0, path.join)(config.sourceRoot, config.lingoDir, "translation-server.log"))
32
+ });
33
+ return logger;
34
+ }
35
+
36
+ //#endregion
37
+ exports.getLogger = getLogger;
@@ -0,0 +1,37 @@
1
+ import { Logger } from "../utils/logger.mjs";
2
+ import { appendFile } from "fs/promises";
3
+ import { join } from "path";
4
+
5
+ //#region src/translation-server/logger.ts
6
+ /**
7
+ * Such weird separation of file writer from logger
8
+ * is needed to avoid leaking node deps to the client build in next,
9
+ * but still keep the main logger logic in one place.
10
+ */
11
+ /**
12
+ * Create a file writer function for a specific log file
13
+ */
14
+ function createFileWriter(filePath, plainPrefix = "[Lingo.dev]") {
15
+ let writeQueue = Promise.resolve();
16
+ return (level, message) => {
17
+ writeQueue = writeQueue.then(async () => {
18
+ try {
19
+ const logLine = `${(/* @__PURE__ */ new Date()).toISOString()} [${level.toUpperCase()}] ${plainPrefix} ${message}\n`;
20
+ await Promise.race([appendFile(filePath, logLine, "utf-8"), new Promise((_, reject) => setTimeout(() => reject(/* @__PURE__ */ new Error("File write timeout")), 1e3))]);
21
+ } catch (error) {}
22
+ }).catch(() => {});
23
+ };
24
+ }
25
+ let logger = void 0;
26
+ function getLogger(config) {
27
+ if (!logger) logger = new Logger({
28
+ enableConsole: false,
29
+ enableDebug: true,
30
+ writeToFile: createFileWriter(join(config.sourceRoot, config.lingoDir, "translation-server.log"))
31
+ });
32
+ return logger;
33
+ }
34
+
35
+ //#endregion
36
+ export { getLogger };
37
+ //# sourceMappingURL=logger.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.mjs","names":["writeQueue: Promise<void>","logger: Logger | undefined"],"sources":["../../src/translation-server/logger.ts"],"sourcesContent":["import { Logger, type LogLevel } from \"../utils/logger\";\nimport { join } from \"path\";\nimport type { TranslationMiddlewareConfig } from \"../types\";\n\n/**\n * Such weird separation of file writer from logger\n * is needed to avoid leaking node deps to the client build in next,\n * but still keep the main logger logic in one place.\n */\nimport { appendFile } from \"fs/promises\";\n\n/**\n * Create a file writer function for a specific log file\n */\nexport function createFileWriter(\n filePath: string,\n plainPrefix: string = \"[Lingo.dev]\",\n) {\n let writeQueue: Promise<void> = Promise.resolve();\n\n return (level: LogLevel, message: string) => {\n writeQueue = writeQueue\n .then(async () => {\n try {\n const timestamp = new Date().toISOString();\n const logLine = `${timestamp} [${level.toUpperCase()}] ${plainPrefix} ${message}\\n`;\n\n await Promise.race([\n appendFile(filePath, logLine, \"utf-8\"),\n new Promise((_, reject) =>\n setTimeout(() => reject(new Error(\"File write timeout\")), 1000),\n ),\n ]);\n } catch (error) {\n // Silently fail to avoid breaking the application\n }\n })\n .catch(() => {});\n };\n}\n\nlet logger: Logger | undefined = undefined;\n\nexport function getLogger(config: TranslationMiddlewareConfig) {\n if (!logger) {\n const translationServerLogPath = join(\n config.sourceRoot,\n config.lingoDir,\n \"translation-server.log\",\n );\n logger = new Logger({\n enableConsole: false,\n enableDebug: true,\n writeToFile: createFileWriter(translationServerLogPath),\n });\n }\n return logger;\n}\n"],"mappings":";;;;;;;;;;;;;AAcA,SAAgB,iBACd,UACA,cAAsB,eACtB;CACA,IAAIA,aAA4B,QAAQ,SAAS;AAEjD,SAAQ,OAAiB,YAAoB;AAC3C,eAAa,WACV,KAAK,YAAY;AAChB,OAAI;IAEF,MAAM,UAAU,oBADE,IAAI,MAAM,EAAC,aAAa,CACb,IAAI,MAAM,aAAa,CAAC,IAAI,YAAY,GAAG,QAAQ;AAEhF,UAAM,QAAQ,KAAK,CACjB,WAAW,UAAU,SAAS,QAAQ,EACtC,IAAI,SAAS,GAAG,WACd,iBAAiB,uBAAO,IAAI,MAAM,qBAAqB,CAAC,EAAE,IAAK,CAChE,CACF,CAAC;YACK,OAAO;IAGhB,CACD,YAAY,GAAG;;;AAItB,IAAIC,SAA6B;AAEjC,SAAgB,UAAU,QAAqC;AAC7D,KAAI,CAAC,OAMH,UAAS,IAAI,OAAO;EAClB,eAAe;EACf,aAAa;EACb,aAAa,iBARkB,KAC/B,OAAO,YACP,OAAO,UACP,yBACD,CAIwD;EACxD,CAAC;AAEJ,QAAO"}