@lingui/cli 3.17.0 → 3.17.2

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/CHANGELOG.md CHANGED
@@ -3,6 +3,30 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [3.17.2](https://github.com/lingui/js-lingui/compare/v3.17.1...v3.17.2) (2023-02-24)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * chain extract on watched file changes ([#1435](https://github.com/lingui/js-lingui/issues/1435)) ([5dd50d3](https://github.com/lingui/js-lingui/commit/5dd50d34152e7eb393437e5de3d35b3baf09e861))
12
+ * **cli:** fix version command ([#1413](https://github.com/lingui/js-lingui/issues/1413)) ([8bc212d](https://github.com/lingui/js-lingui/commit/8bc212d2846af5609d89f51efed952b089244e4e))
13
+
14
+
15
+
16
+
17
+
18
+ ## [3.17.1](https://github.com/lingui/js-lingui/compare/v3.17.0...v3.17.1) (2023-02-07)
19
+
20
+
21
+ ### Bug Fixes
22
+
23
+ * **build:** undeclared dependencies ([#1391](https://github.com/lingui/js-lingui/issues/1391)) ([f390ca4](https://github.com/lingui/js-lingui/commit/f390ca4517144344fcbbbf9c73a42a1a17d0e519))
24
+ * **compile:** remove verbose output when using flow with template ([#1388](https://github.com/lingui/js-lingui/issues/1388)) ([31316f9](https://github.com/lingui/js-lingui/commit/31316f938957dba8e908f9f60a452a2673a934ee))
25
+
26
+
27
+
28
+
29
+
6
30
  # [3.17.0](https://github.com/lingui/js-lingui/compare/v3.16.1...v3.17.0) (2023-02-01)
7
31
 
8
32
 
@@ -3,43 +3,28 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.getCatalogs = getCatalogs;
6
+ exports.cleanObsolete = exports.Catalog = void 0;
7
7
  exports.getCatalogForFile = getCatalogForFile;
8
8
  exports.getCatalogForMerge = getCatalogForMerge;
9
+ exports.getCatalogs = getCatalogs;
9
10
  exports.normalizeRelativePath = normalizeRelativePath;
10
11
  exports.order = order;
11
12
  exports.orderByMessageId = orderByMessageId;
12
13
  exports.orderByOrigin = orderByOrigin;
13
- exports.cleanObsolete = exports.Catalog = void 0;
14
-
15
14
  var _os = _interopRequireDefault(require("os"));
16
-
17
15
  var _fsExtra = _interopRequireDefault(require("fs-extra"));
18
-
19
16
  var _path = _interopRequireDefault(require("path"));
20
-
21
17
  var R = _interopRequireWildcard(require("ramda"));
22
-
23
18
  var _chalk = _interopRequireDefault(require("chalk"));
24
-
25
19
  var _glob = _interopRequireDefault(require("glob"));
26
-
27
20
  var _micromatch = _interopRequireDefault(require("micromatch"));
28
-
29
21
  var _normalizePath = _interopRequireDefault(require("normalize-path"));
30
-
31
22
  var _formats = _interopRequireDefault(require("./formats"));
32
-
33
23
  var _extractors = _interopRequireDefault(require("./extractors"));
34
-
35
24
  var _utils = require("./utils");
36
-
37
- function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
38
-
39
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
40
-
25
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
26
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
41
27
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
42
-
43
28
  const NAME = "{name}";
44
29
  const NAME_REPLACE_RE = /{name}/g;
45
30
  const LOCALE = "{locale}";
@@ -61,7 +46,6 @@ class Catalog {
61
46
  this.config = config;
62
47
  this.format = (0, _formats.default)(config.format);
63
48
  }
64
-
65
49
  async make(options) {
66
50
  const nextCatalog = await this.collect(options);
67
51
  if (!nextCatalog) return false;
@@ -69,22 +53,22 @@ class Catalog {
69
53
  const catalogs = this.merge(prevCatalogs, nextCatalog, {
70
54
  overwrite: options.overwrite,
71
55
  files: options.files
72
- }); // Map over all locales and post-process each catalog
56
+ });
73
57
 
74
- const cleanAndSort = R.map(R.pipe( // Clean obsolete messages
75
- options.clean ? cleanObsolete : R.identity, // Sort messages
58
+ // Map over all locales and post-process each catalog
59
+ const cleanAndSort = R.map(R.pipe(
60
+ // Clean obsolete messages
61
+ options.clean ? cleanObsolete : R.identity,
62
+ // Sort messages
76
63
  order(options.orderBy)));
77
64
  const sortedCatalogs = cleanAndSort(catalogs);
78
-
79
65
  if (options.locale) {
80
66
  this.write(options.locale, sortedCatalogs[options.locale]);
81
67
  } else {
82
68
  this.writeAll(sortedCatalogs);
83
69
  }
84
-
85
70
  return true;
86
71
  }
87
-
88
72
  async makeTemplate(options) {
89
73
  const catalog = await this.collect(options);
90
74
  if (!catalog) return false;
@@ -92,31 +76,25 @@ class Catalog {
92
76
  this.writeTemplate(sort(catalog));
93
77
  return true;
94
78
  }
79
+
95
80
  /**
96
81
  * Collect messages from source paths. Return a raw message catalog as JSON.
97
82
  */
98
-
99
-
100
83
  async collect(options) {
101
84
  const tmpDir = _path.default.join(_os.default.tmpdir(), `lingui-${process.pid}`);
102
-
103
85
  if (_fsExtra.default.existsSync(tmpDir)) {
104
86
  (0, _utils.removeDirectory)(tmpDir, true);
105
87
  } else {
106
88
  _fsExtra.default.mkdirSync(tmpDir);
107
89
  }
108
-
109
90
  try {
110
91
  let paths = this.sourcePaths;
111
-
112
92
  if (options.files) {
113
93
  options.files = options.files.map(p => (0, _normalizePath.default)(p, false));
114
94
  const regex = new RegExp(options.files.join("|"), "i");
115
95
  paths = paths.filter(path => regex.test(path));
116
96
  }
117
-
118
97
  let catalogSuccess = true;
119
-
120
98
  for (let filename of paths) {
121
99
  const fileSuccess = await (0, _extractors.default)(filename, tmpDir, {
122
100
  verbose: options.verbose,
@@ -127,18 +105,14 @@ class Catalog {
127
105
  });
128
106
  catalogSuccess && (catalogSuccess = fileSuccess);
129
107
  }
130
-
131
108
  if (!catalogSuccess) return undefined;
132
109
  return function traverse(directory) {
133
110
  return _fsExtra.default.readdirSync(directory).map(filename => {
134
111
  const filepath = _path.default.join(directory, filename);
135
-
136
112
  if (_fsExtra.default.lstatSync(filepath).isDirectory()) {
137
113
  return traverse(filepath);
138
114
  }
139
-
140
115
  if (!filename.endsWith(".json")) return;
141
-
142
116
  try {
143
117
  return JSON.parse(_fsExtra.default.readFileSync(filepath).toString());
144
118
  } catch (e) {}
@@ -150,20 +124,21 @@ class Catalog {
150
124
  (0, _utils.removeDirectory)(tmpDir);
151
125
  }
152
126
  }
153
-
154
127
  merge(prevCatalogs, nextCatalog, options) {
155
128
  const nextKeys = R.keys(nextCatalog).map(String);
156
129
  return R.mapObjIndexed((prevCatalog, locale) => {
157
130
  const prevKeys = R.keys(prevCatalog).map(String);
158
131
  const newKeys = R.difference(nextKeys, prevKeys);
159
132
  const mergeKeys = R.intersection(nextKeys, prevKeys);
160
- const obsoleteKeys = R.difference(prevKeys, nextKeys); // Initialize new catalog with new keys
133
+ const obsoleteKeys = R.difference(prevKeys, nextKeys);
161
134
 
135
+ // Initialize new catalog with new keys
162
136
  const newMessages = R.mapObjIndexed((message, key) => ({
163
137
  translation: this.config.sourceLocale === locale ? message.message || key : "",
164
138
  ...message
165
- }), R.pick(newKeys, nextCatalog)); // Merge translations from previous catalog
139
+ }), R.pick(newKeys, nextCatalog));
166
140
 
141
+ // Merge translations from previous catalog
167
142
  const mergedMessages = mergeKeys.map(key => {
168
143
  const updateFromDefaults = this.config.sourceLocale === locale && (prevCatalog[key].translation === prevCatalog[key].message || options.overwrite);
169
144
  const translation = updateFromDefaults ? nextCatalog[key].message || key : prevCatalog[key].translation;
@@ -173,40 +148,36 @@ class Catalog {
173
148
  ...R.omit(["obsolete, translation"], nextCatalog[key])
174
149
  }
175
150
  };
176
- }); // Mark all remaining translations as obsolete
177
- // Only if *options.files* is not provided
151
+ });
178
152
 
153
+ // Mark all remaining translations as obsolete
154
+ // Only if *options.files* is not provided
179
155
  const obsoleteMessages = obsoleteKeys.map(key => ({
180
- [key]: { ...prevCatalog[key],
156
+ [key]: {
157
+ ...prevCatalog[key],
181
158
  obsolete: options.files ? false : true
182
159
  }
183
160
  }));
184
161
  return R.mergeAll([newMessages, ...mergedMessages, ...obsoleteMessages]);
185
162
  }, prevCatalogs);
186
163
  }
187
-
188
164
  getTranslations(locale, options) {
189
165
  const catalogs = this.readAll();
190
166
  const template = this.readTemplate() || {};
191
- return R.mapObjIndexed((_value, key) => this.getTranslation(catalogs, locale, key, options), { ...template,
167
+ return R.mapObjIndexed((_value, key) => this.getTranslation(catalogs, locale, key, options), {
168
+ ...template,
192
169
  ...catalogs[locale]
193
170
  });
194
171
  }
195
-
196
172
  getTranslation(catalogs, locale, key, {
197
173
  fallbackLocales,
198
174
  sourceLocale
199
175
  }) {
176
+ var _catalog$key;
200
177
  const catalog = catalogs[locale] || {};
201
-
202
- if (!catalog.hasOwnProperty(key)) {
203
- console.error(`Message with key ${key} is missing in locale ${locale}`);
204
- }
205
-
206
178
  const getTranslation = _locale => {
207
179
  const configLocales = this.config.locales.join('", "');
208
180
  const localeCatalog = catalogs[_locale] || {};
209
-
210
181
  if (!localeCatalog) {
211
182
  console.warn(`
212
183
  Catalog "${_locale}" isn't present in locales config parameter
@@ -217,24 +188,19 @@ class Catalog {
217
188
  `);
218
189
  return null;
219
190
  }
220
-
221
191
  if (!localeCatalog.hasOwnProperty(key)) {
222
- console.error(`Message with key ${key} is missing in locale ${_locale}`);
223
192
  return null;
224
193
  }
225
-
226
194
  if (catalogs[_locale]) {
227
195
  return catalogs[_locale][key].translation;
228
196
  }
229
-
230
197
  return null;
231
198
  };
232
-
233
199
  const getMultipleFallbacks = _locale => {
234
- const fL = fallbackLocales && fallbackLocales[_locale]; // some probably the fallback will be undefined, so just search by locale
200
+ const fL = fallbackLocales && fallbackLocales[_locale];
235
201
 
202
+ // some probably the fallback will be undefined, so just search by locale
236
203
  if (!fL) return null;
237
-
238
204
  if (Array.isArray(fL)) {
239
205
  for (const fallbackLocale of fL) {
240
206
  if (catalogs[fallbackLocale]) {
@@ -245,56 +211,51 @@ class Catalog {
245
211
  return getTranslation(fL);
246
212
  }
247
213
  };
248
-
249
- return (// Get translation in target locale
250
- getTranslation(locale) || // We search in fallbackLocales as dependent of each locale
251
- getMultipleFallbacks(locale) || // Get translation in fallbackLocales.default (if any)
252
- fallbackLocales?.default && getTranslation(fallbackLocales.default) || // Get message default
253
- catalog[key]?.defaults || // If sourceLocale is either target locale of fallback one, use key
254
- sourceLocale && sourceLocale === locale && key || sourceLocale && fallbackLocales?.default && sourceLocale === fallbackLocales.default && key || // Otherwise no translation is available
214
+ return (
215
+ // Get translation in target locale
216
+ getTranslation(locale) ||
217
+ // We search in fallbackLocales as dependent of each locale
218
+ getMultipleFallbacks(locale) ||
219
+ // Get translation in fallbackLocales.default (if any)
220
+ (fallbackLocales === null || fallbackLocales === void 0 ? void 0 : fallbackLocales.default) && getTranslation(fallbackLocales.default) || ( // Get message default
221
+ (_catalog$key = catalog[key]) === null || _catalog$key === void 0 ? void 0 : _catalog$key.defaults) ||
222
+ // If sourceLocale is either target locale of fallback one, use key
223
+ sourceLocale && sourceLocale === locale && key || sourceLocale && (fallbackLocales === null || fallbackLocales === void 0 ? void 0 : fallbackLocales.default) && sourceLocale === fallbackLocales.default && key ||
224
+ // Otherwise no translation is available
255
225
  undefined
256
226
  );
257
227
  }
258
-
259
228
  write(locale, messages) {
260
229
  const filename = this.path.replace(LOCALE_REPLACE_RE, locale) + this.format.catalogExtension;
261
230
  const created = !_fsExtra.default.existsSync(filename);
262
-
263
231
  const basedir = _path.default.dirname(filename);
264
-
265
232
  if (!_fsExtra.default.existsSync(basedir)) {
266
233
  _fsExtra.default.mkdirpSync(basedir);
267
234
  }
268
-
269
- const options = { ...this.config.formatOptions,
235
+ const options = {
236
+ ...this.config.formatOptions,
270
237
  locale
271
238
  };
272
239
  this.format.write(filename, messages, options);
273
240
  return [created, filename];
274
241
  }
275
-
276
242
  writeAll(catalogs) {
277
243
  this.locales.forEach(locale => this.write(locale, catalogs[locale]));
278
244
  }
279
-
280
245
  writeTemplate(messages) {
281
246
  const filename = this.templateFile;
282
-
283
247
  const basedir = _path.default.dirname(filename);
284
-
285
248
  if (!_fsExtra.default.existsSync(basedir)) {
286
249
  _fsExtra.default.mkdirpSync(basedir);
287
250
  }
288
-
289
- const options = { ...this.config.formatOptions,
251
+ const options = {
252
+ ...this.config.formatOptions,
290
253
  locale: undefined
291
254
  };
292
255
  this.format.write(filename, messages, options);
293
256
  }
294
-
295
257
  writeCompiled(locale, compiledCatalog, namespace) {
296
258
  let ext;
297
-
298
259
  if (namespace === "es") {
299
260
  ext = "mjs";
300
261
  } else if (namespace === "ts") {
@@ -302,38 +263,29 @@ class Catalog {
302
263
  } else {
303
264
  ext = "js";
304
265
  }
305
-
306
266
  const filename = `${this.path.replace(LOCALE_REPLACE_RE, locale)}.${ext}`;
307
-
308
267
  const basedir = _path.default.dirname(filename);
309
-
310
268
  if (!_fsExtra.default.existsSync(basedir)) {
311
269
  _fsExtra.default.mkdirpSync(basedir);
312
270
  }
313
-
314
271
  _fsExtra.default.writeFileSync(filename, compiledCatalog);
315
-
316
272
  return filename;
317
273
  }
318
-
319
274
  read(locale) {
320
275
  const filename = this.path.replace(LOCALE_REPLACE_RE, locale) + this.format.catalogExtension;
321
276
  if (!_fsExtra.default.existsSync(filename)) return null;
322
277
  return this.format.read(filename);
323
278
  }
324
-
325
279
  readAll() {
326
280
  return R.mergeAll(this.locales.map(locale => ({
327
281
  [locale]: this.read(locale)
328
282
  })));
329
283
  }
330
-
331
284
  readTemplate() {
332
285
  const filename = this.templateFile;
333
286
  if (!_fsExtra.default.existsSync(filename)) return null;
334
287
  return this.format.read(filename);
335
288
  }
336
-
337
289
  get sourcePaths() {
338
290
  const includeGlobs = this.include.map(includePath => {
339
291
  const isDir = _fsExtra.default.existsSync(includePath) && _fsExtra.default.lstatSync(includePath).isDirectory();
@@ -341,8 +293,6 @@ class Catalog {
341
293
  * glob library results from absolute patterns such as /foo/* are mounted onto the root setting using path.join.
342
294
  * On windows, this will by default result in /foo/* matching C:\foo\bar.txt.
343
295
  */
344
-
345
-
346
296
  return isDir ? (0, _normalizePath.default)(_path.default.resolve(process.cwd(), includePath === "/" ? "" : includePath, "**/*.*")) : includePath;
347
297
  });
348
298
  const patterns = includeGlobs.length > 1 ? `{${includeGlobs.join(",")}}` : includeGlobs[0];
@@ -351,33 +301,25 @@ class Catalog {
351
301
  mark: true
352
302
  });
353
303
  }
354
-
355
304
  get templateFile() {
356
305
  return this.path.replace(LOCALE_SUFFIX_RE, "messages.pot");
357
306
  }
358
-
359
307
  get localeDir() {
360
308
  const localePatternIndex = this.path.indexOf(LOCALE);
361
-
362
309
  if (localePatternIndex === -1) {
363
310
  throw Error(`Invalid catalog path: ${LOCALE} variable is missing`);
364
311
  }
365
-
366
312
  return this.path.substr(0, localePatternIndex);
367
313
  }
368
-
369
314
  get locales() {
370
315
  return this.config.locales;
371
316
  }
372
-
373
317
  }
318
+
374
319
  /**
375
320
  * Parse `config.catalogs` and return a list of configured Catalog instances.
376
321
  */
377
-
378
-
379
322
  exports.Catalog = Catalog;
380
-
381
323
  function getCatalogs(config) {
382
324
  const catalogsConfig = config.catalogs;
383
325
  const catalogs = [];
@@ -386,30 +328,30 @@ function getCatalogs(config) {
386
328
  if (catalog.path.endsWith(PATHSEP)) {
387
329
  const extension = (0, _formats.default)(config.format).catalogExtension;
388
330
  const correctPath = catalog.path.slice(0, -1);
389
- const examplePath = correctPath.replace(LOCALE_REPLACE_RE, // Show example using one of configured locales (if any)
331
+ const examplePath = correctPath.replace(LOCALE_REPLACE_RE,
332
+ // Show example using one of configured locales (if any)
390
333
  (config.locales || [])[0] || "en") + extension;
391
- throw new Error( // prettier-ignore
334
+ throw new Error(
335
+ // prettier-ignore
392
336
  `Remove trailing slash from "${catalog.path}". Catalog path isn't a directory,` + ` but translation file without extension. For example, catalog path "${correctPath}"` + ` results in translation file "${examplePath}".`);
393
337
  }
394
-
395
338
  const include = ensureArray(catalog.include).map(normalizeRelativePath);
396
- const exclude = ensureArray(catalog.exclude).map(normalizeRelativePath); // catalog.path without {name} pattern -> always refers to a single catalog
339
+ const exclude = ensureArray(catalog.exclude).map(normalizeRelativePath);
397
340
 
341
+ // catalog.path without {name} pattern -> always refers to a single catalog
398
342
  if (!catalog.path.includes(NAME)) {
399
343
  // Validate that sourcePaths doesn't use {name} pattern either
400
344
  const invalidSource = include.find(path => path.includes(NAME));
401
-
402
345
  if (invalidSource !== undefined) {
403
346
  throw new Error(`Catalog with path "${catalog.path}" doesn't have a {name} pattern` + ` in it, but one of source directories uses it: "${invalidSource}".` + ` Either add {name} pattern to "${catalog.path}" or remove it` + ` from all source directories.`);
404
- } // catalog name is the last directory of catalog.path.
405
- // If the last part is {locale}, then catalog doesn't have an explicit name
406
-
347
+ }
407
348
 
349
+ // catalog name is the last directory of catalog.path.
350
+ // If the last part is {locale}, then catalog doesn't have an explicit name
408
351
  const name = function () {
409
352
  const _name = catalog.path.split(PATHSEP).slice(-1)[0];
410
353
  return _name !== LOCALE ? _name : null;
411
354
  }();
412
-
413
355
  catalogs.push(new Catalog({
414
356
  name,
415
357
  path: normalizeRelativePath(catalog.path),
@@ -418,17 +360,13 @@ function getCatalogs(config) {
418
360
  }, config));
419
361
  return;
420
362
  }
421
-
422
363
  const patterns = include.map(path => path.replace(NAME_REPLACE_RE, "*"));
423
-
424
364
  const candidates = _glob.default.sync(patterns.length > 1 ? `{${patterns.join(",")}}` : patterns[0], {
425
365
  ignore: exclude,
426
366
  mark: true
427
367
  });
428
-
429
368
  candidates.forEach(catalogDir => {
430
369
  const name = _path.default.basename(catalogDir);
431
-
432
370
  catalogs.push(new Catalog({
433
371
  name,
434
372
  path: normalizeRelativePath(catalog.path.replace(NAME_REPLACE_RE, name)),
@@ -439,14 +377,11 @@ function getCatalogs(config) {
439
377
  });
440
378
  return catalogs;
441
379
  }
442
-
443
380
  function getCatalogForFile(file, catalogs) {
444
381
  for (const catalog of catalogs) {
445
382
  const catalogFile = `${catalog.path}${catalog.format.catalogExtension}`;
446
383
  const catalogGlob = catalogFile.replace(LOCALE_REPLACE_RE, "*");
447
-
448
384
  const match = _micromatch.default.capture(normalizeRelativePath(_path.default.relative(catalog.config.rootDir, catalogGlob)), normalizeRelativePath(file));
449
-
450
385
  if (match) {
451
386
  return {
452
387
  locale: match[0],
@@ -454,34 +389,31 @@ function getCatalogForFile(file, catalogs) {
454
389
  };
455
390
  }
456
391
  }
457
-
458
392
  return null;
459
393
  }
394
+
460
395
  /**
461
396
  * Create catalog for merged messages.
462
397
  */
463
-
464
-
465
398
  function getCatalogForMerge(config) {
466
399
  const catalogConfig = config;
467
-
468
400
  if (catalogConfig.catalogsMergePath.endsWith(PATHSEP)) {
469
401
  const extension = (0, _formats.default)(config.format).catalogExtension;
470
402
  const correctPath = catalogConfig.catalogsMergePath.slice(0, -1);
471
- const examplePath = correctPath.replace(LOCALE_REPLACE_RE, // Show example using one of configured locales (if any)
403
+ const examplePath = correctPath.replace(LOCALE_REPLACE_RE,
404
+ // Show example using one of configured locales (if any)
472
405
  (config.locales || [])[0] || "en") + extension;
473
- throw new Error( // prettier-ignore
406
+ throw new Error(
407
+ // prettier-ignore
474
408
  `Remove trailing slash from "${catalogConfig.catalogsMergePath}". Catalog path isn't a directory,` + ` but translation file without extension. For example, catalog path "${correctPath}"` + ` results in translation file "${examplePath}".`);
475
- } // catalog name is the last directory of catalogPath.
476
- // If the last part is {locale}, then catalog doesn't have an explicit name
477
-
409
+ }
478
410
 
411
+ // catalog name is the last directory of catalogPath.
412
+ // If the last part is {locale}, then catalog doesn't have an explicit name
479
413
  const name = function () {
480
414
  const _name = _path.default.basename(normalizeRelativePath(catalogConfig.catalogsMergePath));
481
-
482
415
  return _name !== LOCALE ? _name : null;
483
416
  }();
484
-
485
417
  const catalog = new Catalog({
486
418
  name,
487
419
  path: normalizeRelativePath(catalogConfig.catalogsMergePath),
@@ -490,65 +422,57 @@ function getCatalogForMerge(config) {
490
422
  }, config);
491
423
  return catalog;
492
424
  }
425
+
493
426
  /**
494
427
  * Merge origins and extractedComments for messages found in different places. All other attributes
495
428
  * should be the same (raise an error if defaults are different).
496
429
  */
497
-
498
-
499
430
  function mergeOriginsAndExtractedComments(msgId, prev, next) {
500
431
  if (prev.defaults !== next.defaults) {
501
432
  throw new Error(`Encountered different defaults for message ${_chalk.default.yellow(msgId)}` + `\n${_chalk.default.yellow((0, _utils.prettyOrigin)(prev.origin))} ${prev.defaults}` + `\n${_chalk.default.yellow((0, _utils.prettyOrigin)(next.origin))} ${next.defaults}`);
502
433
  }
503
-
504
- return { ...next,
434
+ return {
435
+ ...next,
505
436
  extractedComments: R.concat(prev.extractedComments, next.extractedComments),
506
437
  origin: R.concat(prev.origin, next.origin)
507
438
  };
508
439
  }
440
+
509
441
  /**
510
442
  * Ensure that value is always array. If not, turn it into an array of one element.
511
443
  */
512
-
513
-
514
444
  const ensureArray = value => {
515
445
  if (value == null) return [];
516
446
  return Array.isArray(value) ? value : [value];
517
447
  };
448
+
518
449
  /**
519
450
  * Remove ./ at the beginning: ./relative => relative
520
451
  * relative => relative
521
452
  * Preserve directories: ./relative/ => relative/
522
453
  * Preserve absolute paths: /absolute/path => /absolute/path
523
454
  */
524
-
525
-
526
455
  function normalizeRelativePath(sourcePath) {
527
456
  if (_path.default.isAbsolute(sourcePath)) {
528
457
  // absolute path
529
458
  return (0, _normalizePath.default)(sourcePath, false);
530
459
  }
531
-
532
460
  const isDir = _fsExtra.default.existsSync(sourcePath) && _fsExtra.default.lstatSync(sourcePath).isDirectory();
533
-
534
461
  return (0, _normalizePath.default)(_path.default.relative(process.cwd(), sourcePath), false) + (isDir ? "/" : "");
535
462
  }
536
-
537
463
  const cleanObsolete = R.filter(message => !message.obsolete);
538
464
  exports.cleanObsolete = cleanObsolete;
539
-
540
465
  function order(by) {
541
466
  return {
542
467
  messageId: orderByMessageId,
543
468
  origin: orderByOrigin
544
469
  }[by];
545
470
  }
471
+
546
472
  /**
547
473
  * Object keys are in the same order as they were created
548
474
  * https://stackoverflow.com/a/31102605/1535540
549
475
  */
550
-
551
-
552
476
  function orderByMessageId(messages) {
553
477
  const orderedMessages = {};
554
478
  Object.keys(messages).sort().forEach(function (key) {
@@ -556,7 +480,6 @@ function orderByMessageId(messages) {
556
480
  });
557
481
  return orderedMessages;
558
482
  }
559
-
560
483
  function orderByOrigin(messages) {
561
484
  function getFirstOrigin(messageKey) {
562
485
  const sortedOrigins = messages[messageKey].origin.sort((a, b) => {
@@ -566,7 +489,6 @@ function orderByOrigin(messages) {
566
489
  });
567
490
  return sortedOrigins[0];
568
491
  }
569
-
570
492
  return Object.keys(messages).sort(function (a, b) {
571
493
  const [aFile, aLineNumber] = getFirstOrigin(a);
572
494
  const [bFile, bLineNumber] = getFirstOrigin(b);