@lang-tag/cli 0.16.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -14
- package/algorithms/collector/dictionary-collector.d.ts +2 -2
- package/algorithms/collector/index.d.ts +3 -3
- package/algorithms/collector/namespace-collector.d.ts +2 -2
- package/algorithms/collector/type.d.ts +2 -2
- package/algorithms/config-generation/config-keeper.d.ts +1 -1
- package/algorithms/config-generation/index.d.ts +3 -3
- package/algorithms/config-generation/path-based-config-generator.d.ts +1 -1
- package/algorithms/config-generation/prepend-namespace-to-path.d.ts +1 -1
- package/algorithms/import/flexible-import-algorithm.d.ts +1 -1
- package/algorithms/import/index.d.ts +2 -2
- package/algorithms/import/simple-mapping-import-algorithm.d.ts +1 -1
- package/algorithms/index.cjs +380 -27
- package/algorithms/index.d.ts +3 -3
- package/algorithms/index.js +361 -25
- package/chunks/namespace-collector.cjs +75 -0
- package/chunks/namespace-collector.js +76 -0
- package/index.cjs +1463 -862
- package/index.js +1425 -824
- package/logger.d.ts +1 -1
- package/package.json +5 -1
- package/templates/config/config.mustache +180 -0
- package/templates/config/generation-algorithm.mustache +73 -0
- package/{config.d.ts → type.d.ts} +3 -3
- package/flexible-import-algorithm-C-S1c742.js +0 -311
- package/flexible-import-algorithm-Fa-l4jWj.cjs +0 -327
- package/templates/config/init-config.mustache +0 -1
package/algorithms/index.js
CHANGED
|
@@ -1,7 +1,20 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { N, f } from "../flexible-import-algorithm-C-S1c742.js";
|
|
3
|
-
import path, { resolve, sep } from "pathe";
|
|
1
|
+
import * as caseLib from "case";
|
|
4
2
|
import process__default from "node:process";
|
|
3
|
+
import { rm, mkdir } from "fs/promises";
|
|
4
|
+
import path, { resolve, sep, join } from "pathe";
|
|
5
|
+
import { T as TranslationsCollector } from "../chunks/namespace-collector.js";
|
|
6
|
+
import { N } from "../chunks/namespace-collector.js";
|
|
7
|
+
import micromatch from "micromatch";
|
|
8
|
+
function applyCaseTransform(str, caseType) {
|
|
9
|
+
if (caseType === "no") {
|
|
10
|
+
return str;
|
|
11
|
+
}
|
|
12
|
+
const caseFunction = caseLib[caseType];
|
|
13
|
+
if (typeof caseFunction === "function") {
|
|
14
|
+
return caseFunction(str);
|
|
15
|
+
}
|
|
16
|
+
return str;
|
|
17
|
+
}
|
|
5
18
|
class DictionaryCollector extends TranslationsCollector {
|
|
6
19
|
constructor(options = {
|
|
7
20
|
appendNamespaceToPath: false
|
|
@@ -35,12 +48,15 @@ class DictionaryCollector extends TranslationsCollector {
|
|
|
35
48
|
}
|
|
36
49
|
async preWrite(clean) {
|
|
37
50
|
this.clean = clean;
|
|
38
|
-
const baseDictionaryFile = path.join(
|
|
51
|
+
const baseDictionaryFile = path.join(
|
|
52
|
+
this.config.localesDirectory,
|
|
53
|
+
`${this.config.baseLanguageCode}.json`
|
|
54
|
+
);
|
|
39
55
|
if (clean) {
|
|
40
56
|
this.logger.info("Removing {file}", { file: baseDictionaryFile });
|
|
41
|
-
await
|
|
57
|
+
await removeFile(baseDictionaryFile);
|
|
42
58
|
}
|
|
43
|
-
await
|
|
59
|
+
await ensureDirectoryExists(this.config.localesDirectory);
|
|
44
60
|
}
|
|
45
61
|
async resolveCollectionFilePath(baseLanguageCode) {
|
|
46
62
|
return resolve(
|
|
@@ -51,16 +67,23 @@ class DictionaryCollector extends TranslationsCollector {
|
|
|
51
67
|
}
|
|
52
68
|
async onMissingCollection(baseLanguageCode) {
|
|
53
69
|
if (!this.clean) {
|
|
54
|
-
this.logger.warn(
|
|
70
|
+
this.logger.warn(
|
|
71
|
+
`Original dictionary file "{namespace}.json" not found. A new one will be created.`,
|
|
72
|
+
{ namespace: baseLanguageCode }
|
|
73
|
+
);
|
|
55
74
|
}
|
|
56
75
|
}
|
|
57
76
|
async postWrite(changedCollections) {
|
|
58
77
|
if (!changedCollections?.length) {
|
|
59
|
-
this.logger.info(
|
|
78
|
+
this.logger.info(
|
|
79
|
+
"No changes were made based on the current configuration and files"
|
|
80
|
+
);
|
|
60
81
|
return;
|
|
61
82
|
}
|
|
62
83
|
if (changedCollections.length > 1) {
|
|
63
|
-
throw new Error(
|
|
84
|
+
throw new Error(
|
|
85
|
+
"Should not write more than 1 collection! Only 1 base language dictionary expected!"
|
|
86
|
+
);
|
|
64
87
|
}
|
|
65
88
|
const dict = resolve(
|
|
66
89
|
this.config.localesDirectory,
|
|
@@ -69,6 +92,21 @@ class DictionaryCollector extends TranslationsCollector {
|
|
|
69
92
|
this.logger.success("Updated dictionary {dict}", { dict });
|
|
70
93
|
}
|
|
71
94
|
}
|
|
95
|
+
async function ensureDirectoryExists(filePath) {
|
|
96
|
+
try {
|
|
97
|
+
await mkdir(filePath, { recursive: true });
|
|
98
|
+
} catch (error) {
|
|
99
|
+
if (error.code !== "EEXIST") {
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async function removeFile(filePath) {
|
|
105
|
+
try {
|
|
106
|
+
await rm(filePath, { force: true });
|
|
107
|
+
} catch (error) {
|
|
108
|
+
}
|
|
109
|
+
}
|
|
72
110
|
const TRIGGER_NAME$2 = "path-based-config-generator";
|
|
73
111
|
function pathBasedConfigGenerator(options = {}) {
|
|
74
112
|
const {
|
|
@@ -115,15 +153,22 @@ function pathBasedConfigGenerator(options = {}) {
|
|
|
115
153
|
if (hasPathRules) {
|
|
116
154
|
pathSegments = applyPathRules(pathSegments, pathRules);
|
|
117
155
|
} else {
|
|
118
|
-
pathSegments = applyStructuredIgnore(
|
|
156
|
+
pathSegments = applyStructuredIgnore(
|
|
157
|
+
pathSegments,
|
|
158
|
+
ignoreStructured
|
|
159
|
+
);
|
|
119
160
|
}
|
|
120
161
|
if (ignoreIncludesRootDirectories && langTagConfig.includes && pathSegments.length > 0) {
|
|
121
|
-
const extractedDirectories = extractRootDirectoriesFromIncludes(
|
|
162
|
+
const extractedDirectories = extractRootDirectoriesFromIncludes(
|
|
163
|
+
langTagConfig.includes
|
|
164
|
+
);
|
|
122
165
|
if (extractedDirectories.includes(pathSegments[0])) {
|
|
123
166
|
pathSegments = pathSegments.slice(1);
|
|
124
167
|
}
|
|
125
168
|
}
|
|
126
|
-
pathSegments = pathSegments.filter(
|
|
169
|
+
pathSegments = pathSegments.filter(
|
|
170
|
+
(seg) => !ignoreDirectories.includes(seg)
|
|
171
|
+
);
|
|
127
172
|
let namespace;
|
|
128
173
|
let path2;
|
|
129
174
|
if (pathSegments.length >= 1) {
|
|
@@ -146,7 +191,9 @@ function pathBasedConfigGenerator(options = {}) {
|
|
|
146
191
|
}
|
|
147
192
|
if (path2 && pathCase) {
|
|
148
193
|
const pathParts = path2.split(".");
|
|
149
|
-
const transformedParts = pathParts.map(
|
|
194
|
+
const transformedParts = pathParts.map(
|
|
195
|
+
(part) => applyCaseTransform(part, pathCase)
|
|
196
|
+
);
|
|
150
197
|
path2 = transformedParts.join(".");
|
|
151
198
|
}
|
|
152
199
|
const newConfig = event.config ? { ...event.config } : {};
|
|
@@ -305,7 +352,10 @@ function applyPathRules(segments, structure) {
|
|
|
305
352
|
const remainingSegments = segments.slice(i + 1);
|
|
306
353
|
const ruleWithoutRedirect = { ...rule };
|
|
307
354
|
delete ruleWithoutRedirect[">>"];
|
|
308
|
-
const processedRemaining = applyPathRules(
|
|
355
|
+
const processedRemaining = applyPathRules(
|
|
356
|
+
remainingSegments,
|
|
357
|
+
ruleWithoutRedirect
|
|
358
|
+
);
|
|
309
359
|
deepestRedirect = {
|
|
310
360
|
rule: redirectRule,
|
|
311
361
|
remainingSegments: processedRemaining,
|
|
@@ -348,7 +398,7 @@ function extractRootDirectoriesFromIncludes(includes) {
|
|
|
348
398
|
const firstSegment = match[1];
|
|
349
399
|
const groupMatch = firstSegment.match(/^[\(\[]([^\)\]]+)[\)\]]$/);
|
|
350
400
|
if (groupMatch) {
|
|
351
|
-
const groupDirectories = groupMatch[1].split("|").map((
|
|
401
|
+
const groupDirectories = groupMatch[1].split("|").map((f) => f.trim());
|
|
352
402
|
groupDirectories.forEach((directory) => directories.add(directory));
|
|
353
403
|
} else {
|
|
354
404
|
directories.add(firstSegment);
|
|
@@ -431,13 +481,291 @@ function prependNamespaceToPath(options = {}) {
|
|
|
431
481
|
} else {
|
|
432
482
|
newPath = actualNamespace;
|
|
433
483
|
}
|
|
434
|
-
event.save(
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
484
|
+
event.save(
|
|
485
|
+
{
|
|
486
|
+
...currentConfig || {},
|
|
487
|
+
path: newPath,
|
|
488
|
+
namespace: void 0
|
|
489
|
+
},
|
|
490
|
+
TRIGGER_NAME
|
|
491
|
+
);
|
|
439
492
|
};
|
|
440
493
|
}
|
|
494
|
+
function flexibleImportAlgorithm(options = {}) {
|
|
495
|
+
const {
|
|
496
|
+
variableName = {},
|
|
497
|
+
filePath = {},
|
|
498
|
+
include,
|
|
499
|
+
exclude = {},
|
|
500
|
+
configRemap
|
|
501
|
+
} = options;
|
|
502
|
+
const { packages: includePackages, namespaces: includeNamespaces } = include || {};
|
|
503
|
+
const {
|
|
504
|
+
packages: excludePackages = [],
|
|
505
|
+
namespaces: excludeNamespaces = []
|
|
506
|
+
} = exclude;
|
|
507
|
+
return (event) => {
|
|
508
|
+
const { exports, importManager, logger } = event;
|
|
509
|
+
for (const { packageJSON, exportData } of exports) {
|
|
510
|
+
const packageName = packageJSON.name || "unknown-package";
|
|
511
|
+
if (includePackages && !matchesAnyPattern(packageName, includePackages)) {
|
|
512
|
+
logger.debug(
|
|
513
|
+
`Skipping package not in include list: ${packageName}`
|
|
514
|
+
);
|
|
515
|
+
continue;
|
|
516
|
+
}
|
|
517
|
+
if (matchesAnyPattern(packageName, excludePackages)) {
|
|
518
|
+
logger.debug(`Skipping excluded package: ${packageName}`);
|
|
519
|
+
continue;
|
|
520
|
+
}
|
|
521
|
+
logger.debug(`Processing library: ${packageName}`);
|
|
522
|
+
for (const file of exportData.files) {
|
|
523
|
+
const originalFileName = file.relativeFilePath;
|
|
524
|
+
const targetFilePath = generateFilePath(
|
|
525
|
+
packageName,
|
|
526
|
+
originalFileName,
|
|
527
|
+
filePath
|
|
528
|
+
);
|
|
529
|
+
for (let i = 0; i < file.tags.length; i++) {
|
|
530
|
+
const tag = file.tags[i];
|
|
531
|
+
const tagNamespace = tag.config?.namespace;
|
|
532
|
+
if (includeNamespaces && tagNamespace && !matchesAnyPattern(tagNamespace, includeNamespaces)) {
|
|
533
|
+
logger.debug(
|
|
534
|
+
`Skipping namespace not in include list: ${tagNamespace}`
|
|
535
|
+
);
|
|
536
|
+
continue;
|
|
537
|
+
}
|
|
538
|
+
if (tagNamespace && matchesAnyPattern(tagNamespace, excludeNamespaces)) {
|
|
539
|
+
logger.debug(
|
|
540
|
+
`Skipping excluded namespace: ${tagNamespace}`
|
|
541
|
+
);
|
|
542
|
+
continue;
|
|
543
|
+
}
|
|
544
|
+
const finalVariableName = generateVariableName(
|
|
545
|
+
tag.variableName,
|
|
546
|
+
packageName,
|
|
547
|
+
originalFileName,
|
|
548
|
+
i,
|
|
549
|
+
variableName,
|
|
550
|
+
tag
|
|
551
|
+
);
|
|
552
|
+
if (finalVariableName === null) {
|
|
553
|
+
logger.debug(
|
|
554
|
+
`Skipping tag without variableName in ${join(packageName, originalFileName)}`
|
|
555
|
+
);
|
|
556
|
+
continue;
|
|
557
|
+
}
|
|
558
|
+
let finalConfig = tag.config;
|
|
559
|
+
if (configRemap) {
|
|
560
|
+
const remappedConfig = configRemap(tag.config, {
|
|
561
|
+
packageName,
|
|
562
|
+
fileName: originalFileName,
|
|
563
|
+
variableName: finalVariableName,
|
|
564
|
+
tagIndex: i
|
|
565
|
+
});
|
|
566
|
+
if (remappedConfig === null) {
|
|
567
|
+
logger.debug(
|
|
568
|
+
`Removing config due to configRemap returning null in ${join(packageName, originalFileName)}`
|
|
569
|
+
);
|
|
570
|
+
finalConfig = null;
|
|
571
|
+
} else {
|
|
572
|
+
finalConfig = remappedConfig;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
importManager.importTag(targetFilePath, {
|
|
576
|
+
variableName: finalVariableName,
|
|
577
|
+
translations: tag.translations,
|
|
578
|
+
config: finalConfig
|
|
579
|
+
});
|
|
580
|
+
logger.debug(
|
|
581
|
+
`Imported: ${finalVariableName} -> ${targetFilePath}`
|
|
582
|
+
);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
function sanitizeVariableName(name) {
|
|
589
|
+
let sanitized = name.replace(/[^a-zA-Z0-9_$]/g, "$");
|
|
590
|
+
if (/^[0-9]/.test(sanitized)) {
|
|
591
|
+
sanitized = "$" + sanitized;
|
|
592
|
+
}
|
|
593
|
+
if (sanitized === "") {
|
|
594
|
+
sanitized = "$";
|
|
595
|
+
}
|
|
596
|
+
return sanitized;
|
|
597
|
+
}
|
|
598
|
+
function applyCaseTransformToPath(filePath, caseType) {
|
|
599
|
+
if (typeof caseType === "string") {
|
|
600
|
+
const segments = filePath.split("/");
|
|
601
|
+
const fileName = segments[segments.length - 1];
|
|
602
|
+
const directorySegments = segments.slice(0, -1);
|
|
603
|
+
const transformedDirectories = directorySegments.map(
|
|
604
|
+
(dir) => applyCaseTransform(dir, caseType)
|
|
605
|
+
);
|
|
606
|
+
const transformedFileName = applyCaseTransformToFileName(
|
|
607
|
+
fileName,
|
|
608
|
+
caseType
|
|
609
|
+
);
|
|
610
|
+
if (transformedDirectories.length === 0) {
|
|
611
|
+
return transformedFileName;
|
|
612
|
+
}
|
|
613
|
+
return [...transformedDirectories, transformedFileName].join("/");
|
|
614
|
+
}
|
|
615
|
+
if (typeof caseType === "object") {
|
|
616
|
+
const { directories = "no", files = "no" } = caseType;
|
|
617
|
+
const segments = filePath.split("/");
|
|
618
|
+
const fileName = segments[segments.length - 1];
|
|
619
|
+
const directorySegments = segments.slice(0, -1);
|
|
620
|
+
const transformedDirectories = directorySegments.map(
|
|
621
|
+
(dir) => applyCaseTransform(dir, directories)
|
|
622
|
+
);
|
|
623
|
+
const transformedFileName = applyCaseTransformToFileName(
|
|
624
|
+
fileName,
|
|
625
|
+
files
|
|
626
|
+
);
|
|
627
|
+
if (transformedDirectories.length === 0) {
|
|
628
|
+
return transformedFileName;
|
|
629
|
+
}
|
|
630
|
+
return [...transformedDirectories, transformedFileName].join("/");
|
|
631
|
+
}
|
|
632
|
+
return filePath;
|
|
633
|
+
}
|
|
634
|
+
function normalizePackageName(packageName, scopedPackageHandling = "replace", context = "variableName") {
|
|
635
|
+
switch (scopedPackageHandling) {
|
|
636
|
+
case "remove-scope":
|
|
637
|
+
let result = packageName.replace(/^@[^/]+\//, "");
|
|
638
|
+
if (context === "variableName") {
|
|
639
|
+
result = result.replace(/[^a-zA-Z0-9_$]/g, "_");
|
|
640
|
+
}
|
|
641
|
+
return result;
|
|
642
|
+
case "replace":
|
|
643
|
+
default:
|
|
644
|
+
let normalized = packageName.replace(/@/g, "").replace(/\//g, context === "variableName" ? "_" : "-");
|
|
645
|
+
if (context === "variableName") {
|
|
646
|
+
normalized = normalized.replace(/[^a-zA-Z0-9_$]/g, "_");
|
|
647
|
+
}
|
|
648
|
+
return normalized;
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
function generateVariableName(originalVariableName, packageName, fileName, index, options, tag) {
|
|
652
|
+
const {
|
|
653
|
+
prefixWithPackageName = false,
|
|
654
|
+
scopedPackageHandling = "replace",
|
|
655
|
+
case: caseType = "no",
|
|
656
|
+
sanitizeVariableName: shouldSanitize = true,
|
|
657
|
+
handleMissingVariableName = "auto-generate",
|
|
658
|
+
customVariableName
|
|
659
|
+
} = options;
|
|
660
|
+
if (customVariableName) {
|
|
661
|
+
const customName = customVariableName({
|
|
662
|
+
packageName,
|
|
663
|
+
fileName,
|
|
664
|
+
originalVariableName,
|
|
665
|
+
tagIndex: index,
|
|
666
|
+
tag
|
|
667
|
+
});
|
|
668
|
+
if (customName !== null) {
|
|
669
|
+
originalVariableName = customName;
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
if (!originalVariableName) {
|
|
673
|
+
switch (handleMissingVariableName) {
|
|
674
|
+
case "skip":
|
|
675
|
+
return null;
|
|
676
|
+
case "auto-generate":
|
|
677
|
+
originalVariableName = `translations${index + 1}`;
|
|
678
|
+
break;
|
|
679
|
+
default:
|
|
680
|
+
if (typeof handleMissingVariableName === "function") {
|
|
681
|
+
originalVariableName = handleMissingVariableName(
|
|
682
|
+
{},
|
|
683
|
+
packageName,
|
|
684
|
+
fileName,
|
|
685
|
+
index
|
|
686
|
+
);
|
|
687
|
+
} else {
|
|
688
|
+
return null;
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
let finalName = originalVariableName;
|
|
693
|
+
if (prefixWithPackageName) {
|
|
694
|
+
const normalizedPackageName = normalizePackageName(
|
|
695
|
+
packageName,
|
|
696
|
+
scopedPackageHandling,
|
|
697
|
+
"variableName"
|
|
698
|
+
);
|
|
699
|
+
finalName = `${normalizedPackageName}_${originalVariableName}`;
|
|
700
|
+
}
|
|
701
|
+
const transformedName = applyCaseTransform(finalName, caseType);
|
|
702
|
+
return shouldSanitize ? sanitizeVariableName(transformedName) : transformedName;
|
|
703
|
+
}
|
|
704
|
+
function generateFilePath(packageName, originalFileName, options) {
|
|
705
|
+
const {
|
|
706
|
+
groupByPackage = false,
|
|
707
|
+
includePackageInPath = false,
|
|
708
|
+
scopedPackageHandling = "replace",
|
|
709
|
+
case: caseType = "no"
|
|
710
|
+
} = options;
|
|
711
|
+
if (groupByPackage) {
|
|
712
|
+
const normalizedPackageName = normalizePackageName(
|
|
713
|
+
packageName,
|
|
714
|
+
scopedPackageHandling,
|
|
715
|
+
"filePath"
|
|
716
|
+
);
|
|
717
|
+
const fileName = `${normalizedPackageName}.ts`;
|
|
718
|
+
return applyCaseTransformToFileName(
|
|
719
|
+
fileName,
|
|
720
|
+
typeof caseType === "string" ? caseType : caseType.files || "no"
|
|
721
|
+
);
|
|
722
|
+
} else if (includePackageInPath) {
|
|
723
|
+
const normalizedPackageName = normalizePackageName(
|
|
724
|
+
packageName,
|
|
725
|
+
scopedPackageHandling,
|
|
726
|
+
"filePath"
|
|
727
|
+
);
|
|
728
|
+
if (typeof caseType === "string") {
|
|
729
|
+
const transformedPackageName = applyCaseTransform(
|
|
730
|
+
normalizedPackageName,
|
|
731
|
+
caseType
|
|
732
|
+
);
|
|
733
|
+
const transformedFilePath = applyCaseTransformToPath(
|
|
734
|
+
originalFileName,
|
|
735
|
+
caseType
|
|
736
|
+
);
|
|
737
|
+
return join(transformedPackageName, transformedFilePath);
|
|
738
|
+
} else {
|
|
739
|
+
const transformedPackageName = applyCaseTransform(
|
|
740
|
+
normalizedPackageName,
|
|
741
|
+
caseType.directories || "no"
|
|
742
|
+
);
|
|
743
|
+
const transformedFilePath = applyCaseTransformToPath(
|
|
744
|
+
originalFileName,
|
|
745
|
+
caseType
|
|
746
|
+
);
|
|
747
|
+
return join(transformedPackageName, transformedFilePath);
|
|
748
|
+
}
|
|
749
|
+
} else {
|
|
750
|
+
return applyCaseTransformToPath(originalFileName, caseType);
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
function applyCaseTransformToFileName(fileName, caseType) {
|
|
754
|
+
if (caseType === "no") {
|
|
755
|
+
return fileName;
|
|
756
|
+
}
|
|
757
|
+
const lastDotIndex = fileName.lastIndexOf(".");
|
|
758
|
+
if (lastDotIndex === -1) {
|
|
759
|
+
return applyCaseTransform(fileName, caseType);
|
|
760
|
+
}
|
|
761
|
+
const nameWithoutExt = fileName.substring(0, lastDotIndex);
|
|
762
|
+
const extension = fileName.substring(lastDotIndex);
|
|
763
|
+
const transformedName = applyCaseTransform(nameWithoutExt, caseType);
|
|
764
|
+
return transformedName + extension;
|
|
765
|
+
}
|
|
766
|
+
function matchesAnyPattern(str, patterns) {
|
|
767
|
+
return micromatch.isMatch(str, patterns);
|
|
768
|
+
}
|
|
441
769
|
function simpleMappingImportAlgorithm(options) {
|
|
442
770
|
const { mappings, configRemap } = options;
|
|
443
771
|
const packageMap = /* @__PURE__ */ new Map();
|
|
@@ -466,14 +794,20 @@ function simpleMappingImportAlgorithm(options) {
|
|
|
466
794
|
if (!packageFiles) continue;
|
|
467
795
|
const fileMapping = packageFiles.get(sourceFile);
|
|
468
796
|
if (!fileMapping) {
|
|
469
|
-
logger.debug(
|
|
797
|
+
logger.debug(
|
|
798
|
+
`Skipping unmapped file: ${packageName}/${sourceFile}`
|
|
799
|
+
);
|
|
470
800
|
continue;
|
|
471
801
|
}
|
|
472
|
-
logger.debug(
|
|
802
|
+
logger.debug(
|
|
803
|
+
`Processing mapped file: ${packageName}/${sourceFile} -> ${fileMapping.targetFile}`
|
|
804
|
+
);
|
|
473
805
|
for (const tag of file.tags) {
|
|
474
806
|
const originalVariableName = tag.variableName;
|
|
475
807
|
if (!originalVariableName || !(originalVariableName in fileMapping.variables)) {
|
|
476
|
-
logger.debug(
|
|
808
|
+
logger.debug(
|
|
809
|
+
`Skipping unmapped variable: ${originalVariableName} in ${packageName}/${sourceFile}`
|
|
810
|
+
);
|
|
477
811
|
continue;
|
|
478
812
|
}
|
|
479
813
|
const newVariableName = fileMapping.variables[originalVariableName] || originalVariableName;
|
|
@@ -493,7 +827,9 @@ function simpleMappingImportAlgorithm(options) {
|
|
|
493
827
|
translations: tag.translations,
|
|
494
828
|
config: finalConfig
|
|
495
829
|
});
|
|
496
|
-
logger.debug(
|
|
830
|
+
logger.debug(
|
|
831
|
+
`Imported: ${originalVariableName} -> ${newVariableName} in ${targetFilePath}`
|
|
832
|
+
);
|
|
497
833
|
}
|
|
498
834
|
}
|
|
499
835
|
}
|
|
@@ -504,7 +840,7 @@ export {
|
|
|
504
840
|
N as NamespaceCollector,
|
|
505
841
|
applyCaseTransform,
|
|
506
842
|
configKeeper,
|
|
507
|
-
|
|
843
|
+
flexibleImportAlgorithm,
|
|
508
844
|
pathBasedConfigGenerator,
|
|
509
845
|
prependNamespaceToPath,
|
|
510
846
|
simpleMappingImportAlgorithm
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const process = require("node:process");
|
|
3
|
+
const promises = require("fs/promises");
|
|
4
|
+
const path = require("pathe");
|
|
5
|
+
class TranslationsCollector {
|
|
6
|
+
config;
|
|
7
|
+
logger;
|
|
8
|
+
}
|
|
9
|
+
class NamespaceCollector extends TranslationsCollector {
|
|
10
|
+
clean;
|
|
11
|
+
languageDirectory;
|
|
12
|
+
aggregateCollection(namespace) {
|
|
13
|
+
return namespace;
|
|
14
|
+
}
|
|
15
|
+
transformTag(tag) {
|
|
16
|
+
return tag;
|
|
17
|
+
}
|
|
18
|
+
async preWrite(clean) {
|
|
19
|
+
this.clean = clean;
|
|
20
|
+
this.languageDirectory = path.join(
|
|
21
|
+
this.config.localesDirectory,
|
|
22
|
+
this.config.baseLanguageCode
|
|
23
|
+
);
|
|
24
|
+
if (clean) {
|
|
25
|
+
this.logger.info("Cleaning output directory...");
|
|
26
|
+
await removeDirectory(this.languageDirectory);
|
|
27
|
+
}
|
|
28
|
+
await ensureDirectoryExists(this.languageDirectory);
|
|
29
|
+
}
|
|
30
|
+
async resolveCollectionFilePath(collectionName) {
|
|
31
|
+
return path.resolve(
|
|
32
|
+
process.cwd(),
|
|
33
|
+
this.languageDirectory,
|
|
34
|
+
collectionName + ".json"
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
async onMissingCollection(collectionName) {
|
|
38
|
+
if (!this.clean) {
|
|
39
|
+
this.logger.warn(
|
|
40
|
+
`Original namespace file "{namespace}.json" not found. A new one will be created.`,
|
|
41
|
+
{ namespace: collectionName }
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async postWrite(changedCollections) {
|
|
46
|
+
if (!changedCollections?.length) {
|
|
47
|
+
this.logger.info(
|
|
48
|
+
"No changes were made based on the current configuration and files"
|
|
49
|
+
);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const n = changedCollections.map((n2) => `"${n2}.json"`).join(", ");
|
|
53
|
+
this.logger.success("Updated namespaces {outputDir} ({namespaces})", {
|
|
54
|
+
outputDir: this.config.localesDirectory,
|
|
55
|
+
namespaces: n
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async function ensureDirectoryExists(filePath) {
|
|
60
|
+
try {
|
|
61
|
+
await promises.mkdir(filePath, { recursive: true });
|
|
62
|
+
} catch (error) {
|
|
63
|
+
if (error.code !== "EEXIST") {
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async function removeDirectory(dirPath) {
|
|
69
|
+
try {
|
|
70
|
+
await promises.rm(dirPath, { recursive: true, force: true });
|
|
71
|
+
} catch (error) {
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
exports.NamespaceCollector = NamespaceCollector;
|
|
75
|
+
exports.TranslationsCollector = TranslationsCollector;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import process__default from "node:process";
|
|
2
|
+
import { rm, mkdir } from "fs/promises";
|
|
3
|
+
import path, { resolve } from "pathe";
|
|
4
|
+
class TranslationsCollector {
|
|
5
|
+
config;
|
|
6
|
+
logger;
|
|
7
|
+
}
|
|
8
|
+
class NamespaceCollector extends TranslationsCollector {
|
|
9
|
+
clean;
|
|
10
|
+
languageDirectory;
|
|
11
|
+
aggregateCollection(namespace) {
|
|
12
|
+
return namespace;
|
|
13
|
+
}
|
|
14
|
+
transformTag(tag) {
|
|
15
|
+
return tag;
|
|
16
|
+
}
|
|
17
|
+
async preWrite(clean) {
|
|
18
|
+
this.clean = clean;
|
|
19
|
+
this.languageDirectory = path.join(
|
|
20
|
+
this.config.localesDirectory,
|
|
21
|
+
this.config.baseLanguageCode
|
|
22
|
+
);
|
|
23
|
+
if (clean) {
|
|
24
|
+
this.logger.info("Cleaning output directory...");
|
|
25
|
+
await removeDirectory(this.languageDirectory);
|
|
26
|
+
}
|
|
27
|
+
await ensureDirectoryExists(this.languageDirectory);
|
|
28
|
+
}
|
|
29
|
+
async resolveCollectionFilePath(collectionName) {
|
|
30
|
+
return resolve(
|
|
31
|
+
process__default.cwd(),
|
|
32
|
+
this.languageDirectory,
|
|
33
|
+
collectionName + ".json"
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
async onMissingCollection(collectionName) {
|
|
37
|
+
if (!this.clean) {
|
|
38
|
+
this.logger.warn(
|
|
39
|
+
`Original namespace file "{namespace}.json" not found. A new one will be created.`,
|
|
40
|
+
{ namespace: collectionName }
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
async postWrite(changedCollections) {
|
|
45
|
+
if (!changedCollections?.length) {
|
|
46
|
+
this.logger.info(
|
|
47
|
+
"No changes were made based on the current configuration and files"
|
|
48
|
+
);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const n = changedCollections.map((n2) => `"${n2}.json"`).join(", ");
|
|
52
|
+
this.logger.success("Updated namespaces {outputDir} ({namespaces})", {
|
|
53
|
+
outputDir: this.config.localesDirectory,
|
|
54
|
+
namespaces: n
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async function ensureDirectoryExists(filePath) {
|
|
59
|
+
try {
|
|
60
|
+
await mkdir(filePath, { recursive: true });
|
|
61
|
+
} catch (error) {
|
|
62
|
+
if (error.code !== "EEXIST") {
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
async function removeDirectory(dirPath) {
|
|
68
|
+
try {
|
|
69
|
+
await rm(dirPath, { recursive: true, force: true });
|
|
70
|
+
} catch (error) {
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
export {
|
|
74
|
+
NamespaceCollector as N,
|
|
75
|
+
TranslationsCollector as T
|
|
76
|
+
};
|