@angular-eslint/builder 15.2.2-alpha.8 → 16.0.0-alpha.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/lint.impl.d.ts +1 -2
- package/dist/lint.impl.js +48 -32
- package/dist/schema.json +10 -5
- package/dist/utils/eslint-utils.d.ts +5 -3
- package/dist/utils/eslint-utils.js +49 -23
- package/package.json +6 -2
- package/dist/utils/create-directory.d.ts +0 -1
- package/dist/utils/create-directory.js +0 -23
package/dist/lint.impl.d.ts
CHANGED
package/dist/lint.impl.js
CHANGED
|
@@ -1,54 +1,62 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const
|
|
3
|
+
const devkit_1 = require("@nx/devkit");
|
|
4
4
|
const fs_1 = require("fs");
|
|
5
5
|
const path_1 = require("path");
|
|
6
|
-
const create_directory_1 = require("./utils/create-directory");
|
|
7
6
|
const eslint_utils_1 = require("./utils/eslint-utils");
|
|
8
|
-
exports.default = (0,
|
|
9
|
-
var _a, _b, _c;
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
exports.default = (0, devkit_1.convertNxExecutor)(async (options, context) => {
|
|
8
|
+
var _a, _b, _c, _d;
|
|
9
|
+
const systemRoot = context.root;
|
|
10
|
+
// eslint resolves files relative to the current working directory.
|
|
11
|
+
// We want these paths to always be resolved relative to the workspace
|
|
12
|
+
// root to be able to run the lint executor from any subfolder.
|
|
13
|
+
process.chdir(systemRoot);
|
|
14
|
+
const projectName = context.projectName || '<???>';
|
|
13
15
|
const printInfo = options.format && !options.silent;
|
|
14
|
-
const reportOnlyErrors = options.quiet;
|
|
15
|
-
const maxWarnings = options.maxWarnings;
|
|
16
16
|
if (printInfo) {
|
|
17
17
|
console.info(`\nLinting ${JSON.stringify(projectName)}...`);
|
|
18
18
|
}
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
/**
|
|
20
|
+
* We want users to have the option of not specifying the config path, and let
|
|
21
|
+
* eslint automatically resolve the `.eslintrc.json` files in each folder.
|
|
22
|
+
*/
|
|
23
|
+
const eslintConfigPath = options.eslintConfig
|
|
24
|
+
? (0, path_1.resolve)(systemRoot, options.eslintConfig)
|
|
25
|
+
: undefined;
|
|
26
|
+
options.cacheLocation = options.cacheLocation
|
|
27
|
+
? (0, path_1.join)(options.cacheLocation, projectName)
|
|
28
|
+
: null;
|
|
29
|
+
/**
|
|
30
|
+
* Until ESLint v9 is released and the new so called flat config is the default
|
|
31
|
+
* we only want to support it if the user has explicitly opted into it by converting
|
|
32
|
+
* their root ESLint config to use eslint.config.js
|
|
33
|
+
*/
|
|
34
|
+
const useFlatConfig = (0, fs_1.existsSync)((0, devkit_1.joinPathFragments)(devkit_1.workspaceRoot, 'eslint.config.js'));
|
|
35
|
+
const { eslint, ESLint } = await (0, eslint_utils_1.resolveAndInstantiateESLint)(eslintConfigPath, options, useFlatConfig);
|
|
36
|
+
const version = (_a = ESLint === null || ESLint === void 0 ? void 0 : ESLint.version) === null || _a === void 0 ? void 0 : _a.split('.');
|
|
21
37
|
if (!version ||
|
|
22
38
|
version.length < 2 ||
|
|
23
39
|
Number(version[0]) < 7 ||
|
|
24
40
|
(Number(version[0]) === 7 && Number(version[1]) < 6)) {
|
|
25
41
|
throw new Error('ESLint must be version 7.6 or higher.');
|
|
26
42
|
}
|
|
27
|
-
const eslint = new projectESLint.ESLint({});
|
|
28
|
-
/**
|
|
29
|
-
* We want users to have the option of not specifying the config path, and let
|
|
30
|
-
* eslint automatically resolve the `.eslintrc` files in each folder.
|
|
31
|
-
*/
|
|
32
|
-
const eslintConfigPath = options.eslintConfig
|
|
33
|
-
? (0, path_1.resolve)(workspaceRoot, options.eslintConfig)
|
|
34
|
-
: undefined;
|
|
35
43
|
let lintResults = [];
|
|
36
44
|
try {
|
|
37
|
-
lintResults = await
|
|
45
|
+
lintResults = await eslint.lintFiles(options.lintFilePatterns);
|
|
38
46
|
}
|
|
39
47
|
catch (err) {
|
|
40
48
|
if (err instanceof Error &&
|
|
41
49
|
err.message.includes('You must therefore provide a value for the "parserOptions.project" property for @typescript-eslint/parser')) {
|
|
42
50
|
let eslintConfigPathForError = `for ${projectName}`;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
eslintConfigPathForError = `\`${
|
|
51
|
+
if ((_d = (_c = (_b = context.projectsConfigurations) === null || _b === void 0 ? void 0 : _b.projects) === null || _c === void 0 ? void 0 : _c[projectName]) === null || _d === void 0 ? void 0 : _d.root) {
|
|
52
|
+
const { root } = context.projectsConfigurations.projects[projectName];
|
|
53
|
+
eslintConfigPathForError = `\`${root}/.eslintrc.json\``;
|
|
46
54
|
}
|
|
47
55
|
console.error(`
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
56
|
+
Error: You have attempted to use a lint rule which requires the full TypeScript type-checker to be available, but you do not have \`parserOptions.project\` configured to point at your project tsconfig.json files in the relevant TypeScript file "overrides" block of your project ESLint config ${eslintConfigPath || eslintConfigPathForError}
|
|
57
|
+
|
|
58
|
+
For full guidance on how to resolve this issue, please see https://github.com/angular-eslint/angular-eslint/blob/main/docs/RULES_REQUIRING_TYPE_INFORMATION.md
|
|
59
|
+
`);
|
|
52
60
|
return {
|
|
53
61
|
success: false,
|
|
54
62
|
};
|
|
@@ -57,13 +65,21 @@ exports.default = (0, architect_1.createBuilder)(async (options, context) => {
|
|
|
57
65
|
throw err;
|
|
58
66
|
}
|
|
59
67
|
if (lintResults.length === 0) {
|
|
60
|
-
|
|
68
|
+
const ignoredPatterns = (await Promise.all(options.lintFilePatterns.map(async (pattern) => (await eslint.isPathIgnored(pattern)) ? pattern : null)))
|
|
69
|
+
.filter((pattern) => !!pattern)
|
|
70
|
+
.map((pattern) => `- '${pattern}'`);
|
|
71
|
+
if (ignoredPatterns.length) {
|
|
72
|
+
throw new Error(`All files matching the following patterns are ignored:\n${ignoredPatterns.join('\n')}\n\nPlease check your '.eslintignore' file.`);
|
|
73
|
+
}
|
|
74
|
+
throw new Error('Invalid lint configuration. Nothing to lint. Please check your lint target pattern(s).');
|
|
61
75
|
}
|
|
76
|
+
// output fixes to disk, if applicable based on the options
|
|
77
|
+
await ESLint.outputFixes(lintResults);
|
|
62
78
|
const formatter = await eslint.loadFormatter(options.format);
|
|
63
79
|
let totalErrors = 0;
|
|
64
80
|
let totalWarnings = 0;
|
|
65
|
-
|
|
66
|
-
|
|
81
|
+
const reportOnlyErrors = options.quiet;
|
|
82
|
+
const maxWarnings = options.maxWarnings;
|
|
67
83
|
/**
|
|
68
84
|
* Depending on user configuration we may not want to report on all the
|
|
69
85
|
* results, so we need to adjust them before formatting.
|
|
@@ -96,8 +112,8 @@ exports.default = (0, architect_1.createBuilder)(async (options, context) => {
|
|
|
96
112
|
*/
|
|
97
113
|
const formattedResults = await formatter.format(finalLintResults);
|
|
98
114
|
if (options.outputFile) {
|
|
99
|
-
const pathToOutputFile = (0, path_1.join)(context.
|
|
100
|
-
(0,
|
|
115
|
+
const pathToOutputFile = (0, path_1.join)(context.root, options.outputFile);
|
|
116
|
+
(0, fs_1.mkdirSync)((0, path_1.dirname)(pathToOutputFile), { recursive: true });
|
|
101
117
|
(0, fs_1.writeFileSync)(pathToOutputFile, formattedResults);
|
|
102
118
|
}
|
|
103
119
|
else {
|
package/dist/schema.json
CHANGED
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
},
|
|
55
55
|
"lintFilePatterns": {
|
|
56
56
|
"type": "array",
|
|
57
|
-
"description": "One or more files/dirs/globs to pass directly to ESLint's lintFiles() method.",
|
|
57
|
+
"description": "One or more files/dirs/globs to pass directly to ESLint's `lintFiles()` method.",
|
|
58
58
|
"default": [],
|
|
59
59
|
"items": {
|
|
60
60
|
"type": "string"
|
|
@@ -87,16 +87,16 @@
|
|
|
87
87
|
},
|
|
88
88
|
"ignorePath": {
|
|
89
89
|
"type": "string",
|
|
90
|
-
"description": "The path of the
|
|
90
|
+
"description": "The path of the `.eslintignore` file."
|
|
91
91
|
},
|
|
92
92
|
"noEslintrc": {
|
|
93
93
|
"type": "boolean",
|
|
94
|
-
"description": "The equivalent of the
|
|
94
|
+
"description": "The equivalent of the `--no-eslintrc` flag on the ESLint CLI, it is false by default",
|
|
95
95
|
"default": false
|
|
96
96
|
},
|
|
97
97
|
"rulesdir": {
|
|
98
98
|
"type": "array",
|
|
99
|
-
"description": "The equivalent of the
|
|
99
|
+
"description": "The equivalent of the `--rulesdir` flag on the ESLint CLI, it is an empty array by default",
|
|
100
100
|
"default": [],
|
|
101
101
|
"items": {
|
|
102
102
|
"type": "string"
|
|
@@ -104,7 +104,12 @@
|
|
|
104
104
|
},
|
|
105
105
|
"resolvePluginsRelativeTo": {
|
|
106
106
|
"type": "string",
|
|
107
|
-
"description": "The equivalent of the
|
|
107
|
+
"description": "The equivalent of the `--resolve-plugins-relative-to` flag on the ESLint CLI"
|
|
108
|
+
},
|
|
109
|
+
"reportUnusedDisableDirectives": {
|
|
110
|
+
"type": "string",
|
|
111
|
+
"enum": ["off", "warn", "error"],
|
|
112
|
+
"description": "The equivalent of the `--report-unused-disable-directives` flag on the ESLint CLI."
|
|
108
113
|
}
|
|
109
114
|
},
|
|
110
115
|
"additionalProperties": false,
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import type { ESLint } from 'eslint';
|
|
2
2
|
import type { Schema } from '../schema';
|
|
3
|
-
export declare function
|
|
4
|
-
|
|
3
|
+
export declare function resolveAndInstantiateESLint(eslintConfigPath: string | undefined, options: Schema, useFlatConfig?: boolean): Promise<{
|
|
4
|
+
ESLint: typeof import("eslint").ESLint;
|
|
5
|
+
eslint: ESLint;
|
|
6
|
+
}>;
|
|
@@ -23,46 +23,72 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.
|
|
27
|
-
|
|
28
|
-
async function loadESLint() {
|
|
29
|
-
let eslint;
|
|
26
|
+
exports.resolveAndInstantiateESLint = void 0;
|
|
27
|
+
async function resolveESLintClass(useFlatConfig = false) {
|
|
30
28
|
try {
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
if (!useFlatConfig) {
|
|
30
|
+
return (await Promise.resolve().then(() => __importStar(require('eslint')))).ESLint;
|
|
31
|
+
}
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
33
|
+
const { FlatESLint } = require('eslint/use-at-your-own-risk');
|
|
34
|
+
return FlatESLint;
|
|
33
35
|
}
|
|
34
36
|
catch (_a) {
|
|
35
37
|
throw new Error('Unable to find ESLint. Ensure ESLint is installed.');
|
|
36
38
|
}
|
|
37
39
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
useEslintrc: !options.noEslintrc,
|
|
40
|
+
async function resolveAndInstantiateESLint(eslintConfigPath, options, useFlatConfig = false) {
|
|
41
|
+
if (useFlatConfig &&
|
|
42
|
+
eslintConfigPath &&
|
|
43
|
+
!(eslintConfigPath === null || eslintConfigPath === void 0 ? void 0 : eslintConfigPath.endsWith('eslint.config.js'))) {
|
|
44
|
+
throw new Error('When using the new Flat Config with ESLint, all configs must be named eslint.config.js and .eslintrc files may not be used. See https://eslint.org/docs/latest/use/configure/configuration-files-new');
|
|
45
|
+
}
|
|
46
|
+
const ESLint = await resolveESLintClass(useFlatConfig);
|
|
47
|
+
const eslintOptions = {
|
|
47
48
|
overrideConfigFile: eslintConfigPath,
|
|
48
|
-
ignorePath: options.ignorePath || undefined,
|
|
49
49
|
fix: !!options.fix,
|
|
50
50
|
cache: !!options.cache,
|
|
51
51
|
cacheLocation: options.cacheLocation || undefined,
|
|
52
52
|
cacheStrategy: options.cacheStrategy || undefined,
|
|
53
|
-
resolvePluginsRelativeTo: options.resolvePluginsRelativeTo || undefined,
|
|
54
|
-
rulePaths: options.rulesdir || [],
|
|
55
53
|
/**
|
|
56
54
|
* Default is `true` and if not overridden the eslint.lintFiles() method will throw an error
|
|
57
55
|
* when no target files are found.
|
|
58
56
|
*
|
|
59
57
|
* We don't want ESLint to throw an error if a user has only just created
|
|
60
58
|
* a project and therefore doesn't necessarily have matching files, for example.
|
|
59
|
+
*
|
|
60
|
+
* Also, the angular generator creates a lint pattern for `html` files, but there may
|
|
61
|
+
* not be any html files in the project, so keeping it true would break linting every time
|
|
61
62
|
*/
|
|
62
63
|
errorOnUnmatchedPattern: false,
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
reportUnusedDisableDirectives: options.reportUnusedDisableDirectives || undefined,
|
|
65
|
+
};
|
|
66
|
+
if (useFlatConfig) {
|
|
67
|
+
if (typeof options.useEslintrc !== 'undefined') {
|
|
68
|
+
throw new Error('For Flat Config, the `useEslintrc` option is not applicable. See https://eslint.org/docs/latest/use/configure/configuration-files-new');
|
|
69
|
+
}
|
|
70
|
+
if (options.resolvePluginsRelativeTo !== undefined) {
|
|
71
|
+
throw new Error('For Flat Config, ESLint removed `resolvePluginsRelativeTo` and so it is not supported as an option. See https://eslint.org/docs/latest/use/configure/configuration-files-new');
|
|
72
|
+
}
|
|
73
|
+
if (options.ignorePath !== undefined) {
|
|
74
|
+
throw new Error('For Flat Config, ESLint removed `ignorePath` and so it is not supported as an option. See https://eslint.org/docs/latest/use/configure/configuration-files-new');
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
eslintOptions.rulePaths = options.rulesdir || [];
|
|
79
|
+
eslintOptions.resolvePluginsRelativeTo =
|
|
80
|
+
options.resolvePluginsRelativeTo || undefined;
|
|
81
|
+
eslintOptions.ignorePath = options.ignorePath || undefined;
|
|
82
|
+
/**
|
|
83
|
+
* If "noEslintrc" is set to `true` (and therefore here "useEslintrc" will be `false`), then ESLint will not
|
|
84
|
+
* merge the provided config with others it finds automatically.
|
|
85
|
+
*/
|
|
86
|
+
eslintOptions.useEslintrc = !options.noEslintrc;
|
|
87
|
+
}
|
|
88
|
+
const eslint = new ESLint(eslintOptions);
|
|
89
|
+
return {
|
|
90
|
+
ESLint,
|
|
91
|
+
eslint,
|
|
92
|
+
};
|
|
67
93
|
}
|
|
68
|
-
exports.
|
|
94
|
+
exports.resolveAndInstantiateESLint = resolveAndInstantiateESLint;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular-eslint/builder",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "16.0.0-alpha.0",
|
|
4
4
|
"description": "Angular CLI builder for ESLint",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -17,10 +17,14 @@
|
|
|
17
17
|
"LICENSE",
|
|
18
18
|
"builders.json"
|
|
19
19
|
],
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@nx/devkit": "16.0.2",
|
|
22
|
+
"nx": "16.0.2"
|
|
23
|
+
},
|
|
20
24
|
"builders": "./builders.json",
|
|
21
25
|
"peerDependencies": {
|
|
22
26
|
"eslint": "^7.20.0 || ^8.0.0",
|
|
23
27
|
"typescript": "*"
|
|
24
28
|
},
|
|
25
|
-
"gitHead": "
|
|
29
|
+
"gitHead": "4bb6da6362f6625bffe7430d5117bbfb66e38d2b"
|
|
26
30
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function createDirectory(directoryPath: string): void;
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createDirectory = void 0;
|
|
4
|
-
const path_1 = require("path");
|
|
5
|
-
const fs_1 = require("fs");
|
|
6
|
-
function createDirectory(directoryPath) {
|
|
7
|
-
const parentPath = (0, path_1.dirname)(directoryPath);
|
|
8
|
-
if (!directoryExists(parentPath)) {
|
|
9
|
-
createDirectory(parentPath);
|
|
10
|
-
}
|
|
11
|
-
if (!directoryExists(directoryPath)) {
|
|
12
|
-
(0, fs_1.mkdirSync)(directoryPath);
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
exports.createDirectory = createDirectory;
|
|
16
|
-
function directoryExists(name) {
|
|
17
|
-
try {
|
|
18
|
-
return (0, fs_1.statSync)(name).isDirectory();
|
|
19
|
-
}
|
|
20
|
-
catch (_a) {
|
|
21
|
-
return false;
|
|
22
|
-
}
|
|
23
|
-
}
|