@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 +24 -0
- package/build/api/catalog.js +64 -142
- package/build/api/compile.js +12 -22
- package/build/api/detect.js +0 -16
- package/build/api/extract.js +5 -24
- package/build/api/extractors/babel.js +2 -10
- package/build/api/extractors/index.js +0 -12
- package/build/api/extractors/typescript.js +4 -17
- package/build/api/formats/csv.js +0 -15
- package/build/api/formats/index.js +1 -9
- package/build/api/formats/lingui.js +2 -18
- package/build/api/formats/minimal.js +5 -18
- package/build/api/formats/po-gettext.js +45 -79
- package/build/api/formats/po.js +6 -30
- package/build/api/help.js +3 -8
- package/build/api/index.js +8 -12
- package/build/api/locales.js +3 -12
- package/build/api/pseudoLocalize.js +5 -15
- package/build/api/stats.js +2 -8
- package/build/api/utils.js +11 -31
- package/build/lingui-add-locale.js +0 -3
- package/build/lingui-compile.js +24 -53
- package/build/lingui-extract-template.js +5 -14
- package/build/lingui-extract.js +26 -48
- package/build/lingui.js +5 -13
- package/build/services/translationIO.js +61 -85
- package/build/tests.js +2 -16
- package/package.json +12 -11
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
|
|
package/build/api/catalog.js
CHANGED
|
@@ -3,43 +3,28 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
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
|
|
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
|
-
});
|
|
56
|
+
});
|
|
73
57
|
|
|
74
|
-
|
|
75
|
-
|
|
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);
|
|
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));
|
|
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
|
-
});
|
|
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]: {
|
|
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), {
|
|
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];
|
|
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
|
-
|
|
250
|
-
getTranslation(locale) ||
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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(
|
|
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);
|
|
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
|
-
}
|
|
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,
|
|
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(
|
|
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
|
-
}
|
|
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
|
-
|
|
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);
|