@messagevisor/catalog 0.6.0 → 0.7.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/lib/node/index.js CHANGED
@@ -163,6 +163,11 @@ var CatalogProgressReporter = /** @class */ (function () {
163
163
  console.log(" ".concat(colorize("•", 36), " ").concat(label).concat(suffix));
164
164
  return Date.now();
165
165
  };
166
+ CatalogProgressReporter.prototype.substep = function (label, detail) {
167
+ var suffix = detail ? ": ".concat(colorize(detail, 2)) : "";
168
+ console.log(" ".concat(colorize("•", 36), " ").concat(label).concat(suffix));
169
+ return Date.now();
170
+ };
166
171
  CatalogProgressReporter.prototype.done = function (startedAt, detail) {
167
172
  var suffix = detail ? " ".concat(detail) : "";
168
173
  console.log(CLI_FORMAT_DIM, " done in ".concat(prettyDuration(Date.now() - startedAt)).concat(suffix));
@@ -438,15 +443,61 @@ function toLocaleDuplicatesFile(localeKey, duplicatesByLocale) {
438
443
  duplicateValues: duplicateValues,
439
444
  };
440
445
  }
441
- function writeJson(filePath, content) {
446
+ var CatalogJsonWriter = /** @class */ (function () {
447
+ function CatalogJsonWriter() {
448
+ this.directories = new Map();
449
+ }
450
+ CatalogJsonWriter.prototype.ensureDirectory = function (directoryPath) {
451
+ var promise = this.directories.get(directoryPath);
452
+ if (!promise) {
453
+ promise = fs.promises.mkdir(directoryPath, { recursive: true }).then(function () { return undefined; });
454
+ this.directories.set(directoryPath, promise);
455
+ }
456
+ return promise;
457
+ };
458
+ CatalogJsonWriter.prototype.write = function (filePath, content) {
459
+ return __awaiter(this, void 0, void 0, function () {
460
+ return __generator(this, function (_a) {
461
+ switch (_a.label) {
462
+ case 0: return [4 /*yield*/, this.ensureDirectory(path.dirname(filePath))];
463
+ case 1:
464
+ _a.sent();
465
+ return [4 /*yield*/, fs.promises.writeFile(filePath, JSON.stringify(content, null, 2))];
466
+ case 2:
467
+ _a.sent();
468
+ return [2 /*return*/];
469
+ }
470
+ });
471
+ });
472
+ };
473
+ return CatalogJsonWriter;
474
+ }());
475
+ function mapWithConcurrency(items, concurrency, callback) {
442
476
  return __awaiter(this, void 0, void 0, function () {
477
+ var nextIndex, workerCount, workers;
478
+ var _this = this;
443
479
  return __generator(this, function (_a) {
444
480
  switch (_a.label) {
445
- case 0: return [4 /*yield*/, fs.promises.mkdir(path.dirname(filePath), { recursive: true })];
481
+ case 0:
482
+ nextIndex = 0;
483
+ workerCount = Math.min(concurrency, items.length);
484
+ workers = Array.from({ length: workerCount }, function () { return __awaiter(_this, void 0, void 0, function () {
485
+ var index;
486
+ return __generator(this, function (_a) {
487
+ switch (_a.label) {
488
+ case 0:
489
+ if (!(nextIndex < items.length)) return [3 /*break*/, 2];
490
+ index = nextIndex++;
491
+ return [4 /*yield*/, callback(items[index], index)];
492
+ case 1:
493
+ _a.sent();
494
+ return [3 /*break*/, 0];
495
+ case 2: return [2 /*return*/];
496
+ }
497
+ });
498
+ }); });
499
+ return [4 /*yield*/, Promise.all(workers)];
446
500
  case 1:
447
- _a.sent();
448
- return [4 /*yield*/, fs.promises.writeFile(filePath, JSON.stringify(content, null, 2))];
449
- case 2:
450
501
  _a.sent();
451
502
  return [2 /*return*/];
452
503
  }
@@ -537,6 +588,14 @@ function addHistoryIndexEntry(target, key, entry) {
537
588
  }
538
589
  target[key].push(entry);
539
590
  }
591
+ function toEntityHistoryEntry(entry, entity) {
592
+ return {
593
+ commit: entry.commit,
594
+ author: entry.author,
595
+ timestamp: entry.timestamp,
596
+ entities: [entity],
597
+ };
598
+ }
540
599
  function buildCatalogHistoryIndex(entries) {
541
600
  var index = createEmptyHistoryIndex();
542
601
  index.entries = entries;
@@ -549,7 +608,7 @@ function buildCatalogHistoryIndex(entries) {
549
608
  continue;
550
609
  }
551
610
  var entityKey = getHistoryEntityKey(entity.type, entity.key, entity.set);
552
- addHistoryIndexEntry(index.byEntity, entityKey, entry);
611
+ addHistoryIndexEntry(index.byEntity, entityKey, toEntityHistoryEntry(entry, entity));
553
612
  if (!index.lastModifiedByEntity[entityKey]) {
554
613
  index.lastModifiedByEntity[entityKey] = toLastModified(entry);
555
614
  }
@@ -758,6 +817,19 @@ function getRepositoryRootDirectoryPath(rootDirectoryPath) {
758
817
  return getRealPath(rootDirectoryPath);
759
818
  }
760
819
  }
820
+ function getRepositorySourceRootDirectoryPath(rootDirectoryPath) {
821
+ try {
822
+ var gitRootDirectoryPath = runGit(rootDirectoryPath, ["rev-parse", "--show-toplevel"]).trim() || rootDirectoryPath;
823
+ var realRootDirectoryPath = getRealPath(rootDirectoryPath);
824
+ if (realRootDirectoryPath !== rootDirectoryPath) {
825
+ return path.resolve(rootDirectoryPath, path.relative(realRootDirectoryPath, gitRootDirectoryPath));
826
+ }
827
+ return gitRootDirectoryPath;
828
+ }
829
+ catch (_error) {
830
+ return rootDirectoryPath;
831
+ }
832
+ }
761
833
  function getOwnerAndRepoFromGitRemote(origin, host) {
762
834
  var escapedHost = host.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
763
835
  var match = origin.match(new RegExp("".concat(escapedHost, "[:/]([^/]+)/(.+?)(?:\\.git)?$")));
@@ -819,18 +891,22 @@ function chunkHistory(history, pageSize) {
819
891
  }
820
892
  return pages.length > 0 ? pages : [[]];
821
893
  }
822
- function writeHistoryPages(directoryPath, history) {
823
- return __awaiter(this, void 0, void 0, function () {
894
+ function writeHistoryPages(writer_1, directoryPath_1, history_1) {
895
+ return __awaiter(this, arguments, void 0, function (writer, directoryPath, history, options) {
824
896
  var pages, index;
897
+ if (options === void 0) { options = {}; }
825
898
  return __generator(this, function (_a) {
826
899
  switch (_a.label) {
827
900
  case 0:
901
+ if (options.skipEmpty && history.length === 0) {
902
+ return [2 /*return*/, 1];
903
+ }
828
904
  pages = chunkHistory(history);
829
905
  index = 0;
830
906
  _a.label = 1;
831
907
  case 1:
832
908
  if (!(index < pages.length)) return [3 /*break*/, 4];
833
- return [4 /*yield*/, writeJson(path.join(directoryPath, "page-".concat(index + 1, ".json")), {
909
+ return [4 /*yield*/, writer.write(path.join(directoryPath, "page-".concat(index + 1, ".json")), {
834
910
  page: index + 1,
835
911
  pageSize: exports.CATALOG_HISTORY_PAGE_SIZE,
836
912
  totalPages: pages.length,
@@ -842,7 +918,7 @@ function writeHistoryPages(directoryPath, history) {
842
918
  case 3:
843
919
  index++;
844
920
  return [3 /*break*/, 1];
845
- case 4: return [2 /*return*/];
921
+ case 4: return [2 /*return*/, 0];
846
922
  }
847
923
  });
848
924
  });
@@ -850,7 +926,8 @@ function writeHistoryPages(directoryPath, history) {
850
926
  function getHistoryForEntity(historyIndex, type, key, set) {
851
927
  return historyIndex.byEntity[getHistoryEntityKey(type, key, set)] || [];
852
928
  }
853
- function getSourceFileInfo(repositoryRootDirectoryPath, rootDirectoryPath, projectConfig, type, key) {
929
+ function getSourceFileInfo(repositorySourceRootDirectoryPath, rootDirectoryPath, projectConfig, type, key, options) {
930
+ if (options === void 0) { options = {}; }
854
931
  var directoryByType = {
855
932
  locale: projectConfig.localesDirectoryPath,
856
933
  message: projectConfig.messagesDirectoryPath,
@@ -861,9 +938,9 @@ function getSourceFileInfo(repositoryRootDirectoryPath, rootDirectoryPath, proje
861
938
  var extension = ".".concat(projectConfig.parser.extension);
862
939
  var filePath = path.resolve(path.resolve.apply(path, __spreadArray([rootDirectoryPath,
863
940
  directoryByType[type]], key.split(projectConfig.namespaceCharacter), false)) + extension);
864
- var absolutePath = getRealPath(filePath);
941
+ var absolutePath = options.resolveAbsolutePath ? getRealPath(filePath) : filePath;
865
942
  return {
866
- sourcePath: toPosixPath(path.relative(repositoryRootDirectoryPath, absolutePath)),
943
+ sourcePath: toPosixPath(path.relative(repositorySourceRootDirectoryPath, filePath)),
867
944
  absolutePath: absolutePath,
868
945
  };
869
946
  }
@@ -899,10 +976,11 @@ function buildSetCatalog(context, set, projectConfig, datasource, outputRelative
899
976
  translationShards[filename][msgKey].add(lower);
900
977
  }
901
978
  }
902
- var outputDirectoryPath, setStartedAt, entitiesStartedAt, _a, localeKeys, messageKeys, attributeKeys, segmentKeys, targetKeys, _b, locales, messages, attributes, segments, targets, relationshipsStartedAt, messageTargets, targetMessages, localeTargets, attributeTargets, segmentTargets, attributesUsedInSegments, attributesUsedInMessages, segmentsUsedInMessages, _i, targetKeys_1, targetKey, targetLocaleKeys, _c, targetLocaleKeys_1, localeKey, _d, _e, messageKey, _f, segmentKeys_1, segmentKey, usedAttributes, _g, _h, attributeKey, _j, messageKeys_1, messageKey, message, targetsForMessage, _k, _l, override, usedAttributes, usedSegments, _m, _o, attributeKey, _p, targetsForMessage_1, targetKey, _q, _r, segmentKey, _s, targetsForMessage_2, targetKey, _t, _u, attributeKey, _v, _w, segmentKey, _x, _y, targetKey, history, localeDirections, duplicateResult, duplicatesByLocale, index, historyStartedAt, examplesStartedAt, evaluatedMessageExamplesByKey, evaluatedLocaleExamplesByKey, localesStartedAt, _loop_1, _z, localeKeys_1, localeKey, duplicatesStartedAt, _0, localeKeys_2, localeKey, translationShards, messagesStartedAt, _loop_2, _1, messageKeys_2, messageKey, translationSearchStartedAt, _2, messageKeys_3, messageKey, message, _3, localeKeys_3, localeKey, row, _4, _5, override, overrideRow, _6, _7, _8, prefix, messageMap, shardData, _9, _10, _11, msgKey, valueSet, attributesStartedAt, _12, attributeKeys_1, attributeKey, attribute, sourceFileInfo, detail, segmentsStartedAt, _13, segmentKeys_2, segmentKey, segment, usedAttributes, sourceFileInfo, detail, targetsStartedAt, _14, targetKeys_2, targetKey, target, targetLocaleKeys, formatsByLocale, formatRowsByLocale, _15, targetLocaleKeys_2, localeKey, sourceFileInfo, detail, indexStartedAt, _16, _17, type;
903
- var _18, _19;
904
- return __generator(this, function (_20) {
905
- switch (_20.label) {
979
+ var outputDirectoryPath, setStartedAt, entitiesStartedAt, _a, localeKeys, messageKeys, attributeKeys, segmentKeys, targetKeys, _b, locales, messages, attributes, segments, targets, relationshipsStartedAt, messageTargets, targetMessages, localeTargets, attributeTargets, segmentTargets, attributesUsedInSegments, attributesUsedInMessages, segmentsUsedInMessages, _i, targetKeys_1, targetKey, targetLocaleKeys, _c, targetLocaleKeys_1, localeKey, _d, _e, messageKey, _f, segmentKeys_1, segmentKey, usedAttributes, _g, _h, attributeKey, _j, messageKeys_1, messageKey, message, targetsForMessage, _k, _l, override, usedAttributes, usedSegments, _m, _o, attributeKey, _p, targetsForMessage_1, targetKey, _q, _r, segmentKey, _s, targetsForMessage_2, targetKey, _t, _u, attributeKey, _v, _w, segmentKey, _x, _y, targetKey, history, localeDirections, duplicateResult, duplicatesByLocale, index, historyStartedAt, examplesStartedAt, evaluatedMessageExamplesByKey, evaluatedLocaleExamplesByKey, localesStartedAt, skippedEmptyHistoryCount, duplicatesStartedAt, translationShards, messagesStartedAt, messageDetailsStartedAt, skippedEmptyMessageHistoryCount, messageHistoryStartedAt, translationSearchStartedAt, _z, messageKeys_2, messageKey, message, _0, localeKeys_1, localeKey, row, _1, _2, override, overrideRow, _3, _4, _5, prefix, messageMap, shardData, _6, _7, _8, msgKey, valueSet, attributesStartedAt, segmentsStartedAt, targetsStartedAt, indexStartedAt, _9, _10, type;
980
+ var _this = this;
981
+ var _11;
982
+ return __generator(this, function (_12) {
983
+ switch (_12.label) {
906
984
  case 0:
907
985
  outputDirectoryPath = path.join(context.dataDirectoryPath, outputRelativeDirectory);
908
986
  setStartedAt = context.progress.setStart(set);
@@ -915,7 +993,7 @@ function buildSetCatalog(context, set, projectConfig, datasource, outputRelative
915
993
  datasource.listTargets(),
916
994
  ])];
917
995
  case 1:
918
- _a = _20.sent(), localeKeys = _a[0], messageKeys = _a[1], attributeKeys = _a[2], segmentKeys = _a[3], targetKeys = _a[4];
996
+ _a = (_12.sent()), localeKeys = _a[0], messageKeys = _a[1], attributeKeys = _a[2], segmentKeys = _a[3], targetKeys = _a[4];
919
997
  return [4 /*yield*/, Promise.all([
920
998
  readAll(localeKeys, function (key) { return datasource.readLocale(key); }),
921
999
  readAll(messageKeys, function (key) { return datasource.readMessage(key); }),
@@ -924,7 +1002,7 @@ function buildSetCatalog(context, set, projectConfig, datasource, outputRelative
924
1002
  readAll(targetKeys, function (key) { return datasource.readTarget(key); }),
925
1003
  ])];
926
1004
  case 2:
927
- _b = _20.sent(), locales = _b[0], messages = _b[1], attributes = _b[2], segments = _b[3], targets = _b[4];
1005
+ _b = _12.sent(), locales = _b[0], messages = _b[1], attributes = _b[2], segments = _b[3], targets = _b[4];
928
1006
  context.progress.done(entitiesStartedAt, "(".concat([
929
1007
  pluralize(localeKeys.length, "locale"),
930
1008
  pluralize(messageKeys.length, "message"),
@@ -944,7 +1022,7 @@ function buildSetCatalog(context, set, projectConfig, datasource, outputRelative
944
1022
  for (_i = 0, targetKeys_1 = targetKeys; _i < targetKeys_1.length; _i++) {
945
1023
  targetKey = targetKeys_1[_i];
946
1024
  targetMessages[targetKey] = getTargetMessageKeys(targets[targetKey], messageKeys);
947
- targetLocaleKeys = ((_18 = targets[targetKey].locales) === null || _18 === void 0 ? void 0 : _18.length)
1025
+ targetLocaleKeys = ((_11 = targets[targetKey].locales) === null || _11 === void 0 ? void 0 : _11.length)
948
1026
  ? targets[targetKey].locales
949
1027
  : localeKeys;
950
1028
  for (_c = 0, targetLocaleKeys_1 = targetLocaleKeys; _c < targetLocaleKeys_1.length; _c++) {
@@ -1053,16 +1131,16 @@ function buildSetCatalog(context, set, projectConfig, datasource, outputRelative
1053
1131
  },
1054
1132
  };
1055
1133
  historyStartedAt = context.progress.step("Writing history pages");
1056
- return [4 /*yield*/, writeHistoryPages(path.join(outputDirectoryPath, "history"), history)];
1134
+ return [4 /*yield*/, writeHistoryPages(context.writer, path.join(outputDirectoryPath, "history"), history)];
1057
1135
  case 3:
1058
- _20.sent();
1136
+ _12.sent();
1059
1137
  context.progress.done(historyStartedAt, "(".concat(pluralize(history.length, "entry", "entries"), ")"));
1060
1138
  examplesStartedAt = context.progress.step("Evaluating examples");
1061
1139
  return [4 /*yield*/, context.runtime.resolveExamples(projectConfig, datasource, {
1062
1140
  onlyMessages: true,
1063
1141
  })];
1064
1142
  case 4:
1065
- evaluatedMessageExamplesByKey = (_20.sent()).messages.reduce(function (accumulator, example) {
1143
+ evaluatedMessageExamplesByKey = (_12.sent()).messages.reduce(function (accumulator, example) {
1066
1144
  if (!accumulator[example.message]) {
1067
1145
  accumulator[example.message] = [];
1068
1146
  }
@@ -1073,7 +1151,7 @@ function buildSetCatalog(context, set, projectConfig, datasource, outputRelative
1073
1151
  onlyLocales: true,
1074
1152
  })];
1075
1153
  case 5:
1076
- evaluatedLocaleExamplesByKey = (_20.sent()).locales.reduce(function (accumulator, example) {
1154
+ evaluatedLocaleExamplesByKey = (_12.sent()).locales.reduce(function (accumulator, example) {
1077
1155
  var _a;
1078
1156
  var originalTranslation = example.message
1079
1157
  ? resolveTranslationRow((_a = messages[example.message]) === null || _a === void 0 ? void 0 : _a.translations, example.locale, locales)
@@ -1087,159 +1165,155 @@ function buildSetCatalog(context, set, projectConfig, datasource, outputRelative
1087
1165
  }, {});
1088
1166
  context.progress.done(examplesStartedAt, "(".concat(pluralize(Object.values(evaluatedMessageExamplesByKey).reduce(function (total, items) { return total + items.length; }, 0), "message example"), ", ").concat(pluralize(Object.values(evaluatedLocaleExamplesByKey).reduce(function (total, items) { return total + items.length; }, 0), "locale example"), ")"));
1089
1167
  localesStartedAt = context.progress.step("Writing locales");
1090
- _loop_1 = function (localeKey) {
1091
- var locale, sourceFileInfo, detail;
1092
- return __generator(this, function (_21) {
1093
- switch (_21.label) {
1094
- case 0:
1095
- locale = locales[localeKey];
1096
- sourceFileInfo = getSourceFileInfo(context.repositoryRootDirectoryPath, context.rootDirectoryPath, projectConfig, "locale", localeKey);
1097
- detail = {
1098
- type: "locale",
1099
- key: localeKey,
1100
- entity: locale,
1101
- sourcePath: sourceFileInfo.sourcePath,
1102
- editLinks: getEditorLinks(context.devEditors, sourceFileInfo),
1103
- baseFormats: locale.formats || {},
1104
- computedFormats: context.runtime.resolveFormats(localeKey, locales),
1105
- formatRows: getFormatRows(context.runtime, localeKey, locales),
1106
- evaluatedExamples: evaluatedLocaleExamplesByKey[localeKey] || [],
1107
- targetFormats: Object.fromEntries(targetKeys.map(function (targetKey) { return [
1108
- targetKey,
1109
- context.runtime.resolveFormats(localeKey, locales, targets[targetKey]),
1110
- ]; })),
1111
- lastModified: getLastModified(context.historyIndex, "locale", localeKey, set || undefined),
1112
- };
1113
- index.entities.locale.push(getEntitySummary(locale, "locale", localeKey, context.historyIndex, set || undefined, {
1114
- targets: sortStrings(Array.from(localeTargets[localeKey] || [])),
1115
- }));
1116
- return [4 /*yield*/, writeJson(path.join(outputDirectoryPath, "entities", "locale", "".concat(encodeKey(localeKey), ".json")), detail)];
1117
- case 1:
1118
- _21.sent();
1119
- return [4 /*yield*/, writeHistoryPages(path.join(outputDirectoryPath, "history", "locale", encodeKey(localeKey)), getHistoryForEntity(context.historyIndex, "locale", localeKey, set || undefined))];
1120
- case 2:
1121
- _21.sent();
1122
- return [2 /*return*/];
1123
- }
1124
- });
1125
- };
1126
- _z = 0, localeKeys_1 = localeKeys;
1127
- _20.label = 6;
1168
+ skippedEmptyHistoryCount = 0;
1169
+ return [4 /*yield*/, mapWithConcurrency(localeKeys, 32, function (localeKey) { return __awaiter(_this, void 0, void 0, function () {
1170
+ var locale, sourceFileInfo, detail, _a;
1171
+ return __generator(this, function (_b) {
1172
+ switch (_b.label) {
1173
+ case 0:
1174
+ locale = locales[localeKey];
1175
+ sourceFileInfo = getSourceFileInfo(context.repositorySourceRootDirectoryPath, context.rootDirectoryPath, projectConfig, "locale", localeKey, { resolveAbsolutePath: context.devEditors.length > 0 });
1176
+ detail = {
1177
+ type: "locale",
1178
+ key: localeKey,
1179
+ entity: locale,
1180
+ sourcePath: sourceFileInfo.sourcePath,
1181
+ editLinks: getEditorLinks(context.devEditors, sourceFileInfo),
1182
+ baseFormats: locale.formats || {},
1183
+ computedFormats: context.runtime.resolveFormats(localeKey, locales),
1184
+ formatRows: getFormatRows(context.runtime, localeKey, locales),
1185
+ evaluatedExamples: evaluatedLocaleExamplesByKey[localeKey] || [],
1186
+ targetFormats: Object.fromEntries(targetKeys.map(function (targetKey) { return [
1187
+ targetKey,
1188
+ context.runtime.resolveFormats(localeKey, locales, targets[targetKey]),
1189
+ ]; })),
1190
+ lastModified: getLastModified(context.historyIndex, "locale", localeKey, set || undefined),
1191
+ };
1192
+ index.entities.locale.push(getEntitySummary(locale, "locale", localeKey, context.historyIndex, set || undefined, {
1193
+ targets: sortStrings(Array.from(localeTargets[localeKey] || [])),
1194
+ }));
1195
+ return [4 /*yield*/, context.writer.write(path.join(outputDirectoryPath, "entities", "locale", "".concat(encodeKey(localeKey), ".json")), detail)];
1196
+ case 1:
1197
+ _b.sent();
1198
+ _a = skippedEmptyHistoryCount;
1199
+ return [4 /*yield*/, writeHistoryPages(context.writer, path.join(outputDirectoryPath, "history", "locale", encodeKey(localeKey)), getHistoryForEntity(context.historyIndex, "locale", localeKey, set || undefined), { skipEmpty: true })];
1200
+ case 2:
1201
+ skippedEmptyHistoryCount = _a + _b.sent();
1202
+ return [2 /*return*/];
1203
+ }
1204
+ });
1205
+ }); })];
1128
1206
  case 6:
1129
- if (!(_z < localeKeys_1.length)) return [3 /*break*/, 9];
1130
- localeKey = localeKeys_1[_z];
1131
- return [5 /*yield**/, _loop_1(localeKey)];
1132
- case 7:
1133
- _20.sent();
1134
- _20.label = 8;
1135
- case 8:
1136
- _z++;
1137
- return [3 /*break*/, 6];
1138
- case 9:
1207
+ _12.sent();
1139
1208
  context.progress.done(localesStartedAt, "(".concat(pluralize(localeKeys.length, "locale"), ")"));
1140
- if (!context.withDuplicates) return [3 /*break*/, 14];
1209
+ if (!context.withDuplicates) return [3 /*break*/, 8];
1141
1210
  duplicatesStartedAt = context.progress.step("Writing duplicate reports");
1142
- _0 = 0, localeKeys_2 = localeKeys;
1143
- _20.label = 10;
1144
- case 10:
1145
- if (!(_0 < localeKeys_2.length)) return [3 /*break*/, 13];
1146
- localeKey = localeKeys_2[_0];
1147
- return [4 /*yield*/, writeJson(path.join(outputDirectoryPath, "duplicates", "locales", "".concat(encodeKey(localeKey), ".json")), toLocaleDuplicatesFile(localeKey, duplicatesByLocale))];
1148
- case 11:
1149
- _20.sent();
1150
- _20.label = 12;
1151
- case 12:
1152
- _0++;
1153
- return [3 /*break*/, 10];
1154
- case 13:
1211
+ return [4 /*yield*/, mapWithConcurrency(localeKeys, 32, function (localeKey) { return __awaiter(_this, void 0, void 0, function () {
1212
+ return __generator(this, function (_a) {
1213
+ switch (_a.label) {
1214
+ case 0: return [4 /*yield*/, context.writer.write(path.join(outputDirectoryPath, "duplicates", "locales", "".concat(encodeKey(localeKey), ".json")), toLocaleDuplicatesFile(localeKey, duplicatesByLocale))];
1215
+ case 1:
1216
+ _a.sent();
1217
+ return [2 /*return*/];
1218
+ }
1219
+ });
1220
+ }); })];
1221
+ case 7:
1222
+ _12.sent();
1155
1223
  context.progress.done(duplicatesStartedAt, "(".concat(pluralize(localeKeys.length, "locale"), ")"));
1156
- _20.label = 14;
1157
- case 14:
1224
+ _12.label = 8;
1225
+ case 8:
1158
1226
  translationShards = {};
1159
1227
  messagesStartedAt = context.progress.step("Writing messages");
1160
- _loop_2 = function (messageKey) {
1161
- var message, overrides, sourceFileInfo, detail, directLocales, overrideLocalesSet, _22, overrides_1, override, _23, _24, lk, overrideLocalesList;
1162
- return __generator(this, function (_25) {
1163
- switch (_25.label) {
1164
- case 0:
1165
- message = messages[messageKey];
1166
- overrides = (message.overrides || []).map(function (override) {
1167
- var attributes = new Set();
1168
- var overrideSegments = new Set();
1169
- collectAttributeKeysFromConditions(override.conditions, attributes);
1170
- collectSegmentKeys(override.segments, overrideSegments);
1171
- return __assign(__assign({}, override), { usedAttributes: sortStrings(Array.from(attributes)), usedSegments: sortStrings(Array.from(overrideSegments)) });
1172
- });
1173
- sourceFileInfo = getSourceFileInfo(context.repositoryRootDirectoryPath, context.rootDirectoryPath, projectConfig, "message", messageKey);
1174
- detail = {
1175
- type: "message",
1176
- key: messageKey,
1177
- entity: __assign(__assign({}, message), { overrides: overrides }),
1178
- sourcePath: sourceFileInfo.sourcePath,
1179
- editLinks: getEditorLinks(context.devEditors, sourceFileInfo),
1180
- targets: sortStrings(messageTargets[messageKey] || []),
1181
- localeKeys: localeKeys,
1182
- localeDirections: localeDirections,
1183
- translations: localeKeys.map(function (localeKey) {
1184
- return resolveTranslationRow(message.translations, localeKey, locales);
1185
- }),
1186
- evaluatedExamples: evaluatedMessageExamplesByKey[messageKey] || [],
1187
- overrideTranslations: overrides.map(function (override) { return ({
1188
- key: override.key,
1189
- rows: localeKeys.map(function (localeKey) {
1190
- return resolveTranslationRow(override.translations, localeKey, locales);
1228
+ messageDetailsStartedAt = context.progress.substep("Writing message details");
1229
+ skippedEmptyMessageHistoryCount = 0;
1230
+ return [4 /*yield*/, mapWithConcurrency(messageKeys, 32, function (messageKey) { return __awaiter(_this, void 0, void 0, function () {
1231
+ var message, overrides, sourceFileInfo, detail, directLocales, overrideLocalesSet, _i, overrides_1, override, _a, _b, lk, overrideLocalesList;
1232
+ return __generator(this, function (_c) {
1233
+ switch (_c.label) {
1234
+ case 0:
1235
+ message = messages[messageKey];
1236
+ overrides = (message.overrides || []).map(function (override) {
1237
+ var attributes = new Set();
1238
+ var overrideSegments = new Set();
1239
+ collectAttributeKeysFromConditions(override.conditions, attributes);
1240
+ collectSegmentKeys(override.segments, overrideSegments);
1241
+ return __assign(__assign({}, override), { usedAttributes: sortStrings(Array.from(attributes)), usedSegments: sortStrings(Array.from(overrideSegments)) });
1242
+ });
1243
+ sourceFileInfo = getSourceFileInfo(context.repositorySourceRootDirectoryPath, context.rootDirectoryPath, projectConfig, "message", messageKey, { resolveAbsolutePath: context.devEditors.length > 0 });
1244
+ detail = {
1245
+ type: "message",
1246
+ key: messageKey,
1247
+ entity: __assign(__assign({}, message), { overrides: overrides }),
1248
+ sourcePath: sourceFileInfo.sourcePath,
1249
+ editLinks: getEditorLinks(context.devEditors, sourceFileInfo),
1250
+ targets: sortStrings(messageTargets[messageKey] || []),
1251
+ localeKeys: localeKeys,
1252
+ localeDirections: localeDirections,
1253
+ translations: localeKeys.map(function (localeKey) {
1254
+ return resolveTranslationRow(message.translations, localeKey, locales);
1191
1255
  }),
1192
- }); }),
1193
- lastModified: getLastModified(context.historyIndex, "message", messageKey, set || undefined),
1194
- };
1195
- directLocales = localeKeys.filter(function (lk) { return message.translations && typeof message.translations[lk] === "string"; });
1196
- overrideLocalesSet = new Set();
1197
- for (_22 = 0, overrides_1 = overrides; _22 < overrides_1.length; _22++) {
1198
- override = overrides_1[_22];
1199
- for (_23 = 0, _24 = Object.keys(override.translations || {}); _23 < _24.length; _23++) {
1200
- lk = _24[_23];
1201
- overrideLocalesSet.add(lk);
1256
+ evaluatedExamples: evaluatedMessageExamplesByKey[messageKey] || [],
1257
+ overrideTranslations: overrides.map(function (override) { return ({
1258
+ key: override.key,
1259
+ rows: localeKeys.map(function (localeKey) {
1260
+ return resolveTranslationRow(override.translations, localeKey, locales);
1261
+ }),
1262
+ }); }),
1263
+ lastModified: getLastModified(context.historyIndex, "message", messageKey, set || undefined),
1264
+ };
1265
+ directLocales = localeKeys.filter(function (lk) { return message.translations && typeof message.translations[lk] === "string"; });
1266
+ overrideLocalesSet = new Set();
1267
+ for (_i = 0, overrides_1 = overrides; _i < overrides_1.length; _i++) {
1268
+ override = overrides_1[_i];
1269
+ for (_a = 0, _b = Object.keys(override.translations || {}); _a < _b.length; _a++) {
1270
+ lk = _b[_a];
1271
+ overrideLocalesSet.add(lk);
1272
+ }
1202
1273
  }
1203
- }
1204
- overrideLocalesList = sortStrings(Array.from(overrideLocalesSet));
1205
- index.entities.message.push(getEntitySummary(message, "message", messageKey, context.historyIndex, set || undefined, __assign(__assign({ targets: sortStrings(messageTargets[messageKey] || []) }, (directLocales.length > 0 ? { locales: sortStrings(directLocales) } : {})), (overrideLocalesList.length > 0 ? { overrideLocales: overrideLocalesList } : {}))));
1206
- return [4 /*yield*/, writeJson(path.join(outputDirectoryPath, "entities", "message", "".concat(encodeKey(messageKey), ".json")), detail)];
1207
- case 1:
1208
- _25.sent();
1209
- return [4 /*yield*/, writeHistoryPages(path.join(outputDirectoryPath, "history", "message", encodeKey(messageKey)), getHistoryForEntity(context.historyIndex, "message", messageKey, set || undefined))];
1210
- case 2:
1211
- _25.sent();
1212
- return [2 /*return*/];
1213
- }
1214
- });
1215
- };
1216
- _1 = 0, messageKeys_2 = messageKeys;
1217
- _20.label = 15;
1218
- case 15:
1219
- if (!(_1 < messageKeys_2.length)) return [3 /*break*/, 18];
1220
- messageKey = messageKeys_2[_1];
1221
- return [5 /*yield**/, _loop_2(messageKey)];
1222
- case 16:
1223
- _20.sent();
1224
- _20.label = 17;
1225
- case 17:
1226
- _1++;
1227
- return [3 /*break*/, 15];
1228
- case 18:
1229
- context.progress.done(messagesStartedAt, "(".concat(pluralize(messageKeys.length, "message"), ")"));
1230
- if (!context.withTranslationSearch) return [3 /*break*/, 23];
1274
+ overrideLocalesList = sortStrings(Array.from(overrideLocalesSet));
1275
+ index.entities.message.push(getEntitySummary(message, "message", messageKey, context.historyIndex, set || undefined, __assign(__assign({ targets: sortStrings(messageTargets[messageKey] || []) }, (directLocales.length > 0 ? { locales: sortStrings(directLocales) } : {})), (overrideLocalesList.length > 0 ? { overrideLocales: overrideLocalesList } : {}))));
1276
+ return [4 /*yield*/, context.writer.write(path.join(outputDirectoryPath, "entities", "message", "".concat(encodeKey(messageKey), ".json")), detail)];
1277
+ case 1:
1278
+ _c.sent();
1279
+ return [2 /*return*/];
1280
+ }
1281
+ });
1282
+ }); })];
1283
+ case 9:
1284
+ _12.sent();
1285
+ context.progress.done(messageDetailsStartedAt, "(".concat(pluralize(messageKeys.length, "message"), ")"));
1286
+ messageHistoryStartedAt = context.progress.substep("Writing message history pages");
1287
+ return [4 /*yield*/, mapWithConcurrency(messageKeys, 32, function (messageKey) { return __awaiter(_this, void 0, void 0, function () {
1288
+ var skippedHistory;
1289
+ return __generator(this, function (_a) {
1290
+ switch (_a.label) {
1291
+ case 0: return [4 /*yield*/, writeHistoryPages(context.writer, path.join(outputDirectoryPath, "history", "message", encodeKey(messageKey)), getHistoryForEntity(context.historyIndex, "message", messageKey, set || undefined), { skipEmpty: true })];
1292
+ case 1:
1293
+ skippedHistory = _a.sent();
1294
+ skippedEmptyMessageHistoryCount += skippedHistory;
1295
+ skippedEmptyHistoryCount += skippedHistory;
1296
+ return [2 /*return*/];
1297
+ }
1298
+ });
1299
+ }); })];
1300
+ case 10:
1301
+ _12.sent();
1302
+ context.progress.done(messageHistoryStartedAt, "(".concat(pluralize(messageKeys.length, "message"), ", ").concat(pluralize(skippedEmptyMessageHistoryCount, "empty history", "empty histories"), " skipped)"));
1303
+ context.progress.done(messagesStartedAt, "(".concat(pluralize(messageKeys.length, "message"), ", ").concat(pluralize(skippedEmptyMessageHistoryCount, "empty history", "empty histories"), " skipped)"));
1304
+ if (!context.withTranslationSearch) return [3 /*break*/, 15];
1231
1305
  translationSearchStartedAt = context.progress.step("Building translation search shards");
1232
- for (_2 = 0, messageKeys_3 = messageKeys; _2 < messageKeys_3.length; _2++) {
1233
- messageKey = messageKeys_3[_2];
1306
+ for (_z = 0, messageKeys_2 = messageKeys; _z < messageKeys_2.length; _z++) {
1307
+ messageKey = messageKeys_2[_z];
1234
1308
  message = messages[messageKey];
1235
- for (_3 = 0, localeKeys_3 = localeKeys; _3 < localeKeys_3.length; _3++) {
1236
- localeKey = localeKeys_3[_3];
1309
+ for (_0 = 0, localeKeys_1 = localeKeys; _0 < localeKeys_1.length; _0++) {
1310
+ localeKey = localeKeys_1[_0];
1237
1311
  row = resolveTranslationRow(message.translations, localeKey, locales);
1238
1312
  if (row.source !== "missing" && row.value) {
1239
1313
  addToTranslationShard(messageKey, row.value);
1240
1314
  }
1241
- for (_4 = 0, _5 = message.overrides || []; _4 < _5.length; _4++) {
1242
- override = _5[_4];
1315
+ for (_1 = 0, _2 = message.overrides || []; _1 < _2.length; _1++) {
1316
+ override = _2[_1];
1243
1317
  overrideRow = resolveTranslationRow(override.translations, localeKey, locales);
1244
1318
  if (overrideRow.source !== "missing" && overrideRow.value) {
1245
1319
  addToTranslationShard(messageKey, overrideRow.value);
@@ -1247,152 +1321,159 @@ function buildSetCatalog(context, set, projectConfig, datasource, outputRelative
1247
1321
  }
1248
1322
  }
1249
1323
  }
1250
- _6 = 0, _7 = Object.entries(translationShards);
1251
- _20.label = 19;
1252
- case 19:
1253
- if (!(_6 < _7.length)) return [3 /*break*/, 22];
1254
- _8 = _7[_6], prefix = _8[0], messageMap = _8[1];
1324
+ _3 = 0, _4 = Object.entries(translationShards);
1325
+ _12.label = 11;
1326
+ case 11:
1327
+ if (!(_3 < _4.length)) return [3 /*break*/, 14];
1328
+ _5 = _4[_3], prefix = _5[0], messageMap = _5[1];
1255
1329
  shardData = {};
1256
- for (_9 = 0, _10 = Object.entries(messageMap); _9 < _10.length; _9++) {
1257
- _11 = _10[_9], msgKey = _11[0], valueSet = _11[1];
1330
+ for (_6 = 0, _7 = Object.entries(messageMap); _6 < _7.length; _6++) {
1331
+ _8 = _7[_6], msgKey = _8[0], valueSet = _8[1];
1258
1332
  shardData[msgKey] = Array.from(valueSet);
1259
1333
  }
1260
- return [4 /*yield*/, writeJson(path.join(outputDirectoryPath, "translations", "".concat(prefix, ".json")), shardData)];
1261
- case 20:
1262
- _20.sent();
1263
- _20.label = 21;
1264
- case 21:
1265
- _6++;
1266
- return [3 /*break*/, 19];
1267
- case 22:
1334
+ return [4 /*yield*/, context.writer.write(path.join(outputDirectoryPath, "translations", "".concat(prefix, ".json")), shardData)];
1335
+ case 12:
1336
+ _12.sent();
1337
+ _12.label = 13;
1338
+ case 13:
1339
+ _3++;
1340
+ return [3 /*break*/, 11];
1341
+ case 14:
1268
1342
  context.progress.done(translationSearchStartedAt, "(".concat(pluralize(Object.keys(translationShards).length, "shard"), ")"));
1269
- _20.label = 23;
1270
- case 23:
1343
+ _12.label = 15;
1344
+ case 15:
1271
1345
  attributesStartedAt = context.progress.step("Writing attributes");
1272
- _12 = 0, attributeKeys_1 = attributeKeys;
1273
- _20.label = 24;
1274
- case 24:
1275
- if (!(_12 < attributeKeys_1.length)) return [3 /*break*/, 28];
1276
- attributeKey = attributeKeys_1[_12];
1277
- attribute = attributes[attributeKey];
1278
- sourceFileInfo = getSourceFileInfo(context.repositoryRootDirectoryPath, context.rootDirectoryPath, projectConfig, "attribute", attributeKey);
1279
- detail = {
1280
- type: "attribute",
1281
- key: attributeKey,
1282
- entity: attribute,
1283
- sourcePath: sourceFileInfo.sourcePath,
1284
- editLinks: getEditorLinks(context.devEditors, sourceFileInfo),
1285
- usage: {
1286
- segments: sortStrings(Array.from(attributesUsedInSegments[attributeKey] || [])),
1287
- messages: sortStrings(Array.from(attributesUsedInMessages[attributeKey] || [])),
1288
- },
1289
- lastModified: getLastModified(context.historyIndex, "attribute", attributeKey, set || undefined),
1290
- };
1291
- index.entities.attribute.push(getEntitySummary(attribute, "attribute", attributeKey, context.historyIndex, set || undefined, {
1292
- targets: sortStrings(Array.from(attributeTargets[attributeKey] || [])),
1293
- }));
1294
- return [4 /*yield*/, writeJson(path.join(outputDirectoryPath, "entities", "attribute", "".concat(encodeKey(attributeKey), ".json")), detail)];
1295
- case 25:
1296
- _20.sent();
1297
- return [4 /*yield*/, writeHistoryPages(path.join(outputDirectoryPath, "history", "attribute", encodeKey(attributeKey)), getHistoryForEntity(context.historyIndex, "attribute", attributeKey, set || undefined))];
1298
- case 26:
1299
- _20.sent();
1300
- _20.label = 27;
1301
- case 27:
1302
- _12++;
1303
- return [3 /*break*/, 24];
1304
- case 28:
1346
+ return [4 /*yield*/, mapWithConcurrency(attributeKeys, 32, function (attributeKey) { return __awaiter(_this, void 0, void 0, function () {
1347
+ var attribute, sourceFileInfo, detail, _a;
1348
+ return __generator(this, function (_b) {
1349
+ switch (_b.label) {
1350
+ case 0:
1351
+ attribute = attributes[attributeKey];
1352
+ sourceFileInfo = getSourceFileInfo(context.repositorySourceRootDirectoryPath, context.rootDirectoryPath, projectConfig, "attribute", attributeKey, { resolveAbsolutePath: context.devEditors.length > 0 });
1353
+ detail = {
1354
+ type: "attribute",
1355
+ key: attributeKey,
1356
+ entity: attribute,
1357
+ sourcePath: sourceFileInfo.sourcePath,
1358
+ editLinks: getEditorLinks(context.devEditors, sourceFileInfo),
1359
+ usage: {
1360
+ segments: sortStrings(Array.from(attributesUsedInSegments[attributeKey] || [])),
1361
+ messages: sortStrings(Array.from(attributesUsedInMessages[attributeKey] || [])),
1362
+ },
1363
+ lastModified: getLastModified(context.historyIndex, "attribute", attributeKey, set || undefined),
1364
+ };
1365
+ index.entities.attribute.push(getEntitySummary(attribute, "attribute", attributeKey, context.historyIndex, set || undefined, {
1366
+ targets: sortStrings(Array.from(attributeTargets[attributeKey] || [])),
1367
+ }));
1368
+ return [4 /*yield*/, context.writer.write(path.join(outputDirectoryPath, "entities", "attribute", "".concat(encodeKey(attributeKey), ".json")), detail)];
1369
+ case 1:
1370
+ _b.sent();
1371
+ _a = skippedEmptyHistoryCount;
1372
+ return [4 /*yield*/, writeHistoryPages(context.writer, path.join(outputDirectoryPath, "history", "attribute", encodeKey(attributeKey)), getHistoryForEntity(context.historyIndex, "attribute", attributeKey, set || undefined), { skipEmpty: true })];
1373
+ case 2:
1374
+ skippedEmptyHistoryCount = _a + _b.sent();
1375
+ return [2 /*return*/];
1376
+ }
1377
+ });
1378
+ }); })];
1379
+ case 16:
1380
+ _12.sent();
1305
1381
  context.progress.done(attributesStartedAt, "(".concat(pluralize(attributeKeys.length, "attribute"), ")"));
1306
1382
  segmentsStartedAt = context.progress.step("Writing segments");
1307
- _13 = 0, segmentKeys_2 = segmentKeys;
1308
- _20.label = 29;
1309
- case 29:
1310
- if (!(_13 < segmentKeys_2.length)) return [3 /*break*/, 33];
1311
- segmentKey = segmentKeys_2[_13];
1312
- segment = segments[segmentKey];
1313
- usedAttributes = new Set();
1314
- collectAttributeKeysFromConditions(segment.conditions, usedAttributes);
1315
- sourceFileInfo = getSourceFileInfo(context.repositoryRootDirectoryPath, context.rootDirectoryPath, projectConfig, "segment", segmentKey);
1316
- detail = {
1317
- type: "segment",
1318
- key: segmentKey,
1319
- entity: segment,
1320
- sourcePath: sourceFileInfo.sourcePath,
1321
- editLinks: getEditorLinks(context.devEditors, sourceFileInfo),
1322
- usage: {
1323
- attributes: sortStrings(Array.from(usedAttributes)),
1324
- messages: sortStrings(Array.from(segmentsUsedInMessages[segmentKey] || [])),
1325
- },
1326
- lastModified: getLastModified(context.historyIndex, "segment", segmentKey, set || undefined),
1327
- };
1328
- index.entities.segment.push(getEntitySummary(segment, "segment", segmentKey, context.historyIndex, set || undefined, {
1329
- targets: sortStrings(Array.from(segmentTargets[segmentKey] || [])),
1330
- }));
1331
- return [4 /*yield*/, writeJson(path.join(outputDirectoryPath, "entities", "segment", "".concat(encodeKey(segmentKey), ".json")), detail)];
1332
- case 30:
1333
- _20.sent();
1334
- return [4 /*yield*/, writeHistoryPages(path.join(outputDirectoryPath, "history", "segment", encodeKey(segmentKey)), getHistoryForEntity(context.historyIndex, "segment", segmentKey, set || undefined))];
1335
- case 31:
1336
- _20.sent();
1337
- _20.label = 32;
1338
- case 32:
1339
- _13++;
1340
- return [3 /*break*/, 29];
1341
- case 33:
1383
+ return [4 /*yield*/, mapWithConcurrency(segmentKeys, 32, function (segmentKey) { return __awaiter(_this, void 0, void 0, function () {
1384
+ var segment, usedAttributes, sourceFileInfo, detail, _a;
1385
+ return __generator(this, function (_b) {
1386
+ switch (_b.label) {
1387
+ case 0:
1388
+ segment = segments[segmentKey];
1389
+ usedAttributes = new Set();
1390
+ collectAttributeKeysFromConditions(segment.conditions, usedAttributes);
1391
+ sourceFileInfo = getSourceFileInfo(context.repositorySourceRootDirectoryPath, context.rootDirectoryPath, projectConfig, "segment", segmentKey, { resolveAbsolutePath: context.devEditors.length > 0 });
1392
+ detail = {
1393
+ type: "segment",
1394
+ key: segmentKey,
1395
+ entity: segment,
1396
+ sourcePath: sourceFileInfo.sourcePath,
1397
+ editLinks: getEditorLinks(context.devEditors, sourceFileInfo),
1398
+ usage: {
1399
+ attributes: sortStrings(Array.from(usedAttributes)),
1400
+ messages: sortStrings(Array.from(segmentsUsedInMessages[segmentKey] || [])),
1401
+ },
1402
+ lastModified: getLastModified(context.historyIndex, "segment", segmentKey, set || undefined),
1403
+ };
1404
+ index.entities.segment.push(getEntitySummary(segment, "segment", segmentKey, context.historyIndex, set || undefined, {
1405
+ targets: sortStrings(Array.from(segmentTargets[segmentKey] || [])),
1406
+ }));
1407
+ return [4 /*yield*/, context.writer.write(path.join(outputDirectoryPath, "entities", "segment", "".concat(encodeKey(segmentKey), ".json")), detail)];
1408
+ case 1:
1409
+ _b.sent();
1410
+ _a = skippedEmptyHistoryCount;
1411
+ return [4 /*yield*/, writeHistoryPages(context.writer, path.join(outputDirectoryPath, "history", "segment", encodeKey(segmentKey)), getHistoryForEntity(context.historyIndex, "segment", segmentKey, set || undefined), { skipEmpty: true })];
1412
+ case 2:
1413
+ skippedEmptyHistoryCount = _a + _b.sent();
1414
+ return [2 /*return*/];
1415
+ }
1416
+ });
1417
+ }); })];
1418
+ case 17:
1419
+ _12.sent();
1342
1420
  context.progress.done(segmentsStartedAt, "(".concat(pluralize(segmentKeys.length, "segment"), ")"));
1343
1421
  targetsStartedAt = context.progress.step("Writing targets");
1344
- _14 = 0, targetKeys_2 = targetKeys;
1345
- _20.label = 34;
1346
- case 34:
1347
- if (!(_14 < targetKeys_2.length)) return [3 /*break*/, 38];
1348
- targetKey = targetKeys_2[_14];
1349
- target = targets[targetKey];
1350
- targetLocaleKeys = ((_19 = target.locales) === null || _19 === void 0 ? void 0 : _19.length) ? target.locales : localeKeys;
1351
- formatsByLocale = {};
1352
- formatRowsByLocale = {};
1353
- for (_15 = 0, targetLocaleKeys_2 = targetLocaleKeys; _15 < targetLocaleKeys_2.length; _15++) {
1354
- localeKey = targetLocaleKeys_2[_15];
1355
- formatsByLocale[localeKey] = context.runtime.resolveFormats(localeKey, locales, target);
1356
- formatRowsByLocale[localeKey] = getFormatRows(context.runtime, localeKey, locales, target);
1357
- }
1358
- sourceFileInfo = getSourceFileInfo(context.repositoryRootDirectoryPath, context.rootDirectoryPath, projectConfig, "target", targetKey);
1359
- detail = {
1360
- type: "target",
1361
- key: targetKey,
1362
- entity: target,
1363
- sourcePath: sourceFileInfo.sourcePath,
1364
- editLinks: getEditorLinks(context.devEditors, sourceFileInfo),
1365
- locales: targetLocaleKeys,
1366
- formatsByLocale: formatsByLocale,
1367
- formatRowsByLocale: formatRowsByLocale,
1368
- messages: targetMessages[targetKey],
1369
- lastModified: getLastModified(context.historyIndex, "target", targetKey, set || undefined),
1370
- };
1371
- index.entities.target.push(getEntitySummary(target, "target", targetKey, context.historyIndex, set || undefined, {
1372
- messageCount: targetMessages[targetKey].length,
1373
- }));
1374
- return [4 /*yield*/, writeJson(path.join(outputDirectoryPath, "entities", "target", "".concat(encodeKey(targetKey), ".json")), detail)];
1375
- case 35:
1376
- _20.sent();
1377
- return [4 /*yield*/, writeHistoryPages(path.join(outputDirectoryPath, "history", "target", encodeKey(targetKey)), getHistoryForEntity(context.historyIndex, "target", targetKey, set || undefined))];
1378
- case 36:
1379
- _20.sent();
1380
- _20.label = 37;
1381
- case 37:
1382
- _14++;
1383
- return [3 /*break*/, 34];
1384
- case 38:
1422
+ return [4 /*yield*/, mapWithConcurrency(targetKeys, 32, function (targetKey) { return __awaiter(_this, void 0, void 0, function () {
1423
+ var target, targetLocaleKeys, formatsByLocale, formatRowsByLocale, _i, targetLocaleKeys_2, localeKey, sourceFileInfo, detail, _a;
1424
+ var _b;
1425
+ return __generator(this, function (_c) {
1426
+ switch (_c.label) {
1427
+ case 0:
1428
+ target = targets[targetKey];
1429
+ targetLocaleKeys = ((_b = target.locales) === null || _b === void 0 ? void 0 : _b.length) ? target.locales : localeKeys;
1430
+ formatsByLocale = {};
1431
+ formatRowsByLocale = {};
1432
+ for (_i = 0, targetLocaleKeys_2 = targetLocaleKeys; _i < targetLocaleKeys_2.length; _i++) {
1433
+ localeKey = targetLocaleKeys_2[_i];
1434
+ formatsByLocale[localeKey] = context.runtime.resolveFormats(localeKey, locales, target);
1435
+ formatRowsByLocale[localeKey] = getFormatRows(context.runtime, localeKey, locales, target);
1436
+ }
1437
+ sourceFileInfo = getSourceFileInfo(context.repositorySourceRootDirectoryPath, context.rootDirectoryPath, projectConfig, "target", targetKey, { resolveAbsolutePath: context.devEditors.length > 0 });
1438
+ detail = {
1439
+ type: "target",
1440
+ key: targetKey,
1441
+ entity: target,
1442
+ sourcePath: sourceFileInfo.sourcePath,
1443
+ editLinks: getEditorLinks(context.devEditors, sourceFileInfo),
1444
+ locales: targetLocaleKeys,
1445
+ formatsByLocale: formatsByLocale,
1446
+ formatRowsByLocale: formatRowsByLocale,
1447
+ messages: targetMessages[targetKey],
1448
+ lastModified: getLastModified(context.historyIndex, "target", targetKey, set || undefined),
1449
+ };
1450
+ index.entities.target.push(getEntitySummary(target, "target", targetKey, context.historyIndex, set || undefined, {
1451
+ messageCount: targetMessages[targetKey].length,
1452
+ }));
1453
+ return [4 /*yield*/, context.writer.write(path.join(outputDirectoryPath, "entities", "target", "".concat(encodeKey(targetKey), ".json")), detail)];
1454
+ case 1:
1455
+ _c.sent();
1456
+ _a = skippedEmptyHistoryCount;
1457
+ return [4 /*yield*/, writeHistoryPages(context.writer, path.join(outputDirectoryPath, "history", "target", encodeKey(targetKey)), getHistoryForEntity(context.historyIndex, "target", targetKey, set || undefined), { skipEmpty: true })];
1458
+ case 2:
1459
+ skippedEmptyHistoryCount = _a + _c.sent();
1460
+ return [2 /*return*/];
1461
+ }
1462
+ });
1463
+ }); })];
1464
+ case 18:
1465
+ _12.sent();
1385
1466
  context.progress.done(targetsStartedAt, "(".concat(pluralize(targetKeys.length, "target"), ")"));
1386
1467
  indexStartedAt = context.progress.step("Writing catalog index");
1387
- for (_16 = 0, _17 = Object.keys(index.entities); _16 < _17.length; _16++) {
1388
- type = _17[_16];
1468
+ for (_9 = 0, _10 = Object.keys(index.entities); _9 < _10.length; _9++) {
1469
+ type = _10[_9];
1389
1470
  index.entities[type].sort(function (a, b) { return a.key.localeCompare(b.key); });
1390
1471
  }
1391
- return [4 /*yield*/, writeJson(path.join(outputDirectoryPath, "index.json"), index)];
1392
- case 39:
1393
- _20.sent();
1472
+ return [4 /*yield*/, context.writer.write(path.join(outputDirectoryPath, "index.json"), index)];
1473
+ case 19:
1474
+ _12.sent();
1394
1475
  context.progress.done(indexStartedAt);
1395
- context.progress.done(setStartedAt, "total");
1476
+ context.progress.done(setStartedAt, "total (".concat(pluralize(skippedEmptyHistoryCount, "empty history", "empty histories"), " skipped)"));
1396
1477
  return [2 /*return*/, index];
1397
1478
  }
1398
1479
  });
@@ -1424,7 +1505,7 @@ function copyCatalogAssets(outputDirectoryPath) {
1424
1505
  }
1425
1506
  function exportCatalog(runtime_1, rootDirectoryPath_1, projectConfig_1, datasource_1) {
1426
1507
  return __awaiter(this, arguments, void 0, function (runtime, rootDirectoryPath, projectConfig, datasource, options) {
1427
- var outputDirectoryPath, dataDirectoryPath, withTranslationSearch, withDuplicates, progress, stepStartedAt, devEditors, historyIndex, links, duplicateResultsBySet, _a, _b, context, executions, setIndexes, _i, executions_1, execution, outputRelativeDirectory, _c, _d, manifest;
1508
+ var outputDirectoryPath, dataDirectoryPath, withTranslationSearch, withDuplicates, progress, writer, stepStartedAt, devEditors, historyIndex, links, duplicateResultsBySet, _a, _b, context, executions, setIndexes, _i, executions_1, execution, outputRelativeDirectory, _c, _d, manifest;
1428
1509
  if (options === void 0) { options = {}; }
1429
1510
  return __generator(this, function (_e) {
1430
1511
  switch (_e.label) {
@@ -1436,6 +1517,7 @@ function exportCatalog(runtime_1, rootDirectoryPath_1, projectConfig_1, datasour
1436
1517
  withTranslationSearch = options.withTranslationSearch === true;
1437
1518
  withDuplicates = options.withDuplicates === true;
1438
1519
  progress = new CatalogProgressReporter(rootDirectoryPath, outputDirectoryPath);
1520
+ writer = new CatalogJsonWriter();
1439
1521
  progress.start({
1440
1522
  browserRouter: options.browserRouter !== false,
1441
1523
  sets: projectConfig.sets === true,
@@ -1485,6 +1567,7 @@ function exportCatalog(runtime_1, rootDirectoryPath_1, projectConfig_1, datasour
1485
1567
  context = {
1486
1568
  rootDirectoryPath: rootDirectoryPath,
1487
1569
  repositoryRootDirectoryPath: getRepositoryRootDirectoryPath(rootDirectoryPath),
1570
+ repositorySourceRootDirectoryPath: getRepositorySourceRootDirectoryPath(rootDirectoryPath),
1488
1571
  outputDirectoryPath: outputDirectoryPath,
1489
1572
  dataDirectoryPath: dataDirectoryPath,
1490
1573
  historyIndex: historyIndex,
@@ -1494,6 +1577,7 @@ function exportCatalog(runtime_1, rootDirectoryPath_1, projectConfig_1, datasour
1494
1577
  withTranslationSearch: withTranslationSearch,
1495
1578
  withDuplicates: withDuplicates,
1496
1579
  progress: progress,
1580
+ writer: writer,
1497
1581
  };
1498
1582
  stepStartedAt = progress.step("Discovering project sets");
1499
1583
  return [4 /*yield*/, runtime.getProjectSetExecutions(projectConfig, datasource)];
@@ -1504,7 +1588,7 @@ function exportCatalog(runtime_1, rootDirectoryPath_1, projectConfig_1, datasour
1504
1588
  : "(root)");
1505
1589
  setIndexes = {};
1506
1590
  stepStartedAt = progress.step("Writing project history");
1507
- return [4 /*yield*/, writeHistoryPages(path.join(dataDirectoryPath, "project", "history"), historyIndex.entries)];
1591
+ return [4 /*yield*/, writeHistoryPages(writer, path.join(dataDirectoryPath, "project", "history"), historyIndex.entries)];
1508
1592
  case 9:
1509
1593
  _e.sent();
1510
1594
  progress.done(stepStartedAt, "(".concat(pluralize(historyIndex.entries.length, "entry", "entries"), ")"));
@@ -1549,7 +1633,7 @@ function exportCatalog(runtime_1, rootDirectoryPath_1, projectConfig_1, datasour
1549
1633
  },
1550
1634
  counts: Object.fromEntries(Object.keys(setIndexes).map(function (key) { return [key, setIndexes[key].counts]; })),
1551
1635
  };
1552
- return [4 /*yield*/, writeJson(path.join(dataDirectoryPath, "manifest.json"), manifest)];
1636
+ return [4 /*yield*/, writer.write(path.join(dataDirectoryPath, "manifest.json"), manifest)];
1553
1637
  case 14:
1554
1638
  _e.sent();
1555
1639
  progress.done(stepStartedAt);