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

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.
Files changed (100) hide show
  1. package/dist/api/catalog/extractFromFiles.d.ts +5 -0
  2. package/dist/api/catalog/extractFromFiles.js +47 -0
  3. package/dist/api/catalog/getCatalogs.d.ts +14 -0
  4. package/dist/api/catalog/getCatalogs.js +129 -0
  5. package/dist/api/catalog/getTranslationsForCatalog.d.ts +14 -0
  6. package/dist/api/catalog/getTranslationsForCatalog.js +72 -0
  7. package/dist/api/catalog/mergeCatalog.d.ts +3 -0
  8. package/dist/api/catalog/mergeCatalog.js +55 -0
  9. package/dist/api/catalog.d.ts +66 -0
  10. package/dist/api/catalog.js +261 -0
  11. package/dist/api/compile.d.ts +19 -0
  12. package/dist/api/compile.js +88 -0
  13. package/dist/api/extractors/babel.d.ts +3 -0
  14. package/dist/api/extractors/babel.js +101 -0
  15. package/dist/api/extractors/index.d.ts +6 -0
  16. package/dist/api/extractors/index.js +38 -0
  17. package/dist/api/extractors/typescript.d.ts +3 -0
  18. package/dist/api/extractors/typescript.js +11 -0
  19. package/dist/api/formats/formatterWrapper.d.ts +10 -0
  20. package/dist/api/formats/formatterWrapper.js +43 -0
  21. package/dist/api/formats/index.d.ts +5 -0
  22. package/dist/api/formats/index.js +47 -0
  23. package/dist/api/help.d.ts +1 -0
  24. package/dist/api/help.js +40 -0
  25. package/dist/api/index.d.ts +4 -0
  26. package/dist/api/index.js +25 -0
  27. package/dist/api/pseudoLocalize.d.ts +1 -0
  28. package/dist/api/pseudoLocalize.js +56 -0
  29. package/dist/api/rethrownError.d.ts +4 -0
  30. package/dist/api/rethrownError.js +11 -0
  31. package/dist/api/stats.d.ts +6 -0
  32. package/dist/api/stats.js +41 -0
  33. package/dist/api/types.d.ts +5 -0
  34. package/dist/api/types.js +2 -0
  35. package/dist/api/utils.d.ts +22 -0
  36. package/dist/api/utils.js +119 -0
  37. package/dist/extract-experimental/buildExternalizeFilter.d.ts +13 -0
  38. package/dist/extract-experimental/buildExternalizeFilter.js +38 -0
  39. package/dist/extract-experimental/bundleSource.d.ts +2 -0
  40. package/dist/extract-experimental/bundleSource.js +78 -0
  41. package/dist/extract-experimental/constants.d.ts +2 -0
  42. package/dist/extract-experimental/constants.js +5 -0
  43. package/dist/extract-experimental/getEntryPoints.d.ts +1 -0
  44. package/dist/extract-experimental/getEntryPoints.js +12 -0
  45. package/dist/extract-experimental/getExperimentalCatalogs.d.ts +3 -0
  46. package/dist/extract-experimental/getExperimentalCatalogs.js +26 -0
  47. package/dist/extract-experimental/resolveCatalogPath.d.ts +2 -0
  48. package/dist/extract-experimental/resolveCatalogPath.js +23 -0
  49. package/dist/extract-experimental/resolveTemplatePath.d.ts +1 -0
  50. package/dist/extract-experimental/resolveTemplatePath.js +16 -0
  51. package/dist/extract-experimental/writeCatalogs.d.ts +21 -0
  52. package/dist/extract-experimental/writeCatalogs.js +41 -0
  53. package/dist/lingui-compile.d.ts +9 -0
  54. package/dist/lingui-compile.js +170 -0
  55. package/dist/lingui-extract-experimental.d.ts +10 -0
  56. package/dist/lingui-extract-experimental.js +104 -0
  57. package/dist/lingui-extract-template.d.ts +6 -0
  58. package/dist/lingui-extract-template.js +46 -0
  59. package/dist/lingui-extract.d.ts +11 -0
  60. package/dist/lingui-extract.js +156 -0
  61. package/dist/lingui.d.ts +2 -0
  62. package/dist/lingui.js +13 -0
  63. package/dist/services/translationIO.d.ts +3 -0
  64. package/dist/services/translationIO.js +264 -0
  65. package/package.json +29 -14
  66. package/build/LICENSE +0 -21
  67. package/build/api/catalog/extractFromFiles.js +0 -45
  68. package/build/api/catalog/getCatalogs.js +0 -138
  69. package/build/api/catalog/getTranslationsForCatalog.js +0 -77
  70. package/build/api/catalog/mergeCatalog.js +0 -44
  71. package/build/api/catalog.js +0 -245
  72. package/build/api/compile.js +0 -72
  73. package/build/api/extractors/babel.js +0 -92
  74. package/build/api/extractors/index.js +0 -36
  75. package/build/api/extractors/typescript.js +0 -14
  76. package/build/api/formats/formatterWrapper.js +0 -45
  77. package/build/api/formats/index.js +0 -57
  78. package/build/api/generateMessageId.js +0 -12
  79. package/build/api/help.js +0 -42
  80. package/build/api/index.js +0 -58
  81. package/build/api/pseudoLocalize.js +0 -60
  82. package/build/api/rethrownError.js +0 -14
  83. package/build/api/stats.js +0 -40
  84. package/build/api/types.js +0 -5
  85. package/build/api/utils.js +0 -117
  86. package/build/extract-experimental/buildExternalizeFilter.js +0 -39
  87. package/build/extract-experimental/bundleSource.js +0 -69
  88. package/build/extract-experimental/constants.js +0 -10
  89. package/build/extract-experimental/getEntryPoints.js +0 -14
  90. package/build/extract-experimental/getExperimentalCatalogs.js +0 -28
  91. package/build/extract-experimental/resolveCatalogPath.js +0 -23
  92. package/build/extract-experimental/resolveTemplatePath.js +0 -17
  93. package/build/extract-experimental/writeCatalogs.js +0 -59
  94. package/build/lingui-compile.js +0 -156
  95. package/build/lingui-extract-experimental.js +0 -103
  96. package/build/lingui-extract-template.js +0 -46
  97. package/build/lingui-extract.js +0 -143
  98. package/build/lingui.js +0 -6
  99. package/build/services/translationIO.js +0 -266
  100. package/build/tests.js +0 -133
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.normalizeRelativePath = exports.normalizeSlashes = exports.makeInstall = exports.hasYarn = exports.writeFileIfChanged = exports.writeFile = exports.isDirectory = exports.readFile = exports.joinOrigin = exports.splitOrigin = exports.replacePlaceholders = exports.prettyOrigin = exports.PATHSEP = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const normalize_path_1 = __importDefault(require("normalize-path"));
10
+ exports.PATHSEP = "/"; // force posix everywhere
11
+ function prettyOrigin(origins) {
12
+ try {
13
+ return origins.map((origin) => origin.join(":")).join(", ");
14
+ }
15
+ catch (e) {
16
+ return "";
17
+ }
18
+ }
19
+ exports.prettyOrigin = prettyOrigin;
20
+ function replacePlaceholders(input, values) {
21
+ return input.replace(/\{([^}]+)}/g, (m, placeholder) => {
22
+ var _a;
23
+ return (_a = values[placeholder]) !== null && _a !== void 0 ? _a : m;
24
+ });
25
+ }
26
+ exports.replacePlaceholders = replacePlaceholders;
27
+ const splitOrigin = (origin) => {
28
+ const [file, line] = origin.split(":");
29
+ return [file, line ? Number(line) : null];
30
+ };
31
+ exports.splitOrigin = splitOrigin;
32
+ const joinOrigin = (origin) => origin.join(":");
33
+ exports.joinOrigin = joinOrigin;
34
+ async function readFile(fileName) {
35
+ try {
36
+ return (await fs_1.default.promises.readFile(fileName)).toString();
37
+ }
38
+ catch (err) {
39
+ if (err.code != "ENOENT") {
40
+ throw err;
41
+ }
42
+ }
43
+ }
44
+ exports.readFile = readFile;
45
+ async function mkdirp(dir) {
46
+ try {
47
+ await fs_1.default.promises.mkdir(dir, {
48
+ recursive: true,
49
+ });
50
+ }
51
+ catch (err) {
52
+ if (err.code != "EEXIST") {
53
+ throw err;
54
+ }
55
+ }
56
+ }
57
+ function isDirectory(filePath) {
58
+ try {
59
+ return fs_1.default.lstatSync(filePath).isDirectory();
60
+ }
61
+ catch (err) {
62
+ if (err.code != "ENOENT") {
63
+ throw err;
64
+ }
65
+ }
66
+ }
67
+ exports.isDirectory = isDirectory;
68
+ async function writeFile(fileName, content) {
69
+ await mkdirp(path_1.default.dirname(fileName));
70
+ await fs_1.default.promises.writeFile(fileName, content);
71
+ }
72
+ exports.writeFile = writeFile;
73
+ async function writeFileIfChanged(filename, newContent) {
74
+ const raw = await readFile(filename);
75
+ if (raw) {
76
+ if (newContent !== raw) {
77
+ await writeFile(filename, newContent);
78
+ }
79
+ }
80
+ else {
81
+ await writeFile(filename, newContent);
82
+ }
83
+ }
84
+ exports.writeFileIfChanged = writeFileIfChanged;
85
+ function hasYarn() {
86
+ return fs_1.default.existsSync(path_1.default.resolve("yarn.lock"));
87
+ }
88
+ exports.hasYarn = hasYarn;
89
+ function makeInstall(packageName, dev = false) {
90
+ const withYarn = hasYarn();
91
+ return withYarn
92
+ ? `yarn add ${dev ? "--dev " : ""}${packageName}`
93
+ : `npm install ${dev ? "--save-dev" : "--save"} ${packageName}`;
94
+ }
95
+ exports.makeInstall = makeInstall;
96
+ /**
97
+ * Normalize Windows backslashes in path so they look always as posix
98
+ */
99
+ function normalizeSlashes(path) {
100
+ return path.replace("\\", "/");
101
+ }
102
+ exports.normalizeSlashes = normalizeSlashes;
103
+ /**
104
+ * Remove ./ at the beginning: ./relative => relative
105
+ * relative => relative
106
+ * Preserve directories: ./relative/ => relative/
107
+ * Preserve absolute paths: /absolute/path => /absolute/path
108
+ */
109
+ function normalizeRelativePath(sourcePath) {
110
+ if (path_1.default.isAbsolute(sourcePath)) {
111
+ // absolute path
112
+ return (0, normalize_path_1.default)(sourcePath, false);
113
+ }
114
+ // https://github.com/lingui/js-lingui/issues/809
115
+ const isDir = isDirectory(sourcePath);
116
+ return ((0, normalize_path_1.default)(path_1.default.relative(process.cwd(), sourcePath), false) +
117
+ (isDir ? "/" : ""));
118
+ }
119
+ exports.normalizeRelativePath = normalizeRelativePath;
@@ -0,0 +1,13 @@
1
+ type PackageJson = {
2
+ dependencies?: Record<string, string>;
3
+ devDependencies?: Record<string, string>;
4
+ peerDependencies?: Record<string, string>;
5
+ optionalDependencies?: Record<string, string>;
6
+ };
7
+ export declare function buildExternalizeFilter({ includeDeps, excludeDeps, packageJson, }: {
8
+ includeDeps: string[];
9
+ excludeDeps: string[];
10
+ packageJson: PackageJson;
11
+ }): (id: string) => boolean;
12
+ export declare function getPackageJson(rootDir: string): Promise<PackageJson>;
13
+ export {};
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getPackageJson = exports.buildExternalizeFilter = void 0;
4
+ function createPackageRegExp(packageName) {
5
+ return new RegExp("^" + packageName + "(?:\\/.+)?");
6
+ }
7
+ function packages(packages, includeDeps) {
8
+ return Object.keys(packages || {})
9
+ .filter((packageName) => {
10
+ return !includeDeps.some((incl) => packageName.startsWith(incl));
11
+ })
12
+ .map(createPackageRegExp);
13
+ }
14
+ function buildExternalizeFilter({ includeDeps, excludeDeps, packageJson, }) {
15
+ const external = [
16
+ ...packages(packageJson.dependencies, includeDeps),
17
+ ...packages(packageJson.devDependencies, includeDeps),
18
+ ...packages(packageJson.peerDependencies, includeDeps),
19
+ ...packages(packageJson.optionalDependencies, includeDeps),
20
+ ...excludeDeps.map(createPackageRegExp),
21
+ ];
22
+ return (id) => external.some((regExp) => {
23
+ return regExp.test(id);
24
+ });
25
+ }
26
+ exports.buildExternalizeFilter = buildExternalizeFilter;
27
+ async function getPackageJson(rootDir) {
28
+ const { default: pkgUp } = await import("pkg-up");
29
+ const packageJsonPath = await pkgUp({
30
+ cwd: rootDir,
31
+ });
32
+ if (!packageJsonPath) {
33
+ throw new Error("We could not able to find your package.json file. " +
34
+ "Check that `rootDir` is pointing to the folder with package.json");
35
+ }
36
+ return await import(packageJsonPath);
37
+ }
38
+ exports.getPackageJson = getPackageJson;
@@ -0,0 +1,2 @@
1
+ import { ExperimentalExtractorOptions } from "@lingui/conf";
2
+ export declare function bundleSource(config: ExperimentalExtractorOptions, entryPoints: string[], outDir: string, rootDir: string): Promise<import("esbuild").BuildResult<any>>;
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.bundleSource = void 0;
4
+ const buildExternalizeFilter_1 = require("./buildExternalizeFilter");
5
+ function createExtRegExp(extensions) {
6
+ return new RegExp("\\.(?:" + extensions.join("|") + ")(?:\\?.*)?$");
7
+ }
8
+ async function bundleSource(config, entryPoints, outDir, rootDir) {
9
+ const esbuild = await import("esbuild");
10
+ const excludeExtensions = config.excludeExtensions || [
11
+ "ico",
12
+ "pot",
13
+ "xliff",
14
+ "woff2",
15
+ "woff",
16
+ "eot",
17
+ "gif",
18
+ "otf",
19
+ "ttf",
20
+ "mp4",
21
+ "svg",
22
+ "png",
23
+ "css",
24
+ "sass",
25
+ "less",
26
+ "jpg",
27
+ ];
28
+ const packageJson = await (0, buildExternalizeFilter_1.getPackageJson)(rootDir);
29
+ const esbuildOptions = {
30
+ entryPoints: entryPoints,
31
+ outExtension: { ".js": ".jsx" },
32
+ jsx: "preserve",
33
+ bundle: true,
34
+ platform: "node",
35
+ target: ["esnext"],
36
+ format: "esm",
37
+ splitting: false,
38
+ treeShaking: true,
39
+ outdir: outDir,
40
+ sourcemap: "inline",
41
+ sourceRoot: outDir,
42
+ sourcesContent: false,
43
+ outbase: rootDir,
44
+ metafile: true,
45
+ plugins: [
46
+ {
47
+ name: "externalize-deps",
48
+ setup(build) {
49
+ const isExternal = (0, buildExternalizeFilter_1.buildExternalizeFilter)({
50
+ includeDeps: config.includeDeps || [],
51
+ excludeDeps: config.excludeDeps || [],
52
+ packageJson,
53
+ });
54
+ // externalize bare imports
55
+ build.onResolve({ filter: /^[^.].*/ }, async ({ path: id }) => {
56
+ if (isExternal(id)) {
57
+ return {
58
+ external: true,
59
+ };
60
+ }
61
+ });
62
+ },
63
+ },
64
+ {
65
+ name: "externalize-files",
66
+ setup(build) {
67
+ build.onResolve({ filter: createExtRegExp(excludeExtensions) }, () => ({
68
+ external: true,
69
+ }));
70
+ },
71
+ },
72
+ ],
73
+ };
74
+ return await esbuild.build(config.resolveEsbuildOptions
75
+ ? config.resolveEsbuildOptions(esbuildOptions)
76
+ : esbuildOptions);
77
+ }
78
+ exports.bundleSource = bundleSource;
@@ -0,0 +1,2 @@
1
+ export declare const ENTRY_NAME_PH = "{entryName}";
2
+ export declare const DEFAULT_TEMPLATE_NAME = "messages";
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_TEMPLATE_NAME = exports.ENTRY_NAME_PH = void 0;
4
+ exports.ENTRY_NAME_PH = "{entryName}";
5
+ exports.DEFAULT_TEMPLATE_NAME = "messages";
@@ -0,0 +1 @@
1
+ export declare function getEntryPoints(entries: string[]): string[];
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getEntryPoints = void 0;
7
+ const glob_1 = __importDefault(require("glob"));
8
+ function getEntryPoints(entries) {
9
+ const patterns = entries.length > 1 ? `{${entries.join(",")}}` : entries[0];
10
+ return glob_1.default.sync(patterns, { mark: true });
11
+ }
12
+ exports.getEntryPoints = getEntryPoints;
@@ -0,0 +1,3 @@
1
+ import { LinguiConfigNormalized } from "@lingui/conf";
2
+ import { Catalog } from "../api/catalog";
3
+ export declare function getExperimentalCatalogs(linguiConfig: LinguiConfigNormalized): Promise<Catalog[]>;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getExperimentalCatalogs = void 0;
4
+ const getEntryPoints_1 = require("./getEntryPoints");
5
+ const resolveCatalogPath_1 = require("./resolveCatalogPath");
6
+ const catalog_1 = require("../api/catalog");
7
+ const resolveTemplatePath_1 = require("./resolveTemplatePath");
8
+ const formats_1 = require("../api/formats");
9
+ async function getExperimentalCatalogs(linguiConfig) {
10
+ const config = linguiConfig.experimental.extractor;
11
+ const entryPoints = (0, getEntryPoints_1.getEntryPoints)(config.entries);
12
+ const format = await (0, formats_1.getFormat)(linguiConfig.format, linguiConfig.formatOptions, linguiConfig.sourceLocale);
13
+ return entryPoints.map((entryPoint) => {
14
+ const catalogPath = (0, resolveCatalogPath_1.resolveCatalogPath)(config.output, entryPoint, linguiConfig.rootDir, undefined, "");
15
+ const templatePath = (0, resolveTemplatePath_1.resolveTemplatePath)(entryPoint, config.output, linguiConfig.rootDir, format.getTemplateExtension());
16
+ return new catalog_1.Catalog({
17
+ name: undefined,
18
+ path: catalogPath,
19
+ templatePath,
20
+ include: [],
21
+ exclude: [],
22
+ format,
23
+ }, linguiConfig);
24
+ });
25
+ }
26
+ exports.getExperimentalCatalogs = getExperimentalCatalogs;
@@ -0,0 +1,2 @@
1
+ export declare function resolveCatalogPath(configOutput: string, entryPath: string, rootDir: string, locale: string, extension: string): string;
2
+ export declare function getEntryName(entryPath: string): string;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getEntryName = exports.resolveCatalogPath = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ const utils_1 = require("../api/utils");
9
+ function resolveCatalogPath(configOutput, entryPath, rootDir, locale, extension) {
10
+ const entryName = getEntryName(entryPath);
11
+ const entryDir = path_1.default.relative(rootDir, path_1.default.dirname(entryPath));
12
+ return path_1.default.normalize((0, utils_1.replacePlaceholders)(configOutput, {
13
+ entryName,
14
+ entryDir,
15
+ locale,
16
+ }) + extension);
17
+ }
18
+ exports.resolveCatalogPath = resolveCatalogPath;
19
+ function getEntryName(entryPath) {
20
+ const parsedPath = path_1.default.parse(entryPath);
21
+ return parsedPath.name.replace(parsedPath.ext, "");
22
+ }
23
+ exports.getEntryName = getEntryName;
@@ -0,0 +1 @@
1
+ export declare function resolveTemplatePath(entryPoint: string, output: string, rootDir: string, catalogExtension: string): string;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveTemplatePath = void 0;
4
+ const resolveCatalogPath_1 = require("./resolveCatalogPath");
5
+ const constants_1 = require("./constants");
6
+ function resolveTemplatePath(entryPoint, output, rootDir, catalogExtension) {
7
+ let templateName;
8
+ if (output.includes(constants_1.ENTRY_NAME_PH)) {
9
+ templateName = constants_1.DEFAULT_TEMPLATE_NAME;
10
+ }
11
+ else {
12
+ templateName = (0, resolveCatalogPath_1.getEntryName)(entryPoint);
13
+ }
14
+ return (0, resolveCatalogPath_1.resolveCatalogPath)(output, entryPoint, rootDir, templateName, catalogExtension);
15
+ }
16
+ exports.resolveTemplatePath = resolveTemplatePath;
@@ -0,0 +1,21 @@
1
+ import { ExtractedCatalogType } from "../api";
2
+ import { LinguiConfigNormalized } from "@lingui/conf";
3
+ import { FormatterWrapper } from "../api/formats";
4
+ type ExtractTemplateParams = {
5
+ format: FormatterWrapper;
6
+ clean: boolean;
7
+ entryPoint: string;
8
+ outputPattern: string;
9
+ linguiConfig: LinguiConfigNormalized;
10
+ messages: ExtractedCatalogType;
11
+ };
12
+ type ExtractParams = ExtractTemplateParams & {
13
+ locales: string[];
14
+ overwrite: boolean;
15
+ };
16
+ type ExtractStats = {
17
+ statMessage: string;
18
+ };
19
+ export declare function writeCatalogs(params: ExtractParams): Promise<ExtractStats>;
20
+ export declare function writeTemplate(params: ExtractTemplateParams): Promise<ExtractStats>;
21
+ export {};
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.writeTemplate = exports.writeCatalogs = void 0;
7
+ const resolveTemplatePath_1 = require("./resolveTemplatePath");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const resolveCatalogPath_1 = require("./resolveCatalogPath");
10
+ const mergeCatalog_1 = require("../api/catalog/mergeCatalog");
11
+ const stats_1 = require("../api/stats");
12
+ const catalog_1 = require("../api/catalog");
13
+ function cleanAndSort(catalog, clean, orderBy) {
14
+ if (clean) {
15
+ catalog = (0, catalog_1.cleanObsolete)(catalog);
16
+ }
17
+ return (0, catalog_1.order)(orderBy)(catalog);
18
+ }
19
+ async function writeCatalogs(params) {
20
+ const { entryPoint, outputPattern, linguiConfig, locales, overwrite, format, clean, messages, } = params;
21
+ const stat = {};
22
+ for (const locale of locales) {
23
+ const catalogOutput = (0, resolveCatalogPath_1.resolveCatalogPath)(outputPattern, entryPoint, linguiConfig.rootDir, locale, format.getCatalogExtension());
24
+ const catalog = (0, mergeCatalog_1.mergeCatalog)(await format.read(catalogOutput, locale), messages, locale === linguiConfig.sourceLocale, { overwrite });
25
+ await format.write(catalogOutput, cleanAndSort(catalog, clean, linguiConfig.orderBy), locale);
26
+ stat[locale] = catalog;
27
+ }
28
+ return {
29
+ statMessage: (0, stats_1.printStats)(linguiConfig, stat).toString(),
30
+ };
31
+ }
32
+ exports.writeCatalogs = writeCatalogs;
33
+ async function writeTemplate(params) {
34
+ const { entryPoint, outputPattern, linguiConfig, format, clean, messages } = params;
35
+ const catalogOutput = (0, resolveTemplatePath_1.resolveTemplatePath)(entryPoint, outputPattern, linguiConfig.rootDir, format.getTemplateExtension());
36
+ await format.write(catalogOutput, cleanAndSort(messages, clean, linguiConfig.orderBy), undefined);
37
+ return {
38
+ statMessage: `${chalk_1.default.bold(Object.keys(messages).length)} message(s) extracted`,
39
+ };
40
+ }
41
+ exports.writeTemplate = writeTemplate;
@@ -0,0 +1,9 @@
1
+ import { LinguiConfigNormalized } from "@lingui/conf";
2
+ export type CliCompileOptions = {
3
+ verbose?: boolean;
4
+ allowEmpty?: boolean;
5
+ typescript?: boolean;
6
+ watch?: boolean;
7
+ namespace?: string;
8
+ };
9
+ export declare function command(config: LinguiConfigNormalized, options: CliCompileOptions): Promise<boolean>;
@@ -0,0 +1,170 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.command = void 0;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const chokidar_1 = __importDefault(require("chokidar"));
9
+ const fs_1 = __importDefault(require("fs"));
10
+ const commander_1 = require("commander");
11
+ const conf_1 = require("@lingui/conf");
12
+ const compile_1 = require("./api/compile");
13
+ const help_1 = require("./api/help");
14
+ const api_1 = require("./api");
15
+ const getCatalogs_1 = require("./api/catalog/getCatalogs");
16
+ const utils_1 = require("./api/utils");
17
+ const path_1 = __importDefault(require("path"));
18
+ async function command(config, options) {
19
+ const catalogs = await (0, api_1.getCatalogs)(config);
20
+ // Check config.compile.merge if catalogs for current locale are to be merged into a single compiled file
21
+ const doMerge = !!config.catalogsMergePath;
22
+ let mergedCatalogs = {};
23
+ console.log("Compiling message catalogs…");
24
+ for (const locale of config.locales) {
25
+ for (const catalog of catalogs) {
26
+ const missingMessages = [];
27
+ const messages = await catalog.getTranslations(locale, {
28
+ fallbackLocales: config.fallbackLocales,
29
+ sourceLocale: config.sourceLocale,
30
+ onMissing: (missing) => {
31
+ missingMessages.push(missing);
32
+ },
33
+ });
34
+ if (!options.allowEmpty && missingMessages.length > 0) {
35
+ console.error(chalk_1.default.red(`Error: Failed to compile catalog for locale ${chalk_1.default.bold(locale)}!`));
36
+ if (options.verbose) {
37
+ console.error(chalk_1.default.red("Missing translations:"));
38
+ missingMessages.forEach((missing) => {
39
+ const source = missing.source || missing.source === missing.id
40
+ ? `: (${missing.source})`
41
+ : "";
42
+ console.error(`${missing.id}${source}`);
43
+ });
44
+ }
45
+ else {
46
+ console.error(chalk_1.default.red(`Missing ${missingMessages.length} translation(s)`));
47
+ }
48
+ console.error();
49
+ return false;
50
+ }
51
+ if (doMerge) {
52
+ mergedCatalogs = Object.assign(Object.assign({}, mergedCatalogs), messages);
53
+ }
54
+ else {
55
+ const namespace = options.typescript
56
+ ? "ts"
57
+ : options.namespace || config.compileNamespace;
58
+ const compiledCatalog = (0, compile_1.createCompiledCatalog)(locale, messages, {
59
+ strict: false,
60
+ namespace,
61
+ pseudoLocale: config.pseudoLocale,
62
+ compilerBabelOptions: config.compilerBabelOptions,
63
+ });
64
+ let compiledPath = await catalog.writeCompiled(locale, compiledCatalog, namespace);
65
+ if (options.typescript) {
66
+ const typescriptPath = compiledPath.replace(/\.ts?$/, "") + ".d.ts";
67
+ fs_1.default.writeFileSync(typescriptPath, `import { Messages } from '@lingui/core';
68
+ declare const messages: Messages;
69
+ export { messages };
70
+ `);
71
+ }
72
+ compiledPath = (0, utils_1.normalizeSlashes)(path_1.default.relative(config.rootDir, compiledPath));
73
+ options.verbose &&
74
+ console.error(chalk_1.default.green(`${locale} ⇒ ${compiledPath}`));
75
+ }
76
+ }
77
+ if (doMerge) {
78
+ const compileCatalog = await (0, getCatalogs_1.getCatalogForMerge)(config);
79
+ const namespace = options.namespace || config.compileNamespace;
80
+ const compiledCatalog = (0, compile_1.createCompiledCatalog)(locale, mergedCatalogs, {
81
+ strict: false,
82
+ namespace: namespace,
83
+ pseudoLocale: config.pseudoLocale,
84
+ compilerBabelOptions: config.compilerBabelOptions,
85
+ });
86
+ let compiledPath = await compileCatalog.writeCompiled(locale, compiledCatalog, namespace);
87
+ compiledPath = (0, utils_1.normalizeSlashes)(path_1.default.relative(config.rootDir, compiledPath));
88
+ options.verbose && console.log(chalk_1.default.green(`${locale} ⇒ ${compiledPath}`));
89
+ }
90
+ }
91
+ return true;
92
+ }
93
+ exports.command = command;
94
+ if (require.main === module) {
95
+ commander_1.program
96
+ .description("Add compile message catalogs and add language data (plurals) to compiled bundle.")
97
+ .option("--config <path>", "Path to the config file")
98
+ .option("--strict", "Disable defaults for missing translations")
99
+ .option("--verbose", "Verbose output")
100
+ .option("--typescript", "Create Typescript definition for compiled bundle")
101
+ .option("--namespace <namespace>", "Specify namespace for compiled bundle. Ex: cjs(default) -> module.exports, es -> export, window.test -> window.test")
102
+ .option("--watch", "Enables Watch Mode")
103
+ .option("--debounce <delay>", "Debounces compilation for given amount of milliseconds")
104
+ .on("--help", function () {
105
+ console.log("\n Examples:\n");
106
+ console.log(" # Compile translations and use defaults or message IDs for missing translations");
107
+ console.log(` $ ${(0, help_1.helpRun)("compile")}`);
108
+ console.log("");
109
+ console.log(" # Compile translations but fail when there are missing");
110
+ console.log(" # translations (don't replace missing translations with");
111
+ console.log(" # default messages or message IDs)");
112
+ console.log(` $ ${(0, help_1.helpRun)("compile --strict")}`);
113
+ })
114
+ .parse(process.argv);
115
+ const options = commander_1.program.opts();
116
+ const config = (0, conf_1.getConfig)({ configPath: options.config });
117
+ let previousRun = Promise.resolve(true);
118
+ const compile = () => {
119
+ previousRun = previousRun.then(() => command(config, {
120
+ verbose: options.watch || options.verbose || false,
121
+ allowEmpty: !options.strict,
122
+ typescript: options.typescript || config.compileNamespace === "ts" || false,
123
+ namespace: options.namespace, // we want this to be undefined if user does not specify so default can be used
124
+ }));
125
+ return previousRun;
126
+ };
127
+ let debounceTimer;
128
+ const dispatchCompile = () => {
129
+ // Skip debouncing if not enabled
130
+ if (!options.debounce)
131
+ compile();
132
+ // CLear the previous timer if there is any, and schedule the next
133
+ debounceTimer && clearTimeout(debounceTimer);
134
+ debounceTimer = setTimeout(() => compile(), options.debounce);
135
+ };
136
+ // Check if Watch Mode is enabled
137
+ if (options.watch) {
138
+ console.info(chalk_1.default.bold("Initializing Watch Mode..."));
139
+ (async function initWatch() {
140
+ const format = await (0, api_1.getFormat)(config.format, config.formatOptions, config.sourceLocale);
141
+ const catalogs = await (0, api_1.getCatalogs)(config);
142
+ const paths = [];
143
+ config.locales.forEach((locale) => {
144
+ catalogs.forEach((catalog) => {
145
+ paths.push(`${catalog.path
146
+ .replace(/{locale}/g, locale)
147
+ .replace(/{name}/g, "*")}${format.getCatalogExtension()}`);
148
+ });
149
+ });
150
+ const watcher = chokidar_1.default.watch(paths, {
151
+ persistent: true,
152
+ });
153
+ const onReady = () => {
154
+ console.info(chalk_1.default.green.bold("Watcher is ready!"));
155
+ watcher
156
+ .on("add", () => dispatchCompile())
157
+ .on("change", () => dispatchCompile());
158
+ };
159
+ watcher.on("ready", () => onReady());
160
+ })();
161
+ }
162
+ else {
163
+ compile().then((results) => {
164
+ if (!results) {
165
+ process.exit(1);
166
+ }
167
+ console.log("Done!");
168
+ });
169
+ }
170
+ }
@@ -0,0 +1,10 @@
1
+ import { LinguiConfigNormalized } from "@lingui/conf";
2
+ export type CliExtractTemplateOptions = {
3
+ verbose: boolean;
4
+ files?: string[];
5
+ template?: boolean;
6
+ locales?: string[];
7
+ overwrite?: boolean;
8
+ clean?: boolean;
9
+ };
10
+ export default function command(linguiConfig: LinguiConfigNormalized, options: Partial<CliExtractTemplateOptions>): Promise<boolean>;