@lingo.dev/_compiler 0.2.4 → 0.3.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/build/index.cjs +263 -105
- package/build/index.d.cts +1 -1
- package/build/index.d.ts +1 -1
- package/build/index.mjs +256 -98
- package/package.json +5 -2
package/build/index.cjs
CHANGED
|
@@ -4,7 +4,7 @@ var _unplugin = require('unplugin');
|
|
|
4
4
|
// package.json
|
|
5
5
|
var package_default = {
|
|
6
6
|
name: "@lingo.dev/_compiler",
|
|
7
|
-
version: "0.
|
|
7
|
+
version: "0.3.0",
|
|
8
8
|
description: "Lingo.dev Compiler",
|
|
9
9
|
private: false,
|
|
10
10
|
publishConfig: {
|
|
@@ -46,6 +46,8 @@ var package_default = {
|
|
|
46
46
|
"@babel/parser": "^7.26.7",
|
|
47
47
|
"@babel/traverse": "^7.27.4",
|
|
48
48
|
"@babel/types": "^7.26.7",
|
|
49
|
+
"@lingo.dev/_sdk": "workspace:*",
|
|
50
|
+
"@openrouter/ai-sdk-provider": "^0.7.1",
|
|
49
51
|
ai: "^4.2.10",
|
|
50
52
|
dedent: "^1.6.0",
|
|
51
53
|
dotenv: "^16.4.5",
|
|
@@ -53,11 +55,13 @@ var package_default = {
|
|
|
53
55
|
ini: "^5.0.0",
|
|
54
56
|
lodash: "^4.17.21",
|
|
55
57
|
"object-hash": "^3.0.0",
|
|
58
|
+
"ollama-ai-provider": "^1.2.0",
|
|
56
59
|
prettier: "^3.4.2",
|
|
57
60
|
unplugin: "^2.1.2",
|
|
58
61
|
vitest: "^2.1.4",
|
|
59
62
|
zod: "^3.24.1"
|
|
60
|
-
}
|
|
63
|
+
},
|
|
64
|
+
packageManager: "pnpm@9.12.3"
|
|
61
65
|
};
|
|
62
66
|
|
|
63
67
|
// src/index.ts
|
|
@@ -926,7 +930,10 @@ var LCPCache = class {
|
|
|
926
930
|
// src/lib/lcp/api/index.ts
|
|
927
931
|
var _groq = require('@ai-sdk/groq');
|
|
928
932
|
var _google = require('@ai-sdk/google');
|
|
933
|
+
var _aisdkprovider = require('@openrouter/ai-sdk-provider');
|
|
934
|
+
var _ollamaaiprovider = require('ollama-ai-provider');
|
|
929
935
|
var _ai = require('ai');
|
|
936
|
+
var __sdk = require('@lingo.dev/_sdk');
|
|
930
937
|
|
|
931
938
|
|
|
932
939
|
// src/utils/locales.ts
|
|
@@ -949,7 +956,16 @@ function getLocaleModel(localeModels, sourceLocale, targetLocale) {
|
|
|
949
956
|
];
|
|
950
957
|
const modelKey = localeKeys.find((key) => localeModels.hasOwnProperty(key));
|
|
951
958
|
if (modelKey) {
|
|
952
|
-
const
|
|
959
|
+
const value = localeModels[modelKey];
|
|
960
|
+
const firstColonIndex = _optionalChain([value, 'optionalAccess', _29 => _29.indexOf, 'call', _30 => _30(":")]);
|
|
961
|
+
if (value && firstColonIndex !== -1 && firstColonIndex !== void 0) {
|
|
962
|
+
const provider2 = value.substring(0, firstColonIndex);
|
|
963
|
+
const model2 = value.substring(firstColonIndex + 1);
|
|
964
|
+
if (provider2 && model2) {
|
|
965
|
+
return { provider: provider2, model: model2 };
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
const [provider, model] = _optionalChain([value, 'optionalAccess', _31 => _31.split, 'call', _32 => _32(":")]) || [];
|
|
953
969
|
if (provider && model) {
|
|
954
970
|
return { provider, model };
|
|
955
971
|
}
|
|
@@ -962,7 +978,7 @@ var prompt_default = (args) => {
|
|
|
962
978
|
return getUserSystemPrompt(args) || getBuiltInSystemPrompt(args);
|
|
963
979
|
};
|
|
964
980
|
function getUserSystemPrompt(args) {
|
|
965
|
-
const userPrompt = _optionalChain([args, 'access',
|
|
981
|
+
const userPrompt = _optionalChain([args, 'access', _33 => _33.prompt, 'optionalAccess', _34 => _34.trim, 'call', _35 => _35(), 'optionalAccess', _36 => _36.replace, 'call', _37 => _37("{SOURCE_LOCALE}", args.sourceLocale), 'optionalAccess', _38 => _38.replace, 'call', _39 => _39("{TARGET_LOCALE}", args.targetLocale)]);
|
|
966
982
|
if (userPrompt) {
|
|
967
983
|
console.log("\u2728 Compiler is using user-defined prompt.");
|
|
968
984
|
return userPrompt;
|
|
@@ -1172,7 +1188,7 @@ function getKeyFromEnv(envVarName) {
|
|
|
1172
1188
|
path.default.resolve(process.cwd(), ".env.development")
|
|
1173
1189
|
]
|
|
1174
1190
|
});
|
|
1175
|
-
return _optionalChain([result, 'optionalAccess',
|
|
1191
|
+
return _optionalChain([result, 'optionalAccess', _40 => _40.parsed, 'optionalAccess', _41 => _41[envVarName]]);
|
|
1176
1192
|
}
|
|
1177
1193
|
function getKeyFromRc(rcPath) {
|
|
1178
1194
|
const rc = getRc();
|
|
@@ -1188,6 +1204,15 @@ function getGroqKeyFromRc() {
|
|
|
1188
1204
|
function getGroqKeyFromEnv() {
|
|
1189
1205
|
return getKeyFromEnv("GROQ_API_KEY");
|
|
1190
1206
|
}
|
|
1207
|
+
function getLingoDotDevKeyFromEnv() {
|
|
1208
|
+
return getKeyFromEnv("LINGODOTDEV_API_KEY");
|
|
1209
|
+
}
|
|
1210
|
+
function getLingoDotDevKeyFromRc() {
|
|
1211
|
+
return getKeyFromRc("auth.apiKey");
|
|
1212
|
+
}
|
|
1213
|
+
function getLingoDotDevKey() {
|
|
1214
|
+
return getLingoDotDevKeyFromEnv() || getLingoDotDevKeyFromRc();
|
|
1215
|
+
}
|
|
1191
1216
|
function getGoogleKey() {
|
|
1192
1217
|
return getGoogleKeyFromEnv() || getGoogleKeyFromRc();
|
|
1193
1218
|
}
|
|
@@ -1197,6 +1222,15 @@ function getGoogleKeyFromRc() {
|
|
|
1197
1222
|
function getGoogleKeyFromEnv() {
|
|
1198
1223
|
return getKeyFromEnv("GOOGLE_API_KEY");
|
|
1199
1224
|
}
|
|
1225
|
+
function getOpenRouterKey() {
|
|
1226
|
+
return getOpenRouterKeyFromEnv() || getOpenRouterKeyFromRc();
|
|
1227
|
+
}
|
|
1228
|
+
function getOpenRouterKeyFromRc() {
|
|
1229
|
+
return getKeyFromRc("llm.openrouterApiKey");
|
|
1230
|
+
}
|
|
1231
|
+
function getOpenRouterKeyFromEnv() {
|
|
1232
|
+
return getKeyFromEnv("OPENROUTER_API_KEY");
|
|
1233
|
+
}
|
|
1200
1234
|
|
|
1201
1235
|
// src/lib/lcp/api/index.ts
|
|
1202
1236
|
|
|
@@ -1222,6 +1256,22 @@ var providerDetails = {
|
|
|
1222
1256
|
apiKeyConfigKey: "llm.googleApiKey",
|
|
1223
1257
|
getKeyLink: "https://ai.google.dev/",
|
|
1224
1258
|
docsLink: "https://ai.google.dev/gemini-api/docs/troubleshooting"
|
|
1259
|
+
},
|
|
1260
|
+
openrouter: {
|
|
1261
|
+
name: "OpenRouter",
|
|
1262
|
+
apiKeyEnvVar: "OPENROUTER_API_KEY",
|
|
1263
|
+
apiKeyConfigKey: "llm.openrouterApiKey",
|
|
1264
|
+
getKeyLink: "https://openrouter.ai",
|
|
1265
|
+
docsLink: "https://openrouter.ai/docs"
|
|
1266
|
+
},
|
|
1267
|
+
ollama: {
|
|
1268
|
+
name: "Ollama",
|
|
1269
|
+
apiKeyEnvVar: void 0,
|
|
1270
|
+
// Ollama doesn't require an API key
|
|
1271
|
+
apiKeyConfigKey: void 0,
|
|
1272
|
+
// Ollama doesn't require an API key
|
|
1273
|
+
getKeyLink: "https://ollama.com/download",
|
|
1274
|
+
docsLink: "https://github.com/ollama/ollama/tree/main/docs"
|
|
1225
1275
|
}
|
|
1226
1276
|
};
|
|
1227
1277
|
|
|
@@ -1308,59 +1358,118 @@ var LCPAPI = class {
|
|
|
1308
1358
|
};
|
|
1309
1359
|
return dictionary;
|
|
1310
1360
|
}
|
|
1311
|
-
static
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1361
|
+
static _createLingoDotDevEngine() {
|
|
1362
|
+
if (isRunningInCIOrDocker()) {
|
|
1363
|
+
const apiKeyFromEnv = getLingoDotDevKeyFromEnv();
|
|
1364
|
+
if (!apiKeyFromEnv) {
|
|
1365
|
+
this._failMissingLLMKeyCi("lingo.dev");
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
const apiKey = getLingoDotDevKey();
|
|
1369
|
+
if (!apiKey) {
|
|
1318
1370
|
throw new Error(
|
|
1319
|
-
|
|
1371
|
+
"\u26A0\uFE0F Lingo.dev API key not found. Please set LINGODOTDEV_API_KEY environment variable or configure it user-wide."
|
|
1320
1372
|
);
|
|
1321
1373
|
}
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1374
|
+
console.log(`Creating Lingo.dev client`);
|
|
1375
|
+
return new (0, __sdk.LingoDotDevEngine)({
|
|
1376
|
+
apiKey
|
|
1377
|
+
});
|
|
1378
|
+
}
|
|
1379
|
+
static async _translateChunk(models, sourceDictionary, sourceLocale, targetLocale) {
|
|
1380
|
+
if (models === "lingo.dev") {
|
|
1381
|
+
try {
|
|
1382
|
+
const lingoDotDevEngine = this._createLingoDotDevEngine();
|
|
1383
|
+
console.log(
|
|
1384
|
+
`\u2728 Using Lingo.dev Engine to localize from "${sourceLocale}" to "${targetLocale}"`
|
|
1385
|
+
);
|
|
1386
|
+
const result = await lingoDotDevEngine.localizeObject(
|
|
1387
|
+
sourceDictionary,
|
|
1330
1388
|
{
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
}
|
|
1334
|
-
|
|
1389
|
+
sourceLocale,
|
|
1390
|
+
targetLocale
|
|
1391
|
+
}
|
|
1392
|
+
);
|
|
1393
|
+
return result;
|
|
1394
|
+
} catch (error) {
|
|
1395
|
+
this._failLLMFailureLocal(
|
|
1396
|
+
"lingo.dev",
|
|
1397
|
+
targetLocale,
|
|
1398
|
+
error instanceof Error ? error.message : "Unknown error"
|
|
1399
|
+
);
|
|
1400
|
+
throw error;
|
|
1401
|
+
}
|
|
1402
|
+
} else {
|
|
1403
|
+
const { provider, model } = getLocaleModel(
|
|
1404
|
+
models,
|
|
1405
|
+
sourceLocale,
|
|
1406
|
+
targetLocale
|
|
1407
|
+
);
|
|
1408
|
+
if (!provider || !model) {
|
|
1409
|
+
throw new Error(
|
|
1410
|
+
_dedent2.default`
|
|
1411
|
+
🚫 Lingo.dev Localization Engine Not Configured!
|
|
1412
|
+
|
|
1413
|
+
The "models" parameter is missing or incomplete in your Lingo.dev configuration.
|
|
1414
|
+
|
|
1415
|
+
👉 To fix this, set the "models" parameter to either:
|
|
1416
|
+
• "lingo.dev" (for the default engine)
|
|
1417
|
+
• a map of locale-to-model, e.g. { "models": { "en:es": "openai:gpt-3.5-turbo" } }
|
|
1418
|
+
|
|
1419
|
+
Example:
|
|
1420
|
+
{
|
|
1421
|
+
// ...
|
|
1422
|
+
"models": "lingo.dev"
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1425
|
+
For more details, see: https://lingo.dev/compiler
|
|
1426
|
+
To get help, join our Discord: https://lingo.dev/go/discord
|
|
1427
|
+
`
|
|
1428
|
+
);
|
|
1429
|
+
}
|
|
1430
|
+
try {
|
|
1431
|
+
const aiModel = this._createAiModel(provider, model, targetLocale);
|
|
1432
|
+
console.log(
|
|
1433
|
+
`\u2139\uFE0F Using raw LLM API ("${provider}":"${model}") to translate from "${sourceLocale}" to "${targetLocale}"`
|
|
1434
|
+
);
|
|
1435
|
+
const response = await _ai.generateText.call(void 0, {
|
|
1436
|
+
model: aiModel,
|
|
1437
|
+
messages: [
|
|
1335
1438
|
{
|
|
1336
|
-
role: "
|
|
1337
|
-
content:
|
|
1439
|
+
role: "system",
|
|
1440
|
+
content: prompt_default({ sourceLocale, targetLocale })
|
|
1338
1441
|
},
|
|
1442
|
+
...shots_default.flatMap((shotsTuple) => [
|
|
1443
|
+
{
|
|
1444
|
+
role: "user",
|
|
1445
|
+
content: obj2xml(shotsTuple[0])
|
|
1446
|
+
},
|
|
1447
|
+
{
|
|
1448
|
+
role: "assistant",
|
|
1449
|
+
content: obj2xml(shotsTuple[1])
|
|
1450
|
+
}
|
|
1451
|
+
]),
|
|
1339
1452
|
{
|
|
1340
|
-
role: "
|
|
1341
|
-
content: obj2xml(
|
|
1453
|
+
role: "user",
|
|
1454
|
+
content: obj2xml(sourceDictionary)
|
|
1342
1455
|
}
|
|
1343
|
-
]
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
targetLocale,
|
|
1361
|
-
error instanceof Error ? error.message : "Unknown error"
|
|
1362
|
-
);
|
|
1363
|
-
throw error;
|
|
1456
|
+
]
|
|
1457
|
+
});
|
|
1458
|
+
console.log("Response text received for", targetLocale);
|
|
1459
|
+
let responseText = response.text;
|
|
1460
|
+
responseText = responseText.substring(
|
|
1461
|
+
responseText.indexOf("<"),
|
|
1462
|
+
responseText.lastIndexOf(">") + 1
|
|
1463
|
+
);
|
|
1464
|
+
return xml2obj(responseText);
|
|
1465
|
+
} catch (error) {
|
|
1466
|
+
this._failLLMFailureLocal(
|
|
1467
|
+
provider,
|
|
1468
|
+
targetLocale,
|
|
1469
|
+
error instanceof Error ? error.message : "Unknown error"
|
|
1470
|
+
);
|
|
1471
|
+
throw error;
|
|
1472
|
+
}
|
|
1364
1473
|
}
|
|
1365
1474
|
}
|
|
1366
1475
|
/**
|
|
@@ -1374,7 +1483,7 @@ var LCPAPI = class {
|
|
|
1374
1483
|
*/
|
|
1375
1484
|
static _createAiModel(providerId, modelId, targetLocale) {
|
|
1376
1485
|
switch (providerId) {
|
|
1377
|
-
case "groq":
|
|
1486
|
+
case "groq": {
|
|
1378
1487
|
if (isRunningInCIOrDocker()) {
|
|
1379
1488
|
const groqFromEnv = getGroqKeyFromEnv();
|
|
1380
1489
|
if (!groqFromEnv) {
|
|
@@ -1391,7 +1500,8 @@ var LCPAPI = class {
|
|
|
1391
1500
|
`Creating Groq client for ${targetLocale} using model ${modelId}`
|
|
1392
1501
|
);
|
|
1393
1502
|
return _groq.createGroq.call(void 0, { apiKey: groqKey })(modelId);
|
|
1394
|
-
|
|
1503
|
+
}
|
|
1504
|
+
case "google": {
|
|
1395
1505
|
if (isRunningInCIOrDocker()) {
|
|
1396
1506
|
const googleFromEnv = getGoogleKeyFromEnv();
|
|
1397
1507
|
if (!googleFromEnv) {
|
|
@@ -1408,10 +1518,38 @@ var LCPAPI = class {
|
|
|
1408
1518
|
`Creating Google Generative AI client for ${targetLocale} using model ${modelId}`
|
|
1409
1519
|
);
|
|
1410
1520
|
return _google.createGoogleGenerativeAI.call(void 0, { apiKey: googleKey })(modelId);
|
|
1411
|
-
|
|
1521
|
+
}
|
|
1522
|
+
case "openrouter": {
|
|
1523
|
+
if (isRunningInCIOrDocker()) {
|
|
1524
|
+
const openRouterFromEnv = getOpenRouterKeyFromEnv();
|
|
1525
|
+
if (!openRouterFromEnv) {
|
|
1526
|
+
this._failMissingLLMKeyCi(providerId);
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
const openRouterKey = getOpenRouterKey();
|
|
1530
|
+
if (!openRouterKey) {
|
|
1531
|
+
throw new Error(
|
|
1532
|
+
"\u26A0\uFE0F OpenRouter API key not found. Please set OPENROUTER_API_KEY environment variable or configure it user-wide."
|
|
1533
|
+
);
|
|
1534
|
+
}
|
|
1535
|
+
console.log(
|
|
1536
|
+
`Creating OpenRouter client for ${targetLocale} using model ${modelId}`
|
|
1537
|
+
);
|
|
1538
|
+
return _aisdkprovider.createOpenRouter.call(void 0, {
|
|
1539
|
+
apiKey: openRouterKey
|
|
1540
|
+
})(modelId);
|
|
1541
|
+
}
|
|
1542
|
+
case "ollama": {
|
|
1543
|
+
console.log(
|
|
1544
|
+
`Creating Ollama client for ${targetLocale} using model ${modelId} at default Ollama address`
|
|
1545
|
+
);
|
|
1546
|
+
return _ollamaaiprovider.createOllama.call(void 0, )(modelId);
|
|
1547
|
+
}
|
|
1548
|
+
default: {
|
|
1412
1549
|
throw new Error(
|
|
1413
1550
|
`\u26A0\uFE0F Provider "${providerId}" for locale "${targetLocale}" is not supported. Only "groq" and "google" providers are supported at the moment.`
|
|
1414
1551
|
);
|
|
1552
|
+
}
|
|
1415
1553
|
}
|
|
1416
1554
|
}
|
|
1417
1555
|
/**
|
|
@@ -1500,7 +1638,7 @@ var LCPAPI = class {
|
|
|
1500
1638
|
This error comes from the ${details.name} API, please check their documentation for more details: ${details.docsLink}
|
|
1501
1639
|
|
|
1502
1640
|
⭐️ Also:
|
|
1503
|
-
1. Did you set ${details.apiKeyEnvVar} environment variable correctly?
|
|
1641
|
+
1. Did you set ${details.apiKeyEnvVar ? `${details.apiKeyEnvVar}` : "the provider API key"} environment variable correctly ${!details.apiKeyEnvVar ? "(if required)" : ""}?
|
|
1504
1642
|
2. Did you reach any limits of your ${details.name} account?
|
|
1505
1643
|
3. If you have questions, feature requests, or would like to contribute, join our Discord: https://lingo.dev/go/discord
|
|
1506
1644
|
|
|
@@ -1514,31 +1652,39 @@ var LCPAPI = class {
|
|
|
1514
1652
|
|
|
1515
1653
|
// src/lib/lcp/server.ts
|
|
1516
1654
|
var LCPServer = (_class = class {
|
|
1517
|
-
static __initStatic() {this.
|
|
1655
|
+
static __initStatic() {this.dictionariesCache = null}
|
|
1656
|
+
static __initStatic2() {this.inFlightPromise = null}
|
|
1518
1657
|
static async loadDictionaries(params) {
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
setTimeout(resolve3, 500);
|
|
1522
|
-
});
|
|
1658
|
+
if (this.dictionariesCache) {
|
|
1659
|
+
return this.dictionariesCache;
|
|
1523
1660
|
}
|
|
1524
|
-
this.
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1661
|
+
if (this.inFlightPromise) {
|
|
1662
|
+
return this.inFlightPromise;
|
|
1663
|
+
}
|
|
1664
|
+
this.inFlightPromise = (async () => {
|
|
1665
|
+
try {
|
|
1666
|
+
const targetLocales = _lodash2.default.uniq([
|
|
1667
|
+
...params.targetLocales,
|
|
1668
|
+
params.sourceLocale
|
|
1669
|
+
]);
|
|
1670
|
+
const dictionaries = await Promise.all(
|
|
1671
|
+
targetLocales.map(
|
|
1672
|
+
(targetLocale) => this.loadDictionaryForLocale({ ...params, targetLocale })
|
|
1673
|
+
)
|
|
1674
|
+
);
|
|
1675
|
+
const result = _lodash2.default.fromPairs(
|
|
1676
|
+
targetLocales.map((targetLocale, index) => [
|
|
1677
|
+
targetLocale,
|
|
1678
|
+
dictionaries[index]
|
|
1679
|
+
])
|
|
1680
|
+
);
|
|
1681
|
+
this.dictionariesCache = result;
|
|
1682
|
+
return result;
|
|
1683
|
+
} finally {
|
|
1684
|
+
this.inFlightPromise = null;
|
|
1685
|
+
}
|
|
1686
|
+
})();
|
|
1687
|
+
return this.inFlightPromise;
|
|
1542
1688
|
}
|
|
1543
1689
|
static async loadDictionaryForLocale(params) {
|
|
1544
1690
|
const sourceDictionary = this._extractSourceDictionary(
|
|
@@ -1703,14 +1849,14 @@ var LCPServer = (_class = class {
|
|
|
1703
1849
|
const sourceFile = _lodash2.default.get(sourceDictionary.files, fileName);
|
|
1704
1850
|
const targetFile = _lodash2.default.get(targetDictionary.files, fileName);
|
|
1705
1851
|
const entries = removeEmptyEntries ? _lodash2.default.pickBy(
|
|
1706
|
-
_optionalChain([sourceFile, 'optionalAccess',
|
|
1707
|
-
(value) => _optionalChain([String, 'call',
|
|
1708
|
-
) : _optionalChain([sourceFile, 'optionalAccess',
|
|
1852
|
+
_optionalChain([sourceFile, 'optionalAccess', _42 => _42.entries]) || {},
|
|
1853
|
+
(value) => _optionalChain([String, 'call', _43 => _43(value || ""), 'optionalAccess', _44 => _44.trim, 'optionalCall', _45 => _45(), 'optionalAccess', _46 => _46.length]) > 0
|
|
1854
|
+
) : _optionalChain([sourceFile, 'optionalAccess', _47 => _47.entries]) || {};
|
|
1709
1855
|
return [
|
|
1710
1856
|
fileName,
|
|
1711
1857
|
{
|
|
1712
1858
|
...targetFile,
|
|
1713
|
-
entries: _lodash2.default.merge(_optionalChain([targetFile, 'optionalAccess',
|
|
1859
|
+
entries: _lodash2.default.merge({}, _optionalChain([targetFile, 'optionalAccess', _48 => _48.entries]) || {}, entries)
|
|
1714
1860
|
}
|
|
1715
1861
|
];
|
|
1716
1862
|
}).fromPairs().value();
|
|
@@ -1727,7 +1873,7 @@ var LCPServer = (_class = class {
|
|
|
1727
1873
|
0
|
|
1728
1874
|
);
|
|
1729
1875
|
}
|
|
1730
|
-
}, _class.__initStatic(), _class);
|
|
1876
|
+
}, _class.__initStatic(), _class.__initStatic2(), _class);
|
|
1731
1877
|
|
|
1732
1878
|
// src/utils/invokations.ts
|
|
1733
1879
|
|
|
@@ -1916,7 +2062,7 @@ function jsxFragmentMutation(payload) {
|
|
|
1916
2062
|
var jsxHtmlLangMutation = createCodeMutation((payload) => {
|
|
1917
2063
|
_traverse2.default.call(void 0, payload.ast, {
|
|
1918
2064
|
JSXElement: (path7) => {
|
|
1919
|
-
if (_optionalChain([getJsxElementName, 'call',
|
|
2065
|
+
if (_optionalChain([getJsxElementName, 'call', _49 => _49(path7), 'optionalAccess', _50 => _50.toLowerCase, 'call', _51 => _51()]) === "html") {
|
|
1920
2066
|
const mode = getModuleExecutionMode(payload.ast, payload.params.rsc);
|
|
1921
2067
|
const packagePath = mode === "client" ? ModuleId.ReactClient : ModuleId.ReactRSC;
|
|
1922
2068
|
const lingoHtmlComponentImport = getOrCreateImport(payload.ast, {
|
|
@@ -2499,6 +2645,10 @@ var keyCheckers = {
|
|
|
2499
2645
|
google: {
|
|
2500
2646
|
checkEnv: getGoogleKeyFromEnv,
|
|
2501
2647
|
checkRc: getGoogleKeyFromRc
|
|
2648
|
+
},
|
|
2649
|
+
"lingo.dev": {
|
|
2650
|
+
checkEnv: getLingoDotDevKeyFromEnv,
|
|
2651
|
+
checkRc: getLingoDotDevKeyFromRc
|
|
2502
2652
|
}
|
|
2503
2653
|
};
|
|
2504
2654
|
var unplugin = _unplugin.createUnplugin.call(void 0,
|
|
@@ -2506,26 +2656,31 @@ var unplugin = _unplugin.createUnplugin.call(void 0,
|
|
|
2506
2656
|
console.log("\u2139\uFE0F Starting Lingo.dev compiler...");
|
|
2507
2657
|
const params = _lodash2.default.defaults(_params, defaultParams);
|
|
2508
2658
|
if (!isRunningInCIOrDocker()) {
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2659
|
+
if (params.models === "lingo.dev") {
|
|
2660
|
+
validateLLMKeyDetails(["lingo.dev"]);
|
|
2661
|
+
} else {
|
|
2662
|
+
const configuredProviders = getConfiguredProviders(params.models);
|
|
2663
|
+
validateLLMKeyDetails(configuredProviders);
|
|
2664
|
+
const invalidLocales = getInvalidLocales(
|
|
2665
|
+
params.models,
|
|
2666
|
+
params.sourceLocale,
|
|
2667
|
+
params.targetLocales
|
|
2668
|
+
);
|
|
2669
|
+
if (invalidLocales.length > 0) {
|
|
2670
|
+
console.log(_dedent2.default`
|
|
2671
|
+
\n
|
|
2672
|
+
⚠️ Lingo.dev Localization Compiler requires LLM model setup for the following locales: ${invalidLocales.join(", ")}.
|
|
2673
|
+
|
|
2674
|
+
⭐️ Next steps:
|
|
2675
|
+
1. Refer to documentation for help: https://docs.lingo.dev/
|
|
2676
|
+
2. If you want to use a different LLM, raise an issue in our open-source repo: https://lingo.dev/go/gh
|
|
2677
|
+
3. If you have questions, feature requests, or would like to contribute, join our Discord: https://lingo.dev/go/discord
|
|
2678
|
+
|
|
2679
|
+
✨
|
|
2680
|
+
`);
|
|
2681
|
+
process.exit(1);
|
|
2682
|
+
}
|
|
2683
|
+
}
|
|
2529
2684
|
}
|
|
2530
2685
|
LCPCache.ensureDictionaryFile({
|
|
2531
2686
|
sourceRoot: params.sourceRoot,
|
|
@@ -2553,6 +2708,7 @@ var unplugin = _unplugin.createUnplugin.call(void 0,
|
|
|
2553
2708
|
lingoDir: params.lingoDir
|
|
2554
2709
|
});
|
|
2555
2710
|
const dictionary = dictionaries[moduleInfo.params.locale];
|
|
2711
|
+
console.log(JSON.stringify(dictionary, null, 2));
|
|
2556
2712
|
return {
|
|
2557
2713
|
code: `export default ${JSON.stringify(dictionary, null, 2)}`
|
|
2558
2714
|
};
|
|
@@ -2621,10 +2777,12 @@ var src_default = {
|
|
|
2621
2777
|
return config2;
|
|
2622
2778
|
}
|
|
2623
2779
|
};
|
|
2624
|
-
function
|
|
2625
|
-
|
|
2780
|
+
function getConfiguredProviders(models) {
|
|
2781
|
+
return _lodash2.default.chain(Object.values(models)).map((modelString) => modelString.split(":")[0]).filter(Boolean).uniq().filter(
|
|
2626
2782
|
(providerId) => providerDetails.hasOwnProperty(providerId) && keyCheckers.hasOwnProperty(providerId)
|
|
2627
2783
|
).value();
|
|
2784
|
+
}
|
|
2785
|
+
function validateLLMKeyDetails(configuredProviders) {
|
|
2628
2786
|
if (configuredProviders.length === 0) {
|
|
2629
2787
|
return;
|
|
2630
2788
|
}
|
package/build/index.d.cts
CHANGED
package/build/index.d.ts
CHANGED
package/build/index.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { createUnplugin } from "unplugin";
|
|
|
4
4
|
// package.json
|
|
5
5
|
var package_default = {
|
|
6
6
|
name: "@lingo.dev/_compiler",
|
|
7
|
-
version: "0.
|
|
7
|
+
version: "0.3.0",
|
|
8
8
|
description: "Lingo.dev Compiler",
|
|
9
9
|
private: false,
|
|
10
10
|
publishConfig: {
|
|
@@ -46,6 +46,8 @@ var package_default = {
|
|
|
46
46
|
"@babel/parser": "^7.26.7",
|
|
47
47
|
"@babel/traverse": "^7.27.4",
|
|
48
48
|
"@babel/types": "^7.26.7",
|
|
49
|
+
"@lingo.dev/_sdk": "workspace:*",
|
|
50
|
+
"@openrouter/ai-sdk-provider": "^0.7.1",
|
|
49
51
|
ai: "^4.2.10",
|
|
50
52
|
dedent: "^1.6.0",
|
|
51
53
|
dotenv: "^16.4.5",
|
|
@@ -53,11 +55,13 @@ var package_default = {
|
|
|
53
55
|
ini: "^5.0.0",
|
|
54
56
|
lodash: "^4.17.21",
|
|
55
57
|
"object-hash": "^3.0.0",
|
|
58
|
+
"ollama-ai-provider": "^1.2.0",
|
|
56
59
|
prettier: "^3.4.2",
|
|
57
60
|
unplugin: "^2.1.2",
|
|
58
61
|
vitest: "^2.1.4",
|
|
59
62
|
zod: "^3.24.1"
|
|
60
|
-
}
|
|
63
|
+
},
|
|
64
|
+
packageManager: "pnpm@9.12.3"
|
|
61
65
|
};
|
|
62
66
|
|
|
63
67
|
// src/index.ts
|
|
@@ -926,7 +930,10 @@ var LCPCache = class {
|
|
|
926
930
|
// src/lib/lcp/api/index.ts
|
|
927
931
|
import { createGroq } from "@ai-sdk/groq";
|
|
928
932
|
import { createGoogleGenerativeAI } from "@ai-sdk/google";
|
|
933
|
+
import { createOpenRouter } from "@openrouter/ai-sdk-provider";
|
|
934
|
+
import { createOllama } from "ollama-ai-provider";
|
|
929
935
|
import { generateText } from "ai";
|
|
936
|
+
import { LingoDotDevEngine } from "@lingo.dev/_sdk";
|
|
930
937
|
import _6 from "lodash";
|
|
931
938
|
|
|
932
939
|
// src/utils/locales.ts
|
|
@@ -949,7 +956,16 @@ function getLocaleModel(localeModels, sourceLocale, targetLocale) {
|
|
|
949
956
|
];
|
|
950
957
|
const modelKey = localeKeys.find((key) => localeModels.hasOwnProperty(key));
|
|
951
958
|
if (modelKey) {
|
|
952
|
-
const
|
|
959
|
+
const value = localeModels[modelKey];
|
|
960
|
+
const firstColonIndex = value?.indexOf(":");
|
|
961
|
+
if (value && firstColonIndex !== -1 && firstColonIndex !== void 0) {
|
|
962
|
+
const provider2 = value.substring(0, firstColonIndex);
|
|
963
|
+
const model2 = value.substring(firstColonIndex + 1);
|
|
964
|
+
if (provider2 && model2) {
|
|
965
|
+
return { provider: provider2, model: model2 };
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
const [provider, model] = value?.split(":") || [];
|
|
953
969
|
if (provider && model) {
|
|
954
970
|
return { provider, model };
|
|
955
971
|
}
|
|
@@ -1188,6 +1204,15 @@ function getGroqKeyFromRc() {
|
|
|
1188
1204
|
function getGroqKeyFromEnv() {
|
|
1189
1205
|
return getKeyFromEnv("GROQ_API_KEY");
|
|
1190
1206
|
}
|
|
1207
|
+
function getLingoDotDevKeyFromEnv() {
|
|
1208
|
+
return getKeyFromEnv("LINGODOTDEV_API_KEY");
|
|
1209
|
+
}
|
|
1210
|
+
function getLingoDotDevKeyFromRc() {
|
|
1211
|
+
return getKeyFromRc("auth.apiKey");
|
|
1212
|
+
}
|
|
1213
|
+
function getLingoDotDevKey() {
|
|
1214
|
+
return getLingoDotDevKeyFromEnv() || getLingoDotDevKeyFromRc();
|
|
1215
|
+
}
|
|
1191
1216
|
function getGoogleKey() {
|
|
1192
1217
|
return getGoogleKeyFromEnv() || getGoogleKeyFromRc();
|
|
1193
1218
|
}
|
|
@@ -1197,6 +1222,15 @@ function getGoogleKeyFromRc() {
|
|
|
1197
1222
|
function getGoogleKeyFromEnv() {
|
|
1198
1223
|
return getKeyFromEnv("GOOGLE_API_KEY");
|
|
1199
1224
|
}
|
|
1225
|
+
function getOpenRouterKey() {
|
|
1226
|
+
return getOpenRouterKeyFromEnv() || getOpenRouterKeyFromRc();
|
|
1227
|
+
}
|
|
1228
|
+
function getOpenRouterKeyFromRc() {
|
|
1229
|
+
return getKeyFromRc("llm.openrouterApiKey");
|
|
1230
|
+
}
|
|
1231
|
+
function getOpenRouterKeyFromEnv() {
|
|
1232
|
+
return getKeyFromEnv("OPENROUTER_API_KEY");
|
|
1233
|
+
}
|
|
1200
1234
|
|
|
1201
1235
|
// src/lib/lcp/api/index.ts
|
|
1202
1236
|
import dedent2 from "dedent";
|
|
@@ -1222,6 +1256,22 @@ var providerDetails = {
|
|
|
1222
1256
|
apiKeyConfigKey: "llm.googleApiKey",
|
|
1223
1257
|
getKeyLink: "https://ai.google.dev/",
|
|
1224
1258
|
docsLink: "https://ai.google.dev/gemini-api/docs/troubleshooting"
|
|
1259
|
+
},
|
|
1260
|
+
openrouter: {
|
|
1261
|
+
name: "OpenRouter",
|
|
1262
|
+
apiKeyEnvVar: "OPENROUTER_API_KEY",
|
|
1263
|
+
apiKeyConfigKey: "llm.openrouterApiKey",
|
|
1264
|
+
getKeyLink: "https://openrouter.ai",
|
|
1265
|
+
docsLink: "https://openrouter.ai/docs"
|
|
1266
|
+
},
|
|
1267
|
+
ollama: {
|
|
1268
|
+
name: "Ollama",
|
|
1269
|
+
apiKeyEnvVar: void 0,
|
|
1270
|
+
// Ollama doesn't require an API key
|
|
1271
|
+
apiKeyConfigKey: void 0,
|
|
1272
|
+
// Ollama doesn't require an API key
|
|
1273
|
+
getKeyLink: "https://ollama.com/download",
|
|
1274
|
+
docsLink: "https://github.com/ollama/ollama/tree/main/docs"
|
|
1225
1275
|
}
|
|
1226
1276
|
};
|
|
1227
1277
|
|
|
@@ -1308,59 +1358,118 @@ var LCPAPI = class {
|
|
|
1308
1358
|
};
|
|
1309
1359
|
return dictionary;
|
|
1310
1360
|
}
|
|
1311
|
-
static
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1361
|
+
static _createLingoDotDevEngine() {
|
|
1362
|
+
if (isRunningInCIOrDocker()) {
|
|
1363
|
+
const apiKeyFromEnv = getLingoDotDevKeyFromEnv();
|
|
1364
|
+
if (!apiKeyFromEnv) {
|
|
1365
|
+
this._failMissingLLMKeyCi("lingo.dev");
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
const apiKey = getLingoDotDevKey();
|
|
1369
|
+
if (!apiKey) {
|
|
1318
1370
|
throw new Error(
|
|
1319
|
-
|
|
1371
|
+
"\u26A0\uFE0F Lingo.dev API key not found. Please set LINGODOTDEV_API_KEY environment variable or configure it user-wide."
|
|
1320
1372
|
);
|
|
1321
1373
|
}
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1374
|
+
console.log(`Creating Lingo.dev client`);
|
|
1375
|
+
return new LingoDotDevEngine({
|
|
1376
|
+
apiKey
|
|
1377
|
+
});
|
|
1378
|
+
}
|
|
1379
|
+
static async _translateChunk(models, sourceDictionary, sourceLocale, targetLocale) {
|
|
1380
|
+
if (models === "lingo.dev") {
|
|
1381
|
+
try {
|
|
1382
|
+
const lingoDotDevEngine = this._createLingoDotDevEngine();
|
|
1383
|
+
console.log(
|
|
1384
|
+
`\u2728 Using Lingo.dev Engine to localize from "${sourceLocale}" to "${targetLocale}"`
|
|
1385
|
+
);
|
|
1386
|
+
const result = await lingoDotDevEngine.localizeObject(
|
|
1387
|
+
sourceDictionary,
|
|
1330
1388
|
{
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
}
|
|
1334
|
-
|
|
1389
|
+
sourceLocale,
|
|
1390
|
+
targetLocale
|
|
1391
|
+
}
|
|
1392
|
+
);
|
|
1393
|
+
return result;
|
|
1394
|
+
} catch (error) {
|
|
1395
|
+
this._failLLMFailureLocal(
|
|
1396
|
+
"lingo.dev",
|
|
1397
|
+
targetLocale,
|
|
1398
|
+
error instanceof Error ? error.message : "Unknown error"
|
|
1399
|
+
);
|
|
1400
|
+
throw error;
|
|
1401
|
+
}
|
|
1402
|
+
} else {
|
|
1403
|
+
const { provider, model } = getLocaleModel(
|
|
1404
|
+
models,
|
|
1405
|
+
sourceLocale,
|
|
1406
|
+
targetLocale
|
|
1407
|
+
);
|
|
1408
|
+
if (!provider || !model) {
|
|
1409
|
+
throw new Error(
|
|
1410
|
+
dedent2`
|
|
1411
|
+
🚫 Lingo.dev Localization Engine Not Configured!
|
|
1412
|
+
|
|
1413
|
+
The "models" parameter is missing or incomplete in your Lingo.dev configuration.
|
|
1414
|
+
|
|
1415
|
+
👉 To fix this, set the "models" parameter to either:
|
|
1416
|
+
• "lingo.dev" (for the default engine)
|
|
1417
|
+
• a map of locale-to-model, e.g. { "models": { "en:es": "openai:gpt-3.5-turbo" } }
|
|
1418
|
+
|
|
1419
|
+
Example:
|
|
1420
|
+
{
|
|
1421
|
+
// ...
|
|
1422
|
+
"models": "lingo.dev"
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1425
|
+
For more details, see: https://lingo.dev/compiler
|
|
1426
|
+
To get help, join our Discord: https://lingo.dev/go/discord
|
|
1427
|
+
`
|
|
1428
|
+
);
|
|
1429
|
+
}
|
|
1430
|
+
try {
|
|
1431
|
+
const aiModel = this._createAiModel(provider, model, targetLocale);
|
|
1432
|
+
console.log(
|
|
1433
|
+
`\u2139\uFE0F Using raw LLM API ("${provider}":"${model}") to translate from "${sourceLocale}" to "${targetLocale}"`
|
|
1434
|
+
);
|
|
1435
|
+
const response = await generateText({
|
|
1436
|
+
model: aiModel,
|
|
1437
|
+
messages: [
|
|
1335
1438
|
{
|
|
1336
|
-
role: "
|
|
1337
|
-
content:
|
|
1439
|
+
role: "system",
|
|
1440
|
+
content: prompt_default({ sourceLocale, targetLocale })
|
|
1338
1441
|
},
|
|
1442
|
+
...shots_default.flatMap((shotsTuple) => [
|
|
1443
|
+
{
|
|
1444
|
+
role: "user",
|
|
1445
|
+
content: obj2xml(shotsTuple[0])
|
|
1446
|
+
},
|
|
1447
|
+
{
|
|
1448
|
+
role: "assistant",
|
|
1449
|
+
content: obj2xml(shotsTuple[1])
|
|
1450
|
+
}
|
|
1451
|
+
]),
|
|
1339
1452
|
{
|
|
1340
|
-
role: "
|
|
1341
|
-
content: obj2xml(
|
|
1453
|
+
role: "user",
|
|
1454
|
+
content: obj2xml(sourceDictionary)
|
|
1342
1455
|
}
|
|
1343
|
-
]
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
targetLocale,
|
|
1361
|
-
error instanceof Error ? error.message : "Unknown error"
|
|
1362
|
-
);
|
|
1363
|
-
throw error;
|
|
1456
|
+
]
|
|
1457
|
+
});
|
|
1458
|
+
console.log("Response text received for", targetLocale);
|
|
1459
|
+
let responseText = response.text;
|
|
1460
|
+
responseText = responseText.substring(
|
|
1461
|
+
responseText.indexOf("<"),
|
|
1462
|
+
responseText.lastIndexOf(">") + 1
|
|
1463
|
+
);
|
|
1464
|
+
return xml2obj(responseText);
|
|
1465
|
+
} catch (error) {
|
|
1466
|
+
this._failLLMFailureLocal(
|
|
1467
|
+
provider,
|
|
1468
|
+
targetLocale,
|
|
1469
|
+
error instanceof Error ? error.message : "Unknown error"
|
|
1470
|
+
);
|
|
1471
|
+
throw error;
|
|
1472
|
+
}
|
|
1364
1473
|
}
|
|
1365
1474
|
}
|
|
1366
1475
|
/**
|
|
@@ -1374,7 +1483,7 @@ var LCPAPI = class {
|
|
|
1374
1483
|
*/
|
|
1375
1484
|
static _createAiModel(providerId, modelId, targetLocale) {
|
|
1376
1485
|
switch (providerId) {
|
|
1377
|
-
case "groq":
|
|
1486
|
+
case "groq": {
|
|
1378
1487
|
if (isRunningInCIOrDocker()) {
|
|
1379
1488
|
const groqFromEnv = getGroqKeyFromEnv();
|
|
1380
1489
|
if (!groqFromEnv) {
|
|
@@ -1391,7 +1500,8 @@ var LCPAPI = class {
|
|
|
1391
1500
|
`Creating Groq client for ${targetLocale} using model ${modelId}`
|
|
1392
1501
|
);
|
|
1393
1502
|
return createGroq({ apiKey: groqKey })(modelId);
|
|
1394
|
-
|
|
1503
|
+
}
|
|
1504
|
+
case "google": {
|
|
1395
1505
|
if (isRunningInCIOrDocker()) {
|
|
1396
1506
|
const googleFromEnv = getGoogleKeyFromEnv();
|
|
1397
1507
|
if (!googleFromEnv) {
|
|
@@ -1408,10 +1518,38 @@ var LCPAPI = class {
|
|
|
1408
1518
|
`Creating Google Generative AI client for ${targetLocale} using model ${modelId}`
|
|
1409
1519
|
);
|
|
1410
1520
|
return createGoogleGenerativeAI({ apiKey: googleKey })(modelId);
|
|
1411
|
-
|
|
1521
|
+
}
|
|
1522
|
+
case "openrouter": {
|
|
1523
|
+
if (isRunningInCIOrDocker()) {
|
|
1524
|
+
const openRouterFromEnv = getOpenRouterKeyFromEnv();
|
|
1525
|
+
if (!openRouterFromEnv) {
|
|
1526
|
+
this._failMissingLLMKeyCi(providerId);
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
const openRouterKey = getOpenRouterKey();
|
|
1530
|
+
if (!openRouterKey) {
|
|
1531
|
+
throw new Error(
|
|
1532
|
+
"\u26A0\uFE0F OpenRouter API key not found. Please set OPENROUTER_API_KEY environment variable or configure it user-wide."
|
|
1533
|
+
);
|
|
1534
|
+
}
|
|
1535
|
+
console.log(
|
|
1536
|
+
`Creating OpenRouter client for ${targetLocale} using model ${modelId}`
|
|
1537
|
+
);
|
|
1538
|
+
return createOpenRouter({
|
|
1539
|
+
apiKey: openRouterKey
|
|
1540
|
+
})(modelId);
|
|
1541
|
+
}
|
|
1542
|
+
case "ollama": {
|
|
1543
|
+
console.log(
|
|
1544
|
+
`Creating Ollama client for ${targetLocale} using model ${modelId} at default Ollama address`
|
|
1545
|
+
);
|
|
1546
|
+
return createOllama()(modelId);
|
|
1547
|
+
}
|
|
1548
|
+
default: {
|
|
1412
1549
|
throw new Error(
|
|
1413
1550
|
`\u26A0\uFE0F Provider "${providerId}" for locale "${targetLocale}" is not supported. Only "groq" and "google" providers are supported at the moment.`
|
|
1414
1551
|
);
|
|
1552
|
+
}
|
|
1415
1553
|
}
|
|
1416
1554
|
}
|
|
1417
1555
|
/**
|
|
@@ -1500,7 +1638,7 @@ var LCPAPI = class {
|
|
|
1500
1638
|
This error comes from the ${details.name} API, please check their documentation for more details: ${details.docsLink}
|
|
1501
1639
|
|
|
1502
1640
|
⭐️ Also:
|
|
1503
|
-
1. Did you set ${details.apiKeyEnvVar} environment variable correctly?
|
|
1641
|
+
1. Did you set ${details.apiKeyEnvVar ? `${details.apiKeyEnvVar}` : "the provider API key"} environment variable correctly ${!details.apiKeyEnvVar ? "(if required)" : ""}?
|
|
1504
1642
|
2. Did you reach any limits of your ${details.name} account?
|
|
1505
1643
|
3. If you have questions, feature requests, or would like to contribute, join our Discord: https://lingo.dev/go/discord
|
|
1506
1644
|
|
|
@@ -1514,31 +1652,39 @@ var LCPAPI = class {
|
|
|
1514
1652
|
|
|
1515
1653
|
// src/lib/lcp/server.ts
|
|
1516
1654
|
var LCPServer = class {
|
|
1517
|
-
static
|
|
1655
|
+
static dictionariesCache = null;
|
|
1656
|
+
static inFlightPromise = null;
|
|
1518
1657
|
static async loadDictionaries(params) {
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
setTimeout(resolve3, 500);
|
|
1522
|
-
});
|
|
1658
|
+
if (this.dictionariesCache) {
|
|
1659
|
+
return this.dictionariesCache;
|
|
1523
1660
|
}
|
|
1524
|
-
this.
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1661
|
+
if (this.inFlightPromise) {
|
|
1662
|
+
return this.inFlightPromise;
|
|
1663
|
+
}
|
|
1664
|
+
this.inFlightPromise = (async () => {
|
|
1665
|
+
try {
|
|
1666
|
+
const targetLocales = _7.uniq([
|
|
1667
|
+
...params.targetLocales,
|
|
1668
|
+
params.sourceLocale
|
|
1669
|
+
]);
|
|
1670
|
+
const dictionaries = await Promise.all(
|
|
1671
|
+
targetLocales.map(
|
|
1672
|
+
(targetLocale) => this.loadDictionaryForLocale({ ...params, targetLocale })
|
|
1673
|
+
)
|
|
1674
|
+
);
|
|
1675
|
+
const result = _7.fromPairs(
|
|
1676
|
+
targetLocales.map((targetLocale, index) => [
|
|
1677
|
+
targetLocale,
|
|
1678
|
+
dictionaries[index]
|
|
1679
|
+
])
|
|
1680
|
+
);
|
|
1681
|
+
this.dictionariesCache = result;
|
|
1682
|
+
return result;
|
|
1683
|
+
} finally {
|
|
1684
|
+
this.inFlightPromise = null;
|
|
1685
|
+
}
|
|
1686
|
+
})();
|
|
1687
|
+
return this.inFlightPromise;
|
|
1542
1688
|
}
|
|
1543
1689
|
static async loadDictionaryForLocale(params) {
|
|
1544
1690
|
const sourceDictionary = this._extractSourceDictionary(
|
|
@@ -1710,7 +1856,7 @@ var LCPServer = class {
|
|
|
1710
1856
|
fileName,
|
|
1711
1857
|
{
|
|
1712
1858
|
...targetFile,
|
|
1713
|
-
entries: _7.merge(targetFile?.entries || {}, entries)
|
|
1859
|
+
entries: _7.merge({}, targetFile?.entries || {}, entries)
|
|
1714
1860
|
}
|
|
1715
1861
|
];
|
|
1716
1862
|
}).fromPairs().value();
|
|
@@ -2499,6 +2645,10 @@ var keyCheckers = {
|
|
|
2499
2645
|
google: {
|
|
2500
2646
|
checkEnv: getGoogleKeyFromEnv,
|
|
2501
2647
|
checkRc: getGoogleKeyFromRc
|
|
2648
|
+
},
|
|
2649
|
+
"lingo.dev": {
|
|
2650
|
+
checkEnv: getLingoDotDevKeyFromEnv,
|
|
2651
|
+
checkRc: getLingoDotDevKeyFromRc
|
|
2502
2652
|
}
|
|
2503
2653
|
};
|
|
2504
2654
|
var unplugin = createUnplugin(
|
|
@@ -2506,26 +2656,31 @@ var unplugin = createUnplugin(
|
|
|
2506
2656
|
console.log("\u2139\uFE0F Starting Lingo.dev compiler...");
|
|
2507
2657
|
const params = _11.defaults(_params, defaultParams);
|
|
2508
2658
|
if (!isRunningInCIOrDocker()) {
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2659
|
+
if (params.models === "lingo.dev") {
|
|
2660
|
+
validateLLMKeyDetails(["lingo.dev"]);
|
|
2661
|
+
} else {
|
|
2662
|
+
const configuredProviders = getConfiguredProviders(params.models);
|
|
2663
|
+
validateLLMKeyDetails(configuredProviders);
|
|
2664
|
+
const invalidLocales = getInvalidLocales(
|
|
2665
|
+
params.models,
|
|
2666
|
+
params.sourceLocale,
|
|
2667
|
+
params.targetLocales
|
|
2668
|
+
);
|
|
2669
|
+
if (invalidLocales.length > 0) {
|
|
2670
|
+
console.log(dedent3`
|
|
2671
|
+
\n
|
|
2672
|
+
⚠️ Lingo.dev Localization Compiler requires LLM model setup for the following locales: ${invalidLocales.join(", ")}.
|
|
2673
|
+
|
|
2674
|
+
⭐️ Next steps:
|
|
2675
|
+
1. Refer to documentation for help: https://docs.lingo.dev/
|
|
2676
|
+
2. If you want to use a different LLM, raise an issue in our open-source repo: https://lingo.dev/go/gh
|
|
2677
|
+
3. If you have questions, feature requests, or would like to contribute, join our Discord: https://lingo.dev/go/discord
|
|
2678
|
+
|
|
2679
|
+
✨
|
|
2680
|
+
`);
|
|
2681
|
+
process.exit(1);
|
|
2682
|
+
}
|
|
2683
|
+
}
|
|
2529
2684
|
}
|
|
2530
2685
|
LCPCache.ensureDictionaryFile({
|
|
2531
2686
|
sourceRoot: params.sourceRoot,
|
|
@@ -2553,6 +2708,7 @@ var unplugin = createUnplugin(
|
|
|
2553
2708
|
lingoDir: params.lingoDir
|
|
2554
2709
|
});
|
|
2555
2710
|
const dictionary = dictionaries[moduleInfo.params.locale];
|
|
2711
|
+
console.log(JSON.stringify(dictionary, null, 2));
|
|
2556
2712
|
return {
|
|
2557
2713
|
code: `export default ${JSON.stringify(dictionary, null, 2)}`
|
|
2558
2714
|
};
|
|
@@ -2621,10 +2777,12 @@ var src_default = {
|
|
|
2621
2777
|
return config2;
|
|
2622
2778
|
}
|
|
2623
2779
|
};
|
|
2624
|
-
function
|
|
2625
|
-
|
|
2780
|
+
function getConfiguredProviders(models) {
|
|
2781
|
+
return _11.chain(Object.values(models)).map((modelString) => modelString.split(":")[0]).filter(Boolean).uniq().filter(
|
|
2626
2782
|
(providerId) => providerDetails.hasOwnProperty(providerId) && keyCheckers.hasOwnProperty(providerId)
|
|
2627
2783
|
).value();
|
|
2784
|
+
}
|
|
2785
|
+
function validateLLMKeyDetails(configuredProviders) {
|
|
2628
2786
|
if (configuredProviders.length === 0) {
|
|
2629
2787
|
return;
|
|
2630
2788
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lingo.dev/_compiler",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Lingo.dev Compiler",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
"@babel/parser": "^7.26.7",
|
|
36
36
|
"@babel/traverse": "^7.27.4",
|
|
37
37
|
"@babel/types": "^7.26.7",
|
|
38
|
+
"@openrouter/ai-sdk-provider": "^0.7.1",
|
|
38
39
|
"ai": "^4.2.10",
|
|
39
40
|
"dedent": "^1.6.0",
|
|
40
41
|
"dotenv": "^16.4.5",
|
|
@@ -42,10 +43,12 @@
|
|
|
42
43
|
"ini": "^5.0.0",
|
|
43
44
|
"lodash": "^4.17.21",
|
|
44
45
|
"object-hash": "^3.0.0",
|
|
46
|
+
"ollama-ai-provider": "^1.2.0",
|
|
45
47
|
"prettier": "^3.4.2",
|
|
46
48
|
"unplugin": "^2.1.2",
|
|
47
49
|
"vitest": "^2.1.4",
|
|
48
|
-
"zod": "^3.24.1"
|
|
50
|
+
"zod": "^3.24.1",
|
|
51
|
+
"@lingo.dev/_sdk": "0.9.1"
|
|
49
52
|
},
|
|
50
53
|
"scripts": {
|
|
51
54
|
"dev": "tsup --watch",
|