Repository: lingui/js-lingui (ts)

Issue:
Redundant warning Unknown option "extractors"
**Describe the bug**
When config has option `extractors` specified — cli prints warning:
```
● Validation Warning:

  Unknown option "extractors" with value [{"extract": [Function extract], "match": [Function match]}] was found.
  This is probably a typing mistake. Fixing it will remove this message.
```
Option itself seem to work tho. However it seems to have extra issue with documentation, [usage with `require.resolve`](https://github.com/lingui/js-lingui/blob/main/docs/ref/conf.rst?plain=1#L525-L526) does not work, usage with reference to extractor — works.

**To Reproduce**
Add to your config:
```js
const typescript = require('@lingui/cli/api/extractors/typescript');

module.exports = {
  extractors: [typescript.default],
};
```
and run `$ lingui extract`

**Expected behavior**
No warnings printed

**Additional context**
Add any other context about the problem here.

- jsLingui version 3.10.2
- Babel version 7.12.11
- Your Babel config — custom, not involved


Pull request description:
fix(): extractors CLI validation and accept require and require.resolve
Will close #1110 

Patch:
diff --git a/packages/cli/src/api/extractors/index.ts b/packages/cli/src/api/extractors/index.ts
index cb5d23b0..5b735ccb 100644
--- a/packages/cli/src/api/extractors/index.ts
+++ b/packages/cli/src/api/extractors/index.ts
@@ -27,7 +27,15 @@ export default function extract(
 ): boolean {
   const extractorsToExtract = options.extractors ?? DEFAULT_EXTRACTORS
 
-  return extractorsToExtract.some((ext) => {
+  return extractorsToExtract.some((e) => {
+    let ext: ExtractorType = e;
+    if (typeof e === "string") {
+      // in case of the user using require.resolve in their extractors, we require that module
+      ext = require(e)
+      if ((ext as any).default) {
+        ext = (ext as any).default
+      }
+    }
     if (!ext.match(filename)) return false
 
     let spinner
diff --git a/packages/conf/src/index.ts b/packages/conf/src/index.ts
index bb447673..b6787306 100644
--- a/packages/conf/src/index.ts
+++ b/packages/conf/src/index.ts
@@ -45,7 +45,7 @@ export type LinguiConfig = {
   extractBabelOptions: Record<string, unknown>
   compilerBabelOptions: GeneratorOptions
   fallbackLocales?: FallbackLocales
-  extractors?: ExtractorType[]
+  extractors?: ExtractorType[] | string[]
   format: CatalogFormat
   formatOptions: CatalogFormatOptions
   locales: string[]
@@ -82,6 +82,14 @@ export const defaultConfig: LinguiConfig = {
       minimal: true,
     }
   },
+  extractors: multipleValidOptions(
+    [],
+    ["babel"],
+    [{
+      match: (fileName: string) => false,
+      extract: (filename: string, targetDir: string, options?: any) => {}
+    } as ExtractorType]
+  ),
   extractBabelOptions: { plugins: [], presets: [] },
   fallbackLocales: {},
   format: "po",


Test patch:
diff --git a/packages/conf/src/__snapshots__/index.test.ts.snap b/packages/conf/src/__snapshots__/index.test.ts.snap
index 3f88372b..27bdca3f 100644
--- a/packages/conf/src/__snapshots__/index.test.ts.snap
+++ b/packages/conf/src/__snapshots__/index.test.ts.snap
@@ -120,6 +120,18 @@ Object {
     plugins: Array [],
     presets: Array [],
   },
+  extractors: Array [
+    Array [],
+    Array [
+      babel,
+    ],
+    Array [
+      Object {
+        extract: [Function],
+        match: [Function],
+      },
+    ],
+  ],
   fallbackLocales: Object {
     en-gb: en,
   },