@lingui/cli 4.0.0-next.2 → 4.0.0-next.4

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.
@@ -18,7 +18,7 @@ async function extractFromFiles(paths, config) {
18
18
  messages[next.id] = {
19
19
  message: next.message,
20
20
  context: next.context,
21
- extractedComments: [],
21
+ comments: [],
22
22
  origin: []
23
23
  };
24
24
  }
@@ -32,7 +32,7 @@ async function extractFromFiles(paths, config) {
32
32
  }
33
33
  messages[next.id] = {
34
34
  ...prev,
35
- extractedComments: next.comment ? [...prev.extractedComments, next.comment] : prev.extractedComments,
35
+ comments: next.comment ? [...prev.comments, next.comment] : prev.comments,
36
36
  origin: [...prev.origin, [filename, next.origin[1]]]
37
37
  };
38
38
  }, config, {
@@ -20,12 +20,13 @@ const LOCALE_PH = "{locale}";
20
20
  /**
21
21
  * Parse `config.catalogs` and return a list of configured Catalog instances.
22
22
  */
23
- function getCatalogs(config) {
23
+ async function getCatalogs(config) {
24
24
  var _config$experimental, _config$experimental$;
25
25
  const catalogsConfig = config.catalogs;
26
26
  const catalogs = [];
27
+ const format = await (0, _formats.getFormat)(config.format, config.formatOptions, config.sourceLocale);
27
28
  catalogsConfig.forEach(catalog => {
28
- validateCatalogPath(catalog.path, config);
29
+ validateCatalogPath(catalog.path, format.getCatalogExtension());
29
30
  const include = ensureArray(catalog.include).map(_utils.normalizeRelativePath);
30
31
  const exclude = ensureArray(catalog.exclude).map(_utils.normalizeRelativePath);
31
32
 
@@ -40,7 +41,8 @@ function getCatalogs(config) {
40
41
  name: getCatalogName(catalog.path),
41
42
  path: (0, _utils.normalizeRelativePath)(catalog.path),
42
43
  include,
43
- exclude
44
+ exclude,
45
+ format
44
46
  }, config));
45
47
  return;
46
48
  }
@@ -63,12 +65,13 @@ function getCatalogs(config) {
63
65
  })),
64
66
  exclude: exclude.map(path => (0, _utils.replacePlaceholders)(path, {
65
67
  name
66
- }))
68
+ })),
69
+ format
67
70
  }, config));
68
71
  });
69
72
  });
70
73
  if ((_config$experimental = config.experimental) !== null && _config$experimental !== void 0 && (_config$experimental$ = _config$experimental.extractor) !== null && _config$experimental$ !== void 0 && _config$experimental$.entries.length) {
71
- catalogs.push(...(0, _getExperimentalCatalogs.getExperimentalCatalogs)(config));
74
+ catalogs.push(...(await (0, _getExperimentalCatalogs.getExperimentalCatalogs)(config)));
72
75
  }
73
76
  return catalogs;
74
77
  }
