@open-xchange/linter-presets 0.0.6 → 0.1.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/CHANGELOG.md +19 -14
- package/README.md +3 -3
- package/dist/eslint/config/base.d.ts +16 -0
- package/{lib → dist}/eslint/config/base.js +5 -26
- package/dist/eslint/config/directives.d.ts +11 -0
- package/{lib → dist}/eslint/config/directives.js +1 -5
- package/dist/eslint/config/imports.d.ts +15 -0
- package/dist/eslint/config/imports.js +58 -0
- package/dist/eslint/config/js.d.ts +9 -0
- package/dist/eslint/config/js.js +32 -0
- package/dist/eslint/config/jsdoc.d.ts +11 -0
- package/{lib → dist}/eslint/config/jsdoc.js +1 -9
- package/dist/eslint/config/json.d.ts +15 -0
- package/{lib → dist}/eslint/config/json.js +2 -8
- package/dist/eslint/config/license.d.ts +14 -0
- package/{lib → dist}/eslint/config/license.js +12 -18
- package/dist/eslint/config/promises.d.ts +11 -0
- package/{lib → dist}/eslint/config/promises.js +3 -9
- package/dist/eslint/config/stylistic.d.ts +16 -0
- package/{lib → dist}/eslint/config/stylistic.js +12 -22
- package/dist/eslint/config/ts.d.ts +11 -0
- package/{lib → dist}/eslint/config/ts.js +9 -18
- package/dist/eslint/config/yaml.d.ts +15 -0
- package/{lib → dist}/eslint/config/yaml.js +2 -8
- package/dist/eslint/env/browser.d.ts +27 -0
- package/{lib → dist}/eslint/env/browser.js +5 -26
- package/dist/eslint/env/codecept.d.ts +22 -0
- package/{lib → dist}/eslint/env/codecept.js +4 -13
- package/dist/eslint/env/eslint.d.ts +20 -0
- package/{lib → dist}/eslint/env/eslint.js +2 -9
- package/dist/eslint/env/jest.d.ts +21 -0
- package/dist/eslint/env/jest.js +49 -0
- package/dist/eslint/env/node.d.ts +30 -0
- package/{lib → dist}/eslint/env/node.js +2 -14
- package/dist/eslint/env/project.d.ts +18 -0
- package/{lib → dist}/eslint/env/project.js +18 -25
- package/dist/eslint/env/react.d.ts +29 -0
- package/{lib → dist}/eslint/env/react.js +3 -15
- package/dist/eslint/env/tsconfig.d.ts +21 -0
- package/{lib → dist}/eslint/env/tsconfig.js +15 -21
- package/dist/eslint/env/vitest.d.ts +23 -0
- package/{lib → dist}/eslint/env/vitest.js +3 -16
- package/dist/eslint/index.d.ts +63 -0
- package/{lib → dist}/eslint/index.js +3 -25
- package/dist/eslint/rules/no-amd-module-directive.d.ts +3 -0
- package/{lib → dist}/eslint/rules/no-amd-module-directive.js +22 -26
- package/dist/eslint/rules/no-invalid-modules.d.ts +38 -0
- package/{lib → dist}/eslint/rules/no-invalid-modules.js +40 -63
- package/dist/eslint/shared/env-utils.d.ts +150 -0
- package/{lib → dist}/eslint/shared/env-utils.js +12 -23
- package/dist/eslint/shared/rule-utils.d.ts +76 -0
- package/{lib → dist}/eslint/shared/rule-utils.js +27 -60
- package/dist/index.d.ts +3 -0
- package/{lib → dist}/index.js +0 -1
- package/dist/stylelint/index.d.ts +49 -0
- package/{lib → dist}/stylelint/index.js +5 -22
- package/dist/utils/index.d.ts +12 -0
- package/{lib → dist}/utils/index.js +2 -5
- package/package.json +12 -4
- package/lib/eslint/config/imports.js +0 -68
- package/lib/eslint/config/js.js +0 -36
- package/lib/eslint/env/browser.d.ts +0 -21
- package/lib/eslint/env/codecept.d.ts +0 -14
- package/lib/eslint/env/eslint.d.ts +0 -14
- package/lib/eslint/env/jest.d.ts +0 -14
- package/lib/eslint/env/jest.js +0 -56
- package/lib/eslint/env/node.d.ts +0 -28
- package/lib/eslint/env/project.d.ts +0 -21
- package/lib/eslint/env/react.d.ts +0 -20
- package/lib/eslint/env/tsconfig.d.ts +0 -20
- package/lib/eslint/env/vitest.d.ts +0 -14
- package/lib/eslint/index.d.ts +0 -43
- package/lib/eslint/shared/env-utils.d.ts +0 -95
- package/lib/eslint/shared/types.d.ts +0 -107
- package/lib/index.d.ts +0 -4
- package/lib/stylelint/index.d.ts +0 -18
- package/lib/stylelint/types.d.ts +0 -44
- package/lib/utils/index.d.ts +0 -4
- /package/{lib → doc}/eslint/README.md +0 -0
- /package/{lib → doc}/eslint/env/browser.md +0 -0
- /package/{lib → doc}/eslint/env/codecept.md +0 -0
- /package/{lib → doc}/eslint/env/eslint.md +0 -0
- /package/{lib → doc}/eslint/env/jest.md +0 -0
- /package/{lib → doc}/eslint/env/node.md +0 -0
- /package/{lib → doc}/eslint/env/project.md +0 -0
- /package/{lib → doc}/eslint/env/react.md +0 -0
- /package/{lib → doc}/eslint/env/tsconfig.md +0 -0
- /package/{lib → doc}/eslint/env/vitest.md +0 -0
- /package/{lib → doc}/stylelint/README.md +0 -0
- /package/{lib → doc}/utils/README.md +0 -0
|
@@ -18,23 +18,15 @@
|
|
|
18
18
|
* Any use of the work other than as authorized under this license or copyright law is prohibited.
|
|
19
19
|
*
|
|
20
20
|
*/
|
|
21
|
-
|
|
22
21
|
import { createRequire } from "node:module";
|
|
23
22
|
import { posix, dirname, extname } from "node:path";
|
|
24
|
-
|
|
25
23
|
import { packageUpSync } from "package-up";
|
|
26
|
-
|
|
24
|
+
import { AST_NODE_TYPES as NodeType, ESLintUtils } from "@typescript-eslint/utils";
|
|
27
25
|
import { Schema, makeArray, toPosixPath, isFile, matchModuleName, getModuleName } from "../shared/rule-utils.js";
|
|
28
|
-
|
|
29
26
|
// constants ==================================================================
|
|
30
|
-
|
|
31
27
|
const FILE_EXTENSIONS = ["js", "ts", "d.ts"];
|
|
32
|
-
|
|
33
28
|
// exports ====================================================================
|
|
34
|
-
|
|
35
|
-
/** @type {import("eslint").Rule.RuleModule} */
|
|
36
|
-
export default {
|
|
37
|
-
|
|
29
|
+
export default ESLintUtils.RuleCreator.withoutDocs({
|
|
38
30
|
meta: {
|
|
39
31
|
type: "problem",
|
|
40
32
|
schema: [
|
|
@@ -56,47 +48,37 @@ export default {
|
|
|
56
48
|
},
|
|
57
49
|
fixable: "code",
|
|
58
50
|
},
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
external: externalModules = [],
|
|
66
|
-
packages = {},
|
|
67
|
-
} = context.options[0] || {};
|
|
68
|
-
|
|
51
|
+
defaultOptions: [{
|
|
52
|
+
alias: {},
|
|
53
|
+
external: [],
|
|
54
|
+
packages: {},
|
|
55
|
+
}],
|
|
56
|
+
create(context, [options]) {
|
|
69
57
|
// convert "alias" option to map
|
|
70
|
-
const aliasMap = new Map(Object.entries(alias));
|
|
71
|
-
|
|
72
|
-
// convert "packages" options (strings to arrays)
|
|
58
|
+
const aliasMap = new Map(Object.entries(options.alias));
|
|
73
59
|
const packagesMap = new Map();
|
|
74
|
-
for (const [key, settings] of Object.entries(packages)) {
|
|
60
|
+
for (const [key, settings] of Object.entries(options.packages)) {
|
|
75
61
|
packagesMap.set(key, {
|
|
76
62
|
...settings,
|
|
77
63
|
src: makeArray(settings.src),
|
|
78
64
|
extends: makeArray(settings.extends),
|
|
79
65
|
});
|
|
80
66
|
}
|
|
81
|
-
|
|
82
67
|
// collect all globs for package members
|
|
83
68
|
const packagesGlobs = Array.from(packagesMap.values(), settings => settings.src).flat();
|
|
84
|
-
|
|
85
69
|
// resolve file name
|
|
86
70
|
const packagePath = packageUpSync();
|
|
87
|
-
const rootDir = toPosixPath(dirname(packagePath));
|
|
71
|
+
const rootDir = packagePath && toPosixPath(dirname(packagePath));
|
|
88
72
|
const fileName = toPosixPath(context.filename);
|
|
89
|
-
if (!fileName.startsWith(rootDir + "/")) {
|
|
73
|
+
if (!rootDir || !fileName.startsWith(rootDir + "/")) {
|
|
90
74
|
throw new Error("invalid root directory");
|
|
91
75
|
}
|
|
92
|
-
|
|
93
76
|
// path of current module (slice rootDir with "/" from start, and extension with "." from end)
|
|
94
77
|
const fileExt = extname(fileName);
|
|
95
78
|
const selfModulePath = fileName.slice(rootDir.length + 1, -fileExt.length);
|
|
96
79
|
if (!selfModulePath) {
|
|
97
80
|
throw new Error("invalid own module path");
|
|
98
81
|
}
|
|
99
|
-
|
|
100
82
|
// replace alias path with alias key
|
|
101
83
|
let selfModuleName = selfModulePath;
|
|
102
84
|
for (const [aliasKey, aliasPath] of aliasMap) {
|
|
@@ -105,88 +87,83 @@ export default {
|
|
|
105
87
|
break;
|
|
106
88
|
}
|
|
107
89
|
}
|
|
108
|
-
|
|
109
90
|
// returns an existing alias key used by the passed module name
|
|
110
|
-
const resolveAlias = moduleName => {
|
|
91
|
+
const resolveAlias = (moduleName) => {
|
|
111
92
|
const [key, ...rest] = moduleName.split("/");
|
|
112
93
|
const aliasPath = (key && rest[0]) ? aliasMap.get(key) : undefined;
|
|
113
94
|
const aliasKey = aliasPath ? key : "";
|
|
114
95
|
const modulePath = aliasPath ? posix.join(aliasPath, ...rest) : moduleName;
|
|
115
|
-
return
|
|
96
|
+
return [aliasKey, modulePath];
|
|
116
97
|
};
|
|
117
|
-
|
|
118
98
|
// returns whether a source file exists for the specified module
|
|
119
|
-
const fileExists = resolvedName => {
|
|
99
|
+
const fileExists = (resolvedName) => {
|
|
120
100
|
// check modules with explicit extension
|
|
121
101
|
const resolvedPath = posix.join(rootDir, resolvedName);
|
|
122
|
-
if (extname(resolvedName)) {
|
|
102
|
+
if (extname(resolvedName)) {
|
|
103
|
+
return isFile(resolvedPath);
|
|
104
|
+
}
|
|
123
105
|
// search for a file with a known extension
|
|
124
106
|
return FILE_EXTENSIONS.some(ext => isFile(resolvedPath + "." + ext));
|
|
125
107
|
};
|
|
126
|
-
|
|
127
108
|
// returns whether the passed module name is an installed NPM package
|
|
128
109
|
const requireModule = createRequire(packagePath);
|
|
129
|
-
const packageExists = moduleName => {
|
|
110
|
+
const packageExists = (moduleName) => {
|
|
130
111
|
try {
|
|
131
112
|
requireModule.resolve(moduleName);
|
|
132
113
|
return true;
|
|
133
|
-
}
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
134
116
|
return false;
|
|
135
117
|
}
|
|
136
118
|
};
|
|
137
|
-
|
|
138
119
|
return {
|
|
139
120
|
"ImportDeclaration, TSExternalModuleReference, ImportExpression, ExportAllDeclaration, ExportNamedDeclaration"(node) {
|
|
140
|
-
|
|
141
121
|
// import/export statement must contain string literal
|
|
142
122
|
const { sourceNode, moduleName } = getModuleName(node);
|
|
143
|
-
if (!sourceNode || !moduleName) {
|
|
144
|
-
|
|
123
|
+
if (!sourceNode || !moduleName) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
145
126
|
// skip glob patterns in TypeScript type imports
|
|
146
|
-
if ((node.type ===
|
|
127
|
+
if ((node.type === NodeType.ImportDeclaration) && (node.importKind === "type") && moduleName.includes("*")) {
|
|
147
128
|
return;
|
|
148
129
|
}
|
|
149
|
-
|
|
150
130
|
// extract alias key, replace with alias path
|
|
151
|
-
const
|
|
152
|
-
|
|
131
|
+
const [aliasKey, modulePath] = resolveAlias(moduleName);
|
|
153
132
|
// whether the import is a known external module
|
|
154
|
-
const isExternal = !aliasKey && matchModuleName(moduleName,
|
|
155
|
-
|
|
133
|
+
const isExternal = !aliasKey && matchModuleName(moduleName, options.external);
|
|
156
134
|
// whether the import is an installed NPM package
|
|
157
135
|
const isPackage = !isExternal && !aliasKey && packageExists(moduleName);
|
|
158
|
-
|
|
159
136
|
// check existence of source file
|
|
160
137
|
if (!isExternal && !isPackage && !fileExists(modulePath)) {
|
|
161
138
|
context.report({ messageId: "SOURCE_FILE_NOT_FOUND", node: sourceNode, data: { moduleName } });
|
|
162
139
|
return;
|
|
163
140
|
}
|
|
164
|
-
|
|
165
141
|
// check dependencies if the imported module is covered in the configuration
|
|
166
|
-
if (!matchModuleName(moduleName, packagesGlobs)) {
|
|
167
|
-
|
|
142
|
+
if (!matchModuleName(moduleName, packagesGlobs)) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
168
145
|
// check package dependencies
|
|
169
146
|
// whether an invalid static import has been found
|
|
170
147
|
let invalidStatic = false;
|
|
171
|
-
|
|
172
148
|
// recursively checks the imported module for dependency violations
|
|
173
149
|
const checkDependencies = (settings, root) => {
|
|
174
|
-
|
|
175
150
|
// only allow static imports from specified package, if it is not optional
|
|
176
151
|
if (matchModuleName(moduleName, settings.src)) {
|
|
177
|
-
if (!root && (node.type !==
|
|
152
|
+
if (!root && (node.type !== NodeType.ImportExpression) && settings.optional) {
|
|
153
|
+
invalidStatic = true;
|
|
154
|
+
}
|
|
178
155
|
return true;
|
|
179
156
|
}
|
|
180
|
-
|
|
181
157
|
// do not traverse into dependencies of optional modules
|
|
182
158
|
if (!settings.extends.length || (!root && settings.optional)) {
|
|
183
159
|
return false;
|
|
184
160
|
}
|
|
185
|
-
|
|
186
161
|
// allow imports from any of the dependent packages
|
|
187
|
-
return settings.extends.some(key =>
|
|
162
|
+
return settings.extends.some(key => {
|
|
163
|
+
const package2 = packagesMap.get(key);
|
|
164
|
+
return !!package2 && checkDependencies(package2, false);
|
|
165
|
+
});
|
|
188
166
|
};
|
|
189
|
-
|
|
190
167
|
// check dependencies of all configured packages (not for anonymous modules)
|
|
191
168
|
let invalidDeps = false;
|
|
192
169
|
for (const settings of packagesMap.values()) {
|
|
@@ -195,14 +172,14 @@ export default {
|
|
|
195
172
|
break;
|
|
196
173
|
}
|
|
197
174
|
}
|
|
198
|
-
|
|
199
175
|
// report package hierarchy errors
|
|
200
176
|
if (invalidStatic) {
|
|
201
177
|
context.report({ messageId: "UNEXPECTED_OPTIONAL_STATIC", node: sourceNode });
|
|
202
|
-
}
|
|
178
|
+
}
|
|
179
|
+
else if (invalidDeps) {
|
|
203
180
|
context.report({ messageId: "INVALID_PACKAGE_HIERARCHY", node: sourceNode });
|
|
204
181
|
}
|
|
205
182
|
},
|
|
206
183
|
};
|
|
207
184
|
},
|
|
208
|
-
};
|
|
185
|
+
});
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import type { TSESLint } from "@typescript-eslint/utils";
|
|
2
|
+
/**
|
|
3
|
+
* Configuration options for language and project setup.
|
|
4
|
+
*/
|
|
5
|
+
export interface LanguageOptions {
|
|
6
|
+
/**
|
|
7
|
+
* The ECMAScript version to be used in the project (version or year).
|
|
8
|
+
* Default value is `2022`.
|
|
9
|
+
*/
|
|
10
|
+
ecmaVersion?: TSESLint.ParserOptions["ecmaVersion"];
|
|
11
|
+
/**
|
|
12
|
+
* Specifies how to treat `.js`, `.jsx`, `.ts`, and `.tsx` files.
|
|
13
|
+
*
|
|
14
|
+
* - "module": The files will be considered being ES modules.
|
|
15
|
+
* - "commonjs": The files will be considered being CommonJS modules.
|
|
16
|
+
*
|
|
17
|
+
* Default value is "module".
|
|
18
|
+
*/
|
|
19
|
+
sourceType?: "module" | "commonjs";
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Configuration options for code style.
|
|
23
|
+
*/
|
|
24
|
+
export interface StylisticOptions {
|
|
25
|
+
/**
|
|
26
|
+
* Default indentation size (number of space characters). Will be applied
|
|
27
|
+
* to JavaScript, TypeScript, JSON, and YAML files, as well as JSX markup.
|
|
28
|
+
* Default value is `2`.
|
|
29
|
+
*/
|
|
30
|
+
indent?: number;
|
|
31
|
+
/**
|
|
32
|
+
* Specifies whether to require semicolons following all statements. By
|
|
33
|
+
* default, semicolons must be omitted if possible according to ASI rules.
|
|
34
|
+
*/
|
|
35
|
+
semi?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* The type of the string delimiter character. Default value is "single".
|
|
38
|
+
*/
|
|
39
|
+
quotes?: "single" | "double" | "off";
|
|
40
|
+
/**
|
|
41
|
+
* Specifies how to treat dangling commas in multiline lists.
|
|
42
|
+
*
|
|
43
|
+
* - "always": Dangling commas will be required in all multi-line array
|
|
44
|
+
* literals, object literals, function parameters, template parameters,
|
|
45
|
+
* imports, and exports.
|
|
46
|
+
* - "never": Dangling commas will be forbidden.
|
|
47
|
+
* - "off": Dangling commas will not be checked.
|
|
48
|
+
*
|
|
49
|
+
* Default value is "always".
|
|
50
|
+
*/
|
|
51
|
+
dangle?: "always" | "never" | "off";
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Shared options for an environment preset with included and excluded files.
|
|
55
|
+
*/
|
|
56
|
+
export interface EnvFilesOptions {
|
|
57
|
+
/**
|
|
58
|
+
* Glob patterns for source files to be included into the environment.
|
|
59
|
+
*/
|
|
60
|
+
files: string[];
|
|
61
|
+
/**
|
|
62
|
+
* Glob patterns for source files matching `files` to be ignored.
|
|
63
|
+
*/
|
|
64
|
+
ignores?: string[];
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Shared options for an environment preset: include and exclude files, and add
|
|
68
|
+
* more linter rules.
|
|
69
|
+
*/
|
|
70
|
+
export interface EnvBaseOptions extends EnvFilesOptions {
|
|
71
|
+
/**
|
|
72
|
+
* Additional linter rules to be added to the configuration.
|
|
73
|
+
*/
|
|
74
|
+
rules?: TSESLint.FlatConfig.Rules;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Configuration for a single banned global or import.
|
|
78
|
+
*/
|
|
79
|
+
export interface EnvRestrictedName {
|
|
80
|
+
name: string;
|
|
81
|
+
message: string;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Configuration for a single banned object property.
|
|
85
|
+
*/
|
|
86
|
+
export interface EnvRestrictedProperty {
|
|
87
|
+
object: string;
|
|
88
|
+
property: string;
|
|
89
|
+
message: string;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Configuration for a single banned syntax construct.
|
|
93
|
+
*/
|
|
94
|
+
export interface EnvRestrictedSyntax {
|
|
95
|
+
selector: string;
|
|
96
|
+
message: string;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Collection of banned globals, imports, properties, and syntax constructs.
|
|
100
|
+
*/
|
|
101
|
+
export interface EnvRestrictedItems {
|
|
102
|
+
/** The global symbols to be banned. */
|
|
103
|
+
globals?: EnvRestrictedName[];
|
|
104
|
+
/** The module imports to be banned. */
|
|
105
|
+
imports?: EnvRestrictedName[];
|
|
106
|
+
/** The global object properties to be banned. */
|
|
107
|
+
properties?: EnvRestrictedProperty[];
|
|
108
|
+
/** The syntax constructs to be banned. */
|
|
109
|
+
syntax?: EnvRestrictedSyntax[];
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Collection of banned globals, imports, properties, and syntax constructs,
|
|
113
|
+
* for a specific subset of the files included in an environment.
|
|
114
|
+
*/
|
|
115
|
+
export interface EnvRestrictedOverride extends EnvFilesOptions, EnvRestrictedItems {
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Configuration options for restricted imports and globals.
|
|
119
|
+
*/
|
|
120
|
+
export interface EnvRestrictedOptions extends EnvRestrictedItems {
|
|
121
|
+
overrides?: EnvRestrictedOverride[];
|
|
122
|
+
}
|
|
123
|
+
export interface EnvRestrictedRulesResult {
|
|
124
|
+
rules: TSESLint.FlatConfig.Rules;
|
|
125
|
+
overrides: TSESLint.FlatConfig.ConfigArray;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Shared options for the core rule `no-unused-vars`, and the plugin rule
|
|
129
|
+
* `@typescript-eslint/no-unused-vars`.
|
|
130
|
+
*/
|
|
131
|
+
export declare const NO_UNUSED_VARS_OPTIONS: {
|
|
132
|
+
varsIgnorePattern: string;
|
|
133
|
+
argsIgnorePattern: string;
|
|
134
|
+
destructuredArrayIgnorePattern: string;
|
|
135
|
+
caughtErrors: string;
|
|
136
|
+
ignoreRestSiblings: boolean;
|
|
137
|
+
};
|
|
138
|
+
/**
|
|
139
|
+
* Generates various "no-restricted-?" rules from the passed configuration.
|
|
140
|
+
*
|
|
141
|
+
* @param fixed
|
|
142
|
+
* The fixed restricted items provided by the environment preset.
|
|
143
|
+
*
|
|
144
|
+
* @param options
|
|
145
|
+
* The custom configuration passed to an environment preset.
|
|
146
|
+
*
|
|
147
|
+
* @returns
|
|
148
|
+
* The generated linter rules to forbid the restricted items.
|
|
149
|
+
*/
|
|
150
|
+
export declare function generateRestrictedRules(fixed: EnvRestrictedItems, options?: EnvRestrictedOptions): EnvRestrictedRulesResult;
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
1
|
// constants ==================================================================
|
|
3
|
-
|
|
4
2
|
/**
|
|
5
3
|
* Global symbols to be banned in all source code files.
|
|
6
4
|
*/
|
|
@@ -8,7 +6,6 @@ const RESTRICTED_GLOBALS = [
|
|
|
8
6
|
{ name: "isFinite", message: "Use 'Number.isFinite' instead." },
|
|
9
7
|
{ name: "isNaN", message: "Use 'Number.isNaN' instead." },
|
|
10
8
|
];
|
|
11
|
-
|
|
12
9
|
/**
|
|
13
10
|
* Syntax constructs to be banned in all source code files.
|
|
14
11
|
*/
|
|
@@ -17,7 +14,6 @@ const RESTRICTED_SYNTAX = [
|
|
|
17
14
|
{ selector: ":matches(PropertyDefinition, MethodDefinition[kind!='constructor'])[accessibility='private'][decorators.length=0]", message: "Use #private syntax instead." },
|
|
18
15
|
{ selector: "MethodDefinition[kind='constructor'] TSParameterProperty[accessibility]", message: "Use explicit class properties." },
|
|
19
16
|
];
|
|
20
|
-
|
|
21
17
|
/**
|
|
22
18
|
* Shared options for the core rule `no-unused-vars`, and the plugin rule
|
|
23
19
|
* `@typescript-eslint/no-unused-vars`.
|
|
@@ -29,39 +25,36 @@ export const NO_UNUSED_VARS_OPTIONS = {
|
|
|
29
25
|
caughtErrors: "all",
|
|
30
26
|
ignoreRestSiblings: true,
|
|
31
27
|
};
|
|
32
|
-
|
|
33
28
|
// functions ==================================================================
|
|
34
|
-
|
|
35
29
|
/**
|
|
36
|
-
* Concatenates the elements of multiple arrays. Skips
|
|
30
|
+
* Concatenates the elements of multiple arrays. Skips `undefined` parameters.
|
|
37
31
|
*
|
|
38
|
-
* @
|
|
39
|
-
*
|
|
40
|
-
* @param {Array<T[] | undefined | null>} arrays
|
|
32
|
+
* @param arrays
|
|
41
33
|
* The arrays to be concatenated.
|
|
42
34
|
*
|
|
43
|
-
* @returns
|
|
35
|
+
* @returns
|
|
44
36
|
* The concatenated arrays.
|
|
45
37
|
*/
|
|
46
38
|
function concatArrays(...arrays) {
|
|
47
39
|
return arrays.flatMap(array => array || []);
|
|
48
40
|
}
|
|
49
|
-
|
|
50
41
|
/**
|
|
51
42
|
* Creates a rules record for all restricted items.
|
|
52
43
|
*
|
|
53
|
-
* @param
|
|
44
|
+
* @param generator
|
|
54
45
|
* The generator callback function that returns the restricted items to be
|
|
55
46
|
* inserted into the linter rules.
|
|
56
47
|
*
|
|
57
|
-
* @returns
|
|
48
|
+
* @returns
|
|
58
49
|
* The rules record containing entries for all existing restricted items.
|
|
59
50
|
*/
|
|
60
51
|
function createRulesRecord(generator) {
|
|
61
52
|
const rules = {};
|
|
62
53
|
for (const key of ["globals", "imports", "properties", "syntax"]) {
|
|
63
54
|
const items = generator(key);
|
|
64
|
-
if (items?.length) {
|
|
55
|
+
if (items?.length) {
|
|
56
|
+
rules[`no-restricted-${key}`] = ["error", ...items];
|
|
57
|
+
}
|
|
65
58
|
}
|
|
66
59
|
// same restrictions for CommonJS `require` as for `import` statements
|
|
67
60
|
if ("no-restricted-imports" in rules) {
|
|
@@ -69,21 +62,20 @@ function createRulesRecord(generator) {
|
|
|
69
62
|
}
|
|
70
63
|
return rules;
|
|
71
64
|
}
|
|
72
|
-
|
|
65
|
+
// ----------------------------------------------------------------------------
|
|
73
66
|
/**
|
|
74
67
|
* Generates various "no-restricted-?" rules from the passed configuration.
|
|
75
68
|
*
|
|
76
|
-
* @param
|
|
69
|
+
* @param fixed
|
|
77
70
|
* The fixed restricted items provided by the environment preset.
|
|
78
71
|
*
|
|
79
|
-
* @param
|
|
72
|
+
* @param options
|
|
80
73
|
* The custom configuration passed to an environment preset.
|
|
81
74
|
*
|
|
82
|
-
* @returns
|
|
75
|
+
* @returns
|
|
83
76
|
* The generated linter rules to forbid the restricted items.
|
|
84
77
|
*/
|
|
85
78
|
export function generateRestrictedRules(fixed, options) {
|
|
86
|
-
|
|
87
79
|
// restricted items for all files in the environment
|
|
88
80
|
const items = {
|
|
89
81
|
globals: concatArrays(RESTRICTED_GLOBALS, fixed.globals, options?.globals),
|
|
@@ -91,10 +83,8 @@ export function generateRestrictedRules(fixed, options) {
|
|
|
91
83
|
properties: concatArrays(fixed.properties, options?.properties),
|
|
92
84
|
syntax: concatArrays(RESTRICTED_SYNTAX, fixed.syntax, options?.syntax),
|
|
93
85
|
};
|
|
94
|
-
|
|
95
86
|
// base rules for all files in the environment
|
|
96
87
|
const rules = createRulesRecord(key => items[key]);
|
|
97
|
-
|
|
98
88
|
// generate the override entries (join with base items)
|
|
99
89
|
const overrides = [];
|
|
100
90
|
for (const override of options?.overrides ?? []) {
|
|
@@ -104,6 +94,5 @@ export function generateRestrictedRules(fixed, options) {
|
|
|
104
94
|
rules: createRulesRecord(key => concatArrays(items[key], override[key])),
|
|
105
95
|
});
|
|
106
96
|
}
|
|
107
|
-
|
|
108
97
|
return { rules, overrides };
|
|
109
98
|
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import pm from "picomatch";
|
|
2
|
+
import type { JSONSchema, TSESTree } from "@typescript-eslint/utils";
|
|
3
|
+
export type ImportExportNode = TSESTree.ImportDeclaration | TSESTree.ImportExpression | TSESTree.ExportAllDeclaration | TSESTree.ExportNamedDeclaration | TSESTree.TSExternalModuleReference;
|
|
4
|
+
export interface ModuleNameResult {
|
|
5
|
+
sourceNode: TSESTree.StringLiteral | undefined;
|
|
6
|
+
moduleName: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Helper functions to build a JSON schema for custom ESLint rules.
|
|
10
|
+
*/
|
|
11
|
+
export declare const Schema: {
|
|
12
|
+
boolean(): JSONSchema.JSONSchema4BooleanSchema;
|
|
13
|
+
string(): JSONSchema.JSONSchema4StringSchema;
|
|
14
|
+
stringNE(): JSONSchema.JSONSchema4StringSchema;
|
|
15
|
+
array(items: JSONSchema.JSONSchema4): JSONSchema.JSONSchema4ArraySchema;
|
|
16
|
+
maybeArray(items: JSONSchema.JSONSchema4): JSONSchema.JSONSchema4OneOfSchema;
|
|
17
|
+
dictionary(properties: JSONSchema.JSONSchema4): JSONSchema.JSONSchema4ObjectSchema;
|
|
18
|
+
options(properties: Record<string, JSONSchema.JSONSchema4>, required?: boolean | string[]): JSONSchema.JSONSchema4ObjectSchema;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Returns a passed array unmodified, converts the value `undefined` to an
|
|
22
|
+
* empty array, and converts all other values to an array with one element.
|
|
23
|
+
*
|
|
24
|
+
* @param value
|
|
25
|
+
* Any value to be converted to an array.
|
|
26
|
+
*
|
|
27
|
+
* @returns
|
|
28
|
+
* An array containing the value, unless the value is already an array.
|
|
29
|
+
*/
|
|
30
|
+
export declare function makeArray<T>(value: T | T[] | undefined): T[];
|
|
31
|
+
/**
|
|
32
|
+
* Converts a Windows file path to a Posix file path.
|
|
33
|
+
*
|
|
34
|
+
* @param path
|
|
35
|
+
* The file path to be normalized to Posix format.
|
|
36
|
+
*
|
|
37
|
+
* @returns
|
|
38
|
+
* The normalized Posix file path.
|
|
39
|
+
*/
|
|
40
|
+
export declare function toPosixPath(path: string): string;
|
|
41
|
+
/**
|
|
42
|
+
* Returns whether the passed path refers to an existing file.
|
|
43
|
+
*
|
|
44
|
+
* @param path
|
|
45
|
+
* The path to be checked.
|
|
46
|
+
*
|
|
47
|
+
* @returns
|
|
48
|
+
* Whether the passed path refers to an existing file (returns `false` for
|
|
49
|
+
* existing directories).
|
|
50
|
+
*/
|
|
51
|
+
export declare function isFile(path: string): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Returns whether a module name matches the specified glob patterns.
|
|
54
|
+
*
|
|
55
|
+
* @param moduleName
|
|
56
|
+
* The module name to be checked.
|
|
57
|
+
*
|
|
58
|
+
* @param patterns
|
|
59
|
+
* The glob patterns to be matched against the module name.
|
|
60
|
+
*
|
|
61
|
+
* @returns
|
|
62
|
+
* Whether the module name matches at least one glob pattern.
|
|
63
|
+
*/
|
|
64
|
+
export declare const matchModuleName: typeof pm.isMatch;
|
|
65
|
+
/**
|
|
66
|
+
* Extracts the source node and module name of an import/export statement node,
|
|
67
|
+
* or a dynamic import expression node.
|
|
68
|
+
*
|
|
69
|
+
* @param node
|
|
70
|
+
* The import/export statement node, or dynamic import expression node.
|
|
71
|
+
*
|
|
72
|
+
* @returns
|
|
73
|
+
* The string literal node containing the module name, and the resulting
|
|
74
|
+
* extracted module name.
|
|
75
|
+
*/
|
|
76
|
+
export declare function getModuleName(node: ImportExportNode): ModuleNameResult;
|