@lingo.dev/compiler 0.1.2 → 0.1.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.
- package/build/plugin/build-translator.cjs +3 -3
- package/build/plugin/build-translator.mjs +3 -3
- package/build/plugin/build-translator.mjs.map +1 -1
- package/build/plugin/next.cjs +3 -3
- package/build/plugin/next.d.cts.map +1 -1
- package/build/plugin/next.d.mts.map +1 -1
- package/build/plugin/next.mjs +3 -3
- package/build/plugin/next.mjs.map +1 -1
- package/build/plugin/unplugin.cjs +81 -2
- package/build/plugin/unplugin.d.cts.map +1 -1
- package/build/plugin/unplugin.d.mts.map +1 -1
- package/build/plugin/unplugin.mjs +81 -2
- package/build/plugin/unplugin.mjs.map +1 -1
- package/build/react/server/ServerLingoProvider.d.cts +2 -2
- package/build/react/shared/LingoProvider.d.cts +2 -2
- package/build/react/shared/LocaleSwitcher.d.cts +2 -2
- package/build/translation-server/translation-server.cjs +7 -17
- package/build/translation-server/translation-server.mjs +7 -17
- package/build/translation-server/translation-server.mjs.map +1 -1
- package/build/translators/cache-factory.mjs.map +1 -1
- package/build/translators/lingo/model-factory.cjs +5 -10
- package/build/translators/lingo/model-factory.mjs +5 -10
- package/build/translators/lingo/model-factory.mjs.map +1 -1
- package/build/translators/lingo/provider-details.cjs +69 -0
- package/build/translators/lingo/provider-details.mjs +69 -0
- package/build/translators/lingo/provider-details.mjs.map +1 -0
- package/build/translators/lingo/{service.cjs → translator.cjs} +11 -13
- package/build/translators/lingo/{service.mjs → translator.mjs} +12 -14
- package/build/translators/lingo/translator.mjs.map +1 -0
- package/build/translators/memory-cache.cjs +47 -0
- package/build/translators/memory-cache.mjs +47 -0
- package/build/translators/memory-cache.mjs.map +1 -0
- package/build/translators/pluralization/service.cjs +19 -44
- package/build/translators/pluralization/service.mjs +19 -44
- package/build/translators/pluralization/service.mjs.map +1 -1
- package/build/translators/pseudotranslator/index.cjs +2 -10
- package/build/translators/pseudotranslator/index.mjs +2 -10
- package/build/translators/pseudotranslator/index.mjs.map +1 -1
- package/build/translators/translation-service.cjs +55 -57
- package/build/translators/translation-service.mjs +55 -57
- package/build/translators/translation-service.mjs.map +1 -1
- package/build/utils/observability.cjs +84 -0
- package/build/utils/observability.mjs +83 -0
- package/build/utils/observability.mjs.map +1 -0
- package/build/utils/rc.cjs +21 -0
- package/build/utils/rc.mjs +17 -0
- package/build/utils/rc.mjs.map +1 -0
- package/build/utils/repository-id.cjs +64 -0
- package/build/utils/repository-id.mjs +64 -0
- package/build/utils/repository-id.mjs.map +1 -0
- package/build/utils/tracking-events.cjs +28 -0
- package/build/utils/tracking-events.mjs +25 -0
- package/build/utils/tracking-events.mjs.map +1 -0
- package/package.json +12 -8
- package/build/translators/lingo/service.mjs.map +0 -1
- package/build/translators/translator-factory.cjs +0 -49
- package/build/translators/translator-factory.mjs +0 -50
- package/build/translators/translator-factory.mjs.map +0 -1
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/utils/tracking-events.ts
|
|
3
|
+
const TRACKING_EVENTS = {
|
|
4
|
+
BUILD_START: "compiler.build.start",
|
|
5
|
+
BUILD_SUCCESS: "compiler.build.success",
|
|
6
|
+
BUILD_ERROR: "compiler.build.error"
|
|
7
|
+
};
|
|
8
|
+
const TRACKING_VERSION = "3.0";
|
|
9
|
+
const COMPILER_PACKAGE = "@lingo.dev/compiler";
|
|
10
|
+
function sanitizeConfigForTracking(config) {
|
|
11
|
+
return {
|
|
12
|
+
sourceLocale: config.sourceLocale,
|
|
13
|
+
targetLocalesCount: config.targetLocales.length,
|
|
14
|
+
hasCustomModels: config.models !== "lingo.dev",
|
|
15
|
+
isByokMode: config.models !== "lingo.dev",
|
|
16
|
+
useDirective: config.useDirective,
|
|
17
|
+
buildMode: config.buildMode,
|
|
18
|
+
hasPluralisation: config.pluralization.enabled,
|
|
19
|
+
hasCustomPrompt: !!config.prompt,
|
|
20
|
+
hasCustomLocaleResolver: false
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
//#endregion
|
|
25
|
+
exports.COMPILER_PACKAGE = COMPILER_PACKAGE;
|
|
26
|
+
exports.TRACKING_EVENTS = TRACKING_EVENTS;
|
|
27
|
+
exports.TRACKING_VERSION = TRACKING_VERSION;
|
|
28
|
+
exports.sanitizeConfigForTracking = sanitizeConfigForTracking;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//#region src/utils/tracking-events.ts
|
|
2
|
+
const TRACKING_EVENTS = {
|
|
3
|
+
BUILD_START: "compiler.build.start",
|
|
4
|
+
BUILD_SUCCESS: "compiler.build.success",
|
|
5
|
+
BUILD_ERROR: "compiler.build.error"
|
|
6
|
+
};
|
|
7
|
+
const TRACKING_VERSION = "3.0";
|
|
8
|
+
const COMPILER_PACKAGE = "@lingo.dev/compiler";
|
|
9
|
+
function sanitizeConfigForTracking(config) {
|
|
10
|
+
return {
|
|
11
|
+
sourceLocale: config.sourceLocale,
|
|
12
|
+
targetLocalesCount: config.targetLocales.length,
|
|
13
|
+
hasCustomModels: config.models !== "lingo.dev",
|
|
14
|
+
isByokMode: config.models !== "lingo.dev",
|
|
15
|
+
useDirective: config.useDirective,
|
|
16
|
+
buildMode: config.buildMode,
|
|
17
|
+
hasPluralisation: config.pluralization.enabled,
|
|
18
|
+
hasCustomPrompt: !!config.prompt,
|
|
19
|
+
hasCustomLocaleResolver: false
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
export { COMPILER_PACKAGE, TRACKING_EVENTS, TRACKING_VERSION, sanitizeConfigForTracking };
|
|
25
|
+
//# sourceMappingURL=tracking-events.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracking-events.mjs","names":[],"sources":["../../src/utils/tracking-events.ts"],"sourcesContent":["import type { LingoConfig } from \"../types\";\n\nexport const TRACKING_EVENTS = {\n BUILD_START: \"compiler.build.start\",\n BUILD_SUCCESS: \"compiler.build.success\",\n BUILD_ERROR: \"compiler.build.error\",\n} as const;\n\nexport const TRACKING_VERSION = \"3.0\";\n\nexport const COMPILER_PACKAGE = \"@lingo.dev/compiler\";\n\nexport function sanitizeConfigForTracking(config: LingoConfig) {\n return {\n sourceLocale: config.sourceLocale,\n targetLocalesCount: config.targetLocales.length,\n hasCustomModels: config.models !== \"lingo.dev\",\n isByokMode: config.models !== \"lingo.dev\",\n useDirective: config.useDirective,\n buildMode: config.buildMode,\n hasPluralisation: config.pluralization.enabled,\n hasCustomPrompt: !!config.prompt,\n hasCustomLocaleResolver: false,\n };\n}\n"],"mappings":";AAEA,MAAa,kBAAkB;CAC7B,aAAa;CACb,eAAe;CACf,aAAa;CACd;AAED,MAAa,mBAAmB;AAEhC,MAAa,mBAAmB;AAEhC,SAAgB,0BAA0B,QAAqB;AAC7D,QAAO;EACL,cAAc,OAAO;EACrB,oBAAoB,OAAO,cAAc;EACzC,iBAAiB,OAAO,WAAW;EACnC,YAAY,OAAO,WAAW;EAC9B,cAAc,OAAO;EACrB,WAAW,OAAO;EAClB,kBAAkB,OAAO,cAAc;EACvC,iBAAiB,CAAC,CAAC,OAAO;EAC1B,yBAAyB;EAC1B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lingo.dev/compiler",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Lingo.dev Compiler",
|
|
5
5
|
"private": false,
|
|
6
6
|
"repository": {
|
|
@@ -124,6 +124,7 @@
|
|
|
124
124
|
"@types/babel__core": "^7.20.5",
|
|
125
125
|
"@types/babel__generator": "^7.27.0",
|
|
126
126
|
"@types/babel__traverse": "^7.28.0",
|
|
127
|
+
"@types/ini": "4.1.1",
|
|
127
128
|
"@types/node": "^25.0.3",
|
|
128
129
|
"@types/proper-lockfile": "^4.1.4",
|
|
129
130
|
"@types/react": "^19.2.7",
|
|
@@ -153,11 +154,14 @@
|
|
|
153
154
|
"ai-sdk-ollama": "^3.0.0",
|
|
154
155
|
"dotenv": "^17.2.3",
|
|
155
156
|
"fast-xml-parser": "^5.3.3",
|
|
157
|
+
"ini": "5.0.0",
|
|
156
158
|
"intl-messageformat": "^11.0.6",
|
|
157
|
-
"lingo.dev": "^0.117.21",
|
|
158
159
|
"lodash": "^4.17.21",
|
|
160
|
+
"node-machine-id": "1.1.12",
|
|
161
|
+
"posthog-node": "5.14.0",
|
|
159
162
|
"proper-lockfile": "^4.1.2",
|
|
160
|
-
"ws": "^8.18.3"
|
|
163
|
+
"ws": "^8.18.3",
|
|
164
|
+
"lingo.dev": "^0.117.25"
|
|
161
165
|
},
|
|
162
166
|
"peerDependencies": {
|
|
163
167
|
"next": "^15.0.0 || ^16.0.4",
|
|
@@ -176,11 +180,11 @@
|
|
|
176
180
|
"clean": "rm -rf build",
|
|
177
181
|
"test": "vitest --run",
|
|
178
182
|
"test:watch": "vitest -w",
|
|
179
|
-
"test:prepare": "
|
|
180
|
-
"test:e2e": "playwright test
|
|
181
|
-
"test:e2e:next": "playwright test --grep next
|
|
182
|
-
"test:e2e:vite": "playwright test --grep vite
|
|
183
|
-
"test:e2e:shared": "playwright test tests/e2e/shared
|
|
183
|
+
"test:e2e:prepare": "tsx tests/helpers/prepare-fixtures.ts",
|
|
184
|
+
"test:e2e": "playwright test",
|
|
185
|
+
"test:e2e:next": "playwright test --grep next",
|
|
186
|
+
"test:e2e:vite": "playwright test --grep vite",
|
|
187
|
+
"test:e2e:shared": "playwright test tests/e2e/shared",
|
|
184
188
|
"test:e2e:headed": "playwright test --headed",
|
|
185
189
|
"test:e2e:ui": "playwright test --ui",
|
|
186
190
|
"test:e2e:debug": "playwright test --debug",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"service.mjs","names":["config: LingoTranslatorConfig","logger: Logger","sourceDictionary: DictionarySchema","translatedChunks: DictionarySchema[]","chunks: DictionarySchema[]","mergedEntries: Record<string, string>"],"sources":["../../../src/translators/lingo/service.ts"],"sourcesContent":["import { generateText } from \"ai\";\nimport { LingoDotDevEngine } from \"lingo.dev/sdk\";\nimport {\n dictionaryFrom,\n type DictionarySchema,\n type TranslatableEntry,\n type Translator,\n} from \"../api\";\nimport { getSystemPrompt } from \"./prompt\";\nimport { obj2xml, parseXmlFromResponseText } from \"../parse-xml\";\nimport { shots } from \"./shots\";\nimport {\n createAiModel,\n getLocaleModel,\n validateAndGetApiKeys,\n type ValidatedApiKeys,\n} from \"./model-factory\";\nimport { Logger } from \"../../utils/logger\";\nimport { DEFAULT_TIMEOUTS, withTimeout } from \"../../utils/timeout\";\nimport type { LocaleCode } from \"lingo.dev/spec\";\n\n/**\n * Lingo Translator configuration\n */\nexport interface LingoTranslatorConfig {\n models: \"lingo.dev\" | Record<string, string>;\n sourceLocale: LocaleCode;\n prompt?: string;\n}\n\n/**\n * Lingo translator using AI models\n */\nexport class Service implements Translator<LingoTranslatorConfig> {\n private readonly validatedKeys: ValidatedApiKeys;\n\n constructor(\n readonly config: LingoTranslatorConfig,\n private logger: Logger,\n ) {\n this.logger.info(\"Validating API keys for translation...\");\n this.validatedKeys = validateAndGetApiKeys(config.models);\n this.logger.info(\"✅ API keys validated successfully\");\n }\n\n /**\n * Translate multiple entries\n */\n async translate(\n locale: LocaleCode,\n entriesMap: Record<string, TranslatableEntry>,\n ): Promise<Record<string, string>> {\n this.logger.debug(\n `[TRACE-LINGO] translate() called for ${locale} with ${Object.keys(entriesMap).length} entries`,\n );\n\n const sourceDictionary: DictionarySchema = dictionaryFrom(\n this.config.sourceLocale,\n Object.fromEntries(\n Object.entries(entriesMap).map(([hash, entry]) => [hash, entry.text]),\n ),\n );\n\n this.logger.debug(\n `[TRACE-LINGO] Created source dictionary with ${Object.keys(sourceDictionary.entries).length} entries`,\n );\n const translated = await this.translateDictionary(sourceDictionary, locale);\n\n return translated.entries || {};\n }\n\n /**\n * Translate a complete dictionary\n */\n private async translateDictionary(\n sourceDictionary: DictionarySchema,\n targetLocale: string,\n ): Promise<DictionarySchema> {\n this.logger.debug(\n `[TRACE-LINGO] Chunking dictionary with ${Object.keys(sourceDictionary.entries).length} entries`,\n );\n const chunks = this.chunkDictionary(sourceDictionary);\n this.logger.debug(`[TRACE-LINGO] Split into ${chunks.length} chunks`);\n\n const translatedChunks: DictionarySchema[] = [];\n\n for (let i = 0; i < chunks.length; i++) {\n const chunk = chunks[i];\n this.logger.debug(\n `[TRACE-LINGO] Translating chunk ${i + 1}/${chunks.length} with ${Object.keys(chunk.entries).length} entries`,\n );\n const chunkStartTime = performance.now();\n\n const translatedChunk = await this.translateChunk(chunk, targetLocale);\n\n const chunkEndTime = performance.now();\n this.logger.debug(\n `[TRACE-LINGO] Chunk ${i + 1}/${chunks.length} completed in ${(chunkEndTime - chunkStartTime).toFixed(2)}ms`,\n );\n\n translatedChunks.push(translatedChunk);\n }\n\n this.logger.debug(`[TRACE-LINGO] All chunks translated, merging results`);\n const result = this.mergeDictionaries(translatedChunks);\n this.logger.debug(\n `[TRACE-LINGO] Merge completed, final dictionary has ${Object.keys(result.entries).length} entries`,\n );\n\n return result;\n }\n\n /**\n * Translate a single chunk\n */\n private async translateChunk(\n sourceDictionary: DictionarySchema,\n targetLocale: string,\n ): Promise<DictionarySchema> {\n if (this.config.models === \"lingo.dev\") {\n return this.translateWithLingoDotDev(sourceDictionary, targetLocale);\n } else {\n return this.translateWithLLM(sourceDictionary, targetLocale);\n }\n }\n\n /**\n * Translate using Lingo.dev Engine\n * Times out after 60 seconds to prevent indefinite hangs\n */\n private async translateWithLingoDotDev(\n sourceDictionary: DictionarySchema,\n targetLocale: string,\n ): Promise<DictionarySchema> {\n const apiKey = this.validatedKeys[\"lingo.dev\"];\n if (!apiKey) {\n throw new Error(\n \"Internal error: Lingo.dev API key not found after validation. Please restart the service.\",\n );\n }\n\n this.logger.info(\n `Using Lingo.dev Engine to localize from \"${this.config.sourceLocale}\" to \"${targetLocale}\"`,\n );\n\n const engine = new LingoDotDevEngine({ apiKey });\n\n try {\n const result = await withTimeout(\n engine.localizeObject(sourceDictionary, {\n sourceLocale: this.config.sourceLocale,\n targetLocale: targetLocale,\n }),\n DEFAULT_TIMEOUTS.AI_API,\n `Lingo.dev API translation to ${targetLocale}`,\n );\n\n return result as DictionarySchema;\n } catch (error) {\n this.logger.error(`translateWithLingoDotDev() failed:`, error);\n throw new Error(\n `Lingo.dev translation failed: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n\n /**\n * Translate using generic LLM\n * Times out after 60 seconds to prevent indefinite hangs\n */\n private async translateWithLLM(\n sourceDictionary: DictionarySchema,\n targetLocale: string,\n ): Promise<DictionarySchema> {\n const localeModel = getLocaleModel(\n this.config.models as Record<string, string>,\n this.config.sourceLocale,\n targetLocale,\n );\n\n if (!localeModel) {\n throw new Error(\n `No model configured for translation from ${this.config.sourceLocale} to ${targetLocale}`,\n );\n }\n\n this.logger.info(\n `Using LLM (\"${localeModel.provider}\":\"${localeModel.name}\") to translate from \"${this.config.sourceLocale}\" to \"${targetLocale}\"`,\n );\n\n const aiModel = createAiModel(localeModel, this.validatedKeys);\n\n try {\n const response = await withTimeout(\n generateText({\n model: aiModel,\n messages: [\n {\n role: \"system\",\n content: getSystemPrompt({\n sourceLocale: this.config.sourceLocale,\n targetLocale,\n prompt: this.config.prompt,\n }),\n },\n // Add few-shot examples\n ...shots.flatMap((shotsTuple) => [\n {\n role: \"user\" as const,\n content: obj2xml(shotsTuple[0]),\n },\n {\n role: \"assistant\" as const,\n content: obj2xml(shotsTuple[1]),\n },\n ]),\n {\n role: \"user\",\n content: obj2xml(sourceDictionary),\n },\n ],\n }),\n DEFAULT_TIMEOUTS.AI_API,\n `${localeModel.provider} LLM translation to ${targetLocale}`,\n );\n\n return parseXmlFromResponseText<DictionarySchema>(response.text);\n } catch (error) {\n throw new Error(\n `LLM translation failed with ${localeModel.provider}: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n\n /**\n * Split dictionary into chunks for processing\n */\n private chunkDictionary(dictionary: DictionarySchema): DictionarySchema[] {\n const MAX_ENTRIES_PER_CHUNK = 100;\n const { entries, ...rest } = dictionary;\n const chunks: DictionarySchema[] = [];\n\n const entryPairs = Object.entries(entries);\n\n // Split entries into chunks of MAX_ENTRIES_PER_CHUNK\n for (let i = 0; i < entryPairs.length; i += MAX_ENTRIES_PER_CHUNK) {\n const chunkEntries = entryPairs.slice(i, i + MAX_ENTRIES_PER_CHUNK);\n chunks.push({\n ...rest,\n entries: Object.fromEntries(chunkEntries),\n });\n }\n\n return chunks;\n }\n\n /**\n * Merge multiple dictionaries into one\n */\n private mergeDictionaries(\n dictionaries: DictionarySchema[],\n ): DictionarySchema {\n if (dictionaries.length === 0) {\n return dictionaryFrom(this.config.sourceLocale, {});\n }\n\n // Merge all entries from all dictionaries\n const mergedEntries: Record<string, string> = {};\n for (const dict of dictionaries) {\n Object.assign(mergedEntries, dict.entries);\n }\n\n return {\n version: dictionaries[0].version,\n locale: dictionaries[0].locale,\n entries: mergedEntries,\n };\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
const require_index = require('./pseudotranslator/index.cjs');
|
|
2
|
-
const require_service = require('./lingo/service.cjs');
|
|
3
|
-
|
|
4
|
-
//#region src/translators/translator-factory.ts
|
|
5
|
-
/**
|
|
6
|
-
* Create a translator instance based on configuration
|
|
7
|
-
*
|
|
8
|
-
* Development mode behavior:
|
|
9
|
-
* - If translator is "pseudo" or dev.usePseudotranslator is true, use pseudotranslator
|
|
10
|
-
* - If API keys are missing, auto-fallback to pseudotranslator (with warning)
|
|
11
|
-
* - Otherwise, create real translator
|
|
12
|
-
*
|
|
13
|
-
* Production mode behavior:
|
|
14
|
-
* - Always require real translator with valid API keys
|
|
15
|
-
* - Throw error if API keys are missing
|
|
16
|
-
*
|
|
17
|
-
* Note: Translators are stateless and don't handle caching.
|
|
18
|
-
* Caching is handled by TranslationService layer.
|
|
19
|
-
*
|
|
20
|
-
* API key validation is now done in the LingoTranslator constructor
|
|
21
|
-
* which validates and fetches all keys once at initialization.
|
|
22
|
-
*/
|
|
23
|
-
function createTranslator(config, logger) {
|
|
24
|
-
const isDev = config.environment === "development";
|
|
25
|
-
if (isDev && config.dev?.usePseudotranslator) {
|
|
26
|
-
logger.info("📝 Using pseudotranslator (dev.usePseudotranslator enabled)");
|
|
27
|
-
return new require_index.PseudoTranslator({ delayMedian: 100 }, logger);
|
|
28
|
-
}
|
|
29
|
-
try {
|
|
30
|
-
const models = config.models;
|
|
31
|
-
logger.info(`Creating Lingo translator with models: ${JSON.stringify(models)}`);
|
|
32
|
-
return new require_service.Service({
|
|
33
|
-
models,
|
|
34
|
-
sourceLocale: config.sourceLocale,
|
|
35
|
-
prompt: config.prompt
|
|
36
|
-
}, logger);
|
|
37
|
-
} catch (error) {
|
|
38
|
-
if (isDev) {
|
|
39
|
-
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
40
|
-
logger.error(`\n❌ [Lingo] Translation setup error: ${errorMsg}\n`);
|
|
41
|
-
logger.warn("⚠️ [Lingo] Auto-fallback to pseudotranslator in development mode.\n Set the required API keys for real translations.\n");
|
|
42
|
-
return new require_index.PseudoTranslator({ delayMedian: 100 }, logger);
|
|
43
|
-
}
|
|
44
|
-
throw error;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
//#endregion
|
|
49
|
-
exports.createTranslator = createTranslator;
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { PseudoTranslator } from "./pseudotranslator/index.mjs";
|
|
2
|
-
import { Service } from "./lingo/service.mjs";
|
|
3
|
-
|
|
4
|
-
//#region src/translators/translator-factory.ts
|
|
5
|
-
/**
|
|
6
|
-
* Create a translator instance based on configuration
|
|
7
|
-
*
|
|
8
|
-
* Development mode behavior:
|
|
9
|
-
* - If translator is "pseudo" or dev.usePseudotranslator is true, use pseudotranslator
|
|
10
|
-
* - If API keys are missing, auto-fallback to pseudotranslator (with warning)
|
|
11
|
-
* - Otherwise, create real translator
|
|
12
|
-
*
|
|
13
|
-
* Production mode behavior:
|
|
14
|
-
* - Always require real translator with valid API keys
|
|
15
|
-
* - Throw error if API keys are missing
|
|
16
|
-
*
|
|
17
|
-
* Note: Translators are stateless and don't handle caching.
|
|
18
|
-
* Caching is handled by TranslationService layer.
|
|
19
|
-
*
|
|
20
|
-
* API key validation is now done in the LingoTranslator constructor
|
|
21
|
-
* which validates and fetches all keys once at initialization.
|
|
22
|
-
*/
|
|
23
|
-
function createTranslator(config, logger) {
|
|
24
|
-
const isDev = config.environment === "development";
|
|
25
|
-
if (isDev && config.dev?.usePseudotranslator) {
|
|
26
|
-
logger.info("📝 Using pseudotranslator (dev.usePseudotranslator enabled)");
|
|
27
|
-
return new PseudoTranslator({ delayMedian: 100 }, logger);
|
|
28
|
-
}
|
|
29
|
-
try {
|
|
30
|
-
const models = config.models;
|
|
31
|
-
logger.info(`Creating Lingo translator with models: ${JSON.stringify(models)}`);
|
|
32
|
-
return new Service({
|
|
33
|
-
models,
|
|
34
|
-
sourceLocale: config.sourceLocale,
|
|
35
|
-
prompt: config.prompt
|
|
36
|
-
}, logger);
|
|
37
|
-
} catch (error) {
|
|
38
|
-
if (isDev) {
|
|
39
|
-
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
40
|
-
logger.error(`\n❌ [Lingo] Translation setup error: ${errorMsg}\n`);
|
|
41
|
-
logger.warn("⚠️ [Lingo] Auto-fallback to pseudotranslator in development mode.\n Set the required API keys for real translations.\n");
|
|
42
|
-
return new PseudoTranslator({ delayMedian: 100 }, logger);
|
|
43
|
-
}
|
|
44
|
-
throw error;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
//#endregion
|
|
49
|
-
export { createTranslator };
|
|
50
|
-
//# sourceMappingURL=translator-factory.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"translator-factory.mjs","names":[],"sources":["../../src/translators/translator-factory.ts"],"sourcesContent":["/**\n * Factory for creating translators based on configuration\n */\n\nimport type { Translator } from \"./api\";\nimport { PseudoTranslator } from \"./pseudotranslator\";\nimport { Service } from \"./lingo\";\nimport { Logger } from \"../utils/logger\";\nimport type { LocaleCode } from \"lingo.dev/spec\";\nimport type { LingoEnvironment } from \"../types\";\n\ninterface TranslatorFactoryConfig {\n sourceLocale: LocaleCode;\n models: \"lingo.dev\" | Record<string, string>;\n prompt?: string;\n environment: LingoEnvironment;\n dev?: {\n usePseudotranslator?: boolean;\n };\n}\n\n/**\n * Create a translator instance based on configuration\n *\n * Development mode behavior:\n * - If translator is \"pseudo\" or dev.usePseudotranslator is true, use pseudotranslator\n * - If API keys are missing, auto-fallback to pseudotranslator (with warning)\n * - Otherwise, create real translator\n *\n * Production mode behavior:\n * - Always require real translator with valid API keys\n * - Throw error if API keys are missing\n *\n * Note: Translators are stateless and don't handle caching.\n * Caching is handled by TranslationService layer.\n *\n * API key validation is now done in the LingoTranslator constructor\n * which validates and fetches all keys once at initialization.\n */\nexport function createTranslator(\n config: TranslatorFactoryConfig,\n logger: Logger,\n): Translator<unknown> {\n const isDev = config.environment === \"development\";\n\n // 1. Explicit dev override takes precedence\n if (isDev && config.dev?.usePseudotranslator) {\n logger.info(\"📝 Using pseudotranslator (dev.usePseudotranslator enabled)\");\n return new PseudoTranslator({ delayMedian: 100 }, logger);\n }\n\n // 2. Try to create real translator\n // LingoTranslator constructor will validate and fetch API keys\n // If validation fails, it will throw an error with helpful message\n try {\n const models = config.models;\n\n logger.info(\n `Creating Lingo translator with models: ${JSON.stringify(models)}`,\n );\n\n return new Service(\n {\n models,\n sourceLocale: config.sourceLocale,\n prompt: config.prompt,\n },\n logger,\n );\n } catch (error) {\n // 3. Auto-fallback in dev mode if creation fails\n if (isDev) {\n // Use console.error to ensure visibility in all contexts (loader, server, etc.)\n const errorMsg = error instanceof Error ? error.message : String(error);\n logger.error(`\\n❌ [Lingo] Translation setup error: ${errorMsg}\\n`);\n logger.warn(\n `⚠️ [Lingo] Auto-fallback to pseudotranslator in development mode.\\n` +\n ` Set the required API keys for real translations.\\n`,\n );\n\n return new PseudoTranslator({ delayMedian: 100 }, logger);\n }\n\n // 4. Fail in production\n throw error;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAuCA,SAAgB,iBACd,QACA,QACqB;CACrB,MAAM,QAAQ,OAAO,gBAAgB;AAGrC,KAAI,SAAS,OAAO,KAAK,qBAAqB;AAC5C,SAAO,KAAK,8DAA8D;AAC1E,SAAO,IAAI,iBAAiB,EAAE,aAAa,KAAK,EAAE,OAAO;;AAM3D,KAAI;EACF,MAAM,SAAS,OAAO;AAEtB,SAAO,KACL,0CAA0C,KAAK,UAAU,OAAO,GACjE;AAED,SAAO,IAAI,QACT;GACE;GACA,cAAc,OAAO;GACrB,QAAQ,OAAO;GAChB,EACD,OACD;UACM,OAAO;AAEd,MAAI,OAAO;GAET,MAAM,WAAW,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACvE,UAAO,MAAM,wCAAwC,SAAS,IAAI;AAClE,UAAO,KACL,4HAED;AAED,UAAO,IAAI,iBAAiB,EAAE,aAAa,KAAK,EAAE,OAAO;;AAI3D,QAAM"}
|