@lingui/conf 5.9.3 → 6.0.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,18 +1,3 @@
1
- /**
2
- * @deprecated please pass formatter directly to `format`
3
- *
4
- * @example
5
- * ```js
6
- * // lingui.config.{js,ts}
7
- * import {formatter} from "@lingui/format-po"
8
- *
9
- * export default {
10
- * [...]
11
- * format: formatter({lineNumbers: false}),
12
- * }
13
- * ```
14
- */
15
- type CatalogFormat = "lingui" | "minimal" | "po" | "csv" | "po-gettext";
16
1
  type ExtractorCtx = {
17
2
  /**
18
3
  * Raw Sourcemaps object to mapping from.
@@ -23,7 +8,14 @@ type ExtractorCtx = {
23
8
  };
24
9
  type CatalogExtra = Record<string, unknown>;
25
10
  type MessageOrigin = [filename: string, line?: number];
26
- type ExtractedMessageType<Extra = CatalogExtra> = {
11
+ type ExtractedMessageType = {
12
+ message?: string;
13
+ origin: MessageOrigin[];
14
+ comments: string[];
15
+ context?: string;
16
+ placeholders: Record<string, string[]>;
17
+ };
18
+ type MessageType<Extra = CatalogExtra> = {
27
19
  message?: string;
28
20
  origin?: MessageOrigin[];
29
21
  comments?: string[];
@@ -35,19 +27,17 @@ type ExtractedMessageType<Extra = CatalogExtra> = {
35
27
  */
36
28
  extra?: Extra;
37
29
  placeholders?: Record<string, string[]>;
30
+ translation?: string;
38
31
  };
