From bb75ad3cdbebd5f0ffe4f503a3bcdd2cc1935a96 Mon Sep 17 00:00:00 2001 From: Timofei Iatsenko Date: Wed, 25 Jan 2023 09:14:53 +0100 Subject: [PATCH 1/5] refactor(extractor/babel): make opinionated settings for babel extractor --- examples/js/package.json | 2 +- package.json | 2 +- .../test/index.ts | 3 +- packages/cli/package.json | 9 +- .../api/__snapshots__/catalog.test.ts.snap | 79 ++- packages/cli/src/api/catalog.test.ts | 49 +- packages/cli/src/api/catalog.ts | 18 +- packages/cli/src/api/detect.test.ts | 30 - packages/cli/src/api/detect.ts | 60 -- packages/cli/src/api/extractors/babel.ts | 67 +- packages/cli/src/api/extractors/index.ts | 40 +- packages/cli/src/api/extractors/typescript.ts | 68 +-- .../collect-syntax-flow/flow-syntax.js | 5 + .../collect-syntax-flow/lingui.config.js | 10 + .../fixtures/collect-syntax-flow/ts-syntax.ts | 3 + .../collect-typescript-jsx/jsx-syntax.jsx | 38 ++ .../collect-typescript-jsx/lingui.config.js | 3 + .../fixtures/collect-typescript-jsx/macro.tsx | 25 + .../collect-typescript-jsx/tsx-syntax.tsx | 47 ++ packages/cli/src/lingui-extract-template.ts | 9 - packages/cli/src/lingui-extract.ts | 43 +- packages/cli/src/tests.ts | 2 +- .../conf/src/__snapshots__/index.test.ts.snap | 5 +- packages/conf/src/makeConfig.ts | 31 +- packages/conf/src/types.ts | 16 +- packages/macro/src/index.ts | 26 +- packages/macro/src/macroJs.test.ts | 5 +- packages/macro/src/macroJs.ts | 16 +- packages/macro/src/macroJsx.test.ts | 2 +- packages/macro/src/macroJsx.ts | 28 +- packages/macro/test/index.ts | 43 +- packages/macro/test/js-t.ts | 30 + packages/macro/test/jsx-trans.ts | 15 + tsconfig.json | 3 +- yarn.lock | 574 +++++++++--------- 35 files changed, 770 insertions(+), 636 deletions(-) delete mode 100644 packages/cli/src/api/detect.test.ts delete mode 100644 packages/cli/src/api/detect.ts create mode 100644 packages/cli/src/api/fixtures/collect-syntax-flow/flow-syntax.js create mode 100644 packages/cli/src/api/fixtures/collect-syntax-flow/lingui.config.js create mode 100644 packages/cli/src/api/fixtures/collect-syntax-flow/ts-syntax.ts create mode 100644 packages/cli/src/api/fixtures/collect-typescript-jsx/jsx-syntax.jsx create mode 100644 packages/cli/src/api/fixtures/collect-typescript-jsx/lingui.config.js create mode 100644 packages/cli/src/api/fixtures/collect-typescript-jsx/macro.tsx create mode 100644 packages/cli/src/api/fixtures/collect-typescript-jsx/tsx-syntax.tsx diff --git a/examples/js/package.json b/examples/js/package.json index 26642433a..8fd5b56e7 100644 --- a/examples/js/package.json +++ b/examples/js/package.json @@ -20,7 +20,7 @@ "@babel/preset-env": "^7.20.2", "@lingui/cli": "^3.5.1", "babel-jest": "^26.6.1", - "babel-plugin-macros": "^2.8.0", + "babel-plugin-macros": "^3.1.0", "jest": "^26.6.1" } } diff --git a/package.json b/package.json index fcbc3ea7a..43b437562 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "@typescript-eslint/parser": "^5.50.0", "babel-eslint": "^10.1.0", "babel-jest": "^26.5.2", - "babel-plugin-macros": "^2.8.0", + "babel-plugin-macros": "^3.1.0", "chalk": "^4.1.0", "codecov": "^3.8.1", "cross-env": "^7.0.2", diff --git a/packages/babel-plugin-extract-messages/test/index.ts b/packages/babel-plugin-extract-messages/test/index.ts index 377dc1e2b..c2a1e8655 100644 --- a/packages/babel-plugin-extract-messages/test/index.ts +++ b/packages/babel-plugin-extract-messages/test/index.ts @@ -18,7 +18,6 @@ const transformCode = ( filename = "test-case.js", rootDir = "." ) => { - process.env.LINGUI_EXTRACT = "1" process.env.LINGUI_CONFIG = path.join( __dirname, "fixtures", @@ -45,6 +44,7 @@ const transformCode = ( [ "macros", { + lingui: { extract: true }, // macro plugin uses package `resolve` to find a path of macro file // this will not follow jest pathMapping and will resolve path from ./build // instead of ./src which makes testing & developing hard. @@ -56,7 +56,6 @@ const transformCode = ( ], }) } finally { - process.env.LINGUI_EXTRACT = null process.env.LINGUI_CONFIG = null } diff --git a/packages/cli/package.json b/packages/cli/package.json index 712608184..8fa841965 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -50,6 +50,7 @@ "@babel/plugin-syntax-jsx": "^7.18.6", "@babel/runtime": "^7.20.13", "@babel/types": "^7.20.7", + "@babel/core": "^7.20.12", "@lingui/babel-plugin-extract-messages": "3.17.1", "@lingui/conf": "3.17.1", "@lingui/core": "3.17.1", @@ -71,7 +72,6 @@ "normalize-path": "^3.0.0", "ora": "^5.1.0", "papaparse": "^5.3.0", - "pkg-up": "^3.1.0", "plurals-cldr": "^1.0.4", "pofile": "^1.1.4", "pseudolocale": "^1.1.0", @@ -83,11 +83,6 @@ "@types/papaparse": "^5.2.3", "@types/plurals-cldr": "^1.0.1", "mockdate": "^3.0.2", - "typescript": "^4.9.5" - }, - "peerDependencies": { - "@babel/core": "^7.0.0", - "babel-plugin-macros": "2 || 3", - "typescript": "2 || 3 || 4" + "fs-extra": "^9.0.1" } } diff --git a/packages/cli/src/api/__snapshots__/catalog.test.ts.snap b/packages/cli/src/api/__snapshots__/catalog.test.ts.snap index fc1dd47de..8a199800b 100644 --- a/packages/cli/src/api/__snapshots__/catalog.test.ts.snap +++ b/packages/cli/src/api/__snapshots__/catalog.test.ts.snap @@ -118,7 +118,84 @@ Object { } `; -exports[`Catalog collect should handle errors 1`] = `undefined`; +exports[`Catalog collect should support Flow syntax if enabled 1`] = `Object {}`; + +exports[`Catalog collect should support JSX and Typescript 1`] = ` +Object { + Description: Object { + extractedComments: Array [ + description, + ], + message: undefined, + origin: Array [ + Array [ + collect-typescript-jsx/macro.tsx, + 6, + ], + ], + }, + Hi, my name is {name}: Object { + extractedComments: Array [], + message: undefined, + origin: Array [ + Array [ + collect-typescript-jsx/macro.tsx, + 17, + ], + ], + }, + ID Some: Object { + extractedComments: Array [], + message: Message with id some, + origin: Array [ + Array [ + collect-typescript-jsx/macro.tsx, + 11, + ], + ], + }, + Message: Object { + extractedComments: Array [], + message: undefined, + origin: Array [ + Array [ + collect-typescript-jsx/macro.tsx, + 4, + ], + ], + }, + Some message: Object { + extractedComments: Array [], + message: undefined, + origin: Array [ + Array [ + collect-typescript-jsx/macro.tsx, + 18, + ], + ], + }, + Title: Object { + extractedComments: Array [], + message: undefined, + origin: Array [ + Array [ + collect-typescript-jsx/macro.tsx, + 19, + ], + ], + }, + {count, plural, one {# book} other {# books}}: Object { + extractedComments: Array [], + message: undefined, + origin: Array [ + Array [ + collect-typescript-jsx/macro.tsx, + 21, + ], + ], + }, +} +`; exports[`Catalog make should collect and write catalogs 1`] = ` Object { diff --git a/packages/cli/src/api/catalog.test.ts b/packages/cli/src/api/catalog.test.ts index 719a5b058..fd56724cb 100644 --- a/packages/cli/src/api/catalog.test.ts +++ b/packages/cli/src/api/catalog.test.ts @@ -198,6 +198,49 @@ describe("Catalog", () => { }) describe("collect", () => { + it("should support JSX and Typescript", async () => { + process.env.LINGUI_CONFIG = path.join( + __dirname, + "fixtures/collect-typescript-jsx/lingui.config.js" + ) + const catalog = new Catalog( + { + name: "messages", + path: "locales/{locale}", + include: [fixture("collect-typescript-jsx/")], + exclude: [], + }, + mockConfig() + ) + + const messages = await catalog.collect() + expect(messages).toBeTruthy() + expect(messages).toMatchSnapshot() + }) + + it("should support Flow syntax if enabled", async () => { + process.env.LINGUI_CONFIG = path.join( + __dirname, + "fixtures/collect-syntax-flow/lingui.config.js" + ) + const catalog = new Catalog( + { + name: "messages", + path: "locales/{locale}", + include: [fixture("collect-syntax-flow/")], + exclude: [], + }, + mockConfig({ + extractorParserOptions: { + flow: true, + }, + }) + ) + + const messages = await catalog.collect() + expect(messages).toBeTruthy() + expect(messages).toMatchSnapshot() + }) it("should extract messages from source files", async () => { const catalog = new Catalog( { @@ -209,7 +252,7 @@ describe("Catalog", () => { mockConfig() ) - const messages = await catalog.collect(defaultMakeOptions) + const messages = await catalog.collect() expect(messages).toMatchSnapshot() }) @@ -228,7 +271,6 @@ describe("Catalog", () => { ) const messages = await catalog.collect({ - ...defaultMakeOptions, files: [fixture("collect/componentA")], }) expect(messages).toMatchSnapshot() @@ -247,7 +289,6 @@ describe("Catalog", () => { mockConsole(async (console) => { await catalog.collect({ - ...defaultMakeOptions, files: [fixture("duplicate-id.js")], }) @@ -271,7 +312,7 @@ describe("Catalog", () => { ) mockConsole(async (console) => { - const messages = await catalog.collect(defaultMakeOptions) + const messages = await catalog.collect() expect(console.error).toBeCalledWith( expect.stringContaining(`Cannot process file`) ) diff --git a/packages/cli/src/api/catalog.ts b/packages/cli/src/api/catalog.ts index 46dabfd98..2e153cca9 100644 --- a/packages/cli/src/api/catalog.ts +++ b/packages/cli/src/api/catalog.ts @@ -11,7 +11,7 @@ import getFormat, { CatalogFormatOptionsInternal, CatalogFormatter, } from "./formats" -import extract, { ExtractedMessage } from "./extractors" +import extract, { ExtractedMessage, ExtractorType } from "./extractors" import { CliExtractOptions } from "../lingui-extract" import { CliExtractTemplateOptions } from "../lingui-extract-template" import { CompiledCatalogNamespace } from "./compile" @@ -54,17 +54,13 @@ export type AllCatalogsType = { } export type MakeOptions = CliExtractOptions & { - projectType?: string orderBy?: OrderBy } export type MakeTemplateOptions = CliExtractTemplateOptions & { - projectType?: string orderBy?: OrderBy } -type CollectOptions = MakeOptions | MakeTemplateOptions - export type MergeOptions = { overwrite: boolean files?: string[] @@ -115,7 +111,7 @@ export class Catalog { } async make(options: MakeOptions): Promise { - const nextCatalog = await this.collect(options) + const nextCatalog = await this.collect({ files: options.files }) if (!nextCatalog) return false const prevCatalogs = this.readAll() @@ -145,7 +141,7 @@ export class Catalog { } async makeTemplate(options: MakeTemplateOptions): Promise { - const catalog = await this.collect(options) + const catalog = await this.collect({ files: options.files }) if (!catalog) return false const sort = order(options.orderBy) this.writeTemplate(sort(catalog as CatalogType)) @@ -156,7 +152,7 @@ export class Catalog { * Collect messages from source paths. Return a raw message catalog as JSON. */ async collect( - options: CollectOptions + options: { files?: string[] } = {} ): Promise { const messages: ExtractedCatalogType = {} @@ -207,10 +203,8 @@ export class Catalog { } }, { - verbose: options.verbose, - babelOptions: this.config.extractBabelOptions, - extractors: options.extractors, - projectType: options.projectType, + parserOptions: this.config.extractorParserOptions, + extractors: this.config.extractors as ExtractorType[], } ) catalogSuccess &&= fileSuccess diff --git a/packages/cli/src/api/detect.test.ts b/packages/cli/src/api/detect.test.ts deleted file mode 100644 index 528e6d190..000000000 --- a/packages/cli/src/api/detect.test.ts +++ /dev/null @@ -1,30 +0,0 @@ -import mockFs from "mock-fs" -import { detect, projectType } from "./detect" - -describe("detect", function () { - afterEach(mockFs.restore) - - it("should detect create-react-app project", () => { - mockFs({ - "package.json": JSON.stringify({ - dependencies: { - "react-scripts": "2.0.0", - }, - }), - }) - - expect(detect()).toEqual(projectType.CRA) - }) - - it("should detect react project", () => { - mockFs({ - "package.json": JSON.stringify({ - dependencies: { - react: "16.4.1", - }, - }), - }) - - expect(detect()).toEqual(projectType.REACT) - }) -}) diff --git a/packages/cli/src/api/detect.ts b/packages/cli/src/api/detect.ts deleted file mode 100644 index 2daa0f8bb..000000000 --- a/packages/cli/src/api/detect.ts +++ /dev/null @@ -1,60 +0,0 @@ -import fs from "fs" -import nodePath from "path" -import pkgUp from "pkg-up" -import cliPackageJson from "../../package.json" - -export const projectType = { - CRA: "CRA", - REACT: "REACT", -} - -type PackageJson = { - name: string - dependencies: Record - devDependencies: Record -} - -function getPackageJson(cwd?: string): { path: string; content: PackageJson } { - const packageJsonPath = pkgUp.sync({ - cwd, - }) - - try { - const json = fs.readFileSync(packageJsonPath, "utf8") - return { path: packageJsonPath, content: JSON.parse(json) } - } catch (e) { - console.error(e) - return null - } -} - -function hasDependency(pkg: PackageJson, name: string) { - return ( - (pkg.dependencies && pkg.dependencies[name]) || - (pkg.devDependencies && pkg.devDependencies[name]) - ) -} - -function detectFramework(pkg: PackageJson) { - if (hasDependency(pkg, "react-scripts")) { - return projectType.CRA - } - - if (hasDependency(pkg, "react")) { - return projectType.REACT - } - - return null -} - -export function detect() { - let pkg = getPackageJson() - - if (!pkg) return null - - if (pkg.content.name === cliPackageJson.name) { - pkg = getPackageJson(nodePath.dirname(pkg.path)) - } - - return detectFramework(pkg.content) -} diff --git a/packages/cli/src/api/extractors/babel.ts b/packages/cli/src/api/extractors/babel.ts index 8b8c15d16..7d910ee43 100644 --- a/packages/cli/src/api/extractors/babel.ts +++ b/packages/cli/src/api/extractors/babel.ts @@ -1,14 +1,14 @@ -import { DEFAULT_EXTENSIONS, transformFileSync } from "@babel/core" +import { DEFAULT_EXTENSIONS, transformAsync } from "@babel/core" import type { ExtractPluginOpts } from "@lingui/babel-plugin-extract-messages" import linguiExtractMessages from "@lingui/babel-plugin-extract-messages" -import { BabelOptions, ExtractorType } from "." -import { projectType } from "../detect" +import { ExtractorType } from "." +import { ParserPlugin } from "@babel/parser" const babelRe = new RegExp( "\\.(" + - [...DEFAULT_EXTENSIONS, ".ts", ".tsx"] + [...DEFAULT_EXTENSIONS, ".ts", ".mts", ".cts", ".tsx"] .map((ext) => ext.slice(1)) .join("|") + ")$", @@ -20,26 +20,57 @@ const extractor: ExtractorType = { return babelRe.test(filename) }, - extract(filename, onMessageExtracted, options = {}) { - const { babelOptions: _babelOptions = {} } = options - const { plugins = [], ...babelOptions } = _babelOptions - const frameworkOptions: BabelOptions = {} + async extract(filename, code, onMessageExtracted, options = {}) { + const parserPlugins: ParserPlugin[] = [ + // https://babeljs.io/docs/en/babel-parser#latest-ecmascript-features + [ + "decorators", + { + decoratorsBeforeExport: + options?.parserOptions?.decoratorsBeforeExport || true, + }, + ], + ] - if (options.projectType === projectType.CRA) { - frameworkOptions.presets = ["react-app"] + if ( + [/\.ts$/, /\.mts$/, /\.cts$/, /\.tsx$/].some((r) => filename.match(r)) + ) { + parserPlugins.push("typescript") + } else if (options?.parserOptions?.flow) { + parserPlugins.push("flow") } - const pluginOpts: ExtractPluginOpts = { + if ([/\.jsx$/, /\.tsx$/].some((r) => filename.match(r))) { + parserPlugins.push("jsx") + } + + const extractPluginOpts: ExtractPluginOpts = { onMessageExtracted, } - transformFileSync(filename, { - ...babelOptions, - ...frameworkOptions, - // we override envName to avoid issues with NODE_ENV=production - // https://github.com/lingui/js-lingui/issues/952 - envName: "development", - plugins: ["macros", [linguiExtractMessages, pluginOpts], ...plugins], + await transformAsync(code, { + // don't generate code + code: false, + + babelrc: false, + configFile: false, + + filename: filename, + + sourceMaps: options.sourceMaps, + parserOpts: { + plugins: parserPlugins, + }, + + plugins: [ + [ + "macros", + { + lingui: { extract: true }, + }, + ], + [linguiExtractMessages, extractPluginOpts], + ], }) }, } diff --git a/packages/cli/src/api/extractors/index.ts b/packages/cli/src/api/extractors/index.ts index 8eb6bcb60..c3a091c82 100644 --- a/packages/cli/src/api/extractors/index.ts +++ b/packages/cli/src/api/extractors/index.ts @@ -1,11 +1,11 @@ -import ora from "ora" +import fs from "fs/promises" import babel from "./babel" const DEFAULT_EXTRACTORS: ExtractorType[] = [babel] -export type BabelOptions = { - plugins?: Array - presets?: Array +export type ParserOptions = { + decoratorsBeforeExport?: boolean + flow?: boolean } export type ExtractedMessage = { @@ -18,19 +18,23 @@ export type ExtractedMessage = { comment?: string } -export type ExtractOptions = { - verbose?: boolean - projectType?: string +type ExtractOptions = { extractors?: ExtractorType[] - babelOptions?: BabelOptions + parserOptions?: ParserOptions +} + +export type ExtractorOptions = { + parserOptions?: ParserOptions + sourceMaps?: any } export type ExtractorType = { match(filename: string): boolean extract( filename: string, + code: string, onMessageExtracted: (msg: ExtractedMessage) => void, - options?: ExtractOptions + options?: ExtractorOptions ): Promise | void } @@ -53,21 +57,15 @@ export default async function extract( if (!ext.match(filename)) continue - let spinner - if (options.verbose) spinner = ora().start(filename) - try { - await ext.extract(filename, onMessageExtracted, options) - - if (options.verbose && spinner) spinner.succeed() + const file = await fs.readFile(filename) + await ext.extract(filename, file.toString(), onMessageExtracted, { + parserOptions: options.parserOptions, + }) return true } catch (e) { - if (options.verbose && spinner) { - spinner.fail((e as Error).message) - } else { - console.error(`Cannot process file ${(e as Error).message}`) - console.error((e as Error).stack) - } + console.error(`Cannot process file ${(e as Error).message}`) + console.error((e as Error).stack) return false } } diff --git a/packages/cli/src/api/extractors/typescript.ts b/packages/cli/src/api/extractors/typescript.ts index 2849b29b8..67285eebf 100644 --- a/packages/cli/src/api/extractors/typescript.ts +++ b/packages/cli/src/api/extractors/typescript.ts @@ -1,69 +1,15 @@ -import fs from "fs" -import { transform } from "@babel/core" -import linguiExtractMessages, { - ExtractPluginOpts, -} from "@lingui/babel-plugin-extract-messages" - -import { projectType } from "../detect" -import { ExtractorType, BabelOptions } from "." - -const typescriptRe = /(^.?|\.[^d]|[^.]d|[^.][^d])\.tsx?$/i +import { ExtractorType } from "." const extractor: ExtractorType = { match(filename) { - return typescriptRe.test(filename) + throw new Error( + "Typescript extractor was removed. " + + "Lingui CLI can parse typescript out of the box. " + + "Please remove it from your lingui.config.js" + ) }, - extract( - filename: string, - onMessageExtracted, - options = {} - ): Promise | void { - const ts = require("typescript") - - const content = fs.readFileSync(filename, "utf8") - const isTsx = filename.endsWith(".tsx") - // pass jsx to babel untouched - const jsx = isTsx ? ts.JsxEmit.Preserve : ts.JsxEmit.None - const stripped = ts.transpileModule(content, { - compilerOptions: { - filename, - jsx, - module: ts.ModuleKind.ESNext, - target: ts.ScriptTarget.ES2016, // use ES2015 or ES2016 to preserve tagged template literal - allowSyntheticDefaultImports: true, - moduleResolution: ts.ModuleResolutionKind.NodeJs, - }, - }) - - const frameworkOptions: BabelOptions = {} - - if (options.projectType === projectType.CRA) { - frameworkOptions.presets = ["react-app"] - } - - const pluginOpts: ExtractPluginOpts = { - onMessageExtracted, - } - - const { babelOptions = {} } = options - const plugins = [ - "macros", - [linguiExtractMessages, pluginOpts], - ...(babelOptions.plugins || []), - ] - - if (isTsx) { - plugins.unshift(require.resolve("@babel/plugin-syntax-jsx")) - } - - transform(stripped.outputText, { - ...babelOptions, - ...frameworkOptions, - filename, - plugins, - }) - }, + extract(): Promise | void {}, } export default extractor diff --git a/packages/cli/src/api/fixtures/collect-syntax-flow/flow-syntax.js b/packages/cli/src/api/fixtures/collect-syntax-flow/flow-syntax.js new file mode 100644 index 000000000..11fcf8686 --- /dev/null +++ b/packages/cli/src/api/fixtures/collect-syntax-flow/flow-syntax.js @@ -0,0 +1,5 @@ +// @flow +function truthy(a: ?string, b: ?string): boolean %checks { + return a != null && b != null; +} + diff --git a/packages/cli/src/api/fixtures/collect-syntax-flow/lingui.config.js b/packages/cli/src/api/fixtures/collect-syntax-flow/lingui.config.js new file mode 100644 index 000000000..265afcf7f --- /dev/null +++ b/packages/cli/src/api/fixtures/collect-syntax-flow/lingui.config.js @@ -0,0 +1,10 @@ +/** + * + * @type {import('@lingui/conf').LinguiConfig} + */ +module.exports = { + locales: ["en", "cs"], + extractorParserOptions: { + flow: true + } +} diff --git a/packages/cli/src/api/fixtures/collect-syntax-flow/ts-syntax.ts b/packages/cli/src/api/fixtures/collect-syntax-flow/ts-syntax.ts new file mode 100644 index 000000000..40a428ef5 --- /dev/null +++ b/packages/cli/src/api/fixtures/collect-syntax-flow/ts-syntax.ts @@ -0,0 +1,3 @@ +function foo(bar?: string): string { + return bar; +} diff --git a/packages/cli/src/api/fixtures/collect-typescript-jsx/jsx-syntax.jsx b/packages/cli/src/api/fixtures/collect-typescript-jsx/jsx-syntax.jsx new file mode 100644 index 000000000..a169d7425 --- /dev/null +++ b/packages/cli/src/api/fixtures/collect-typescript-jsx/jsx-syntax.jsx @@ -0,0 +1,38 @@ +// check parsing different syntax proposals + +const jsx =
Hello!
+ +@Decorator() +export class TestDecorator { + @Decorator() + prop; + + @Decorator() + method() {}; +} + +class A { + // classProperties + b = 1; + + // classPrivateProperties + #b = 1; +} + +// dynamicImport +import('./guy').then(a) + +// exportNamespaceFrom +export * as ns from "mod" + +// nullishCoalescingOperator +const a = a ?? b; + +// objectRestSpread +const b = { b, ...c }; + +// optionalChaining +const c = a?.b; + +// topLevelAwait +await promise; diff --git a/packages/cli/src/api/fixtures/collect-typescript-jsx/lingui.config.js b/packages/cli/src/api/fixtures/collect-typescript-jsx/lingui.config.js new file mode 100644 index 000000000..56ad10839 --- /dev/null +++ b/packages/cli/src/api/fixtures/collect-typescript-jsx/lingui.config.js @@ -0,0 +1,3 @@ +module.exports = { + locales: ["en", "cs"] +} diff --git a/packages/cli/src/api/fixtures/collect-typescript-jsx/macro.tsx b/packages/cli/src/api/fixtures/collect-typescript-jsx/macro.tsx new file mode 100644 index 000000000..3f499dcd9 --- /dev/null +++ b/packages/cli/src/api/fixtures/collect-typescript-jsx/macro.tsx @@ -0,0 +1,25 @@ +import { t, defineMessage, plural, Trans } from "@lingui/macro" + +// JS Macro usages +const msg = t`Message` + +const withDescription = defineMessage({ + message: 'Description', + comment: "description" +}) + +const withTId = t({ + id: "ID Some", + message: "Message with id some" + }) + +// JSX Macro usages +;Hi, my name is {name} +;Some message +; +; diff --git a/packages/cli/src/api/fixtures/collect-typescript-jsx/tsx-syntax.tsx b/packages/cli/src/api/fixtures/collect-typescript-jsx/tsx-syntax.tsx new file mode 100644 index 000000000..0b7c3ba2d --- /dev/null +++ b/packages/cli/src/api/fixtures/collect-typescript-jsx/tsx-syntax.tsx @@ -0,0 +1,47 @@ +const jsx =
Hello!
+ +// Typescript syntax +function foo(bar: string): string { + return bar; +} + +const test1: string = ""; + +// check parsing different syntax proposals +@Decorator() +export class TestDecorator { + @Decorator() + prop; + + @Decorator() + method() {}; +} + +// optional chaining +const test = foo?.bar?.baz; + +class A { + // classProperties + b = 1; + + // classPrivateProperties + #b = 1; +} + +// dynamicImport +import('./guy').then(a) + +// exportNamespaceFrom +export * as ns from "mod" + +// nullishCoalescingOperator +const a = a ?? b; + +// objectRestSpread +const b = { b, ...c }; + +// optionalChaining +const c = a?.b; + +// topLevelAwait +await promise; diff --git a/packages/cli/src/lingui-extract-template.ts b/packages/cli/src/lingui-extract-template.ts index 2ad506d7b..2137fdedb 100644 --- a/packages/cli/src/lingui-extract-template.ts +++ b/packages/cli/src/lingui-extract-template.ts @@ -4,13 +4,10 @@ import program from "commander" import { getConfig, LinguiConfig } from "@lingui/conf" import { getCatalogs } from "./api/catalog" -import { detect } from "./api/detect" -import { ExtractorType } from "./api/extractors" export type CliExtractTemplateOptions = { verbose: boolean configPath: string - extractors?: ExtractorType[] files?: string[] } @@ -24,11 +21,6 @@ export default async function command( process.env.BABEL_ENV = "development" } - // We need macros to keep imports, so extract-messages plugin know what componets - // to collect. Users usually use both BABEN_ENV and NODE_ENV, so it's probably - // safer to introduce a new env variable. LINGUI_EXTRACT=1 during `lingui extract` - process.env.LINGUI_EXTRACT = "1" - options.verbose && console.log("Extracting messages from source files…") const catalogs = getCatalogs(config) const catalogStats: { [path: string]: Number } = {} @@ -38,7 +30,6 @@ export default async function command( await catalog.makeTemplate({ ...(options as CliExtractTemplateOptions), orderBy: config.orderBy, - projectType: detect(), }) const catalogTemplate = catalog.readTemplate() if (catalogTemplate !== null && catalogTemplate !== undefined) { diff --git a/packages/cli/src/lingui-extract.ts b/packages/cli/src/lingui-extract.ts index 9e62756ff..9bbff2806 100644 --- a/packages/cli/src/lingui-extract.ts +++ b/packages/cli/src/lingui-extract.ts @@ -6,15 +6,13 @@ import { getConfig, LinguiConfigNormalized } from "@lingui/conf" import { AllCatalogsType, getCatalogs } from "./api/catalog" import { printStats } from "./api/stats" -import { detect } from "./api/detect" import { helpRun } from "./api/help" -import { ExtractorType } from "./api/extractors" +import ora from "ora" export type CliExtractOptions = { verbose: boolean files?: string[] clean: boolean - extractors?: ExtractorType[] configPath: string overwrite: boolean locale: string @@ -32,28 +30,30 @@ export default async function command( process.env.BABEL_ENV = "development" } - // We need macros to keep imports, so extract-messages plugin know what componets - // to collect. Users usually use both BABEN_ENV and NODE_ENV, so it's probably - // safer to introduce a new env variable. LINGUI_EXTRACT=1 during `lingui extract` - process.env.LINGUI_EXTRACT = "1" - options.verbose && console.log("Extracting messages from source files…") const catalogs = getCatalogs(config) const catalogStats: { [path: string]: AllCatalogsType } = {} let commandSuccess = true + + const spinner = ora().start() + for (let catalog of catalogs) { const catalogSuccess = await catalog.make({ ...(options as CliExtractOptions), orderBy: config.orderBy, - extractors: config.extractors as ExtractorType[], - projectType: detect(), }) catalogStats[catalog.path] = catalog.readAll() commandSuccess &&= catalogSuccess } + if (commandSuccess) { + spinner.succeed() + } else { + spinner.fail() + } + Object.entries(catalogStats).forEach(([key, value]) => { console.log(`Catalog statistics for ${key}: `) console.log(printStats(config, value).toString()) @@ -108,12 +108,6 @@ if (require.main === module) { "Convert from previous format of message catalogs" ) .option("--watch", "Enables Watch Mode") - // Obsolete options - .option( - "--babelOptions", - "Babel options passed to transform/extract plugins" - ) - .option("--format ", "Format of message catalogs") .parse(process.argv) const config = getConfig({ @@ -121,23 +115,6 @@ if (require.main === module) { }) let hasErrors = false - if (program.format) { - hasErrors = true - const msg = - "--format option is deprecated." + - " Please set format in configuration https://lingui.dev/ref/conf#format" - console.error(msg) - console.error() - } - - if (program.babelOptions) { - hasErrors = true - const msg = - "--babelOptions option is deprecated." + - " Please set extractBabelOptions in configuration https://lingui.dev/ref/conf#extractbabeloptions" - console.error(msg) - console.error() - } const prevFormat = program.convertFrom if (prevFormat && config.format === prevFormat) { diff --git a/packages/cli/src/tests.ts b/packages/cli/src/tests.ts index 5891a2cec..490cf17d8 100644 --- a/packages/cli/src/tests.ts +++ b/packages/cli/src/tests.ts @@ -12,7 +12,7 @@ import { } from "./api/catalog" import { LinguiConfig, makeConfig } from "@lingui/conf" -export function copyFixture(fixtureDir) { +export function copyFixture(fixtureDir: string) { const tmpDir = fs.mkdtempSync( path.join(os.tmpdir(), `lingui-test-${process.pid}`) ) diff --git a/packages/conf/src/__snapshots__/index.test.ts.snap b/packages/conf/src/__snapshots__/index.test.ts.snap index fc9815c14..2ebd2f015 100644 --- a/packages/conf/src/__snapshots__/index.test.ts.snap +++ b/packages/conf/src/__snapshots__/index.test.ts.snap @@ -41,10 +41,7 @@ Object { }, minified: true, }, - extractBabelOptions: Object { - plugins: Array [], - presets: Array [], - }, + extractorParserOptions: Object {}, fallbackLocales: Object { en-gb: en, }, diff --git a/packages/conf/src/makeConfig.ts b/packages/conf/src/makeConfig.ts index a2f1f720d..b7c68b049 100644 --- a/packages/conf/src/makeConfig.ts +++ b/packages/conf/src/makeConfig.ts @@ -1,4 +1,5 @@ import { + ExtractedMessage, ExtractorType, FallbackLocales, LinguiConfig, @@ -17,6 +18,7 @@ import { replaceRootDir } from "./utils/replaceRootDir" import { multipleValidOptions, validate } from "jest-validate" import { setCldrParentLocales } from "./migrations/setCldrParentLocales" import { pathJoinPosix } from "./utils/pathJoinPosix" +import type { ExtractorOptions } from "@lingui/cli/src/api/extractors" export function makeConfig( userConfig: Partial, @@ -63,7 +65,10 @@ export const defaultConfig: LinguiConfig = { minimal: true, }, }, - extractBabelOptions: { plugins: [], presets: [] }, + extractorParserOptions: { + flow: false, + decoratorsBeforeExport: false, + }, fallbackLocales: {} as FallbackLocales, format: "po", formatOptions: { origins: true, lineNumbers: true }, @@ -83,7 +88,12 @@ export const exampleConfig = { [ { match: (fileName: string) => false, - extract: (filename: string, onMessageExtracted, options?: any) => {}, + extract: ( + filename: string, + code: string, + onMessageExtracted: (msg: ExtractedMessage) => void, + options?: ExtractorOptions + ) => {}, } as ExtractorType, ] ), @@ -98,20 +108,9 @@ export const exampleConfig = { { default: "en" }, false ), - extractBabelOptions: { - extends: "babelconfig.js", - rootMode: "rootmode", - plugins: ["plugin"], - presets: ["preset"], - targets: multipleValidOptions( - {}, - "> 0.5%", - ["> 0.5%", "not dead"], - undefined - ), - assumptions: multipleValidOptions({}, undefined), - browserslistConfigFile: multipleValidOptions(true, undefined), - browserslistEnv: multipleValidOptions(".browserslistrc", undefined), + extractorParserOptions: { + flow: false, + decoratorsBeforeExport: false, }, } diff --git a/packages/conf/src/types.ts b/packages/conf/src/types.ts index cb79820b3..bfd338aa7 100644 --- a/packages/conf/src/types.ts +++ b/packages/conf/src/types.ts @@ -1,5 +1,5 @@ import { GeneratorOptions } from "@babel/core" -import { ExtractOptions } from "@lingui/cli/src/api/extractors" +import type { ExtractorOptions } from "@lingui/cli/src/api/extractors" export type CatalogFormat = "lingui" | "minimal" | "po" | "csv" | "po-gettext" @@ -17,8 +17,9 @@ export type ExtractorType = { match(filename: string): boolean extract( filename: string, + code: string, onMessageExtracted: (msg: ExtractedMessage) => void, - options?: ExtractOptions + options?: ExtractorOptions ): Promise | void } @@ -54,7 +55,16 @@ type CatalogService = { export type LinguiConfig = { catalogs: CatalogConfig[] compileNamespace: "es" | "ts" | "cjs" | string - extractBabelOptions: Record + extractorParserOptions: { + /** + * default true + */ + decoratorsBeforeExport?: boolean + /** + * Enable if you use flow. This will apply Flow syntax to js files + */ + flow?: boolean + } compilerBabelOptions: GeneratorOptions fallbackLocales?: FallbackLocales | false extractors?: ExtractorType[] | string[] diff --git a/packages/macro/src/index.ts b/packages/macro/src/index.ts index fe6944086..a774ec9fe 100644 --- a/packages/macro/src/index.ts +++ b/packages/macro/src/index.ts @@ -10,6 +10,11 @@ import { isIdentifier, } from "@babel/types" +export type LinguiMacroOpts = { + // explicitly set by CLI when running extraction process + extract?: boolean +} + const config = getConfig({ configPath: process.env.LINGUI_CONFIG }) const getSymbolSource = ( @@ -44,7 +49,9 @@ const jsMacroTags = new Set([ const jsxMacroTags = new Set(["Trans", "Plural", "Select", "SelectOrdinal"]) -function macro({ references, state, babel }: MacroParams) { +function macro({ references, state, babel, config }: MacroParams) { + const opts: LinguiMacroOpts = config as LinguiMacroOpts + const jsxNodes: NodePath[] = [] const jsNodes: NodePath[] = [] let needsI18nImport = false @@ -66,15 +73,18 @@ function macro({ references, state, babel }: MacroParams) { } }) + const stripNonEssentialProps = + process.env.NODE_ENV == "production" && !opts.extract + jsNodes.filter(isRootPath(jsNodes)).forEach((path) => { if (alreadyVisited(path)) return - const macro = new MacroJS(babel, { i18nImportName }) + const macro = new MacroJS(babel, { i18nImportName, stripNonEssentialProps }) if (macro.replacePath(path)) needsI18nImport = true }) jsxNodes.filter(isRootPath(jsxNodes)).forEach((path) => { if (alreadyVisited(path)) return - const macro = new MacroJSX(babel) + const macro = new MacroJSX(babel, { stripNonEssentialProps }) macro.replacePath(path) }) @@ -85,12 +95,6 @@ function macro({ references, state, babel }: MacroParams) { if (jsxNodes.length) { addImport(babel, state, TransImportModule, TransImportName) } - - if (process.env.LINGUI_EXTRACT === "1") { - return { - keepImports: true, - } - } } function addImport( @@ -165,4 +169,6 @@ const alreadyVisited = (path: NodePath) => { }) }) -export default createMacro(macro) +export default createMacro(macro, { + configName: "lingui", +}) diff --git a/packages/macro/src/macroJs.test.ts b/packages/macro/src/macroJs.test.ts index 70cd648f3..474a8c16f 100644 --- a/packages/macro/src/macroJs.test.ts +++ b/packages/macro/src/macroJs.test.ts @@ -4,7 +4,10 @@ import MacroJs from "./macroJs" import { CallExpression } from "@babel/types" function createMacro() { - return new MacroJs({ types }, { i18nImportName: "i18n" }) + return new MacroJs( + { types }, + { i18nImportName: "i18n", stripNonEssentialProps: false } + ) } describe("js macro", () => { diff --git a/packages/macro/src/macroJs.ts b/packages/macro/src/macroJs.ts index 6b953c3b9..54f964ae1 100644 --- a/packages/macro/src/macroJs.ts +++ b/packages/macro/src/macroJs.ts @@ -28,22 +28,26 @@ function normalizeWhitespace(text: string): string { return text.replace(keepSpaceRe, " ").replace(keepNewLineRe, "\n").trim() } +export type MacroJsOpts = { + i18nImportName: string + stripNonEssentialProps: boolean +} + export default class MacroJs { // Babel Types types: typeof babelTypes // Identifier of i18n object i18nImportName: string + stripNonEssentialProps: boolean // Positional expressions counter (e.g. for placeholders `Hello {0}, today is {1}`) _expressionIndex = makeCounter() - constructor( - { types }: { types: typeof babelTypes }, - { i18nImportName }: { i18nImportName: string } - ) { + constructor({ types }: { types: typeof babelTypes }, opts: MacroJsOpts) { this.types = types - this.i18nImportName = i18nImportName + this.i18nImportName = opts.i18nImportName + this.stripNonEssentialProps = opts.stripNonEssentialProps } replacePathWithMessage = ( @@ -258,7 +262,7 @@ export default class MacroJs { messageNode ) - if (process.env.NODE_ENV === "production") { + if (this.stripNonEssentialProps) { descriptor.properties = descriptor.properties.filter( (property) => isObjectProperty(property) && diff --git a/packages/macro/src/macroJsx.test.ts b/packages/macro/src/macroJsx.test.ts index a2b5f7088..f3efb99a8 100644 --- a/packages/macro/src/macroJsx.test.ts +++ b/packages/macro/src/macroJsx.test.ts @@ -9,7 +9,7 @@ const parseExpression = (expression: string) => }) as JSXElement function createMacro() { - return new MacroJSX({ types }) + return new MacroJSX({ types }, { stripNonEssentialProps: false }) } describe("jsx macro", () => { diff --git a/packages/macro/src/macroJsx.ts b/packages/macro/src/macroJsx.ts index 6306d7b5e..1c944815a 100644 --- a/packages/macro/src/macroJsx.ts +++ b/packages/macro/src/macroJsx.ts @@ -58,13 +58,19 @@ export function normalizeWhitespace(text: string): string { ) } +export type MacroJsxOpts = { + stripNonEssentialProps: boolean +} + export default class MacroJSX { types: typeof babelTypes expressionIndex = makeCounter() elementIndex = makeCounter() + stripNonEssentialProps: boolean - constructor({ types }: { types: typeof babelTypes }) { + constructor({ types }: { types: typeof babelTypes }, opts: MacroJsxOpts) { this.types = types + this.stripNonEssentialProps = opts.stripNonEssentialProps } safeJsxAttribute = (name: string, value: string) => { @@ -102,24 +108,20 @@ export default class MacroJSX { ) ) - if (process.env.NODE_ENV !== "production") { - if (message) { - attributes.push(this.safeJsxAttribute(MESSAGE, message)) - } + if (!this.stripNonEssentialProps && message) { + attributes.push(this.safeJsxAttribute(MESSAGE, message)) } } else { attributes.push(this.safeJsxAttribute(ID, message)) } - if (process.env.NODE_ENV !== "production") { - if (comment) { - attributes.push( - this.types.jsxAttribute( - this.types.jsxIdentifier(COMMENT), - this.types.stringLiteral(comment) - ) + if (!this.stripNonEssentialProps && comment) { + attributes.push( + this.types.jsxAttribute( + this.types.jsxIdentifier(COMMENT), + this.types.stringLiteral(comment) ) - } + ) } if (context) { diff --git a/packages/macro/test/index.ts b/packages/macro/test/index.ts index 70569f5cd..a3d37bdbc 100644 --- a/packages/macro/test/index.ts +++ b/packages/macro/test/index.ts @@ -2,6 +2,7 @@ import fs from "fs" import path from "path" import { transformFileSync, TransformOptions, transformSync } from "@babel/core" import prettier from "prettier" +import { LinguiMacroOpts } from "../src/index" export type TestCase = { name?: string @@ -10,6 +11,7 @@ export type TestCase = { filename?: string production?: boolean useTypescriptPreset?: boolean + macroOpts?: LinguiMacroOpts only?: boolean skip?: boolean } @@ -30,29 +32,34 @@ const testCases: Record = { describe("macro", function () { process.env.LINGUI_CONFIG = path.join(__dirname, "lingui.config.js") - const babelOptions: TransformOptions = { - filename: "", - configFile: false, - presets: [], - plugins: [ - "@babel/plugin-syntax-jsx", - [ - "macros", - { - // macro plugin uses package `resolve` to find a path of macro file - // this will not follow jest pathMapping and will resolve path from ./build - // instead of ./src which makes testing & developing hard. - // here we override resolve and provide correct path for testing - resolvePath: (source: string) => require.resolve(source), - }, + const getDefaultBabelOptions = ( + macroOpts: LinguiMacroOpts = {} + ): TransformOptions => { + return { + filename: "", + configFile: false, + presets: [], + plugins: [ + "@babel/plugin-syntax-jsx", + [ + "macros", + { + lingui: macroOpts, + // macro plugin uses package `resolve` to find a path of macro file + // this will not follow jest pathMapping and will resolve path from ./build + // instead of ./src which makes testing & developing hard. + // here we override resolve and provide correct path for testing + resolvePath: (source: string) => require.resolve(source), + }, + ], ], - ], + } } // return function, so we can test exceptions const transformCode = (code: string) => () => { try { - return transformSync(code, babelOptions).code.trim() + return transformSync(code, getDefaultBabelOptions()).code.trim() } catch (e) { e.message = e.message.replace(/([^:]*:){2}/, "") throw e @@ -77,6 +84,7 @@ describe("macro", function () { useTypescriptPreset, only, skip, + macroOpts, }, index ) => { @@ -84,6 +92,7 @@ describe("macro", function () { if (only) run = it.only if (skip) run = it.skip run(name != null ? name : `${suiteName} #${index + 1}`, () => { + const babelOptions = getDefaultBabelOptions(macroOpts) expect(input || filename).toBeDefined() const originalEnv = process.env.NODE_ENV diff --git a/packages/macro/test/js-t.ts b/packages/macro/test/js-t.ts index 4a243b8a7..f31b4189c 100644 --- a/packages/macro/test/js-t.ts +++ b/packages/macro/test/js-t.ts @@ -275,6 +275,36 @@ const cases: TestCase[] = [ }); `, }, + { + name: "Production - all props kept if extract: true", + production: true, + macroOpts: { + extract: true, + }, + input: ` + import { t } from '@lingui/macro'; + const msg = t({ + message: \`Hello $\{name\}\`, + id: 'msgId', + comment: 'description for translators', + context: 'My Context', + }) + `, + expected: ` + import { i18n } from "@lingui/core"; + const msg = + i18n._(/*i18n*/ + { + message: "Hello {name}", + id: 'msgId', + comment: "description for translators", + context: 'My Context', + values: { + name: name, + }, + }); + `, + }, { name: "Newlines after continuation character are removed", filename: "js-t-continuation-character.js", diff --git a/packages/macro/test/jsx-trans.ts b/packages/macro/test/jsx-trans.ts index cb219cc4f..000b39408 100644 --- a/packages/macro/test/jsx-trans.ts +++ b/packages/macro/test/jsx-trans.ts @@ -270,6 +270,21 @@ const cases: TestCase[] = [ ; `, }, + { + name: "Production - all props kept if extract: true", + production: true, + macroOpts: { + extract: true, + }, + input: ` + import { Trans } from '@lingui/macro'; + Hello World + `, + expected: ` + import { Trans } from "@lingui/react"; + ; + `, + }, { name: "Production - import type doesn't interference on normal import", production: true, diff --git a/tsconfig.json b/tsconfig.json index cbc8a6d93..a5f7f5884 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -25,6 +25,7 @@ "examples/next-js", "examples/create-react-app", "build", - "website" + "website", + "**/fixtures/**" ] } diff --git a/yarn.lock b/yarn.lock index 60b3d622a..e68758fc5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -25,9 +25,9 @@ "@babel/highlight" "^7.18.6" "@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.1", "@babel/compat-data@^7.20.5": - version "7.20.14" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.14.tgz#4106fc8b755f3e3ee0a0a7c27dde5de1d2b2baf8" - integrity sha512-0YpKHD6ImkWMEINCyDAD0HLLUH/lPCefG8ld9it8DJB2wnApraKuhgYTvTY1z7UFIfBTGy5LwncZ+5HWWGbhFw== + version "7.20.10" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.10.tgz#9d92fa81b87542fff50e848ed585b4212c1d34ec" + integrity sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg== "@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.20.12", "@babel/core@^7.7.5": version "7.20.12" @@ -50,7 +50,7 @@ json5 "^2.2.2" semver "^6.3.0" -"@babel/generator@^7.20.14", "@babel/generator@^7.20.7": +"@babel/generator@^7.20.14": version "7.20.14" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.14.tgz#9fa772c9f86a46c6ac9b321039400712b96f64ce" integrity sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg== @@ -59,6 +59,15 @@ "@jridgewell/gen-mapping" "^0.3.2" jsesc "^2.5.1" +"@babel/generator@^7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.7.tgz#f8ef57c8242665c5929fe2e8d82ba75460187b4a" + integrity sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw== + dependencies: + "@babel/types" "^7.20.7" + "@jridgewell/gen-mapping" "^0.3.2" + jsesc "^2.5.1" + "@babel/helper-annotate-as-pure@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz#eaa49f6f80d5a33f9a5dd2276e6d6e451be0a6bb" @@ -272,7 +281,12 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.13", "@babel/parser@^7.20.15", "@babel/parser@^7.20.7", "@babel/parser@^7.7.0": +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.13", "@babel/parser@^7.20.7", "@babel/parser@^7.7.0": + version "7.20.13" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.13.tgz#ddf1eb5a813588d2fb1692b70c6fce75b945c088" + integrity sha512-gFDLKMfpiXCsjt4za2JA9oTMn70CeseCehb11kRZgvd7+F67Hih3OHOK24cRrWECJ/ljfPGac6ygXAs/C8kIvw== + +"@babel/parser@^7.20.15": version "7.20.15" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.15.tgz#eec9f36d8eaf0948bb88c87a46784b5ee9fd0c89" integrity sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg== @@ -579,9 +593,9 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-block-scoping@^7.20.2": - version "7.20.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.15.tgz#3e1b2aa9cbbe1eb8d644c823141a9c5c2a22392d" - integrity sha512-Vv4DMZ6MiNOhu/LdaZsT/bsLRxgL94d269Mv4R/9sp6+Mp++X/JqypZYypJXLlM4mlL352/Egzbzr98iABH1CA== + version "7.20.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.11.tgz#9f5a3424bd112a3f32fe0cf9364fbb155cff262a" + integrity sha512-tA4N427a7fjf1P0/2I4ScsHGc5jcHPbb30xMbaTke2gxDuWpUfXDuX1FEymJwKk4tuGUvGcejAR6HdZVqmmPyw== dependencies: "@babel/helper-plugin-utils" "^7.20.2" @@ -981,7 +995,7 @@ core-js-pure "^3.25.1" regenerator-runtime "^0.13.11" -"@babel/runtime@^7", "@babel/runtime@^7.10.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.20.13", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4": +"@babel/runtime@^7", "@babel/runtime@^7.10.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.20.13", "@babel/runtime@^7.8.4": version "7.20.13" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.13.tgz#7055ab8a7cff2b8f6058bf6ae45ff84ad2aded4b" integrity sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA== @@ -1042,125 +1056,125 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" -"@esbuild/android-arm64@0.17.5": - version "0.17.5" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.5.tgz#a145f43018e639bed94ed637369e2dcdd6bf9ea2" - integrity sha512-KHWkDqYAMmKZjY4RAN1PR96q6UOtfkWlTS8uEwWxdLtkRt/0F/csUhXIrVfaSIFxnscIBMPynGfhsMwQDRIBQw== +"@esbuild/android-arm64@0.17.4": + version "0.17.4" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.4.tgz#0a900a7e448cc038ae5a751255257fc67163ed32" + integrity sha512-91VwDrl4EpxBCiG6h2LZZEkuNvVZYJkv2T9gyLG/mhGG1qrM7i5SwUcg/hlSPnL/4hDT0TFcF35/XMGSn0bemg== "@esbuild/android-arm@0.15.18": version "0.15.18" resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.15.18.tgz#266d40b8fdcf87962df8af05b76219bc786b4f80" integrity sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw== -"@esbuild/android-arm@0.17.5": - version "0.17.5" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.5.tgz#9fa2deff7fc5d180bb4ecff70beea3a95ac44251" - integrity sha512-crmPUzgCmF+qZXfl1YkiFoUta2XAfixR1tEnr/gXIixE+WL8Z0BGqfydP5oox0EUOgQMMRgtATtakyAcClQVqQ== - -"@esbuild/android-x64@0.17.5": - version "0.17.5" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.5.tgz#145fc61f810400e65a56b275280d1422a102c2ef" - integrity sha512-8fI/AnIdmWz/+1iza2WrCw8kwXK9wZp/yZY/iS8ioC+U37yJCeppi9EHY05ewJKN64ASoBIseufZROtcFnX5GA== - -"@esbuild/darwin-arm64@0.17.5": - version "0.17.5" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.5.tgz#61fb0546aa4bae0850817d6e0d008b1cb3f64b49" - integrity sha512-EAvaoyIySV6Iif3NQCglUNpnMfHSUgC5ugt2efl3+QDntucJe5spn0udNZjTgNi6tKVqSceOw9tQ32liNZc1Xw== - -"@esbuild/darwin-x64@0.17.5": - version "0.17.5" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.5.tgz#54b770f0c49f524ae9ba24c85d6dea8b521f610d" - integrity sha512-ha7QCJh1fuSwwCgoegfdaljowwWozwTDjBgjD3++WAy/qwee5uUi1gvOg2WENJC6EUyHBOkcd3YmLDYSZ2TPPA== - -"@esbuild/freebsd-arm64@0.17.5": - version "0.17.5" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.5.tgz#be1dd18b7b9411f10bdc362ba8bff16386175367" - integrity sha512-VbdXJkn2aI2pQ/wxNEjEcnEDwPpxt3CWWMFYmO7CcdFBoOsABRy2W8F3kjbF9F/pecEUDcI3b5i2w+By4VQFPg== - -"@esbuild/freebsd-x64@0.17.5": - version "0.17.5" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.5.tgz#c9c1960fa3e1eada4e5d4be2a11a2f04ce14198f" - integrity sha512-olgGYND1/XnnWxwhjtY3/ryjOG/M4WfcA6XH8dBTH1cxMeBemMODXSFhkw71Kf4TeZFFTN25YOomaNh0vq2iXg== - -"@esbuild/linux-arm64@0.17.5": - version "0.17.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.5.tgz#34d96d11c6899017ecae42fb97de8e0c3282902f" - integrity sha512-8a0bqSwu3OlLCfu2FBbDNgQyBYdPJh1B9PvNX7jMaKGC9/KopgHs37t+pQqeMLzcyRqG6z55IGNQAMSlCpBuqg== - -"@esbuild/linux-arm@0.17.5": - version "0.17.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.5.tgz#86332e6293fd713a54ab299a5e2ed7c60c9e1c07" - integrity sha512-YBdCyQwA3OQupi6W2/WO4FnI+NWFWe79cZEtlbqSESOHEg7a73htBIRiE6uHPQe7Yp5E4aALv+JxkRLGEUL7tw== - -"@esbuild/linux-ia32@0.17.5": - version "0.17.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.5.tgz#7bd9185c844e7dfce6a01dfdec584e115602a8c4" - integrity sha512-uCwm1r/+NdP7vndctgq3PoZrnmhmnecWAr114GWMRwg2QMFFX+kIWnp7IO220/JLgnXK/jP7VKAFBGmeOYBQYQ== +"@esbuild/android-arm@0.17.4": + version "0.17.4" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.4.tgz#fe32ce82eb6064d3dc13c0d8ca0e440bbc776c93" + integrity sha512-R9GCe2xl2XDSc2XbQB63mFiFXHIVkOP+ltIxICKXqUPrFX97z6Z7vONCLQM1pSOLGqfLrGi3B7nbhxmFY/fomg== + +"@esbuild/android-x64@0.17.4": + version "0.17.4" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.4.tgz#6ae1056f6ecf1963c1d076cf5f0109b52d8049f6" + integrity sha512-mGSqhEPL7029XL7QHNPxPs15JVa02hvZvysUcyMP9UXdGFwncl2WU0bqx+Ysgzd+WAbv8rfNa73QveOxAnAM2w== + +"@esbuild/darwin-arm64@0.17.4": + version "0.17.4" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.4.tgz#5064d81ee5b8d646a5b7cc3e53c98cb983c4af55" + integrity sha512-tTyJRM9dHvlMPt1KrBFVB5OW1kXOsRNvAPtbzoKazd5RhD5/wKlXk1qR2MpaZRYwf4WDMadt0Pv0GwxB41CVow== + +"@esbuild/darwin-x64@0.17.4": + version "0.17.4" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.4.tgz#67f0213b3333248b32a97a7fc3fee880c2157674" + integrity sha512-phQuC2Imrb3TjOJwLN8EO50nb2FHe8Ew0OwgZDH1SV6asIPGudnwTQtighDF2EAYlXChLoMJwqjAp4vAaACq6w== + +"@esbuild/freebsd-arm64@0.17.4": + version "0.17.4" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.4.tgz#8eaaa126d9ff24822c730f06a71ac2d1091dc1c2" + integrity sha512-oH6JUZkocgmjzzYaP5juERLpJQSwazdjZrTPgLRmAU2bzJ688x0vfMB/WTv4r58RiecdHvXOPC46VtsMy/mepg== + +"@esbuild/freebsd-x64@0.17.4": + version "0.17.4" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.4.tgz#314eff900a71abf64d4e5bea31e430d8ebd78d79" + integrity sha512-U4iWGn/9TrAfpAdfd56eO0pRxIgb0a8Wj9jClrhT8hvZnOnS4dfMPW7o4fn15D/KqoiVYHRm43jjBaTt3g/2KA== + +"@esbuild/linux-arm64@0.17.4": + version "0.17.4" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.4.tgz#5bed6bb8eb1d331644f8b31c87b8df57f204e84e" + integrity sha512-UkGfQvYlwOaeYJzZG4cLV0hCASzQZnKNktRXUo3/BMZvdau40AOz9GzmGA063n1piq6VrFFh43apRDQx8hMP2w== + +"@esbuild/linux-arm@0.17.4": + version "0.17.4" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.4.tgz#6eaa41f37e231d113da715a1d9cc820e5523aeb6" + integrity sha512-S2s9xWTGMTa/fG5EyMGDeL0wrWVgOSQcNddJWgu6rG1NCSXJHs76ZP9AsxjB3f2nZow9fWOyApklIgiTGZKhiw== + +"@esbuild/linux-ia32@0.17.4": + version "0.17.4" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.4.tgz#3fc352bb54e0959fda273cd2253b1c72ca41b8c2" + integrity sha512-3lqFi4VFo/Vwvn77FZXeLd0ctolIJH/uXkH3yNgEk89Eh6D3XXAC9/iTPEzeEpsNE5IqGIsFa5Z0iPeOh25IyA== "@esbuild/linux-loong64@0.15.18": version "0.15.18" resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.15.18.tgz#128b76ecb9be48b60cf5cfc1c63a4f00691a3239" integrity sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ== -"@esbuild/linux-loong64@0.17.5": - version "0.17.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.5.tgz#2907d4120c7b3642b96be6014f77e7624c378eea" - integrity sha512-3YxhSBl5Sb6TtBjJu+HP93poBruFzgXmf3PVfIe4xOXMj1XpxboYZyw3W8BhoX/uwxzZz4K1I99jTE/5cgDT1g== - -"@esbuild/linux-mips64el@0.17.5": - version "0.17.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.5.tgz#fc98be741e8080ecd13b404d5fca5302d3835bf4" - integrity sha512-Hy5Z0YVWyYHdtQ5mfmfp8LdhVwGbwVuq8mHzLqrG16BaMgEmit2xKO+iDakHs+OetEx0EN/2mUzDdfdktI+Nmg== - -"@esbuild/linux-ppc64@0.17.5": - version "0.17.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.5.tgz#ea12e8f6b290a613ac4903c9e00835c69ced065c" - integrity sha512-5dbQvBLbU/Y3Q4ABc9gi23hww1mQcM7KZ9KBqabB7qhJswYMf8WrDDOSw3gdf3p+ffmijMd28mfVMvFucuECyg== - -"@esbuild/linux-riscv64@0.17.5": - version "0.17.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.5.tgz#ce47b15fd4227eeb0590826e41bdc430c5bfd06c" - integrity sha512-fp/KUB/ZPzEWGTEUgz9wIAKCqu7CjH1GqXUO2WJdik1UNBQ7Xzw7myIajpxztE4Csb9504ERiFMxZg5KZ6HlZQ== - -"@esbuild/linux-s390x@0.17.5": - version "0.17.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.5.tgz#962fa540d7498967270eb1d4b9ac6c4a4f339735" - integrity sha512-kRV3yw19YDqHTp8SfHXfObUFXlaiiw4o2lvT1XjsPZ++22GqZwSsYWJLjMi1Sl7j9qDlDUduWDze/nQx0d6Lzw== - -"@esbuild/linux-x64@0.17.5": - version "0.17.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.5.tgz#9fa52884c3d876593a522aa1d4df43b717907050" - integrity sha512-vnxuhh9e4pbtABNLbT2ANW4uwQ/zvcHRCm1JxaYkzSehugoFd5iXyC4ci1nhXU13mxEwCnrnTIiiSGwa/uAF1g== - -"@esbuild/netbsd-x64@0.17.5": - version "0.17.5" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.5.tgz#47bb187b86aad9622051cb80c27e439b7d9e3a9a" - integrity sha512-cigBpdiSx/vPy7doUyImsQQBnBjV5f1M99ZUlaJckDAJjgXWl6y9W17FIfJTy8TxosEF6MXq+fpLsitMGts2nA== - -"@esbuild/openbsd-x64@0.17.5": - version "0.17.5" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.5.tgz#abc55c35a1ed2bc3c5ede2ef50a3b2f87395009a" - integrity sha512-VdqRqPVIjjZfkf40LrqOaVuhw9EQiAZ/GNCSM2UplDkaIzYVsSnycxcFfAnHdWI8Gyt6dO15KHikbpxwx+xHbw== - -"@esbuild/sunos-x64@0.17.5": - version "0.17.5" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.5.tgz#b83c080a2147662599a5d18b2ff47f07c93e03a0" - integrity sha512-ItxPaJ3MBLtI4nK+mALLEoUs6amxsx+J1ibnfcYMkqaCqHST1AkF4aENpBehty3czqw64r/XqL+W9WqU6kc2Qw== - -"@esbuild/win32-arm64@0.17.5": - version "0.17.5" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.5.tgz#2a4c41f427d9cf25b75f9d61493711a482106850" - integrity sha512-4u2Q6qsJTYNFdS9zHoAi80spzf78C16m2wla4eJPh4kSbRv+BpXIfl6TmBSWupD8e47B1NrTfrOlEuco7mYQtg== - -"@esbuild/win32-ia32@0.17.5": - version "0.17.5" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.17.5.tgz#7c14e3250725d0e2c21f89c98eb6abb520cba0e0" - integrity sha512-KYlm+Xu9TXsfTWAcocLuISRtqxKp/Y9ZBVg6CEEj0O5J9mn7YvBKzAszo2j1ndyzUPk+op+Tie2PJeN+BnXGqQ== - -"@esbuild/win32-x64@0.17.5": - version "0.17.5" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.5.tgz#a8f3d26d8afc5186eccda265ceb1820b8e8830be" - integrity sha512-XgA9qWRqby7xdYXuF6KALsn37QGBMHsdhmnpjfZtYxKxbTOwfnDM6MYi2WuUku5poNaX2n9XGVr20zgT/2QwCw== +"@esbuild/linux-loong64@0.17.4": + version "0.17.4" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.4.tgz#86d54f690be53669cd2a38a5333ecf2608c11189" + integrity sha512-HqpWZkVslDHIwdQ9D+gk7NuAulgQvRxF9no54ut/M55KEb3mi7sQS3GwpPJzSyzzP0UkjQVN7/tbk88/CaX4EQ== + +"@esbuild/linux-mips64el@0.17.4": + version "0.17.4" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.4.tgz#3dbd897bd8f047fef35e69bd253b8f07ca7fe483" + integrity sha512-d/nMCKKh/SVDbqR9ju+b78vOr0tNXtfBjcp5vfHONCCOAL9ad8gN9dC/u+UnH939pz7wO+0u/x9y1MaZcb/lKA== + +"@esbuild/linux-ppc64@0.17.4": + version "0.17.4" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.4.tgz#defaff6db9a60f08936fc0c59e0eabfb1055968a" + integrity sha512-lOD9p2dmjZcNiTU+sGe9Nn6G3aYw3k0HBJies1PU0j5IGfp6tdKOQ6mzfACRFCqXjnBuTqK7eTYpwx09O5LLfg== + +"@esbuild/linux-riscv64@0.17.4": + version "0.17.4" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.4.tgz#270a09f6f4205a8a8c8ed3c7dbabdcebaafa8a84" + integrity sha512-mTGnwWwVshAjGsd8rP+K6583cPDgxOunsqqldEYij7T5/ysluMHKqUIT4TJHfrDFadUwrghAL6QjER4FeqQXoA== + +"@esbuild/linux-s390x@0.17.4": + version "0.17.4" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.4.tgz#197695bece68f514dcdcc286562b5d48c5dad5f9" + integrity sha512-AQYuUGp50XM29/N/dehADxvc2bUqDcoqrVuijop1Wv72SyxT6dDB9wjUxuPZm2HwIM876UoNNBMVd+iX/UTKVQ== + +"@esbuild/linux-x64@0.17.4": + version "0.17.4" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.4.tgz#db50cdfb071c0d367025c1c98563aab1318f800e" + integrity sha512-+AsFBwKgQuhV2shfGgA9YloxLDVjXgUEWZum7glR5lLmV94IThu/u2JZGxTgjYby6kyXEx8lKOqP5rTEVBR0Rw== + +"@esbuild/netbsd-x64@0.17.4": + version "0.17.4" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.4.tgz#e4d5d8022f8eddbd7d9899d58265915444f46f3b" + integrity sha512-zD1TKYX9553OiLS/qkXPMlWoELYkH/VkzRYNKEU+GwFiqkq0SuxsKnsCg5UCdxN3cqd+1KZ8SS3R+WG/Hxy2jQ== + +"@esbuild/openbsd-x64@0.17.4": + version "0.17.4" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.4.tgz#9b770e1e7745824cbe155f5a742fc781855a7e68" + integrity sha512-PY1NjEsLRhPEFFg1AV0/4Or/gR+q2dOb9s5rXcPuCjyHRzbt8vnHJl3vYj+641TgWZzTFmSUnZbzs1zwTzjeqw== + +"@esbuild/sunos-x64@0.17.4": + version "0.17.4" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.4.tgz#4c6d2290f8bf39ab9284f5a1b9a2210858e2d6e6" + integrity sha512-B3Z7s8QZQW9tKGleMRXvVmwwLPAUoDCHs4WZ2ElVMWiortLJFowU1NjAhXOKjDgC7o9ByeVcwyOlJ+F2r6ZgmQ== + +"@esbuild/win32-arm64@0.17.4": + version "0.17.4" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.4.tgz#424954b6d598f40e2c5a0d85e3af07147fb41909" + integrity sha512-0HCu8R3mY/H5V7N6kdlsJkvrT591bO/oRZy8ztF1dhgNU5xD5tAh5bKByT1UjTGjp/VVBsl1PDQ3L18SfvtnBQ== + +"@esbuild/win32-ia32@0.17.4": + version "0.17.4" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.17.4.tgz#2c94e9c3a82c779d3f07b3fb5c482a2e3fecedb1" + integrity sha512-VUjhVDQycse1gLbe06pC/uaA0M+piQXJpdpNdhg8sPmeIZZqu5xPoGWVCmcsOO2gaM2cywuTYTHkXRozo3/Nkg== + +"@esbuild/win32-x64@0.17.4": + version "0.17.4" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.4.tgz#9b7760cdc77678bdbc5b582fae2cf3de449df048" + integrity sha512-0kLAjs+xN5OjhTt/aUA6t48SfENSCKgGPfExADYTOo/UCn0ivxos9/anUVeSfg+L+2O9xkFxvJXIJfG+Q4sYSg== "@eslint/eslintrc@^0.4.3": version "0.4.3" @@ -2459,71 +2473,71 @@ source-map-support "^0.5.21" tslib "^2.4.1" -"@swc/core-darwin-arm64@1.3.32": - version "1.3.32" - resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.32.tgz#841b0a244c2c75e67bb9d3cb665b2ede601e4e3a" - integrity sha512-o19bhlxuUgjUElm6i+QhXgZ0vD6BebiB/gQpK3en5aAwhOvinwr4sah3GqFXsQzz/prKVDuMkj9SW6F/Ug5hgg== - -"@swc/core-darwin-x64@1.3.32": - version "1.3.32" - resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.3.32.tgz#125247c6a5d7189776a6973b0a539a07576d5585" - integrity sha512-hVEGd+v5Afh+YekGADOGKwhuS4/AXk91nLuk7pmhWkk8ceQ1cfmah90kXjIXUlCe2G172MLRfHNWlZxr29E/Og== - -"@swc/core-linux-arm-gnueabihf@1.3.32": - version "1.3.32" - resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.32.tgz#d8ba8da3707b91e62059e65e375fc6093c4d5f82" - integrity sha512-5X01WqI9EbJ69oHAOGlI08YqvEIXMfT/mCJ1UWDQBb21xWRE2W1yFAAeuqOLtiagLrXjPv/UKQ0S2gyWQR5AXQ== - -"@swc/core-linux-arm64-gnu@1.3.32": - version "1.3.32" - resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.32.tgz#15973e533c45e2976e57c590613e3e5dca0e62ad" - integrity sha512-PTJ6oPiutkNBg+m22bUUPa4tNuMmsgpSnsnv2wnWVOgK0lhvQT6bAPTUXDq/8peVAgR/SlpP2Ht8TRRqYMRjRQ== - -"@swc/core-linux-arm64-musl@1.3.32": - version "1.3.32" - resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.32.tgz#0e20f30885c8588bd13e7e5628ce8bdbe6cb44b6" - integrity sha512-lG0VOuYNPWOCJ99Aza69cTljjeft/wuRQeYFF8d+1xCQS/OT7gnbgi7BOz39uSHIPTBqfzdIsuvzdKlp9QydrQ== - -"@swc/core-linux-x64-gnu@1.3.32": - version "1.3.32" - resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.32.tgz#2ea5e17d13a70e6a13742282cf30e92e4074f4c5" - integrity sha512-ecqtSWX4NBrs7Ji2VX3fDWeqUfrbLlYqBuufAziCM27xMxwlAVgmyGQk4FYgoQ3SAUAu3XFH87+3Q7uWm2X7xg== - -"@swc/core-linux-x64-musl@1.3.32": - version "1.3.32" - resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.32.tgz#d96cde03d54f13f77dd1d6602a049bd2baaef446" - integrity sha512-rl3dMcUuENVkpk5NGW/LXovjK0+JFm4GWPjy4NM3Q5cPvhBpGwSeLZlR+zAw9K0fdGoIXiayRTTfENrQwwsH+g== - -"@swc/core-win32-arm64-msvc@1.3.32": - version "1.3.32" - resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.32.tgz#3870113492cc3d2679945372f4975ce7f60594cc" - integrity sha512-VlybAZp8DcS66CH1LDnfp9zdwbPlnGXREtHDMHaBfK9+80AWVTg+zn0tCYz+HfcrRONqxbudwOUIPj+dwl/8jw== - -"@swc/core-win32-ia32-msvc@1.3.32": - version "1.3.32" - resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.32.tgz#643519663778e64941c8b730197d4ba762dffcb0" - integrity sha512-MEUMdpUFIQ+RD+K/iHhHKfu0TFNj9VXwIxT5hmPeqyboKo095CoFEFBJ0sHG04IGlnu8T9i+uE2Pi18qUEbFug== - -"@swc/core-win32-x64-msvc@1.3.32": - version "1.3.32" - resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.32.tgz#aa9595cb93d9dd5bbc7e5cfdabd8bb086ea6c21d" - integrity sha512-DPMoneNFQco7SqmVVOUv1Vn53YmoImEfrAPMY9KrqQzgfzqNTuL2JvfxUqfAxwQ6pEKYAdyKJvZ483rIhgG9XQ== +"@swc/core-darwin-arm64@1.3.28": + version "1.3.28" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.28.tgz#3ab15dd6f0ede5b3c7d6ed557a26c0fad34ee5c9" + integrity sha512-f1ph5DDIOX6bvjhlOuWz8ZDiTghhq144Sy9gaRi+DjK3gdnftc4p5AyZHA4Xb03MZ+fd0mj8q6/znco5aBMi1A== + +"@swc/core-darwin-x64@1.3.28": + version "1.3.28" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.3.28.tgz#e0eaa0eb763bc7def581df93b1a5df1249eb5528" + integrity sha512-5dB5Z4Ry45UTXXAxhwagCYfh57njffkdIJkjid1f+Qt4i7cOznOaIiD4wobGD7xHCATEcs8F23yWkAmvrbacew== + +"@swc/core-linux-arm-gnueabihf@1.3.28": + version "1.3.28" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.28.tgz#f7038e60bddebc6b0c0aa444c50157fe4908fb58" + integrity sha512-VmtAQAENJ5SHBXTKxXNlnnM34xGOtJpHYva83zeZM/2epdoz1BJ6Ny3gTBXDftaWgAj2SRwVIjMR3/c71aJysQ== + +"@swc/core-linux-arm64-gnu@1.3.28": + version "1.3.28" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.28.tgz#6e3013176c4cc5dd006c848911e3bccaf1fa77dd" + integrity sha512-KIJ1SHGbusM6W2rxue1f+IN/iuzmspgMY9qP/qW5Z43Mm9mrHdzDmhsMoEH1y2gPUsu/ZZnkXlODJ0M0454JNQ== + +"@swc/core-linux-arm64-musl@1.3.28": + version "1.3.28" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.28.tgz#01896d81f967104fb851534962dd344252d85025" + integrity sha512-Zz2DZj8ncSvVEAsol8gtoXrVLP8e+IYSx6o8txYVR0p0pviJBzeuYGaLe5sbQdQnVVS2M5N90LX28P6/mQb6sQ== + +"@swc/core-linux-x64-gnu@1.3.28": + version "1.3.28" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.28.tgz#03d9b0171267ccc5d0efd2a939150f5d1da550ae" + integrity sha512-Za3uowhcP74qSCNqjZLBx3nAmjIFYNbB0nGBKwkLBopbMcpO0BjvnsdzmoWqv2Uq41vaeVk/o9vATQMojfHHQg== + +"@swc/core-linux-x64-musl@1.3.28": + version "1.3.28" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.28.tgz#6badfc87d94b7891c11aa71496498d2ff29535db" + integrity sha512-i3BAkmrf19VXybbjuS9Jnlnx5Ie4vukLMCQRfXCQqIqaiSw3QzubjolYo07sGtzoVI3nBscDt3i8T+oxTPOMkw== + +"@swc/core-win32-arm64-msvc@1.3.28": + version "1.3.28" + resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.28.tgz#2441d2cdbc313618332de014be0c6c3573931b62" + integrity sha512-DdNxKP/P0/OFqX1dtl9Ubrd567QPMSeJvp9iDtMdgCBWN2N6HXvyMj623WIA0y9FIcA7wexz0Hh3gS+G9Jof+Q== + +"@swc/core-win32-ia32-msvc@1.3.28": + version "1.3.28" + resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.28.tgz#82319fcff87289e3e9439dd76524a7bdfe58f5fa" + integrity sha512-/jZWBIgaNkKTlKiZ7DXmMJzW0n1ychDKS1bYRuNLrtTRthMP5M3LRZXITz0AcvPl0mIA0IXeMQbE4ZMUc7LAFg== + +"@swc/core-win32-x64-msvc@1.3.28": + version "1.3.28" + resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.28.tgz#a2067da2f3f4f95ef1b05eb86941d0609a66e9c6" + integrity sha512-HKhE0LznEwTP/qi6EVclmJzfNdykzuK6sjYMTjcDqNJOuuRNMu+IJzPzCPuakgljymWGFmddnuuubd9Y+kl3eg== "@swc/core@^1.3.26": - version "1.3.32" - resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.3.32.tgz#ecb3c9d7717e0a15796230def1b17968b18228f1" - integrity sha512-Yx/n1j+uUkcqlJAW8IRg8Qymgkdow6NHJZPFShiR0YiaYq2sXY+JHmvh16O6GkL91Y+gTlDUS7uVgDz50czJUQ== + version "1.3.28" + resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.3.28.tgz#e0fc1fd15b2e7e01d0f16d55eb60b74e65fb1025" + integrity sha512-yzc61HbAIjHeOYTUW/IgXAywlSviMFymnUiLY7dNUELGHjMVxSp0XnIlPQN4v5UekYbwLEV8+KChaoQRACiQCw== optionalDependencies: - "@swc/core-darwin-arm64" "1.3.32" - "@swc/core-darwin-x64" "1.3.32" - "@swc/core-linux-arm-gnueabihf" "1.3.32" - "@swc/core-linux-arm64-gnu" "1.3.32" - "@swc/core-linux-arm64-musl" "1.3.32" - "@swc/core-linux-x64-gnu" "1.3.32" - "@swc/core-linux-x64-musl" "1.3.32" - "@swc/core-win32-arm64-msvc" "1.3.32" - "@swc/core-win32-ia32-msvc" "1.3.32" - "@swc/core-win32-x64-msvc" "1.3.32" + "@swc/core-darwin-arm64" "1.3.28" + "@swc/core-darwin-x64" "1.3.28" + "@swc/core-linux-arm-gnueabihf" "1.3.28" + "@swc/core-linux-arm64-gnu" "1.3.28" + "@swc/core-linux-arm64-musl" "1.3.28" + "@swc/core-linux-x64-gnu" "1.3.28" + "@swc/core-linux-x64-musl" "1.3.28" + "@swc/core-win32-arm64-msvc" "1.3.28" + "@swc/core-win32-ia32-msvc" "1.3.28" + "@swc/core-win32-x64-msvc" "1.3.28" "@swc/jest@^0.2.24": version "0.2.24" @@ -3534,9 +3548,9 @@ astral-regex@^2.0.0: integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== async-each@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.5.tgz#6eea184b2df0ec09f3deebe165c97c85c911d7b8" - integrity sha512-5QzqtU3BlagehwmdoqwaS2FBQF2P5eL6vFqXwNsb5jwoEsmtfAXg1ocFvW7I6/gGLFhBMKwcMwZuy7uv/Bo9jA== + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== asynckit@^0.4.0: version "0.4.0" @@ -3620,16 +3634,7 @@ babel-plugin-jest-hoist@^26.6.2: "@types/babel__core" "^7.0.0" "@types/babel__traverse" "^7.0.6" -babel-plugin-macros@^2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz#0f958a7cc6556b1e65344465d99111a1e5e10138" - integrity sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg== - dependencies: - "@babel/runtime" "^7.7.2" - cosmiconfig "^6.0.0" - resolve "^1.12.0" - -babel-plugin-macros@^3.0.1: +babel-plugin-macros@^3.0.1, babel-plugin-macros@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz#9ef6dc74deb934b4db344dc973ee851d148c50c1" integrity sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg== @@ -3888,14 +3893,14 @@ browserify-zlib@^0.2.0: pako "~1.0.5" browserslist@^4.21.3, browserslist@^4.21.4: - version "4.21.5" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7" - integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== + version "4.21.4" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" + integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== dependencies: - caniuse-lite "^1.0.30001449" - electron-to-chromium "^1.4.284" - node-releases "^2.0.8" - update-browserslist-db "^1.0.10" + caniuse-lite "^1.0.30001400" + electron-to-chromium "^1.4.251" + node-releases "^2.0.6" + update-browserslist-db "^1.0.9" bs-logger@0.x: version "0.2.6" @@ -4097,10 +4102,10 @@ camelcase@^6.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001449: - version "1.0.30001450" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001450.tgz#022225b91200589196b814b51b1bbe45144cf74f" - integrity sha512-qMBmvmQmFXaSxexkjjfMvD5rnDL0+m+dUMZKoDYsGG8iZN29RuYh9eRoMvKsT6uMAWlyUUGDEQGJJYjzCIO9ew== +caniuse-lite@^1.0.30001400: + version "1.0.30001447" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001447.tgz#ef1f39ae38d839d7176713735a8e467a0a2523bd" + integrity sha512-bdKU1BQDPeEXe9A39xJnGtY0uRq/z5osrnXUw0TcK+EYno45Y+U7QU9HhHEyzvMDffpYadFXi3idnSNkcwLkTw== capture-exit@^2.0.0: version "2.0.0" @@ -4636,17 +4641,6 @@ cosmiconfig@^5.1.0: js-yaml "^3.13.1" parse-json "^4.0.0" -cosmiconfig@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" - integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== - dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.1.0" - parse-json "^5.0.0" - path-type "^4.0.0" - yaml "^1.7.2" - cosmiconfig@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" @@ -5115,7 +5109,7 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" -electron-to-chromium@^1.4.284: +electron-to-chromium@^1.4.251: version "1.4.284" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz#61046d1e4cab3a25238f6bf7413795270f125592" integrity sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA== @@ -5437,32 +5431,32 @@ esbuild@^0.15.9: esbuild-windows-arm64 "0.15.18" esbuild@^0.17.2: - version "0.17.5" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.5.tgz#cd76d75700d49ac050ad9eedfbed777bd6a9d930" - integrity sha512-Bu6WLCc9NMsNoMJUjGl3yBzTjVLXdysMltxQWiLAypP+/vQrf+3L1Xe8fCXzxaECus2cEJ9M7pk4yKatEwQMqQ== + version "0.17.4" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.4.tgz#af4f8f78604c67f8e6afbdee36a3f4211ecfc859" + integrity sha512-zBn9MeCwT7W5F1a3lXClD61ip6vQM+H8Msb0w8zMT4ZKBpDg+rFAraNyWCDelB/2L6M3g6AXHPnsyvjMFnxtFw== optionalDependencies: - "@esbuild/android-arm" "0.17.5" - "@esbuild/android-arm64" "0.17.5" - "@esbuild/android-x64" "0.17.5" - "@esbuild/darwin-arm64" "0.17.5" - "@esbuild/darwin-x64" "0.17.5" - "@esbuild/freebsd-arm64" "0.17.5" - "@esbuild/freebsd-x64" "0.17.5" - "@esbuild/linux-arm" "0.17.5" - "@esbuild/linux-arm64" "0.17.5" - "@esbuild/linux-ia32" "0.17.5" - "@esbuild/linux-loong64" "0.17.5" - "@esbuild/linux-mips64el" "0.17.5" - "@esbuild/linux-ppc64" "0.17.5" - "@esbuild/linux-riscv64" "0.17.5" - "@esbuild/linux-s390x" "0.17.5" - "@esbuild/linux-x64" "0.17.5" - "@esbuild/netbsd-x64" "0.17.5" - "@esbuild/openbsd-x64" "0.17.5" - "@esbuild/sunos-x64" "0.17.5" - "@esbuild/win32-arm64" "0.17.5" - "@esbuild/win32-ia32" "0.17.5" - "@esbuild/win32-x64" "0.17.5" + "@esbuild/android-arm" "0.17.4" + "@esbuild/android-arm64" "0.17.4" + "@esbuild/android-x64" "0.17.4" + "@esbuild/darwin-arm64" "0.17.4" + "@esbuild/darwin-x64" "0.17.4" + "@esbuild/freebsd-arm64" "0.17.4" + "@esbuild/freebsd-x64" "0.17.4" + "@esbuild/linux-arm" "0.17.4" + "@esbuild/linux-arm64" "0.17.4" + "@esbuild/linux-ia32" "0.17.4" + "@esbuild/linux-loong64" "0.17.4" + "@esbuild/linux-mips64el" "0.17.4" + "@esbuild/linux-ppc64" "0.17.4" + "@esbuild/linux-riscv64" "0.17.4" + "@esbuild/linux-s390x" "0.17.4" + "@esbuild/linux-x64" "0.17.4" + "@esbuild/netbsd-x64" "0.17.4" + "@esbuild/openbsd-x64" "0.17.4" + "@esbuild/sunos-x64" "0.17.4" + "@esbuild/win32-arm64" "0.17.4" + "@esbuild/win32-ia32" "0.17.4" + "@esbuild/win32-x64" "0.17.4" escalade@^3.1.1: version "3.1.1" @@ -5543,9 +5537,9 @@ eslint-plugin-promise@^4.1.1: integrity sha512-bY2sGqyptzFBDLh/GMbAxfdJC+b0f23ME63FOE4+Jao0oZ3E1LEwFtWJX/1pGMJLiTtrSSern2CRM/g+dfc0eQ== eslint-plugin-react@^7.21.4: - version "7.32.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.32.2.tgz#e71f21c7c265ebce01bcbc9d0955170c55571f10" - integrity sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg== + version "7.32.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.32.1.tgz#88cdeb4065da8ca0b64e1274404f53a0f9890200" + integrity sha512-vOjdgyd0ZHBXNsmvU+785xY8Bfe57EFbTYYk8XrROzWpr9QBvpjITvAXt9xqcE6+8cjR/g1+mfumPToxsl1www== dependencies: array-includes "^3.1.6" array.prototype.flatmap "^1.3.1" @@ -6377,9 +6371,9 @@ globals@^11.1.0: integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== globals@^13.6.0, globals@^13.9.0: - version "13.20.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" - integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== + version "13.19.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.19.0.tgz#7a42de8e6ad4f7242fbcca27ea5b23aca367b5c8" + integrity sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ== dependencies: type-fest "^0.20.2" @@ -6735,7 +6729,7 @@ import-fresh@^2.0.0: caller-path "^2.0.0" resolve-from "^3.0.0" -import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: +import-fresh@^3.0.0, import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -7218,12 +7212,7 @@ is-stream@^3.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== -is-string@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" - integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== - -is-string@^1.0.7: +is-string@^1.0.5, is-string@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== @@ -8764,9 +8753,9 @@ node-fetch-npm@^2.0.2: safe-buffer "^5.1.1" node-fetch@^2.5.0, node-fetch@^2.6.1, node-fetch@^2.6.7: - version "2.6.9" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.9.tgz#7c7f744b5cc6eb5fd404e0c7a9fec630a55657e6" - integrity sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg== + version "2.6.8" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.8.tgz#a68d30b162bc1d8fd71a367e81b997e1f4d4937e" + integrity sha512-RZ6dBYuj8dRSfxpUSu+NsdF1dpPpluJxwOp+6IoDp/sH2QNDSvurYsAa+F1WxY2RjA1iP93xhcsUoYbF2XBqVg== dependencies: whatwg-url "^5.0.0" @@ -8840,10 +8829,10 @@ node-notifier@^8.0.0: uuid "^8.3.0" which "^2.0.2" -node-releases@^2.0.8: - version "2.0.9" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.9.tgz#fe66405285382b0c4ac6bcfbfbe7e8a510650b4d" - integrity sha512-2xfmOrRkGogbTK9R6Leda0DGiXeY3p2NJpy4+gNCffdUvV6mdEJnaDEic1i3Ec2djAo8jWYoJMR5PB0MSMpxUA== +node-releases@^2.0.6: + version "2.0.8" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.8.tgz#0f349cdc8fcfa39a92ac0be9bc48b7706292b9ae" + integrity sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A== nopt@^4.0.1: version "4.0.3" @@ -9041,16 +9030,11 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" -object-inspect@^1.12.2: +object-inspect@^1.12.2, object-inspect@^1.9.0: version "1.12.3" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== -object-inspect@^1.9.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a" - integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw== - object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" @@ -9578,13 +9562,6 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -pkg-up@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" - integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA== - dependencies: - find-up "^3.0.0" - plur@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/plur/-/plur-4.0.0.tgz#729aedb08f452645fe8c58ef115bf16b0a73ef84" @@ -10287,9 +10264,9 @@ rfdc@^1.3.0: integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== rimraf@^2.5.4, rimraf@^2.6.2, rimraf@^2.6.3: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== dependencies: glob "^7.1.3" @@ -10325,9 +10302,9 @@ rollup@^2.79.1: fsevents "~2.3.2" rollup@^3.10.0: - version "3.12.1" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.12.1.tgz#2975b97713e4af98c15e7024b88292d7fddb3853" - integrity sha512-t9elERrz2i4UU9z7AwISj3CQcXP39cWxgRWLdf4Tm6aKm1eYrqHIgjzXBgb67GNY1sZckTFFi0oMozh3/S++Ig== + version "3.10.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.10.1.tgz#56278901ed11fc2898421e8e3e2c8155bc7b40b4" + integrity sha512-3Er+yel3bZbZX1g2kjVM+FW+RUWDxbG87fcqFM5/9HbPCTpbVp6JOLn7jlxnNlbu7s/N/uDA4EV/91E2gWnxzw== optionalDependencies: fsevents "~2.3.2" @@ -10642,9 +10619,9 @@ snapdragon@^0.8.1: use "^3.1.0" snyk@^1.91.0: - version "1.1095.0" - resolved "https://registry.yarnpkg.com/snyk/-/snyk-1.1095.0.tgz#0393d5315b857dbe869aa3d9c095d38b92b8e0c2" - integrity sha512-9iiI+ru3qliNCUOX2GYgFYK7pCgNaYzsVRD8x7GlS0tanlDGVN5DK59EhPbqTSC1up3GKQsT3T5IgTSkQya19g== + version "1.1090.0" + resolved "https://registry.yarnpkg.com/snyk/-/snyk-1.1090.0.tgz#33eb9b18fd041f9c21a71fca0aac5d0444714dac" + integrity sha512-9lxsKFtwWP/l7DEBvpuI4J6edzGSCPf1R8s6JpEvPmXQDyUnlU/IQnTd40HceFRu9C+YNn1h7clbJeEQ6Sqndw== socks-proxy-agent@^4.0.0: version "4.0.2" @@ -10892,7 +10869,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.2.3: +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -10918,15 +10895,6 @@ string-width@^3.0.0, string-width@^3.1.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" -string-width@^4.1.0, string-width@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" - integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.0" - string-width@^5.0.0: version "5.1.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" @@ -11451,11 +11419,16 @@ tslib@^1.8.1, tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.1.0, tslib@^2.4.1: +tslib@^2.1.0: version "2.5.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== +tslib@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" + integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA== + tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" @@ -11667,7 +11640,7 @@ upath@^1.1.1, upath@^1.2.0: resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== -update-browserslist-db@^1.0.10: +update-browserslist-db@^1.0.9: version "1.0.10" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== @@ -12172,7 +12145,7 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yaml@^1.10.0, yaml@^1.7.2: +yaml@^1.10.0: version "1.10.2" resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== @@ -12182,10 +12155,10 @@ yaml@^2.1.3: resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.2.1.tgz#3014bf0482dcd15147aa8e56109ce8632cd60ce4" integrity sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw== -yargs-parser@20.x, yargs-parser@^20.2.3: - version "20.2.3" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.3.tgz#92419ba867b858c868acf8bae9bf74af0dd0ce26" - integrity sha512-emOFRT9WVHw03QSvN5qor9QQT9+sw5vwxfYweivSMHTcAXPefwVae2FjO7JJjj8hCE4CzPOPeFM83VwT29HCww== +yargs-parser@20.x, yargs-parser@^20.2.2, yargs-parser@^20.2.3: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== yargs-parser@^15.0.1: version "15.0.3" @@ -12203,11 +12176,6 @@ yargs-parser@^18.1.2: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^20.2.2: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - yargs@^14.2.2: version "14.2.3" resolved "https://registry.yarnpkg.com/yargs/-/yargs-14.2.3.tgz#1a1c3edced1afb2a2fea33604bc6d1d8d688a414" From 43343df2dc110d3473d0c3f1b033877d7c2fbd8d Mon Sep 17 00:00:00 2001 From: Timofei Iatsenko Date: Mon, 13 Feb 2023 11:05:59 +0100 Subject: [PATCH 2/5] docs(extractor): add docs and migration guide --- website/docs/guides/custom-extractor.md | 36 ++++++++++++ website/docs/guides/flow.md | 11 ++++ website/docs/guides/typescript.md | 77 +------------------------ website/docs/ref/conf.md | 38 ++++++------ website/docs/releases/migration-4.md | 67 +++++++++++++++++++++ website/sidebars.ts | 16 ++++- 6 files changed, 149 insertions(+), 96 deletions(-) create mode 100644 website/docs/guides/custom-extractor.md create mode 100644 website/docs/guides/flow.md create mode 100644 website/docs/releases/migration-4.md diff --git a/website/docs/guides/custom-extractor.md b/website/docs/guides/custom-extractor.md new file mode 100644 index 000000000..755a8ee86 --- /dev/null +++ b/website/docs/guides/custom-extractor.md @@ -0,0 +1,36 @@ +# Custom Extractor + +If your project is not playing well with Lingui's Extractor you can write your custom extractor implementation. + +That might be the case if you use some experimental features (stage0 - stage2) or frameworks with custom syntax such as Vue.js or Svelte. + +```ts title="./my-custom-extractor.ts" +import babel from "@lingui/cli/api/extractors/babel" + +export const extractor: ExtractorType = { + match(filename: string) { + return filename.endsWith(".custom"); + }, + extract(filename: string, code: string, onMessageExtracted) { + // transform to plain JS + Sourcemaps + const {code, sourcemaps} = transformMyCustomFileToJs(filename, code); + + // reuse extractor from cli + return babel(filename, code, onMessageExtracted, {sourcemaps}) + } +} +``` + +Then in your `lingui.config.ts`: + +```ts title="lingui.config.ts" +import {extractor} from './my-custom-extractor.ts' +module.exports = { + [...] + extractors: [extractor] +} +``` + +:::caution Important +If you use TypeScript to create your extractor, you should use the `ts` extension for your Lingui configuration file. +::: diff --git a/website/docs/guides/flow.md b/website/docs/guides/flow.md new file mode 100644 index 000000000..001909e14 --- /dev/null +++ b/website/docs/guides/flow.md @@ -0,0 +1,11 @@ +# Flow + +Lingui already supports [Flow](https://flow.org/) by default. All you need to do is enable it in your config file: + +```js title="lingui.config.js" +module.export = { + extractorParserOptions: { + flow: true + } +} +``` diff --git a/website/docs/guides/typescript.md b/website/docs/guides/typescript.md index 1603476f1..84907eb4f 100644 --- a/website/docs/guides/typescript.md +++ b/website/docs/guides/typescript.md @@ -1,63 +1,6 @@ # Typescript -Lingui supports typescript types out of the box since version `3.0.0`. Feel free to submit any query you find related to typescript on GitHub Issues. - -## Webpack setup - -The ability of lingui to support the intuitive syntax comes from the `@lingui/babel-preset-react` Babel transformation. The preset consist of 2 plugins, namely `@lingui/babel-plugin-transform-js` and `@lingui/babel-plugin-transform-react`. - -The plugins perform transformation only on the JSX and tagged template literals. Thus, the JSX and tagged template literals *must not* be transpiled before the 2 plugins get to do their magic to process the intuitive syntax. - -In order to preserve JSX and tagged template literals for the lingui plugins, you must set the following in your `tsconfig.json`. - -```json title="tsconfig.json" -{ - "compilerOptions": { - "jsx": "preserve", - "target": "es2016" - } -} -``` - -For lingui 2.0+, install `babel-loader`, `babel-preset-react`, `babel-preset-env`, `@lingui/babel-preset-react`. Use the presets by changing your `.babelrc` to the following. The order of the preset is important. - -```json title=".babelrc" -{ - "presets": [ - "babel-preset-env", - "babel-preset-react", - "@lingui/babel-preset-react" - ] -} -``` - -In your `webpack.config.js`, use both `babel-loader` and `ts-loader` for Typescript files. - -```js title="webpack.config.js" -{ - module: { - rules: [ - { - test: /\.tsx?$/, - exclude: /node_modules/, - use: ['babel-loader', 'ts-loader'] - } - ] - } -} -``` - -:::note -If you are not using `.babelrc` file, keep in mind that by running [`lingui extract`](/docs/ref/cli.md#extract), the Webpack config is not used. To supply babel options for the extraction process use [`extractBabelOptions`](/docs/ref/conf.md#extractbabeloptions) configuration option. -::: - -[`compileNamespace`](/docs/ref/conf.md#compilenamespace) must be set to `ts` (ES6 default export) in the Lingui config otherwise compiled catalogs can't be imported using ES `import`, but rather CommonJS `require`: - -``` js -{ - "compileNamespace": "ts" -} -``` +Lingui supports typescript types out of the box since version `3.0.0`. ## Macros types in non-React environments @@ -79,21 +22,3 @@ Now you can modify your `tsconfig.json` in your root directory and reference the } } ``` - -## Type definitions - -Since version `3.0.0` types are already inside `@lingui` modules, so you don't need to install any external dependency related to types. - -**For earlier versions**: - -[Jeow Li Huan](https://github.com/huan086) wrote type definition for `@lingui/core` and `@lingui/react`: - -The type definitions requires Typescript 2.8 or later. - -```bash npm2yarn -npm install --save-dev @types/lingui__core # types for @lingui/core -npm install --save-dev @types/lingui__react # types for @lingui/react -npm install --save-dev @types/lingui__macro # types for @lingui/macro -``` - -Please report any issues in [maintainers repo](https://github.com/huan086/lingui-typings). diff --git a/website/docs/ref/conf.md b/website/docs/ref/conf.md index 9353cafd9..b898a6f0c 100644 --- a/website/docs/ref/conf.md +++ b/website/docs/ref/conf.md @@ -21,7 +21,7 @@ Default config: "exclude": ["**/node_modules/**"] }], "compileNamespace": "cjs", - "extractBabelOptions": {}, + "extractorParserOptions": {}, "compilerBabelOptions": {}, "fallbackLocales": {}, "format": "po", @@ -207,17 +207,24 @@ For example, setting [`compileNamespace`](#compilenamespace) to `window.i18n` cr /* eslint-disable */window.i18n={messages: {"..."}} ``` -## extractBabelOptions +## extractorParserOptions Default: `{}` -Specify extra babel options used to parse source files when messages are being extracted. This is required when project doesn't use standard Babel config (e.g. Create React App). - -``` json -{ - "extractBabelOptions": { - "plugins": ["@babel/plugin-syntax-dynamic-import"] - } +Specify extra options used to parse source files when messages are being extracted. + +```ts +"extractorParserOptions": { + /** + * default true + * Use for Stage 3 decorators syntax + */ + decoratorsBeforeExport?: boolean + /** + * Enable if you use flow. Default false + * This will apply Flow syntax to files with .js, cjs, .mjs extension. + */ + flow?: boolean } ``` @@ -432,20 +439,13 @@ The difference between [`fallbackLocales`](#fallbacklocales) and `sourceLocale` Default: `[babel]` -Extractors it's the way to customize which extractor you want for your codebase, a long time ago Babel wasn't ready yet to work with Typescript, so we added two extractors as default `[babel, typescript]`, but right now Babel already works good with Typescript so isn't a requirement anymore to compile two times the same code. - -Anyway, if you want to use the typescript extractor in conjunction with babel you can do: +Extractors it's the way to customize which extractor you want for your codebase. ``` js { "extractors": [ - require.resolve("@lingui/cli/api/extractors/babel"), - require.resolve("@lingui/cli/api/extractors/typescript"), + myCustomExtractor, ] } ``` - -Of course, you can build your own extractor, take a look to babel and typescript extractors to see how you should do it, but basically exports two methods: - -- match: regex to a filename extension, should return `true`|`false` -- extract: is the responsible for transforming the code and using @lingui/babel-plugin-extract-messages +Visit [Advanced: Custom Extractor](/guides/custom-extractor.md) to learn more how to create custom extractor. diff --git a/website/docs/releases/migration-4.md b/website/docs/releases/migration-4.md new file mode 100644 index 000000000..bacefa865 --- /dev/null +++ b/website/docs/releases/migration-4.md @@ -0,0 +1,67 @@ +# Migration guide from 3.x to 4.x + +## Backward incompatible changes + +Minimal required versions are: + +- TypeScript (if used on the project): 4.1 + +### Extractor configuration changes + +The big change in the v4 changes in extractor internals. Now it is less fragile, and not depends on the host project settings. + +For most projects, it should work without extra configuration as long as it is a valid ES code. + +`extractorBabelOptions` is not useful anymore, please delete it from your config. + +```diff title="lingui.config.js" +module.exports = { +- extractorBabelOptions: { [...] } +} +``` + +#### Flow Syntax supported in the Extractor with the flag + +If your project uses Flow, you need explicitly enable support in the extractor: + +```js title="lingui.config.js" +module.exports = { + extractorParserOptions: { + flow: true + } +} +``` + +### `@lingui/cli/api/extractors/typescript` was deleted +Extractor supports TypeScript out of the box. Please delete it from your configuration file. + +### No need to have `NODE_ENV=development` before `lingui-extract` + +If your extract command looks like: + +```bash + NODE_ENV=development lingui-extract +``` + +Now you can safely change it to just: + +```bash + lingui-extract +``` + +### Public interface of `ExtractorType` was changed + +```diff +declare type ExtractorType = { + match(filename: string): boolean +- extract(filename: string, targetDir: string, options?: any): void ++ extract( ++ filename: string, ++ code: string, ++ onMessageExtracted: (msg: ExtractedMessage) => void, ++ options?: ExtractorOptions ++ ): Promise | void +} +``` + +Read more about custom extractor on the [Custom Extractor Page](/guides/custom-extractor) diff --git a/website/sidebars.ts b/website/sidebars.ts index e3ed2e6ef..ddac9fb1b 100644 --- a/website/sidebars.ts +++ b/website/sidebars.ts @@ -65,6 +65,10 @@ const sidebar = [ label: 'TypeScript', id: 'guides/typescript', }, + { + type: 'doc', + id: 'guides/flow', + }, { type: 'doc', label: 'Excluding build files', @@ -95,6 +99,16 @@ const sidebar = [ label: 'Pseudolocalization', id: 'guides/pseudolocalization', }, + { + type: 'category', + label: 'Advanced', + items: [ + { + type: 'doc', + id: 'guides/custom-extractor', + }, + ], + }, ], }, { @@ -182,7 +196,7 @@ const sidebar = [ { type: 'category', label: 'Releases', - items: ['releases/migration-3'], + items: ['releases/migration-3', 'releases/migration-4'], }, ]; From 434e5cb7ee11560a68a1d413311d6c4842d72b14 Mon Sep 17 00:00:00 2001 From: Timofei Iatsenko Date: Tue, 14 Feb 2023 09:04:42 +0100 Subject: [PATCH 3/5] feat(extractor): add deprecation warning for `extractBabelOptions` in conf --- .../conf/src/__snapshots__/index.test.ts.snap | 18 +++++++++++++++++- packages/conf/src/index.test.ts | 15 +++++++++++++++ packages/conf/src/makeConfig.ts | 14 ++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/packages/conf/src/__snapshots__/index.test.ts.snap b/packages/conf/src/__snapshots__/index.test.ts.snap index 2ebd2f015..d6f23ad89 100644 --- a/packages/conf/src/__snapshots__/index.test.ts.snap +++ b/packages/conf/src/__snapshots__/index.test.ts.snap @@ -1,5 +1,18 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`@lingui/conf config file extractBabelOptions deprecation if deprecated extractBabelOptions is defined, we show deprecation message 1`] = ` +● Deprecation Warning: + + Option extractBabelOptions was removed. + + Please remove it from your config file. + + You can find more information here: https://lingui.dev/releases/migration-4.md + + +Documentation: https://lingui.dev/ref/conf +`; + exports[`@lingui/conf config file fallbackLocale deprecation if deprecated fallbackLocale is defined, we set fallbackLocales.default and show message 1`] = ` ● Deprecation Warning: @@ -41,7 +54,10 @@ Object { }, minified: true, }, - extractorParserOptions: Object {}, + extractorParserOptions: Object { + decoratorsBeforeExport: false, + flow: false, + }, fallbackLocales: Object { en-gb: en, }, diff --git a/packages/conf/src/index.test.ts b/packages/conf/src/index.test.ts index 8d98a467f..1994f0e33 100644 --- a/packages/conf/src/index.test.ts +++ b/packages/conf/src/index.test.ts @@ -69,6 +69,21 @@ describe("@lingui/conf", () => { }) }) + describe("extractBabelOptions deprecation", () => { + it("if deprecated extractBabelOptions is defined, we show deprecation message", () => { + mockConsole((console) => { + makeConfig({ + locales: ["en-US"], + extractBabelOptions: { + prop: "value", + }, + } as LinguiConfig & { extractBabelOptions: any }) + + expect(getConsoleMockCalls(console.warn)).toMatchSnapshot() + }) + }) + }) + describe("Build parent cldr fallbackLocales", () => { it("if fallbackLocales.default is defined, we dont build the cldr", () => { const config = makeConfig({ diff --git a/packages/conf/src/makeConfig.ts b/packages/conf/src/makeConfig.ts index b7c68b049..092997b54 100644 --- a/packages/conf/src/makeConfig.ts +++ b/packages/conf/src/makeConfig.ts @@ -114,11 +114,25 @@ export const exampleConfig = { }, } +/** + * Introduced in v4, remove in v5 + */ +const extractBabelOptionsDeprecations = { + extractBabelOptions: () => + ` Option ${chalk.bold("extractBabelOptions")} was removed. + + Please remove it from your config file. + + You can find more information here: https://lingui.dev/releases/migration-4.md + `, +} + const configValidation = { exampleConfig, deprecatedConfig: { ...catalogMigrationDeprecations, ...fallbackLanguageMigrationDeprecations, + ...extractBabelOptionsDeprecations, }, comment: "Documentation: https://lingui.dev/ref/conf", } From 86d393085b76aaf4509e48e59670340c80683412 Mon Sep 17 00:00:00 2001 From: Timofei Iatsenko Date: Tue, 14 Feb 2023 09:05:27 +0100 Subject: [PATCH 4/5] docs: remove `extractBabelOptions` from monorepo docs --- website/docs/guides/monorepo.md | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/website/docs/guides/monorepo.md b/website/docs/guides/monorepo.md index 00596c11c..d9ab5b1d8 100644 --- a/website/docs/guides/monorepo.md +++ b/website/docs/guides/monorepo.md @@ -1,23 +1,6 @@ # Monorepo -If you're using lingui within a monorepo, you need to pass some extra options to `lingui` babel. `{ rootMode: "upward" }` is required to `lingui` find the correct babel config. - -``` json -{ - "catalogs": [{ - "path": "/locale/{locale}/messages", - "include": [""], - "exclude": ["**/node_modules/**"] - }], - "extractBabelOptions": { - "rootMode": "upward", - }, - "format": "po", - "locales": ["en"], -} -``` - -In summary, we'll have: +If you're using lingui within a monorepo you need: - 1x `babel.config.js` within root - 1x `lingui.config.js` within root From a7a7ef9fc805704822a46a34f497c04f2c91e468 Mon Sep 17 00:00:00 2001 From: Timofey Date: Tue, 14 Feb 2023 12:52:42 +0100 Subject: [PATCH 5/5] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Martin Chrástek --- packages/conf/src/__snapshots__/index.test.ts.snap | 2 +- packages/conf/src/makeConfig.ts | 2 +- website/docs/guides/custom-extractor.md | 10 +++++----- website/docs/ref/conf.md | 8 ++++---- website/docs/releases/migration-4.md | 10 +++++----- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/conf/src/__snapshots__/index.test.ts.snap b/packages/conf/src/__snapshots__/index.test.ts.snap index d6f23ad89..6d957d0bd 100644 --- a/packages/conf/src/__snapshots__/index.test.ts.snap +++ b/packages/conf/src/__snapshots__/index.test.ts.snap @@ -7,7 +7,7 @@ exports[`@lingui/conf config file extractBabelOptions deprecation if deprecated Please remove it from your config file. - You can find more information here: https://lingui.dev/releases/migration-4.md + You can find more information here: https://lingui.dev/releases/migration-4 Documentation: https://lingui.dev/ref/conf diff --git a/packages/conf/src/makeConfig.ts b/packages/conf/src/makeConfig.ts index 092997b54..0de87429e 100644 --- a/packages/conf/src/makeConfig.ts +++ b/packages/conf/src/makeConfig.ts @@ -123,7 +123,7 @@ const extractBabelOptionsDeprecations = { Please remove it from your config file. - You can find more information here: https://lingui.dev/releases/migration-4.md + You can find more information here: https://lingui.dev/releases/migration-4 `, } diff --git a/website/docs/guides/custom-extractor.md b/website/docs/guides/custom-extractor.md index 755a8ee86..618e1ba64 100644 --- a/website/docs/guides/custom-extractor.md +++ b/website/docs/guides/custom-extractor.md @@ -1,6 +1,6 @@ # Custom Extractor -If your project is not playing well with Lingui's Extractor you can write your custom extractor implementation. +If your project is not working well with Lingui's Extractor, you can write your custom extractor implementation. That might be the case if you use some experimental features (stage0 - stage2) or frameworks with custom syntax such as Vue.js or Svelte. @@ -13,10 +13,10 @@ export const extractor: ExtractorType = { }, extract(filename: string, code: string, onMessageExtracted) { // transform to plain JS + Sourcemaps - const {code, sourcemaps} = transformMyCustomFileToJs(filename, code); + const {code, sourcemaps} = transformMyCustomFileToJs(filename, code); - // reuse extractor from cli - return babel(filename, code, onMessageExtracted, {sourcemaps}) + // reuse extractor from cli + return babel(filename, code, onMessageExtracted, {sourcemaps}) } } ``` @@ -24,7 +24,7 @@ export const extractor: ExtractorType = { Then in your `lingui.config.ts`: ```ts title="lingui.config.ts" -import {extractor} from './my-custom-extractor.ts' +import { extractor } from './my-custom-extractor.ts' module.exports = { [...] extractors: [extractor] diff --git a/website/docs/ref/conf.md b/website/docs/ref/conf.md index b898a6f0c..cbc0f9e8b 100644 --- a/website/docs/ref/conf.md +++ b/website/docs/ref/conf.md @@ -217,12 +217,12 @@ Specify extra options used to parse source files when messages are being extract "extractorParserOptions": { /** * default true - * Use for Stage 3 decorators syntax + * Use for Stage 3 decorators syntax. */ decoratorsBeforeExport?: boolean /** - * Enable if you use flow. Default false - * This will apply Flow syntax to files with .js, cjs, .mjs extension. + * default false + * Enable if you use flow. This will apply Flow syntax to files with .js, cjs, .mjs extension. */ flow?: boolean } @@ -448,4 +448,4 @@ Extractors it's the way to customize which extractor you want for your codebase. ] } ``` -Visit [Advanced: Custom Extractor](/guides/custom-extractor.md) to learn more how to create custom extractor. +Visit [Advanced: Custom Extractor](/guides/custom-extractor.md) to learn how to create custom extractor. diff --git a/website/docs/releases/migration-4.md b/website/docs/releases/migration-4.md index bacefa865..358b69991 100644 --- a/website/docs/releases/migration-4.md +++ b/website/docs/releases/migration-4.md @@ -8,7 +8,7 @@ Minimal required versions are: ### Extractor configuration changes -The big change in the v4 changes in extractor internals. Now it is less fragile, and not depends on the host project settings. +The big change in the v4 is in extractor internals. Now it is less fragile, and doesn't depend on the host project settings. For most projects, it should work without extra configuration as long as it is a valid ES code. @@ -22,7 +22,7 @@ module.exports = { #### Flow Syntax supported in the Extractor with the flag -If your project uses Flow, you need explicitly enable support in the extractor: +If your project uses Flow, you need to explicitly enable support in the extractor: ```js title="lingui.config.js" module.exports = { @@ -40,13 +40,13 @@ Extractor supports TypeScript out of the box. Please delete it from your configu If your extract command looks like: ```bash - NODE_ENV=development lingui-extract +NODE_ENV=development lingui-extract ``` Now you can safely change it to just: ```bash - lingui-extract +lingui-extract ``` ### Public interface of `ExtractorType` was changed @@ -64,4 +64,4 @@ declare type ExtractorType = { } ``` -Read more about custom extractor on the [Custom Extractor Page](/guides/custom-extractor) +Read more about custom extractor on the [Advanced: Custom Extractor](/guides/custom-extractor) page.