lingo.dev 0.98.0 → 0.99.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/cli.cjs CHANGED
@@ -30,7 +30,8 @@ function getSettings(explicitApiKey) {
30
30
  openaiApiKey: env.OPENAI_API_KEY || _optionalChain([systemFile, 'access', _40 => _40.llm, 'optionalAccess', _41 => _41.openaiApiKey]),
31
31
  anthropicApiKey: env.ANTHROPIC_API_KEY || _optionalChain([systemFile, 'access', _42 => _42.llm, 'optionalAccess', _43 => _43.anthropicApiKey]),
32
32
  groqApiKey: env.GROQ_API_KEY || _optionalChain([systemFile, 'access', _44 => _44.llm, 'optionalAccess', _45 => _45.groqApiKey]),
33
- googleApiKey: env.GOOGLE_API_KEY || _optionalChain([systemFile, 'access', _46 => _46.llm, 'optionalAccess', _47 => _47.googleApiKey])
33
+ googleApiKey: env.GOOGLE_API_KEY || _optionalChain([systemFile, 'access', _46 => _46.llm, 'optionalAccess', _47 => _47.googleApiKey]),
34
+ openrouterApiKey: env.OPENROUTER_API_KEY || _optionalChain([systemFile, 'access', _48 => _48.llm, 'optionalAccess', _49 => _49.openrouterApiKey])
34
35
  }
35
36
  };
36
37
  }
@@ -59,7 +60,8 @@ var SettingsSchema = _zod2.default.object({
59
60
  openaiApiKey: _zod2.default.string().optional(),
60
61
  anthropicApiKey: _zod2.default.string().optional(),
61
62
  groqApiKey: _zod2.default.string().optional(),
62
- googleApiKey: _zod2.default.string().optional()
63
+ googleApiKey: _zod2.default.string().optional(),
64
+ openrouterApiKey: _zod2.default.string().optional()
63
65
  })
64
66
  });
65
67
  var SETTINGS_KEYS = flattenZodObject(
@@ -83,7 +85,8 @@ function _loadEnv() {
83
85
  OPENAI_API_KEY: _zod2.default.string().optional(),
84
86
  ANTHROPIC_API_KEY: _zod2.default.string().optional(),
85
87
  GROQ_API_KEY: _zod2.default.string().optional(),
86
- GOOGLE_API_KEY: _zod2.default.string().optional()
88
+ GOOGLE_API_KEY: _zod2.default.string().optional(),
89
+ OPENROUTER_API_KEY: _zod2.default.string().optional()
87
90
  }).passthrough().parse(process.env);
88
91
  }
89
92
  function _loadSystemFile() {
@@ -100,7 +103,8 @@ function _loadSystemFile() {
100
103
  openaiApiKey: _zod2.default.string().optional(),
101
104
  anthropicApiKey: _zod2.default.string().optional(),
102
105
  groqApiKey: _zod2.default.string().optional(),
103
- googleApiKey: _zod2.default.string().optional()
106
+ googleApiKey: _zod2.default.string().optional(),
107
+ openrouterApiKey: _zod2.default.string().optional()
104
108
  }).optional()
105
109
  }).passthrough().parse(data);
106
110
  }
