Upload folder using huggingface_hub
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- node_modules/eslint-plugin-react/README.md +423 -0
- node_modules/eslint-plugin-react/configs/all.js +13 -0
- node_modules/eslint-plugin-react/configs/jsx-runtime.js +13 -0
- node_modules/eslint-plugin-react/configs/recommended.js +13 -0
- node_modules/eslint-plugin-react/index.d.ts +187 -0
- node_modules/eslint-plugin-react/index.d.ts.map +1 -0
- node_modules/eslint-plugin-react/index.js +125 -0
- node_modules/eslint-plugin-react/lib/rules/boolean-prop-naming.d.ts +3 -0
- node_modules/eslint-plugin-react/lib/rules/boolean-prop-naming.d.ts.map +1 -0
- node_modules/eslint-plugin-react/lib/rules/boolean-prop-naming.js +426 -0
- node_modules/eslint-plugin-react/lib/rules/button-has-type.d.ts +3 -0
- node_modules/eslint-plugin-react/lib/rules/button-has-type.d.ts.map +1 -0
- node_modules/eslint-plugin-react/lib/rules/button-has-type.js +169 -0
- node_modules/eslint-plugin-react/lib/rules/checked-requires-onchange-or-readonly.d.ts +3 -0
- node_modules/eslint-plugin-react/lib/rules/checked-requires-onchange-or-readonly.d.ts.map +1 -0
- node_modules/eslint-plugin-react/lib/rules/checked-requires-onchange-or-readonly.js +142 -0
- node_modules/eslint-plugin-react/lib/rules/default-props-match-prop-types.d.ts +3 -0
- node_modules/eslint-plugin-react/lib/rules/default-props-match-prop-types.d.ts.map +1 -0
- node_modules/eslint-plugin-react/lib/rules/default-props-match-prop-types.js +109 -0
- node_modules/eslint-plugin-react/lib/rules/destructuring-assignment.d.ts +3 -0
- node_modules/eslint-plugin-react/lib/rules/destructuring-assignment.d.ts.map +1 -0
- node_modules/eslint-plugin-react/lib/rules/destructuring-assignment.js +319 -0
- node_modules/eslint-plugin-react/lib/rules/display-name.d.ts +3 -0
- node_modules/eslint-plugin-react/lib/rules/display-name.d.ts.map +1 -0
- node_modules/eslint-plugin-react/lib/rules/display-name.js +285 -0
- node_modules/eslint-plugin-react/lib/rules/forbid-component-props.d.ts +3 -0
- node_modules/eslint-plugin-react/lib/rules/forbid-component-props.d.ts.map +1 -0
- node_modules/eslint-plugin-react/lib/rules/forbid-component-props.js +239 -0
- node_modules/eslint-plugin-react/lib/rules/forbid-dom-props.d.ts +3 -0
- node_modules/eslint-plugin-react/lib/rules/forbid-dom-props.d.ts.map +1 -0
- node_modules/eslint-plugin-react/lib/rules/forbid-dom-props.js +122 -0
- node_modules/eslint-plugin-react/lib/rules/forbid-elements.d.ts +3 -0
- node_modules/eslint-plugin-react/lib/rules/forbid-elements.d.ts.map +1 -0
- node_modules/eslint-plugin-react/lib/rules/forbid-elements.js +119 -0
- node_modules/eslint-plugin-react/lib/rules/forbid-foreign-prop-types.d.ts +3 -0
- node_modules/eslint-plugin-react/lib/rules/forbid-foreign-prop-types.d.ts.map +1 -0
- node_modules/eslint-plugin-react/lib/rules/forbid-foreign-prop-types.js +141 -0
- node_modules/eslint-plugin-react/lib/rules/forbid-prop-types.d.ts +3 -0
- node_modules/eslint-plugin-react/lib/rules/forbid-prop-types.d.ts.map +1 -0
- node_modules/eslint-plugin-react/lib/rules/forbid-prop-types.js +298 -0
- node_modules/eslint-plugin-react/lib/rules/forward-ref-uses-ref.d.ts +3 -0
- node_modules/eslint-plugin-react/lib/rules/forward-ref-uses-ref.d.ts.map +1 -0
- node_modules/eslint-plugin-react/lib/rules/forward-ref-uses-ref.js +100 -0
- node_modules/eslint-plugin-react/lib/rules/function-component-definition.d.ts +3 -0
- node_modules/eslint-plugin-react/lib/rules/function-component-definition.d.ts.map +1 -0
- node_modules/eslint-plugin-react/lib/rules/function-component-definition.js +285 -0
- node_modules/eslint-plugin-react/lib/rules/hook-use-state.d.ts +3 -0
- node_modules/eslint-plugin-react/lib/rules/hook-use-state.d.ts.map +1 -0
- node_modules/eslint-plugin-react/lib/rules/hook-use-state.js +205 -0
- node_modules/eslint-plugin-react/lib/rules/iframe-missing-sandbox.d.ts +3 -0
node_modules/eslint-plugin-react/README.md
ADDED
|
@@ -0,0 +1,423 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# `eslint-plugin-react` <sup>[![Version Badge][npm-version-svg]][package-url]</sup>
|
| 2 |
+
|
| 3 |
+
===================
|
| 4 |
+
|
| 5 |
+
[![github actions][actions-image]][actions-url]
|
| 6 |
+
[![Maintenance Status][status-image]][status-url]
|
| 7 |
+
[![NPM version][npm-image]][npm-url]
|
| 8 |
+
[![Tidelift][tidelift-image]][tidelift-url]
|
| 9 |
+
|
| 10 |
+
React specific linting rules for `eslint`
|
| 11 |
+
|
| 12 |
+
## Installation
|
| 13 |
+
|
| 14 |
+
```sh
|
| 15 |
+
npm install eslint eslint-plugin-react --save-dev
|
| 16 |
+
```
|
| 17 |
+
|
| 18 |
+
It is also possible to install ESLint globally rather than locally (using `npm install -g eslint`). However, this is not recommended, and any plugins or shareable configs that you use must be installed locally in either case.
|
| 19 |
+
|
| 20 |
+
## Configuration (legacy: `.eslintrc*`) <a id="configuration"></a>
|
| 21 |
+
|
| 22 |
+
Use [our preset](#recommended) to get reasonable defaults:
|
| 23 |
+
|
| 24 |
+
```json
|
| 25 |
+
"extends": [
|
| 26 |
+
"eslint:recommended",
|
| 27 |
+
"plugin:react/recommended"
|
| 28 |
+
]
|
| 29 |
+
```
|
| 30 |
+
|
| 31 |
+
If you are using the [new JSX transform from React 17](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html#removing-unused-react-imports), extend [`react/jsx-runtime`](https://github.com/jsx-eslint/eslint-plugin-react/blob/c8917b0885094b5e4cc2a6f613f7fb6f16fe932e/index.js#L163-L176) in your eslint config (add `"plugin:react/jsx-runtime"` to `"extends"`) to disable the relevant rules.
|
| 32 |
+
|
| 33 |
+
You should also specify settings that will be shared across all the plugin rules. ([More about eslint shared settings](https://eslint.org/docs/latest/use/configure/configuration-files#configuring-shared-settings))
|
| 34 |
+
|
| 35 |
+
```json5
|
| 36 |
+
{
|
| 37 |
+
"settings": {
|
| 38 |
+
"react": {
|
| 39 |
+
"createClass": "createReactClass", // Regex for Component Factory to use,
|
| 40 |
+
// default to "createReactClass"
|
| 41 |
+
"pragma": "React", // Pragma to use, default to "React"
|
| 42 |
+
"fragment": "Fragment", // Fragment to use (may be a property of <pragma>), default to "Fragment"
|
| 43 |
+
"version": "detect", // React version. "detect" automatically picks the version you have installed.
|
| 44 |
+
// You can also use `16.0`, `16.3`, etc, if you want to override the detected value.
|
| 45 |
+
// Defaults to the "defaultVersion" setting and warns if missing, and to "detect" in the future
|
| 46 |
+
"defaultVersion": "", // Default React version to use when the version you have installed cannot be detected.
|
| 47 |
+
// If not provided, defaults to the latest React version.
|
| 48 |
+
"flowVersion": "0.53" // Flow version
|
| 49 |
+
},
|
| 50 |
+
"propWrapperFunctions": [
|
| 51 |
+
// The names of any function used to wrap propTypes, e.g. `forbidExtraProps`. If this isn't set, any propTypes wrapped in a function will be skipped.
|
| 52 |
+
"forbidExtraProps",
|
| 53 |
+
{"property": "freeze", "object": "Object"},
|
| 54 |
+
{"property": "myFavoriteWrapper"},
|
| 55 |
+
// for rules that check exact prop wrappers
|
| 56 |
+
{"property": "forbidExtraProps", "exact": true}
|
| 57 |
+
],
|
| 58 |
+
"componentWrapperFunctions": [
|
| 59 |
+
// The name of any function used to wrap components, e.g. Mobx `observer` function. If this isn't set, components wrapped by these functions will be skipped.
|
| 60 |
+
"observer", // `property`
|
| 61 |
+
{"property": "styled"}, // `object` is optional
|
| 62 |
+
{"property": "observer", "object": "Mobx"},
|
| 63 |
+
{"property": "observer", "object": "<pragma>"} // sets `object` to whatever value `settings.react.pragma` is set to
|
| 64 |
+
],
|
| 65 |
+
"formComponents": [
|
| 66 |
+
// Components used as alternatives to <form> for forms, eg. <Form endpoint={ url } />
|
| 67 |
+
"CustomForm",
|
| 68 |
+
{"name": "SimpleForm", "formAttribute": "endpoint"},
|
| 69 |
+
{"name": "Form", "formAttribute": ["registerEndpoint", "loginEndpoint"]}, // allows specifying multiple properties if necessary
|
| 70 |
+
],
|
| 71 |
+
"linkComponents": [
|
| 72 |
+
// Components used as alternatives to <a> for linking, eg. <Link to={ url } />
|
| 73 |
+
"Hyperlink",
|
| 74 |
+
{"name": "MyLink", "linkAttribute": "to"},
|
| 75 |
+
{"name": "Link", "linkAttribute": ["to", "href"]}, // allows specifying multiple properties if necessary
|
| 76 |
+
]
|
| 77 |
+
}
|
| 78 |
+
}
|
| 79 |
+
```
|
| 80 |
+
|
| 81 |
+
If you do not use a preset you will need to specify individual rules and add extra configuration.
|
| 82 |
+
|
| 83 |
+
Add "react" to the plugins section.
|
| 84 |
+
|
| 85 |
+
```json
|
| 86 |
+
{
|
| 87 |
+
"plugins": [
|
| 88 |
+
"react"
|
| 89 |
+
]
|
| 90 |
+
}
|
| 91 |
+
```
|
| 92 |
+
|
| 93 |
+
Enable JSX support.
|
| 94 |
+
|
| 95 |
+
With `eslint` 2+
|
| 96 |
+
|
| 97 |
+
```json
|
| 98 |
+
{
|
| 99 |
+
"parserOptions": {
|
| 100 |
+
"ecmaFeatures": {
|
| 101 |
+
"jsx": true
|
| 102 |
+
}
|
| 103 |
+
}
|
| 104 |
+
}
|
| 105 |
+
```
|
| 106 |
+
|
| 107 |
+
Enable the rules that you would like to use.
|
| 108 |
+
|
| 109 |
+
```json
|
| 110 |
+
"rules": {
|
| 111 |
+
"react/jsx-uses-react": "error",
|
| 112 |
+
"react/jsx-uses-vars": "error",
|
| 113 |
+
}
|
| 114 |
+
```
|
| 115 |
+
|
| 116 |
+
### Shareable configs
|
| 117 |
+
|
| 118 |
+
#### Recommended
|
| 119 |
+
|
| 120 |
+
This plugin exports a `recommended` configuration that enforces React good practices.
|
| 121 |
+
|
| 122 |
+
To enable this configuration use the `extends` property in your `.eslintrc` config file:
|
| 123 |
+
|
| 124 |
+
```json
|
| 125 |
+
{
|
| 126 |
+
"extends": ["eslint:recommended", "plugin:react/recommended"]
|
| 127 |
+
}
|
| 128 |
+
```
|
| 129 |
+
|
| 130 |
+
See [`eslint` documentation](https://eslint.org/docs/user-guide/configuring/configuration-files#extending-configuration-files) for more information about extending configuration files.
|
| 131 |
+
|
| 132 |
+
#### All
|
| 133 |
+
|
| 134 |
+
This plugin also exports an `all` configuration that includes every available rule.
|
| 135 |
+
This pairs well with the `eslint:all` rule.
|
| 136 |
+
|
| 137 |
+
```json
|
| 138 |
+
{
|
| 139 |
+
"plugins": [
|
| 140 |
+
"react"
|
| 141 |
+
],
|
| 142 |
+
"extends": ["eslint:all", "plugin:react/all"]
|
| 143 |
+
}
|
| 144 |
+
```
|
| 145 |
+
|
| 146 |
+
**Note**: These configurations will import `eslint-plugin-react` and enable JSX in [parser options](https://eslint.org/docs/user-guide/configuring/language-options#specifying-parser-options).
|
| 147 |
+
|
| 148 |
+
## Configuration (new: `eslint.config.js`)
|
| 149 |
+
|
| 150 |
+
From [`v8.21.0`](https://github.com/eslint/eslint/releases/tag/v8.21.0), eslint announced a new config system.
|
| 151 |
+
In the new system, `.eslintrc*` is no longer used. `eslint.config.js` would be the default config file name.
|
| 152 |
+
In eslint `v8`, the legacy system (`.eslintrc*`) would still be supported, while in eslint `v9`, only the new system would be supported.
|
| 153 |
+
|
| 154 |
+
And from [`v8.23.0`](https://github.com/eslint/eslint/releases/tag/v8.23.0), eslint CLI starts to look up `eslint.config.js`.
|
| 155 |
+
**So, if your eslint is `>=8.23.0`, you're 100% ready to use the new config system.**
|
| 156 |
+
|
| 157 |
+
You might want to check out the official blog posts,
|
| 158 |
+
|
| 159 |
+
- <https://eslint.org/blog/2022/08/new-config-system-part-1/>
|
| 160 |
+
- <https://eslint.org/blog/2022/08/new-config-system-part-2/>
|
| 161 |
+
- <https://eslint.org/blog/2022/08/new-config-system-part-3/>
|
| 162 |
+
|
| 163 |
+
and the [official docs](https://eslint.org/docs/latest/user-guide/configuring/configuration-files-new).
|
| 164 |
+
|
| 165 |
+
### Plugin
|
| 166 |
+
|
| 167 |
+
The default export of `eslint-plugin-react` is a plugin object.
|
| 168 |
+
|
| 169 |
+
```js
|
| 170 |
+
const react = require('eslint-plugin-react');
|
| 171 |
+
const globals = require('globals');
|
| 172 |
+
|
| 173 |
+
module.exports = [
|
| 174 |
+
…
|
| 175 |
+
{
|
| 176 |
+
files: ['**/*.{js,jsx,mjs,cjs,ts,tsx}'],
|
| 177 |
+
plugins: {
|
| 178 |
+
react,
|
| 179 |
+
},
|
| 180 |
+
languageOptions: {
|
| 181 |
+
parserOptions: {
|
| 182 |
+
ecmaFeatures: {
|
| 183 |
+
jsx: true,
|
| 184 |
+
},
|
| 185 |
+
},
|
| 186 |
+
globals: {
|
| 187 |
+
...globals.browser,
|
| 188 |
+
},
|
| 189 |
+
},
|
| 190 |
+
rules: {
|
| 191 |
+
// ... any rules you want
|
| 192 |
+
'react/jsx-uses-react': 'error',
|
| 193 |
+
'react/jsx-uses-vars': 'error',
|
| 194 |
+
},
|
| 195 |
+
// ... others are omitted for brevity
|
| 196 |
+
},
|
| 197 |
+
…
|
| 198 |
+
];
|
| 199 |
+
```
|
| 200 |
+
|
| 201 |
+
### Configuring shared settings
|
| 202 |
+
|
| 203 |
+
Refer to the [official docs](https://eslint.org/docs/latest/user-guide/configuring/configuration-files-new#configuring-shared-settings).
|
| 204 |
+
|
| 205 |
+
The schema of the `settings.react` object would be identical to that of what's already described above in the legacy config section.
|
| 206 |
+
|
| 207 |
+
<!-- markdownlint-disable-next-line no-duplicate-heading -->
|
| 208 |
+
### Flat Configs
|
| 209 |
+
|
| 210 |
+
This plugin exports 3 flat configs:
|
| 211 |
+
|
| 212 |
+
- `flat.all`
|
| 213 |
+
- `flat.recommended`
|
| 214 |
+
- `flat['jsx-runtime']`
|
| 215 |
+
|
| 216 |
+
The flat configs are available via the root plugin import. They will configure the plugin under the `react/` namespace and enable JSX in [`languageOptions.parserOptions`](https://eslint.org/docs/latest/use/configure/language-options#specifying-parser-options).
|
| 217 |
+
|
| 218 |
+
```js
|
| 219 |
+
const reactPlugin = require('eslint-plugin-react');
|
| 220 |
+
|
| 221 |
+
module.exports = [
|
| 222 |
+
…
|
| 223 |
+
reactPlugin.configs.flat.recommended, // This is not a plugin object, but a shareable config object
|
| 224 |
+
reactPlugin.configs.flat['jsx-runtime'], // Add this if you are using React 17+
|
| 225 |
+
…
|
| 226 |
+
];
|
| 227 |
+
```
|
| 228 |
+
|
| 229 |
+
You can of course add/override some properties.
|
| 230 |
+
|
| 231 |
+
**Note**: Our shareable configs does not preconfigure `files` or [`languageOptions.globals`](https://eslint.org/docs/latest/user-guide/configuring/configuration-files-new#configuration-objects).
|
| 232 |
+
For most of the cases, you probably want to configure some properties by yourself.
|
| 233 |
+
|
| 234 |
+
```js
|
| 235 |
+
const reactPlugin = require('eslint-plugin-react');
|
| 236 |
+
const globals = require('globals');
|
| 237 |
+
|
| 238 |
+
module.exports = [
|
| 239 |
+
…
|
| 240 |
+
{
|
| 241 |
+
files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'],
|
| 242 |
+
...reactPlugin.configs.flat.recommended,
|
| 243 |
+
languageOptions: {
|
| 244 |
+
...reactPlugin.configs.flat.recommended.languageOptions,
|
| 245 |
+
globals: {
|
| 246 |
+
...globals.serviceworker,
|
| 247 |
+
...globals.browser,
|
| 248 |
+
},
|
| 249 |
+
},
|
| 250 |
+
},
|
| 251 |
+
…
|
| 252 |
+
];
|
| 253 |
+
```
|
| 254 |
+
|
| 255 |
+
The above example is same as the example below, as the new config system is based on chaining.
|
| 256 |
+
|
| 257 |
+
```js
|
| 258 |
+
const reactPlugin = require('eslint-plugin-react');
|
| 259 |
+
const globals = require('globals');
|
| 260 |
+
|
| 261 |
+
module.exports = [
|
| 262 |
+
…
|
| 263 |
+
{
|
| 264 |
+
files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'],
|
| 265 |
+
...reactPlugin.configs.flat.recommended,
|
| 266 |
+
},
|
| 267 |
+
{
|
| 268 |
+
files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'],
|
| 269 |
+
languageOptions: {
|
| 270 |
+
globals: {
|
| 271 |
+
...globals.serviceworker,
|
| 272 |
+
...globals.browser,
|
| 273 |
+
},
|
| 274 |
+
},
|
| 275 |
+
},
|
| 276 |
+
…
|
| 277 |
+
];
|
| 278 |
+
```
|
| 279 |
+
|
| 280 |
+
## List of supported rules
|
| 281 |
+
|
| 282 |
+
<!-- begin auto-generated rules list -->
|
| 283 |
+
|
| 284 |
+
💼 [Configurations](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs) enabled in.\
|
| 285 |
+
🚫 [Configurations](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs) disabled in.\
|
| 286 |
+
🏃 Set in the `jsx-runtime` [configuration](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs).\
|
| 287 |
+
☑️ Set in the `recommended` [configuration](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs).\
|
| 288 |
+
🔧 Automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/user-guide/command-line-interface#--fix).\
|
| 289 |
+
💡 Manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).\
|
| 290 |
+
❌ Deprecated.
|
| 291 |
+
|
| 292 |
+
| Name | Description | 💼 | 🚫 | 🔧 | 💡 | ❌ |
|
| 293 |
+
| :------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------- | :- | :- | :- | :- | :- |
|
| 294 |
+
| [boolean-prop-naming](docs/rules/boolean-prop-naming.md) | Enforces consistent naming for boolean props | | | | | |
|
| 295 |
+
| [button-has-type](docs/rules/button-has-type.md) | Disallow usage of `button` elements without an explicit `type` attribute | | | | | |
|
| 296 |
+
| [checked-requires-onchange-or-readonly](docs/rules/checked-requires-onchange-or-readonly.md) | Enforce using `onChange` or `readonly` attribute when `checked` is used | | | | | |
|
| 297 |
+
| [default-props-match-prop-types](docs/rules/default-props-match-prop-types.md) | Enforce all defaultProps have a corresponding non-required PropType | | | | | |
|
| 298 |
+
| [destructuring-assignment](docs/rules/destructuring-assignment.md) | Enforce consistent usage of destructuring assignment of props, state, and context | | | 🔧 | | |
|
| 299 |
+
| [display-name](docs/rules/display-name.md) | Disallow missing displayName in a React component definition | ☑️ | | | | |
|
| 300 |
+
| [forbid-component-props](docs/rules/forbid-component-props.md) | Disallow certain props on components | | | | | |
|
| 301 |
+
| [forbid-dom-props](docs/rules/forbid-dom-props.md) | Disallow certain props on DOM Nodes | | | | | |
|
| 302 |
+
| [forbid-elements](docs/rules/forbid-elements.md) | Disallow certain elements | | | | | |
|
| 303 |
+
| [forbid-foreign-prop-types](docs/rules/forbid-foreign-prop-types.md) | Disallow using another component's propTypes | | | | | |
|
| 304 |
+
| [forbid-prop-types](docs/rules/forbid-prop-types.md) | Disallow certain propTypes | | | | | |
|
| 305 |
+
| [forward-ref-uses-ref](docs/rules/forward-ref-uses-ref.md) | Require all forwardRef components include a ref parameter | | | | 💡 | |
|
| 306 |
+
| [function-component-definition](docs/rules/function-component-definition.md) | Enforce a specific function type for function components | | | 🔧 | | |
|
| 307 |
+
| [hook-use-state](docs/rules/hook-use-state.md) | Ensure destructuring and symmetric naming of useState hook value and setter variables | | | | 💡 | |
|
| 308 |
+
| [iframe-missing-sandbox](docs/rules/iframe-missing-sandbox.md) | Enforce sandbox attribute on iframe elements | | | | | |
|
| 309 |
+
| [jsx-boolean-value](docs/rules/jsx-boolean-value.md) | Enforce boolean attributes notation in JSX | | | 🔧 | | |
|
| 310 |
+
| [jsx-child-element-spacing](docs/rules/jsx-child-element-spacing.md) | Enforce or disallow spaces inside of curly braces in JSX attributes and expressions | | | | | |
|
| 311 |
+
| [jsx-closing-bracket-location](docs/rules/jsx-closing-bracket-location.md) | Enforce closing bracket location in JSX | | | 🔧 | | |
|
| 312 |
+
| [jsx-closing-tag-location](docs/rules/jsx-closing-tag-location.md) | Enforce closing tag location for multiline JSX | | | 🔧 | | |
|
| 313 |
+
| [jsx-curly-brace-presence](docs/rules/jsx-curly-brace-presence.md) | Disallow unnecessary JSX expressions when literals alone are sufficient or enforce JSX expressions on literals in JSX children or attributes | | | 🔧 | | |
|
| 314 |
+
| [jsx-curly-newline](docs/rules/jsx-curly-newline.md) | Enforce consistent linebreaks in curly braces in JSX attributes and expressions | | | 🔧 | | |
|
| 315 |
+
| [jsx-curly-spacing](docs/rules/jsx-curly-spacing.md) | Enforce or disallow spaces inside of curly braces in JSX attributes and expressions | | | 🔧 | | |
|
| 316 |
+
| [jsx-equals-spacing](docs/rules/jsx-equals-spacing.md) | Enforce or disallow spaces around equal signs in JSX attributes | | | 🔧 | | |
|
| 317 |
+
| [jsx-filename-extension](docs/rules/jsx-filename-extension.md) | Disallow file extensions that may contain JSX | | | | | |
|
| 318 |
+
| [jsx-first-prop-new-line](docs/rules/jsx-first-prop-new-line.md) | Enforce proper position of the first property in JSX | | | 🔧 | | |
|
| 319 |
+
| [jsx-fragments](docs/rules/jsx-fragments.md) | Enforce shorthand or standard form for React fragments | | | 🔧 | | |
|
| 320 |
+
| [jsx-handler-names](docs/rules/jsx-handler-names.md) | Enforce event handler naming conventions in JSX | | | | | |
|
| 321 |
+
| [jsx-indent](docs/rules/jsx-indent.md) | Enforce JSX indentation | | | 🔧 | | |
|
| 322 |
+
| [jsx-indent-props](docs/rules/jsx-indent-props.md) | Enforce props indentation in JSX | | | 🔧 | | |
|
| 323 |
+
| [jsx-key](docs/rules/jsx-key.md) | Disallow missing `key` props in iterators/collection literals | ☑️ | | | | |
|
| 324 |
+
| [jsx-max-depth](docs/rules/jsx-max-depth.md) | Enforce JSX maximum depth | | | | | |
|
| 325 |
+
| [jsx-max-props-per-line](docs/rules/jsx-max-props-per-line.md) | Enforce maximum of props on a single line in JSX | | | 🔧 | | |
|
| 326 |
+
| [jsx-newline](docs/rules/jsx-newline.md) | Require or prevent a new line after jsx elements and expressions. | | | 🔧 | | |
|
| 327 |
+
| [jsx-no-bind](docs/rules/jsx-no-bind.md) | Disallow `.bind()` or arrow functions in JSX props | | | | | |
|
| 328 |
+
| [jsx-no-comment-textnodes](docs/rules/jsx-no-comment-textnodes.md) | Disallow comments from being inserted as text nodes | ☑️ | | | | |
|
| 329 |
+
| [jsx-no-constructed-context-values](docs/rules/jsx-no-constructed-context-values.md) | Disallows JSX context provider values from taking values that will cause needless rerenders | | | | | |
|
| 330 |
+
| [jsx-no-duplicate-props](docs/rules/jsx-no-duplicate-props.md) | Disallow duplicate properties in JSX | ☑️ | | | | |
|
| 331 |
+
| [jsx-no-leaked-render](docs/rules/jsx-no-leaked-render.md) | Disallow problematic leaked values from being rendered | | | 🔧 | | |
|
| 332 |
+
| [jsx-no-literals](docs/rules/jsx-no-literals.md) | Disallow usage of string literals in JSX | | | | | |
|
| 333 |
+
| [jsx-no-script-url](docs/rules/jsx-no-script-url.md) | Disallow usage of `javascript:` URLs | | | | | |
|
| 334 |
+
| [jsx-no-target-blank](docs/rules/jsx-no-target-blank.md) | Disallow `target="_blank"` attribute without `rel="noreferrer"` | ☑️ | | 🔧 | | |
|
| 335 |
+
| [jsx-no-undef](docs/rules/jsx-no-undef.md) | Disallow undeclared variables in JSX | ☑️ | | | | |
|
| 336 |
+
| [jsx-no-useless-fragment](docs/rules/jsx-no-useless-fragment.md) | Disallow unnecessary fragments | | | 🔧 | | |
|
| 337 |
+
| [jsx-one-expression-per-line](docs/rules/jsx-one-expression-per-line.md) | Require one JSX element per line | | | 🔧 | | |
|
| 338 |
+
| [jsx-pascal-case](docs/rules/jsx-pascal-case.md) | Enforce PascalCase for user-defined JSX components | | | | | |
|
| 339 |
+
| [jsx-props-no-multi-spaces](docs/rules/jsx-props-no-multi-spaces.md) | Disallow multiple spaces between inline JSX props | | | 🔧 | | |
|
| 340 |
+
| [jsx-props-no-spread-multi](docs/rules/jsx-props-no-spread-multi.md) | Disallow JSX prop spreading the same identifier multiple times | | | | | |
|
| 341 |
+
| [jsx-props-no-spreading](docs/rules/jsx-props-no-spreading.md) | Disallow JSX prop spreading | | | | | |
|
| 342 |
+
| [jsx-sort-default-props](docs/rules/jsx-sort-default-props.md) | Enforce defaultProps declarations alphabetical sorting | | | | | ❌ |
|
| 343 |
+
| [jsx-sort-props](docs/rules/jsx-sort-props.md) | Enforce props alphabetical sorting | | | 🔧 | | |
|
| 344 |
+
| [jsx-space-before-closing](docs/rules/jsx-space-before-closing.md) | Enforce spacing before closing bracket in JSX | | | 🔧 | | ❌ |
|
| 345 |
+
| [jsx-tag-spacing](docs/rules/jsx-tag-spacing.md) | Enforce whitespace in and around the JSX opening and closing brackets | | | 🔧 | | |
|
| 346 |
+
| [jsx-uses-react](docs/rules/jsx-uses-react.md) | Disallow React to be incorrectly marked as unused | ☑️ | 🏃 | | | |
|
| 347 |
+
| [jsx-uses-vars](docs/rules/jsx-uses-vars.md) | Disallow variables used in JSX to be incorrectly marked as unused | ☑️ | | | | |
|
| 348 |
+
| [jsx-wrap-multilines](docs/rules/jsx-wrap-multilines.md) | Disallow missing parentheses around multiline JSX | | | 🔧 | | |
|
| 349 |
+
| [no-access-state-in-setstate](docs/rules/no-access-state-in-setstate.md) | Disallow when this.state is accessed within setState | | | | | |
|
| 350 |
+
| [no-adjacent-inline-elements](docs/rules/no-adjacent-inline-elements.md) | Disallow adjacent inline elements not separated by whitespace. | | | | | |
|
| 351 |
+
| [no-array-index-key](docs/rules/no-array-index-key.md) | Disallow usage of Array index in keys | | | | | |
|
| 352 |
+
| [no-arrow-function-lifecycle](docs/rules/no-arrow-function-lifecycle.md) | Lifecycle methods should be methods on the prototype, not class fields | | | 🔧 | | |
|
| 353 |
+
| [no-children-prop](docs/rules/no-children-prop.md) | Disallow passing of children as props | ☑️ | | | | |
|
| 354 |
+
| [no-danger](docs/rules/no-danger.md) | Disallow usage of dangerous JSX properties | | | | | |
|
| 355 |
+
| [no-danger-with-children](docs/rules/no-danger-with-children.md) | Disallow when a DOM element is using both children and dangerouslySetInnerHTML | ☑️ | | | | |
|
| 356 |
+
| [no-deprecated](docs/rules/no-deprecated.md) | Disallow usage of deprecated methods | ☑️ | | | | |
|
| 357 |
+
| [no-did-mount-set-state](docs/rules/no-did-mount-set-state.md) | Disallow usage of setState in componentDidMount | | | | | |
|
| 358 |
+
| [no-did-update-set-state](docs/rules/no-did-update-set-state.md) | Disallow usage of setState in componentDidUpdate | | | | | |
|
| 359 |
+
| [no-direct-mutation-state](docs/rules/no-direct-mutation-state.md) | Disallow direct mutation of this.state | ☑️ | | | | |
|
| 360 |
+
| [no-find-dom-node](docs/rules/no-find-dom-node.md) | Disallow usage of findDOMNode | ☑️ | | | | |
|
| 361 |
+
| [no-invalid-html-attribute](docs/rules/no-invalid-html-attribute.md) | Disallow usage of invalid attributes | | | | 💡 | |
|
| 362 |
+
| [no-is-mounted](docs/rules/no-is-mounted.md) | Disallow usage of isMounted | ☑️ | | | | |
|
| 363 |
+
| [no-multi-comp](docs/rules/no-multi-comp.md) | Disallow multiple component definition per file | | | | | |
|
| 364 |
+
| [no-namespace](docs/rules/no-namespace.md) | Enforce that namespaces are not used in React elements | | | | | |
|
| 365 |
+
| [no-object-type-as-default-prop](docs/rules/no-object-type-as-default-prop.md) | Disallow usage of referential-type variables as default param in functional component | | | | | |
|
| 366 |
+
| [no-redundant-should-component-update](docs/rules/no-redundant-should-component-update.md) | Disallow usage of shouldComponentUpdate when extending React.PureComponent | | | | | |
|
| 367 |
+
| [no-render-return-value](docs/rules/no-render-return-value.md) | Disallow usage of the return value of ReactDOM.render | ☑️ | | | | |
|
| 368 |
+
| [no-set-state](docs/rules/no-set-state.md) | Disallow usage of setState | | | | | |
|
| 369 |
+
| [no-string-refs](docs/rules/no-string-refs.md) | Disallow using string references | ☑️ | | | | |
|
| 370 |
+
| [no-this-in-sfc](docs/rules/no-this-in-sfc.md) | Disallow `this` from being used in stateless functional components | | | | | |
|
| 371 |
+
| [no-typos](docs/rules/no-typos.md) | Disallow common typos | | | | | |
|
| 372 |
+
| [no-unescaped-entities](docs/rules/no-unescaped-entities.md) | Disallow unescaped HTML entities from appearing in markup | ☑️ | | | 💡 | |
|
| 373 |
+
| [no-unknown-property](docs/rules/no-unknown-property.md) | Disallow usage of unknown DOM property | ☑️ | | 🔧 | | |
|
| 374 |
+
| [no-unsafe](docs/rules/no-unsafe.md) | Disallow usage of unsafe lifecycle methods | | ☑️ | | | |
|
| 375 |
+
| [no-unstable-nested-components](docs/rules/no-unstable-nested-components.md) | Disallow creating unstable components inside components | | | | | |
|
| 376 |
+
| [no-unused-class-component-methods](docs/rules/no-unused-class-component-methods.md) | Disallow declaring unused methods of component class | | | | | |
|
| 377 |
+
| [no-unused-prop-types](docs/rules/no-unused-prop-types.md) | Disallow definitions of unused propTypes | | | | | |
|
| 378 |
+
| [no-unused-state](docs/rules/no-unused-state.md) | Disallow definitions of unused state | | | | | |
|
| 379 |
+
| [no-will-update-set-state](docs/rules/no-will-update-set-state.md) | Disallow usage of setState in componentWillUpdate | | | | | |
|
| 380 |
+
| [prefer-es6-class](docs/rules/prefer-es6-class.md) | Enforce ES5 or ES6 class for React Components | | | | | |
|
| 381 |
+
| [prefer-exact-props](docs/rules/prefer-exact-props.md) | Prefer exact proptype definitions | | | | | |
|
| 382 |
+
| [prefer-read-only-props](docs/rules/prefer-read-only-props.md) | Enforce that props are read-only | | | 🔧 | | |
|
| 383 |
+
| [prefer-stateless-function](docs/rules/prefer-stateless-function.md) | Enforce stateless components to be written as a pure function | | | | | |
|
| 384 |
+
| [prop-types](docs/rules/prop-types.md) | Disallow missing props validation in a React component definition | ☑️ | | | | |
|
| 385 |
+
| [react-in-jsx-scope](docs/rules/react-in-jsx-scope.md) | Disallow missing React when using JSX | ☑️ | 🏃 | | | |
|
| 386 |
+
| [require-default-props](docs/rules/require-default-props.md) | Enforce a defaultProps definition for every prop that is not a required prop | | | | | |
|
| 387 |
+
| [require-optimization](docs/rules/require-optimization.md) | Enforce React components to have a shouldComponentUpdate method | | | | | |
|
| 388 |
+
| [require-render-return](docs/rules/require-render-return.md) | Enforce ES5 or ES6 class for returning value in render function | ☑️ | | | | |
|
| 389 |
+
| [self-closing-comp](docs/rules/self-closing-comp.md) | Disallow extra closing tags for components without children | | | 🔧 | | |
|
| 390 |
+
| [sort-comp](docs/rules/sort-comp.md) | Enforce component methods order | | | | | |
|
| 391 |
+
| [sort-default-props](docs/rules/sort-default-props.md) | Enforce defaultProps declarations alphabetical sorting | | | | | |
|
| 392 |
+
| [sort-prop-types](docs/rules/sort-prop-types.md) | Enforce propTypes declarations alphabetical sorting | | | 🔧 | | |
|
| 393 |
+
| [state-in-constructor](docs/rules/state-in-constructor.md) | Enforce class component state initialization style | | | | | |
|
| 394 |
+
| [static-property-placement](docs/rules/static-property-placement.md) | Enforces where React component static properties should be positioned. | | | | | |
|
| 395 |
+
| [style-prop-object](docs/rules/style-prop-object.md) | Enforce style prop value is an object | | | | | |
|
| 396 |
+
| [void-dom-elements-no-children](docs/rules/void-dom-elements-no-children.md) | Disallow void DOM elements (e.g. `<img />`, `<br />`) from receiving children | | | | | |
|
| 397 |
+
|
| 398 |
+
<!-- end auto-generated rules list -->
|
| 399 |
+
|
| 400 |
+
## Other useful plugins
|
| 401 |
+
|
| 402 |
+
- Rules of Hooks: [eslint-plugin-react-hooks](https://github.com/facebook/react/tree/master/packages/eslint-plugin-react-hooks)
|
| 403 |
+
- JSX accessibility: [eslint-plugin-jsx-a11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y)
|
| 404 |
+
- React Native: [eslint-plugin-react-native](https://github.com/Intellicode/eslint-plugin-react-native)
|
| 405 |
+
|
| 406 |
+
## License
|
| 407 |
+
|
| 408 |
+
`eslint-plugin-react` is licensed under the [MIT License](https://opensource.org/licenses/mit-license.php).
|
| 409 |
+
|
| 410 |
+
[npm-url]: https://npmjs.org/package/eslint-plugin-react
|
| 411 |
+
[npm-image]: https://img.shields.io/npm/v/eslint-plugin-react.svg
|
| 412 |
+
|
| 413 |
+
[status-url]: https://github.com/jsx-eslint/eslint-plugin-react/pulse
|
| 414 |
+
[status-image]: https://img.shields.io/github/last-commit/jsx-eslint/eslint-plugin-react.svg
|
| 415 |
+
|
| 416 |
+
[tidelift-url]: https://tidelift.com/subscription/pkg/npm-eslint-plugin-react?utm_source=npm-eslint-plugin-react&utm_medium=referral&utm_campaign=readme
|
| 417 |
+
[tidelift-image]: https://tidelift.com/badges/package/npm/eslint-plugin-react?style=flat
|
| 418 |
+
|
| 419 |
+
[package-url]: https://npmjs.org/package/eslint-plugin-react
|
| 420 |
+
[npm-version-svg]: https://versionbadg.es/jsx-eslint/eslint-plugin-react.svg
|
| 421 |
+
|
| 422 |
+
[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/jsx-eslint/eslint-plugin-react
|
| 423 |
+
[actions-url]: https://github.com/jsx-eslint/eslint-plugin-react/actions
|
node_modules/eslint-plugin-react/configs/all.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
'use strict';
|
| 2 |
+
|
| 3 |
+
const plugin = require('..');
|
| 4 |
+
|
| 5 |
+
const legacyConfig = plugin.configs.all;
|
| 6 |
+
|
| 7 |
+
module.exports = {
|
| 8 |
+
plugins: { react: plugin },
|
| 9 |
+
rules: legacyConfig.rules,
|
| 10 |
+
languageOptions: { parserOptions: legacyConfig.parserOptions },
|
| 11 |
+
};
|
| 12 |
+
|
| 13 |
+
Object.defineProperty(module.exports, 'languageOptions', { enumerable: false });
|
node_modules/eslint-plugin-react/configs/jsx-runtime.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
'use strict';
|
| 2 |
+
|
| 3 |
+
const plugin = require('..');
|
| 4 |
+
|
| 5 |
+
const legacyConfig = plugin.configs['jsx-runtime'];
|
| 6 |
+
|
| 7 |
+
module.exports = {
|
| 8 |
+
plugins: { react: plugin },
|
| 9 |
+
rules: legacyConfig.rules,
|
| 10 |
+
languageOptions: { parserOptions: legacyConfig.parserOptions },
|
| 11 |
+
};
|
| 12 |
+
|
| 13 |
+
Object.defineProperty(module.exports, 'languageOptions', { enumerable: false });
|
node_modules/eslint-plugin-react/configs/recommended.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
'use strict';
|
| 2 |
+
|
| 3 |
+
const plugin = require('..');
|
| 4 |
+
|
| 5 |
+
const legacyConfig = plugin.configs.recommended;
|
| 6 |
+
|
| 7 |
+
module.exports = {
|
| 8 |
+
plugins: { react: plugin },
|
| 9 |
+
rules: legacyConfig.rules,
|
| 10 |
+
languageOptions: { parserOptions: legacyConfig.parserOptions },
|
| 11 |
+
};
|
| 12 |
+
|
| 13 |
+
Object.defineProperty(module.exports, 'languageOptions', { enumerable: false });
|
node_modules/eslint-plugin-react/index.d.ts
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
export = plugin;
|
| 2 |
+
/** @typedef {{ plugins: { react: typeof plugin }, rules: import('eslint').Linter.RulesRecord, languageOptions: { parserOptions: import('eslint').Linter.ParserOptions } }} ReactFlatConfig */
|
| 3 |
+
/** @type {{ deprecatedRules: typeof deprecatedRules, rules: typeof allRules, configs: typeof configs & { flat: Record<string, ReactFlatConfig> }}} */
|
| 4 |
+
declare const plugin: {
|
| 5 |
+
deprecatedRules: typeof deprecatedRules;
|
| 6 |
+
rules: typeof allRules;
|
| 7 |
+
configs: typeof configs & {
|
| 8 |
+
flat: Record<string, ReactFlatConfig>;
|
| 9 |
+
};
|
| 10 |
+
};
|
| 11 |
+
declare namespace plugin {
|
| 12 |
+
export { ReactFlatConfig };
|
| 13 |
+
}
|
| 14 |
+
/** @type {Partial<typeof allRules>} */
|
| 15 |
+
declare const deprecatedRules: Partial<typeof allRules>;
|
| 16 |
+
declare const allRules: {
|
| 17 |
+
'boolean-prop-naming': import("eslint").Rule.RuleModule;
|
| 18 |
+
'button-has-type': import("eslint").Rule.RuleModule;
|
| 19 |
+
'checked-requires-onchange-or-readonly': import("eslint").Rule.RuleModule;
|
| 20 |
+
'default-props-match-prop-types': import("eslint").Rule.RuleModule;
|
| 21 |
+
'destructuring-assignment': import("eslint").Rule.RuleModule;
|
| 22 |
+
'display-name': import("eslint").Rule.RuleModule;
|
| 23 |
+
'forbid-component-props': import("eslint").Rule.RuleModule;
|
| 24 |
+
'forbid-dom-props': import("eslint").Rule.RuleModule;
|
| 25 |
+
'forbid-elements': import("eslint").Rule.RuleModule;
|
| 26 |
+
'forbid-foreign-prop-types': import("eslint").Rule.RuleModule;
|
| 27 |
+
'forbid-prop-types': import("eslint").Rule.RuleModule;
|
| 28 |
+
'forward-ref-uses-ref': import("eslint").Rule.RuleModule;
|
| 29 |
+
'function-component-definition': import("eslint").Rule.RuleModule;
|
| 30 |
+
'hook-use-state': import("eslint").Rule.RuleModule;
|
| 31 |
+
'iframe-missing-sandbox': import("eslint").Rule.RuleModule;
|
| 32 |
+
'jsx-boolean-value': import("eslint").Rule.RuleModule;
|
| 33 |
+
'jsx-child-element-spacing': import("eslint").Rule.RuleModule;
|
| 34 |
+
'jsx-closing-bracket-location': import("eslint").Rule.RuleModule;
|
| 35 |
+
'jsx-closing-tag-location': import("eslint").Rule.RuleModule;
|
| 36 |
+
'jsx-curly-spacing': import("eslint").Rule.RuleModule;
|
| 37 |
+
'jsx-curly-newline': import("eslint").Rule.RuleModule;
|
| 38 |
+
'jsx-equals-spacing': import("eslint").Rule.RuleModule;
|
| 39 |
+
'jsx-filename-extension': import("eslint").Rule.RuleModule;
|
| 40 |
+
'jsx-first-prop-new-line': import("eslint").Rule.RuleModule;
|
| 41 |
+
'jsx-handler-names': import("eslint").Rule.RuleModule;
|
| 42 |
+
'jsx-indent': import("eslint").Rule.RuleModule;
|
| 43 |
+
'jsx-indent-props': import("eslint").Rule.RuleModule;
|
| 44 |
+
'jsx-key': import("eslint").Rule.RuleModule;
|
| 45 |
+
'jsx-max-depth': import("eslint").Rule.RuleModule;
|
| 46 |
+
'jsx-max-props-per-line': import("eslint").Rule.RuleModule;
|
| 47 |
+
'jsx-newline': import("eslint").Rule.RuleModule;
|
| 48 |
+
'jsx-no-bind': import("eslint").Rule.RuleModule;
|
| 49 |
+
'jsx-no-comment-textnodes': import("eslint").Rule.RuleModule;
|
| 50 |
+
'jsx-no-constructed-context-values': import("eslint").Rule.RuleModule;
|
| 51 |
+
'jsx-no-duplicate-props': import("eslint").Rule.RuleModule;
|
| 52 |
+
'jsx-no-leaked-render': import("eslint").Rule.RuleModule;
|
| 53 |
+
'jsx-no-literals': import("eslint").Rule.RuleModule;
|
| 54 |
+
'jsx-no-script-url': import("eslint").Rule.RuleModule;
|
| 55 |
+
'jsx-no-target-blank': import("eslint").Rule.RuleModule;
|
| 56 |
+
'jsx-no-useless-fragment': import("eslint").Rule.RuleModule;
|
| 57 |
+
'jsx-one-expression-per-line': import("eslint").Rule.RuleModule;
|
| 58 |
+
'jsx-no-undef': import("eslint").Rule.RuleModule;
|
| 59 |
+
'jsx-curly-brace-presence': import("eslint").Rule.RuleModule;
|
| 60 |
+
'jsx-pascal-case': import("eslint").Rule.RuleModule;
|
| 61 |
+
'jsx-fragments': import("eslint").Rule.RuleModule;
|
| 62 |
+
'jsx-props-no-multi-spaces': import("eslint").Rule.RuleModule;
|
| 63 |
+
'jsx-props-no-spreading': import("eslint").Rule.RuleModule;
|
| 64 |
+
'jsx-props-no-spread-multi': import("eslint").Rule.RuleModule;
|
| 65 |
+
'jsx-sort-default-props': import("eslint").Rule.RuleModule;
|
| 66 |
+
'jsx-sort-props': import("eslint").Rule.RuleModule;
|
| 67 |
+
'jsx-space-before-closing': import("eslint").Rule.RuleModule;
|
| 68 |
+
'jsx-tag-spacing': import("eslint").Rule.RuleModule;
|
| 69 |
+
'jsx-uses-react': import("eslint").Rule.RuleModule;
|
| 70 |
+
'jsx-uses-vars': import("eslint").Rule.RuleModule;
|
| 71 |
+
'jsx-wrap-multilines': import("eslint").Rule.RuleModule;
|
| 72 |
+
'no-invalid-html-attribute': import("eslint").Rule.RuleModule;
|
| 73 |
+
'no-access-state-in-setstate': import("eslint").Rule.RuleModule;
|
| 74 |
+
'no-adjacent-inline-elements': import("eslint").Rule.RuleModule;
|
| 75 |
+
'no-array-index-key': import("eslint").Rule.RuleModule;
|
| 76 |
+
'no-arrow-function-lifecycle': import("eslint").Rule.RuleModule;
|
| 77 |
+
'no-children-prop': import("eslint").Rule.RuleModule;
|
| 78 |
+
'no-danger': import("eslint").Rule.RuleModule;
|
| 79 |
+
'no-danger-with-children': import("eslint").Rule.RuleModule;
|
| 80 |
+
'no-deprecated': import("eslint").Rule.RuleModule;
|
| 81 |
+
'no-did-mount-set-state': import("eslint").Rule.RuleModule;
|
| 82 |
+
'no-did-update-set-state': import("eslint").Rule.RuleModule;
|
| 83 |
+
'no-direct-mutation-state': import("eslint").Rule.RuleModule;
|
| 84 |
+
'no-find-dom-node': import("eslint").Rule.RuleModule;
|
| 85 |
+
'no-is-mounted': import("eslint").Rule.RuleModule;
|
| 86 |
+
'no-multi-comp': import("eslint").Rule.RuleModule;
|
| 87 |
+
'no-namespace': import("eslint").Rule.RuleModule;
|
| 88 |
+
'no-set-state': import("eslint").Rule.RuleModule;
|
| 89 |
+
'no-string-refs': import("eslint").Rule.RuleModule;
|
| 90 |
+
'no-redundant-should-component-update': import("eslint").Rule.RuleModule;
|
| 91 |
+
'no-render-return-value': import("eslint").Rule.RuleModule;
|
| 92 |
+
'no-this-in-sfc': import("eslint").Rule.RuleModule;
|
| 93 |
+
'no-typos': import("eslint").Rule.RuleModule;
|
| 94 |
+
'no-unescaped-entities': import("eslint").Rule.RuleModule;
|
| 95 |
+
'no-unknown-property': import("eslint").Rule.RuleModule;
|
| 96 |
+
'no-unsafe': import("eslint").Rule.RuleModule;
|
| 97 |
+
'no-unstable-nested-components': import("eslint").Rule.RuleModule;
|
| 98 |
+
'no-unused-class-component-methods': import("eslint").Rule.RuleModule;
|
| 99 |
+
'no-unused-prop-types': import("eslint").Rule.RuleModule;
|
| 100 |
+
'no-unused-state': import("eslint").Rule.RuleModule;
|
| 101 |
+
'no-object-type-as-default-prop': import("eslint").Rule.RuleModule;
|
| 102 |
+
'no-will-update-set-state': import("eslint").Rule.RuleModule;
|
| 103 |
+
'prefer-es6-class': import("eslint").Rule.RuleModule;
|
| 104 |
+
'prefer-exact-props': import("eslint").Rule.RuleModule;
|
| 105 |
+
'prefer-read-only-props': import("eslint").Rule.RuleModule;
|
| 106 |
+
'prefer-stateless-function': import("eslint").Rule.RuleModule;
|
| 107 |
+
'prop-types': import("eslint").Rule.RuleModule;
|
| 108 |
+
'react-in-jsx-scope': import("eslint").Rule.RuleModule;
|
| 109 |
+
'require-default-props': import("eslint").Rule.RuleModule;
|
| 110 |
+
'require-optimization': import("eslint").Rule.RuleModule;
|
| 111 |
+
'require-render-return': import("eslint").Rule.RuleModule;
|
| 112 |
+
'self-closing-comp': import("eslint").Rule.RuleModule;
|
| 113 |
+
'sort-comp': import("eslint").Rule.RuleModule;
|
| 114 |
+
'sort-default-props': import("eslint").Rule.RuleModule;
|
| 115 |
+
'sort-prop-types': import("eslint").Rule.RuleModule;
|
| 116 |
+
'state-in-constructor': import("eslint").Rule.RuleModule;
|
| 117 |
+
'static-property-placement': import("eslint").Rule.RuleModule;
|
| 118 |
+
'style-prop-object': import("eslint").Rule.RuleModule;
|
| 119 |
+
'void-dom-elements-no-children': import("eslint").Rule.RuleModule;
|
| 120 |
+
};
|
| 121 |
+
declare const configs: {
|
| 122 |
+
recommended: {
|
| 123 |
+
plugins: ["react"];
|
| 124 |
+
parserOptions: {
|
| 125 |
+
ecmaFeatures: {
|
| 126 |
+
jsx: boolean;
|
| 127 |
+
};
|
| 128 |
+
};
|
| 129 |
+
rules: {
|
| 130 |
+
'react/display-name': 2;
|
| 131 |
+
'react/jsx-key': 2;
|
| 132 |
+
'react/jsx-no-comment-textnodes': 2;
|
| 133 |
+
'react/jsx-no-duplicate-props': 2;
|
| 134 |
+
'react/jsx-no-target-blank': 2;
|
| 135 |
+
'react/jsx-no-undef': 2;
|
| 136 |
+
'react/jsx-uses-react': 2;
|
| 137 |
+
'react/jsx-uses-vars': 2;
|
| 138 |
+
'react/no-children-prop': 2;
|
| 139 |
+
'react/no-danger-with-children': 2;
|
| 140 |
+
'react/no-deprecated': 2;
|
| 141 |
+
'react/no-direct-mutation-state': 2;
|
| 142 |
+
'react/no-find-dom-node': 2;
|
| 143 |
+
'react/no-is-mounted': 2;
|
| 144 |
+
'react/no-render-return-value': 2;
|
| 145 |
+
'react/no-string-refs': 2;
|
| 146 |
+
'react/no-unescaped-entities': 2;
|
| 147 |
+
'react/no-unknown-property': 2;
|
| 148 |
+
'react/no-unsafe': 0;
|
| 149 |
+
'react/prop-types': 2;
|
| 150 |
+
'react/react-in-jsx-scope': 2;
|
| 151 |
+
'react/require-render-return': 2;
|
| 152 |
+
};
|
| 153 |
+
};
|
| 154 |
+
all: {
|
| 155 |
+
plugins: ["react"];
|
| 156 |
+
parserOptions: {
|
| 157 |
+
ecmaFeatures: {
|
| 158 |
+
jsx: boolean;
|
| 159 |
+
};
|
| 160 |
+
};
|
| 161 |
+
rules: Record<"boolean-prop-naming" | "button-has-type" | "checked-requires-onchange-or-readonly" | "default-props-match-prop-types" | "destructuring-assignment" | "display-name" | "forbid-component-props" | "forbid-dom-props" | "forbid-elements" | "forbid-foreign-prop-types" | "forbid-prop-types" | "prop-types" | "forward-ref-uses-ref" | "function-component-definition" | "hook-use-state" | "iframe-missing-sandbox" | "jsx-boolean-value" | "jsx-child-element-spacing" | "jsx-closing-bracket-location" | "jsx-closing-tag-location" | "jsx-curly-spacing" | "jsx-curly-newline" | "jsx-equals-spacing" | "jsx-filename-extension" | "jsx-first-prop-new-line" | "jsx-handler-names" | "jsx-indent" | "jsx-indent-props" | "jsx-key" | "jsx-max-depth" | "jsx-max-props-per-line" | "jsx-newline" | "jsx-no-bind" | "jsx-no-comment-textnodes" | "jsx-no-constructed-context-values" | "jsx-no-duplicate-props" | "jsx-no-leaked-render" | "jsx-no-literals" | "jsx-no-script-url" | "jsx-no-target-blank" | "jsx-no-useless-fragment" | "jsx-one-expression-per-line" | "jsx-no-undef" | "jsx-curly-brace-presence" | "jsx-pascal-case" | "jsx-fragments" | "jsx-props-no-multi-spaces" | "jsx-props-no-spreading" | "jsx-props-no-spread-multi" | "sort-default-props" | "jsx-sort-default-props" | "jsx-sort-props" | "jsx-tag-spacing" | "jsx-space-before-closing" | "jsx-uses-react" | "jsx-uses-vars" | "jsx-wrap-multilines" | "no-invalid-html-attribute" | "no-access-state-in-setstate" | "no-adjacent-inline-elements" | "no-array-index-key" | "no-arrow-function-lifecycle" | "no-children-prop" | "no-danger" | "no-danger-with-children" | "no-deprecated" | "no-direct-mutation-state" | "no-find-dom-node" | "no-is-mounted" | "no-multi-comp" | "no-namespace" | "no-set-state" | "no-string-refs" | "no-redundant-should-component-update" | "no-render-return-value" | "no-this-in-sfc" | "no-typos" | "no-unescaped-entities" | "no-unknown-property" | "no-unsafe" | "no-unstable-nested-components" | "no-unused-class-component-methods" | "no-unused-prop-types" | "no-unused-state" | "no-object-type-as-default-prop" | "prefer-es6-class" | "prefer-exact-props" | "prefer-read-only-props" | "prefer-stateless-function" | "react-in-jsx-scope" | "require-default-props" | "require-optimization" | "require-render-return" | "self-closing-comp" | "sort-comp" | "sort-prop-types" | "state-in-constructor" | "static-property-placement" | "style-prop-object" | "void-dom-elements-no-children" | "no-did-mount-set-state" | "no-did-update-set-state" | "no-will-update-set-state", 2 | "error">;
|
| 162 |
+
};
|
| 163 |
+
'jsx-runtime': {
|
| 164 |
+
plugins: ["react"];
|
| 165 |
+
parserOptions: {
|
| 166 |
+
ecmaFeatures: {
|
| 167 |
+
jsx: boolean;
|
| 168 |
+
};
|
| 169 |
+
jsxPragma: any;
|
| 170 |
+
};
|
| 171 |
+
rules: {
|
| 172 |
+
'react/react-in-jsx-scope': 0;
|
| 173 |
+
'react/jsx-uses-react': 0;
|
| 174 |
+
};
|
| 175 |
+
};
|
| 176 |
+
flat: Record<string, ReactFlatConfig>;
|
| 177 |
+
};
|
| 178 |
+
type ReactFlatConfig = {
|
| 179 |
+
plugins: {
|
| 180 |
+
react: typeof plugin;
|
| 181 |
+
};
|
| 182 |
+
rules: import('eslint').Linter.RulesRecord;
|
| 183 |
+
languageOptions: {
|
| 184 |
+
parserOptions: import('eslint').Linter.ParserOptions;
|
| 185 |
+
};
|
| 186 |
+
};
|
| 187 |
+
//# sourceMappingURL=index.d.ts.map
|
node_modules/eslint-plugin-react/index.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.js"],"names":[],"mappings":";AAiGA,8LAA8L;AAE9L,sJAAsJ;AACtJ,sBADW;IAAE,eAAe,EAAE,OAAO,eAAe,CAAC;IAAC,KAAK,EAAE,OAAO,QAAQ,CAAC;IAAC,OAAO,EAAE,OAAO,OAAO,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;KAAE,CAAA;CAAC,CAKhJ;;;;AAhFF,uCAAuC;AACvC,+BADW,OAAO,CAAC,OAAO,QAAQ,CAAC,CAC2C;AApB9E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAwC;AAgCxC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAuDmB,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC;EAGhD;;aAEuB;QAAE,KAAK,EAAE,OAAO,MAAM,CAAA;KAAE;WAAS,OAAO,QAAQ,EAAE,MAAM,CAAC,WAAW;qBAAmB;QAAE,aAAa,EAAE,OAAO,QAAQ,EAAE,MAAM,CAAC,aAAa,CAAA;KAAE"}
|
node_modules/eslint-plugin-react/index.js
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
'use strict';
|
| 2 |
+
|
| 3 |
+
const fromEntries = require('object.fromentries');
|
| 4 |
+
const entries = require('object.entries');
|
| 5 |
+
|
| 6 |
+
const allRules = require('./lib/rules');
|
| 7 |
+
|
| 8 |
+
function filterRules(rules, predicate) {
|
| 9 |
+
return fromEntries(entries(rules).filter((entry) => predicate(entry[1])));
|
| 10 |
+
}
|
| 11 |
+
|
| 12 |
+
/**
|
| 13 |
+
* @param {object} rules - rules object mapping rule name to rule module
|
| 14 |
+
* @returns {Record<string, SEVERITY_ERROR | 'error'>}
|
| 15 |
+
*/
|
| 16 |
+
function configureAsError(rules) {
|
| 17 |
+
return fromEntries(Object.keys(rules).map((key) => [`react/${key}`, 2]));
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
/** @type {Partial<typeof allRules>} */
|
| 21 |
+
const activeRules = filterRules(allRules, (rule) => !rule.meta.deprecated);
|
| 22 |
+
/** @type {Record<keyof typeof activeRules, 2 | 'error'>} */
|
| 23 |
+
const activeRulesConfig = configureAsError(activeRules);
|
| 24 |
+
|
| 25 |
+
/** @type {Partial<typeof allRules>} */
|
| 26 |
+
const deprecatedRules = filterRules(allRules, (rule) => rule.meta.deprecated);
|
| 27 |
+
|
| 28 |
+
/** @type {['react']} */
|
| 29 |
+
// for legacy config system
|
| 30 |
+
const plugins = [
|
| 31 |
+
'react',
|
| 32 |
+
];
|
| 33 |
+
|
| 34 |
+
// TODO: with TS 4.5+, inline this
|
| 35 |
+
const SEVERITY_ERROR = /** @type {2} */ (2);
|
| 36 |
+
const SEVERITY_OFF = /** @type {0} */ (0);
|
| 37 |
+
|
| 38 |
+
const configs = {
|
| 39 |
+
recommended: {
|
| 40 |
+
plugins,
|
| 41 |
+
parserOptions: {
|
| 42 |
+
ecmaFeatures: {
|
| 43 |
+
jsx: true,
|
| 44 |
+
},
|
| 45 |
+
},
|
| 46 |
+
rules: {
|
| 47 |
+
'react/display-name': SEVERITY_ERROR,
|
| 48 |
+
'react/jsx-key': SEVERITY_ERROR,
|
| 49 |
+
'react/jsx-no-comment-textnodes': SEVERITY_ERROR,
|
| 50 |
+
'react/jsx-no-duplicate-props': SEVERITY_ERROR,
|
| 51 |
+
'react/jsx-no-target-blank': SEVERITY_ERROR,
|
| 52 |
+
'react/jsx-no-undef': SEVERITY_ERROR,
|
| 53 |
+
'react/jsx-uses-react': SEVERITY_ERROR,
|
| 54 |
+
'react/jsx-uses-vars': SEVERITY_ERROR,
|
| 55 |
+
'react/no-children-prop': SEVERITY_ERROR,
|
| 56 |
+
'react/no-danger-with-children': SEVERITY_ERROR,
|
| 57 |
+
'react/no-deprecated': SEVERITY_ERROR,
|
| 58 |
+
'react/no-direct-mutation-state': SEVERITY_ERROR,
|
| 59 |
+
'react/no-find-dom-node': SEVERITY_ERROR,
|
| 60 |
+
'react/no-is-mounted': SEVERITY_ERROR,
|
| 61 |
+
'react/no-render-return-value': SEVERITY_ERROR,
|
| 62 |
+
'react/no-string-refs': SEVERITY_ERROR,
|
| 63 |
+
'react/no-unescaped-entities': SEVERITY_ERROR,
|
| 64 |
+
'react/no-unknown-property': SEVERITY_ERROR,
|
| 65 |
+
'react/no-unsafe': SEVERITY_OFF,
|
| 66 |
+
'react/prop-types': SEVERITY_ERROR,
|
| 67 |
+
'react/react-in-jsx-scope': SEVERITY_ERROR,
|
| 68 |
+
'react/require-render-return': SEVERITY_ERROR,
|
| 69 |
+
},
|
| 70 |
+
},
|
| 71 |
+
all: {
|
| 72 |
+
plugins,
|
| 73 |
+
parserOptions: {
|
| 74 |
+
ecmaFeatures: {
|
| 75 |
+
jsx: true,
|
| 76 |
+
},
|
| 77 |
+
},
|
| 78 |
+
rules: activeRulesConfig,
|
| 79 |
+
},
|
| 80 |
+
'jsx-runtime': {
|
| 81 |
+
plugins,
|
| 82 |
+
parserOptions: {
|
| 83 |
+
ecmaFeatures: {
|
| 84 |
+
jsx: true,
|
| 85 |
+
},
|
| 86 |
+
jsxPragma: null, // for @typescript/eslint-parser
|
| 87 |
+
},
|
| 88 |
+
rules: {
|
| 89 |
+
'react/react-in-jsx-scope': SEVERITY_OFF,
|
| 90 |
+
'react/jsx-uses-react': SEVERITY_OFF,
|
| 91 |
+
},
|
| 92 |
+
},
|
| 93 |
+
flat: /** @type {Record<string, ReactFlatConfig>} */ ({
|
| 94 |
+
__proto__: null,
|
| 95 |
+
}),
|
| 96 |
+
};
|
| 97 |
+
|
| 98 |
+
/** @typedef {{ plugins: { react: typeof plugin }, rules: import('eslint').Linter.RulesRecord, languageOptions: { parserOptions: import('eslint').Linter.ParserOptions } }} ReactFlatConfig */
|
| 99 |
+
|
| 100 |
+
/** @type {{ deprecatedRules: typeof deprecatedRules, rules: typeof allRules, configs: typeof configs & { flat: Record<string, ReactFlatConfig> }}} */
|
| 101 |
+
const plugin = {
|
| 102 |
+
deprecatedRules,
|
| 103 |
+
rules: allRules,
|
| 104 |
+
configs,
|
| 105 |
+
};
|
| 106 |
+
|
| 107 |
+
Object.assign(configs.flat, {
|
| 108 |
+
recommended: {
|
| 109 |
+
plugins: { react: plugin },
|
| 110 |
+
rules: configs.recommended.rules,
|
| 111 |
+
languageOptions: { parserOptions: configs.recommended.parserOptions },
|
| 112 |
+
},
|
| 113 |
+
all: {
|
| 114 |
+
plugins: { react: plugin },
|
| 115 |
+
rules: configs.all.rules,
|
| 116 |
+
languageOptions: { parserOptions: configs.all.parserOptions },
|
| 117 |
+
},
|
| 118 |
+
'jsx-runtime': {
|
| 119 |
+
plugins: { react: plugin },
|
| 120 |
+
rules: configs['jsx-runtime'].rules,
|
| 121 |
+
languageOptions: { parserOptions: configs['jsx-runtime'].parserOptions },
|
| 122 |
+
},
|
| 123 |
+
});
|
| 124 |
+
|
| 125 |
+
module.exports = plugin;
|
node_modules/eslint-plugin-react/lib/rules/boolean-prop-naming.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
declare const _exports: import('eslint').Rule.RuleModule;
|
| 2 |
+
export = _exports;
|
| 3 |
+
//# sourceMappingURL=boolean-prop-naming.d.ts.map
|
node_modules/eslint-plugin-react/lib/rules/boolean-prop-naming.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"boolean-prop-naming.d.ts","sourceRoot":"","sources":["boolean-prop-naming.js"],"names":[],"mappings":"wBAyCW,OAAO,QAAQ,EAAE,IAAI,CAAC,UAAU"}
|
node_modules/eslint-plugin-react/lib/rules/boolean-prop-naming.js
ADDED
|
@@ -0,0 +1,426 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* @fileoverview Enforces consistent naming for boolean props
|
| 3 |
+
* @author Ev Haus
|
| 4 |
+
*/
|
| 5 |
+
|
| 6 |
+
'use strict';
|
| 7 |
+
|
| 8 |
+
const flatMap = require('array.prototype.flatmap');
|
| 9 |
+
const values = require('object.values');
|
| 10 |
+
|
| 11 |
+
const Components = require('../util/Components');
|
| 12 |
+
const propsUtil = require('../util/props');
|
| 13 |
+
const astUtil = require('../util/ast');
|
| 14 |
+
const docsUrl = require('../util/docsUrl');
|
| 15 |
+
const propWrapperUtil = require('../util/propWrapper');
|
| 16 |
+
const report = require('../util/report');
|
| 17 |
+
const eslintUtil = require('../util/eslint');
|
| 18 |
+
|
| 19 |
+
const getSourceCode = eslintUtil.getSourceCode;
|
| 20 |
+
const getText = eslintUtil.getText;
|
| 21 |
+
|
| 22 |
+
/**
|
| 23 |
+
* Checks if prop is nested
|
| 24 |
+
* @param {Object} prop Property object, single prop type declaration
|
| 25 |
+
* @returns {boolean}
|
| 26 |
+
*/
|
| 27 |
+
function nestedPropTypes(prop) {
|
| 28 |
+
return (
|
| 29 |
+
prop.type === 'Property'
|
| 30 |
+
&& astUtil.isCallExpression(prop.value)
|
| 31 |
+
);
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
// ------------------------------------------------------------------------------
|
| 35 |
+
// Rule Definition
|
| 36 |
+
// ------------------------------------------------------------------------------
|
| 37 |
+
|
| 38 |
+
const messages = {
|
| 39 |
+
patternMismatch: 'Prop name `{{propName}}` doesn’t match rule `{{pattern}}`',
|
| 40 |
+
};
|
| 41 |
+
|
| 42 |
+
/** @type {import('eslint').Rule.RuleModule} */
|
| 43 |
+
module.exports = {
|
| 44 |
+
meta: {
|
| 45 |
+
docs: {
|
| 46 |
+
category: 'Stylistic Issues',
|
| 47 |
+
description: 'Enforces consistent naming for boolean props',
|
| 48 |
+
recommended: false,
|
| 49 |
+
url: docsUrl('boolean-prop-naming'),
|
| 50 |
+
},
|
| 51 |
+
|
| 52 |
+
messages,
|
| 53 |
+
|
| 54 |
+
schema: [{
|
| 55 |
+
additionalProperties: false,
|
| 56 |
+
properties: {
|
| 57 |
+
propTypeNames: {
|
| 58 |
+
items: {
|
| 59 |
+
type: 'string',
|
| 60 |
+
},
|
| 61 |
+
minItems: 1,
|
| 62 |
+
type: 'array',
|
| 63 |
+
uniqueItems: true,
|
| 64 |
+
},
|
| 65 |
+
rule: {
|
| 66 |
+
default: '^(is|has)[A-Z]([A-Za-z0-9]?)+',
|
| 67 |
+
minLength: 1,
|
| 68 |
+
type: 'string',
|
| 69 |
+
},
|
| 70 |
+
message: {
|
| 71 |
+
minLength: 1,
|
| 72 |
+
type: 'string',
|
| 73 |
+
},
|
| 74 |
+
validateNested: {
|
| 75 |
+
default: false,
|
| 76 |
+
type: 'boolean',
|
| 77 |
+
},
|
| 78 |
+
},
|
| 79 |
+
type: 'object',
|
| 80 |
+
}],
|
| 81 |
+
},
|
| 82 |
+
|
| 83 |
+
create: Components.detect((context, components, utils) => {
|
| 84 |
+
const config = context.options[0] || {};
|
| 85 |
+
const rule = config.rule ? new RegExp(config.rule) : null;
|
| 86 |
+
const propTypeNames = config.propTypeNames || ['bool'];
|
| 87 |
+
|
| 88 |
+
// Remembers all Flowtype object definitions
|
| 89 |
+
const objectTypeAnnotations = new Map();
|
| 90 |
+
|
| 91 |
+
/**
|
| 92 |
+
* Returns the prop key to ensure we handle the following cases:
|
| 93 |
+
* propTypes: {
|
| 94 |
+
* full: React.PropTypes.bool,
|
| 95 |
+
* short: PropTypes.bool,
|
| 96 |
+
* direct: bool,
|
| 97 |
+
* required: PropTypes.bool.isRequired
|
| 98 |
+
* }
|
| 99 |
+
* @param {Object} node The node we're getting the name of
|
| 100 |
+
* @returns {string | null}
|
| 101 |
+
*/
|
| 102 |
+
function getPropKey(node) {
|
| 103 |
+
// Check for `ExperimentalSpreadProperty` (eslint 3/4) and `SpreadElement` (eslint 5)
|
| 104 |
+
// so we can skip validation of those fields.
|
| 105 |
+
// Otherwise it will look for `node.value.property` which doesn't exist and breaks eslint.
|
| 106 |
+
if (node.type === 'ExperimentalSpreadProperty' || node.type === 'SpreadElement') {
|
| 107 |
+
return null;
|
| 108 |
+
}
|
| 109 |
+
if (node.value && node.value.property) {
|
| 110 |
+
const name = node.value.property.name;
|
| 111 |
+
if (name === 'isRequired') {
|
| 112 |
+
if (node.value.object && node.value.object.property) {
|
| 113 |
+
return node.value.object.property.name;
|
| 114 |
+
}
|
| 115 |
+
return null;
|
| 116 |
+
}
|
| 117 |
+
return name;
|
| 118 |
+
}
|
| 119 |
+
if (node.value && node.value.type === 'Identifier') {
|
| 120 |
+
return node.value.name;
|
| 121 |
+
}
|
| 122 |
+
return null;
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
/**
|
| 126 |
+
* Returns the name of the given node (prop)
|
| 127 |
+
* @param {Object} node The node we're getting the name of
|
| 128 |
+
* @returns {string}
|
| 129 |
+
*/
|
| 130 |
+
function getPropName(node) {
|
| 131 |
+
// Due to this bug https://github.com/babel/babel-eslint/issues/307
|
| 132 |
+
// we can't get the name of the Flow object key name. So we have
|
| 133 |
+
// to hack around it for now.
|
| 134 |
+
if (node.type === 'ObjectTypeProperty') {
|
| 135 |
+
return getSourceCode(context).getFirstToken(node).value;
|
| 136 |
+
}
|
| 137 |
+
|
| 138 |
+
return node.key.name;
|
| 139 |
+
}
|
| 140 |
+
|
| 141 |
+
/**
|
| 142 |
+
* Checks if prop is declared in flow way
|
| 143 |
+
* @param {Object} prop Property object, single prop type declaration
|
| 144 |
+
* @returns {boolean}
|
| 145 |
+
*/
|
| 146 |
+
function flowCheck(prop) {
|
| 147 |
+
return (
|
| 148 |
+
prop.type === 'ObjectTypeProperty'
|
| 149 |
+
&& prop.value.type === 'BooleanTypeAnnotation'
|
| 150 |
+
&& rule.test(getPropName(prop)) === false
|
| 151 |
+
);
|
| 152 |
+
}
|
| 153 |
+
|
| 154 |
+
/**
|
| 155 |
+
* Checks if prop is declared in regular way
|
| 156 |
+
* @param {Object} prop Property object, single prop type declaration
|
| 157 |
+
* @returns {boolean}
|
| 158 |
+
*/
|
| 159 |
+
function regularCheck(prop) {
|
| 160 |
+
const propKey = getPropKey(prop);
|
| 161 |
+
return (
|
| 162 |
+
propKey
|
| 163 |
+
&& propTypeNames.indexOf(propKey) >= 0
|
| 164 |
+
&& rule.test(getPropName(prop)) === false
|
| 165 |
+
);
|
| 166 |
+
}
|
| 167 |
+
|
| 168 |
+
function tsCheck(prop) {
|
| 169 |
+
if (prop.type !== 'TSPropertySignature') return false;
|
| 170 |
+
const typeAnnotation = (prop.typeAnnotation || {}).typeAnnotation;
|
| 171 |
+
return (
|
| 172 |
+
typeAnnotation
|
| 173 |
+
&& typeAnnotation.type === 'TSBooleanKeyword'
|
| 174 |
+
&& rule.test(getPropName(prop)) === false
|
| 175 |
+
);
|
| 176 |
+
}
|
| 177 |
+
|
| 178 |
+
/**
|
| 179 |
+
* Runs recursive check on all proptypes
|
| 180 |
+
* @param {Array} proptypes A list of Property object (for each proptype defined)
|
| 181 |
+
* @param {Function} addInvalidProp callback to run for each error
|
| 182 |
+
*/
|
| 183 |
+
function runCheck(proptypes, addInvalidProp) {
|
| 184 |
+
if (proptypes) {
|
| 185 |
+
proptypes.forEach((prop) => {
|
| 186 |
+
if (config.validateNested && nestedPropTypes(prop)) {
|
| 187 |
+
runCheck(prop.value.arguments[0].properties, addInvalidProp);
|
| 188 |
+
return;
|
| 189 |
+
}
|
| 190 |
+
if (flowCheck(prop) || regularCheck(prop) || tsCheck(prop)) {
|
| 191 |
+
addInvalidProp(prop);
|
| 192 |
+
}
|
| 193 |
+
});
|
| 194 |
+
}
|
| 195 |
+
}
|
| 196 |
+
|
| 197 |
+
/**
|
| 198 |
+
* Checks and mark props with invalid naming
|
| 199 |
+
* @param {Object} node The component node we're testing
|
| 200 |
+
* @param {Array} proptypes A list of Property object (for each proptype defined)
|
| 201 |
+
*/
|
| 202 |
+
function validatePropNaming(node, proptypes) {
|
| 203 |
+
const component = components.get(node) || node;
|
| 204 |
+
const invalidProps = component.invalidProps || [];
|
| 205 |
+
|
| 206 |
+
runCheck(proptypes, (prop) => {
|
| 207 |
+
invalidProps.push(prop);
|
| 208 |
+
});
|
| 209 |
+
|
| 210 |
+
components.set(node, {
|
| 211 |
+
invalidProps,
|
| 212 |
+
});
|
| 213 |
+
}
|
| 214 |
+
|
| 215 |
+
/**
|
| 216 |
+
* Reports invalid prop naming
|
| 217 |
+
* @param {Object} component The component to process
|
| 218 |
+
*/
|
| 219 |
+
function reportInvalidNaming(component) {
|
| 220 |
+
component.invalidProps.forEach((propNode) => {
|
| 221 |
+
const propName = getPropName(propNode);
|
| 222 |
+
report(context, config.message || messages.patternMismatch, !config.message && 'patternMismatch', {
|
| 223 |
+
node: propNode,
|
| 224 |
+
data: {
|
| 225 |
+
component: propName,
|
| 226 |
+
propName,
|
| 227 |
+
pattern: config.rule,
|
| 228 |
+
},
|
| 229 |
+
});
|
| 230 |
+
});
|
| 231 |
+
}
|
| 232 |
+
|
| 233 |
+
function checkPropWrapperArguments(node, args) {
|
| 234 |
+
if (!node || !Array.isArray(args)) {
|
| 235 |
+
return;
|
| 236 |
+
}
|
| 237 |
+
args.filter((arg) => arg.type === 'ObjectExpression').forEach((object) => validatePropNaming(node, object.properties));
|
| 238 |
+
}
|
| 239 |
+
|
| 240 |
+
function getComponentTypeAnnotation(component) {
|
| 241 |
+
// If this is a functional component that uses a global type, check it
|
| 242 |
+
if (
|
| 243 |
+
(component.node.type === 'FunctionDeclaration' || component.node.type === 'ArrowFunctionExpression')
|
| 244 |
+
&& component.node.params
|
| 245 |
+
&& component.node.params.length > 0
|
| 246 |
+
&& component.node.params[0].typeAnnotation
|
| 247 |
+
) {
|
| 248 |
+
return component.node.params[0].typeAnnotation.typeAnnotation;
|
| 249 |
+
}
|
| 250 |
+
|
| 251 |
+
if (
|
| 252 |
+
!component.node.parent
|
| 253 |
+
|| component.node.parent.type !== 'VariableDeclarator'
|
| 254 |
+
|| !component.node.parent.id
|
| 255 |
+
|| component.node.parent.id.type !== 'Identifier'
|
| 256 |
+
|| !component.node.parent.id.typeAnnotation
|
| 257 |
+
|| !component.node.parent.id.typeAnnotation.typeAnnotation
|
| 258 |
+
) {
|
| 259 |
+
return;
|
| 260 |
+
}
|
| 261 |
+
|
| 262 |
+
const annotationTypeArguments = propsUtil.getTypeArguments(
|
| 263 |
+
component.node.parent.id.typeAnnotation.typeAnnotation
|
| 264 |
+
);
|
| 265 |
+
if (
|
| 266 |
+
annotationTypeArguments && (
|
| 267 |
+
annotationTypeArguments.type === 'TSTypeParameterInstantiation'
|
| 268 |
+
|| annotationTypeArguments.type === 'TypeParameterInstantiation'
|
| 269 |
+
)
|
| 270 |
+
) {
|
| 271 |
+
return annotationTypeArguments.params.find(
|
| 272 |
+
(param) => param.type === 'TSTypeReference' || param.type === 'GenericTypeAnnotation'
|
| 273 |
+
);
|
| 274 |
+
}
|
| 275 |
+
}
|
| 276 |
+
|
| 277 |
+
function findAllTypeAnnotations(identifier, node) {
|
| 278 |
+
if (node.type === 'TSTypeLiteral' || node.type === 'ObjectTypeAnnotation' || node.type === 'TSInterfaceBody') {
|
| 279 |
+
const currentNode = [].concat(
|
| 280 |
+
objectTypeAnnotations.get(identifier.name) || [],
|
| 281 |
+
node
|
| 282 |
+
);
|
| 283 |
+
objectTypeAnnotations.set(identifier.name, currentNode);
|
| 284 |
+
} else if (
|
| 285 |
+
node.type === 'TSParenthesizedType'
|
| 286 |
+
&& (
|
| 287 |
+
node.typeAnnotation.type === 'TSIntersectionType'
|
| 288 |
+
|| node.typeAnnotation.type === 'TSUnionType'
|
| 289 |
+
)
|
| 290 |
+
) {
|
| 291 |
+
node.typeAnnotation.types.forEach((type) => {
|
| 292 |
+
findAllTypeAnnotations(identifier, type);
|
| 293 |
+
});
|
| 294 |
+
} else if (
|
| 295 |
+
node.type === 'TSIntersectionType'
|
| 296 |
+
|| node.type === 'TSUnionType'
|
| 297 |
+
|| node.type === 'IntersectionTypeAnnotation'
|
| 298 |
+
|| node.type === 'UnionTypeAnnotation'
|
| 299 |
+
) {
|
| 300 |
+
node.types.forEach((type) => {
|
| 301 |
+
findAllTypeAnnotations(identifier, type);
|
| 302 |
+
});
|
| 303 |
+
}
|
| 304 |
+
}
|
| 305 |
+
|
| 306 |
+
// --------------------------------------------------------------------------
|
| 307 |
+
// Public
|
| 308 |
+
// --------------------------------------------------------------------------
|
| 309 |
+
|
| 310 |
+
return {
|
| 311 |
+
'ClassProperty, PropertyDefinition'(node) {
|
| 312 |
+
if (!rule || !propsUtil.isPropTypesDeclaration(node)) {
|
| 313 |
+
return;
|
| 314 |
+
}
|
| 315 |
+
if (
|
| 316 |
+
node.value
|
| 317 |
+
&& astUtil.isCallExpression(node.value)
|
| 318 |
+
&& propWrapperUtil.isPropWrapperFunction(
|
| 319 |
+
context,
|
| 320 |
+
getText(context, node.value.callee)
|
| 321 |
+
)
|
| 322 |
+
) {
|
| 323 |
+
checkPropWrapperArguments(node, node.value.arguments);
|
| 324 |
+
}
|
| 325 |
+
if (node.value && node.value.properties) {
|
| 326 |
+
validatePropNaming(node, node.value.properties);
|
| 327 |
+
}
|
| 328 |
+
if (node.typeAnnotation && node.typeAnnotation.typeAnnotation) {
|
| 329 |
+
validatePropNaming(node, node.typeAnnotation.typeAnnotation.properties);
|
| 330 |
+
}
|
| 331 |
+
},
|
| 332 |
+
|
| 333 |
+
MemberExpression(node) {
|
| 334 |
+
if (!rule || !propsUtil.isPropTypesDeclaration(node)) {
|
| 335 |
+
return;
|
| 336 |
+
}
|
| 337 |
+
const component = utils.getRelatedComponent(node);
|
| 338 |
+
if (!component || !node.parent.right) {
|
| 339 |
+
return;
|
| 340 |
+
}
|
| 341 |
+
const right = node.parent.right;
|
| 342 |
+
if (
|
| 343 |
+
astUtil.isCallExpression(right)
|
| 344 |
+
&& propWrapperUtil.isPropWrapperFunction(
|
| 345 |
+
context,
|
| 346 |
+
getText(context, right.callee)
|
| 347 |
+
)
|
| 348 |
+
) {
|
| 349 |
+
checkPropWrapperArguments(component.node, right.arguments);
|
| 350 |
+
return;
|
| 351 |
+
}
|
| 352 |
+
validatePropNaming(component.node, node.parent.right.properties);
|
| 353 |
+
},
|
| 354 |
+
|
| 355 |
+
ObjectExpression(node) {
|
| 356 |
+
if (!rule) {
|
| 357 |
+
return;
|
| 358 |
+
}
|
| 359 |
+
|
| 360 |
+
// Search for the proptypes declaration
|
| 361 |
+
node.properties.forEach((property) => {
|
| 362 |
+
if (!propsUtil.isPropTypesDeclaration(property)) {
|
| 363 |
+
return;
|
| 364 |
+
}
|
| 365 |
+
validatePropNaming(node, property.value.properties);
|
| 366 |
+
});
|
| 367 |
+
},
|
| 368 |
+
|
| 369 |
+
TypeAlias(node) {
|
| 370 |
+
findAllTypeAnnotations(node.id, node.right);
|
| 371 |
+
},
|
| 372 |
+
|
| 373 |
+
TSTypeAliasDeclaration(node) {
|
| 374 |
+
findAllTypeAnnotations(node.id, node.typeAnnotation);
|
| 375 |
+
},
|
| 376 |
+
|
| 377 |
+
TSInterfaceDeclaration(node) {
|
| 378 |
+
findAllTypeAnnotations(node.id, node.body);
|
| 379 |
+
},
|
| 380 |
+
|
| 381 |
+
// eslint-disable-next-line object-shorthand
|
| 382 |
+
'Program:exit'() {
|
| 383 |
+
if (!rule) {
|
| 384 |
+
return;
|
| 385 |
+
}
|
| 386 |
+
|
| 387 |
+
values(components.list()).forEach((component) => {
|
| 388 |
+
const annotation = getComponentTypeAnnotation(component);
|
| 389 |
+
|
| 390 |
+
if (annotation) {
|
| 391 |
+
let propType;
|
| 392 |
+
if (annotation.type === 'GenericTypeAnnotation') {
|
| 393 |
+
propType = objectTypeAnnotations.get(annotation.id.name);
|
| 394 |
+
} else if (annotation.type === 'ObjectTypeAnnotation' || annotation.type === 'TSTypeLiteral') {
|
| 395 |
+
propType = annotation;
|
| 396 |
+
} else if (annotation.type === 'TSTypeReference') {
|
| 397 |
+
propType = objectTypeAnnotations.get(annotation.typeName.name);
|
| 398 |
+
} else if (annotation.type === 'TSIntersectionType') {
|
| 399 |
+
propType = flatMap(annotation.types, (type) => (
|
| 400 |
+
type.type === 'TSTypeReference'
|
| 401 |
+
? objectTypeAnnotations.get(type.typeName.name)
|
| 402 |
+
: type
|
| 403 |
+
));
|
| 404 |
+
}
|
| 405 |
+
|
| 406 |
+
if (propType) {
|
| 407 |
+
[].concat(propType).filter(Boolean).forEach((prop) => {
|
| 408 |
+
validatePropNaming(
|
| 409 |
+
component.node,
|
| 410 |
+
prop.properties || prop.members || prop.body
|
| 411 |
+
);
|
| 412 |
+
});
|
| 413 |
+
}
|
| 414 |
+
}
|
| 415 |
+
|
| 416 |
+
if (component.invalidProps && component.invalidProps.length > 0) {
|
| 417 |
+
reportInvalidNaming(component);
|
| 418 |
+
}
|
| 419 |
+
});
|
| 420 |
+
|
| 421 |
+
// Reset cache
|
| 422 |
+
objectTypeAnnotations.clear();
|
| 423 |
+
},
|
| 424 |
+
};
|
| 425 |
+
}),
|
| 426 |
+
};
|
node_modules/eslint-plugin-react/lib/rules/button-has-type.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
declare const _exports: import('eslint').Rule.RuleModule;
|
| 2 |
+
export = _exports;
|
| 3 |
+
//# sourceMappingURL=button-has-type.d.ts.map
|
node_modules/eslint-plugin-react/lib/rules/button-has-type.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"button-has-type.d.ts","sourceRoot":"","sources":["button-has-type.js"],"names":[],"mappings":"wBA8BW,OAAO,QAAQ,EAAE,IAAI,CAAC,UAAU"}
|
node_modules/eslint-plugin-react/lib/rules/button-has-type.js
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* @fileoverview Forbid "button" element without an explicit "type" attribute
|
| 3 |
+
* @author Filipp Riabchun
|
| 4 |
+
*/
|
| 5 |
+
|
| 6 |
+
'use strict';
|
| 7 |
+
|
| 8 |
+
const getProp = require('jsx-ast-utils/getProp');
|
| 9 |
+
const getLiteralPropValue = require('jsx-ast-utils/getLiteralPropValue');
|
| 10 |
+
const docsUrl = require('../util/docsUrl');
|
| 11 |
+
const isCreateElement = require('../util/isCreateElement');
|
| 12 |
+
const report = require('../util/report');
|
| 13 |
+
|
| 14 |
+
// ------------------------------------------------------------------------------
|
| 15 |
+
// Rule Definition
|
| 16 |
+
// ------------------------------------------------------------------------------
|
| 17 |
+
|
| 18 |
+
const optionDefaults = {
|
| 19 |
+
button: true,
|
| 20 |
+
submit: true,
|
| 21 |
+
reset: true,
|
| 22 |
+
};
|
| 23 |
+
|
| 24 |
+
const messages = {
|
| 25 |
+
missingType: 'Missing an explicit type attribute for button',
|
| 26 |
+
complexType: 'The button type attribute must be specified by a static string or a trivial ternary expression',
|
| 27 |
+
invalidValue: '"{{value}}" is an invalid value for button type attribute',
|
| 28 |
+
forbiddenValue: '"{{value}}" is an invalid value for button type attribute',
|
| 29 |
+
};
|
| 30 |
+
|
| 31 |
+
/** @type {import('eslint').Rule.RuleModule} */
|
| 32 |
+
module.exports = {
|
| 33 |
+
meta: {
|
| 34 |
+
docs: {
|
| 35 |
+
description: 'Disallow usage of `button` elements without an explicit `type` attribute',
|
| 36 |
+
category: 'Possible Errors',
|
| 37 |
+
recommended: false,
|
| 38 |
+
url: docsUrl('button-has-type'),
|
| 39 |
+
},
|
| 40 |
+
|
| 41 |
+
messages,
|
| 42 |
+
|
| 43 |
+
schema: [{
|
| 44 |
+
type: 'object',
|
| 45 |
+
properties: {
|
| 46 |
+
button: {
|
| 47 |
+
default: optionDefaults.button,
|
| 48 |
+
type: 'boolean',
|
| 49 |
+
},
|
| 50 |
+
submit: {
|
| 51 |
+
default: optionDefaults.submit,
|
| 52 |
+
type: 'boolean',
|
| 53 |
+
},
|
| 54 |
+
reset: {
|
| 55 |
+
default: optionDefaults.reset,
|
| 56 |
+
type: 'boolean',
|
| 57 |
+
},
|
| 58 |
+
},
|
| 59 |
+
additionalProperties: false,
|
| 60 |
+
}],
|
| 61 |
+
},
|
| 62 |
+
|
| 63 |
+
create(context) {
|
| 64 |
+
const configuration = Object.assign({}, optionDefaults, context.options[0]);
|
| 65 |
+
|
| 66 |
+
function reportMissing(node) {
|
| 67 |
+
report(context, messages.missingType, 'missingType', {
|
| 68 |
+
node,
|
| 69 |
+
});
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
function reportComplex(node) {
|
| 73 |
+
report(context, messages.complexType, 'complexType', {
|
| 74 |
+
node,
|
| 75 |
+
});
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
function checkValue(node, value) {
|
| 79 |
+
if (!(value in configuration)) {
|
| 80 |
+
report(context, messages.invalidValue, 'invalidValue', {
|
| 81 |
+
node,
|
| 82 |
+
data: {
|
| 83 |
+
value,
|
| 84 |
+
},
|
| 85 |
+
});
|
| 86 |
+
} else if (!configuration[value]) {
|
| 87 |
+
report(context, messages.forbiddenValue, 'forbiddenValue', {
|
| 88 |
+
node,
|
| 89 |
+
data: {
|
| 90 |
+
value,
|
| 91 |
+
},
|
| 92 |
+
});
|
| 93 |
+
}
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
function checkExpression(node, expression) {
|
| 97 |
+
switch (expression.type) {
|
| 98 |
+
case 'Literal':
|
| 99 |
+
checkValue(node, expression.value);
|
| 100 |
+
return;
|
| 101 |
+
case 'TemplateLiteral':
|
| 102 |
+
if (expression.expressions.length === 0) {
|
| 103 |
+
checkValue(node, expression.quasis[0].value.raw);
|
| 104 |
+
} else {
|
| 105 |
+
reportComplex(expression);
|
| 106 |
+
}
|
| 107 |
+
return;
|
| 108 |
+
case 'ConditionalExpression':
|
| 109 |
+
checkExpression(node, expression.consequent);
|
| 110 |
+
checkExpression(node, expression.alternate);
|
| 111 |
+
return;
|
| 112 |
+
default:
|
| 113 |
+
reportComplex(expression);
|
| 114 |
+
}
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
return {
|
| 118 |
+
JSXElement(node) {
|
| 119 |
+
if (node.openingElement.name.name !== 'button') {
|
| 120 |
+
return;
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
const typeProp = getProp(node.openingElement.attributes, 'type');
|
| 124 |
+
|
| 125 |
+
if (!typeProp) {
|
| 126 |
+
reportMissing(node);
|
| 127 |
+
return;
|
| 128 |
+
}
|
| 129 |
+
|
| 130 |
+
if (typeProp.value && typeProp.value.type === 'JSXExpressionContainer') {
|
| 131 |
+
checkExpression(node, typeProp.value.expression);
|
| 132 |
+
return;
|
| 133 |
+
}
|
| 134 |
+
|
| 135 |
+
const propValue = getLiteralPropValue(typeProp);
|
| 136 |
+
checkValue(node, propValue);
|
| 137 |
+
},
|
| 138 |
+
CallExpression(node) {
|
| 139 |
+
if (!isCreateElement(context, node) || node.arguments.length < 1) {
|
| 140 |
+
return;
|
| 141 |
+
}
|
| 142 |
+
|
| 143 |
+
if (node.arguments[0].type !== 'Literal' || node.arguments[0].value !== 'button') {
|
| 144 |
+
return;
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
if (!node.arguments[1] || node.arguments[1].type !== 'ObjectExpression') {
|
| 148 |
+
reportMissing(node);
|
| 149 |
+
return;
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
const props = node.arguments[1].properties;
|
| 153 |
+
const typeProp = props.find((prop) => (
|
| 154 |
+
'key' in prop
|
| 155 |
+
&& prop.key
|
| 156 |
+
&& 'name' in prop.key
|
| 157 |
+
&& prop.key.name === 'type'
|
| 158 |
+
));
|
| 159 |
+
|
| 160 |
+
if (!typeProp) {
|
| 161 |
+
reportMissing(node);
|
| 162 |
+
return;
|
| 163 |
+
}
|
| 164 |
+
|
| 165 |
+
checkExpression(node, 'value' in typeProp ? typeProp.value : undefined);
|
| 166 |
+
},
|
| 167 |
+
};
|
| 168 |
+
},
|
| 169 |
+
};
|
node_modules/eslint-plugin-react/lib/rules/checked-requires-onchange-or-readonly.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
declare const _exports: import('eslint').Rule.RuleModule;
|
| 2 |
+
export = _exports;
|
| 3 |
+
//# sourceMappingURL=checked-requires-onchange-or-readonly.d.ts.map
|
node_modules/eslint-plugin-react/lib/rules/checked-requires-onchange-or-readonly.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"checked-requires-onchange-or-readonly.d.ts","sourceRoot":"","sources":["checked-requires-onchange-or-readonly.js"],"names":[],"mappings":"wBA2CW,OAAO,QAAQ,EAAE,IAAI,CAAC,UAAU"}
|
node_modules/eslint-plugin-react/lib/rules/checked-requires-onchange-or-readonly.js
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* @fileoverview Enforce the use of the 'onChange' or 'readonly' attribute when 'checked' is used'
|
| 3 |
+
* @author Jaesoekjjang
|
| 4 |
+
*/
|
| 5 |
+
|
| 6 |
+
'use strict';
|
| 7 |
+
|
| 8 |
+
const ASTUtils = require('jsx-ast-utils');
|
| 9 |
+
const flatMap = require('array.prototype.flatmap');
|
| 10 |
+
const isCreateElement = require('../util/isCreateElement');
|
| 11 |
+
const report = require('../util/report');
|
| 12 |
+
const docsUrl = require('../util/docsUrl');
|
| 13 |
+
|
| 14 |
+
const messages = {
|
| 15 |
+
missingProperty: '`checked` should be used with either `onChange` or `readOnly`.',
|
| 16 |
+
exclusiveCheckedAttribute: 'Use either `checked` or `defaultChecked`, but not both.',
|
| 17 |
+
};
|
| 18 |
+
|
| 19 |
+
const targetPropSet = new Set(['checked', 'onChange', 'readOnly', 'defaultChecked']);
|
| 20 |
+
|
| 21 |
+
const defaultOptions = {
|
| 22 |
+
ignoreMissingProperties: false,
|
| 23 |
+
ignoreExclusiveCheckedAttribute: false,
|
| 24 |
+
};
|
| 25 |
+
|
| 26 |
+
/**
|
| 27 |
+
* @param {object[]} properties
|
| 28 |
+
* @param {string} keyName
|
| 29 |
+
* @returns {Set<string>}
|
| 30 |
+
*/
|
| 31 |
+
function extractTargetProps(properties, keyName) {
|
| 32 |
+
return new Set(
|
| 33 |
+
flatMap(
|
| 34 |
+
properties,
|
| 35 |
+
(prop) => (
|
| 36 |
+
prop[keyName] && targetPropSet.has(prop[keyName].name)
|
| 37 |
+
? [prop[keyName].name]
|
| 38 |
+
: []
|
| 39 |
+
)
|
| 40 |
+
)
|
| 41 |
+
);
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
/** @type {import('eslint').Rule.RuleModule} */
|
| 45 |
+
module.exports = {
|
| 46 |
+
meta: {
|
| 47 |
+
docs: {
|
| 48 |
+
description: 'Enforce using `onChange` or `readonly` attribute when `checked` is used',
|
| 49 |
+
category: 'Best Practices',
|
| 50 |
+
recommended: false,
|
| 51 |
+
url: docsUrl('checked-requires-onchange-or-readonly'),
|
| 52 |
+
},
|
| 53 |
+
messages,
|
| 54 |
+
schema: [{
|
| 55 |
+
additionalProperties: false,
|
| 56 |
+
properties: {
|
| 57 |
+
ignoreMissingProperties: {
|
| 58 |
+
type: 'boolean',
|
| 59 |
+
},
|
| 60 |
+
ignoreExclusiveCheckedAttribute: {
|
| 61 |
+
type: 'boolean',
|
| 62 |
+
},
|
| 63 |
+
},
|
| 64 |
+
}],
|
| 65 |
+
},
|
| 66 |
+
create(context) {
|
| 67 |
+
const options = Object.assign({}, defaultOptions, context.options[0]);
|
| 68 |
+
|
| 69 |
+
function reportMissingProperty(node) {
|
| 70 |
+
report(
|
| 71 |
+
context,
|
| 72 |
+
messages.missingProperty,
|
| 73 |
+
'missingProperty',
|
| 74 |
+
{ node }
|
| 75 |
+
);
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
function reportExclusiveCheckedAttribute(node) {
|
| 79 |
+
report(
|
| 80 |
+
context,
|
| 81 |
+
messages.exclusiveCheckedAttribute,
|
| 82 |
+
'exclusiveCheckedAttribute',
|
| 83 |
+
{ node }
|
| 84 |
+
);
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
/**
|
| 88 |
+
* @param {ASTNode} node
|
| 89 |
+
* @param {Set<string>} propSet
|
| 90 |
+
* @returns {void}
|
| 91 |
+
*/
|
| 92 |
+
const checkAttributesAndReport = (node, propSet) => {
|
| 93 |
+
if (!propSet.has('checked')) {
|
| 94 |
+
return;
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
if (!options.ignoreExclusiveCheckedAttribute && propSet.has('defaultChecked')) {
|
| 98 |
+
reportExclusiveCheckedAttribute(node);
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
+
if (
|
| 102 |
+
!options.ignoreMissingProperties
|
| 103 |
+
&& !(propSet.has('onChange') || propSet.has('readOnly'))
|
| 104 |
+
) {
|
| 105 |
+
reportMissingProperty(node);
|
| 106 |
+
}
|
| 107 |
+
};
|
| 108 |
+
|
| 109 |
+
return {
|
| 110 |
+
JSXOpeningElement(node) {
|
| 111 |
+
if (ASTUtils.elementType(node) !== 'input') {
|
| 112 |
+
return;
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
const propSet = extractTargetProps(node.attributes, 'name');
|
| 116 |
+
checkAttributesAndReport(node, propSet);
|
| 117 |
+
},
|
| 118 |
+
CallExpression(node) {
|
| 119 |
+
if (!isCreateElement(context, node)) {
|
| 120 |
+
return;
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
const firstArg = node.arguments[0];
|
| 124 |
+
const secondArg = node.arguments[1];
|
| 125 |
+
if (
|
| 126 |
+
!firstArg
|
| 127 |
+
|| firstArg.type !== 'Literal'
|
| 128 |
+
|| firstArg.value !== 'input'
|
| 129 |
+
) {
|
| 130 |
+
return;
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
if (!secondArg || secondArg.type !== 'ObjectExpression') {
|
| 134 |
+
return;
|
| 135 |
+
}
|
| 136 |
+
|
| 137 |
+
const propSet = extractTargetProps(secondArg.properties, 'key');
|
| 138 |
+
checkAttributesAndReport(node, propSet);
|
| 139 |
+
},
|
| 140 |
+
};
|
| 141 |
+
},
|
| 142 |
+
};
|
node_modules/eslint-plugin-react/lib/rules/default-props-match-prop-types.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
declare const _exports: import('eslint').Rule.RuleModule;
|
| 2 |
+
export = _exports;
|
| 3 |
+
//# sourceMappingURL=default-props-match-prop-types.d.ts.map
|
node_modules/eslint-plugin-react/lib/rules/default-props-match-prop-types.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"default-props-match-prop-types.d.ts","sourceRoot":"","sources":["default-props-match-prop-types.js"],"names":[],"mappings":"wBAuBW,OAAO,QAAQ,EAAE,IAAI,CAAC,UAAU"}
|
node_modules/eslint-plugin-react/lib/rules/default-props-match-prop-types.js
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* @fileOverview Enforce all defaultProps are defined in propTypes
|
| 3 |
+
* @author Vitor Balocco
|
| 4 |
+
* @author Roy Sutton
|
| 5 |
+
*/
|
| 6 |
+
|
| 7 |
+
'use strict';
|
| 8 |
+
|
| 9 |
+
const values = require('object.values');
|
| 10 |
+
|
| 11 |
+
const Components = require('../util/Components');
|
| 12 |
+
const docsUrl = require('../util/docsUrl');
|
| 13 |
+
const report = require('../util/report');
|
| 14 |
+
|
| 15 |
+
// ------------------------------------------------------------------------------
|
| 16 |
+
// Rule Definition
|
| 17 |
+
// ------------------------------------------------------------------------------
|
| 18 |
+
|
| 19 |
+
const messages = {
|
| 20 |
+
requiredHasDefault: 'defaultProp "{{name}}" defined for isRequired propType.',
|
| 21 |
+
defaultHasNoType: 'defaultProp "{{name}}" has no corresponding propTypes declaration.',
|
| 22 |
+
};
|
| 23 |
+
|
| 24 |
+
/** @type {import('eslint').Rule.RuleModule} */
|
| 25 |
+
module.exports = {
|
| 26 |
+
meta: {
|
| 27 |
+
docs: {
|
| 28 |
+
description: 'Enforce all defaultProps have a corresponding non-required PropType',
|
| 29 |
+
category: 'Best Practices',
|
| 30 |
+
url: docsUrl('default-props-match-prop-types'),
|
| 31 |
+
},
|
| 32 |
+
|
| 33 |
+
messages,
|
| 34 |
+
|
| 35 |
+
schema: [{
|
| 36 |
+
type: 'object',
|
| 37 |
+
properties: {
|
| 38 |
+
allowRequiredDefaults: {
|
| 39 |
+
default: false,
|
| 40 |
+
type: 'boolean',
|
| 41 |
+
},
|
| 42 |
+
},
|
| 43 |
+
additionalProperties: false,
|
| 44 |
+
}],
|
| 45 |
+
},
|
| 46 |
+
|
| 47 |
+
create: Components.detect((context, components) => {
|
| 48 |
+
const configuration = context.options[0] || {};
|
| 49 |
+
const allowRequiredDefaults = configuration.allowRequiredDefaults || false;
|
| 50 |
+
|
| 51 |
+
/**
|
| 52 |
+
* Reports all defaultProps passed in that don't have an appropriate propTypes counterpart.
|
| 53 |
+
* @param {Object[]} propTypes Array of propTypes to check.
|
| 54 |
+
* @param {Object} defaultProps Object of defaultProps to check. Keys are the props names.
|
| 55 |
+
* @return {void}
|
| 56 |
+
*/
|
| 57 |
+
function reportInvalidDefaultProps(propTypes, defaultProps) {
|
| 58 |
+
// If this defaultProps is "unresolved" or the propTypes is undefined, then we should ignore
|
| 59 |
+
// this component and not report any errors for it, to avoid false-positives with e.g.
|
| 60 |
+
// external defaultProps/propTypes declarations or spread operators.
|
| 61 |
+
if (defaultProps === 'unresolved' || !propTypes || Object.keys(propTypes).length === 0) {
|
| 62 |
+
return;
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
Object.keys(defaultProps).forEach((defaultPropName) => {
|
| 66 |
+
const defaultProp = defaultProps[defaultPropName];
|
| 67 |
+
const prop = propTypes[defaultPropName];
|
| 68 |
+
|
| 69 |
+
if (prop && (allowRequiredDefaults || !prop.isRequired)) {
|
| 70 |
+
return;
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
if (prop) {
|
| 74 |
+
report(context, messages.requiredHasDefault, 'requiredHasDefault', {
|
| 75 |
+
node: defaultProp.node,
|
| 76 |
+
data: {
|
| 77 |
+
name: defaultPropName,
|
| 78 |
+
},
|
| 79 |
+
});
|
| 80 |
+
} else {
|
| 81 |
+
report(context, messages.defaultHasNoType, 'defaultHasNoType', {
|
| 82 |
+
node: defaultProp.node,
|
| 83 |
+
data: {
|
| 84 |
+
name: defaultPropName,
|
| 85 |
+
},
|
| 86 |
+
});
|
| 87 |
+
}
|
| 88 |
+
});
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
// --------------------------------------------------------------------------
|
| 92 |
+
// Public API
|
| 93 |
+
// --------------------------------------------------------------------------
|
| 94 |
+
|
| 95 |
+
return {
|
| 96 |
+
'Program:exit'() {
|
| 97 |
+
// If no defaultProps could be found, we don't report anything.
|
| 98 |
+
values(components.list())
|
| 99 |
+
.filter((component) => component.defaultProps)
|
| 100 |
+
.forEach((component) => {
|
| 101 |
+
reportInvalidDefaultProps(
|
| 102 |
+
component.declaredPropTypes,
|
| 103 |
+
component.defaultProps || {}
|
| 104 |
+
);
|
| 105 |
+
});
|
| 106 |
+
},
|
| 107 |
+
};
|
| 108 |
+
}),
|
| 109 |
+
};
|
node_modules/eslint-plugin-react/lib/rules/destructuring-assignment.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
declare const _exports: import('eslint').Rule.RuleModule;
|
| 2 |
+
export = _exports;
|
| 3 |
+
//# sourceMappingURL=destructuring-assignment.d.ts.map
|
node_modules/eslint-plugin-react/lib/rules/destructuring-assignment.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"destructuring-assignment.d.ts","sourceRoot":"","sources":["destructuring-assignment.js"],"names":[],"mappings":"wBA2DW,OAAO,QAAQ,EAAE,IAAI,CAAC,UAAU"}
|
node_modules/eslint-plugin-react/lib/rules/destructuring-assignment.js
ADDED
|
@@ -0,0 +1,319 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* @fileoverview Enforce consistent usage of destructuring assignment of props, state, and context.
|
| 3 |
+
*/
|
| 4 |
+
|
| 5 |
+
'use strict';
|
| 6 |
+
|
| 7 |
+
const Components = require('../util/Components');
|
| 8 |
+
const docsUrl = require('../util/docsUrl');
|
| 9 |
+
const eslintUtil = require('../util/eslint');
|
| 10 |
+
const isAssignmentLHS = require('../util/ast').isAssignmentLHS;
|
| 11 |
+
const report = require('../util/report');
|
| 12 |
+
|
| 13 |
+
const getScope = eslintUtil.getScope;
|
| 14 |
+
const getText = eslintUtil.getText;
|
| 15 |
+
|
| 16 |
+
const DEFAULT_OPTION = 'always';
|
| 17 |
+
|
| 18 |
+
function createSFCParams() {
|
| 19 |
+
const queue = [];
|
| 20 |
+
|
| 21 |
+
return {
|
| 22 |
+
push(params) {
|
| 23 |
+
queue.unshift(params);
|
| 24 |
+
},
|
| 25 |
+
pop() {
|
| 26 |
+
queue.shift();
|
| 27 |
+
},
|
| 28 |
+
propsName() {
|
| 29 |
+
const found = queue.find((params) => {
|
| 30 |
+
const props = params[0];
|
| 31 |
+
return props && !props.destructuring && props.name;
|
| 32 |
+
});
|
| 33 |
+
return found && found[0] && found[0].name;
|
| 34 |
+
},
|
| 35 |
+
contextName() {
|
| 36 |
+
const found = queue.find((params) => {
|
| 37 |
+
const context = params[1];
|
| 38 |
+
return context && !context.destructuring && context.name;
|
| 39 |
+
});
|
| 40 |
+
return found && found[1] && found[1].name;
|
| 41 |
+
},
|
| 42 |
+
};
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
function evalParams(params) {
|
| 46 |
+
return params.map((param) => ({
|
| 47 |
+
destructuring: param.type === 'ObjectPattern',
|
| 48 |
+
name: param.type === 'Identifier' && param.name,
|
| 49 |
+
}));
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
const messages = {
|
| 53 |
+
noDestructPropsInSFCArg: 'Must never use destructuring props assignment in SFC argument',
|
| 54 |
+
noDestructContextInSFCArg: 'Must never use destructuring context assignment in SFC argument',
|
| 55 |
+
noDestructAssignment: 'Must never use destructuring {{type}} assignment',
|
| 56 |
+
useDestructAssignment: 'Must use destructuring {{type}} assignment',
|
| 57 |
+
destructureInSignature: 'Must destructure props in the function signature.',
|
| 58 |
+
};
|
| 59 |
+
|
| 60 |
+
/** @type {import('eslint').Rule.RuleModule} */
|
| 61 |
+
module.exports = {
|
| 62 |
+
meta: {
|
| 63 |
+
docs: {
|
| 64 |
+
description: 'Enforce consistent usage of destructuring assignment of props, state, and context',
|
| 65 |
+
category: 'Stylistic Issues',
|
| 66 |
+
recommended: false,
|
| 67 |
+
url: docsUrl('destructuring-assignment'),
|
| 68 |
+
},
|
| 69 |
+
fixable: 'code',
|
| 70 |
+
messages,
|
| 71 |
+
|
| 72 |
+
schema: [{
|
| 73 |
+
type: 'string',
|
| 74 |
+
enum: [
|
| 75 |
+
'always',
|
| 76 |
+
'never',
|
| 77 |
+
],
|
| 78 |
+
}, {
|
| 79 |
+
type: 'object',
|
| 80 |
+
properties: {
|
| 81 |
+
ignoreClassFields: {
|
| 82 |
+
type: 'boolean',
|
| 83 |
+
},
|
| 84 |
+
destructureInSignature: {
|
| 85 |
+
type: 'string',
|
| 86 |
+
enum: [
|
| 87 |
+
'always',
|
| 88 |
+
'ignore',
|
| 89 |
+
],
|
| 90 |
+
},
|
| 91 |
+
},
|
| 92 |
+
additionalProperties: false,
|
| 93 |
+
}],
|
| 94 |
+
},
|
| 95 |
+
|
| 96 |
+
create: Components.detect((context, components, utils) => {
|
| 97 |
+
const configuration = context.options[0] || DEFAULT_OPTION;
|
| 98 |
+
const ignoreClassFields = (context.options[1] && (context.options[1].ignoreClassFields === true)) || false;
|
| 99 |
+
const destructureInSignature = (context.options[1] && context.options[1].destructureInSignature) || 'ignore';
|
| 100 |
+
const sfcParams = createSFCParams();
|
| 101 |
+
|
| 102 |
+
/**
|
| 103 |
+
* @param {ASTNode} node We expect either an ArrowFunctionExpression,
|
| 104 |
+
* FunctionDeclaration, or FunctionExpression
|
| 105 |
+
*/
|
| 106 |
+
function handleStatelessComponent(node) {
|
| 107 |
+
const params = evalParams(node.params);
|
| 108 |
+
|
| 109 |
+
const SFCComponent = components.get(getScope(context, node).block);
|
| 110 |
+
if (!SFCComponent) {
|
| 111 |
+
return;
|
| 112 |
+
}
|
| 113 |
+
sfcParams.push(params);
|
| 114 |
+
|
| 115 |
+
if (params[0] && params[0].destructuring && components.get(node) && configuration === 'never') {
|
| 116 |
+
report(context, messages.noDestructPropsInSFCArg, 'noDestructPropsInSFCArg', {
|
| 117 |
+
node,
|
| 118 |
+
});
|
| 119 |
+
} else if (params[1] && params[1].destructuring && components.get(node) && configuration === 'never') {
|
| 120 |
+
report(context, messages.noDestructContextInSFCArg, 'noDestructContextInSFCArg', {
|
| 121 |
+
node,
|
| 122 |
+
});
|
| 123 |
+
}
|
| 124 |
+
}
|
| 125 |
+
|
| 126 |
+
function handleStatelessComponentExit(node) {
|
| 127 |
+
const SFCComponent = components.get(getScope(context, node).block);
|
| 128 |
+
if (SFCComponent) {
|
| 129 |
+
sfcParams.pop();
|
| 130 |
+
}
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
function handleSFCUsage(node) {
|
| 134 |
+
const propsName = sfcParams.propsName();
|
| 135 |
+
const contextName = sfcParams.contextName();
|
| 136 |
+
// props.aProp || context.aProp
|
| 137 |
+
const isPropUsed = (
|
| 138 |
+
(propsName && node.object.name === propsName)
|
| 139 |
+
|| (contextName && node.object.name === contextName)
|
| 140 |
+
)
|
| 141 |
+
&& !isAssignmentLHS(node);
|
| 142 |
+
if (isPropUsed && configuration === 'always' && !node.optional) {
|
| 143 |
+
report(context, messages.useDestructAssignment, 'useDestructAssignment', {
|
| 144 |
+
node,
|
| 145 |
+
data: {
|
| 146 |
+
type: node.object.name,
|
| 147 |
+
},
|
| 148 |
+
});
|
| 149 |
+
}
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
function isInClassProperty(node) {
|
| 153 |
+
let curNode = node.parent;
|
| 154 |
+
while (curNode) {
|
| 155 |
+
if (curNode.type === 'ClassProperty' || curNode.type === 'PropertyDefinition') {
|
| 156 |
+
return true;
|
| 157 |
+
}
|
| 158 |
+
curNode = curNode.parent;
|
| 159 |
+
}
|
| 160 |
+
return false;
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
function handleClassUsage(node) {
|
| 164 |
+
// this.props.Aprop || this.context.aProp || this.state.aState
|
| 165 |
+
const isPropUsed = (
|
| 166 |
+
node.object.type === 'MemberExpression' && node.object.object.type === 'ThisExpression'
|
| 167 |
+
&& (node.object.property.name === 'props' || node.object.property.name === 'context' || node.object.property.name === 'state')
|
| 168 |
+
&& !isAssignmentLHS(node)
|
| 169 |
+
);
|
| 170 |
+
|
| 171 |
+
if (
|
| 172 |
+
isPropUsed && configuration === 'always'
|
| 173 |
+
&& !(ignoreClassFields && isInClassProperty(node))
|
| 174 |
+
) {
|
| 175 |
+
report(context, messages.useDestructAssignment, 'useDestructAssignment', {
|
| 176 |
+
node,
|
| 177 |
+
data: {
|
| 178 |
+
type: node.object.property.name,
|
| 179 |
+
},
|
| 180 |
+
});
|
| 181 |
+
}
|
| 182 |
+
}
|
| 183 |
+
|
| 184 |
+
// valid-jsdoc cannot read function types
|
| 185 |
+
// eslint-disable-next-line valid-jsdoc
|
| 186 |
+
/**
|
| 187 |
+
* Find a parent that satisfy the given predicate
|
| 188 |
+
* @param {ASTNode} node
|
| 189 |
+
* @param {(node: ASTNode) => boolean} predicate
|
| 190 |
+
* @returns {ASTNode | undefined}
|
| 191 |
+
*/
|
| 192 |
+
function findParent(node, predicate) {
|
| 193 |
+
let n = node;
|
| 194 |
+
while (n) {
|
| 195 |
+
if (predicate(n)) {
|
| 196 |
+
return n;
|
| 197 |
+
}
|
| 198 |
+
n = n.parent;
|
| 199 |
+
}
|
| 200 |
+
return undefined;
|
| 201 |
+
}
|
| 202 |
+
|
| 203 |
+
return {
|
| 204 |
+
|
| 205 |
+
FunctionDeclaration: handleStatelessComponent,
|
| 206 |
+
|
| 207 |
+
ArrowFunctionExpression: handleStatelessComponent,
|
| 208 |
+
|
| 209 |
+
FunctionExpression: handleStatelessComponent,
|
| 210 |
+
|
| 211 |
+
'FunctionDeclaration:exit': handleStatelessComponentExit,
|
| 212 |
+
|
| 213 |
+
'ArrowFunctionExpression:exit': handleStatelessComponentExit,
|
| 214 |
+
|
| 215 |
+
'FunctionExpression:exit': handleStatelessComponentExit,
|
| 216 |
+
|
| 217 |
+
MemberExpression(node) {
|
| 218 |
+
const SFCComponent = utils.getParentStatelessComponent(node);
|
| 219 |
+
if (SFCComponent) {
|
| 220 |
+
handleSFCUsage(node);
|
| 221 |
+
}
|
| 222 |
+
|
| 223 |
+
const classComponent = utils.getParentComponent(node);
|
| 224 |
+
if (classComponent) {
|
| 225 |
+
handleClassUsage(node);
|
| 226 |
+
}
|
| 227 |
+
},
|
| 228 |
+
|
| 229 |
+
TSQualifiedName(node) {
|
| 230 |
+
if (configuration !== 'always') {
|
| 231 |
+
return;
|
| 232 |
+
}
|
| 233 |
+
// handle `typeof props.a.b`
|
| 234 |
+
if (node.left.type === 'Identifier'
|
| 235 |
+
&& node.left.name === sfcParams.propsName()
|
| 236 |
+
&& findParent(node, (n) => n.type === 'TSTypeQuery')
|
| 237 |
+
&& utils.getParentStatelessComponent(node)
|
| 238 |
+
) {
|
| 239 |
+
report(context, messages.useDestructAssignment, 'useDestructAssignment', {
|
| 240 |
+
node,
|
| 241 |
+
data: {
|
| 242 |
+
type: 'props',
|
| 243 |
+
},
|
| 244 |
+
});
|
| 245 |
+
}
|
| 246 |
+
},
|
| 247 |
+
|
| 248 |
+
VariableDeclarator(node) {
|
| 249 |
+
const classComponent = utils.getParentComponent(node);
|
| 250 |
+
const SFCComponent = components.get(getScope(context, node).block);
|
| 251 |
+
|
| 252 |
+
const destructuring = (node.init && node.id && node.id.type === 'ObjectPattern');
|
| 253 |
+
// let {foo} = props;
|
| 254 |
+
const destructuringSFC = destructuring && (node.init.name === 'props' || node.init.name === 'context');
|
| 255 |
+
// let {foo} = this.props;
|
| 256 |
+
const destructuringClass = destructuring && node.init.object && node.init.object.type === 'ThisExpression' && (
|
| 257 |
+
node.init.property.name === 'props' || node.init.property.name === 'context' || node.init.property.name === 'state'
|
| 258 |
+
);
|
| 259 |
+
|
| 260 |
+
if (SFCComponent && destructuringSFC && configuration === 'never') {
|
| 261 |
+
report(context, messages.noDestructAssignment, 'noDestructAssignment', {
|
| 262 |
+
node,
|
| 263 |
+
data: {
|
| 264 |
+
type: node.init.name,
|
| 265 |
+
},
|
| 266 |
+
});
|
| 267 |
+
}
|
| 268 |
+
|
| 269 |
+
if (
|
| 270 |
+
classComponent && destructuringClass && configuration === 'never'
|
| 271 |
+
&& !(ignoreClassFields && (node.parent.type === 'ClassProperty' || node.parent.type === 'PropertyDefinition'))
|
| 272 |
+
) {
|
| 273 |
+
report(context, messages.noDestructAssignment, 'noDestructAssignment', {
|
| 274 |
+
node,
|
| 275 |
+
data: {
|
| 276 |
+
type: node.init.property.name,
|
| 277 |
+
},
|
| 278 |
+
});
|
| 279 |
+
}
|
| 280 |
+
|
| 281 |
+
if (
|
| 282 |
+
SFCComponent
|
| 283 |
+
&& destructuringSFC
|
| 284 |
+
&& configuration === 'always'
|
| 285 |
+
&& destructureInSignature === 'always'
|
| 286 |
+
&& node.init.name === 'props'
|
| 287 |
+
) {
|
| 288 |
+
const scopeSetProps = getScope(context, node).set.get('props');
|
| 289 |
+
const propsRefs = scopeSetProps && scopeSetProps.references;
|
| 290 |
+
if (!propsRefs) {
|
| 291 |
+
return;
|
| 292 |
+
}
|
| 293 |
+
|
| 294 |
+
// Skip if props is used elsewhere
|
| 295 |
+
if (propsRefs.length > 1) {
|
| 296 |
+
return;
|
| 297 |
+
}
|
| 298 |
+
report(context, messages.destructureInSignature, 'destructureInSignature', {
|
| 299 |
+
node,
|
| 300 |
+
fix(fixer) {
|
| 301 |
+
const param = SFCComponent.node.params[0];
|
| 302 |
+
if (!param) {
|
| 303 |
+
return;
|
| 304 |
+
}
|
| 305 |
+
const replaceRange = [
|
| 306 |
+
param.range[0],
|
| 307 |
+
param.typeAnnotation ? param.typeAnnotation.range[0] : param.range[1],
|
| 308 |
+
];
|
| 309 |
+
return [
|
| 310 |
+
fixer.replaceTextRange(replaceRange, getText(context, node.id)),
|
| 311 |
+
fixer.remove(node.parent),
|
| 312 |
+
];
|
| 313 |
+
},
|
| 314 |
+
});
|
| 315 |
+
}
|
| 316 |
+
},
|
| 317 |
+
};
|
| 318 |
+
}),
|
| 319 |
+
};
|
node_modules/eslint-plugin-react/lib/rules/display-name.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
declare const _exports: import('eslint').Rule.RuleModule;
|
| 2 |
+
export = _exports;
|
| 3 |
+
//# sourceMappingURL=display-name.d.ts.map
|
node_modules/eslint-plugin-react/lib/rules/display-name.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"display-name.d.ts","sourceRoot":"","sources":["display-name.js"],"names":[],"mappings":"wBA6BW,OAAO,QAAQ,EAAE,IAAI,CAAC,UAAU"}
|
node_modules/eslint-plugin-react/lib/rules/display-name.js
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* @fileoverview Prevent missing displayName in a React component definition
|
| 3 |
+
* @author Yannick Croissant
|
| 4 |
+
*/
|
| 5 |
+
|
| 6 |
+
'use strict';
|
| 7 |
+
|
| 8 |
+
const values = require('object.values');
|
| 9 |
+
const filter = require('es-iterator-helpers/Iterator.prototype.filter');
|
| 10 |
+
const forEach = require('es-iterator-helpers/Iterator.prototype.forEach');
|
| 11 |
+
|
| 12 |
+
const Components = require('../util/Components');
|
| 13 |
+
const isCreateContext = require('../util/isCreateContext');
|
| 14 |
+
const astUtil = require('../util/ast');
|
| 15 |
+
const componentUtil = require('../util/componentUtil');
|
| 16 |
+
const docsUrl = require('../util/docsUrl');
|
| 17 |
+
const testReactVersion = require('../util/version').testReactVersion;
|
| 18 |
+
const propsUtil = require('../util/props');
|
| 19 |
+
const report = require('../util/report');
|
| 20 |
+
|
| 21 |
+
// ------------------------------------------------------------------------------
|
| 22 |
+
// Rule Definition
|
| 23 |
+
// ------------------------------------------------------------------------------
|
| 24 |
+
|
| 25 |
+
const messages = {
|
| 26 |
+
noDisplayName: 'Component definition is missing display name',
|
| 27 |
+
noContextDisplayName: 'Context definition is missing display name',
|
| 28 |
+
};
|
| 29 |
+
|
| 30 |
+
/** @type {import('eslint').Rule.RuleModule} */
|
| 31 |
+
module.exports = {
|
| 32 |
+
meta: {
|
| 33 |
+
docs: {
|
| 34 |
+
description: 'Disallow missing displayName in a React component definition',
|
| 35 |
+
category: 'Best Practices',
|
| 36 |
+
recommended: true,
|
| 37 |
+
url: docsUrl('display-name'),
|
| 38 |
+
},
|
| 39 |
+
|
| 40 |
+
messages,
|
| 41 |
+
|
| 42 |
+
schema: [{
|
| 43 |
+
type: 'object',
|
| 44 |
+
properties: {
|
| 45 |
+
ignoreTranspilerName: {
|
| 46 |
+
type: 'boolean',
|
| 47 |
+
},
|
| 48 |
+
checkContextObjects: {
|
| 49 |
+
type: 'boolean',
|
| 50 |
+
},
|
| 51 |
+
},
|
| 52 |
+
additionalProperties: false,
|
| 53 |
+
}],
|
| 54 |
+
},
|
| 55 |
+
|
| 56 |
+
create: Components.detect((context, components, utils) => {
|
| 57 |
+
const config = context.options[0] || {};
|
| 58 |
+
const ignoreTranspilerName = config.ignoreTranspilerName || false;
|
| 59 |
+
const checkContextObjects = (config.checkContextObjects || false) && testReactVersion(context, '>= 16.3.0');
|
| 60 |
+
|
| 61 |
+
const contextObjects = new Map();
|
| 62 |
+
|
| 63 |
+
/**
|
| 64 |
+
* Mark a prop type as declared
|
| 65 |
+
* @param {ASTNode} node The AST node being checked.
|
| 66 |
+
*/
|
| 67 |
+
function markDisplayNameAsDeclared(node) {
|
| 68 |
+
components.set(node, {
|
| 69 |
+
hasDisplayName: true,
|
| 70 |
+
});
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
/**
|
| 74 |
+
* Checks if React.forwardRef is nested inside React.memo
|
| 75 |
+
* @param {ASTNode} node The AST node being checked.
|
| 76 |
+
* @returns {boolean} True if React.forwardRef is nested inside React.memo, false if not.
|
| 77 |
+
*/
|
| 78 |
+
function isNestedMemo(node) {
|
| 79 |
+
return astUtil.isCallExpression(node)
|
| 80 |
+
&& node.arguments
|
| 81 |
+
&& astUtil.isCallExpression(node.arguments[0])
|
| 82 |
+
&& utils.isPragmaComponentWrapper(node);
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
/**
|
| 86 |
+
* Reports missing display name for a given component
|
| 87 |
+
* @param {Object} component The component to process
|
| 88 |
+
*/
|
| 89 |
+
function reportMissingDisplayName(component) {
|
| 90 |
+
if (
|
| 91 |
+
testReactVersion(context, '^0.14.10 || ^15.7.0 || >= 16.12.0')
|
| 92 |
+
&& isNestedMemo(component.node)
|
| 93 |
+
) {
|
| 94 |
+
return;
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
report(context, messages.noDisplayName, 'noDisplayName', {
|
| 98 |
+
node: component.node,
|
| 99 |
+
});
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
/**
|
| 103 |
+
* Reports missing display name for a given context object
|
| 104 |
+
* @param {Object} contextObj The context object to process
|
| 105 |
+
*/
|
| 106 |
+
function reportMissingContextDisplayName(contextObj) {
|
| 107 |
+
report(context, messages.noContextDisplayName, 'noContextDisplayName', {
|
| 108 |
+
node: contextObj.node,
|
| 109 |
+
});
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
/**
|
| 113 |
+
* Checks if the component have a name set by the transpiler
|
| 114 |
+
* @param {ASTNode} node The AST node being checked.
|
| 115 |
+
* @returns {boolean} True if component has a name, false if not.
|
| 116 |
+
*/
|
| 117 |
+
function hasTranspilerName(node) {
|
| 118 |
+
const namedObjectAssignment = (
|
| 119 |
+
node.type === 'ObjectExpression'
|
| 120 |
+
&& node.parent
|
| 121 |
+
&& node.parent.parent
|
| 122 |
+
&& node.parent.parent.type === 'AssignmentExpression'
|
| 123 |
+
&& (
|
| 124 |
+
!node.parent.parent.left.object
|
| 125 |
+
|| node.parent.parent.left.object.name !== 'module'
|
| 126 |
+
|| node.parent.parent.left.property.name !== 'exports'
|
| 127 |
+
)
|
| 128 |
+
);
|
| 129 |
+
const namedObjectDeclaration = (
|
| 130 |
+
node.type === 'ObjectExpression'
|
| 131 |
+
&& node.parent
|
| 132 |
+
&& node.parent.parent
|
| 133 |
+
&& node.parent.parent.type === 'VariableDeclarator'
|
| 134 |
+
);
|
| 135 |
+
const namedClass = (
|
| 136 |
+
(node.type === 'ClassDeclaration' || node.type === 'ClassExpression')
|
| 137 |
+
&& node.id
|
| 138 |
+
&& !!node.id.name
|
| 139 |
+
);
|
| 140 |
+
|
| 141 |
+
const namedFunctionDeclaration = (
|
| 142 |
+
(node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression')
|
| 143 |
+
&& node.id
|
| 144 |
+
&& !!node.id.name
|
| 145 |
+
);
|
| 146 |
+
|
| 147 |
+
const namedFunctionExpression = (
|
| 148 |
+
astUtil.isFunctionLikeExpression(node)
|
| 149 |
+
&& node.parent
|
| 150 |
+
&& (node.parent.type === 'VariableDeclarator' || node.parent.type === 'Property' || node.parent.method === true)
|
| 151 |
+
&& (!node.parent.parent || !componentUtil.isES5Component(node.parent.parent, context))
|
| 152 |
+
);
|
| 153 |
+
|
| 154 |
+
if (
|
| 155 |
+
namedObjectAssignment || namedObjectDeclaration
|
| 156 |
+
|| namedClass
|
| 157 |
+
|| namedFunctionDeclaration || namedFunctionExpression
|
| 158 |
+
) {
|
| 159 |
+
return true;
|
| 160 |
+
}
|
| 161 |
+
return false;
|
| 162 |
+
}
|
| 163 |
+
|
| 164 |
+
// --------------------------------------------------------------------------
|
| 165 |
+
// Public
|
| 166 |
+
// --------------------------------------------------------------------------
|
| 167 |
+
|
| 168 |
+
return {
|
| 169 |
+
ExpressionStatement(node) {
|
| 170 |
+
if (checkContextObjects && isCreateContext(node)) {
|
| 171 |
+
contextObjects.set(node.expression.left.name, { node, hasDisplayName: false });
|
| 172 |
+
}
|
| 173 |
+
},
|
| 174 |
+
VariableDeclarator(node) {
|
| 175 |
+
if (checkContextObjects && isCreateContext(node)) {
|
| 176 |
+
contextObjects.set(node.id.name, { node, hasDisplayName: false });
|
| 177 |
+
}
|
| 178 |
+
},
|
| 179 |
+
'ClassProperty, PropertyDefinition'(node) {
|
| 180 |
+
if (!propsUtil.isDisplayNameDeclaration(node)) {
|
| 181 |
+
return;
|
| 182 |
+
}
|
| 183 |
+
markDisplayNameAsDeclared(node);
|
| 184 |
+
},
|
| 185 |
+
|
| 186 |
+
MemberExpression(node) {
|
| 187 |
+
if (!propsUtil.isDisplayNameDeclaration(node.property)) {
|
| 188 |
+
return;
|
| 189 |
+
}
|
| 190 |
+
if (
|
| 191 |
+
checkContextObjects
|
| 192 |
+
&& node.object
|
| 193 |
+
&& node.object.name
|
| 194 |
+
&& contextObjects.has(node.object.name)
|
| 195 |
+
) {
|
| 196 |
+
contextObjects.get(node.object.name).hasDisplayName = true;
|
| 197 |
+
}
|
| 198 |
+
const component = utils.getRelatedComponent(node);
|
| 199 |
+
if (!component) {
|
| 200 |
+
return;
|
| 201 |
+
}
|
| 202 |
+
markDisplayNameAsDeclared(astUtil.unwrapTSAsExpression(component.node));
|
| 203 |
+
},
|
| 204 |
+
|
| 205 |
+
'FunctionExpression, FunctionDeclaration, ArrowFunctionExpression'(node) {
|
| 206 |
+
if (ignoreTranspilerName || !hasTranspilerName(node)) {
|
| 207 |
+
return;
|
| 208 |
+
}
|
| 209 |
+
if (components.get(node)) {
|
| 210 |
+
markDisplayNameAsDeclared(node);
|
| 211 |
+
}
|
| 212 |
+
},
|
| 213 |
+
|
| 214 |
+
MethodDefinition(node) {
|
| 215 |
+
if (!propsUtil.isDisplayNameDeclaration(node.key)) {
|
| 216 |
+
return;
|
| 217 |
+
}
|
| 218 |
+
markDisplayNameAsDeclared(node);
|
| 219 |
+
},
|
| 220 |
+
|
| 221 |
+
'ClassExpression, ClassDeclaration'(node) {
|
| 222 |
+
if (ignoreTranspilerName || !hasTranspilerName(node)) {
|
| 223 |
+
return;
|
| 224 |
+
}
|
| 225 |
+
markDisplayNameAsDeclared(node);
|
| 226 |
+
},
|
| 227 |
+
|
| 228 |
+
ObjectExpression(node) {
|
| 229 |
+
if (!componentUtil.isES5Component(node, context)) {
|
| 230 |
+
return;
|
| 231 |
+
}
|
| 232 |
+
if (ignoreTranspilerName || !hasTranspilerName(node)) {
|
| 233 |
+
// Search for the displayName declaration
|
| 234 |
+
node.properties.forEach((property) => {
|
| 235 |
+
if (!property.key || !propsUtil.isDisplayNameDeclaration(property.key)) {
|
| 236 |
+
return;
|
| 237 |
+
}
|
| 238 |
+
markDisplayNameAsDeclared(node);
|
| 239 |
+
});
|
| 240 |
+
return;
|
| 241 |
+
}
|
| 242 |
+
markDisplayNameAsDeclared(node);
|
| 243 |
+
},
|
| 244 |
+
|
| 245 |
+
CallExpression(node) {
|
| 246 |
+
if (!utils.isPragmaComponentWrapper(node)) {
|
| 247 |
+
return;
|
| 248 |
+
}
|
| 249 |
+
|
| 250 |
+
if (node.arguments.length > 0 && astUtil.isFunctionLikeExpression(node.arguments[0])) {
|
| 251 |
+
// Skip over React.forwardRef declarations that are embedded within
|
| 252 |
+
// a React.memo i.e. React.memo(React.forwardRef(/* ... */))
|
| 253 |
+
// This means that we raise a single error for the call to React.memo
|
| 254 |
+
// instead of one for React.memo and one for React.forwardRef
|
| 255 |
+
const isWrappedInAnotherPragma = utils.getPragmaComponentWrapper(node);
|
| 256 |
+
if (
|
| 257 |
+
!isWrappedInAnotherPragma
|
| 258 |
+
&& (ignoreTranspilerName || !hasTranspilerName(node.arguments[0]))
|
| 259 |
+
) {
|
| 260 |
+
return;
|
| 261 |
+
}
|
| 262 |
+
|
| 263 |
+
if (components.get(node)) {
|
| 264 |
+
markDisplayNameAsDeclared(node);
|
| 265 |
+
}
|
| 266 |
+
}
|
| 267 |
+
},
|
| 268 |
+
|
| 269 |
+
'Program:exit'() {
|
| 270 |
+
const list = components.list();
|
| 271 |
+
// Report missing display name for all components
|
| 272 |
+
values(list).filter((component) => !component.hasDisplayName).forEach((component) => {
|
| 273 |
+
reportMissingDisplayName(component);
|
| 274 |
+
});
|
| 275 |
+
if (checkContextObjects) {
|
| 276 |
+
// Report missing display name for all context objects
|
| 277 |
+
forEach(
|
| 278 |
+
filter(contextObjects.values(), (v) => !v.hasDisplayName),
|
| 279 |
+
(contextObj) => reportMissingContextDisplayName(contextObj)
|
| 280 |
+
);
|
| 281 |
+
}
|
| 282 |
+
},
|
| 283 |
+
};
|
| 284 |
+
}),
|
| 285 |
+
};
|
node_modules/eslint-plugin-react/lib/rules/forbid-component-props.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
declare const _exports: import('eslint').Rule.RuleModule;
|
| 2 |
+
export = _exports;
|
| 3 |
+
//# sourceMappingURL=forbid-component-props.d.ts.map
|
node_modules/eslint-plugin-react/lib/rules/forbid-component-props.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"forbid-component-props.d.ts","sourceRoot":"","sources":["forbid-component-props.js"],"names":[],"mappings":"wBAyBW,OAAO,QAAQ,EAAE,IAAI,CAAC,UAAU"}
|
node_modules/eslint-plugin-react/lib/rules/forbid-component-props.js
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* @fileoverview Forbid certain props on components
|
| 3 |
+
* @author Joe Lencioni
|
| 4 |
+
*/
|
| 5 |
+
|
| 6 |
+
'use strict';
|
| 7 |
+
|
| 8 |
+
const minimatch = require('minimatch');
|
| 9 |
+
const docsUrl = require('../util/docsUrl');
|
| 10 |
+
const report = require('../util/report');
|
| 11 |
+
|
| 12 |
+
// ------------------------------------------------------------------------------
|
| 13 |
+
// Constants
|
| 14 |
+
// ------------------------------------------------------------------------------
|
| 15 |
+
|
| 16 |
+
const DEFAULTS = ['className', 'style'];
|
| 17 |
+
|
| 18 |
+
// ------------------------------------------------------------------------------
|
| 19 |
+
// Rule Definition
|
| 20 |
+
// ------------------------------------------------------------------------------
|
| 21 |
+
|
| 22 |
+
const messages = {
|
| 23 |
+
propIsForbidden: 'Prop "{{prop}}" is forbidden on Components',
|
| 24 |
+
};
|
| 25 |
+
|
| 26 |
+
/** @type {import('eslint').Rule.RuleModule} */
|
| 27 |
+
module.exports = {
|
| 28 |
+
meta: {
|
| 29 |
+
docs: {
|
| 30 |
+
description: 'Disallow certain props on components',
|
| 31 |
+
category: 'Best Practices',
|
| 32 |
+
recommended: false,
|
| 33 |
+
url: docsUrl('forbid-component-props'),
|
| 34 |
+
},
|
| 35 |
+
|
| 36 |
+
messages,
|
| 37 |
+
|
| 38 |
+
schema: [{
|
| 39 |
+
type: 'object',
|
| 40 |
+
properties: {
|
| 41 |
+
forbid: {
|
| 42 |
+
type: 'array',
|
| 43 |
+
items: {
|
| 44 |
+
anyOf: [
|
| 45 |
+
{ type: 'string' },
|
| 46 |
+
{
|
| 47 |
+
type: 'object',
|
| 48 |
+
properties: {
|
| 49 |
+
propName: { type: 'string' },
|
| 50 |
+
allowedFor: {
|
| 51 |
+
type: 'array',
|
| 52 |
+
uniqueItems: true,
|
| 53 |
+
items: { type: 'string' },
|
| 54 |
+
},
|
| 55 |
+
allowedForPatterns: {
|
| 56 |
+
type: 'array',
|
| 57 |
+
uniqueItems: true,
|
| 58 |
+
items: { type: 'string' },
|
| 59 |
+
},
|
| 60 |
+
message: { type: 'string' },
|
| 61 |
+
},
|
| 62 |
+
additionalProperties: false,
|
| 63 |
+
},
|
| 64 |
+
{
|
| 65 |
+
type: 'object',
|
| 66 |
+
properties: {
|
| 67 |
+
propName: { type: 'string' },
|
| 68 |
+
disallowedFor: {
|
| 69 |
+
type: 'array',
|
| 70 |
+
uniqueItems: true,
|
| 71 |
+
minItems: 1,
|
| 72 |
+
items: { type: 'string' },
|
| 73 |
+
},
|
| 74 |
+
disallowedForPatterns: {
|
| 75 |
+
type: 'array',
|
| 76 |
+
uniqueItems: true,
|
| 77 |
+
minItems: 1,
|
| 78 |
+
items: { type: 'string' },
|
| 79 |
+
},
|
| 80 |
+
message: { type: 'string' },
|
| 81 |
+
},
|
| 82 |
+
anyOf: [
|
| 83 |
+
{ required: ['disallowedFor'] },
|
| 84 |
+
{ required: ['disallowedForPatterns'] },
|
| 85 |
+
],
|
| 86 |
+
additionalProperties: false,
|
| 87 |
+
},
|
| 88 |
+
{
|
| 89 |
+
type: 'object',
|
| 90 |
+
properties: {
|
| 91 |
+
propNamePattern: { type: 'string' },
|
| 92 |
+
allowedFor: {
|
| 93 |
+
type: 'array',
|
| 94 |
+
uniqueItems: true,
|
| 95 |
+
items: { type: 'string' },
|
| 96 |
+
},
|
| 97 |
+
allowedForPatterns: {
|
| 98 |
+
type: 'array',
|
| 99 |
+
uniqueItems: true,
|
| 100 |
+
items: { type: 'string' },
|
| 101 |
+
},
|
| 102 |
+
message: { type: 'string' },
|
| 103 |
+
},
|
| 104 |
+
additionalProperties: false,
|
| 105 |
+
},
|
| 106 |
+
{
|
| 107 |
+
type: 'object',
|
| 108 |
+
properties: {
|
| 109 |
+
propNamePattern: { type: 'string' },
|
| 110 |
+
disallowedFor: {
|
| 111 |
+
type: 'array',
|
| 112 |
+
uniqueItems: true,
|
| 113 |
+
minItems: 1,
|
| 114 |
+
items: { type: 'string' },
|
| 115 |
+
},
|
| 116 |
+
disallowedForPatterns: {
|
| 117 |
+
type: 'array',
|
| 118 |
+
uniqueItems: true,
|
| 119 |
+
minItems: 1,
|
| 120 |
+
items: { type: 'string' },
|
| 121 |
+
},
|
| 122 |
+
message: { type: 'string' },
|
| 123 |
+
},
|
| 124 |
+
anyOf: [
|
| 125 |
+
{ required: ['disallowedFor'] },
|
| 126 |
+
{ required: ['disallowedForPatterns'] },
|
| 127 |
+
],
|
| 128 |
+
additionalProperties: false,
|
| 129 |
+
},
|
| 130 |
+
],
|
| 131 |
+
},
|
| 132 |
+
},
|
| 133 |
+
},
|
| 134 |
+
}],
|
| 135 |
+
},
|
| 136 |
+
|
| 137 |
+
create(context) {
|
| 138 |
+
const configuration = context.options[0] || {};
|
| 139 |
+
const forbid = new Map((configuration.forbid || DEFAULTS).map((value) => {
|
| 140 |
+
const propName = typeof value === 'string' ? value : value.propName;
|
| 141 |
+
const propPattern = value.propNamePattern;
|
| 142 |
+
const prop = propName || propPattern;
|
| 143 |
+
const options = {
|
| 144 |
+
allowList: [].concat(value.allowedFor || []),
|
| 145 |
+
allowPatternList: [].concat(value.allowedForPatterns || []),
|
| 146 |
+
disallowList: [].concat(value.disallowedFor || []),
|
| 147 |
+
disallowPatternList: [].concat(value.disallowedForPatterns || []),
|
| 148 |
+
message: typeof value === 'string' ? null : value.message,
|
| 149 |
+
isPattern: !!value.propNamePattern,
|
| 150 |
+
};
|
| 151 |
+
return [prop, options];
|
| 152 |
+
}));
|
| 153 |
+
|
| 154 |
+
function getPropOptions(prop) {
|
| 155 |
+
// Get config options having pattern
|
| 156 |
+
const propNamePatternArray = Array.from(forbid.entries()).filter((propEntry) => propEntry[1].isPattern);
|
| 157 |
+
// Match current prop with pattern options, return if matched
|
| 158 |
+
const propNamePattern = propNamePatternArray.find((propPatternVal) => minimatch(prop, propPatternVal[0]));
|
| 159 |
+
// Get options for matched propNamePattern
|
| 160 |
+
const propNamePatternOptions = propNamePattern && propNamePattern[1];
|
| 161 |
+
|
| 162 |
+
const options = forbid.get(prop) || propNamePatternOptions;
|
| 163 |
+
return options;
|
| 164 |
+
}
|
| 165 |
+
|
| 166 |
+
function isForbidden(prop, tagName) {
|
| 167 |
+
const options = getPropOptions(prop);
|
| 168 |
+
if (!options) {
|
| 169 |
+
return false;
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
function checkIsTagForbiddenByAllowOptions() {
|
| 173 |
+
if (options.allowList.indexOf(tagName) !== -1) {
|
| 174 |
+
return false;
|
| 175 |
+
}
|
| 176 |
+
|
| 177 |
+
if (options.allowPatternList.length === 0) {
|
| 178 |
+
return true;
|
| 179 |
+
}
|
| 180 |
+
|
| 181 |
+
return options.allowPatternList.every(
|
| 182 |
+
(pattern) => !minimatch(tagName, pattern)
|
| 183 |
+
);
|
| 184 |
+
}
|
| 185 |
+
|
| 186 |
+
function checkIsTagForbiddenByDisallowOptions() {
|
| 187 |
+
if (options.disallowList.indexOf(tagName) !== -1) {
|
| 188 |
+
return true;
|
| 189 |
+
}
|
| 190 |
+
|
| 191 |
+
if (options.disallowPatternList.length === 0) {
|
| 192 |
+
return false;
|
| 193 |
+
}
|
| 194 |
+
|
| 195 |
+
return options.disallowPatternList.some(
|
| 196 |
+
(pattern) => minimatch(tagName, pattern)
|
| 197 |
+
);
|
| 198 |
+
}
|
| 199 |
+
|
| 200 |
+
const hasDisallowOptions = options.disallowList.length > 0 || options.disallowPatternList.length > 0;
|
| 201 |
+
|
| 202 |
+
// disallowList should have a least one item (schema configuration)
|
| 203 |
+
const isTagForbidden = hasDisallowOptions
|
| 204 |
+
? checkIsTagForbiddenByDisallowOptions()
|
| 205 |
+
: checkIsTagForbiddenByAllowOptions();
|
| 206 |
+
|
| 207 |
+
// if the tagName is undefined (`<this.something>`), we assume it's a forbidden element
|
| 208 |
+
return typeof tagName === 'undefined' || isTagForbidden;
|
| 209 |
+
}
|
| 210 |
+
|
| 211 |
+
return {
|
| 212 |
+
JSXAttribute(node) {
|
| 213 |
+
const parentName = node.parent.name;
|
| 214 |
+
// Extract a component name when using a "namespace", e.g. `<AntdLayout.Content />`.
|
| 215 |
+
const tag = parentName.name || `${parentName.object.name}.${parentName.property.name}`;
|
| 216 |
+
const componentName = parentName.name || parentName.property.name;
|
| 217 |
+
if (componentName && typeof componentName[0] === 'string' && componentName[0] !== componentName[0].toUpperCase()) {
|
| 218 |
+
// This is a DOM node, not a Component, so exit.
|
| 219 |
+
return;
|
| 220 |
+
}
|
| 221 |
+
|
| 222 |
+
const prop = node.name.name;
|
| 223 |
+
|
| 224 |
+
if (!isForbidden(prop, tag)) {
|
| 225 |
+
return;
|
| 226 |
+
}
|
| 227 |
+
|
| 228 |
+
const customMessage = getPropOptions(prop).message;
|
| 229 |
+
|
| 230 |
+
report(context, customMessage || messages.propIsForbidden, !customMessage && 'propIsForbidden', {
|
| 231 |
+
node,
|
| 232 |
+
data: {
|
| 233 |
+
prop,
|
| 234 |
+
},
|
| 235 |
+
});
|
| 236 |
+
},
|
| 237 |
+
};
|
| 238 |
+
},
|
| 239 |
+
};
|
node_modules/eslint-plugin-react/lib/rules/forbid-dom-props.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
declare const _exports: import('eslint').Rule.RuleModule;
|
| 2 |
+
export = _exports;
|
| 3 |
+
//# sourceMappingURL=forbid-dom-props.d.ts.map
|
node_modules/eslint-plugin-react/lib/rules/forbid-dom-props.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"forbid-dom-props.d.ts","sourceRoot":"","sources":["forbid-dom-props.js"],"names":[],"mappings":"wBAuCW,OAAO,QAAQ,EAAE,IAAI,CAAC,UAAU"}
|
node_modules/eslint-plugin-react/lib/rules/forbid-dom-props.js
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* @fileoverview Forbid certain props on DOM Nodes
|
| 3 |
+
* @author David Vázquez
|
| 4 |
+
*/
|
| 5 |
+
|
| 6 |
+
'use strict';
|
| 7 |
+
|
| 8 |
+
const docsUrl = require('../util/docsUrl');
|
| 9 |
+
const report = require('../util/report');
|
| 10 |
+
|
| 11 |
+
// ------------------------------------------------------------------------------
|
| 12 |
+
// Constants
|
| 13 |
+
// ------------------------------------------------------------------------------
|
| 14 |
+
|
| 15 |
+
const DEFAULTS = [];
|
| 16 |
+
|
| 17 |
+
// ------------------------------------------------------------------------------
|
| 18 |
+
// Rule Definition
|
| 19 |
+
// ------------------------------------------------------------------------------
|
| 20 |
+
|
| 21 |
+
/**
|
| 22 |
+
* @param {Map<string, object>} forbidMap // { disallowList: null | string[], message: null | string }
|
| 23 |
+
* @param {string} prop
|
| 24 |
+
* @param {string} tagName
|
| 25 |
+
* @returns {boolean}
|
| 26 |
+
*/
|
| 27 |
+
function isForbidden(forbidMap, prop, tagName) {
|
| 28 |
+
const options = forbidMap.get(prop);
|
| 29 |
+
return options && (
|
| 30 |
+
typeof tagName === 'undefined'
|
| 31 |
+
|| !options.disallowList
|
| 32 |
+
|| options.disallowList.indexOf(tagName) !== -1
|
| 33 |
+
);
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
const messages = {
|
| 37 |
+
propIsForbidden: 'Prop "{{prop}}" is forbidden on DOM Nodes',
|
| 38 |
+
};
|
| 39 |
+
|
| 40 |
+
/** @type {import('eslint').Rule.RuleModule} */
|
| 41 |
+
module.exports = {
|
| 42 |
+
meta: {
|
| 43 |
+
docs: {
|
| 44 |
+
description: 'Disallow certain props on DOM Nodes',
|
| 45 |
+
category: 'Best Practices',
|
| 46 |
+
recommended: false,
|
| 47 |
+
url: docsUrl('forbid-dom-props'),
|
| 48 |
+
},
|
| 49 |
+
|
| 50 |
+
messages,
|
| 51 |
+
|
| 52 |
+
schema: [{
|
| 53 |
+
type: 'object',
|
| 54 |
+
properties: {
|
| 55 |
+
forbid: {
|
| 56 |
+
type: 'array',
|
| 57 |
+
items: {
|
| 58 |
+
anyOf: [{
|
| 59 |
+
type: 'string',
|
| 60 |
+
}, {
|
| 61 |
+
type: 'object',
|
| 62 |
+
properties: {
|
| 63 |
+
propName: {
|
| 64 |
+
type: 'string',
|
| 65 |
+
},
|
| 66 |
+
disallowedFor: {
|
| 67 |
+
type: 'array',
|
| 68 |
+
uniqueItems: true,
|
| 69 |
+
items: {
|
| 70 |
+
type: 'string',
|
| 71 |
+
},
|
| 72 |
+
},
|
| 73 |
+
message: {
|
| 74 |
+
type: 'string',
|
| 75 |
+
},
|
| 76 |
+
},
|
| 77 |
+
}],
|
| 78 |
+
minLength: 1,
|
| 79 |
+
},
|
| 80 |
+
uniqueItems: true,
|
| 81 |
+
},
|
| 82 |
+
},
|
| 83 |
+
additionalProperties: false,
|
| 84 |
+
}],
|
| 85 |
+
},
|
| 86 |
+
|
| 87 |
+
create(context) {
|
| 88 |
+
const configuration = context.options[0] || {};
|
| 89 |
+
const forbid = new Map((configuration.forbid || DEFAULTS).map((value) => {
|
| 90 |
+
const propName = typeof value === 'string' ? value : value.propName;
|
| 91 |
+
return [propName, {
|
| 92 |
+
disallowList: typeof value === 'string' ? null : (value.disallowedFor || null),
|
| 93 |
+
message: typeof value === 'string' ? null : value.message,
|
| 94 |
+
}];
|
| 95 |
+
}));
|
| 96 |
+
|
| 97 |
+
return {
|
| 98 |
+
JSXAttribute(node) {
|
| 99 |
+
const tag = node.parent.name.name;
|
| 100 |
+
if (!(tag && typeof tag === 'string' && tag[0] !== tag[0].toUpperCase())) {
|
| 101 |
+
// This is a Component, not a DOM node, so exit.
|
| 102 |
+
return;
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
const prop = node.name.name;
|
| 106 |
+
|
| 107 |
+
if (!isForbidden(forbid, prop, tag)) {
|
| 108 |
+
return;
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
const customMessage = forbid.get(prop).message;
|
| 112 |
+
|
| 113 |
+
report(context, customMessage || messages.propIsForbidden, !customMessage && 'propIsForbidden', {
|
| 114 |
+
node,
|
| 115 |
+
data: {
|
| 116 |
+
prop,
|
| 117 |
+
},
|
| 118 |
+
});
|
| 119 |
+
},
|
| 120 |
+
};
|
| 121 |
+
},
|
| 122 |
+
};
|
node_modules/eslint-plugin-react/lib/rules/forbid-elements.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
declare const _exports: import('eslint').Rule.RuleModule;
|
| 2 |
+
export = _exports;
|
| 3 |
+
//# sourceMappingURL=forbid-elements.d.ts.map
|
node_modules/eslint-plugin-react/lib/rules/forbid-elements.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"forbid-elements.d.ts","sourceRoot":"","sources":["forbid-elements.js"],"names":[],"mappings":"wBAsBW,OAAO,QAAQ,EAAE,IAAI,CAAC,UAAU"}
|
node_modules/eslint-plugin-react/lib/rules/forbid-elements.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* @fileoverview Forbid certain elements
|
| 3 |
+
* @author Kenneth Chung
|
| 4 |
+
*/
|
| 5 |
+
|
| 6 |
+
'use strict';
|
| 7 |
+
|
| 8 |
+
const has = require('hasown');
|
| 9 |
+
const docsUrl = require('../util/docsUrl');
|
| 10 |
+
const getText = require('../util/eslint').getText;
|
| 11 |
+
const isCreateElement = require('../util/isCreateElement');
|
| 12 |
+
const report = require('../util/report');
|
| 13 |
+
|
| 14 |
+
// ------------------------------------------------------------------------------
|
| 15 |
+
// Rule Definition
|
| 16 |
+
// ------------------------------------------------------------------------------
|
| 17 |
+
|
| 18 |
+
const messages = {
|
| 19 |
+
forbiddenElement: '<{{element}}> is forbidden',
|
| 20 |
+
forbiddenElement_message: '<{{element}}> is forbidden, {{message}}',
|
| 21 |
+
};
|
| 22 |
+
|
| 23 |
+
/** @type {import('eslint').Rule.RuleModule} */
|
| 24 |
+
module.exports = {
|
| 25 |
+
meta: {
|
| 26 |
+
docs: {
|
| 27 |
+
description: 'Disallow certain elements',
|
| 28 |
+
category: 'Best Practices',
|
| 29 |
+
recommended: false,
|
| 30 |
+
url: docsUrl('forbid-elements'),
|
| 31 |
+
},
|
| 32 |
+
|
| 33 |
+
messages,
|
| 34 |
+
|
| 35 |
+
schema: [{
|
| 36 |
+
type: 'object',
|
| 37 |
+
properties: {
|
| 38 |
+
forbid: {
|
| 39 |
+
type: 'array',
|
| 40 |
+
items: {
|
| 41 |
+
anyOf: [
|
| 42 |
+
{ type: 'string' },
|
| 43 |
+
{
|
| 44 |
+
type: 'object',
|
| 45 |
+
properties: {
|
| 46 |
+
element: { type: 'string' },
|
| 47 |
+
message: { type: 'string' },
|
| 48 |
+
},
|
| 49 |
+
required: ['element'],
|
| 50 |
+
additionalProperties: false,
|
| 51 |
+
},
|
| 52 |
+
],
|
| 53 |
+
},
|
| 54 |
+
},
|
| 55 |
+
},
|
| 56 |
+
additionalProperties: false,
|
| 57 |
+
}],
|
| 58 |
+
},
|
| 59 |
+
|
| 60 |
+
create(context) {
|
| 61 |
+
const configuration = context.options[0] || {};
|
| 62 |
+
const forbidConfiguration = configuration.forbid || [];
|
| 63 |
+
|
| 64 |
+
/** @type {Record<string, { element: string, message?: string }>} */
|
| 65 |
+
const indexedForbidConfigs = {};
|
| 66 |
+
|
| 67 |
+
forbidConfiguration.forEach((item) => {
|
| 68 |
+
if (typeof item === 'string') {
|
| 69 |
+
indexedForbidConfigs[item] = { element: item };
|
| 70 |
+
} else {
|
| 71 |
+
indexedForbidConfigs[item.element] = item;
|
| 72 |
+
}
|
| 73 |
+
});
|
| 74 |
+
|
| 75 |
+
function reportIfForbidden(element, node) {
|
| 76 |
+
if (has(indexedForbidConfigs, element)) {
|
| 77 |
+
const message = indexedForbidConfigs[element].message;
|
| 78 |
+
|
| 79 |
+
report(
|
| 80 |
+
context,
|
| 81 |
+
message ? messages.forbiddenElement_message : messages.forbiddenElement,
|
| 82 |
+
message ? 'forbiddenElement_message' : 'forbiddenElement',
|
| 83 |
+
{
|
| 84 |
+
node,
|
| 85 |
+
data: {
|
| 86 |
+
element,
|
| 87 |
+
message,
|
| 88 |
+
},
|
| 89 |
+
}
|
| 90 |
+
);
|
| 91 |
+
}
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
return {
|
| 95 |
+
JSXOpeningElement(node) {
|
| 96 |
+
reportIfForbidden(getText(context, node.name), node.name);
|
| 97 |
+
},
|
| 98 |
+
|
| 99 |
+
CallExpression(node) {
|
| 100 |
+
if (!isCreateElement(context, node)) {
|
| 101 |
+
return;
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
const argument = node.arguments[0];
|
| 105 |
+
if (!argument) {
|
| 106 |
+
return;
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
if (argument.type === 'Identifier' && /^[A-Z_]/.test(argument.name)) {
|
| 110 |
+
reportIfForbidden(argument.name, argument);
|
| 111 |
+
} else if (argument.type === 'Literal' && /^[a-z][^.]*$/.test(String(argument.value))) {
|
| 112 |
+
reportIfForbidden(argument.value, argument);
|
| 113 |
+
} else if (argument.type === 'MemberExpression') {
|
| 114 |
+
reportIfForbidden(getText(context, argument), argument);
|
| 115 |
+
}
|
| 116 |
+
},
|
| 117 |
+
};
|
| 118 |
+
},
|
| 119 |
+
};
|
node_modules/eslint-plugin-react/lib/rules/forbid-foreign-prop-types.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
declare const _exports: import('eslint').Rule.RuleModule;
|
| 2 |
+
export = _exports;
|
| 3 |
+
//# sourceMappingURL=forbid-foreign-prop-types.d.ts.map
|
node_modules/eslint-plugin-react/lib/rules/forbid-foreign-prop-types.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"forbid-foreign-prop-types.d.ts","sourceRoot":"","sources":["forbid-foreign-prop-types.js"],"names":[],"mappings":"wBAeW,OAAO,QAAQ,EAAE,IAAI,CAAC,UAAU"}
|
node_modules/eslint-plugin-react/lib/rules/forbid-foreign-prop-types.js
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* @fileoverview Forbid using another component's propTypes
|
| 3 |
+
* @author Ian Christian Myers
|
| 4 |
+
*/
|
| 5 |
+
|
| 6 |
+
'use strict';
|
| 7 |
+
|
| 8 |
+
const docsUrl = require('../util/docsUrl');
|
| 9 |
+
const ast = require('../util/ast');
|
| 10 |
+
const report = require('../util/report');
|
| 11 |
+
|
| 12 |
+
const messages = {
|
| 13 |
+
forbiddenPropType: 'Using propTypes from another component is not safe because they may be removed in production builds',
|
| 14 |
+
};
|
| 15 |
+
|
| 16 |
+
/** @type {import('eslint').Rule.RuleModule} */
|
| 17 |
+
module.exports = {
|
| 18 |
+
meta: {
|
| 19 |
+
docs: {
|
| 20 |
+
description: 'Disallow using another component\'s propTypes',
|
| 21 |
+
category: 'Best Practices',
|
| 22 |
+
recommended: false,
|
| 23 |
+
url: docsUrl('forbid-foreign-prop-types'),
|
| 24 |
+
},
|
| 25 |
+
|
| 26 |
+
messages,
|
| 27 |
+
|
| 28 |
+
schema: [
|
| 29 |
+
{
|
| 30 |
+
type: 'object',
|
| 31 |
+
properties: {
|
| 32 |
+
allowInPropTypes: {
|
| 33 |
+
type: 'boolean',
|
| 34 |
+
},
|
| 35 |
+
},
|
| 36 |
+
additionalProperties: false,
|
| 37 |
+
},
|
| 38 |
+
],
|
| 39 |
+
},
|
| 40 |
+
|
| 41 |
+
create(context) {
|
| 42 |
+
const config = context.options[0] || {};
|
| 43 |
+
const allowInPropTypes = config.allowInPropTypes || false;
|
| 44 |
+
|
| 45 |
+
// --------------------------------------------------------------------------
|
| 46 |
+
// Helpers
|
| 47 |
+
// --------------------------------------------------------------------------
|
| 48 |
+
|
| 49 |
+
function findParentAssignmentExpression(node) {
|
| 50 |
+
let parent = node.parent;
|
| 51 |
+
|
| 52 |
+
while (parent && parent.type !== 'Program') {
|
| 53 |
+
if (parent.type === 'AssignmentExpression') {
|
| 54 |
+
return parent;
|
| 55 |
+
}
|
| 56 |
+
parent = parent.parent;
|
| 57 |
+
}
|
| 58 |
+
return null;
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
function findParentClassProperty(node) {
|
| 62 |
+
let parent = node.parent;
|
| 63 |
+
|
| 64 |
+
while (parent && parent.type !== 'Program') {
|
| 65 |
+
if (parent.type === 'ClassProperty' || parent.type === 'PropertyDefinition') {
|
| 66 |
+
return parent;
|
| 67 |
+
}
|
| 68 |
+
parent = parent.parent;
|
| 69 |
+
}
|
| 70 |
+
return null;
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
function isAllowedAssignment(node) {
|
| 74 |
+
if (!allowInPropTypes) {
|
| 75 |
+
return false;
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
const assignmentExpression = findParentAssignmentExpression(node);
|
| 79 |
+
|
| 80 |
+
if (
|
| 81 |
+
assignmentExpression
|
| 82 |
+
&& assignmentExpression.left
|
| 83 |
+
&& assignmentExpression.left.property
|
| 84 |
+
&& assignmentExpression.left.property.name === 'propTypes'
|
| 85 |
+
) {
|
| 86 |
+
return true;
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
const classProperty = findParentClassProperty(node);
|
| 90 |
+
|
| 91 |
+
if (
|
| 92 |
+
classProperty
|
| 93 |
+
&& classProperty.key
|
| 94 |
+
&& classProperty.key.name === 'propTypes'
|
| 95 |
+
) {
|
| 96 |
+
return true;
|
| 97 |
+
}
|
| 98 |
+
return false;
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
+
return {
|
| 102 |
+
MemberExpression(node) {
|
| 103 |
+
if (
|
| 104 |
+
(node.property
|
| 105 |
+
&& (
|
| 106 |
+
!node.computed
|
| 107 |
+
&& node.property.type === 'Identifier'
|
| 108 |
+
&& node.property.name === 'propTypes'
|
| 109 |
+
&& !ast.isAssignmentLHS(node)
|
| 110 |
+
&& !isAllowedAssignment(node)
|
| 111 |
+
)) || (
|
| 112 |
+
// @ts-expect-error: The JSXText type is not present in the estree type definitions
|
| 113 |
+
(node.property.type === 'Literal' || node.property.type === 'JSXText')
|
| 114 |
+
&& 'value' in node.property
|
| 115 |
+
&& node.property.value === 'propTypes'
|
| 116 |
+
&& !ast.isAssignmentLHS(node)
|
| 117 |
+
&& !isAllowedAssignment(node)
|
| 118 |
+
)
|
| 119 |
+
) {
|
| 120 |
+
report(context, messages.forbiddenPropType, 'forbiddenPropType', {
|
| 121 |
+
node: node.property,
|
| 122 |
+
});
|
| 123 |
+
}
|
| 124 |
+
},
|
| 125 |
+
|
| 126 |
+
ObjectPattern(node) {
|
| 127 |
+
const propTypesNode = node.properties.find((property) => (
|
| 128 |
+
property.type === 'Property'
|
| 129 |
+
&& 'name' in property.key
|
| 130 |
+
&& property.key.name === 'propTypes'
|
| 131 |
+
));
|
| 132 |
+
|
| 133 |
+
if (propTypesNode) {
|
| 134 |
+
report(context, messages.forbiddenPropType, 'forbiddenPropType', {
|
| 135 |
+
node: propTypesNode,
|
| 136 |
+
});
|
| 137 |
+
}
|
| 138 |
+
},
|
| 139 |
+
};
|
| 140 |
+
},
|
| 141 |
+
};
|
node_modules/eslint-plugin-react/lib/rules/forbid-prop-types.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
declare const _exports: import('eslint').Rule.RuleModule;
|
| 2 |
+
export = _exports;
|
| 3 |
+
//# sourceMappingURL=forbid-prop-types.d.ts.map
|
node_modules/eslint-plugin-react/lib/rules/forbid-prop-types.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"forbid-prop-types.d.ts","sourceRoot":"","sources":["forbid-prop-types.js"],"names":[],"mappings":"wBA4BW,OAAO,QAAQ,EAAE,IAAI,CAAC,UAAU"}
|
node_modules/eslint-plugin-react/lib/rules/forbid-prop-types.js
ADDED
|
@@ -0,0 +1,298 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* @fileoverview Forbid certain propTypes
|
| 3 |
+
*/
|
| 4 |
+
|
| 5 |
+
'use strict';
|
| 6 |
+
|
| 7 |
+
const variableUtil = require('../util/variable');
|
| 8 |
+
const propsUtil = require('../util/props');
|
| 9 |
+
const astUtil = require('../util/ast');
|
| 10 |
+
const docsUrl = require('../util/docsUrl');
|
| 11 |
+
const propWrapperUtil = require('../util/propWrapper');
|
| 12 |
+
const report = require('../util/report');
|
| 13 |
+
const getText = require('../util/eslint').getText;
|
| 14 |
+
|
| 15 |
+
// ------------------------------------------------------------------------------
|
| 16 |
+
// Constants
|
| 17 |
+
// ------------------------------------------------------------------------------
|
| 18 |
+
|
| 19 |
+
const DEFAULTS = ['any', 'array', 'object'];
|
| 20 |
+
|
| 21 |
+
// ------------------------------------------------------------------------------
|
| 22 |
+
// Rule Definition
|
| 23 |
+
// ------------------------------------------------------------------------------
|
| 24 |
+
|
| 25 |
+
const messages = {
|
| 26 |
+
forbiddenPropType: 'Prop type "{{target}}" is forbidden',
|
| 27 |
+
};
|
| 28 |
+
|
| 29 |
+
/** @type {import('eslint').Rule.RuleModule} */
|
| 30 |
+
module.exports = {
|
| 31 |
+
meta: {
|
| 32 |
+
docs: {
|
| 33 |
+
description: 'Disallow certain propTypes',
|
| 34 |
+
category: 'Best Practices',
|
| 35 |
+
recommended: false,
|
| 36 |
+
url: docsUrl('forbid-prop-types'),
|
| 37 |
+
},
|
| 38 |
+
|
| 39 |
+
messages,
|
| 40 |
+
|
| 41 |
+
schema: [{
|
| 42 |
+
type: 'object',
|
| 43 |
+
properties: {
|
| 44 |
+
forbid: {
|
| 45 |
+
type: 'array',
|
| 46 |
+
items: {
|
| 47 |
+
type: 'string',
|
| 48 |
+
},
|
| 49 |
+
},
|
| 50 |
+
checkContextTypes: {
|
| 51 |
+
type: 'boolean',
|
| 52 |
+
},
|
| 53 |
+
checkChildContextTypes: {
|
| 54 |
+
type: 'boolean',
|
| 55 |
+
},
|
| 56 |
+
},
|
| 57 |
+
additionalProperties: true,
|
| 58 |
+
}],
|
| 59 |
+
},
|
| 60 |
+
|
| 61 |
+
create(context) {
|
| 62 |
+
const configuration = context.options[0] || {};
|
| 63 |
+
const checkContextTypes = configuration.checkContextTypes || false;
|
| 64 |
+
const checkChildContextTypes = configuration.checkChildContextTypes || false;
|
| 65 |
+
let propTypesPackageName = null;
|
| 66 |
+
let reactPackageName = null;
|
| 67 |
+
let isForeignPropTypesPackage = false;
|
| 68 |
+
|
| 69 |
+
function isPropTypesPackage(node) {
|
| 70 |
+
return (
|
| 71 |
+
node.type === 'Identifier'
|
| 72 |
+
&& (
|
| 73 |
+
node.name === null
|
| 74 |
+
|| node.name === propTypesPackageName
|
| 75 |
+
|| !isForeignPropTypesPackage
|
| 76 |
+
)
|
| 77 |
+
) || (
|
| 78 |
+
node.type === 'MemberExpression'
|
| 79 |
+
&& (
|
| 80 |
+
node.object.name === null
|
| 81 |
+
|| node.object.name === reactPackageName
|
| 82 |
+
|| !isForeignPropTypesPackage
|
| 83 |
+
)
|
| 84 |
+
);
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
function isForbidden(type) {
|
| 88 |
+
const forbid = configuration.forbid || DEFAULTS;
|
| 89 |
+
return forbid.indexOf(type) >= 0;
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
function reportIfForbidden(type, declaration, target) {
|
| 93 |
+
if (isForbidden(type)) {
|
| 94 |
+
report(context, messages.forbiddenPropType, 'forbiddenPropType', {
|
| 95 |
+
node: declaration,
|
| 96 |
+
data: {
|
| 97 |
+
target,
|
| 98 |
+
},
|
| 99 |
+
});
|
| 100 |
+
}
|
| 101 |
+
}
|
| 102 |
+
|
| 103 |
+
function shouldCheckContextTypes(node) {
|
| 104 |
+
if (checkContextTypes && propsUtil.isContextTypesDeclaration(node)) {
|
| 105 |
+
return true;
|
| 106 |
+
}
|
| 107 |
+
return false;
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
function shouldCheckChildContextTypes(node) {
|
| 111 |
+
if (checkChildContextTypes && propsUtil.isChildContextTypesDeclaration(node)) {
|
| 112 |
+
return true;
|
| 113 |
+
}
|
| 114 |
+
return false;
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
/**
|
| 118 |
+
* Checks if propTypes declarations are forbidden
|
| 119 |
+
* @param {Array} declarations The array of AST nodes being checked.
|
| 120 |
+
* @returns {void}
|
| 121 |
+
*/
|
| 122 |
+
function checkProperties(declarations) {
|
| 123 |
+
if (declarations) {
|
| 124 |
+
declarations.forEach((declaration) => {
|
| 125 |
+
if (declaration.type !== 'Property') {
|
| 126 |
+
return;
|
| 127 |
+
}
|
| 128 |
+
let target;
|
| 129 |
+
let value = declaration.value;
|
| 130 |
+
if (
|
| 131 |
+
value.type === 'MemberExpression'
|
| 132 |
+
&& value.property
|
| 133 |
+
&& value.property.name
|
| 134 |
+
&& value.property.name === 'isRequired'
|
| 135 |
+
) {
|
| 136 |
+
value = value.object;
|
| 137 |
+
}
|
| 138 |
+
if (astUtil.isCallExpression(value)) {
|
| 139 |
+
if (!isPropTypesPackage(value.callee)) {
|
| 140 |
+
return;
|
| 141 |
+
}
|
| 142 |
+
value.arguments.forEach((arg) => {
|
| 143 |
+
const name = arg.type === 'MemberExpression' ? arg.property.name : arg.name;
|
| 144 |
+
reportIfForbidden(name, declaration, name);
|
| 145 |
+
});
|
| 146 |
+
value = value.callee;
|
| 147 |
+
}
|
| 148 |
+
if (!isPropTypesPackage(value)) {
|
| 149 |
+
return;
|
| 150 |
+
}
|
| 151 |
+
if (value.property) {
|
| 152 |
+
target = value.property.name;
|
| 153 |
+
} else if (value.type === 'Identifier') {
|
| 154 |
+
target = value.name;
|
| 155 |
+
}
|
| 156 |
+
reportIfForbidden(target, declaration, target);
|
| 157 |
+
});
|
| 158 |
+
}
|
| 159 |
+
}
|
| 160 |
+
|
| 161 |
+
function checkNode(node) {
|
| 162 |
+
if (!node) {
|
| 163 |
+
return;
|
| 164 |
+
}
|
| 165 |
+
|
| 166 |
+
if (node.type === 'ObjectExpression') {
|
| 167 |
+
checkProperties(node.properties);
|
| 168 |
+
} else if (node.type === 'Identifier') {
|
| 169 |
+
const propTypesObject = variableUtil.findVariableByName(context, node, node.name);
|
| 170 |
+
if (propTypesObject && propTypesObject.properties) {
|
| 171 |
+
checkProperties(propTypesObject.properties);
|
| 172 |
+
}
|
| 173 |
+
} else if (astUtil.isCallExpression(node)) {
|
| 174 |
+
const innerNode = node.arguments && node.arguments[0];
|
| 175 |
+
if (
|
| 176 |
+
propWrapperUtil.isPropWrapperFunction(context, getText(context, node.callee))
|
| 177 |
+
&& innerNode
|
| 178 |
+
) {
|
| 179 |
+
checkNode(innerNode);
|
| 180 |
+
}
|
| 181 |
+
}
|
| 182 |
+
}
|
| 183 |
+
|
| 184 |
+
return {
|
| 185 |
+
ImportDeclaration(node) {
|
| 186 |
+
if (node.source && node.source.value === 'prop-types') { // import PropType from "prop-types"
|
| 187 |
+
if (node.specifiers.length > 0) {
|
| 188 |
+
propTypesPackageName = node.specifiers[0].local.name;
|
| 189 |
+
}
|
| 190 |
+
} else if (node.source && node.source.value === 'react') { // import { PropTypes } from "react"
|
| 191 |
+
if (node.specifiers.length > 0) {
|
| 192 |
+
reactPackageName = node.specifiers[0].local.name; // guard against accidental anonymous `import "react"`
|
| 193 |
+
}
|
| 194 |
+
if (node.specifiers.length >= 1) {
|
| 195 |
+
const propTypesSpecifier = node.specifiers.find((specifier) => (
|
| 196 |
+
'imported' in specifier
|
| 197 |
+
&& specifier.imported
|
| 198 |
+
&& 'name' in specifier.imported
|
| 199 |
+
&& specifier.imported.name === 'PropTypes'
|
| 200 |
+
));
|
| 201 |
+
if (propTypesSpecifier) {
|
| 202 |
+
propTypesPackageName = propTypesSpecifier.local.name;
|
| 203 |
+
}
|
| 204 |
+
}
|
| 205 |
+
} else { // package is not imported from "react" or "prop-types"
|
| 206 |
+
// eslint-disable-next-line no-lonely-if
|
| 207 |
+
if (node.specifiers.some((x) => x.local.name === 'PropTypes')) { // assert: node.specifiers.length > 1
|
| 208 |
+
isForeignPropTypesPackage = true;
|
| 209 |
+
}
|
| 210 |
+
}
|
| 211 |
+
},
|
| 212 |
+
|
| 213 |
+
'ClassProperty, PropertyDefinition'(node) {
|
| 214 |
+
if (
|
| 215 |
+
!propsUtil.isPropTypesDeclaration(node)
|
| 216 |
+
&& !isPropTypesPackage(node)
|
| 217 |
+
&& !shouldCheckContextTypes(node)
|
| 218 |
+
&& !shouldCheckChildContextTypes(node)
|
| 219 |
+
) {
|
| 220 |
+
return;
|
| 221 |
+
}
|
| 222 |
+
checkNode(node.value);
|
| 223 |
+
},
|
| 224 |
+
|
| 225 |
+
MemberExpression(node) {
|
| 226 |
+
if (
|
| 227 |
+
!propsUtil.isPropTypesDeclaration(node)
|
| 228 |
+
&& !isPropTypesPackage(node)
|
| 229 |
+
&& !shouldCheckContextTypes(node)
|
| 230 |
+
&& !shouldCheckChildContextTypes(node)
|
| 231 |
+
) {
|
| 232 |
+
return;
|
| 233 |
+
}
|
| 234 |
+
|
| 235 |
+
checkNode('right' in node.parent && node.parent.right);
|
| 236 |
+
},
|
| 237 |
+
|
| 238 |
+
CallExpression(node) {
|
| 239 |
+
if (
|
| 240 |
+
node.callee.type === 'MemberExpression'
|
| 241 |
+
&& node.callee.object
|
| 242 |
+
&& !isPropTypesPackage(node.callee.object)
|
| 243 |
+
&& !propsUtil.isPropTypesDeclaration(node.callee)
|
| 244 |
+
) {
|
| 245 |
+
return;
|
| 246 |
+
}
|
| 247 |
+
|
| 248 |
+
if (
|
| 249 |
+
node.arguments.length > 0
|
| 250 |
+
&& (
|
| 251 |
+
('name' in node.callee && node.callee.name === 'shape')
|
| 252 |
+
|| astUtil.getPropertyName(node.callee) === 'shape'
|
| 253 |
+
)
|
| 254 |
+
) {
|
| 255 |
+
checkProperties('properties' in node.arguments[0] && node.arguments[0].properties);
|
| 256 |
+
}
|
| 257 |
+
},
|
| 258 |
+
|
| 259 |
+
MethodDefinition(node) {
|
| 260 |
+
if (
|
| 261 |
+
!propsUtil.isPropTypesDeclaration(node)
|
| 262 |
+
&& !isPropTypesPackage(node)
|
| 263 |
+
&& !shouldCheckContextTypes(node)
|
| 264 |
+
&& !shouldCheckChildContextTypes(node)
|
| 265 |
+
) {
|
| 266 |
+
return;
|
| 267 |
+
}
|
| 268 |
+
|
| 269 |
+
const returnStatement = astUtil.findReturnStatement(node);
|
| 270 |
+
|
| 271 |
+
if (returnStatement && returnStatement.argument) {
|
| 272 |
+
checkNode(returnStatement.argument);
|
| 273 |
+
}
|
| 274 |
+
},
|
| 275 |
+
|
| 276 |
+
ObjectExpression(node) {
|
| 277 |
+
node.properties.forEach((property) => {
|
| 278 |
+
if (!('key' in property) || !property.key) {
|
| 279 |
+
return;
|
| 280 |
+
}
|
| 281 |
+
|
| 282 |
+
if (
|
| 283 |
+
!propsUtil.isPropTypesDeclaration(property)
|
| 284 |
+
&& !isPropTypesPackage(property)
|
| 285 |
+
&& !shouldCheckContextTypes(property)
|
| 286 |
+
&& !shouldCheckChildContextTypes(property)
|
| 287 |
+
) {
|
| 288 |
+
return;
|
| 289 |
+
}
|
| 290 |
+
if (property.value.type === 'ObjectExpression') {
|
| 291 |
+
checkProperties(property.value.properties);
|
| 292 |
+
}
|
| 293 |
+
});
|
| 294 |
+
},
|
| 295 |
+
|
| 296 |
+
};
|
| 297 |
+
},
|
| 298 |
+
};
|
node_modules/eslint-plugin-react/lib/rules/forward-ref-uses-ref.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
declare const _exports: import('eslint').Rule.RuleModule;
|
| 2 |
+
export = _exports;
|
| 3 |
+
//# sourceMappingURL=forward-ref-uses-ref.d.ts.map
|
node_modules/eslint-plugin-react/lib/rules/forward-ref-uses-ref.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"forward-ref-uses-ref.d.ts","sourceRoot":"","sources":["forward-ref-uses-ref.js"],"names":[],"mappings":"wBA2CW,OAAO,QAAQ,EAAE,IAAI,CAAC,UAAU"}
|
node_modules/eslint-plugin-react/lib/rules/forward-ref-uses-ref.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* @fileoverview Require all forwardRef components include a ref parameter
|
| 3 |
+
*/
|
| 4 |
+
|
| 5 |
+
'use strict';
|
| 6 |
+
|
| 7 |
+
const isParenthesized = require('../util/ast').isParenthesized;
|
| 8 |
+
const docsUrl = require('../util/docsUrl');
|
| 9 |
+
const report = require('../util/report');
|
| 10 |
+
const getMessageData = require('../util/message');
|
| 11 |
+
|
| 12 |
+
// ------------------------------------------------------------------------------
|
| 13 |
+
// Rule Definition
|
| 14 |
+
// ------------------------------------------------------------------------------
|
| 15 |
+
|
| 16 |
+
/**
|
| 17 |
+
* @param {ASTNode} node
|
| 18 |
+
* @returns {boolean} If the node represents the identifier `forwardRef`.
|
| 19 |
+
*/
|
| 20 |
+
function isForwardRefIdentifier(node) {
|
| 21 |
+
return node.type === 'Identifier' && node.name === 'forwardRef';
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
/**
|
| 25 |
+
* @param {ASTNode} node
|
| 26 |
+
* @returns {boolean} If the node represents a function call `forwardRef()` or `React.forwardRef()`.
|
| 27 |
+
*/
|
| 28 |
+
function isForwardRefCall(node) {
|
| 29 |
+
return (
|
| 30 |
+
node.type === 'CallExpression'
|
| 31 |
+
&& (
|
| 32 |
+
isForwardRefIdentifier(node.callee)
|
| 33 |
+
|| (node.callee.type === 'MemberExpression' && isForwardRefIdentifier(node.callee.property))
|
| 34 |
+
)
|
| 35 |
+
);
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
const messages = {
|
| 39 |
+
missingRefParameter: 'forwardRef is used with this component but no ref parameter is set',
|
| 40 |
+
addRefParameter: 'Add a ref parameter',
|
| 41 |
+
removeForwardRef: 'Remove forwardRef wrapper',
|
| 42 |
+
};
|
| 43 |
+
|
| 44 |
+
/** @type {import('eslint').Rule.RuleModule} */
|
| 45 |
+
module.exports = {
|
| 46 |
+
meta: {
|
| 47 |
+
docs: {
|
| 48 |
+
description: 'Require all forwardRef components include a ref parameter',
|
| 49 |
+
category: 'Possible Errors',
|
| 50 |
+
recommended: false,
|
| 51 |
+
url: docsUrl('forward-ref-uses-ref'),
|
| 52 |
+
},
|
| 53 |
+
messages,
|
| 54 |
+
schema: [],
|
| 55 |
+
type: 'suggestion',
|
| 56 |
+
hasSuggestions: true,
|
| 57 |
+
},
|
| 58 |
+
|
| 59 |
+
create(context) {
|
| 60 |
+
const sourceCode = context.getSourceCode();
|
| 61 |
+
|
| 62 |
+
return {
|
| 63 |
+
'FunctionExpression, ArrowFunctionExpression'(node) {
|
| 64 |
+
if (!isForwardRefCall(node.parent)) {
|
| 65 |
+
return;
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
if (node.params.length === 1) {
|
| 69 |
+
report(context, messages.missingRefParameter, 'missingRefParameter', {
|
| 70 |
+
node,
|
| 71 |
+
suggest: [
|
| 72 |
+
Object.assign(
|
| 73 |
+
getMessageData('addRefParameter', messages.addRefParameter),
|
| 74 |
+
{
|
| 75 |
+
fix(fixer) {
|
| 76 |
+
const param = node.params[0];
|
| 77 |
+
// If using shorthand arrow function syntax, add parentheses around the new parameter pair
|
| 78 |
+
const shouldAddParentheses = node.type === 'ArrowFunctionExpression' && !isParenthesized(context, param);
|
| 79 |
+
return [].concat(
|
| 80 |
+
shouldAddParentheses ? fixer.insertTextBefore(param, '(') : [],
|
| 81 |
+
fixer.insertTextAfter(param, `, ref${shouldAddParentheses ? ')' : ''}`)
|
| 82 |
+
);
|
| 83 |
+
},
|
| 84 |
+
}
|
| 85 |
+
),
|
| 86 |
+
Object.assign(
|
| 87 |
+
getMessageData('removeForwardRef', messages.removeForwardRef),
|
| 88 |
+
{
|
| 89 |
+
fix(fixer) {
|
| 90 |
+
return fixer.replaceText(node.parent, sourceCode.getText(node));
|
| 91 |
+
},
|
| 92 |
+
}
|
| 93 |
+
),
|
| 94 |
+
],
|
| 95 |
+
});
|
| 96 |
+
}
|
| 97 |
+
},
|
| 98 |
+
};
|
| 99 |
+
},
|
| 100 |
+
};
|
node_modules/eslint-plugin-react/lib/rules/function-component-definition.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
declare const _exports: import('eslint').Rule.RuleModule;
|
| 2 |
+
export = _exports;
|
| 3 |
+
//# sourceMappingURL=function-component-definition.d.ts.map
|
node_modules/eslint-plugin-react/lib/rules/function-component-definition.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"function-component-definition.d.ts","sourceRoot":"","sources":["function-component-definition.js"],"names":[],"mappings":"wBAqHW,OAAO,QAAQ,EAAE,IAAI,CAAC,UAAU"}
|
node_modules/eslint-plugin-react/lib/rules/function-component-definition.js
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* @fileoverview Standardize the way function component get defined
|
| 3 |
+
* @author Stefan Wullems
|
| 4 |
+
*/
|
| 5 |
+
|
| 6 |
+
'use strict';
|
| 7 |
+
|
| 8 |
+
const arrayIncludes = require('array-includes');
|
| 9 |
+
const Components = require('../util/Components');
|
| 10 |
+
const docsUrl = require('../util/docsUrl');
|
| 11 |
+
const reportC = require('../util/report');
|
| 12 |
+
const getText = require('../util/eslint').getText;
|
| 13 |
+
const propsUtil = require('../util/props');
|
| 14 |
+
|
| 15 |
+
// ------------------------------------------------------------------------------
|
| 16 |
+
// Rule Definition
|
| 17 |
+
// ------------------------------------------------------------------------------
|
| 18 |
+
|
| 19 |
+
function buildFunction(template, parts) {
|
| 20 |
+
return Object.keys(parts).reduce(
|
| 21 |
+
(acc, key) => acc.replace(`{${key}}`, () => parts[key] || ''),
|
| 22 |
+
template
|
| 23 |
+
);
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
const NAMED_FUNCTION_TEMPLATES = {
|
| 27 |
+
'function-declaration': 'function {name}{typeParams}({params}){returnType} {body}',
|
| 28 |
+
'arrow-function': '{varType} {name}{typeAnnotation} = {typeParams}({params}){returnType} => {body}',
|
| 29 |
+
'function-expression': '{varType} {name}{typeAnnotation} = function{typeParams}({params}){returnType} {body}',
|
| 30 |
+
};
|
| 31 |
+
|
| 32 |
+
const UNNAMED_FUNCTION_TEMPLATES = {
|
| 33 |
+
'function-expression': 'function{typeParams}({params}){returnType} {body}',
|
| 34 |
+
'arrow-function': '{typeParams}({params}){returnType} => {body}',
|
| 35 |
+
};
|
| 36 |
+
|
| 37 |
+
function hasOneUnconstrainedTypeParam(node) {
|
| 38 |
+
const nodeTypeArguments = propsUtil.getTypeArguments(node);
|
| 39 |
+
|
| 40 |
+
return nodeTypeArguments
|
| 41 |
+
&& nodeTypeArguments.params
|
| 42 |
+
&& nodeTypeArguments.params.length === 1
|
| 43 |
+
&& !nodeTypeArguments.params[0].constraint;
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
function hasName(node) {
|
| 47 |
+
return (
|
| 48 |
+
node.type === 'FunctionDeclaration'
|
| 49 |
+
|| node.parent.type === 'VariableDeclarator'
|
| 50 |
+
);
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
function getNodeText(prop, source) {
|
| 54 |
+
if (!prop) return null;
|
| 55 |
+
return source.slice(prop.range[0], prop.range[1]);
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
function getName(node) {
|
| 59 |
+
if (node.type === 'FunctionDeclaration') {
|
| 60 |
+
return node.id.name;
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
if (
|
| 64 |
+
node.type === 'ArrowFunctionExpression'
|
| 65 |
+
|| node.type === 'FunctionExpression'
|
| 66 |
+
) {
|
| 67 |
+
return hasName(node) && node.parent.id.name;
|
| 68 |
+
}
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
function getParams(node, source) {
|
| 72 |
+
if (node.params.length === 0) return null;
|
| 73 |
+
return source.slice(
|
| 74 |
+
node.params[0].range[0],
|
| 75 |
+
node.params[node.params.length - 1].range[1]
|
| 76 |
+
);
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
function getBody(node, source) {
|
| 80 |
+
const range = node.body.range;
|
| 81 |
+
|
| 82 |
+
if (node.body.type !== 'BlockStatement') {
|
| 83 |
+
return ['{', ` return ${source.slice(range[0], range[1])}`, '}'].join('\n');
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
return source.slice(range[0], range[1]);
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
function getTypeAnnotation(node, source) {
|
| 90 |
+
if (!hasName(node) || node.type === 'FunctionDeclaration') return;
|
| 91 |
+
|
| 92 |
+
if (
|
| 93 |
+
node.type === 'ArrowFunctionExpression'
|
| 94 |
+
|| node.type === 'FunctionExpression'
|
| 95 |
+
) {
|
| 96 |
+
return getNodeText(node.parent.id.typeAnnotation, source);
|
| 97 |
+
}
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
function isUnfixableBecauseOfExport(node) {
|
| 101 |
+
return (
|
| 102 |
+
node.type === 'FunctionDeclaration'
|
| 103 |
+
&& node.parent
|
| 104 |
+
&& node.parent.type === 'ExportDefaultDeclaration'
|
| 105 |
+
);
|
| 106 |
+
}
|
| 107 |
+
|
| 108 |
+
function isFunctionExpressionWithName(node) {
|
| 109 |
+
return node.type === 'FunctionExpression' && node.id && node.id.name;
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
const messages = {
|
| 113 |
+
'function-declaration': 'Function component is not a function declaration',
|
| 114 |
+
'function-expression': 'Function component is not a function expression',
|
| 115 |
+
'arrow-function': 'Function component is not an arrow function',
|
| 116 |
+
};
|
| 117 |
+
|
| 118 |
+
/** @type {import('eslint').Rule.RuleModule} */
|
| 119 |
+
module.exports = {
|
| 120 |
+
meta: {
|
| 121 |
+
docs: {
|
| 122 |
+
description: 'Enforce a specific function type for function components',
|
| 123 |
+
category: 'Stylistic Issues',
|
| 124 |
+
recommended: false,
|
| 125 |
+
url: docsUrl('function-component-definition'),
|
| 126 |
+
},
|
| 127 |
+
fixable: 'code',
|
| 128 |
+
|
| 129 |
+
messages,
|
| 130 |
+
|
| 131 |
+
schema: [
|
| 132 |
+
{
|
| 133 |
+
type: 'object',
|
| 134 |
+
properties: {
|
| 135 |
+
namedComponents: {
|
| 136 |
+
anyOf: [
|
| 137 |
+
{
|
| 138 |
+
enum: [
|
| 139 |
+
'function-declaration',
|
| 140 |
+
'arrow-function',
|
| 141 |
+
'function-expression',
|
| 142 |
+
],
|
| 143 |
+
},
|
| 144 |
+
{
|
| 145 |
+
type: 'array',
|
| 146 |
+
items: {
|
| 147 |
+
type: 'string',
|
| 148 |
+
enum: [
|
| 149 |
+
'function-declaration',
|
| 150 |
+
'arrow-function',
|
| 151 |
+
'function-expression',
|
| 152 |
+
],
|
| 153 |
+
},
|
| 154 |
+
},
|
| 155 |
+
],
|
| 156 |
+
},
|
| 157 |
+
unnamedComponents: {
|
| 158 |
+
anyOf: [
|
| 159 |
+
{ enum: ['arrow-function', 'function-expression'] },
|
| 160 |
+
{
|
| 161 |
+
type: 'array',
|
| 162 |
+
items: {
|
| 163 |
+
type: 'string',
|
| 164 |
+
enum: ['arrow-function', 'function-expression'],
|
| 165 |
+
},
|
| 166 |
+
},
|
| 167 |
+
],
|
| 168 |
+
},
|
| 169 |
+
},
|
| 170 |
+
},
|
| 171 |
+
],
|
| 172 |
+
},
|
| 173 |
+
|
| 174 |
+
create: Components.detect((context, components) => {
|
| 175 |
+
const configuration = context.options[0] || {};
|
| 176 |
+
let fileVarType = 'var';
|
| 177 |
+
|
| 178 |
+
const namedConfig = [].concat(
|
| 179 |
+
configuration.namedComponents || 'function-declaration'
|
| 180 |
+
);
|
| 181 |
+
const unnamedConfig = [].concat(
|
| 182 |
+
configuration.unnamedComponents || 'function-expression'
|
| 183 |
+
);
|
| 184 |
+
|
| 185 |
+
function getFixer(node, options) {
|
| 186 |
+
const source = getText(context);
|
| 187 |
+
|
| 188 |
+
const typeAnnotation = getTypeAnnotation(node, source);
|
| 189 |
+
|
| 190 |
+
if (options.type === 'function-declaration' && typeAnnotation) {
|
| 191 |
+
return;
|
| 192 |
+
}
|
| 193 |
+
if (options.type === 'arrow-function' && hasOneUnconstrainedTypeParam(node)) {
|
| 194 |
+
return;
|
| 195 |
+
}
|
| 196 |
+
if (isUnfixableBecauseOfExport(node)) return;
|
| 197 |
+
if (isFunctionExpressionWithName(node)) return;
|
| 198 |
+
let varType = fileVarType;
|
| 199 |
+
if (
|
| 200 |
+
(node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression')
|
| 201 |
+
&& node.parent.type === 'VariableDeclarator'
|
| 202 |
+
) {
|
| 203 |
+
varType = node.parent.parent.kind;
|
| 204 |
+
}
|
| 205 |
+
|
| 206 |
+
const nodeTypeArguments = propsUtil.getTypeArguments(node);
|
| 207 |
+
return (fixer) => fixer.replaceTextRange(
|
| 208 |
+
options.range,
|
| 209 |
+
buildFunction(options.template, {
|
| 210 |
+
typeAnnotation,
|
| 211 |
+
typeParams: getNodeText(nodeTypeArguments, source),
|
| 212 |
+
params: getParams(node, source),
|
| 213 |
+
returnType: getNodeText(node.returnType, source),
|
| 214 |
+
body: getBody(node, source),
|
| 215 |
+
name: getName(node),
|
| 216 |
+
varType,
|
| 217 |
+
})
|
| 218 |
+
);
|
| 219 |
+
}
|
| 220 |
+
|
| 221 |
+
function report(node, options) {
|
| 222 |
+
reportC(context, messages[options.messageId], options.messageId, {
|
| 223 |
+
node,
|
| 224 |
+
fix: getFixer(node, options.fixerOptions),
|
| 225 |
+
});
|
| 226 |
+
}
|
| 227 |
+
|
| 228 |
+
function validate(node, functionType) {
|
| 229 |
+
if (!components.get(node)) return;
|
| 230 |
+
|
| 231 |
+
if (node.parent && node.parent.type === 'Property') return;
|
| 232 |
+
|
| 233 |
+
if (hasName(node) && !arrayIncludes(namedConfig, functionType)) {
|
| 234 |
+
report(node, {
|
| 235 |
+
messageId: namedConfig[0],
|
| 236 |
+
fixerOptions: {
|
| 237 |
+
type: namedConfig[0],
|
| 238 |
+
template: NAMED_FUNCTION_TEMPLATES[namedConfig[0]],
|
| 239 |
+
range:
|
| 240 |
+
node.type === 'FunctionDeclaration'
|
| 241 |
+
? node.range
|
| 242 |
+
: node.parent.parent.range,
|
| 243 |
+
},
|
| 244 |
+
});
|
| 245 |
+
}
|
| 246 |
+
if (!hasName(node) && !arrayIncludes(unnamedConfig, functionType)) {
|
| 247 |
+
report(node, {
|
| 248 |
+
messageId: unnamedConfig[0],
|
| 249 |
+
fixerOptions: {
|
| 250 |
+
type: unnamedConfig[0],
|
| 251 |
+
template: UNNAMED_FUNCTION_TEMPLATES[unnamedConfig[0]],
|
| 252 |
+
range: node.range,
|
| 253 |
+
},
|
| 254 |
+
});
|
| 255 |
+
}
|
| 256 |
+
}
|
| 257 |
+
|
| 258 |
+
// --------------------------------------------------------------------------
|
| 259 |
+
// Public
|
| 260 |
+
// --------------------------------------------------------------------------
|
| 261 |
+
const validatePairs = [];
|
| 262 |
+
let hasES6OrJsx = false;
|
| 263 |
+
return {
|
| 264 |
+
FunctionDeclaration(node) {
|
| 265 |
+
validatePairs.push([node, 'function-declaration']);
|
| 266 |
+
},
|
| 267 |
+
ArrowFunctionExpression(node) {
|
| 268 |
+
validatePairs.push([node, 'arrow-function']);
|
| 269 |
+
},
|
| 270 |
+
FunctionExpression(node) {
|
| 271 |
+
validatePairs.push([node, 'function-expression']);
|
| 272 |
+
},
|
| 273 |
+
VariableDeclaration(node) {
|
| 274 |
+
hasES6OrJsx = hasES6OrJsx || node.kind === 'const' || node.kind === 'let';
|
| 275 |
+
},
|
| 276 |
+
'Program:exit'() {
|
| 277 |
+
if (hasES6OrJsx) fileVarType = 'const';
|
| 278 |
+
validatePairs.forEach((pair) => validate(pair[0], pair[1]));
|
| 279 |
+
},
|
| 280 |
+
'ImportDeclaration, ExportNamedDeclaration, ExportDefaultDeclaration, ExportAllDeclaration, ExportSpecifier, ExportDefaultSpecifier, JSXElement, TSExportAssignment, TSImportEqualsDeclaration'() {
|
| 281 |
+
hasES6OrJsx = true;
|
| 282 |
+
},
|
| 283 |
+
};
|
| 284 |
+
}),
|
| 285 |
+
};
|
node_modules/eslint-plugin-react/lib/rules/hook-use-state.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
declare const _exports: import('eslint').Rule.RuleModule;
|
| 2 |
+
export = _exports;
|
| 3 |
+
//# sourceMappingURL=hook-use-state.d.ts.map
|
node_modules/eslint-plugin-react/lib/rules/hook-use-state.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"hook-use-state.d.ts","sourceRoot":"","sources":["hook-use-state.js"],"names":[],"mappings":"wBA4BW,OAAO,QAAQ,EAAE,IAAI,CAAC,UAAU"}
|
node_modules/eslint-plugin-react/lib/rules/hook-use-state.js
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* @fileoverview Ensure symmetric naming of useState hook value and setter variables
|
| 3 |
+
* @author Duncan Beevers
|
| 4 |
+
*/
|
| 5 |
+
|
| 6 |
+
'use strict';
|
| 7 |
+
|
| 8 |
+
const Components = require('../util/Components');
|
| 9 |
+
const docsUrl = require('../util/docsUrl');
|
| 10 |
+
const report = require('../util/report');
|
| 11 |
+
const getMessageData = require('../util/message');
|
| 12 |
+
const getText = require('../util/eslint').getText;
|
| 13 |
+
|
| 14 |
+
// ------------------------------------------------------------------------------
|
| 15 |
+
// Rule Definition
|
| 16 |
+
// ------------------------------------------------------------------------------
|
| 17 |
+
|
| 18 |
+
function isNodeDestructuring(node) {
|
| 19 |
+
return node && (node.type === 'ArrayPattern' || node.type === 'ObjectPattern');
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
const messages = {
|
| 23 |
+
useStateErrorMessage: 'useState call is not destructured into value + setter pair',
|
| 24 |
+
useStateErrorMessageOrAddOption: 'useState call is not destructured into value + setter pair (you can allow destructuring by enabling "allowDestructuredState" option)',
|
| 25 |
+
suggestPair: 'Destructure useState call into value + setter pair',
|
| 26 |
+
suggestMemo: 'Replace useState call with useMemo',
|
| 27 |
+
};
|
| 28 |
+
|
| 29 |
+
/** @type {import('eslint').Rule.RuleModule} */
|
| 30 |
+
module.exports = {
|
| 31 |
+
meta: {
|
| 32 |
+
docs: {
|
| 33 |
+
description: 'Ensure destructuring and symmetric naming of useState hook value and setter variables',
|
| 34 |
+
category: 'Best Practices',
|
| 35 |
+
recommended: false,
|
| 36 |
+
url: docsUrl('hook-use-state'),
|
| 37 |
+
},
|
| 38 |
+
messages,
|
| 39 |
+
schema: [{
|
| 40 |
+
type: 'object',
|
| 41 |
+
properties: {
|
| 42 |
+
allowDestructuredState: {
|
| 43 |
+
default: false,
|
| 44 |
+
type: 'boolean',
|
| 45 |
+
},
|
| 46 |
+
},
|
| 47 |
+
additionalProperties: false,
|
| 48 |
+
}],
|
| 49 |
+
type: 'suggestion',
|
| 50 |
+
hasSuggestions: true,
|
| 51 |
+
},
|
| 52 |
+
|
| 53 |
+
create: Components.detect((context, components, util) => {
|
| 54 |
+
const configuration = context.options[0] || {};
|
| 55 |
+
const allowDestructuredState = configuration.allowDestructuredState || false;
|
| 56 |
+
|
| 57 |
+
return {
|
| 58 |
+
CallExpression(node) {
|
| 59 |
+
const isImmediateReturn = node.parent
|
| 60 |
+
&& node.parent.type === 'ReturnStatement';
|
| 61 |
+
|
| 62 |
+
if (isImmediateReturn || !util.isReactHookCall(node, ['useState'])) {
|
| 63 |
+
return;
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
const isDestructuringDeclarator = node.parent
|
| 67 |
+
&& node.parent.type === 'VariableDeclarator'
|
| 68 |
+
&& node.parent.id.type === 'ArrayPattern';
|
| 69 |
+
|
| 70 |
+
if (!isDestructuringDeclarator) {
|
| 71 |
+
report(
|
| 72 |
+
context,
|
| 73 |
+
messages.useStateErrorMessage,
|
| 74 |
+
'useStateErrorMessage',
|
| 75 |
+
{
|
| 76 |
+
node,
|
| 77 |
+
suggest: false,
|
| 78 |
+
}
|
| 79 |
+
);
|
| 80 |
+
return;
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
const variableNodes = node.parent.id.elements;
|
| 84 |
+
const valueVariable = variableNodes[0];
|
| 85 |
+
const setterVariable = variableNodes[1];
|
| 86 |
+
const isOnlyValueDestructuring = isNodeDestructuring(valueVariable) && !isNodeDestructuring(setterVariable);
|
| 87 |
+
|
| 88 |
+
if (allowDestructuredState && isOnlyValueDestructuring) {
|
| 89 |
+
return;
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
const valueVariableName = valueVariable
|
| 93 |
+
? valueVariable.name
|
| 94 |
+
: undefined;
|
| 95 |
+
|
| 96 |
+
const setterVariableName = setterVariable
|
| 97 |
+
? setterVariable.name
|
| 98 |
+
: undefined;
|
| 99 |
+
|
| 100 |
+
const caseCandidateMatch = valueVariableName ? valueVariableName.match(/(^[a-z]+)(.*)/) : undefined;
|
| 101 |
+
const upperCaseCandidatePrefix = caseCandidateMatch ? caseCandidateMatch[1] : undefined;
|
| 102 |
+
const caseCandidateSuffix = caseCandidateMatch ? caseCandidateMatch[2] : undefined;
|
| 103 |
+
const expectedSetterVariableNames = upperCaseCandidatePrefix ? [
|
| 104 |
+
`set${upperCaseCandidatePrefix.charAt(0).toUpperCase()}${upperCaseCandidatePrefix.slice(1)}${caseCandidateSuffix}`,
|
| 105 |
+
`set${upperCaseCandidatePrefix.toUpperCase()}${caseCandidateSuffix}`,
|
| 106 |
+
] : [];
|
| 107 |
+
|
| 108 |
+
const isSymmetricGetterSetterPair = valueVariable
|
| 109 |
+
&& setterVariable
|
| 110 |
+
&& expectedSetterVariableNames.indexOf(setterVariableName) !== -1
|
| 111 |
+
&& variableNodes.length === 2;
|
| 112 |
+
|
| 113 |
+
if (!isSymmetricGetterSetterPair) {
|
| 114 |
+
const suggestions = [
|
| 115 |
+
Object.assign(
|
| 116 |
+
getMessageData('suggestPair', messages.suggestPair),
|
| 117 |
+
{
|
| 118 |
+
fix(fixer) {
|
| 119 |
+
if (expectedSetterVariableNames.length > 0) {
|
| 120 |
+
return fixer.replaceTextRange(
|
| 121 |
+
node.parent.id.range,
|
| 122 |
+
`[${valueVariableName}, ${expectedSetterVariableNames[0]}]`
|
| 123 |
+
);
|
| 124 |
+
}
|
| 125 |
+
},
|
| 126 |
+
}
|
| 127 |
+
),
|
| 128 |
+
];
|
| 129 |
+
|
| 130 |
+
const defaultReactImports = components.getDefaultReactImports();
|
| 131 |
+
const defaultReactImportSpecifier = defaultReactImports
|
| 132 |
+
? defaultReactImports[0]
|
| 133 |
+
: undefined;
|
| 134 |
+
|
| 135 |
+
const defaultReactImportName = defaultReactImportSpecifier
|
| 136 |
+
? defaultReactImportSpecifier.local.name
|
| 137 |
+
: undefined;
|
| 138 |
+
|
| 139 |
+
const namedReactImports = components.getNamedReactImports();
|
| 140 |
+
const useStateReactImportSpecifier = namedReactImports
|
| 141 |
+
? namedReactImports.find((specifier) => specifier.imported.name === 'useState')
|
| 142 |
+
: undefined;
|
| 143 |
+
|
| 144 |
+
const isSingleGetter = valueVariable && variableNodes.length === 1;
|
| 145 |
+
const isUseStateCalledWithSingleArgument = node.arguments.length === 1;
|
| 146 |
+
if (isSingleGetter && isUseStateCalledWithSingleArgument) {
|
| 147 |
+
const useMemoReactImportSpecifier = namedReactImports
|
| 148 |
+
&& namedReactImports.find((specifier) => specifier.imported.name === 'useMemo');
|
| 149 |
+
|
| 150 |
+
let useMemoCode;
|
| 151 |
+
if (useMemoReactImportSpecifier) {
|
| 152 |
+
useMemoCode = useMemoReactImportSpecifier.local.name;
|
| 153 |
+
} else if (defaultReactImportName) {
|
| 154 |
+
useMemoCode = `${defaultReactImportName}.useMemo`;
|
| 155 |
+
} else {
|
| 156 |
+
useMemoCode = 'useMemo';
|
| 157 |
+
}
|
| 158 |
+
|
| 159 |
+
suggestions.unshift(Object.assign(
|
| 160 |
+
getMessageData('suggestMemo', messages.suggestMemo),
|
| 161 |
+
{
|
| 162 |
+
fix: (fixer) => [
|
| 163 |
+
// Add useMemo import, if necessary
|
| 164 |
+
useStateReactImportSpecifier
|
| 165 |
+
&& (!useMemoReactImportSpecifier || defaultReactImportName)
|
| 166 |
+
&& fixer.insertTextAfter(useStateReactImportSpecifier, ', useMemo'),
|
| 167 |
+
// Convert single-value destructure to simple assignment
|
| 168 |
+
fixer.replaceTextRange(node.parent.id.range, valueVariableName),
|
| 169 |
+
// Convert useState call to useMemo + arrow function + dependency array
|
| 170 |
+
fixer.replaceTextRange(
|
| 171 |
+
node.range,
|
| 172 |
+
`${useMemoCode}(() => ${getText(context, node.arguments[0])}, [])`
|
| 173 |
+
),
|
| 174 |
+
].filter(Boolean),
|
| 175 |
+
}
|
| 176 |
+
));
|
| 177 |
+
}
|
| 178 |
+
|
| 179 |
+
if (isOnlyValueDestructuring) {
|
| 180 |
+
report(
|
| 181 |
+
context,
|
| 182 |
+
messages.useStateErrorMessageOrAddOption,
|
| 183 |
+
'useStateErrorMessageOrAddOption',
|
| 184 |
+
{
|
| 185 |
+
node: node.parent.id,
|
| 186 |
+
suggest: false,
|
| 187 |
+
}
|
| 188 |
+
);
|
| 189 |
+
return;
|
| 190 |
+
}
|
| 191 |
+
|
| 192 |
+
report(
|
| 193 |
+
context,
|
| 194 |
+
messages.useStateErrorMessage,
|
| 195 |
+
'useStateErrorMessage',
|
| 196 |
+
{
|
| 197 |
+
node: node.parent.id,
|
| 198 |
+
suggest: suggestions,
|
| 199 |
+
}
|
| 200 |
+
);
|
| 201 |
+
}
|
| 202 |
+
},
|
| 203 |
+
};
|
| 204 |
+
}),
|
| 205 |
+
};
|
node_modules/eslint-plugin-react/lib/rules/iframe-missing-sandbox.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
declare const _exports: import('eslint').Rule.RuleModule;
|
| 2 |
+
export = _exports;
|
| 3 |
+
//# sourceMappingURL=iframe-missing-sandbox.d.ts.map
|