diff --git a/.eslintrc.json b/.eslintrc.json index b6ce63da..98eb2203 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,71 +1,104 @@ { "parser": "@typescript-eslint/parser", + "plugins": [ + "@typescript-eslint", + "eslint-plugin-import", + "typescript-sort-keys", + "prefer-arrow" + ], "extends": [ - "plugin:react/recommended" + "eslint:recommended", + "plugin:react/recommended", + "plugin:@typescript-eslint/recommended", + "plugin:jest/recommended", + "plugin:jest/style", + "plugin:typescript-sort-keys/recommended" ], - "settings": { - "react": { - "version": "detect" - } - }, - "env": { - "browser": true - }, "ignorePatterns": [ - "**/node_modules/*" + "**/node_modules/*", + "**/out/*", + "**/.next/*" ], "rules": { - "padded-blocks": 0, - "global-require": 0, - "function-paren-newline": 0, - "no-buffer-constructor": 0, - "import/no-extraneous-dependencies": 0, - "import/no-unresolved": 0, - "import/extensions": 0, - "import/no-mutable-exports": 0, + "comma-dangle": [ + "error", + "always-multiline" + ], + "eol-last": ["error", "always"], + "indent": ["error", 2], + "jest/no-conditional-expect": 0, + "no-console": 2, + "no-trailing-spaces": 2, + "max-len": ["error", { + "code": 80, + "comments": 80, + "ignorePattern": "^import\\s.+\\sfrom\\s.+$", + "ignoreStrings": true, + "ignoreTemplateLiterals": true + }], + "multiline-comment-style": ["error", "separate-lines"], + "no-multiple-empty-lines": "error", + "no-multi-spaces": ["error", { "exceptions": { "Property": false } }], + "no-return-await": 2, + "arrow-body-style": ["error", "as-needed"], + "import/no-amd": 2, + "import/no-commonjs": 2, + "import/no-default-export": 2, + "import/no-namespace": 2, + "import/no-nodejs-modules": 0, + "keyword-spacing": ["error", { "overrides": {} }], + "react/prefer-stateless-function": 2, "react/prop-types": 0, - "react/display-name": 0, - "react/jsx-filename-extension": 0, - "react/prefer-stateless-function": 0, - "react/react-in-jsx-scope": 0, - "no-restricted-syntax": 0, - "no-useless-escape": 0, - "no-console": [ + "react/jsx-wrap-multilines": ["error", { + "declaration": "parens-new-line", + "assignment": "parens-new-line", + "return": "parens-new-line", + "arrow": "parens-new-line", + "condition": "parens-new-line", + "logical": "parens-new-line", + "prop": "parens-new-line" + } + ], + "semi": ["error", "never"], + "sort-keys": 2, + "space-before-blocks": 2, + "@typescript-eslint/explicit-function-return-type": 0, + "@typescript-eslint/explicit-module-boundary-types": 0, + "@typescript-eslint/member-delimiter-style": ["error", { + "multiline": { + "delimiter": "none", + "requireLast": false + }, + "singleline": { + "delimiter": "comma", + "requireLast": false + } + }], + "@typescript-eslint/no-explicit-any": 0, + "@typescript-eslint/no-unused-vars": [ + 2, + { + "argsIgnorePattern": "^_" + } + ], + "@typescript-eslint/no-var-requires": 0, + "prefer-arrow/prefer-arrow-functions": [ "error", { - "allow": [ - "warn", - "error" - ] + "disallowPrototype": true, + "singleReturnOnly": false, + "classPropertiesAllowed": false } - ] + ], + "prefer-destructuring": ["error", {"object": true, "array": true}], + "quotes": ["error", "single"], + "quote-props": ["error", "as-needed"], + "jsx-quotes": ["error", "prefer-single"] }, - "overrides": [ - { - "files": [ - "src/**/*.{ts,tsx}" - ], - "extends": [ - "plugin:@typescript-eslint/recommended" - ], - "rules": { - "@typescript-eslint/indent": [ - "error", - 2 - ], - "semi": "off", - "@typescript-eslint/semi": [ - "error", - "never" - ], - "@typescript-eslint/no-var-requires": 0, - "@typescript-eslint/no-explicit-any": 0, - "@typescript-eslint/explicit-function-return-type": 0, - "@typescript-eslint/explicit-member-accessibility": 0, - "@typescript-eslint/no-object-literal-type-assertion": 0, - "@typescript-eslint/prefer-interface": 0 - }, - "parser": "@typescript-eslint/parser" + "settings": { + "react": { + "pragma": "React", + "version": "16.13.1" } - ] + } } diff --git a/examples/simple/components/Header.js b/examples/simple/components/Header.js index 0e612e74..111b1f39 100644 --- a/examples/simple/components/Header.js +++ b/examples/simple/components/Header.js @@ -6,12 +6,12 @@ export const Header = ({ title }) => ( next-i18next - - + + - - - + + +

next-i18next @@ -21,10 +21,10 @@ export const Header = ({ title }) => ( {title}

- + ) diff --git a/examples/simple/next-i18next.config.js b/examples/simple/next-i18next.config.js index f0b97b7a..c8fcc18b 100644 --- a/examples/simple/next-i18next.config.js +++ b/examples/simple/next-i18next.config.js @@ -2,5 +2,5 @@ module.exports = { i18n: { defaultLocale: 'en', locales: ['en', 'de'], - } + }, } diff --git a/examples/simple/pages/index.js b/examples/simple/pages/index.js index e6b1d971..373889e1 100644 --- a/examples/simple/pages/index.js +++ b/examples/simple/pages/index.js @@ -42,7 +42,7 @@ const Homepage = () => { export const getStaticProps = async ({ locale }) => ({ props: { ...await serverSideTranslations(locale, ['common', 'footer']), - } + }, }) export default Homepage diff --git a/examples/simple/pages/second-page.js b/examples/simple/pages/second-page.js index 47ac4411..603d98f1 100644 --- a/examples/simple/pages/second-page.js +++ b/examples/simple/pages/second-page.js @@ -30,7 +30,7 @@ const SecondPage = () => { export const getStaticProps = async ({ locale }) => ({ props: { ...await serverSideTranslations(locale, ['second-page', 'footer']), - } + }, }) export default SecondPage diff --git a/package.json b/package.json index b8f43250..deed9022 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ ], "scripts": { "check-types": "tsc", - "lint": "eslint types.d.ts src/**/* examples", + "lint": "eslint --ext .ts,.tsx types.d.ts src", "lint:fix": "eslint types.d.ts src/**/* examples --fix", "clean": "rm -rf examples/simple/.next && rm -rf dist && mkdir dist", "build:es": "BABEL_ENV=es babel src --extensions '.ts,.tsx' --out-dir dist/es --copy-files", @@ -83,7 +83,10 @@ "bundlesize": "^0.18.0", "eslint": "^7.17.0", "eslint-plugin-import": "^2.22.1", + "eslint-plugin-jest": "^24.1.5", + "eslint-plugin-prefer-arrow": "^1.2.3", "eslint-plugin-react": "^7.22.0", + "eslint-plugin-typescript-sort-keys": "^1.5.0", "husky": "^3.0.0", "jest": "^24.1.0", "next": "^10.0.4", diff --git a/src/appWithTranslation.tsx b/src/appWithTranslation.tsx index d262adef..4c397896 100644 --- a/src/appWithTranslation.tsx +++ b/src/appWithTranslation.tsx @@ -9,10 +9,12 @@ import { SSRConfig } from '../types' export { I18nContext, Trans, useTranslation, withTranslation } from 'react-i18next' type AppProps = { - pageProps: SSRConfig; + pageProps: SSRConfig } -export const appWithTranslation =

>(WrappedComponent: React.ComponentType | React.ElementType): React.ComponentType

| React.ElementType

=> { +export const appWithTranslation =

>( + WrappedComponent: React.ComponentType | React.ElementType): + React.ComponentType

| React.ElementType

=> { const AppWithTranslation = (props: AppProps) => { let i18n = null let locale = null @@ -27,7 +29,7 @@ export const appWithTranslation =

>(WrappedCom const parsedUserConfig = Function(`'use strict';return(${userConfig})`)() locale = initialLocale; - + ({ i18n } = createClient({ ...createConfig({ ...parsedUserConfig, diff --git a/src/config/createConfig.test.ts b/src/config/createConfig.test.ts index 4d0f313f..21c589a7 100644 --- a/src/config/createConfig.test.ts +++ b/src/config/createConfig.test.ts @@ -19,14 +19,14 @@ describe('createConfig', () => { (fs.existsSync as jest.Mock).mockReturnValue(true); (fs.readdirSync as jest.Mock).mockReturnValue([]) }) - + it('throws when lng is not provided', () => { expect(createConfig).toThrow('config.lng was not passed into createConfig') }) - + it('returns a valid config when only lng is provided', () => { const config = createConfig({ lng: 'en' } as UserConfig) - + expect((config.backend as any).addPath).toMatch('/public/locales/{{lng}}/{{ns}}.missing.json') expect((config.backend as any).loadPath).toMatch('/public/locales/{{lng}}/{{ns}}.json') expect(config.defaultLocale).toEqual('en') @@ -49,20 +49,20 @@ describe('createConfig', () => { it('deep merges backend', () => { const config = createConfig({ - lng: 'en', backend: { hello: 'world', - } + }, + lng: 'en', } as UserConfig) expect((config.backend as any).hello).toEqual('world') }) it('deep merges detection', () => { const config = createConfig({ - lng: 'en', detection: { hello: 'world', - } + }, + lng: 'en', } as UserConfig) expect((config.detection as any).hello).toEqual('world') }) @@ -73,7 +73,7 @@ describe('createConfig', () => { (fs.existsSync as jest.Mock).mockReturnValueOnce(false) const config = createConfig.bind(null, { - lng: 'en' + lng: 'en', }) expect(config).toThrow('Default namespace not found at public/locales/en/common.json') @@ -84,21 +84,21 @@ describe('createConfig', () => { it('returns a config without calling any fs methods', () => { (fs.existsSync as jest.Mock).mockReset(); (fs.readdirSync as jest.Mock).mockReset() - + createConfig({ lng: 'en', use: [{ - type: 'backend' + type: 'backend', }] } as UserConfig) - + expect(fs.existsSync).toHaveBeenCalledTimes(0) expect(fs.readdirSync).toHaveBeenCalledTimes(0) }) }) - describe('ci mode', () => { + describe('ci mode', () => { it('returns a config without calling any fs methods', () => { createConfig({ lng: 'cimode' } as UserConfig) - + expect(fs.existsSync).toHaveBeenCalledTimes(0) expect(fs.readdirSync).toHaveBeenCalledTimes(0) }) @@ -113,10 +113,10 @@ describe('createConfig', () => { it('throws when lng is not provided', () => { expect(createConfig).toThrow('config.lng was not passed into createConfig') }) - + it('returns a valid config when only lng is provided', () => { const config = createConfig({ lng: 'en' } as UserConfig) - + expect((config.backend as any).addPath).toMatch('/public/locales/{{lng}}/{{ns}}.missing.json') expect((config.backend as any).loadPath).toMatch('/public/locales/{{lng}}/{{ns}}.json') expect(config.defaultLocale).toEqual('en') @@ -129,7 +129,7 @@ describe('createConfig', () => { expect(config.localeStructure).toEqual('{{lng}}/{{ns}}') expect(config.locales).toEqual(['en']) expect(config.ns).toEqual(['common']) - expect(config.preload).toEqual(undefined) + expect(config.preload).toBeUndefined() expect(config.strictMode).toEqual(true) expect(config.use).toEqual([]) }) diff --git a/src/config/createConfig.ts b/src/config/createConfig.ts index dde30fbb..b311f238 100644 --- a/src/config/createConfig.ts +++ b/src/config/createConfig.ts @@ -8,9 +8,9 @@ export const createConfig = (userConfig: UserConfig): InternalConfig => { throw new Error('config.lng was not passed into createConfig') } - /* - Initial merge of default and user-provided config - */ + // + // Initial merge of default and user-provided config + // const { i18n: userI18n, ...userConfigStripped } = userConfig const { i18n: defaultI18n, ...defaultConfigStripped } = defaultConfig const combinedConfig = { @@ -46,10 +46,10 @@ export const createConfig = (userConfig: UserConfig): InternalConfig => { const path = require('path') const serverLocalePath = localePath - /* - Validate defaultNS - https://github.com/isaachinman/next-i18next/issues/358 - */ + // + // Validate defaultNS + // https://github.com/isaachinman/next-i18next/issues/358 + // if (typeof combinedConfig.defaultNS === 'string') { const defaultFile = `/${lng}/${combinedConfig.defaultNS}.${localeExtension}` const defaultNSPath = path.join(localePath, defaultFile) @@ -59,17 +59,17 @@ export const createConfig = (userConfig: UserConfig): InternalConfig => { } } - /* - Set server side backend - */ + // + // Set server side backend + // combinedConfig.backend = { - loadPath: path.resolve(process.cwd(), `${serverLocalePath}/${localeStructure}.${localeExtension}`), addPath: path.resolve(process.cwd(), `${serverLocalePath}/${localeStructure}.missing.${localeExtension}`), + loadPath: path.resolve(process.cwd(), `${serverLocalePath}/${localeStructure}.${localeExtension}`), } - /* - Set server side preload (namespaces) - */ + // + // Set server side preload (namespaces) + // if (!combinedConfig.ns) { const getAllNamespaces = p => fs.readdirSync(p).map(file => file.replace(`.${localeExtension}`, '')) combinedConfig.ns = getAllNamespaces(path.resolve(process.cwd(), `${serverLocalePath}/${lng}`)) @@ -79,27 +79,27 @@ export const createConfig = (userConfig: UserConfig): InternalConfig => { let clientLocalePath = localePath - /* - Remove public prefix from client site config - */ + // + // Remove public prefix from client site config + // if (localePath.startsWith('/public/')) { clientLocalePath = localePath.replace(/^\/public/, '') } - /* - Set client side backend - */ + // + // Set client side backend + // combinedConfig.backend = { - loadPath: `${clientLocalePath}/${localeStructure}.${localeExtension}`, addPath: `${clientLocalePath}/${localeStructure}.missing.${localeExtension}`, + loadPath: `${clientLocalePath}/${localeStructure}.${localeExtension}`, } combinedConfig.ns = [combinedConfig.defaultNS] } - /* - Deep merge with overwrite - goes last - */ + // + // Deep merge with overwrite - goes last + // deepMergeObjects.forEach((obj) => { if (userConfig[obj]) { combinedConfig[obj] = { diff --git a/src/config/defaultConfig.ts b/src/config/defaultConfig.ts index 0c62dc38..0eb78e46 100644 --- a/src/config/defaultConfig.ts +++ b/src/config/defaultConfig.ts @@ -6,29 +6,28 @@ const LOCALE_STRUCTURE = '{{lng}}/{{ns}}' const LOCALE_EXTENSION = 'json' export const defaultConfig = { + defaultNS: DEFAULT_NAMESPACE, + errorStackTraceLimit: 0, i18n: { defaultLocale: DEFAULT_LOCALE, locales: LOCALES, }, - - load: 'currentOnly', - localePath: LOCALE_PATH, - localeStructure: LOCALE_STRUCTURE, - localeExtension: LOCALE_EXTENSION, - use: [], - defaultNS: DEFAULT_NAMESPACE, + get initImmediate(): boolean { + return process.browser + }, interpolation: { escapeValue: false, - formatSeparator: ',', format: (value: string, format: string): string => (format === 'uppercase' ? value.toUpperCase() : value), + formatSeparator: ',', }, + load: 'currentOnly', + localeExtension: LOCALE_EXTENSION, + localePath: LOCALE_PATH, + localeStructure: LOCALE_STRUCTURE, react: { - wait: true, useSuspense: false, + wait: true, }, strictMode: true, - errorStackTraceLimit: 0, - get initImmediate(): boolean { - return process.browser - } + use: [], } diff --git a/src/createClient/.eslintrc.json b/src/createClient/.eslintrc.json new file mode 100644 index 00000000..cf664baf --- /dev/null +++ b/src/createClient/.eslintrc.json @@ -0,0 +1,5 @@ +{ + "rules": { + "import/no-default-export": "off" + } +} diff --git a/src/createClient/browser.test.ts b/src/createClient/browser.test.ts index 7cb27e22..12c67a18 100644 --- a/src/createClient/browser.test.ts +++ b/src/createClient/browser.test.ts @@ -13,7 +13,9 @@ describe('createClientBrowser', () => { expect(typeof client.initPromise.then).toEqual('function') expect(typeof client.i18n.addResource).toEqual('function') expect(typeof (client.i18n as any).translator).toEqual('object') - expect((client.i18n.options as any).defaultLocale).toEqual(config.defaultLocale) + expect( + (client.i18n.options as any).defaultLocale + ).toEqual(config.defaultLocale) expect((client.i18n.options as any).locales).toEqual(config.locales) }) }) diff --git a/src/createClient/node.test.ts b/src/createClient/node.test.ts index 9a7d2d9b..a977efc6 100644 --- a/src/createClient/node.test.ts +++ b/src/createClient/node.test.ts @@ -13,7 +13,9 @@ describe('createClientBrowser', () => { expect(typeof client.initPromise.then).toEqual('function') expect(typeof client.i18n.addResource).toEqual('function') expect(typeof (client.i18n as any).translator).toEqual('object') - expect((client.i18n.options as any).defaultLocale).toEqual(config.defaultLocale) + expect( + (client.i18n.options as any).defaultLocale + ).toEqual(config.defaultLocale) expect((client.i18n.options as any).locales).toEqual(config.locales) }) }) diff --git a/src/serverSideTranslations.ts b/src/serverSideTranslations.ts index feb907d2..32a4151e 100644 --- a/src/serverSideTranslations.ts +++ b/src/serverSideTranslations.ts @@ -32,7 +32,7 @@ export const serverSideTranslations = async ( await initPromise const initialI18nStore = { - [initialLocale]: {} + [initialLocale]: {}, } namespacesRequired.forEach((ns) => { @@ -46,6 +46,6 @@ export const serverSideTranslations = async ( initialI18nStore, initialLocale, userConfig: serialize(userConfig), - } + }, } } diff --git a/src/utils/consoleMessage.test.ts b/src/utils/consoleMessage.test.ts index f6d25885..af03b4fc 100644 --- a/src/utils/consoleMessage.test.ts +++ b/src/utils/consoleMessage.test.ts @@ -1,10 +1,12 @@ +/* eslint-disable no-console */ + import { consoleMessage } from '../../src/utils' import { InternalConfig } from '../../types' const consoleMessageStrictMode = (type, message) => consoleMessage(type, message, { - strictMode: true, errorStackTraceLimit: 0, + strictMode: true, } as InternalConfig) const consoleMessageNotStrictMode = (type, message) => @@ -90,20 +92,22 @@ describe('consoleMessage utility function', () => { consoleMessageStrictMode('info', ['An', 'array', 'of', 'message']) consoleMessageStrictMode('info', () => 'Function message') - const [[errorObject1], [errorObject2], [errorObject3]] = consoleErrSpy.mock.calls + const [ + [errorObject1], [errorObject2], [errorObject3], + ] = consoleErrSpy.mock.calls expect(errorObject1.name).toBe('Meta') expect(errorObject1.message).toMatch( - "Param message needs to be of type: string. Instead, 'object' was provided", + 'Param message needs to be of type: string. Instead, \'object\' was provided', ) expect(errorObject2.name).toBe('Meta') expect(errorObject2.message).toMatch( - "Param message needs to be of type: string. Instead, 'object' was provided", + 'Param message needs to be of type: string. Instead, \'object\' was provided', ) expect(errorObject3.name).toBe('Meta') expect(errorObject3.message).toMatch( - "Param message needs to be of type: string. Instead, 'function' was provided", + 'Param message needs to be of type: string. Instead, \'function\' was provided', ) }) }) diff --git a/src/utils/consoleMessage.ts b/src/utils/consoleMessage.ts index 567fdd20..976888a2 100644 --- a/src/utils/consoleMessage.ts +++ b/src/utils/consoleMessage.ts @@ -1,6 +1,6 @@ /* eslint-disable no-console */ -import { InternalConfig } from "../../types" +import { InternalConfig } from '../../types' type MessageType = 'error' | 'info' | 'warn' @@ -20,7 +20,11 @@ const logMessage = (messageType: MessageType, message: string) => { } } -export const consoleMessage = (messageType: MessageType, message: string, config: InternalConfig): void => { +export const consoleMessage = ( + messageType: MessageType, + message: string, + config: InternalConfig +): void => { const { errorStackTraceLimit, strictMode } = config @@ -38,20 +42,20 @@ export const consoleMessage = (messageType: MessageType, message: string, config return } - /* - Temporarily set the stacktrace to 0 or errorStackTraceLimit, - in order to only display a message - */ + // + // Temporarily set the stacktrace to 0 or errorStackTraceLimit, + // in order to only display a message + // Error.stackTraceLimit = errorStackTraceLimit - /* - Make room for new message - */ + // + // Make room for new message + // console.log() - /* - Make sure the message is a string - */ + // + // Make sure the message is a string + // if (typeof message !== 'string') { const metaError = new Error() metaError.name = 'Meta' @@ -68,14 +72,14 @@ export const consoleMessage = (messageType: MessageType, message: string, config return } - /* - Log the message to console - */ + // + // Log the message to console + // logMessage(messageType, message) - /* - Reset stack limit - */ + // + // Reset stack limit + // Error.stackTraceLimit = prevStackLimit } diff --git a/types.d.ts b/types.d.ts index 17fa445a..de66d87c 100644 --- a/types.d.ts +++ b/types.d.ts @@ -1,38 +1,36 @@ /* tslint:disable no-explicit-any */ - -import * as React from 'react' import { I18nContext, useTranslation, Trans, withTranslation, - WithTranslation as ReactI18nextWithTranslation + WithTranslation as ReactI18nextWithTranslation, } from 'react-i18next' import { InitOptions, i18n, TFunction as I18NextTFunction } from 'i18next' -import { appWithTranslation } from './src'; +import { appWithTranslation } from './src' type NextJsI18NConfig = { - defaultLocale: string; - locales: string[]; + defaultLocale: string + locales: string[] } export type UserConfig = { - i18n: NextJsI18NConfig; - localeExtension?: string; - localePath?: string; - localeStructure?: string; - strictMode?: boolean; - use?: any[]; + i18n: NextJsI18NConfig + localeExtension?: string + localePath?: string + localeStructure?: string + strictMode?: boolean + use?: any[] } & InitOptions export type InternalConfig = Omit & NextJsI18NConfig & { errorStackTraceLimit: number - fallbackLng: boolean; - supportedLngs: string[]; - // temporal backwards compatibility WHITELIST REMOVAL - whitelist: string[]; + fallbackLng: boolean // end temporal backwards compatibility WHITELIST REMOVAL - preload: string[]; + preload: string[] + supportedLngs: string[] + // temporal backwards compatibility WHITELIST REMOVAL + whitelist: string[] } export type UseTranslation = typeof useTranslation @@ -43,16 +41,16 @@ export type WithTranslationHocType = typeof withTranslation export type WithTranslation = ReactI18nextWithTranslation export type InitPromise = Promise export type CreateClientReturn = { - i18n: I18n; - initPromise: InitPromise; + i18n: I18n + initPromise: InitPromise } export type SSRConfig = { _nextI18Next: { - initialI18nStore: any; - initialLocale: string; - userConfig: UserConfig; - }; + initialI18nStore: any + initialLocale: string + userConfig: UserConfig + } } export { diff --git a/yarn.lock b/yarn.lock index bbddb395..a4a4166e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1427,6 +1427,28 @@ eslint-scope "^5.0.0" eslint-utils "^2.0.0" +"@typescript-eslint/experimental-utils@^2.32.0": + version "2.34.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz#d3524b644cdb40eebceca67f8cf3e4cc9c8f980f" + integrity sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA== + dependencies: + "@types/json-schema" "^7.0.3" + "@typescript-eslint/typescript-estree" "2.34.0" + eslint-scope "^5.0.0" + eslint-utils "^2.0.0" + +"@typescript-eslint/experimental-utils@^4.0.1": + version "4.15.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.15.1.tgz#d744d1ac40570a84b447f7aa1b526368afd17eec" + integrity sha512-9LQRmOzBRI1iOdJorr4jEnQhadxK4c9R2aEAsm7WE/7dq8wkKD1suaV0S/JucTL8QlYUPU1y2yjqg+aGC0IQBQ== + dependencies: + "@types/json-schema" "^7.0.3" + "@typescript-eslint/scope-manager" "4.15.1" + "@typescript-eslint/types" "4.15.1" + "@typescript-eslint/typescript-estree" "4.15.1" + eslint-scope "^5.0.0" + eslint-utils "^2.0.0" + "@typescript-eslint/parser@^4.11.1": version "4.11.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.11.1.tgz#981e18de2e019d6ca312596615f92e8f6f6598ed" @@ -1445,11 +1467,37 @@ "@typescript-eslint/types" "4.11.1" "@typescript-eslint/visitor-keys" "4.11.1" +"@typescript-eslint/scope-manager@4.15.1": + version "4.15.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.15.1.tgz#f6511eb38def2a8a6be600c530c243bbb56ac135" + integrity sha512-ibQrTFcAm7yG4C1iwpIYK7vDnFg+fKaZVfvyOm3sNsGAerKfwPVFtYft5EbjzByDJ4dj1WD8/34REJfw/9wdVA== + dependencies: + "@typescript-eslint/types" "4.15.1" + "@typescript-eslint/visitor-keys" "4.15.1" + "@typescript-eslint/types@4.11.1": version "4.11.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.11.1.tgz#3ba30c965963ef9f8ced5a29938dd0c465bd3e05" integrity sha512-5kvd38wZpqGY4yP/6W3qhYX6Hz0NwUbijVsX2rxczpY6OXaMxh0+5E5uLJKVFwaBM7PJe1wnMym85NfKYIh6CA== +"@typescript-eslint/types@4.15.1": + version "4.15.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.15.1.tgz#da702f544ef1afae4bc98da699eaecd49cf31c8c" + integrity sha512-iGsaUyWFyLz0mHfXhX4zO6P7O3sExQpBJ2dgXB0G5g/8PRVfBBsmQIc3r83ranEQTALLR3Vko/fnCIVqmH+mPw== + +"@typescript-eslint/typescript-estree@2.34.0": + version "2.34.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz#14aeb6353b39ef0732cc7f1b8285294937cf37d5" + integrity sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg== + dependencies: + debug "^4.1.1" + eslint-visitor-keys "^1.1.0" + glob "^7.1.6" + is-glob "^4.0.1" + lodash "^4.17.15" + semver "^7.3.2" + tsutils "^3.17.1" + "@typescript-eslint/typescript-estree@4.11.1": version "4.11.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.11.1.tgz#a4416b4a65872a48773b9e47afabdf7519eb10bc" @@ -1464,6 +1512,19 @@ semver "^7.3.2" tsutils "^3.17.1" +"@typescript-eslint/typescript-estree@4.15.1": + version "4.15.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.15.1.tgz#fa9a9ff88b4a04d901ddbe5b248bc0a00cd610be" + integrity sha512-z8MN3CicTEumrWAEB2e2CcoZa3KP9+SMYLIA2aM49XW3cWIaiVSOAGq30ffR5XHxRirqE90fgLw3e6WmNx5uNw== + dependencies: + "@typescript-eslint/types" "4.15.1" + "@typescript-eslint/visitor-keys" "4.15.1" + debug "^4.1.1" + globby "^11.0.1" + is-glob "^4.0.1" + semver "^7.3.2" + tsutils "^3.17.1" + "@typescript-eslint/visitor-keys@4.11.1": version "4.11.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.11.1.tgz#4c050a4c1f7239786e2dd4e69691436143024e05" @@ -1472,6 +1533,14 @@ "@typescript-eslint/types" "4.11.1" eslint-visitor-keys "^2.0.0" +"@typescript-eslint/visitor-keys@4.15.1": + version "4.15.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.15.1.tgz#c76abbf2a3be8a70ed760f0e5756bf62de5865dd" + integrity sha512-tYzaTP9plooRJY8eNlpAewTOqtWW/4ff/5wBjNVaJ0S0wC4Gpq/zDVRTJa5bq2v1pCNQ08xxMCndcvR+h7lMww== + dependencies: + "@typescript-eslint/types" "4.15.1" + eslint-visitor-keys "^2.0.0" + "@webassemblyjs/ast@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" @@ -3560,6 +3629,18 @@ eslint-plugin-import@^2.22.1: resolve "^1.17.0" tsconfig-paths "^3.9.0" +eslint-plugin-jest@^24.1.5: + version "24.1.5" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-24.1.5.tgz#1e866a9f0deac587d0a3d5d7cefe99815a580de2" + integrity sha512-FIP3lwC8EzEG+rOs1y96cOJmMVpdFNreoDJv29B5vIupVssRi8zrSY3QadogT0K3h1Y8TMxJ6ZSAzYUmFCp2hg== + dependencies: + "@typescript-eslint/experimental-utils" "^4.0.1" + +eslint-plugin-prefer-arrow@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-prefer-arrow/-/eslint-plugin-prefer-arrow-1.2.3.tgz#e7fbb3fa4cd84ff1015b9c51ad86550e55041041" + integrity sha512-J9I5PKCOJretVuiZRGvPQxCbllxGAV/viI20JO3LYblAodofBxyMnZAJ+WGeClHgANnSJberTNoFWWjrWKBuXQ== + eslint-plugin-react@^7.22.0: version "7.22.0" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.22.0.tgz#3d1c542d1d3169c45421c1215d9470e341707269" @@ -3577,6 +3658,15 @@ eslint-plugin-react@^7.22.0: resolve "^1.18.1" string.prototype.matchall "^4.0.2" +eslint-plugin-typescript-sort-keys@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-typescript-sort-keys/-/eslint-plugin-typescript-sort-keys-1.5.0.tgz#cc2ae7a9311422d8eab760ae01524426fd204004" + integrity sha512-Pq0geV5TbkoGyxiPUH9AZhloRbQekrprmiXpMWmtSURfWvsWtPtsEPDLVKhDN19S791zbqnw+cm7enzu6833/w== + dependencies: + "@typescript-eslint/experimental-utils" "^2.32.0" + json-schema "^0.2.5" + natural-compare-lite "^1.4.0" + eslint-scope@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" @@ -4162,7 +4252,7 @@ glob-to-regexp@^0.4.1: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: +glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== @@ -5342,6 +5432,11 @@ json-schema@0.2.3: resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= +json-schema@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.5.tgz#97997f50972dd0500214e208c407efa4b5d7063b" + integrity sha512-gWJOWYFrhQ8j7pVm0EM8Slr+EPVq1Phf6lvzvD/WCeqkrx/f2xBI0xOsRRS9xCn3I4vKtP519dvs3TP09r24wQ== + json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" @@ -5818,6 +5913,11 @@ native-url@0.3.4: dependencies: querystring "^0.2.0" +natural-compare-lite@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" + integrity sha1-F7CVgZiJef3a/gIB6TG6kzyWy7Q= + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"