@@ -133,36 +137,42 @@ Please use LINGODOTDEV_API_KEY instead.
133
137
  function _envVarsInfo() {
134
138
  const env = _loadEnv();
135
139
  const systemFile = _loadSystemFile();
136
- if (env.LINGODOTDEV_API_KEY && _optionalChain([systemFile, 'access', _48 => _48.auth, 'optionalAccess', _49 => _49.apiKey])) {
140
+ if (env.LINGODOTDEV_API_KEY && _optionalChain([systemFile, 'access', _50 => _50.auth, 'optionalAccess', _51 => _51.apiKey])) {
137
141
  console.info(
138
142
  "\x1B[36m%s\x1B[0m",
139
143
  `\u2139\uFE0F Using LINGODOTDEV_API_KEY env var instead of credentials from user config`
140
144
  );
141
145
  }
142
- if (env.OPENAI_API_KEY && _optionalChain([systemFile, 'access', _50 => _50.llm, 'optionalAccess', _51 => _51.openaiApiKey])) {
146
+ if (env.OPENAI_API_KEY && _optionalChain([systemFile, 'access', _52 => _52.llm, 'optionalAccess', _53 => _53.openaiApiKey])) {
143
147
  console.info(
144
148
  "\x1B[36m%s\x1B[0m",
145
149
  `\u2139\uFE0F Using OPENAI_API_KEY env var instead of key from user config.`
146
150
  );
147
151
  }
148
- if (env.ANTHROPIC_API_KEY && _optionalChain([systemFile, 'access', _52 => _52.llm, 'optionalAccess', _53 => _53.anthropicApiKey])) {
152
+ if (env.ANTHROPIC_API_KEY && _optionalChain([systemFile, 'access', _54 => _54.llm, 'optionalAccess', _55 => _55.anthropicApiKey])) {
149
153
  console.info(
150
154
  "\x1B[36m%s\x1B[0m",
151
155
  `\u2139\uFE0F Using ANTHROPIC_API_KEY env var instead of key from user config`
152
156
  );
153
157
  }
154
- if (env.GROQ_API_KEY && _optionalChain([systemFile, 'access', _54 => _54.llm, 'optionalAccess', _55 => _55.groqApiKey])) {
158
+ if (env.GROQ_API_KEY && _optionalChain([systemFile, 'access', _56 => _56.llm, 'optionalAccess', _57 => _57.groqApiKey])) {
155
159
  console.info(
156
160
  "\x1B[36m%s\x1B[0m",
157
161
  `\u2139\uFE0F Using GROQ_API_KEY env var instead of key from user config`
158
162
  );
159
163
  }
160
- if (env.GOOGLE_API_KEY && _optionalChain([systemFile, 'access', _56 => _56.llm, 'optionalAccess', _57 => _57.googleApiKey])) {
164
+ if (env.GOOGLE_API_KEY && _optionalChain([systemFile, 'access', _58 => _58.llm, 'optionalAccess', _59 => _59.googleApiKey])) {
161
165
  console.info(
162
166
  "\x1B[36m%s\x1B[0m",
163
167
  `\u2139\uFE0F Using GOOGLE_API_KEY env var instead of key from user config`
164
168
  );
165
169
  }
170
+ if (env.OPENROUTER_API_KEY && _optionalChain([systemFile, 'access', _60 => _60.llm, 'optionalAccess', _61 => _61.openrouterApiKey])) {
171
+ console.info(
172
+ "\x1B[36m%s\x1B[0m",
173
+ `\u2139\uFE0F Using OPENROUTER_API_KEY env var instead of key from user config`
174
+ );
175
+ }
166
176
  if (env.LINGODOTDEV_API_URL) {
167
177
  console.info(
168
178
  "\x1B[36m%s\x1B[0m",
@@ -238,7 +248,7 @@ function createAuthenticator(params) {
238
248
  });
239
249
  if (res.ok) {
240
250
  const payload = await res.json();
241
- if (!_optionalChain([payload, 'optionalAccess', _58 => _58.email])) {
251
+ if (!_optionalChain([payload, 'optionalAccess', _62 => _62.email])) {
242
252
  return null;
243
253
  }
244
254
  return {
@@ -1024,7 +1034,7 @@ var init_default = new (0, _interactivecommander.InteractiveCommand)().command("
1024
1034
  });
1025
1035
  const auth2 = await newAuthenticator.whoami();
1026
1036
  if (auth2) {
1027
- _ora2.default.call(void 0, ).succeed(`Authenticated as ${_optionalChain([auth2, 'optionalAccess', _59 => _59.email])}`);
1037
+ _ora2.default.call(void 0, ).succeed(`Authenticated as ${_optionalChain([auth2, 'optionalAccess', _63 => _63.email])}`);
1028
1038
  } else {
1029
1039
  _ora2.default.call(void 0, ).fail("Authentication failed.");
1030
1040
  }
@@ -1109,7 +1119,7 @@ function getBuckets(i18nConfig) {
1109
1119
  const includeItems = bucketEntry.include.map(
1110
1120
  (item) => resolveBucketItem(item)
1111
1121
  );
1112
- const excludeItems = _optionalChain([bucketEntry, 'access', _60 => _60.exclude, 'optionalAccess', _61 => _61.map, 'call', _62 => _62(
1122
+ const excludeItems = _optionalChain([bucketEntry, 'access', _64 => _64.exclude, 'optionalAccess', _65 => _65.map, 'call', _66 => _66(
1113
1123
  (item) => resolveBucketItem(item)
1114
1124
  )]);
1115
1125
  const config = {
@@ -1147,7 +1157,7 @@ function extractPathPatterns(sourceLocale, include, exclude) {
1147
1157
  delimiter: pattern.delimiter
1148
1158
  }))
1149
1159
  );
1150
- const excludedPatterns = _optionalChain([exclude, 'optionalAccess', _63 => _63.flatMap, 'call', _64 => _64(
1160
+ const excludedPatterns = _optionalChain([exclude, 'optionalAccess', _67 => _67.flatMap, 'call', _68 => _68(
1151
1161
  (pattern) => expandPlaceholderedGlob(
1152
1162
  pattern.path,
1153
1163
  __spec.resolveOverriddenLocale.call(void 0, sourceLocale, pattern.delimiter)
@@ -1400,12 +1410,12 @@ function composeLoaders(...loaders) {
1400
1410
  return {
1401
1411
  init: async () => {
1402
1412
  for (const loader of loaders) {
1403
- await _optionalChain([loader, 'access', _65 => _65.init, 'optionalCall', _66 => _66()]);
1413
+ await _optionalChain([loader, 'access', _69 => _69.init, 'optionalCall', _70 => _70()]);
1404
1414
  }
1405
1415
  },
1406
1416
  setDefaultLocale(locale) {
1407
1417
  for (const loader of loaders) {
1408
- _optionalChain([loader, 'access', _67 => _67.setDefaultLocale, 'optionalCall', _68 => _68(locale)]);
1418
+ _optionalChain([loader, 'access', _71 => _71.setDefaultLocale, 'optionalCall', _72 => _72(locale)]);
1409
1419
  }
1410
1420
  return this;
1411
1421
  },
@@ -1438,7 +1448,7 @@ function createLoader(lDefinition) {
1438
1448
  if (state.initCtx) {
1439
1449
  return state.initCtx;
1440
1450
  }
1441
- state.initCtx = await _optionalChain([lDefinition, 'access', _69 => _69.init, 'optionalCall', _70 => _70()]);
1451
+ state.initCtx = await _optionalChain([lDefinition, 'access', _73 => _73.init, 'optionalCall', _74 => _74()]);
1442
1452
  return state.initCtx;
1443
1453
  },
1444
1454
  setDefaultLocale(locale) {
@@ -1543,7 +1553,7 @@ function createNormalizeLoader() {
1543
1553
  return normalized;
1544
1554
  },
1545
1555
  push: async (locale, data, originalInput) => {
1546
- const keysMap = _nullishCoalesce(_optionalChain([originalInput, 'optionalAccess', _71 => _71.keysMap]), () => ( {}));
1556
+ const keysMap = _nullishCoalesce(_optionalChain([originalInput, 'optionalAccess', _75 => _75.keysMap]), () => ( {}));
1547
1557
  const input2 = mapDenormalizedKeys(data, keysMap);
1548
1558
  const denormalized = _flat.unflatten.call(void 0, input2, {
1549
1559
  delimiter: "/",
@@ -1646,8 +1656,8 @@ async function getTrailingNewLine(pathPattern, locale, originalLocale) {
1646
1656
  if (!templateData) {
1647
1657
  templateData = await readFileForLocale(pathPattern, originalLocale);
1648
1658
  }
1649
- if (_optionalChain([templateData, 'optionalAccess', _72 => _72.match, 'call', _73 => _73(/[\r\n]$/)])) {
1650
- const ending = _optionalChain([templateData, 'optionalAccess', _74 => _74.includes, 'call', _75 => _75("\r\n")]) ? "\r\n" : _optionalChain([templateData, 'optionalAccess', _76 => _76.includes, 'call', _77 => _77("\r")]) ? "\r" : "\n";
1659
+ if (_optionalChain([templateData, 'optionalAccess', _76 => _76.match, 'call', _77 => _77(/[\r\n]$/)])) {
1660
+ const ending = _optionalChain([templateData, 'optionalAccess', _78 => _78.includes, 'call', _79 => _79("\r\n")]) ? "\r\n" : _optionalChain([templateData, 'optionalAccess', _80 => _80.includes, 'call', _81 => _81("\r")]) ? "\r" : "\n";
1651
1661
  return ending;
1652
1662
  }
1653
1663
  return "";
@@ -1911,7 +1921,7 @@ var _sync3 = require('csv-stringify/sync');
1911
1921
 
1912
1922
  function detectKeyColumnName(csvString) {
1913
1923
  const row = _sync.parse.call(void 0, csvString)[0];
1914
- const firstColumn = _optionalChain([row, 'optionalAccess', _78 => _78[0], 'optionalAccess', _79 => _79.trim, 'call', _80 => _80()]);
1924
+ const firstColumn = _optionalChain([row, 'optionalAccess', _82 => _82[0], 'optionalAccess', _83 => _83.trim, 'call', _84 => _84()]);
1915
1925
  return firstColumn || "KEY";
1916
1926
  }
1917
1927
  function createCsvLoader() {
@@ -2009,7 +2019,7 @@ function createHtmlLoader() {
2009
2019
  break;
2010
2020
  }
2011
2021
  const siblings = Array.from(parent.childNodes).filter(
2012
- (n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _81 => _81.textContent, 'optionalAccess', _82 => _82.trim, 'call', _83 => _83()])
2022
+ (n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _85 => _85.textContent, 'optionalAccess', _86 => _86.trim, 'call', _87 => _87()])
2013
2023
  );
2014
2024
  const index = siblings.indexOf(current);
2015
2025
  if (index !== -1) {
@@ -2044,11 +2054,11 @@ function createHtmlLoader() {
2044
2054
  result[getPath(element, attr)] = value;
2045
2055
  }
2046
2056
  });
2047
- Array.from(element.childNodes).filter((n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _84 => _84.textContent, 'optionalAccess', _85 => _85.trim, 'call', _86 => _86()])).forEach(processNode);
2057
+ Array.from(element.childNodes).filter((n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _88 => _88.textContent, 'optionalAccess', _89 => _89.trim, 'call', _90 => _90()])).forEach(processNode);
2048
2058
  }
2049
2059
  };
2050
- Array.from(document.head.childNodes).filter((n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _87 => _87.textContent, 'optionalAccess', _88 => _88.trim, 'call', _89 => _89()])).forEach(processNode);
2051
- Array.from(document.body.childNodes).filter((n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _90 => _90.textContent, 'optionalAccess', _91 => _91.trim, 'call', _92 => _92()])).forEach(processNode);
2060
+ Array.from(document.head.childNodes).filter((n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _91 => _91.textContent, 'optionalAccess', _92 => _92.trim, 'call', _93 => _93()])).forEach(processNode);
2061
+ Array.from(document.body.childNodes).filter((n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _94 => _94.textContent, 'optionalAccess', _95 => _95.trim, 'call', _96 => _96()])).forEach(processNode);
2052
2062
  return result;
2053
2063
  },
2054
2064
  async push(locale, data, originalInput) {
@@ -2070,7 +2080,7 @@ function createHtmlLoader() {
2070
2080
  for (let i = 0; i < indices.length; i++) {
2071
2081
  const index = parseInt(indices[i]);
2072
2082
  const siblings = Array.from(parent.childNodes).filter(
2073
- (n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _93 => _93.textContent, 'optionalAccess', _94 => _94.trim, 'call', _95 => _95()])
2083
+ (n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _97 => _97.textContent, 'optionalAccess', _98 => _98.trim, 'call', _99 => _99()])
2074
2084
  );
2075
2085
  if (index >= siblings.length) {
2076
2086
  if (i === indices.length - 1) {
@@ -2121,7 +2131,7 @@ function createMarkdownLoader() {
2121
2131
  yaml: yamlEngine
2122
2132
  }
2123
2133
  });
2124
- const sections = content.split(SECTION_REGEX).map((section) => _nullishCoalesce(_optionalChain([section, 'optionalAccess', _96 => _96.trim, 'call', _97 => _97()]), () => ( ""))).filter(Boolean);
2134
+ const sections = content.split(SECTION_REGEX).map((section) => _nullishCoalesce(_optionalChain([section, 'optionalAccess', _100 => _100.trim, 'call', _101 => _101()]), () => ( ""))).filter(Boolean);
2125
2135
  return {
2126
2136
  ...Object.fromEntries(
2127
2137
  sections.map((section, index) => [`${MD_SECTION_PREFIX}${index}`, section]).filter(([, section]) => Boolean(section))
@@ -2133,7 +2143,7 @@ function createMarkdownLoader() {
2133
2143
  const frontmatter = Object.fromEntries(
2134
2144
  Object.entries(data).filter(([key]) => key.startsWith(FM_ATTR_PREFIX)).map(([key, value]) => [key.replace(FM_ATTR_PREFIX, ""), value])
2135
2145
  );
2136
- let content = Object.entries(data).filter(([key]) => key.startsWith(MD_SECTION_PREFIX)).sort(([a], [b]) => Number(a.split("-").pop()) - Number(b.split("-").pop())).map(([, value]) => _nullishCoalesce(_optionalChain([value, 'optionalAccess', _98 => _98.trim, 'call', _99 => _99()]), () => ( ""))).filter(Boolean).join("\n\n");
2146
+ let content = Object.entries(data).filter(([key]) => key.startsWith(MD_SECTION_PREFIX)).sort(([a], [b]) => Number(a.split("-").pop()) - Number(b.split("-").pop())).map(([, value]) => _nullishCoalesce(_optionalChain([value, 'optionalAccess', _102 => _102.trim, 'call', _103 => _103()]), () => ( ""))).filter(Boolean).join("\n\n");
2137
2147
  if (Object.keys(frontmatter).length > 0) {
2138
2148
  content = `
2139
2149
  ${content}`;
@@ -2177,7 +2187,7 @@ function isSkippableLine(line) {
2177
2187
  function parsePropertyLine(line) {
2178
2188
  const [key, ...valueParts] = line.split("=");
2179
2189
  return {
2180
- key: _optionalChain([key, 'optionalAccess', _100 => _100.trim, 'call', _101 => _101()]) || "",
2190
+ key: _optionalChain([key, 'optionalAccess', _104 => _104.trim, 'call', _105 => _105()]) || "",
2181
2191
  value: valueParts.join("=").trim()
2182
2192
  };
2183
2193
  }
@@ -2263,7 +2273,7 @@ function createXcodeXcstringsLoader(defaultLocale) {
2263
2273
  if (rootTranslationEntity.shouldTranslate === false) {
2264
2274
  continue;
2265
2275
  }
2266
- const langTranslationEntity = _optionalChain([rootTranslationEntity, 'optionalAccess', _102 => _102.localizations, 'optionalAccess', _103 => _103[locale]]);
2276
+ const langTranslationEntity = _optionalChain([rootTranslationEntity, 'optionalAccess', _106 => _106.localizations, 'optionalAccess', _107 => _107[locale]]);
2267
2277
  if (langTranslationEntity) {
2268
2278
  if ("stringUnit" in langTranslationEntity) {
2269
2279
  resultData[translationKey] = langTranslationEntity.stringUnit.value;
@@ -2272,7 +2282,7 @@ function createXcodeXcstringsLoader(defaultLocale) {
2272
2282
  resultData[translationKey] = {};
2273
2283
  const pluralForms = langTranslationEntity.variations.plural;
2274
2284
  for (const form in pluralForms) {
2275
- if (_optionalChain([pluralForms, 'access', _104 => _104[form], 'optionalAccess', _105 => _105.stringUnit, 'optionalAccess', _106 => _106.value])) {
2285
+ if (_optionalChain([pluralForms, 'access', _108 => _108[form], 'optionalAccess', _109 => _109.stringUnit, 'optionalAccess', _110 => _110.value])) {
2276
2286
  resultData[translationKey][form] = pluralForms[form].stringUnit.value;
2277
2287
  }
2278
2288
  }
@@ -2295,7 +2305,7 @@ function createXcodeXcstringsLoader(defaultLocale) {
2295
2305
  const hasDoNotTranslateFlag = originalInput && originalInput.strings && originalInput.strings[key] && originalInput.strings[key].shouldTranslate === false;
2296
2306
  if (typeof value === "string") {
2297
2307
  langDataToMerge.strings[key] = {
2298
- extractionState: _optionalChain([originalInput, 'optionalAccess', _107 => _107.strings, 'optionalAccess', _108 => _108[key], 'optionalAccess', _109 => _109.extractionState]),
2308
+ extractionState: _optionalChain([originalInput, 'optionalAccess', _111 => _111.strings, 'optionalAccess', _112 => _112[key], 'optionalAccess', _113 => _113.extractionState]),
2299
2309
  localizations: {
2300
2310
  [locale]: {
2301
2311
  stringUnit: {
@@ -2478,7 +2488,7 @@ function createPoDataLoader(params) {
2478
2488
  Object.entries(entries).forEach(([msgid, entry]) => {
2479
2489
  if (msgid && entry.msgid) {
2480
2490
  const context = entry.msgctxt || "";
2481
- const fullEntry = _optionalChain([parsedPo, 'access', _110 => _110.translations, 'access', _111 => _111[context], 'optionalAccess', _112 => _112[msgid]]);
2491
+ const fullEntry = _optionalChain([parsedPo, 'access', _114 => _114.translations, 'access', _115 => _115[context], 'optionalAccess', _116 => _116[msgid]]);
2482
2492
  if (fullEntry) {
2483
2493
  result[msgid] = fullEntry;
2484
2494
  }
@@ -2488,8 +2498,8 @@ function createPoDataLoader(params) {
2488
2498
  return result;
2489
2499
  },
2490
2500
  async push(locale, data, originalInput, originalLocale, pullInput) {
2491
- const currentSections = _optionalChain([pullInput, 'optionalAccess', _113 => _113.split, 'call', _114 => _114("\n\n"), 'access', _115 => _115.filter, 'call', _116 => _116(Boolean)]) || [];
2492
- const originalSections = _optionalChain([originalInput, 'optionalAccess', _117 => _117.split, 'call', _118 => _118("\n\n"), 'access', _119 => _119.filter, 'call', _120 => _120(Boolean)]) || [];
2501
+ const currentSections = _optionalChain([pullInput, 'optionalAccess', _117 => _117.split, 'call', _118 => _118("\n\n"), 'access', _119 => _119.filter, 'call', _120 => _120(Boolean)]) || [];
2502
+ const originalSections = _optionalChain([originalInput, 'optionalAccess', _121 => _121.split, 'call', _122 => _122("\n\n"), 'access', _123 => _123.filter, 'call', _124 => _124(Boolean)]) || [];
2493
2503
  const result = originalSections.map((section) => {
2494
2504
  const sectionPo = _gettextparser2.default.po.parse(section);
2495
2505
  if (Object.keys(sectionPo.translations).length === 0) {
@@ -2558,8 +2568,8 @@ function createPoContentLoader() {
2558
2568
  {
2559
2569
  ...entry,
2560
2570
  msgstr: [
2561
- _optionalChain([data, 'access', _121 => _121[entry.msgid], 'optionalAccess', _122 => _122.singular]),
2562
- _optionalChain([data, 'access', _123 => _123[entry.msgid], 'optionalAccess', _124 => _124.plural]) || null
2571
+ _optionalChain([data, 'access', _125 => _125[entry.msgid], 'optionalAccess', _126 => _126.singular]),
2572
+ _optionalChain([data, 'access', _127 => _127[entry.msgid], 'optionalAccess', _128 => _128.plural]) || null
2563
2573
  ].filter(Boolean)
2564
2574
  }
2565
2575
  ]).fromPairs().value();
@@ -2835,7 +2845,7 @@ function createDatoClient(params) {
2835
2845
  only_valid: "true",
2836
2846
  ids: !records.length ? void 0 : records.join(",")
2837
2847
  }
2838
- }).catch((error) => Promise.reject(_optionalChain([error, 'optionalAccess', _125 => _125.response, 'optionalAccess', _126 => _126.body, 'optionalAccess', _127 => _127.data, 'optionalAccess', _128 => _128[0]]) || error));
2848
+ }).catch((error) => Promise.reject(_optionalChain([error, 'optionalAccess', _129 => _129.response, 'optionalAccess', _130 => _130.body, 'optionalAccess', _131 => _131.data, 'optionalAccess', _132 => _132[0]]) || error));
2839
2849
  },
2840
2850
  findRecordsForModel: async (modelId, records) => {
2841
2851
  try {
@@ -2845,9 +2855,9 @@ function createDatoClient(params) {
2845
2855
  filter: {
2846
2856
  type: modelId,
2847
2857
  only_valid: "true",
2848
- ids: !_optionalChain([records, 'optionalAccess', _129 => _129.length]) ? void 0 : records.join(",")
2858
+ ids: !_optionalChain([records, 'optionalAccess', _133 => _133.length]) ? void 0 : records.join(",")
2849
2859
  }
2850
- }).catch((error) => Promise.reject(_optionalChain([error, 'optionalAccess', _130 => _130.response, 'optionalAccess', _131 => _131.body, 'optionalAccess', _132 => _132.data, 'optionalAccess', _133 => _133[0]]) || error));
2860
+ }).catch((error) => Promise.reject(_optionalChain([error, 'optionalAccess', _134 => _134.response, 'optionalAccess', _135 => _135.body, 'optionalAccess', _136 => _136.data, 'optionalAccess', _137 => _137[0]]) || error));
2851
2861
  return result;
2852
2862
  } catch (_error) {
2853
2863
  throw new Error(
@@ -2861,9 +2871,9 @@ function createDatoClient(params) {
2861
2871
  },
2862
2872
  updateRecord: async (id, payload) => {
2863
2873
  try {
2864
- await dato.items.update(id, payload).catch((error) => Promise.reject(_optionalChain([error, 'optionalAccess', _134 => _134.response, 'optionalAccess', _135 => _135.body, 'optionalAccess', _136 => _136.data, 'optionalAccess', _137 => _137[0]]) || error));
2874
+ await dato.items.update(id, payload).catch((error) => Promise.reject(_optionalChain([error, 'optionalAccess', _138 => _138.response, 'optionalAccess', _139 => _139.body, 'optionalAccess', _140 => _140.data, 'optionalAccess', _141 => _141[0]]) || error));
2865
2875
  } catch (_error) {
2866
- if (_optionalChain([_error, 'optionalAccess', _138 => _138.attributes, 'optionalAccess', _139 => _139.details, 'optionalAccess', _140 => _140.message])) {
2876
+ if (_optionalChain([_error, 'optionalAccess', _142 => _142.attributes, 'optionalAccess', _143 => _143.details, 'optionalAccess', _144 => _144.message])) {
2867
2877
  throw new Error(
2868
2878
  [
2869
2879
  `${_error.attributes.details.message}`,
@@ -2884,9 +2894,9 @@ function createDatoClient(params) {
2884
2894
  },
2885
2895
  enableFieldLocalization: async (args) => {
2886
2896
  try {
2887
- await dato.fields.update(`${args.modelId}::${args.fieldId}`, { localized: true }).catch((error) => Promise.reject(_optionalChain([error, 'optionalAccess', _141 => _141.response, 'optionalAccess', _142 => _142.body, 'optionalAccess', _143 => _143.data, 'optionalAccess', _144 => _144[0]]) || error));
2897
+ await dato.fields.update(`${args.modelId}::${args.fieldId}`, { localized: true }).catch((error) => Promise.reject(_optionalChain([error, 'optionalAccess', _145 => _145.response, 'optionalAccess', _146 => _146.body, 'optionalAccess', _147 => _147.data, 'optionalAccess', _148 => _148[0]]) || error));
2888
2898
  } catch (_error) {
2889
- if (_optionalChain([_error, 'optionalAccess', _145 => _145.attributes, 'optionalAccess', _146 => _146.code]) === "NOT_FOUND") {
2899
+ if (_optionalChain([_error, 'optionalAccess', _149 => _149.attributes, 'optionalAccess', _150 => _150.code]) === "NOT_FOUND") {
2890
2900
  throw new Error(
2891
2901
  [
2892
2902
  `Field "${args.fieldId}" not found in model "${args.modelId}".`,
@@ -2894,7 +2904,7 @@ function createDatoClient(params) {
2894
2904
  ].join("\n\n")
2895
2905
  );
2896
2906
  }
2897
- if (_optionalChain([_error, 'optionalAccess', _147 => _147.attributes, 'optionalAccess', _148 => _148.details, 'optionalAccess', _149 => _149.message])) {
2907
+ if (_optionalChain([_error, 'optionalAccess', _151 => _151.attributes, 'optionalAccess', _152 => _152.details, 'optionalAccess', _153 => _153.message])) {
2898
2908
  throw new Error(
2899
2909
  [`${_error.attributes.details.message}`, `Error: ${JSON.stringify(_error, null, 2)}`].join("\n\n")
2900
2910
  );
@@ -2960,7 +2970,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
2960
2970
  }
2961
2971
  }
2962
2972
  const records = await dato.findRecordsForModel(modelId);
2963
- const recordChoices = createRecordChoices(records, _optionalChain([config, 'access', _150 => _150.models, 'access', _151 => _151[modelId], 'optionalAccess', _152 => _152.records]) || [], project);
2973
+ const recordChoices = createRecordChoices(records, _optionalChain([config, 'access', _154 => _154.models, 'access', _155 => _155[modelId], 'optionalAccess', _156 => _156.records]) || [], project);
2964
2974
  const selectedRecords = await promptRecordSelection(modelName, recordChoices);
2965
2975
  result.models[modelId].records = records.filter((record) => selectedRecords.includes(record.id));
2966
2976
  updatedConfig.models[modelId].records = selectedRecords;
@@ -2972,14 +2982,14 @@ function createDatoApiLoader(config, onConfigUpdate) {
2972
2982
  },
2973
2983
  async pull(locale, input2, initCtx) {
2974
2984
  const result = {};
2975
- for (const modelId of _lodash2.default.keys(_optionalChain([initCtx, 'optionalAccess', _153 => _153.models]) || {})) {
2976
- let records = _optionalChain([initCtx, 'optionalAccess', _154 => _154.models, 'access', _155 => _155[modelId], 'access', _156 => _156.records]) || [];
2985
+ for (const modelId of _lodash2.default.keys(_optionalChain([initCtx, 'optionalAccess', _157 => _157.models]) || {})) {
2986
+ let records = _optionalChain([initCtx, 'optionalAccess', _158 => _158.models, 'access', _159 => _159[modelId], 'access', _160 => _160.records]) || [];
2977
2987
  const recordIds = records.map((record) => record.id);
2978
2988
  records = await dato.findRecords(recordIds);
2979
2989
  console.log(`Fetched ${records.length} records for model ${modelId}`);
2980
2990
  if (records.length > 0) {
2981
2991
  result[modelId] = {
2982
- fields: _optionalChain([initCtx, 'optionalAccess', _157 => _157.models, 'optionalAccess', _158 => _158[modelId], 'optionalAccess', _159 => _159.fields]) || [],
2992
+ fields: _optionalChain([initCtx, 'optionalAccess', _161 => _161.models, 'optionalAccess', _162 => _162[modelId], 'optionalAccess', _163 => _163.fields]) || [],
2983
2993
  records
2984
2994
  };
2985
2995
  }
@@ -3038,7 +3048,7 @@ function createRecordChoices(records, selectedIds = [], project) {
3038
3048
  return records.map((record) => ({
3039
3049
  name: `${record.id} - https://${project.internal_domain}/editor/item_types/${record.item_type.id}/items/${record.id}`,
3040
3050
  value: record.id,
3041
- checked: _optionalChain([selectedIds, 'optionalAccess', _160 => _160.includes, 'call', _161 => _161(record.id)])
3051
+ checked: _optionalChain([selectedIds, 'optionalAccess', _164 => _164.includes, 'call', _165 => _165(record.id)])
3042
3052
  }));
3043
3053
  }
3044
3054
  async function promptRecordSelection(modelName, choices) {
@@ -3308,7 +3318,7 @@ function createVttLoader() {
3308
3318
  if (!input2) {
3309
3319
  return "";
3310
3320
  }
3311
- const vtt = _optionalChain([_nodewebvtt2.default, 'access', _162 => _162.parse, 'call', _163 => _163(input2), 'optionalAccess', _164 => _164.cues]);
3321
+ const vtt = _optionalChain([_nodewebvtt2.default, 'access', _166 => _166.parse, 'call', _167 => _167(input2), 'optionalAccess', _168 => _168.cues]);
3312
3322
  if (Object.keys(vtt).length === 0) {
3313
3323
  return {};
3314
3324
  } else {
@@ -3362,7 +3372,7 @@ function variableExtractLoader(params) {
3362
3372
  for (let i = 0; i < matches.length; i++) {
3363
3373
  const match = matches[i];
3364
3374
  const currentValue = result[key].value;
3365
- const newValue = _optionalChain([currentValue, 'optionalAccess', _165 => _165.replace, 'call', _166 => _166(match, `{variable:${i}}`)]);
3375
+ const newValue = _optionalChain([currentValue, 'optionalAccess', _169 => _169.replace, 'call', _170 => _170(match, `{variable:${i}}`)]);
3366
3376
  result[key].value = newValue;
3367
3377
  result[key].variables[i] = match;
3368
3378
  }
@@ -3376,7 +3386,7 @@ function variableExtractLoader(params) {
3376
3386
  for (let i = 0; i < valueObj.variables.length; i++) {
3377
3387
  const variable = valueObj.variables[i];
3378
3388
  const currentValue = result[key];
3379
- const newValue = _optionalChain([currentValue, 'optionalAccess', _167 => _167.replace, 'call', _168 => _168(`{variable:${i}}`, variable)]);
3389
+ const newValue = _optionalChain([currentValue, 'optionalAccess', _171 => _171.replace, 'call', _172 => _172(`{variable:${i}}`, variable)]);
3380
3390
  result[key] = newValue;
3381
3391
  }
3382
3392
  }
@@ -3559,7 +3569,7 @@ function createVueJsonLoader() {
3559
3569
  return createLoader({
3560
3570
  pull: async (locale, input2, ctx) => {
3561
3571
  const parsed = parseVueFile(input2);
3562
- return _nullishCoalesce(_optionalChain([parsed, 'optionalAccess', _169 => _169.i18n, 'optionalAccess', _170 => _170[locale]]), () => ( {}));
3572
+ return _nullishCoalesce(_optionalChain([parsed, 'optionalAccess', _173 => _173.i18n, 'optionalAccess', _174 => _174[locale]]), () => ( {}));
3563
3573
  },
3564
3574
  push: async (locale, data, originalInput) => {
3565
3575
  const parsed = parseVueFile(_nullishCoalesce(originalInput, () => ( "")));
@@ -3740,7 +3750,7 @@ function updateStringsInObjectExpression(objectExpression, data) {
3740
3750
  objectExpression.properties.forEach((prop) => {
3741
3751
  if (!t.isObjectProperty(prop)) return;
3742
3752
  const key = getPropertyKey(prop);
3743
- const incomingVal = _optionalChain([data, 'optionalAccess', _171 => _171[key]]);
3753
+ const incomingVal = _optionalChain([data, 'optionalAccess', _175 => _175[key]]);
3744
3754
  if (incomingVal === void 0) {
3745
3755
  return;
3746
3756
  }
@@ -3776,7 +3786,7 @@ function updateStringsInArrayExpression(arrayExpression, incoming) {
3776
3786
  let modified = false;
3777
3787
  arrayExpression.elements.forEach((element, index) => {
3778
3788
  if (!element) return;
3779
- const incomingVal = _optionalChain([incoming, 'optionalAccess', _172 => _172[index]]);
3789
+ const incomingVal = _optionalChain([incoming, 'optionalAccess', _176 => _176[index]]);
3780
3790
  if (incomingVal === void 0) return;
3781
3791
  if (t.isStringLiteral(element) && typeof incomingVal === "string") {
3782
3792
  if (element.value !== incomingVal) {
@@ -4052,7 +4062,7 @@ function createMdxSectionsSplit2Loader() {
4052
4062
  const content = _lodash2.default.chain(data.sections).values().join("\n\n").value();
4053
4063
  const result = {
4054
4064
  frontmatter: data.frontmatter,
4055
- codePlaceholders: _optionalChain([pullInput, 'optionalAccess', _173 => _173.codePlaceholders]) || {},
4065
+ codePlaceholders: _optionalChain([pullInput, 'optionalAccess', _177 => _177.codePlaceholders]) || {},
4056
4066
  content
4057
4067
  };
4058
4068
  return result;
@@ -4495,7 +4505,7 @@ function createBasicTranslator(model, systemPrompt) {
4495
4505
  ]
4496
4506
  });
4497
4507
  const result = JSON.parse(response.text);
4498
- return _optionalChain([result, 'optionalAccess', _174 => _174.data]) || {};
4508
+ return _optionalChain([result, 'optionalAccess', _178 => _178.data]) || {};
4499
4509
  }
4500
4510
  }
4501
4511
  function extractPayloadChunks(payload) {
@@ -4537,6 +4547,8 @@ function countWordsInRecord(payload) {
4537
4547
  var _openai = require('@ai-sdk/openai');
4538
4548
  var _anthropic = require('@ai-sdk/anthropic');
4539
4549
  var _google = require('@ai-sdk/google');
4550
+ var _aisdkprovider = require('@openrouter/ai-sdk-provider');
4551
+ var _ollamaaiprovider = require('ollama-ai-provider');
4540
4552
  function createProcessor(provider, params) {
4541
4553
  if (!provider) {
4542
4554
  const result = createLingoLocalizer(params);
@@ -4549,10 +4561,10 @@ function createProcessor(provider, params) {
4549
4561
  }
4550
4562
  function getPureModelProvider(provider) {
4551
4563
  const createMissingKeyErrorMessage = (providerId, envVar) => _dedent2.default`
4552
- You're trying to use raw ${_chalk2.default.dim(providerId)} API for translation, however, ${_chalk2.default.dim(envVar)} environment variable is not set.
4564
+ You're trying to use raw ${_chalk2.default.dim(providerId)} API for translation. ${envVar ? `However, ${_chalk2.default.dim(envVar)} environment variable is not set.` : "However, that provider is unavailable."}
4553
4565
 
4554
4566
  To fix this issue:
4555
- 1. Set ${_chalk2.default.dim(envVar)} in your environment variables, or
4567
+ 1. ${envVar ? `Set ${_chalk2.default.dim(envVar)} in your environment variables` : "Set the environment variable for your provider (if required)"}, or
4556
4568
  2. Remove the ${_chalk2.default.italic("provider")} node from your i18n.json configuration to switch to ${_chalk2.default.hex(colors.green)("Lingo.dev")}
4557
4569
 
4558
4570
  ${_chalk2.default.hex(colors.blue)("Docs: https://lingo.dev/go/docs")}
@@ -4566,8 +4578,8 @@ function getPureModelProvider(provider) {
4566
4578
 
4567
4579
  ${_chalk2.default.hex(colors.blue)("Docs: https://lingo.dev/go/docs")}
4568
4580
  `;
4569
- switch (_optionalChain([provider, 'optionalAccess', _175 => _175.id])) {
4570
- case "openai":
4581
+ switch (_optionalChain([provider, 'optionalAccess', _179 => _179.id])) {
4582
+ case "openai": {
4571
4583
  if (!process.env.OPENAI_API_KEY) {
4572
4584
  throw new Error(
4573
4585
  createMissingKeyErrorMessage("OpenAI", "OPENAI_API_KEY")
@@ -4577,7 +4589,8 @@ function getPureModelProvider(provider) {
4577
4589
  apiKey: process.env.OPENAI_API_KEY,
4578
4590
  baseURL: provider.baseUrl
4579
4591
  })(provider.model);
4580
- case "anthropic":
4592
+ }
4593
+ case "anthropic": {
4581
4594
  if (!process.env.ANTHROPIC_API_KEY) {
4582
4595
  throw new Error(
4583
4596
  createMissingKeyErrorMessage("Anthropic", "ANTHROPIC_API_KEY")
@@ -4586,7 +4599,8 @@ function getPureModelProvider(provider) {
4586
4599
  return _anthropic.createAnthropic.call(void 0, {
4587
4600
  apiKey: process.env.ANTHROPIC_API_KEY
4588
4601
  })(provider.model);
4589
- case "google":
4602
+ }
4603
+ case "google": {
4590
4604
  if (!process.env.GOOGLE_API_KEY) {
4591
4605
  throw new Error(
4592
4606
  createMissingKeyErrorMessage("Google", "GOOGLE_API_KEY")
@@ -4595,8 +4609,24 @@ function getPureModelProvider(provider) {
4595
4609
  return _google.createGoogleGenerativeAI.call(void 0, {
4596
4610
  apiKey: process.env.GOOGLE_API_KEY
4597
4611
  })(provider.model);
4598
- default:
4599
- throw new Error(createUnsupportedProviderErrorMessage(_optionalChain([provider, 'optionalAccess', _176 => _176.id])));
4612
+ }
4613
+ case "openrouter": {
4614
+ if (!process.env.OPENROUTER_API_KEY) {
4615
+ throw new Error(
4616
+ createMissingKeyErrorMessage("OpenRouter", "OPENROUTER_API_KEY")
4617
+ );
4618
+ }
4619
+ return _aisdkprovider.createOpenRouter.call(void 0, {
4620
+ apiKey: process.env.OPENROUTER_API_KEY,
4621
+ baseURL: provider.baseUrl
4622
+ })(provider.model);
4623
+ }
4624
+ case "ollama": {
4625
+ return _ollamaaiprovider.createOllama.call(void 0, )(provider.model);
4626
+ }
4627
+ default: {
4628
+ throw new Error(createUnsupportedProviderErrorMessage(_optionalChain([provider, 'optionalAccess', _180 => _180.id])));
4629
+ }
4600
4630
  }
4601
4631
  }
4602
4632
 
@@ -4820,7 +4850,7 @@ var i18n_default = new (0, _interactivecommander.Command)().command("i18n").desc
4820
4850
  validateParams(i18nConfig, flags);
4821
4851
  ora.succeed("Localization configuration is valid");
4822
4852
  ora.start("Connecting to Lingo.dev Localization Engine...");
4823
- const isByokMode = !!_optionalChain([i18nConfig, 'optionalAccess', _177 => _177.provider]);
4853
+ const isByokMode = !!_optionalChain([i18nConfig, 'optionalAccess', _181 => _181.provider]);
4824
4854
  if (isByokMode) {
4825
4855
  authId = null;
4826
4856
  ora.succeed("Using external provider (BYOK mode)");
@@ -4834,16 +4864,16 @@ var i18n_default = new (0, _interactivecommander.Command)().command("i18n").desc
4834
4864
  flags
4835
4865
  });
4836
4866
  let buckets = getBuckets(i18nConfig);
4837
- if (_optionalChain([flags, 'access', _178 => _178.bucket, 'optionalAccess', _179 => _179.length])) {
4867
+ if (_optionalChain([flags, 'access', _182 => _182.bucket, 'optionalAccess', _183 => _183.length])) {
4838
4868
  buckets = buckets.filter(
4839
4869
  (bucket) => flags.bucket.includes(bucket.type)
4840
4870
  );
4841
4871
  }
4842
4872
  ora.succeed("Buckets retrieved");
4843
- if (_optionalChain([flags, 'access', _180 => _180.file, 'optionalAccess', _181 => _181.length])) {
4873
+ if (_optionalChain([flags, 'access', _184 => _184.file, 'optionalAccess', _185 => _185.length])) {
4844
4874
  buckets = buckets.map((bucket) => {
4845
4875
  const paths = bucket.paths.filter(
4846
- (path16) => flags.file.find((file) => _optionalChain([path16, 'access', _182 => _182.pathPattern, 'optionalAccess', _183 => _183.includes, 'call', _184 => _184(file)]))
4876
+ (path16) => flags.file.find((file) => _optionalChain([path16, 'access', _186 => _186.pathPattern, 'optionalAccess', _187 => _187.includes, 'call', _188 => _188(file)]))
4847
4877
  );
4848
4878
  return { ...bucket, paths };
4849
4879
  }).filter((bucket) => bucket.paths.length > 0);
@@ -4862,7 +4892,7 @@ var i18n_default = new (0, _interactivecommander.Command)().command("i18n").desc
4862
4892
  });
4863
4893
  }
4864
4894
  }
4865
- const targetLocales = _optionalChain([flags, 'access', _185 => _185.locale, 'optionalAccess', _186 => _186.length]) ? flags.locale : i18nConfig.locale.targets;
4895
+ const targetLocales = _optionalChain([flags, 'access', _189 => _189.locale, 'optionalAccess', _190 => _190.length]) ? flags.locale : i18nConfig.locale.targets;
4866
4896
  ora.start("Setting up localization cache...");
4867
4897
  const checkLockfileProcessor = createDeltaProcessor("");
4868
4898
  const lockfileExists = await checkLockfileProcessor.checkIfLockExists();
@@ -5206,12 +5236,12 @@ function validateParams(i18nConfig, flags) {
5206
5236
  message: "No buckets found in i18n.json. Please add at least one bucket containing i18n content.",
5207
5237
  docUrl: "bucketNotFound"
5208
5238
  });
5209
- } else if (_optionalChain([flags, 'access', _187 => _187.locale, 'optionalAccess', _188 => _188.some, 'call', _189 => _189((locale) => !i18nConfig.locale.targets.includes(locale))])) {
5239
+ } else if (_optionalChain([flags, 'access', _191 => _191.locale, 'optionalAccess', _192 => _192.some, 'call', _193 => _193((locale) => !i18nConfig.locale.targets.includes(locale))])) {
5210
5240
  throw new CLIError({
5211
5241
  message: `One or more specified locales do not exist in i18n.json locale.targets. Please add them to the list and try again.`,
5212
5242
  docUrl: "localeTargetNotFound"
5213
5243
  });
5214
- } else if (_optionalChain([flags, 'access', _190 => _190.bucket, 'optionalAccess', _191 => _191.some, 'call', _192 => _192(
5244
+ } else if (_optionalChain([flags, 'access', _194 => _194.bucket, 'optionalAccess', _195 => _195.some, 'call', _196 => _196(
5215
5245
  (bucket) => !i18nConfig.buckets[bucket]
5216
5246
  )])) {
5217
5247
  throw new CLIError({
@@ -5661,7 +5691,7 @@ function createLingoDotDevLocalizer(explicitApiKey) {
5661
5691
  const response = await engine.whoami();
5662
5692
  return {
5663
5693
  authenticated: !!response,
5664
- username: _optionalChain([response, 'optionalAccess', _193 => _193.email])
5694
+ username: _optionalChain([response, 'optionalAccess', _197 => _197.email])
5665
5695
  };
5666
5696
  } catch (e2) {
5667
5697
  return { authenticated: false };
@@ -5696,6 +5726,8 @@ function createLingoDotDevLocalizer(explicitApiKey) {
5696
5726
 
5697
5727
 
5698
5728
 
5729
+
5730
+
5699
5731
  function createExplicitLocalizer(provider) {
5700
5732
  switch (provider.id) {
5701
5733
  default:
@@ -5734,27 +5766,42 @@ function createExplicitLocalizer(provider) {
5734
5766
  apiKeyName: "GOOGLE_API_KEY",
5735
5767
  baseUrl: provider.baseUrl
5736
5768
  });
5769
+ case "openrouter":
5770
+ return createAiSdkLocalizer({
5771
+ factory: (params) => _aisdkprovider.createOpenRouter.call(void 0, params).languageModel(provider.model),
5772
+ id: provider.id,
5773
+ prompt: provider.prompt,
5774
+ apiKeyName: "OPENROUTER_API_KEY",
5775
+ baseUrl: provider.baseUrl
5776
+ });
5777
+ case "ollama":
5778
+ return createAiSdkLocalizer({
5779
+ factory: (_params) => _ollamaaiprovider.createOllama.call(void 0, ).languageModel(provider.model),
5780
+ id: provider.id,
5781
+ prompt: provider.prompt,
5782
+ skipAuth: true
5783
+ });
5737
5784
  }
5738
5785
  }
5739
5786
  function createAiSdkLocalizer(params) {
5740
- const apiKey = process.env[params.apiKeyName];
5741
- if (!apiKey) {
5787
+ const skipAuth = params.skipAuth === true;
5788
+ const apiKey = process.env[_nullishCoalesce(_optionalChain([params, 'optionalAccess', _198 => _198.apiKeyName]), () => ( ""))];
5789
+ if (!skipAuth && !apiKey || !params.apiKeyName) {
5742
5790
  throw new Error(
5743
5791
  _dedent2.default`
5744
- You're trying to use raw ${_chalk2.default.dim(params.id)} API for translation, however, ${_chalk2.default.dim(params.apiKeyName)} environment variable is not set.
5792
+ You're trying to use raw ${_chalk2.default.dim(params.id)} API for translation. ${params.apiKeyName ? `However, ${_chalk2.default.dim(params.apiKeyName)} environment variable is not set.` : "However, that provider is unavailable."}
5745
5793
 
5746
5794
  To fix this issue:
5747
- 1. Set ${_chalk2.default.dim(params.apiKeyName)} in your environment variables, or
5795
+ 1. ${params.apiKeyName ? `Set ${_chalk2.default.dim(params.apiKeyName)} in your environment variables` : "Set the environment variable for your provider (if required)"}, or
5748
5796
  2. Remove the ${_chalk2.default.italic("provider")} node from your i18n.json configuration to switch to ${_chalk2.default.hex(colors.green)("Lingo.dev")}
5749
5797
 
5750
5798
  ${_chalk2.default.hex(colors.blue)("Docs: https://lingo.dev/go/docs")}
5751
5799
  `
5752
5800
  );
5753
5801
  }
5754
- const model = params.factory({
5755
- apiKey,
5756
- baseUrl: params.baseUrl
5757
- });
5802
+ const model = params.factory(
5803
+ skipAuth ? {} : { apiKey, baseUrl: params.baseUrl }
5804
+ );
5758
5805
  return {
5759
5806
  id: params.id,
5760
5807
  checkAuth: async () => {
@@ -5855,8 +5902,8 @@ async function setup(input2) {
5855
5902
  throw new Error(
5856
5903
  "No buckets found in i18n.json. Please add at least one bucket containing i18n content."
5857
5904
  );
5858
- } else if (_optionalChain([ctx, 'access', _194 => _194.flags, 'access', _195 => _195.bucket, 'optionalAccess', _196 => _196.some, 'call', _197 => _197(
5859
- (bucket) => !_optionalChain([ctx, 'access', _198 => _198.config, 'optionalAccess', _199 => _199.buckets, 'access', _200 => _200[bucket]])
5905
+ } else if (_optionalChain([ctx, 'access', _199 => _199.flags, 'access', _200 => _200.bucket, 'optionalAccess', _201 => _201.some, 'call', _202 => _202(
5906
+ (bucket) => !_optionalChain([ctx, 'access', _203 => _203.config, 'optionalAccess', _204 => _204.buckets, 'access', _205 => _205[bucket]])
5860
5907
  )])) {
5861
5908
  throw new Error(
5862
5909
  `One or more specified buckets do not exist in i18n.json. Please add them to the list first and try again.`
@@ -5869,7 +5916,7 @@ async function setup(input2) {
5869
5916
  title: "Selecting localization provider",
5870
5917
  task: async (ctx, task) => {
5871
5918
  ctx.localizer = createLocalizer(
5872
- _optionalChain([ctx, 'access', _201 => _201.config, 'optionalAccess', _202 => _202.provider]),
5919
+ _optionalChain([ctx, 'access', _206 => _206.config, 'optionalAccess', _207 => _207.provider]),
5873
5920
  ctx.flags.apiKey
5874
5921
  );
5875
5922
  if (!ctx.localizer) {
@@ -6249,13 +6296,13 @@ var flagsSchema2 = _zod.z.object({
6249
6296
 
6250
6297
  // src/cli/cmd/run/_utils.ts
6251
6298
  async function determineAuthId(ctx) {
6252
- const isByokMode = !!_optionalChain([ctx, 'access', _203 => _203.config, 'optionalAccess', _204 => _204.provider]);
6299
+ const isByokMode = !!_optionalChain([ctx, 'access', _208 => _208.config, 'optionalAccess', _209 => _209.provider]);
6253
6300
  if (isByokMode) {
6254
6301
  return null;
6255
6302
  } else {
6256
6303
  try {
6257
- const authStatus = await _optionalChain([ctx, 'access', _205 => _205.localizer, 'optionalAccess', _206 => _206.checkAuth, 'call', _207 => _207()]);
6258
- return _optionalChain([authStatus, 'optionalAccess', _208 => _208.username]) || null;
6304
+ const authStatus = await _optionalChain([ctx, 'access', _210 => _210.localizer, 'optionalAccess', _211 => _211.checkAuth, 'call', _212 => _212()]);
6305
+ return _optionalChain([authStatus, 'optionalAccess', _213 => _213.username]) || null;
6259
6306
  } catch (e3) {
6260
6307
  return null;
6261
6308
  }
@@ -6403,7 +6450,7 @@ var InBranchFlow = class extends IntegrationFlow {
6403
6450
  _child_process.execSync.call(void 0, `git config --global safe.directory ${process.cwd()}`);
6404
6451
  _child_process.execSync.call(void 0, `git config user.name "${gitConfig.userName}"`);
6405
6452
  _child_process.execSync.call(void 0, `git config user.email "${gitConfig.userEmail}"`);
6406
- _optionalChain([this, 'access', _209 => _209.platformKit, 'optionalAccess', _210 => _210.gitConfig, 'call', _211 => _211()]);
6453
+ _optionalChain([this, 'access', _214 => _214.platformKit, 'optionalAccess', _215 => _215.gitConfig, 'call', _216 => _216()]);
6407
6454
  _child_process.execSync.call(void 0, `git fetch origin ${baseBranchName}`, { stdio: "inherit" });
6408
6455
  _child_process.execSync.call(void 0, `git checkout ${baseBranchName} --`, { stdio: "inherit" });
6409
6456
  if (!processOwnCommits) {
@@ -6435,7 +6482,7 @@ var InBranchFlow = class extends IntegrationFlow {
6435
6482
  // src/cli/cmd/ci/flows/pull-request.ts
6436
6483
  var PullRequestFlow = class extends InBranchFlow {
6437
6484
  async preRun() {
6438
- const canContinue = await _optionalChain([super.preRun.bind(this), 'optionalCall', _212 => _212()]);
6485
+ const canContinue = await _optionalChain([super.preRun.bind(this), 'optionalCall', _217 => _217()]);
6439
6486
  if (!canContinue) {
6440
6487
  return false;
6441
6488
  }
@@ -6690,10 +6737,10 @@ var BitbucketPlatformKit = class extends PlatformKit {
6690
6737
  repo_slug: this.platformConfig.repositoryName,
6691
6738
  state: "OPEN"
6692
6739
  }).then(({ data: { values } }) => {
6693
- return _optionalChain([values, 'optionalAccess', _213 => _213.find, 'call', _214 => _214(
6694
- ({ source, destination }) => _optionalChain([source, 'optionalAccess', _215 => _215.branch, 'optionalAccess', _216 => _216.name]) === branch && _optionalChain([destination, 'optionalAccess', _217 => _217.branch, 'optionalAccess', _218 => _218.name]) === this.platformConfig.baseBranchName
6740
+ return _optionalChain([values, 'optionalAccess', _218 => _218.find, 'call', _219 => _219(
6741
+ ({ source, destination }) => _optionalChain([source, 'optionalAccess', _220 => _220.branch, 'optionalAccess', _221 => _221.name]) === branch && _optionalChain([destination, 'optionalAccess', _222 => _222.branch, 'optionalAccess', _223 => _223.name]) === this.platformConfig.baseBranchName
6695
6742
  )]);
6696
- }).then((pr) => _optionalChain([pr, 'optionalAccess', _219 => _219.id]));
6743
+ }).then((pr) => _optionalChain([pr, 'optionalAccess', _224 => _224.id]));
6697
6744
  }
6698
6745
  async closePullRequest({ pullRequestNumber }) {
6699
6746
  await this.bb.repositories.declinePullRequest({
@@ -6789,7 +6836,7 @@ var GitHubPlatformKit = class extends PlatformKit {
6789
6836
  repo: this.platformConfig.repositoryName,
6790
6837
  base: this.platformConfig.baseBranchName,
6791
6838
  state: "open"
6792
- }).then(({ data }) => data[0]).then((pr) => _optionalChain([pr, 'optionalAccess', _220 => _220.number]));
6839
+ }).then(({ data }) => data[0]).then((pr) => _optionalChain([pr, 'optionalAccess', _225 => _225.number]));
6793
6840
  }
6794
6841
  async closePullRequest({ pullRequestNumber }) {
6795
6842
  await this.octokit.rest.pulls.update({
@@ -6916,7 +6963,7 @@ var GitlabPlatformKit = class extends PlatformKit {
6916
6963
  sourceBranch: branch,
6917
6964
  state: "opened"
6918
6965
  });
6919
- return _optionalChain([mergeRequests, 'access', _221 => _221[0], 'optionalAccess', _222 => _222.iid]);
6966
+ return _optionalChain([mergeRequests, 'access', _226 => _226[0], 'optionalAccess', _227 => _227.iid]);
6920
6967
  }
6921
6968
  async closePullRequest({
6922
6969
  pullRequestNumber
@@ -7006,7 +7053,7 @@ var ci_default = new (0, _interactivecommander.Command)().command("ci").descript
7006
7053
  }
7007
7054
  const env = {
7008
7055
  LINGODOTDEV_API_KEY: settings.auth.apiKey,
7009
- LINGODOTDEV_PULL_REQUEST: _optionalChain([options, 'access', _223 => _223.pullRequest, 'optionalAccess', _224 => _224.toString, 'call', _225 => _225()]) || "false",
7056
+ LINGODOTDEV_PULL_REQUEST: _optionalChain([options, 'access', _228 => _228.pullRequest, 'optionalAccess', _229 => _229.toString, 'call', _230 => _230()]) || "false",
7010
7057
  ...options.commitMessage && {
7011
7058
  LINGODOTDEV_COMMIT_MESSAGE: options.commitMessage
7012
7059
  },
@@ -7026,7 +7073,7 @@ var ci_default = new (0, _interactivecommander.Command)().command("ci").descript
7026
7073
  const { isPullRequestMode } = platformKit.config;
7027
7074
  ora.info(`Pull request mode: ${isPullRequestMode ? "on" : "off"}`);
7028
7075
  const flow = isPullRequestMode ? new PullRequestFlow(ora, platformKit) : new InBranchFlow(ora, platformKit);
7029
- const canRun = await _optionalChain([flow, 'access', _226 => _226.preRun, 'optionalCall', _227 => _227()]);
7076
+ const canRun = await _optionalChain([flow, 'access', _231 => _231.preRun, 'optionalCall', _232 => _232()]);
7030
7077
  if (canRun === false) {
7031
7078
  return;
7032
7079
  }
@@ -7036,7 +7083,7 @@ var ci_default = new (0, _interactivecommander.Command)().command("ci").descript
7036
7083
  if (!hasChanges) {
7037
7084
  return;
7038
7085
  }
7039
- await _optionalChain([flow, 'access', _228 => _228.postRun, 'optionalCall', _229 => _229()]);
7086
+ await _optionalChain([flow, 'access', _233 => _233.postRun, 'optionalCall', _234 => _234()]);
7040
7087
  });
7041
7088
  function parseBooleanArg(val) {
7042
7089
  if (val === true) return true;
@@ -7087,13 +7134,13 @@ var status_default = new (0, _interactivecommander.Command)().command("status").
7087
7134
  flags
7088
7135
  });
7089
7136
  let buckets = getBuckets(i18nConfig);
7090
- if (_optionalChain([flags, 'access', _230 => _230.bucket, 'optionalAccess', _231 => _231.length])) {
7137
+ if (_optionalChain([flags, 'access', _235 => _235.bucket, 'optionalAccess', _236 => _236.length])) {
7091
7138
  buckets = buckets.filter((bucket) => flags.bucket.includes(bucket.type));
7092
7139
  }
7093
7140
  ora.succeed("Buckets retrieved");
7094
- if (_optionalChain([flags, 'access', _232 => _232.file, 'optionalAccess', _233 => _233.length])) {
7141
+ if (_optionalChain([flags, 'access', _237 => _237.file, 'optionalAccess', _238 => _238.length])) {
7095
7142
  buckets = buckets.map((bucket) => {
7096
- const paths = bucket.paths.filter((path16) => flags.file.find((file) => _optionalChain([path16, 'access', _234 => _234.pathPattern, 'optionalAccess', _235 => _235.match, 'call', _236 => _236(file)])));
7143
+ const paths = bucket.paths.filter((path16) => flags.file.find((file) => _optionalChain([path16, 'access', _239 => _239.pathPattern, 'optionalAccess', _240 => _240.match, 'call', _241 => _241(file)])));
7097
7144
  return { ...bucket, paths };
7098
7145
  }).filter((bucket) => bucket.paths.length > 0);
7099
7146
  if (buckets.length === 0) {
@@ -7109,7 +7156,7 @@ var status_default = new (0, _interactivecommander.Command)().command("status").
7109
7156
  });
7110
7157
  }
7111
7158
  }
7112
- const targetLocales = _optionalChain([flags, 'access', _237 => _237.locale, 'optionalAccess', _238 => _238.length]) ? flags.locale : i18nConfig.locale.targets;
7159
+ const targetLocales = _optionalChain([flags, 'access', _242 => _242.locale, 'optionalAccess', _243 => _243.length]) ? flags.locale : i18nConfig.locale.targets;
7113
7160
  let totalSourceKeyCount = 0;
7114
7161
  let uniqueKeysToTranslate = 0;
7115
7162
  let totalExistingTranslations = 0;
@@ -7450,12 +7497,12 @@ function validateParams2(i18nConfig, flags) {
7450
7497
  message: "No buckets found in i18n.json. Please add at least one bucket containing i18n content.",
7451
7498
  docUrl: "bucketNotFound"
7452
7499
  });
7453
- } else if (_optionalChain([flags, 'access', _239 => _239.locale, 'optionalAccess', _240 => _240.some, 'call', _241 => _241((locale) => !i18nConfig.locale.targets.includes(locale))])) {
7500
+ } else if (_optionalChain([flags, 'access', _244 => _244.locale, 'optionalAccess', _245 => _245.some, 'call', _246 => _246((locale) => !i18nConfig.locale.targets.includes(locale))])) {
7454
7501
  throw new CLIError({
7455
7502
  message: `One or more specified locales do not exist in i18n.json locale.targets. Please add them to the list and try again.`,
7456
7503
  docUrl: "localeTargetNotFound"
7457
7504
  });
7458
- } else if (_optionalChain([flags, 'access', _242 => _242.bucket, 'optionalAccess', _243 => _243.some, 'call', _244 => _244((bucket) => !i18nConfig.buckets[bucket])])) {
7505
+ } else if (_optionalChain([flags, 'access', _247 => _247.bucket, 'optionalAccess', _248 => _248.some, 'call', _249 => _249((bucket) => !i18nConfig.buckets[bucket])])) {
7459
7506
  throw new CLIError({
7460
7507
  message: `One or more specified buckets do not exist in i18n.json. Please add them to the list and try again.`,
7461
7508
  docUrl: "bucketNotFound"
@@ -7538,7 +7585,7 @@ async function renderHero2() {
7538
7585
  // package.json
7539
7586
  var package_default = {
7540
7587
  name: "lingo.dev",
7541
- version: "0.98.0",
7588
+ version: "0.99.0",
7542
7589
  description: "Lingo.dev CLI",
7543
7590
  private: false,
7544
7591
  publishConfig: {
@@ -7666,6 +7713,7 @@ var package_default = {
7666
7713
  "@lingo.dev/_sdk": "workspace:*",
7667
7714
  "@lingo.dev/_spec": "workspace:*",
7668
7715
  "@modelcontextprotocol/sdk": "^1.5.0",
7716
+ "@openrouter/ai-sdk-provider": "^0.7.1",
7669
7717
  "@paralleldrive/cuid2": "^2.2.2",
7670
7718
  ai: "^4.3.15",
7671
7719
  bitbucket: "^2.12.0",
@@ -7707,6 +7755,7 @@ var package_default = {
7707
7755
  "node-webvtt": "^1.9.4",
7708
7756
  "object-hash": "^3.0.0",
7709
7757
  octokit: "^4.0.2",
7758
+ "ollama-ai-provider": "^1.2.0",
7710
7759
  open: "^10.1.2",
7711
7760
  ora: "^8.1.1",
7712
7761
  "p-limit": "^6.2.0",