@@ -84,13 +87,15 @@ const ensureArray = value => {
84
87
  /**
85
88
  * Create catalog for merged messages.
86
89
  */
87
- function getCatalogForMerge(config) {
88
- validateCatalogPath(config.catalogsMergePath, config);
90
+ async function getCatalogForMerge(config) {
91
+ const format = await (0, _formats.getFormat)(config.format, config.formatOptions, config.sourceLocale);
92
+ validateCatalogPath(config.catalogsMergePath, format.getCatalogExtension());
89
93
  return new _catalog.Catalog({
90
94
  name: getCatalogName(config.catalogsMergePath),
91
95
  path: (0, _utils.normalizeRelativePath)(config.catalogsMergePath),
92
96
  include: [],
93
- exclude: []
97
+ exclude: [],
98
+ format
94
99
  }, config);
95
100
  }
96
101
  function getCatalogForFile(file, catalogs) {
@@ -113,14 +118,13 @@ function getCatalogForFile(file, catalogs) {
113
118
  /**
114
119
  * Validate that `catalogPath` doesn't end with trailing slash
115
120
  */
116
- function validateCatalogPath(path, config) {
121
+ function validateCatalogPath(path, extension) {
117
122
  if (!path.endsWith(_utils.PATHSEP)) {
118
123
  return;
119
124
  }
120
- const extension = (0, _formats.getFormat)(config.format, config.formatOptions).getCatalogExtension();
121
125
  const correctPath = path.slice(0, -1);
122
126
  const examplePath = (0, _utils.replacePlaceholders)(correctPath, {
123
- locale: (config.locales || [])[0] || "en"
127
+ locale: "en"
124
128
  }) + extension;
125
129
  throw new Error(
126
130
  // prettier-ignore
@@ -11,7 +11,6 @@ var _path = _interopRequireDefault(require("path"));
11
11
  var R = _interopRequireWildcard(require("ramda"));
12
12
  var _glob = _interopRequireDefault(require("glob"));
13
13
  var _normalizePath = _interopRequireDefault(require("normalize-path"));
14
- var _formats = require("./formats");
15
14
  var _getTranslationsForCatalog = require("./catalog/getTranslationsForCatalog");
16
15
  var _mergeCatalog = require("./catalog/mergeCatalog");
17
16
  var _extractFromFiles = require("./catalog/extractFromFiles");
@@ -27,6 +26,7 @@ class Catalog {
27
26
  path,
28
27
  include,
29
28
  templatePath,
29
+ format,
30
30
  exclude = []
31
31
  }, config) {
32
32
  this.config = config;
@@ -34,7 +34,7 @@ class Catalog {
34
34
  this.path = (0, _utils.normalizeRelativePath)(path);
35
35
  this.include = include.map(_utils.normalizeRelativePath);
36
36
  this.exclude = [this.localeDir, ...exclude.map(_utils.normalizeRelativePath)];
37
- this.format = (0, _formats.getFormat)(config.format, config.formatOptions);
37
+ this.format = format;
38
38
  this.templateFile = templatePath || getTemplatePath(this.format.getTemplateExtension(), this.path);
39
39
  }
40
40
  async make(options) {
@@ -4,11 +4,12 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.FormatterWrapper = void 0;
7
- var _utils = require("../../utils");
8
- var _rethrownError = require("../../rethrownError");
7
+ var _utils = require("../utils");
8
+ var _rethrownError = require("../rethrownError");
9
9
  class FormatterWrapper {
10
- constructor(f) {
10
+ constructor(f, sourceLocale) {
11
11
  this.f = f;
12
+ this.sourceLocale = sourceLocale;
12
13
  }
13
14
  getCatalogExtension() {
14
15
  return this.f.catalogExtension;
@@ -19,6 +20,7 @@ class FormatterWrapper {
19
20
  async write(filename, catalog, locale) {
20
21
  const content = await this.f.serialize(catalog, {
21
22
  locale,
23
+ sourceLocale: this.sourceLocale,
22
24
  existing: await (0, _utils.readFile)(filename),
23
25
  filename
24
26
  });
@@ -32,6 +34,7 @@ class FormatterWrapper {
32
34
  try {
33
35
  return this.f.parse(content, {
34
36
  locale,
37
+ sourceLocale: this.sourceLocale,
35
38
  filename
36
39
  });
37
40
  } catch (e) {
@@ -10,21 +10,48 @@ Object.defineProperty(exports, "FormatterWrapper", {
10
10
  }
11
11
  });
12
12
  exports.getFormat = getFormat;
13
- var _formatterWrapper = require("./api/formatterWrapper");
13
+ var _formatterWrapper = require("./formatterWrapper");
14
+ var _utils = require("../utils");
15
+ 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); }
16
+ 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; }
17
+ function createDeprecationError(packageName, format, installCode) {
18
+ const installCmd = (0, _utils.makeInstall)(packageName);
19
+ return `
20
+ Format \`${format}\` is no longer included in \`@lingui/cli\` by default.
21
+ You need to install it using ${installCmd} command and add to your \`lingui.config.{js,ts}\`:
22
+
23
+ import { formatter } from "${packageName}"
24
+
25
+ export default {
26
+ [...]
27
+ format: ${installCode}
28
+ }
29
+ `.trim();
30
+ }
31
+
32
+ // Introduced in v4. Remove this deprecation in v5
14
33
  const formats = {
15
- lingui: () => require("./lingui").default,
16
- minimal: () => require("./minimal").default,
17
- po: () => require("./po").default,
18
- csv: () => require("./csv").default,
19
- "po-gettext": () => require("./po-gettext").default
34
+ lingui: async () => {
35
+ throw new Error(createDeprecationError("@lingui/format-json", "lingui", 'formatter({style: "lingui"})'));
36
+ },
37
+ minimal: async () => {
38
+ throw new Error(createDeprecationError("@lingui/format-json", "minimal", 'formatter({style: "minimal"})'));
39
+ },
40
+ po: async () => (await Promise.resolve().then(() => _interopRequireWildcard(require("@lingui/format-po")))).formatter,
41
+ csv: async () => {
42
+ throw new Error(createDeprecationError("@lingui/format-csv", "csv", "formatter()"));
43
+ },
44
+ "po-gettext": async () => {
45
+ throw new Error(createDeprecationError("@lingui/format-po-gettext", "po-gettext", "formatter()"));
46
+ }
20
47
  };
21
- function getFormat(_format, options) {
48
+ async function getFormat(_format, options, sourceLocale) {
22
49
  if (typeof _format !== "string") {
23
- return new _formatterWrapper.FormatterWrapper(_format);
50
+ return new _formatterWrapper.FormatterWrapper(_format, sourceLocale);
24
51
  }
25
52
  const format = formats[_format];
26
53
  if (!format) {
27
54
  throw new Error(`Unknown format "${_format}". Use one of following: ${Object.keys(formats).join(", ")}`);
28
55
  }
29
- return new _formatterWrapper.FormatterWrapper(format()(options));
56
+ return new _formatterWrapper.FormatterWrapper((await format())(options), sourceLocale);
30
57
  }
@@ -87,9 +87,9 @@ async function writeFileIfChanged(filename, newContent) {
87
87
  function hasYarn() {
88
88
  return _fs.default.existsSync(_path.default.resolve("yarn.lock"));
89
89
  }
90
- function makeInstall() {
90
+ function makeInstall(packageName, dev = false) {
91
91
  const withYarn = hasYarn();
92
- return (packageName, dev = false) => withYarn ? `yarn add ${dev ? "--dev " : ""}${packageName}` : `npm install ${dev ? "--save-dev" : "--save"} ${packageName}`;
92
+ return withYarn ? `yarn add ${dev ? "--dev " : ""}${packageName}` : `npm install ${dev ? "--save-dev" : "--save"} ${packageName}`;
93
93
  }
94
94
 
95
95
  /**
@@ -9,19 +9,20 @@ var _resolveCatalogPath = require("./resolveCatalogPath");
9
9
  var _catalog = require("../api/catalog");
10
10
  var _resolveTemplatePath = require("./resolveTemplatePath");
11
11
  var _api = require("@lingui/cli/api");
12
- function getExperimentalCatalogs(linguiConfig) {
12
+ async function getExperimentalCatalogs(linguiConfig) {
13
13
  const config = linguiConfig.experimental.extractor;
14
14
  const entryPoints = (0, _getEntryPoints.getEntryPoints)(config.entries);
15
+ const format = await (0, _api.getFormat)(linguiConfig.format, linguiConfig.formatOptions, linguiConfig.sourceLocale);
15
16
  return entryPoints.map(entryPoint => {
16
17
  const catalogPath = (0, _resolveCatalogPath.resolveCatalogPath)(config.output, entryPoint, linguiConfig.rootDir, undefined, "");
17
- const format = (0, _api.getFormat)(linguiConfig.format, linguiConfig.formatOptions);
18
18
  const templatePath = (0, _resolveTemplatePath.resolveTemplatePath)(entryPoint, config.output, linguiConfig.rootDir, format.getTemplateExtension());
19
19
  return new _catalog.Catalog({
20
20
  name: undefined,
21
21
  path: catalogPath,
22
22
  templatePath,
23
23
  include: [],
24
- exclude: []
24
+ exclude: [],
25
+ format
25
26
  }, linguiConfig);
26
27
  });
27
28
  }
@@ -17,7 +17,7 @@ var _utils = require("./api/utils");
17
17
  var _path = _interopRequireDefault(require("path"));
18
18
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
19
  async function command(config, options) {
20
- const catalogs = (0, _api.getCatalogs)(config);
20
+ const catalogs = await (0, _api.getCatalogs)(config);
21
21
 
22
22
  // Check config.compile.merge if catalogs for current locale are to be merged into a single compiled file
23
23
  const doMerge = !!config.catalogsMergePath;
@@ -73,7 +73,7 @@ async function command(config, options) {
73
73
  }
74
74
  }
75
75
  if (doMerge) {
76
- const compileCatalog = (0, _getCatalogs.getCatalogForMerge)(config);
76
+ const compileCatalog = await (0, _getCatalogs.getCatalogForMerge)(config);
77
77
  const namespace = options.namespace || config.compileNamespace;
78
78
  const compiledCatalog = (0, _compile.createCompiledCatalog)(locale, mergedCatalogs, {
79
79
  strict: false,
@@ -127,22 +127,24 @@ if (require.main === module) {
127
127
  // Check if Watch Mode is enabled
128
128
  if (options.watch) {
129
129
  console.info(_chalk.default.bold("Initializing Watch Mode..."));
130
- const catalogs = (0, _api.getCatalogs)(config);
131
- let paths = [];
132
- const catalogExtension = (0, _api.getFormat)(config.format, config.formatOptions).getCatalogExtension();
133
- config.locales.forEach(locale => {
134
- catalogs.forEach(catalog => {
135
- paths.push(`${catalog.path.replace(/{locale}/g, locale).replace(/{name}/g, "*")}${catalogExtension}`);
130
+ (async function initWatch() {
131
+ const format = await (0, _api.getFormat)(config.format, config.formatOptions, config.sourceLocale);
132
+ const catalogs = await (0, _api.getCatalogs)(config);
133
+ const paths = [];
134
+ config.locales.forEach(locale => {
135
+ catalogs.forEach(catalog => {
136
+ paths.push(`${catalog.path.replace(/{locale}/g, locale).replace(/{name}/g, "*")}${format.getCatalogExtension()}`);
137
+ });
136
138
  });
137
- });
138
- const watcher = _chokidar.default.watch(paths, {
139
- persistent: true
140
- });
141
- const onReady = () => {
142
- console.info(_chalk.default.green.bold("Watcher is ready!"));
143
- watcher.on("add", () => dispatchCompile()).on("change", () => dispatchCompile());
144
- };
145
- watcher.on("ready", () => onReady());
139
+ const watcher = _chokidar.default.watch(paths, {
140
+ persistent: true
141
+ });
142
+ const onReady = () => {
143
+ console.info(_chalk.default.green.bold("Watcher is ready!"));
144
+ watcher.on("add", () => dispatchCompile()).on("change", () => dispatchCompile());
145
+ };
146
+ watcher.on("ready", () => onReady());
147
+ })();
146
148
  } else {
147
149
  compile().then(results => {
148
150
  if (!results) {
@@ -33,7 +33,7 @@ async function command(linguiConfig, options) {
33
33
  const bundleResult = await (0, _bundleSource.bundleSource)(config, (0, _getEntryPoints.getEntryPoints)(config.entries), tempDir, linguiConfig.rootDir);
34
34
  const stats = [];
35
35
  let commandSuccess = true;
36
- const format = (0, _formats.getFormat)(linguiConfig.format, linguiConfig.formatOptions);
36
+ const format = await (0, _formats.getFormat)(linguiConfig.format, linguiConfig.formatOptions, linguiConfig.sourceLocale);
37
37
  for (const outFile of Object.keys(bundleResult.metafile.outputs)) {
38
38
  const messages = await (0, _extractFromFiles.extractFromFiles)([outFile], linguiConfig);
39
39
  const {
@@ -13,7 +13,7 @@ var _utils = require("./api/utils");
13
13
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14
14
  async function command(config, options) {
15
15
  options.verbose && console.log("Extracting messages from source files…");
16
- const catalogs = (0, _api.getCatalogs)(config);
16
+ const catalogs = await (0, _api.getCatalogs)(config);
17
17
  const catalogStats = {};
18
18
  let commandSuccess = true;
19
19
  await Promise.all(catalogs.map(async catalog => {
@@ -19,7 +19,7 @@ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "functio
19
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; }
20
20
  async function command(config, options) {
21
21
  options.verbose && console.log("Extracting messages from source files…");
22
- const catalogs = (0, _api.getCatalogs)(config);
22
+ const catalogs = await (0, _api.getCatalogs)(config);
23
23
  const catalogStats = {};
24
24
  let commandSuccess = true;
25
25
  const spinner = (0, _ora.default)().start();
@@ -111,22 +111,24 @@ if (require.main === module) {
111
111
  // Check if Watch Mode is enabled
112
112
  if (options.watch) {
113
113
  console.info(_chalk.default.bold("Initializing Watch Mode..."));
114
- const catalogs = (0, _api.getCatalogs)(config);
115
- let paths = [];
116
- let ignored = [];
117
- catalogs.forEach(catalog => {
118
- paths.push(...catalog.include);
119
- ignored.push(...catalog.exclude);
120
- });
121
- const watcher = _chokidar.default.watch(paths, {
122
- ignored: ["/(^|[/\\])../", ...ignored],
123
- persistent: true
124
- });
125
- const onReady = () => {
126
- console.info(_chalk.default.green.bold("Watcher is ready!"));
127
- watcher.on("add", path => dispatchExtract([path])).on("change", path => dispatchExtract([path]));
128
- };
129
- watcher.on("ready", () => onReady());
114
+ (async function initWatch() {
115
+ const catalogs = await (0, _api.getCatalogs)(config);
116
+ let paths = [];
117
+ let ignored = [];
118
+ catalogs.forEach(catalog => {
119
+ paths.push(...catalog.include);
120
+ ignored.push(...catalog.exclude);
121
+ });
122
+ const watcher = _chokidar.default.watch(paths, {
123
+ ignored: ["/(^|[/\\])../", ...ignored],
124
+ persistent: true
125
+ });
126
+ const onReady = () => {
127
+ console.info(_chalk.default.green.bold("Watcher is ready!"));
128
+ watcher.on("add", path => dispatchExtract([path])).on("change", path => dispatchExtract([path]));
129
+ };
130
+ watcher.on("ready", () => onReady());
131
+ })();
130
132
  } else if (_commander.program.args) {
131
133
  // this behaviour occurs when we extract files by his name
132
134
  // for ex: lingui extract src/app, this will extract only files included in src/app
package/build/tests.js CHANGED
@@ -17,6 +17,7 @@ var _path = _interopRequireDefault(require("path"));
17
17
  var _fs = _interopRequireDefault(require("fs"));
18
18
  var _catalog = require("./api/catalog");
19
19
  var _conf = require("@lingui/conf");
20
+ var _api = require("./api");
20
21
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
22
  async function copyFixture(fixtureDir) {
22
23
  const tmpDir = await _fs.default.promises.mkdtemp(_path.default.join(_os.default.tmpdir(), `lingui-test-${process.pid}`));
@@ -54,15 +55,17 @@ const defaultMergeOptions = {
54
55
  exports.defaultMergeOptions = defaultMergeOptions;
55
56
  const normalizeLineEndings = str => str.replace(/\r?\n/g, "\r\n");
56
57
  exports.normalizeLineEndings = normalizeLineEndings;
57
- const makeCatalog = (config = {}) => {
58
+ const makeCatalog = async (_config = {}) => {
59
+ const config = (0, _conf.makeConfig)(_config, {
60
+ skipValidation: true
61
+ });
58
62
  return new _catalog.Catalog({
59
63
  name: "messages",
60
64
  path: "{locale}/messages",
61
65
  include: [],
62
- exclude: []
63
- }, (0, _conf.makeConfig)(config, {
64
- skipValidation: true
65
- }));
66
+ exclude: [],
67
+ format: await (0, _api.getFormat)(config.format, config.formatOptions, config.sourceLocale)
68
+ }, config);
66
69
  };
67
70
  exports.makeCatalog = makeCatalog;
68
71
  function makePrevMessage(message = {}) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lingui/cli",
3
- "version": "4.0.0-next.2",
3
+ "version": "4.0.0-next.4",
4
4
  "description": "CLI for working wit message catalogs",
5
5
  "keywords": [
6
6
  "cli",
@@ -50,10 +50,10 @@
50
50
  "@babel/parser": "^7.21.2",
51
51
  "@babel/runtime": "^7.21.0",
52
52
  "@babel/types": "^7.21.2",
53
- "@lingui/babel-plugin-extract-messages": "^4.0.0-next.2",
54
- "@lingui/conf": "^4.0.0-next.2",
55
- "@lingui/core": "^4.0.0-next.2",
56
- "@messageformat/parser": "^5.0.0",
53
+ "@lingui/babel-plugin-extract-messages": "^4.0.0-next.4",
54
+ "@lingui/conf": "^4.0.0-next.4",
55
+ "@lingui/core": "^4.0.0-next.4",
56
+ "@lingui/format-po": "^4.0.0-next.4",
57
57
  "babel-plugin-macros": "^3.0.1",
58
58
  "chalk": "^4.1.0",
59
59
  "chokidar": "3.5.1",
@@ -65,13 +65,9 @@
65
65
  "glob": "^7.1.4",
66
66
  "inquirer": "^7.3.3",
67
67
  "micromatch": "4.0.2",
68
- "mkdirp": "^1.0.4",
69
- "node-gettext": "^3.0.0",
70
68
  "normalize-path": "^3.0.0",
71
69
  "ora": "^5.1.0",
72
- "papaparse": "^5.3.0",
73
70
  "pkg-up": "^3.1.0",
74
- "plurals-cldr": "^1.0.4",
75
71
  "pofile": "^1.1.4",
76
72
  "pseudolocale": "^1.1.0",
77
73
  "ramda": "^0.27.1",
@@ -82,10 +78,8 @@
82
78
  "@types/convert-source-map": "^2.0.0",
83
79
  "@types/micromatch": "^4.0.1",
84
80
  "@types/normalize-path": "^3.0.0",
85
- "@types/papaparse": "^5.2.3",
86
- "@types/plurals-cldr": "^1.0.1",
87
81
  "mock-fs": "^5.2.0",
88
- "mockdate": "^3.0.2"
82
+ "mockdate": "^3.0.5"
89
83
  },
90
- "gitHead": "556ab57e20c2ac9d384a22424c6a90c2ba0dd133"
84
+ "gitHead": "3b999e35d26e67dec7cf0591f794be782e11022c"
91
85
  }
@@ -1,39 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = _default;
7
- var _papaparse = _interopRequireDefault(require("papaparse"));
8
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
9
- const serialize = catalog => {
10
- const rawArr = Object.keys(catalog).map(key => [key, catalog[key].translation]);
11
- return _papaparse.default.unparse(rawArr);
12
- };
13
- const deserialize = raw => {
14
- const rawCatalog = _papaparse.default.parse(raw);
15
- const messages = {};
16
- if (rawCatalog.errors.length) {
17
- throw new Error(rawCatalog.errors.map(err => JSON.stringify(err)).join(";"));
18
- }
19
- rawCatalog.data.forEach(([key, translation]) => {
20
- messages[key] = {
21
- translation,
22
- obsolete: false,
23
- message: null,
24
- origin: []
25
- };
26
- });
27
- return messages;
28
- };
29
- function _default() {
30
- return {
31
- catalogExtension: ".csv",
32
- parse(content) {
33
- return deserialize(content);
34
- },
35
- serialize(catalog) {
36
- return serialize(catalog);
37
- }
38
- };
39
- }
@@ -1,46 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = _default;
7
- var R = _interopRequireWildcard(require("ramda"));
8
- 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); }
9
- 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; }
10
- const removeOrigins = R.map(({
11
- origin,
12
- ...message
13
- }) => message);
14
- const removeLineNumbers = R.map(message => {
15
- if (message.origin) {
16
- message.origin = message.origin.map(([file]) => [file]);
17
- }
18
- return message;
19
- });
20
- function _default(options = {}) {
21
- options = {
22
- origins: true,
23
- lineNumbers: true,
24
- ...options
25
- };
26
- return {
27
- catalogExtension: ".json",
28
- serialize(catalog, {
29
- existing
30
- }) {
31
- let outputCatalog = catalog;
32
- if (options.origins === false) {
33
- outputCatalog = removeOrigins(outputCatalog);
34
- }
35
- if (options.origins !== false && options.lineNumbers === false) {
36
- outputCatalog = removeLineNumbers(outputCatalog);
37
- }
38
- const shouldUseTrailingNewline = existing === null || (existing === null || existing === void 0 ? void 0 : existing.endsWith("\n"));
39
- const trailingNewLine = shouldUseTrailingNewline ? "\n" : "";
40
- return JSON.stringify(outputCatalog, null, 2) + trailingNewLine;
41
- },
42
- parse(content) {
43
- return JSON.parse(content);
44
- }
45
- };
46
- }
@@ -1,31 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = _default;
7
- var R = _interopRequireWildcard(require("ramda"));
8
- 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); }
9
- 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; }
10
- const serialize = R.map(message => message.translation || "");
11
- const deserialize = R.map(translation => ({
12
- translation,
13
- obsolete: false,
14
- message: null,
15
- origin: []
16
- }));
17
- function _default() {
18
- return {
19
- catalogExtension: ".json",
20
- serialize(catalog, {
21
- existing
22
- }) {
23
- const shouldUseTrailingNewline = existing === null || (existing === null || existing === void 0 ? void 0 : existing.endsWith("\n"));
24
- const trailingNewLine = shouldUseTrailingNewline ? "\n" : "";
25
- return JSON.stringify(serialize(catalog), null, 2) + trailingNewLine;
26
- },
27
- parse(content) {
28
- return deserialize(JSON.parse(content));
29
- }
30
- };
31
- }
@@ -1,225 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = _default;
7
- exports.parse = parse;
8
- exports.serialize = void 0;
9
- var _dateFns = require("date-fns");
10
- var _parser = require("@messageformat/parser");
11
- var _pluralsCldr = _interopRequireDefault(require("plurals-cldr"));
12
- var _pofile = _interopRequireDefault(require("pofile"));
13
- var _plurals = _interopRequireDefault(require("node-gettext/lib/plurals"));
14
- var _po = require("./po");
15
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16
- // @ts-ignore
17
-
18
- function getCreateHeaders(language) {
19
- return {
20
- "POT-Creation-Date": (0, _dateFns.format)(new Date(), "yyyy-MM-dd HH:mmxxxx"),
21
- "MIME-Version": "1.0",
22
- "Content-Type": "text/plain; charset=utf-8",
23
- "Content-Transfer-Encoding": "8bit",
24
- "X-Generator": "@lingui/cli",
25
- ...(language ? {
26
- Language: language
27
- } : {})
28
- };
29
- }
30
-
31
- // Attempts to turn a single tokenized ICU plural case back into a string.
32
- function stringifyICUCase(icuCase) {
33
- return icuCase.tokens.map(token => {
34
- if (token.type === "content") {
35
- return token.value;
36
- } else if (token.type === "octothorpe") {
37
- return "#";
38
- } else if (token.type === "argument") {
39
- return "{" + token.arg + "}";
40
- } else {
41
- console.warn(`Unexpected token "${token}" while stringifying plural case "${icuCase}". Token will be ignored.`);
42
- return "";
43
- }
44
- }).join("");
45
- }
46
- const ICU_PLURAL_REGEX = /^{.*, plural, .*}$/;
47
- const ICU_SELECT_REGEX = /^{.*, select(Ordinal)?, .*}$/;
48
- const LINE_ENDINGS = /\r?\n/g;
49
-
50
- // Prefix that is used to identitify context information used by this module in PO's "extracted comments".
51
- const CTX_PREFIX = "js-lingui:";
52
- function serializePlurals(item, message, id, isGeneratedId, options) {
53
- // Depending on whether custom ids are used by the developer, the (potential plural) "original", untranslated ICU
54
- // message can be found in `message.message` or in the item's `key` itself.
55
- const icuMessage = message.message;
56
- if (!icuMessage) {
57
- return;
58
- }
59
- const _simplifiedMessage = icuMessage.replace(LINE_ENDINGS, " ");
60
-
61
- // Quick check to see if original message is a plural localization.
62
- if (ICU_PLURAL_REGEX.test(_simplifiedMessage)) {
63
- try {
64
- var _message$translation;
65
- const messageAst = (0, _parser.parse)(icuMessage)[0];
66
-
67
- // Check if any of the plural cases contain plurals themselves.
68
- if (messageAst.cases.some(icuCase => icuCase.tokens.some(token => token.type === "plural"))) {
69
- console.warn(`Nested plurals cannot be expressed with gettext plurals. ` + `Message with key "%s" will not be saved correctly.`, id);
70
- }
71
-
72
- // Store placeholder that is pluralized upon to allow restoring ICU format later.
73
- const ctx = new URLSearchParams({
74
- pluralize_on: messageAst.arg
75
- });
76
- if (isGeneratedId) {
77
- // For messages without developer-set ID, use first case as `msgid` and the last case as `msgid_plural`.
78
- // This does not necessarily make sense for development languages with more than two numbers, but gettext
79
- // only supports exactly two plural forms.
80
- item.msgid = stringifyICUCase(messageAst.cases[0]);
81
- item.msgid_plural = stringifyICUCase(messageAst.cases[messageAst.cases.length - 1]);
82
-
83
- // Since the original msgid is overwritten, store ICU message to allow restoring that ID later.
84
- ctx.set("icu", icuMessage);
85
- } else {
86
- // For messages with developer-set ID, append `_plural` to the key to generate `msgid_plural`.
87
- item.msgid_plural = id + "_plural";
88
- }
89
- ctx.sort();
90
- item.extractedComments.push(CTX_PREFIX + ctx.toString());
91
-
92
- // If there is a translated value, parse that instead of the original message to prevent overriding localized
93
- // content with the original message. If there is no translated value, don't touch msgstr, since marking item as
94
- // plural (above) already causes `pofile` to automatically generate `msgstr[0]` and `msgstr[1]`.
95
- if (((_message$translation = message.translation) === null || _message$translation === void 0 ? void 0 : _message$translation.length) > 0) {
96
- const ast = (0, _parser.parse)(message.translation)[0];
97
- if (ast.cases == null) {
98
- console.warn(`Found translation without plural cases for key "${id}". ` + `This likely means that a translated .po file misses multiple msgstr[] entries for the key. ` + `Translation found: "${message.translation}"`);
99
- item.msgstr = [message.translation];
100
- } else {
101
- item.msgstr = ast.cases.map(stringifyICUCase);
102
- }
103
- }
104
- } catch (e) {
105
- console.error(`Error parsing message ICU for key "${id}":`, e);
106
- }
107
- } else {
108
- if (!options.disableSelectWarning && ICU_SELECT_REGEX.test(_simplifiedMessage)) {
109
- console.warn(`ICU 'select' and 'selectOrdinal' formats cannot be expressed natively in gettext format. ` + `Item with key "%s" will be included in the catalog as raw ICU message. ` + `To disable this warning, include '{ disableSelectWarning: true }' in the config's 'formatOptions'`, id);
110
- }
111
- item.msgstr = [message.translation];
112
- }
113
- return item;
114
- }
115
- const serialize = (catalog, options) => {
116
- return (0, _po.serialize)(catalog, options, (item, message, id, isGeneratedId) => serializePlurals(item, message, id, isGeneratedId, options));
117
- };
118
-
119
- /**
120
- * Returns ICU case labels in the order that gettext lists localized messages, e.g. 0,1,2 => `["one", "two", "other"]`.
121
- *
122
- * Obtaining the ICU case labels for gettext-supported inputs (gettext doesn't support fractions, even though some
123
- * languages have a separate case for fractional numbers) works by applying the CLDR selector to the example values
124
- * listed in the node-gettext plurals module.
125
- *
126
- * This approach is heavily influenced by
127
- * https://github.com/LLK/po2icu/blob/9eb97f81f72b2fee02b77f1424702e019647e9b9/lib/po2icu.js#L148.
128
- */
129
- exports.serialize = serialize;
130
- const getPluralCases = lang => {
131
- // If users uses locale with underscore or slash, es-ES, es_ES, gettextplural is "es" not es-ES.
132
- const [correctLang] = lang.split(/[-_]/g);
133
- const gettextPluralsInfo = _plurals.default[correctLang];
134
- return gettextPluralsInfo === null || gettextPluralsInfo === void 0 ? void 0 : gettextPluralsInfo.examples.map(pluralCase => (0, _pluralsCldr.default)(correctLang, pluralCase.sample));
135
- };
136
- const convertPluralsToICU = (item, pluralForms, lang) => {
137
- var _item$extractedCommen;
138
- const translationCount = item.msgstr.length;
139
- const messageKey = item.msgid;
140
-
141
- // Messages without multiple translations (= plural cases) need no further processing.
142
- if (translationCount <= 1 && !item.msgid_plural) {
143
- return;
144
- }
145
-
146
- // msgid_plural must be set, but its actual value is not important.
147
- if (!item.msgid_plural) {
148
- console.warn(`Multiple translations for item with key "%s" but missing 'msgid_plural' in catalog "${lang}". This is not supported and the plural cases will be ignored.`, messageKey);
149
- return;
150
- }
151
- const contextComment = (_item$extractedCommen = item.extractedComments.find(comment => comment.startsWith(CTX_PREFIX))) === null || _item$extractedCommen === void 0 ? void 0 : _item$extractedCommen.substr(CTX_PREFIX.length);
152
- const ctx = new URLSearchParams(contextComment);
153
- if (contextComment != null) {
154
- item.extractedComments = item.extractedComments.filter(comment => !comment.startsWith(CTX_PREFIX));
155
- }
156
-
157
- // If an original ICU was stored, use that as `msgid` to match the catalog that was originally exported.
158
- const storedICU = ctx.get("icu");
159
- if (storedICU != null) {
160
- item.msgid = storedICU;
161
- }
162
-
163
- // If all translations are empty, ignore item.
164
- if (item.msgstr.every(str => str.length === 0)) {
165
- return;
166
- }
167
- if (pluralForms == null) {
168
- console.warn(`Multiple translations for item with key "%s" in language "${lang}", but no plural cases were found. ` + `This prohibits the translation of .po plurals into ICU plurals. Pluralization will not work for this key.`, messageKey);
169
- return;
170
- }
171
- const pluralCount = pluralForms.length;
172
- if (translationCount > pluralCount) {
173
- console.warn(`More translations provided (${translationCount}) for item with key "%s" in language "${lang}" than there are plural cases available (${pluralCount}). ` + `This will result in not all translations getting picked up.`, messageKey);
174
- }
175
-
176
- // Map each msgstr to a "<pluralform> {<translated_string>}" entry, joined by one space.
177
- const pluralClauses = item.msgstr.map((str, index) => pluralForms[index] + " {" + str + "}").join(" ");
178
-
179
- // Find out placeholder name from item's message context, defaulting to "count".
180
- let pluralizeOn = ctx.get("pluralize_on");
181
- if (!pluralizeOn) {
182
- console.warn(`Unable to determine plural placeholder name for item with key "%s" in language "${lang}" (should be stored in a comment starting with "#. ${CTX_PREFIX}"), assuming "count".`, messageKey);
183
- pluralizeOn = "count";
184
- }
185
- item.msgstr = ["{" + pluralizeOn + ", plural, " + pluralClauses + "}"];
186
- };
187
- function parse(raw) {
188
- const po = _pofile.default.parse(raw);
189
-
190
- // .po plurals are numbered 0-N and need to be mapped to ICU plural classes ("one", "few", "many"...). Different
191
- // languages can have different plural classes (some start with "zero", some with "one"), so read that data from CLDR.
192
- // `pluralForms` may be `null` if lang is not found. As long as no plural is used, don't report an error.
193
- let pluralForms = getPluralCases(po.headers.Language);
194
- return (0, _po.deserialize)(po.items, item => {
195
- convertPluralsToICU(item, pluralForms, po.headers.Language);
196
- });
197
- }
198
- function _default(options = {}) {
199
- options = {
200
- origins: true,
201
- lineNumbers: true,
202
- ...options
203
- };
204
- return {
205
- catalogExtension: ".po",
206
- templateExtension: ".pot",
207
- parse(content) {
208
- return parse(content);
209
- },
210
- serialize(catalog, ctx) {
211
- let po;
212
- if (ctx.existing) {
213
- po = _pofile.default.parse(ctx.existing);
214
- } else {
215
- po = new _pofile.default();
216
- po.headers = getCreateHeaders(ctx.locale)
217
- // accessing private property
218
- ;
219
- po.headerOrder = Object.keys(po.headers);
220
- }
221
- po.items = serialize(catalog, options);
222
- return po.toString();
223
- }
224
- };
225
- }
@@ -1,125 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = _default;
7
- exports.deserialize = deserialize;
8
- exports.serialize = void 0;
9
- var _dateFns = require("date-fns");
10
- var _pofile = _interopRequireDefault(require("pofile"));
11
- var _utils = require("../utils");
12
- var _generateMessageId = require("../generateMessageId");
13
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14
- function isGeneratedId(id, message) {
15
- return id === (0, _generateMessageId.generateMessageId)(message.message, message.context);
16
- }
17
- function getCreateHeaders(language) {
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 ? {
25
- Language: language
26
- } : {})
27
- };
28
- }
29
- const EXPLICIT_ID_FLAG = "explicit-id";
30
- const serialize = (catalog, options, postProcessItem) => {
31
- return Object.keys(catalog).map(id => {
32
- const message = catalog[id];
33
- const item = new _pofile.default.Item();
34
-
35
- // The extractedComments array may be modified in this method,
36
- // so create a new array with the message's elements.
37
- item.extractedComments = [...(message.extractedComments || [])];
38
- item.flags = (message.flags || []).reduce((acc, flag) => {
39
- acc[flag] = true;
40
- return acc;
41
- }, {});
42
- const _isGeneratedId = isGeneratedId(id, message);
43
- if (_isGeneratedId) {
44
- item.msgid = message.message;
45
- if (!item.extractedComments.find(c => c.includes("js-lingui-id"))) {
46
- item.extractedComments.push(`js-lingui-id: ${id}`);
47
- }
48
- } else {
49
- item.flags[EXPLICIT_ID_FLAG] = true;
50
- item.msgid = id;
51
- }
52
- if (message.context) {
53
- item.msgctxt = message.context;
54
- }
55
- item.msgstr = [message.translation];
56
- item.comments = message.comments || [];
57
- if (options.origins !== false) {
58
- if (message.origin && options.lineNumbers === false) {
59
- item.references = message.origin.map(([path]) => path);
60
- } else {
61
- item.references = message.origin ? message.origin.map(_utils.joinOrigin) : [];
62
- }
63
- }
64
- item.obsolete = message.obsolete;
65
- return postProcessItem ? postProcessItem(item, message, id, _isGeneratedId) : item;
66
- });
67
- };
68
- exports.serialize = serialize;
69
- function deserialize(items, onItem) {
70
- return items.reduce((catalog, item) => {
71
- onItem(item);
72
- const message = {
73
- translation: item.msgstr[0],
74
- extractedComments: item.extractedComments || [],
75
- comments: item.comments || [],
76
- context: item.msgctxt ?? null,
77
- obsolete: item.flags.obsolete || item.obsolete,
78
- origin: (item.references || []).map(ref => (0, _utils.splitOrigin)(ref)),
79
- flags: Object.keys(item.flags).map(flag => flag.trim())
80
- };
81
- let id = item.msgid;
82
-
83
- // if generated id, recreate it
84
- if (!item.flags[EXPLICIT_ID_FLAG]) {
85
- id = (0, _generateMessageId.generateMessageId)(item.msgid, item.msgctxt);
86
- message.message = item.msgid;
87
- }
88
- catalog[id] = message;
89
- return catalog;
90
- }, {});
91
- }
92
- function validateItem(item) {
93
- if (item.msgstr.length > 1) {
94
- console.warn(`Multiple translations for item with key ${item.msgid} is not supported and it will be ignored.`);
95
- }
96
- }
97
- function _default(options = {}) {
98
- options = {
99
- origins: true,
100
- lineNumbers: true,
101
- ...options
102
- };
103
- return {
104
- catalogExtension: ".po",
105
- templateExtension: ".pot",
106
- parse(content) {
107
- const po = _pofile.default.parse(content);
108
- return deserialize(po.items, validateItem);
109
- },
110
- serialize(catalog, ctx) {
111
- let po;
112
- if (ctx.existing) {
113
- po = _pofile.default.parse(ctx.existing);
114
- } else {
115
- po = new _pofile.default();
116
- po.headers = getCreateHeaders(ctx.locale)
117
- // accessing private property
118
- ;
119
- po.headerOrder = Object.keys(po.headers);
120
- }
121
- po.items = serialize(catalog, options);
122
- return po.toString();
123
- }
124
- };
125
- }