@lang-tag/cli 0.18.1 → 0.19.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/algorithms/index.cjs +1 -1
- package/algorithms/index.js +1 -1
- package/index.cjs +76 -14
- package/index.js +76 -14
- package/package.json +1 -1
- package/type.d.ts +2 -0
package/algorithms/index.cjs
CHANGED
|
@@ -35,7 +35,7 @@ function applyCaseTransform(str, caseType) {
|
|
|
35
35
|
}
|
|
36
36
|
class DictionaryCollector extends namespaceCollector.TranslationsCollector {
|
|
37
37
|
constructor(options = {
|
|
38
|
-
appendNamespaceToPath:
|
|
38
|
+
appendNamespaceToPath: true
|
|
39
39
|
}) {
|
|
40
40
|
super();
|
|
41
41
|
this.options = options;
|
package/algorithms/index.js
CHANGED
package/index.cjs
CHANGED
|
@@ -102,22 +102,83 @@ class $LT_TagProcessor {
|
|
|
102
102
|
const matches = [];
|
|
103
103
|
let currentIndex = 0;
|
|
104
104
|
const skipRanges = this.buildSkipRanges(fileContent);
|
|
105
|
-
const
|
|
106
|
-
`${optionalVariableAssignment}${tagName}
|
|
105
|
+
const tagNamePattern = new RegExp(
|
|
106
|
+
`${optionalVariableAssignment}${tagName}`,
|
|
107
107
|
"g"
|
|
108
108
|
);
|
|
109
109
|
while (true) {
|
|
110
|
-
|
|
111
|
-
const
|
|
112
|
-
if (!
|
|
113
|
-
const
|
|
114
|
-
const variableName =
|
|
110
|
+
tagNamePattern.lastIndex = currentIndex;
|
|
111
|
+
const tagNameMatch = tagNamePattern.exec(fileContent);
|
|
112
|
+
if (!tagNameMatch) break;
|
|
113
|
+
const tagNameStartIndex = tagNameMatch.index;
|
|
114
|
+
const variableName = tagNameMatch[1] || void 0;
|
|
115
|
+
if (this.isInSkipRange(tagNameStartIndex, skipRanges)) {
|
|
116
|
+
currentIndex = tagNameStartIndex + 1;
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
let i = tagNameStartIndex + tagNameMatch[0].length;
|
|
120
|
+
let genericType = void 0;
|
|
121
|
+
let matchStartIndex = tagNameStartIndex;
|
|
122
|
+
while (i < fileContent.length && /\s/.test(fileContent[i])) {
|
|
123
|
+
i++;
|
|
124
|
+
}
|
|
125
|
+
if (i < fileContent.length && fileContent[i] === "<") {
|
|
126
|
+
const genericStart = i;
|
|
127
|
+
let angleCount = 1;
|
|
128
|
+
i++;
|
|
129
|
+
while (i < fileContent.length && angleCount > 0) {
|
|
130
|
+
const char = fileContent[i];
|
|
131
|
+
if (char === "<") angleCount++;
|
|
132
|
+
else if (char === ">") angleCount--;
|
|
133
|
+
else if ((char === '"' || char === "'" || char === "`") && !this.isInSkipRange(i, skipRanges)) {
|
|
134
|
+
i++;
|
|
135
|
+
while (i < fileContent.length) {
|
|
136
|
+
if (fileContent[i] === "\\") {
|
|
137
|
+
i += 2;
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
if (fileContent[i] === char) {
|
|
141
|
+
i++;
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
i++;
|
|
145
|
+
}
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
i++;
|
|
149
|
+
}
|
|
150
|
+
if (angleCount === 0) {
|
|
151
|
+
genericType = fileContent.substring(genericStart + 1, i - 1).trim();
|
|
152
|
+
matchStartIndex = tagNameStartIndex;
|
|
153
|
+
} else {
|
|
154
|
+
currentIndex = tagNameStartIndex + 1;
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
} else {
|
|
158
|
+
matchStartIndex = tagNameStartIndex;
|
|
159
|
+
}
|
|
160
|
+
while (i < fileContent.length && /\s/.test(fileContent[i])) {
|
|
161
|
+
i++;
|
|
162
|
+
}
|
|
163
|
+
if (i >= fileContent.length || fileContent[i] !== "(" || i + 1 >= fileContent.length) {
|
|
164
|
+
currentIndex = tagNameStartIndex + 1;
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
i++;
|
|
168
|
+
while (i < fileContent.length && /\s/.test(fileContent[i])) {
|
|
169
|
+
i++;
|
|
170
|
+
}
|
|
171
|
+
if (i >= fileContent.length || fileContent[i] !== "{") {
|
|
172
|
+
currentIndex = tagNameStartIndex + 1;
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
const braceStartIndex = i;
|
|
115
176
|
if (this.isInSkipRange(matchStartIndex, skipRanges)) {
|
|
116
177
|
currentIndex = matchStartIndex + 1;
|
|
117
178
|
continue;
|
|
118
179
|
}
|
|
119
180
|
let braceCount = 1;
|
|
120
|
-
|
|
181
|
+
i++;
|
|
121
182
|
while (i < fileContent.length && braceCount > 0) {
|
|
122
183
|
if (fileContent[i] === "{") braceCount++;
|
|
123
184
|
if (fileContent[i] === "}") braceCount--;
|
|
@@ -127,10 +188,7 @@ class $LT_TagProcessor {
|
|
|
127
188
|
currentIndex = matchStartIndex + 1;
|
|
128
189
|
continue;
|
|
129
190
|
}
|
|
130
|
-
let parameter1Text = fileContent.substring(
|
|
131
|
-
matchStartIndex + startMatch[0].length - 1,
|
|
132
|
-
i
|
|
133
|
-
);
|
|
191
|
+
let parameter1Text = fileContent.substring(braceStartIndex, i);
|
|
134
192
|
let parameter2Text;
|
|
135
193
|
while (i < fileContent.length && (fileContent[i] === " " || fileContent[i] === "\n" || fileContent[i] === " ")) {
|
|
136
194
|
i++;
|
|
@@ -225,6 +283,7 @@ class $LT_TagProcessor {
|
|
|
225
283
|
matches.push({
|
|
226
284
|
fullMatch,
|
|
227
285
|
variableName,
|
|
286
|
+
genericType,
|
|
228
287
|
parameter1Text,
|
|
229
288
|
parameter2Text,
|
|
230
289
|
parameterTranslations,
|
|
@@ -278,7 +337,8 @@ class $LT_TagProcessor {
|
|
|
278
337
|
}
|
|
279
338
|
const arg1 = this.config.translationArgPosition === 1 ? newTranslationsString : newConfigString;
|
|
280
339
|
const arg2 = this.config.translationArgPosition === 1 ? newConfigString : newTranslationsString;
|
|
281
|
-
|
|
340
|
+
const genericTypePart = tag.genericType ? `<${tag.genericType}>` : "";
|
|
341
|
+
let tagFunction = `${this.config.tagName}${genericTypePart}(${arg1}`;
|
|
282
342
|
if (arg2) tagFunction += `, ${arg2}`;
|
|
283
343
|
tagFunction += ")";
|
|
284
344
|
if (tag.variableName)
|
|
@@ -1581,9 +1641,11 @@ async function generateImportFiles(config, logger, importManager) {
|
|
|
1581
1641
|
const content = renderTemplate$2(templateData);
|
|
1582
1642
|
await $LT_EnsureDirectoryExists(path.dirname(filePath));
|
|
1583
1643
|
await promises.writeFile(filePath, content, "utf-8");
|
|
1644
|
+
const encodedFilePath = encodeURI(filePath);
|
|
1584
1645
|
logger.success('Created tag file: "{file}"', {
|
|
1585
1646
|
file: importedFile.pathRelativeToImportDir
|
|
1586
1647
|
});
|
|
1648
|
+
logger.debug(" └── link: file://{path}", { path: encodedFilePath });
|
|
1587
1649
|
}
|
|
1588
1650
|
}
|
|
1589
1651
|
class ImportManager {
|
|
@@ -1661,12 +1723,12 @@ async function $LT_ImportLibraries(config, logger) {
|
|
|
1661
1723
|
logger.warn("No tags were imported from any library files");
|
|
1662
1724
|
return;
|
|
1663
1725
|
}
|
|
1726
|
+
await $LT_EnsureDirectoryExists(config.import.dir);
|
|
1664
1727
|
await generateImportFiles(config, logger, importManager);
|
|
1665
1728
|
if (config.import.onImportFinish) config.import.onImportFinish();
|
|
1666
1729
|
}
|
|
1667
1730
|
async function $LT_ImportTranslations() {
|
|
1668
1731
|
const { config, logger } = await $LT_GetCommandEssentials();
|
|
1669
|
-
await $LT_EnsureDirectoryExists(config.import.dir);
|
|
1670
1732
|
logger.info("Importing translations from libraries...");
|
|
1671
1733
|
await $LT_ImportLibraries(config, logger);
|
|
1672
1734
|
logger.success("Successfully imported translations from libraries.");
|
package/index.js
CHANGED
|
@@ -82,22 +82,83 @@ class $LT_TagProcessor {
|
|
|
82
82
|
const matches = [];
|
|
83
83
|
let currentIndex = 0;
|
|
84
84
|
const skipRanges = this.buildSkipRanges(fileContent);
|
|
85
|
-
const
|
|
86
|
-
`${optionalVariableAssignment}${tagName}
|
|
85
|
+
const tagNamePattern = new RegExp(
|
|
86
|
+
`${optionalVariableAssignment}${tagName}`,
|
|
87
87
|
"g"
|
|
88
88
|
);
|
|
89
89
|
while (true) {
|
|
90
|
-
|
|
91
|
-
const
|
|
92
|
-
if (!
|
|
93
|
-
const
|
|
94
|
-
const variableName =
|
|
90
|
+
tagNamePattern.lastIndex = currentIndex;
|
|
91
|
+
const tagNameMatch = tagNamePattern.exec(fileContent);
|
|
92
|
+
if (!tagNameMatch) break;
|
|
93
|
+
const tagNameStartIndex = tagNameMatch.index;
|
|
94
|
+
const variableName = tagNameMatch[1] || void 0;
|
|
95
|
+
if (this.isInSkipRange(tagNameStartIndex, skipRanges)) {
|
|
96
|
+
currentIndex = tagNameStartIndex + 1;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
let i = tagNameStartIndex + tagNameMatch[0].length;
|
|
100
|
+
let genericType = void 0;
|
|
101
|
+
let matchStartIndex = tagNameStartIndex;
|
|
102
|
+
while (i < fileContent.length && /\s/.test(fileContent[i])) {
|
|
103
|
+
i++;
|
|
104
|
+
}
|
|
105
|
+
if (i < fileContent.length && fileContent[i] === "<") {
|
|
106
|
+
const genericStart = i;
|
|
107
|
+
let angleCount = 1;
|
|
108
|
+
i++;
|
|
109
|
+
while (i < fileContent.length && angleCount > 0) {
|
|
110
|
+
const char = fileContent[i];
|
|
111
|
+
if (char === "<") angleCount++;
|
|
112
|
+
else if (char === ">") angleCount--;
|
|
113
|
+
else if ((char === '"' || char === "'" || char === "`") && !this.isInSkipRange(i, skipRanges)) {
|
|
114
|
+
i++;
|
|
115
|
+
while (i < fileContent.length) {
|
|
116
|
+
if (fileContent[i] === "\\") {
|
|
117
|
+
i += 2;
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (fileContent[i] === char) {
|
|
121
|
+
i++;
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
i++;
|
|
125
|
+
}
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
i++;
|
|
129
|
+
}
|
|
130
|
+
if (angleCount === 0) {
|
|
131
|
+
genericType = fileContent.substring(genericStart + 1, i - 1).trim();
|
|
132
|
+
matchStartIndex = tagNameStartIndex;
|
|
133
|
+
} else {
|
|
134
|
+
currentIndex = tagNameStartIndex + 1;
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
} else {
|
|
138
|
+
matchStartIndex = tagNameStartIndex;
|
|
139
|
+
}
|
|
140
|
+
while (i < fileContent.length && /\s/.test(fileContent[i])) {
|
|
141
|
+
i++;
|
|
142
|
+
}
|
|
143
|
+
if (i >= fileContent.length || fileContent[i] !== "(" || i + 1 >= fileContent.length) {
|
|
144
|
+
currentIndex = tagNameStartIndex + 1;
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
i++;
|
|
148
|
+
while (i < fileContent.length && /\s/.test(fileContent[i])) {
|
|
149
|
+
i++;
|
|
150
|
+
}
|
|
151
|
+
if (i >= fileContent.length || fileContent[i] !== "{") {
|
|
152
|
+
currentIndex = tagNameStartIndex + 1;
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
const braceStartIndex = i;
|
|
95
156
|
if (this.isInSkipRange(matchStartIndex, skipRanges)) {
|
|
96
157
|
currentIndex = matchStartIndex + 1;
|
|
97
158
|
continue;
|
|
98
159
|
}
|
|
99
160
|
let braceCount = 1;
|
|
100
|
-
|
|
161
|
+
i++;
|
|
101
162
|
while (i < fileContent.length && braceCount > 0) {
|
|
102
163
|
if (fileContent[i] === "{") braceCount++;
|
|
103
164
|
if (fileContent[i] === "}") braceCount--;
|
|
@@ -107,10 +168,7 @@ class $LT_TagProcessor {
|
|
|
107
168
|
currentIndex = matchStartIndex + 1;
|
|
108
169
|
continue;
|
|
109
170
|
}
|
|
110
|
-
let parameter1Text = fileContent.substring(
|
|
111
|
-
matchStartIndex + startMatch[0].length - 1,
|
|
112
|
-
i
|
|
113
|
-
);
|
|
171
|
+
let parameter1Text = fileContent.substring(braceStartIndex, i);
|
|
114
172
|
let parameter2Text;
|
|
115
173
|
while (i < fileContent.length && (fileContent[i] === " " || fileContent[i] === "\n" || fileContent[i] === " ")) {
|
|
116
174
|
i++;
|
|
@@ -205,6 +263,7 @@ class $LT_TagProcessor {
|
|
|
205
263
|
matches.push({
|
|
206
264
|
fullMatch,
|
|
207
265
|
variableName,
|
|
266
|
+
genericType,
|
|
208
267
|
parameter1Text,
|
|
209
268
|
parameter2Text,
|
|
210
269
|
parameterTranslations,
|
|
@@ -258,7 +317,8 @@ class $LT_TagProcessor {
|
|
|
258
317
|
}
|
|
259
318
|
const arg1 = this.config.translationArgPosition === 1 ? newTranslationsString : newConfigString;
|
|
260
319
|
const arg2 = this.config.translationArgPosition === 1 ? newConfigString : newTranslationsString;
|
|
261
|
-
|
|
320
|
+
const genericTypePart = tag.genericType ? `<${tag.genericType}>` : "";
|
|
321
|
+
let tagFunction = `${this.config.tagName}${genericTypePart}(${arg1}`;
|
|
262
322
|
if (arg2) tagFunction += `, ${arg2}`;
|
|
263
323
|
tagFunction += ")";
|
|
264
324
|
if (tag.variableName)
|
|
@@ -1561,9 +1621,11 @@ async function generateImportFiles(config, logger, importManager) {
|
|
|
1561
1621
|
const content = renderTemplate$2(templateData);
|
|
1562
1622
|
await $LT_EnsureDirectoryExists(dirname(filePath));
|
|
1563
1623
|
await writeFile(filePath, content, "utf-8");
|
|
1624
|
+
const encodedFilePath = encodeURI(filePath);
|
|
1564
1625
|
logger.success('Created tag file: "{file}"', {
|
|
1565
1626
|
file: importedFile.pathRelativeToImportDir
|
|
1566
1627
|
});
|
|
1628
|
+
logger.debug(" └── link: file://{path}", { path: encodedFilePath });
|
|
1567
1629
|
}
|
|
1568
1630
|
}
|
|
1569
1631
|
class ImportManager {
|
|
@@ -1641,12 +1703,12 @@ async function $LT_ImportLibraries(config, logger) {
|
|
|
1641
1703
|
logger.warn("No tags were imported from any library files");
|
|
1642
1704
|
return;
|
|
1643
1705
|
}
|
|
1706
|
+
await $LT_EnsureDirectoryExists(config.import.dir);
|
|
1644
1707
|
await generateImportFiles(config, logger, importManager);
|
|
1645
1708
|
if (config.import.onImportFinish) config.import.onImportFinish();
|
|
1646
1709
|
}
|
|
1647
1710
|
async function $LT_ImportTranslations() {
|
|
1648
1711
|
const { config, logger } = await $LT_GetCommandEssentials();
|
|
1649
|
-
await $LT_EnsureDirectoryExists(config.import.dir);
|
|
1650
1712
|
logger.info("Importing translations from libraries...");
|
|
1651
1713
|
await $LT_ImportLibraries(config, logger);
|
|
1652
1714
|
logger.success("Successfully imported translations from libraries.");
|
package/package.json
CHANGED
package/type.d.ts
CHANGED
|
@@ -144,6 +144,8 @@ export interface LangTagCLIProcessedTag {
|
|
|
144
144
|
parameterTranslations: any;
|
|
145
145
|
parameterConfig?: any;
|
|
146
146
|
variableName?: string;
|
|
147
|
+
/** Generic type parameter if present (e.g., "ValidationTranslations" from "lang<ValidationTranslations>(...)") */
|
|
148
|
+
genericType?: string;
|
|
147
149
|
/** Character index in the whole text where the match starts */
|
|
148
150
|
index: number;
|
|
149
151
|
/** Line number (1-based) where the match was found */
|