@nx/eslint-plugin 20.8.0 → 20.8.2
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/eslint-plugin",
|
|
3
|
-
"version": "20.8.
|
|
3
|
+
"version": "20.8.2",
|
|
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": {
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
}
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@nx/devkit": "20.8.
|
|
38
|
-
"@nx/js": "20.8.
|
|
37
|
+
"@nx/devkit": "20.8.2",
|
|
38
|
+
"@nx/js": "20.8.2",
|
|
39
39
|
"@typescript-eslint/type-utils": "^8.0.0",
|
|
40
40
|
"@typescript-eslint/utils": "^8.0.0",
|
|
41
41
|
"chalk": "^4.1.0",
|
|
@@ -27,7 +27,7 @@ exports.default = typescript_eslint_1.default.config({
|
|
|
27
27
|
},
|
|
28
28
|
},
|
|
29
29
|
}, {
|
|
30
|
-
files: ['**/*.ts', '**/*.tsx',
|
|
30
|
+
files: ['**/*.ts', '**/*.tsx', '**/*.cts', '**/*.mts'],
|
|
31
31
|
rules: {
|
|
32
32
|
'@typescript-eslint/explicit-member-accessibility': 'off',
|
|
33
33
|
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
|
@@ -251,7 +251,7 @@ exports.default = utils_1.ESLintUtils.RuleCreator(() => `https://github.com/nrwl
|
|
|
251
251
|
!(0, graph_utils_1.circularPathHasPair)([sourceProject, targetProject], expandedIgnoreCircularDependencies)) {
|
|
252
252
|
if (!allowCircularSelfDependency &&
|
|
253
253
|
!(0, fileutils_1.isRelativePath)(imp) &&
|
|
254
|
-
!(0, runtime_lint_utils_1.
|
|
254
|
+
!(0, runtime_lint_utils_1.belongsToDifferentEntryPoint)(imp, sourceFilePath, sourceProject.data.root)) {
|
|
255
255
|
context.report({
|
|
256
256
|
node,
|
|
257
257
|
messageId: 'noSelfCircularDependencies',
|
|
@@ -391,7 +391,7 @@ exports.default = utils_1.ESLintUtils.RuleCreator(() => `https://github.com/nrwl
|
|
|
391
391
|
}
|
|
392
392
|
// if we import a library using loadChildren, we should not import it using es6imports
|
|
393
393
|
if (!checkDynamicDependenciesExceptions.some((a) => (0, runtime_lint_utils_1.matchImportWithWildcard)(a, imp)) &&
|
|
394
|
-
(0, runtime_lint_utils_1.hasStaticImportOfDynamicResource)(node, projectGraph, sourceProject.name, targetProject.name)) {
|
|
394
|
+
(0, runtime_lint_utils_1.hasStaticImportOfDynamicResource)(node, projectGraph, sourceProject.name, targetProject.name, imp, sourceFilePath)) {
|
|
395
395
|
const filesWithLazyImports = (0, graph_utils_1.findFilesWithDynamicImports)(projectFileMap, sourceProject.name, targetProject.name);
|
|
396
396
|
context.report({
|
|
397
397
|
data: {
|
|
@@ -40,7 +40,7 @@ export declare function isAbsoluteImportIntoAnotherProject(imp: string, workspac
|
|
|
40
40
|
}): boolean;
|
|
41
41
|
export declare function findProjectUsingImport(projectGraph: ProjectGraph, targetProjectLocator: TargetProjectLocator, filePath: string, imp: string): ProjectGraphProjectNode | ProjectGraphExternalNode;
|
|
42
42
|
export declare function findConstraintsFor(depConstraints: DepConstraint[], sourceProject: ProjectGraphProjectNode): DepConstraint[];
|
|
43
|
-
export declare function hasStaticImportOfDynamicResource(node: TSESTree.ImportDeclaration | TSESTree.ImportExpression | TSESTree.ExportAllDeclaration | TSESTree.ExportNamedDeclaration, graph: ProjectGraph, sourceProjectName: string, targetProjectName: string): boolean;
|
|
43
|
+
export declare function hasStaticImportOfDynamicResource(node: TSESTree.ImportDeclaration | TSESTree.ImportExpression | TSESTree.ExportAllDeclaration | TSESTree.ExportNamedDeclaration, graph: ProjectGraph, sourceProjectName: string, targetProjectName: string, importExpr: string, filePath: string): boolean;
|
|
44
44
|
export declare function getSourceFilePath(sourceFileName: string, projectPath: string): string;
|
|
45
45
|
export declare function hasBannedImport(source: ProjectGraphProjectNode, target: ProjectGraphExternalNode, depConstraints: DepConstraint[], imp: string): DepConstraint | undefined;
|
|
46
46
|
/**
|
|
@@ -80,7 +80,15 @@ export declare function groupImports(importsToRemap: {
|
|
|
80
80
|
/**
|
|
81
81
|
* Checks if source file belongs to a secondary entry point different than the import one
|
|
82
82
|
*/
|
|
83
|
-
export declare function
|
|
83
|
+
export declare function belongsToDifferentEntryPoint(importExpr: string, filePath: string, projectRoot: string): boolean;
|
|
84
|
+
export declare function getSecondaryEntryPointPath(importExpr: string, filePath: string, projectRoot: string): string | undefined;
|
|
85
|
+
export declare function parseExports(exports: string | null | Record<string, any>, projectRoot: string, entryPaths: Array<{
|
|
86
|
+
path: string;
|
|
87
|
+
file: string;
|
|
88
|
+
}>, basePath?: string): Array<{
|
|
89
|
+
path: string;
|
|
90
|
+
file: string;
|
|
91
|
+
}>;
|
|
84
92
|
/**
|
|
85
93
|
* Returns true if the given project contains MFE config with "exposes:" section
|
|
86
94
|
*/
|
|
@@ -20,7 +20,9 @@ exports.isDirectDependency = isDirectDependency;
|
|
|
20
20
|
exports.hasBuildExecutor = hasBuildExecutor;
|
|
21
21
|
exports.isTerminalRun = isTerminalRun;
|
|
22
22
|
exports.groupImports = groupImports;
|
|
23
|
-
exports.
|
|
23
|
+
exports.belongsToDifferentEntryPoint = belongsToDifferentEntryPoint;
|
|
24
|
+
exports.getSecondaryEntryPointPath = getSecondaryEntryPointPath;
|
|
25
|
+
exports.parseExports = parseExports;
|
|
24
26
|
exports.appIsMFERemote = appIsMFERemote;
|
|
25
27
|
exports.getParserServices = getParserServices;
|
|
26
28
|
const tslib_1 = require("tslib");
|
|
@@ -135,14 +137,15 @@ function findConstraintsFor(depConstraints, sourceProject) {
|
|
|
135
137
|
}
|
|
136
138
|
});
|
|
137
139
|
}
|
|
138
|
-
function hasStaticImportOfDynamicResource(node, graph, sourceProjectName, targetProjectName) {
|
|
140
|
+
function hasStaticImportOfDynamicResource(node, graph, sourceProjectName, targetProjectName, importExpr, filePath) {
|
|
139
141
|
if (node.type !== utils_1.AST_NODE_TYPES.ImportDeclaration ||
|
|
140
142
|
node.importKind === 'type') {
|
|
141
143
|
return false;
|
|
142
144
|
}
|
|
143
|
-
return
|
|
145
|
+
return (hasDynamicImport(graph, sourceProjectName, targetProjectName, []) &&
|
|
146
|
+
!getSecondaryEntryPointPath(importExpr, filePath, graph.nodes[targetProjectName].data.root));
|
|
144
147
|
}
|
|
145
|
-
function
|
|
148
|
+
function hasDynamicImport(graph, sourceProjectName, targetProjectName, visited) {
|
|
146
149
|
if (visited.indexOf(sourceProjectName) > -1) {
|
|
147
150
|
return false;
|
|
148
151
|
}
|
|
@@ -153,7 +156,7 @@ function onlyLoadChildren(graph, sourceProjectName, targetProjectName, visited)
|
|
|
153
156
|
if (d.target === targetProjectName) {
|
|
154
157
|
return true;
|
|
155
158
|
}
|
|
156
|
-
return
|
|
159
|
+
return hasDynamicImport(graph, d.target, targetProjectName, [
|
|
157
160
|
...visited,
|
|
158
161
|
sourceProjectName,
|
|
159
162
|
]);
|
|
@@ -325,21 +328,34 @@ function groupImports(importsToRemap) {
|
|
|
325
328
|
/**
|
|
326
329
|
* Checks if source file belongs to a secondary entry point different than the import one
|
|
327
330
|
*/
|
|
328
|
-
function
|
|
331
|
+
function belongsToDifferentEntryPoint(importExpr, filePath, projectRoot) {
|
|
332
|
+
const importEntryPoint = getSecondaryEntryPointPath(importExpr, filePath, projectRoot);
|
|
333
|
+
const srcEntryPoint = getEntryPoint(filePath, projectRoot);
|
|
334
|
+
// check if the entry point of import expression is different than the source file's entry point
|
|
335
|
+
return importEntryPoint !== srcEntryPoint;
|
|
336
|
+
}
|
|
337
|
+
function getSecondaryEntryPointPath(importExpr, filePath, projectRoot) {
|
|
329
338
|
const resolvedImportFile = (0, internal_1.resolveModuleByImport)(importExpr, filePath, // not strictly necessary, but speeds up resolution
|
|
330
339
|
path.join(devkit_1.workspaceRoot, (0, js_1.getRootTsConfigFileName)()));
|
|
331
340
|
if (!resolvedImportFile) {
|
|
332
|
-
return
|
|
341
|
+
return undefined;
|
|
333
342
|
}
|
|
334
|
-
const
|
|
335
|
-
|
|
336
|
-
// check if the entry point of import expression is different than the source file's entry point
|
|
337
|
-
return importEntryPoint !== srcEntryPoint;
|
|
343
|
+
const entryPoint = getEntryPoint(resolvedImportFile, projectRoot);
|
|
344
|
+
return entryPoint;
|
|
338
345
|
}
|
|
339
|
-
function
|
|
346
|
+
function getEntryPoint(file, projectRoot) {
|
|
347
|
+
const packageEntryPoints = getPackageEntryPoints(projectRoot);
|
|
348
|
+
const fileEntryPoint = packageEntryPoints.find((entry) => entry.file === file);
|
|
349
|
+
if (fileEntryPoint) {
|
|
350
|
+
return fileEntryPoint.file;
|
|
351
|
+
}
|
|
340
352
|
let parent = (0, devkit_1.joinPathFragments)(file, '../');
|
|
341
353
|
while (parent !== `${projectRoot}/`) {
|
|
342
|
-
|
|
354
|
+
const entryPoint = packageEntryPoints.find((entry) => entry.path === parent);
|
|
355
|
+
if (entryPoint) {
|
|
356
|
+
return entryPoint.file;
|
|
357
|
+
}
|
|
358
|
+
// for Angular we need to find closest existing ng-package.json
|
|
343
359
|
// in order to determine if the file matches the secondary entry point
|
|
344
360
|
const ngPackageContent = (0, fileutils_1.readFileIfExisting)(path.join(devkit_1.workspaceRoot, parent, 'ng-package.json'));
|
|
345
361
|
if (ngPackageContent) {
|
|
@@ -351,6 +367,45 @@ function getAngularEntryPoint(file, projectRoot) {
|
|
|
351
367
|
}
|
|
352
368
|
return undefined;
|
|
353
369
|
}
|
|
370
|
+
function getPackageEntryPoints(projectRoot) {
|
|
371
|
+
const packageContent = (0, fileutils_1.readFileIfExisting)(path.join(devkit_1.workspaceRoot, projectRoot, 'package.json'));
|
|
372
|
+
if (!packageContent) {
|
|
373
|
+
return [];
|
|
374
|
+
}
|
|
375
|
+
const exports = (0, devkit_1.parseJson)(packageContent).exports;
|
|
376
|
+
if (!exports) {
|
|
377
|
+
return [];
|
|
378
|
+
}
|
|
379
|
+
const entryPaths = [];
|
|
380
|
+
parseExports(exports, projectRoot, entryPaths);
|
|
381
|
+
return entryPaths;
|
|
382
|
+
}
|
|
383
|
+
function parseExports(exports, projectRoot, entryPaths, basePath = '.') {
|
|
384
|
+
if (exports === null) {
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
if (typeof exports === 'string') {
|
|
388
|
+
if (basePath === '.') {
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
else {
|
|
392
|
+
entryPaths.push({
|
|
393
|
+
path: (0, devkit_1.joinPathFragments)(projectRoot, basePath),
|
|
394
|
+
file: (0, devkit_1.joinPathFragments)(projectRoot, exports),
|
|
395
|
+
});
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
// parse conditional exports
|
|
400
|
+
if (exports.import || exports.require || exports.default || exports.node) {
|
|
401
|
+
parseExports(exports.default || exports.import || exports.require || exports.node, projectRoot, entryPaths, basePath);
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
// parse general nested exports
|
|
405
|
+
for (const [key, value] of Object.entries(exports)) {
|
|
406
|
+
parseExports(value, projectRoot, entryPaths, key);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
354
409
|
/**
|
|
355
410
|
* Returns true if the given project contains MFE config with "exposes:" section
|
|
356
411
|
*/
|