aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2023-09-25 12:33:00 +0200
committerArmand Philippot <git@armandphilippot.com>2023-10-24 12:23:48 +0200
commit31695306bfed44409f03006ea717fd2cceff8f87 (patch)
tree03c1f4dab34d8f4927e1b824ddf0ab8031538221
parenta22214f2a2efcdac2666e1aad3332cb49d2f2198 (diff)
build(eslint): improve ESlint rules
In my opinion, next/core-web-vitals rules are too loose so I added a custom config to improve code consistency and to enforce best practices.
-rw-r--r--.eslintrc.cjs606
-rw-r--r--mdx.d.ts9
-rw-r--r--next.config.js10
-rw-r--r--package.json8
-rw-r--r--tsconfig.eslint.json18
-rw-r--r--tsconfig.json10
-rw-r--r--yarn.lock66
7 files changed, 693 insertions, 34 deletions
diff --git a/.eslintrc.cjs b/.eslintrc.cjs
index 09a4e71..7e2f9b1 100644
--- a/.eslintrc.cjs
+++ b/.eslintrc.cjs
@@ -1,11 +1,248 @@
module.exports = {
- extends: ['next/core-web-vitals', 'prettier', 'plugin:storybook/recommended'],
- plugins: ['formatjs'],
+ env: {
+ browser: true,
+ es6: true,
+ node: true,
+ },
+ extends: [
+ 'eslint:recommended',
+ 'plugin:import/recommended',
+ 'plugin:react/recommended',
+ 'plugin:react/jsx-runtime',
+ 'plugin:react-hooks/recommended',
+ 'plugin:jsx-a11y/recommended',
+ 'next/core-web-vitals',
+ 'prettier',
+ ],
+ plugins: ['react', 'import', 'jsx-a11y', 'formatjs'],
parserOptions: {
- project: ['tsconfig.json', './tests/cypress/tsconfig.json'],
- tsconfigRootDir: __dirname,
+ ecmaFeatures: {
+ jsx: true,
+ },
+ ecmaVersion: 'latest',
+ },
+ settings: {
+ 'import/extensions': ['.js', '.jsx'],
+ 'import/resolver': {
+ node: true,
+ },
+ react: {
+ version: 'detect',
+ },
},
rules: {
+ // CORE RULES
+ 'array-callback-return': [
+ 'error',
+ { allowImplicit: false, checkForEach: true },
+ ],
+ 'arrow-body-style': [
+ 'error',
+ 'as-needed',
+ { requireReturnForObjectLiteral: true },
+ ],
+ 'block-scoped-var': 'error',
+ // cspell:disable-next-line
+ camelcase: [
+ 'error',
+ {
+ properties: 'always',
+ ignoreDestructuring: false,
+ ignoreImports: false,
+ ignoreGlobals: true,
+ },
+ ],
+ complexity: ['error', { max: 20 }],
+ 'consistent-return': ['error', { treatUndefinedAsUnspecified: false }],
+ 'default-case': 'error',
+ 'default-case-last': 'error',
+ 'default-param-last': 'error',
+ 'dot-notation': ['error', { allowKeywords: true }],
+ eqeqeq: ['error', 'always', { null: 'always' }],
+ 'func-name-matching': ['error', 'always'],
+ 'func-names': ['error', 'always'],
+ 'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
+ 'guard-for-in': 'error',
+ 'init-declarations': ['error', 'always'],
+ 'max-depth': ['error', { max: 4 }],
+ 'max-nested-callbacks': ['error', { max: 10 }],
+ 'max-params': ['error', { max: 3 }],
+ 'max-statements': ['error', { max: 10 }],
+ 'new-cap': [
+ 'error',
+ {
+ capIsNew: true,
+ capIsNewExceptionPattern: '^[A-Z]+[A-Z._]*[A-Z]+$',
+ newIsCap: true,
+ properties: true,
+ },
+ ],
+ 'no-alert': 'error',
+ 'no-array-constructor': 'error',
+ 'no-await-in-loop': 'error',
+ 'no-bitwise': 'error',
+ 'no-caller': 'error',
+ 'no-confusing-arrow': [
+ 'error',
+ { allowParens: false, onlyOneSimpleParam: false },
+ ],
+ 'no-constant-binary-expression': 'error',
+ 'no-constructor-return': 'error',
+ 'no-div-regex': 'error',
+ 'no-duplicate-imports': ['error', { includeExports: false }],
+ 'no-else-return': ['error', { allowElseIf: false }],
+ 'no-empty-function': 'error',
+ 'no-empty-static-block': 'error',
+ 'no-eq-null': 'error',
+ 'no-eval': 'error',
+ 'no-extend-native': 'error',
+ 'no-extra-bind': 'error',
+ 'no-extra-label': 'error',
+ 'no-floating-decimal': 'error',
+ 'no-implicit-coercion': [
+ 'error',
+ {
+ boolean: false,
+ number: true,
+ string: true,
+ disallowTemplateShorthand: false,
+ },
+ ],
+ 'no-implicit-globals': 'error',
+ 'no-implied-eval': 'error',
+ 'no-invalid-this': ['error', { capIsConstructor: true }],
+ 'no-iterator': 'error',
+ 'no-label-var': 'error',
+ 'no-labels': ['error', { allowLoop: false, allowSwitch: false }],
+ 'no-lone-blocks': 'error',
+ 'no-lonely-if': 'error',
+ 'no-loop-func': 'error',
+ 'no-magic-numbers': [
+ 'error',
+ {
+ detectObjects: false,
+ enforceConst: false,
+ ignore: [-1, 0, 1, 2],
+ ignoreArrayIndexes: false,
+ ignoreClassFieldInitialValues: true,
+ ignoreDefaultValues: true,
+ },
+ ],
+ 'no-multi-assign': ['error', { ignoreNonDeclaration: false }],
+ 'no-multi-str': 'error',
+ 'no-negated-condition': 'error',
+ 'no-new': 'error',
+ 'no-new-func': 'error',
+ // cspell:disable-next-line
+ 'no-new-native-nonconstructor': 'error',
+ 'no-new-object': 'error',
+ 'no-new-wrappers': 'error',
+ 'no-octal-escape': 'error',
+ 'no-param-reassign': ['error', { props: false }],
+ 'no-promise-executor-return': 'error',
+ 'no-proto': 'error',
+ // cspell:disable-next-line
+ 'no-restricted-globals': ['error', 'event', 'fdescribe'],
+ 'no-restricted-syntax': ['error', 'WithStatement'],
+ 'no-return-assign': ['error', 'always'],
+ 'no-return-await': 'error',
+ 'no-script-url': 'error',
+ 'no-self-compare': 'error',
+ 'no-sequences': ['error', { allowInParentheses: true }],
+ 'no-shadow': [
+ 'error',
+ {
+ builtinGlobals: true,
+ hoist: 'functions',
+ allow: ['name'],
+ ignoreOnInitialization: false,
+ },
+ ],
+ 'no-template-curly-in-string': 'error',
+ 'no-throw-literal': 'error',
+ 'no-unmodified-loop-condition': 'error',
+ 'no-unneeded-ternary': ['error', { defaultAssignment: false }],
+ 'no-unreachable-loop': 'error',
+ 'no-unused-expressions': [
+ 'error',
+ {
+ allowShortCircuit: false,
+ allowTernary: false,
+ allowTaggedTemplates: false,
+ enforceForJSX: true,
+ },
+ ],
+ 'no-unused-vars': [
+ 'error',
+ {
+ argsIgnorePattern: '^_',
+ ignoreRestSiblings: true,
+ varsIgnorePattern: '^_',
+ },
+ ],
+ 'no-use-before-define': [
+ 'error',
+ {
+ functions: true,
+ classes: true,
+ variables: true,
+ allowNamedExports: false,
+ },
+ ],
+ 'no-useless-call': 'error',
+ 'no-useless-computed-key': ['error', { enforceForClassMembers: true }],
+ 'no-useless-concat': 'error',
+ 'no-useless-rename': [
+ 'error',
+ { ignoreImport: false, ignoreExport: false, ignoreDestructuring: false },
+ ],
+ 'no-useless-return': 'error',
+ 'no-var': 'error',
+ 'no-warning-comments': [
+ 'error',
+ { location: 'anywhere', terms: ['fixme'] },
+ ],
+ 'object-shorthand': ['error', 'properties'],
+ 'one-var': ['error', 'never'],
+ 'prefer-arrow-callback': [
+ 'error',
+ { allowNamedFunctions: false, allowUnboundThis: true },
+ ],
+ 'prefer-const': [
+ 'error',
+ { destructuring: 'any', ignoreReadBeforeAssign: false },
+ ],
+ 'prefer-destructuring': [
+ 'error',
+ {
+ array: false,
+ object: true,
+ },
+ {
+ enforceForRenamedProperties: false,
+ },
+ ],
+ 'prefer-named-capture-group': 'error',
+ 'prefer-object-has-own': 'error',
+ 'prefer-object-spread': 'error',
+ 'prefer-promise-reject-errors': ['error', { allowEmptyReject: false }],
+ 'prefer-regex-literals': ['error', { disallowRedundantWrapping: true }],
+ 'prefer-rest-params': 'error',
+ 'prefer-spread': 'error',
+ 'prefer-template': 'error',
+ 'quote-props': [
+ 'error',
+ 'as-needed',
+ { keywords: false, numbers: true, unnecessary: true },
+ ],
+ radix: ['error', 'always'],
+ 'require-atomic-updates': ['error', { allowProperties: false }],
+ 'require-await': 'error',
+ strict: ['error', 'safe'],
+ 'symbol-description': 'error',
+ 'vars-on-top': 'error',
+ yoda: ['error', 'never', { exceptRange: false, onlyEquality: false }],
+ // FORMATJS PLUGIN
'formatjs/enforce-default-message': ['error', 'literal'],
'formatjs/enforce-description': ['error', 'literal'],
'formatjs/enforce-id': [
@@ -14,5 +251,366 @@ module.exports = {
idInterpolationPattern: '[sha512:contenthash:base64:6]',
},
],
+ // IMPORT PLUGIN
+ 'import/first': 'error',
+ 'import/newline-after-import': [
+ 'error',
+ { considerComments: true, count: 1 },
+ ],
+ 'import/no-absolute-path': 'error',
+ 'import/no-amd': 'error',
+ 'import/no-deprecated': 'warn',
+ 'import/no-duplicates': [
+ 'error',
+ { considerQueryString: true, 'prefer-inline': true },
+ ],
+ 'import/no-empty-named-blocks': 'error',
+ 'import/no-import-module-exports': 'error',
+ 'import/no-mutable-exports': 'error',
+ 'import/no-named-default': 'error',
+ 'import/no-self-import': 'error',
+ 'import/no-useless-path-segments': [
+ 'error',
+ {
+ noUselessIndex: true,
+ },
+ ],
+ 'import/order': [
+ 'error',
+ { alphabetize: { order: 'asc', caseInsensitive: true } },
+ ],
+ // JSX A11Y PLUGIN
+ 'jsx-a11y/control-has-associated-label': 'warn',
+ 'jsx-a11y/no-aria-hidden-on-focusable': 'error',
+ 'jsx-a11y/prefer-tag-over-role': 'warn',
+ // REACT PLUGIN
+ 'react/boolean-prop-naming': [
+ 'warn',
+ {
+ propTypeNames: ['bool'],
+ rule: '^(is|has|hide|show)[A-Z]([A-Za-z0-9]?)+',
+ message:
+ 'It is better if your prop ({{ propName }}) matches this pattern: ({{ pattern }})',
+ validateNested: true,
+ },
+ ],
+ 'react/button-has-type': [
+ 'error',
+ {
+ button: true,
+ submit: true,
+ reset: true,
+ },
+ ],
+ 'react/default-props-match-prop-types': [
+ 'error',
+ { allowRequiredDefaults: false },
+ ],
+ 'react/destructuring-assignment': [
+ 'error',
+ 'always',
+ { ignoreClassFields: false, destructureInSignature: 'ignore' },
+ ],
+ 'react/forbid-prop-types': ['error', { allowInPropTypes: true }],
+ 'react/hook-use-state': ['error', { allowDestructuredState: false }],
+ 'react/iframe-missing-sandbox': 'warn',
+ 'react/jsx-child-element-spacing': 'warn',
+ 'react/jsx-closing-bracket-location': ['error', 'tag-aligned'],
+ 'react/jsx-closing-tag-location': 'error',
+ 'react/jsx-curly-brace-presence': [
+ 'warn',
+ { children: 'ignore', propElementValues: 'always', props: 'never' },
+ ],
+ 'react/jsx-equals-spacing': ['warn', 'never'],
+ 'react/jsx-filename-extension': [
+ 'error',
+ { allow: 'as-needed', extensions: ['.jsx'] },
+ ],
+ 'react/jsx-fragments': ['error', 'syntax'],
+ 'react/jsx-key': [
+ 'error',
+ {
+ checkFragmentShorthand: true,
+ checkKeyMustBeforeSpread: false,
+ warnOnDuplicates: true,
+ },
+ ],
+ 'react/jsx-no-bind': [
+ 'error',
+ {
+ ignoreDOMComponents: false,
+ ignoreRefs: false,
+ allowArrowFunctions: false,
+ allowFunctions: false,
+ allowBind: false,
+ },
+ ],
+ 'react/jsx-no-constructed-context-values': 'error',
+ 'react/jsx-no-leaked-render': [
+ 'error',
+ { validStrategies: ['ternary', 'coerce'] },
+ ],
+ 'react/jsx-no-literals': [
+ 'warn',
+ {
+ allowedStrings: ['button', 'reset', 'submit'],
+ ignoreProps: false,
+ noAttributeStrings: true,
+ noStrings: true,
+ },
+ ],
+ 'react/jsx-no-script-url': 'error',
+ 'react/jsx-no-useless-fragment': ['warn', { allowExpressions: true }],
+ 'react/jsx-pascal-case': [
+ 'error',
+ {
+ allowAllCaps: false,
+ allowLeadingUnderscore: false,
+ allowNamespace: false,
+ },
+ ],
+ // cspell:disable-next-line
+ 'react/no-access-state-in-setstate': 'error',
+ 'react/no-array-index-key': 'warn',
+ 'react/no-arrow-function-lifecycle': 'error',
+ 'react/no-danger': 'warn',
+ 'react/no-did-mount-set-state': 'error',
+ 'react/no-did-update-set-state': 'error',
+ 'react/no-invalid-html-attribute': 'error',
+ 'react/no-namespace': 'error',
+ 'react/no-object-type-as-default-prop': 'error',
+ 'react/no-redundant-should-component-update': 'error',
+ 'react/no-this-in-sfc': 'error',
+ 'react/no-typos': 'error',
+ 'react/no-unstable-nested-components': ['error', { allowAsProps: true }],
+ 'react/no-unused-class-component-methods': 'error',
+ 'react/no-unused-prop-types': ['error', { skipShapeProps: true }],
+ 'react/no-unused-state': 'error',
+ 'react/no-will-update-set-state': 'error',
+ 'react/self-closing-comp': [
+ 'error',
+ {
+ component: true,
+ html: true,
+ },
+ ],
+ 'react/style-prop-object': 'error',
+ 'react/void-dom-elements-no-children': 'error',
},
+ overrides: [
+ {
+ files: ['*.ts', '*.tsx', '.mts', '.cts'],
+ extends: [
+ 'plugin:@typescript-eslint/recommended',
+ 'plugin:@typescript-eslint/stylistic-type-checked',
+ 'plugin:import/typescript',
+ ],
+ plugins: ['@typescript-eslint'],
+ parserOptions: {
+ ecmaVersion: 'latest',
+ project: ['tsconfig.eslint.json', './tests/cypress/tsconfig.json'],
+ sourceType: 'module',
+ tsconfigRootDir: __dirname,
+ warnOnUnsupportedTypeScriptVersion: true,
+ },
+ settings: {
+ 'import/extensions': ['.js', '.jsx', '.ts', '.tsx'],
+ 'import/parsers': {
+ '@typescript-eslint/parser': ['.ts', '.tsx'],
+ },
+ 'import/resolver': {
+ node: true,
+ typescript: {
+ alwaysTryTypes: true,
+ },
+ },
+ },
+ rules: {
+ 'react/jsx-filename-extension': [
+ 'error',
+ { allow: 'as-needed', extensions: ['.tsx'] },
+ ],
+ '@typescript-eslint/consistent-type-definitions': ['error', 'type'],
+ '@typescript-eslint/consistent-type-exports': [
+ 'error',
+ { fixMixedExportsWithInlineTypeSpecifier: false },
+ ],
+ '@typescript-eslint/consistent-type-imports': [
+ 'error',
+ {
+ prefer: 'type-imports',
+ fixStyle: 'inline-type-imports',
+ disallowTypeAnnotations: true,
+ },
+ ],
+ '@typescript-eslint/method-signature-style': ['error', 'property'],
+ '@typescript-eslint/no-base-to-string': 'warn',
+ '@typescript-eslint/no-confusing-void-expression': [
+ 'error',
+ { ignoreArrowShorthand: true, ignoreVoidOperator: true },
+ ],
+ '@typescript-eslint/no-duplicate-enum-values': 'error',
+ '@typescript-eslint/no-dynamic-delete': 'error',
+ '@typescript-eslint/no-import-type-side-effects': 'error',
+ '@typescript-eslint/no-invalid-void-type': [
+ 'warn',
+ { allowInGenericTypeArguments: true, allowAsThisParameter: false },
+ ],
+ '@typescript-eslint/no-mixed-enums': 'error',
+ '@typescript-eslint/no-non-null-asserted-nullish-coalescing': 'error',
+ '@typescript-eslint/no-non-null-assertion': 'error',
+ '@typescript-eslint/no-redundant-type-constituents': 'error',
+ '@typescript-eslint/no-require-imports': 'error',
+ '@typescript-eslint/no-unnecessary-boolean-literal-compare': [
+ 'warn',
+ {
+ allowComparingNullableBooleansToTrue: true,
+ allowComparingNullableBooleansToFalse: true,
+ },
+ ],
+ '@typescript-eslint/no-unnecessary-condition': [
+ 'error',
+ {
+ allowConstantLoopConditions: false,
+ allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing: false,
+ },
+ ],
+ '@typescript-eslint/no-unnecessary-type-arguments': 'error',
+ '@typescript-eslint/no-unsafe-declaration-merging': 'error',
+ '@typescript-eslint/no-useless-empty-export': 'error',
+ '@typescript-eslint/prefer-enum-initializers': 'error',
+ '@typescript-eslint/prefer-function-type': 'error',
+ '@typescript-eslint/prefer-includes': 'error',
+ '@typescript-eslint/prefer-literal-enum-member': [
+ 'error',
+ { allowBitwiseExpressions: false },
+ ],
+ '@typescript-eslint/prefer-nullish-coalescing': [
+ 'error',
+ {
+ ignoreConditionalTests: true,
+ ignoreTernaryTests: true,
+ ignoreMixedLogicalExpressions: true,
+ allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing: false,
+ },
+ ],
+ '@typescript-eslint/prefer-optional-chain': 'error',
+ '@typescript-eslint/prefer-string-starts-ends-with': 'error',
+ '@typescript-eslint/prefer-ts-expect-error': 'error',
+ '@typescript-eslint/promise-function-async': [
+ 'error',
+ {
+ allowAny: true,
+ allowedPromiseNames: [],
+ checkArrowFunctions: true,
+ checkFunctionDeclarations: true,
+ checkFunctionExpressions: true,
+ checkMethodDeclarations: true,
+ },
+ ],
+ '@typescript-eslint/require-array-sort-compare': [
+ 'warn',
+ { ignoreStringArrays: false },
+ ],
+ '@typescript-eslint/switch-exhaustiveness-check': 'error',
+ '@typescript-eslint/unified-signatures': [
+ 'warn',
+ { ignoreDifferentlyNamedParameters: false },
+ ],
+ /**
+ * Typescript extension rules -- Core rules need to be disabled.
+ */
+ 'default-param-last': 'off',
+ '@typescript-eslint/default-param-last': 'error',
+ 'dot-notation': 'off',
+ '@typescript-eslint/dot-notation': ['error', { allowKeywords: true }],
+ 'init-declarations': 'off',
+ '@typescript-eslint/init-declarations': ['error', 'always'],
+ 'no-array-constructor': 'off',
+ '@typescript-eslint/no-array-constructor': 'error',
+ 'no-empty-function': 'off',
+ '@typescript-eslint/no-empty-function': 'error',
+ 'no-implied-eval': 'off',
+ '@typescript-eslint/no-implied-eval': 'error',
+ 'no-invalid-this': 'off',
+ '@typescript-eslint/no-invalid-this': [
+ 'error',
+ { capIsConstructor: true },
+ ],
+ 'no-loop-func': 'off',
+ '@typescript-eslint/no-loop-func': 'error',
+ 'no-magic-numbers': 'off',
+ '@typescript-eslint/no-magic-numbers': [
+ 'error',
+ {
+ detectObjects: false,
+ enforceConst: false,
+ ignore: [-1, 0, 1, 2],
+ ignoreArrayIndexes: false,
+ ignoreClassFieldInitialValues: true,
+ ignoreDefaultValues: true,
+ },
+ ],
+ 'no-shadow': 'off',
+ '@typescript-eslint/no-shadow': [
+ 'error',
+ {
+ builtinGlobals: true,
+ hoist: 'functions',
+ allow: ['name'],
+ ignoreOnInitialization: false,
+ },
+ ],
+ 'no-throw-literal': 'off',
+ '@typescript-eslint/no-throw-literal': 'error',
+ 'no-unused-expressions': 'off',
+ '@typescript-eslint/no-unused-expressions': [
+ 'error',
+ {
+ allowShortCircuit: false,
+ allowTernary: false,
+ allowTaggedTemplates: false,
+ enforceForJSX: true,
+ },
+ ],
+ 'no-unused-vars': 'off',
+ '@typescript-eslint/no-unused-vars': [
+ 'error',
+ {
+ argsIgnorePattern: '^_',
+ ignoreRestSiblings: true,
+ varsIgnorePattern: '^_',
+ },
+ ],
+ 'no-use-before-define': 'off',
+ '@typescript-eslint/no-use-before-define': [
+ 'error',
+ {
+ functions: true,
+ classes: true,
+ variables: true,
+ allowNamedExports: false,
+ },
+ ],
+ 'require-await': 'off',
+ '@typescript-eslint/require-await': 'error',
+ },
+ },
+ {
+ files: ['*.stories.@(ts|tsx|js|jsx|mjs|cjs)'],
+ extends: ['plugin:storybook/recommended'],
+ rules: {
+ 'react/jsx-no-literals': 'off',
+ 'storybook/csf-component': 'warn',
+ 'storybook/no-stories-of': 'warn',
+ 'storybook/no-title-property-in-meta': 'off',
+ },
+ },
+ {
+ files: ['*.test.@(ts|tsx|js|jsx|mjs|cjs)'],
+ rules: {
+ 'react/jsx-no-literals': 'off',
+ },
+ },
+ ],
};
diff --git a/mdx.d.ts b/mdx.d.ts
index b4e333d..4fd2076 100644
--- a/mdx.d.ts
+++ b/mdx.d.ts
@@ -1,8 +1,11 @@
+/* eslint-disable @typescript-eslint/consistent-type-imports */
declare module '*.mdx' {
- import { MDXData, MDXPageMeta, MDXProjectMeta } from '@ts/types/mdx';
- import { MDXProps } from 'mdx/types';
+ type MDXProps = import('mdx/types').MDXProps;
+ type MDXData = import('./src/types/mdx').MDXData;
+ type MDXPageMeta = import('./src/types/mdx').MDXPageMeta;
+ type MDXProjectMeta = import('./src/types/mdx').MDXProjectMeta;
- let MDXComponent: (props: MDXProps) => JSX.Element;
+ const MDXComponent: (props: MDXProps) => JSX.Element;
export default MDXComponent;
export const data: MDXData;
export const meta: MDXPageMeta | MDXProjectMeta;
diff --git a/next.config.js b/next.config.js
index 04802f1..d590934 100644
--- a/next.config.js
+++ b/next.config.js
@@ -71,9 +71,9 @@ const securityHeaders = [
{
key: 'Content-Security-Policy',
value:
- process.env.NODE_ENV !== 'development'
- ? contentSecurityPolicy.replace(/\s{2,}/g, ' ').trim()
- : contentSecurityPolicyDev.replace(/\s{2,}/g, ' ').trim(),
+ process.env.NODE_ENV === 'development'
+ ? contentSecurityPolicyDev.replace(/\s{2,}/g, ' ').trim()
+ : contentSecurityPolicy.replace(/\s{2,}/g, ' ').trim(),
},
];
@@ -82,7 +82,7 @@ const nextConfig = {
experimental: {
scrollRestoration: true,
},
- async headers() {
+ headers() {
return [
{
// Apply these headers to all routes in your application.
@@ -101,7 +101,7 @@ const nextConfig = {
output: 'standalone',
poweredByHeader: false,
reactStrictMode: true,
- async rewrites() {
+ rewrites() {
return [
{
source: '/feed',
diff --git a/package.json b/package.json
index a0c8aff..2def275 100644
--- a/package.json
+++ b/package.json
@@ -88,6 +88,8 @@
"@types/prismjs": "^1.26.0",
"@types/react": "^18.2.22",
"@types/use-ackee": "^2.0.1",
+ "@typescript-eslint/eslint-plugin": "^6.7.2",
+ "@typescript-eslint/parser": "^6.7.2",
"commit-and-tag-version": "^11.2.3",
"cspell": "^7.3.6",
"cypress": "^13.2.0",
@@ -95,7 +97,11 @@
"eslint-config-next": "^13.4.19",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-formatjs": "^4.10.5",
- "eslint-plugin-storybook": "^0.6.13",
+ "eslint-plugin-import": "^2.28.1",
+ "eslint-plugin-jsx-a11y": "^6.7.1",
+ "eslint-plugin-react": "^7.33.2",
+ "eslint-plugin-react-hooks": "^4.6.0",
+ "eslint-plugin-storybook": "^0.6.14",
"eslint-plugin-testing-library": "^6.0.1",
"husky": "^8.0.3",
"jest": "^29.7.0",
diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json
new file mode 100644
index 0000000..0ada21c
--- /dev/null
+++ b/tsconfig.eslint.json
@@ -0,0 +1,18 @@
+{
+ "extends": "./tsconfig.json",
+ "exclude": ["**/node_modules/**", "**/dist/**"],
+ "include": [
+ "./.storybook/**/*",
+ "./src/**/*",
+ "./tests/**/*",
+ "./commitlint.config.js",
+ "./cypress.config.js",
+ "./jest.config.js",
+ "./jest.setup.js",
+ "./lint-staged.config.js",
+ "./mdx.d.ts",
+ "./next-sitemap.config.js",
+ "./next-env.d.ts",
+ "./next.config.js"
+ ]
+}
diff --git a/tsconfig.json b/tsconfig.json
index c348299..231b990 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -17,12 +17,6 @@
"types": ["jest", "@testing-library/jest-dom/jest-globals"],
"baseUrl": "."
},
- "include": [
- "next-env.d.ts",
- "**/*.ts",
- "**/*.tsx",
- ".storybook/preview.tsx",
- "src/utils/plugins/prism-color-scheme.js"
- ],
- "exclude": ["node_modules", "tests/cypress/", "cypress.config.js"]
+ "include": ["next-env.d.ts", "mdx.d.ts", "./src/**/*"],
+ "exclude": ["node_modules"]
}
diff --git a/yarn.lock b/yarn.lock
index 975a6e6..8c172c4 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1877,14 +1877,14 @@
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz#786c5f41f043b07afb1af37683d7c33668858f6d"
integrity sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==
-"@eslint-community/eslint-utils@^4.2.0":
+"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59"
integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==
dependencies:
eslint-visitor-keys "^3.3.0"
-"@eslint-community/regexpp@^4.6.1":
+"@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1":
version "4.8.1"
resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.8.1.tgz#8c4bb756cc2aa7eaf13cfa5e69c83afb3260c20c"
integrity sha512-PWiOzLIUAjN/w5K17PoF4n6sKBw0gqLHPhywmYHP4t1VFQQVYeb1yWsJwnMVEMl3tUHME7X/SJPZLmtG7XBDxQ==
@@ -4274,7 +4274,7 @@
"@types/tough-cookie" "*"
parse5 "^7.0.0"
-"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9":
+"@types/json-schema@*", "@types/json-schema@^7.0.12", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9":
version "7.0.13"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.13.tgz#02c24f4363176d2d18fc8b70b9f3c54aba178a85"
integrity sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==
@@ -4425,7 +4425,7 @@
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.3.tgz#cef09e3ec9af1d63d2a6cc5b383a737e24e6dcf5"
integrity sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==
-"@types/semver@^7.3.12", "@types/semver@^7.3.4":
+"@types/semver@^7.3.12", "@types/semver@^7.3.4", "@types/semver@^7.5.0":
version "7.5.2"
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.2.tgz#31f6eec1ed7ec23f4f05608d3a2d381df041f564"
integrity sha512-7aqorHYgdNO4DM36stTiGO3DvKoex9TQRwsJU6vMaFGyqpBA1MNZkz+PG3gaNUPpTAOYhT1WR7M1JyA3fbS9Cw==
@@ -4505,7 +4505,24 @@
dependencies:
"@types/node" "*"
-"@typescript-eslint/parser@^5.4.2 || ^6.0.0":
+"@typescript-eslint/eslint-plugin@^6.7.2":
+ version "6.7.2"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.2.tgz#f18cc75c9cceac8080a9dc2e7d166008c5207b9f"
+ integrity sha512-ooaHxlmSgZTM6CHYAFRlifqh1OAr3PAQEwi7lhYhaegbnXrnh7CDcHmc3+ihhbQC7H0i4JF0psI5ehzkF6Yl6Q==
+ dependencies:
+ "@eslint-community/regexpp" "^4.5.1"
+ "@typescript-eslint/scope-manager" "6.7.2"
+ "@typescript-eslint/type-utils" "6.7.2"
+ "@typescript-eslint/utils" "6.7.2"
+ "@typescript-eslint/visitor-keys" "6.7.2"
+ debug "^4.3.4"
+ graphemer "^1.4.0"
+ ignore "^5.2.4"
+ natural-compare "^1.4.0"
+ semver "^7.5.4"
+ ts-api-utils "^1.0.1"
+
+"@typescript-eslint/parser@^5.4.2 || ^6.0.0", "@typescript-eslint/parser@^6.7.2":
version "6.7.2"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.7.2.tgz#e0ae93771441b9518e67d0660c79e3a105497af4"
integrity sha512-KA3E4ox0ws+SPyxQf9iSI25R6b4Ne78ORhNHeVKrPQnoYsb9UhieoiRoJgrzgEeKGOXhcY1i8YtOeCHHTDa6Fw==
@@ -4532,6 +4549,16 @@
"@typescript-eslint/types" "6.7.2"
"@typescript-eslint/visitor-keys" "6.7.2"
+"@typescript-eslint/type-utils@6.7.2":
+ version "6.7.2"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.7.2.tgz#ed921c9db87d72fa2939fee242d700561454f367"
+ integrity sha512-36F4fOYIROYRl0qj95dYKx6kybddLtsbmPIYNK0OBeXv2j9L5nZ17j9jmfy+bIDHKQgn2EZX+cofsqi8NPATBQ==
+ dependencies:
+ "@typescript-eslint/typescript-estree" "6.7.2"
+ "@typescript-eslint/utils" "6.7.2"
+ debug "^4.3.4"
+ ts-api-utils "^1.0.1"
+
"@typescript-eslint/types@5.62.0":
version "5.62.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f"
@@ -4568,6 +4595,19 @@
semver "^7.5.4"
ts-api-utils "^1.0.1"
+"@typescript-eslint/utils@6.7.2":
+ version "6.7.2"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.7.2.tgz#b9ef0da6f04932167a9222cb4ac59cb187165ebf"
+ integrity sha512-ZCcBJug/TS6fXRTsoTkgnsvyWSiXwMNiPzBUani7hDidBdj1779qwM1FIAmpH4lvlOZNF3EScsxxuGifjpLSWQ==
+ dependencies:
+ "@eslint-community/eslint-utils" "^4.4.0"
+ "@types/json-schema" "^7.0.12"
+ "@types/semver" "^7.5.0"
+ "@typescript-eslint/scope-manager" "6.7.2"
+ "@typescript-eslint/types" "6.7.2"
+ "@typescript-eslint/typescript-estree" "6.7.2"
+ semver "^7.5.4"
+
"@typescript-eslint/utils@^5.45.0", "@typescript-eslint/utils@^5.58.0":
version "5.62.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.62.0.tgz#141e809c71636e4a75daa39faed2fb5f4b10df86"
@@ -7619,7 +7659,7 @@ eslint-plugin-formatjs@^4.10.5:
typescript "^4.7 || 5"
unicode-emoji-utils "^1.1.1"
-eslint-plugin-import@^2.26.0:
+eslint-plugin-import@^2.26.0, eslint-plugin-import@^2.28.1:
version "2.28.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz#63b8b5b3c409bfc75ebaf8fb206b07ab435482c4"
integrity sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==
@@ -7642,7 +7682,7 @@ eslint-plugin-import@^2.26.0:
semver "^6.3.1"
tsconfig-paths "^3.14.2"
-eslint-plugin-jsx-a11y@^6.5.1:
+eslint-plugin-jsx-a11y@^6.5.1, eslint-plugin-jsx-a11y@^6.7.1:
version "6.7.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz#fca5e02d115f48c9a597a6894d5bcec2f7a76976"
integrity sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA==
@@ -7664,12 +7704,12 @@ eslint-plugin-jsx-a11y@^6.5.1:
object.fromentries "^2.0.6"
semver "^6.3.0"
-"eslint-plugin-react-hooks@^4.5.0 || 5.0.0-canary-7118f5dd7-20230705":
+"eslint-plugin-react-hooks@^4.5.0 || 5.0.0-canary-7118f5dd7-20230705", eslint-plugin-react-hooks@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3"
integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==
-eslint-plugin-react@^7.31.7:
+eslint-plugin-react@^7.31.7, eslint-plugin-react@^7.33.2:
version "7.33.2"
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz#69ee09443ffc583927eafe86ffebb470ee737608"
integrity sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==
@@ -7691,10 +7731,10 @@ eslint-plugin-react@^7.31.7:
semver "^6.3.1"
string.prototype.matchall "^4.0.8"
-eslint-plugin-storybook@^0.6.13:
- version "0.6.13"
- resolved "https://registry.yarnpkg.com/eslint-plugin-storybook/-/eslint-plugin-storybook-0.6.13.tgz#897a9f6a9bb88c63b02f05850f30c28a9848a3f7"
- integrity sha512-smd+CS0WH1jBqUEJ3znGS7DU4ayBE9z6lkQAK2yrSUv1+rq8BT/tiI5C/rKE7rmiqiAfojtNYZRhzo5HrulccQ==
+eslint-plugin-storybook@^0.6.14:
+ version "0.6.14"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-storybook/-/eslint-plugin-storybook-0.6.14.tgz#dfc2b58700e45eb4a13c172dda2973c2e033cd71"
+ integrity sha512-IeYigPur/MvESNDo43Z+Z5UvlcEVnt0dDZmnw1odi9X2Th1R3bpGyOZsHXb9bp1pFecOpRUuoMG5xdID2TwwOg==
dependencies:
"@storybook/csf" "^0.0.1"
"@typescript-eslint/utils" "^5.45.0"