@lang-tag/cli 0.14.0 → 0.16.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/case-utils.d.ts +12 -0
- package/algorithms/collector/dictionary-collector.d.ts +17 -0
- package/algorithms/collector/index.d.ts +10 -0
- package/algorithms/collector/namespace-collector.d.ts +12 -0
- package/algorithms/collector/type.d.ts +12 -0
- package/algorithms/config-generation/index.d.ts +1 -0
- package/algorithms/config-generation/path-based-config-generator.d.ts +3 -2
- package/algorithms/config-generation/prepend-namespace-to-path.d.ts +28 -0
- 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 +161 -28
- package/algorithms/index.d.ts +9 -3
- package/algorithms/index.js +177 -26
- package/config.d.ts +95 -75
- package/flexible-import-algorithm-C-S1c742.js +311 -0
- package/flexible-import-algorithm-Fa-l4jWj.cjs +327 -0
- package/index.cjs +236 -203
- package/index.js +233 -200
- package/package.json +1 -1
- package/templates/config/init-config.mustache +1 -0
- package/templates/import/imported-tag.mustache +14 -0
- /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/index.cjs
CHANGED
|
@@ -9,7 +9,9 @@ const path = require("path");
|
|
|
9
9
|
const globby = require("globby");
|
|
10
10
|
const path$1 = require("pathe");
|
|
11
11
|
const url = require("url");
|
|
12
|
+
require("case");
|
|
12
13
|
const process$1 = require("node:process");
|
|
14
|
+
const flexibleImportAlgorithm = require("./flexible-import-algorithm-Fa-l4jWj.cjs");
|
|
13
15
|
const acorn = require("acorn");
|
|
14
16
|
const micromatch = require("micromatch");
|
|
15
17
|
const chokidar = require("chokidar");
|
|
@@ -498,13 +500,16 @@ function isConfigSame(c1, c2) {
|
|
|
498
500
|
return false;
|
|
499
501
|
}
|
|
500
502
|
const CONFIG_FILE_NAME = ".lang-tag.config.js";
|
|
501
|
-
const EXPORTS_FILE_NAME = "
|
|
503
|
+
const EXPORTS_FILE_NAME = "lang-tags.json";
|
|
502
504
|
const LANG_TAG_DEFAULT_CONFIG = {
|
|
503
505
|
tagName: "lang",
|
|
506
|
+
isLibrary: false,
|
|
504
507
|
includes: ["src/**/*.{js,ts,jsx,tsx}"],
|
|
505
508
|
excludes: ["node_modules", "dist", "build"],
|
|
506
|
-
|
|
509
|
+
localesDirectory: "locales",
|
|
510
|
+
baseLanguageCode: "en",
|
|
507
511
|
collect: {
|
|
512
|
+
collector: new flexibleImportAlgorithm.NamespaceCollector(),
|
|
508
513
|
defaultNamespace: "common",
|
|
509
514
|
ignoreConflictsWithMatchingValues: true,
|
|
510
515
|
onCollectConfigFix: ({ config, langTagConfig }) => {
|
|
@@ -524,15 +529,19 @@ const LANG_TAG_DEFAULT_CONFIG = {
|
|
|
524
529
|
import: {
|
|
525
530
|
dir: "src/lang-libraries",
|
|
526
531
|
tagImportPath: 'import { lang } from "@/my-lang-tag-path"',
|
|
527
|
-
onImport: ({
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
}
|
|
532
|
+
onImport: flexibleImportAlgorithm.flexibleImportAlgorithm({
|
|
533
|
+
filePath: {
|
|
534
|
+
includePackageInPath: true
|
|
535
|
+
}
|
|
536
|
+
})
|
|
537
|
+
// onImport: ({importedRelativePath, fileGenerationData}: LangTagCLIOnImportParams, actions)=> {
|
|
538
|
+
// const exportIndex = (fileGenerationData.index || 0) + 1;
|
|
539
|
+
// fileGenerationData.index = exportIndex;
|
|
540
|
+
//
|
|
541
|
+
// actions.setFile(path.basename(importedRelativePath));
|
|
542
|
+
// actions.setExportName(`translations${exportIndex}`);
|
|
543
|
+
// }
|
|
533
544
|
},
|
|
534
|
-
isLibrary: false,
|
|
535
|
-
language: "en",
|
|
536
545
|
translationArgPosition: 1,
|
|
537
546
|
onConfigGeneration: async (event) => {
|
|
538
547
|
}
|
|
@@ -552,7 +561,7 @@ async function $LT_ReadConfig(projectPath) {
|
|
|
552
561
|
if (tn === "langtag" || tn === "lang-tag") {
|
|
553
562
|
throw new Error('Custom tagName cannot be "lang-tag" or "langtag"! (It is not recommended for use with libraries)\n');
|
|
554
563
|
}
|
|
555
|
-
|
|
564
|
+
const config = {
|
|
556
565
|
...LANG_TAG_DEFAULT_CONFIG,
|
|
557
566
|
...userConfig,
|
|
558
567
|
import: {
|
|
@@ -564,39 +573,14 @@ async function $LT_ReadConfig(projectPath) {
|
|
|
564
573
|
...userConfig.collect
|
|
565
574
|
}
|
|
566
575
|
};
|
|
576
|
+
if (!config.collect.collector) {
|
|
577
|
+
throw new Error("Collector not found! (config.collect.collector)");
|
|
578
|
+
}
|
|
579
|
+
return config;
|
|
567
580
|
} catch (error) {
|
|
568
581
|
throw error;
|
|
569
582
|
}
|
|
570
583
|
}
|
|
571
|
-
async function $LT_EnsureDirectoryExists(filePath) {
|
|
572
|
-
await promises.mkdir(filePath, { recursive: true });
|
|
573
|
-
}
|
|
574
|
-
async function $LT_RemoveDirectory(dirPath) {
|
|
575
|
-
try {
|
|
576
|
-
await promises.rm(dirPath, { recursive: true, force: true });
|
|
577
|
-
} catch (error) {
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
async function $LT_WriteJSON(filePath, data) {
|
|
581
|
-
await promises.writeFile(filePath, JSON.stringify(data, null, 2), "utf-8");
|
|
582
|
-
}
|
|
583
|
-
async function $LT_ReadJSON(filePath) {
|
|
584
|
-
const content = await promises.readFile(filePath, "utf-8");
|
|
585
|
-
return JSON.parse(content);
|
|
586
|
-
}
|
|
587
|
-
async function $LT_WriteFileWithDirs(filePath, content) {
|
|
588
|
-
const dir = path.dirname(filePath);
|
|
589
|
-
try {
|
|
590
|
-
await promises.mkdir(dir, { recursive: true });
|
|
591
|
-
} catch (error) {
|
|
592
|
-
}
|
|
593
|
-
await promises.writeFile(filePath, content, "utf-8");
|
|
594
|
-
}
|
|
595
|
-
async function $LT_ReadFileContent(relativeFilePath) {
|
|
596
|
-
const cwd = process.cwd();
|
|
597
|
-
const absolutePath = path.resolve(cwd, relativeFilePath);
|
|
598
|
-
return await promises.readFile(absolutePath, "utf-8");
|
|
599
|
-
}
|
|
600
584
|
function parseObjectAST(code) {
|
|
601
585
|
const nodes = [];
|
|
602
586
|
try {
|
|
@@ -809,7 +793,7 @@ function printLines(lines, startLineNumber, errorLines = /* @__PURE__ */ new Set
|
|
|
809
793
|
}
|
|
810
794
|
async function getLangTagCodeSection(tagInfo) {
|
|
811
795
|
const { tag, relativeFilePath } = tagInfo;
|
|
812
|
-
const fileContent = await
|
|
796
|
+
const fileContent = await flexibleImportAlgorithm.$LT_ReadFileContent(relativeFilePath);
|
|
813
797
|
const fileLines = fileContent.split("\n");
|
|
814
798
|
const startLine = tag.line;
|
|
815
799
|
const endLine = tag.line + tag.fullMatch.split("\n").length - 1;
|
|
@@ -998,6 +982,8 @@ function $LT_CreateDefaultLogger(debugMode, translationArgPosition = 1) {
|
|
|
998
982
|
async function $LT_GetCommandEssentials() {
|
|
999
983
|
const config = await $LT_ReadConfig(process$1.cwd());
|
|
1000
984
|
const logger = $LT_CreateDefaultLogger(config.debug, config.translationArgPosition);
|
|
985
|
+
config.collect.collector.config = config;
|
|
986
|
+
config.collect.collector.logger = logger;
|
|
1001
987
|
return {
|
|
1002
988
|
config,
|
|
1003
989
|
logger
|
|
@@ -1060,36 +1046,26 @@ function deepMergeTranslations(target, source) {
|
|
|
1060
1046
|
}
|
|
1061
1047
|
return changed;
|
|
1062
1048
|
}
|
|
1063
|
-
async function $
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
}
|
|
1069
|
-
await $LT_EnsureDirectoryExists(config.outputDir);
|
|
1070
|
-
for (let namespace of Object.keys(namespaces)) {
|
|
1071
|
-
if (!namespace) {
|
|
1049
|
+
async function $LT_WriteToCollections({ config, collections, logger, clean }) {
|
|
1050
|
+
await config.collect.collector.preWrite(clean);
|
|
1051
|
+
const changedCollections = [];
|
|
1052
|
+
for (let collectionName of Object.keys(collections)) {
|
|
1053
|
+
if (!collectionName) {
|
|
1072
1054
|
continue;
|
|
1073
1055
|
}
|
|
1074
|
-
const filePath =
|
|
1075
|
-
process$1.cwd(),
|
|
1076
|
-
config.outputDir,
|
|
1077
|
-
namespace + ".json"
|
|
1078
|
-
);
|
|
1056
|
+
const filePath = await config.collect.collector.resolveCollectionFilePath(collectionName);
|
|
1079
1057
|
let originalJSON = {};
|
|
1080
1058
|
try {
|
|
1081
|
-
originalJSON = await
|
|
1059
|
+
originalJSON = await flexibleImportAlgorithm.$LT_ReadJSON(filePath);
|
|
1082
1060
|
} catch (e) {
|
|
1083
|
-
|
|
1084
|
-
logger.warn(`Original namespace file "{namespace}.json" not found. A new one will be created.`, { namespace });
|
|
1085
|
-
}
|
|
1061
|
+
await config.collect.collector.onMissingCollection(collectionName);
|
|
1086
1062
|
}
|
|
1087
|
-
if (deepMergeTranslations(originalJSON,
|
|
1088
|
-
|
|
1089
|
-
await
|
|
1063
|
+
if (deepMergeTranslations(originalJSON, collections[collectionName])) {
|
|
1064
|
+
changedCollections.push(collectionName);
|
|
1065
|
+
await flexibleImportAlgorithm.$LT_WriteJSON(filePath, originalJSON);
|
|
1090
1066
|
}
|
|
1091
1067
|
}
|
|
1092
|
-
|
|
1068
|
+
await config.collect.collector.postWrite(changedCollections);
|
|
1093
1069
|
}
|
|
1094
1070
|
async function $LT_CollectCandidateFilesWithTags(props) {
|
|
1095
1071
|
const { config, logger } = props;
|
|
@@ -1120,51 +1096,43 @@ async function $LT_CollectCandidateFilesWithTags(props) {
|
|
|
1120
1096
|
return candidates;
|
|
1121
1097
|
}
|
|
1122
1098
|
async function $LT_WriteAsExportFile({ config, logger, files }) {
|
|
1123
|
-
const packageJson = await
|
|
1099
|
+
const packageJson = await flexibleImportAlgorithm.$LT_ReadJSON(path.resolve(process.cwd(), "package.json"));
|
|
1124
1100
|
if (!packageJson) {
|
|
1125
1101
|
throw new Error("package.json not found");
|
|
1126
1102
|
}
|
|
1127
|
-
const
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
config: C,
|
|
1138
|
-
variableName: tag.variableName
|
|
1139
|
-
};
|
|
1140
|
-
})
|
|
1141
|
-
};
|
|
1142
|
-
}
|
|
1143
|
-
const data = {
|
|
1144
|
-
language: config.language,
|
|
1145
|
-
packageName: packageJson.name || "",
|
|
1146
|
-
files: langTagFiles
|
|
1103
|
+
const exportData = {
|
|
1104
|
+
baseLanguageCode: config.baseLanguageCode,
|
|
1105
|
+
files: files.map(({ relativeFilePath, tags }) => ({
|
|
1106
|
+
relativeFilePath,
|
|
1107
|
+
tags: tags.map((tag) => ({
|
|
1108
|
+
variableName: tag.variableName,
|
|
1109
|
+
config: tag.parameterConfig,
|
|
1110
|
+
translations: tag.parameterTranslations
|
|
1111
|
+
}))
|
|
1112
|
+
}))
|
|
1147
1113
|
};
|
|
1148
|
-
await
|
|
1114
|
+
await promises.writeFile(EXPORTS_FILE_NAME, JSON.stringify(exportData), "utf-8");
|
|
1149
1115
|
logger.success(`Written {file}`, { file: EXPORTS_FILE_NAME });
|
|
1150
1116
|
}
|
|
1151
|
-
async function $
|
|
1117
|
+
async function $LT_GroupTagsToCollections({ logger, files, config }) {
|
|
1152
1118
|
let totalTags = 0;
|
|
1153
|
-
const
|
|
1154
|
-
function
|
|
1155
|
-
const
|
|
1156
|
-
|
|
1157
|
-
|
|
1119
|
+
const collections = {};
|
|
1120
|
+
function getTranslationsCollection(namespace) {
|
|
1121
|
+
const collectionName = config.collect.collector.aggregateCollection(namespace);
|
|
1122
|
+
const collection = collections[collectionName] || {};
|
|
1123
|
+
if (!(collectionName in collections)) {
|
|
1124
|
+
collections[collectionName] = collection;
|
|
1158
1125
|
}
|
|
1159
|
-
return
|
|
1126
|
+
return collection;
|
|
1160
1127
|
}
|
|
1161
1128
|
const allConflicts = [];
|
|
1162
1129
|
const existingValuesByNamespace = /* @__PURE__ */ new Map();
|
|
1163
1130
|
for (const file of files) {
|
|
1164
1131
|
totalTags += file.tags.length;
|
|
1165
|
-
for (const
|
|
1132
|
+
for (const _tag of file.tags) {
|
|
1133
|
+
const tag = config.collect.collector.transformTag(_tag);
|
|
1166
1134
|
const tagConfig = tag.parameterConfig;
|
|
1167
|
-
const
|
|
1135
|
+
const collection = getTranslationsCollection(tagConfig.namespace);
|
|
1168
1136
|
let existingValues = existingValuesByNamespace.get(tagConfig.namespace);
|
|
1169
1137
|
if (!existingValues) {
|
|
1170
1138
|
existingValues = /* @__PURE__ */ new Map();
|
|
@@ -1207,7 +1175,7 @@ async function $LT_GroupTagsToNamespaces({ logger, files, config }) {
|
|
|
1207
1175
|
};
|
|
1208
1176
|
const target = await ensureNestedObject(
|
|
1209
1177
|
tagConfig.path,
|
|
1210
|
-
|
|
1178
|
+
collection,
|
|
1211
1179
|
valueTracker,
|
|
1212
1180
|
addConflict
|
|
1213
1181
|
);
|
|
@@ -1227,7 +1195,7 @@ async function $LT_GroupTagsToNamespaces({ logger, files, config }) {
|
|
|
1227
1195
|
let shouldContinue = true;
|
|
1228
1196
|
config.collect.onCollectFinish({
|
|
1229
1197
|
totalTags,
|
|
1230
|
-
namespaces,
|
|
1198
|
+
namespaces: collections,
|
|
1231
1199
|
conflicts: allConflicts,
|
|
1232
1200
|
logger,
|
|
1233
1201
|
exit() {
|
|
@@ -1238,11 +1206,11 @@ async function $LT_GroupTagsToNamespaces({ logger, files, config }) {
|
|
|
1238
1206
|
throw new Error(`LangTagConflictResolution:Processing stopped due to collect finish handler`);
|
|
1239
1207
|
}
|
|
1240
1208
|
}
|
|
1241
|
-
return
|
|
1209
|
+
return collections;
|
|
1242
1210
|
}
|
|
1243
|
-
async function ensureNestedObject(path2,
|
|
1244
|
-
if (!path2 || !path2.trim()) return
|
|
1245
|
-
let current =
|
|
1211
|
+
async function ensureNestedObject(path2, rootCollection, valueTracker, addConflict) {
|
|
1212
|
+
if (!path2 || !path2.trim()) return rootCollection;
|
|
1213
|
+
let current = rootCollection;
|
|
1246
1214
|
let currentPath = "";
|
|
1247
1215
|
for (const key of path2.split(".")) {
|
|
1248
1216
|
currentPath = currentPath ? `${currentPath}.${key}` : key;
|
|
@@ -1342,19 +1310,10 @@ async function $LT_CMD_Collect(options) {
|
|
|
1342
1310
|
return;
|
|
1343
1311
|
}
|
|
1344
1312
|
try {
|
|
1345
|
-
const
|
|
1313
|
+
const collections = await $LT_GroupTagsToCollections({ logger, files, config });
|
|
1346
1314
|
const totalTags = files.reduce((sum, file) => sum + file.tags.length, 0);
|
|
1347
1315
|
logger.debug("Found {totalTags} translation tags", { totalTags });
|
|
1348
|
-
|
|
1349
|
-
if (!changedNamespaces?.length) {
|
|
1350
|
-
logger.info("No changes were made based on the current configuration and files");
|
|
1351
|
-
return;
|
|
1352
|
-
}
|
|
1353
|
-
const n = changedNamespaces.map((n2) => `"${n2}.json"`).join(", ");
|
|
1354
|
-
logger.success("Updated namespaces {outputDir} ({namespaces})", {
|
|
1355
|
-
outputDir: config.outputDir,
|
|
1356
|
-
namespaces: n
|
|
1357
|
-
});
|
|
1316
|
+
await $LT_WriteToCollections({ config, collections, logger, clean: options?.clean });
|
|
1358
1317
|
} catch (e) {
|
|
1359
1318
|
const prefix = "LangTagConflictResolution:";
|
|
1360
1319
|
if (e.message.startsWith(prefix)) {
|
|
@@ -1420,15 +1379,8 @@ async function handleFile(config, logger, cwdRelativeFilePath, event) {
|
|
|
1420
1379
|
const absoluteFilePath = path.join(cwd, cwdRelativeFilePath);
|
|
1421
1380
|
await checkAndRegenerateFileLangTags(config, logger, absoluteFilePath, cwdRelativeFilePath);
|
|
1422
1381
|
const files = await $LT_CollectCandidateFilesWithTags({ filesToScan: [cwdRelativeFilePath], config, logger });
|
|
1423
|
-
const namespaces = await $
|
|
1424
|
-
|
|
1425
|
-
if (changedNamespaces.length > 0) {
|
|
1426
|
-
const n = changedNamespaces.map((n2) => `"${n2}.json"`).join(", ");
|
|
1427
|
-
logger.success("Updated namespaces {outputDir} ({namespaces})", {
|
|
1428
|
-
outputDir: config.outputDir,
|
|
1429
|
-
namespaces: n
|
|
1430
|
-
});
|
|
1431
|
-
}
|
|
1382
|
+
const namespaces = await $LT_GroupTagsToCollections({ logger, files, config });
|
|
1383
|
+
await $LT_WriteToCollections({ config, collections: namespaces, logger });
|
|
1432
1384
|
}
|
|
1433
1385
|
async function detectModuleSystem() {
|
|
1434
1386
|
const packageJsonPath = path.join(process.cwd(), "package.json");
|
|
@@ -1468,7 +1420,13 @@ const generationAlgorithm = pathBasedConfigGenerator({
|
|
|
1468
1420
|
// },
|
|
1469
1421
|
// admin: {
|
|
1470
1422
|
// '>': 'management', // rename "admin" to "management"
|
|
1471
|
-
// users: false // ignore "users"
|
|
1423
|
+
// users: false // ignore "users",
|
|
1424
|
+
// ui: {
|
|
1425
|
+
// '>>': { // 'redirect' - ignore everything, jump to 'ui' namespace and prefix all paths with 'admin'
|
|
1426
|
+
// namespace: 'ui',
|
|
1427
|
+
// pathPrefix: 'admin'
|
|
1428
|
+
// }
|
|
1429
|
+
// }
|
|
1472
1430
|
// }
|
|
1473
1431
|
// }
|
|
1474
1432
|
// }
|
|
@@ -1481,7 +1439,8 @@ const config = {
|
|
|
1481
1439
|
isLibrary: false,
|
|
1482
1440
|
includes: ['src/**/*.{js,ts,jsx,tsx}'],
|
|
1483
1441
|
excludes: ['node_modules', 'dist', 'build', '**/*.test.ts'],
|
|
1484
|
-
|
|
1442
|
+
localesDirectory: 'public/locales',
|
|
1443
|
+
baseLanguageCode: 'en',
|
|
1485
1444
|
onConfigGeneration: async event => {
|
|
1486
1445
|
// We do not modify imported configurations
|
|
1487
1446
|
if (event.isImportedLibrary) return;
|
|
@@ -1523,115 +1482,189 @@ async function $LT_CMD_InitConfig() {
|
|
|
1523
1482
|
logger.error(error?.message);
|
|
1524
1483
|
}
|
|
1525
1484
|
}
|
|
1526
|
-
function $
|
|
1485
|
+
async function $LT_CollectExportFiles(logger) {
|
|
1527
1486
|
const nodeModulesPath = path$1.join(process$1.cwd(), "node_modules");
|
|
1528
1487
|
if (!fs.existsSync(nodeModulesPath)) {
|
|
1529
1488
|
logger.error('"node_modules" directory not found');
|
|
1530
1489
|
return [];
|
|
1531
1490
|
}
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1491
|
+
const results = [];
|
|
1492
|
+
try {
|
|
1493
|
+
const exportFiles = await globby.globby([
|
|
1494
|
+
`node_modules/**/${EXPORTS_FILE_NAME}`
|
|
1495
|
+
], {
|
|
1496
|
+
cwd: process$1.cwd(),
|
|
1497
|
+
onlyFiles: true,
|
|
1498
|
+
ignore: ["**/node_modules/**/node_modules/**"],
|
|
1499
|
+
deep: 4
|
|
1500
|
+
});
|
|
1501
|
+
for (const exportFile of exportFiles) {
|
|
1502
|
+
const fullExportPath = path$1.resolve(exportFile);
|
|
1503
|
+
const packageJsonPath = findPackageJsonForExport(fullExportPath, nodeModulesPath);
|
|
1504
|
+
if (packageJsonPath) {
|
|
1505
|
+
results.push({
|
|
1506
|
+
exportPath: fullExportPath,
|
|
1507
|
+
packageJsonPath
|
|
1508
|
+
});
|
|
1509
|
+
} else {
|
|
1510
|
+
logger.warn("Found export file but could not match package.json: {exportPath}", {
|
|
1511
|
+
exportPath: fullExportPath
|
|
1512
|
+
});
|
|
1545
1513
|
}
|
|
1546
|
-
} catch (error) {
|
|
1547
|
-
logger.error('Error reading directory "{dir}": {error}', {
|
|
1548
|
-
dir,
|
|
1549
|
-
error: String(error)
|
|
1550
|
-
});
|
|
1551
1514
|
}
|
|
1552
|
-
|
|
1515
|
+
logger.debug("Found {count} export files with matching package.json in node_modules", {
|
|
1516
|
+
count: results.length
|
|
1517
|
+
});
|
|
1518
|
+
} catch (error) {
|
|
1519
|
+
logger.error("Error scanning node_modules with globby: {error}", {
|
|
1520
|
+
error: String(error)
|
|
1521
|
+
});
|
|
1553
1522
|
}
|
|
1554
|
-
return
|
|
1523
|
+
return results;
|
|
1555
1524
|
}
|
|
1556
|
-
|
|
1557
|
-
const
|
|
1558
|
-
const
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
let exportName = match.variableName || "";
|
|
1569
|
-
config.import.onImport({
|
|
1570
|
-
packageName: exportData.packageName,
|
|
1571
|
-
importedRelativePath: langTagFilePath,
|
|
1572
|
-
originalExportName: match.variableName,
|
|
1573
|
-
translations: parsedTranslations,
|
|
1574
|
-
config: parsedConfig,
|
|
1575
|
-
fileGenerationData
|
|
1576
|
-
}, {
|
|
1577
|
-
setFile: (f) => {
|
|
1578
|
-
file = f;
|
|
1579
|
-
},
|
|
1580
|
-
setExportName: (name) => {
|
|
1581
|
-
exportName = name;
|
|
1582
|
-
},
|
|
1583
|
-
setConfig: (newConfig) => {
|
|
1584
|
-
parsedConfig = newConfig;
|
|
1585
|
-
}
|
|
1586
|
-
});
|
|
1587
|
-
if (!file || !exportName) {
|
|
1588
|
-
throw new Error(`[lang-tag] onImport did not set fileName or exportName for package: ${exportData.packageName}, file: '${file}' (original: '${langTagFilePath}'), exportName: '${exportName}' (original: ${match.variableName})`);
|
|
1589
|
-
}
|
|
1590
|
-
let exports2 = generationFiles[file];
|
|
1591
|
-
if (!exports2) {
|
|
1592
|
-
exports2 = {};
|
|
1593
|
-
generationFiles[file] = exports2;
|
|
1594
|
-
}
|
|
1595
|
-
const param1 = config.translationArgPosition === 1 ? parsedTranslations : parsedConfig;
|
|
1596
|
-
const param2 = config.translationArgPosition === 1 ? parsedConfig : parsedTranslations;
|
|
1597
|
-
exports2[exportName] = `${config.tagName}(${JSON5.stringify(param1, void 0, 4)}, ${JSON5.stringify(param2, void 0, 4)})`;
|
|
1525
|
+
function findPackageJsonForExport(exportPath, nodeModulesPath) {
|
|
1526
|
+
const relativePath = path$1.relative(nodeModulesPath, exportPath);
|
|
1527
|
+
const pathParts = relativePath.split(path$1.sep);
|
|
1528
|
+
if (pathParts.length < 2) {
|
|
1529
|
+
return null;
|
|
1530
|
+
}
|
|
1531
|
+
if (pathParts[0].startsWith("@")) {
|
|
1532
|
+
if (pathParts.length >= 3) {
|
|
1533
|
+
const packageDir = path$1.join(nodeModulesPath, pathParts[0], pathParts[1]);
|
|
1534
|
+
const packageJsonPath = path$1.join(packageDir, "package.json");
|
|
1535
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
1536
|
+
return packageJsonPath;
|
|
1598
1537
|
}
|
|
1599
1538
|
}
|
|
1539
|
+
} else {
|
|
1540
|
+
const packageDir = path$1.join(nodeModulesPath, pathParts[0]);
|
|
1541
|
+
const packageJsonPath = path$1.join(packageDir, "package.json");
|
|
1542
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
1543
|
+
return packageJsonPath;
|
|
1544
|
+
}
|
|
1600
1545
|
}
|
|
1601
|
-
|
|
1546
|
+
return null;
|
|
1547
|
+
}
|
|
1548
|
+
const __filename$1 = url.fileURLToPath(typeof document === "undefined" ? require("url").pathToFileURL(__filename).href : _documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === "SCRIPT" && _documentCurrentScript.src || new URL("index.cjs", document.baseURI).href);
|
|
1549
|
+
const __dirname$1 = path.dirname(__filename$1);
|
|
1550
|
+
const templatePath = path.join(__dirname$1, "templates", "import", "imported-tag.mustache");
|
|
1551
|
+
const template = fs.readFileSync(templatePath, "utf-8");
|
|
1552
|
+
function renderTemplate$1(data) {
|
|
1553
|
+
return mustache.render(template, data, {}, { escape: (text) => text });
|
|
1554
|
+
}
|
|
1555
|
+
async function generateImportFiles(config, logger, importManager) {
|
|
1556
|
+
const importedFiles = importManager.getImportedFiles();
|
|
1557
|
+
for (const importedFile of importedFiles) {
|
|
1602
1558
|
const filePath = path$1.resolve(
|
|
1603
1559
|
process__namespace.cwd(),
|
|
1604
1560
|
config.import.dir,
|
|
1605
|
-
|
|
1561
|
+
importedFile.pathRelativeToImportDir
|
|
1606
1562
|
);
|
|
1607
|
-
const
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1563
|
+
const processedExports = importedFile.tags.map((tag) => {
|
|
1564
|
+
const parameter1 = config.translationArgPosition === 1 ? tag.translations : tag.config;
|
|
1565
|
+
const parameter2 = config.translationArgPosition === 1 ? tag.config : tag.translations;
|
|
1566
|
+
const hasParameter2 = parameter2 !== null && parameter2 !== void 0 && (typeof parameter2 !== "object" || Object.keys(parameter2).length > 0);
|
|
1567
|
+
return {
|
|
1568
|
+
name: tag.variableName,
|
|
1569
|
+
parameter1: JSON5.stringify(parameter1, void 0, 4),
|
|
1570
|
+
parameter2: hasParameter2 ? JSON5.stringify(parameter2, void 0, 4) : null,
|
|
1571
|
+
hasParameter2,
|
|
1572
|
+
config: {
|
|
1573
|
+
tagName: config.tagName
|
|
1574
|
+
}
|
|
1575
|
+
};
|
|
1576
|
+
});
|
|
1577
|
+
const templateData = {
|
|
1578
|
+
tagImportPath: config.import.tagImportPath,
|
|
1579
|
+
exports: processedExports
|
|
1580
|
+
};
|
|
1581
|
+
const content = renderTemplate$1(templateData);
|
|
1582
|
+
await flexibleImportAlgorithm.$LT_EnsureDirectoryExists(path.dirname(filePath));
|
|
1614
1583
|
await promises.writeFile(filePath, content, "utf-8");
|
|
1615
|
-
logger.success('
|
|
1584
|
+
logger.success('Created tag file: "{file}"', { file: importedFile.pathRelativeToImportDir });
|
|
1616
1585
|
}
|
|
1586
|
+
}
|
|
1587
|
+
class ImportManager {
|
|
1588
|
+
importedFiles = [];
|
|
1589
|
+
constructor() {
|
|
1590
|
+
this.importedFiles = [];
|
|
1591
|
+
}
|
|
1592
|
+
importTag(pathRelativeToImportDir, tag) {
|
|
1593
|
+
if (!pathRelativeToImportDir) {
|
|
1594
|
+
throw new Error(`pathRelativeToImportDir required, got: ${pathRelativeToImportDir}`);
|
|
1595
|
+
}
|
|
1596
|
+
if (!tag?.variableName) {
|
|
1597
|
+
throw new Error(`tag.variableName required, got: ${tag?.variableName}`);
|
|
1598
|
+
}
|
|
1599
|
+
if (!this.isValidJavaScriptIdentifier(tag.variableName)) {
|
|
1600
|
+
throw new Error(`Invalid JavaScript identifier: "${tag.variableName}". Variable names must start with a letter, underscore, or dollar sign, and contain only letters, digits, underscores, and dollar signs.`);
|
|
1601
|
+
}
|
|
1602
|
+
if (tag.translations == null) {
|
|
1603
|
+
throw new Error(`tag.translations required`);
|
|
1604
|
+
}
|
|
1605
|
+
let importedFile = this.importedFiles.find(
|
|
1606
|
+
(file) => file.pathRelativeToImportDir === pathRelativeToImportDir
|
|
1607
|
+
);
|
|
1608
|
+
if (importedFile) {
|
|
1609
|
+
const duplicateTag = importedFile.tags.find(
|
|
1610
|
+
(existingTag) => existingTag.variableName === tag.variableName
|
|
1611
|
+
);
|
|
1612
|
+
if (duplicateTag) {
|
|
1613
|
+
throw new Error(`Duplicate variable name "${tag.variableName}" in file "${pathRelativeToImportDir}". Variable names must be unique within the same file.`);
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
if (!importedFile) {
|
|
1617
|
+
importedFile = { pathRelativeToImportDir, tags: [] };
|
|
1618
|
+
this.importedFiles.push(importedFile);
|
|
1619
|
+
}
|
|
1620
|
+
importedFile.tags.push(tag);
|
|
1621
|
+
}
|
|
1622
|
+
getImportedFiles() {
|
|
1623
|
+
return [...this.importedFiles];
|
|
1624
|
+
}
|
|
1625
|
+
getImportedFilesCount() {
|
|
1626
|
+
return this.importedFiles.length;
|
|
1627
|
+
}
|
|
1628
|
+
hasImportedFiles() {
|
|
1629
|
+
return this.importedFiles.length > 0;
|
|
1630
|
+
}
|
|
1631
|
+
isValidJavaScriptIdentifier(name) {
|
|
1632
|
+
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1635
|
+
async function $LT_ImportLibraries(config, logger) {
|
|
1636
|
+
const exportFiles = await $LT_CollectExportFiles(logger);
|
|
1637
|
+
const importManager = new ImportManager();
|
|
1638
|
+
let exports2 = [];
|
|
1639
|
+
for (const { exportPath, packageJsonPath } of exportFiles) {
|
|
1640
|
+
const exportData = await flexibleImportAlgorithm.$LT_ReadJSON(exportPath);
|
|
1641
|
+
const packageJSON = await flexibleImportAlgorithm.$LT_ReadJSON(packageJsonPath);
|
|
1642
|
+
exports2.push({ packageJSON, exportData });
|
|
1643
|
+
}
|
|
1644
|
+
config.import.onImport({ exports: exports2, importManager, logger, langTagConfig: config });
|
|
1645
|
+
if (!importManager.hasImportedFiles()) {
|
|
1646
|
+
logger.warn("No tags were imported from any library files");
|
|
1647
|
+
return;
|
|
1648
|
+
}
|
|
1649
|
+
await generateImportFiles(config, logger, importManager);
|
|
1617
1650
|
if (config.import.onImportFinish) config.import.onImportFinish();
|
|
1618
1651
|
}
|
|
1619
1652
|
async function $LT_ImportTranslations() {
|
|
1620
1653
|
const { config, logger } = await $LT_GetCommandEssentials();
|
|
1621
|
-
await
|
|
1654
|
+
await flexibleImportAlgorithm.$LT_EnsureDirectoryExists(config.import.dir);
|
|
1622
1655
|
logger.info("Importing translations from libraries...");
|
|
1623
1656
|
await $LT_ImportLibraries(config, logger);
|
|
1624
1657
|
logger.success("Successfully imported translations from libraries.");
|
|
1625
1658
|
}
|
|
1626
|
-
function renderTemplate(
|
|
1627
|
-
return mustache.render(
|
|
1659
|
+
function renderTemplate(template2, data) {
|
|
1660
|
+
return mustache.render(template2, data, {}, { escape: (text) => text });
|
|
1628
1661
|
}
|
|
1629
1662
|
function loadTemplate(templateName) {
|
|
1630
|
-
const
|
|
1631
|
-
const __dirname = path.dirname(
|
|
1632
|
-
const
|
|
1663
|
+
const __filename2 = url.fileURLToPath(typeof document === "undefined" ? require("url").pathToFileURL(__filename2).href : _documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === "SCRIPT" && _documentCurrentScript.src || new URL("index.cjs", document.baseURI).href);
|
|
1664
|
+
const __dirname = path.dirname(__filename2);
|
|
1665
|
+
const templatePath2 = path.join(__dirname, "templates", "tag", `${templateName}.mustache`);
|
|
1633
1666
|
try {
|
|
1634
|
-
return fs.readFileSync(
|
|
1667
|
+
return fs.readFileSync(templatePath2, "utf-8");
|
|
1635
1668
|
} catch (error) {
|
|
1636
1669
|
throw new Error(`Failed to load template ${templateName}: ${error}`);
|
|
1637
1670
|
}
|
|
@@ -1719,7 +1752,7 @@ async function $LT_CMD_InitTagFile(options = {}) {
|
|
|
1719
1752
|
return;
|
|
1720
1753
|
}
|
|
1721
1754
|
try {
|
|
1722
|
-
await
|
|
1755
|
+
await flexibleImportAlgorithm.$LT_WriteFileWithDirs(outputPath, renderedContent);
|
|
1723
1756
|
logger.success("Lang-tag file created successfully: {outputPath}", { outputPath });
|
|
1724
1757
|
logger.info("Next steps:");
|
|
1725
1758
|
logger.info("1. Import the {tagName} function in your files:", { tagName: renderOptions.tagName });
|