@lingui/cli 3.17.2 → 4.0.0-next.1
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/build/api/catalog/extractFromFiles.js +45 -0
- package/build/api/catalog/getCatalogs.js +129 -0
- package/build/api/catalog/getTranslationsForCatalog.js +77 -0
- package/build/api/catalog/mergeCatalog.js +44 -0
- package/build/api/catalog.js +75 -336
- package/build/api/compile.js +0 -12
- package/build/api/extractors/babel.js +67 -24
- package/build/api/extractors/index.js +8 -11
- package/build/api/extractors/typescript.js +2 -46
- package/build/api/formats/csv.js +4 -2
- package/build/api/formats/index.js +1 -1
- package/build/api/formats/lingui.js +4 -3
- package/build/api/formats/minimal.js +8 -14
- package/build/api/formats/po-gettext.js +89 -126
- package/build/api/formats/po.js +92 -61
- package/build/api/generateMessageId.js +12 -0
- package/build/api/help.js +3 -3
- package/build/api/index.js +31 -6
- package/build/api/types.js +5 -0
- package/build/api/utils.js +77 -53
- package/build/lingui-compile.js +32 -50
- package/build/lingui-extract-template.js +17 -26
- package/build/lingui-extract.js +36 -54
- package/build/lingui.js +2 -5
- package/build/services/translationIO.js +7 -3
- package/build/tests.js +55 -10
- package/package.json +16 -21
- package/CHANGELOG.md +0 -530
- package/build/api/detect.js +0 -52
- package/build/api/extract.js +0 -59
- package/build/api/locales.js +0 -36
- package/build/lingui-add-locale.js +0 -8
package/build/api/formats/po.js
CHANGED
|
@@ -4,74 +4,101 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
exports.deserialize = deserialize;
|
|
8
|
+
exports.serialize = void 0;
|
|
9
9
|
var _dateFns = require("date-fns");
|
|
10
10
|
var _pofile = _interopRequireDefault(require("pofile"));
|
|
11
11
|
var _utils = require("../utils");
|
|
12
|
-
|
|
13
|
-
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; }
|
|
12
|
+
var _generateMessageId = require("../generateMessageId");
|
|
14
13
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
14
|
+
function isGeneratedId(id, message) {
|
|
15
|
+
return id === (0, _generateMessageId.generateMessageId)(message.message, message.context);
|
|
16
|
+
}
|
|
17
|
+
function getCreateHeaders(language = "no") {
|
|
18
|
+
return {
|
|
19
|
+
"POT-Creation-Date": (0, _dateFns.format)(new Date(), "yyyy-MM-dd HH:mmxxxx"),
|
|
20
|
+
"MIME-Version": "1.0",
|
|
21
|
+
"Content-Type": "text/plain; charset=utf-8",
|
|
22
|
+
"Content-Transfer-Encoding": "8bit",
|
|
23
|
+
"X-Generator": "@lingui/cli",
|
|
24
|
+
Language: language
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
const EXPLICIT_ID_FLAG = "explicit-id";
|
|
28
|
+
const serialize = (catalog, options, postProcessItem) => {
|
|
29
|
+
return Object.keys(catalog).map(id => {
|
|
30
|
+
const message = catalog[id];
|
|
31
|
+
const item = new _pofile.default.Item();
|
|
32
|
+
|
|
33
|
+
// The extractedComments array may be modified in this method,
|
|
34
|
+
// so create a new array with the message's elements.
|
|
35
|
+
item.extractedComments = [...(message.extractedComments || [])];
|
|
36
|
+
item.flags = (message.flags || []).reduce((acc, flag) => {
|
|
37
|
+
acc[flag] = true;
|
|
38
|
+
return acc;
|
|
39
|
+
}, {});
|
|
40
|
+
const _isGeneratedId = isGeneratedId(id, message);
|
|
41
|
+
if (_isGeneratedId) {
|
|
42
|
+
item.msgid = message.message;
|
|
43
|
+
if (!item.extractedComments.find(c => c.includes("js-lingui-id"))) {
|
|
44
|
+
item.extractedComments.push(`js-lingui-id: ${id}`);
|
|
45
|
+
}
|
|
35
46
|
} else {
|
|
36
|
-
item.
|
|
47
|
+
item.flags[EXPLICIT_ID_FLAG] = true;
|
|
48
|
+
item.msgid = id;
|
|
37
49
|
}
|
|
50
|
+
if (message.context) {
|
|
51
|
+
item.msgctxt = message.context;
|
|
52
|
+
}
|
|
53
|
+
item.msgstr = [message.translation];
|
|
54
|
+
item.comments = message.comments || [];
|
|
55
|
+
if (options.origins !== false) {
|
|
56
|
+
if (message.origin && options.lineNumbers === false) {
|
|
57
|
+
item.references = message.origin.map(([path]) => path);
|
|
58
|
+
} else {
|
|
59
|
+
item.references = message.origin ? message.origin.map(_utils.joinOrigin) : [];
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
item.obsolete = message.obsolete;
|
|
63
|
+
return postProcessItem ? postProcessItem(item, message, id, _isGeneratedId) : item;
|
|
64
|
+
});
|
|
65
|
+
};
|
|
66
|
+
exports.serialize = serialize;
|
|
67
|
+
function deserialize(items, onItem) {
|
|
68
|
+
return items.reduce((catalog, item) => {
|
|
69
|
+
onItem(item);
|
|
70
|
+
const message = {
|
|
71
|
+
translation: item.msgstr[0],
|
|
72
|
+
extractedComments: item.extractedComments || [],
|
|
73
|
+
comments: item.comments || [],
|
|
74
|
+
context: item.msgctxt ?? null,
|
|
75
|
+
obsolete: item.flags.obsolete || item.obsolete,
|
|
76
|
+
origin: (item.references || []).map(ref => (0, _utils.splitOrigin)(ref)),
|
|
77
|
+
flags: Object.keys(item.flags).map(flag => flag.trim())
|
|
78
|
+
};
|
|
79
|
+
let id = item.msgid;
|
|
80
|
+
|
|
81
|
+
// if generated id, recreate it
|
|
82
|
+
if (!item.flags[EXPLICIT_ID_FLAG]) {
|
|
83
|
+
id = (0, _generateMessageId.generateMessageId)(item.msgid, item.msgctxt);
|
|
84
|
+
message.message = item.msgid;
|
|
85
|
+
}
|
|
86
|
+
catalog[id] = message;
|
|
87
|
+
return catalog;
|
|
88
|
+
}, {});
|
|
89
|
+
}
|
|
90
|
+
function validateItem(item) {
|
|
91
|
+
if (item.msgstr.length > 1) {
|
|
92
|
+
console.warn(`Multiple translations for item with key ${item.msgid} is not supported and it will be ignored.`);
|
|
38
93
|
}
|
|
39
|
-
|
|
40
|
-
item.obsolete = message.obsolete;
|
|
41
|
-
item.flags = message.flags ? R.fromPairs(message.flags.map(flag => [flag, true])) : {};
|
|
42
|
-
return item;
|
|
43
|
-
}))(items);
|
|
44
|
-
const getMessageKey = R.prop("msgid");
|
|
45
|
-
const getTranslations = R.prop("msgstr");
|
|
46
|
-
const getExtractedComments = R.prop("extractedComments");
|
|
47
|
-
const getTranslatorComments = R.prop("comments");
|
|
48
|
-
const getMessageContext = R.prop("msgctxt");
|
|
49
|
-
const getOrigins = R.prop("references");
|
|
50
|
-
const getFlags = R.compose(R.map(R.trim), R.keys, R.dissoc("obsolete"),
|
|
51
|
-
// backward-compatibility, remove in 3.x
|
|
52
|
-
R.prop("flags"));
|
|
53
|
-
const isObsolete = R.either(R.path(["flags", "obsolete"]), R.prop("obsolete"));
|
|
54
|
-
const deserialize = R.map(R.applySpec({
|
|
55
|
-
translation: R.compose(R.head, R.defaultTo([]), getTranslations),
|
|
56
|
-
extractedComments: R.compose(R.defaultTo([]), getExtractedComments),
|
|
57
|
-
comments: R.compose(R.defaultTo([]), getTranslatorComments),
|
|
58
|
-
context: R.compose(R.defaultTo(null), getMessageContext),
|
|
59
|
-
obsolete: isObsolete,
|
|
60
|
-
origin: R.compose(R.map(_utils.splitOrigin), R.defaultTo([]), getOrigins),
|
|
61
|
-
flags: getFlags
|
|
62
|
-
}));
|
|
63
|
-
const validateItems = R.forEach(item => {
|
|
64
|
-
if (R.length(getTranslations(item)) > 1) {
|
|
65
|
-
console.warn("Multiple translations for item with key %s is not supported and it will be ignored.", getMessageKey(item));
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
const indexItems = R.indexBy(getMessageKey);
|
|
94
|
+
}
|
|
69
95
|
const po = {
|
|
70
96
|
catalogExtension: ".po",
|
|
97
|
+
templateExtension: ".pot",
|
|
71
98
|
write(filename, catalog, options) {
|
|
72
99
|
let po;
|
|
73
|
-
|
|
74
|
-
|
|
100
|
+
const raw = (0, _utils.readFile)(filename);
|
|
101
|
+
if (raw) {
|
|
75
102
|
po = _pofile.default.parse(raw);
|
|
76
103
|
} else {
|
|
77
104
|
po = new _pofile.default();
|
|
@@ -79,19 +106,23 @@ const po = {
|
|
|
79
106
|
if (options.locale === undefined) {
|
|
80
107
|
delete po.headers.Language;
|
|
81
108
|
}
|
|
82
|
-
|
|
109
|
+
// accessing private property
|
|
110
|
+
;
|
|
111
|
+
po.headerOrder = Object.keys(po.headers);
|
|
83
112
|
}
|
|
84
113
|
po.items = serialize(catalog, options);
|
|
85
114
|
(0, _utils.writeFileIfChanged)(filename, po.toString());
|
|
86
115
|
},
|
|
87
116
|
read(filename) {
|
|
88
|
-
const raw =
|
|
117
|
+
const raw = (0, _utils.readFile)(filename);
|
|
118
|
+
if (!raw) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
89
121
|
return this.parse(raw);
|
|
90
122
|
},
|
|
91
123
|
parse(raw) {
|
|
92
124
|
const po = _pofile.default.parse(raw);
|
|
93
|
-
|
|
94
|
-
return deserialize(indexItems(po.items));
|
|
125
|
+
return deserialize(po.items, validateItem);
|
|
95
126
|
}
|
|
96
127
|
};
|
|
97
128
|
var _default = po;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.generateMessageId = generateMessageId;
|
|
7
|
+
var _crypto = _interopRequireDefault(require("crypto"));
|
|
8
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
9
|
+
const UNIT_SEPARATOR = "\u001F";
|
|
10
|
+
function generateMessageId(msg, context = "") {
|
|
11
|
+
return _crypto.default.createHash("sha256").update(msg + UNIT_SEPARATOR + (context || "")).digest("base64").slice(0, 6);
|
|
12
|
+
}
|
package/build/api/help.js
CHANGED
|
@@ -36,7 +36,7 @@ function helpRun(command) {
|
|
|
36
36
|
command = res[0];
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
|
+
const isYarn = process.env.npm_config_user_agent && process.env.npm_config_user_agent.includes("yarn");
|
|
40
|
+
const runCommand = isYarn ? "yarn" : "npm run";
|
|
39
41
|
return `${runCommand} ${command}`;
|
|
40
|
-
}
|
|
41
|
-
const isYarn = process.env.npm_config_user_agent && process.env.npm_config_user_agent.includes("yarn");
|
|
42
|
-
const runCommand = isYarn ? "yarn" : "npm run";
|
|
42
|
+
}
|
package/build/api/index.js
CHANGED
|
@@ -3,31 +3,56 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
var _exportNames = {
|
|
7
|
+
getFormat: true,
|
|
8
|
+
getCatalogForFile: true,
|
|
9
|
+
getCatalogs: true,
|
|
10
|
+
createCompiledCatalog: true,
|
|
11
|
+
generateMessageId: true
|
|
12
|
+
};
|
|
6
13
|
Object.defineProperty(exports, "createCompiledCatalog", {
|
|
7
14
|
enumerable: true,
|
|
8
15
|
get: function () {
|
|
9
16
|
return _compile.createCompiledCatalog;
|
|
10
17
|
}
|
|
11
18
|
});
|
|
19
|
+
Object.defineProperty(exports, "generateMessageId", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: function () {
|
|
22
|
+
return _generateMessageId.generateMessageId;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
12
25
|
Object.defineProperty(exports, "getCatalogForFile", {
|
|
13
26
|
enumerable: true,
|
|
14
27
|
get: function () {
|
|
15
|
-
return
|
|
28
|
+
return _getCatalogs.getCatalogForFile;
|
|
16
29
|
}
|
|
17
30
|
});
|
|
18
31
|
Object.defineProperty(exports, "getCatalogs", {
|
|
19
32
|
enumerable: true,
|
|
20
33
|
get: function () {
|
|
21
|
-
return
|
|
34
|
+
return _getCatalogs.getCatalogs;
|
|
22
35
|
}
|
|
23
36
|
});
|
|
24
37
|
Object.defineProperty(exports, "getFormat", {
|
|
25
38
|
enumerable: true,
|
|
26
39
|
get: function () {
|
|
27
|
-
return _formats.
|
|
40
|
+
return _formats.getFormat;
|
|
28
41
|
}
|
|
29
42
|
});
|
|
30
|
-
var _formats =
|
|
31
|
-
var
|
|
43
|
+
var _formats = require("./formats");
|
|
44
|
+
var _getCatalogs = require("./catalog/getCatalogs");
|
|
32
45
|
var _compile = require("./compile");
|
|
33
|
-
|
|
46
|
+
var _generateMessageId = require("./generateMessageId");
|
|
47
|
+
var _types = require("./types");
|
|
48
|
+
Object.keys(_types).forEach(function (key) {
|
|
49
|
+
if (key === "default" || key === "__esModule") return;
|
|
50
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
51
|
+
if (key in exports && exports[key] === _types[key]) return;
|
|
52
|
+
Object.defineProperty(exports, key, {
|
|
53
|
+
enumerable: true,
|
|
54
|
+
get: function () {
|
|
55
|
+
return _types[key];
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
});
|
package/build/api/utils.js
CHANGED
|
@@ -3,38 +3,25 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
exports.PATHSEP = void 0;
|
|
6
7
|
exports.hasYarn = hasYarn;
|
|
7
|
-
exports.
|
|
8
|
+
exports.isDirectory = isDirectory;
|
|
8
9
|
exports.joinOrigin = void 0;
|
|
9
10
|
exports.makeInstall = makeInstall;
|
|
11
|
+
exports.normalizeRelativePath = normalizeRelativePath;
|
|
12
|
+
exports.normalizeSlashes = normalizeSlashes;
|
|
10
13
|
exports.prettyOrigin = prettyOrigin;
|
|
11
|
-
exports.
|
|
14
|
+
exports.readFile = readFile;
|
|
15
|
+
exports.replacePlaceholders = replacePlaceholders;
|
|
12
16
|
exports.splitOrigin = void 0;
|
|
17
|
+
exports.writeFile = writeFile;
|
|
13
18
|
exports.writeFileIfChanged = writeFileIfChanged;
|
|
14
19
|
var _fs = _interopRequireDefault(require("fs"));
|
|
15
20
|
var _path = _interopRequireDefault(require("path"));
|
|
16
|
-
var
|
|
17
|
-
var _fuzzaldrin = require("fuzzaldrin");
|
|
21
|
+
var _normalizePath = _interopRequireDefault(require("normalize-path"));
|
|
18
22
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const list = _fs.default.readdirSync(dir);
|
|
22
|
-
for (let i = 0; i < list.length; i++) {
|
|
23
|
-
const filename = _path.default.join(dir, list[i]);
|
|
24
|
-
const stat = _fs.default.statSync(filename);
|
|
25
|
-
if (filename === "." || filename === "..") {
|
|
26
|
-
// pass these files
|
|
27
|
-
} else if (stat.isDirectory()) {
|
|
28
|
-
// rmdir recursively
|
|
29
|
-
removeDirectory(filename);
|
|
30
|
-
} else {
|
|
31
|
-
_fs.default.unlinkSync(filename);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
if (!onlyContent) {
|
|
35
|
-
_fs.default.rmdirSync(dir);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
23
|
+
const PATHSEP = "/"; // force posix everywhere
|
|
24
|
+
exports.PATHSEP = PATHSEP;
|
|
38
25
|
function prettyOrigin(origins) {
|
|
39
26
|
try {
|
|
40
27
|
return origins.map(origin => origin.join(":")).join(", ");
|
|
@@ -42,44 +29,59 @@ function prettyOrigin(origins) {
|
|
|
42
29
|
return "";
|
|
43
30
|
}
|
|
44
31
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
* :param: availableCommands - all commands defined in commander.js
|
|
50
|
-
*
|
|
51
|
-
* If unknown commands is passed to CLI, check it agains all available commands
|
|
52
|
-
* for possible misspelled letter. Output help with suggestions to console.
|
|
53
|
-
*/
|
|
54
|
-
function helpMisspelledCommand(command, availableCommands = []) {
|
|
55
|
-
const commandNames = availableCommands.map(command => command.name());
|
|
56
|
-
|
|
57
|
-
// if no command is supplied, then commander.js shows help automatically
|
|
58
|
-
if (!command || commandNames.includes(command)) {
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
const suggestions = commandNames.map(name => ({
|
|
62
|
-
name,
|
|
63
|
-
score: (0, _fuzzaldrin.score)(name, command.slice(0, name.length))
|
|
64
|
-
})).filter(nameScore => nameScore.score > 0).slice(0, 3).map(commandScore => _chalk.default.inverse(commandScore.name)).join(", ");
|
|
65
|
-
console.log(`lingui: command ${command} is not a lingui command. ` + `See 'lingui --help' for the list of available commands.`);
|
|
66
|
-
if (suggestions) {
|
|
67
|
-
console.log();
|
|
68
|
-
console.log(`Did you mean: ${suggestions}?`);
|
|
69
|
-
}
|
|
32
|
+
function replacePlaceholders(input, values) {
|
|
33
|
+
return input.replace(/\{([^}]+)}/g, (m, placeholder) => {
|
|
34
|
+
return values[placeholder] || m;
|
|
35
|
+
});
|
|
70
36
|
}
|
|
71
|
-
const splitOrigin = origin =>
|
|
37
|
+
const splitOrigin = origin => {
|
|
38
|
+
const [file, line] = origin.split(":");
|
|
39
|
+
return [file, line ? Number(line) : null];
|
|
40
|
+
};
|
|
72
41
|
exports.splitOrigin = splitOrigin;
|
|
73
42
|
const joinOrigin = origin => origin.join(":");
|
|
74
43
|
exports.joinOrigin = joinOrigin;
|
|
44
|
+
function readFile(fileName) {
|
|
45
|
+
try {
|
|
46
|
+
return _fs.default.readFileSync(fileName).toString();
|
|
47
|
+
} catch (err) {
|
|
48
|
+
if (err.code != "ENOENT") {
|
|
49
|
+
throw err;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function mkdirp(dir) {
|
|
54
|
+
try {
|
|
55
|
+
_fs.default.mkdirSync(dir, {
|
|
56
|
+
recursive: true
|
|
57
|
+
});
|
|
58
|
+
} catch (err) {
|
|
59
|
+
if (err.code != "EEXIST") {
|
|
60
|
+
throw err;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function isDirectory(filePath) {
|
|
65
|
+
try {
|
|
66
|
+
return _fs.default.lstatSync(filePath).isDirectory();
|
|
67
|
+
} catch (err) {
|
|
68
|
+
if (err.code != "ENOENT") {
|
|
69
|
+
throw err;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function writeFile(fileName, content) {
|
|
74
|
+
mkdirp(_path.default.dirname(fileName));
|
|
75
|
+
_fs.default.writeFileSync(fileName, content);
|
|
76
|
+
}
|
|
75
77
|
function writeFileIfChanged(filename, newContent) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
+
const raw = readFile(filename);
|
|
79
|
+
if (raw) {
|
|
78
80
|
if (newContent !== raw) {
|
|
79
|
-
|
|
81
|
+
writeFile(filename, newContent);
|
|
80
82
|
}
|
|
81
83
|
} else {
|
|
82
|
-
|
|
84
|
+
writeFile(filename, newContent);
|
|
83
85
|
}
|
|
84
86
|
}
|
|
85
87
|
function hasYarn() {
|
|
@@ -88,4 +90,26 @@ function hasYarn() {
|
|
|
88
90
|
function makeInstall() {
|
|
89
91
|
const withYarn = hasYarn();
|
|
90
92
|
return (packageName, dev = false) => withYarn ? `yarn add ${dev ? "--dev " : ""}${packageName}` : `npm install ${dev ? "--save-dev" : "--save"} ${packageName}`;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Normalize Windows backslashes in path so they look always as posix
|
|
97
|
+
*/
|
|
98
|
+
function normalizeSlashes(path) {
|
|
99
|
+
return path.replace("\\", "/");
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Remove ./ at the beginning: ./relative => relative
|
|
104
|
+
* relative => relative
|
|
105
|
+
* Preserve directories: ./relative/ => relative/
|
|
106
|
+
* Preserve absolute paths: /absolute/path => /absolute/path
|
|
107
|
+
*/
|
|
108
|
+
function normalizeRelativePath(sourcePath) {
|
|
109
|
+
if (_path.default.isAbsolute(sourcePath)) {
|
|
110
|
+
// absolute path
|
|
111
|
+
return (0, _normalizePath.default)(sourcePath, false);
|
|
112
|
+
}
|
|
113
|
+
const isDir = isDirectory(sourcePath);
|
|
114
|
+
return (0, _normalizePath.default)(_path.default.relative(process.cwd(), sourcePath), false) + (isDir ? "/" : "");
|
|
91
115
|
}
|
package/build/lingui-compile.js
CHANGED
|
@@ -7,57 +7,43 @@ exports.command = command;
|
|
|
7
7
|
var _chalk = _interopRequireDefault(require("chalk"));
|
|
8
8
|
var _chokidar = _interopRequireDefault(require("chokidar"));
|
|
9
9
|
var _fs = _interopRequireDefault(require("fs"));
|
|
10
|
-
var
|
|
11
|
-
var _commander = _interopRequireDefault(require("commander"));
|
|
12
|
-
var plurals = _interopRequireWildcard(require("make-plural"));
|
|
10
|
+
var _commander = require("commander");
|
|
13
11
|
var _conf = require("@lingui/conf");
|
|
14
|
-
var _catalog = require("./api/catalog");
|
|
15
12
|
var _compile = require("./api/compile");
|
|
16
13
|
var _help = require("./api/help");
|
|
17
14
|
var _api = require("./api");
|
|
18
|
-
|
|
19
|
-
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; }
|
|
15
|
+
var _getCatalogs = require("./api/catalog/getCatalogs");
|
|
20
16
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
21
|
-
const noMessages = R.pipe(R.map(R.isEmpty), R.values, R.all(R.equals(true)));
|
|
22
17
|
function command(config, options) {
|
|
23
|
-
const catalogs = (0,
|
|
24
|
-
|
|
25
|
-
// fixme: this is definitely doesn't work
|
|
26
|
-
if (noMessages(catalogs)) {
|
|
27
|
-
console.error("Nothing to compile, message catalogs are empty!\n");
|
|
28
|
-
console.error(`(use "${_chalk.default.yellow((0, _help.helpRun)("extract"))}" to extract messages from source files)`);
|
|
29
|
-
return false;
|
|
30
|
-
}
|
|
18
|
+
const catalogs = (0, _api.getCatalogs)(config);
|
|
31
19
|
|
|
32
20
|
// Check config.compile.merge if catalogs for current locale are to be merged into a single compiled file
|
|
33
21
|
const doMerge = !!config.catalogsMergePath;
|
|
34
22
|
let mergedCatalogs = {};
|
|
35
23
|
console.log("Compiling message catalogs…");
|
|
36
24
|
for (const locale of config.locales) {
|
|
37
|
-
const [language] = locale.split(/[_-]/);
|
|
38
|
-
// todo: this validation should be in @lingui/conf
|
|
39
|
-
if (locale !== config.pseudoLocale && !plurals[language]) {
|
|
40
|
-
console.error(_chalk.default.red(`Error: Invalid locale ${_chalk.default.bold(locale)} (missing plural rules)!`));
|
|
41
|
-
console.error();
|
|
42
|
-
}
|
|
43
25
|
for (const catalog of catalogs) {
|
|
26
|
+
const missingMessages = [];
|
|
44
27
|
const messages = catalog.getTranslations(locale, {
|
|
45
28
|
fallbackLocales: config.fallbackLocales,
|
|
46
|
-
sourceLocale: config.sourceLocale
|
|
29
|
+
sourceLocale: config.sourceLocale,
|
|
30
|
+
onMissing: missing => {
|
|
31
|
+
missingMessages.push(missing);
|
|
32
|
+
}
|
|
47
33
|
});
|
|
48
|
-
if (!options.allowEmpty) {
|
|
49
|
-
|
|
50
|
-
if (
|
|
51
|
-
console.error(_chalk.default.red(
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
console.error();
|
|
59
|
-
return false;
|
|
34
|
+
if (!options.allowEmpty && missingMessages.length > 0) {
|
|
35
|
+
console.error(_chalk.default.red(`Error: Failed to compile catalog for locale ${_chalk.default.bold(locale)}!`));
|
|
36
|
+
if (options.verbose) {
|
|
37
|
+
console.error(_chalk.default.red("Missing translations:"));
|
|
38
|
+
missingMessages.forEach(missing => {
|
|
39
|
+
const source = missing.source || missing.source === missing.id ? `: (${missing.source})` : "";
|
|
40
|
+
console.error(`${missing.id}${source}`);
|
|
41
|
+
});
|
|
42
|
+
} else {
|
|
43
|
+
console.error(_chalk.default.red(`Missing ${missingMessages.length} translation(s)`));
|
|
60
44
|
}
|
|
45
|
+
console.error();
|
|
46
|
+
return false;
|
|
61
47
|
}
|
|
62
48
|
if (doMerge) {
|
|
63
49
|
mergedCatalogs = {
|
|
@@ -84,7 +70,7 @@ function command(config, options) {
|
|
|
84
70
|
}
|
|
85
71
|
}
|
|
86
72
|
if (doMerge) {
|
|
87
|
-
const compileCatalog = (0,
|
|
73
|
+
const compileCatalog = (0, _getCatalogs.getCatalogForMerge)(config);
|
|
88
74
|
const namespace = options.namespace || config.compileNamespace;
|
|
89
75
|
const compiledCatalog = (0, _compile.createCompiledCatalog)(locale, mergedCatalogs, {
|
|
90
76
|
strict: false,
|
|
@@ -99,7 +85,7 @@ function command(config, options) {
|
|
|
99
85
|
return true;
|
|
100
86
|
}
|
|
101
87
|
if (require.main === module) {
|
|
102
|
-
_commander.
|
|
88
|
+
_commander.program.description("Add compile message catalogs and add language data (plurals) to compiled bundle.").option("--config <path>", "Path to the config file").option("--strict", "Disable defaults for missing translations").option("--verbose", "Verbose output").option("--typescript", "Create Typescript definition for compiled bundle").option("--namespace <namespace>", "Specify namespace for compiled bundle. Ex: cjs(default) -> module.exports, es -> export, window.test -> window.test").option("--watch", "Enables Watch Mode").option("--debounce <delay>", "Debounces compilation for given amount of milliseconds").on("--help", function () {
|
|
103
89
|
console.log("\n Examples:\n");
|
|
104
90
|
console.log(" # Compile translations and use defaults or message IDs for missing translations");
|
|
105
91
|
console.log(` $ ${(0, _help.helpRun)("compile")}`);
|
|
@@ -109,35 +95,31 @@ if (require.main === module) {
|
|
|
109
95
|
console.log(" # default messages or message IDs)");
|
|
110
96
|
console.log(` $ ${(0, _help.helpRun)("compile --strict")}`);
|
|
111
97
|
}).parse(process.argv);
|
|
98
|
+
const options = _commander.program.opts();
|
|
112
99
|
const config = (0, _conf.getConfig)({
|
|
113
|
-
configPath:
|
|
100
|
+
configPath: options.config
|
|
114
101
|
});
|
|
115
|
-
if (_commander.default.format) {
|
|
116
|
-
const msg = "--format option is deprecated and will be removed in @lingui/cli@3.0.0." + " Please set format in configuration https://lingui.dev/ref/conf#format";
|
|
117
|
-
console.warn(msg);
|
|
118
|
-
config.format = _commander.default.format;
|
|
119
|
-
}
|
|
120
102
|
const compile = () => command(config, {
|
|
121
|
-
verbose:
|
|
122
|
-
allowEmpty: !
|
|
123
|
-
typescript:
|
|
124
|
-
namespace:
|
|
103
|
+
verbose: options.watch || options.verbose || false,
|
|
104
|
+
allowEmpty: !options.strict,
|
|
105
|
+
typescript: options.typescript || config.compileNamespace === "ts" || false,
|
|
106
|
+
namespace: options.namespace // we want this to be undefined if user does not specify so default can be used
|
|
125
107
|
});
|
|
126
108
|
|
|
127
109
|
let debounceTimer;
|
|
128
110
|
const dispatchCompile = () => {
|
|
129
111
|
// Skip debouncing if not enabled
|
|
130
|
-
if (!
|
|
112
|
+
if (!options.debounce) return compile();
|
|
131
113
|
|
|
132
114
|
// CLear the previous timer if there is any, and schedule the next
|
|
133
115
|
debounceTimer && clearTimeout(debounceTimer);
|
|
134
|
-
debounceTimer = setTimeout(() => compile(),
|
|
116
|
+
debounceTimer = setTimeout(() => compile(), options.debounce);
|
|
135
117
|
};
|
|
136
118
|
|
|
137
119
|
// Check if Watch Mode is enabled
|
|
138
|
-
if (
|
|
120
|
+
if (options.watch) {
|
|
139
121
|
console.info(_chalk.default.bold("Initializing Watch Mode..."));
|
|
140
|
-
const catalogs = (0,
|
|
122
|
+
const catalogs = (0, _api.getCatalogs)(config);
|
|
141
123
|
let paths = [];
|
|
142
124
|
const catalogExtension = (0, _api.getFormat)(config.format).catalogExtension;
|
|
143
125
|
config.locales.forEach(locale => {
|
|
@@ -5,50 +5,41 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = command;
|
|
7
7
|
var _chalk = _interopRequireDefault(require("chalk"));
|
|
8
|
-
var _commander =
|
|
8
|
+
var _commander = require("commander");
|
|
9
9
|
var _conf = require("@lingui/conf");
|
|
10
|
-
var
|
|
11
|
-
var
|
|
10
|
+
var _api = require("./api");
|
|
11
|
+
var _path = _interopRequireDefault(require("path"));
|
|
12
|
+
var _utils = require("./api/utils");
|
|
12
13
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
14
|
async function command(config, options) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
if (!process.env.BABEL_ENV && !process.env.NODE_ENV) {
|
|
17
|
-
process.env.BABEL_ENV = "development";
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// We need macros to keep imports, so extract-messages plugin know what componets
|
|
21
|
-
// to collect. Users usually use both BABEN_ENV and NODE_ENV, so it's probably
|
|
22
|
-
// safer to introduce a new env variable. LINGUI_EXTRACT=1 during `lingui extract`
|
|
23
|
-
process.env.LINGUI_EXTRACT = "1";
|
|
24
|
-
options.verbose && console.error("Extracting messages from source files…");
|
|
25
|
-
const catalogs = (0, _catalog.getCatalogs)(config);
|
|
15
|
+
options.verbose && console.log("Extracting messages from source files…");
|
|
16
|
+
const catalogs = (0, _api.getCatalogs)(config);
|
|
26
17
|
const catalogStats = {};
|
|
18
|
+
let commandSuccess = true;
|
|
27
19
|
await Promise.all(catalogs.map(async catalog => {
|
|
28
|
-
await catalog.makeTemplate({
|
|
20
|
+
const result = await catalog.makeTemplate({
|
|
29
21
|
...options,
|
|
30
|
-
orderBy: config.orderBy
|
|
31
|
-
projectType: (0, _detect.detect)()
|
|
22
|
+
orderBy: config.orderBy
|
|
32
23
|
});
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
catalogStats[catalog.templateFile] = Object.keys(catalogTemplate).length;
|
|
24
|
+
if (result) {
|
|
25
|
+
catalogStats[(0, _utils.normalizeSlashes)(_path.default.relative(config.rootDir, catalog.templateFile))] = Object.keys(result).length;
|
|
36
26
|
}
|
|
27
|
+
commandSuccess && (commandSuccess = Boolean(result));
|
|
37
28
|
}));
|
|
38
29
|
Object.entries(catalogStats).forEach(([key, value]) => {
|
|
39
30
|
console.log(`Catalog statistics for ${_chalk.default.bold(key)}: ${_chalk.default.green(value)} messages`);
|
|
40
31
|
console.log();
|
|
41
32
|
});
|
|
42
|
-
return
|
|
33
|
+
return commandSuccess;
|
|
43
34
|
}
|
|
44
35
|
if (require.main === module) {
|
|
45
|
-
_commander.
|
|
36
|
+
_commander.program.option("--config <path>", "Path to the config file").option("--verbose", "Verbose output").parse(process.argv);
|
|
37
|
+
const options = _commander.program.opts();
|
|
46
38
|
const config = (0, _conf.getConfig)({
|
|
47
|
-
configPath:
|
|
39
|
+
configPath: options.config
|
|
48
40
|
});
|
|
49
41
|
const result = command(config, {
|
|
50
|
-
verbose:
|
|
51
|
-
configPath: _commander.default.config || process.env.LINGUI_CONFIG
|
|
42
|
+
verbose: options.verbose || false
|
|
52
43
|
}).then(() => {
|
|
53
44
|
if (!result) process.exit(1);
|
|
54
45
|
});
|