@friendsoftheweb/eslint-plugin 0.0.2 → 0.0.3-beta.1
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 +94 -21
- package/dist/cjs/index.js +183 -55
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +183 -55
- package/dist/esm/index.js.map +1 -1
- package/dist/types/index.d.ts +16 -0
- package/dist/types/rules/ban-lodash-import.d.ts +3 -0
- package/dist/types/rules/css-module-class-exists.d.ts +3 -0
- package/dist/types/rules/css-module-name-matches.d.ts +3 -0
- package/dist/types/rules/no-legacy-node-import.d.ts +4 -0
- package/dist/types/rules/react-named-func-components.d.ts +3 -0
- package/dist/types/rules/valid-server-actions-path.d.ts +3 -0
- package/package.json +7 -2
- package/dist/types/index.d.mts +0 -3
- package/dist/types/rules/ban-lodash-import.d.mts +0 -24
- package/dist/types/rules/css-module-class-exists.d.mts +0 -29
- package/dist/types/rules/css-module-name-matches.d.mts +0 -23
- package/dist/types/rules/valid-server-actions-path.d.mts +0 -23
package/README.md
CHANGED
|
@@ -8,14 +8,16 @@ yarn add -D @friendsoftheweb/eslint-plugin
|
|
|
8
8
|
|
|
9
9
|
## Rules
|
|
10
10
|
|
|
11
|
-
###
|
|
11
|
+
### Recommended Rules
|
|
12
|
+
|
|
13
|
+
#### `friendsoftheweb/ban-lodash-import`
|
|
12
14
|
|
|
13
15
|
Enforces importing functions from `lodash-es` instead of `lodash`.
|
|
14
16
|
|
|
15
17
|
This rule helps ensure tree shaking works properly by preferring ES module
|
|
16
18
|
imports from `lodash-es` over CommonJS imports from `lodash`.
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
##### Examples
|
|
19
21
|
|
|
20
22
|
❌ **Incorrect:**
|
|
21
23
|
|
|
@@ -35,12 +37,12 @@ import debounce from 'lodash-es/debounce';
|
|
|
35
37
|
**Note:** This rule provides automatic fixes for most cases, except for
|
|
36
38
|
`lodash/fp` imports which require manual migration.
|
|
37
39
|
|
|
38
|
-
|
|
40
|
+
#### `friendsoftheweb/css-module-class-exists`
|
|
39
41
|
|
|
40
42
|
Enforces that class names used from an imported CSS module exist in the module
|
|
41
43
|
file.
|
|
42
44
|
|
|
43
|
-
|
|
45
|
+
#### `friendsoftheweb/css-module-name-matches`
|
|
44
46
|
|
|
45
47
|
Enforces that a CSS module's filename matches the filename of the importing
|
|
46
48
|
file.
|
|
@@ -48,7 +50,7 @@ file.
|
|
|
48
50
|
This rule ensures consistent naming conventions by requiring CSS module files to
|
|
49
51
|
have the same base name as the file importing them.
|
|
50
52
|
|
|
51
|
-
|
|
53
|
+
#### `friendsoftheweb/valid-server-actions-path`
|
|
52
54
|
|
|
53
55
|
Enforces server actions are exported from file paths that match
|
|
54
56
|
`app/**/_actions.ts` or `app/**/_actions/**/*.ts`.
|
|
@@ -56,12 +58,80 @@ Enforces server actions are exported from file paths that match
|
|
|
56
58
|
This rule helps maintain a consistent file structure for Next.js server actions
|
|
57
59
|
by ensuring they are placed in designated locations.
|
|
58
60
|
|
|
61
|
+
### Future Rules
|
|
62
|
+
|
|
63
|
+
#### `friendsoftheweb/react-named-func-components`
|
|
64
|
+
|
|
65
|
+
Enforces using named functions when defining React components instead of arrow
|
|
66
|
+
functions. Component definitions that are wrapped in a function call (e.g.
|
|
67
|
+
`forwardRef()`) are allowed to use arrow functions.
|
|
68
|
+
|
|
69
|
+
This rule promotes better debugging and development experience by ensuring React
|
|
70
|
+
components are defined as named functions, which provide clearer stack traces
|
|
71
|
+
and better display names in React DevTools.
|
|
72
|
+
|
|
73
|
+
##### Examples
|
|
74
|
+
|
|
75
|
+
❌ **Incorrect:**
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
const Button: FC<PropsWithChildren> = (props) => {
|
|
79
|
+
const { children } = props;
|
|
80
|
+
|
|
81
|
+
return <button>{children}</button>;
|
|
82
|
+
};
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
✅ **Correct:**
|
|
86
|
+
|
|
87
|
+
```tsx
|
|
88
|
+
function Button(props: PropsWithChildren) {
|
|
89
|
+
const { children } = props;
|
|
90
|
+
|
|
91
|
+
return <button>{children}</button>;
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
```tsx
|
|
96
|
+
const Button = forwardRef<HTMLButtonElement, PropsWithChildren>(
|
|
97
|
+
(props, ref) => {
|
|
98
|
+
const { children } = props;
|
|
99
|
+
|
|
100
|
+
return <button ref={ref}>{children}</button>;
|
|
101
|
+
},
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
Button.displayName = 'Button';
|
|
105
|
+
```
|
|
106
|
+
|
|
59
107
|
## Example Configurations
|
|
60
108
|
|
|
61
|
-
###
|
|
109
|
+
### Recommended Configuration
|
|
110
|
+
|
|
111
|
+
```javascript
|
|
112
|
+
import friendsOfTheWeb from '@friendsoftheweb/eslint-plugin';
|
|
113
|
+
import { defineConfig } from 'eslint/config';
|
|
114
|
+
import tseslint from 'typescript-eslint';
|
|
115
|
+
|
|
116
|
+
export default defineConfig([
|
|
117
|
+
{ ignores: ['.yarn/**/*'] },
|
|
118
|
+
{
|
|
119
|
+
files: ['**/*.{js,jsx,ts,tsx}'],
|
|
120
|
+
extends: [
|
|
121
|
+
tseslint.configs.recommended,
|
|
122
|
+
friendsOfTheWeb.configs['flat/recommended'],
|
|
123
|
+
],
|
|
124
|
+
},
|
|
125
|
+
]);
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
#### Recommended Configuration with React
|
|
62
129
|
|
|
63
130
|
```javascript
|
|
64
131
|
import friendsOfTheWeb from '@friendsoftheweb/eslint-plugin';
|
|
132
|
+
import react from 'eslint-plugin-react';
|
|
133
|
+
import reactCompiler from 'eslint-plugin-react-compiler';
|
|
134
|
+
import reactHooks from 'eslint-plugin-react-hooks';
|
|
65
135
|
import { defineConfig } from 'eslint/config';
|
|
66
136
|
import tseslint from 'typescript-eslint';
|
|
67
137
|
|
|
@@ -71,13 +141,22 @@ export default defineConfig([
|
|
|
71
141
|
files: ['**/*.{js,jsx,ts,tsx}'],
|
|
72
142
|
extends: [
|
|
73
143
|
tseslint.configs.recommended,
|
|
144
|
+
react.configs.flat.recommended,
|
|
145
|
+
react.configs.flat['jsx-runtime'],
|
|
146
|
+
reactHooks.configs.flat.recommended,
|
|
147
|
+
reactCompiler.configs.recommended,
|
|
74
148
|
friendsOfTheWeb.configs['flat/recommended'],
|
|
75
149
|
],
|
|
150
|
+
settings: {
|
|
151
|
+
react: {
|
|
152
|
+
version: 'detect',
|
|
153
|
+
},
|
|
154
|
+
},
|
|
76
155
|
},
|
|
77
156
|
]);
|
|
78
157
|
```
|
|
79
158
|
|
|
80
|
-
|
|
159
|
+
#### Gradual Adoption
|
|
81
160
|
|
|
82
161
|
There is an additional configuration that makes it easier to adopt this plugin
|
|
83
162
|
by only warning about violations.
|
|
@@ -99,13 +178,16 @@ export default defineConfig([
|
|
|
99
178
|
]);
|
|
100
179
|
```
|
|
101
180
|
|
|
102
|
-
###
|
|
181
|
+
### Future Configuration
|
|
182
|
+
|
|
183
|
+
This configuration includes all of the [recommended rules](#recommended-rules)
|
|
184
|
+
and [additional rules](#future-rules) that will be considered violations in the
|
|
185
|
+
future.
|
|
186
|
+
|
|
187
|
+
Future rule violations are considered warnings with this configuration.
|
|
103
188
|
|
|
104
189
|
```javascript
|
|
105
190
|
import friendsOfTheWeb from '@friendsoftheweb/eslint-plugin';
|
|
106
|
-
import react from 'eslint-plugin-react';
|
|
107
|
-
import reactCompiler from 'eslint-plugin-react-compiler';
|
|
108
|
-
import reactHooks from 'eslint-plugin-react-hooks';
|
|
109
191
|
import { defineConfig } from 'eslint/config';
|
|
110
192
|
import tseslint from 'typescript-eslint';
|
|
111
193
|
|
|
@@ -115,17 +197,8 @@ export default defineConfig([
|
|
|
115
197
|
files: ['**/*.{js,jsx,ts,tsx}'],
|
|
116
198
|
extends: [
|
|
117
199
|
tseslint.configs.recommended,
|
|
118
|
-
|
|
119
|
-
react.configs.flat['jsx-runtime'],
|
|
120
|
-
reactHooks.configs.flat.recommended,
|
|
121
|
-
reactCompiler.configs.recommended,
|
|
122
|
-
friendsOfTheWeb.configs['flat/recommended'],
|
|
200
|
+
friendsOfTheWeb.configs['flat/future'],
|
|
123
201
|
],
|
|
124
|
-
settings: {
|
|
125
|
-
react: {
|
|
126
|
-
version: 'detect',
|
|
127
|
-
},
|
|
128
|
-
},
|
|
129
202
|
},
|
|
130
203
|
]);
|
|
131
204
|
```
|
package/dist/cjs/index.js
CHANGED
|
@@ -6,13 +6,12 @@ var postcss = require('postcss');
|
|
|
6
6
|
var selectorParser = require('postcss-selector-parser');
|
|
7
7
|
|
|
8
8
|
var name = "@friendsoftheweb/eslint-plugin";
|
|
9
|
-
var version = "0.0.
|
|
9
|
+
var version = "0.0.3-beta.1";
|
|
10
10
|
var packageJson = {
|
|
11
11
|
name: name,
|
|
12
12
|
version: version};
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
var banLodashImport = {
|
|
14
|
+
const banLodashImportRule = {
|
|
16
15
|
meta: {
|
|
17
16
|
type: 'problem',
|
|
18
17
|
fixable: 'code',
|
|
@@ -25,6 +24,7 @@ var banLodashImport = {
|
|
|
25
24
|
invalidImport: 'Functions must be imported from "lodash-es" instead of "lodash"',
|
|
26
25
|
},
|
|
27
26
|
},
|
|
27
|
+
defaultOptions: [],
|
|
28
28
|
create(context) {
|
|
29
29
|
return {
|
|
30
30
|
ImportDeclaration(node) {
|
|
@@ -55,8 +55,7 @@ var banLodashImport = {
|
|
|
55
55
|
},
|
|
56
56
|
};
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
var cssModuleNameMatchesRule = {
|
|
58
|
+
const cssModuleNameMatchesRule = {
|
|
60
59
|
meta: {
|
|
61
60
|
type: 'problem',
|
|
62
61
|
docs: {
|
|
@@ -68,6 +67,7 @@ var cssModuleNameMatchesRule = {
|
|
|
68
67
|
filenameMismatch: 'CSS module filename "{{cssModuleFilename}}" does not match the current filename "{{filename}}"',
|
|
69
68
|
},
|
|
70
69
|
},
|
|
70
|
+
defaultOptions: [],
|
|
71
71
|
create(context) {
|
|
72
72
|
return {
|
|
73
73
|
ImportDeclaration(node) {
|
|
@@ -93,8 +93,7 @@ var cssModuleNameMatchesRule = {
|
|
|
93
93
|
},
|
|
94
94
|
};
|
|
95
95
|
|
|
96
|
-
|
|
97
|
-
var cssModuleClassExistsRule = {
|
|
96
|
+
const cssModuleClassExistsRule = {
|
|
98
97
|
meta: {
|
|
99
98
|
type: 'problem',
|
|
100
99
|
docs: {
|
|
@@ -110,6 +109,7 @@ var cssModuleClassExistsRule = {
|
|
|
110
109
|
classDoesNotExist: 'Class `.{{className}}` does not exist in the CSS module imported as `{{objectName}}`',
|
|
111
110
|
},
|
|
112
111
|
},
|
|
112
|
+
defaultOptions: [],
|
|
113
113
|
create(context) {
|
|
114
114
|
const classNames = {};
|
|
115
115
|
return {
|
|
@@ -255,8 +255,155 @@ var cssModuleClassExistsRule = {
|
|
|
255
255
|
},
|
|
256
256
|
};
|
|
257
257
|
|
|
258
|
-
|
|
259
|
-
|
|
258
|
+
const noLegacyNodeImportRule = {
|
|
259
|
+
meta: {
|
|
260
|
+
type: 'problem',
|
|
261
|
+
fixable: 'code',
|
|
262
|
+
docs: {
|
|
263
|
+
description: 'enforce importing node standard library modules using `node:` prefix',
|
|
264
|
+
url: 'https://github.com/friendsoftheweb/eslint-plugin#friendsofthewebno-legacy-node-import',
|
|
265
|
+
},
|
|
266
|
+
schema: [],
|
|
267
|
+
messages: {
|
|
268
|
+
invalidImport: 'Node standard library modules must be imported using the "node:" prefix',
|
|
269
|
+
},
|
|
270
|
+
},
|
|
271
|
+
defaultOptions: [],
|
|
272
|
+
create(context) {
|
|
273
|
+
return {
|
|
274
|
+
ImportDeclaration(node) {
|
|
275
|
+
if (typeof node.source.value !== 'string' ||
|
|
276
|
+
!NODE_STANDARD_MODULES.includes(node.source.value)) {
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
context.report({
|
|
280
|
+
node,
|
|
281
|
+
messageId: 'invalidImport',
|
|
282
|
+
fix(fixer) {
|
|
283
|
+
if (typeof node.source.value !== 'string') {
|
|
284
|
+
return null;
|
|
285
|
+
}
|
|
286
|
+
const newImportPath = `node:${node.source.value}`;
|
|
287
|
+
const quote = node.source.raw[0]; // preserve original quote style
|
|
288
|
+
return fixer.replaceText(node.source, `${quote}${newImportPath}${quote}`);
|
|
289
|
+
},
|
|
290
|
+
});
|
|
291
|
+
},
|
|
292
|
+
};
|
|
293
|
+
},
|
|
294
|
+
};
|
|
295
|
+
const NODE_STANDARD_MODULES = Object.freeze([
|
|
296
|
+
'assert',
|
|
297
|
+
'assert/strict',
|
|
298
|
+
'async_hooks',
|
|
299
|
+
'buffer',
|
|
300
|
+
'child_process',
|
|
301
|
+
'cluster',
|
|
302
|
+
'console',
|
|
303
|
+
'crypto',
|
|
304
|
+
'dns',
|
|
305
|
+
'dns/promises',
|
|
306
|
+
'domain',
|
|
307
|
+
'events',
|
|
308
|
+
'fs',
|
|
309
|
+
'fs/promises',
|
|
310
|
+
'http',
|
|
311
|
+
'http2',
|
|
312
|
+
'https',
|
|
313
|
+
'inspector',
|
|
314
|
+
'module',
|
|
315
|
+
'net',
|
|
316
|
+
'os',
|
|
317
|
+
'path',
|
|
318
|
+
'perf_hooks',
|
|
319
|
+
'process',
|
|
320
|
+
'punycode',
|
|
321
|
+
'querystring',
|
|
322
|
+
'readline',
|
|
323
|
+
'readline/promises',
|
|
324
|
+
'repl',
|
|
325
|
+
'sqlite',
|
|
326
|
+
'stream',
|
|
327
|
+
'stream/promises',
|
|
328
|
+
'string_decoder',
|
|
329
|
+
'test',
|
|
330
|
+
'timers',
|
|
331
|
+
'timers/promises',
|
|
332
|
+
'tls',
|
|
333
|
+
'trace_events',
|
|
334
|
+
'tty',
|
|
335
|
+
'url',
|
|
336
|
+
'util',
|
|
337
|
+
'util/types',
|
|
338
|
+
'v8',
|
|
339
|
+
'vm',
|
|
340
|
+
'wasi',
|
|
341
|
+
'worker_threads',
|
|
342
|
+
'zlib',
|
|
343
|
+
]);
|
|
344
|
+
|
|
345
|
+
const reactNamedFuncComponentsRule = {
|
|
346
|
+
meta: {
|
|
347
|
+
type: 'problem',
|
|
348
|
+
docs: {
|
|
349
|
+
description: 'enforce use of named functions when defining React components',
|
|
350
|
+
url: 'https://github.com/friendsoftheweb/eslint-plugin#friendsofthewebreact-named-func-components',
|
|
351
|
+
},
|
|
352
|
+
schema: [],
|
|
353
|
+
messages: {
|
|
354
|
+
invalidComponentDefinition: 'React components must be defined using named functions',
|
|
355
|
+
},
|
|
356
|
+
},
|
|
357
|
+
defaultOptions: [],
|
|
358
|
+
create(context) {
|
|
359
|
+
return {
|
|
360
|
+
VariableDeclarator(node) {
|
|
361
|
+
if (!isReactComponent(node)) {
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
context.report({
|
|
365
|
+
node,
|
|
366
|
+
messageId: 'invalidComponentDefinition',
|
|
367
|
+
});
|
|
368
|
+
},
|
|
369
|
+
};
|
|
370
|
+
},
|
|
371
|
+
};
|
|
372
|
+
function isReactComponent(node) {
|
|
373
|
+
if (node.type === 'VariableDeclarator') {
|
|
374
|
+
if (node.init == null) {
|
|
375
|
+
return false;
|
|
376
|
+
}
|
|
377
|
+
if (node.init.type !== 'ArrowFunctionExpression') {
|
|
378
|
+
return false;
|
|
379
|
+
}
|
|
380
|
+
if (node.id.type !== 'Identifier' || !/^[A-Z]/.test(node.id.name)) {
|
|
381
|
+
return false;
|
|
382
|
+
}
|
|
383
|
+
return isReactComponent(node.init);
|
|
384
|
+
}
|
|
385
|
+
else if (node.type === 'FunctionDeclaration') {
|
|
386
|
+
if (node.id != null && !/^[A-Z]/.test(node.id.name)) {
|
|
387
|
+
return false;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
if (node.body.type !== 'BlockStatement') {
|
|
391
|
+
return false;
|
|
392
|
+
}
|
|
393
|
+
for (const statement of node.body.body) {
|
|
394
|
+
if (statement.type === 'ReturnStatement' &&
|
|
395
|
+
statement.argument != null &&
|
|
396
|
+
// @ts-expect-error: ESTree types are missing JSXElement
|
|
397
|
+
(statement.argument.type === 'JSXElement' ||
|
|
398
|
+
(statement.argument.type === 'Literal' &&
|
|
399
|
+
statement.argument.value === null))) {
|
|
400
|
+
return true;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
return false;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
const validServerActionsPathRule = {
|
|
260
407
|
meta: {
|
|
261
408
|
type: 'problem',
|
|
262
409
|
docs: {
|
|
@@ -268,6 +415,7 @@ var validServerActionsPathRule = {
|
|
|
268
415
|
invalidPath: 'Server action files must be located in a directory named "_actions" or have the filename "_actions.ts"',
|
|
269
416
|
},
|
|
270
417
|
},
|
|
418
|
+
defaultOptions: [],
|
|
271
419
|
create(context) {
|
|
272
420
|
return {
|
|
273
421
|
ExpressionStatement(node) {
|
|
@@ -293,7 +441,6 @@ var validServerActionsPathRule = {
|
|
|
293
441
|
},
|
|
294
442
|
};
|
|
295
443
|
|
|
296
|
-
/** @type {import('eslint').ESLint.Plugin} */
|
|
297
444
|
const plugin = {
|
|
298
445
|
meta: {
|
|
299
446
|
name: packageJson.name,
|
|
@@ -301,57 +448,38 @@ const plugin = {
|
|
|
301
448
|
},
|
|
302
449
|
configs: {},
|
|
303
450
|
rules: {
|
|
304
|
-
'ban-lodash-import':
|
|
451
|
+
'ban-lodash-import': banLodashImportRule,
|
|
305
452
|
'css-module-name-matches': cssModuleNameMatchesRule,
|
|
306
453
|
'css-module-class-exists': cssModuleClassExistsRule,
|
|
454
|
+
'no-legacy-node-import': noLegacyNodeImportRule,
|
|
455
|
+
'react-named-func-components': reactNamedFuncComponentsRule,
|
|
307
456
|
'valid-server-actions-path': validServerActionsPathRule,
|
|
308
457
|
},
|
|
309
458
|
};
|
|
310
|
-
Object.
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
'friendsoftheweb/css-module-name-matches': 'error',
|
|
319
|
-
'friendsoftheweb/css-module-class-exists': 'error',
|
|
320
|
-
'friendsoftheweb/valid-server-actions-path': 'error',
|
|
321
|
-
},
|
|
459
|
+
const RULE_NAMES = Object.keys(plugin.rules).map((ruleName) => `friendsoftheweb/${ruleName}`);
|
|
460
|
+
/**
|
|
461
|
+
* @param {'error' | 'warn'} reportLevel
|
|
462
|
+
*/
|
|
463
|
+
function buildConfig(reportLevel) {
|
|
464
|
+
return {
|
|
465
|
+
plugins: {
|
|
466
|
+
friendsoftheweb: plugin,
|
|
322
467
|
},
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
plugins: { friendsoftheweb: plugin },
|
|
339
|
-
rules: {
|
|
340
|
-
'friendsoftheweb/ban-lodash-import': 'error',
|
|
341
|
-
'friendsoftheweb/css-module-name-matches': 'error',
|
|
342
|
-
'friendsoftheweb/css-module-class-exists': 'error',
|
|
343
|
-
'friendsoftheweb/valid-server-actions-path': 'error',
|
|
344
|
-
},
|
|
345
|
-
},
|
|
346
|
-
migrate: {
|
|
347
|
-
plugins: { friendsoftheweb: plugin },
|
|
348
|
-
rules: {
|
|
349
|
-
'friendsoftheweb/ban-lodash-import': 'warn',
|
|
350
|
-
'friendsoftheweb/css-module-name-matches': 'warn',
|
|
351
|
-
'friendsoftheweb/css-module-class-exists': 'warn',
|
|
352
|
-
'friendsoftheweb/valid-server-actions-path': 'warn',
|
|
353
|
-
},
|
|
354
|
-
},
|
|
468
|
+
rules: Object.fromEntries(RULE_NAMES.map((ruleName) => [ruleName, reportLevel])),
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
const errorConfig = buildConfig('error');
|
|
472
|
+
const warnConfig = buildConfig('warn');
|
|
473
|
+
const futureConfig = Object.assign(Object.assign({}, errorConfig), { rules: Object.assign(Object.assign({}, errorConfig.rules), { 'friendsoftheweb/react-named-func-components': 'warn' }) });
|
|
474
|
+
const recommendedConfig = Object.assign(Object.assign({}, errorConfig), { rules: Object.assign(Object.assign({}, errorConfig.rules), { 'friendsoftheweb/react-named-func-components': 'off' }) });
|
|
475
|
+
const migrateConfig = Object.assign(Object.assign({}, warnConfig), { rules: Object.assign(Object.assign({}, warnConfig.rules), { 'friendsoftheweb/react-named-func-components': 'off' }) });
|
|
476
|
+
Object.assign(plugin.configs, {
|
|
477
|
+
'flat/future': [futureConfig],
|
|
478
|
+
'flat/recommended': [recommendedConfig],
|
|
479
|
+
'flat/migrate': [migrateConfig],
|
|
480
|
+
future: futureConfig,
|
|
481
|
+
recommended: recommendedConfig,
|
|
482
|
+
migrate: migrateConfig,
|
|
355
483
|
});
|
|
356
484
|
|
|
357
485
|
module.exports = plugin;
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../src/rules/ban-lodash-import.mjs","../../../../src/rules/css-module-name-matches.mjs","../../../../src/rules/css-module-class-exists.mjs","../../../../src/rules/valid-server-actions-path.mjs","../../../../src/index.mjs"],"sourcesContent":["/** @type {import('eslint').JSRuleDefinition} */\nexport default {\n meta: {\n type: 'problem',\n fixable: 'code',\n docs: {\n description:\n 'enforce importing functions from `lodash-es` instead of `lodash`',\n url: 'https://github.com/friendsoftheweb/eslint-plugin#friendsofthewebban-lodash-import',\n },\n schema: [],\n messages: {\n invalidImport:\n 'Functions must be imported from \"lodash-es\" instead of \"lodash\"',\n },\n },\n create(context) {\n return {\n ImportDeclaration(node) {\n if (\n typeof node.source.value !== 'string' ||\n (node.source.value !== 'lodash' &&\n !node.source.value.startsWith('lodash/'))\n ) {\n return;\n }\n\n context.report({\n node,\n messageId: 'invalidImport',\n fix(fixer) {\n if (typeof node.source.value !== 'string') {\n return null;\n }\n\n if (node.source.value === 'lodash/fp') {\n return null; // no automatic fix for fp imports\n }\n\n const newImportPath =\n node.source.value === 'lodash'\n ? 'lodash-es'\n : node.source.value.replace(/^lodash\\//, 'lodash-es/');\n\n const quote = node.source.raw[0]; // preserve original quote style\n\n return fixer.replaceText(\n node.source,\n `${quote}${newImportPath}${quote}`,\n );\n },\n });\n },\n };\n },\n};\n","import path from 'node:path';\n\n/** @type {import('eslint').JSRuleDefinition} */\nexport default {\n meta: {\n type: 'problem',\n docs: {\n description:\n \"enforce that a CSS module's filename matches the filename of the importing file\",\n url: 'https://github.com/friendsoftheweb/eslint-plugin#friendsofthewebcss-module-name-matches',\n },\n schema: [],\n messages: {\n filenameMismatch:\n 'CSS module filename \"{{cssModuleFilename}}\" does not match the current filename \"{{filename}}\"',\n },\n },\n create(context) {\n return {\n ImportDeclaration(node) {\n if (\n typeof node.source.value !== 'string' ||\n !node.source.value.endsWith('.module.css')\n ) {\n return;\n }\n\n const filename = path.basename(\n context.filename,\n path.extname(context.filename),\n );\n\n const cssModulePath = node.source.value;\n const cssModuleFilename = path.basename(cssModulePath, '.module.css');\n\n if (cssModuleFilename !== filename) {\n context.report({\n node,\n messageId: 'filenameMismatch',\n data: {\n cssModuleFilename,\n filename,\n },\n });\n }\n },\n };\n },\n};\n","import path from 'node:path';\nimport fs from 'node:fs';\n\nimport { parse } from 'postcss';\nimport selectorParser from 'postcss-selector-parser';\n\n/** @type {import('eslint').JSRuleDefinition} */\nexport default {\n meta: {\n type: 'problem',\n docs: {\n description:\n 'enforce that class names used from an imported CSS module exist in the module file',\n url: 'https://github.com/friendsoftheweb/eslint-plugin#friendsofthewebcss-module-class-exists',\n },\n schema: [],\n messages: {\n relativePath:\n 'CSS module import \"{{importPath}}\" should be a relative path',\n defaultImport:\n 'CSS module import \"{{importPath}}\" should have a default import',\n onlyDefaultImport:\n 'CSS module import \"{{importPath}}\" should have only a default import',\n fileDoesNotExist:\n 'CSS module file \"{{absoluteImportPath}}\" does not exist',\n classDoesNotExist:\n 'Class `.{{className}}` does not exist in the CSS module imported as `{{objectName}}`',\n },\n },\n create(context) {\n const classNames = {};\n\n return {\n ImportDeclaration(node) {\n if (\n typeof node.source.value !== 'string' ||\n !node.source.value.endsWith('.module.css')\n ) {\n return;\n }\n\n const importPath = node.source.value;\n\n if (!(importPath.startsWith('./') || importPath.startsWith('../'))) {\n context.report({\n node,\n messageId: 'relativePath',\n data: { importPath },\n });\n\n return;\n }\n\n if (node.specifiers.length === 0) {\n context.report({\n node,\n messageId: 'defaultImport',\n data: { importPath },\n });\n\n return;\n }\n\n if (node.specifiers.length > 1) {\n context.report({\n node,\n messageId: 'onlyDefaultImport',\n data: { importPath },\n });\n\n return;\n }\n\n const defaultImportSpecifier = node.specifiers.find(\n (specifier) => specifier.type === 'ImportDefaultSpecifier',\n );\n\n if (defaultImportSpecifier == null) {\n context.report({\n node,\n messageId: 'onlyDefaultImport',\n data: { importPath },\n });\n\n return;\n }\n\n const dirname = path.dirname(context.physicalFilename);\n const absoluteImportPath = path.resolve(dirname, importPath);\n\n if (!fs.existsSync(absoluteImportPath)) {\n context.report({\n node,\n messageId: 'fileDoesNotExist',\n data: { absoluteImportPath },\n });\n\n return;\n }\n\n const importName = defaultImportSpecifier.local.name;\n\n classNames[importName] = new Set();\n\n const cssModuleContent = fs.readFileSync(absoluteImportPath, 'utf8');\n const root = parse(cssModuleContent);\n\n for (const node of root.nodes) {\n if (node.type === 'rule') {\n selectorParser(function transform(selectors) {\n selectors.walkClasses((classNode) => {\n classNames[importName].add(classNode.value);\n });\n }).processSync(node.selector);\n } else if (\n node.type === 'atrule' &&\n (node.name === 'media' ||\n node.name === 'container' ||\n node.name === 'layer')\n ) {\n for (const childNode of node.nodes) {\n if (childNode.type !== 'rule') {\n continue;\n }\n\n selectorParser(function transform(selectors) {\n selectors.walkClasses((classNode) => {\n classNames[importName].add(classNode.value);\n });\n }).processSync(childNode.selector);\n }\n }\n }\n },\n MemberExpression(node) {\n if (node.object.type !== 'Identifier') {\n return;\n }\n\n if (classNames[node.object.name] == null) {\n return;\n }\n\n const objectName = node.object.name;\n\n if (node.property.type === 'Identifier') {\n const className = node.property.name;\n\n if (!classNames[objectName].has(className)) {\n context.report({\n node,\n messageId: 'classDoesNotExist',\n data: { className, objectName },\n });\n }\n\n return;\n }\n\n if (\n node.property.type === 'Literal' &&\n typeof node.property.value === 'string'\n ) {\n const className = node.property.value;\n\n if (!classNames[objectName].has(className)) {\n context.report({\n node,\n messageId: 'classDoesNotExist',\n data: { className, objectName },\n });\n }\n }\n },\n VariableDeclarator(node) {\n if (node.id.type !== 'ObjectPattern') {\n return;\n }\n\n if (node.init?.type !== 'Identifier') {\n return;\n }\n\n const objectName = node.init.name;\n\n if (classNames[objectName] == null) {\n return;\n }\n\n for (const property of node.id.properties) {\n if (property.type !== 'Property') {\n continue;\n }\n\n if (property.key.type !== 'Identifier') {\n continue;\n }\n\n const className = property.key.name;\n\n if (!classNames[objectName].has(className)) {\n context.report({\n node: property,\n messageId: 'classDoesNotExist',\n data: { className, objectName },\n });\n }\n }\n },\n };\n },\n};\n","import path from 'node:path';\n\n/** @type {import('eslint').JSRuleDefinition} */\nexport default {\n meta: {\n type: 'problem',\n docs: {\n description:\n 'enforce server actions are exported from file paths that match \"app/**/_actions.ts\" or \"app/**/_actions/**/*.ts\"',\n url: 'https://github.com/friendsoftheweb/eslint-plugin#friendsofthewebvalid-server-actions-path',\n },\n schema: [],\n messages: {\n invalidPath:\n 'Server action files must be located in a directory named \"_actions\" or have the filename \"_actions.ts\"',\n },\n },\n create(context) {\n return {\n ExpressionStatement(node) {\n if (\n node.expression.type !== 'Literal' ||\n node.expression.value !== 'use server'\n ) {\n return;\n }\n\n const basename = path.basename(context.filename);\n const dirname = path.dirname(context.filename);\n\n // Escape backslashes for RegExp (Windows paths)\n const escapedSep = path.sep.replace('\\\\', '\\\\\\\\');\n\n const isInActionsDir = new RegExp(\n `app(${escapedSep}.*)?${escapedSep}_actions`,\n ).test(dirname);\n\n const isActionsFile =\n (dirname === 'app' || new RegExp(`app${escapedSep}`).test(dirname)) &&\n /_actions\\.(js|ts)$/.test(basename);\n\n if (!isInActionsDir && !isActionsFile) {\n context.report({\n node,\n messageId: 'invalidPath',\n });\n }\n },\n };\n },\n};\n","import packageJson from '../package.json' with { type: 'json' };\n\nimport banLodashImport from './rules/ban-lodash-import.mjs';\nimport cssModuleNameMatchesRule from './rules/css-module-name-matches.mjs';\nimport cssModuleClassExistsRule from './rules/css-module-class-exists.mjs';\nimport validServerActionsPathRule from './rules/valid-server-actions-path.mjs';\n\n/** @type {import('eslint').ESLint.Plugin} */\nconst plugin = {\n meta: {\n name: packageJson.name,\n version: packageJson.version,\n },\n configs: {},\n rules: {\n 'ban-lodash-import': banLodashImport,\n 'css-module-name-matches': cssModuleNameMatchesRule,\n 'css-module-class-exists': cssModuleClassExistsRule,\n 'valid-server-actions-path': validServerActionsPathRule,\n },\n};\n\nObject.assign(plugin.configs, {\n 'flat/recommended': [\n {\n plugins: {\n friendsoftheweb: plugin,\n },\n rules: {\n 'friendsoftheweb/ban-lodash-import': 'error',\n 'friendsoftheweb/css-module-name-matches': 'error',\n 'friendsoftheweb/css-module-class-exists': 'error',\n 'friendsoftheweb/valid-server-actions-path': 'error',\n },\n },\n ],\n\n 'flat/migrate': [\n {\n plugins: {\n friendsoftheweb: plugin,\n },\n rules: {\n 'friendsoftheweb/ban-lodash-import': 'warn',\n 'friendsoftheweb/css-module-name-matches': 'warn',\n 'friendsoftheweb/css-module-class-exists': 'warn',\n 'friendsoftheweb/valid-server-actions-path': 'warn',\n },\n },\n ],\n\n recommended: {\n plugins: { friendsoftheweb: plugin },\n rules: {\n 'friendsoftheweb/ban-lodash-import': 'error',\n 'friendsoftheweb/css-module-name-matches': 'error',\n 'friendsoftheweb/css-module-class-exists': 'error',\n 'friendsoftheweb/valid-server-actions-path': 'error',\n },\n },\n\n migrate: {\n plugins: { friendsoftheweb: plugin },\n rules: {\n 'friendsoftheweb/ban-lodash-import': 'warn',\n 'friendsoftheweb/css-module-name-matches': 'warn',\n 'friendsoftheweb/css-module-class-exists': 'warn',\n 'friendsoftheweb/valid-server-actions-path': 'warn',\n },\n },\n});\n\nexport default plugin;\n"],"names":["parse"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/rules/ban-lodash-import.ts","../../../../src/rules/css-module-name-matches.ts","../../../../src/rules/css-module-class-exists.ts","../../../../src/rules/no-legacy-node-import.ts","../../../../src/rules/react-named-func-components.ts","../../../../src/rules/valid-server-actions-path.ts","../../../../src/index.ts"],"sourcesContent":["import type { RuleModule } from '@typescript-eslint/utils/ts-eslint';\n\nconst banLodashImportRule: RuleModule<'invalidImport'> = {\n meta: {\n type: 'problem',\n fixable: 'code',\n docs: {\n description:\n 'enforce importing functions from `lodash-es` instead of `lodash`',\n url: 'https://github.com/friendsoftheweb/eslint-plugin#friendsofthewebban-lodash-import',\n },\n schema: [],\n messages: {\n invalidImport:\n 'Functions must be imported from \"lodash-es\" instead of \"lodash\"',\n },\n },\n defaultOptions: [],\n create(context) {\n return {\n ImportDeclaration(node) {\n if (\n typeof node.source.value !== 'string' ||\n (node.source.value !== 'lodash' &&\n !node.source.value.startsWith('lodash/'))\n ) {\n return;\n }\n\n context.report({\n node,\n messageId: 'invalidImport',\n fix(fixer) {\n if (typeof node.source.value !== 'string') {\n return null;\n }\n\n if (node.source.value === 'lodash/fp') {\n return null; // no automatic fix for fp imports\n }\n\n const newImportPath =\n node.source.value === 'lodash'\n ? 'lodash-es'\n : node.source.value.replace(/^lodash\\//, 'lodash-es/');\n\n const quote = node.source.raw[0]; // preserve original quote style\n\n return fixer.replaceText(\n node.source,\n `${quote}${newImportPath}${quote}`,\n );\n },\n });\n },\n };\n },\n};\n\nexport default banLodashImportRule;\n","import path from 'node:path';\n\nimport type { RuleModule } from '@typescript-eslint/utils/ts-eslint';\n\nconst cssModuleNameMatchesRule: RuleModule<'filenameMismatch'> = {\n meta: {\n type: 'problem',\n docs: {\n description:\n \"enforce that a CSS module's filename matches the filename of the importing file\",\n url: 'https://github.com/friendsoftheweb/eslint-plugin#friendsofthewebcss-module-name-matches',\n },\n schema: [],\n messages: {\n filenameMismatch:\n 'CSS module filename \"{{cssModuleFilename}}\" does not match the current filename \"{{filename}}\"',\n },\n },\n defaultOptions: [],\n create(context) {\n return {\n ImportDeclaration(node) {\n if (\n typeof node.source.value !== 'string' ||\n !node.source.value.endsWith('.module.css')\n ) {\n return;\n }\n\n const filename = path.basename(\n context.filename,\n path.extname(context.filename),\n );\n\n const cssModulePath = node.source.value;\n const cssModuleFilename = path.basename(cssModulePath, '.module.css');\n\n if (cssModuleFilename !== filename) {\n context.report({\n node,\n messageId: 'filenameMismatch',\n data: {\n cssModuleFilename,\n filename,\n },\n });\n }\n },\n };\n },\n};\n\nexport default cssModuleNameMatchesRule;\n","import fs from 'node:fs';\nimport path from 'node:path';\n\nimport type { RuleModule } from '@typescript-eslint/utils/ts-eslint';\nimport { parse } from 'postcss';\nimport selectorParser from 'postcss-selector-parser';\n\nconst cssModuleClassExistsRule: RuleModule<\n | 'relativePath'\n | 'defaultImport'\n | 'onlyDefaultImport'\n | 'fileDoesNotExist'\n | 'classDoesNotExist'\n> = {\n meta: {\n type: 'problem',\n docs: {\n description:\n 'enforce that class names used from an imported CSS module exist in the module file',\n url: 'https://github.com/friendsoftheweb/eslint-plugin#friendsofthewebcss-module-class-exists',\n },\n schema: [],\n messages: {\n relativePath:\n 'CSS module import \"{{importPath}}\" should be a relative path',\n defaultImport:\n 'CSS module import \"{{importPath}}\" should have a default import',\n onlyDefaultImport:\n 'CSS module import \"{{importPath}}\" should have only a default import',\n fileDoesNotExist:\n 'CSS module file \"{{absoluteImportPath}}\" does not exist',\n classDoesNotExist:\n 'Class `.{{className}}` does not exist in the CSS module imported as `{{objectName}}`',\n },\n },\n defaultOptions: [],\n create(context) {\n const classNames = {};\n\n return {\n ImportDeclaration(node) {\n if (\n typeof node.source.value !== 'string' ||\n !node.source.value.endsWith('.module.css')\n ) {\n return;\n }\n\n const importPath = node.source.value;\n\n if (!(importPath.startsWith('./') || importPath.startsWith('../'))) {\n context.report({\n node,\n messageId: 'relativePath',\n data: { importPath },\n });\n\n return;\n }\n\n if (node.specifiers.length === 0) {\n context.report({\n node,\n messageId: 'defaultImport',\n data: { importPath },\n });\n\n return;\n }\n\n if (node.specifiers.length > 1) {\n context.report({\n node,\n messageId: 'onlyDefaultImport',\n data: { importPath },\n });\n\n return;\n }\n\n const defaultImportSpecifier = node.specifiers.find(\n (specifier) => specifier.type === 'ImportDefaultSpecifier',\n );\n\n if (defaultImportSpecifier == null) {\n context.report({\n node,\n messageId: 'onlyDefaultImport',\n data: { importPath },\n });\n\n return;\n }\n\n const dirname = path.dirname(context.physicalFilename);\n const absoluteImportPath = path.resolve(dirname, importPath);\n\n if (!fs.existsSync(absoluteImportPath)) {\n context.report({\n node,\n messageId: 'fileDoesNotExist',\n data: { absoluteImportPath },\n });\n\n return;\n }\n\n const importName = defaultImportSpecifier.local.name;\n\n classNames[importName] = new Set();\n\n const cssModuleContent = fs.readFileSync(absoluteImportPath, 'utf8');\n const root = parse(cssModuleContent);\n\n for (const node of root.nodes) {\n if (node.type === 'rule') {\n selectorParser(function transform(selectors) {\n selectors.walkClasses((classNode) => {\n classNames[importName].add(classNode.value);\n });\n }).processSync(node.selector);\n } else if (\n node.type === 'atrule' &&\n (node.name === 'media' ||\n node.name === 'container' ||\n node.name === 'layer')\n ) {\n for (const childNode of node.nodes) {\n if (childNode.type !== 'rule') {\n continue;\n }\n\n selectorParser(function transform(selectors) {\n selectors.walkClasses((classNode) => {\n classNames[importName].add(classNode.value);\n });\n }).processSync(childNode.selector);\n }\n }\n }\n },\n MemberExpression(node) {\n if (node.object.type !== 'Identifier') {\n return;\n }\n\n if (classNames[node.object.name] == null) {\n return;\n }\n\n const objectName = node.object.name;\n\n if (node.property.type === 'Identifier') {\n const className = node.property.name;\n\n if (!classNames[objectName].has(className)) {\n context.report({\n node,\n messageId: 'classDoesNotExist',\n data: { className, objectName },\n });\n }\n\n return;\n }\n\n if (\n node.property.type === 'Literal' &&\n typeof node.property.value === 'string'\n ) {\n const className = node.property.value;\n\n if (!classNames[objectName].has(className)) {\n context.report({\n node,\n messageId: 'classDoesNotExist',\n data: { className, objectName },\n });\n }\n }\n },\n VariableDeclarator(node) {\n if (node.id.type !== 'ObjectPattern') {\n return;\n }\n\n if (node.init?.type !== 'Identifier') {\n return;\n }\n\n const objectName = node.init.name;\n\n if (classNames[objectName] == null) {\n return;\n }\n\n for (const property of node.id.properties) {\n if (property.type !== 'Property') {\n continue;\n }\n\n if (property.key.type !== 'Identifier') {\n continue;\n }\n\n const className = property.key.name;\n\n if (!classNames[objectName].has(className)) {\n context.report({\n node: property,\n messageId: 'classDoesNotExist',\n data: { className, objectName },\n });\n }\n }\n },\n };\n },\n};\n\nexport default cssModuleClassExistsRule;\n","import type { RuleModule } from '@typescript-eslint/utils/ts-eslint';\n\nconst noLegacyNodeImportRule: RuleModule<'invalidImport'> = {\n meta: {\n type: 'problem',\n fixable: 'code',\n docs: {\n description:\n 'enforce importing node standard library modules using `node:` prefix',\n url: 'https://github.com/friendsoftheweb/eslint-plugin#friendsofthewebno-legacy-node-import',\n },\n schema: [],\n messages: {\n invalidImport:\n 'Node standard library modules must be imported using the \"node:\" prefix',\n },\n },\n defaultOptions: [],\n create(context) {\n return {\n ImportDeclaration(node) {\n if (\n typeof node.source.value !== 'string' ||\n !NODE_STANDARD_MODULES.includes(node.source.value)\n ) {\n return;\n }\n\n context.report({\n node,\n messageId: 'invalidImport',\n fix(fixer) {\n if (typeof node.source.value !== 'string') {\n return null;\n }\n\n const newImportPath = `node:${node.source.value}`;\n const quote = node.source.raw[0]; // preserve original quote style\n\n return fixer.replaceText(\n node.source,\n `${quote}${newImportPath}${quote}`,\n );\n },\n });\n },\n };\n },\n};\n\nexport default noLegacyNodeImportRule;\n\nexport const NODE_STANDARD_MODULES = Object.freeze([\n 'assert',\n 'assert/strict',\n 'async_hooks',\n 'buffer',\n 'child_process',\n 'cluster',\n 'console',\n 'crypto',\n 'dns',\n 'dns/promises',\n 'domain',\n 'events',\n 'fs',\n 'fs/promises',\n 'http',\n 'http2',\n 'https',\n 'inspector',\n 'module',\n 'net',\n 'os',\n 'path',\n 'perf_hooks',\n 'process',\n 'punycode',\n 'querystring',\n 'readline',\n 'readline/promises',\n 'repl',\n 'sqlite',\n 'stream',\n 'stream/promises',\n 'string_decoder',\n 'test',\n 'timers',\n 'timers/promises',\n 'tls',\n 'trace_events',\n 'tty',\n 'url',\n 'util',\n 'util/types',\n 'v8',\n 'vm',\n 'wasi',\n 'worker_threads',\n 'zlib',\n]);\n","import type { RuleModule } from '@typescript-eslint/utils/ts-eslint';\nimport type {\n ArrowFunctionExpression,\n FunctionDeclaration,\n VariableDeclarator,\n} from 'estree';\n\nconst reactNamedFuncComponentsRule: RuleModule<'invalidComponentDefinition'> = {\n meta: {\n type: 'problem',\n docs: {\n description:\n 'enforce use of named functions when defining React components',\n url: 'https://github.com/friendsoftheweb/eslint-plugin#friendsofthewebreact-named-func-components',\n },\n schema: [],\n messages: {\n invalidComponentDefinition:\n 'React components must be defined using named functions',\n },\n },\n defaultOptions: [],\n create(context) {\n return {\n VariableDeclarator(node) {\n if (!isReactComponent(node as VariableDeclarator)) {\n return;\n }\n\n context.report({\n node,\n messageId: 'invalidComponentDefinition',\n });\n },\n };\n },\n};\n\nexport default reactNamedFuncComponentsRule;\n\nfunction isReactComponent(\n node: FunctionDeclaration | ArrowFunctionExpression | VariableDeclarator,\n) {\n if (node.type === 'VariableDeclarator') {\n if (node.init == null) {\n return false;\n }\n\n if (node.init.type !== 'ArrowFunctionExpression') {\n return false;\n }\n\n if (node.id.type !== 'Identifier' || !/^[A-Z]/.test(node.id.name)) {\n return false;\n }\n\n return isReactComponent(node.init);\n } else if (node.type === 'FunctionDeclaration') {\n if (node.id != null && !/^[A-Z]/.test(node.id.name)) {\n return false;\n }\n }\n\n if (node.body.type !== 'BlockStatement') {\n return false;\n }\n\n for (const statement of node.body.body) {\n if (\n statement.type === 'ReturnStatement' &&\n statement.argument != null &&\n // @ts-expect-error: ESTree types are missing JSXElement\n (statement.argument.type === 'JSXElement' ||\n (statement.argument.type === 'Literal' &&\n statement.argument.value === null))\n ) {\n return true;\n }\n }\n\n return false;\n}\n","import path from 'node:path';\n\nimport type { RuleModule } from '@typescript-eslint/utils/ts-eslint';\n\nconst validServerActionsPathRule: RuleModule<'invalidPath'> = {\n meta: {\n type: 'problem',\n docs: {\n description:\n 'enforce server actions are exported from file paths that match \"app/**/_actions.ts\" or \"app/**/_actions/**/*.ts\"',\n url: 'https://github.com/friendsoftheweb/eslint-plugin#friendsofthewebvalid-server-actions-path',\n },\n schema: [],\n messages: {\n invalidPath:\n 'Server action files must be located in a directory named \"_actions\" or have the filename \"_actions.ts\"',\n },\n },\n defaultOptions: [],\n create(context) {\n return {\n ExpressionStatement(node) {\n if (\n node.expression.type !== 'Literal' ||\n node.expression.value !== 'use server'\n ) {\n return;\n }\n\n const basename = path.basename(context.filename);\n const dirname = path.dirname(context.filename);\n\n // Escape backslashes for RegExp (Windows paths)\n const escapedSep = path.sep.replace('\\\\', '\\\\\\\\');\n\n const isInActionsDir = new RegExp(\n `app(${escapedSep}.*)?${escapedSep}_actions`,\n ).test(dirname);\n\n const isActionsFile =\n (dirname === 'app' || new RegExp(`app${escapedSep}`).test(dirname)) &&\n /_actions\\.(js|ts)$/.test(basename);\n\n if (!isInActionsDir && !isActionsFile) {\n context.report({\n node,\n messageId: 'invalidPath',\n });\n }\n },\n };\n },\n};\n\nexport default validServerActionsPathRule;\n","import packageJson from '../package.json' with { type: 'json' };\n\nimport banLodashImport from './rules/ban-lodash-import.ts';\nimport cssModuleNameMatchesRule from './rules/css-module-name-matches.ts';\nimport cssModuleClassExistsRule from './rules/css-module-class-exists.ts';\nimport noLegacyNodeImport from './rules/no-legacy-node-import.ts';\nimport reactNamedFuncComponents from './rules/react-named-func-components.ts';\nimport validServerActionsPathRule from './rules/valid-server-actions-path.ts';\n\nconst plugin = {\n meta: {\n name: packageJson.name,\n version: packageJson.version,\n },\n configs: {},\n rules: {\n 'ban-lodash-import': banLodashImport,\n 'css-module-name-matches': cssModuleNameMatchesRule,\n 'css-module-class-exists': cssModuleClassExistsRule,\n 'no-legacy-node-import': noLegacyNodeImport,\n 'react-named-func-components': reactNamedFuncComponents,\n 'valid-server-actions-path': validServerActionsPathRule,\n },\n};\n\nconst RULE_NAMES = Object.keys(plugin.rules).map(\n (ruleName) => `friendsoftheweb/${ruleName}`,\n);\n\n/**\n * @param {'error' | 'warn'} reportLevel\n */\nfunction buildConfig(reportLevel) {\n return {\n plugins: {\n friendsoftheweb: plugin,\n },\n rules: Object.fromEntries(\n RULE_NAMES.map((ruleName) => [ruleName, reportLevel]),\n ),\n };\n}\n\nconst errorConfig = buildConfig('error');\nconst warnConfig = buildConfig('warn');\n\nconst futureConfig = {\n ...errorConfig,\n rules: {\n ...errorConfig.rules,\n 'friendsoftheweb/react-named-func-components': 'warn',\n },\n};\n\nconst recommendedConfig = {\n ...errorConfig,\n rules: {\n ...errorConfig.rules,\n 'friendsoftheweb/react-named-func-components': 'off',\n },\n};\n\nconst migrateConfig = {\n ...warnConfig,\n rules: {\n ...warnConfig.rules,\n 'friendsoftheweb/react-named-func-components': 'off',\n },\n};\n\nObject.assign(plugin.configs, {\n 'flat/future': [futureConfig],\n 'flat/recommended': [recommendedConfig],\n 'flat/migrate': [migrateConfig],\n future: futureConfig,\n recommended: recommendedConfig,\n migrate: migrateConfig,\n});\n\nexport default plugin;\n"],"names":["parse","banLodashImport","noLegacyNodeImport","reactNamedFuncComponents"],"mappings":"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"}
|
package/dist/esm/index.js
CHANGED
|
@@ -4,13 +4,12 @@ import { parse } from 'postcss';
|
|
|
4
4
|
import selectorParser from 'postcss-selector-parser';
|
|
5
5
|
|
|
6
6
|
var name = "@friendsoftheweb/eslint-plugin";
|
|
7
|
-
var version = "0.0.
|
|
7
|
+
var version = "0.0.3-beta.1";
|
|
8
8
|
var packageJson = {
|
|
9
9
|
name: name,
|
|
10
10
|
version: version};
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
var banLodashImport = {
|
|
12
|
+
const banLodashImportRule = {
|
|
14
13
|
meta: {
|
|
15
14
|
type: 'problem',
|
|
16
15
|
fixable: 'code',
|
|
@@ -23,6 +22,7 @@ var banLodashImport = {
|
|
|
23
22
|
invalidImport: 'Functions must be imported from "lodash-es" instead of "lodash"',
|
|
24
23
|
},
|
|
25
24
|
},
|
|
25
|
+
defaultOptions: [],
|
|
26
26
|
create(context) {
|
|
27
27
|
return {
|
|
28
28
|
ImportDeclaration(node) {
|
|
@@ -53,8 +53,7 @@ var banLodashImport = {
|
|
|
53
53
|
},
|
|
54
54
|
};
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
var cssModuleNameMatchesRule = {
|
|
56
|
+
const cssModuleNameMatchesRule = {
|
|
58
57
|
meta: {
|
|
59
58
|
type: 'problem',
|
|
60
59
|
docs: {
|
|
@@ -66,6 +65,7 @@ var cssModuleNameMatchesRule = {
|
|
|
66
65
|
filenameMismatch: 'CSS module filename "{{cssModuleFilename}}" does not match the current filename "{{filename}}"',
|
|
67
66
|
},
|
|
68
67
|
},
|
|
68
|
+
defaultOptions: [],
|
|
69
69
|
create(context) {
|
|
70
70
|
return {
|
|
71
71
|
ImportDeclaration(node) {
|
|
@@ -91,8 +91,7 @@ var cssModuleNameMatchesRule = {
|
|
|
91
91
|
},
|
|
92
92
|
};
|
|
93
93
|
|
|
94
|
-
|
|
95
|
-
var cssModuleClassExistsRule = {
|
|
94
|
+
const cssModuleClassExistsRule = {
|
|
96
95
|
meta: {
|
|
97
96
|
type: 'problem',
|
|
98
97
|
docs: {
|
|
@@ -108,6 +107,7 @@ var cssModuleClassExistsRule = {
|
|
|
108
107
|
classDoesNotExist: 'Class `.{{className}}` does not exist in the CSS module imported as `{{objectName}}`',
|
|
109
108
|
},
|
|
110
109
|
},
|
|
110
|
+
defaultOptions: [],
|
|
111
111
|
create(context) {
|
|
112
112
|
const classNames = {};
|
|
113
113
|
return {
|
|
@@ -253,8 +253,155 @@ var cssModuleClassExistsRule = {
|
|
|
253
253
|
},
|
|
254
254
|
};
|
|
255
255
|
|
|
256
|
-
|
|
257
|
-
|
|
256
|
+
const noLegacyNodeImportRule = {
|
|
257
|
+
meta: {
|
|
258
|
+
type: 'problem',
|
|
259
|
+
fixable: 'code',
|
|
260
|
+
docs: {
|
|
261
|
+
description: 'enforce importing node standard library modules using `node:` prefix',
|
|
262
|
+
url: 'https://github.com/friendsoftheweb/eslint-plugin#friendsofthewebno-legacy-node-import',
|
|
263
|
+
},
|
|
264
|
+
schema: [],
|
|
265
|
+
messages: {
|
|
266
|
+
invalidImport: 'Node standard library modules must be imported using the "node:" prefix',
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
defaultOptions: [],
|
|
270
|
+
create(context) {
|
|
271
|
+
return {
|
|
272
|
+
ImportDeclaration(node) {
|
|
273
|
+
if (typeof node.source.value !== 'string' ||
|
|
274
|
+
!NODE_STANDARD_MODULES.includes(node.source.value)) {
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
context.report({
|
|
278
|
+
node,
|
|
279
|
+
messageId: 'invalidImport',
|
|
280
|
+
fix(fixer) {
|
|
281
|
+
if (typeof node.source.value !== 'string') {
|
|
282
|
+
return null;
|
|
283
|
+
}
|
|
284
|
+
const newImportPath = `node:${node.source.value}`;
|
|
285
|
+
const quote = node.source.raw[0]; // preserve original quote style
|
|
286
|
+
return fixer.replaceText(node.source, `${quote}${newImportPath}${quote}`);
|
|
287
|
+
},
|
|
288
|
+
});
|
|
289
|
+
},
|
|
290
|
+
};
|
|
291
|
+
},
|
|
292
|
+
};
|
|
293
|
+
const NODE_STANDARD_MODULES = Object.freeze([
|
|
294
|
+
'assert',
|
|
295
|
+
'assert/strict',
|
|
296
|
+
'async_hooks',
|
|
297
|
+
'buffer',
|
|
298
|
+
'child_process',
|
|
299
|
+
'cluster',
|
|
300
|
+
'console',
|
|
301
|
+
'crypto',
|
|
302
|
+
'dns',
|
|
303
|
+
'dns/promises',
|
|
304
|
+
'domain',
|
|
305
|
+
'events',
|
|
306
|
+
'fs',
|
|
307
|
+
'fs/promises',
|
|
308
|
+
'http',
|
|
309
|
+
'http2',
|
|
310
|
+
'https',
|
|
311
|
+
'inspector',
|
|
312
|
+
'module',
|
|
313
|
+
'net',
|
|
314
|
+
'os',
|
|
315
|
+
'path',
|
|
316
|
+
'perf_hooks',
|
|
317
|
+
'process',
|
|
318
|
+
'punycode',
|
|
319
|
+
'querystring',
|
|
320
|
+
'readline',
|
|
321
|
+
'readline/promises',
|
|
322
|
+
'repl',
|
|
323
|
+
'sqlite',
|
|
324
|
+
'stream',
|
|
325
|
+
'stream/promises',
|
|
326
|
+
'string_decoder',
|
|
327
|
+
'test',
|
|
328
|
+
'timers',
|
|
329
|
+
'timers/promises',
|
|
330
|
+
'tls',
|
|
331
|
+
'trace_events',
|
|
332
|
+
'tty',
|
|
333
|
+
'url',
|
|
334
|
+
'util',
|
|
335
|
+
'util/types',
|
|
336
|
+
'v8',
|
|
337
|
+
'vm',
|
|
338
|
+
'wasi',
|
|
339
|
+
'worker_threads',
|
|
340
|
+
'zlib',
|
|
341
|
+
]);
|
|
342
|
+
|
|
343
|
+
const reactNamedFuncComponentsRule = {
|
|
344
|
+
meta: {
|
|
345
|
+
type: 'problem',
|
|
346
|
+
docs: {
|
|
347
|
+
description: 'enforce use of named functions when defining React components',
|
|
348
|
+
url: 'https://github.com/friendsoftheweb/eslint-plugin#friendsofthewebreact-named-func-components',
|
|
349
|
+
},
|
|
350
|
+
schema: [],
|
|
351
|
+
messages: {
|
|
352
|
+
invalidComponentDefinition: 'React components must be defined using named functions',
|
|
353
|
+
},
|
|
354
|
+
},
|
|
355
|
+
defaultOptions: [],
|
|
356
|
+
create(context) {
|
|
357
|
+
return {
|
|
358
|
+
VariableDeclarator(node) {
|
|
359
|
+
if (!isReactComponent(node)) {
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
context.report({
|
|
363
|
+
node,
|
|
364
|
+
messageId: 'invalidComponentDefinition',
|
|
365
|
+
});
|
|
366
|
+
},
|
|
367
|
+
};
|
|
368
|
+
},
|
|
369
|
+
};
|
|
370
|
+
function isReactComponent(node) {
|
|
371
|
+
if (node.type === 'VariableDeclarator') {
|
|
372
|
+
if (node.init == null) {
|
|
373
|
+
return false;
|
|
374
|
+
}
|
|
375
|
+
if (node.init.type !== 'ArrowFunctionExpression') {
|
|
376
|
+
return false;
|
|
377
|
+
}
|
|
378
|
+
if (node.id.type !== 'Identifier' || !/^[A-Z]/.test(node.id.name)) {
|
|
379
|
+
return false;
|
|
380
|
+
}
|
|
381
|
+
return isReactComponent(node.init);
|
|
382
|
+
}
|
|
383
|
+
else if (node.type === 'FunctionDeclaration') {
|
|
384
|
+
if (node.id != null && !/^[A-Z]/.test(node.id.name)) {
|
|
385
|
+
return false;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
if (node.body.type !== 'BlockStatement') {
|
|
389
|
+
return false;
|
|
390
|
+
}
|
|
391
|
+
for (const statement of node.body.body) {
|
|
392
|
+
if (statement.type === 'ReturnStatement' &&
|
|
393
|
+
statement.argument != null &&
|
|
394
|
+
// @ts-expect-error: ESTree types are missing JSXElement
|
|
395
|
+
(statement.argument.type === 'JSXElement' ||
|
|
396
|
+
(statement.argument.type === 'Literal' &&
|
|
397
|
+
statement.argument.value === null))) {
|
|
398
|
+
return true;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
return false;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
const validServerActionsPathRule = {
|
|
258
405
|
meta: {
|
|
259
406
|
type: 'problem',
|
|
260
407
|
docs: {
|
|
@@ -266,6 +413,7 @@ var validServerActionsPathRule = {
|
|
|
266
413
|
invalidPath: 'Server action files must be located in a directory named "_actions" or have the filename "_actions.ts"',
|
|
267
414
|
},
|
|
268
415
|
},
|
|
416
|
+
defaultOptions: [],
|
|
269
417
|
create(context) {
|
|
270
418
|
return {
|
|
271
419
|
ExpressionStatement(node) {
|
|
@@ -291,7 +439,6 @@ var validServerActionsPathRule = {
|
|
|
291
439
|
},
|
|
292
440
|
};
|
|
293
441
|
|
|
294
|
-
/** @type {import('eslint').ESLint.Plugin} */
|
|
295
442
|
const plugin = {
|
|
296
443
|
meta: {
|
|
297
444
|
name: packageJson.name,
|
|
@@ -299,57 +446,38 @@ const plugin = {
|
|
|
299
446
|
},
|
|
300
447
|
configs: {},
|
|
301
448
|
rules: {
|
|
302
|
-
'ban-lodash-import':
|
|
449
|
+
'ban-lodash-import': banLodashImportRule,
|
|
303
450
|
'css-module-name-matches': cssModuleNameMatchesRule,
|
|
304
451
|
'css-module-class-exists': cssModuleClassExistsRule,
|
|
452
|
+
'no-legacy-node-import': noLegacyNodeImportRule,
|
|
453
|
+
'react-named-func-components': reactNamedFuncComponentsRule,
|
|
305
454
|
'valid-server-actions-path': validServerActionsPathRule,
|
|
306
455
|
},
|
|
307
456
|
};
|
|
308
|
-
Object.
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
'friendsoftheweb/css-module-name-matches': 'error',
|
|
317
|
-
'friendsoftheweb/css-module-class-exists': 'error',
|
|
318
|
-
'friendsoftheweb/valid-server-actions-path': 'error',
|
|
319
|
-
},
|
|
457
|
+
const RULE_NAMES = Object.keys(plugin.rules).map((ruleName) => `friendsoftheweb/${ruleName}`);
|
|
458
|
+
/**
|
|
459
|
+
* @param {'error' | 'warn'} reportLevel
|
|
460
|
+
*/
|
|
461
|
+
function buildConfig(reportLevel) {
|
|
462
|
+
return {
|
|
463
|
+
plugins: {
|
|
464
|
+
friendsoftheweb: plugin,
|
|
320
465
|
},
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
plugins: { friendsoftheweb: plugin },
|
|
337
|
-
rules: {
|
|
338
|
-
'friendsoftheweb/ban-lodash-import': 'error',
|
|
339
|
-
'friendsoftheweb/css-module-name-matches': 'error',
|
|
340
|
-
'friendsoftheweb/css-module-class-exists': 'error',
|
|
341
|
-
'friendsoftheweb/valid-server-actions-path': 'error',
|
|
342
|
-
},
|
|
343
|
-
},
|
|
344
|
-
migrate: {
|
|
345
|
-
plugins: { friendsoftheweb: plugin },
|
|
346
|
-
rules: {
|
|
347
|
-
'friendsoftheweb/ban-lodash-import': 'warn',
|
|
348
|
-
'friendsoftheweb/css-module-name-matches': 'warn',
|
|
349
|
-
'friendsoftheweb/css-module-class-exists': 'warn',
|
|
350
|
-
'friendsoftheweb/valid-server-actions-path': 'warn',
|
|
351
|
-
},
|
|
352
|
-
},
|
|
466
|
+
rules: Object.fromEntries(RULE_NAMES.map((ruleName) => [ruleName, reportLevel])),
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
const errorConfig = buildConfig('error');
|
|
470
|
+
const warnConfig = buildConfig('warn');
|
|
471
|
+
const futureConfig = Object.assign(Object.assign({}, errorConfig), { rules: Object.assign(Object.assign({}, errorConfig.rules), { 'friendsoftheweb/react-named-func-components': 'warn' }) });
|
|
472
|
+
const recommendedConfig = Object.assign(Object.assign({}, errorConfig), { rules: Object.assign(Object.assign({}, errorConfig.rules), { 'friendsoftheweb/react-named-func-components': 'off' }) });
|
|
473
|
+
const migrateConfig = Object.assign(Object.assign({}, warnConfig), { rules: Object.assign(Object.assign({}, warnConfig.rules), { 'friendsoftheweb/react-named-func-components': 'off' }) });
|
|
474
|
+
Object.assign(plugin.configs, {
|
|
475
|
+
'flat/future': [futureConfig],
|
|
476
|
+
'flat/recommended': [recommendedConfig],
|
|
477
|
+
'flat/migrate': [migrateConfig],
|
|
478
|
+
future: futureConfig,
|
|
479
|
+
recommended: recommendedConfig,
|
|
480
|
+
migrate: migrateConfig,
|
|
353
481
|
});
|
|
354
482
|
|
|
355
483
|
export { plugin as default };
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../src/rules/ban-lodash-import.mjs","../../../../src/rules/css-module-name-matches.mjs","../../../../src/rules/css-module-class-exists.mjs","../../../../src/rules/valid-server-actions-path.mjs","../../../../src/index.mjs"],"sourcesContent":["/** @type {import('eslint').JSRuleDefinition} */\nexport default {\n meta: {\n type: 'problem',\n fixable: 'code',\n docs: {\n description:\n 'enforce importing functions from `lodash-es` instead of `lodash`',\n url: 'https://github.com/friendsoftheweb/eslint-plugin#friendsofthewebban-lodash-import',\n },\n schema: [],\n messages: {\n invalidImport:\n 'Functions must be imported from \"lodash-es\" instead of \"lodash\"',\n },\n },\n create(context) {\n return {\n ImportDeclaration(node) {\n if (\n typeof node.source.value !== 'string' ||\n (node.source.value !== 'lodash' &&\n !node.source.value.startsWith('lodash/'))\n ) {\n return;\n }\n\n context.report({\n node,\n messageId: 'invalidImport',\n fix(fixer) {\n if (typeof node.source.value !== 'string') {\n return null;\n }\n\n if (node.source.value === 'lodash/fp') {\n return null; // no automatic fix for fp imports\n }\n\n const newImportPath =\n node.source.value === 'lodash'\n ? 'lodash-es'\n : node.source.value.replace(/^lodash\\//, 'lodash-es/');\n\n const quote = node.source.raw[0]; // preserve original quote style\n\n return fixer.replaceText(\n node.source,\n `${quote}${newImportPath}${quote}`,\n );\n },\n });\n },\n };\n },\n};\n","import path from 'node:path';\n\n/** @type {import('eslint').JSRuleDefinition} */\nexport default {\n meta: {\n type: 'problem',\n docs: {\n description:\n \"enforce that a CSS module's filename matches the filename of the importing file\",\n url: 'https://github.com/friendsoftheweb/eslint-plugin#friendsofthewebcss-module-name-matches',\n },\n schema: [],\n messages: {\n filenameMismatch:\n 'CSS module filename \"{{cssModuleFilename}}\" does not match the current filename \"{{filename}}\"',\n },\n },\n create(context) {\n return {\n ImportDeclaration(node) {\n if (\n typeof node.source.value !== 'string' ||\n !node.source.value.endsWith('.module.css')\n ) {\n return;\n }\n\n const filename = path.basename(\n context.filename,\n path.extname(context.filename),\n );\n\n const cssModulePath = node.source.value;\n const cssModuleFilename = path.basename(cssModulePath, '.module.css');\n\n if (cssModuleFilename !== filename) {\n context.report({\n node,\n messageId: 'filenameMismatch',\n data: {\n cssModuleFilename,\n filename,\n },\n });\n }\n },\n };\n },\n};\n","import path from 'node:path';\nimport fs from 'node:fs';\n\nimport { parse } from 'postcss';\nimport selectorParser from 'postcss-selector-parser';\n\n/** @type {import('eslint').JSRuleDefinition} */\nexport default {\n meta: {\n type: 'problem',\n docs: {\n description:\n 'enforce that class names used from an imported CSS module exist in the module file',\n url: 'https://github.com/friendsoftheweb/eslint-plugin#friendsofthewebcss-module-class-exists',\n },\n schema: [],\n messages: {\n relativePath:\n 'CSS module import \"{{importPath}}\" should be a relative path',\n defaultImport:\n 'CSS module import \"{{importPath}}\" should have a default import',\n onlyDefaultImport:\n 'CSS module import \"{{importPath}}\" should have only a default import',\n fileDoesNotExist:\n 'CSS module file \"{{absoluteImportPath}}\" does not exist',\n classDoesNotExist:\n 'Class `.{{className}}` does not exist in the CSS module imported as `{{objectName}}`',\n },\n },\n create(context) {\n const classNames = {};\n\n return {\n ImportDeclaration(node) {\n if (\n typeof node.source.value !== 'string' ||\n !node.source.value.endsWith('.module.css')\n ) {\n return;\n }\n\n const importPath = node.source.value;\n\n if (!(importPath.startsWith('./') || importPath.startsWith('../'))) {\n context.report({\n node,\n messageId: 'relativePath',\n data: { importPath },\n });\n\n return;\n }\n\n if (node.specifiers.length === 0) {\n context.report({\n node,\n messageId: 'defaultImport',\n data: { importPath },\n });\n\n return;\n }\n\n if (node.specifiers.length > 1) {\n context.report({\n node,\n messageId: 'onlyDefaultImport',\n data: { importPath },\n });\n\n return;\n }\n\n const defaultImportSpecifier = node.specifiers.find(\n (specifier) => specifier.type === 'ImportDefaultSpecifier',\n );\n\n if (defaultImportSpecifier == null) {\n context.report({\n node,\n messageId: 'onlyDefaultImport',\n data: { importPath },\n });\n\n return;\n }\n\n const dirname = path.dirname(context.physicalFilename);\n const absoluteImportPath = path.resolve(dirname, importPath);\n\n if (!fs.existsSync(absoluteImportPath)) {\n context.report({\n node,\n messageId: 'fileDoesNotExist',\n data: { absoluteImportPath },\n });\n\n return;\n }\n\n const importName = defaultImportSpecifier.local.name;\n\n classNames[importName] = new Set();\n\n const cssModuleContent = fs.readFileSync(absoluteImportPath, 'utf8');\n const root = parse(cssModuleContent);\n\n for (const node of root.nodes) {\n if (node.type === 'rule') {\n selectorParser(function transform(selectors) {\n selectors.walkClasses((classNode) => {\n classNames[importName].add(classNode.value);\n });\n }).processSync(node.selector);\n } else if (\n node.type === 'atrule' &&\n (node.name === 'media' ||\n node.name === 'container' ||\n node.name === 'layer')\n ) {\n for (const childNode of node.nodes) {\n if (childNode.type !== 'rule') {\n continue;\n }\n\n selectorParser(function transform(selectors) {\n selectors.walkClasses((classNode) => {\n classNames[importName].add(classNode.value);\n });\n }).processSync(childNode.selector);\n }\n }\n }\n },\n MemberExpression(node) {\n if (node.object.type !== 'Identifier') {\n return;\n }\n\n if (classNames[node.object.name] == null) {\n return;\n }\n\n const objectName = node.object.name;\n\n if (node.property.type === 'Identifier') {\n const className = node.property.name;\n\n if (!classNames[objectName].has(className)) {\n context.report({\n node,\n messageId: 'classDoesNotExist',\n data: { className, objectName },\n });\n }\n\n return;\n }\n\n if (\n node.property.type === 'Literal' &&\n typeof node.property.value === 'string'\n ) {\n const className = node.property.value;\n\n if (!classNames[objectName].has(className)) {\n context.report({\n node,\n messageId: 'classDoesNotExist',\n data: { className, objectName },\n });\n }\n }\n },\n VariableDeclarator(node) {\n if (node.id.type !== 'ObjectPattern') {\n return;\n }\n\n if (node.init?.type !== 'Identifier') {\n return;\n }\n\n const objectName = node.init.name;\n\n if (classNames[objectName] == null) {\n return;\n }\n\n for (const property of node.id.properties) {\n if (property.type !== 'Property') {\n continue;\n }\n\n if (property.key.type !== 'Identifier') {\n continue;\n }\n\n const className = property.key.name;\n\n if (!classNames[objectName].has(className)) {\n context.report({\n node: property,\n messageId: 'classDoesNotExist',\n data: { className, objectName },\n });\n }\n }\n },\n };\n },\n};\n","import path from 'node:path';\n\n/** @type {import('eslint').JSRuleDefinition} */\nexport default {\n meta: {\n type: 'problem',\n docs: {\n description:\n 'enforce server actions are exported from file paths that match \"app/**/_actions.ts\" or \"app/**/_actions/**/*.ts\"',\n url: 'https://github.com/friendsoftheweb/eslint-plugin#friendsofthewebvalid-server-actions-path',\n },\n schema: [],\n messages: {\n invalidPath:\n 'Server action files must be located in a directory named \"_actions\" or have the filename \"_actions.ts\"',\n },\n },\n create(context) {\n return {\n ExpressionStatement(node) {\n if (\n node.expression.type !== 'Literal' ||\n node.expression.value !== 'use server'\n ) {\n return;\n }\n\n const basename = path.basename(context.filename);\n const dirname = path.dirname(context.filename);\n\n // Escape backslashes for RegExp (Windows paths)\n const escapedSep = path.sep.replace('\\\\', '\\\\\\\\');\n\n const isInActionsDir = new RegExp(\n `app(${escapedSep}.*)?${escapedSep}_actions`,\n ).test(dirname);\n\n const isActionsFile =\n (dirname === 'app' || new RegExp(`app${escapedSep}`).test(dirname)) &&\n /_actions\\.(js|ts)$/.test(basename);\n\n if (!isInActionsDir && !isActionsFile) {\n context.report({\n node,\n messageId: 'invalidPath',\n });\n }\n },\n };\n },\n};\n","import packageJson from '../package.json' with { type: 'json' };\n\nimport banLodashImport from './rules/ban-lodash-import.mjs';\nimport cssModuleNameMatchesRule from './rules/css-module-name-matches.mjs';\nimport cssModuleClassExistsRule from './rules/css-module-class-exists.mjs';\nimport validServerActionsPathRule from './rules/valid-server-actions-path.mjs';\n\n/** @type {import('eslint').ESLint.Plugin} */\nconst plugin = {\n meta: {\n name: packageJson.name,\n version: packageJson.version,\n },\n configs: {},\n rules: {\n 'ban-lodash-import': banLodashImport,\n 'css-module-name-matches': cssModuleNameMatchesRule,\n 'css-module-class-exists': cssModuleClassExistsRule,\n 'valid-server-actions-path': validServerActionsPathRule,\n },\n};\n\nObject.assign(plugin.configs, {\n 'flat/recommended': [\n {\n plugins: {\n friendsoftheweb: plugin,\n },\n rules: {\n 'friendsoftheweb/ban-lodash-import': 'error',\n 'friendsoftheweb/css-module-name-matches': 'error',\n 'friendsoftheweb/css-module-class-exists': 'error',\n 'friendsoftheweb/valid-server-actions-path': 'error',\n },\n },\n ],\n\n 'flat/migrate': [\n {\n plugins: {\n friendsoftheweb: plugin,\n },\n rules: {\n 'friendsoftheweb/ban-lodash-import': 'warn',\n 'friendsoftheweb/css-module-name-matches': 'warn',\n 'friendsoftheweb/css-module-class-exists': 'warn',\n 'friendsoftheweb/valid-server-actions-path': 'warn',\n },\n },\n ],\n\n recommended: {\n plugins: { friendsoftheweb: plugin },\n rules: {\n 'friendsoftheweb/ban-lodash-import': 'error',\n 'friendsoftheweb/css-module-name-matches': 'error',\n 'friendsoftheweb/css-module-class-exists': 'error',\n 'friendsoftheweb/valid-server-actions-path': 'error',\n },\n },\n\n migrate: {\n plugins: { friendsoftheweb: plugin },\n rules: {\n 'friendsoftheweb/ban-lodash-import': 'warn',\n 'friendsoftheweb/css-module-name-matches': 'warn',\n 'friendsoftheweb/css-module-class-exists': 'warn',\n 'friendsoftheweb/valid-server-actions-path': 'warn',\n },\n },\n});\n\nexport default plugin;\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/rules/ban-lodash-import.ts","../../../../src/rules/css-module-name-matches.ts","../../../../src/rules/css-module-class-exists.ts","../../../../src/rules/no-legacy-node-import.ts","../../../../src/rules/react-named-func-components.ts","../../../../src/rules/valid-server-actions-path.ts","../../../../src/index.ts"],"sourcesContent":["import type { RuleModule } from '@typescript-eslint/utils/ts-eslint';\n\nconst banLodashImportRule: RuleModule<'invalidImport'> = {\n meta: {\n type: 'problem',\n fixable: 'code',\n docs: {\n description:\n 'enforce importing functions from `lodash-es` instead of `lodash`',\n url: 'https://github.com/friendsoftheweb/eslint-plugin#friendsofthewebban-lodash-import',\n },\n schema: [],\n messages: {\n invalidImport:\n 'Functions must be imported from \"lodash-es\" instead of \"lodash\"',\n },\n },\n defaultOptions: [],\n create(context) {\n return {\n ImportDeclaration(node) {\n if (\n typeof node.source.value !== 'string' ||\n (node.source.value !== 'lodash' &&\n !node.source.value.startsWith('lodash/'))\n ) {\n return;\n }\n\n context.report({\n node,\n messageId: 'invalidImport',\n fix(fixer) {\n if (typeof node.source.value !== 'string') {\n return null;\n }\n\n if (node.source.value === 'lodash/fp') {\n return null; // no automatic fix for fp imports\n }\n\n const newImportPath =\n node.source.value === 'lodash'\n ? 'lodash-es'\n : node.source.value.replace(/^lodash\\//, 'lodash-es/');\n\n const quote = node.source.raw[0]; // preserve original quote style\n\n return fixer.replaceText(\n node.source,\n `${quote}${newImportPath}${quote}`,\n );\n },\n });\n },\n };\n },\n};\n\nexport default banLodashImportRule;\n","import path from 'node:path';\n\nimport type { RuleModule } from '@typescript-eslint/utils/ts-eslint';\n\nconst cssModuleNameMatchesRule: RuleModule<'filenameMismatch'> = {\n meta: {\n type: 'problem',\n docs: {\n description:\n \"enforce that a CSS module's filename matches the filename of the importing file\",\n url: 'https://github.com/friendsoftheweb/eslint-plugin#friendsofthewebcss-module-name-matches',\n },\n schema: [],\n messages: {\n filenameMismatch:\n 'CSS module filename \"{{cssModuleFilename}}\" does not match the current filename \"{{filename}}\"',\n },\n },\n defaultOptions: [],\n create(context) {\n return {\n ImportDeclaration(node) {\n if (\n typeof node.source.value !== 'string' ||\n !node.source.value.endsWith('.module.css')\n ) {\n return;\n }\n\n const filename = path.basename(\n context.filename,\n path.extname(context.filename),\n );\n\n const cssModulePath = node.source.value;\n const cssModuleFilename = path.basename(cssModulePath, '.module.css');\n\n if (cssModuleFilename !== filename) {\n context.report({\n node,\n messageId: 'filenameMismatch',\n data: {\n cssModuleFilename,\n filename,\n },\n });\n }\n },\n };\n },\n};\n\nexport default cssModuleNameMatchesRule;\n","import fs from 'node:fs';\nimport path from 'node:path';\n\nimport type { RuleModule } from '@typescript-eslint/utils/ts-eslint';\nimport { parse } from 'postcss';\nimport selectorParser from 'postcss-selector-parser';\n\nconst cssModuleClassExistsRule: RuleModule<\n | 'relativePath'\n | 'defaultImport'\n | 'onlyDefaultImport'\n | 'fileDoesNotExist'\n | 'classDoesNotExist'\n> = {\n meta: {\n type: 'problem',\n docs: {\n description:\n 'enforce that class names used from an imported CSS module exist in the module file',\n url: 'https://github.com/friendsoftheweb/eslint-plugin#friendsofthewebcss-module-class-exists',\n },\n schema: [],\n messages: {\n relativePath:\n 'CSS module import \"{{importPath}}\" should be a relative path',\n defaultImport:\n 'CSS module import \"{{importPath}}\" should have a default import',\n onlyDefaultImport:\n 'CSS module import \"{{importPath}}\" should have only a default import',\n fileDoesNotExist:\n 'CSS module file \"{{absoluteImportPath}}\" does not exist',\n classDoesNotExist:\n 'Class `.{{className}}` does not exist in the CSS module imported as `{{objectName}}`',\n },\n },\n defaultOptions: [],\n create(context) {\n const classNames = {};\n\n return {\n ImportDeclaration(node) {\n if (\n typeof node.source.value !== 'string' ||\n !node.source.value.endsWith('.module.css')\n ) {\n return;\n }\n\n const importPath = node.source.value;\n\n if (!(importPath.startsWith('./') || importPath.startsWith('../'))) {\n context.report({\n node,\n messageId: 'relativePath',\n data: { importPath },\n });\n\n return;\n }\n\n if (node.specifiers.length === 0) {\n context.report({\n node,\n messageId: 'defaultImport',\n data: { importPath },\n });\n\n return;\n }\n\n if (node.specifiers.length > 1) {\n context.report({\n node,\n messageId: 'onlyDefaultImport',\n data: { importPath },\n });\n\n return;\n }\n\n const defaultImportSpecifier = node.specifiers.find(\n (specifier) => specifier.type === 'ImportDefaultSpecifier',\n );\n\n if (defaultImportSpecifier == null) {\n context.report({\n node,\n messageId: 'onlyDefaultImport',\n data: { importPath },\n });\n\n return;\n }\n\n const dirname = path.dirname(context.physicalFilename);\n const absoluteImportPath = path.resolve(dirname, importPath);\n\n if (!fs.existsSync(absoluteImportPath)) {\n context.report({\n node,\n messageId: 'fileDoesNotExist',\n data: { absoluteImportPath },\n });\n\n return;\n }\n\n const importName = defaultImportSpecifier.local.name;\n\n classNames[importName] = new Set();\n\n const cssModuleContent = fs.readFileSync(absoluteImportPath, 'utf8');\n const root = parse(cssModuleContent);\n\n for (const node of root.nodes) {\n if (node.type === 'rule') {\n selectorParser(function transform(selectors) {\n selectors.walkClasses((classNode) => {\n classNames[importName].add(classNode.value);\n });\n }).processSync(node.selector);\n } else if (\n node.type === 'atrule' &&\n (node.name === 'media' ||\n node.name === 'container' ||\n node.name === 'layer')\n ) {\n for (const childNode of node.nodes) {\n if (childNode.type !== 'rule') {\n continue;\n }\n\n selectorParser(function transform(selectors) {\n selectors.walkClasses((classNode) => {\n classNames[importName].add(classNode.value);\n });\n }).processSync(childNode.selector);\n }\n }\n }\n },\n MemberExpression(node) {\n if (node.object.type !== 'Identifier') {\n return;\n }\n\n if (classNames[node.object.name] == null) {\n return;\n }\n\n const objectName = node.object.name;\n\n if (node.property.type === 'Identifier') {\n const className = node.property.name;\n\n if (!classNames[objectName].has(className)) {\n context.report({\n node,\n messageId: 'classDoesNotExist',\n data: { className, objectName },\n });\n }\n\n return;\n }\n\n if (\n node.property.type === 'Literal' &&\n typeof node.property.value === 'string'\n ) {\n const className = node.property.value;\n\n if (!classNames[objectName].has(className)) {\n context.report({\n node,\n messageId: 'classDoesNotExist',\n data: { className, objectName },\n });\n }\n }\n },\n VariableDeclarator(node) {\n if (node.id.type !== 'ObjectPattern') {\n return;\n }\n\n if (node.init?.type !== 'Identifier') {\n return;\n }\n\n const objectName = node.init.name;\n\n if (classNames[objectName] == null) {\n return;\n }\n\n for (const property of node.id.properties) {\n if (property.type !== 'Property') {\n continue;\n }\n\n if (property.key.type !== 'Identifier') {\n continue;\n }\n\n const className = property.key.name;\n\n if (!classNames[objectName].has(className)) {\n context.report({\n node: property,\n messageId: 'classDoesNotExist',\n data: { className, objectName },\n });\n }\n }\n },\n };\n },\n};\n\nexport default cssModuleClassExistsRule;\n","import type { RuleModule } from '@typescript-eslint/utils/ts-eslint';\n\nconst noLegacyNodeImportRule: RuleModule<'invalidImport'> = {\n meta: {\n type: 'problem',\n fixable: 'code',\n docs: {\n description:\n 'enforce importing node standard library modules using `node:` prefix',\n url: 'https://github.com/friendsoftheweb/eslint-plugin#friendsofthewebno-legacy-node-import',\n },\n schema: [],\n messages: {\n invalidImport:\n 'Node standard library modules must be imported using the \"node:\" prefix',\n },\n },\n defaultOptions: [],\n create(context) {\n return {\n ImportDeclaration(node) {\n if (\n typeof node.source.value !== 'string' ||\n !NODE_STANDARD_MODULES.includes(node.source.value)\n ) {\n return;\n }\n\n context.report({\n node,\n messageId: 'invalidImport',\n fix(fixer) {\n if (typeof node.source.value !== 'string') {\n return null;\n }\n\n const newImportPath = `node:${node.source.value}`;\n const quote = node.source.raw[0]; // preserve original quote style\n\n return fixer.replaceText(\n node.source,\n `${quote}${newImportPath}${quote}`,\n );\n },\n });\n },\n };\n },\n};\n\nexport default noLegacyNodeImportRule;\n\nexport const NODE_STANDARD_MODULES = Object.freeze([\n 'assert',\n 'assert/strict',\n 'async_hooks',\n 'buffer',\n 'child_process',\n 'cluster',\n 'console',\n 'crypto',\n 'dns',\n 'dns/promises',\n 'domain',\n 'events',\n 'fs',\n 'fs/promises',\n 'http',\n 'http2',\n 'https',\n 'inspector',\n 'module',\n 'net',\n 'os',\n 'path',\n 'perf_hooks',\n 'process',\n 'punycode',\n 'querystring',\n 'readline',\n 'readline/promises',\n 'repl',\n 'sqlite',\n 'stream',\n 'stream/promises',\n 'string_decoder',\n 'test',\n 'timers',\n 'timers/promises',\n 'tls',\n 'trace_events',\n 'tty',\n 'url',\n 'util',\n 'util/types',\n 'v8',\n 'vm',\n 'wasi',\n 'worker_threads',\n 'zlib',\n]);\n","import type { RuleModule } from '@typescript-eslint/utils/ts-eslint';\nimport type {\n ArrowFunctionExpression,\n FunctionDeclaration,\n VariableDeclarator,\n} from 'estree';\n\nconst reactNamedFuncComponentsRule: RuleModule<'invalidComponentDefinition'> = {\n meta: {\n type: 'problem',\n docs: {\n description:\n 'enforce use of named functions when defining React components',\n url: 'https://github.com/friendsoftheweb/eslint-plugin#friendsofthewebreact-named-func-components',\n },\n schema: [],\n messages: {\n invalidComponentDefinition:\n 'React components must be defined using named functions',\n },\n },\n defaultOptions: [],\n create(context) {\n return {\n VariableDeclarator(node) {\n if (!isReactComponent(node as VariableDeclarator)) {\n return;\n }\n\n context.report({\n node,\n messageId: 'invalidComponentDefinition',\n });\n },\n };\n },\n};\n\nexport default reactNamedFuncComponentsRule;\n\nfunction isReactComponent(\n node: FunctionDeclaration | ArrowFunctionExpression | VariableDeclarator,\n) {\n if (node.type === 'VariableDeclarator') {\n if (node.init == null) {\n return false;\n }\n\n if (node.init.type !== 'ArrowFunctionExpression') {\n return false;\n }\n\n if (node.id.type !== 'Identifier' || !/^[A-Z]/.test(node.id.name)) {\n return false;\n }\n\n return isReactComponent(node.init);\n } else if (node.type === 'FunctionDeclaration') {\n if (node.id != null && !/^[A-Z]/.test(node.id.name)) {\n return false;\n }\n }\n\n if (node.body.type !== 'BlockStatement') {\n return false;\n }\n\n for (const statement of node.body.body) {\n if (\n statement.type === 'ReturnStatement' &&\n statement.argument != null &&\n // @ts-expect-error: ESTree types are missing JSXElement\n (statement.argument.type === 'JSXElement' ||\n (statement.argument.type === 'Literal' &&\n statement.argument.value === null))\n ) {\n return true;\n }\n }\n\n return false;\n}\n","import path from 'node:path';\n\nimport type { RuleModule } from '@typescript-eslint/utils/ts-eslint';\n\nconst validServerActionsPathRule: RuleModule<'invalidPath'> = {\n meta: {\n type: 'problem',\n docs: {\n description:\n 'enforce server actions are exported from file paths that match \"app/**/_actions.ts\" or \"app/**/_actions/**/*.ts\"',\n url: 'https://github.com/friendsoftheweb/eslint-plugin#friendsofthewebvalid-server-actions-path',\n },\n schema: [],\n messages: {\n invalidPath:\n 'Server action files must be located in a directory named \"_actions\" or have the filename \"_actions.ts\"',\n },\n },\n defaultOptions: [],\n create(context) {\n return {\n ExpressionStatement(node) {\n if (\n node.expression.type !== 'Literal' ||\n node.expression.value !== 'use server'\n ) {\n return;\n }\n\n const basename = path.basename(context.filename);\n const dirname = path.dirname(context.filename);\n\n // Escape backslashes for RegExp (Windows paths)\n const escapedSep = path.sep.replace('\\\\', '\\\\\\\\');\n\n const isInActionsDir = new RegExp(\n `app(${escapedSep}.*)?${escapedSep}_actions`,\n ).test(dirname);\n\n const isActionsFile =\n (dirname === 'app' || new RegExp(`app${escapedSep}`).test(dirname)) &&\n /_actions\\.(js|ts)$/.test(basename);\n\n if (!isInActionsDir && !isActionsFile) {\n context.report({\n node,\n messageId: 'invalidPath',\n });\n }\n },\n };\n },\n};\n\nexport default validServerActionsPathRule;\n","import packageJson from '../package.json' with { type: 'json' };\n\nimport banLodashImport from './rules/ban-lodash-import.ts';\nimport cssModuleNameMatchesRule from './rules/css-module-name-matches.ts';\nimport cssModuleClassExistsRule from './rules/css-module-class-exists.ts';\nimport noLegacyNodeImport from './rules/no-legacy-node-import.ts';\nimport reactNamedFuncComponents from './rules/react-named-func-components.ts';\nimport validServerActionsPathRule from './rules/valid-server-actions-path.ts';\n\nconst plugin = {\n meta: {\n name: packageJson.name,\n version: packageJson.version,\n },\n configs: {},\n rules: {\n 'ban-lodash-import': banLodashImport,\n 'css-module-name-matches': cssModuleNameMatchesRule,\n 'css-module-class-exists': cssModuleClassExistsRule,\n 'no-legacy-node-import': noLegacyNodeImport,\n 'react-named-func-components': reactNamedFuncComponents,\n 'valid-server-actions-path': validServerActionsPathRule,\n },\n};\n\nconst RULE_NAMES = Object.keys(plugin.rules).map(\n (ruleName) => `friendsoftheweb/${ruleName}`,\n);\n\n/**\n * @param {'error' | 'warn'} reportLevel\n */\nfunction buildConfig(reportLevel) {\n return {\n plugins: {\n friendsoftheweb: plugin,\n },\n rules: Object.fromEntries(\n RULE_NAMES.map((ruleName) => [ruleName, reportLevel]),\n ),\n };\n}\n\nconst errorConfig = buildConfig('error');\nconst warnConfig = buildConfig('warn');\n\nconst futureConfig = {\n ...errorConfig,\n rules: {\n ...errorConfig.rules,\n 'friendsoftheweb/react-named-func-components': 'warn',\n },\n};\n\nconst recommendedConfig = {\n ...errorConfig,\n rules: {\n ...errorConfig.rules,\n 'friendsoftheweb/react-named-func-components': 'off',\n },\n};\n\nconst migrateConfig = {\n ...warnConfig,\n rules: {\n ...warnConfig.rules,\n 'friendsoftheweb/react-named-func-components': 'off',\n },\n};\n\nObject.assign(plugin.configs, {\n 'flat/future': [futureConfig],\n 'flat/recommended': [recommendedConfig],\n 'flat/migrate': [migrateConfig],\n future: futureConfig,\n recommended: recommendedConfig,\n migrate: migrateConfig,\n});\n\nexport default plugin;\n"],"names":["banLodashImport","noLegacyNodeImport","reactNamedFuncComponents"],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
declare const plugin: {
|
|
2
|
+
meta: {
|
|
3
|
+
name: string;
|
|
4
|
+
version: string;
|
|
5
|
+
};
|
|
6
|
+
configs: {};
|
|
7
|
+
rules: {
|
|
8
|
+
'ban-lodash-import': import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidImport", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
9
|
+
'css-module-name-matches': import("@typescript-eslint/utils/ts-eslint").RuleModule<"filenameMismatch", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
10
|
+
'css-module-class-exists': import("@typescript-eslint/utils/ts-eslint").RuleModule<"relativePath" | "defaultImport" | "onlyDefaultImport" | "fileDoesNotExist" | "classDoesNotExist", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
11
|
+
'no-legacy-node-import': import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidImport", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
12
|
+
'react-named-func-components': import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidComponentDefinition", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
13
|
+
'valid-server-actions-path': import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidPath", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
export default plugin;
|
package/package.json
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
"repository": {
|
|
4
4
|
"url": "git+https://github.com/friendsoftheweb/eslint-plugin.git"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.0.
|
|
6
|
+
"version": "0.0.3-beta.1",
|
|
7
|
+
"type": "module",
|
|
7
8
|
"license": "MIT",
|
|
8
9
|
"packageManager": "yarn@4.12.0",
|
|
9
10
|
"main": "./dist/cjs/index.js",
|
|
@@ -21,7 +22,7 @@
|
|
|
21
22
|
"dist"
|
|
22
23
|
],
|
|
23
24
|
"scripts": {
|
|
24
|
-
"test": "node test/index.
|
|
25
|
+
"test": "node --experimental-strip-types test/index.ts",
|
|
25
26
|
"types:check": "tsc --noEmit",
|
|
26
27
|
"lint": "eslint",
|
|
27
28
|
"format:check": "prettier --check .",
|
|
@@ -32,6 +33,10 @@
|
|
|
32
33
|
"@rollup/plugin-json": "^6.1.0",
|
|
33
34
|
"@rollup/plugin-typescript": "^12.3.0",
|
|
34
35
|
"@types/node": "^22.19.3",
|
|
36
|
+
"@types/sinon": "^21.0.0",
|
|
37
|
+
"@typescript-eslint/rule-tester": "^8.52.0",
|
|
38
|
+
"@typescript-eslint/types": "^8.52.0",
|
|
39
|
+
"@typescript-eslint/utils": "^8.52.0",
|
|
35
40
|
"eslint": "^9.39.2",
|
|
36
41
|
"eslint-plugin-eslint-plugin": "^7.3.0",
|
|
37
42
|
"prettier": "^3.7.4",
|
package/dist/types/index.d.mts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
declare const _default: {
|
|
2
|
-
meta: {
|
|
3
|
-
type: "problem";
|
|
4
|
-
fixable: "code";
|
|
5
|
-
docs: {
|
|
6
|
-
description: string;
|
|
7
|
-
url: string;
|
|
8
|
-
};
|
|
9
|
-
schema: any[];
|
|
10
|
-
messages: {
|
|
11
|
-
invalidImport: string;
|
|
12
|
-
};
|
|
13
|
-
};
|
|
14
|
-
create(context: import("@eslint/core", { with: { "resolution-mode": "require" } }).RuleContext<{
|
|
15
|
-
LangOptions: import("eslint").Linter.LanguageOptions;
|
|
16
|
-
Code: import("eslint").SourceCode;
|
|
17
|
-
RuleOptions: unknown[];
|
|
18
|
-
Node: import("eslint").JSSyntaxElement;
|
|
19
|
-
MessageIds: string;
|
|
20
|
-
}>): {
|
|
21
|
-
ImportDeclaration(node: import("estree").ImportDeclaration & import("eslint").Rule.NodeParentExtension): void;
|
|
22
|
-
};
|
|
23
|
-
};
|
|
24
|
-
export default _default;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
declare const _default: {
|
|
2
|
-
meta: {
|
|
3
|
-
type: "problem";
|
|
4
|
-
docs: {
|
|
5
|
-
description: string;
|
|
6
|
-
url: string;
|
|
7
|
-
};
|
|
8
|
-
schema: any[];
|
|
9
|
-
messages: {
|
|
10
|
-
relativePath: string;
|
|
11
|
-
defaultImport: string;
|
|
12
|
-
onlyDefaultImport: string;
|
|
13
|
-
fileDoesNotExist: string;
|
|
14
|
-
classDoesNotExist: string;
|
|
15
|
-
};
|
|
16
|
-
};
|
|
17
|
-
create(context: import("@eslint/core", { with: { "resolution-mode": "require" } }).RuleContext<{
|
|
18
|
-
LangOptions: import("eslint").Linter.LanguageOptions;
|
|
19
|
-
Code: import("eslint").SourceCode;
|
|
20
|
-
RuleOptions: unknown[];
|
|
21
|
-
Node: import("eslint").JSSyntaxElement;
|
|
22
|
-
MessageIds: string;
|
|
23
|
-
}>): {
|
|
24
|
-
ImportDeclaration(node: import("estree").ImportDeclaration & import("eslint").Rule.NodeParentExtension): void;
|
|
25
|
-
MemberExpression(node: import("estree").MemberExpression & import("eslint").Rule.NodeParentExtension): void;
|
|
26
|
-
VariableDeclarator(node: import("estree").VariableDeclarator & import("eslint").Rule.NodeParentExtension): void;
|
|
27
|
-
};
|
|
28
|
-
};
|
|
29
|
-
export default _default;
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
declare const _default: {
|
|
2
|
-
meta: {
|
|
3
|
-
type: "problem";
|
|
4
|
-
docs: {
|
|
5
|
-
description: string;
|
|
6
|
-
url: string;
|
|
7
|
-
};
|
|
8
|
-
schema: any[];
|
|
9
|
-
messages: {
|
|
10
|
-
filenameMismatch: string;
|
|
11
|
-
};
|
|
12
|
-
};
|
|
13
|
-
create(context: import("@eslint/core", { with: { "resolution-mode": "require" } }).RuleContext<{
|
|
14
|
-
LangOptions: import("eslint").Linter.LanguageOptions;
|
|
15
|
-
Code: import("eslint").SourceCode;
|
|
16
|
-
RuleOptions: unknown[];
|
|
17
|
-
Node: import("eslint").JSSyntaxElement;
|
|
18
|
-
MessageIds: string;
|
|
19
|
-
}>): {
|
|
20
|
-
ImportDeclaration(node: import("estree").ImportDeclaration & import("eslint").Rule.NodeParentExtension): void;
|
|
21
|
-
};
|
|
22
|
-
};
|
|
23
|
-
export default _default;
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
declare const _default: {
|
|
2
|
-
meta: {
|
|
3
|
-
type: "problem";
|
|
4
|
-
docs: {
|
|
5
|
-
description: string;
|
|
6
|
-
url: string;
|
|
7
|
-
};
|
|
8
|
-
schema: any[];
|
|
9
|
-
messages: {
|
|
10
|
-
invalidPath: string;
|
|
11
|
-
};
|
|
12
|
-
};
|
|
13
|
-
create(context: import("@eslint/core", { with: { "resolution-mode": "require" } }).RuleContext<{
|
|
14
|
-
LangOptions: import("eslint").Linter.LanguageOptions;
|
|
15
|
-
Code: import("eslint").SourceCode;
|
|
16
|
-
RuleOptions: unknown[];
|
|
17
|
-
Node: import("eslint").JSSyntaxElement;
|
|
18
|
-
MessageIds: string;
|
|
19
|
-
}>): {
|
|
20
|
-
ExpressionStatement(node: import("estree").ExpressionStatement & import("eslint").Rule.NodeParentExtension): void;
|
|
21
|
-
};
|
|
22
|
-
};
|
|
23
|
-
export default _default;
|