lingo.dev 0.74.15 → 0.74.17
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 +372 -164
- package/build/cli.cjs.map +1 -1
- package/build/cli.mjs +483 -275
- package/build/cli.mjs.map +1 -1
- package/package.json +1 -1
package/build/cli.mjs
CHANGED
|
@@ -263,15 +263,173 @@ function _getConfigFilePath() {
|
|
|
263
263
|
}
|
|
264
264
|
|
|
265
265
|
// src/cli/cmd/init.ts
|
|
266
|
-
import { defaultConfig, resolveLocaleCode, bucketTypes } from "@lingo.dev/_spec";
|
|
267
|
-
import
|
|
268
|
-
import
|
|
266
|
+
import { defaultConfig, resolveLocaleCode as resolveLocaleCode2, bucketTypes } from "@lingo.dev/_spec";
|
|
267
|
+
import fs4 from "fs";
|
|
268
|
+
import path5 from "path";
|
|
269
269
|
import { spawn } from "child_process";
|
|
270
|
+
import _3 from "lodash";
|
|
271
|
+
import { checkbox, confirm, input } from "@inquirer/prompts";
|
|
272
|
+
|
|
273
|
+
// src/cli/utils/find-locale-paths.ts
|
|
274
|
+
import path3 from "path";
|
|
275
|
+
import { glob } from "glob";
|
|
270
276
|
import _2 from "lodash";
|
|
271
|
-
import {
|
|
272
|
-
|
|
277
|
+
import { resolveLocaleCode } from "@lingo.dev/_spec";
|
|
278
|
+
function findLocaleFiles(bucket) {
|
|
279
|
+
switch (bucket) {
|
|
280
|
+
case "json":
|
|
281
|
+
return findLocaleFilesWithExtension(".json");
|
|
282
|
+
case "yaml":
|
|
283
|
+
return findLocaleFilesWithExtension(".yml");
|
|
284
|
+
case "flutter":
|
|
285
|
+
return findLocaleFilesWithExtension(".arb");
|
|
286
|
+
case "android":
|
|
287
|
+
return findLocaleFilesWithExtension(".xml");
|
|
288
|
+
case "markdown":
|
|
289
|
+
return findLocaleFilesWithExtension(".md");
|
|
290
|
+
case "xcode-xcstrings":
|
|
291
|
+
return findLocaleFilesForFilename("Localizable.xcstrings");
|
|
292
|
+
case "xcode-strings":
|
|
293
|
+
return findLocaleFilesForFilename("Localizable.strings");
|
|
294
|
+
case "xcode-stringsdict":
|
|
295
|
+
return findLocaleFilesForFilename("Localizable.stringsdict");
|
|
296
|
+
default:
|
|
297
|
+
throw new Error(`Unsupported bucket type: ${bucket}`);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
function findLocaleFilesWithExtension(ext) {
|
|
301
|
+
const files = glob.sync(`**/*${ext}`, {
|
|
302
|
+
ignore: ["node_modules/**", "package*.json", "i18n.json", "lingo.json"]
|
|
303
|
+
});
|
|
304
|
+
const localeFilePattern = new RegExp(`[/\\\\]([a-z]{2}(-[A-Z]{2})?)${ext}$`);
|
|
305
|
+
const localeDirectoryPattern = new RegExp(`[/\\\\]([a-z]{2}(-[A-Z]{2})?)[/\\\\][^/\\\\]+${ext}$`);
|
|
306
|
+
const potentialLocaleFiles = files.filter(
|
|
307
|
+
(file) => localeFilePattern.test(file) || localeDirectoryPattern.test(file)
|
|
308
|
+
);
|
|
309
|
+
const localeFilesAndPatterns = potentialLocaleFiles.map((file) => {
|
|
310
|
+
const match = file.match(new RegExp(`[/|\\\\]([a-z]{2}(-[A-Z]{2})?)(/|\\\\|${ext})`));
|
|
311
|
+
const locale = match?.[1];
|
|
312
|
+
const localeInDir = match?.[3] !== ext;
|
|
313
|
+
const filePattern = localeInDir ? file.replace(`/${locale}/`, `/[locale]/`) : path3.join(path3.dirname(file), `[locale]${ext}`);
|
|
314
|
+
return { file, locale, pattern: filePattern };
|
|
315
|
+
}).filter(({ locale }) => {
|
|
316
|
+
try {
|
|
317
|
+
resolveLocaleCode(locale);
|
|
318
|
+
return true;
|
|
319
|
+
} catch (e) {
|
|
320
|
+
}
|
|
321
|
+
return false;
|
|
322
|
+
});
|
|
323
|
+
const grouppedFilesAndPatterns = _2.groupBy(localeFilesAndPatterns, "pattern");
|
|
324
|
+
const patterns = Object.keys(grouppedFilesAndPatterns);
|
|
325
|
+
if (patterns.length > 0) {
|
|
326
|
+
return { found: true, patterns };
|
|
327
|
+
}
|
|
328
|
+
return { found: false, patterns: [`i18n/[locale]${ext}`] };
|
|
329
|
+
}
|
|
330
|
+
function findLocaleFilesForFilename(fileName) {
|
|
331
|
+
const pattern = fileName;
|
|
332
|
+
const localeFiles = glob.sync(`**/${fileName}`, {
|
|
333
|
+
ignore: ["node_modules/**", "package*.json", "i18n.json", "lingo.json"]
|
|
334
|
+
});
|
|
335
|
+
const localeFilesAndPatterns = localeFiles.map((file) => ({
|
|
336
|
+
file,
|
|
337
|
+
pattern: path3.join(path3.dirname(file), pattern)
|
|
338
|
+
}));
|
|
339
|
+
const grouppedFilesAndPatterns = _2.groupBy(localeFilesAndPatterns, "pattern");
|
|
340
|
+
const patterns = Object.keys(grouppedFilesAndPatterns);
|
|
341
|
+
if (patterns.length > 0) {
|
|
342
|
+
return { found: true, patterns };
|
|
343
|
+
}
|
|
344
|
+
return { found: false, patterns: [fileName] };
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// src/cli/utils/ensure-patterns.ts
|
|
348
|
+
import fs3 from "fs";
|
|
349
|
+
import path4 from "path";
|
|
350
|
+
function ensurePatterns(patterns, source) {
|
|
351
|
+
if (patterns.length === 0) {
|
|
352
|
+
throw new Error("No patterns found");
|
|
353
|
+
}
|
|
354
|
+
patterns.forEach((pattern) => {
|
|
355
|
+
const filePath = pattern.replace("[locale]", source);
|
|
356
|
+
if (!fs3.existsSync(filePath)) {
|
|
357
|
+
const defaultContent = getDefaultContent(path4.extname(filePath), source);
|
|
358
|
+
fs3.mkdirSync(path4.dirname(filePath), { recursive: true });
|
|
359
|
+
fs3.writeFileSync(filePath, defaultContent);
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
function getDefaultContent(ext, source) {
|
|
364
|
+
const defaultGreeting = "Hello from Lingo.dev";
|
|
365
|
+
switch (ext) {
|
|
366
|
+
case ".json":
|
|
367
|
+
case ".arb":
|
|
368
|
+
return `{
|
|
369
|
+
"greeting": "${defaultGreeting}"
|
|
370
|
+
}`;
|
|
371
|
+
case ".yml":
|
|
372
|
+
return `${source}:
|
|
373
|
+
greeting: "${defaultGreeting}"`;
|
|
374
|
+
case ".xml":
|
|
375
|
+
return `<resources>
|
|
376
|
+
<string name="greeting">${defaultGreeting}</string>
|
|
377
|
+
</resources>`;
|
|
378
|
+
case ".md":
|
|
379
|
+
return `# ${defaultGreeting}`;
|
|
380
|
+
case ".xcstrings":
|
|
381
|
+
return `{
|
|
382
|
+
"sourceLanguage" : "${source}",
|
|
383
|
+
"strings" : {
|
|
384
|
+
"${defaultGreeting}" : {
|
|
385
|
+
"extractionState" : "manual",
|
|
386
|
+
"localizations" : {
|
|
387
|
+
"${source}" : {
|
|
388
|
+
"stringUnit" : {
|
|
389
|
+
"state" : "translated",
|
|
390
|
+
"value" : "${defaultGreeting}"
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}`;
|
|
397
|
+
case ".strings":
|
|
398
|
+
return `"greeting" = "${defaultGreeting}";`;
|
|
399
|
+
case ".stringsdict":
|
|
400
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
401
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
402
|
+
<plist version="1.0">
|
|
403
|
+
<dict>
|
|
404
|
+
<key>key</key>
|
|
405
|
+
<dict>
|
|
406
|
+
<key>NSStringLocalizedFormatKey</key>
|
|
407
|
+
<string>%#@count@</string>
|
|
408
|
+
<key>count</key>
|
|
409
|
+
<dict>
|
|
410
|
+
<key>NSStringFormatSpecTypeKey</key>
|
|
411
|
+
<string>NSStringPluralRuleType</string>
|
|
412
|
+
<key>NSStringFormatValueTypeKey</key>
|
|
413
|
+
<string>d</string>
|
|
414
|
+
<key>zero</key>
|
|
415
|
+
<string>No items</string>
|
|
416
|
+
<key>one</key>
|
|
417
|
+
<string>One item</string>
|
|
418
|
+
<key>other</key>
|
|
419
|
+
<string>%d items</string>
|
|
420
|
+
</dict>
|
|
421
|
+
</dict>
|
|
422
|
+
</dict>
|
|
423
|
+
</plist>`;
|
|
424
|
+
default:
|
|
425
|
+
throw new Error(`Unsupported file extension: ${ext}`);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// src/cli/cmd/init.ts
|
|
430
|
+
var openUrl = (path11) => {
|
|
273
431
|
const settings = getSettings(void 0);
|
|
274
|
-
spawn("open", [`${settings.auth.webUrl}${
|
|
432
|
+
spawn("open", [`${settings.auth.webUrl}${path11}`]);
|
|
275
433
|
};
|
|
276
434
|
var throwHelpError = (option, value) => {
|
|
277
435
|
if (value === "help") {
|
|
@@ -286,7 +444,7 @@ Do you need support for ${value} ${option}? Type "help" and we will.`
|
|
|
286
444
|
var init_default = new InteractiveCommand().command("init").description("Initialize Lingo.dev project").helpOption("-h, --help", "Show help").addOption(new InteractiveOption("-f --force", "Overwrite existing config").prompt(void 0).default(false)).addOption(
|
|
287
445
|
new InteractiveOption("-s --source <locale>", "Source locale").argParser((value) => {
|
|
288
446
|
try {
|
|
289
|
-
|
|
447
|
+
resolveLocaleCode2(value);
|
|
290
448
|
} catch (e) {
|
|
291
449
|
throwHelpError("locale", value);
|
|
292
450
|
}
|
|
@@ -297,7 +455,7 @@ var init_default = new InteractiveCommand().command("init").description("Initial
|
|
|
297
455
|
const values = value.includes(",") ? value.split(",") : value.split(" ");
|
|
298
456
|
values.forEach((value2) => {
|
|
299
457
|
try {
|
|
300
|
-
|
|
458
|
+
resolveLocaleCode2(value2);
|
|
301
459
|
} catch (e) {
|
|
302
460
|
throwHelpError("locale", value2);
|
|
303
461
|
}
|
|
@@ -317,8 +475,8 @@ var init_default = new InteractiveCommand().command("init").description("Initial
|
|
|
317
475
|
const values = value.includes(",") ? value.split(",") : value.split(" ");
|
|
318
476
|
for (const p of values) {
|
|
319
477
|
try {
|
|
320
|
-
const dirPath =
|
|
321
|
-
const stats =
|
|
478
|
+
const dirPath = path5.dirname(p);
|
|
479
|
+
const stats = fs4.statSync(dirPath);
|
|
322
480
|
if (!stats.isDirectory()) {
|
|
323
481
|
throw new Error(`${dirPath} is not a directory`);
|
|
324
482
|
}
|
|
@@ -327,26 +485,60 @@ var init_default = new InteractiveCommand().command("init").description("Initial
|
|
|
327
485
|
}
|
|
328
486
|
}
|
|
329
487
|
return values;
|
|
330
|
-
}).default([])
|
|
488
|
+
}).prompt(void 0).default([])
|
|
331
489
|
).action(async (options) => {
|
|
332
490
|
const settings = getSettings(void 0);
|
|
491
|
+
const isInteractive = options.interactive;
|
|
333
492
|
const spinner = Ora2().start("Initializing Lingo.dev project");
|
|
334
493
|
let existingConfig = await getConfig(false);
|
|
335
494
|
if (existingConfig && !options.force) {
|
|
336
495
|
spinner.fail("Lingo.dev project already initialized");
|
|
337
496
|
return process.exit(1);
|
|
338
497
|
}
|
|
339
|
-
const newConfig =
|
|
498
|
+
const newConfig = _3.cloneDeep(defaultConfig);
|
|
340
499
|
newConfig.locale.source = options.source;
|
|
341
500
|
newConfig.locale.targets = options.targets;
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
501
|
+
if (!isInteractive) {
|
|
502
|
+
newConfig.buckets = {
|
|
503
|
+
[options.bucket]: {
|
|
504
|
+
include: options.paths || []
|
|
505
|
+
}
|
|
506
|
+
};
|
|
507
|
+
} else {
|
|
508
|
+
let selectedPatterns = [];
|
|
509
|
+
const { found, patterns } = findLocaleFiles(options.bucket);
|
|
510
|
+
if (found) {
|
|
511
|
+
spinner.succeed("Found existing locale files:");
|
|
512
|
+
selectedPatterns = await checkbox({
|
|
513
|
+
message: "Select the paths to use",
|
|
514
|
+
choices: patterns.map((value) => ({
|
|
515
|
+
value
|
|
516
|
+
}))
|
|
517
|
+
});
|
|
518
|
+
} else {
|
|
519
|
+
spinner.succeed("No existing locale files found.");
|
|
520
|
+
const useDefault = await confirm({
|
|
521
|
+
message: `Use (and create) default path ${patterns.join(", ")}?`
|
|
522
|
+
});
|
|
523
|
+
ensurePatterns(patterns, options.source);
|
|
524
|
+
if (useDefault) {
|
|
525
|
+
selectedPatterns = patterns;
|
|
526
|
+
}
|
|
345
527
|
}
|
|
346
|
-
|
|
528
|
+
if (selectedPatterns.length === 0) {
|
|
529
|
+
const customPaths = await input({
|
|
530
|
+
message: "Enter paths to use"
|
|
531
|
+
});
|
|
532
|
+
selectedPatterns = customPaths.includes(",") ? customPaths.split(",") : customPaths.split(" ");
|
|
533
|
+
}
|
|
534
|
+
newConfig.buckets = {
|
|
535
|
+
[options.bucket]: {
|
|
536
|
+
include: selectedPatterns || []
|
|
537
|
+
}
|
|
538
|
+
};
|
|
539
|
+
}
|
|
347
540
|
await saveConfig(newConfig);
|
|
348
541
|
spinner.succeed("Lingo.dev project initialized");
|
|
349
|
-
const isInteractive = !process.argv.includes("-y") && !process.argv.includes("--no-interactive");
|
|
350
542
|
if (isInteractive) {
|
|
351
543
|
const openDocs = await confirm({ message: "Would you like to see our docs?" });
|
|
352
544
|
if (openDocs) {
|
|
@@ -394,22 +586,22 @@ import { Command as Command5 } from "interactive-commander";
|
|
|
394
586
|
|
|
395
587
|
// src/cli/cmd/show/config.ts
|
|
396
588
|
import { Command as Command2 } from "interactive-commander";
|
|
397
|
-
import
|
|
398
|
-
import
|
|
399
|
-
import
|
|
589
|
+
import _4 from "lodash";
|
|
590
|
+
import fs5 from "fs";
|
|
591
|
+
import path6 from "path";
|
|
400
592
|
import { defaultConfig as defaultConfig2 } from "@lingo.dev/_spec";
|
|
401
593
|
var config_default = new Command2().command("config").description("Print out the current configuration").helpOption("-h, --help", "Show help").action(async (options) => {
|
|
402
594
|
const fileConfig = loadReplexicaFileConfig();
|
|
403
|
-
const config =
|
|
595
|
+
const config = _4.merge({}, defaultConfig2, fileConfig);
|
|
404
596
|
console.log(JSON.stringify(config, null, 2));
|
|
405
597
|
});
|
|
406
598
|
function loadReplexicaFileConfig() {
|
|
407
|
-
const replexicaConfigPath =
|
|
408
|
-
const fileExists =
|
|
599
|
+
const replexicaConfigPath = path6.resolve(process.cwd(), "i18n.json");
|
|
600
|
+
const fileExists = fs5.existsSync(replexicaConfigPath);
|
|
409
601
|
if (!fileExists) {
|
|
410
602
|
return void 0;
|
|
411
603
|
}
|
|
412
|
-
const fileContent =
|
|
604
|
+
const fileContent = fs5.readFileSync(replexicaConfigPath, "utf-8");
|
|
413
605
|
const replexicaFileConfig = JSON.parse(fileContent);
|
|
414
606
|
return replexicaFileConfig;
|
|
415
607
|
}
|
|
@@ -445,9 +637,9 @@ import { Command as Command4 } from "interactive-commander";
|
|
|
445
637
|
import Ora4 from "ora";
|
|
446
638
|
|
|
447
639
|
// src/cli/utils/buckets.ts
|
|
448
|
-
import
|
|
449
|
-
import
|
|
450
|
-
import * as
|
|
640
|
+
import _5 from "lodash";
|
|
641
|
+
import path7 from "path";
|
|
642
|
+
import * as glob2 from "glob";
|
|
451
643
|
import { resolveOverridenLocale } from "@lingo.dev/_spec";
|
|
452
644
|
function getBuckets(i18nConfig) {
|
|
453
645
|
const result = Object.entries(i18nConfig.buckets).map(([bucketType, bucketEntry]) => {
|
|
@@ -477,13 +669,13 @@ function extractPathPatterns(sourceLocale, include, exclude) {
|
|
|
477
669
|
})
|
|
478
670
|
)
|
|
479
671
|
);
|
|
480
|
-
const result =
|
|
672
|
+
const result = _5.differenceBy(includedPatterns, excludedPatterns ?? [], (item) => item.pathPattern);
|
|
481
673
|
return result;
|
|
482
674
|
}
|
|
483
675
|
function expandPlaceholderedGlob(_pathPattern, sourceLocale) {
|
|
484
|
-
const absolutePathPattern =
|
|
485
|
-
const pathPattern =
|
|
486
|
-
if (
|
|
676
|
+
const absolutePathPattern = path7.resolve(_pathPattern);
|
|
677
|
+
const pathPattern = path7.relative(process.cwd(), absolutePathPattern);
|
|
678
|
+
if (path7.relative(process.cwd(), pathPattern).startsWith("..")) {
|
|
487
679
|
throw new CLIError({
|
|
488
680
|
message: `Invalid path pattern: ${pathPattern}. Path pattern must be within the current working directory.`,
|
|
489
681
|
docUrl: "invalidPathPattern"
|
|
@@ -501,19 +693,19 @@ function expandPlaceholderedGlob(_pathPattern, sourceLocale) {
|
|
|
501
693
|
docUrl: "invalidPathPattern"
|
|
502
694
|
});
|
|
503
695
|
}
|
|
504
|
-
const pathPatternChunks = pathPattern.split(
|
|
696
|
+
const pathPatternChunks = pathPattern.split(path7.sep);
|
|
505
697
|
const localeSegmentIndex = pathPatternChunks.findIndex((segment) => segment.includes("[locale]"));
|
|
506
698
|
const localePlaceholderIndex = pathPatternChunks[localeSegmentIndex]?.indexOf("[locale]") ?? -1;
|
|
507
699
|
const sourcePathPattern = pathPattern.replace(/\[locale\]/g, sourceLocale);
|
|
508
|
-
const sourcePaths =
|
|
700
|
+
const sourcePaths = glob2.sync(sourcePathPattern, { follow: true, withFileTypes: true }).filter((file) => file.isFile() || file.isSymbolicLink()).map((file) => file.fullpath()).map((fullpath) => path7.relative(process.cwd(), fullpath));
|
|
509
701
|
const placeholderedPaths = sourcePaths.map((sourcePath) => {
|
|
510
|
-
const sourcePathChunks = sourcePath.split(
|
|
702
|
+
const sourcePathChunks = sourcePath.split(path7.sep);
|
|
511
703
|
if (localeSegmentIndex >= 0 && localePlaceholderIndex >= 0) {
|
|
512
704
|
const placeholderedPathChunk = sourcePathChunks[localeSegmentIndex];
|
|
513
705
|
const placeholderedSegment = placeholderedPathChunk.substring(0, localePlaceholderIndex) + "[locale]" + placeholderedPathChunk.substring(localePlaceholderIndex + sourceLocale.length);
|
|
514
706
|
sourcePathChunks[localeSegmentIndex] = placeholderedSegment;
|
|
515
707
|
}
|
|
516
|
-
const placeholderedPath = sourcePathChunks.join(
|
|
708
|
+
const placeholderedPath = sourcePathChunks.join(path7.sep);
|
|
517
709
|
return placeholderedPath;
|
|
518
710
|
});
|
|
519
711
|
return placeholderedPaths;
|
|
@@ -555,8 +747,8 @@ var files_default = new Command4().command("files").description("Print out the l
|
|
|
555
747
|
} else if (type.target) {
|
|
556
748
|
result.push(...targetPaths);
|
|
557
749
|
}
|
|
558
|
-
result.forEach((
|
|
559
|
-
console.log(
|
|
750
|
+
result.forEach((path11) => {
|
|
751
|
+
console.log(path11);
|
|
560
752
|
});
|
|
561
753
|
}
|
|
562
754
|
}
|
|
@@ -580,7 +772,7 @@ import { bucketTypeSchema, localeCodeSchema, resolveOverridenLocale as resolveOv
|
|
|
580
772
|
import { ReplexicaEngine } from "@lingo.dev/_sdk";
|
|
581
773
|
import { Command as Command6 } from "interactive-commander";
|
|
582
774
|
import Z4 from "zod";
|
|
583
|
-
import
|
|
775
|
+
import _19 from "lodash";
|
|
584
776
|
import Ora5 from "ora";
|
|
585
777
|
|
|
586
778
|
// src/cli/loaders/_utils.ts
|
|
@@ -597,8 +789,8 @@ function composeLoaders(...loaders) {
|
|
|
597
789
|
}
|
|
598
790
|
return this;
|
|
599
791
|
},
|
|
600
|
-
pull: async (locale,
|
|
601
|
-
let result =
|
|
792
|
+
pull: async (locale, input2) => {
|
|
793
|
+
let result = input2;
|
|
602
794
|
for (let i = 0; i < loaders.length; i++) {
|
|
603
795
|
result = await loaders[i].pull(locale, result);
|
|
604
796
|
}
|
|
@@ -634,7 +826,7 @@ function createLoader(lDefinition) {
|
|
|
634
826
|
state.defaultLocale = locale;
|
|
635
827
|
return this;
|
|
636
828
|
},
|
|
637
|
-
async pull(locale,
|
|
829
|
+
async pull(locale, input2) {
|
|
638
830
|
if (!state.defaultLocale) {
|
|
639
831
|
throw new Error("Default locale not set");
|
|
640
832
|
}
|
|
@@ -642,9 +834,9 @@ function createLoader(lDefinition) {
|
|
|
642
834
|
throw new Error("The first pull must be for the default locale");
|
|
643
835
|
}
|
|
644
836
|
if (locale === state.defaultLocale) {
|
|
645
|
-
state.originalInput =
|
|
837
|
+
state.originalInput = input2 || null;
|
|
646
838
|
}
|
|
647
|
-
return lDefinition.pull(locale,
|
|
839
|
+
return lDefinition.pull(locale, input2, state.initCtx);
|
|
648
840
|
},
|
|
649
841
|
async push(locale, data) {
|
|
650
842
|
if (!state.defaultLocale) {
|
|
@@ -663,8 +855,8 @@ function createLoader(lDefinition) {
|
|
|
663
855
|
import { jsonrepair } from "jsonrepair";
|
|
664
856
|
function createJsonLoader() {
|
|
665
857
|
return createLoader({
|
|
666
|
-
pull: async (locale,
|
|
667
|
-
const jsonString =
|
|
858
|
+
pull: async (locale, input2) => {
|
|
859
|
+
const jsonString = input2 || "{}";
|
|
668
860
|
let result;
|
|
669
861
|
try {
|
|
670
862
|
result = JSON.parse(jsonString);
|
|
@@ -682,33 +874,46 @@ function createJsonLoader() {
|
|
|
682
874
|
|
|
683
875
|
// src/cli/loaders/flat.ts
|
|
684
876
|
import { flatten, unflatten } from "flat";
|
|
685
|
-
import
|
|
877
|
+
import _6 from "lodash";
|
|
686
878
|
var OBJECT_NUMERIC_KEY_PREFIX = "__lingodotdev__obj__";
|
|
687
879
|
function createFlatLoader() {
|
|
688
|
-
|
|
880
|
+
return composeLoaders(createDenormalizeLoader(), createNormalizeLoader());
|
|
881
|
+
}
|
|
882
|
+
function createDenormalizeLoader() {
|
|
689
883
|
return createLoader({
|
|
690
|
-
pull: async (locale,
|
|
691
|
-
const
|
|
692
|
-
const
|
|
884
|
+
pull: async (locale, input2) => {
|
|
885
|
+
const inputDenormalized = denormalizeObjectKeys(input2 || {});
|
|
886
|
+
const denormalized = flatten(inputDenormalized, {
|
|
693
887
|
delimiter: "/",
|
|
694
888
|
transformKey(key) {
|
|
695
889
|
return encodeURIComponent(String(key));
|
|
696
890
|
}
|
|
697
891
|
});
|
|
698
|
-
|
|
699
|
-
|
|
892
|
+
const keysMap = buildDenormalizedKeysMap(denormalized);
|
|
893
|
+
return { denormalized, keysMap };
|
|
894
|
+
},
|
|
895
|
+
push: async (locale, { denormalized }) => {
|
|
896
|
+
const normalized = normalizeObjectKeys(denormalized);
|
|
897
|
+
return normalized;
|
|
898
|
+
}
|
|
899
|
+
});
|
|
900
|
+
}
|
|
901
|
+
function createNormalizeLoader() {
|
|
902
|
+
return createLoader({
|
|
903
|
+
pull: async (locale, input2) => {
|
|
904
|
+
const normalized = normalizeObjectKeys(input2.denormalized);
|
|
700
905
|
return normalized;
|
|
701
906
|
},
|
|
702
|
-
push: async (locale, data) => {
|
|
703
|
-
const
|
|
704
|
-
const
|
|
907
|
+
push: async (locale, data, originalInput) => {
|
|
908
|
+
const keysMap = originalInput?.keysMap ?? {};
|
|
909
|
+
const input2 = mapDenormalizedKeys(data, keysMap);
|
|
910
|
+
const denormalized = unflatten(input2, {
|
|
705
911
|
delimiter: "/",
|
|
706
912
|
transformKey(key) {
|
|
707
913
|
return decodeURIComponent(String(key));
|
|
708
914
|
}
|
|
709
915
|
});
|
|
710
|
-
|
|
711
|
-
return normalized;
|
|
916
|
+
return { denormalized, keysMap: keysMap || {} };
|
|
712
917
|
}
|
|
713
918
|
});
|
|
714
919
|
}
|
|
@@ -728,7 +933,7 @@ function buildDenormalizedKeysMap(obj) {
|
|
|
728
933
|
function mapDenormalizedKeys(obj, denormalizedKeysMap) {
|
|
729
934
|
return Object.keys(obj).reduce(
|
|
730
935
|
(acc, key) => {
|
|
731
|
-
const denormalizedKey = denormalizedKeysMap[key];
|
|
936
|
+
const denormalizedKey = denormalizedKeysMap[key] ?? key;
|
|
732
937
|
acc[denormalizedKey] = obj[key];
|
|
733
938
|
return acc;
|
|
734
939
|
},
|
|
@@ -736,12 +941,12 @@ function mapDenormalizedKeys(obj, denormalizedKeysMap) {
|
|
|
736
941
|
);
|
|
737
942
|
}
|
|
738
943
|
function denormalizeObjectKeys(obj) {
|
|
739
|
-
if (
|
|
740
|
-
return
|
|
944
|
+
if (_6.isObject(obj) && !_6.isArray(obj)) {
|
|
945
|
+
return _6.transform(
|
|
741
946
|
obj,
|
|
742
947
|
(result, value, key) => {
|
|
743
948
|
const newKey = !isNaN(Number(key)) ? `${OBJECT_NUMERIC_KEY_PREFIX}${key}` : key;
|
|
744
|
-
result[newKey] =
|
|
949
|
+
result[newKey] = _6.isObject(value) ? denormalizeObjectKeys(value) : value;
|
|
745
950
|
},
|
|
746
951
|
{}
|
|
747
952
|
);
|
|
@@ -750,12 +955,12 @@ function denormalizeObjectKeys(obj) {
|
|
|
750
955
|
}
|
|
751
956
|
}
|
|
752
957
|
function normalizeObjectKeys(obj) {
|
|
753
|
-
if (
|
|
754
|
-
return
|
|
958
|
+
if (_6.isObject(obj) && !_6.isArray(obj)) {
|
|
959
|
+
return _6.transform(
|
|
755
960
|
obj,
|
|
756
961
|
(result, value, key) => {
|
|
757
962
|
const newKey = `${key}`.replace(OBJECT_NUMERIC_KEY_PREFIX, "");
|
|
758
|
-
result[newKey] =
|
|
963
|
+
result[newKey] = _6.isObject(value) ? normalizeObjectKeys(value) : value;
|
|
759
964
|
},
|
|
760
965
|
{}
|
|
761
966
|
);
|
|
@@ -765,8 +970,8 @@ function normalizeObjectKeys(obj) {
|
|
|
765
970
|
}
|
|
766
971
|
|
|
767
972
|
// src/cli/loaders/text-file.ts
|
|
768
|
-
import
|
|
769
|
-
import
|
|
973
|
+
import fs6 from "fs/promises";
|
|
974
|
+
import path8 from "path";
|
|
770
975
|
function createTextFileLoader(pathPattern) {
|
|
771
976
|
return createLoader({
|
|
772
977
|
async pull(locale) {
|
|
@@ -774,15 +979,15 @@ function createTextFileLoader(pathPattern) {
|
|
|
774
979
|
const trimmedResult = result.trim();
|
|
775
980
|
return trimmedResult;
|
|
776
981
|
},
|
|
777
|
-
async push(locale, data,
|
|
982
|
+
async push(locale, data, _21, originalLocale) {
|
|
778
983
|
const draftPath = pathPattern.replace("[locale]", locale);
|
|
779
|
-
const finalPath =
|
|
780
|
-
const dirPath =
|
|
781
|
-
await
|
|
984
|
+
const finalPath = path8.resolve(draftPath);
|
|
985
|
+
const dirPath = path8.dirname(finalPath);
|
|
986
|
+
await fs6.mkdir(dirPath, { recursive: true });
|
|
782
987
|
const trimmedPayload = data.trim();
|
|
783
988
|
const trailingNewLine = await getTrailingNewLine(pathPattern, locale, originalLocale);
|
|
784
989
|
let finalPayload = trimmedPayload + trailingNewLine;
|
|
785
|
-
await
|
|
990
|
+
await fs6.writeFile(finalPath, finalPayload, {
|
|
786
991
|
encoding: "utf-8",
|
|
787
992
|
flag: "w"
|
|
788
993
|
});
|
|
@@ -791,12 +996,12 @@ function createTextFileLoader(pathPattern) {
|
|
|
791
996
|
}
|
|
792
997
|
async function readFileForLocale(pathPattern, locale) {
|
|
793
998
|
const draftPath = pathPattern.replace("[locale]", locale);
|
|
794
|
-
const finalPath =
|
|
795
|
-
const exists = await
|
|
999
|
+
const finalPath = path8.resolve(draftPath);
|
|
1000
|
+
const exists = await fs6.access(finalPath).then(() => true).catch(() => false);
|
|
796
1001
|
if (!exists) {
|
|
797
1002
|
return "";
|
|
798
1003
|
}
|
|
799
|
-
return
|
|
1004
|
+
return fs6.readFile(finalPath, "utf-8");
|
|
800
1005
|
}
|
|
801
1006
|
async function getTrailingNewLine(pathPattern, locale, originalLocale) {
|
|
802
1007
|
let templateData = await readFileForLocale(pathPattern, locale);
|
|
@@ -814,8 +1019,8 @@ async function getTrailingNewLine(pathPattern, locale, originalLocale) {
|
|
|
814
1019
|
import YAML from "yaml";
|
|
815
1020
|
function createYamlLoader() {
|
|
816
1021
|
return createLoader({
|
|
817
|
-
async pull(locale,
|
|
818
|
-
return YAML.parse(
|
|
1022
|
+
async pull(locale, input2) {
|
|
1023
|
+
return YAML.parse(input2) || {};
|
|
819
1024
|
},
|
|
820
1025
|
async push(locale, payload) {
|
|
821
1026
|
return YAML.stringify(payload, {
|
|
@@ -828,8 +1033,8 @@ function createYamlLoader() {
|
|
|
828
1033
|
// src/cli/loaders/root-key.ts
|
|
829
1034
|
function createRootKeyLoader(replaceAll = false) {
|
|
830
1035
|
return createLoader({
|
|
831
|
-
async pull(locale,
|
|
832
|
-
const result =
|
|
1036
|
+
async pull(locale, input2) {
|
|
1037
|
+
const result = input2[locale];
|
|
833
1038
|
return result;
|
|
834
1039
|
},
|
|
835
1040
|
async push(locale, data, originalInput) {
|
|
@@ -843,15 +1048,15 @@ function createRootKeyLoader(replaceAll = false) {
|
|
|
843
1048
|
}
|
|
844
1049
|
|
|
845
1050
|
// src/cli/loaders/flutter.ts
|
|
846
|
-
import
|
|
1051
|
+
import _7 from "lodash";
|
|
847
1052
|
function createFlutterLoader() {
|
|
848
1053
|
return createLoader({
|
|
849
|
-
async pull(locale,
|
|
850
|
-
const result =
|
|
1054
|
+
async pull(locale, input2) {
|
|
1055
|
+
const result = _7.pickBy(input2, (value, key) => !key.startsWith("@"));
|
|
851
1056
|
return result;
|
|
852
1057
|
},
|
|
853
1058
|
async push(locale, data, originalInput) {
|
|
854
|
-
const result =
|
|
1059
|
+
const result = _7.merge({}, originalInput, { "@@locale": locale }, data);
|
|
855
1060
|
return result;
|
|
856
1061
|
}
|
|
857
1062
|
});
|
|
@@ -861,10 +1066,10 @@ function createFlutterLoader() {
|
|
|
861
1066
|
import { parseStringPromise, Builder } from "xml2js";
|
|
862
1067
|
function createAndroidLoader() {
|
|
863
1068
|
return createLoader({
|
|
864
|
-
async pull(locale,
|
|
1069
|
+
async pull(locale, input2) {
|
|
865
1070
|
try {
|
|
866
1071
|
const result = {};
|
|
867
|
-
const parsed = !
|
|
1072
|
+
const parsed = !input2 ? { resources: {} } : await parseStringPromise(input2, { explicitArray: true });
|
|
868
1073
|
if (!parsed || !parsed.resources) {
|
|
869
1074
|
console.warn("No resources found in the Android resource file");
|
|
870
1075
|
return result;
|
|
@@ -953,16 +1158,16 @@ function createAndroidLoader() {
|
|
|
953
1158
|
// src/cli/loaders/csv.ts
|
|
954
1159
|
import { parse } from "csv-parse/sync";
|
|
955
1160
|
import { stringify } from "csv-stringify/sync";
|
|
956
|
-
import
|
|
1161
|
+
import _8 from "lodash";
|
|
957
1162
|
function createCsvLoader() {
|
|
958
1163
|
return createLoader({
|
|
959
1164
|
async pull(locale, _input) {
|
|
960
|
-
const
|
|
1165
|
+
const input2 = parse(_input, {
|
|
961
1166
|
columns: true,
|
|
962
1167
|
skip_empty_lines: true
|
|
963
1168
|
});
|
|
964
1169
|
const result = {};
|
|
965
|
-
|
|
1170
|
+
_8.forEach(input2, (row) => {
|
|
966
1171
|
const key = row.id;
|
|
967
1172
|
if (key && row[locale] && row[locale].trim() !== "") {
|
|
968
1173
|
result[key] = row[locale];
|
|
@@ -971,16 +1176,16 @@ function createCsvLoader() {
|
|
|
971
1176
|
return result;
|
|
972
1177
|
},
|
|
973
1178
|
async push(locale, data, originalInput) {
|
|
974
|
-
const
|
|
1179
|
+
const input2 = parse(originalInput || "", {
|
|
975
1180
|
columns: true,
|
|
976
1181
|
skip_empty_lines: true
|
|
977
1182
|
});
|
|
978
|
-
const columns =
|
|
979
|
-
const updatedRows =
|
|
1183
|
+
const columns = input2.length > 0 ? Object.keys(input2[0]) : ["id", locale];
|
|
1184
|
+
const updatedRows = input2.map((row) => ({
|
|
980
1185
|
...row,
|
|
981
1186
|
[locale]: data[row.id] || row[locale] || ""
|
|
982
1187
|
}));
|
|
983
|
-
const existingKeys = new Set(
|
|
1188
|
+
const existingKeys = new Set(input2.map((row) => row.id));
|
|
984
1189
|
Object.entries(data).forEach(([key, value]) => {
|
|
985
1190
|
if (!existingKeys.has(key)) {
|
|
986
1191
|
const newRow = {
|
|
@@ -1015,9 +1220,9 @@ function createHtmlLoader() {
|
|
|
1015
1220
|
};
|
|
1016
1221
|
const UNLOCALIZABLE_TAGS = ["script", "style"];
|
|
1017
1222
|
return createLoader({
|
|
1018
|
-
async pull(locale,
|
|
1223
|
+
async pull(locale, input2) {
|
|
1019
1224
|
const result = {};
|
|
1020
|
-
const dom = new JSDOM(
|
|
1225
|
+
const dom = new JSDOM(input2);
|
|
1021
1226
|
const document = dom.window.document;
|
|
1022
1227
|
const getPath = (node, attribute) => {
|
|
1023
1228
|
const indices = [];
|
|
@@ -1083,9 +1288,9 @@ function createHtmlLoader() {
|
|
|
1083
1288
|
const bDepth = b.split("/").length;
|
|
1084
1289
|
return aDepth - bDepth;
|
|
1085
1290
|
});
|
|
1086
|
-
paths.forEach((
|
|
1087
|
-
const value = data[
|
|
1088
|
-
const [nodePath, attribute] =
|
|
1291
|
+
paths.forEach((path11) => {
|
|
1292
|
+
const value = data[path11];
|
|
1293
|
+
const [nodePath, attribute] = path11.split("#");
|
|
1089
1294
|
const [rootTag, ...indices] = nodePath.split("/");
|
|
1090
1295
|
let parent = rootTag === "head" ? document.head : document.body;
|
|
1091
1296
|
let current = parent;
|
|
@@ -1137,8 +1342,8 @@ var yamlEngine = {
|
|
|
1137
1342
|
};
|
|
1138
1343
|
function createMarkdownLoader() {
|
|
1139
1344
|
return createLoader({
|
|
1140
|
-
async pull(locale,
|
|
1141
|
-
const { data: frontmatter, content } = matter(
|
|
1345
|
+
async pull(locale, input2) {
|
|
1346
|
+
const { data: frontmatter, content } = matter(input2, {
|
|
1142
1347
|
engines: {
|
|
1143
1348
|
yaml: yamlEngine
|
|
1144
1349
|
}
|
|
@@ -1188,7 +1393,7 @@ function createPropertiesLoader() {
|
|
|
1188
1393
|
return result;
|
|
1189
1394
|
},
|
|
1190
1395
|
async push(locale, payload) {
|
|
1191
|
-
const result = Object.entries(payload).filter(([
|
|
1396
|
+
const result = Object.entries(payload).filter(([_21, value]) => value != null).map(([key, value]) => `${key}=${value}`).join("\n");
|
|
1192
1397
|
return result;
|
|
1193
1398
|
}
|
|
1194
1399
|
});
|
|
@@ -1207,8 +1412,8 @@ function parsePropertyLine(line) {
|
|
|
1207
1412
|
// src/cli/loaders/xcode-strings.ts
|
|
1208
1413
|
function createXcodeStringsLoader() {
|
|
1209
1414
|
return createLoader({
|
|
1210
|
-
async pull(locale,
|
|
1211
|
-
const lines =
|
|
1415
|
+
async pull(locale, input2) {
|
|
1416
|
+
const lines = input2.split("\n");
|
|
1212
1417
|
const result = {};
|
|
1213
1418
|
for (const line of lines) {
|
|
1214
1419
|
const trimmedLine = line.trim();
|
|
@@ -1249,9 +1454,9 @@ var emptyData = [
|
|
|
1249
1454
|
].join("\n");
|
|
1250
1455
|
function createXcodeStringsdictLoader() {
|
|
1251
1456
|
return createLoader({
|
|
1252
|
-
async pull(locale,
|
|
1457
|
+
async pull(locale, input2) {
|
|
1253
1458
|
try {
|
|
1254
|
-
const parsed = plist.parse(
|
|
1459
|
+
const parsed = plist.parse(input2 || emptyData);
|
|
1255
1460
|
if (typeof parsed !== "object" || parsed === null) {
|
|
1256
1461
|
throw new CLIError({
|
|
1257
1462
|
message: "Invalid .stringsdict format",
|
|
@@ -1274,12 +1479,12 @@ function createXcodeStringsdictLoader() {
|
|
|
1274
1479
|
}
|
|
1275
1480
|
|
|
1276
1481
|
// src/cli/loaders/xcode-xcstrings.ts
|
|
1277
|
-
import
|
|
1482
|
+
import _9 from "lodash";
|
|
1278
1483
|
function createXcodeXcstringsLoader() {
|
|
1279
1484
|
return createLoader({
|
|
1280
|
-
async pull(locale,
|
|
1485
|
+
async pull(locale, input2) {
|
|
1281
1486
|
const resultData = {};
|
|
1282
|
-
for (const [translationKey, _translationEntity] of Object.entries(
|
|
1487
|
+
for (const [translationKey, _translationEntity] of Object.entries(input2.strings)) {
|
|
1283
1488
|
const rootTranslationEntity = _translationEntity;
|
|
1284
1489
|
const langTranslationEntity = rootTranslationEntity?.localizations?.[locale];
|
|
1285
1490
|
if (langTranslationEntity) {
|
|
@@ -1338,7 +1543,7 @@ function createXcodeXcstringsLoader() {
|
|
|
1338
1543
|
};
|
|
1339
1544
|
}
|
|
1340
1545
|
}
|
|
1341
|
-
const result =
|
|
1546
|
+
const result = _9.merge({}, originalInput, langDataToMerge);
|
|
1342
1547
|
return result;
|
|
1343
1548
|
}
|
|
1344
1549
|
});
|
|
@@ -1380,33 +1585,36 @@ async function loadPrettierConfig() {
|
|
|
1380
1585
|
}
|
|
1381
1586
|
|
|
1382
1587
|
// src/cli/loaders/unlocalizable.ts
|
|
1383
|
-
import
|
|
1588
|
+
import _10 from "lodash";
|
|
1384
1589
|
import _isUrl from "is-url";
|
|
1385
1590
|
import { isValid, parseISO } from "date-fns";
|
|
1386
|
-
function createUnlocalizableLoader() {
|
|
1591
|
+
function createUnlocalizableLoader(isCacheRestore = false) {
|
|
1387
1592
|
const rules = {
|
|
1388
|
-
isEmpty: (v) =>
|
|
1389
|
-
isNumber: (v) => !
|
|
1390
|
-
isBoolean: (v) =>
|
|
1391
|
-
isIsoDate: (v) =>
|
|
1392
|
-
isSystemId: (v) =>
|
|
1393
|
-
isUrl: (v) =>
|
|
1593
|
+
isEmpty: (v) => _10.isEmpty(v),
|
|
1594
|
+
isNumber: (v) => !_10.isNaN(_10.toNumber(v)),
|
|
1595
|
+
isBoolean: (v) => _10.isBoolean(v),
|
|
1596
|
+
isIsoDate: (v) => _10.isString(v) && _isIsoDate(v),
|
|
1597
|
+
isSystemId: (v) => _10.isString(v) && _isSystemId(v),
|
|
1598
|
+
isUrl: (v) => _10.isString(v) && _isUrl(v)
|
|
1394
1599
|
};
|
|
1395
1600
|
return createLoader({
|
|
1396
|
-
async pull(locale,
|
|
1397
|
-
const passthroughKeys = Object.entries(
|
|
1601
|
+
async pull(locale, input2) {
|
|
1602
|
+
const passthroughKeys = Object.entries(input2).filter(([key, value]) => {
|
|
1398
1603
|
for (const [ruleName, rule] of Object.entries(rules)) {
|
|
1399
1604
|
if (rule(value)) {
|
|
1400
1605
|
return true;
|
|
1401
1606
|
}
|
|
1402
1607
|
}
|
|
1403
1608
|
return false;
|
|
1404
|
-
}).map(([key,
|
|
1405
|
-
const result =
|
|
1609
|
+
}).map(([key, _21]) => key);
|
|
1610
|
+
const result = _10.omitBy(input2, (_21, key) => passthroughKeys.includes(key));
|
|
1406
1611
|
return result;
|
|
1407
1612
|
},
|
|
1408
1613
|
async push(locale, data, originalInput) {
|
|
1409
|
-
|
|
1614
|
+
if (isCacheRestore) {
|
|
1615
|
+
return _10.merge({}, data);
|
|
1616
|
+
}
|
|
1617
|
+
const result = _10.merge({}, originalInput, data);
|
|
1410
1618
|
return result;
|
|
1411
1619
|
}
|
|
1412
1620
|
});
|
|
@@ -1419,20 +1627,20 @@ function _isIsoDate(v) {
|
|
|
1419
1627
|
}
|
|
1420
1628
|
|
|
1421
1629
|
// src/cli/loaders/po/index.ts
|
|
1422
|
-
import
|
|
1630
|
+
import _11 from "lodash";
|
|
1423
1631
|
import gettextParser from "gettext-parser";
|
|
1424
1632
|
function createPoLoader(params = { multiline: false }) {
|
|
1425
1633
|
return composeLoaders(createPoDataLoader(params), createPoContentLoader());
|
|
1426
1634
|
}
|
|
1427
1635
|
function createPoDataLoader(params) {
|
|
1428
1636
|
return createLoader({
|
|
1429
|
-
async pull(locale,
|
|
1430
|
-
const parsedPo = gettextParser.po.parse(
|
|
1637
|
+
async pull(locale, input2) {
|
|
1638
|
+
const parsedPo = gettextParser.po.parse(input2);
|
|
1431
1639
|
const result = {};
|
|
1432
|
-
const sections =
|
|
1640
|
+
const sections = input2.split("\n\n").filter(Boolean);
|
|
1433
1641
|
for (const section of sections) {
|
|
1434
1642
|
const sectionPo = gettextParser.po.parse(section);
|
|
1435
|
-
const contextKey =
|
|
1643
|
+
const contextKey = _11.keys(sectionPo.translations)[0];
|
|
1436
1644
|
const entries = sectionPo.translations[contextKey];
|
|
1437
1645
|
Object.entries(entries).forEach(([msgid, entry]) => {
|
|
1438
1646
|
if (msgid && entry.msgid) {
|
|
@@ -1450,12 +1658,12 @@ function createPoDataLoader(params) {
|
|
|
1450
1658
|
const sections = originalInput?.split("\n\n").filter(Boolean) || [];
|
|
1451
1659
|
const result = sections.map((section) => {
|
|
1452
1660
|
const sectionPo = gettextParser.po.parse(section);
|
|
1453
|
-
const contextKey =
|
|
1661
|
+
const contextKey = _11.keys(sectionPo.translations)[0];
|
|
1454
1662
|
const entries = sectionPo.translations[contextKey];
|
|
1455
1663
|
const msgid = Object.keys(entries).find((key) => entries[key].msgid);
|
|
1456
1664
|
if (!msgid) return section;
|
|
1457
1665
|
if (data[msgid]) {
|
|
1458
|
-
const updatedPo =
|
|
1666
|
+
const updatedPo = _11.merge({}, sectionPo, {
|
|
1459
1667
|
translations: {
|
|
1460
1668
|
[contextKey]: {
|
|
1461
1669
|
[msgid]: {
|
|
@@ -1474,8 +1682,8 @@ function createPoDataLoader(params) {
|
|
|
1474
1682
|
}
|
|
1475
1683
|
function createPoContentLoader() {
|
|
1476
1684
|
return createLoader({
|
|
1477
|
-
async pull(locale,
|
|
1478
|
-
const result =
|
|
1685
|
+
async pull(locale, input2) {
|
|
1686
|
+
const result = _11.chain(input2).entries().filter(([, entry]) => !!entry.msgid).map(([, entry]) => [
|
|
1479
1687
|
entry.msgid,
|
|
1480
1688
|
{
|
|
1481
1689
|
singular: entry.msgstr[0] || entry.msgid,
|
|
@@ -1485,7 +1693,7 @@ function createPoContentLoader() {
|
|
|
1485
1693
|
return result;
|
|
1486
1694
|
},
|
|
1487
1695
|
async push(locale, data, originalInput) {
|
|
1488
|
-
const result =
|
|
1696
|
+
const result = _11.chain(originalInput).entries().map(([, entry]) => [
|
|
1489
1697
|
entry.msgid,
|
|
1490
1698
|
{
|
|
1491
1699
|
...entry,
|
|
@@ -1501,8 +1709,8 @@ function createPoContentLoader() {
|
|
|
1501
1709
|
import xliff from "xliff";
|
|
1502
1710
|
function createXliffLoader() {
|
|
1503
1711
|
return createLoader({
|
|
1504
|
-
async pull(locale,
|
|
1505
|
-
const js = await xliff.xliff2js(
|
|
1712
|
+
async pull(locale, input2) {
|
|
1713
|
+
const js = await xliff.xliff2js(input2);
|
|
1506
1714
|
return js || {};
|
|
1507
1715
|
},
|
|
1508
1716
|
async push(locale, payload) {
|
|
@@ -1519,10 +1727,10 @@ function normalizeXMLString(xmlString) {
|
|
|
1519
1727
|
}
|
|
1520
1728
|
function createXmlLoader() {
|
|
1521
1729
|
return createLoader({
|
|
1522
|
-
async pull(locale,
|
|
1730
|
+
async pull(locale, input2) {
|
|
1523
1731
|
let result = {};
|
|
1524
1732
|
try {
|
|
1525
|
-
const parsed = await parseStringPromise2(
|
|
1733
|
+
const parsed = await parseStringPromise2(input2, {
|
|
1526
1734
|
explicitArray: false,
|
|
1527
1735
|
mergeAttrs: false,
|
|
1528
1736
|
normalize: true,
|
|
@@ -1557,8 +1765,8 @@ import srtParser from "srt-parser-2";
|
|
|
1557
1765
|
function createSrtLoader() {
|
|
1558
1766
|
const parser = new srtParser();
|
|
1559
1767
|
return createLoader({
|
|
1560
|
-
async pull(locale,
|
|
1561
|
-
const parsed = parser.fromSrt(
|
|
1768
|
+
async pull(locale, input2) {
|
|
1769
|
+
const parsed = parser.fromSrt(input2) || [];
|
|
1562
1770
|
const result = {};
|
|
1563
1771
|
parsed.forEach((entry) => {
|
|
1564
1772
|
const key = `${entry.id}#${entry.startTime}-${entry.endTime}`;
|
|
@@ -1586,7 +1794,7 @@ function createSrtLoader() {
|
|
|
1586
1794
|
}
|
|
1587
1795
|
|
|
1588
1796
|
// src/cli/loaders/dato/index.ts
|
|
1589
|
-
import
|
|
1797
|
+
import fs7 from "fs";
|
|
1590
1798
|
import JSON5 from "json5";
|
|
1591
1799
|
|
|
1592
1800
|
// src/cli/loaders/dato/_base.ts
|
|
@@ -1608,34 +1816,34 @@ var datoSettingsSchema = Z2.object({
|
|
|
1608
1816
|
});
|
|
1609
1817
|
|
|
1610
1818
|
// src/cli/loaders/dato/filter.ts
|
|
1611
|
-
import
|
|
1819
|
+
import _12 from "lodash";
|
|
1612
1820
|
function createDatoFilterLoader() {
|
|
1613
1821
|
return createLoader({
|
|
1614
|
-
async pull(locale,
|
|
1822
|
+
async pull(locale, input2) {
|
|
1615
1823
|
const result = {};
|
|
1616
|
-
for (const [modelId, modelInfo] of
|
|
1824
|
+
for (const [modelId, modelInfo] of _12.entries(input2)) {
|
|
1617
1825
|
result[modelId] = {};
|
|
1618
1826
|
for (const record of modelInfo.records) {
|
|
1619
|
-
result[modelId][record.id] =
|
|
1827
|
+
result[modelId][record.id] = _12.chain(modelInfo.fields).mapKeys((field) => field.api_key).mapValues((field) => _12.get(record, [field.api_key, locale])).value();
|
|
1620
1828
|
}
|
|
1621
1829
|
}
|
|
1622
1830
|
return result;
|
|
1623
1831
|
},
|
|
1624
1832
|
async push(locale, data, originalInput, originalLocale) {
|
|
1625
|
-
const result =
|
|
1626
|
-
for (const [modelId, modelInfo] of
|
|
1833
|
+
const result = _12.cloneDeep(originalInput || {});
|
|
1834
|
+
for (const [modelId, modelInfo] of _12.entries(result)) {
|
|
1627
1835
|
for (const record of modelInfo.records) {
|
|
1628
|
-
for (const [fieldId, fieldValue] of
|
|
1836
|
+
for (const [fieldId, fieldValue] of _12.entries(record)) {
|
|
1629
1837
|
const fieldInfo = modelInfo.fields.find((field) => field.api_key === fieldId);
|
|
1630
1838
|
if (fieldInfo) {
|
|
1631
|
-
const sourceFieldValue =
|
|
1632
|
-
const targetFieldValue =
|
|
1839
|
+
const sourceFieldValue = _12.get(fieldValue, [originalLocale]);
|
|
1840
|
+
const targetFieldValue = _12.get(data, [modelId, record.id, fieldId]);
|
|
1633
1841
|
if (targetFieldValue) {
|
|
1634
|
-
|
|
1842
|
+
_12.set(record, [fieldId, locale], targetFieldValue);
|
|
1635
1843
|
} else {
|
|
1636
|
-
|
|
1844
|
+
_12.set(record, [fieldId, locale], sourceFieldValue);
|
|
1637
1845
|
}
|
|
1638
|
-
|
|
1846
|
+
_12.chain(fieldValue).keys().reject((loc) => loc === locale || loc === originalLocale).filter((loc) => _12.isEmpty(_12.get(fieldValue, [loc]))).forEach((loc) => _12.set(record, [fieldId, loc], sourceFieldValue)).value();
|
|
1639
1847
|
}
|
|
1640
1848
|
}
|
|
1641
1849
|
}
|
|
@@ -1646,10 +1854,10 @@ function createDatoFilterLoader() {
|
|
|
1646
1854
|
}
|
|
1647
1855
|
|
|
1648
1856
|
// src/cli/loaders/dato/api.ts
|
|
1649
|
-
import
|
|
1857
|
+
import _14 from "lodash";
|
|
1650
1858
|
|
|
1651
1859
|
// src/cli/loaders/dato/_utils.ts
|
|
1652
|
-
import
|
|
1860
|
+
import _13 from "lodash";
|
|
1653
1861
|
import { buildClient } from "@datocms/cma-client-node";
|
|
1654
1862
|
function createDatoClient(params) {
|
|
1655
1863
|
if (!params.apiKey) {
|
|
@@ -1824,7 +2032,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
|
|
|
1824
2032
|
const result = {
|
|
1825
2033
|
models: {}
|
|
1826
2034
|
};
|
|
1827
|
-
const updatedConfig =
|
|
2035
|
+
const updatedConfig = _14.cloneDeep(config);
|
|
1828
2036
|
console.log(`Initializing DatoCMS loader...`);
|
|
1829
2037
|
const project = await dato.findProject();
|
|
1830
2038
|
const modelChoices = await getModelChoices(dato, config);
|
|
@@ -1842,7 +2050,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
|
|
|
1842
2050
|
delete updatedConfig.models[modelId];
|
|
1843
2051
|
}
|
|
1844
2052
|
}
|
|
1845
|
-
for (const modelId of
|
|
2053
|
+
for (const modelId of _14.keys(updatedConfig.models)) {
|
|
1846
2054
|
const { modelName, fields } = await getModelFields(dato, modelId);
|
|
1847
2055
|
if (fields.length > 0) {
|
|
1848
2056
|
result.models[modelId] = { fields: [], records: [] };
|
|
@@ -1853,7 +2061,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
|
|
|
1853
2061
|
const isLocalized = await updateFieldLocalization(dato, fieldInfo, selectedFields.includes(fieldInfo.id));
|
|
1854
2062
|
if (isLocalized) {
|
|
1855
2063
|
result.models[modelId].fields.push(fieldInfo);
|
|
1856
|
-
updatedConfig.models[modelId].fields =
|
|
2064
|
+
updatedConfig.models[modelId].fields = _14.uniq([
|
|
1857
2065
|
...updatedConfig.models[modelId].fields || [],
|
|
1858
2066
|
fieldInfo.api_key
|
|
1859
2067
|
]);
|
|
@@ -1870,9 +2078,9 @@ function createDatoApiLoader(config, onConfigUpdate) {
|
|
|
1870
2078
|
onConfigUpdate(updatedConfig);
|
|
1871
2079
|
return result;
|
|
1872
2080
|
},
|
|
1873
|
-
async pull(locale,
|
|
2081
|
+
async pull(locale, input2, initCtx) {
|
|
1874
2082
|
const result = {};
|
|
1875
|
-
for (const modelId of
|
|
2083
|
+
for (const modelId of _14.keys(initCtx?.models || {})) {
|
|
1876
2084
|
let records = initCtx?.models[modelId].records || [];
|
|
1877
2085
|
const recordIds = records.map((record) => record.id);
|
|
1878
2086
|
records = await dato.findRecords(recordIds);
|
|
@@ -1887,7 +2095,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
|
|
|
1887
2095
|
return result;
|
|
1888
2096
|
},
|
|
1889
2097
|
async push(locale, data, originalInput) {
|
|
1890
|
-
for (const modelId of
|
|
2098
|
+
for (const modelId of _14.keys(data)) {
|
|
1891
2099
|
for (let i = 0; i < data[modelId].records.length; i++) {
|
|
1892
2100
|
const record = data[modelId].records[i];
|
|
1893
2101
|
console.log(`Updating record ${i + 1}/${data[modelId].records.length} for model ${modelId}...`);
|
|
@@ -1901,7 +2109,7 @@ async function getModelFields(dato, modelId) {
|
|
|
1901
2109
|
const modelInfo = await dato.findModel(modelId);
|
|
1902
2110
|
return {
|
|
1903
2111
|
modelName: modelInfo.name,
|
|
1904
|
-
fields:
|
|
2112
|
+
fields: _14.filter(modelInfo.fields, (field) => field.type === "field")
|
|
1905
2113
|
};
|
|
1906
2114
|
}
|
|
1907
2115
|
async function getFieldDetails(dato, fields) {
|
|
@@ -1979,17 +2187,17 @@ async function promptModelSelection(choices) {
|
|
|
1979
2187
|
}
|
|
1980
2188
|
|
|
1981
2189
|
// src/cli/loaders/dato/extract.ts
|
|
1982
|
-
import
|
|
2190
|
+
import _15 from "lodash";
|
|
1983
2191
|
function createDatoExtractLoader() {
|
|
1984
2192
|
return createLoader({
|
|
1985
|
-
async pull(locale,
|
|
2193
|
+
async pull(locale, input2) {
|
|
1986
2194
|
const result = {};
|
|
1987
|
-
for (const [modelId, modelInfo] of
|
|
1988
|
-
for (const [recordId, record] of
|
|
1989
|
-
for (const [fieldName, fieldValue] of
|
|
2195
|
+
for (const [modelId, modelInfo] of _15.entries(input2)) {
|
|
2196
|
+
for (const [recordId, record] of _15.entries(modelInfo)) {
|
|
2197
|
+
for (const [fieldName, fieldValue] of _15.entries(record)) {
|
|
1990
2198
|
const parsedValue = createParsedDatoValue(fieldValue);
|
|
1991
2199
|
if (parsedValue) {
|
|
1992
|
-
|
|
2200
|
+
_15.set(result, [modelId, `_${recordId}`, fieldName], parsedValue);
|
|
1993
2201
|
}
|
|
1994
2202
|
}
|
|
1995
2203
|
}
|
|
@@ -1997,14 +2205,14 @@ function createDatoExtractLoader() {
|
|
|
1997
2205
|
return result;
|
|
1998
2206
|
},
|
|
1999
2207
|
async push(locale, data, originalInput) {
|
|
2000
|
-
const result =
|
|
2001
|
-
for (const [modelId, modelInfo] of
|
|
2002
|
-
for (const [virtualRecordId, record] of
|
|
2003
|
-
for (const [fieldName, fieldValue] of
|
|
2208
|
+
const result = _15.cloneDeep(originalInput || {});
|
|
2209
|
+
for (const [modelId, modelInfo] of _15.entries(data)) {
|
|
2210
|
+
for (const [virtualRecordId, record] of _15.entries(modelInfo)) {
|
|
2211
|
+
for (const [fieldName, fieldValue] of _15.entries(record)) {
|
|
2004
2212
|
const [, recordId] = virtualRecordId.split("_");
|
|
2005
|
-
const originalFieldValue =
|
|
2213
|
+
const originalFieldValue = _15.get(originalInput, [modelId, recordId, fieldName]);
|
|
2006
2214
|
const rawValue = createRawDatoValue(fieldValue, originalFieldValue, true);
|
|
2007
|
-
|
|
2215
|
+
_15.set(result, [modelId, recordId, fieldName], rawValue || originalFieldValue);
|
|
2008
2216
|
}
|
|
2009
2217
|
}
|
|
2010
2218
|
}
|
|
@@ -2013,25 +2221,25 @@ function createDatoExtractLoader() {
|
|
|
2013
2221
|
});
|
|
2014
2222
|
}
|
|
2015
2223
|
function detectDatoFieldType(rawDatoValue) {
|
|
2016
|
-
if (
|
|
2224
|
+
if (_15.has(rawDatoValue, "document") && _15.get(rawDatoValue, "schema") === "dast") {
|
|
2017
2225
|
return "structured_text";
|
|
2018
|
-
} else if (
|
|
2226
|
+
} else if (_15.has(rawDatoValue, "no_index") || _15.has(rawDatoValue, "twitter_card")) {
|
|
2019
2227
|
return "seo";
|
|
2020
|
-
} else if (
|
|
2228
|
+
} else if (_15.get(rawDatoValue, "type") === "item") {
|
|
2021
2229
|
return "single_block";
|
|
2022
|
-
} else if (
|
|
2230
|
+
} else if (_15.isArray(rawDatoValue) && _15.every(rawDatoValue, (item) => _15.get(item, "type") === "item")) {
|
|
2023
2231
|
return "rich_text";
|
|
2024
2232
|
} else if (_isFile(rawDatoValue)) {
|
|
2025
2233
|
return "file";
|
|
2026
|
-
} else if (
|
|
2234
|
+
} else if (_15.isArray(rawDatoValue) && _15.every(rawDatoValue, (item) => _isFile(item))) {
|
|
2027
2235
|
return "gallery";
|
|
2028
2236
|
} else if (_isJson(rawDatoValue)) {
|
|
2029
2237
|
return "json";
|
|
2030
|
-
} else if (
|
|
2238
|
+
} else if (_15.isString(rawDatoValue)) {
|
|
2031
2239
|
return "string";
|
|
2032
2240
|
} else if (_isVideo(rawDatoValue)) {
|
|
2033
2241
|
return "video";
|
|
2034
|
-
} else if (
|
|
2242
|
+
} else if (_15.isArray(rawDatoValue) && _15.every(rawDatoValue, (item) => _15.isString(item))) {
|
|
2035
2243
|
return "ref_list";
|
|
2036
2244
|
} else {
|
|
2037
2245
|
return null;
|
|
@@ -2089,62 +2297,62 @@ function createRawDatoValue(parsedDatoValue, originalRawDatoValue, isClean = fal
|
|
|
2089
2297
|
}
|
|
2090
2298
|
function serializeStructuredText(rawStructuredText) {
|
|
2091
2299
|
return serializeStructuredTextNode(rawStructuredText);
|
|
2092
|
-
function serializeStructuredTextNode(node,
|
|
2300
|
+
function serializeStructuredTextNode(node, path11 = [], acc = {}) {
|
|
2093
2301
|
if ("document" in node) {
|
|
2094
|
-
return serializeStructuredTextNode(node.document, [...
|
|
2302
|
+
return serializeStructuredTextNode(node.document, [...path11, "document"], acc);
|
|
2095
2303
|
}
|
|
2096
|
-
if (!
|
|
2097
|
-
acc[[...
|
|
2098
|
-
} else if (
|
|
2099
|
-
acc[[...
|
|
2304
|
+
if (!_15.isNil(node.value)) {
|
|
2305
|
+
acc[[...path11, "value"].join(".")] = node.value;
|
|
2306
|
+
} else if (_15.get(node, "type") === "block") {
|
|
2307
|
+
acc[[...path11, "item"].join(".")] = serializeBlock(node.item);
|
|
2100
2308
|
}
|
|
2101
2309
|
if (node.children) {
|
|
2102
2310
|
for (let i = 0; i < node.children.length; i++) {
|
|
2103
|
-
serializeStructuredTextNode(node.children[i], [...
|
|
2311
|
+
serializeStructuredTextNode(node.children[i], [...path11, i.toString()], acc);
|
|
2104
2312
|
}
|
|
2105
2313
|
}
|
|
2106
2314
|
return acc;
|
|
2107
2315
|
}
|
|
2108
2316
|
}
|
|
2109
2317
|
function serializeSeo(rawSeo) {
|
|
2110
|
-
return
|
|
2318
|
+
return _15.chain(rawSeo).pick(["title", "description"]).value();
|
|
2111
2319
|
}
|
|
2112
2320
|
function serializeBlock(rawBlock) {
|
|
2113
|
-
if (
|
|
2321
|
+
if (_15.get(rawBlock, "type") === "item" && _15.has(rawBlock, "id")) {
|
|
2114
2322
|
return serializeBlock(rawBlock.attributes);
|
|
2115
2323
|
}
|
|
2116
2324
|
const result = {};
|
|
2117
|
-
for (const [attributeName, attributeValue] of
|
|
2325
|
+
for (const [attributeName, attributeValue] of _15.entries(rawBlock)) {
|
|
2118
2326
|
result[attributeName] = createParsedDatoValue(attributeValue);
|
|
2119
2327
|
}
|
|
2120
2328
|
return result;
|
|
2121
2329
|
}
|
|
2122
2330
|
function serializeBlockList(rawBlockList) {
|
|
2123
|
-
return
|
|
2331
|
+
return _15.chain(rawBlockList).map((block) => serializeBlock(block)).value();
|
|
2124
2332
|
}
|
|
2125
2333
|
function serializeVideo(rawVideo) {
|
|
2126
|
-
return
|
|
2334
|
+
return _15.chain(rawVideo).pick(["title"]).value();
|
|
2127
2335
|
}
|
|
2128
2336
|
function serializeFile(rawFile) {
|
|
2129
|
-
return
|
|
2337
|
+
return _15.chain(rawFile).pick(["alt", "title"]).value();
|
|
2130
2338
|
}
|
|
2131
2339
|
function serializeGallery(rawGallery) {
|
|
2132
|
-
return
|
|
2340
|
+
return _15.chain(rawGallery).map((item) => serializeFile(item)).value();
|
|
2133
2341
|
}
|
|
2134
2342
|
function deserializeFile(parsedFile, originalRawFile) {
|
|
2135
|
-
return
|
|
2343
|
+
return _15.chain(parsedFile).defaults(originalRawFile).value();
|
|
2136
2344
|
}
|
|
2137
2345
|
function deserializeGallery(parsedGallery, originalRawGallery) {
|
|
2138
|
-
return
|
|
2346
|
+
return _15.chain(parsedGallery).map((item, i) => deserializeFile(item, originalRawGallery[i])).value();
|
|
2139
2347
|
}
|
|
2140
2348
|
function deserializeVideo(parsedVideo, originalRawVideo) {
|
|
2141
|
-
return
|
|
2349
|
+
return _15.chain(parsedVideo).defaults(originalRawVideo).value();
|
|
2142
2350
|
}
|
|
2143
2351
|
function deserializeBlock(payload, rawNode, isClean = false) {
|
|
2144
|
-
const result =
|
|
2145
|
-
for (const [attributeName, attributeValue] of
|
|
2352
|
+
const result = _15.cloneDeep(rawNode);
|
|
2353
|
+
for (const [attributeName, attributeValue] of _15.entries(rawNode.attributes)) {
|
|
2146
2354
|
const rawValue = createRawDatoValue(payload[attributeName], attributeValue, isClean);
|
|
2147
|
-
|
|
2355
|
+
_15.set(result, ["attributes", attributeName], rawValue);
|
|
2148
2356
|
}
|
|
2149
2357
|
if (isClean) {
|
|
2150
2358
|
delete result["id"];
|
|
@@ -2152,45 +2360,45 @@ function deserializeBlock(payload, rawNode, isClean = false) {
|
|
|
2152
2360
|
return result;
|
|
2153
2361
|
}
|
|
2154
2362
|
function deserializeSeo(parsedSeo, originalRawSeo) {
|
|
2155
|
-
return
|
|
2363
|
+
return _15.chain(parsedSeo).pick(["title", "description"]).defaults(originalRawSeo).value();
|
|
2156
2364
|
}
|
|
2157
2365
|
function deserializeBlockList(parsedBlockList, originalRawBlockList, isClean = false) {
|
|
2158
|
-
return
|
|
2366
|
+
return _15.chain(parsedBlockList).map((block, i) => deserializeBlock(block, originalRawBlockList[i], isClean)).value();
|
|
2159
2367
|
}
|
|
2160
2368
|
function deserializeStructuredText(parsedStructuredText, originalRawStructuredText) {
|
|
2161
|
-
const result =
|
|
2162
|
-
for (const [
|
|
2163
|
-
const realPath =
|
|
2164
|
-
const deserializedValue = createRawDatoValue(value,
|
|
2165
|
-
|
|
2369
|
+
const result = _15.cloneDeep(originalRawStructuredText);
|
|
2370
|
+
for (const [path11, value] of _15.entries(parsedStructuredText)) {
|
|
2371
|
+
const realPath = _15.chain(path11.split(".")).flatMap((s) => !_15.isNaN(_15.toNumber(s)) ? ["children", s] : s).value();
|
|
2372
|
+
const deserializedValue = createRawDatoValue(value, _15.get(originalRawStructuredText, realPath), true);
|
|
2373
|
+
_15.set(result, realPath, deserializedValue);
|
|
2166
2374
|
}
|
|
2167
2375
|
return result;
|
|
2168
2376
|
}
|
|
2169
2377
|
function _isJson(rawDatoValue) {
|
|
2170
2378
|
try {
|
|
2171
|
-
return
|
|
2379
|
+
return _15.isString(rawDatoValue) && rawDatoValue.startsWith("{") && rawDatoValue.endsWith("}") && !!JSON.parse(rawDatoValue);
|
|
2172
2380
|
} catch (e) {
|
|
2173
2381
|
return false;
|
|
2174
2382
|
}
|
|
2175
2383
|
}
|
|
2176
2384
|
function _isFile(rawDatoValue) {
|
|
2177
|
-
return
|
|
2385
|
+
return _15.isObject(rawDatoValue) && ["alt", "title", "custom_data", "focal_point", "upload_id"].every((key) => _15.has(rawDatoValue, key));
|
|
2178
2386
|
}
|
|
2179
2387
|
function _isVideo(rawDatoValue) {
|
|
2180
|
-
return
|
|
2181
|
-
(key) =>
|
|
2388
|
+
return _15.isObject(rawDatoValue) && ["url", "title", "width", "height", "provider", "provider_uid", "thumbnail_url"].every(
|
|
2389
|
+
(key) => _15.has(rawDatoValue, key)
|
|
2182
2390
|
);
|
|
2183
2391
|
}
|
|
2184
2392
|
|
|
2185
2393
|
// src/cli/loaders/dato/index.ts
|
|
2186
2394
|
function createDatoLoader(configFilePath) {
|
|
2187
2395
|
try {
|
|
2188
|
-
const configContent =
|
|
2396
|
+
const configContent = fs7.readFileSync(configFilePath, "utf-8");
|
|
2189
2397
|
const datoConfig = datoConfigSchema.parse(JSON5.parse(configContent));
|
|
2190
2398
|
return composeLoaders(
|
|
2191
2399
|
createDatoApiLoader(
|
|
2192
2400
|
datoConfig,
|
|
2193
|
-
(updatedConfig) =>
|
|
2401
|
+
(updatedConfig) => fs7.writeFileSync(configFilePath, JSON5.stringify(updatedConfig, null, 2))
|
|
2194
2402
|
),
|
|
2195
2403
|
createDatoFilterLoader(),
|
|
2196
2404
|
createDatoExtractLoader()
|
|
@@ -2204,8 +2412,8 @@ function createDatoLoader(configFilePath) {
|
|
|
2204
2412
|
import webvtt from "node-webvtt";
|
|
2205
2413
|
function createVttLoader() {
|
|
2206
2414
|
return createLoader({
|
|
2207
|
-
async pull(locale,
|
|
2208
|
-
const vtt = webvtt.parse(
|
|
2415
|
+
async pull(locale, input2) {
|
|
2416
|
+
const vtt = webvtt.parse(input2)?.cues;
|
|
2209
2417
|
if (Object.keys(vtt).length === 0) {
|
|
2210
2418
|
return {};
|
|
2211
2419
|
} else {
|
|
@@ -2228,27 +2436,27 @@ function createVttLoader() {
|
|
|
2228
2436
|
text
|
|
2229
2437
|
};
|
|
2230
2438
|
});
|
|
2231
|
-
const
|
|
2439
|
+
const input2 = {
|
|
2232
2440
|
valid: true,
|
|
2233
2441
|
strict: true,
|
|
2234
2442
|
cues: output
|
|
2235
2443
|
};
|
|
2236
|
-
return webvtt.compile(
|
|
2444
|
+
return webvtt.compile(input2);
|
|
2237
2445
|
}
|
|
2238
2446
|
});
|
|
2239
2447
|
}
|
|
2240
2448
|
|
|
2241
2449
|
// src/cli/loaders/variable/index.ts
|
|
2242
|
-
import
|
|
2450
|
+
import _16 from "lodash";
|
|
2243
2451
|
function createVariableLoader(params) {
|
|
2244
2452
|
return composeLoaders(variableExtractLoader(params), variableContentLoader());
|
|
2245
2453
|
}
|
|
2246
2454
|
function variableExtractLoader(params) {
|
|
2247
2455
|
const specifierPattern = getFormatSpecifierPattern(params.type);
|
|
2248
2456
|
return createLoader({
|
|
2249
|
-
pull: async (locale,
|
|
2457
|
+
pull: async (locale, input2) => {
|
|
2250
2458
|
const result = {};
|
|
2251
|
-
for (const [key, value] of Object.entries(
|
|
2459
|
+
for (const [key, value] of Object.entries(input2)) {
|
|
2252
2460
|
const matches = value.match(specifierPattern) || [];
|
|
2253
2461
|
result[key] = result[key] || {
|
|
2254
2462
|
value,
|
|
@@ -2281,12 +2489,12 @@ function variableExtractLoader(params) {
|
|
|
2281
2489
|
}
|
|
2282
2490
|
function variableContentLoader() {
|
|
2283
2491
|
return createLoader({
|
|
2284
|
-
pull: async (locale,
|
|
2285
|
-
const result =
|
|
2492
|
+
pull: async (locale, input2) => {
|
|
2493
|
+
const result = _16.mapValues(input2, (payload) => payload.value);
|
|
2286
2494
|
return result;
|
|
2287
2495
|
},
|
|
2288
2496
|
push: async (locale, data, originalInput) => {
|
|
2289
|
-
const result =
|
|
2497
|
+
const result = _16.cloneDeep(originalInput || {});
|
|
2290
2498
|
for (const [key, originalValueObj] of Object.entries(result)) {
|
|
2291
2499
|
result[key] = {
|
|
2292
2500
|
...originalValueObj,
|
|
@@ -2309,20 +2517,20 @@ function getFormatSpecifierPattern(type) {
|
|
|
2309
2517
|
}
|
|
2310
2518
|
|
|
2311
2519
|
// src/cli/loaders/sync.ts
|
|
2312
|
-
import
|
|
2520
|
+
import _17 from "lodash";
|
|
2313
2521
|
function createSyncLoader() {
|
|
2314
2522
|
return createLoader({
|
|
2315
|
-
async pull(locale,
|
|
2523
|
+
async pull(locale, input2, originalInput) {
|
|
2316
2524
|
if (!originalInput) {
|
|
2317
|
-
return
|
|
2525
|
+
return input2;
|
|
2318
2526
|
}
|
|
2319
|
-
return
|
|
2527
|
+
return _17.chain(originalInput).mapValues((value, key) => input2[key]).value();
|
|
2320
2528
|
},
|
|
2321
2529
|
async push(locale, data, originalInput) {
|
|
2322
2530
|
if (!originalInput) {
|
|
2323
2531
|
return data;
|
|
2324
2532
|
}
|
|
2325
|
-
return
|
|
2533
|
+
return _17.chain(originalInput || {}).mapValues((value, key) => data[key]).value();
|
|
2326
2534
|
}
|
|
2327
2535
|
});
|
|
2328
2536
|
}
|
|
@@ -2387,7 +2595,7 @@ function createPlutilJsonTextLoader() {
|
|
|
2387
2595
|
}
|
|
2388
2596
|
|
|
2389
2597
|
// src/cli/loaders/index.ts
|
|
2390
|
-
function createBucketLoader(bucketType, bucketPathPattern) {
|
|
2598
|
+
function createBucketLoader(bucketType, bucketPathPattern, { isCacheRestore = false } = {}) {
|
|
2391
2599
|
switch (bucketType) {
|
|
2392
2600
|
default:
|
|
2393
2601
|
throw new Error(`Unsupported bucket type: ${bucketType}`);
|
|
@@ -2397,7 +2605,7 @@ function createBucketLoader(bucketType, bucketPathPattern) {
|
|
|
2397
2605
|
createAndroidLoader(),
|
|
2398
2606
|
createFlatLoader(),
|
|
2399
2607
|
createSyncLoader(),
|
|
2400
|
-
createUnlocalizableLoader()
|
|
2608
|
+
createUnlocalizableLoader(isCacheRestore)
|
|
2401
2609
|
);
|
|
2402
2610
|
case "csv":
|
|
2403
2611
|
return composeLoaders(
|
|
@@ -2405,7 +2613,7 @@ function createBucketLoader(bucketType, bucketPathPattern) {
|
|
|
2405
2613
|
createCsvLoader(),
|
|
2406
2614
|
createFlatLoader(),
|
|
2407
2615
|
createSyncLoader(),
|
|
2408
|
-
createUnlocalizableLoader()
|
|
2616
|
+
createUnlocalizableLoader(isCacheRestore)
|
|
2409
2617
|
);
|
|
2410
2618
|
case "html":
|
|
2411
2619
|
return composeLoaders(
|
|
@@ -2413,7 +2621,7 @@ function createBucketLoader(bucketType, bucketPathPattern) {
|
|
|
2413
2621
|
createPrettierLoader({ parser: "html", alwaysFormat: true }),
|
|
2414
2622
|
createHtmlLoader(),
|
|
2415
2623
|
createSyncLoader(),
|
|
2416
|
-
createUnlocalizableLoader()
|
|
2624
|
+
createUnlocalizableLoader(isCacheRestore)
|
|
2417
2625
|
);
|
|
2418
2626
|
case "json":
|
|
2419
2627
|
return composeLoaders(
|
|
@@ -2422,7 +2630,7 @@ function createBucketLoader(bucketType, bucketPathPattern) {
|
|
|
2422
2630
|
createJsonLoader(),
|
|
2423
2631
|
createFlatLoader(),
|
|
2424
2632
|
createSyncLoader(),
|
|
2425
|
-
createUnlocalizableLoader()
|
|
2633
|
+
createUnlocalizableLoader(isCacheRestore)
|
|
2426
2634
|
);
|
|
2427
2635
|
case "markdown":
|
|
2428
2636
|
return composeLoaders(
|
|
@@ -2430,7 +2638,7 @@ function createBucketLoader(bucketType, bucketPathPattern) {
|
|
|
2430
2638
|
createPrettierLoader({ parser: "markdown" }),
|
|
2431
2639
|
createMarkdownLoader(),
|
|
2432
2640
|
createSyncLoader(),
|
|
2433
|
-
createUnlocalizableLoader()
|
|
2641
|
+
createUnlocalizableLoader(isCacheRestore)
|
|
2434
2642
|
);
|
|
2435
2643
|
case "po":
|
|
2436
2644
|
return composeLoaders(
|
|
@@ -2438,7 +2646,7 @@ function createBucketLoader(bucketType, bucketPathPattern) {
|
|
|
2438
2646
|
createPoLoader(),
|
|
2439
2647
|
createFlatLoader(),
|
|
2440
2648
|
createSyncLoader(),
|
|
2441
|
-
createUnlocalizableLoader(),
|
|
2649
|
+
createUnlocalizableLoader(isCacheRestore),
|
|
2442
2650
|
createVariableLoader({ type: "python" })
|
|
2443
2651
|
);
|
|
2444
2652
|
case "properties":
|
|
@@ -2446,14 +2654,14 @@ function createBucketLoader(bucketType, bucketPathPattern) {
|
|
|
2446
2654
|
createTextFileLoader(bucketPathPattern),
|
|
2447
2655
|
createPropertiesLoader(),
|
|
2448
2656
|
createSyncLoader(),
|
|
2449
|
-
createUnlocalizableLoader()
|
|
2657
|
+
createUnlocalizableLoader(isCacheRestore)
|
|
2450
2658
|
);
|
|
2451
2659
|
case "xcode-strings":
|
|
2452
2660
|
return composeLoaders(
|
|
2453
2661
|
createTextFileLoader(bucketPathPattern),
|
|
2454
2662
|
createXcodeStringsLoader(),
|
|
2455
2663
|
createSyncLoader(),
|
|
2456
|
-
createUnlocalizableLoader()
|
|
2664
|
+
createUnlocalizableLoader(isCacheRestore)
|
|
2457
2665
|
);
|
|
2458
2666
|
case "xcode-stringsdict":
|
|
2459
2667
|
return composeLoaders(
|
|
@@ -2461,7 +2669,7 @@ function createBucketLoader(bucketType, bucketPathPattern) {
|
|
|
2461
2669
|
createXcodeStringsdictLoader(),
|
|
2462
2670
|
createFlatLoader(),
|
|
2463
2671
|
createSyncLoader(),
|
|
2464
|
-
createUnlocalizableLoader()
|
|
2672
|
+
createUnlocalizableLoader(isCacheRestore)
|
|
2465
2673
|
);
|
|
2466
2674
|
case "xcode-xcstrings":
|
|
2467
2675
|
return composeLoaders(
|
|
@@ -2471,7 +2679,7 @@ function createBucketLoader(bucketType, bucketPathPattern) {
|
|
|
2471
2679
|
createXcodeXcstringsLoader(),
|
|
2472
2680
|
createFlatLoader(),
|
|
2473
2681
|
createSyncLoader(),
|
|
2474
|
-
createUnlocalizableLoader(),
|
|
2682
|
+
createUnlocalizableLoader(isCacheRestore),
|
|
2475
2683
|
createVariableLoader({ type: "ieee" })
|
|
2476
2684
|
);
|
|
2477
2685
|
case "yaml":
|
|
@@ -2481,7 +2689,7 @@ function createBucketLoader(bucketType, bucketPathPattern) {
|
|
|
2481
2689
|
createYamlLoader(),
|
|
2482
2690
|
createFlatLoader(),
|
|
2483
2691
|
createSyncLoader(),
|
|
2484
|
-
createUnlocalizableLoader()
|
|
2692
|
+
createUnlocalizableLoader(isCacheRestore)
|
|
2485
2693
|
);
|
|
2486
2694
|
case "yaml-root-key":
|
|
2487
2695
|
return composeLoaders(
|
|
@@ -2491,7 +2699,7 @@ function createBucketLoader(bucketType, bucketPathPattern) {
|
|
|
2491
2699
|
createRootKeyLoader(true),
|
|
2492
2700
|
createFlatLoader(),
|
|
2493
2701
|
createSyncLoader(),
|
|
2494
|
-
createUnlocalizableLoader()
|
|
2702
|
+
createUnlocalizableLoader(isCacheRestore)
|
|
2495
2703
|
);
|
|
2496
2704
|
case "flutter":
|
|
2497
2705
|
return composeLoaders(
|
|
@@ -2501,7 +2709,7 @@ function createBucketLoader(bucketType, bucketPathPattern) {
|
|
|
2501
2709
|
createFlutterLoader(),
|
|
2502
2710
|
createFlatLoader(),
|
|
2503
2711
|
createSyncLoader(),
|
|
2504
|
-
createUnlocalizableLoader()
|
|
2712
|
+
createUnlocalizableLoader(isCacheRestore)
|
|
2505
2713
|
);
|
|
2506
2714
|
case "xliff":
|
|
2507
2715
|
return composeLoaders(
|
|
@@ -2509,7 +2717,7 @@ function createBucketLoader(bucketType, bucketPathPattern) {
|
|
|
2509
2717
|
createXliffLoader(),
|
|
2510
2718
|
createFlatLoader(),
|
|
2511
2719
|
createSyncLoader(),
|
|
2512
|
-
createUnlocalizableLoader()
|
|
2720
|
+
createUnlocalizableLoader(isCacheRestore)
|
|
2513
2721
|
);
|
|
2514
2722
|
case "xml":
|
|
2515
2723
|
return composeLoaders(
|
|
@@ -2517,84 +2725,84 @@ function createBucketLoader(bucketType, bucketPathPattern) {
|
|
|
2517
2725
|
createXmlLoader(),
|
|
2518
2726
|
createFlatLoader(),
|
|
2519
2727
|
createSyncLoader(),
|
|
2520
|
-
createUnlocalizableLoader()
|
|
2728
|
+
createUnlocalizableLoader(isCacheRestore)
|
|
2521
2729
|
);
|
|
2522
2730
|
case "srt":
|
|
2523
2731
|
return composeLoaders(
|
|
2524
2732
|
createTextFileLoader(bucketPathPattern),
|
|
2525
2733
|
createSrtLoader(),
|
|
2526
2734
|
createSyncLoader(),
|
|
2527
|
-
createUnlocalizableLoader()
|
|
2735
|
+
createUnlocalizableLoader(isCacheRestore)
|
|
2528
2736
|
);
|
|
2529
2737
|
case "dato":
|
|
2530
2738
|
return composeLoaders(
|
|
2531
2739
|
createDatoLoader(bucketPathPattern),
|
|
2532
2740
|
createSyncLoader(),
|
|
2533
2741
|
createFlatLoader(),
|
|
2534
|
-
createUnlocalizableLoader()
|
|
2742
|
+
createUnlocalizableLoader(isCacheRestore)
|
|
2535
2743
|
);
|
|
2536
2744
|
case "vtt":
|
|
2537
2745
|
return composeLoaders(
|
|
2538
2746
|
createTextFileLoader(bucketPathPattern),
|
|
2539
2747
|
createVttLoader(),
|
|
2540
2748
|
createSyncLoader(),
|
|
2541
|
-
createUnlocalizableLoader()
|
|
2749
|
+
createUnlocalizableLoader(isCacheRestore)
|
|
2542
2750
|
);
|
|
2543
2751
|
}
|
|
2544
2752
|
}
|
|
2545
2753
|
|
|
2546
2754
|
// src/cli/utils/lockfile.ts
|
|
2547
|
-
import
|
|
2548
|
-
import
|
|
2755
|
+
import fs8 from "fs";
|
|
2756
|
+
import path9 from "path";
|
|
2549
2757
|
import Z3 from "zod";
|
|
2550
2758
|
import YAML3 from "yaml";
|
|
2551
2759
|
import { MD5 } from "object-hash";
|
|
2552
|
-
import
|
|
2760
|
+
import _18 from "lodash";
|
|
2553
2761
|
function createLockfileHelper() {
|
|
2554
2762
|
return {
|
|
2555
2763
|
isLockfileExists: () => {
|
|
2556
2764
|
const lockfilePath = _getLockfilePath();
|
|
2557
|
-
return
|
|
2765
|
+
return fs8.existsSync(lockfilePath);
|
|
2558
2766
|
},
|
|
2559
2767
|
registerSourceData: (pathPattern, sourceData) => {
|
|
2560
2768
|
const lockfile = _loadLockfile();
|
|
2561
2769
|
const sectionKey = MD5(pathPattern);
|
|
2562
|
-
const sectionChecksums =
|
|
2770
|
+
const sectionChecksums = _18.mapValues(sourceData, (value) => MD5(value));
|
|
2563
2771
|
lockfile.checksums[sectionKey] = sectionChecksums;
|
|
2564
2772
|
_saveLockfile(lockfile);
|
|
2565
2773
|
},
|
|
2566
2774
|
registerPartialSourceData: (pathPattern, partialSourceData) => {
|
|
2567
2775
|
const lockfile = _loadLockfile();
|
|
2568
2776
|
const sectionKey = MD5(pathPattern);
|
|
2569
|
-
const sectionChecksums =
|
|
2570
|
-
lockfile.checksums[sectionKey] =
|
|
2777
|
+
const sectionChecksums = _18.mapValues(partialSourceData, (value) => MD5(value));
|
|
2778
|
+
lockfile.checksums[sectionKey] = _18.merge({}, lockfile.checksums[sectionKey] ?? {}, sectionChecksums);
|
|
2571
2779
|
_saveLockfile(lockfile);
|
|
2572
2780
|
},
|
|
2573
2781
|
extractUpdatedData: (pathPattern, sourceData) => {
|
|
2574
2782
|
const lockfile = _loadLockfile();
|
|
2575
2783
|
const sectionKey = MD5(pathPattern);
|
|
2576
|
-
const currentChecksums =
|
|
2784
|
+
const currentChecksums = _18.mapValues(sourceData, (value) => MD5(value));
|
|
2577
2785
|
const savedChecksums = lockfile.checksums[sectionKey] || {};
|
|
2578
|
-
const updatedData =
|
|
2786
|
+
const updatedData = _18.pickBy(sourceData, (value, key) => savedChecksums[key] !== currentChecksums[key]);
|
|
2579
2787
|
return updatedData;
|
|
2580
2788
|
}
|
|
2581
2789
|
};
|
|
2582
2790
|
function _loadLockfile() {
|
|
2583
2791
|
const lockfilePath = _getLockfilePath();
|
|
2584
|
-
if (!
|
|
2792
|
+
if (!fs8.existsSync(lockfilePath)) {
|
|
2585
2793
|
return LockfileSchema.parse({});
|
|
2586
2794
|
}
|
|
2587
|
-
const content =
|
|
2795
|
+
const content = fs8.readFileSync(lockfilePath, "utf-8");
|
|
2588
2796
|
const result = LockfileSchema.parse(YAML3.parse(content));
|
|
2589
2797
|
return result;
|
|
2590
2798
|
}
|
|
2591
2799
|
function _saveLockfile(lockfile) {
|
|
2592
2800
|
const lockfilePath = _getLockfilePath();
|
|
2593
2801
|
const content = YAML3.stringify(lockfile);
|
|
2594
|
-
|
|
2802
|
+
fs8.writeFileSync(lockfilePath, content);
|
|
2595
2803
|
}
|
|
2596
2804
|
function _getLockfilePath() {
|
|
2597
|
-
return
|
|
2805
|
+
return path9.join(process.cwd(), "i18n.lock");
|
|
2598
2806
|
}
|
|
2599
2807
|
}
|
|
2600
2808
|
var LockfileSchema = Z3.object({
|
|
@@ -2619,8 +2827,8 @@ import inquirer2 from "inquirer";
|
|
|
2619
2827
|
import externalEditor from "external-editor";
|
|
2620
2828
|
|
|
2621
2829
|
// src/cli/utils/cache.ts
|
|
2622
|
-
import
|
|
2623
|
-
import
|
|
2830
|
+
import path10 from "path";
|
|
2831
|
+
import fs9 from "fs";
|
|
2624
2832
|
var cacheChunk = (targetLocale, sourceChunk, processedChunk) => {
|
|
2625
2833
|
const rows = Object.entries(sourceChunk).map(([key, source]) => ({
|
|
2626
2834
|
targetLocale,
|
|
@@ -2650,26 +2858,26 @@ function getNormalizedCache() {
|
|
|
2650
2858
|
function deleteCache() {
|
|
2651
2859
|
const cacheFilePath = _getCacheFilePath();
|
|
2652
2860
|
try {
|
|
2653
|
-
|
|
2861
|
+
fs9.unlinkSync(cacheFilePath);
|
|
2654
2862
|
} catch (e) {
|
|
2655
2863
|
}
|
|
2656
2864
|
}
|
|
2657
2865
|
function _loadCache() {
|
|
2658
2866
|
const cacheFilePath = _getCacheFilePath();
|
|
2659
|
-
if (!
|
|
2867
|
+
if (!fs9.existsSync(cacheFilePath)) {
|
|
2660
2868
|
return [];
|
|
2661
2869
|
}
|
|
2662
|
-
const content =
|
|
2870
|
+
const content = fs9.readFileSync(cacheFilePath, "utf-8");
|
|
2663
2871
|
const result = _parseJSONLines(content);
|
|
2664
2872
|
return result;
|
|
2665
2873
|
}
|
|
2666
2874
|
function _appendToCache(rows) {
|
|
2667
2875
|
const cacheFilePath = _getCacheFilePath();
|
|
2668
2876
|
const lines = _buildJSONLines(rows);
|
|
2669
|
-
|
|
2877
|
+
fs9.appendFileSync(cacheFilePath, lines);
|
|
2670
2878
|
}
|
|
2671
2879
|
function _getCacheFilePath() {
|
|
2672
|
-
return
|
|
2880
|
+
return path10.join(process.cwd(), "i18n.cache");
|
|
2673
2881
|
}
|
|
2674
2882
|
function _buildJSONLines(rows) {
|
|
2675
2883
|
return rows.map((row) => JSON.stringify(row)).join("\n") + "\n";
|
|
@@ -2745,7 +2953,7 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
|
|
|
2745
2953
|
const bucketOra = Ora5({ indent: 4 });
|
|
2746
2954
|
bucketOra.info(`Processing path: ${bucketConfig.pathPattern}`);
|
|
2747
2955
|
const sourceLocale = resolveOverridenLocale3(i18nConfig.locale.source, bucketConfig.delimiter);
|
|
2748
|
-
const bucketLoader = createBucketLoader(bucket.type, bucketConfig.pathPattern);
|
|
2956
|
+
const bucketLoader = createBucketLoader(bucket.type, bucketConfig.pathPattern, { isCacheRestore: true });
|
|
2749
2957
|
bucketLoader.setDefaultLocale(sourceLocale);
|
|
2750
2958
|
await bucketLoader.init();
|
|
2751
2959
|
const sourceData = await bucketLoader.pull(sourceLocale);
|
|
@@ -2823,7 +3031,7 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
|
|
|
2823
3031
|
targetData
|
|
2824
3032
|
});
|
|
2825
3033
|
if (flags.key) {
|
|
2826
|
-
processableData =
|
|
3034
|
+
processableData = _19.pickBy(processableData, (_21, key) => key === flags.key);
|
|
2827
3035
|
}
|
|
2828
3036
|
if (flags.verbose) {
|
|
2829
3037
|
bucketOra.info(JSON.stringify(processableData, null, 2));
|
|
@@ -2859,7 +3067,7 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
|
|
|
2859
3067
|
if (flags.verbose) {
|
|
2860
3068
|
bucketOra.info(JSON.stringify(processedTargetData, null, 2));
|
|
2861
3069
|
}
|
|
2862
|
-
let finalTargetData =
|
|
3070
|
+
let finalTargetData = _19.merge({}, sourceData, targetData, processedTargetData);
|
|
2863
3071
|
if (flags.interactive) {
|
|
2864
3072
|
bucketOra.stop();
|
|
2865
3073
|
const reviewedData = await reviewChanges({
|
|
@@ -2873,7 +3081,7 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
|
|
|
2873
3081
|
finalTargetData = reviewedData;
|
|
2874
3082
|
bucketOra.start(`Applying changes to ${bucketConfig} (${targetLocale})`);
|
|
2875
3083
|
}
|
|
2876
|
-
const finalDiffSize =
|
|
3084
|
+
const finalDiffSize = _19.chain(finalTargetData).omitBy((value, key) => value === targetData[key]).size().value();
|
|
2877
3085
|
if (finalDiffSize > 0 || flags.force) {
|
|
2878
3086
|
await bucketLoader.push(targetLocale, finalTargetData);
|
|
2879
3087
|
bucketOra.succeed(`[${sourceLocale} -> ${targetLocale}] Localization completed`);
|
|
@@ -2918,9 +3126,9 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
|
|
|
2918
3126
|
}
|
|
2919
3127
|
});
|
|
2920
3128
|
function calculateDataDelta(args) {
|
|
2921
|
-
const newKeys =
|
|
3129
|
+
const newKeys = _19.difference(Object.keys(args.sourceData), Object.keys(args.targetData));
|
|
2922
3130
|
const updatedKeys = Object.keys(args.updatedSourceData);
|
|
2923
|
-
const result =
|
|
3131
|
+
const result = _19.chain(args.sourceData).pickBy((value, key) => newKeys.includes(key) || updatedKeys.includes(key)).value();
|
|
2924
3132
|
return result;
|
|
2925
3133
|
}
|
|
2926
3134
|
async function retryWithExponentialBackoff(operation, maxAttempts, baseDelay = 1e3) {
|
|
@@ -3061,7 +3269,7 @@ Reviewing changes for ${chalk.blue(args.pathPattern)} (${chalk.yellow(args.targe
|
|
|
3061
3269
|
return args.currentData;
|
|
3062
3270
|
}
|
|
3063
3271
|
const customData = { ...args.currentData };
|
|
3064
|
-
const changes =
|
|
3272
|
+
const changes = _19.reduce(
|
|
3065
3273
|
args.proposedData,
|
|
3066
3274
|
(result, value, key) => {
|
|
3067
3275
|
if (args.currentData[key] !== value) {
|
|
@@ -3142,7 +3350,7 @@ var flagsSchema = Z5.object({
|
|
|
3142
3350
|
// src/cli/cmd/cleanup.ts
|
|
3143
3351
|
import { resolveOverridenLocale as resolveOverridenLocale5 } from "@lingo.dev/_spec";
|
|
3144
3352
|
import { Command as Command8 } from "interactive-commander";
|
|
3145
|
-
import
|
|
3353
|
+
import _20 from "lodash";
|
|
3146
3354
|
import Ora7 from "ora";
|
|
3147
3355
|
var cleanup_default = new Command8().command("cleanup").description("Remove keys from target files that do not exist in the source file").helpOption("-h, --help", "Show help").option("--locale <locale>", "Specific locale to cleanup").option("--bucket <bucket>", "Specific bucket to cleanup").option("--dry-run", "Show what would be removed without making changes").option("--verbose", "Show verbose output").action(async function(options) {
|
|
3148
3356
|
const ora = Ora7();
|
|
@@ -3172,7 +3380,7 @@ var cleanup_default = new Command8().command("cleanup").description("Remove keys
|
|
|
3172
3380
|
try {
|
|
3173
3381
|
const targetData = await bucketLoader.pull(targetLocale);
|
|
3174
3382
|
const targetKeys = Object.keys(targetData);
|
|
3175
|
-
const keysToRemove =
|
|
3383
|
+
const keysToRemove = _20.difference(targetKeys, sourceKeys);
|
|
3176
3384
|
if (keysToRemove.length === 0) {
|
|
3177
3385
|
bucketOra.succeed(`[${targetLocale}] No keys to remove`);
|
|
3178
3386
|
continue;
|
|
@@ -3181,7 +3389,7 @@ var cleanup_default = new Command8().command("cleanup").description("Remove keys
|
|
|
3181
3389
|
bucketOra.info(`[${targetLocale}] Keys to remove: ${JSON.stringify(keysToRemove, null, 2)}`);
|
|
3182
3390
|
}
|
|
3183
3391
|
if (!options.dryRun) {
|
|
3184
|
-
const cleanedData =
|
|
3392
|
+
const cleanedData = _20.pick(targetData, sourceKeys);
|
|
3185
3393
|
await bucketLoader.push(targetLocale, cleanedData);
|
|
3186
3394
|
bucketOra.succeed(`[${targetLocale}] Removed ${keysToRemove.length} keys`);
|
|
3187
3395
|
} else {
|
|
@@ -3233,7 +3441,7 @@ function displaySummary(results) {
|
|
|
3233
3441
|
// package.json
|
|
3234
3442
|
var package_default = {
|
|
3235
3443
|
name: "lingo.dev",
|
|
3236
|
-
version: "0.74.
|
|
3444
|
+
version: "0.74.17",
|
|
3237
3445
|
description: "Lingo.dev CLI",
|
|
3238
3446
|
private: false,
|
|
3239
3447
|
publishConfig: {
|