dependency-cruiser 11.7.0 → 11.7.1
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 +10 -8
- package/src/cli/format.js +6 -0
- package/src/enrich/index.js +13 -0
- package/src/extract/ast-extractors/swc-dependency-visitor.js +4 -0
- package/src/extract/gather-initial-sources.js +1 -1
- package/src/extract/get-dependencies.js +6 -6
- package/src/extract/index.js +10 -0
- package/src/extract/parse/to-javascript-ast.js +8 -2
- package/src/extract/parse/to-swc-ast.js +2 -0
- package/src/extract/parse/to-typescript-ast.js +1 -0
- package/src/extract/resolve/determine-dependency-types.js +25 -2
- package/src/extract/resolve/index.js +11 -16
- package/src/extract/transpile/meta.d.ts +22 -0
- package/src/extract/transpile/meta.js +1 -1
- package/src/extract/utl/path-to-posix.js +2 -2
- package/src/graph-utl/consolidate-module-dependencies.js +2 -2
- package/src/graph-utl/rule-set.js +12 -7
- package/src/main/files-and-dirs/normalize.js +10 -1
- package/src/main/options/defaults.js +2 -1
- package/src/main/options/normalize.js +22 -6
- package/src/main/options/validate.js +13 -2
- package/src/main/report-wrap.js +6 -1
- package/src/main/resolve-options/normalize.js +16 -2
- package/src/main/rule-set/normalize.js +6 -6
- package/src/main/rule-set/validate.js +5 -1
- package/src/main/utl/normalize-re-properties.js +8 -6
- package/src/meta.js +1 -1
- package/src/report/anon/anonymize-path.js +1 -1
- package/src/report/anon/index.js +67 -10
- package/src/report/csv.js +3 -3
- package/src/report/dot/index.js +1 -7
- package/src/report/error-html/index.js +2 -2
- package/src/report/error.js +2 -2
- package/src/report/html/index.js +6 -8
- package/src/report/identity.js +2 -3
- package/src/report/index.js +2 -2
- package/src/report/json.js +2 -3
- package/src/report/metrics.js +0 -4
- package/src/report/teamcity.js +2 -3
- package/src/report/text.js +2 -6
- package/src/utl/array-util.js +2 -1
- package/src/utl/regex-util.js +7 -3
- package/src/validate/index.d.ts +60 -0
- package/src/validate/index.js +11 -22
- package/src/validate/match-dependency-rule.js +11 -1
- package/src/validate/match-folder-dependency-rule.js +11 -1
- package/src/validate/match-module-rule.js +62 -10
- package/src/validate/rule-classifiers.js +3 -3
- package/types/cruise-result.d.ts +42 -33
- package/types/dependency-cruiser.d.ts +4 -2
- package/types/resolve-options.d.ts +15 -1
- package/types/rule-set.d.ts +5 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dependency-cruiser",
|
|
3
|
-
"version": "11.7.
|
|
3
|
+
"version": "11.7.1",
|
|
4
4
|
"description": "Validate and visualize dependencies. With your rules. JavaScript, TypeScript, CoffeeScript. ES6, CommonJS, AMD.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"static analysis",
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
"lint:prettier": "prettier --loglevel warn --check \"src/**/*.js\" \"configs/**/*.js\" \"tools/**/*.mjs\" \"bin/*\" \"types/*.d.ts\" \"test/**/*.spec.{cjs,js}\" \"test/**/*.{spec,utl}.mjs\"",
|
|
99
99
|
"lint:prettier:fix": "prettier --loglevel warn --write \"src/**/*.js\" \"configs/**/*.js\" \"tools/**/*.mjs\" \"bin/*\" \"types/*.d.ts\" \"test/**/*.spec.{cjs,js}\" \"test/**/*.{spec,utl}.mjs\"",
|
|
100
100
|
"lint:types": "npm-run-all lint:types:tsc lint:types:lint",
|
|
101
|
-
"lint:types:tsc": "tsc --
|
|
101
|
+
"lint:types:tsc": "tsc --project types/tsconfig.json",
|
|
102
102
|
"lint:types:lint": "eslint --no-ignore --config types/.eslintrc.json types/*.d.ts",
|
|
103
103
|
"lint:types:fix": "eslint --no-ignore --config types/.eslintrc.json --fix types/*.d.ts",
|
|
104
104
|
"scm:push": "run-p --aggregate-output scm:push:*",
|
|
@@ -163,18 +163,20 @@
|
|
|
163
163
|
"@babel/core": "7.17.10",
|
|
164
164
|
"@babel/plugin-transform-modules-commonjs": "7.17.9",
|
|
165
165
|
"@babel/preset-typescript": "7.16.7",
|
|
166
|
-
"@swc/core": "1.2.
|
|
167
|
-
"@
|
|
168
|
-
"@
|
|
166
|
+
"@swc/core": "1.2.183",
|
|
167
|
+
"@types/lodash": "4.14.182",
|
|
168
|
+
"@types/node": "17.0.33",
|
|
169
|
+
"@typescript-eslint/eslint-plugin": "5.23.0",
|
|
170
|
+
"@typescript-eslint/parser": "5.23.0",
|
|
169
171
|
"@vue/compiler-sfc": "3.2.33",
|
|
170
172
|
"c8": "7.11.2",
|
|
171
173
|
"chai": "4.3.6",
|
|
172
174
|
"chai-json-schema": "1.5.1",
|
|
173
175
|
"coffeescript": "2.7.0",
|
|
174
|
-
"eslint": "^8.
|
|
176
|
+
"eslint": "^8.15.0",
|
|
175
177
|
"eslint-config-moving-meadow": "3.0.0",
|
|
176
178
|
"eslint-config-prettier": "8.5.0",
|
|
177
|
-
"eslint-plugin-budapestian": "3.0.
|
|
179
|
+
"eslint-plugin-budapestian": "3.0.2",
|
|
178
180
|
"eslint-plugin-import": "2.26.0",
|
|
179
181
|
"eslint-plugin-mocha": "^9.0.0",
|
|
180
182
|
"eslint-plugin-node": "11.1.0",
|
|
@@ -206,7 +208,7 @@
|
|
|
206
208
|
{
|
|
207
209
|
"package": "eslint-plugin-mocha",
|
|
208
210
|
"policy": "wanted",
|
|
209
|
-
"because": "version 10
|
|
211
|
+
"because": "version 10 bumps into https://github.com/lo1tuma/eslint-plugin-mocha/issues/322"
|
|
210
212
|
},
|
|
211
213
|
{
|
|
212
214
|
"package": "figures",
|
package/src/cli/format.js
CHANGED
|
@@ -15,6 +15,12 @@ const KNOWN_FMT_OPTIONS = [
|
|
|
15
15
|
"version",
|
|
16
16
|
];
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
*
|
|
20
|
+
* @param {string} pResultFile the name of the file with cruise results
|
|
21
|
+
* @param {import("../../types/dependency-cruiser").IFormatOptions} pOptions
|
|
22
|
+
* @returns {Number} an exitCode
|
|
23
|
+
*/
|
|
18
24
|
module.exports = async (pResultFile, pOptions) => {
|
|
19
25
|
const lOptions = normalizeOptions(pOptions, KNOWN_FMT_OPTIONS);
|
|
20
26
|
|
package/src/enrich/index.js
CHANGED
|
@@ -3,6 +3,19 @@ const aggregateToFolders = require("./derive/folders");
|
|
|
3
3
|
const summarize = require("./summarize");
|
|
4
4
|
const clearCaches = require("./clear-caches");
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Enriches the passed modules with things like cycle detection, validations,
|
|
8
|
+
* metrics, folders and reachability & dependents analysis.
|
|
9
|
+
*
|
|
10
|
+
* Also adds a summary to the cruise result with common stats and the options
|
|
11
|
+
* used in the cruise, so consumers of the cruise result (reporters, depcruise-fmt,
|
|
12
|
+
* caching) can use that.
|
|
13
|
+
*
|
|
14
|
+
* @param {import("../../types/dependency-cruiser").IModule[]} pModules
|
|
15
|
+
* @param {import("../../types/dependency-cruiser").ICruiseOptions} pOptions
|
|
16
|
+
* @param {string[]} pFileAndDirectoryArray
|
|
17
|
+
* @returns {import("../../types/dependency-cruiser").ICruiseResult}
|
|
18
|
+
*/
|
|
6
19
|
module.exports = function enrich(pModules, pOptions, pFileAndDirectoryArray) {
|
|
7
20
|
clearCaches();
|
|
8
21
|
const lModules = enrichModules(pModules, pOptions);
|
|
@@ -148,7 +148,9 @@ if (VisitorModule) {
|
|
|
148
148
|
visitExportAllDeclration(pNode) {
|
|
149
149
|
this.pushImportExportSource(pNode);
|
|
150
150
|
/* c8 ignore start */
|
|
151
|
+
// @ts-ignore
|
|
151
152
|
if (super.visitExportAllDeclration) {
|
|
153
|
+
// @ts-ignore
|
|
152
154
|
return super.visitExportAllDeclration(pNode);
|
|
153
155
|
} else {
|
|
154
156
|
/* c8 ignore stop */
|
|
@@ -166,7 +168,9 @@ if (VisitorModule) {
|
|
|
166
168
|
visitExportNamedDeclration(pNode) {
|
|
167
169
|
this.pushImportExportSource(pNode);
|
|
168
170
|
/* c8 ignore start */
|
|
171
|
+
// @ts-ignore
|
|
169
172
|
if (super.visitExportNamedDeclration) {
|
|
173
|
+
// @ts-ignore
|
|
170
174
|
return super.visitExportNamedDeclration(pNode);
|
|
171
175
|
} else {
|
|
172
176
|
/* c8 ignore stop */
|
|
@@ -84,7 +84,7 @@ function gatherScannableFilesFromDirectory(pDirectoryName, pOptions) {
|
|
|
84
84
|
*
|
|
85
85
|
* @param {string[]} pFileAndDirectoryArray globs and/ or paths to files or
|
|
86
86
|
* directories to be gathered
|
|
87
|
-
* @param {import('../../types/
|
|
87
|
+
* @param {import('../../types/dependency-cruiser').ICruiseOptions} pOptions options that
|
|
88
88
|
* influence what needs to be gathered/ scanned
|
|
89
89
|
* notably useful attributes:
|
|
90
90
|
* - exclude - regexp of what to exclude
|
|
@@ -108,13 +108,13 @@ function extractWithTsc(
|
|
|
108
108
|
|
|
109
109
|
/**
|
|
110
110
|
*
|
|
111
|
-
* @param {import('../../types/
|
|
111
|
+
* @param {import('../../types/dependency-cruiser').ICruiseOptions} pCruiseOptions
|
|
112
112
|
* @param {string} pFileName
|
|
113
113
|
* @param {any} pTranspileOptions
|
|
114
|
-
* @returns {
|
|
114
|
+
* @returns {import('../../types/cruise-result').IDependency[]}
|
|
115
115
|
*/
|
|
116
116
|
function extractDependencies(pCruiseOptions, pFileName, pTranspileOptions) {
|
|
117
|
-
/** @type
|
|
117
|
+
/** @type import('../../types/cruise-result').IDependency[] */
|
|
118
118
|
let lDependencies = [];
|
|
119
119
|
|
|
120
120
|
if (!pCruiseOptions.extraExtensionsToScan.includes(path.extname(pFileName))) {
|
|
@@ -208,9 +208,9 @@ function compareDeps(pLeft, pRight) {
|
|
|
208
208
|
*
|
|
209
209
|
*
|
|
210
210
|
* @param {string} pFileName path to the file
|
|
211
|
-
* @param {import("
|
|
212
|
-
* @param {import("../../types/
|
|
213
|
-
* @param {
|
|
211
|
+
* @param {import("../../types/dependency-cruiser").ICruiseOptions} pCruiseOptions cruise options
|
|
212
|
+
* @param {import("../../types/dependency-cruiser").IResolveOptions} pResolveOptions webpack 'enhanced-resolve' options
|
|
213
|
+
* @param {import("../../types/dependency-cruiser").ITranspileOptions} pTranspileOptions an object with tsconfig ('typescript project') options
|
|
214
214
|
* ('flattened' so there's no need for file access on any
|
|
215
215
|
* 'extends' option in there)
|
|
216
216
|
* @return {import("../../types/dependency-cruiser").IDependency[]} an array of dependency objects (see above)
|
package/src/extract/index.js
CHANGED
|
@@ -136,6 +136,16 @@ function filterExcludedDynamicDependencies(pModule, pExclude) {
|
|
|
136
136
|
};
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Recursively runs through the modules matching the pFileDirectoryArray and
|
|
141
|
+
* returns an array of all the modules it finds that way.
|
|
142
|
+
*
|
|
143
|
+
* @param {string[]} pFileDirectoryArray
|
|
144
|
+
* @param {import("../../types/dependency-cruiser").ICruiseOptions} pCruiseOptions
|
|
145
|
+
* @param {import("../../types/dependency-cruiser").IResolveOptions} pResolveOptions
|
|
146
|
+
* @param {import("../../types/dependency-cruiser").ITranspileOptions} pTranspileOptions
|
|
147
|
+
* @returns {Partial<import("../../types/dependency-cruiser").IModule[]>}
|
|
148
|
+
*/
|
|
139
149
|
module.exports = function extract(
|
|
140
150
|
pFileDirectoryArray,
|
|
141
151
|
pCruiseOptions,
|
|
@@ -7,6 +7,7 @@ const _memoize = require("lodash/memoize");
|
|
|
7
7
|
const transpile = require("../transpile");
|
|
8
8
|
const getExtension = require("../utl/get-extension");
|
|
9
9
|
|
|
10
|
+
/** @type acorn.Options */
|
|
10
11
|
const ACORN_OPTIONS = {
|
|
11
12
|
sourceType: "module",
|
|
12
13
|
ecmaVersion: 11,
|
|
@@ -33,6 +34,11 @@ function getASTFromSource(pFileRecord, pTranspileOptions) {
|
|
|
33
34
|
if (needsJSXTreatment(pFileRecord, pTranspileOptions)) {
|
|
34
35
|
return acornJsxParser.parse(lJavaScriptSource, {
|
|
35
36
|
...ACORN_OPTIONS,
|
|
37
|
+
// @ts-ignore
|
|
38
|
+
// acornJsxParser.parse takes an acorn.Options which doesn't include
|
|
39
|
+
// allowNamespacedObjects. acornJsx.Options doesn't include sourceType
|
|
40
|
+
// though, so a bit rock < this code > hard place hence ignore it
|
|
41
|
+
// type wise
|
|
36
42
|
allowNamespacedObjects: true,
|
|
37
43
|
});
|
|
38
44
|
}
|
|
@@ -55,7 +61,7 @@ function getASTFromSource(pFileRecord, pTranspileOptions) {
|
|
|
55
61
|
* @param {string} pFileName path to the file to be parsed
|
|
56
62
|
* @param {any} pTranspileOptions options for the transpiler(s) - a tsconfig or
|
|
57
63
|
* a babel config
|
|
58
|
-
* @returns {
|
|
64
|
+
* @returns {acorn.Node} the abstract syntax tree
|
|
59
65
|
*/
|
|
60
66
|
function getAST(pFileName, pTranspileOptions) {
|
|
61
67
|
return getASTFromSource(
|
|
@@ -87,7 +93,7 @@ module.exports = {
|
|
|
87
93
|
*
|
|
88
94
|
* @param {string} pFileName - the name of the file to compile
|
|
89
95
|
* @param {any} pTranspileOptions - options for the transpiler(s) - typically a tsconfig or a babel config
|
|
90
|
-
* @return {
|
|
96
|
+
* @return {acorn.Node} - a (javascript) AST
|
|
91
97
|
*/
|
|
92
98
|
getASTCached,
|
|
93
99
|
|
|
@@ -22,6 +22,7 @@ function getASTFromSource(pSource) {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
function getAST(pFileName) {
|
|
25
|
+
/** @type {import('@swc/core')} swc */
|
|
25
26
|
return swc.parseFileSync(pFileName, SWC_PARSE_OPTIONS);
|
|
26
27
|
}
|
|
27
28
|
|
|
@@ -38,6 +39,7 @@ module.exports = {
|
|
|
38
39
|
* @return {boolean} - true if the swc compiler is available,
|
|
39
40
|
* false in all other cases
|
|
40
41
|
*/
|
|
42
|
+
// @ts-ignore
|
|
41
43
|
isAvailable: () => swc !== false,
|
|
42
44
|
|
|
43
45
|
/**
|
|
@@ -47,6 +47,7 @@ function determineManifestDependencyTypes(
|
|
|
47
47
|
pPackageDependencies,
|
|
48
48
|
pResolverModulePaths
|
|
49
49
|
) {
|
|
50
|
+
/** @type {import("../../../types/shared-types").DependencyType[]} */
|
|
50
51
|
let lReturnValue = ["npm-unknown"];
|
|
51
52
|
|
|
52
53
|
if (Boolean(pPackageDependencies)) {
|
|
@@ -90,12 +91,21 @@ function dependencyIsBundled(pModule, pPackageDeps) {
|
|
|
90
91
|
return lReturnValue;
|
|
91
92
|
}
|
|
92
93
|
|
|
94
|
+
/**
|
|
95
|
+
*
|
|
96
|
+
* @param {string} pModuleName
|
|
97
|
+
* @param {string} pPackageDeps
|
|
98
|
+
* @param {string} pFileDirectory
|
|
99
|
+
* @param {import("../../../types/dependency-cruiser").IResolveOptions} pResolveOptions
|
|
100
|
+
* @returns {import("../../../types/shared-types").DependencyType[]}
|
|
101
|
+
*/
|
|
93
102
|
function determineNodeModuleDependencyTypes(
|
|
94
103
|
pModuleName,
|
|
95
104
|
pPackageDeps,
|
|
96
105
|
pFileDirectory,
|
|
97
106
|
pResolveOptions
|
|
98
107
|
) {
|
|
108
|
+
/** @type {import("../../../types/shared-types").DependencyType[]} */
|
|
99
109
|
let lReturnValue = determineManifestDependencyTypes(
|
|
100
110
|
externalModuleHelpers.getPackageRoot(pModuleName),
|
|
101
111
|
pPackageDeps,
|
|
@@ -117,17 +127,30 @@ function determineNodeModuleDependencyTypes(
|
|
|
117
127
|
return lReturnValue;
|
|
118
128
|
}
|
|
119
129
|
|
|
130
|
+
/**
|
|
131
|
+
*
|
|
132
|
+
* @param {import("../../../types/cruise-result").IDependency} pDependency
|
|
133
|
+
* @param {string} pModuleName
|
|
134
|
+
* @param {any} pPackageDeps
|
|
135
|
+
* @param {string} pFileDirectory
|
|
136
|
+
* @param {import("../../../types/dependency-cruiser").IResolveOptions} pResolveOptions
|
|
137
|
+
* @param {string} pBaseDirectory
|
|
138
|
+
* @returns {import("../../../types/shared-types").DependencyType[]}
|
|
139
|
+
*/
|
|
120
140
|
function determineExternalModuleDependencyTypes(
|
|
121
|
-
|
|
141
|
+
pDependency,
|
|
122
142
|
pModuleName,
|
|
123
143
|
pPackageDeps,
|
|
124
144
|
pFileDirectory,
|
|
125
145
|
pResolveOptions,
|
|
126
146
|
pBaseDirectory
|
|
127
147
|
) {
|
|
148
|
+
/** @type {import("../../../types/shared-types").DependencyType[]} */
|
|
128
149
|
let lReturnValue = [];
|
|
129
150
|
|
|
130
|
-
if (
|
|
151
|
+
if (
|
|
152
|
+
isExternalModule(pDependency.resolved, ["node_modules"], pBaseDirectory)
|
|
153
|
+
) {
|
|
131
154
|
lReturnValue = determineNodeModuleDependencyTypes(
|
|
132
155
|
pModuleName,
|
|
133
156
|
pPackageDeps,
|
|
@@ -10,6 +10,14 @@ const resolveHelpers = require("./resolve-helpers");
|
|
|
10
10
|
const determineDependencyTypes = require("./determine-dependency-types");
|
|
11
11
|
const getManifest = require("./get-manifest");
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
*
|
|
15
|
+
* @param {import("../../../types/dependency-cruiser").IModule} pModule
|
|
16
|
+
* @param {string} pBaseDirectory
|
|
17
|
+
* @param {string} pFileDirectory
|
|
18
|
+
* @param {import("../../../types/dependency-cruiser").IResolveOptions} pResolveOptions
|
|
19
|
+
* @returns {any}
|
|
20
|
+
*/
|
|
13
21
|
function resolveModule(
|
|
14
22
|
pModule,
|
|
15
23
|
pBaseDirectory,
|
|
@@ -33,8 +41,7 @@ function resolveModule(
|
|
|
33
41
|
lReturnValue = resolveAMD(
|
|
34
42
|
lStrippedModuleName,
|
|
35
43
|
pBaseDirectory,
|
|
36
|
-
pFileDirectory
|
|
37
|
-
pResolveOptions
|
|
44
|
+
pFileDirectory
|
|
38
45
|
);
|
|
39
46
|
}
|
|
40
47
|
return lReturnValue;
|
|
@@ -119,20 +126,8 @@ function resolveWithRetry(
|
|
|
119
126
|
* for resolved files.
|
|
120
127
|
* @param {string} pFileDirectory the directory of the file the dependency was
|
|
121
128
|
* detected in
|
|
122
|
-
* @param {import(../../../types/resolve-options").IResolveOptions} pResolveOptions
|
|
123
|
-
* @return {Partial <import("../../../types/cruise-result").IDependency>}
|
|
124
|
-
* - resolved: a string representing the pDependency
|
|
125
|
-
* resolved to a file on disk (or the pDependency
|
|
126
|
-
* name itself when it could not be resolved)
|
|
127
|
-
* - coreModule: true the dependency is a (node)
|
|
128
|
-
* core module - false in all other cases
|
|
129
|
-
* (deprecated over dependencyType === 'core')
|
|
130
|
-
* - followable: true when it is worthwhile to
|
|
131
|
-
* follow dependencies of this dependency (
|
|
132
|
-
* typically not true for .json)
|
|
133
|
-
* - couldNotResolve: true if it was not possible
|
|
134
|
-
* to resolve the dependency to a file on disk
|
|
135
|
-
* - dependencyTypes: an array of dependencyTypes
|
|
129
|
+
* @param {import("../../../types/resolve-options").IResolveOptions} pResolveOptions
|
|
130
|
+
* @return {Partial <import("../../../types/cruise-result").IDependency>}
|
|
136
131
|
*
|
|
137
132
|
*/
|
|
138
133
|
// eslint-disable-next-line max-lines-per-function
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface ITranspilerWrapper {
|
|
2
|
+
isAvailable: () => boolean;
|
|
3
|
+
transpile: (
|
|
4
|
+
pSource: string,
|
|
5
|
+
pFileName?: string,
|
|
6
|
+
pTranspilerOptions?: any
|
|
7
|
+
) => string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function getWrapper(pExtension, pTranspileOptions): ITranspilerWrapper;
|
|
11
|
+
|
|
12
|
+
export const scannableExtensions: string[];
|
|
13
|
+
|
|
14
|
+
export const allExtensions: string[];
|
|
15
|
+
|
|
16
|
+
export interface IAvailableTranspiler {
|
|
17
|
+
name: string;
|
|
18
|
+
version: string;
|
|
19
|
+
available: boolean;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function getAvailableTranspilers(): IAvailableTranspiler[];
|
|
@@ -95,7 +95,7 @@ module.exports.getWrapper = (pExtension, pTranspilerOptions) => {
|
|
|
95
95
|
* all supported extensions and whether or not it is supported
|
|
96
96
|
* in the current environment
|
|
97
97
|
*
|
|
98
|
-
* @type {
|
|
98
|
+
* @type {IAvailableExtension[]}
|
|
99
99
|
*/
|
|
100
100
|
module.exports.allExtensions = Object.keys(EXTENSION2WRAPPER).map(
|
|
101
101
|
(pExtension) => ({
|
|
@@ -15,11 +15,11 @@ const path = require("path");
|
|
|
15
15
|
* with 100% confidence.
|
|
16
16
|
*
|
|
17
17
|
* @param {string} pFilePath the path to transform
|
|
18
|
-
* @param {
|
|
18
|
+
* @param {path} pPathModule? optional - the path module/ object to use (for testing
|
|
19
19
|
* this module on posix platforms only; defaults to require('path'))
|
|
20
20
|
* @return {string} the transformed path
|
|
21
21
|
*/
|
|
22
|
-
module.exports = function pathToPosix(pFilePath, pPathModule) {
|
|
22
|
+
module.exports = function pathToPosix(pFilePath, pPathModule = path) {
|
|
23
23
|
const lPathModule = pPathModule || path;
|
|
24
24
|
|
|
25
25
|
if (lPathModule.sep !== path.posix.sep) {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
const _clone = require("lodash/clone");
|
|
2
2
|
const _get = require("lodash/get");
|
|
3
3
|
const _reject = require("lodash/reject");
|
|
4
|
-
const
|
|
4
|
+
const _uniq = require("lodash/uniq");
|
|
5
5
|
const compare = require("./compare");
|
|
6
6
|
|
|
7
7
|
function mergeDependency(pLeftDependency, pRightDependency) {
|
|
8
8
|
return {
|
|
9
9
|
...pLeftDependency,
|
|
10
10
|
...pRightDependency,
|
|
11
|
-
dependencyTypes:
|
|
11
|
+
dependencyTypes: _uniq(
|
|
12
12
|
pLeftDependency.dependencyTypes.concat(pRightDependency.dependencyTypes)
|
|
13
13
|
),
|
|
14
14
|
rules: pLeftDependency.rules
|
|
@@ -8,9 +8,9 @@ const _has = require("lodash/has");
|
|
|
8
8
|
*
|
|
9
9
|
* (this thing probably belongs in a model-like folder and not in utl)
|
|
10
10
|
*
|
|
11
|
-
* @param {import("../../types/
|
|
11
|
+
* @param {import("../../types/dependency-cruiser").IFlattenedRuleSet} pRuleSet - The rule set to search in
|
|
12
12
|
* @param {string} pName - The rule name to look for
|
|
13
|
-
* @return {import("../../types/rule-set").IForbiddenRuleType|
|
|
13
|
+
* @return {import("../../types/rule-set").IForbiddenRuleType|undefined} - a rule (or 'undefined' if nothing found)
|
|
14
14
|
*/
|
|
15
15
|
function findRuleByName(pRuleSet, pName) {
|
|
16
16
|
return _get(pRuleSet, "forbidden", []).find(
|
|
@@ -24,26 +24,31 @@ function findRuleByName(pRuleSet, pName) {
|
|
|
24
24
|
*
|
|
25
25
|
* Returns false in all other cases
|
|
26
26
|
*
|
|
27
|
-
* @param {import('
|
|
27
|
+
* @param {import('../../types/dependency-cruiser').IFlattenedRuleSet} pRuleSet
|
|
28
28
|
* @return {boolean}
|
|
29
29
|
*/
|
|
30
30
|
function ruleSetHasLicenseRule(pRuleSet) {
|
|
31
31
|
return (
|
|
32
32
|
_get(pRuleSet, "forbidden", []).some(
|
|
33
|
-
(pRule) => _has(pRule
|
|
33
|
+
(pRule) => _has(pRule, "to.license") || _has(pRule, "to.licenseNot")
|
|
34
34
|
) ||
|
|
35
35
|
_get(pRuleSet, "allowed", []).some(
|
|
36
|
-
(pRule) => _has(pRule
|
|
36
|
+
(pRule) => _has(pRule, "to.license") || _has(pRule, "to.licenseNot")
|
|
37
37
|
)
|
|
38
38
|
);
|
|
39
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
*
|
|
42
|
+
* @param {import('../../types/dependency-cruiser').IFlattenedRuleSet} pRuleSet
|
|
43
|
+
* @return {boolean}
|
|
44
|
+
*/
|
|
40
45
|
function ruleSetHasDeprecationRule(pRuleSet) {
|
|
41
46
|
return (
|
|
42
47
|
_get(pRuleSet, "forbidden", []).some((pRule) =>
|
|
43
|
-
_get(pRule
|
|
48
|
+
_get(pRule, "to.dependencyTypes", []).includes("deprecated")
|
|
44
49
|
) ||
|
|
45
50
|
_get(pRuleSet, "allowed", []).some((pRule) =>
|
|
46
|
-
_get(pRule
|
|
51
|
+
_get(pRule, "to.dependencyTypes", []).includes("deprecated")
|
|
47
52
|
)
|
|
48
53
|
);
|
|
49
54
|
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
const path = require("path");
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
*
|
|
4
|
+
* @param {string} pFileDirectory
|
|
5
|
+
* @returns {string}
|
|
6
|
+
*/
|
|
3
7
|
function relativize(pFileDirectory) {
|
|
4
8
|
// if pFileDirectory === process.cwd() path.relative will yield an empty string
|
|
5
9
|
// whereas we actually want something non-empty => hence normalize
|
|
@@ -9,6 +13,11 @@ function relativize(pFileDirectory) {
|
|
|
9
13
|
: pFileDirectory;
|
|
10
14
|
}
|
|
11
15
|
|
|
16
|
+
/**
|
|
17
|
+
*
|
|
18
|
+
* @param {string[]} pFileAndDirectoryArray
|
|
19
|
+
* @returns {string[]}
|
|
20
|
+
*/
|
|
12
21
|
module.exports = function normalizeFileAndDirectoryArray(
|
|
13
22
|
pFileAndDirectoryArray
|
|
14
23
|
) {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
/** @type {import('../../../types/options').ICruiseOptions} */
|
|
1
2
|
module.exports = {
|
|
2
3
|
validate: false,
|
|
3
4
|
maxDepth: 0,
|
|
4
|
-
moduleSystems: ["
|
|
5
|
+
moduleSystems: ["es6", "cjs", "tsd", "amd"],
|
|
5
6
|
tsPreCompilationDeps: false,
|
|
6
7
|
preserveSymlinks: false,
|
|
7
8
|
combinedDependencies: false,
|
|
@@ -67,6 +67,11 @@ function normalizeCollapse(pCollapse) {
|
|
|
67
67
|
return lReturnValue;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
/**
|
|
71
|
+
*
|
|
72
|
+
* @param {import("../../../types/dependency-cruiser").IForbiddenRuleType} pRule
|
|
73
|
+
* @returns {boolean}
|
|
74
|
+
*/
|
|
70
75
|
function hasMetricsRule(pRule) {
|
|
71
76
|
// TODO: philosophy: is a rule with 'folder' in it a metrics rule?
|
|
72
77
|
// Or is it a misuse to ensure folder derivations (like cycles) get
|
|
@@ -76,6 +81,11 @@ function hasMetricsRule(pRule) {
|
|
|
76
81
|
);
|
|
77
82
|
}
|
|
78
83
|
|
|
84
|
+
/**
|
|
85
|
+
*
|
|
86
|
+
* @param {import("../../../types/dependency-cruiser").IFlattenedRuleSet} pRuleSet
|
|
87
|
+
* @returns {boolean}
|
|
88
|
+
*/
|
|
79
89
|
function ruleSetHasMetricsRule(pRuleSet) {
|
|
80
90
|
const lRuleSet = pRuleSet || {};
|
|
81
91
|
return (
|
|
@@ -87,7 +97,7 @@ function ruleSetHasMetricsRule(pRuleSet) {
|
|
|
87
97
|
/**
|
|
88
98
|
* Determines whether (instability) metrics should be calculated
|
|
89
99
|
*
|
|
90
|
-
* @param {import('../../../types/
|
|
100
|
+
* @param {import('../../../types/dependency-cruiser').ICruiseOptions} pOptions
|
|
91
101
|
* @returns Boolean
|
|
92
102
|
*/
|
|
93
103
|
function shouldCalculateMetrics(pOptions) {
|
|
@@ -100,7 +110,7 @@ function shouldCalculateMetrics(pOptions) {
|
|
|
100
110
|
|
|
101
111
|
/**
|
|
102
112
|
*
|
|
103
|
-
* @param {Partial
|
|
113
|
+
* @param {Partial<import('../../../types/options').ICruiseOptions>} pOptions
|
|
104
114
|
* @returns {import('../../../types/options').ICruiseOptions}
|
|
105
115
|
*/
|
|
106
116
|
function normalizeCruiseOptions(pOptions) {
|
|
@@ -111,8 +121,11 @@ function normalizeCruiseOptions(pOptions) {
|
|
|
111
121
|
...pOptions,
|
|
112
122
|
};
|
|
113
123
|
|
|
124
|
+
// @ts-ignore the idea of normalizing maxDepth to number is that after
|
|
125
|
+
// that we're sure it's a number. Should maybe best be solved by
|
|
126
|
+
// having two types/ interfaces
|
|
114
127
|
lReturnValue.maxDepth = Number.parseInt(lReturnValue.maxDepth, 10);
|
|
115
|
-
lReturnValue.moduleSystems = uniq(lReturnValue.moduleSystems
|
|
128
|
+
lReturnValue.moduleSystems = uniq(lReturnValue.moduleSystems);
|
|
116
129
|
if (has(lReturnValue, "collapse")) {
|
|
117
130
|
lReturnValue.collapse = normalizeCollapse(lReturnValue.collapse);
|
|
118
131
|
}
|
|
@@ -125,9 +138,7 @@ function normalizeCruiseOptions(pOptions) {
|
|
|
125
138
|
lReturnValue.extraExtensionsToScan = lReturnValue.extraExtensionsToScan || [];
|
|
126
139
|
lReturnValue = normalizeFilterOptions(lReturnValue, ["focus", "includeOnly"]);
|
|
127
140
|
|
|
128
|
-
lReturnValue.exoticRequireStrings = uniq(
|
|
129
|
-
lReturnValue.exoticRequireStrings.sort()
|
|
130
|
-
);
|
|
141
|
+
lReturnValue.exoticRequireStrings = uniq(lReturnValue.exoticRequireStrings);
|
|
131
142
|
if (lReturnValue.reporterOptions) {
|
|
132
143
|
lReturnValue.reporterOptions = normalizeReporterOptions(
|
|
133
144
|
lReturnValue.reporterOptions
|
|
@@ -138,6 +149,11 @@ function normalizeCruiseOptions(pOptions) {
|
|
|
138
149
|
return lReturnValue;
|
|
139
150
|
}
|
|
140
151
|
|
|
152
|
+
/**
|
|
153
|
+
*
|
|
154
|
+
* @param {import("../../../types/dependency-cruiser").IFormatOptions} pFormatOptions
|
|
155
|
+
* @returns {import("../../../types/dependency-cruiser").IFormatOptions}
|
|
156
|
+
*/
|
|
141
157
|
function normalizeFormatOptions(pFormatOptions) {
|
|
142
158
|
const lFormatOptions = clone(pFormatOptions);
|
|
143
159
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const _get = require("lodash/get");
|
|
2
|
-
const
|
|
2
|
+
const has = require("lodash/has");
|
|
3
3
|
const safeRegex = require("safe-regex");
|
|
4
4
|
const report = require("../../report");
|
|
5
5
|
|
|
@@ -55,6 +55,12 @@ function validatePathsSafety(pFilterOption) {
|
|
|
55
55
|
validateRegExpSafety(_get(pFilterOption, "pathNot", ""));
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
/**
|
|
59
|
+
*
|
|
60
|
+
* @param {any} pOptions
|
|
61
|
+
* @throws {Error}
|
|
62
|
+
* @returns {import("../../../types/dependency-cruiser").ICruiseOptions}
|
|
63
|
+
*/
|
|
58
64
|
function validateCruiseOptions(pOptions) {
|
|
59
65
|
let lReturnValue = {};
|
|
60
66
|
|
|
@@ -75,7 +81,7 @@ function validateCruiseOptions(pOptions) {
|
|
|
75
81
|
// neccessary because not found a way to do this properly in JSON schema
|
|
76
82
|
validateMaxDepth(pOptions.maxDepth);
|
|
77
83
|
|
|
78
|
-
if (
|
|
84
|
+
if (has(pOptions, "ruleSet.options")) {
|
|
79
85
|
lReturnValue = validateCruiseOptions(pOptions.ruleSet.options);
|
|
80
86
|
}
|
|
81
87
|
return { ...lReturnValue, ...pOptions };
|
|
@@ -83,6 +89,11 @@ function validateCruiseOptions(pOptions) {
|
|
|
83
89
|
return lReturnValue;
|
|
84
90
|
}
|
|
85
91
|
|
|
92
|
+
/**
|
|
93
|
+
*
|
|
94
|
+
* @param {import("../../../types/dependency-cruiser").IFormatOptions} pFormatOptions
|
|
95
|
+
* @throws {Error}
|
|
96
|
+
*/
|
|
86
97
|
function validateFormatOptions(pFormatOptions) {
|
|
87
98
|
validatePathsSafety(pFormatOptions.exclude);
|
|
88
99
|
validatePathsSafety(pFormatOptions.focus);
|
package/src/main/report-wrap.js
CHANGED
|
@@ -39,7 +39,12 @@ function reSummarizeResults(pResult, pFormatOptions) {
|
|
|
39
39
|
modules: lModules,
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
|
-
|
|
42
|
+
/**
|
|
43
|
+
*
|
|
44
|
+
* @param {import("../../types/dependency-cruiser").ICruiseResult} pResult result of a previous run of dependency-cruiser
|
|
45
|
+
* @param {import("../../types/dependency-cruiser").IFormatOptions} pFormatOptions
|
|
46
|
+
* @returns {import("../../types/dependency-cruiser").IReporterOutput}
|
|
47
|
+
*/
|
|
43
48
|
module.exports = function reportWrap(pResult, pFormatOptions) {
|
|
44
49
|
const lReportFunction = report.getReporter(pFormatOptions.outputType);
|
|
45
50
|
const lReportOptions = _get(
|