39
- type MessageType<Extra = CatalogExtra> = ExtractedMessageType<Extra> & {
40
- translation: string;
41
- };
42
- type ExtractedCatalogType<Extra = CatalogExtra> = {
43
- [msgId: string]: ExtractedMessageType<Extra>;
32
+ type ExtractedCatalogType = {
33
+ [msgId: string]: ExtractedMessageType;
44
34
  };
45
35
  type CatalogType<Extra = CatalogExtra> = {
46
36
  [msgId: string]: MessageType<Extra>;
47
37
  };
48
38
  type ExtractorType = {
49
39
  match(filename: string): boolean;
50
- extract(filename: string, code: string, onMessageExtracted: (msg: ExtractedMessage) => void, ctx?: ExtractorCtx): Promise<void> | void;
40
+ extract(filename: string, code: string, onMessageExtracted: (msg: ExtractedMessage) => void, ctx: ExtractorCtx): Promise<void> | void;
51
41
  };
52
42
  type CatalogFormatter = {
53
43
  catalogExtension: string;
@@ -57,15 +47,15 @@ type CatalogFormatter = {
57
47
  */
58
48
  templateExtension?: string;
59
49
  parse(content: string, ctx: {
60
- locale: string | null;
50
+ locale: string | undefined;
61
51
  sourceLocale: string;
62
52
  filename: string;
63
53
  }): Promise<CatalogType> | CatalogType;
64
54
  serialize(catalog: CatalogType, ctx: {
65
- locale: string | null;
55
+ locale: string | undefined;
66
56
  sourceLocale: string;
67
57
  filename: string;
68
- existing: string | null;
58
+ existing: string | undefined;
69
59
  }): Promise<string> | string;
70
60
  };
71
61
  type ExtractedMessage = {
@@ -76,17 +66,12 @@ type ExtractedMessage = {
76
66
  comment?: string;
77
67
  placeholders?: Record<string, string>;
78
68
  };
79
- type CatalogFormatOptions = {
80
- origins?: boolean;
81
- lineNumbers?: boolean;
82
- disableSelectWarning?: boolean;
83
- };
84
69
  type OrderByFn = (a: {
85
70
  messageId: string;
86
- entry: ExtractedMessageType;
71
+ entry: MessageType;
87
72
  }, b: {
88
73
  messageId: string;
89
- entry: ExtractedMessageType;
74
+ entry: MessageType;
90
75
  }) => number;
91
76
  type OrderBy = "messageId" | "message" | "origin" | OrderByFn;
92
77
  type CatalogConfig = {
@@ -171,6 +156,19 @@ type LinguiConfig = {
171
156
  compileNamespace?: "es" | "ts" | "cjs" | string;
172
157
  /**
173
158
  * Specify additional options used to parse source files when extracting messages.
159
+ *
160
+ * @deprecated please pass options directly to the extractor implementation
161
+ *
162
+ * @example
163
+ * ```ts
164
+ * import { createBabelExtractor } from '@lingui/cli/api/extractors/babel'
165
+ *
166
+ * export default {
167
+ * [...]
168
+ * extractors: [createBabelExtractor({parserOptions: { tsExperimentalDecorators: true }})],
169
+ * }
170
+ * ```
171
+ * https://lingui.dev/guides/custom-extractor
174
172
  */
175
173
  extractorParserOptions?: {
176
174
  /**
@@ -193,14 +191,26 @@ type LinguiConfig = {
193
191
  * https://lingui.dev/guides/custom-extractor
194
192
  */
195
193
  extractors?: ExtractorType[];
196
- prevFormat?: CatalogFormat;
197
194
  /**
198
- * Message catalog format. The po formatter is used by default. Other formatters are available as separate packages.
195
+ * Message catalog format. If not set, po formatter would be used.
196
+ *
197
+ * Other formatters are available as separate packages.
198
+ *
199
+ * If you want to set additional options for po formatter you need to
200
+ * install it as a separate package and provide in config:
201
+ *
202
+ * @example
203
+ * ```js
204
+ * import {formatter} from "@lingui/format-po"
205
+ *
206
+ * export default {
207
+ * [...]
208
+ * format: formatter({lineNumbers: false}),
209
+ * }
210
+ * ```
199
211
  *
200
- * @default "po"
201
212
  */
202
- format?: CatalogFormat | CatalogFormatter;
203
- formatOptions?: CatalogFormatOptions;
213
+ format?: CatalogFormatter;
204
214
  /**
205
215
  * The locale tags used in the project. The `extract` and `compile` commands write a catalog for each locale specified.
206
216
  *
@@ -297,7 +307,7 @@ type LinguiConfig = {
297
307
  * msg`Hello` // <-- would be correctly picked up by macro
298
308
  * ```
299
309
  *
300
- * @default ["@lingui/macro", "@lingui/core/macro"]
310
+ * @default [ "@lingui/core/macro"]
301
311
  */
302
312
  corePackage?: string[];
303
313
  /**
@@ -317,7 +327,7 @@ type LinguiConfig = {
317
327
  * <Trans>Hello</Trans> // <-- would be correctly picked up by macro
318
328
  * ```
319
329
  *
320
- * @default ["@lingui/macro", "@lingui/react/macro"]
330
+ * @default ["@lingui/react/macro"]
321
331
  */
322
332
  jsxPackage?: string[];
323
333
  };
@@ -326,9 +336,8 @@ type LinguiConfig = {
326
336
  };
327
337
  };
328
338
  type ModuleSourceNormalized = readonly [module: string, specifier: string];
329
- type LinguiConfigNormalized = Omit<LinguiConfig, "runtimeConfigModule"> & {
339
+ type LinguiConfigNormalized = Omit<LinguiConfig & typeof defaultConfig, "runtimeConfigModule"> & {
330
340
  resolvedConfigPath?: string;
331
- fallbackLocales?: FallbackLocales;
332
341
  runtimeConfigModule: {
333
342
  i18n: ModuleSourceNormalized;
334
343
  useLingui: ModuleSourceNormalized;
@@ -340,6 +349,32 @@ declare function makeConfig(userConfig: Partial<LinguiConfig>, opts?: {
340
349
  skipValidation?: boolean;
341
350
  resolvedConfigPath?: string;
342
351
  }): LinguiConfigNormalized;
352
+ declare const defaultConfig: {
353
+ catalogs: {
354
+ path: string;
355
+ include: string[];
356
+ exclude: string[];
357
+ }[];
358
+ catalogsMergePath: string;
359
+ compileNamespace: string;
360
+ compilerBabelOptions: {
361
+ minified: boolean;
362
+ jsescOption: {
363
+ minimal: boolean;
364
+ };
365
+ };
366
+ fallbackLocales: FallbackLocales;
367
+ locales: never[];
368
+ orderBy: "message";
369
+ pseudoLocale: string;
370
+ rootDir: string;
371
+ runtimeConfigModule: [string, string];
372
+ macro: {
373
+ corePackage: string[];
374
+ jsxPackage: string[];
375
+ };
376
+ sourceLocale: string;
377
+ };
343
378
 
344
379
  /**
345
380
  * Type helper for lingui.config.ts, returns {@link LinguiConfig} object
@@ -352,4 +387,5 @@ declare function getConfig({ cwd, configPath, skipValidation, }?: {
352
387
  skipValidation?: boolean;
353
388
  }): LinguiConfigNormalized;
354
389
 
355
- export { type CatalogConfig, type CatalogFormat, type CatalogFormatOptions, type CatalogFormatter, type CatalogType, type ExperimentalExtractorOptions, type ExtractedCatalogType, type ExtractedMessage, type ExtractedMessageType, type ExtractorCtx, type ExtractorType, type FallbackLocales, type LinguiConfig, type LinguiConfigNormalized, type MessageOrigin, type MessageType, type OrderBy, type OrderByFn, defineConfig, getConfig, makeConfig };
390
+ export { defineConfig, getConfig, makeConfig };
391
+ export type { CatalogConfig, CatalogFormatter, CatalogType, ExperimentalExtractorOptions, ExtractedCatalogType, ExtractedMessage, ExtractedMessageType, ExtractorCtx, ExtractorType, FallbackLocales, LinguiConfig, LinguiConfigNormalized, MessageOrigin, MessageType, OrderBy, OrderByFn };
package/dist/index.mjs CHANGED
@@ -1,15 +1,16 @@
1
- import pico from 'picocolors';
1
+ import { styleText } from 'node:util';
2
2
  import { validate, multipleValidOptions } from 'jest-validate';
3
3
  import path from 'path';
4
4
  import fs from 'fs';
5
- import { cosmiconfigSync } from 'cosmiconfig';
5
+ import { lilconfigSync } from 'lilconfig';
6
6
  import { createJiti } from 'jiti';
7
+ import normalizePath from 'normalize-path';
7
8
 
8
9
  function replaceRootDir(config, rootDir) {
9
10
  if (!rootDir) {
10
11
  return config;
11
12
  }
12
- return function replaceDeep(value, rootDir2) {
13
+ return (function replaceDeep(value, rootDir2) {
13
14
  const replace = (s) => s.replace("<rootDir>", rootDir2);
14
15
  if (value == null) {
15
16
  return value;
@@ -21,12 +22,11 @@ function replaceRootDir(config, rootDir) {
21
22
  Object.keys(value).forEach((key) => {
22
23
  const newKey = replaceDeep(key, rootDir2);
23
24
  value[newKey] = replaceDeep(value[key], rootDir2);
24
- if (key !== newKey)
25
- delete value[key];
25
+ if (key !== newKey) delete value[key];
26
26
  });
27
27
  }
28
28
  return value;
29
- }(config, rootDir);
29
+ })(config, rootDir);
30
30
  }
31
31
 
32
32
  function setCldrParentLocales(config) {
@@ -274,8 +274,10 @@ function makeConfig(userConfig, opts = {}) {
274
274
  }
275
275
  };
276
276
  if (!opts.skipValidation) {
277
+ validateFormat(config);
277
278
  validate(config, configValidation);
278
279
  validateLocales(config);
280
+ deprecateParserOptions(config);
279
281
  }
280
282
  config = setCldrParentLocales(config);
281
283
  config = normalizeRuntimeConfigModule(config);
@@ -304,28 +306,21 @@ const defaultConfig = {
304
306
  minimal: true
305
307
  }
306
308
  },
307
- extractorParserOptions: {
308
- flow: false,
309
- tsExperimentalDecorators: false
310
- },
311
309
  fallbackLocales: {},
312
- format: "po",
313
- formatOptions: { origins: true, lineNumbers: true },
314
310
  locales: [],
315
311
  orderBy: "message",
316
312
  pseudoLocale: "",
317
313
  rootDir: ".",
318
314
  runtimeConfigModule: ["@lingui/core", "i18n"],
319
315
  macro: {
320
- corePackage: ["@lingui/macro", "@lingui/core/macro"],
321
- jsxPackage: ["@lingui/macro", "@lingui/react/macro"]
316
+ corePackage: ["@lingui/core/macro"],
317
+ jsxPackage: ["@lingui/react/macro"]
322
318
  },
323
- sourceLocale: "",
324
- service: { name: "", apiKey: "" }
319
+ sourceLocale: ""
325
320
  };
326
321
  const exampleConfig = {
327
322
  ...defaultConfig,
328
- format: multipleValidOptions({}, "po"),
323
+ format: multipleValidOptions({}, {}),
329
324
  extractors: multipleValidOptions([], ["babel"], [Object]),
330
325
  runtimeConfigModule: multipleValidOptions(
331
326
  { i18n: ["@lingui/core", "i18n"], Trans: ["@lingui/react", "Trans"] },
@@ -342,6 +337,10 @@ const exampleConfig = {
342
337
  flow: false,
343
338
  tsExperimentalDecorators: false
344
339
  },
340
+ service: {
341
+ apiKey: "",
342
+ name: ""
343
+ },
345
344
  experimental: {
346
345
  extractor: {
347
346
  entries: [],
@@ -357,13 +356,49 @@ const configValidation = {
357
356
  exampleConfig,
358
357
  comment: "Documentation: https://lingui.dev/ref/conf"
359
358
  };
359
+ function deprecateParserOptions(config) {
360
+ if (config.extractorParserOptions) {
361
+ console.error(
362
+ `\`extractorParserOptions\` config option is deprecated.
363
+
364
+ Please pass options directly to the extractor implementation:
365
+
366
+ import { createBabelExtractor } from '@lingui/cli/api/extractors/babel'
367
+
368
+ export default {
369
+ [...]
370
+ extractors: [createBabelExtractor({parserOptions: { tsExperimentalDecorators: true }})],
371
+ }
372
+ `.trim()
373
+ );
374
+ }
375
+ }
376
+ function validateFormat(config) {
377
+ if (typeof config.format === "string") {
378
+ throw new Error(
379
+ `String formats like \`{format: ${config.format}}\` are no longer supported.
380
+
381
+ Formatters must now be installed as separate packages and provided via format in lingui config:
382
+
383
+ import { formatter } from "@lingui/format-po"
384
+
385
+ export default {
386
+ [...]
387
+ format: formatter({lineNumbers: false}),
388
+ }
389
+ `.trim()
390
+ );
391
+ }
392
+ }
360
393
  function validateLocales(config) {
361
394
  if (!Array.isArray(config.locales) || !config.locales.length) {
362
395
  console.error("No locales defined!\n");
363
396
  console.error(
364
- `Add ${pico.yellow(
397
+ `Add ${styleText(
398
+ "yellow",
365
399
  "'locales'"
366
- )} to your configuration. See ${pico.underline(
400
+ )} to your configuration. See ${styleText(
401
+ "underline",
367
402
  "https://lingui.dev/ref/conf#locales"
368
403
  )}`
369
404
  );
@@ -379,13 +414,13 @@ function configExists(path2) {
379
414
  }
380
415
  function JitiLoader() {
381
416
  return (filepath) => {
382
- const jiti = createJiti(__filename);
417
+ const jiti = createJiti(import.meta.url);
383
418
  const mod = jiti(filepath);
384
419
  return mod?.default ?? mod;
385
420
  };
386
421
  }
387
422
  const moduleName = "lingui";
388
- const configExplorer = cosmiconfigSync(moduleName, {
423
+ const configExplorer = lilconfigSync(moduleName, {
389
424
  searchPlaces: [
390
425
  `${moduleName}.config.js`,
391
426
  `${moduleName}.config.cjs`,
@@ -394,8 +429,6 @@ const configExplorer = cosmiconfigSync(moduleName, {
394
429
  "package.json",
395
430
  `.${moduleName}rc`,
396
431
  `.${moduleName}rc.json`,
397
- `.${moduleName}rc.yaml`,
398
- `.${moduleName}rc.yml`,
399
432
  `.${moduleName}rc.ts`,
400
433
  `.${moduleName}rc.js`
401
434
  ],
@@ -412,23 +445,29 @@ function getConfig({
412
445
  } = {}) {
413
446
  const defaultRootDir = cwd || process.cwd();
414
447
  configPath = configPath || process.env.LINGUI_CONFIG;
415
- const result = configExists(configPath) ? configExplorer.load(configPath) : configExplorer.search(defaultRootDir);
448
+ let result;
449
+ try {
450
+ result = configExists(configPath) ? configExplorer.load(configPath) : configExplorer.search(defaultRootDir);
451
+ } catch (error) {
452
+ result = null;
453
+ }
416
454
  if (!result) {
417
455
  console.error("Lingui was unable to find a config!\n");
418
456
  console.error(
419
- `Create ${pico.bold(
457
+ `Create ${styleText(
458
+ "bold",
420
459
  "'lingui.config.js'"
421
- )} file with LinguiJS configuration in root of your project (next to package.json). See ${pico.underline(
460
+ )} file with LinguiJS configuration in root of your project (next to package.json). See ${styleText(
461
+ "underline",
422
462
  "https://lingui.dev/ref/conf"
423
463
  )}`
424
464
  );
425
465
  throw new Error("No Lingui config found");
426
466
  }
427
- const userConfig = result ? result.config : {};
428
467
  return makeConfig(
429
468
  {
430
- rootDir: result ? path.dirname(result.filepath) : defaultRootDir,
431
- ...userConfig
469
+ rootDir: result ? normalizePath(path.dirname(result.filepath)) : defaultRootDir,
470
+ ...result.config
432
471
  },
433
472
  { skipValidation, resolvedConfigPath: result.filepath }
434
473
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lingui/conf",
3
- "version": "5.9.3",
3
+ "version": "6.0.0-next.1",
4
4
  "sideEffects": false,
5
5
  "description": "Get lingui configuration from package.json",
6
6
  "keywords": [
@@ -19,22 +19,22 @@
19
19
  "name": "Tomáš Ehrlich",
20
20
  "email": "tomas.ehrlich@gmail.com"
21
21
  },
22
- "main": "dist/index.cjs",
23
- "module": "dist/index.mjs",
24
- "types": "dist/index.d.ts",
22
+ "type": "module",
25
23
  "engines": {
26
- "node": ">=20.0.0"
24
+ "node": ">=22.19.0"
27
25
  },
28
26
  "scripts": {
29
- "build": "rimraf ./dist && unbuild",
30
- "stub": "unbuild --stub"
27
+ "build": "unbuild",
28
+ "check-types": "tsc --noEmit"
29
+ },
30
+ "exports": {
31
+ ".": "./dist/index.mjs"
31
32
  },
32
33
  "dependencies": {
33
- "@babel/runtime": "^7.20.13",
34
- "cosmiconfig": "^8.0.0",
35
34
  "jest-validate": "^29.4.3",
36
35
  "jiti": "^2.5.1",
37
- "picocolors": "^1.1.1"
36
+ "lilconfig": "^3.1.3",
37
+ "normalize-path": "^3.0.0"
38
38
  },
39
39
  "files": [
40
40
  "LICENSE",
@@ -42,8 +42,13 @@
42
42
  "/dist"
43
43
  ],
44
44
  "devDependencies": {
45
- "@lingui/jest-mocks": "*",
46
- "unbuild": "^2.0.0"
45
+ "@lingui/test-utils": "3.0.3",
46
+ "@types/normalize-path": "^3.0.0",
47
+ "unbuild": "3.6.1",
48
+ "vitest": "4.0.18"
49
+ },
50
+ "unbuild": {
51
+ "declaration": "node16"
47
52
  },
48
- "gitHead": "67be09ce3416ebd662822bf0689454dbb5e3261a"
53
+ "gitHead": "783af0c0371c7795e1fc43316f49dd253e161221"
49
54
  }