@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.
- package/LICENSE.md +201 -0
- package/README.md +192 -0
- package/build/_virtual/rolldown_runtime.cjs +29 -0
- package/build/_virtual/rolldown_runtime.mjs +7 -0
- package/build/index.cjs +0 -0
- package/build/index.d.cts +2 -0
- package/build/index.d.mts +2 -0
- package/build/index.mjs +1 -0
- package/build/metadata/manager.cjs +131 -0
- package/build/metadata/manager.mjs +123 -0
- package/build/metadata/manager.mjs.map +1 -0
- package/build/plugin/build-translator.cjs +198 -0
- package/build/plugin/build-translator.mjs +196 -0
- package/build/plugin/build-translator.mjs.map +1 -0
- package/build/plugin/cleanup.cjs +20 -0
- package/build/plugin/cleanup.mjs +20 -0
- package/build/plugin/cleanup.mjs.map +1 -0
- package/build/plugin/next-compiler-loader.cjs +41 -0
- package/build/plugin/next-compiler-loader.d.cts +12 -0
- package/build/plugin/next-compiler-loader.d.cts.map +1 -0
- package/build/plugin/next-compiler-loader.d.mts +13 -0
- package/build/plugin/next-compiler-loader.d.mts.map +1 -0
- package/build/plugin/next-compiler-loader.mjs +42 -0
- package/build/plugin/next-compiler-loader.mjs.map +1 -0
- package/build/plugin/next-config-loader.cjs +13 -0
- package/build/plugin/next-config-loader.d.cts +8 -0
- package/build/plugin/next-config-loader.d.cts.map +1 -0
- package/build/plugin/next-config-loader.d.mts +9 -0
- package/build/plugin/next-config-loader.d.mts.map +1 -0
- package/build/plugin/next-config-loader.mjs +14 -0
- package/build/plugin/next-config-loader.mjs.map +1 -0
- package/build/plugin/next-locale-client-loader.cjs +9 -0
- package/build/plugin/next-locale-client-loader.d.cts +8 -0
- package/build/plugin/next-locale-client-loader.d.cts.map +1 -0
- package/build/plugin/next-locale-client-loader.d.mts +9 -0
- package/build/plugin/next-locale-client-loader.d.mts.map +1 -0
- package/build/plugin/next-locale-client-loader.mjs +10 -0
- package/build/plugin/next-locale-client-loader.mjs.map +1 -0
- package/build/plugin/next-locale-server-loader.cjs +9 -0
- package/build/plugin/next-locale-server-loader.d.cts +8 -0
- package/build/plugin/next-locale-server-loader.d.cts.map +1 -0
- package/build/plugin/next-locale-server-loader.d.mts +9 -0
- package/build/plugin/next-locale-server-loader.d.mts.map +1 -0
- package/build/plugin/next-locale-server-loader.mjs +10 -0
- package/build/plugin/next-locale-server-loader.mjs.map +1 -0
- package/build/plugin/next.cjs +220 -0
- package/build/plugin/next.d.cts +9 -0
- package/build/plugin/next.d.cts.map +1 -0
- package/build/plugin/next.d.mts +9 -0
- package/build/plugin/next.d.mts.map +1 -0
- package/build/plugin/next.mjs +222 -0
- package/build/plugin/next.mjs.map +1 -0
- package/build/plugin/transform/babel-compat.cjs +13 -0
- package/build/plugin/transform/babel-compat.mjs +10 -0
- package/build/plugin/transform/babel-compat.mjs.map +1 -0
- package/build/plugin/transform/index.cjs +44 -0
- package/build/plugin/transform/index.mjs +42 -0
- package/build/plugin/transform/index.mjs.map +1 -0
- package/build/plugin/transform/metadata.cjs +142 -0
- package/build/plugin/transform/metadata.mjs +141 -0
- package/build/plugin/transform/metadata.mjs.map +1 -0
- package/build/plugin/transform/parse-override.cjs +145 -0
- package/build/plugin/transform/parse-override.mjs +144 -0
- package/build/plugin/transform/parse-override.mjs.map +1 -0
- package/build/plugin/transform/process-file.cjs +391 -0
- package/build/plugin/transform/process-file.mjs +390 -0
- package/build/plugin/transform/process-file.mjs.map +1 -0
- package/build/plugin/transform/use-i18n.cjs +8 -0
- package/build/plugin/transform/use-i18n.mjs +7 -0
- package/build/plugin/transform/use-i18n.mjs.map +1 -0
- package/build/plugin/transform/utils.cjs +205 -0
- package/build/plugin/transform/utils.mjs +192 -0
- package/build/plugin/transform/utils.mjs.map +1 -0
- package/build/plugin/unplugin.cjs +188 -0
- package/build/plugin/unplugin.d.cts +8 -0
- package/build/plugin/unplugin.d.cts.map +1 -0
- package/build/plugin/unplugin.d.mts +8 -0
- package/build/plugin/unplugin.d.mts.map +1 -0
- package/build/plugin/unplugin.mjs +186 -0
- package/build/plugin/unplugin.mjs.map +1 -0
- package/build/plugin/vite.cjs +28 -0
- package/build/plugin/vite.d.cts +9 -0
- package/build/plugin/vite.d.cts.map +1 -0
- package/build/plugin/vite.d.mts +9 -0
- package/build/plugin/vite.d.mts.map +1 -0
- package/build/plugin/vite.mjs +29 -0
- package/build/plugin/vite.mjs.map +1 -0
- package/build/plugin/webpack.cjs +27 -0
- package/build/plugin/webpack.d.cts +8 -0
- package/build/plugin/webpack.d.cts.map +1 -0
- package/build/plugin/webpack.d.mts +8 -0
- package/build/plugin/webpack.d.mts.map +1 -0
- package/build/plugin/webpack.mjs +28 -0
- package/build/plugin/webpack.mjs.map +1 -0
- package/build/react/client/index.cjs +9 -0
- package/build/react/client/index.d.cts +5 -0
- package/build/react/client/index.d.mts +5 -0
- package/build/react/client/index.mjs +6 -0
- package/build/react/client/useTranslation.cjs +71 -0
- package/build/react/client/useTranslation.d.cts +42 -0
- package/build/react/client/useTranslation.d.cts.map +1 -0
- package/build/react/client/useTranslation.d.mts +42 -0
- package/build/react/client/useTranslation.d.mts.map +1 -0
- package/build/react/client/useTranslation.mjs +71 -0
- package/build/react/client/useTranslation.mjs.map +1 -0
- package/build/react/next/client.cjs +25 -0
- package/build/react/next/client.d.cts +9 -0
- package/build/react/next/client.d.cts.map +1 -0
- package/build/react/next/client.d.mts +9 -0
- package/build/react/next/client.d.mts.map +1 -0
- package/build/react/next/client.mjs +24 -0
- package/build/react/next/client.mjs.map +1 -0
- package/build/react/next/cookie-locale-resolver.cjs +29 -0
- package/build/react/next/cookie-locale-resolver.d.cts +33 -0
- package/build/react/next/cookie-locale-resolver.d.cts.map +1 -0
- package/build/react/next/cookie-locale-resolver.d.mts +33 -0
- package/build/react/next/cookie-locale-resolver.d.mts.map +1 -0
- package/build/react/next/cookie-locale-resolver.mjs +29 -0
- package/build/react/next/cookie-locale-resolver.mjs.map +1 -0
- package/build/react/next/server.cjs +21 -0
- package/build/react/next/server.d.cts +13 -0
- package/build/react/next/server.d.cts.map +1 -0
- package/build/react/next/server.d.mts +14 -0
- package/build/react/next/server.d.mts.map +1 -0
- package/build/react/next/server.mjs +20 -0
- package/build/react/next/server.mjs.map +1 -0
- package/build/react/server/ServerLingoProvider.cjs +19 -0
- package/build/react/server/ServerLingoProvider.d.cts +12 -0
- package/build/react/server/ServerLingoProvider.d.cts.map +1 -0
- package/build/react/server/ServerLingoProvider.d.mts +12 -0
- package/build/react/server/ServerLingoProvider.d.mts.map +1 -0
- package/build/react/server/ServerLingoProvider.mjs +19 -0
- package/build/react/server/ServerLingoProvider.mjs.map +1 -0
- package/build/react/server/index.cjs +7 -0
- package/build/react/server/index.d.cts +4 -0
- package/build/react/server/index.d.mts +4 -0
- package/build/react/server/index.mjs +5 -0
- package/build/react/server/useTranslation.cjs +60 -0
- package/build/react/server/useTranslation.d.cts +36 -0
- package/build/react/server/useTranslation.d.cts.map +1 -0
- package/build/react/server/useTranslation.d.mts +36 -0
- package/build/react/server/useTranslation.d.mts.map +1 -0
- package/build/react/server/useTranslation.mjs +60 -0
- package/build/react/server/useTranslation.mjs.map +1 -0
- package/build/react/server-only/index.cjs +42 -0
- package/build/react/server-only/index.d.cts +38 -0
- package/build/react/server-only/index.d.cts.map +1 -0
- package/build/react/server-only/index.d.mts +38 -0
- package/build/react/server-only/index.d.mts.map +1 -0
- package/build/react/server-only/index.mjs +42 -0
- package/build/react/server-only/index.mjs.map +1 -0
- package/build/react/server-only/translations.cjs +85 -0
- package/build/react/server-only/translations.mjs +85 -0
- package/build/react/server-only/translations.mjs.map +1 -0
- package/build/react/shared/LingoContext.cjs +14 -0
- package/build/react/shared/LingoContext.d.cts +41 -0
- package/build/react/shared/LingoContext.d.cts.map +1 -0
- package/build/react/shared/LingoContext.d.mts +41 -0
- package/build/react/shared/LingoContext.d.mts.map +1 -0
- package/build/react/shared/LingoContext.mjs +13 -0
- package/build/react/shared/LingoContext.mjs.map +1 -0
- package/build/react/shared/LingoProvider.cjs +274 -0
- package/build/react/shared/LingoProvider.d.cts +76 -0
- package/build/react/shared/LingoProvider.d.cts.map +1 -0
- package/build/react/shared/LingoProvider.d.mts +76 -0
- package/build/react/shared/LingoProvider.d.mts.map +1 -0
- package/build/react/shared/LingoProvider.mjs +274 -0
- package/build/react/shared/LingoProvider.mjs.map +1 -0
- package/build/react/shared/LocaleSwitcher.cjs +61 -0
- package/build/react/shared/LocaleSwitcher.d.cts +71 -0
- package/build/react/shared/LocaleSwitcher.d.cts.map +1 -0
- package/build/react/shared/LocaleSwitcher.d.mts +71 -0
- package/build/react/shared/LocaleSwitcher.d.mts.map +1 -0
- package/build/react/shared/LocaleSwitcher.mjs +61 -0
- package/build/react/shared/LocaleSwitcher.mjs.map +1 -0
- package/build/react/shared/render-rich-text.cjs +55 -0
- package/build/react/shared/render-rich-text.d.cts +17 -0
- package/build/react/shared/render-rich-text.d.cts.map +1 -0
- package/build/react/shared/render-rich-text.d.mts +17 -0
- package/build/react/shared/render-rich-text.d.mts.map +1 -0
- package/build/react/shared/render-rich-text.mjs +54 -0
- package/build/react/shared/render-rich-text.mjs.map +1 -0
- package/build/react/shared/utils.cjs +34 -0
- package/build/react/shared/utils.mjs +35 -0
- package/build/react/shared/utils.mjs.map +1 -0
- package/build/react/types.d.cts +16 -0
- package/build/react/types.d.cts.map +1 -0
- package/build/react/types.d.mts +16 -0
- package/build/react/types.d.mts.map +1 -0
- package/build/translation-server/logger.cjs +37 -0
- package/build/translation-server/logger.mjs +37 -0
- package/build/translation-server/logger.mjs.map +1 -0
- package/build/translation-server/translation-server.cjs +547 -0
- package/build/translation-server/translation-server.mjs +544 -0
- package/build/translation-server/translation-server.mjs.map +1 -0
- package/build/translation-server/ws-events.cjs +15 -0
- package/build/translation-server/ws-events.mjs +15 -0
- package/build/translation-server/ws-events.mjs.map +1 -0
- package/build/translators/api.cjs +12 -0
- package/build/translators/api.mjs +12 -0
- package/build/translators/api.mjs.map +1 -0
- package/build/translators/cache-factory.cjs +26 -0
- package/build/translators/cache-factory.mjs +27 -0
- package/build/translators/cache-factory.mjs.map +1 -0
- package/build/translators/lingo/model-factory.cjs +179 -0
- package/build/translators/lingo/model-factory.mjs +174 -0
- package/build/translators/lingo/model-factory.mjs.map +1 -0
- package/build/translators/lingo/prompt.cjs +43 -0
- package/build/translators/lingo/prompt.mjs +43 -0
- package/build/translators/lingo/prompt.mjs.map +1 -0
- package/build/translators/lingo/service.cjs +152 -0
- package/build/translators/lingo/service.mjs +152 -0
- package/build/translators/lingo/service.mjs.map +1 -0
- package/build/translators/lingo/shots.cjs +28 -0
- package/build/translators/lingo/shots.mjs +28 -0
- package/build/translators/lingo/shots.mjs.map +1 -0
- package/build/translators/local-cache.cjs +115 -0
- package/build/translators/local-cache.mjs +113 -0
- package/build/translators/local-cache.mjs.map +1 -0
- package/build/translators/parse-xml.cjs +109 -0
- package/build/translators/parse-xml.mjs +108 -0
- package/build/translators/parse-xml.mjs.map +1 -0
- package/build/translators/pluralization/icu-validator.cjs +36 -0
- package/build/translators/pluralization/icu-validator.mjs +36 -0
- package/build/translators/pluralization/icu-validator.mjs.map +1 -0
- package/build/translators/pluralization/pattern-detector.cjs +25 -0
- package/build/translators/pluralization/pattern-detector.mjs +25 -0
- package/build/translators/pluralization/pattern-detector.mjs.map +1 -0
- package/build/translators/pluralization/prompt.cjs +98 -0
- package/build/translators/pluralization/prompt.mjs +98 -0
- package/build/translators/pluralization/prompt.mjs.map +1 -0
- package/build/translators/pluralization/service.cjs +247 -0
- package/build/translators/pluralization/service.mjs +247 -0
- package/build/translators/pluralization/service.mjs.map +1 -0
- package/build/translators/pluralization/shots.cjs +53 -0
- package/build/translators/pluralization/shots.mjs +53 -0
- package/build/translators/pluralization/shots.mjs.map +1 -0
- package/build/translators/pluralization/types.d.cts +17 -0
- package/build/translators/pluralization/types.d.cts.map +1 -0
- package/build/translators/pluralization/types.d.mts +17 -0
- package/build/translators/pluralization/types.d.mts.map +1 -0
- package/build/translators/pseudotranslator/index.cjs +129 -0
- package/build/translators/pseudotranslator/index.mjs +129 -0
- package/build/translators/pseudotranslator/index.mjs.map +1 -0
- package/build/translators/translation-service.cjs +182 -0
- package/build/translators/translation-service.mjs +183 -0
- package/build/translators/translation-service.mjs.map +1 -0
- package/build/translators/translator-factory.cjs +49 -0
- package/build/translators/translator-factory.mjs +50 -0
- package/build/translators/translator-factory.mjs.map +1 -0
- package/build/types.d.cts +161 -0
- package/build/types.d.cts.map +1 -0
- package/build/types.d.mts +161 -0
- package/build/types.d.mts.map +1 -0
- package/build/utils/config-factory.cjs +58 -0
- package/build/utils/config-factory.mjs +58 -0
- package/build/utils/config-factory.mjs.map +1 -0
- package/build/utils/hash.cjs +17 -0
- package/build/utils/hash.mjs +16 -0
- package/build/utils/hash.mjs.map +1 -0
- package/build/utils/is-valid-locale.cjs +14 -0
- package/build/utils/is-valid-locale.mjs +14 -0
- package/build/utils/is-valid-locale.mjs.map +1 -0
- package/build/utils/logger.cjs +51 -0
- package/build/utils/logger.mjs +50 -0
- package/build/utils/logger.mjs.map +1 -0
- package/build/utils/path-helpers.cjs +49 -0
- package/build/utils/path-helpers.mjs +47 -0
- package/build/utils/path-helpers.mjs.map +1 -0
- package/build/utils/timeout.cjs +42 -0
- package/build/utils/timeout.mjs +41 -0
- package/build/utils/timeout.mjs.map +1 -0
- package/build/virtual/code-generator.cjs +54 -0
- package/build/virtual/code-generator.mjs +53 -0
- package/build/virtual/code-generator.mjs.map +1 -0
- package/build/virtual/config.cjs +10 -0
- package/build/virtual/config.d.cts +9 -0
- package/build/virtual/config.d.cts.map +1 -0
- package/build/virtual/config.d.mts +9 -0
- package/build/virtual/config.d.mts.map +1 -0
- package/build/virtual/config.mjs +8 -0
- package/build/virtual/config.mjs.map +1 -0
- package/build/virtual/locale/client.cjs +23 -0
- package/build/virtual/locale/client.d.cts +19 -0
- package/build/virtual/locale/client.d.cts.map +1 -0
- package/build/virtual/locale/client.d.mts +19 -0
- package/build/virtual/locale/client.d.mts.map +1 -0
- package/build/virtual/locale/client.mjs +22 -0
- package/build/virtual/locale/client.mjs.map +1 -0
- package/build/virtual/locale/server.cjs +13 -0
- package/build/virtual/locale/server.d.cts +13 -0
- package/build/virtual/locale/server.d.cts.map +1 -0
- package/build/virtual/locale/server.d.mts +13 -0
- package/build/virtual/locale/server.d.mts.map +1 -0
- package/build/virtual/locale/server.mjs +13 -0
- package/build/virtual/locale/server.mjs.map +1 -0
- package/build/widget/lingo-dev-widget.cjs +228 -0
- package/build/widget/lingo-dev-widget.mjs +229 -0
- package/build/widget/lingo-dev-widget.mjs.map +1 -0
- 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"}
|