@lingui/cli 3.17.2 → 4.0.0-next.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/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 +6 -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 +33 -41
- 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 -19
- package/CHANGELOG.md +0 -530
- package/build/api/detect.js +0 -52
- package/build/api/extract.js +0 -59
- 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,27 +7,18 @@ 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"));
|
|
10
|
+
var _commander = require("commander");
|
|
12
11
|
var plurals = _interopRequireWildcard(require("make-plural"));
|
|
13
12
|
var _conf = require("@lingui/conf");
|
|
14
|
-
var _catalog = require("./api/catalog");
|
|
15
13
|
var _compile = require("./api/compile");
|
|
16
14
|
var _help = require("./api/help");
|
|
17
15
|
var _api = require("./api");
|
|
16
|
+
var _getCatalogs = require("./api/catalog/getCatalogs");
|
|
18
17
|
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); }
|
|
19
18
|
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; }
|
|
20
19
|
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
20
|
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
|
-
}
|
|
21
|
+
const catalogs = (0, _api.getCatalogs)(config);
|
|
31
22
|
|
|
32
23
|
// Check config.compile.merge if catalogs for current locale are to be merged into a single compiled file
|
|
33
24
|
const doMerge = !!config.catalogsMergePath;
|
|
@@ -36,28 +27,33 @@ function command(config, options) {
|
|
|
36
27
|
for (const locale of config.locales) {
|
|
37
28
|
const [language] = locale.split(/[_-]/);
|
|
38
29
|
// todo: this validation should be in @lingui/conf
|
|
30
|
+
// todo: validate locales according bcp47, instead of plurals
|
|
39
31
|
if (locale !== config.pseudoLocale && !plurals[language]) {
|
|
40
32
|
console.error(_chalk.default.red(`Error: Invalid locale ${_chalk.default.bold(locale)} (missing plural rules)!`));
|
|
41
33
|
console.error();
|
|
42
34
|
}
|
|
43
35
|
for (const catalog of catalogs) {
|
|
36
|
+
const missingMessages = [];
|
|
44
37
|
const messages = catalog.getTranslations(locale, {
|
|
45
38
|
fallbackLocales: config.fallbackLocales,
|
|
46
|
-
sourceLocale: config.sourceLocale
|
|
39
|
+
sourceLocale: config.sourceLocale,
|
|
40
|
+
onMissing: missing => {
|
|
41
|
+
missingMessages.push(missing);
|
|
42
|
+
}
|
|
47
43
|
});
|
|
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;
|
|
44
|
+
if (!options.allowEmpty && missingMessages.length > 0) {
|
|
45
|
+
console.error(_chalk.default.red(`Error: Failed to compile catalog for locale ${_chalk.default.bold(locale)}!`));
|
|
46
|
+
if (options.verbose) {
|
|
47
|
+
console.error(_chalk.default.red("Missing translations:"));
|
|
48
|
+
missingMessages.forEach(missing => {
|
|
49
|
+
const source = missing.source || missing.source === missing.id ? `: (${missing.source})` : "";
|
|
50
|
+
console.error(`${missing.id}${source}`);
|
|
51
|
+
});
|
|
52
|
+
} else {
|
|
53
|
+
console.error(_chalk.default.red(`Missing ${missingMessages.length} translation(s)`));
|
|
60
54
|
}
|
|
55
|
+
console.error();
|
|
56
|
+
return false;
|
|
61
57
|
}
|
|
62
58
|
if (doMerge) {
|
|
63
59
|
mergedCatalogs = {
|
|
@@ -84,7 +80,7 @@ function command(config, options) {
|
|
|
84
80
|
}
|
|
85
81
|
}
|
|
86
82
|
if (doMerge) {
|
|
87
|
-
const compileCatalog = (0,
|
|
83
|
+
const compileCatalog = (0, _getCatalogs.getCatalogForMerge)(config);
|
|
88
84
|
const namespace = options.namespace || config.compileNamespace;
|
|
89
85
|
const compiledCatalog = (0, _compile.createCompiledCatalog)(locale, mergedCatalogs, {
|
|
90
86
|
strict: false,
|
|
@@ -99,7 +95,7 @@ function command(config, options) {
|
|
|
99
95
|
return true;
|
|
100
96
|
}
|
|
101
97
|
if (require.main === module) {
|
|
102
|
-
_commander.
|
|
98
|
+
_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
99
|
console.log("\n Examples:\n");
|
|
104
100
|
console.log(" # Compile translations and use defaults or message IDs for missing translations");
|
|
105
101
|
console.log(` $ ${(0, _help.helpRun)("compile")}`);
|
|
@@ -109,35 +105,31 @@ if (require.main === module) {
|
|
|
109
105
|
console.log(" # default messages or message IDs)");
|
|
110
106
|
console.log(` $ ${(0, _help.helpRun)("compile --strict")}`);
|
|
111
107
|
}).parse(process.argv);
|
|
108
|
+
const options = _commander.program.opts();
|
|
112
109
|
const config = (0, _conf.getConfig)({
|
|
113
|
-
configPath:
|
|
110
|
+
configPath: options.config
|
|
114
111
|
});
|
|
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
112
|
const compile = () => command(config, {
|
|
121
|
-
verbose:
|
|
122
|
-
allowEmpty: !
|
|
123
|
-
typescript:
|
|
124
|
-
namespace:
|
|
113
|
+
verbose: options.watch || options.verbose || false,
|
|
114
|
+
allowEmpty: !options.strict,
|
|
115
|
+
typescript: options.typescript || config.compileNamespace === "ts" || false,
|
|
116
|
+
namespace: options.namespace // we want this to be undefined if user does not specify so default can be used
|
|
125
117
|
});
|
|
126
118
|
|
|
127
119
|
let debounceTimer;
|
|
128
120
|
const dispatchCompile = () => {
|
|
129
121
|
// Skip debouncing if not enabled
|
|
130
|
-
if (!
|
|
122
|
+
if (!options.debounce) return compile();
|
|
131
123
|
|
|
132
124
|
// CLear the previous timer if there is any, and schedule the next
|
|
133
125
|
debounceTimer && clearTimeout(debounceTimer);
|
|
134
|
-
debounceTimer = setTimeout(() => compile(),
|
|
126
|
+
debounceTimer = setTimeout(() => compile(), options.debounce);
|
|
135
127
|
};
|
|
136
128
|
|
|
137
129
|
// Check if Watch Mode is enabled
|
|
138
|
-
if (
|
|
130
|
+
if (options.watch) {
|
|
139
131
|
console.info(_chalk.default.bold("Initializing Watch Mode..."));
|
|
140
|
-
const catalogs = (0,
|
|
132
|
+
const catalogs = (0, _api.getCatalogs)(config);
|
|
141
133
|
let paths = [];
|
|
142
134
|
const catalogExtension = (0, _api.getFormat)(config.format).catalogExtension;
|
|
143
135
|
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
|
});
|