@lang-tag/cli 0.15.0 → 0.17.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/case-utils.d.ts +12 -0
- 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 +4 -3
- package/algorithms/config-generation/prepend-namespace-to-path.d.ts +1 -1
- package/algorithms/import/flexible-import-algorithm.d.ts +232 -0
- package/algorithms/import/index.d.ts +2 -1
- package/algorithms/import/simple-mapping-import-algorithm.d.ts +120 -0
- package/algorithms/index.cjs +418 -26
- package/algorithms/index.d.ts +6 -3
- package/algorithms/index.js +420 -28
- package/chunks/namespace-collector.cjs +75 -0
- package/chunks/namespace-collector.js +76 -0
- package/index.cjs +1156 -743
- package/index.js +1316 -903
- package/logger.d.ts +1 -1
- package/package.json +1 -1
- package/templates/config/init-config.mustache +1 -0
- package/templates/import/imported-tag.mustache +14 -0
- package/{config.d.ts → type.d.ts} +41 -32
- package/namespace-collector-DCruv_PK.js +0 -95
- package/namespace-collector-DRnZvkDR.cjs +0 -94
- /package/{template → templates/tag}/base-app.mustache +0 -0
- /package/{template → templates/tag}/base-library.mustache +0 -0
- /package/{template → templates/tag}/placeholder.mustache +0 -0
package/algorithms/index.js
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
|
-
import { T as TranslationsCollector, e as $LT_RemoveFile, c as $LT_EnsureDirectoryExists } from "../namespace-collector-DCruv_PK.js";
|
|
2
|
-
import { N } from "../namespace-collector-DCruv_PK.js";
|
|
3
|
-
import path, { resolve, sep } from "pathe";
|
|
4
|
-
import process__default from "node:process";
|
|
5
1
|
import * as caseLib from "case";
|
|
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
|
+
}
|
|
6
18
|
class DictionaryCollector extends TranslationsCollector {
|
|
7
19
|
constructor(options = {
|
|
8
20
|
appendNamespaceToPath: false
|
|
@@ -36,12 +48,15 @@ class DictionaryCollector extends TranslationsCollector {
|
|
|
36
48
|
}
|
|
37
49
|
async preWrite(clean) {
|
|
38
50
|
this.clean = clean;
|
|
39
|
-
const baseDictionaryFile = path.join(
|
|
51
|
+
const baseDictionaryFile = path.join(
|
|
52
|
+
this.config.localesDirectory,
|
|
53
|
+
`${this.config.baseLanguageCode}.json`
|
|
54
|
+
);
|
|
40
55
|
if (clean) {
|
|
41
56
|
this.logger.info("Removing {file}", { file: baseDictionaryFile });
|
|
42
|
-
await
|
|
57
|
+
await removeFile(baseDictionaryFile);
|
|
43
58
|
}
|
|
44
|
-
await
|
|
59
|
+
await ensureDirectoryExists(this.config.localesDirectory);
|
|
45
60
|
}
|
|
46
61
|
async resolveCollectionFilePath(baseLanguageCode) {
|
|
47
62
|
return resolve(
|
|
@@ -52,16 +67,23 @@ class DictionaryCollector extends TranslationsCollector {
|
|
|
52
67
|
}
|
|
53
68
|
async onMissingCollection(baseLanguageCode) {
|
|
54
69
|
if (!this.clean) {
|
|
55
|
-
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
|
+
);
|
|
56
74
|
}
|
|
57
75
|
}
|
|
58
76
|
async postWrite(changedCollections) {
|
|
59
77
|
if (!changedCollections?.length) {
|
|
60
|
-
this.logger.info(
|
|
78
|
+
this.logger.info(
|
|
79
|
+
"No changes were made based on the current configuration and files"
|
|
80
|
+
);
|
|
61
81
|
return;
|
|
62
82
|
}
|
|
63
83
|
if (changedCollections.length > 1) {
|
|
64
|
-
throw new Error(
|
|
84
|
+
throw new Error(
|
|
85
|
+
"Should not write more than 1 collection! Only 1 base language dictionary expected!"
|
|
86
|
+
);
|
|
65
87
|
}
|
|
66
88
|
const dict = resolve(
|
|
67
89
|
this.config.localesDirectory,
|
|
@@ -70,6 +92,21 @@ class DictionaryCollector extends TranslationsCollector {
|
|
|
70
92
|
this.logger.success("Updated dictionary {dict}", { dict });
|
|
71
93
|
}
|
|
72
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
|
+
}
|
|
73
110
|
const TRIGGER_NAME$2 = "path-based-config-generator";
|
|
74
111
|
function pathBasedConfigGenerator(options = {}) {
|
|
75
112
|
const {
|
|
@@ -116,15 +153,22 @@ function pathBasedConfigGenerator(options = {}) {
|
|
|
116
153
|
if (hasPathRules) {
|
|
117
154
|
pathSegments = applyPathRules(pathSegments, pathRules);
|
|
118
155
|
} else {
|
|
119
|
-
pathSegments = applyStructuredIgnore(
|
|
156
|
+
pathSegments = applyStructuredIgnore(
|
|
157
|
+
pathSegments,
|
|
158
|
+
ignoreStructured
|
|
159
|
+
);
|
|
120
160
|
}
|
|
121
161
|
if (ignoreIncludesRootDirectories && langTagConfig.includes && pathSegments.length > 0) {
|
|
122
|
-
const extractedDirectories = extractRootDirectoriesFromIncludes(
|
|
162
|
+
const extractedDirectories = extractRootDirectoriesFromIncludes(
|
|
163
|
+
langTagConfig.includes
|
|
164
|
+
);
|
|
123
165
|
if (extractedDirectories.includes(pathSegments[0])) {
|
|
124
166
|
pathSegments = pathSegments.slice(1);
|
|
125
167
|
}
|
|
126
168
|
}
|
|
127
|
-
pathSegments = pathSegments.filter(
|
|
169
|
+
pathSegments = pathSegments.filter(
|
|
170
|
+
(seg) => !ignoreDirectories.includes(seg)
|
|
171
|
+
);
|
|
128
172
|
let namespace;
|
|
129
173
|
let path2;
|
|
130
174
|
if (pathSegments.length >= 1) {
|
|
@@ -147,7 +191,9 @@ function pathBasedConfigGenerator(options = {}) {
|
|
|
147
191
|
}
|
|
148
192
|
if (path2 && pathCase) {
|
|
149
193
|
const pathParts = path2.split(".");
|
|
150
|
-
const transformedParts = pathParts.map(
|
|
194
|
+
const transformedParts = pathParts.map(
|
|
195
|
+
(part) => applyCaseTransform(part, pathCase)
|
|
196
|
+
);
|
|
151
197
|
path2 = transformedParts.join(".");
|
|
152
198
|
}
|
|
153
199
|
const newConfig = event.config ? { ...event.config } : {};
|
|
@@ -306,7 +352,10 @@ function applyPathRules(segments, structure) {
|
|
|
306
352
|
const remainingSegments = segments.slice(i + 1);
|
|
307
353
|
const ruleWithoutRedirect = { ...rule };
|
|
308
354
|
delete ruleWithoutRedirect[">>"];
|
|
309
|
-
const processedRemaining = applyPathRules(
|
|
355
|
+
const processedRemaining = applyPathRules(
|
|
356
|
+
remainingSegments,
|
|
357
|
+
ruleWithoutRedirect
|
|
358
|
+
);
|
|
310
359
|
deepestRedirect = {
|
|
311
360
|
rule: redirectRule,
|
|
312
361
|
remainingSegments: processedRemaining,
|
|
@@ -340,13 +389,6 @@ function applyPathRules(segments, structure) {
|
|
|
340
389
|
}
|
|
341
390
|
return result;
|
|
342
391
|
}
|
|
343
|
-
function applyCaseTransform(str, caseType) {
|
|
344
|
-
const caseFunction = caseLib[caseType];
|
|
345
|
-
if (typeof caseFunction === "function") {
|
|
346
|
-
return caseFunction(str);
|
|
347
|
-
}
|
|
348
|
-
return str;
|
|
349
|
-
}
|
|
350
392
|
function extractRootDirectoriesFromIncludes(includes) {
|
|
351
393
|
const directories = /* @__PURE__ */ new Set();
|
|
352
394
|
for (const pattern of includes) {
|
|
@@ -439,17 +481,367 @@ function prependNamespaceToPath(options = {}) {
|
|
|
439
481
|
} else {
|
|
440
482
|
newPath = actualNamespace;
|
|
441
483
|
}
|
|
442
|
-
event.save(
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
484
|
+
event.save(
|
|
485
|
+
{
|
|
486
|
+
...currentConfig || {},
|
|
487
|
+
path: newPath,
|
|
488
|
+
namespace: void 0
|
|
489
|
+
},
|
|
490
|
+
TRIGGER_NAME
|
|
491
|
+
);
|
|
492
|
+
};
|
|
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
|
+
}
|
|
769
|
+
function simpleMappingImportAlgorithm(options) {
|
|
770
|
+
const { mappings, configRemap } = options;
|
|
771
|
+
const packageMap = /* @__PURE__ */ new Map();
|
|
772
|
+
const fileMap = /* @__PURE__ */ new Map();
|
|
773
|
+
for (const mapping of mappings) {
|
|
774
|
+
packageMap.set(mapping.packageName, mapping);
|
|
775
|
+
const files = /* @__PURE__ */ new Map();
|
|
776
|
+
for (const file of mapping.files) {
|
|
777
|
+
files.set(file.sourceFile, file);
|
|
778
|
+
}
|
|
779
|
+
fileMap.set(mapping.packageName, files);
|
|
780
|
+
}
|
|
781
|
+
return (event) => {
|
|
782
|
+
const { exports, importManager, logger } = event;
|
|
783
|
+
for (const { packageJSON, exportData } of exports) {
|
|
784
|
+
const packageName = packageJSON.name || "unknown-package";
|
|
785
|
+
const packageMapping = packageMap.get(packageName);
|
|
786
|
+
if (!packageMapping) {
|
|
787
|
+
logger.debug(`Skipping unmapped package: ${packageName}`);
|
|
788
|
+
continue;
|
|
789
|
+
}
|
|
790
|
+
logger.debug(`Processing mapped package: ${packageName}`);
|
|
791
|
+
for (const file of exportData.files) {
|
|
792
|
+
const sourceFile = file.relativeFilePath;
|
|
793
|
+
const packageFiles = fileMap.get(packageName);
|
|
794
|
+
if (!packageFiles) continue;
|
|
795
|
+
const fileMapping = packageFiles.get(sourceFile);
|
|
796
|
+
if (!fileMapping) {
|
|
797
|
+
logger.debug(
|
|
798
|
+
`Skipping unmapped file: ${packageName}/${sourceFile}`
|
|
799
|
+
);
|
|
800
|
+
continue;
|
|
801
|
+
}
|
|
802
|
+
logger.debug(
|
|
803
|
+
`Processing mapped file: ${packageName}/${sourceFile} -> ${fileMapping.targetFile}`
|
|
804
|
+
);
|
|
805
|
+
for (const tag of file.tags) {
|
|
806
|
+
const originalVariableName = tag.variableName;
|
|
807
|
+
if (!originalVariableName || !(originalVariableName in fileMapping.variables)) {
|
|
808
|
+
logger.debug(
|
|
809
|
+
`Skipping unmapped variable: ${originalVariableName} in ${packageName}/${sourceFile}`
|
|
810
|
+
);
|
|
811
|
+
continue;
|
|
812
|
+
}
|
|
813
|
+
const newVariableName = fileMapping.variables[originalVariableName] || originalVariableName;
|
|
814
|
+
const targetFilePath = fileMapping.targetFile;
|
|
815
|
+
let finalConfig = tag.config;
|
|
816
|
+
if (configRemap) {
|
|
817
|
+
finalConfig = configRemap(tag.config, {
|
|
818
|
+
packageName,
|
|
819
|
+
sourceFile,
|
|
820
|
+
targetFile: targetFilePath,
|
|
821
|
+
variableName: newVariableName,
|
|
822
|
+
originalVariableName
|
|
823
|
+
});
|
|
824
|
+
}
|
|
825
|
+
importManager.importTag(targetFilePath, {
|
|
826
|
+
variableName: newVariableName,
|
|
827
|
+
translations: tag.translations,
|
|
828
|
+
config: finalConfig
|
|
829
|
+
});
|
|
830
|
+
logger.debug(
|
|
831
|
+
`Imported: ${originalVariableName} -> ${newVariableName} in ${targetFilePath}`
|
|
832
|
+
);
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
}
|
|
447
836
|
};
|
|
448
837
|
}
|
|
449
838
|
export {
|
|
450
839
|
DictionaryCollector,
|
|
451
840
|
N as NamespaceCollector,
|
|
841
|
+
applyCaseTransform,
|
|
452
842
|
configKeeper,
|
|
843
|
+
flexibleImportAlgorithm,
|
|
453
844
|
pathBasedConfigGenerator,
|
|
454
|
-
prependNamespaceToPath
|
|
845
|
+
prependNamespaceToPath,
|
|
846
|
+
simpleMappingImportAlgorithm
|
|
455
847
|
};
|
|
@@ -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
|
+
};
|