lingo.dev 0.116.1 → 0.116.3
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 +417 -501
- package/build/cli.cjs.map +1 -1
- package/build/cli.mjs +421 -505
- package/build/cli.mjs.map +1 -1
- package/package.json +1 -1
package/build/cli.mjs
CHANGED
|
@@ -2036,7 +2036,7 @@ function createTextFileLoader(pathPattern) {
|
|
|
2036
2036
|
const trimmedResult = result.trim();
|
|
2037
2037
|
return trimmedResult;
|
|
2038
2038
|
},
|
|
2039
|
-
async push(locale, data,
|
|
2039
|
+
async push(locale, data, _37, originalLocale) {
|
|
2040
2040
|
const draftPath = pathPattern.replaceAll("[locale]", locale);
|
|
2041
2041
|
const finalPath = path10.resolve(draftPath);
|
|
2042
2042
|
const dirPath = path10.dirname(finalPath);
|
|
@@ -3666,7 +3666,7 @@ function createPropertiesLoader() {
|
|
|
3666
3666
|
return result;
|
|
3667
3667
|
},
|
|
3668
3668
|
async push(locale, payload) {
|
|
3669
|
-
const result = Object.entries(payload).filter(([
|
|
3669
|
+
const result = Object.entries(payload).filter(([_37, value]) => value != null).map(([key, value]) => `${key}=${value}`).join("\n");
|
|
3670
3670
|
return result;
|
|
3671
3671
|
}
|
|
3672
3672
|
});
|
|
@@ -3988,7 +3988,7 @@ function createXcodeStringsLoader() {
|
|
|
3988
3988
|
return result;
|
|
3989
3989
|
},
|
|
3990
3990
|
async push(locale, payload) {
|
|
3991
|
-
const lines = Object.entries(payload).filter(([
|
|
3991
|
+
const lines = Object.entries(payload).filter(([_37, value]) => value != null).map(([key, value]) => {
|
|
3992
3992
|
const escapedValue = escapeString(value);
|
|
3993
3993
|
return `"${key}" = "${escapedValue}";`;
|
|
3994
3994
|
});
|
|
@@ -4050,6 +4050,11 @@ function createXcodeXcstringsLoader(defaultLocale) {
|
|
|
4050
4050
|
if (langTranslationEntity) {
|
|
4051
4051
|
if ("stringUnit" in langTranslationEntity) {
|
|
4052
4052
|
resultData[translationKey] = langTranslationEntity.stringUnit.value;
|
|
4053
|
+
} else if ("stringSet" in langTranslationEntity) {
|
|
4054
|
+
const values = langTranslationEntity.stringSet.values;
|
|
4055
|
+
if (Array.isArray(values) && values.length > 0) {
|
|
4056
|
+
resultData[translationKey] = values;
|
|
4057
|
+
}
|
|
4053
4058
|
} else if ("variations" in langTranslationEntity) {
|
|
4054
4059
|
if ("plural" in langTranslationEntity.variations) {
|
|
4055
4060
|
resultData[translationKey] = {};
|
|
@@ -4094,6 +4099,21 @@ function createXcodeXcstringsLoader(defaultLocale) {
|
|
|
4094
4099
|
if (hasDoNotTranslateFlag) {
|
|
4095
4100
|
langDataToMerge.strings[key].shouldTranslate = false;
|
|
4096
4101
|
}
|
|
4102
|
+
} else if (Array.isArray(value)) {
|
|
4103
|
+
langDataToMerge.strings[key] = {
|
|
4104
|
+
extractionState: originalInput?.strings?.[key]?.extractionState,
|
|
4105
|
+
localizations: {
|
|
4106
|
+
[locale]: {
|
|
4107
|
+
stringSet: {
|
|
4108
|
+
state: "translated",
|
|
4109
|
+
values: value
|
|
4110
|
+
}
|
|
4111
|
+
}
|
|
4112
|
+
}
|
|
4113
|
+
};
|
|
4114
|
+
if (hasDoNotTranslateFlag) {
|
|
4115
|
+
langDataToMerge.strings[key].shouldTranslate = false;
|
|
4116
|
+
}
|
|
4097
4117
|
} else {
|
|
4098
4118
|
const updatedVariations = {};
|
|
4099
4119
|
for (const form in value) {
|
|
@@ -4166,218 +4186,21 @@ function _removeLocale(input2, locale) {
|
|
|
4166
4186
|
return { ...input2, strings: newStrings };
|
|
4167
4187
|
}
|
|
4168
4188
|
|
|
4169
|
-
// src/cli/loaders/xcode-xcstrings-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
"two",
|
|
4175
|
-
"few",
|
|
4176
|
-
"many",
|
|
4177
|
-
"other"
|
|
4178
|
-
]);
|
|
4179
|
-
function isICUPluralObject(value) {
|
|
4180
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
4181
|
-
return false;
|
|
4182
|
-
}
|
|
4183
|
-
if (ICU_TYPE_MARKER in value) {
|
|
4184
|
-
return true;
|
|
4185
|
-
}
|
|
4186
|
-
if (!("icu" in value) || typeof value.icu !== "string") {
|
|
4187
|
-
return false;
|
|
4188
|
-
}
|
|
4189
|
-
const icuPluralPattern = /^\{[\w]+,\s*plural,\s*.+\}$/;
|
|
4190
|
-
if (!icuPluralPattern.test(value.icu)) {
|
|
4191
|
-
return false;
|
|
4192
|
-
}
|
|
4193
|
-
if (value._meta !== void 0) {
|
|
4194
|
-
if (typeof value._meta !== "object" || !value._meta.variables || typeof value._meta.variables !== "object") {
|
|
4195
|
-
return false;
|
|
4196
|
-
}
|
|
4197
|
-
for (const [varName, varMeta] of Object.entries(value._meta.variables)) {
|
|
4198
|
-
if (!varMeta || typeof varMeta !== "object" || typeof varMeta.format !== "string" || varMeta.role !== "plural" && varMeta.role !== "other") {
|
|
4199
|
-
return false;
|
|
4200
|
-
}
|
|
4201
|
-
}
|
|
4202
|
-
}
|
|
4203
|
-
return true;
|
|
4204
|
-
}
|
|
4205
|
-
function isPluralFormsObject(value) {
|
|
4206
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
4207
|
-
return false;
|
|
4208
|
-
}
|
|
4209
|
-
const keys = Object.keys(value);
|
|
4210
|
-
if (keys.length === 0) {
|
|
4211
|
-
return false;
|
|
4212
|
-
}
|
|
4213
|
-
const allKeysAreCldr = keys.every((key) => CLDR_PLURAL_CATEGORIES.has(key));
|
|
4214
|
-
if (!allKeysAreCldr) {
|
|
4215
|
-
return false;
|
|
4216
|
-
}
|
|
4217
|
-
const allValuesAreStrings = keys.every(
|
|
4218
|
-
(key) => typeof value[key] === "string"
|
|
4189
|
+
// src/cli/loaders/xcode-xcstrings-v2.ts
|
|
4190
|
+
import _10 from "lodash";
|
|
4191
|
+
function buildIcuPluralString(forms) {
|
|
4192
|
+
const parts = Object.entries(forms).map(
|
|
4193
|
+
([form, text]) => `${form} {${text}}`
|
|
4219
4194
|
);
|
|
4220
|
-
|
|
4221
|
-
return false;
|
|
4222
|
-
}
|
|
4223
|
-
if (!("other" in value)) {
|
|
4224
|
-
return false;
|
|
4225
|
-
}
|
|
4226
|
-
return true;
|
|
4227
|
-
}
|
|
4228
|
-
function getRequiredPluralCategories(locale) {
|
|
4229
|
-
try {
|
|
4230
|
-
const pluralRules = new Intl.PluralRules(locale);
|
|
4231
|
-
const categories = pluralRules.resolvedOptions().pluralCategories;
|
|
4232
|
-
if (!categories || categories.length === 0) {
|
|
4233
|
-
throw new Error(`No plural categories found for locale: ${locale}`);
|
|
4234
|
-
}
|
|
4235
|
-
return categories;
|
|
4236
|
-
} catch (error) {
|
|
4237
|
-
console.warn(
|
|
4238
|
-
`[xcode-xcstrings-icu] Failed to resolve plural categories for locale "${locale}". Using fallback ["one", "other"]. Error: ${error instanceof Error ? error.message : String(error)}`
|
|
4239
|
-
);
|
|
4240
|
-
return ["one", "other"];
|
|
4241
|
-
}
|
|
4242
|
-
}
|
|
4243
|
-
var CLDR_CATEGORY_TO_NUMBER = {
|
|
4244
|
-
zero: 0,
|
|
4245
|
-
one: 1,
|
|
4246
|
-
two: 2
|
|
4247
|
-
};
|
|
4248
|
-
var NUMBER_TO_CLDR_CATEGORY = {
|
|
4249
|
-
0: "zero",
|
|
4250
|
-
1: "one",
|
|
4251
|
-
2: "two"
|
|
4252
|
-
};
|
|
4253
|
-
function xcstringsToPluralWithMeta(pluralForms, sourceLocale = "en") {
|
|
4254
|
-
if (!pluralForms || Object.keys(pluralForms).length === 0) {
|
|
4255
|
-
throw new Error("pluralForms cannot be empty");
|
|
4256
|
-
}
|
|
4257
|
-
const requiredCategories = getRequiredPluralCategories(sourceLocale);
|
|
4258
|
-
const variables = {};
|
|
4259
|
-
const formatRegex = /(%(?:(\d+)\$)?(?:[+-])?(?:\d+)?(?:\.(\d+))?([lhqLzjt]*)([diuoxXfFeEgGaAcspn@]))/g;
|
|
4260
|
-
let maxMatches = [];
|
|
4261
|
-
let maxMatchText = "";
|
|
4262
|
-
for (const [form, text] of Object.entries(pluralForms)) {
|
|
4263
|
-
if (typeof text !== "string") {
|
|
4264
|
-
console.warn(
|
|
4265
|
-
`Warning: Plural form "${form}" has non-string value:`,
|
|
4266
|
-
text
|
|
4267
|
-
);
|
|
4268
|
-
continue;
|
|
4269
|
-
}
|
|
4270
|
-
const matches = [...text.matchAll(formatRegex)];
|
|
4271
|
-
if (matches.length > maxMatches.length) {
|
|
4272
|
-
maxMatches = matches;
|
|
4273
|
-
maxMatchText = text;
|
|
4274
|
-
}
|
|
4275
|
-
}
|
|
4276
|
-
let lastNumericIndex = -1;
|
|
4277
|
-
maxMatches.forEach((match2, idx) => {
|
|
4278
|
-
const specifier = match2[5];
|
|
4279
|
-
if (/[diuoxXfFeE]/.test(specifier)) {
|
|
4280
|
-
lastNumericIndex = idx;
|
|
4281
|
-
}
|
|
4282
|
-
});
|
|
4283
|
-
let nonPluralCounter = 0;
|
|
4284
|
-
maxMatches.forEach((match2, idx) => {
|
|
4285
|
-
const fullFormat = match2[1];
|
|
4286
|
-
const position = match2[2];
|
|
4287
|
-
const precision = match2[3];
|
|
4288
|
-
const lengthMod = match2[4];
|
|
4289
|
-
const specifier = match2[5];
|
|
4290
|
-
const isPluralVar = idx === lastNumericIndex;
|
|
4291
|
-
const varName = isPluralVar ? "count" : `var${nonPluralCounter++}`;
|
|
4292
|
-
variables[varName] = {
|
|
4293
|
-
format: fullFormat,
|
|
4294
|
-
role: isPluralVar ? "plural" : "other"
|
|
4295
|
-
};
|
|
4296
|
-
});
|
|
4297
|
-
const variableKeys = Object.keys(variables);
|
|
4298
|
-
const icuForms = Object.entries(pluralForms).filter(([form, text]) => {
|
|
4299
|
-
if (typeof text !== "string") {
|
|
4300
|
-
return false;
|
|
4301
|
-
}
|
|
4302
|
-
return true;
|
|
4303
|
-
}).map(([form, text]) => {
|
|
4304
|
-
let processed = text;
|
|
4305
|
-
let vIdx = 0;
|
|
4306
|
-
processed = processed.replace(formatRegex, () => {
|
|
4307
|
-
if (vIdx >= variableKeys.length) {
|
|
4308
|
-
vIdx++;
|
|
4309
|
-
return "#";
|
|
4310
|
-
}
|
|
4311
|
-
const varName = variableKeys[vIdx];
|
|
4312
|
-
const varMeta = variables[varName];
|
|
4313
|
-
vIdx++;
|
|
4314
|
-
if (varMeta.role === "plural") {
|
|
4315
|
-
return "#";
|
|
4316
|
-
} else {
|
|
4317
|
-
return `{${varName}}`;
|
|
4318
|
-
}
|
|
4319
|
-
});
|
|
4320
|
-
const isRequired = requiredCategories.includes(form);
|
|
4321
|
-
const formKey = !isRequired && form in CLDR_CATEGORY_TO_NUMBER ? `=${CLDR_CATEGORY_TO_NUMBER[form]}` : form;
|
|
4322
|
-
return `${formKey} {${processed}}`;
|
|
4323
|
-
}).join(" ");
|
|
4324
|
-
const pluralVarName = Object.keys(variables).find((name) => variables[name].role === "plural") || "count";
|
|
4325
|
-
const icu = `{${pluralVarName}, plural, ${icuForms}}`;
|
|
4326
|
-
const result = {
|
|
4327
|
-
icu,
|
|
4328
|
-
_meta: Object.keys(variables).length > 0 ? { variables } : void 0,
|
|
4329
|
-
[ICU_TYPE_MARKER]: true
|
|
4330
|
-
// Add type marker for robust detection
|
|
4331
|
-
};
|
|
4332
|
-
return result;
|
|
4195
|
+
return `{count, plural, ${parts.join(" ")}}`;
|
|
4333
4196
|
}
|
|
4334
|
-
function
|
|
4335
|
-
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
const ast = parseICU(data.icu);
|
|
4339
|
-
if (!ast || ast.length === 0) {
|
|
4340
|
-
throw new Error("Invalid ICU format");
|
|
4341
|
-
}
|
|
4342
|
-
const pluralNode = ast.find((node) => node.type === "plural");
|
|
4343
|
-
if (!pluralNode) {
|
|
4344
|
-
throw new Error("No plural found in ICU format");
|
|
4197
|
+
function parseIcuPluralString(icuString) {
|
|
4198
|
+
const pluralMatch = icuString.match(/\{[\w]+,\s*plural,\s*(.+)\}$/);
|
|
4199
|
+
if (!pluralMatch) {
|
|
4200
|
+
throw new Error(`Invalid ICU plural format: ${icuString}`);
|
|
4345
4201
|
}
|
|
4202
|
+
const formsText = pluralMatch[1];
|
|
4346
4203
|
const forms = {};
|
|
4347
|
-
for (const [form, option] of Object.entries(pluralNode.options)) {
|
|
4348
|
-
let text = "";
|
|
4349
|
-
const optionValue = option.value;
|
|
4350
|
-
for (const element of optionValue) {
|
|
4351
|
-
if (element.type === "literal") {
|
|
4352
|
-
text += element.value;
|
|
4353
|
-
} else if (element.type === "pound") {
|
|
4354
|
-
const pluralVar = Object.entries(data._meta?.variables || {}).find(
|
|
4355
|
-
([_36, meta]) => meta.role === "plural"
|
|
4356
|
-
);
|
|
4357
|
-
text += pluralVar?.[1].format || "%lld";
|
|
4358
|
-
} else if (element.type === "argument") {
|
|
4359
|
-
const varName = element.value;
|
|
4360
|
-
const varMeta = data._meta?.variables?.[varName];
|
|
4361
|
-
text += varMeta?.format || "%@";
|
|
4362
|
-
}
|
|
4363
|
-
}
|
|
4364
|
-
let xcstringsFormName = form;
|
|
4365
|
-
if (form.startsWith("=")) {
|
|
4366
|
-
const numValue = parseInt(form.substring(1), 10);
|
|
4367
|
-
xcstringsFormName = NUMBER_TO_CLDR_CATEGORY[numValue] || form;
|
|
4368
|
-
}
|
|
4369
|
-
forms[xcstringsFormName] = text;
|
|
4370
|
-
}
|
|
4371
|
-
return forms;
|
|
4372
|
-
}
|
|
4373
|
-
function parseICU(icu) {
|
|
4374
|
-
const match2 = icu.match(/\{(\w+),\s*plural,\s*(.+)\}$/);
|
|
4375
|
-
if (!match2) {
|
|
4376
|
-
throw new Error("Invalid ICU plural format");
|
|
4377
|
-
}
|
|
4378
|
-
const varName = match2[1];
|
|
4379
|
-
const formsText = match2[2];
|
|
4380
|
-
const options = {};
|
|
4381
4204
|
let i = 0;
|
|
4382
4205
|
while (i < formsText.length) {
|
|
4383
4206
|
while (i < formsText.length && /\s/.test(formsText[i])) {
|
|
@@ -4423,149 +4246,228 @@ function parseICU(icu) {
|
|
|
4423
4246
|
i++;
|
|
4424
4247
|
}
|
|
4425
4248
|
if (braceCount !== 0) {
|
|
4426
|
-
const preview = formsText.substring(
|
|
4427
|
-
Math.max(0, i - 50),
|
|
4428
|
-
Math.min(formsText.length, i + 50)
|
|
4429
|
-
);
|
|
4430
4249
|
throw new Error(
|
|
4431
|
-
`Unclosed brace for form '${formName}' in ICU
|
|
4432
|
-
Expected ${braceCount} more closing brace(s).
|
|
4433
|
-
Context: ...${preview}...
|
|
4434
|
-
Full ICU: {${varName}, plural, ${formsText}}`
|
|
4250
|
+
`Unclosed brace for form '${formName}' in ICU: ${icuString}`
|
|
4435
4251
|
);
|
|
4436
4252
|
}
|
|
4437
|
-
|
|
4438
|
-
options[formName] = {
|
|
4439
|
-
value: elements
|
|
4440
|
-
};
|
|
4253
|
+
forms[formName] = formText;
|
|
4441
4254
|
}
|
|
4442
|
-
return
|
|
4443
|
-
{
|
|
4444
|
-
type: "plural",
|
|
4445
|
-
value: varName,
|
|
4446
|
-
options
|
|
4447
|
-
}
|
|
4448
|
-
];
|
|
4255
|
+
return forms;
|
|
4449
4256
|
}
|
|
4450
|
-
function
|
|
4451
|
-
|
|
4452
|
-
let currentText = "";
|
|
4453
|
-
let i = 0;
|
|
4454
|
-
while (i < text.length) {
|
|
4455
|
-
if (text[i] === "#") {
|
|
4456
|
-
if (currentText) {
|
|
4457
|
-
elements.push({ type: "literal", value: currentText });
|
|
4458
|
-
currentText = "";
|
|
4459
|
-
}
|
|
4460
|
-
elements.push({ type: "pound" });
|
|
4461
|
-
i++;
|
|
4462
|
-
} else if (text[i] === "{") {
|
|
4463
|
-
if (currentText) {
|
|
4464
|
-
elements.push({ type: "literal", value: currentText });
|
|
4465
|
-
currentText = "";
|
|
4466
|
-
}
|
|
4467
|
-
let braceCount = 1;
|
|
4468
|
-
let j = i + 1;
|
|
4469
|
-
while (j < text.length && braceCount > 0) {
|
|
4470
|
-
if (text[j] === "{") {
|
|
4471
|
-
braceCount++;
|
|
4472
|
-
} else if (text[j] === "}") {
|
|
4473
|
-
braceCount--;
|
|
4474
|
-
}
|
|
4475
|
-
j++;
|
|
4476
|
-
}
|
|
4477
|
-
if (braceCount !== 0) {
|
|
4478
|
-
throw new Error("Unclosed variable reference");
|
|
4479
|
-
}
|
|
4480
|
-
const varName = text.slice(i + 1, j - 1);
|
|
4481
|
-
elements.push({ type: "argument", value: varName });
|
|
4482
|
-
i = j;
|
|
4483
|
-
} else {
|
|
4484
|
-
currentText += text[i];
|
|
4485
|
-
i++;
|
|
4486
|
-
}
|
|
4487
|
-
}
|
|
4488
|
-
if (currentText) {
|
|
4489
|
-
elements.push({ type: "literal", value: currentText });
|
|
4490
|
-
}
|
|
4491
|
-
return elements;
|
|
4257
|
+
function isIcuPluralString(value) {
|
|
4258
|
+
return typeof value === "string" && /^\{[\w]+,\s*plural,\s*.+\}$/.test(value);
|
|
4492
4259
|
}
|
|
4493
|
-
|
|
4494
|
-
// src/cli/loaders/xcode-xcstrings-v2-loader.ts
|
|
4495
|
-
function createXcodeXcstringsV2Loader(defaultLocale = "en") {
|
|
4260
|
+
function createXcodeXcstringsV2Loader(defaultLocale) {
|
|
4496
4261
|
return createLoader({
|
|
4497
|
-
async pull(locale, input2) {
|
|
4498
|
-
const
|
|
4499
|
-
|
|
4500
|
-
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
|
|
4504
|
-
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
|
|
4510
|
-
|
|
4511
|
-
`
|
|
4512
|
-
);
|
|
4513
|
-
result[key] = value;
|
|
4262
|
+
async pull(locale, input2, initCtx) {
|
|
4263
|
+
const resultData = {};
|
|
4264
|
+
const isSourceLanguage = locale === defaultLocale;
|
|
4265
|
+
for (const [translationKey, _translationEntity] of Object.entries(
|
|
4266
|
+
input2.strings
|
|
4267
|
+
)) {
|
|
4268
|
+
const rootTranslationEntity = _translationEntity;
|
|
4269
|
+
if (rootTranslationEntity.shouldTranslate === false) {
|
|
4270
|
+
continue;
|
|
4271
|
+
}
|
|
4272
|
+
const langTranslationEntity = rootTranslationEntity?.localizations?.[locale];
|
|
4273
|
+
if (langTranslationEntity) {
|
|
4274
|
+
if (!resultData[translationKey]) {
|
|
4275
|
+
resultData[translationKey] = {};
|
|
4514
4276
|
}
|
|
4515
|
-
|
|
4516
|
-
|
|
4277
|
+
if ("stringUnit" in langTranslationEntity) {
|
|
4278
|
+
resultData[translationKey].stringUnit = langTranslationEntity.stringUnit.value;
|
|
4279
|
+
if ("substitutions" in langTranslationEntity) {
|
|
4280
|
+
resultData[translationKey].substitutions = {};
|
|
4281
|
+
for (const [subName, subData] of Object.entries(
|
|
4282
|
+
langTranslationEntity.substitutions
|
|
4283
|
+
)) {
|
|
4284
|
+
const pluralForms = subData.variations?.plural;
|
|
4285
|
+
if (pluralForms) {
|
|
4286
|
+
const forms = {};
|
|
4287
|
+
for (const [form, formData] of Object.entries(pluralForms)) {
|
|
4288
|
+
forms[form] = formData.stringUnit.value;
|
|
4289
|
+
}
|
|
4290
|
+
const icuString = buildIcuPluralString(forms);
|
|
4291
|
+
resultData[translationKey].substitutions[subName] = {
|
|
4292
|
+
variations: {
|
|
4293
|
+
plural: icuString
|
|
4294
|
+
}
|
|
4295
|
+
};
|
|
4296
|
+
}
|
|
4297
|
+
}
|
|
4298
|
+
}
|
|
4299
|
+
} else if ("stringSet" in langTranslationEntity) {
|
|
4300
|
+
const values = langTranslationEntity.stringSet.values;
|
|
4301
|
+
if (Array.isArray(values) && values.length > 0) {
|
|
4302
|
+
resultData[translationKey].stringSet = values;
|
|
4303
|
+
}
|
|
4304
|
+
} else if ("variations" in langTranslationEntity) {
|
|
4305
|
+
if ("plural" in langTranslationEntity.variations) {
|
|
4306
|
+
const pluralForms = langTranslationEntity.variations.plural;
|
|
4307
|
+
const forms = {};
|
|
4308
|
+
for (const [form, formData] of Object.entries(pluralForms)) {
|
|
4309
|
+
if (formData?.stringUnit?.value) {
|
|
4310
|
+
forms[form] = formData.stringUnit.value;
|
|
4311
|
+
}
|
|
4312
|
+
}
|
|
4313
|
+
const icuString = buildIcuPluralString(forms);
|
|
4314
|
+
resultData[translationKey].variations = {
|
|
4315
|
+
plural: icuString
|
|
4316
|
+
};
|
|
4317
|
+
}
|
|
4318
|
+
}
|
|
4319
|
+
} else if (isSourceLanguage) {
|
|
4320
|
+
if (!resultData[translationKey]) {
|
|
4321
|
+
resultData[translationKey] = {};
|
|
4322
|
+
}
|
|
4323
|
+
resultData[translationKey].stringUnit = translationKey;
|
|
4517
4324
|
}
|
|
4518
4325
|
}
|
|
4519
|
-
return
|
|
4326
|
+
return resultData;
|
|
4520
4327
|
},
|
|
4521
|
-
async push(locale, payload) {
|
|
4522
|
-
const
|
|
4523
|
-
|
|
4524
|
-
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
|
|
4328
|
+
async push(locale, payload, originalInput) {
|
|
4329
|
+
const langDataToMerge = {};
|
|
4330
|
+
langDataToMerge.strings = {};
|
|
4331
|
+
const input2 = _10.cloneDeep(originalInput) || {
|
|
4332
|
+
sourceLanguage: locale,
|
|
4333
|
+
strings: {}
|
|
4334
|
+
};
|
|
4335
|
+
for (const [baseKey, keyData] of Object.entries(payload)) {
|
|
4336
|
+
if (!keyData || typeof keyData !== "object") {
|
|
4337
|
+
continue;
|
|
4338
|
+
}
|
|
4339
|
+
const hasDoNotTranslateFlag = originalInput && originalInput.strings && originalInput.strings[baseKey] && originalInput.strings[baseKey].shouldTranslate === false;
|
|
4340
|
+
const localizationData = {};
|
|
4341
|
+
if ("stringUnit" in keyData) {
|
|
4342
|
+
localizationData.stringUnit = {
|
|
4343
|
+
state: "translated",
|
|
4344
|
+
value: keyData.stringUnit
|
|
4345
|
+
};
|
|
4346
|
+
}
|
|
4347
|
+
if ("substitutions" in keyData && keyData.substitutions) {
|
|
4348
|
+
const subs = {};
|
|
4349
|
+
for (const [subName, subData] of Object.entries(
|
|
4350
|
+
keyData.substitutions
|
|
4351
|
+
)) {
|
|
4352
|
+
const pluralValue = subData?.variations?.plural;
|
|
4353
|
+
if (pluralValue && isIcuPluralString(pluralValue)) {
|
|
4354
|
+
try {
|
|
4355
|
+
const pluralForms = parseIcuPluralString(pluralValue);
|
|
4356
|
+
const pluralOut = {};
|
|
4357
|
+
for (const [form, text] of Object.entries(pluralForms)) {
|
|
4358
|
+
pluralOut[form] = {
|
|
4359
|
+
stringUnit: {
|
|
4360
|
+
state: "translated",
|
|
4361
|
+
value: text
|
|
4362
|
+
}
|
|
4363
|
+
};
|
|
4364
|
+
}
|
|
4365
|
+
const sourceLocale = originalInput?.sourceLanguage || "en";
|
|
4366
|
+
const origFormatSpec = originalInput?.strings?.[baseKey]?.localizations?.[sourceLocale]?.substitutions?.[subName]?.formatSpecifier || subName;
|
|
4367
|
+
subs[subName] = {
|
|
4368
|
+
formatSpecifier: origFormatSpec,
|
|
4369
|
+
variations: {
|
|
4370
|
+
plural: pluralOut
|
|
4371
|
+
}
|
|
4372
|
+
};
|
|
4373
|
+
} catch (error) {
|
|
4374
|
+
throw new Error(
|
|
4375
|
+
`Failed to write substitution plural translation for key "${baseKey}/substitutions/${subName}" (locale: ${locale}).
|
|
4531
4376
|
${error instanceof Error ? error.message : String(error)}`
|
|
4532
|
-
|
|
4377
|
+
);
|
|
4378
|
+
}
|
|
4379
|
+
}
|
|
4380
|
+
}
|
|
4381
|
+
if (Object.keys(subs).length > 0) {
|
|
4382
|
+
localizationData.substitutions = subs;
|
|
4383
|
+
}
|
|
4384
|
+
}
|
|
4385
|
+
if ("stringSet" in keyData && Array.isArray(keyData.stringSet)) {
|
|
4386
|
+
localizationData.stringSet = {
|
|
4387
|
+
state: "translated",
|
|
4388
|
+
values: keyData.stringSet
|
|
4389
|
+
};
|
|
4390
|
+
}
|
|
4391
|
+
if ("variations" in keyData && keyData.variations?.plural) {
|
|
4392
|
+
const pluralValue = keyData.variations.plural;
|
|
4393
|
+
if (isIcuPluralString(pluralValue)) {
|
|
4394
|
+
try {
|
|
4395
|
+
const pluralForms = parseIcuPluralString(pluralValue);
|
|
4396
|
+
const pluralOut = {};
|
|
4397
|
+
for (const [form, text] of Object.entries(pluralForms)) {
|
|
4398
|
+
pluralOut[form] = {
|
|
4399
|
+
stringUnit: {
|
|
4400
|
+
state: "translated",
|
|
4401
|
+
value: text
|
|
4402
|
+
}
|
|
4403
|
+
};
|
|
4404
|
+
}
|
|
4405
|
+
localizationData.variations = {
|
|
4406
|
+
plural: pluralOut
|
|
4407
|
+
};
|
|
4408
|
+
} catch (error) {
|
|
4409
|
+
throw new Error(
|
|
4410
|
+
`Failed to write plural translation for key "${baseKey}" (locale: ${locale}).
|
|
4411
|
+
${error instanceof Error ? error.message : String(error)}`
|
|
4412
|
+
);
|
|
4413
|
+
}
|
|
4414
|
+
}
|
|
4415
|
+
}
|
|
4416
|
+
if (Object.keys(localizationData).length > 0) {
|
|
4417
|
+
langDataToMerge.strings[baseKey] = {
|
|
4418
|
+
extractionState: originalInput?.strings?.[baseKey]?.extractionState,
|
|
4419
|
+
localizations: {
|
|
4420
|
+
[locale]: localizationData
|
|
4421
|
+
}
|
|
4422
|
+
};
|
|
4423
|
+
if (hasDoNotTranslateFlag) {
|
|
4424
|
+
langDataToMerge.strings[baseKey].shouldTranslate = false;
|
|
4533
4425
|
}
|
|
4534
|
-
} else {
|
|
4535
|
-
result[key] = value;
|
|
4536
4426
|
}
|
|
4537
4427
|
}
|
|
4538
|
-
return
|
|
4428
|
+
return _10.merge(input2, langDataToMerge);
|
|
4429
|
+
},
|
|
4430
|
+
async pullHints(input2) {
|
|
4431
|
+
const hints = {};
|
|
4432
|
+
for (const [translationKey, _translationEntity] of Object.entries(
|
|
4433
|
+
input2.strings || {}
|
|
4434
|
+
)) {
|
|
4435
|
+
const rootTranslationEntity = _translationEntity;
|
|
4436
|
+
if (rootTranslationEntity.comment && typeof rootTranslationEntity.comment === "string") {
|
|
4437
|
+
hints[translationKey] = { hint: rootTranslationEntity.comment };
|
|
4438
|
+
}
|
|
4439
|
+
}
|
|
4440
|
+
return hints;
|
|
4539
4441
|
}
|
|
4540
4442
|
});
|
|
4541
4443
|
}
|
|
4542
4444
|
|
|
4543
4445
|
// src/cli/loaders/unlocalizable.ts
|
|
4544
|
-
import
|
|
4446
|
+
import _11 from "lodash";
|
|
4545
4447
|
import _isUrl from "is-url";
|
|
4546
4448
|
import { isValid, parseISO } from "date-fns";
|
|
4547
4449
|
function createUnlocalizableLoader(returnUnlocalizedKeys = false) {
|
|
4548
4450
|
return createLoader({
|
|
4549
4451
|
async pull(locale, input2) {
|
|
4550
4452
|
const unlocalizableKeys = _getUnlocalizableKeys(input2);
|
|
4551
|
-
const result =
|
|
4453
|
+
const result = _11.omitBy(
|
|
4552
4454
|
input2,
|
|
4553
|
-
(
|
|
4455
|
+
(_37, key) => unlocalizableKeys.includes(key)
|
|
4554
4456
|
);
|
|
4555
4457
|
if (returnUnlocalizedKeys) {
|
|
4556
|
-
result.unlocalizable =
|
|
4458
|
+
result.unlocalizable = _11.omitBy(
|
|
4557
4459
|
input2,
|
|
4558
|
-
(
|
|
4460
|
+
(_37, key) => !unlocalizableKeys.includes(key)
|
|
4559
4461
|
);
|
|
4560
4462
|
}
|
|
4561
4463
|
return result;
|
|
4562
4464
|
},
|
|
4563
4465
|
async push(locale, data, originalInput) {
|
|
4564
4466
|
const unlocalizableKeys = _getUnlocalizableKeys(originalInput);
|
|
4565
|
-
const result =
|
|
4467
|
+
const result = _11.merge(
|
|
4566
4468
|
{},
|
|
4567
4469
|
data,
|
|
4568
|
-
|
|
4470
|
+
_11.omitBy(originalInput, (_37, key) => !unlocalizableKeys.includes(key))
|
|
4569
4471
|
);
|
|
4570
4472
|
return result;
|
|
4571
4473
|
}
|
|
@@ -4579,12 +4481,12 @@ function _isIsoDate(v) {
|
|
|
4579
4481
|
}
|
|
4580
4482
|
function _getUnlocalizableKeys(input2) {
|
|
4581
4483
|
const rules = {
|
|
4582
|
-
isEmpty: (v) =>
|
|
4484
|
+
isEmpty: (v) => _11.isEmpty(v),
|
|
4583
4485
|
isNumber: (v) => typeof v === "number" || /^[0-9]+$/.test(v),
|
|
4584
|
-
isBoolean: (v) =>
|
|
4585
|
-
isIsoDate: (v) =>
|
|
4586
|
-
isSystemId: (v) =>
|
|
4587
|
-
isUrl: (v) =>
|
|
4486
|
+
isBoolean: (v) => _11.isBoolean(v),
|
|
4487
|
+
isIsoDate: (v) => _11.isString(v) && _isIsoDate(v),
|
|
4488
|
+
isSystemId: (v) => _11.isString(v) && _isSystemId(v),
|
|
4489
|
+
isUrl: (v) => _11.isString(v) && _isUrl(v)
|
|
4588
4490
|
};
|
|
4589
4491
|
if (!input2) {
|
|
4590
4492
|
return [];
|
|
@@ -4596,7 +4498,7 @@ function _getUnlocalizableKeys(input2) {
|
|
|
4596
4498
|
}
|
|
4597
4499
|
}
|
|
4598
4500
|
return false;
|
|
4599
|
-
}).map(([key,
|
|
4501
|
+
}).map(([key, _37]) => key);
|
|
4600
4502
|
}
|
|
4601
4503
|
|
|
4602
4504
|
// src/cli/loaders/formatters/prettier.ts
|
|
@@ -4763,7 +4665,7 @@ function createFormatterLoader(formatterType, parser, bucketPathPattern) {
|
|
|
4763
4665
|
}
|
|
4764
4666
|
|
|
4765
4667
|
// src/cli/loaders/po/index.ts
|
|
4766
|
-
import
|
|
4668
|
+
import _12 from "lodash";
|
|
4767
4669
|
import gettextParser from "gettext-parser";
|
|
4768
4670
|
function createPoLoader(params = { multiline: false }) {
|
|
4769
4671
|
return composeLoaders(createPoDataLoader(params), createPoContentLoader());
|
|
@@ -4779,7 +4681,7 @@ function createPoDataLoader(params) {
|
|
|
4779
4681
|
if (Object.keys(sectionPo.translations).length === 0) {
|
|
4780
4682
|
continue;
|
|
4781
4683
|
}
|
|
4782
|
-
const contextKey =
|
|
4684
|
+
const contextKey = _12.keys(sectionPo.translations)[0];
|
|
4783
4685
|
const entries = sectionPo.translations[contextKey];
|
|
4784
4686
|
Object.entries(entries).forEach(([msgid, entry]) => {
|
|
4785
4687
|
if (msgid && entry.msgid) {
|
|
@@ -4801,13 +4703,13 @@ function createPoDataLoader(params) {
|
|
|
4801
4703
|
if (Object.keys(sectionPo.translations).length === 0) {
|
|
4802
4704
|
return null;
|
|
4803
4705
|
}
|
|
4804
|
-
const contextKey =
|
|
4706
|
+
const contextKey = _12.keys(sectionPo.translations)[0];
|
|
4805
4707
|
const entries = sectionPo.translations[contextKey];
|
|
4806
4708
|
const msgid = Object.keys(entries).find((key) => entries[key].msgid);
|
|
4807
4709
|
if (!msgid) {
|
|
4808
4710
|
const currentSection = currentSections.find((cs) => {
|
|
4809
4711
|
const csPo = gettextParser.po.parse(cs);
|
|
4810
|
-
const csContextKey =
|
|
4712
|
+
const csContextKey = _12.keys(csPo.translations)[0];
|
|
4811
4713
|
const csEntries = csPo.translations[csContextKey];
|
|
4812
4714
|
const csMsgid = Object.keys(csEntries).find(
|
|
4813
4715
|
(key) => csEntries[key].msgid
|
|
@@ -4820,7 +4722,7 @@ function createPoDataLoader(params) {
|
|
|
4820
4722
|
return section;
|
|
4821
4723
|
}
|
|
4822
4724
|
if (data[msgid]) {
|
|
4823
|
-
const updatedPo =
|
|
4725
|
+
const updatedPo = _12.merge({}, sectionPo, {
|
|
4824
4726
|
translations: {
|
|
4825
4727
|
[contextKey]: {
|
|
4826
4728
|
[msgid]: {
|
|
@@ -4844,7 +4746,7 @@ function createPoDataLoader(params) {
|
|
|
4844
4746
|
function createPoContentLoader() {
|
|
4845
4747
|
return createLoader({
|
|
4846
4748
|
async pull(locale, input2, initCtx, originalLocale) {
|
|
4847
|
-
const result =
|
|
4749
|
+
const result = _12.chain(input2).entries().filter(([, entry]) => !!entry.msgid).map(([, entry]) => {
|
|
4848
4750
|
const singularFallback = locale === originalLocale ? entry.msgid : null;
|
|
4849
4751
|
const pluralFallback = locale === originalLocale ? entry.msgid_plural || entry.msgid : null;
|
|
4850
4752
|
const hasPlural = entry.msgstr.length > 1;
|
|
@@ -4859,7 +4761,7 @@ function createPoContentLoader() {
|
|
|
4859
4761
|
return result;
|
|
4860
4762
|
},
|
|
4861
4763
|
async push(locale, data, originalInput) {
|
|
4862
|
-
const result =
|
|
4764
|
+
const result = _12.chain(originalInput).entries().map(([, entry]) => [
|
|
4863
4765
|
entry.msgid,
|
|
4864
4766
|
{
|
|
4865
4767
|
...entry,
|
|
@@ -5402,41 +5304,41 @@ var datoSettingsSchema = Z2.object({
|
|
|
5402
5304
|
});
|
|
5403
5305
|
|
|
5404
5306
|
// src/cli/loaders/dato/filter.ts
|
|
5405
|
-
import
|
|
5307
|
+
import _13 from "lodash";
|
|
5406
5308
|
function createDatoFilterLoader() {
|
|
5407
5309
|
return createLoader({
|
|
5408
5310
|
async pull(locale, input2) {
|
|
5409
5311
|
const result = {};
|
|
5410
|
-
for (const [modelId, modelInfo] of
|
|
5312
|
+
for (const [modelId, modelInfo] of _13.entries(input2)) {
|
|
5411
5313
|
result[modelId] = {};
|
|
5412
5314
|
for (const record of modelInfo.records) {
|
|
5413
|
-
result[modelId][record.id] =
|
|
5315
|
+
result[modelId][record.id] = _13.chain(modelInfo.fields).mapKeys((field) => field.api_key).mapValues((field) => _13.get(record, [field.api_key, locale])).value();
|
|
5414
5316
|
}
|
|
5415
5317
|
}
|
|
5416
5318
|
return result;
|
|
5417
5319
|
},
|
|
5418
5320
|
async push(locale, data, originalInput, originalLocale) {
|
|
5419
|
-
const result =
|
|
5420
|
-
for (const [modelId, modelInfo] of
|
|
5321
|
+
const result = _13.cloneDeep(originalInput || {});
|
|
5322
|
+
for (const [modelId, modelInfo] of _13.entries(result)) {
|
|
5421
5323
|
for (const record of modelInfo.records) {
|
|
5422
|
-
for (const [fieldId, fieldValue] of
|
|
5324
|
+
for (const [fieldId, fieldValue] of _13.entries(record)) {
|
|
5423
5325
|
const fieldInfo = modelInfo.fields.find(
|
|
5424
5326
|
(field) => field.api_key === fieldId
|
|
5425
5327
|
);
|
|
5426
5328
|
if (fieldInfo) {
|
|
5427
|
-
const sourceFieldValue =
|
|
5428
|
-
const targetFieldValue =
|
|
5329
|
+
const sourceFieldValue = _13.get(fieldValue, [originalLocale]);
|
|
5330
|
+
const targetFieldValue = _13.get(data, [
|
|
5429
5331
|
modelId,
|
|
5430
5332
|
record.id,
|
|
5431
5333
|
fieldId
|
|
5432
5334
|
]);
|
|
5433
5335
|
if (targetFieldValue) {
|
|
5434
|
-
|
|
5336
|
+
_13.set(record, [fieldId, locale], targetFieldValue);
|
|
5435
5337
|
} else {
|
|
5436
|
-
|
|
5338
|
+
_13.set(record, [fieldId, locale], sourceFieldValue);
|
|
5437
5339
|
}
|
|
5438
|
-
|
|
5439
|
-
(loc) =>
|
|
5340
|
+
_13.chain(fieldValue).keys().reject((loc) => loc === locale || loc === originalLocale).filter((loc) => _13.isEmpty(_13.get(fieldValue, [loc]))).forEach(
|
|
5341
|
+
(loc) => _13.set(record, [fieldId, loc], sourceFieldValue)
|
|
5440
5342
|
).value();
|
|
5441
5343
|
}
|
|
5442
5344
|
}
|
|
@@ -5448,10 +5350,10 @@ function createDatoFilterLoader() {
|
|
|
5448
5350
|
}
|
|
5449
5351
|
|
|
5450
5352
|
// src/cli/loaders/dato/api.ts
|
|
5451
|
-
import
|
|
5353
|
+
import _15 from "lodash";
|
|
5452
5354
|
|
|
5453
5355
|
// src/cli/loaders/dato/_utils.ts
|
|
5454
|
-
import
|
|
5356
|
+
import _14 from "lodash";
|
|
5455
5357
|
import { buildClient } from "@datocms/cma-client-node";
|
|
5456
5358
|
function createDatoClient(params) {
|
|
5457
5359
|
if (!params.apiKey) {
|
|
@@ -5644,7 +5546,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
|
|
|
5644
5546
|
const result = {
|
|
5645
5547
|
models: {}
|
|
5646
5548
|
};
|
|
5647
|
-
const updatedConfig =
|
|
5549
|
+
const updatedConfig = _15.cloneDeep(config);
|
|
5648
5550
|
console.log(`Initializing DatoCMS loader...`);
|
|
5649
5551
|
const project = await dato.findProject();
|
|
5650
5552
|
const modelChoices = await getModelChoices(dato, config);
|
|
@@ -5662,7 +5564,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
|
|
|
5662
5564
|
delete updatedConfig.models[modelId];
|
|
5663
5565
|
}
|
|
5664
5566
|
}
|
|
5665
|
-
for (const modelId of
|
|
5567
|
+
for (const modelId of _15.keys(updatedConfig.models)) {
|
|
5666
5568
|
const { modelName, fields } = await getModelFields(dato, modelId);
|
|
5667
5569
|
if (fields.length > 0) {
|
|
5668
5570
|
result.models[modelId] = { fields: [], records: [] };
|
|
@@ -5680,7 +5582,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
|
|
|
5680
5582
|
);
|
|
5681
5583
|
if (isLocalized) {
|
|
5682
5584
|
result.models[modelId].fields.push(fieldInfo);
|
|
5683
|
-
updatedConfig.models[modelId].fields =
|
|
5585
|
+
updatedConfig.models[modelId].fields = _15.uniq([
|
|
5684
5586
|
...updatedConfig.models[modelId].fields || [],
|
|
5685
5587
|
fieldInfo.api_key
|
|
5686
5588
|
]);
|
|
@@ -5708,7 +5610,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
|
|
|
5708
5610
|
},
|
|
5709
5611
|
async pull(locale, input2, initCtx) {
|
|
5710
5612
|
const result = {};
|
|
5711
|
-
for (const modelId of
|
|
5613
|
+
for (const modelId of _15.keys(initCtx?.models || {})) {
|
|
5712
5614
|
let records = initCtx?.models[modelId].records || [];
|
|
5713
5615
|
const recordIds = records.map((record) => record.id);
|
|
5714
5616
|
records = await dato.findRecords(recordIds);
|
|
@@ -5723,7 +5625,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
|
|
|
5723
5625
|
return result;
|
|
5724
5626
|
},
|
|
5725
5627
|
async push(locale, data, originalInput) {
|
|
5726
|
-
for (const modelId of
|
|
5628
|
+
for (const modelId of _15.keys(data)) {
|
|
5727
5629
|
for (let i = 0; i < data[modelId].records.length; i++) {
|
|
5728
5630
|
const record = data[modelId].records[i];
|
|
5729
5631
|
console.log(
|
|
@@ -5739,7 +5641,7 @@ async function getModelFields(dato, modelId) {
|
|
|
5739
5641
|
const modelInfo = await dato.findModel(modelId);
|
|
5740
5642
|
return {
|
|
5741
5643
|
modelName: modelInfo.name,
|
|
5742
|
-
fields:
|
|
5644
|
+
fields: _15.filter(modelInfo.fields, (field) => field.type === "field")
|
|
5743
5645
|
};
|
|
5744
5646
|
}
|
|
5745
5647
|
async function getFieldDetails(dato, fields) {
|
|
@@ -5819,17 +5721,17 @@ async function promptModelSelection(choices) {
|
|
|
5819
5721
|
}
|
|
5820
5722
|
|
|
5821
5723
|
// src/cli/loaders/dato/extract.ts
|
|
5822
|
-
import
|
|
5724
|
+
import _16 from "lodash";
|
|
5823
5725
|
function createDatoExtractLoader() {
|
|
5824
5726
|
return createLoader({
|
|
5825
5727
|
async pull(locale, input2) {
|
|
5826
5728
|
const result = {};
|
|
5827
|
-
for (const [modelId, modelInfo] of
|
|
5828
|
-
for (const [recordId, record] of
|
|
5829
|
-
for (const [fieldName, fieldValue] of
|
|
5729
|
+
for (const [modelId, modelInfo] of _16.entries(input2)) {
|
|
5730
|
+
for (const [recordId, record] of _16.entries(modelInfo)) {
|
|
5731
|
+
for (const [fieldName, fieldValue] of _16.entries(record)) {
|
|
5830
5732
|
const parsedValue = createParsedDatoValue(fieldValue);
|
|
5831
5733
|
if (parsedValue) {
|
|
5832
|
-
|
|
5734
|
+
_16.set(result, [modelId, `_${recordId}`, fieldName], parsedValue);
|
|
5833
5735
|
}
|
|
5834
5736
|
}
|
|
5835
5737
|
}
|
|
@@ -5837,12 +5739,12 @@ function createDatoExtractLoader() {
|
|
|
5837
5739
|
return result;
|
|
5838
5740
|
},
|
|
5839
5741
|
async push(locale, data, originalInput) {
|
|
5840
|
-
const result =
|
|
5841
|
-
for (const [modelId, modelInfo] of
|
|
5842
|
-
for (const [virtualRecordId, record] of
|
|
5843
|
-
for (const [fieldName, fieldValue] of
|
|
5742
|
+
const result = _16.cloneDeep(originalInput || {});
|
|
5743
|
+
for (const [modelId, modelInfo] of _16.entries(data)) {
|
|
5744
|
+
for (const [virtualRecordId, record] of _16.entries(modelInfo)) {
|
|
5745
|
+
for (const [fieldName, fieldValue] of _16.entries(record)) {
|
|
5844
5746
|
const [, recordId] = virtualRecordId.split("_");
|
|
5845
|
-
const originalFieldValue =
|
|
5747
|
+
const originalFieldValue = _16.get(originalInput, [
|
|
5846
5748
|
modelId,
|
|
5847
5749
|
recordId,
|
|
5848
5750
|
fieldName
|
|
@@ -5852,7 +5754,7 @@ function createDatoExtractLoader() {
|
|
|
5852
5754
|
originalFieldValue,
|
|
5853
5755
|
true
|
|
5854
5756
|
);
|
|
5855
|
-
|
|
5757
|
+
_16.set(
|
|
5856
5758
|
result,
|
|
5857
5759
|
[modelId, recordId, fieldName],
|
|
5858
5760
|
rawValue || originalFieldValue
|
|
@@ -5865,25 +5767,25 @@ function createDatoExtractLoader() {
|
|
|
5865
5767
|
});
|
|
5866
5768
|
}
|
|
5867
5769
|
function detectDatoFieldType(rawDatoValue) {
|
|
5868
|
-
if (
|
|
5770
|
+
if (_16.has(rawDatoValue, "document") && _16.get(rawDatoValue, "schema") === "dast") {
|
|
5869
5771
|
return "structured_text";
|
|
5870
|
-
} else if (
|
|
5772
|
+
} else if (_16.has(rawDatoValue, "no_index") || _16.has(rawDatoValue, "twitter_card")) {
|
|
5871
5773
|
return "seo";
|
|
5872
|
-
} else if (
|
|
5774
|
+
} else if (_16.get(rawDatoValue, "type") === "item") {
|
|
5873
5775
|
return "single_block";
|
|
5874
|
-
} else if (
|
|
5776
|
+
} else if (_16.isArray(rawDatoValue) && _16.every(rawDatoValue, (item) => _16.get(item, "type") === "item")) {
|
|
5875
5777
|
return "rich_text";
|
|
5876
5778
|
} else if (_isFile(rawDatoValue)) {
|
|
5877
5779
|
return "file";
|
|
5878
|
-
} else if (
|
|
5780
|
+
} else if (_16.isArray(rawDatoValue) && _16.every(rawDatoValue, (item) => _isFile(item))) {
|
|
5879
5781
|
return "gallery";
|
|
5880
5782
|
} else if (_isJson(rawDatoValue)) {
|
|
5881
5783
|
return "json";
|
|
5882
|
-
} else if (
|
|
5784
|
+
} else if (_16.isString(rawDatoValue)) {
|
|
5883
5785
|
return "string";
|
|
5884
5786
|
} else if (_isVideo(rawDatoValue)) {
|
|
5885
5787
|
return "video";
|
|
5886
|
-
} else if (
|
|
5788
|
+
} else if (_16.isArray(rawDatoValue) && _16.every(rawDatoValue, (item) => _16.isString(item))) {
|
|
5887
5789
|
return "ref_list";
|
|
5888
5790
|
} else {
|
|
5889
5791
|
return null;
|
|
@@ -5953,9 +5855,9 @@ function serializeStructuredText(rawStructuredText) {
|
|
|
5953
5855
|
acc
|
|
5954
5856
|
);
|
|
5955
5857
|
}
|
|
5956
|
-
if (!
|
|
5858
|
+
if (!_16.isNil(node.value)) {
|
|
5957
5859
|
acc[[...path19, "value"].join(".")] = node.value;
|
|
5958
|
-
} else if (
|
|
5860
|
+
} else if (_16.get(node, "type") === "block") {
|
|
5959
5861
|
acc[[...path19, "item"].join(".")] = serializeBlock(node.item);
|
|
5960
5862
|
}
|
|
5961
5863
|
if (node.children) {
|
|
@@ -5971,48 +5873,48 @@ function serializeStructuredText(rawStructuredText) {
|
|
|
5971
5873
|
}
|
|
5972
5874
|
}
|
|
5973
5875
|
function serializeSeo(rawSeo) {
|
|
5974
|
-
return
|
|
5876
|
+
return _16.chain(rawSeo).pick(["title", "description"]).value();
|
|
5975
5877
|
}
|
|
5976
5878
|
function serializeBlock(rawBlock) {
|
|
5977
|
-
if (
|
|
5879
|
+
if (_16.get(rawBlock, "type") === "item" && _16.has(rawBlock, "id")) {
|
|
5978
5880
|
return serializeBlock(rawBlock.attributes);
|
|
5979
5881
|
}
|
|
5980
5882
|
const result = {};
|
|
5981
|
-
for (const [attributeName, attributeValue] of
|
|
5883
|
+
for (const [attributeName, attributeValue] of _16.entries(rawBlock)) {
|
|
5982
5884
|
result[attributeName] = createParsedDatoValue(attributeValue);
|
|
5983
5885
|
}
|
|
5984
5886
|
return result;
|
|
5985
5887
|
}
|
|
5986
5888
|
function serializeBlockList(rawBlockList) {
|
|
5987
|
-
return
|
|
5889
|
+
return _16.chain(rawBlockList).map((block) => serializeBlock(block)).value();
|
|
5988
5890
|
}
|
|
5989
5891
|
function serializeVideo(rawVideo) {
|
|
5990
|
-
return
|
|
5892
|
+
return _16.chain(rawVideo).pick(["title"]).value();
|
|
5991
5893
|
}
|
|
5992
5894
|
function serializeFile(rawFile) {
|
|
5993
|
-
return
|
|
5895
|
+
return _16.chain(rawFile).pick(["alt", "title"]).value();
|
|
5994
5896
|
}
|
|
5995
5897
|
function serializeGallery(rawGallery) {
|
|
5996
|
-
return
|
|
5898
|
+
return _16.chain(rawGallery).map((item) => serializeFile(item)).value();
|
|
5997
5899
|
}
|
|
5998
5900
|
function deserializeFile(parsedFile, originalRawFile) {
|
|
5999
|
-
return
|
|
5901
|
+
return _16.chain(parsedFile).defaults(originalRawFile).value();
|
|
6000
5902
|
}
|
|
6001
5903
|
function deserializeGallery(parsedGallery, originalRawGallery) {
|
|
6002
|
-
return
|
|
5904
|
+
return _16.chain(parsedGallery).map((item, i) => deserializeFile(item, originalRawGallery[i])).value();
|
|
6003
5905
|
}
|
|
6004
5906
|
function deserializeVideo(parsedVideo, originalRawVideo) {
|
|
6005
|
-
return
|
|
5907
|
+
return _16.chain(parsedVideo).defaults(originalRawVideo).value();
|
|
6006
5908
|
}
|
|
6007
5909
|
function deserializeBlock(payload, rawNode, isClean = false) {
|
|
6008
|
-
const result =
|
|
6009
|
-
for (const [attributeName, attributeValue] of
|
|
5910
|
+
const result = _16.cloneDeep(rawNode);
|
|
5911
|
+
for (const [attributeName, attributeValue] of _16.entries(rawNode.attributes)) {
|
|
6010
5912
|
const rawValue = createRawDatoValue(
|
|
6011
5913
|
payload[attributeName],
|
|
6012
5914
|
attributeValue,
|
|
6013
5915
|
isClean
|
|
6014
5916
|
);
|
|
6015
|
-
|
|
5917
|
+
_16.set(result, ["attributes", attributeName], rawValue);
|
|
6016
5918
|
}
|
|
6017
5919
|
if (isClean) {
|
|
6018
5920
|
delete result["id"];
|
|
@@ -6020,40 +5922,40 @@ function deserializeBlock(payload, rawNode, isClean = false) {
|
|
|
6020
5922
|
return result;
|
|
6021
5923
|
}
|
|
6022
5924
|
function deserializeSeo(parsedSeo, originalRawSeo) {
|
|
6023
|
-
return
|
|
5925
|
+
return _16.chain(parsedSeo).pick(["title", "description"]).defaults(originalRawSeo).value();
|
|
6024
5926
|
}
|
|
6025
5927
|
function deserializeBlockList(parsedBlockList, originalRawBlockList, isClean = false) {
|
|
6026
|
-
return
|
|
5928
|
+
return _16.chain(parsedBlockList).map(
|
|
6027
5929
|
(block, i) => deserializeBlock(block, originalRawBlockList[i], isClean)
|
|
6028
5930
|
).value();
|
|
6029
5931
|
}
|
|
6030
5932
|
function deserializeStructuredText(parsedStructuredText, originalRawStructuredText) {
|
|
6031
|
-
const result =
|
|
6032
|
-
for (const [path19, value] of
|
|
6033
|
-
const realPath =
|
|
5933
|
+
const result = _16.cloneDeep(originalRawStructuredText);
|
|
5934
|
+
for (const [path19, value] of _16.entries(parsedStructuredText)) {
|
|
5935
|
+
const realPath = _16.chain(path19.split(".")).flatMap((s) => !_16.isNaN(_16.toNumber(s)) ? ["children", s] : s).value();
|
|
6034
5936
|
const deserializedValue = createRawDatoValue(
|
|
6035
5937
|
value,
|
|
6036
|
-
|
|
5938
|
+
_16.get(originalRawStructuredText, realPath),
|
|
6037
5939
|
true
|
|
6038
5940
|
);
|
|
6039
|
-
|
|
5941
|
+
_16.set(result, realPath, deserializedValue);
|
|
6040
5942
|
}
|
|
6041
5943
|
return result;
|
|
6042
5944
|
}
|
|
6043
5945
|
function _isJson(rawDatoValue) {
|
|
6044
5946
|
try {
|
|
6045
|
-
return
|
|
5947
|
+
return _16.isString(rawDatoValue) && rawDatoValue.startsWith("{") && rawDatoValue.endsWith("}") && !!JSON.parse(rawDatoValue);
|
|
6046
5948
|
} catch (e) {
|
|
6047
5949
|
return false;
|
|
6048
5950
|
}
|
|
6049
5951
|
}
|
|
6050
5952
|
function _isFile(rawDatoValue) {
|
|
6051
|
-
return
|
|
6052
|
-
(key) =>
|
|
5953
|
+
return _16.isObject(rawDatoValue) && ["alt", "title", "custom_data", "focal_point", "upload_id"].every(
|
|
5954
|
+
(key) => _16.has(rawDatoValue, key)
|
|
6053
5955
|
);
|
|
6054
5956
|
}
|
|
6055
5957
|
function _isVideo(rawDatoValue) {
|
|
6056
|
-
return
|
|
5958
|
+
return _16.isObject(rawDatoValue) && [
|
|
6057
5959
|
"url",
|
|
6058
5960
|
"title",
|
|
6059
5961
|
"width",
|
|
@@ -6061,7 +5963,7 @@ function _isVideo(rawDatoValue) {
|
|
|
6061
5963
|
"provider",
|
|
6062
5964
|
"provider_uid",
|
|
6063
5965
|
"thumbnail_url"
|
|
6064
|
-
].every((key) =>
|
|
5966
|
+
].every((key) => _16.has(rawDatoValue, key));
|
|
6065
5967
|
}
|
|
6066
5968
|
|
|
6067
5969
|
// src/cli/loaders/dato/index.ts
|
|
@@ -6131,7 +6033,7 @@ function createVttLoader() {
|
|
|
6131
6033
|
}
|
|
6132
6034
|
|
|
6133
6035
|
// src/cli/loaders/variable/index.ts
|
|
6134
|
-
import
|
|
6036
|
+
import _17 from "lodash";
|
|
6135
6037
|
function createVariableLoader(params) {
|
|
6136
6038
|
return composeLoaders(variableExtractLoader(params), variableContentLoader());
|
|
6137
6039
|
}
|
|
@@ -6140,18 +6042,9 @@ function variableExtractLoader(params) {
|
|
|
6140
6042
|
return createLoader({
|
|
6141
6043
|
pull: async (locale, input2, initXtx, originalLocale, originalInput) => {
|
|
6142
6044
|
const result = {};
|
|
6143
|
-
const inputValues =
|
|
6045
|
+
const inputValues = _17.omitBy(input2, _17.isEmpty);
|
|
6144
6046
|
for (const [key, value] of Object.entries(inputValues)) {
|
|
6145
6047
|
const originalValue = originalInput[key];
|
|
6146
|
-
if (isICUPluralObject(originalValue)) {
|
|
6147
|
-
const icuValue = isICUPluralObject(value) ? { icu: value.icu } : value;
|
|
6148
|
-
result[key] = {
|
|
6149
|
-
value: icuValue,
|
|
6150
|
-
variables: []
|
|
6151
|
-
// Metadata stored separately, not in variables
|
|
6152
|
-
};
|
|
6153
|
-
continue;
|
|
6154
|
-
}
|
|
6155
6048
|
const matches = originalValue.match(specifierPattern) || [];
|
|
6156
6049
|
result[key] = result[key] || {
|
|
6157
6050
|
value,
|
|
@@ -6171,19 +6064,14 @@ function variableExtractLoader(params) {
|
|
|
6171
6064
|
const result = {};
|
|
6172
6065
|
for (const [key, valueObj] of Object.entries(data)) {
|
|
6173
6066
|
result[key] = valueObj.value;
|
|
6174
|
-
const resultValue = result[key];
|
|
6175
|
-
if (isICUPluralObject(resultValue)) {
|
|
6176
|
-
const originalValue = originalInput?.[key];
|
|
6177
|
-
if (isICUPluralObject(originalValue) && originalValue._meta) {
|
|
6178
|
-
resultValue._meta = originalValue._meta;
|
|
6179
|
-
resultValue[Symbol.for("@lingo.dev/icu-plural-object")] = true;
|
|
6180
|
-
}
|
|
6181
|
-
}
|
|
6182
6067
|
for (let i = 0; i < valueObj.variables.length; i++) {
|
|
6183
6068
|
const variable = valueObj.variables[i];
|
|
6184
6069
|
const currentValue = result[key];
|
|
6185
6070
|
if (typeof currentValue === "string") {
|
|
6186
|
-
const newValue = currentValue?.
|
|
6071
|
+
const newValue = currentValue?.replaceAll(
|
|
6072
|
+
`{variable:${i}}`,
|
|
6073
|
+
variable
|
|
6074
|
+
);
|
|
6187
6075
|
result[key] = newValue;
|
|
6188
6076
|
}
|
|
6189
6077
|
}
|
|
@@ -6195,11 +6083,11 @@ function variableExtractLoader(params) {
|
|
|
6195
6083
|
function variableContentLoader() {
|
|
6196
6084
|
return createLoader({
|
|
6197
6085
|
pull: async (locale, input2) => {
|
|
6198
|
-
const result =
|
|
6086
|
+
const result = _17.mapValues(input2, (payload) => payload.value);
|
|
6199
6087
|
return result;
|
|
6200
6088
|
},
|
|
6201
6089
|
push: async (locale, data, originalInput, defaultLocale, pullInput) => {
|
|
6202
|
-
const result =
|
|
6090
|
+
const result = _17.cloneDeep(
|
|
6203
6091
|
originalInput || {}
|
|
6204
6092
|
);
|
|
6205
6093
|
for (const [key, originalValueObj] of Object.entries(result)) {
|
|
@@ -6224,20 +6112,20 @@ function getFormatSpecifierPattern(type) {
|
|
|
6224
6112
|
}
|
|
6225
6113
|
|
|
6226
6114
|
// src/cli/loaders/sync.ts
|
|
6227
|
-
import
|
|
6115
|
+
import _18 from "lodash";
|
|
6228
6116
|
function createSyncLoader() {
|
|
6229
6117
|
return createLoader({
|
|
6230
6118
|
async pull(locale, input2, initCtx, originalLocale, originalInput) {
|
|
6231
6119
|
if (!originalInput) {
|
|
6232
6120
|
return input2;
|
|
6233
6121
|
}
|
|
6234
|
-
return
|
|
6122
|
+
return _18.chain(originalInput).mapValues((value, key) => input2[key]).value();
|
|
6235
6123
|
},
|
|
6236
6124
|
async push(locale, data, originalInput) {
|
|
6237
6125
|
if (!originalInput) {
|
|
6238
6126
|
return data;
|
|
6239
6127
|
}
|
|
6240
|
-
return
|
|
6128
|
+
return _18.chain(originalInput || {}).mapValues((value, key) => data[key]).value();
|
|
6241
6129
|
}
|
|
6242
6130
|
});
|
|
6243
6131
|
}
|
|
@@ -6419,7 +6307,7 @@ function parseVueFile(input2) {
|
|
|
6419
6307
|
|
|
6420
6308
|
// src/cli/loaders/typescript/index.ts
|
|
6421
6309
|
import { parse as parse3 } from "@babel/parser";
|
|
6422
|
-
import
|
|
6310
|
+
import _19 from "lodash";
|
|
6423
6311
|
import babelTraverseModule from "@babel/traverse";
|
|
6424
6312
|
import * as t from "@babel/types";
|
|
6425
6313
|
import babelGenerateModule from "@babel/generator";
|
|
@@ -6455,7 +6343,7 @@ function createTypescriptLoader() {
|
|
|
6455
6343
|
},
|
|
6456
6344
|
push: async (locale, data, originalInput, defaultLocale, pullInput, pullOutput) => {
|
|
6457
6345
|
const ast = parseTypeScript(originalInput || "");
|
|
6458
|
-
const finalData =
|
|
6346
|
+
const finalData = _19.merge({}, pullOutput, data);
|
|
6459
6347
|
updateStringsInDefaultExport(ast, finalData);
|
|
6460
6348
|
const { code } = generate(ast, {
|
|
6461
6349
|
jsescOption: {
|
|
@@ -6656,7 +6544,7 @@ function getPropertyKey(prop) {
|
|
|
6656
6544
|
}
|
|
6657
6545
|
|
|
6658
6546
|
// src/cli/loaders/inject-locale.ts
|
|
6659
|
-
import
|
|
6547
|
+
import _20 from "lodash";
|
|
6660
6548
|
|
|
6661
6549
|
// ../../node_modules/.pnpm/@isaacs+balanced-match@4.0.1/node_modules/@isaacs/balanced-match/dist/esm/index.js
|
|
6662
6550
|
var balanced = (a, b, str) => {
|
|
@@ -7347,7 +7235,7 @@ var AST = class _AST {
|
|
|
7347
7235
|
if (!this.type) {
|
|
7348
7236
|
const noEmpty = this.isStart() && this.isEnd();
|
|
7349
7237
|
const src = this.#parts.map((p) => {
|
|
7350
|
-
const [re,
|
|
7238
|
+
const [re, _37, hasMagic, uflag] = typeof p === "string" ? _AST.#parseGlob(p, this.#hasMagic, noEmpty) : p.toRegExpSource(allowDot);
|
|
7351
7239
|
this.#hasMagic = this.#hasMagic || hasMagic;
|
|
7352
7240
|
this.#uflag = this.#uflag || uflag;
|
|
7353
7241
|
return re;
|
|
@@ -7420,7 +7308,7 @@ var AST = class _AST {
|
|
|
7420
7308
|
if (typeof p === "string") {
|
|
7421
7309
|
throw new Error("string type in extglob ast??");
|
|
7422
7310
|
}
|
|
7423
|
-
const [re,
|
|
7311
|
+
const [re, _37, _hasMagic, uflag] = p.toRegExpSource(dot);
|
|
7424
7312
|
this.#uflag = this.#uflag || uflag;
|
|
7425
7313
|
return re;
|
|
7426
7314
|
}).filter((p) => !(this.isStart() && this.isEnd()) || !!p).join("|");
|
|
@@ -7665,7 +7553,7 @@ var Minimatch = class {
|
|
|
7665
7553
|
}
|
|
7666
7554
|
return false;
|
|
7667
7555
|
}
|
|
7668
|
-
debug(...
|
|
7556
|
+
debug(..._37) {
|
|
7669
7557
|
}
|
|
7670
7558
|
make() {
|
|
7671
7559
|
const pattern = this.pattern;
|
|
@@ -7687,7 +7575,7 @@ var Minimatch = class {
|
|
|
7687
7575
|
const rawGlobParts = this.globSet.map((s) => this.slashSplit(s));
|
|
7688
7576
|
this.globParts = this.preprocess(rawGlobParts);
|
|
7689
7577
|
this.debug(this.pattern, this.globParts);
|
|
7690
|
-
let set = this.globParts.map((s,
|
|
7578
|
+
let set = this.globParts.map((s, _37, __) => {
|
|
7691
7579
|
if (this.isWindows && this.windowsNoMagicRoot) {
|
|
7692
7580
|
const isUNC = s[0] === "" && s[1] === "" && (s[2] === "?" || !globMagic.test(s[2])) && !globMagic.test(s[3]);
|
|
7693
7581
|
const isDrive = /^[a-z]:/i.test(s[0]);
|
|
@@ -8204,7 +8092,7 @@ function createInjectLocaleLoader(injectLocaleKeys) {
|
|
|
8204
8092
|
return data;
|
|
8205
8093
|
}
|
|
8206
8094
|
const omitKeys = _getKeysWithLocales(data, injectLocaleKeys, locale);
|
|
8207
|
-
const result =
|
|
8095
|
+
const result = _20.omit(data, omitKeys);
|
|
8208
8096
|
return result;
|
|
8209
8097
|
},
|
|
8210
8098
|
async push(locale, data, originalInput, originalLocale) {
|
|
@@ -8217,7 +8105,7 @@ function createInjectLocaleLoader(injectLocaleKeys) {
|
|
|
8217
8105
|
originalLocale
|
|
8218
8106
|
);
|
|
8219
8107
|
localeKeys.forEach((key) => {
|
|
8220
|
-
|
|
8108
|
+
_20.set(data, key, locale);
|
|
8221
8109
|
});
|
|
8222
8110
|
return data;
|
|
8223
8111
|
}
|
|
@@ -8226,7 +8114,7 @@ function createInjectLocaleLoader(injectLocaleKeys) {
|
|
|
8226
8114
|
function _getKeysWithLocales(data, injectLocaleKeys, locale) {
|
|
8227
8115
|
const allKeys = _getAllKeys(data);
|
|
8228
8116
|
return allKeys.filter((key) => {
|
|
8229
|
-
return injectLocaleKeys.some((pattern) => minimatch(key, pattern)) &&
|
|
8117
|
+
return injectLocaleKeys.some((pattern) => minimatch(key, pattern)) && _20.get(data, key) === locale;
|
|
8230
8118
|
});
|
|
8231
8119
|
}
|
|
8232
8120
|
function _getAllKeys(obj, prefix = "") {
|
|
@@ -8244,7 +8132,7 @@ function _getAllKeys(obj, prefix = "") {
|
|
|
8244
8132
|
}
|
|
8245
8133
|
|
|
8246
8134
|
// src/cli/loaders/locked-keys.ts
|
|
8247
|
-
import
|
|
8135
|
+
import _21 from "lodash";
|
|
8248
8136
|
|
|
8249
8137
|
// src/cli/utils/key-matching.ts
|
|
8250
8138
|
function matchesKeyPattern(key, patterns) {
|
|
@@ -8263,14 +8151,14 @@ function formatDisplayValue(value, maxLength = 50) {
|
|
|
8263
8151
|
function createLockedKeysLoader(lockedKeys) {
|
|
8264
8152
|
return createLoader({
|
|
8265
8153
|
pull: async (locale, data) => {
|
|
8266
|
-
return
|
|
8154
|
+
return _21.pickBy(
|
|
8267
8155
|
data,
|
|
8268
8156
|
(value, key) => !matchesKeyPattern(key, lockedKeys)
|
|
8269
8157
|
);
|
|
8270
8158
|
},
|
|
8271
8159
|
push: async (locale, data, originalInput) => {
|
|
8272
|
-
const lockedSubObject =
|
|
8273
|
-
return
|
|
8160
|
+
const lockedSubObject = _21.chain(originalInput).pickBy((value, key) => matchesKeyPattern(key, lockedKeys)).value();
|
|
8161
|
+
return _21.merge({}, data, lockedSubObject);
|
|
8274
8162
|
}
|
|
8275
8163
|
});
|
|
8276
8164
|
}
|
|
@@ -8322,7 +8210,7 @@ function md5(input2) {
|
|
|
8322
8210
|
}
|
|
8323
8211
|
|
|
8324
8212
|
// src/cli/loaders/mdx2/code-placeholder.ts
|
|
8325
|
-
import
|
|
8213
|
+
import _22 from "lodash";
|
|
8326
8214
|
var fenceRegex = /([ \t]*)(^>\s*)?```([\s\S]*?)```/gm;
|
|
8327
8215
|
var inlineCodeRegex = /(?<!`)`([^`\r\n]+?)`(?!`)/g;
|
|
8328
8216
|
var imageRegex = /([ \t]*)(^>\s*)?!\[[^\]]*?\]\(([^()]*(\([^()]*\)[^()]*)*)\)/gm;
|
|
@@ -8345,7 +8233,7 @@ ${match2}
|
|
|
8345
8233
|
found = true;
|
|
8346
8234
|
}
|
|
8347
8235
|
} while (found);
|
|
8348
|
-
content =
|
|
8236
|
+
content = _22.chain(content).split("\n\n").map((section) => _22.trim(section, "\n")).filter(Boolean).join("\n\n").value();
|
|
8349
8237
|
return content;
|
|
8350
8238
|
}
|
|
8351
8239
|
function ensureTrailingFenceNewline(_content) {
|
|
@@ -8367,7 +8255,7 @@ ${match2}
|
|
|
8367
8255
|
found = true;
|
|
8368
8256
|
}
|
|
8369
8257
|
} while (found);
|
|
8370
|
-
content =
|
|
8258
|
+
content = _22.chain(content).split("\n\n").map((section) => _22.trim(section, "\n")).filter(Boolean).join("\n\n").value();
|
|
8371
8259
|
return content;
|
|
8372
8260
|
}
|
|
8373
8261
|
function extractCodePlaceholders(content) {
|
|
@@ -8409,7 +8297,7 @@ function createMdxCodePlaceholderLoader() {
|
|
|
8409
8297
|
async push(locale, data, originalInput, originalLocale, pullInput) {
|
|
8410
8298
|
const sourceInfo = extractCodePlaceholders(originalInput ?? "");
|
|
8411
8299
|
const currentInfo = extractCodePlaceholders(pullInput ?? "");
|
|
8412
|
-
const codePlaceholders =
|
|
8300
|
+
const codePlaceholders = _22.merge(
|
|
8413
8301
|
sourceInfo.codePlaceholders,
|
|
8414
8302
|
currentInfo.codePlaceholders,
|
|
8415
8303
|
globalPlaceholderRegistry
|
|
@@ -8417,7 +8305,7 @@ function createMdxCodePlaceholderLoader() {
|
|
|
8417
8305
|
);
|
|
8418
8306
|
let result = data;
|
|
8419
8307
|
for (const [placeholder, original] of Object.entries(codePlaceholders)) {
|
|
8420
|
-
const replacement = original.startsWith(">") ?
|
|
8308
|
+
const replacement = original.startsWith(">") ? _22.trimStart(original, "> ") : original;
|
|
8421
8309
|
result = result.replaceAll(placeholder, () => replacement);
|
|
8422
8310
|
}
|
|
8423
8311
|
return result;
|
|
@@ -8445,11 +8333,11 @@ function createLocalizableMdxDocumentLoader() {
|
|
|
8445
8333
|
}
|
|
8446
8334
|
|
|
8447
8335
|
// src/cli/loaders/mdx2/sections-split-2.ts
|
|
8448
|
-
import
|
|
8336
|
+
import _23 from "lodash";
|
|
8449
8337
|
function createMdxSectionsSplit2Loader() {
|
|
8450
8338
|
return createLoader({
|
|
8451
8339
|
async pull(locale, input2) {
|
|
8452
|
-
const sections =
|
|
8340
|
+
const sections = _23.chain(input2.content).split("\n\n").filter(Boolean).map((section, index) => [index, section]).fromPairs().value();
|
|
8453
8341
|
const result = {
|
|
8454
8342
|
frontmatter: input2.frontmatter,
|
|
8455
8343
|
sections
|
|
@@ -8457,7 +8345,7 @@ function createMdxSectionsSplit2Loader() {
|
|
|
8457
8345
|
return result;
|
|
8458
8346
|
},
|
|
8459
8347
|
async push(locale, data, originalInput, _originalLocale, pullInput) {
|
|
8460
|
-
const content =
|
|
8348
|
+
const content = _23.chain(data.sections).values().join("\n\n").value();
|
|
8461
8349
|
const result = {
|
|
8462
8350
|
frontmatter: data.frontmatter,
|
|
8463
8351
|
codePlaceholders: pullInput?.codePlaceholders || {},
|
|
@@ -8523,18 +8411,18 @@ function createLockedPatternsLoader(defaultPatterns) {
|
|
|
8523
8411
|
}
|
|
8524
8412
|
|
|
8525
8413
|
// src/cli/loaders/ignored-keys.ts
|
|
8526
|
-
import
|
|
8414
|
+
import _24 from "lodash";
|
|
8527
8415
|
function createIgnoredKeysLoader(ignoredKeys) {
|
|
8528
8416
|
return createLoader({
|
|
8529
8417
|
pull: async (locale, data) => {
|
|
8530
|
-
const result =
|
|
8418
|
+
const result = _24.omitBy(
|
|
8531
8419
|
data,
|
|
8532
8420
|
(value, key) => matchesKeyPattern(key, ignoredKeys)
|
|
8533
8421
|
);
|
|
8534
8422
|
return result;
|
|
8535
8423
|
},
|
|
8536
8424
|
push: async (locale, data, originalInput, originalLocale, pullInput) => {
|
|
8537
|
-
const result =
|
|
8425
|
+
const result = _24.omitBy(
|
|
8538
8426
|
data,
|
|
8539
8427
|
(value, key) => matchesKeyPattern(key, ignoredKeys)
|
|
8540
8428
|
);
|
|
@@ -8675,7 +8563,7 @@ function createEjsLoader() {
|
|
|
8675
8563
|
}
|
|
8676
8564
|
|
|
8677
8565
|
// src/cli/loaders/ensure-key-order.ts
|
|
8678
|
-
import
|
|
8566
|
+
import _25 from "lodash";
|
|
8679
8567
|
function createEnsureKeyOrderLoader() {
|
|
8680
8568
|
return createLoader({
|
|
8681
8569
|
pull: async (_locale, input2) => {
|
|
@@ -8690,10 +8578,10 @@ function createEnsureKeyOrderLoader() {
|
|
|
8690
8578
|
});
|
|
8691
8579
|
}
|
|
8692
8580
|
function reorderKeys(data, originalInput) {
|
|
8693
|
-
if (
|
|
8581
|
+
if (_25.isArray(originalInput) && _25.isArray(data)) {
|
|
8694
8582
|
return data.map((item, idx) => reorderKeys(item, originalInput[idx] ?? {}));
|
|
8695
8583
|
}
|
|
8696
|
-
if (!
|
|
8584
|
+
if (!_25.isObject(data) || _25.isArray(data) || _25.isDate(data)) {
|
|
8697
8585
|
return data;
|
|
8698
8586
|
}
|
|
8699
8587
|
const orderedData = {};
|
|
@@ -8725,13 +8613,13 @@ function createTxtLoader() {
|
|
|
8725
8613
|
const sortedEntries = Object.entries(payload).sort(
|
|
8726
8614
|
([a], [b]) => parseInt(a) - parseInt(b)
|
|
8727
8615
|
);
|
|
8728
|
-
return sortedEntries.map(([
|
|
8616
|
+
return sortedEntries.map(([_37, value]) => value).join("\n");
|
|
8729
8617
|
}
|
|
8730
8618
|
});
|
|
8731
8619
|
}
|
|
8732
8620
|
|
|
8733
8621
|
// src/cli/loaders/json-dictionary.ts
|
|
8734
|
-
import
|
|
8622
|
+
import _26 from "lodash";
|
|
8735
8623
|
var TOP_LEVEL_KEY = "--content--";
|
|
8736
8624
|
function createJsonDictionaryLoader() {
|
|
8737
8625
|
return createLoader({
|
|
@@ -8746,7 +8634,7 @@ function createJsonDictionaryLoader() {
|
|
|
8746
8634
|
if (!originalInput) {
|
|
8747
8635
|
throw new Error("Error while parsing json-dictionary bucket");
|
|
8748
8636
|
}
|
|
8749
|
-
const input2 =
|
|
8637
|
+
const input2 = _26.cloneDeep(originalInput);
|
|
8750
8638
|
if (Object.keys(data).length === 1 && Object.keys(data)[0] === TOP_LEVEL_KEY) {
|
|
8751
8639
|
setNestedLocale(
|
|
8752
8640
|
{ [TOP_LEVEL_KEY]: input2 },
|
|
@@ -9016,9 +8904,8 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys,
|
|
|
9016
8904
|
createPlutilJsonTextLoader(),
|
|
9017
8905
|
createLockedPatternsLoader(lockedPatterns),
|
|
9018
8906
|
createJsonLoader(),
|
|
9019
|
-
createXcodeXcstringsLoader(options.defaultLocale),
|
|
9020
8907
|
createXcodeXcstringsV2Loader(options.defaultLocale),
|
|
9021
|
-
createFlatLoader(
|
|
8908
|
+
createFlatLoader(),
|
|
9022
8909
|
createEnsureKeyOrderLoader(),
|
|
9023
8910
|
createLockedKeysLoader(lockedKeys || []),
|
|
9024
8911
|
createIgnoredKeysLoader(ignoredKeys || []),
|
|
@@ -9327,7 +9214,7 @@ import { Command as Command13 } from "interactive-commander";
|
|
|
9327
9214
|
import { Command as Command10 } from "interactive-commander";
|
|
9328
9215
|
import chalk2 from "chalk";
|
|
9329
9216
|
import dedent from "dedent";
|
|
9330
|
-
import
|
|
9217
|
+
import _27 from "lodash";
|
|
9331
9218
|
var set_default = new Command10().name("set").description("Set or update a CLI setting in ~/.lingodotdevrc").addHelpText("afterAll", `
|
|
9332
9219
|
Available keys:
|
|
9333
9220
|
${SETTINGS_KEYS.join("\n ")}`).argument(
|
|
@@ -9345,8 +9232,8 @@ Available keys:
|
|
|
9345
9232
|
return;
|
|
9346
9233
|
}
|
|
9347
9234
|
const current = loadSystemSettings();
|
|
9348
|
-
const updated =
|
|
9349
|
-
|
|
9235
|
+
const updated = _27.cloneDeep(current);
|
|
9236
|
+
_27.set(updated, key, value);
|
|
9350
9237
|
try {
|
|
9351
9238
|
saveSettings(updated);
|
|
9352
9239
|
console.log(`${chalk2.green("\u2714")} Set ${chalk2.bold(key)}`);
|
|
@@ -9366,7 +9253,7 @@ Available keys:
|
|
|
9366
9253
|
import { Command as Command11 } from "interactive-commander";
|
|
9367
9254
|
import chalk3 from "chalk";
|
|
9368
9255
|
import dedent2 from "dedent";
|
|
9369
|
-
import
|
|
9256
|
+
import _28 from "lodash";
|
|
9370
9257
|
var unset_default = new Command11().name("unset").description("Remove a CLI setting from ~/.lingodotdevrc").addHelpText("afterAll", `
|
|
9371
9258
|
Available keys:
|
|
9372
9259
|
${SETTINGS_KEYS.join("\n ")}`).argument(
|
|
@@ -9386,13 +9273,13 @@ Available keys:
|
|
|
9386
9273
|
return;
|
|
9387
9274
|
}
|
|
9388
9275
|
const settings = loadSystemSettings();
|
|
9389
|
-
const currentValue =
|
|
9390
|
-
if (!
|
|
9276
|
+
const currentValue = _28.get(settings, key);
|
|
9277
|
+
if (!_28.trim(String(currentValue || ""))) {
|
|
9391
9278
|
console.log(`${chalk3.cyan("\u2139")} ${chalk3.bold(key)} is not set.`);
|
|
9392
9279
|
return;
|
|
9393
9280
|
} else {
|
|
9394
|
-
const updated =
|
|
9395
|
-
|
|
9281
|
+
const updated = _28.cloneDeep(settings);
|
|
9282
|
+
_28.unset(updated, key);
|
|
9396
9283
|
try {
|
|
9397
9284
|
saveSettings(updated);
|
|
9398
9285
|
console.log(
|
|
@@ -9414,7 +9301,7 @@ Available keys:
|
|
|
9414
9301
|
// src/cli/cmd/config/get.ts
|
|
9415
9302
|
import { Command as Command12 } from "interactive-commander";
|
|
9416
9303
|
import chalk4 from "chalk";
|
|
9417
|
-
import
|
|
9304
|
+
import _29 from "lodash";
|
|
9418
9305
|
import dedent3 from "dedent";
|
|
9419
9306
|
var get_default = new Command12().name("get").description("Display the value of a CLI setting from ~/.lingodotdevrc").addHelpText("afterAll", `
|
|
9420
9307
|
Available keys:
|
|
@@ -9433,7 +9320,7 @@ Available keys:
|
|
|
9433
9320
|
return;
|
|
9434
9321
|
}
|
|
9435
9322
|
const settings = loadSystemSettings();
|
|
9436
|
-
const value =
|
|
9323
|
+
const value = _29.get(settings, key);
|
|
9437
9324
|
if (!value) {
|
|
9438
9325
|
console.log(`${chalk4.cyan("\u2139")} ${chalk4.bold(key)} is not set.`);
|
|
9439
9326
|
return;
|
|
@@ -9458,7 +9345,7 @@ import {
|
|
|
9458
9345
|
} from "@lingo.dev/_spec";
|
|
9459
9346
|
import { Command as Command14 } from "interactive-commander";
|
|
9460
9347
|
import Z3 from "zod";
|
|
9461
|
-
import
|
|
9348
|
+
import _32 from "lodash";
|
|
9462
9349
|
import Ora9 from "ora";
|
|
9463
9350
|
import chalk6 from "chalk";
|
|
9464
9351
|
import { createTwoFilesPatch } from "diff";
|
|
@@ -9498,7 +9385,7 @@ function createLingoLocalizer(params) {
|
|
|
9498
9385
|
|
|
9499
9386
|
// src/cli/processor/basic.ts
|
|
9500
9387
|
import { generateText } from "ai";
|
|
9501
|
-
import
|
|
9388
|
+
import _30 from "lodash";
|
|
9502
9389
|
function createBasicTranslator(model, systemPrompt, settings = {}) {
|
|
9503
9390
|
return async (input2, onProgress) => {
|
|
9504
9391
|
const chunks = extractPayloadChunks(input2.processableData);
|
|
@@ -9512,7 +9399,7 @@ function createBasicTranslator(model, systemPrompt, settings = {}) {
|
|
|
9512
9399
|
subResults.push(result2);
|
|
9513
9400
|
onProgress(i / chunks.length * 100, chunk, result2);
|
|
9514
9401
|
}
|
|
9515
|
-
const result =
|
|
9402
|
+
const result = _30.merge({}, ...subResults);
|
|
9516
9403
|
return result;
|
|
9517
9404
|
};
|
|
9518
9405
|
async function doJob(input2) {
|
|
@@ -9789,7 +9676,7 @@ function trackEvent(distinctId, event, properties) {
|
|
|
9789
9676
|
}
|
|
9790
9677
|
|
|
9791
9678
|
// src/cli/utils/delta.ts
|
|
9792
|
-
import
|
|
9679
|
+
import _31 from "lodash";
|
|
9793
9680
|
import z from "zod";
|
|
9794
9681
|
|
|
9795
9682
|
// src/cli/utils/fs.ts
|
|
@@ -9838,11 +9725,11 @@ function createDeltaProcessor(fileKey) {
|
|
|
9838
9725
|
return checkIfFileExists(lockfilePath);
|
|
9839
9726
|
},
|
|
9840
9727
|
async calculateDelta(params) {
|
|
9841
|
-
let added =
|
|
9728
|
+
let added = _31.difference(
|
|
9842
9729
|
Object.keys(params.sourceData),
|
|
9843
9730
|
Object.keys(params.targetData)
|
|
9844
9731
|
);
|
|
9845
|
-
let removed =
|
|
9732
|
+
let removed = _31.difference(
|
|
9846
9733
|
Object.keys(params.targetData),
|
|
9847
9734
|
Object.keys(params.sourceData)
|
|
9848
9735
|
);
|
|
@@ -9904,12 +9791,41 @@ function createDeltaProcessor(fileKey) {
|
|
|
9904
9791
|
await this.saveLock(lockfileData);
|
|
9905
9792
|
},
|
|
9906
9793
|
async createChecksums(sourceData) {
|
|
9907
|
-
const checksums =
|
|
9794
|
+
const checksums = _31.mapValues(sourceData, (value) => md5(value));
|
|
9908
9795
|
return checksums;
|
|
9909
9796
|
}
|
|
9910
9797
|
};
|
|
9911
9798
|
}
|
|
9912
9799
|
|
|
9800
|
+
// src/cli/loaders/xcode-xcstrings-icu.ts
|
|
9801
|
+
var ICU_TYPE_MARKER = Symbol.for("@lingo.dev/icu-plural-object");
|
|
9802
|
+
function isICUPluralObject(value) {
|
|
9803
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
9804
|
+
return false;
|
|
9805
|
+
}
|
|
9806
|
+
if (ICU_TYPE_MARKER in value) {
|
|
9807
|
+
return true;
|
|
9808
|
+
}
|
|
9809
|
+
if (!("icu" in value) || typeof value.icu !== "string") {
|
|
9810
|
+
return false;
|
|
9811
|
+
}
|
|
9812
|
+
const icuPluralPattern = /^\{[\w]+,\s*plural,\s*.+\}$/;
|
|
9813
|
+
if (!icuPluralPattern.test(value.icu)) {
|
|
9814
|
+
return false;
|
|
9815
|
+
}
|
|
9816
|
+
if (value._meta !== void 0) {
|
|
9817
|
+
if (typeof value._meta !== "object" || !value._meta.variables || typeof value._meta.variables !== "object") {
|
|
9818
|
+
return false;
|
|
9819
|
+
}
|
|
9820
|
+
for (const [varName, varMeta] of Object.entries(value._meta.variables)) {
|
|
9821
|
+
if (!varMeta || typeof varMeta !== "object" || typeof varMeta.format !== "string" || varMeta.role !== "plural" && varMeta.role !== "other") {
|
|
9822
|
+
return false;
|
|
9823
|
+
}
|
|
9824
|
+
}
|
|
9825
|
+
}
|
|
9826
|
+
return true;
|
|
9827
|
+
}
|
|
9828
|
+
|
|
9913
9829
|
// src/cli/cmd/i18n.ts
|
|
9914
9830
|
var i18n_default = new Command14().command("i18n").description(
|
|
9915
9831
|
"DEPRECATED: Run localization pipeline (prefer `run` command instead)"
|
|
@@ -10097,7 +10013,7 @@ var i18n_default = new Command14().command("i18n").description(
|
|
|
10097
10013
|
const deltaProcessor = createDeltaProcessor(bucketPath.pathPattern);
|
|
10098
10014
|
const sourceChecksums = await deltaProcessor.createChecksums(sourceData);
|
|
10099
10015
|
const savedChecksums = await deltaProcessor.loadChecksums();
|
|
10100
|
-
const updatedSourceData =
|
|
10016
|
+
const updatedSourceData = _32.pickBy(
|
|
10101
10017
|
sourceData,
|
|
10102
10018
|
(value, key) => sourceChecksums[key] !== savedChecksums[key]
|
|
10103
10019
|
);
|
|
@@ -10111,15 +10027,15 @@ var i18n_default = new Command14().command("i18n").description(
|
|
|
10111
10027
|
bucketPath.delimiter
|
|
10112
10028
|
);
|
|
10113
10029
|
const { unlocalizable: targetUnlocalizable, ...targetData } = await bucketLoader.pull(targetLocale);
|
|
10114
|
-
const missingKeys =
|
|
10030
|
+
const missingKeys = _32.difference(
|
|
10115
10031
|
Object.keys(sourceData),
|
|
10116
10032
|
Object.keys(targetData)
|
|
10117
10033
|
);
|
|
10118
|
-
const extraKeys =
|
|
10034
|
+
const extraKeys = _32.difference(
|
|
10119
10035
|
Object.keys(targetData),
|
|
10120
10036
|
Object.keys(sourceData)
|
|
10121
10037
|
);
|
|
10122
|
-
const unlocalizableDataDiff = !
|
|
10038
|
+
const unlocalizableDataDiff = !_32.isEqual(
|
|
10123
10039
|
sourceUnlocalizable,
|
|
10124
10040
|
targetUnlocalizable
|
|
10125
10041
|
);
|
|
@@ -10203,13 +10119,13 @@ var i18n_default = new Command14().command("i18n").description(
|
|
|
10203
10119
|
targetData,
|
|
10204
10120
|
checksums: checksums2
|
|
10205
10121
|
});
|
|
10206
|
-
let processableData =
|
|
10122
|
+
let processableData = _32.chain(sourceData).entries().filter(
|
|
10207
10123
|
([key, value]) => delta.added.includes(key) || delta.updated.includes(key) || !!flags.force
|
|
10208
10124
|
).fromPairs().value();
|
|
10209
10125
|
if (flags.key) {
|
|
10210
|
-
processableData =
|
|
10126
|
+
processableData = _32.pickBy(
|
|
10211
10127
|
processableData,
|
|
10212
|
-
(
|
|
10128
|
+
(_37, key) => key === flags.key
|
|
10213
10129
|
);
|
|
10214
10130
|
}
|
|
10215
10131
|
if (flags.verbose) {
|
|
@@ -10242,13 +10158,13 @@ var i18n_default = new Command14().command("i18n").description(
|
|
|
10242
10158
|
if (flags.verbose) {
|
|
10243
10159
|
bucketOra.info(JSON.stringify(processedTargetData, null, 2));
|
|
10244
10160
|
}
|
|
10245
|
-
let finalTargetData =
|
|
10161
|
+
let finalTargetData = _32.merge(
|
|
10246
10162
|
{},
|
|
10247
10163
|
sourceData,
|
|
10248
10164
|
targetData,
|
|
10249
10165
|
processedTargetData
|
|
10250
10166
|
);
|
|
10251
|
-
finalTargetData =
|
|
10167
|
+
finalTargetData = _32.chain(finalTargetData).entries().map(([key, value]) => {
|
|
10252
10168
|
const renaming = delta.renamed.find(
|
|
10253
10169
|
([oldKey, newKey]) => oldKey === key
|
|
10254
10170
|
);
|
|
@@ -10272,10 +10188,10 @@ var i18n_default = new Command14().command("i18n").description(
|
|
|
10272
10188
|
`Applying changes to ${bucketPath} (${targetLocale})`
|
|
10273
10189
|
);
|
|
10274
10190
|
}
|
|
10275
|
-
const finalDiffSize =
|
|
10191
|
+
const finalDiffSize = _32.chain(finalTargetData).omitBy((value, key) => {
|
|
10276
10192
|
const targetValue = targetData[key];
|
|
10277
10193
|
if (isICUPluralObject(value) && isICUPluralObject(targetValue)) {
|
|
10278
|
-
return
|
|
10194
|
+
return _32.isEqual(
|
|
10279
10195
|
{ icu: value.icu, _meta: value._meta },
|
|
10280
10196
|
{ icu: targetValue.icu, _meta: targetValue._meta }
|
|
10281
10197
|
);
|
|
@@ -10512,7 +10428,7 @@ Reviewing changes for ${chalk6.blue(args.pathPattern)} (${chalk6.yellow(
|
|
|
10512
10428
|
return args.currentData;
|
|
10513
10429
|
}
|
|
10514
10430
|
const customData = { ...args.currentData };
|
|
10515
|
-
const changes =
|
|
10431
|
+
const changes = _32.reduce(
|
|
10516
10432
|
args.proposedData,
|
|
10517
10433
|
(result, value, key) => {
|
|
10518
10434
|
if (args.currentData[key] !== value) {
|
|
@@ -10585,7 +10501,7 @@ import path16 from "path";
|
|
|
10585
10501
|
import Z4 from "zod";
|
|
10586
10502
|
import YAML6 from "yaml";
|
|
10587
10503
|
import { MD5 as MD52 } from "object-hash";
|
|
10588
|
-
import
|
|
10504
|
+
import _33 from "lodash";
|
|
10589
10505
|
function createLockfileHelper() {
|
|
10590
10506
|
return {
|
|
10591
10507
|
isLockfileExists: () => {
|
|
@@ -10595,18 +10511,18 @@ function createLockfileHelper() {
|
|
|
10595
10511
|
registerSourceData: (pathPattern, sourceData) => {
|
|
10596
10512
|
const lockfile = _loadLockfile();
|
|
10597
10513
|
const sectionKey = MD52(pathPattern);
|
|
10598
|
-
const sectionChecksums =
|
|
10514
|
+
const sectionChecksums = _33.mapValues(sourceData, (value) => MD52(value));
|
|
10599
10515
|
lockfile.checksums[sectionKey] = sectionChecksums;
|
|
10600
10516
|
_saveLockfile(lockfile);
|
|
10601
10517
|
},
|
|
10602
10518
|
registerPartialSourceData: (pathPattern, partialSourceData) => {
|
|
10603
10519
|
const lockfile = _loadLockfile();
|
|
10604
10520
|
const sectionKey = MD52(pathPattern);
|
|
10605
|
-
const sectionChecksums =
|
|
10521
|
+
const sectionChecksums = _33.mapValues(
|
|
10606
10522
|
partialSourceData,
|
|
10607
10523
|
(value) => MD52(value)
|
|
10608
10524
|
);
|
|
10609
|
-
lockfile.checksums[sectionKey] =
|
|
10525
|
+
lockfile.checksums[sectionKey] = _33.merge(
|
|
10610
10526
|
{},
|
|
10611
10527
|
lockfile.checksums[sectionKey] ?? {},
|
|
10612
10528
|
sectionChecksums
|
|
@@ -10616,9 +10532,9 @@ function createLockfileHelper() {
|
|
|
10616
10532
|
extractUpdatedData: (pathPattern, sourceData) => {
|
|
10617
10533
|
const lockfile = _loadLockfile();
|
|
10618
10534
|
const sectionKey = MD52(pathPattern);
|
|
10619
|
-
const currentChecksums =
|
|
10535
|
+
const currentChecksums = _33.mapValues(sourceData, (value) => MD52(value));
|
|
10620
10536
|
const savedChecksums = lockfile.checksums[sectionKey] || {};
|
|
10621
|
-
const updatedData =
|
|
10537
|
+
const updatedData = _33.pickBy(
|
|
10622
10538
|
sourceData,
|
|
10623
10539
|
(value, key) => savedChecksums[key] !== currentChecksums[key]
|
|
10624
10540
|
);
|
|
@@ -10711,7 +10627,7 @@ var flagsSchema = Z5.object({
|
|
|
10711
10627
|
// src/cli/cmd/cleanup.ts
|
|
10712
10628
|
import { resolveOverriddenLocale as resolveOverriddenLocale6 } from "@lingo.dev/_spec";
|
|
10713
10629
|
import { Command as Command16 } from "interactive-commander";
|
|
10714
|
-
import
|
|
10630
|
+
import _34 from "lodash";
|
|
10715
10631
|
import Ora11 from "ora";
|
|
10716
10632
|
var cleanup_default = new Command16().command("cleanup").description(
|
|
10717
10633
|
"Remove translation keys from target locales that no longer exist in the source locale"
|
|
@@ -10775,7 +10691,7 @@ var cleanup_default = new Command16().command("cleanup").description(
|
|
|
10775
10691
|
try {
|
|
10776
10692
|
const targetData = await bucketLoader.pull(targetLocale);
|
|
10777
10693
|
const targetKeys = Object.keys(targetData);
|
|
10778
|
-
const keysToRemove =
|
|
10694
|
+
const keysToRemove = _34.difference(targetKeys, sourceKeys);
|
|
10779
10695
|
if (keysToRemove.length === 0) {
|
|
10780
10696
|
bucketOra.succeed(`[${targetLocale}] No keys to remove`);
|
|
10781
10697
|
continue;
|
|
@@ -10790,7 +10706,7 @@ var cleanup_default = new Command16().command("cleanup").description(
|
|
|
10790
10706
|
);
|
|
10791
10707
|
}
|
|
10792
10708
|
if (!options.dryRun) {
|
|
10793
|
-
const cleanedData =
|
|
10709
|
+
const cleanedData = _34.pick(targetData, sourceKeys);
|
|
10794
10710
|
await bucketLoader.push(targetLocale, cleanedData);
|
|
10795
10711
|
bucketOra.succeed(
|
|
10796
10712
|
`[${targetLocale}] Removed ${keysToRemove.length} keys`
|
|
@@ -10853,7 +10769,7 @@ import Z6 from "zod";
|
|
|
10853
10769
|
import { ReplexicaEngine } from "@lingo.dev/_sdk";
|
|
10854
10770
|
var mcp_default = new Command17().command("mcp").description(
|
|
10855
10771
|
"Start a Model Context Protocol (MCP) server for AI assistant integration"
|
|
10856
|
-
).helpOption("-h, --help", "Show help").action(async (
|
|
10772
|
+
).helpOption("-h, --help", "Show help").action(async (_37, program) => {
|
|
10857
10773
|
const apiKey = program.args[0];
|
|
10858
10774
|
const settings = getSettings(apiKey);
|
|
10859
10775
|
if (!settings.auth.apiKey) {
|
|
@@ -11439,7 +11355,7 @@ async function plan(input2) {
|
|
|
11439
11355
|
import chalk12 from "chalk";
|
|
11440
11356
|
import { Listr as Listr3 } from "listr2";
|
|
11441
11357
|
import pLimit from "p-limit";
|
|
11442
|
-
import
|
|
11358
|
+
import _35 from "lodash";
|
|
11443
11359
|
var MAX_WORKER_COUNT = 10;
|
|
11444
11360
|
async function execute(input2) {
|
|
11445
11361
|
const effectiveConcurrency = Math.min(
|
|
@@ -11469,7 +11385,7 @@ async function execute(input2) {
|
|
|
11469
11385
|
return;
|
|
11470
11386
|
}
|
|
11471
11387
|
const initialChecksumsMap = /* @__PURE__ */ new Map();
|
|
11472
|
-
const uniqueBucketPatterns =
|
|
11388
|
+
const uniqueBucketPatterns = _35.uniq(
|
|
11473
11389
|
ctx.tasks.map((t2) => t2.bucketPathPattern)
|
|
11474
11390
|
);
|
|
11475
11391
|
for (const bucketPathPattern of uniqueBucketPatterns) {
|
|
@@ -11491,7 +11407,7 @@ async function execute(input2) {
|
|
|
11491
11407
|
const workerTasks = [];
|
|
11492
11408
|
for (let i = 0; i < workersCount; i++) {
|
|
11493
11409
|
const assignedTasks = ctx.tasks.filter(
|
|
11494
|
-
(
|
|
11410
|
+
(_37, idx) => idx % workersCount === i
|
|
11495
11411
|
);
|
|
11496
11412
|
workerTasks.push(
|
|
11497
11413
|
createWorkerTask({
|
|
@@ -11601,7 +11517,7 @@ function createWorkerTask(args) {
|
|
|
11601
11517
|
targetData,
|
|
11602
11518
|
checksums: initialChecksums
|
|
11603
11519
|
});
|
|
11604
|
-
const processableData =
|
|
11520
|
+
const processableData = _35.chain(sourceData).entries().filter(
|
|
11605
11521
|
([key, value]) => delta.added.includes(key) || delta.updated.includes(key) || !!args.ctx.flags.force
|
|
11606
11522
|
).filter(
|
|
11607
11523
|
([key]) => !assignedTask.onlyKeys.length || assignedTask.onlyKeys?.some(
|
|
@@ -11619,7 +11535,7 @@ function createWorkerTask(args) {
|
|
|
11619
11535
|
targetLocale: assignedTask.targetLocale
|
|
11620
11536
|
};
|
|
11621
11537
|
}
|
|
11622
|
-
const relevantHints =
|
|
11538
|
+
const relevantHints = _35.pick(hints, Object.keys(processableData));
|
|
11623
11539
|
const processedTargetData = await args.ctx.localizer.localize(
|
|
11624
11540
|
{
|
|
11625
11541
|
sourceLocale: assignedTask.sourceLocale,
|
|
@@ -11635,7 +11551,7 @@ function createWorkerTask(args) {
|
|
|
11635
11551
|
const latestTargetData = await bucketLoader.pull(
|
|
11636
11552
|
assignedTask.targetLocale
|
|
11637
11553
|
);
|
|
11638
|
-
const _partialData =
|
|
11554
|
+
const _partialData = _35.merge(
|
|
11639
11555
|
{},
|
|
11640
11556
|
latestTargetData,
|
|
11641
11557
|
processedChunk
|
|
@@ -11655,7 +11571,7 @@ function createWorkerTask(args) {
|
|
|
11655
11571
|
});
|
|
11656
11572
|
}
|
|
11657
11573
|
);
|
|
11658
|
-
const finalTargetData =
|
|
11574
|
+
const finalTargetData = _35.merge(
|
|
11659
11575
|
{},
|
|
11660
11576
|
sourceData,
|
|
11661
11577
|
targetData,
|
|
@@ -11704,7 +11620,7 @@ function countTasks(ctx, predicate) {
|
|
|
11704
11620
|
).length;
|
|
11705
11621
|
}
|
|
11706
11622
|
function processRenamedKeys(delta, targetData) {
|
|
11707
|
-
return
|
|
11623
|
+
return _35.chain(targetData).entries().map(([key, value]) => {
|
|
11708
11624
|
const renaming = delta.renamed.find(([oldKey]) => oldKey === key);
|
|
11709
11625
|
if (!renaming) {
|
|
11710
11626
|
return [key, value];
|
|
@@ -11872,7 +11788,7 @@ var flagsSchema2 = z2.object({
|
|
|
11872
11788
|
// src/cli/cmd/run/frozen.ts
|
|
11873
11789
|
import chalk14 from "chalk";
|
|
11874
11790
|
import { Listr as Listr4 } from "listr2";
|
|
11875
|
-
import
|
|
11791
|
+
import _36 from "lodash";
|
|
11876
11792
|
import { resolveOverriddenLocale as resolveOverriddenLocale8 } from "@lingo.dev/_spec";
|
|
11877
11793
|
async function frozen(input2) {
|
|
11878
11794
|
console.log(chalk14.hex(colors.orange)("[Frozen]"));
|
|
@@ -11960,7 +11876,7 @@ async function frozen(input2) {
|
|
|
11960
11876
|
const delta = createDeltaProcessor(bucketPath.pathPattern);
|
|
11961
11877
|
const sourceChecksums = await delta.createChecksums(src);
|
|
11962
11878
|
const savedChecksums = await delta.loadChecksums();
|
|
11963
|
-
const updatedSourceData =
|
|
11879
|
+
const updatedSourceData = _36.pickBy(
|
|
11964
11880
|
src,
|
|
11965
11881
|
(value, key) => sourceChecksums[key] !== savedChecksums[key]
|
|
11966
11882
|
);
|
|
@@ -11975,7 +11891,7 @@ async function frozen(input2) {
|
|
|
11975
11891
|
bucketPath.delimiter
|
|
11976
11892
|
);
|
|
11977
11893
|
const { unlocalizable: tgtUnlocalizable, ...tgt } = await loader.pull(resolvedTargetLocale);
|
|
11978
|
-
const missingKeys =
|
|
11894
|
+
const missingKeys = _36.difference(
|
|
11979
11895
|
Object.keys(src),
|
|
11980
11896
|
Object.keys(tgt)
|
|
11981
11897
|
);
|
|
@@ -11984,7 +11900,7 @@ async function frozen(input2) {
|
|
|
11984
11900
|
`Localization data has changed; please update i18n.lock or run without --frozen. Details: Target file is missing translations.`
|
|
11985
11901
|
);
|
|
11986
11902
|
}
|
|
11987
|
-
const extraKeys =
|
|
11903
|
+
const extraKeys = _36.difference(
|
|
11988
11904
|
Object.keys(tgt),
|
|
11989
11905
|
Object.keys(src)
|
|
11990
11906
|
);
|
|
@@ -11993,7 +11909,7 @@ async function frozen(input2) {
|
|
|
11993
11909
|
`Localization data has changed; please update i18n.lock or run without --frozen. Details: Target file has extra translations not present in the source file.`
|
|
11994
11910
|
);
|
|
11995
11911
|
}
|
|
11996
|
-
const unlocalizableDataDiff = !
|
|
11912
|
+
const unlocalizableDataDiff = !_36.isEqual(
|
|
11997
11913
|
srcUnlocalizable,
|
|
11998
11914
|
tgtUnlocalizable
|
|
11999
11915
|
);
|
|
@@ -13536,7 +13452,7 @@ async function renderHero2() {
|
|
|
13536
13452
|
// package.json
|
|
13537
13453
|
var package_default = {
|
|
13538
13454
|
name: "lingo.dev",
|
|
13539
|
-
version: "0.116.
|
|
13455
|
+
version: "0.116.3",
|
|
13540
13456
|
description: "Lingo.dev CLI",
|
|
13541
13457
|
private: false,
|
|
13542
13458
|
publishConfig: {
|