@mui/internal-code-infra 0.0.3-canary.6 → 0.0.3-canary.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -0
- package/build/babel-config.d.mts +40 -0
- package/build/brokenLinksChecker/index.d.mts +138 -0
- package/build/cli/cmdArgosPush.d.mts +13 -0
- package/build/cli/cmdBuild.d.mts +56 -0
- package/build/cli/cmdCopyFiles.d.mts +20 -0
- package/build/cli/cmdExtractErrorCodes.d.mts +3 -0
- package/build/cli/cmdGithubAuth.d.mts +6 -0
- package/build/cli/cmdListWorkspaces.d.mts +18 -0
- package/build/cli/cmdPublish.d.mts +27 -0
- package/build/cli/cmdPublishCanary.d.mts +30 -0
- package/build/cli/cmdPublishNewPackage.d.mts +8 -0
- package/build/cli/cmdSetVersionOverrides.d.mts +9 -0
- package/build/cli/cmdValidateBuiltTypes.d.mts +2 -0
- package/build/cli/index.d.mts +1 -0
- package/build/eslint/baseConfig.d.mts +10 -0
- package/build/eslint/docsConfig.d.mts +4 -0
- package/build/eslint/extensions.d.mts +8 -0
- package/build/eslint/index.d.mts +4 -0
- package/build/eslint/jsonConfig.d.mts +4 -0
- package/build/eslint/material-ui/config.d.mts +8 -0
- package/build/eslint/material-ui/index.d.mts +2 -0
- package/build/eslint/material-ui/rules/disallow-active-element-as-key-event-target.d.mts +5 -0
- package/build/eslint/material-ui/rules/disallow-react-api-in-server-components.d.mts +2 -0
- package/build/eslint/material-ui/rules/docgen-ignore-before-comment.d.mts +2 -0
- package/build/eslint/material-ui/rules/mui-name-matches-component-name.d.mts +5 -0
- package/build/eslint/material-ui/rules/no-empty-box.d.mts +5 -0
- package/build/eslint/material-ui/rules/no-restricted-resolved-imports.d.mts +12 -0
- package/build/eslint/material-ui/rules/no-styled-box.d.mts +5 -0
- package/build/eslint/material-ui/rules/rules-of-use-theme-variants.d.mts +9 -0
- package/build/eslint/material-ui/rules/straight-quotes.d.mts +5 -0
- package/build/eslint/testConfig.d.mts +14 -0
- package/build/markdownlint/duplicate-h1.d.mts +27 -0
- package/build/markdownlint/git-diff.d.mts +8 -0
- package/build/markdownlint/index.d.mts +56 -0
- package/build/markdownlint/straight-quotes.d.mts +8 -0
- package/build/markdownlint/table-alignment.d.mts +8 -0
- package/build/markdownlint/terminal-language.d.mts +8 -0
- package/build/prettier.d.mts +20 -0
- package/build/stylelint/index.d.mts +32 -0
- package/build/utils/babel.d.mts +71 -0
- package/build/utils/build.d.mts +50 -0
- package/build/utils/changelog.d.mts +64 -0
- package/build/utils/credentials.d.mts +17 -0
- package/build/utils/extractErrorCodes.d.mts +19 -0
- package/build/utils/git.d.mts +26 -0
- package/build/utils/github.d.mts +41 -0
- package/build/utils/pnpm.d.mts +238 -0
- package/build/utils/typescript.d.mts +35 -0
- package/package.json +92 -42
- package/src/babel-config.mjs +52 -8
- package/src/brokenLinksChecker/__fixtures__/static-site/broken-links.html +20 -0
- package/src/brokenLinksChecker/__fixtures__/static-site/broken-targets.html +22 -0
- package/src/brokenLinksChecker/__fixtures__/static-site/example.md +9 -0
- package/src/brokenLinksChecker/__fixtures__/static-site/external-links.html +21 -0
- package/src/brokenLinksChecker/__fixtures__/static-site/ignored-page.html +17 -0
- package/src/brokenLinksChecker/__fixtures__/static-site/index.html +26 -0
- package/src/brokenLinksChecker/__fixtures__/static-site/known-targets.json +5 -0
- package/src/brokenLinksChecker/__fixtures__/static-site/nested/page.html +19 -0
- package/src/brokenLinksChecker/__fixtures__/static-site/orphaned-page.html +20 -0
- package/src/brokenLinksChecker/__fixtures__/static-site/page-with-api-links.html +20 -0
- package/src/brokenLinksChecker/__fixtures__/static-site/page-with-custom-targets.html +24 -0
- package/src/brokenLinksChecker/__fixtures__/static-site/page-with-ignored-content.html +28 -0
- package/src/brokenLinksChecker/__fixtures__/static-site/page-with-known-target-links.html +19 -0
- package/src/brokenLinksChecker/__fixtures__/static-site/valid.html +20 -0
- package/src/brokenLinksChecker/__fixtures__/static-site/with-anchors.html +31 -0
- package/src/brokenLinksChecker/index.mjs +641 -0
- package/src/brokenLinksChecker/index.test.ts +178 -0
- package/src/cli/cmdArgosPush.mjs +13 -2
- package/src/cli/cmdBuild.mjs +228 -31
- package/src/cli/cmdGithubAuth.mjs +36 -0
- package/src/cli/cmdListWorkspaces.mjs +2 -2
- package/src/cli/cmdPublish.mjs +203 -49
- package/src/cli/cmdPublishCanary.mjs +404 -46
- package/src/cli/cmdPublishNewPackage.mjs +86 -0
- package/src/cli/cmdSetVersionOverrides.mjs +17 -1
- package/src/cli/cmdValidateBuiltTypes.mjs +49 -0
- package/src/cli/index.mjs +6 -2
- package/src/cli/packageJson.d.ts +729 -0
- package/src/eslint/baseConfig.mjs +96 -78
- package/src/eslint/docsConfig.mjs +13 -13
- package/src/eslint/extensions.mjs +8 -8
- package/src/eslint/jsonConfig.mjs +40 -0
- package/src/eslint/material-ui/config.mjs +8 -9
- package/src/eslint/material-ui/rules/mui-name-matches-component-name.mjs +4 -2
- package/src/eslint/material-ui/rules/rules-of-use-theme-variants.mjs +2 -1
- package/src/eslint/testConfig.mjs +72 -66
- package/src/stylelint/index.mjs +46 -0
- package/src/untyped-plugins.d.ts +13 -0
- package/src/{cli → utils}/babel.mjs +10 -3
- package/src/utils/build.mjs +27 -1
- package/src/utils/changelog.mjs +157 -0
- package/src/utils/credentials.mjs +71 -0
- package/src/utils/extractErrorCodes.mjs +2 -2
- package/src/utils/git.mjs +67 -0
- package/src/utils/github.mjs +263 -0
- package/src/{cli → utils}/pnpm.mjs +23 -13
- package/src/{cli → utils}/typescript.mjs +13 -7
- package/src/cli/cmdJsonLint.mjs +0 -69
|
@@ -1,102 +1,120 @@
|
|
|
1
1
|
import { includeIgnoreFile } from '@eslint/compat';
|
|
2
2
|
import eslintJs from '@eslint/js';
|
|
3
|
+
import { defineConfig } from 'eslint/config';
|
|
3
4
|
import prettier from 'eslint-config-prettier/flat';
|
|
5
|
+
import compatPlugin from 'eslint-plugin-compat';
|
|
4
6
|
import importPlugin from 'eslint-plugin-import';
|
|
5
7
|
import jsxA11yPlugin from 'eslint-plugin-jsx-a11y';
|
|
6
8
|
import reactPlugin from 'eslint-plugin-react';
|
|
7
9
|
import { configs as reactCompilerPluginConfigs } from 'eslint-plugin-react-compiler';
|
|
8
|
-
import
|
|
10
|
+
import reactHooks from 'eslint-plugin-react-hooks';
|
|
9
11
|
import globals from 'globals';
|
|
10
|
-
import * as fs from 'node:fs';
|
|
11
12
|
import * as path from 'node:path';
|
|
12
13
|
import * as tseslint from 'typescript-eslint';
|
|
13
|
-
|
|
14
|
+
import fs from 'node:fs';
|
|
14
15
|
import { createCoreConfig } from './material-ui/config.mjs';
|
|
15
16
|
import muiPlugin from './material-ui/index.mjs';
|
|
17
|
+
import { EXTENSION_TS } from './extensions.mjs';
|
|
18
|
+
import { createJsonConfig } from './jsonConfig.mjs';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @param {string} filePath
|
|
22
|
+
* @param {string | undefined} description
|
|
23
|
+
*/
|
|
24
|
+
function includeIgnoreIfExists(filePath, description) {
|
|
25
|
+
if (fs.existsSync(filePath)) {
|
|
26
|
+
return includeIgnoreFile(filePath, description);
|
|
27
|
+
}
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
|
|
16
31
|
/**
|
|
17
32
|
* @param {Object} [params]
|
|
18
33
|
* @param {boolean} [params.enableReactCompiler] - Whether the config is for spec files.
|
|
19
|
-
* @param {string} params.baseDirectory - The base directory for the configuration.
|
|
34
|
+
* @param {string} [params.baseDirectory] - The base directory for the configuration.
|
|
20
35
|
* @returns {import('eslint').Linter.Config[]}
|
|
21
36
|
*/
|
|
22
|
-
export function createBaseConfig(
|
|
23
|
-
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
ecmaVersion: 7,
|
|
55
|
-
globals: {
|
|
56
|
-
...globals.es2020,
|
|
57
|
-
...globals.browser,
|
|
58
|
-
...globals.node,
|
|
37
|
+
export function createBaseConfig({
|
|
38
|
+
enableReactCompiler = false,
|
|
39
|
+
baseDirectory = process.cwd(),
|
|
40
|
+
} = {}) {
|
|
41
|
+
return defineConfig([
|
|
42
|
+
includeIgnoreIfExists(path.join(baseDirectory, '.gitignore'), `Ignore rules from .gitignore`),
|
|
43
|
+
includeIgnoreIfExists(path.join(baseDirectory, '.lintignore'), `Ignore rules from .lintignore`),
|
|
44
|
+
createJsonConfig(),
|
|
45
|
+
prettier,
|
|
46
|
+
{
|
|
47
|
+
name: 'Base config',
|
|
48
|
+
files: [`**/*${EXTENSION_TS}`],
|
|
49
|
+
extends: defineConfig([
|
|
50
|
+
eslintJs.configs.recommended,
|
|
51
|
+
importPlugin.flatConfigs.recommended,
|
|
52
|
+
importPlugin.flatConfigs.react,
|
|
53
|
+
jsxA11yPlugin.flatConfigs.recommended,
|
|
54
|
+
reactPlugin.configs.flat.recommended,
|
|
55
|
+
reactHooks.configs.flat.recommended,
|
|
56
|
+
tseslint.configs.recommended,
|
|
57
|
+
importPlugin.flatConfigs.typescript,
|
|
58
|
+
enableReactCompiler ? reactCompilerPluginConfigs.recommended : {},
|
|
59
|
+
compatPlugin.configs['flat/recommended'],
|
|
60
|
+
{
|
|
61
|
+
name: 'typescript-eslint-parser',
|
|
62
|
+
languageOptions: {
|
|
63
|
+
ecmaVersion: 7,
|
|
64
|
+
globals: {
|
|
65
|
+
...globals.es2020,
|
|
66
|
+
...globals.browser,
|
|
67
|
+
...globals.node,
|
|
68
|
+
},
|
|
59
69
|
},
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
rules: {
|
|
69
|
-
'import/extensions': [
|
|
70
|
-
'error',
|
|
71
|
-
'ignorePackages',
|
|
72
|
-
{
|
|
73
|
-
js: 'always',
|
|
74
|
-
mjs: 'always',
|
|
70
|
+
plugins: {
|
|
71
|
+
'material-ui': muiPlugin,
|
|
72
|
+
},
|
|
73
|
+
settings: {
|
|
74
|
+
browserslistOpts: {
|
|
75
|
+
config: path.join(baseDirectory, '.browserslistrc'),
|
|
76
|
+
env: 'stable',
|
|
77
|
+
ignoreUnknownVersions: true,
|
|
75
78
|
},
|
|
76
|
-
|
|
79
|
+
},
|
|
80
|
+
extends: createCoreConfig({ enableReactCompiler }),
|
|
77
81
|
},
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
82
|
+
// Lint rule to disallow usage of typescript namespaces.We've seen at least two problems with them:
|
|
83
|
+
// * Creates non-portable types in base ui. [1]
|
|
84
|
+
// * This pattern [2] leads to broken bundling in codesandbox [3].
|
|
85
|
+
// Gauging the ecosystem it also looks like support for namespaces in tooling is poor and tends to
|
|
86
|
+
// be treated as a deprecated feature.
|
|
87
|
+
// [1] https://github.com/mui/base-ui/pull/2324
|
|
88
|
+
// [2] https://github.com/mui/mui-x/blob/1cf853ed45cf301211ece1c0ca21981ea208edfb/packages/x-virtualizer/src/models/core.ts#L4-L10
|
|
89
|
+
// [3] https://codesandbox.io/embed/kgylpd?module=/src/Demo.tsx&fontsize=12
|
|
90
|
+
{
|
|
91
|
+
rules: {
|
|
92
|
+
'@typescript-eslint/no-namespace': 'error',
|
|
93
|
+
},
|
|
90
94
|
},
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
// Part of the migration away from airbnb config. Turned off initially.
|
|
96
|
+
{
|
|
97
|
+
rules: {
|
|
98
|
+
'@typescript-eslint/no-explicit-any': 'off',
|
|
99
|
+
'@typescript-eslint/no-unsafe-function-type': 'off',
|
|
100
|
+
'@typescript-eslint/no-empty-object-type': 'off',
|
|
101
|
+
},
|
|
98
102
|
},
|
|
103
|
+
]),
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
name: 'ESM JS files',
|
|
107
|
+
files: ['**/*.mjs'],
|
|
108
|
+
rules: {
|
|
109
|
+
'import/extensions': [
|
|
110
|
+
'error',
|
|
111
|
+
'ignorePackages',
|
|
112
|
+
{
|
|
113
|
+
js: 'always',
|
|
114
|
+
mjs: 'always',
|
|
115
|
+
},
|
|
116
|
+
],
|
|
99
117
|
},
|
|
100
|
-
|
|
101
|
-
);
|
|
118
|
+
},
|
|
119
|
+
]);
|
|
102
120
|
}
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import nextjs from '@next/eslint-plugin-next';
|
|
2
|
-
import
|
|
2
|
+
import { defineConfig } from 'eslint/config';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @returns {import('eslint').Linter.Config[]}
|
|
6
6
|
*/
|
|
7
7
|
export function createDocsConfig() {
|
|
8
|
-
return
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
rootDir: 'docs',
|
|
13
|
-
},
|
|
8
|
+
return defineConfig(nextjs.flatConfig.recommended, {
|
|
9
|
+
settings: {
|
|
10
|
+
next: {
|
|
11
|
+
rootDir: 'docs',
|
|
14
12
|
},
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
13
|
+
},
|
|
14
|
+
files: ['**/*.js', '**/*.mjs', '**/*.jsx', '**/*.ts', '**/*.tsx'],
|
|
15
|
+
rules: {
|
|
16
|
+
'compat/compat': 'off',
|
|
17
|
+
'jsx-a11y/anchor-is-valid': 'off',
|
|
18
|
+
'no-irregular-whitespace': ['error', { skipJSXText: true, skipStrings: true }],
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
21
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export const EXTENSION_JS = '
|
|
2
|
-
export const EXTENSION_JS_NO_MODULE = 'js?(x)';
|
|
3
|
-
export const EXTENSION_TS = '
|
|
4
|
-
export const EXTENSION_TS_NO_MODULE = '[jt]s?(x)';
|
|
5
|
-
export const EXTENSION_TS_ONLY = '
|
|
6
|
-
export const EXTENSION_TS_ONLY_NO_MODULE = 'ts?(x)';
|
|
7
|
-
export const EXTENSION_DTS = `.d
|
|
8
|
-
export const EXTENSION_TEST_FILE = `.test
|
|
1
|
+
export const EXTENSION_JS = '.?(c|m)js?(x)';
|
|
2
|
+
export const EXTENSION_JS_NO_MODULE = '.js?(x)';
|
|
3
|
+
export const EXTENSION_TS = '.?(c|m)[jt]s?(x)';
|
|
4
|
+
export const EXTENSION_TS_NO_MODULE = '.[jt]s?(x)';
|
|
5
|
+
export const EXTENSION_TS_ONLY = '.?(c|m)ts?(x)';
|
|
6
|
+
export const EXTENSION_TS_ONLY_NO_MODULE = '.ts?(x)';
|
|
7
|
+
export const EXTENSION_DTS = `.d${EXTENSION_TS_ONLY}`;
|
|
8
|
+
export const EXTENSION_TEST_FILE = `.test${EXTENSION_TS}`;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { defineConfig } from 'eslint/config';
|
|
2
|
+
import json from '@eslint/json';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @returns {import('eslint').Linter.Config[]}
|
|
6
|
+
*/
|
|
7
|
+
export function createJsonConfig() {
|
|
8
|
+
return defineConfig([
|
|
9
|
+
{
|
|
10
|
+
name: 'JSON files',
|
|
11
|
+
files: ['**/*.json'],
|
|
12
|
+
ignores: ['package-lock.json'],
|
|
13
|
+
plugins: { json },
|
|
14
|
+
language: 'json/json',
|
|
15
|
+
extends: [json.configs.recommended],
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
{
|
|
19
|
+
name: 'JSONC files',
|
|
20
|
+
files: [
|
|
21
|
+
'**/*.jsonc',
|
|
22
|
+
'**/tsconfig.json',
|
|
23
|
+
'**/tsconfig.*.json',
|
|
24
|
+
'.vscode/**/*.json',
|
|
25
|
+
'renovate.json',
|
|
26
|
+
],
|
|
27
|
+
plugins: { json },
|
|
28
|
+
language: 'json/jsonc',
|
|
29
|
+
extends: [json.configs.recommended],
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
{
|
|
33
|
+
name: 'JSON5 files',
|
|
34
|
+
files: ['**/*.json5'],
|
|
35
|
+
plugins: { json },
|
|
36
|
+
language: 'json/json5',
|
|
37
|
+
extends: [json.configs.recommended],
|
|
38
|
+
},
|
|
39
|
+
]);
|
|
40
|
+
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { defineConfig } from 'eslint/config';
|
|
2
|
+
|
|
1
3
|
const restrictedMethods = ['setTimeout', 'setInterval', 'clearTimeout', 'clearInterval'];
|
|
2
4
|
|
|
3
5
|
const restrictedSyntaxRules = restrictedMethods.map((method) => ({
|
|
@@ -42,9 +44,6 @@ const criticalAirbnbRules = {
|
|
|
42
44
|
'no-restricted-globals': ['error', 'isFinite', 'isNaN'],
|
|
43
45
|
|
|
44
46
|
// Styles
|
|
45
|
-
// require or disallow an empty line between class members
|
|
46
|
-
// https://eslint.org/docs/rules/lines-between-class-members
|
|
47
|
-
'lines-between-class-members': ['error', 'always', { exceptAfterSingleLine: false }],
|
|
48
47
|
// require a capital letter for constructors
|
|
49
48
|
'new-cap': [
|
|
50
49
|
'error',
|
|
@@ -302,11 +301,11 @@ const airbnbJsxA11y = {
|
|
|
302
301
|
|
|
303
302
|
/**
|
|
304
303
|
* @param {Object} [options]
|
|
305
|
-
* @param {boolean} [options.
|
|
306
|
-
* @returns {import('
|
|
304
|
+
* @param {boolean} [options.enableReactCompiler] - Whether the config is for spec files.
|
|
305
|
+
* @returns {import('eslint').Linter.Config[]}
|
|
307
306
|
*/
|
|
308
307
|
export function createCoreConfig(options = {}) {
|
|
309
|
-
return [
|
|
308
|
+
return defineConfig([
|
|
310
309
|
{
|
|
311
310
|
name: 'material-ui-base',
|
|
312
311
|
settings: {
|
|
@@ -433,7 +432,7 @@ export function createCoreConfig(options = {}) {
|
|
|
433
432
|
'react/forbid-prop-types': 'off', // Too strict, no time for that
|
|
434
433
|
'react/jsx-curly-brace-presence': 'off', // broken
|
|
435
434
|
// airbnb is using .jsx
|
|
436
|
-
'react/jsx-filename-extension': ['error', { extensions: ['.
|
|
435
|
+
'react/jsx-filename-extension': ['error', { extensions: ['.jsx', '.tsx'] }],
|
|
437
436
|
// Prefer <React.Fragment> over <>.
|
|
438
437
|
'react/jsx-fragments': ['error', 'element'],
|
|
439
438
|
// Enforces premature optimization
|
|
@@ -501,11 +500,11 @@ export function createCoreConfig(options = {}) {
|
|
|
501
500
|
|
|
502
501
|
'react/jsx-no-useless-fragment': ['error', { allowExpressions: true }],
|
|
503
502
|
'lines-around-directive': 'off',
|
|
504
|
-
...(options.
|
|
503
|
+
...(options.enableReactCompiler ? { 'react-compiler/react-compiler': 'error' } : {}),
|
|
505
504
|
// Prevent the use of `e` as a shorthand for `event`, `error`, etc.
|
|
506
505
|
'id-denylist': ['error', 'e'],
|
|
507
506
|
'@typescript-eslint/return-await': 'off',
|
|
508
507
|
},
|
|
509
508
|
},
|
|
510
|
-
];
|
|
509
|
+
]);
|
|
511
510
|
}
|
|
@@ -88,7 +88,8 @@ const rule = {
|
|
|
88
88
|
callee.name === 'useDefaultProps' || callee.name === 'useThemeProps';
|
|
89
89
|
if (isUseDefaultPropsCall) {
|
|
90
90
|
let isCalledFromCustomHook = false;
|
|
91
|
-
|
|
91
|
+
/** @type {import('eslint').Rule.Node | null} */
|
|
92
|
+
let parent = node.parent;
|
|
92
93
|
while (parent != null) {
|
|
93
94
|
if (parent.type === 'FunctionExpression' || parent.type === 'FunctionDeclaration') {
|
|
94
95
|
if (
|
|
@@ -112,7 +113,8 @@ const rule = {
|
|
|
112
113
|
|
|
113
114
|
if (nameLiteral !== null) {
|
|
114
115
|
let componentName = null;
|
|
115
|
-
|
|
116
|
+
/** @type {import('eslint').Rule.Node | null} */
|
|
117
|
+
let parent = node.parent;
|
|
116
118
|
while (parent != null && componentName === null) {
|
|
117
119
|
if (parent.type === 'FunctionExpression' || parent.type === 'FunctionDeclaration') {
|
|
118
120
|
componentName = /** @type {import('estree').Identifier} */ (parent.id).name;
|
|
@@ -32,8 +32,9 @@ export default {
|
|
|
32
32
|
* @param {import("estree").CallExpression & import("eslint").Rule.NodeParentExtension} hookCallNode
|
|
33
33
|
*/
|
|
34
34
|
function getComponentBlockNode(hookCallNode) {
|
|
35
|
+
/** @type {import("eslint").Rule.Node | null} */
|
|
35
36
|
let node = hookCallNode.parent;
|
|
36
|
-
while (node
|
|
37
|
+
while (node) {
|
|
37
38
|
if (node.type === 'BlockStatement') {
|
|
38
39
|
return node;
|
|
39
40
|
}
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import mochaPlugin from 'eslint-plugin-mocha';
|
|
2
|
+
import vitestPlugin from '@vitest/eslint-plugin';
|
|
2
3
|
import testingLibrary from 'eslint-plugin-testing-library';
|
|
4
|
+
import { defineConfig } from 'eslint/config';
|
|
3
5
|
import globals from 'globals';
|
|
4
6
|
import * as tseslint from 'typescript-eslint';
|
|
7
|
+
import { EXTENSION_TS } from './extensions.mjs';
|
|
5
8
|
|
|
6
9
|
/**
|
|
7
10
|
* @type {import('eslint').Linter.Config}
|
|
8
11
|
*/
|
|
9
12
|
export const baseSpecRules = {
|
|
10
|
-
|
|
13
|
+
name: 'Spec files rules',
|
|
14
|
+
files: [`**/*.spec${EXTENSION_TS}`],
|
|
11
15
|
rules: {
|
|
16
|
+
'compat/compat': 'off',
|
|
12
17
|
'no-alert': 'off',
|
|
13
18
|
'no-console': 'off',
|
|
14
19
|
'no-empty-pattern': 'off',
|
|
@@ -41,79 +46,80 @@ export const baseSpecRules = {
|
|
|
41
46
|
/**
|
|
42
47
|
* @param {Object} [options]
|
|
43
48
|
* @param {boolean} [options.useMocha]
|
|
49
|
+
* @param {boolean} [options.useVitest]
|
|
44
50
|
* @returns {import('eslint').Linter.Config[]}
|
|
45
51
|
*/
|
|
46
52
|
export function createTestConfig(options = {}) {
|
|
47
|
-
const { useMocha = true } = options;
|
|
48
|
-
return
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
},
|
|
60
|
-
globals: globals.mocha,
|
|
53
|
+
const { useMocha = true, useVitest = false } = options;
|
|
54
|
+
return defineConfig(
|
|
55
|
+
useMocha ? mochaPlugin.configs.recommended : {},
|
|
56
|
+
useVitest ? vitestPlugin.configs.recommended : {},
|
|
57
|
+
testingLibrary.configs['flat/dom'],
|
|
58
|
+
testingLibrary.configs['flat/react'],
|
|
59
|
+
{
|
|
60
|
+
name: 'Test files',
|
|
61
|
+
languageOptions: {
|
|
62
|
+
parser: tseslint.parser,
|
|
63
|
+
parserOptions: {
|
|
64
|
+
ecmaVersion: 7,
|
|
61
65
|
},
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
+
globals: globals.mocha,
|
|
67
|
+
},
|
|
68
|
+
rules: {
|
|
69
|
+
'compat/compat': 'off',
|
|
70
|
+
// does not work with wildcard imports. Mistakes will throw at runtime anyway
|
|
71
|
+
'import/named': 'off',
|
|
72
|
+
'material-ui/disallow-active-element-as-key-event-target': 'error',
|
|
66
73
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
74
|
+
// disable eslint-plugin-jsx-a11y
|
|
75
|
+
// tests are not driven by assistive technology
|
|
76
|
+
// add `jsx-a11y` rules once you encounter them in tests
|
|
77
|
+
'jsx-a11y/click-events-have-key-events': 'off',
|
|
78
|
+
'jsx-a11y/control-has-associated-label': 'off',
|
|
79
|
+
'jsx-a11y/iframe-has-title': 'off',
|
|
80
|
+
'jsx-a11y/label-has-associated-control': 'off',
|
|
81
|
+
'jsx-a11y/mouse-events-have-key-events': 'off',
|
|
82
|
+
'jsx-a11y/no-noninteractive-tabindex': 'off',
|
|
83
|
+
'jsx-a11y/no-static-element-interactions': 'off',
|
|
84
|
+
'jsx-a11y/tabindex-no-positive': 'off',
|
|
85
|
+
'jsx-a11y/anchor-is-valid': 'off',
|
|
79
86
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
87
|
+
// In tests this is generally intended.
|
|
88
|
+
'react/button-has-type': 'off',
|
|
89
|
+
// They are accessed to test custom validator implementation with PropTypes.checkPropTypes
|
|
90
|
+
'react/forbid-foreign-prop-types': 'off',
|
|
91
|
+
// components that are defined in test are isolated enough
|
|
92
|
+
// that they don't need type-checking
|
|
93
|
+
'react/prop-types': 'off',
|
|
94
|
+
'react/no-unused-prop-types': 'off',
|
|
95
|
+
// Part of the migration away from airbnb config. Turned of initially.
|
|
96
|
+
'@typescript-eslint/no-empty-function': 'off',
|
|
97
|
+
'@typescript-eslint/ban-ts-comment': 'off',
|
|
98
|
+
'testing-library/no-node-access': 'off',
|
|
99
|
+
'@typescript-eslint/no-non-null-asserted-optional-chain': 'off',
|
|
100
|
+
// end migration
|
|
101
|
+
...(useMocha
|
|
102
|
+
? {
|
|
103
|
+
'mocha/consistent-spacing-between-blocks': 'off',
|
|
97
104
|
|
|
98
|
-
|
|
99
|
-
|
|
105
|
+
// upgraded level from recommended
|
|
106
|
+
'mocha/no-pending-tests': 'error',
|
|
100
107
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
},
|
|
108
|
+
// no rationale provided in /recommended
|
|
109
|
+
'mocha/no-mocha-arrows': 'off',
|
|
110
|
+
// definitely a useful rule but too many false positives
|
|
111
|
+
// due to `describeConformance`
|
|
112
|
+
// "If you're using dynamically generated tests, you should disable this rule.""
|
|
113
|
+
'mocha/no-setup-in-describe': 'off',
|
|
114
|
+
// `beforeEach` for a single case is optimized for change
|
|
115
|
+
// when we add a test we don't have to refactor the existing
|
|
116
|
+
// test to `beforeEach`.
|
|
117
|
+
// `beforeEach`+`afterEach` also means that the `beforeEach`
|
|
118
|
+
// is cleaned up in `afterEach` if the test causes a crash
|
|
119
|
+
'mocha/no-hooks-for-single-case': 'off',
|
|
120
|
+
}
|
|
121
|
+
: {}),
|
|
116
122
|
},
|
|
117
|
-
|
|
123
|
+
},
|
|
118
124
|
);
|
|
119
125
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import postcssStylesSyntax from 'postcss-styled-syntax';
|
|
2
|
+
import standardConfig from 'stylelint-config-standard';
|
|
3
|
+
|
|
4
|
+
/** @type {import('stylelint').Config} */
|
|
5
|
+
export default {
|
|
6
|
+
extends: standardConfig,
|
|
7
|
+
rules: {
|
|
8
|
+
// Too opinionated?
|
|
9
|
+
'no-descending-specificity': null,
|
|
10
|
+
|
|
11
|
+
// Adopted from mui/material-ui repo
|
|
12
|
+
'alpha-value-notation': null,
|
|
13
|
+
'custom-property-pattern': null,
|
|
14
|
+
'media-feature-range-notation': null,
|
|
15
|
+
'no-empty-source': null,
|
|
16
|
+
'selector-class-pattern': null,
|
|
17
|
+
'string-no-newline': null, // not compatible with prettier
|
|
18
|
+
'value-keyword-case': null,
|
|
19
|
+
'import-notation': null,
|
|
20
|
+
|
|
21
|
+
// Responsibility of prettier:
|
|
22
|
+
'at-rule-empty-line-before': null,
|
|
23
|
+
'comment-empty-line-before': null,
|
|
24
|
+
'custom-property-empty-line-before': null,
|
|
25
|
+
'declaration-empty-line-before': null,
|
|
26
|
+
'rule-empty-line-before': null,
|
|
27
|
+
|
|
28
|
+
// Tailwind
|
|
29
|
+
'at-rule-no-unknown': [true, { ignoreAtRules: ['theme', 'config'] }],
|
|
30
|
+
|
|
31
|
+
// Don't assume we use a preprocessor
|
|
32
|
+
'property-no-vendor-prefix': null,
|
|
33
|
+
'property-no-deprecated': null,
|
|
34
|
+
'declaration-property-value-keyword-no-deprecated': null,
|
|
35
|
+
|
|
36
|
+
// Responsibility of a minifier
|
|
37
|
+
'color-hex-length': null,
|
|
38
|
+
'declaration-block-no-redundant-longhand-properties': null,
|
|
39
|
+
},
|
|
40
|
+
overrides: [
|
|
41
|
+
{
|
|
42
|
+
files: ['**/*.?(c|m)[jt]s?(x)'],
|
|
43
|
+
customSyntax: /** @type {any} */ (postcssStylesSyntax),
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
};
|
package/src/untyped-plugins.d.ts
CHANGED
|
@@ -154,3 +154,16 @@ declare module '@babel/preset-typescript' {
|
|
|
154
154
|
declare const preset: PluginItem;
|
|
155
155
|
export default preset;
|
|
156
156
|
}
|
|
157
|
+
|
|
158
|
+
declare module 'stylelint-config-standard' {
|
|
159
|
+
import type { Config } from 'stylelint';
|
|
160
|
+
|
|
161
|
+
declare const configExtends: Config['extends'];
|
|
162
|
+
export default configExtends;
|
|
163
|
+
}
|
|
164
|
+
declare module 'postcss-styled-syntax' {
|
|
165
|
+
import type { Syntax } from 'postcss';
|
|
166
|
+
|
|
167
|
+
declare const syntax: Syntax;
|
|
168
|
+
export default syntax;
|
|
169
|
+
}
|