@nx/eslint-plugin 16.8.0-beta.4 → 16.8.0-beta.6
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/package.json +5 -5
- package/src/configs/angular.js +2 -3
- package/src/index.js +6 -1
- package/src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages.js +23 -26
- package/src/rules/dependency-checks.js +2 -3
- package/src/rules/nx-plugin-checks.js +18 -14
- package/src/utils/ast-utils.js +4 -7
- package/src/utils/config-utils.js +1 -1
- package/src/utils/package-json-utils.js +11 -2
- package/src/utils/project-graph-utils.js +1 -1
- package/src/utils/runtime-lint-utils.js +4 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/eslint-plugin",
|
|
3
|
-
"version": "16.8.0-beta.
|
|
3
|
+
"version": "16.8.0-beta.6",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "The eslint-plugin package is an ESLint plugin that contains a collection of recommended ESLint rule configurations which you can extend from in your own ESLint configs, as well as an Nx-specific lint rule called enforce-module-boundaries.",
|
|
6
6
|
"repository": {
|
|
@@ -33,9 +33,9 @@
|
|
|
33
33
|
}
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@nrwl/eslint-plugin-nx": "16.8.0-beta.
|
|
37
|
-
"@nx/devkit": "16.8.0-beta.
|
|
38
|
-
"@nx/js": "16.8.0-beta.
|
|
36
|
+
"@nrwl/eslint-plugin-nx": "16.8.0-beta.6",
|
|
37
|
+
"@nx/devkit": "16.8.0-beta.6",
|
|
38
|
+
"@nx/js": "16.8.0-beta.6",
|
|
39
39
|
"@typescript-eslint/type-utils": "^5.60.1",
|
|
40
40
|
"@typescript-eslint/utils": "^5.60.1",
|
|
41
41
|
"chalk": "^4.1.0",
|
|
@@ -51,5 +51,5 @@
|
|
|
51
51
|
"migrations": "./migrations.json"
|
|
52
52
|
},
|
|
53
53
|
"type": "commonjs",
|
|
54
|
-
"gitHead": "
|
|
54
|
+
"gitHead": "0cc6ba996f2ef09f00b932c8eacf42de642457f3"
|
|
55
55
|
}
|
package/src/configs/angular.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var _a;
|
|
3
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
3
|
let angularEslintPlugin;
|
|
5
4
|
try {
|
|
6
5
|
angularEslintPlugin = require('@angular-eslint/eslint-plugin');
|
|
7
6
|
}
|
|
8
|
-
catch
|
|
7
|
+
catch { }
|
|
9
8
|
/**
|
|
10
9
|
* This configuration is intended to be applied to ALL .ts files in Angular
|
|
11
10
|
* projects within an Nx workspace.
|
|
@@ -30,7 +29,7 @@ exports.default = {
|
|
|
30
29
|
* TODO: Consider dropping this extends and explicitly carrying over rules we care about
|
|
31
30
|
* into our typescript preset in v13
|
|
32
31
|
*/
|
|
33
|
-
...(
|
|
32
|
+
...(angularEslintPlugin?.configs?.['recommended--extra']
|
|
34
33
|
? ['plugin:@angular-eslint/recommended--extra']
|
|
35
34
|
: []),
|
|
36
35
|
],
|
package/src/index.js
CHANGED
|
@@ -24,5 +24,10 @@ module.exports = {
|
|
|
24
24
|
angular: angular_1.default,
|
|
25
25
|
'angular-template': angular_template_1.default,
|
|
26
26
|
},
|
|
27
|
-
rules:
|
|
27
|
+
rules: {
|
|
28
|
+
[enforce_module_boundaries_1.RULE_NAME]: enforce_module_boundaries_1.default,
|
|
29
|
+
[nx_plugin_checks_1.RULE_NAME]: nx_plugin_checks_1.default,
|
|
30
|
+
[dependency_checks_1.RULE_NAME]: dependency_checks_1.default,
|
|
31
|
+
...resolve_workspace_rules_1.workspaceRules,
|
|
32
|
+
},
|
|
28
33
|
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const tslib_1 = require("tslib");
|
|
4
3
|
const devkit_1 = require("@nx/devkit");
|
|
5
4
|
const replace_package_1 = require("@nx/devkit/src/utils/replace-package");
|
|
6
5
|
const path_1 = require("path");
|
|
@@ -14,33 +13,31 @@ const eslintFileNames = [
|
|
|
14
13
|
'.eslintrc.json',
|
|
15
14
|
'eslint.config.js', // new format that requires `ESLINT_USE_FLAT_CONFIG=true`
|
|
16
15
|
];
|
|
17
|
-
function replacePackage(tree) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
(0,
|
|
28
|
-
|
|
16
|
+
async function replacePackage(tree) {
|
|
17
|
+
await (0, replace_package_1.replaceNrwlPackageWithNxPackage)(tree, '@nrwl/eslint-plugin-nx', '@nx/eslint-plugin');
|
|
18
|
+
/**
|
|
19
|
+
* Matches:
|
|
20
|
+
* * // eslint-disable-next-line @nrwl/nx/...
|
|
21
|
+
* * // eslint-disable-line @nrwl/nx/...
|
|
22
|
+
* * /* eslint-disable @nrwl/nx/...
|
|
23
|
+
*/
|
|
24
|
+
const ignoreLineRegex = /(eslint-disable(?:(?:-next)?-line)?\s*)@nrwl\/nx/g;
|
|
25
|
+
(0, devkit_1.visitNotIgnoredFiles)(tree, '.', (path) => {
|
|
26
|
+
if ((0, binary_extensions_1.isBinaryPath)(path)) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
let contents = tree.read(path).toString();
|
|
30
|
+
if (eslintFileNames.includes((0, path_1.basename)(path))) {
|
|
31
|
+
if (!contents.includes('@nrwl/nx')) {
|
|
29
32
|
return;
|
|
30
33
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
if (ignoreLineRegex.test(contents)) {
|
|
39
|
-
contents = contents.replace(ignoreLineRegex, '$1@nx');
|
|
40
|
-
}
|
|
41
|
-
tree.write(path, contents);
|
|
42
|
-
});
|
|
43
|
-
yield (0, devkit_1.formatFiles)(tree);
|
|
34
|
+
contents = contents.replace(new RegExp('@nrwl/nx', 'g'), '@nx');
|
|
35
|
+
}
|
|
36
|
+
if (ignoreLineRegex.test(contents)) {
|
|
37
|
+
contents = contents.replace(ignoreLineRegex, '$1@nx');
|
|
38
|
+
}
|
|
39
|
+
tree.write(path, contents);
|
|
44
40
|
});
|
|
41
|
+
await (0, devkit_1.formatFiles)(tree);
|
|
45
42
|
}
|
|
46
43
|
exports.default = replacePackage;
|
|
@@ -53,7 +53,6 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
|
|
|
53
53
|
},
|
|
54
54
|
],
|
|
55
55
|
create(context, [{ buildTargets, ignoredDependencies, ignoredFiles, checkMissingDependencies, checkObsoleteDependencies, checkVersionMismatches, includeTransitiveDependencies, },]) {
|
|
56
|
-
var _a;
|
|
57
56
|
if (!context.parserServices.isJSON) {
|
|
58
57
|
return {};
|
|
59
58
|
}
|
|
@@ -73,7 +72,7 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
|
|
|
73
72
|
return {};
|
|
74
73
|
}
|
|
75
74
|
// check if library has a build target
|
|
76
|
-
const buildTarget = buildTargets.find((t) =>
|
|
75
|
+
const buildTarget = buildTargets.find((t) => sourceProject.data.targets?.[t]);
|
|
77
76
|
if (!buildTarget) {
|
|
78
77
|
return {};
|
|
79
78
|
}
|
|
@@ -85,7 +84,7 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
|
|
|
85
84
|
});
|
|
86
85
|
const expectedDependencyNames = Object.keys(npmDependencies);
|
|
87
86
|
const projPackageJsonPath = (0, path_1.join)(devkit_1.workspaceRoot, sourceProject.data.root, 'package.json');
|
|
88
|
-
|
|
87
|
+
globalThis.projPackageJsonDeps ??= (0, package_json_utils_1.getProductionDependencies)((0, package_json_utils_1.getPackageJson)(projPackageJsonPath));
|
|
89
88
|
const projPackageJsonDeps = globalThis.projPackageJsonDeps;
|
|
90
89
|
const rootPackageJsonDeps = (0, package_json_utils_1.getAllDependencies)(rootPackageJson);
|
|
91
90
|
function validateMissingDependencies(node) {
|
|
@@ -82,17 +82,23 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
|
|
|
82
82
|
},
|
|
83
83
|
});
|
|
84
84
|
function normalizeOptions(sourceProject, options) {
|
|
85
|
-
const base =
|
|
85
|
+
const base = { ...DEFAULT_OPTIONS, ...options };
|
|
86
86
|
const pathPrefix = sourceProject.data.root !== '.' ? `${sourceProject.data.root}/` : '';
|
|
87
|
-
return
|
|
87
|
+
return {
|
|
88
|
+
...base,
|
|
89
|
+
executorsJson: base.executorsJson
|
|
88
90
|
? `${pathPrefix}${base.executorsJson}`
|
|
89
|
-
: undefined,
|
|
91
|
+
: undefined,
|
|
92
|
+
generatorsJson: base.generatorsJson
|
|
90
93
|
? `${pathPrefix}${base.generatorsJson}`
|
|
91
|
-
: undefined,
|
|
94
|
+
: undefined,
|
|
95
|
+
migrationsJson: base.migrationsJson
|
|
92
96
|
? `${pathPrefix}${base.migrationsJson}`
|
|
93
|
-
: undefined,
|
|
97
|
+
: undefined,
|
|
98
|
+
packageJson: base.packageJson
|
|
94
99
|
? `${pathPrefix}${base.packageJson}`
|
|
95
|
-
: undefined
|
|
100
|
+
: undefined,
|
|
101
|
+
};
|
|
96
102
|
}
|
|
97
103
|
function checkCollectionFileNode(baseNode, mode, context) {
|
|
98
104
|
const schematicsRootNode = baseNode.properties.find((x) => x.key.type === 'JSONLiteral' && x.key.value === 'schematics');
|
|
@@ -280,7 +286,7 @@ function validateImplemenationNode(implementationNode, key, context) {
|
|
|
280
286
|
});
|
|
281
287
|
}
|
|
282
288
|
}
|
|
283
|
-
catch
|
|
289
|
+
catch {
|
|
284
290
|
context.report({
|
|
285
291
|
messageId: 'unableToReadImplementationExports',
|
|
286
292
|
node: implementationNode.value,
|
|
@@ -294,13 +300,12 @@ function validateImplemenationNode(implementationNode, key, context) {
|
|
|
294
300
|
}
|
|
295
301
|
exports.validateImplemenationNode = validateImplemenationNode;
|
|
296
302
|
function validatePackageGroup(baseNode, context) {
|
|
297
|
-
|
|
298
|
-
const migrationsNode = (_a = baseNode.properties.find((x) => x.key.type === 'JSONLiteral' &&
|
|
303
|
+
const migrationsNode = baseNode.properties.find((x) => x.key.type === 'JSONLiteral' &&
|
|
299
304
|
x.value.type === 'JSONObjectExpression' &&
|
|
300
305
|
(x.key.value === 'nx-migrations' ||
|
|
301
306
|
x.key.value === 'ng-update' ||
|
|
302
|
-
x.key.value === 'migrations'))
|
|
303
|
-
const packageGroupNode = migrationsNode
|
|
307
|
+
x.key.value === 'migrations'))?.value;
|
|
308
|
+
const packageGroupNode = migrationsNode?.properties.find((x) => x.key.type === 'JSONLiteral' && x.key.value === 'packageGroup');
|
|
304
309
|
if (packageGroupNode) {
|
|
305
310
|
// Package group is defined as an array
|
|
306
311
|
if (packageGroupNode.value.type === 'JSONArrayExpression') {
|
|
@@ -310,7 +315,7 @@ function validatePackageGroup(baseNode, context) {
|
|
|
310
315
|
for (const member of members) {
|
|
311
316
|
const versionPropertyNode = member.properties.find((x) => x.key.type === 'JSONLiteral' && x.key.value === 'version');
|
|
312
317
|
const packageNode = member.properties.find((x) => x.key.type === 'JSONLiteral' && x.key.value === 'package');
|
|
313
|
-
const key =
|
|
318
|
+
const key = packageNode?.value?.value ?? 'unknown';
|
|
314
319
|
if (versionPropertyNode) {
|
|
315
320
|
if (!validateVersionJsonExpression(versionPropertyNode.value, context))
|
|
316
321
|
context.report({
|
|
@@ -348,11 +353,10 @@ function validatePackageGroup(baseNode, context) {
|
|
|
348
353
|
}
|
|
349
354
|
exports.validatePackageGroup = validatePackageGroup;
|
|
350
355
|
function validateVersionJsonExpression(node, context) {
|
|
351
|
-
var _a;
|
|
352
356
|
return (node &&
|
|
353
357
|
node.type === 'JSONLiteral' &&
|
|
354
358
|
typeof node.value === 'string' &&
|
|
355
359
|
((0, semver_1.valid)(node.value) ||
|
|
356
|
-
|
|
360
|
+
context.options[0]?.allowedVersionStrings.includes(node.value)));
|
|
357
361
|
}
|
|
358
362
|
exports.validateVersionJsonExpression = validateVersionJsonExpression;
|
package/src/utils/ast-utils.js
CHANGED
|
@@ -22,7 +22,6 @@ function tryReadBaseJson() {
|
|
|
22
22
|
* @returns
|
|
23
23
|
*/
|
|
24
24
|
function getBarrelEntryPointByImportScope(importScope) {
|
|
25
|
-
var _a;
|
|
26
25
|
const tryPaths = (paths, importScope) => {
|
|
27
26
|
// TODO check and warn that the entries of paths[importScope] have no wildcards; that'd be user misconfiguration
|
|
28
27
|
if (paths[importScope])
|
|
@@ -47,15 +46,14 @@ function getBarrelEntryPointByImportScope(importScope) {
|
|
|
47
46
|
return Array.from(result);
|
|
48
47
|
};
|
|
49
48
|
const tsConfigBase = tryReadBaseJson();
|
|
50
|
-
if (!
|
|
49
|
+
if (!tsConfigBase?.compilerOptions?.paths)
|
|
51
50
|
return [];
|
|
52
51
|
return tryPaths(tsConfigBase.compilerOptions.paths, importScope);
|
|
53
52
|
}
|
|
54
53
|
exports.getBarrelEntryPointByImportScope = getBarrelEntryPointByImportScope;
|
|
55
54
|
function getBarrelEntryPointProjectNode(projectNode) {
|
|
56
|
-
var _a;
|
|
57
55
|
const tsConfigBase = tryReadBaseJson();
|
|
58
|
-
if (
|
|
56
|
+
if (tsConfigBase?.compilerOptions?.paths) {
|
|
59
57
|
const potentialEntryPoints = Object.keys(tsConfigBase.compilerOptions.paths)
|
|
60
58
|
.filter((entry) => {
|
|
61
59
|
const sourceFolderPaths = tsConfigBase.compilerOptions.paths[entry];
|
|
@@ -81,7 +79,6 @@ function hasMemberExport(exportedMember, filePath) {
|
|
|
81
79
|
return ((0, js_1.findNodes)(sourceFile, ts.SyntaxKind.Identifier).filter((identifier) => identifier.text === exportedMember).length > 0);
|
|
82
80
|
}
|
|
83
81
|
function getRelativeImportPath(exportedMember, filePath, basePath) {
|
|
84
|
-
var _a, _b;
|
|
85
82
|
if ((0, fs_1.lstatSync)(filePath).isDirectory()) {
|
|
86
83
|
const file = (0, fs_1.readdirSync)(filePath).find((file) => /^index\.[jt]sx?$/.exec(file));
|
|
87
84
|
if (file) {
|
|
@@ -130,7 +127,7 @@ function getRelativeImportPath(exportedMember, filePath, basePath) {
|
|
|
130
127
|
hasExport = true;
|
|
131
128
|
break;
|
|
132
129
|
}
|
|
133
|
-
if ((
|
|
130
|
+
if ((0, type_utils_1.getModifiers)(parent)?.find((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword)) {
|
|
134
131
|
/**
|
|
135
132
|
* if we get to a function export declaration we need to verify whether the
|
|
136
133
|
* exported function is actually the member we are searching for. Otherwise
|
|
@@ -151,7 +148,7 @@ function getRelativeImportPath(exportedMember, filePath, basePath) {
|
|
|
151
148
|
* starting from `SOME_CONSTANT` identifier usages.
|
|
152
149
|
*/
|
|
153
150
|
if (parent.kind === ts.SyntaxKind.FunctionDeclaration) {
|
|
154
|
-
const parentName =
|
|
151
|
+
const parentName = parent.name?.text;
|
|
155
152
|
if (parentName === exportedMember) {
|
|
156
153
|
hasExport = true;
|
|
157
154
|
break;
|
|
@@ -4,11 +4,20 @@ exports.getPackageJson = exports.getProductionDependencies = exports.getAllDepen
|
|
|
4
4
|
const devkit_1 = require("@nx/devkit");
|
|
5
5
|
const fs_1 = require("fs");
|
|
6
6
|
function getAllDependencies(packageJson) {
|
|
7
|
-
return
|
|
7
|
+
return {
|
|
8
|
+
...packageJson.dependencies,
|
|
9
|
+
...packageJson.devDependencies,
|
|
10
|
+
...packageJson.peerDependencies,
|
|
11
|
+
...packageJson.optionalDependencies,
|
|
12
|
+
};
|
|
8
13
|
}
|
|
9
14
|
exports.getAllDependencies = getAllDependencies;
|
|
10
15
|
function getProductionDependencies(packageJson) {
|
|
11
|
-
return
|
|
16
|
+
return {
|
|
17
|
+
...packageJson.dependencies,
|
|
18
|
+
...packageJson.peerDependencies,
|
|
19
|
+
...packageJson.optionalDependencies,
|
|
20
|
+
};
|
|
12
21
|
}
|
|
13
22
|
exports.getProductionDependencies = getProductionDependencies;
|
|
14
23
|
function getPackageJson(path) {
|
|
@@ -30,7 +30,7 @@ function ensureGlobalProjectGraph(ruleName) {
|
|
|
30
30
|
global.projectFileMap = (0, nx_deps_cache_1.readProjectFileMapCache)().projectFileMap;
|
|
31
31
|
global.targetProjectLocator = new internal_1.TargetProjectLocator(projectGraph.nodes, projectGraph.externalNodes);
|
|
32
32
|
}
|
|
33
|
-
catch
|
|
33
|
+
catch {
|
|
34
34
|
const WARNING_PREFIX = `${chalk.reset.keyword('orange')('warning')}`;
|
|
35
35
|
const RULE_NAME_SUFFIX = `${chalk.reset.dim(`@nx/${ruleName}`)}`;
|
|
36
36
|
process.stdout
|
|
@@ -108,9 +108,8 @@ function isAbsoluteImportIntoAnotherProject(imp, workspaceLayout = { libsDir: 'l
|
|
|
108
108
|
}
|
|
109
109
|
exports.isAbsoluteImportIntoAnotherProject = isAbsoluteImportIntoAnotherProject;
|
|
110
110
|
function findProjectUsingImport(projectGraph, targetProjectLocator, filePath, imp) {
|
|
111
|
-
var _a;
|
|
112
111
|
const target = targetProjectLocator.findProjectWithImport(imp, filePath);
|
|
113
|
-
return projectGraph.nodes[target] ||
|
|
112
|
+
return projectGraph.nodes[target] || projectGraph.externalNodes?.[target];
|
|
114
113
|
}
|
|
115
114
|
exports.findProjectUsingImport = findProjectUsingImport;
|
|
116
115
|
function findConstraintsFor(depConstraints, sourceProject) {
|
|
@@ -158,11 +157,11 @@ function isConstraintBanningProject(externalProject, constraint, imp) {
|
|
|
158
157
|
return false;
|
|
159
158
|
}
|
|
160
159
|
/* Check if import is banned... */
|
|
161
|
-
if (bannedExternalImports
|
|
160
|
+
if (bannedExternalImports?.some((importDefinition) => mapGlobToRegExp(importDefinition).test(imp))) {
|
|
162
161
|
return true;
|
|
163
162
|
}
|
|
164
163
|
/* ... then check if there is a whitelist and if there is a match in the whitelist. */
|
|
165
|
-
return allowedExternalImports
|
|
164
|
+
return allowedExternalImports?.every((importDefinition) => !imp.startsWith(packageName) ||
|
|
166
165
|
!mapGlobToRegExp(importDefinition).test(imp));
|
|
167
166
|
}
|
|
168
167
|
function hasBannedImport(source, target, depConstraints, imp) {
|
|
@@ -322,7 +321,6 @@ function isAngularSecondaryEntrypoint(importExpr, filePath, projectRoot) {
|
|
|
322
321
|
}
|
|
323
322
|
exports.isAngularSecondaryEntrypoint = isAngularSecondaryEntrypoint;
|
|
324
323
|
function fileIsSecondaryEntryPoint(file, projectRoot) {
|
|
325
|
-
var _a, _b;
|
|
326
324
|
let parent = (0, devkit_1.joinPathFragments)(file, '../');
|
|
327
325
|
while (parent !== `${projectRoot}/`) {
|
|
328
326
|
// we need to find closest existing ng-package.json
|
|
@@ -330,7 +328,7 @@ function fileIsSecondaryEntryPoint(file, projectRoot) {
|
|
|
330
328
|
const ngPackageContent = (0, fileutils_1.readFileIfExisting)((0, devkit_1.joinPathFragments)(devkit_1.workspaceRoot, parent, 'ng-package.json'));
|
|
331
329
|
if (ngPackageContent) {
|
|
332
330
|
// https://github.com/ng-packagr/ng-packagr/blob/23c718d04eea85e015b4c261310b7bd0c39e5311/src/ng-package.schema.json#L54
|
|
333
|
-
const entryFile = (
|
|
331
|
+
const entryFile = (0, devkit_1.parseJson)(ngPackageContent)?.lib?.entryFile;
|
|
334
332
|
return entryFile && file === (0, devkit_1.joinPathFragments)(parent, entryFile);
|
|
335
333
|
}
|
|
336
334
|
parent = (0, devkit_1.joinPathFragments)(parent, '../');
|