@lingui/cli 3.15.0 → 3.16.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/CHANGELOG.md +482 -0
- package/build/LICENSE +21 -0
- package/build/api/catalog.js +582 -0
- package/build/api/compile.js +89 -0
- package/{api → build/api}/detect.js +23 -9
- package/build/api/extract.js +78 -0
- package/build/api/extractors/babel.js +51 -0
- package/build/api/extractors/index.js +51 -0
- package/build/api/extractors/typescript.js +71 -0
- package/build/api/formats/csv.js +65 -0
- package/{api → build/api}/formats/index.js +8 -5
- package/build/api/formats/lingui.js +67 -0
- package/build/api/formats/minimal.js +63 -0
- package/build/api/formats/po-gettext.js +296 -0
- package/build/api/formats/po.js +122 -0
- package/{api → build/api}/help.js +6 -18
- package/{api → build/api}/index.js +7 -7
- package/build/api/locales.js +45 -0
- package/{api → build/api}/pseudoLocalize.js +13 -13
- package/build/api/stats.js +46 -0
- package/{api → build/api}/utils.js +21 -40
- package/build/lingui-add-locale.js +11 -0
- package/build/lingui-compile.js +192 -0
- package/build/lingui-extract-template.js +64 -0
- package/build/lingui-extract.js +181 -0
- package/{lingui.js → build/lingui.js} +2 -2
- package/{services → build/services}/translationIO.js +78 -94
- package/build/tests.js +78 -0
- package/package.json +18 -12
- package/api/catalog.js +0 -778
- package/api/compile.js +0 -172
- package/api/extract.js +0 -192
- package/api/extractors/babel.js +0 -61
- package/api/extractors/index.js +0 -130
- package/api/extractors/typescript.js +0 -77
- package/api/formats/csv.js +0 -71
- package/api/formats/lingui.js +0 -64
- package/api/formats/minimal.js +0 -63
- package/api/formats/po-gettext.js +0 -331
- package/api/formats/po.js +0 -130
- package/api/locales.js +0 -43
- package/api/stats.js +0 -51
- package/lingui-add-locale.js +0 -11
- package/lingui-compile.js +0 -198
- package/lingui-extract-template.js +0 -123
- package/lingui-extract.js +0 -286
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
-
|
|
5
3
|
Object.defineProperty(exports, "__esModule", {
|
|
6
4
|
value: true
|
|
7
5
|
});
|
|
@@ -21,16 +19,17 @@ var _chalk = _interopRequireDefault(require("chalk"));
|
|
|
21
19
|
|
|
22
20
|
var _fuzzaldrin = require("fuzzaldrin");
|
|
23
21
|
|
|
24
|
-
function
|
|
25
|
-
|
|
22
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
23
|
+
|
|
24
|
+
function removeDirectory(dir, onlyContent = false) {
|
|
26
25
|
if (!_fs.default.existsSync(dir)) return;
|
|
27
26
|
|
|
28
|
-
|
|
27
|
+
const list = _fs.default.readdirSync(dir);
|
|
29
28
|
|
|
30
|
-
for (
|
|
31
|
-
|
|
29
|
+
for (let i = 0; i < list.length; i++) {
|
|
30
|
+
const filename = _path.default.join(dir, list[i]);
|
|
32
31
|
|
|
33
|
-
|
|
32
|
+
const stat = _fs.default.statSync(filename);
|
|
34
33
|
|
|
35
34
|
if (filename === "." || filename === "..") {// pass these files
|
|
36
35
|
} else if (stat.isDirectory()) {
|
|
@@ -48,9 +47,7 @@ function removeDirectory(dir) {
|
|
|
48
47
|
|
|
49
48
|
function prettyOrigin(origins) {
|
|
50
49
|
try {
|
|
51
|
-
return origins.map(
|
|
52
|
-
return origin.join(":");
|
|
53
|
-
}).join(", ");
|
|
50
|
+
return origins.map(origin => origin.join(":")).join(", ");
|
|
54
51
|
} catch (e) {
|
|
55
52
|
return "";
|
|
56
53
|
}
|
|
@@ -65,49 +62,36 @@ function prettyOrigin(origins) {
|
|
|
65
62
|
*/
|
|
66
63
|
|
|
67
64
|
|
|
68
|
-
function helpMisspelledCommand(command) {
|
|
69
|
-
|
|
70
|
-
var commandNames = availableCommands.map(function (command) {
|
|
71
|
-
return command.name();
|
|
72
|
-
}); // if no command is supplied, then commander.js shows help automatically
|
|
65
|
+
function helpMisspelledCommand(command, availableCommands = []) {
|
|
66
|
+
const commandNames = availableCommands.map(command => command.name()); // if no command is supplied, then commander.js shows help automatically
|
|
73
67
|
|
|
74
68
|
if (!command || commandNames.includes(command)) {
|
|
75
69
|
return;
|
|
76
70
|
}
|
|
77
71
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}).filter(function (nameScore) {
|
|
84
|
-
return nameScore.score > 0;
|
|
85
|
-
}).slice(0, 3).map(function (commandScore) {
|
|
86
|
-
return _chalk.default.inverse(commandScore.name);
|
|
87
|
-
}).join(", ");
|
|
88
|
-
console.log("lingui: command ".concat(command, " is not a lingui command. ") + "See 'lingui --help' for the list of available commands.");
|
|
72
|
+
const suggestions = commandNames.map(name => ({
|
|
73
|
+
name,
|
|
74
|
+
score: (0, _fuzzaldrin.score)(name, command.slice(0, name.length))
|
|
75
|
+
})).filter(nameScore => nameScore.score > 0).slice(0, 3).map(commandScore => _chalk.default.inverse(commandScore.name)).join(", ");
|
|
76
|
+
console.log(`lingui: command ${command} is not a lingui command. ` + `See 'lingui --help' for the list of available commands.`);
|
|
89
77
|
|
|
90
78
|
if (suggestions) {
|
|
91
79
|
console.log();
|
|
92
|
-
console.log(
|
|
80
|
+
console.log(`Did you mean: ${suggestions}?`);
|
|
93
81
|
}
|
|
94
82
|
}
|
|
95
83
|
|
|
96
|
-
|
|
97
|
-
return origin.split(":");
|
|
98
|
-
};
|
|
84
|
+
const splitOrigin = origin => origin.split(":");
|
|
99
85
|
|
|
100
86
|
exports.splitOrigin = splitOrigin;
|
|
101
87
|
|
|
102
|
-
|
|
103
|
-
return origin.join(":");
|
|
104
|
-
};
|
|
88
|
+
const joinOrigin = origin => origin.join(":");
|
|
105
89
|
|
|
106
90
|
exports.joinOrigin = joinOrigin;
|
|
107
91
|
|
|
108
92
|
function writeFileIfChanged(filename, newContent) {
|
|
109
93
|
if (_fs.default.existsSync(filename)) {
|
|
110
|
-
|
|
94
|
+
const raw = _fs.default.readFileSync(filename).toString();
|
|
111
95
|
|
|
112
96
|
if (newContent !== raw) {
|
|
113
97
|
_fs.default.writeFileSync(filename, newContent);
|
|
@@ -122,9 +106,6 @@ function hasYarn() {
|
|
|
122
106
|
}
|
|
123
107
|
|
|
124
108
|
function makeInstall() {
|
|
125
|
-
|
|
126
|
-
return
|
|
127
|
-
var dev = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
128
|
-
return withYarn ? "yarn add ".concat(dev ? "--dev " : "").concat(packageName) : "npm install ".concat(dev ? "--save-dev" : "--save", " ").concat(packageName);
|
|
129
|
-
};
|
|
109
|
+
const withYarn = hasYarn();
|
|
110
|
+
return (packageName, dev = false) => withYarn ? `yarn add ${dev ? "--dev " : ""}${packageName}` : `npm install ${dev ? "--save-dev" : "--save"} ${packageName}`;
|
|
130
111
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _chalk = _interopRequireDefault(require("chalk"));
|
|
4
|
+
|
|
5
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
6
|
+
|
|
7
|
+
if (require.main === module) {
|
|
8
|
+
const msg = "lingui add-locale command is deprecated. " + `Please set ${_chalk.default.yellow("'locales'")} in configuration. ` + _chalk.default.underline("https://lingui.js.org/ref/conf.html#locales");
|
|
9
|
+
|
|
10
|
+
console.error(msg);
|
|
11
|
+
}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _chalk = _interopRequireDefault(require("chalk"));
|
|
4
|
+
|
|
5
|
+
var _chokidar = _interopRequireDefault(require("chokidar"));
|
|
6
|
+
|
|
7
|
+
var _fs = _interopRequireDefault(require("fs"));
|
|
8
|
+
|
|
9
|
+
var R = _interopRequireWildcard(require("ramda"));
|
|
10
|
+
|
|
11
|
+
var _commander = _interopRequireDefault(require("commander"));
|
|
12
|
+
|
|
13
|
+
var plurals = _interopRequireWildcard(require("make-plural"));
|
|
14
|
+
|
|
15
|
+
var _conf = require("@lingui/conf");
|
|
16
|
+
|
|
17
|
+
var _catalog = require("./api/catalog");
|
|
18
|
+
|
|
19
|
+
var _compile = require("./api/compile");
|
|
20
|
+
|
|
21
|
+
var _help = require("./api/help");
|
|
22
|
+
|
|
23
|
+
var _api = require("./api");
|
|
24
|
+
|
|
25
|
+
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
|
|
26
|
+
|
|
27
|
+
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; }
|
|
28
|
+
|
|
29
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
30
|
+
|
|
31
|
+
const noMessages = R.pipe(R.map(R.isEmpty), R.values, R.all(R.equals(true)));
|
|
32
|
+
|
|
33
|
+
function command(config, options) {
|
|
34
|
+
const catalogs = (0, _catalog.getCatalogs)(config);
|
|
35
|
+
|
|
36
|
+
if (noMessages(catalogs)) {
|
|
37
|
+
console.error("Nothing to compile, message catalogs are empty!\n");
|
|
38
|
+
console.error(`(use "${_chalk.default.yellow((0, _help.helpRun)("extract"))}" to extract messages from source files)`);
|
|
39
|
+
return false;
|
|
40
|
+
} // Check config.compile.merge if catalogs for current locale are to be merged into a single compiled file
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
const doMerge = !!config.catalogsMergePath;
|
|
44
|
+
let mergedCatalogs = {};
|
|
45
|
+
console.error("Compiling message catalogs…");
|
|
46
|
+
config.locales.forEach(locale => {
|
|
47
|
+
const [language] = locale.split(/[_-]/);
|
|
48
|
+
|
|
49
|
+
if (locale !== config.pseudoLocale && !plurals[language]) {
|
|
50
|
+
console.log(_chalk.default.red(`Error: Invalid locale ${_chalk.default.bold(locale)} (missing plural rules)!`));
|
|
51
|
+
console.error();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
catalogs.forEach(catalog => {
|
|
55
|
+
const messages = catalog.getTranslations(locale, {
|
|
56
|
+
fallbackLocales: config.fallbackLocales,
|
|
57
|
+
sourceLocale: config.sourceLocale
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
if (!options.allowEmpty) {
|
|
61
|
+
const missingMsgIds = R.pipe(R.pickBy(R.isNil), R.keys)(messages);
|
|
62
|
+
|
|
63
|
+
if (missingMsgIds.length > 0) {
|
|
64
|
+
console.error(_chalk.default.red(`Error: Failed to compile catalog for locale ${_chalk.default.bold(locale)}!`));
|
|
65
|
+
|
|
66
|
+
if (options.verbose) {
|
|
67
|
+
console.error(_chalk.default.red("Missing translations:"));
|
|
68
|
+
missingMsgIds.forEach(msgId => console.log(msgId));
|
|
69
|
+
} else {
|
|
70
|
+
console.error(_chalk.default.red(`Missing ${missingMsgIds.length} translation(s)`));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
console.error();
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (doMerge) {
|
|
79
|
+
mergedCatalogs = { ...mergedCatalogs,
|
|
80
|
+
...messages
|
|
81
|
+
};
|
|
82
|
+
} else {
|
|
83
|
+
const namespace = options.typescript ? "ts" : options.namespace || config.compileNamespace;
|
|
84
|
+
const compiledCatalog = (0, _compile.createCompiledCatalog)(locale, messages, {
|
|
85
|
+
strict: false,
|
|
86
|
+
namespace,
|
|
87
|
+
pseudoLocale: config.pseudoLocale,
|
|
88
|
+
compilerBabelOptions: config.compilerBabelOptions
|
|
89
|
+
});
|
|
90
|
+
const compiledPath = catalog.writeCompiled(locale, compiledCatalog, namespace);
|
|
91
|
+
|
|
92
|
+
if (options.typescript) {
|
|
93
|
+
const typescriptPath = compiledPath.replace(/\.ts?$/, "") + ".d.ts";
|
|
94
|
+
|
|
95
|
+
_fs.default.writeFileSync(typescriptPath, `import { Messages } from '@lingui/core';
|
|
96
|
+
declare const messages: Messages;
|
|
97
|
+
export { messages };
|
|
98
|
+
`);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
options.verbose && console.error(_chalk.default.green(`${locale} ⇒ ${compiledPath}`));
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
if (doMerge) {
|
|
106
|
+
const compileCatalog = (0, _catalog.getCatalogForMerge)(config);
|
|
107
|
+
const namespace = options.namespace || config.compileNamespace;
|
|
108
|
+
const compiledCatalog = (0, _compile.createCompiledCatalog)(locale, mergedCatalogs, {
|
|
109
|
+
strict: false,
|
|
110
|
+
namespace: namespace,
|
|
111
|
+
pseudoLocale: config.pseudoLocale,
|
|
112
|
+
compilerBabelOptions: config.compilerBabelOptions
|
|
113
|
+
});
|
|
114
|
+
const compiledPath = compileCatalog.writeCompiled(locale, compiledCatalog, namespace);
|
|
115
|
+
options.verbose && console.log(_chalk.default.green(`${locale} ⇒ ${compiledPath}`));
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (require.main === module) {
|
|
122
|
+
_commander.default.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("--format <format>", "Format of message catalog").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 () {
|
|
123
|
+
console.log("\n Examples:\n");
|
|
124
|
+
console.log(" # Compile translations and use defaults or message IDs for missing translations");
|
|
125
|
+
console.log(` $ ${(0, _help.helpRun)("compile")}`);
|
|
126
|
+
console.log("");
|
|
127
|
+
console.log(" # Compile translations but fail when there are missing");
|
|
128
|
+
console.log(" # translations (don't replace missing translations with");
|
|
129
|
+
console.log(" # default messages or message IDs)");
|
|
130
|
+
console.log(` $ ${(0, _help.helpRun)("compile --strict")}`);
|
|
131
|
+
}).parse(process.argv);
|
|
132
|
+
|
|
133
|
+
const config = (0, _conf.getConfig)({
|
|
134
|
+
configPath: _commander.default.config
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
if (_commander.default.format) {
|
|
138
|
+
const msg = "--format option is deprecated and will be removed in @lingui/cli@3.0.0." + " Please set format in configuration https://lingui.js.org/ref/conf.html#format";
|
|
139
|
+
console.warn(msg);
|
|
140
|
+
config.format = _commander.default.format;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const compile = () => command(config, {
|
|
144
|
+
verbose: _commander.default.watch || _commander.default.verbose || false,
|
|
145
|
+
allowEmpty: !_commander.default.strict,
|
|
146
|
+
typescript: _commander.default.typescript || config.compileNamespace === "ts" || false,
|
|
147
|
+
namespace: _commander.default.namespace // we want this to be undefined if user does not specify so default can be used
|
|
148
|
+
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
let debounceTimer;
|
|
152
|
+
|
|
153
|
+
const dispatchCompile = () => {
|
|
154
|
+
// Skip debouncing if not enabled
|
|
155
|
+
if (!_commander.default.debounce) return compile(); // CLear the previous timer if there is any, and schedule the next
|
|
156
|
+
|
|
157
|
+
debounceTimer && clearTimeout(debounceTimer);
|
|
158
|
+
debounceTimer = setTimeout(() => compile(), _commander.default.debounce);
|
|
159
|
+
}; // Check if Watch Mode is enabled
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
if (_commander.default.watch) {
|
|
163
|
+
console.info(_chalk.default.bold("Initializing Watch Mode..."));
|
|
164
|
+
const catalogs = (0, _catalog.getCatalogs)(config);
|
|
165
|
+
let paths = [];
|
|
166
|
+
const catalogExtension = (0, _api.getFormat)(config.format).catalogExtension;
|
|
167
|
+
config.locales.forEach(locale => {
|
|
168
|
+
catalogs.forEach(catalog => {
|
|
169
|
+
paths.push(`${catalog.path.replace(/{locale}/g, locale).replace(/{name}/g, "*")}${catalogExtension}`);
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
const watcher = _chokidar.default.watch(paths, {
|
|
174
|
+
persistent: true
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
const onReady = () => {
|
|
178
|
+
console.info(_chalk.default.green.bold("Watcher is ready!"));
|
|
179
|
+
watcher.on("add", () => dispatchCompile()).on("change", () => dispatchCompile());
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
watcher.on("ready", () => onReady());
|
|
183
|
+
} else {
|
|
184
|
+
const results = compile();
|
|
185
|
+
|
|
186
|
+
if (!results) {
|
|
187
|
+
process.exit(1);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
console.log("Done!");
|
|
191
|
+
}
|
|
192
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = command;
|
|
7
|
+
|
|
8
|
+
var _chalk = _interopRequireDefault(require("chalk"));
|
|
9
|
+
|
|
10
|
+
var _commander = _interopRequireDefault(require("commander"));
|
|
11
|
+
|
|
12
|
+
var _conf = require("@lingui/conf");
|
|
13
|
+
|
|
14
|
+
var _catalog = require("./api/catalog");
|
|
15
|
+
|
|
16
|
+
var _detect = require("./api/detect");
|
|
17
|
+
|
|
18
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
19
|
+
|
|
20
|
+
async function command(config, options) {
|
|
21
|
+
// `react-app` babel plugin used by CRA requires either BABEL_ENV or NODE_ENV to be
|
|
22
|
+
// set. We're setting it here, because lingui macros are going to use them as well.
|
|
23
|
+
if (!process.env.BABEL_ENV && !process.env.NODE_ENV) {
|
|
24
|
+
process.env.BABEL_ENV = "development";
|
|
25
|
+
} // We need macros to keep imports, so extract-messages plugin know what componets
|
|
26
|
+
// to collect. Users usually use both BABEN_ENV and NODE_ENV, so it's probably
|
|
27
|
+
// safer to introduce a new env variable. LINGUI_EXTRACT=1 during `lingui extract`
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
process.env.LINGUI_EXTRACT = "1";
|
|
31
|
+
options.verbose && console.error("Extracting messages from source files…");
|
|
32
|
+
const catalogs = (0, _catalog.getCatalogs)(config);
|
|
33
|
+
const catalogStats = {};
|
|
34
|
+
await Promise.all(catalogs.map(async catalog => {
|
|
35
|
+
await catalog.makeTemplate({ ...options,
|
|
36
|
+
orderBy: config.orderBy,
|
|
37
|
+
projectType: (0, _detect.detect)()
|
|
38
|
+
});
|
|
39
|
+
const catalogTemplate = catalog.readTemplate();
|
|
40
|
+
|
|
41
|
+
if (catalogTemplate !== null && catalogTemplate !== undefined) {
|
|
42
|
+
catalogStats[catalog.templateFile] = Object.keys(catalogTemplate).length;
|
|
43
|
+
}
|
|
44
|
+
}));
|
|
45
|
+
Object.entries(catalogStats).forEach(([key, value]) => {
|
|
46
|
+
console.log(`Catalog statistics for ${_chalk.default.bold(key)}: ${_chalk.default.green(value)} messages`);
|
|
47
|
+
console.log();
|
|
48
|
+
});
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (require.main === module) {
|
|
53
|
+
_commander.default.option("--config <path>", "Path to the config file").option("--verbose", "Verbose output").parse(process.argv);
|
|
54
|
+
|
|
55
|
+
const config = (0, _conf.getConfig)({
|
|
56
|
+
configPath: _commander.default.config || process.env.LINGUI_CONFIG
|
|
57
|
+
});
|
|
58
|
+
const result = command(config, {
|
|
59
|
+
verbose: _commander.default.verbose || false,
|
|
60
|
+
configPath: _commander.default.config || process.env.LINGUI_CONFIG
|
|
61
|
+
}).then(() => {
|
|
62
|
+
if (!result) process.exit(1);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = command;
|
|
7
|
+
|
|
8
|
+
var _chalk = _interopRequireDefault(require("chalk"));
|
|
9
|
+
|
|
10
|
+
var _chokidar = _interopRequireDefault(require("chokidar"));
|
|
11
|
+
|
|
12
|
+
var _commander = _interopRequireDefault(require("commander"));
|
|
13
|
+
|
|
14
|
+
var _conf = require("@lingui/conf");
|
|
15
|
+
|
|
16
|
+
var _catalog = require("./api/catalog");
|
|
17
|
+
|
|
18
|
+
var _stats = require("./api/stats");
|
|
19
|
+
|
|
20
|
+
var _detect = require("./api/detect");
|
|
21
|
+
|
|
22
|
+
var _help = require("./api/help");
|
|
23
|
+
|
|
24
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
25
|
+
|
|
26
|
+
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
|
|
27
|
+
|
|
28
|
+
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; }
|
|
29
|
+
|
|
30
|
+
async function command(config, options) {
|
|
31
|
+
// `react-app` babel plugin used by CRA requires either BABEL_ENV or NODE_ENV to be
|
|
32
|
+
// set. We're setting it here, because lingui macros are going to use them as well.
|
|
33
|
+
if (!process.env.BABEL_ENV && !process.env.NODE_ENV) {
|
|
34
|
+
process.env.BABEL_ENV = "development";
|
|
35
|
+
} // We need macros to keep imports, so extract-messages plugin know what componets
|
|
36
|
+
// to collect. Users usually use both BABEN_ENV and NODE_ENV, so it's probably
|
|
37
|
+
// safer to introduce a new env variable. LINGUI_EXTRACT=1 during `lingui extract`
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
process.env.LINGUI_EXTRACT = "1";
|
|
41
|
+
options.verbose && console.error("Extracting messages from source files…");
|
|
42
|
+
const catalogs = (0, _catalog.getCatalogs)(config);
|
|
43
|
+
const catalogStats = {};
|
|
44
|
+
let commandSuccess = true;
|
|
45
|
+
|
|
46
|
+
for (let catalog of catalogs) {
|
|
47
|
+
const catalogSuccess = await catalog.make({ ...options,
|
|
48
|
+
orderBy: config.orderBy,
|
|
49
|
+
extractors: config.extractors,
|
|
50
|
+
projectType: (0, _detect.detect)()
|
|
51
|
+
});
|
|
52
|
+
catalogStats[catalog.path] = catalog.readAll();
|
|
53
|
+
commandSuccess && (commandSuccess = catalogSuccess);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
Object.entries(catalogStats).forEach(([key, value]) => {
|
|
57
|
+
console.log(`Catalog statistics for ${key}: `);
|
|
58
|
+
console.log((0, _stats.printStats)(config, value).toString());
|
|
59
|
+
console.log();
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
if (!options.watch) {
|
|
63
|
+
console.error(`(use "${_chalk.default.yellow((0, _help.helpRun)("extract"))}" to update catalogs with new messages)`);
|
|
64
|
+
console.error(`(use "${_chalk.default.yellow((0, _help.helpRun)("compile"))}" to compile catalogs for production)`);
|
|
65
|
+
} // If service key is present in configuration, synchronize with cloud translation platform
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
if (typeof config.service === 'object' && config.service.name && config.service.name.length) {
|
|
69
|
+
const moduleName = config.service.name.charAt(0).toLowerCase() + config.service.name.slice(1);
|
|
70
|
+
Promise.resolve(`./services/${moduleName}`).then(s => _interopRequireWildcard(require(s))).then(module => module.default(config, options)).catch(err => console.error(`Can't load service module ${moduleName}`, err));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return commandSuccess;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (require.main === module) {
|
|
77
|
+
_commander.default.option("--config <path>", "Path to the config file").option("--locale <locale>", "Only extract the specified locale").option("--overwrite", "Overwrite translations for source locale").option("--clean", "Remove obsolete translations").option("--debounce <delay>", "Debounces extraction for given amount of milliseconds").option("--verbose", "Verbose output").option("--convert-from <format>", "Convert from previous format of message catalogs").option("--watch", "Enables Watch Mode") // Obsolete options
|
|
78
|
+
.option("--babelOptions", "Babel options passed to transform/extract plugins").option("--format <format>", "Format of message catalogs").parse(process.argv);
|
|
79
|
+
|
|
80
|
+
const config = (0, _conf.getConfig)({
|
|
81
|
+
configPath: _commander.default.config || process.env.LINGUI_CONFIG
|
|
82
|
+
});
|
|
83
|
+
let hasErrors = false;
|
|
84
|
+
|
|
85
|
+
if (_commander.default.format) {
|
|
86
|
+
hasErrors = true;
|
|
87
|
+
const msg = "--format option is deprecated." + " Please set format in configuration https://lingui.js.org/ref/conf.html#format";
|
|
88
|
+
console.error(msg);
|
|
89
|
+
console.error();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (_commander.default.babelOptions) {
|
|
93
|
+
hasErrors = true;
|
|
94
|
+
const msg = "--babelOptions option is deprecated." + " Please set extractBabelOptions in configuration https://lingui.js.org/ref/conf.html#extractBabelOptions";
|
|
95
|
+
console.error(msg);
|
|
96
|
+
console.error();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const prevFormat = _commander.default.convertFrom;
|
|
100
|
+
|
|
101
|
+
if (prevFormat && config.format === prevFormat) {
|
|
102
|
+
hasErrors = true;
|
|
103
|
+
console.error("Trying to migrate message catalog to the same format");
|
|
104
|
+
console.error(`Set ${_chalk.default.bold("new")} format in LinguiJS configuration\n` + ` and ${_chalk.default.bold("previous")} format using --convert-from option.`);
|
|
105
|
+
console.log();
|
|
106
|
+
console.log(`Example: Convert from lingui format to minimal`);
|
|
107
|
+
console.log(_chalk.default.yellow((0, _help.helpRun)(`extract --convert-from lingui`)));
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (_commander.default.locale && !config.locales.includes(_commander.default.locale)) {
|
|
112
|
+
hasErrors = true;
|
|
113
|
+
console.error(`Locale ${_chalk.default.bold(_commander.default.locale)} does not exist.`);
|
|
114
|
+
console.error();
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (hasErrors) process.exit(1);
|
|
118
|
+
|
|
119
|
+
const extract = filePath => {
|
|
120
|
+
return command(config, {
|
|
121
|
+
verbose: _commander.default.watch || _commander.default.verbose || false,
|
|
122
|
+
clean: _commander.default.watch ? false : _commander.default.clean || false,
|
|
123
|
+
overwrite: _commander.default.watch || _commander.default.overwrite || false,
|
|
124
|
+
locale: _commander.default.locale,
|
|
125
|
+
configPath: _commander.default.config || process.env.LINGUI_CONFIG,
|
|
126
|
+
watch: _commander.default.watch || false,
|
|
127
|
+
files: filePath?.length ? filePath : undefined,
|
|
128
|
+
prevFormat
|
|
129
|
+
});
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
const changedPaths = new Set();
|
|
133
|
+
let debounceTimer;
|
|
134
|
+
|
|
135
|
+
const dispatchExtract = filePath => {
|
|
136
|
+
// Skip debouncing if not enabled
|
|
137
|
+
if (!_commander.default.debounce) return extract(filePath);
|
|
138
|
+
filePath?.forEach(path => changedPaths.add(path)); // CLear the previous timer if there is any, and schedule the next
|
|
139
|
+
|
|
140
|
+
debounceTimer && clearTimeout(debounceTimer);
|
|
141
|
+
debounceTimer = setTimeout(async () => {
|
|
142
|
+
const filePath = [...changedPaths];
|
|
143
|
+
changedPaths.clear();
|
|
144
|
+
await extract(filePath);
|
|
145
|
+
}, _commander.default.debounce);
|
|
146
|
+
}; // Check if Watch Mode is enabled
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
if (_commander.default.watch) {
|
|
150
|
+
console.info(_chalk.default.bold("Initializing Watch Mode..."));
|
|
151
|
+
const catalogs = (0, _catalog.getCatalogs)(config);
|
|
152
|
+
let paths = [];
|
|
153
|
+
let ignored = [];
|
|
154
|
+
catalogs.forEach(catalog => {
|
|
155
|
+
paths.push(...catalog.include);
|
|
156
|
+
ignored.push(...catalog.exclude);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
const watcher = _chokidar.default.watch(paths, {
|
|
160
|
+
ignored: ["/(^|[/\\])../", ...ignored],
|
|
161
|
+
persistent: true
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
const onReady = () => {
|
|
165
|
+
console.info(_chalk.default.green.bold("Watcher is ready!"));
|
|
166
|
+
watcher.on("add", path => dispatchExtract([path])).on("change", path => dispatchExtract([path]));
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
watcher.on("ready", () => onReady());
|
|
170
|
+
} else if (_commander.default.args) {
|
|
171
|
+
// this behaviour occurs when we extract files by his name
|
|
172
|
+
// for ex: lingui extract src/app, this will extract only files included in src/app
|
|
173
|
+
extract(_commander.default.args).then(result => {
|
|
174
|
+
if (!result) process.exit(1);
|
|
175
|
+
});
|
|
176
|
+
} else {
|
|
177
|
+
extract().then(result => {
|
|
178
|
+
if (!result) process.exit(1);
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|