@angular-eslint/schematics 21.4.1-alpha.7 → 22.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/add-eslint-to-project/schema.json +1 -1
- package/dist/application/schema.json +1 -1
- package/dist/library/schema.json +1 -1
- package/dist/ng-add/index.d.ts +0 -2
- package/dist/ng-add/index.d.ts.map +1 -1
- package/dist/ng-add/index.js +30 -59
- package/dist/utils.d.ts +10 -31
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +40 -195
- package/package.json +8 -8
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
},
|
|
15
15
|
"setParserOptionsProject": {
|
|
16
16
|
"type": "boolean",
|
|
17
|
-
"description": "Whether or not to
|
|
17
|
+
"description": "Whether or not to enable rules that require type information by configuring the ESLint `parserOptions.projectService` option. We do not do this by default for lint performance reasons.",
|
|
18
18
|
"default": false
|
|
19
19
|
}
|
|
20
20
|
},
|
|
@@ -141,7 +141,7 @@
|
|
|
141
141
|
},
|
|
142
142
|
"setParserOptionsProject": {
|
|
143
143
|
"type": "boolean",
|
|
144
|
-
"description": "Whether or not to
|
|
144
|
+
"description": "Whether or not to enable rules that require type information by configuring the ESLint `parserOptions.projectService` option. We do not do this by default for lint performance reasons.",
|
|
145
145
|
"default": false
|
|
146
146
|
}
|
|
147
147
|
},
|
package/dist/library/schema.json
CHANGED
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
},
|
|
63
63
|
"setParserOptionsProject": {
|
|
64
64
|
"type": "boolean",
|
|
65
|
-
"description": "Whether or not to
|
|
65
|
+
"description": "Whether or not to enable rules that require type information by configuring the ESLint `parserOptions.projectService` option. We do not do this by default for lint performance reasons.",
|
|
66
66
|
"default": false
|
|
67
67
|
}
|
|
68
68
|
},
|
package/dist/ng-add/index.d.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import type { Rule } from '@angular-devkit/schematics';
|
|
2
2
|
import type { Schema } from './schema';
|
|
3
|
-
export declare const FIXED_ESLINT_V8_VERSION = "8.57.1";
|
|
4
|
-
export declare const FIXED_TYPESCRIPT_ESLINT_V7_VERSION = "7.11.0";
|
|
5
3
|
/**
|
|
6
4
|
* Entry point for the ng-add schematic.
|
|
7
5
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ng-add/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAA0B,MAAM,4BAA4B,CAAC;AAG/E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ng-add/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAA0B,MAAM,4BAA4B,CAAC;AAG/E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAkLvC;;;;GAIG;AACH,MAAM,CAAC,OAAO,WAAW,OAAO,EAAE,MAAM,GAAG,IAAI,CAY9C"}
|
package/dist/ng-add/index.js
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FIXED_TYPESCRIPT_ESLINT_V7_VERSION = exports.FIXED_ESLINT_V8_VERSION = void 0;
|
|
4
3
|
exports.default = default_1;
|
|
5
4
|
const schematics_1 = require("@angular-devkit/schematics");
|
|
6
5
|
const tasks_1 = require("@angular-devkit/schematics/tasks");
|
|
7
6
|
const utils_1 = require("../utils");
|
|
8
|
-
exports.FIXED_ESLINT_V8_VERSION = '8.57.1';
|
|
9
|
-
exports.FIXED_TYPESCRIPT_ESLINT_V7_VERSION = '7.11.0';
|
|
10
7
|
const packageJSON = require('../../package.json');
|
|
11
|
-
function addAngularESLintPackages(json,
|
|
8
|
+
function addAngularESLintPackages(json, options) {
|
|
12
9
|
return (host, context) => {
|
|
13
10
|
if (!host.exists('package.json')) {
|
|
14
11
|
throw new Error('Could not find a `package.json` file at the root of your workspace');
|
|
@@ -18,29 +15,25 @@ function addAngularESLintPackages(json, useFlatConfig, options) {
|
|
|
18
15
|
}
|
|
19
16
|
json.scripts = json.scripts || {};
|
|
20
17
|
json.scripts['lint'] = json.scripts['lint'] || 'ng lint';
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
const isNpm = host.exists('package-lock.json');
|
|
36
|
-
if (!isNpm) {
|
|
37
|
-
// Ensure @angular-eslint/builder is always resolvable in non-npm installations (https://github.com/angular-eslint/angular-eslint/issues/2241)
|
|
38
|
-
json.devDependencies['@angular-eslint/builder'] = packageJSON.version;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
18
|
+
json.devDependencies = json.devDependencies || {};
|
|
19
|
+
applyDevDependenciesForFlatConfig(json);
|
|
20
|
+
// Check if yarn PnP is used https://yarnpkg.com/advanced/pnpapi#processversionspnp and install extra explicit packages to make it happy
|
|
21
|
+
if (process.versions.pnp) {
|
|
22
|
+
// An explicit reference to the builder is needed for running `ng lint` in PnP
|
|
23
|
+
json.devDependencies['@angular-eslint/builder'] = packageJSON.version;
|
|
24
|
+
// The linting cannot complete without these explicitly in the root package.json in PnP
|
|
25
|
+
const typescriptESLintVersion = packageJSON.devDependencies['@typescript-eslint/utils'];
|
|
26
|
+
json.devDependencies['@typescript-eslint/types'] =
|
|
27
|
+
typescriptESLintVersion;
|
|
28
|
+
json.devDependencies['@typescript-eslint/utils'] =
|
|
29
|
+
typescriptESLintVersion;
|
|
41
30
|
}
|
|
42
31
|
else {
|
|
43
|
-
|
|
32
|
+
const isNpm = host.exists('package-lock.json');
|
|
33
|
+
if (!isNpm) {
|
|
34
|
+
// Ensure @angular-eslint/builder is always resolvable in non-npm installations (https://github.com/angular-eslint/angular-eslint/issues/2241)
|
|
35
|
+
json.devDependencies['@angular-eslint/builder'] = packageJSON.version;
|
|
36
|
+
}
|
|
44
37
|
}
|
|
45
38
|
json.devDependencies = (0, utils_1.sortObjectByKeys)(json.devDependencies);
|
|
46
39
|
host.overwrite('package.json', JSON.stringify(json, null, 2));
|
|
@@ -62,25 +55,6 @@ Please see https://github.com/angular-eslint/angular-eslint for how to add ESLin
|
|
|
62
55
|
return host;
|
|
63
56
|
};
|
|
64
57
|
}
|
|
65
|
-
function applyDevDependenciesForESLintRC(json) {
|
|
66
|
-
json.devDependencies['eslint'] = exports.FIXED_ESLINT_V8_VERSION;
|
|
67
|
-
/**
|
|
68
|
-
* @angular-eslint packages
|
|
69
|
-
*/
|
|
70
|
-
json.devDependencies['@angular-eslint/builder'] = packageJSON.version;
|
|
71
|
-
json.devDependencies['@angular-eslint/eslint-plugin'] = packageJSON.version;
|
|
72
|
-
json.devDependencies['@angular-eslint/eslint-plugin-template'] =
|
|
73
|
-
packageJSON.version;
|
|
74
|
-
json.devDependencies['@angular-eslint/schematics'] = packageJSON.version;
|
|
75
|
-
json.devDependencies['@angular-eslint/template-parser'] = packageJSON.version;
|
|
76
|
-
/**
|
|
77
|
-
* @typescript-eslint packages
|
|
78
|
-
*/
|
|
79
|
-
json.devDependencies['@typescript-eslint/eslint-plugin'] =
|
|
80
|
-
exports.FIXED_TYPESCRIPT_ESLINT_V7_VERSION;
|
|
81
|
-
json.devDependencies['@typescript-eslint/parser'] =
|
|
82
|
-
exports.FIXED_TYPESCRIPT_ESLINT_V7_VERSION;
|
|
83
|
-
}
|
|
84
58
|
function applyDevDependenciesForFlatConfig(json) {
|
|
85
59
|
json.devDependencies['eslint'] = `^${packageJSON.devDependencies['eslint']}`;
|
|
86
60
|
json.devDependencies['@eslint/js'] =
|
|
@@ -105,7 +79,7 @@ function applyDevDependenciesForFlatConfig(json) {
|
|
|
105
79
|
delete json.devDependencies['@typescript-eslint/eslint-plugin'];
|
|
106
80
|
delete json.devDependencies['@typescript-eslint/utils'];
|
|
107
81
|
}
|
|
108
|
-
function applyESLintConfigIfSingleProjectWithNoExistingTSLint(
|
|
82
|
+
function applyESLintConfigIfSingleProjectWithNoExistingTSLint() {
|
|
109
83
|
return (host, context) => {
|
|
110
84
|
const angularJson = (0, utils_1.readJsonInTree)(host, 'angular.json');
|
|
111
85
|
if (!angularJson || !angularJson.projects) {
|
|
@@ -122,16 +96,14 @@ function applyESLintConfigIfSingleProjectWithNoExistingTSLint(useFlatConfig) {
|
|
|
122
96
|
const projectNames = Object.keys(angularJson.projects);
|
|
123
97
|
if (projectNames.length === 0) {
|
|
124
98
|
return (0, schematics_1.chain)([
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
: (0, utils_1.updateJsonInTree)('.eslintrc.json', () => (0, utils_1.createRootESLintConfig)(null)),
|
|
134
|
-
(0, utils_1.updateJsonInTree)('angular.json', (json) => (0, utils_1.updateSchematicCollections)(json, useFlatConfig ? 'angular-eslint' : '@angular-eslint/schematics')),
|
|
99
|
+
(host) => {
|
|
100
|
+
// If the root package.json uses type: module, generate ESM content
|
|
101
|
+
const packageJson = (0, utils_1.readJsonInTree)(host, 'package.json');
|
|
102
|
+
const isESM = packageJson.type === 'module';
|
|
103
|
+
host.create('eslint.config.js', (0, utils_1.createStringifiedRootESLintConfig)(null, isESM));
|
|
104
|
+
return host;
|
|
105
|
+
},
|
|
106
|
+
(0, utils_1.updateJsonInTree)('angular.json', (json) => (0, utils_1.updateSchematicCollections)(json, 'angular-eslint')),
|
|
135
107
|
]);
|
|
136
108
|
}
|
|
137
109
|
/**
|
|
@@ -159,7 +131,7 @@ Please see https://github.com/angular-eslint/angular-eslint for more information
|
|
|
159
131
|
`.trimStart());
|
|
160
132
|
return (0, schematics_1.chain)([
|
|
161
133
|
(0, schematics_1.schematic)('add-eslint-to-project', {}),
|
|
162
|
-
(0, utils_1.updateJsonInTree)('angular.json', (json) => (0, utils_1.updateSchematicCollections)(json,
|
|
134
|
+
(0, utils_1.updateJsonInTree)('angular.json', (json) => (0, utils_1.updateSchematicCollections)(json, 'angular-eslint')),
|
|
163
135
|
]);
|
|
164
136
|
};
|
|
165
137
|
}
|
|
@@ -172,10 +144,9 @@ function default_1(options) {
|
|
|
172
144
|
return (host, context) => {
|
|
173
145
|
const workspacePackageJSON = host.read('package.json').toString('utf-8');
|
|
174
146
|
const json = JSON.parse(workspacePackageJSON);
|
|
175
|
-
const useFlatConfig = (0, utils_1.shouldUseFlatConfig)(host, json);
|
|
176
147
|
return (0, schematics_1.chain)([
|
|
177
|
-
addAngularESLintPackages(json,
|
|
178
|
-
applyESLintConfigIfSingleProjectWithNoExistingTSLint(
|
|
148
|
+
addAngularESLintPackages(json, options),
|
|
149
|
+
applyESLintConfigIfSingleProjectWithNoExistingTSLint(),
|
|
179
150
|
])(host, context);
|
|
180
151
|
};
|
|
181
152
|
}
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import type { Path } from '@angular-devkit/core';
|
|
2
2
|
import type { Rule, SchematicContext, Tree } from '@angular-devkit/schematics';
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* The conventional flat config file names that ESLint resolves automatically
|
|
5
|
+
* and that these schematics scaffold by default.
|
|
6
|
+
*
|
|
7
|
+
* NOTE: this is NOT a restriction on what an ESLint flat config file may be
|
|
8
|
+
* named - a flat config can have any name. We only use these conventional names
|
|
9
|
+
* when detecting an existing root config or resolving its path during code
|
|
10
|
+
* generation.
|
|
11
|
+
*/
|
|
12
|
+
export declare const defaultFlatConfigNames: string[];
|
|
4
13
|
/**
|
|
5
14
|
* This method is specifically for reading JSON files in a Tree
|
|
6
15
|
* @param host The host tree
|
|
@@ -29,29 +38,6 @@ export declare function addESLintTargetToProject(projectName: string, targetName
|
|
|
29
38
|
* Utility to act on all files in a tree that are not ignored by git.
|
|
30
39
|
*/
|
|
31
40
|
export declare function visitNotIgnoredFiles(visitor: (file: Path, host: Tree, context: SchematicContext) => void | Rule, dir?: Path): Rule;
|
|
32
|
-
export declare function createRootESLintConfig(prefix: string | null): {
|
|
33
|
-
root: boolean;
|
|
34
|
-
ignorePatterns: string[];
|
|
35
|
-
overrides: {
|
|
36
|
-
files: string[];
|
|
37
|
-
extends: string[];
|
|
38
|
-
rules: {
|
|
39
|
-
'@angular-eslint/directive-selector': (string | {
|
|
40
|
-
type: string;
|
|
41
|
-
prefix: string;
|
|
42
|
-
style: string;
|
|
43
|
-
})[];
|
|
44
|
-
'@angular-eslint/component-selector': (string | {
|
|
45
|
-
type: string;
|
|
46
|
-
prefix: string;
|
|
47
|
-
style: string;
|
|
48
|
-
})[];
|
|
49
|
-
} | {
|
|
50
|
-
'@angular-eslint/directive-selector'?: undefined;
|
|
51
|
-
'@angular-eslint/component-selector'?: undefined;
|
|
52
|
-
};
|
|
53
|
-
}[];
|
|
54
|
-
};
|
|
55
41
|
export declare function createStringifiedRootESLintConfig(prefix: string | null, isESM: boolean): string;
|
|
56
42
|
export declare function createESLintConfigForProject(projectName: string, setParserOptionsProject: boolean): Rule;
|
|
57
43
|
export declare function sortObjectByKeys(obj: Record<string, unknown>): Record<string, unknown>;
|
|
@@ -66,13 +52,6 @@ export declare function determineTargetProjectName(tree: Tree, maybeProject?: st
|
|
|
66
52
|
*/
|
|
67
53
|
export declare function updateSchematicCollections(angularJson: Record<string, any>, collectionName: '@angular-eslint/schematics' | 'angular-eslint'): Record<string, any>;
|
|
68
54
|
export declare function updateSchematicDefaults(angularJson: Record<string, any>, schematicFullName: string, defaultValues: Record<string, unknown>): Record<string, any>;
|
|
69
|
-
/**
|
|
70
|
-
* In order to support both flat config and eslintrc we need to dynamically figure out
|
|
71
|
-
* what the user should be using based on:
|
|
72
|
-
* - their existing files
|
|
73
|
-
* - their eslint version
|
|
74
|
-
*/
|
|
75
|
-
export declare function shouldUseFlatConfig(tree: Tree, existingJson?: Record<string, unknown>): boolean;
|
|
76
55
|
export declare function resolveRootESLintConfigPath(tree: Tree): string | null;
|
|
77
56
|
export declare function determineNewProjectESLintConfigContentAndExtension(tree: Tree, rootConfigPath: string, projectRoot: string): {
|
|
78
57
|
isESM: boolean;
|
package/dist/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAEjD,OAAO,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAEjD,OAAO,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;AAQ/E;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,UAOlC,CAAC;AAEF;;;;;GAKG;AAEH,wBAAgB,cAAc,CAAC,CAAC,GAAG,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,CAenE;AAED;;;;;GAKG;AAEH,wBAAgB,gBAAgB,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,EAC7C,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,gBAAgB,KAAK,CAAC,GAClD,IAAI,CAYN;AAED,KAAK,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAE3E,wBAAgB,2BAA2B,CACzC,aAAa,EAAE;IAAE,SAAS,CAAC,EAAE,aAAa,CAAA;CAAE,GAAG;IAAE,OAAO,CAAC,EAAE,aAAa,CAAA;CAAE,GACzE,aAAa,GAAG,IAAI,CAYtB;AA6BD,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,QAAQ,GAAG,MAAM,GAC5B,IAAI,CA4DN;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,gBAAgB,KAAK,IAAI,GAAG,IAAI,EAC3E,GAAG,GAAE,IAAoB,GACxB,IAAI,CA8BN;AAID,wBAAgB,iCAAiC,CAC/C,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,KAAK,EAAE,OAAO,GACb,MAAM,CAkDR;AAuDD,wBAAgB,4BAA4B,CAC1C,WAAW,EAAE,MAAM,EACnB,uBAAuB,EAAE,OAAO,GAC/B,IAAI,CAmDN;AAcD,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC3B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASzB;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,IAAI,EACV,YAAY,CAAC,EAAE,MAAM,GACpB,MAAM,GAAG,IAAI,CAUf;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAChC,cAAc,EAAE,4BAA4B,GAAG,gBAAgB,uBAUhE;AAED,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAChC,iBAAiB,EAAE,MAAM,EACzB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,uBAUvC;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAOrE;AAED,wBAAgB,kDAAkD,CAChE,IAAI,EAAE,IAAI,EACV,cAAc,EAAE,MAAM,EACtB,WAAW,EAAE,MAAM,GAClB;IACD,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;CACb,CAmCA"}
|
package/dist/utils.js
CHANGED
|
@@ -3,29 +3,35 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.defaultFlatConfigNames = void 0;
|
|
7
7
|
exports.readJsonInTree = readJsonInTree;
|
|
8
8
|
exports.updateJsonInTree = updateJsonInTree;
|
|
9
9
|
exports.getTargetsConfigFromProject = getTargetsConfigFromProject;
|
|
10
10
|
exports.addESLintTargetToProject = addESLintTargetToProject;
|
|
11
11
|
exports.visitNotIgnoredFiles = visitNotIgnoredFiles;
|
|
12
|
-
exports.createRootESLintConfig = createRootESLintConfig;
|
|
13
12
|
exports.createStringifiedRootESLintConfig = createStringifiedRootESLintConfig;
|
|
14
13
|
exports.createESLintConfigForProject = createESLintConfigForProject;
|
|
15
14
|
exports.sortObjectByKeys = sortObjectByKeys;
|
|
16
15
|
exports.determineTargetProjectName = determineTargetProjectName;
|
|
17
16
|
exports.updateSchematicCollections = updateSchematicCollections;
|
|
18
17
|
exports.updateSchematicDefaults = updateSchematicDefaults;
|
|
19
|
-
exports.shouldUseFlatConfig = shouldUseFlatConfig;
|
|
20
18
|
exports.resolveRootESLintConfigPath = resolveRootESLintConfigPath;
|
|
21
19
|
exports.determineNewProjectESLintConfigContentAndExtension = determineNewProjectESLintConfigContentAndExtension;
|
|
22
20
|
const core_1 = require("@angular-devkit/core");
|
|
23
21
|
const schematics_1 = require("@angular-devkit/schematics");
|
|
24
22
|
const ignore_1 = __importDefault(require("ignore"));
|
|
25
|
-
const semver_1 = __importDefault(require("semver"));
|
|
26
23
|
const strip_json_comments_1 = __importDefault(require("strip-json-comments"));
|
|
27
24
|
const DEFAULT_PREFIX = 'app';
|
|
28
|
-
|
|
25
|
+
/**
|
|
26
|
+
* The conventional flat config file names that ESLint resolves automatically
|
|
27
|
+
* and that these schematics scaffold by default.
|
|
28
|
+
*
|
|
29
|
+
* NOTE: this is NOT a restriction on what an ESLint flat config file may be
|
|
30
|
+
* named - a flat config can have any name. We only use these conventional names
|
|
31
|
+
* when detecting an existing root config or resolving its path during code
|
|
32
|
+
* generation.
|
|
33
|
+
*/
|
|
34
|
+
exports.defaultFlatConfigNames = [
|
|
29
35
|
'eslint.config.js',
|
|
30
36
|
'eslint.config.mjs',
|
|
31
37
|
'eslint.config.cjs',
|
|
@@ -123,17 +129,15 @@ function addESLintTargetToProject(projectName, targetName) {
|
|
|
123
129
|
};
|
|
124
130
|
let eslintConfig;
|
|
125
131
|
if (existingProjectConfig.root !== '') {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
eslintConfig = flatConfigPath;
|
|
136
|
-
}
|
|
132
|
+
const rootConfigPath = resolveRootESLintConfigPath(tree);
|
|
133
|
+
if (!rootConfigPath ||
|
|
134
|
+
(!rootConfigPath.endsWith('js') && !rootConfigPath.endsWith('ts'))) {
|
|
135
|
+
throw new Error('Root ESLint config must be a JavaScript/TypeScript file (.js,.mjs,.cjs,.ts,.mts,.cts)');
|
|
136
|
+
}
|
|
137
|
+
const { ext } = determineNewProjectESLintConfigContentAndExtension(tree, rootConfigPath, existingProjectConfig.root);
|
|
138
|
+
const flatConfigPath = (0, core_1.join)(existingProjectConfig.root, `eslint.config.${ext}`);
|
|
139
|
+
if (tree.exists(flatConfigPath)) {
|
|
140
|
+
eslintConfig = flatConfigPath;
|
|
137
141
|
}
|
|
138
142
|
}
|
|
139
143
|
eslintTargetConfig.options.eslintConfig = eslintConfig;
|
|
@@ -173,62 +177,6 @@ function visitNotIgnoredFiles(visitor, dir = (0, core_1.normalize)('')) {
|
|
|
173
177
|
visit(dir);
|
|
174
178
|
};
|
|
175
179
|
}
|
|
176
|
-
function setESLintProjectBasedOnProjectType(projectRoot, projectType, hasE2e) {
|
|
177
|
-
let project;
|
|
178
|
-
if (projectType === 'application') {
|
|
179
|
-
project = [`${projectRoot}/tsconfig.(app|spec).json`];
|
|
180
|
-
if (hasE2e) {
|
|
181
|
-
project.push(`${projectRoot}/e2e/tsconfig.json`);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
// Libraries don't have an e2e directory
|
|
185
|
-
if (projectType === 'library') {
|
|
186
|
-
project = [`${projectRoot}/tsconfig.(lib|spec).json`];
|
|
187
|
-
}
|
|
188
|
-
return project;
|
|
189
|
-
}
|
|
190
|
-
function createRootESLintConfig(prefix) {
|
|
191
|
-
let codeRules;
|
|
192
|
-
if (prefix) {
|
|
193
|
-
codeRules = {
|
|
194
|
-
'@angular-eslint/directive-selector': [
|
|
195
|
-
'error',
|
|
196
|
-
{ type: 'attribute', prefix, style: 'camelCase' },
|
|
197
|
-
],
|
|
198
|
-
'@angular-eslint/component-selector': [
|
|
199
|
-
'error',
|
|
200
|
-
{ type: 'element', prefix, style: 'kebab-case' },
|
|
201
|
-
],
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
else {
|
|
205
|
-
codeRules = {};
|
|
206
|
-
}
|
|
207
|
-
return {
|
|
208
|
-
root: true,
|
|
209
|
-
ignorePatterns: ['projects/**/*'],
|
|
210
|
-
overrides: [
|
|
211
|
-
{
|
|
212
|
-
files: ['*.ts'],
|
|
213
|
-
extends: [
|
|
214
|
-
'eslint:recommended',
|
|
215
|
-
'plugin:@typescript-eslint/recommended',
|
|
216
|
-
'plugin:@angular-eslint/recommended',
|
|
217
|
-
'plugin:@angular-eslint/template/process-inline-templates',
|
|
218
|
-
],
|
|
219
|
-
rules: codeRules,
|
|
220
|
-
},
|
|
221
|
-
{
|
|
222
|
-
files: ['*.html'],
|
|
223
|
-
extends: [
|
|
224
|
-
'plugin:@angular-eslint/template/recommended',
|
|
225
|
-
'plugin:@angular-eslint/template/accessibility',
|
|
226
|
-
],
|
|
227
|
-
rules: {},
|
|
228
|
-
},
|
|
229
|
-
],
|
|
230
|
-
};
|
|
231
|
-
}
|
|
232
180
|
function createStringifiedRootESLintConfig(prefix, isESM) {
|
|
233
181
|
return `// @ts-check
|
|
234
182
|
${isESM ? 'import eslint from "@eslint/js";' : 'const eslint = require("@eslint/js");'}
|
|
@@ -278,39 +226,7 @@ ${isESM ? 'export default' : 'module.exports ='} defineConfig([
|
|
|
278
226
|
]);
|
|
279
227
|
`;
|
|
280
228
|
}
|
|
281
|
-
function
|
|
282
|
-
return {
|
|
283
|
-
extends: `${offsetFromRoot(projectRoot)}.eslintrc.json`,
|
|
284
|
-
ignorePatterns: ['!**/*'],
|
|
285
|
-
overrides: [
|
|
286
|
-
{
|
|
287
|
-
files: ['*.ts'],
|
|
288
|
-
...(setParserOptionsProject
|
|
289
|
-
? {
|
|
290
|
-
parserOptions: {
|
|
291
|
-
project: setESLintProjectBasedOnProjectType(projectRoot, projectType, hasE2e),
|
|
292
|
-
},
|
|
293
|
-
}
|
|
294
|
-
: null),
|
|
295
|
-
rules: {
|
|
296
|
-
'@angular-eslint/directive-selector': [
|
|
297
|
-
'error',
|
|
298
|
-
{ type: 'attribute', prefix, style: 'camelCase' },
|
|
299
|
-
],
|
|
300
|
-
'@angular-eslint/component-selector': [
|
|
301
|
-
'error',
|
|
302
|
-
{ type: 'element', prefix, style: 'kebab-case' },
|
|
303
|
-
],
|
|
304
|
-
},
|
|
305
|
-
},
|
|
306
|
-
{
|
|
307
|
-
files: ['*.html'],
|
|
308
|
-
rules: {},
|
|
309
|
-
},
|
|
310
|
-
],
|
|
311
|
-
};
|
|
312
|
-
}
|
|
313
|
-
function createStringifiedProjectESLintConfig(projectRoot, projectType, prefix, setParserOptionsProject, hasE2e, isESM, rootConfigPath) {
|
|
229
|
+
function createStringifiedProjectESLintConfig(projectRoot, projectType, prefix, setParserOptionsProject, isESM, rootConfigPath) {
|
|
314
230
|
const relativeRootConfigPath = offsetFromRoot(projectRoot) + rootConfigPath;
|
|
315
231
|
return `// @ts-check
|
|
316
232
|
${isESM ? 'import { defineConfig } from "eslint/config";' : 'const { defineConfig } = require("eslint/config");'}
|
|
@@ -357,44 +273,33 @@ function createESLintConfigForProject(projectName, setParserOptionsProject) {
|
|
|
357
273
|
return (tree) => {
|
|
358
274
|
const angularJSON = readJsonInTree(tree, 'angular.json');
|
|
359
275
|
const { root: projectRoot, projectType, prefix, } = angularJSON.projects[projectName];
|
|
360
|
-
const
|
|
361
|
-
const useFlatConfig = shouldUseFlatConfig(tree);
|
|
362
|
-
const alreadyHasRootFlatConfig = exports.supportedFlatConfigNames.some((name) => tree.exists(name));
|
|
363
|
-
const alreadyHasRootESLintRC = tree.exists('.eslintrc.json');
|
|
276
|
+
const alreadyHasRootFlatConfig = exports.defaultFlatConfigNames.some((name) => tree.exists(name));
|
|
364
277
|
/**
|
|
365
278
|
* If the root is an empty string it must be the initial project created at the
|
|
366
279
|
* root by the Angular CLI's workspace schematic
|
|
367
280
|
*/
|
|
368
281
|
if (projectRoot === '') {
|
|
369
|
-
return createRootESLintConfigFile(prefix || DEFAULT_PREFIX
|
|
282
|
+
return createRootESLintConfigFile(prefix || DEFAULT_PREFIX);
|
|
370
283
|
}
|
|
371
284
|
const rules = [];
|
|
372
|
-
// If, for whatever reason, the root eslint.config
|
|
373
|
-
if (!
|
|
374
|
-
rules.push(createRootESLintConfigFile(prefix || DEFAULT_PREFIX
|
|
375
|
-
}
|
|
376
|
-
if (useFlatConfig) {
|
|
377
|
-
const rootConfigPath = resolveRootESLintConfigPath(tree) ?? 'eslint.config.js';
|
|
378
|
-
rules.push((tree) => {
|
|
379
|
-
const { isESM, ext } = determineNewProjectESLintConfigContentAndExtension(tree, rootConfigPath, projectRoot);
|
|
380
|
-
return tree.create((0, core_1.join)((0, core_1.normalize)(projectRoot), `eslint.config.${ext}`), createStringifiedProjectESLintConfig(projectRoot, projectType || 'library', prefix || DEFAULT_PREFIX, setParserOptionsProject, hasE2e, isESM, rootConfigPath));
|
|
381
|
-
});
|
|
382
|
-
}
|
|
383
|
-
else {
|
|
384
|
-
rules.push(updateJsonInTree((0, core_1.join)((0, core_1.normalize)(projectRoot), '.eslintrc.json'), () => createProjectESLintConfig(projectRoot, projectType || 'library', prefix || DEFAULT_PREFIX, setParserOptionsProject, hasE2e)));
|
|
285
|
+
// If, for whatever reason, the root eslint.config.* doesn't exist yet, create it
|
|
286
|
+
if (!alreadyHasRootFlatConfig) {
|
|
287
|
+
rules.push(createRootESLintConfigFile(prefix || DEFAULT_PREFIX));
|
|
385
288
|
}
|
|
289
|
+
const rootConfigPath = resolveRootESLintConfigPath(tree) ?? 'eslint.config.js';
|
|
290
|
+
rules.push((tree) => {
|
|
291
|
+
const { isESM, ext } = determineNewProjectESLintConfigContentAndExtension(tree, rootConfigPath, projectRoot);
|
|
292
|
+
return tree.create((0, core_1.join)((0, core_1.normalize)(projectRoot), `eslint.config.${ext}`), createStringifiedProjectESLintConfig(projectRoot, projectType || 'library', prefix || DEFAULT_PREFIX, setParserOptionsProject, isESM, rootConfigPath));
|
|
293
|
+
});
|
|
386
294
|
return (0, schematics_1.chain)(rules);
|
|
387
295
|
};
|
|
388
296
|
}
|
|
389
|
-
function createRootESLintConfigFile(prefix
|
|
297
|
+
function createRootESLintConfigFile(prefix) {
|
|
390
298
|
return (tree) => {
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
return tree.create('eslint.config.js', createStringifiedRootESLintConfig(prefix, isESM));
|
|
396
|
-
}
|
|
397
|
-
return updateJsonInTree('.eslintrc.json', () => createRootESLintConfig(prefix));
|
|
299
|
+
// If the root package.json uses type: module, generate ESM content
|
|
300
|
+
const packageJson = readJsonInTree(tree, 'package.json');
|
|
301
|
+
const isESM = packageJson.type === 'module';
|
|
302
|
+
return tree.create('eslint.config.js', createStringifiedRootESLintConfig(prefix, isESM));
|
|
398
303
|
};
|
|
399
304
|
}
|
|
400
305
|
function sortObjectByKeys(obj) {
|
|
@@ -422,15 +327,6 @@ function determineTargetProjectName(tree, maybeProject) {
|
|
|
422
327
|
}
|
|
423
328
|
return null;
|
|
424
329
|
}
|
|
425
|
-
/**
|
|
426
|
-
* Checking if the target project has e2e setup
|
|
427
|
-
* Method will check if angular project architect has e2e configuration to determine if e2e setup
|
|
428
|
-
*/
|
|
429
|
-
function determineTargetProjectHasE2E(
|
|
430
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
431
|
-
angularJSON, projectName) {
|
|
432
|
-
return !!getTargetsConfigFromProject(angularJSON.projects[projectName])?.e2e;
|
|
433
|
-
}
|
|
434
330
|
/**
|
|
435
331
|
* See `schematicCollections` docs here:
|
|
436
332
|
* https://github.com/angular/angular-cli/blob/8431b3f0769b5f95b9e13807a09293d820c4b017/docs/specifications/schematic-collections-config.md
|
|
@@ -455,62 +351,11 @@ function updateSchematicDefaults(angularJson, schematicFullName, defaultValues)
|
|
|
455
351
|
};
|
|
456
352
|
return angularJson;
|
|
457
353
|
}
|
|
458
|
-
/**
|
|
459
|
-
* In order to support both flat config and eslintrc we need to dynamically figure out
|
|
460
|
-
* what the user should be using based on:
|
|
461
|
-
* - their existing files
|
|
462
|
-
* - their eslint version
|
|
463
|
-
*/
|
|
464
|
-
function shouldUseFlatConfig(tree, existingJson) {
|
|
465
|
-
let useFlatConfig = true;
|
|
466
|
-
try {
|
|
467
|
-
const alreadyHasRootFlatConfig = exports.supportedFlatConfigNames.some((name) => tree.exists(name));
|
|
468
|
-
const alreadyHasRootESLintRC = tree.exists('.eslintrc.json');
|
|
469
|
-
if (alreadyHasRootFlatConfig) {
|
|
470
|
-
useFlatConfig = true;
|
|
471
|
-
}
|
|
472
|
-
else if (alreadyHasRootESLintRC) {
|
|
473
|
-
useFlatConfig = false;
|
|
474
|
-
}
|
|
475
|
-
else {
|
|
476
|
-
const json = existingJson ??
|
|
477
|
-
JSON.parse(tree.read('package.json').toString('utf-8'));
|
|
478
|
-
json.devDependencies = json.devDependencies || {};
|
|
479
|
-
const existingESLintVersion = json.devDependencies['eslint'];
|
|
480
|
-
if (existingESLintVersion) {
|
|
481
|
-
const v = semver_1.default.minVersion(existingESLintVersion);
|
|
482
|
-
if (v) {
|
|
483
|
-
useFlatConfig = semver_1.default.gte(v.raw, '9.0.0');
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
return useFlatConfig;
|
|
488
|
-
}
|
|
489
|
-
catch {
|
|
490
|
-
return useFlatConfig;
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
354
|
function resolveRootESLintConfigPath(tree) {
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
return 'eslint.config.js';
|
|
499
|
-
}
|
|
500
|
-
if (tree.exists('eslint.config.mjs')) {
|
|
501
|
-
return 'eslint.config.mjs';
|
|
502
|
-
}
|
|
503
|
-
if (tree.exists('eslint.config.cjs')) {
|
|
504
|
-
return 'eslint.config.cjs';
|
|
505
|
-
}
|
|
506
|
-
if (tree.exists('eslint.config.ts')) {
|
|
507
|
-
return 'eslint.config.ts';
|
|
508
|
-
}
|
|
509
|
-
if (tree.exists('eslint.config.mts')) {
|
|
510
|
-
return 'eslint.config.mts';
|
|
511
|
-
}
|
|
512
|
-
if (tree.exists('eslint.config.cts')) {
|
|
513
|
-
return 'eslint.config.cts';
|
|
355
|
+
for (const name of exports.defaultFlatConfigNames) {
|
|
356
|
+
if (tree.exists(name)) {
|
|
357
|
+
return name;
|
|
358
|
+
}
|
|
514
359
|
}
|
|
515
360
|
return null;
|
|
516
361
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular-eslint/schematics",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "22.0.0",
|
|
4
4
|
"description": "Angular Schematics for angular-eslint",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -36,20 +36,20 @@
|
|
|
36
36
|
"save": "devDependencies"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
|
-
"@angular/cli": ">=
|
|
39
|
+
"@angular/cli": ">= 22.0.0 < 23.0.0"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@angular-devkit/core": ">=
|
|
43
|
-
"@angular-devkit/schematics": ">=
|
|
42
|
+
"@angular-devkit/core": ">= 22.0.0 < 23.0.0",
|
|
43
|
+
"@angular-devkit/schematics": ">= 22.0.0 < 23.0.0",
|
|
44
44
|
"ignore": "7.0.5",
|
|
45
|
-
"semver": "7.
|
|
45
|
+
"semver": "7.8.0",
|
|
46
46
|
"strip-json-comments": "3.1.1",
|
|
47
|
-
"@angular-eslint/eslint-plugin": "
|
|
48
|
-
"@angular-eslint/eslint-plugin-template": "
|
|
47
|
+
"@angular-eslint/eslint-plugin": "22.0.0",
|
|
48
|
+
"@angular-eslint/eslint-plugin-template": "22.0.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@eslint/js": "10.0.1",
|
|
52
|
-
"@typescript-eslint/utils": "8.
|
|
52
|
+
"@typescript-eslint/utils": "8.60.1",
|
|
53
53
|
"eslint": "10.3.0"
|
|
54
54
|
},
|
|
55
55
|
"gitHead": "e2006e5e9c99e5a943d1a999e0efa5247d29ec24"
|