eslint-plugin-constructors 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +128 -62
- package/docs/LICENSE.md +9 -0
- package/docs/SECURITY.md +3 -0
- package/package.json +27 -5
- package/src/index.d.ts +6 -0
- package/src/index.js +1 -3
- package/src/rules/no-explicit-return.js +14 -14
- package/src/rules/require-new.js +8 -12
package/README.md
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
|
+
<a id="top"></a>
|
|
2
|
+
|
|
1
3
|
# eslint-plugin-constructors
|
|
2
4
|
|
|
3
|
-
[]
|
|
5
|
+
[][epc-npm]
|
|
6
|
+
[](./#license)
|
|
4
7
|
[](https://eslint.org/)
|
|
5
8
|
|
|
6
|
-
ESLint
|
|
9
|
+
ESLint rules to enforce best practices for constructor usage.
|
|
10
|
+
|
|
11
|
+
<img src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-constructors/6eeba7b2cb/assets/images/screenshots/vs-code/squiggles.png">
|
|
7
12
|
|
|
8
13
|
## Installation
|
|
9
14
|
|
|
15
|
+
From your project root:
|
|
16
|
+
|
|
10
17
|
```bash
|
|
11
18
|
npm i -D eslint-plugin-constructors
|
|
12
19
|
```
|
|
@@ -19,84 +26,95 @@ Add `constructors` to your flat config:
|
|
|
19
26
|
import constructors from 'eslint-plugin-constructors'
|
|
20
27
|
|
|
21
28
|
export default [
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
{
|
|
30
|
+
files: ['**/*.js'],
|
|
31
|
+
plugins: { constructors },
|
|
32
|
+
rules: {
|
|
33
|
+
'constructors/no-explicit-return': 'error',
|
|
34
|
+
'constructors/require-error-subclass-name': 'error',
|
|
35
|
+
'constructors/require-new': ['error', 'error-only']
|
|
36
|
+
}
|
|
37
|
+
}
|
|
31
38
|
]
|
|
32
39
|
```
|
|
33
40
|
|
|
34
|
-
|
|
41
|
+
**Note:** Rule config is either a severity string (`'off'`, `'warn'`, `'error'`) or an array `[severity, options]` when the rule accepts options.
|
|
42
|
+
|
|
43
|
+
To use the bundled recommended config (enables all 3 rules at `'error'`):
|
|
35
44
|
|
|
36
45
|
```js
|
|
37
46
|
import constructors from 'eslint-plugin-constructors'
|
|
38
47
|
|
|
39
48
|
export default [
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
]
|
|
49
|
+
{
|
|
50
|
+
files: ['**/*.js'],
|
|
51
|
+
...constructors.configs.recommended
|
|
52
|
+
}
|
|
53
|
+
]
|
|
45
54
|
```
|
|
46
55
|
|
|
47
56
|
## Rules
|
|
48
57
|
|
|
49
|
-
|
|
58
|
+
- [`no-explicit-return`](#no-explicit-return)
|
|
59
|
+
- [`require-error-subclass-name`](#require-error-subclass-name)
|
|
60
|
+
- [`require-new`](#require-new)
|
|
50
61
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
Requires `new` when calling error constructors (and optionally other built‑in constructors).
|
|
62
|
+
---
|
|
54
63
|
|
|
55
|
-
|
|
64
|
+
### `no-explicit-return`
|
|
56
65
|
|
|
57
|
-
|
|
58
|
-
- `"builtins"` – also includes `Array`, `Boolean`, `Date`, `Function`, `Number`, `Object`, `RegExp`, `String`, `Symbol`, `BigInt`, `Map`, `Set`, `WeakMap`, `WeakSet`
|
|
66
|
+
> Disallows explicit `return` statements inside class constructors.
|
|
59
67
|
|
|
60
|
-
####
|
|
68
|
+
#### Incorrect code
|
|
61
69
|
|
|
62
70
|
```js
|
|
63
|
-
|
|
64
|
-
|
|
71
|
+
class A {
|
|
72
|
+
constructor() {
|
|
73
|
+
return
|
|
74
|
+
}
|
|
75
|
+
}
|
|
65
76
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
77
|
+
class B {
|
|
78
|
+
constructor() {
|
|
79
|
+
return this
|
|
80
|
+
}
|
|
81
|
+
}
|
|
69
82
|
```
|
|
70
83
|
|
|
71
|
-
####
|
|
84
|
+
#### Correct code
|
|
72
85
|
|
|
73
86
|
```js
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
m = new Map()
|
|
87
|
+
class A {
|
|
88
|
+
constructor() {
|
|
89
|
+
this.x = 1
|
|
90
|
+
}
|
|
91
|
+
}
|
|
80
92
|
```
|
|
81
93
|
|
|
82
94
|
#### When not to use it
|
|
83
95
|
|
|
84
|
-
If you
|
|
96
|
+
If you need to return a different object from a constructor.
|
|
97
|
+
|
|
98
|
+
<div align="center">
|
|
99
|
+
|
|
100
|
+
[Back to index ↑][epc-rules]
|
|
101
|
+
|
|
102
|
+
</div>
|
|
85
103
|
|
|
86
104
|
---
|
|
87
105
|
|
|
88
106
|
### `require-error-subclass-name`
|
|
89
107
|
|
|
90
|
-
Requires classes extending `Error` have a name ending in `Error`.
|
|
108
|
+
> Requires classes extending `Error` have a name ending in `Error`.
|
|
91
109
|
|
|
92
|
-
####
|
|
110
|
+
#### Incorrect code
|
|
93
111
|
|
|
94
112
|
```js
|
|
95
113
|
class My extends Error {}
|
|
96
114
|
const Custom = class extends Error {}
|
|
97
115
|
```
|
|
98
116
|
|
|
99
|
-
####
|
|
117
|
+
#### Correct code
|
|
100
118
|
|
|
101
119
|
```js
|
|
102
120
|
class MyError extends Error {}
|
|
@@ -107,42 +125,90 @@ const CustomError = class extends Error {}
|
|
|
107
125
|
|
|
108
126
|
If you don't follow the convention of suffixing custom error classes w/ `Error`.
|
|
109
127
|
|
|
128
|
+
<div align="center">
|
|
129
|
+
|
|
130
|
+
[Back to index ↑][epc-rules]
|
|
131
|
+
|
|
132
|
+
</div>
|
|
133
|
+
|
|
110
134
|
---
|
|
111
135
|
|
|
112
|
-
### `
|
|
136
|
+
### `require-new`
|
|
137
|
+
|
|
138
|
+
> Requires `new` when calling error constructors (and optionally other built‑in constructors).
|
|
139
|
+
|
|
140
|
+
#### Options
|
|
113
141
|
|
|
114
|
-
|
|
142
|
+
- `'error-only'` (default) – only error constructors (`AggregateError`, `Error`, `EvalError`, `RangeError`, `ReferenceError`, `SyntaxError`, `TypeError`, `URIError`)
|
|
143
|
+
- `'builtins'` – also includes `Array`, `BigInt`, `Boolean`, `Date`, `Function`, `Map`, `Number`, `Object`, `RegExp`, `Set`, `String`, `Symbol`, `WeakMap`, `WeakSet`
|
|
115
144
|
|
|
116
|
-
#### Incorrect
|
|
145
|
+
#### Incorrect code
|
|
117
146
|
|
|
118
147
|
```js
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
return
|
|
122
|
-
}
|
|
123
|
-
}
|
|
148
|
+
throw Error('boom')
|
|
149
|
+
throw TypeError('bad')
|
|
124
150
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
}
|
|
151
|
+
// w/ builtins:
|
|
152
|
+
const arr = Array(),
|
|
153
|
+
m = Map()
|
|
130
154
|
```
|
|
131
155
|
|
|
132
|
-
#### Correct
|
|
156
|
+
#### Correct code
|
|
133
157
|
|
|
134
158
|
```js
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
159
|
+
throw new Error('boom')
|
|
160
|
+
throw new TypeError('bad')
|
|
161
|
+
|
|
162
|
+
// w/ builtins:
|
|
163
|
+
const arr = new Array(),
|
|
164
|
+
m = new Map()
|
|
140
165
|
```
|
|
141
166
|
|
|
142
167
|
#### When not to use it
|
|
143
168
|
|
|
144
|
-
If you
|
|
169
|
+
If you prefer the convenience of calling built‑ins without `new` (which is allowed by the spec).
|
|
170
|
+
|
|
171
|
+
<div align="center">
|
|
172
|
+
|
|
173
|
+
[Back to index ↑][epc-rules]
|
|
174
|
+
|
|
175
|
+
</div>
|
|
176
|
+
|
|
177
|
+
---
|
|
145
178
|
|
|
146
179
|
## License
|
|
147
180
|
|
|
148
|
-
Copyright © 2026 [Adam Lui](
|
|
181
|
+
> Copyright © 2026 [Adam Lui][adamlui-cb] under the [MIT license](./docs/LICENSE.md).
|
|
182
|
+
|
|
183
|
+
## Related
|
|
184
|
+
|
|
185
|
+
<!-- eslint-plugin-greasemonkey -->
|
|
186
|
+
|
|
187
|
+
### [<img width=16 src="https://www.google.com/s2/favicons?domain=eslint.org&sz=16">][epg-readme] [eslint-plugin-greasemonkey][epg-readme]
|
|
188
|
+
|
|
189
|
+
<details>
|
|
190
|
+
|
|
191
|
+
<summary>ESLint rules for Greasemonkey userscripts.</summary><br>
|
|
192
|
+
|
|
193
|
+
> [<img width=555 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/c9ac2985bb/assets/images/screenshots/vs-code/squiggles.png">][epg-readme]
|
|
194
|
+
|
|
195
|
+
> [**Install**][epg-install] / [Readme][epg-readme] / [Report bug][epg-issues]
|
|
196
|
+
|
|
197
|
+
</details>
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
<div align="center">
|
|
202
|
+
|
|
203
|
+
[**Latest releases**][epc-releases] / [More packages by author][adamlui-npmx] / [Back to top ↑](#top)
|
|
204
|
+
|
|
205
|
+
</div>
|
|
206
|
+
|
|
207
|
+
[adamlui-cb]: https://codeberg.org/adamlui
|
|
208
|
+
[adamlui-npmx]: https://npmx.dev/org/adamlui
|
|
209
|
+
[epc-npm]: https://www.npmjs.com/package/eslint-plugin-constructors
|
|
210
|
+
[epc-rules]: #rules
|
|
211
|
+
[epc-releases]: https://codeberg.org/adamlui/eslint-plugin-constructors/releases
|
|
212
|
+
[epg-install]: https://codeberg.org/adamlui/eslint-plugin-greasemonkey/#installation
|
|
213
|
+
[epg-readme]: https://codeberg.org/adamlui/eslint-plugin-greasemonkey/#readme
|
|
214
|
+
[epg-issues]: https://codeberg.org/adamlui/eslint-plugin-greasemonkey/issues/new
|
package/docs/LICENSE.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# 🏛️ MIT License
|
|
2
|
+
|
|
3
|
+
**Copyright © 2026 [Adam Lui](https://codeberg.org/adamlui).**
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
|
package/docs/SECURITY.md
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-constructors",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "ESLint rules for constructor usage",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -12,11 +12,27 @@
|
|
|
12
12
|
"url": "https://codeberg.org/adamlui"
|
|
13
13
|
},
|
|
14
14
|
"homepage": "https://codeberg.org/adamlui/eslint-plugin-constructors/#readme",
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://codeberg.org/adamlui/eslint-plugin-constructors/issues",
|
|
17
|
+
"email": "support@adamlui.com"
|
|
18
|
+
},
|
|
15
19
|
"license": "MIT",
|
|
20
|
+
"funding": [
|
|
21
|
+
{
|
|
22
|
+
"type": "ko-fi",
|
|
23
|
+
"url": "https://ko-fi.com/adamlui"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"type": "paypal",
|
|
27
|
+
"url": "https://paypal.me/adamlui"
|
|
28
|
+
}
|
|
29
|
+
],
|
|
16
30
|
"main": "src/index.js",
|
|
17
31
|
"files": [
|
|
18
|
-
"
|
|
32
|
+
"docs/",
|
|
33
|
+
"src/"
|
|
19
34
|
],
|
|
35
|
+
"types": "src/index.d.ts",
|
|
20
36
|
"scripts": {
|
|
21
37
|
"prepare": "husky",
|
|
22
38
|
"lint": "eslint . --cache && yamllint .",
|
|
@@ -30,6 +46,10 @@
|
|
|
30
46
|
"bump:feat": "npm run bump:minor",
|
|
31
47
|
"bump:major": "bash utils/bump.sh major"
|
|
32
48
|
},
|
|
49
|
+
"repository": {
|
|
50
|
+
"type": "git",
|
|
51
|
+
"url": "git+https://codeberg.org/adamlui/eslint-plugin-constructors.git"
|
|
52
|
+
},
|
|
33
53
|
"keywords": [
|
|
34
54
|
"code-quality",
|
|
35
55
|
"constructor",
|
|
@@ -39,6 +59,9 @@
|
|
|
39
59
|
"eslintplugin",
|
|
40
60
|
"security"
|
|
41
61
|
],
|
|
62
|
+
"peerDependencies": {
|
|
63
|
+
"eslint": ">=9.0.0"
|
|
64
|
+
},
|
|
42
65
|
"devDependencies": {
|
|
43
66
|
"@e18e/eslint-plugin": "^0.8.0",
|
|
44
67
|
"@eslint/js": "^10.0.1",
|
|
@@ -46,7 +69,9 @@
|
|
|
46
69
|
"@eslint/markdown": "^8.0.3",
|
|
47
70
|
"@stylistic/eslint-plugin": "^5.10.0",
|
|
48
71
|
"eslint": "^10.10.0",
|
|
72
|
+
"eslint-plugin-eslint-plugin": "^7.6.2",
|
|
49
73
|
"eslint-plugin-import-x": "^4.17.1",
|
|
74
|
+
"eslint-plugin-n": "^18.3.0",
|
|
50
75
|
"eslint-plugin-no-secrets": "^2.3.3",
|
|
51
76
|
"eslint-plugin-no-unsanitized": "^4.1.5",
|
|
52
77
|
"eslint-plugin-promise": "^7.3.0",
|
|
@@ -54,8 +79,5 @@
|
|
|
54
79
|
"globals": "^17.12.0",
|
|
55
80
|
"husky": "^9.1.7",
|
|
56
81
|
"yamllint-js": "^0.2.4"
|
|
57
|
-
},
|
|
58
|
-
"peerDependencies": {
|
|
59
|
-
"eslint": ">=9.0.0"
|
|
60
82
|
}
|
|
61
83
|
}
|
package/src/index.d.ts
ADDED
package/src/index.js
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
const reFuncNodeType = /^(?:Arrow)?Function(?:Declaration|Expression)$/
|
|
2
2
|
|
|
3
|
+
function isInsideConstructorFunc(node) {
|
|
4
|
+
let current = node.parent
|
|
5
|
+
while (current) {
|
|
6
|
+
if (reFuncNodeType.test(current.type))
|
|
7
|
+
return ( // whether this func is constructor's val
|
|
8
|
+
current.parent?.type == 'MethodDefinition'
|
|
9
|
+
&& current.parent.kind == 'constructor'
|
|
10
|
+
&& !current.parent.static
|
|
11
|
+
)
|
|
12
|
+
current = current.parent
|
|
13
|
+
}
|
|
14
|
+
return false
|
|
15
|
+
}
|
|
16
|
+
|
|
3
17
|
export default {
|
|
4
18
|
meta: {
|
|
5
19
|
type: 'problem',
|
|
@@ -13,20 +27,6 @@ export default {
|
|
|
13
27
|
},
|
|
14
28
|
|
|
15
29
|
create(context) {
|
|
16
|
-
function isInsideConstructorFunc(node) {
|
|
17
|
-
let current = node.parent
|
|
18
|
-
while (current) {
|
|
19
|
-
if (reFuncNodeType.test(current.type))
|
|
20
|
-
return ( // whether this func is constructor's val
|
|
21
|
-
current.parent?.type == 'MethodDefinition'
|
|
22
|
-
&& current.parent.kind == 'constructor'
|
|
23
|
-
&& !current.parent.static
|
|
24
|
-
)
|
|
25
|
-
current = current.parent
|
|
26
|
-
}
|
|
27
|
-
return false
|
|
28
|
-
}
|
|
29
|
-
|
|
30
30
|
return {
|
|
31
31
|
ReturnStatement(node) {
|
|
32
32
|
if (isInsideConstructorFunc(node))
|
package/src/rules/require-new.js
CHANGED
|
@@ -1,17 +1,8 @@
|
|
|
1
1
|
const ERR_CONSTRUCTORS = new Set([
|
|
2
|
-
'Error',
|
|
3
|
-
'TypeError',
|
|
4
|
-
'RangeError',
|
|
5
|
-
'SyntaxError',
|
|
6
|
-
'ReferenceError',
|
|
7
|
-
'URIError',
|
|
8
|
-
'EvalError',
|
|
9
|
-
'AggregateError'
|
|
10
|
-
])
|
|
2
|
+
'AggregateError', 'Error', 'EvalError', 'RangeError', 'ReferenceError', 'SyntaxError', 'TypeError', 'URIError'])
|
|
11
3
|
|
|
12
4
|
const BUILTIN_CONSTRUCTORS = new Set([
|
|
13
|
-
'Array', 'Boolean', 'Date', 'Function', 'Number', 'Object',
|
|
14
|
-
'RegExp', 'String', 'Symbol', 'BigInt', 'Map', 'Set',
|
|
5
|
+
'Array', 'BigInt', 'Boolean', 'Date', 'Function', 'Map', 'Number', 'Object', 'RegExp', 'Set', 'String', 'Symbol',
|
|
15
6
|
'WeakMap', 'WeakSet'
|
|
16
7
|
])
|
|
17
8
|
|
|
@@ -26,7 +17,12 @@ export default {
|
|
|
26
17
|
recommended: true
|
|
27
18
|
},
|
|
28
19
|
fixable: 'code',
|
|
29
|
-
schema: [{
|
|
20
|
+
schema: [{
|
|
21
|
+
type: 'string',
|
|
22
|
+
enum: ['error-only', 'builtins'],
|
|
23
|
+
description: 'Constructor categories to check: "error-only" (default) or "builtins".'
|
|
24
|
+
}],
|
|
25
|
+
defaultOptions: ['error-only'],
|
|
30
26
|
messages: { requireNew: 'Use `new {{name}}()` instead of `{{name}}()`' }
|
|
31
27
|
},
|
|
32
28
|
|