@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.
@@ -35,7 +35,7 @@ function applyCaseTransform(str, caseType) {
35
35
  }
36
36
  class DictionaryCollector extends namespaceCollector.TranslationsCollector {
37
37
  constructor(options = {
38
- appendNamespaceToPath: false
38
+ appendNamespaceToPath: true
39
39
  }) {
40
40
  super();
41
41
  this.options = options;
@@ -17,7 +17,7 @@ function applyCaseTransform(str, caseType) {
17
17
  }
18
18
  class DictionaryCollector extends TranslationsCollector {
19
19
  constructor(options = {
20
- appendNamespaceToPath: false
20
+ appendNamespaceToPath: true
21
21
  }) {
22
22
  super();
23
23
  this.options = options;
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 startPattern = new RegExp(
106
- `${optionalVariableAssignment}${tagName}\\(\\s*\\{`,
105
+ const tagNamePattern = new RegExp(
106
+ `${optionalVariableAssignment}${tagName}`,
107
107
  "g"
108
108
  );
109
109
  while (true) {
110
- startPattern.lastIndex = currentIndex;
111
- const startMatch = startPattern.exec(fileContent);
112
- if (!startMatch) break;
113
- const matchStartIndex = startMatch.index;
114
- const variableName = startMatch[1] || void 0;
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
- let i = matchStartIndex + startMatch[0].length;
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
- let tagFunction = `${this.config.tagName}(${arg1}`;
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 startPattern = new RegExp(
86
- `${optionalVariableAssignment}${tagName}\\(\\s*\\{`,
85
+ const tagNamePattern = new RegExp(
86
+ `${optionalVariableAssignment}${tagName}`,
87
87
  "g"
88
88
  );
89
89
  while (true) {
90
- startPattern.lastIndex = currentIndex;
91
- const startMatch = startPattern.exec(fileContent);
92
- if (!startMatch) break;
93
- const matchStartIndex = startMatch.index;
94
- const variableName = startMatch[1] || void 0;
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
- let i = matchStartIndex + startMatch[0].length;
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
- let tagFunction = `${this.config.tagName}(${arg1}`;
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lang-tag/cli",
3
- "version": "0.18.1",
3
+ "version": "0.19.0",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
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 */