@lvce-editor/eslint-plugin-eslint-config 18.0.0
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/dist/index.js +138 -0
- package/package.json +12 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
const eslintConfigModule = 'eslint/config';
|
|
2
|
+
const defineConfigName = 'defineConfig';
|
|
3
|
+
const getImportedName = specifier => {
|
|
4
|
+
const {
|
|
5
|
+
imported
|
|
6
|
+
} = specifier;
|
|
7
|
+
if (imported?.type === 'Identifier') {
|
|
8
|
+
return imported.name;
|
|
9
|
+
}
|
|
10
|
+
if (imported?.type === 'Literal' && typeof imported.value === 'string') {
|
|
11
|
+
return imported.value;
|
|
12
|
+
}
|
|
13
|
+
return undefined;
|
|
14
|
+
};
|
|
15
|
+
const getDefineConfigBindings = program => {
|
|
16
|
+
const named = new Set();
|
|
17
|
+
const namespaces = new Set();
|
|
18
|
+
for (const statement of program.body) {
|
|
19
|
+
if (statement.type !== 'ImportDeclaration' || statement.source.value !== eslintConfigModule) {
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
for (const specifier of statement.specifiers) {
|
|
23
|
+
if (specifier.type === 'ImportNamespaceSpecifier') {
|
|
24
|
+
namespaces.add(specifier.local.name);
|
|
25
|
+
} else if (specifier.type === 'ImportSpecifier' && getImportedName(specifier) === defineConfigName) {
|
|
26
|
+
named.add(specifier.local.name);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
named,
|
|
32
|
+
namespaces
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
const isDefineConfigProperty = node => {
|
|
36
|
+
if (node.computed) {
|
|
37
|
+
return node.property?.type === 'Literal' && node.property.value === defineConfigName;
|
|
38
|
+
}
|
|
39
|
+
return node.property?.type === 'Identifier' && node.property.name === defineConfigName;
|
|
40
|
+
};
|
|
41
|
+
const isDefineConfigCall = (node, bindings) => {
|
|
42
|
+
if (node.type !== 'CallExpression') {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
const {
|
|
46
|
+
callee
|
|
47
|
+
} = node;
|
|
48
|
+
if (callee.type === 'Identifier') {
|
|
49
|
+
return bindings.named.has(callee.name);
|
|
50
|
+
}
|
|
51
|
+
return callee.type === 'MemberExpression' && callee.object.type === 'Identifier' && bindings.namespaces.has(callee.object.name) && isDefineConfigProperty(callee);
|
|
52
|
+
};
|
|
53
|
+
const meta$1 = {
|
|
54
|
+
docs: {
|
|
55
|
+
description: 'Enforce using defineConfig from eslint/config for ESLint flat configurations'
|
|
56
|
+
},
|
|
57
|
+
messages: {
|
|
58
|
+
useDefineConfig: 'Wrap the default export in `defineConfig` imported from `eslint/config`.'
|
|
59
|
+
},
|
|
60
|
+
type: 'suggestion'
|
|
61
|
+
};
|
|
62
|
+
const create$1 = context => {
|
|
63
|
+
return {
|
|
64
|
+
'Program:exit'(program) {
|
|
65
|
+
const bindings = getDefineConfigBindings(program);
|
|
66
|
+
const defaultExport = program.body.find(statement => statement.type === 'ExportDefaultDeclaration');
|
|
67
|
+
if (defaultExport && isDefineConfigCall(defaultExport.declaration, bindings)) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
context.report({
|
|
71
|
+
messageId: 'useDefineConfig',
|
|
72
|
+
node: defaultExport ?? program
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const defineConfig = {
|
|
79
|
+
__proto__: null,
|
|
80
|
+
create: create$1,
|
|
81
|
+
meta: meta$1
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const githubActionsPlugin = '@lvce-editor/eslint-plugin-github-actions';
|
|
85
|
+
const isGithubActionsPlugin = source => {
|
|
86
|
+
return typeof source === 'string' && (source === githubActionsPlugin || source.startsWith(`${githubActionsPlugin}/`));
|
|
87
|
+
};
|
|
88
|
+
const meta = {
|
|
89
|
+
docs: {
|
|
90
|
+
description: 'Prefer the shared recommendedActions configuration over importing the GitHub Actions plugin directly'
|
|
91
|
+
},
|
|
92
|
+
messages: {
|
|
93
|
+
preferRecommendedActions: 'Use `config.recommendedActions` from `@lvce-editor/eslint-config` instead of importing `@lvce-editor/eslint-plugin-github-actions` directly.'
|
|
94
|
+
},
|
|
95
|
+
type: 'suggestion'
|
|
96
|
+
};
|
|
97
|
+
const create = context => {
|
|
98
|
+
return {
|
|
99
|
+
ImportDeclaration(node) {
|
|
100
|
+
if (isGithubActionsPlugin(node.source.value)) {
|
|
101
|
+
context.report({
|
|
102
|
+
messageId: 'preferRecommendedActions',
|
|
103
|
+
node
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const preferRecommendedActions = {
|
|
111
|
+
__proto__: null,
|
|
112
|
+
create,
|
|
113
|
+
meta
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const plugin = {
|
|
117
|
+
configs: {},
|
|
118
|
+
meta: {
|
|
119
|
+
name: 'eslint-config',
|
|
120
|
+
version: '0.0.1'
|
|
121
|
+
},
|
|
122
|
+
rules: {
|
|
123
|
+
'define-config': defineConfig,
|
|
124
|
+
'prefer-recommended-actions': preferRecommendedActions
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
const recommended = [{
|
|
128
|
+
files: ['**/eslint.config.js'],
|
|
129
|
+
plugins: {
|
|
130
|
+
'eslint-config': plugin
|
|
131
|
+
},
|
|
132
|
+
rules: {
|
|
133
|
+
'eslint-config/define-config': 'error',
|
|
134
|
+
'eslint-config/prefer-recommended-actions': 'error'
|
|
135
|
+
}
|
|
136
|
+
}];
|
|
137
|
+
|
|
138
|
+
export { recommended as default };
|
package/package.json
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lvce-editor/eslint-plugin-eslint-config",
|
|
3
|
+
"version": "18.0.0",
|
|
4
|
+
"main": "dist/index.js",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/lvce-editor/eslint-config.git"
|
|
8
|
+
},
|
|
9
|
+
"type": "module",
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"description": "ESLint rules for ESLint flat configuration files."
|
|
12
|
+
}
|