dependency-cruiser 13.0.0-beta-1 → 13.0.0-beta-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/README.md +2 -2
- package/package.json +14 -19
- package/src/cache/helpers.mjs +2 -2
- package/src/cli/index.mjs +3 -3
- package/src/cli/init-config/validators.mjs +2 -2
- package/src/cli/normalize-cli-options.mjs +4 -4
- package/src/cli/utl/io.mjs +2 -1
- package/src/config-utl/extract-babel-config.mjs +4 -4
- package/src/config-utl/extract-depcruise-config/index.mjs +2 -2
- package/src/config-utl/extract-depcruise-config/merge-configs.mjs +11 -13
- package/src/config-utl/extract-ts-config.mjs +2 -2
- package/src/config-utl/extract-webpack-resolve-config.mjs +45 -39
- package/src/enrich/derive/folders/aggregate-to-folders.mjs +4 -4
- package/src/enrich/derive/folders/utl.mjs +3 -3
- package/src/extract/gather-initial-sources.mjs +3 -4
- package/src/extract/get-dependencies.mjs +2 -3
- package/src/main/helpers.mjs +0 -1
- package/src/main/resolve-options/normalize.mjs +7 -10
- package/src/meta.js +1 -1
- package/src/report/csv.mjs +7 -6
- package/src/report/error.mjs +15 -12
- package/src/report/text.mjs +2 -1
package/README.md
CHANGED
|
@@ -63,7 +63,7 @@ npx depcruise src --include-only "^src" --output-type dot | dot -T svg > depende
|
|
|
63
63
|
options in the [command line interface](./doc/cli.md) documentation.
|
|
64
64
|
- _[Real world samples](./doc/real-world-samples.md)_
|
|
65
65
|
contains dependency cruises of some of the most used projects on npm.
|
|
66
|
-
- If
|
|
66
|
+
- If your grandma is more into formats like `mermaid`, `json`, `csv`, `html` or plain text
|
|
67
67
|
we've [got her covered](./doc/cli.md#--output-type-specify-the-output-format)
|
|
68
68
|
as well.
|
|
69
69
|
|
|
@@ -107,7 +107,7 @@ Sample rule:
|
|
|
107
107
|
#### Report them
|
|
108
108
|
|
|
109
109
|
```sh
|
|
110
|
-
npx depcruise
|
|
110
|
+
npx depcruise src
|
|
111
111
|
```
|
|
112
112
|
|
|
113
113
|
This will validate against your rules and shows any violations in an eslint-like format:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dependency-cruiser",
|
|
3
|
-
"version": "13.0.0-beta-
|
|
3
|
+
"version": "13.0.0-beta-2",
|
|
4
4
|
"description": "Validate and visualize dependencies. With your rules. JavaScript, TypeScript, CoffeeScript. ES6, CommonJS, AMD.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"static analysis",
|
|
@@ -46,24 +46,19 @@
|
|
|
46
46
|
"main": "src/main/index.mjs",
|
|
47
47
|
"exports": {
|
|
48
48
|
".": {
|
|
49
|
-
"import": "./src/main/index.mjs"
|
|
50
|
-
"require": "./dist/main/index.js"
|
|
49
|
+
"import": "./src/main/index.mjs"
|
|
51
50
|
},
|
|
52
51
|
"./config-utl/extract-babel-config": {
|
|
53
|
-
"import": "./src/config-utl/extract-babel-config.mjs"
|
|
54
|
-
"require": "./dist/config-utl/extract-babel-config.js"
|
|
52
|
+
"import": "./src/config-utl/extract-babel-config.mjs"
|
|
55
53
|
},
|
|
56
54
|
"./config-utl/extract-depcruise-config": {
|
|
57
|
-
"import": "./src/config-utl/extract-depcruise-config/index.mjs"
|
|
58
|
-
"require": "./dist/config-utl/extract-depcruise-config/index.js"
|
|
55
|
+
"import": "./src/config-utl/extract-depcruise-config/index.mjs"
|
|
59
56
|
},
|
|
60
57
|
"./config-utl/extract-ts-config": {
|
|
61
|
-
"import": "./src/config-utl/extract-ts-config.mjs"
|
|
62
|
-
"require": "./dist/config-utl/extract-ts-config.js"
|
|
58
|
+
"import": "./src/config-utl/extract-ts-config.mjs"
|
|
63
59
|
},
|
|
64
60
|
"./config-utl/extract-webpack-resolve-config": {
|
|
65
|
-
"import": "./src/config-utl/extract-webpack-resolve-config.mjs"
|
|
66
|
-
"require": "./dist/config-utl/extract-webpack-resolve-config.js"
|
|
61
|
+
"import": "./src/config-utl/extract-webpack-resolve-config.mjs"
|
|
67
62
|
},
|
|
68
63
|
"./sample-reporter-plugin": "./configs/plugins/stats-reporter-plugin.js",
|
|
69
64
|
"./sample-3d-reporter-plugin": "./configs/plugins/3d-reporter-plugin.js",
|
|
@@ -153,11 +148,11 @@
|
|
|
153
148
|
"acorn-walk": "8.2.0",
|
|
154
149
|
"ajv": "8.12.0",
|
|
155
150
|
"chalk": "5.2.0",
|
|
156
|
-
"commander": "10.0.
|
|
151
|
+
"commander": "10.0.1",
|
|
157
152
|
"enhanced-resolve": "5.12.0",
|
|
158
153
|
"figures": "5.0.0",
|
|
159
154
|
"get-stream": "^6.0.1",
|
|
160
|
-
"glob": "10.
|
|
155
|
+
"glob": "10.1.0",
|
|
161
156
|
"handlebars": "4.7.7",
|
|
162
157
|
"ignore": "5.2.4",
|
|
163
158
|
"indent-string": "5.0.0",
|
|
@@ -168,23 +163,23 @@
|
|
|
168
163
|
"prompts": "2.4.2",
|
|
169
164
|
"rechoir": "^0.8.0",
|
|
170
165
|
"safe-regex": "2.1.1",
|
|
171
|
-
"semver": "^7.
|
|
166
|
+
"semver": "^7.4.0",
|
|
172
167
|
"semver-try-require": "6.2.2",
|
|
173
168
|
"teamcity-service-messages": "0.1.14",
|
|
174
169
|
"tsconfig-paths-webpack-plugin": "4.0.1",
|
|
175
|
-
"watskeburt": "0.10.
|
|
170
|
+
"watskeburt": "0.10.2",
|
|
176
171
|
"wrap-ansi": "8.1.0"
|
|
177
172
|
},
|
|
178
173
|
"devDependencies": {
|
|
179
174
|
"@babel/core": "7.21.4",
|
|
180
175
|
"@babel/plugin-transform-modules-commonjs": "7.21.2",
|
|
181
176
|
"@babel/preset-typescript": "7.21.4",
|
|
182
|
-
"@swc/core": "1.3.
|
|
183
|
-
"@types/lodash": "4.14.
|
|
177
|
+
"@swc/core": "1.3.50",
|
|
178
|
+
"@types/lodash": "4.14.194",
|
|
184
179
|
"@types/node": "18.15.11",
|
|
185
180
|
"@types/prompts": "2.4.4",
|
|
186
|
-
"@typescript-eslint/eslint-plugin": "5.
|
|
187
|
-
"@typescript-eslint/parser": "5.
|
|
181
|
+
"@typescript-eslint/eslint-plugin": "5.58.0",
|
|
182
|
+
"@typescript-eslint/parser": "5.58.0",
|
|
188
183
|
"@vue/compiler-sfc": "3.2.47",
|
|
189
184
|
"c8": "7.13.0",
|
|
190
185
|
"chai": "4.3.7",
|
package/src/cache/helpers.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable import/exports-last */
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
3
|
import { readFileSync } from "node:fs";
|
|
4
|
-
import
|
|
4
|
+
import { extname } from "node:path";
|
|
5
5
|
import memoize from "lodash/memoize.js";
|
|
6
6
|
import { filenameMatchesPattern } from "../graph-utl/match-facade.mjs";
|
|
7
7
|
|
|
@@ -69,7 +69,7 @@ export function includeOnlyFilter(pIncludeOnlyFilter) {
|
|
|
69
69
|
* @returns {(pFileName: string) => boolean}
|
|
70
70
|
*/
|
|
71
71
|
export function hasInterestingExtension(pExtensions) {
|
|
72
|
-
return (pFileName) => pExtensions.has(
|
|
72
|
+
return (pFileName) => pExtensions.has(extname(pFileName));
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
/**
|
package/src/cli/index.mjs
CHANGED
|
@@ -23,13 +23,13 @@ import setUpPerformanceLogListener from "./listeners/performance-log/index.mjs";
|
|
|
23
23
|
import setUpNDJSONListener from "./listeners/ndjson.mjs";
|
|
24
24
|
import initConfig from "./init-config/index.mjs";
|
|
25
25
|
|
|
26
|
-
function extractResolveOptions(pCruiseOptions) {
|
|
26
|
+
async function extractResolveOptions(pCruiseOptions) {
|
|
27
27
|
let lResolveOptions = {};
|
|
28
28
|
const lWebPackConfigFileName =
|
|
29
29
|
pCruiseOptions?.ruleSet?.options?.webpackConfig?.fileName ?? null;
|
|
30
30
|
|
|
31
31
|
if (lWebPackConfigFileName) {
|
|
32
|
-
lResolveOptions = extractWebpackResolveConfig(
|
|
32
|
+
lResolveOptions = await extractWebpackResolveConfig(
|
|
33
33
|
lWebPackConfigFileName,
|
|
34
34
|
pCruiseOptions?.ruleSet?.options?.webpackConfig?.env ?? null,
|
|
35
35
|
pCruiseOptions?.ruleSet?.options?.webpackConfig?.arguments ?? null
|
|
@@ -118,7 +118,7 @@ async function runCruise(pFileDirectoryArray, pCruiseOptions) {
|
|
|
118
118
|
const lReportingResult = await cruise(
|
|
119
119
|
pFileDirectoryArray,
|
|
120
120
|
lCruiseOptions,
|
|
121
|
-
extractResolveOptions(lCruiseOptions),
|
|
121
|
+
await extractResolveOptions(lCruiseOptions),
|
|
122
122
|
{
|
|
123
123
|
tsConfig: extractTSConfigOptions(lCruiseOptions),
|
|
124
124
|
babelConfig: await extractBabelConfigOptions(lCruiseOptions),
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { statSync } from "node:fs";
|
|
2
2
|
import { toSourceLocationArray } from "./environment-helpers.mjs";
|
|
3
3
|
|
|
4
4
|
export function validateLocation(pLocations) {
|
|
5
5
|
for (const lLocation of toSourceLocationArray(pLocations)) {
|
|
6
6
|
try {
|
|
7
|
-
if (!
|
|
7
|
+
if (!statSync(lLocation).isDirectory()) {
|
|
8
8
|
return `'${lLocation}' doesn't seem to be a folder - please try again`;
|
|
9
9
|
}
|
|
10
10
|
} catch (pError) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import { accessSync, R_OK } from "node:fs";
|
|
2
|
+
import { isAbsolute } from "node:path";
|
|
3
3
|
import set from "lodash/set.js";
|
|
4
4
|
import get from "lodash/get.js";
|
|
5
5
|
import has from "lodash/has.js";
|
|
@@ -45,7 +45,7 @@ function normalizeConfigFileName(pCliOptions, pConfigWrapperName, pDefault) {
|
|
|
45
45
|
|
|
46
46
|
function fileExists(pFileName) {
|
|
47
47
|
try {
|
|
48
|
-
|
|
48
|
+
accessSync(pFileName, R_OK);
|
|
49
49
|
return true;
|
|
50
50
|
} catch (pError) {
|
|
51
51
|
return false;
|
|
@@ -129,7 +129,7 @@ async function normalizeValidationOption(pCliOptions) {
|
|
|
129
129
|
return {
|
|
130
130
|
rulesFile,
|
|
131
131
|
ruleSet: await loadConfig(
|
|
132
|
-
|
|
132
|
+
isAbsolute(rulesFile) ? rulesFile : `./${rulesFile}`
|
|
133
133
|
),
|
|
134
134
|
validate: true,
|
|
135
135
|
};
|
package/src/cli/utl/io.mjs
CHANGED
|
@@ -32,8 +32,9 @@ function writeToStdOut(pString, pBufferSize = PIPE_BUFFER_SIZE) {
|
|
|
32
32
|
|
|
33
33
|
/* eslint no-plusplus: 0 */
|
|
34
34
|
for (lIndex = 0; lIndex < lNumberOfChunks; lIndex++) {
|
|
35
|
+
const lChunkStart = lIndex * pBufferSize;
|
|
35
36
|
process.stdout.write(
|
|
36
|
-
pString.
|
|
37
|
+
pString.substring(lChunkStart, lChunkStart + pBufferSize),
|
|
37
38
|
"utf8"
|
|
38
39
|
);
|
|
39
40
|
}
|
|
@@ -7,7 +7,7 @@ import tryImport from "semver-try-require";
|
|
|
7
7
|
import meta from "../meta.js";
|
|
8
8
|
import makeAbsolute from "./make-absolute.mjs";
|
|
9
9
|
|
|
10
|
-
async function
|
|
10
|
+
async function getJSConfig(pBabelConfigFileName) {
|
|
11
11
|
let lReturnValue = {};
|
|
12
12
|
|
|
13
13
|
try {
|
|
@@ -55,9 +55,9 @@ function getJSON5Config(pBabelConfigFileName) {
|
|
|
55
55
|
|
|
56
56
|
async function getConfig(pBabelConfigFileName) {
|
|
57
57
|
const lExtensionToParseFunction = {
|
|
58
|
-
".js":
|
|
59
|
-
".cjs":
|
|
60
|
-
".mjs":
|
|
58
|
+
".js": getJSConfig,
|
|
59
|
+
".cjs": getJSConfig,
|
|
60
|
+
".mjs": getJSConfig,
|
|
61
61
|
"": getJSON5Config,
|
|
62
62
|
".json": getJSON5Config,
|
|
63
63
|
".json5": getJSON5Config,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { dirname } from "node:path";
|
|
2
2
|
import cloneDeep from "lodash/cloneDeep.js";
|
|
3
3
|
import has from "lodash/has.js";
|
|
4
4
|
import { resolve } from "../../extract/resolve/resolve.mjs";
|
|
@@ -67,7 +67,7 @@ export default async function extractDepcruiseConfig(
|
|
|
67
67
|
),
|
|
68
68
|
"cli"
|
|
69
69
|
);
|
|
70
|
-
const lBaseDirectory =
|
|
70
|
+
const lBaseDirectory = dirname(lResolvedFileName);
|
|
71
71
|
|
|
72
72
|
if (pAlreadyVisited.has(lResolvedFileName)) {
|
|
73
73
|
throw new Error(
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { isDeepStrictEqual } from "node:util";
|
|
2
|
-
import get from "lodash/get.js";
|
|
3
2
|
import uniqBy from "lodash/uniqBy.js";
|
|
4
3
|
import uniqWith from "lodash/uniqWith.js";
|
|
5
4
|
|
|
@@ -87,10 +86,8 @@ function mergeOptions(pOptionsExtended, pOptionsBase) {
|
|
|
87
86
|
* @returns {string} - a string from the SeverityType value set
|
|
88
87
|
*/
|
|
89
88
|
function mergeAllowedSeverities(pConfigExtended, pConfigBase) {
|
|
90
|
-
return
|
|
91
|
-
pConfigExtended
|
|
92
|
-
"allowedSeverity",
|
|
93
|
-
get(pConfigBase, "allowedSeverity", "warn")
|
|
89
|
+
return (
|
|
90
|
+
pConfigExtended?.allowedSeverity ?? pConfigBase?.allowedSeverity ?? "warn"
|
|
94
91
|
);
|
|
95
92
|
}
|
|
96
93
|
|
|
@@ -108,18 +105,19 @@ function mergeAllowedSeverities(pConfigExtended, pConfigBase) {
|
|
|
108
105
|
*
|
|
109
106
|
* @returns {Object} - The merged rule set
|
|
110
107
|
*/
|
|
108
|
+
// eslint-disable-next-line complexity
|
|
111
109
|
export default (pConfigExtended, pConfigBase) => {
|
|
112
110
|
const lForbidden = mergeRules(
|
|
113
|
-
|
|
114
|
-
|
|
111
|
+
pConfigExtended?.forbidden ?? [],
|
|
112
|
+
pConfigBase?.forbidden ?? []
|
|
115
113
|
);
|
|
116
114
|
const lRequired = mergeRules(
|
|
117
|
-
|
|
118
|
-
|
|
115
|
+
pConfigExtended?.required ?? [],
|
|
116
|
+
pConfigBase?.required ?? []
|
|
119
117
|
);
|
|
120
118
|
const lAllowed = mergeAllowedRules(
|
|
121
|
-
|
|
122
|
-
|
|
119
|
+
pConfigExtended?.allowed ?? [],
|
|
120
|
+
pConfigBase?.allowed ?? []
|
|
123
121
|
);
|
|
124
122
|
|
|
125
123
|
return {
|
|
@@ -132,8 +130,8 @@ export default (pConfigExtended, pConfigBase) => {
|
|
|
132
130
|
}
|
|
133
131
|
: {}),
|
|
134
132
|
options: mergeOptions(
|
|
135
|
-
|
|
136
|
-
|
|
133
|
+
pConfigExtended?.options ?? {},
|
|
134
|
+
pConfigBase?.options ?? {}
|
|
137
135
|
),
|
|
138
136
|
};
|
|
139
137
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { dirname, resolve } from "node:path";
|
|
2
2
|
import tryImport from "semver-try-require";
|
|
3
3
|
import meta from "../meta.js";
|
|
4
4
|
|
|
@@ -55,7 +55,7 @@ export default function extractTSConfig(pTSConfigFileName) {
|
|
|
55
55
|
lReturnValue = typescript.parseJsonConfigFileContent(
|
|
56
56
|
lConfig.config,
|
|
57
57
|
typescript.sys,
|
|
58
|
-
|
|
58
|
+
dirname(resolve(pTSConfigFileName)),
|
|
59
59
|
{},
|
|
60
60
|
pTSConfigFileName
|
|
61
61
|
);
|
|
@@ -46,14 +46,6 @@ function suggestModules(pSuggestionList, pWebpackConfigFilename) {
|
|
|
46
46
|
|
|
47
47
|
function tryRegisterNonNative(pWebpackConfigFilename) {
|
|
48
48
|
const lConfigExtension = extname(pWebpackConfigFilename);
|
|
49
|
-
|
|
50
|
-
if (lConfigExtension === ".mjs") {
|
|
51
|
-
throw new Error(
|
|
52
|
-
`dependency-cruiser currently does not support webpack configurations in` +
|
|
53
|
-
`\n ES Module format (like '${pWebpackConfigFilename}').\n`
|
|
54
|
-
);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
49
|
const interpret = require("interpret");
|
|
58
50
|
const rechoir = require("rechoir");
|
|
59
51
|
|
|
@@ -71,6 +63,41 @@ function tryRegisterNonNative(pWebpackConfigFilename) {
|
|
|
71
63
|
}
|
|
72
64
|
}
|
|
73
65
|
|
|
66
|
+
function isNativelySupported(pWebpackConfigFilename) {
|
|
67
|
+
const lNativelySupportedExtensions = [
|
|
68
|
+
".js",
|
|
69
|
+
".cjs",
|
|
70
|
+
".mjs",
|
|
71
|
+
".json",
|
|
72
|
+
".node",
|
|
73
|
+
];
|
|
74
|
+
const lWebpackConfigExtension = extname(pWebpackConfigFilename);
|
|
75
|
+
return lNativelySupportedExtensions.includes(lWebpackConfigExtension);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async function attemptImport(pAbsoluteWebpackConfigFileName) {
|
|
79
|
+
try {
|
|
80
|
+
if (isNativelySupported(pAbsoluteWebpackConfigFileName)) {
|
|
81
|
+
const lModule = await import(`file://${pAbsoluteWebpackConfigFileName}`);
|
|
82
|
+
return lModule.default;
|
|
83
|
+
} else {
|
|
84
|
+
tryRegisterNonNative(pAbsoluteWebpackConfigFileName);
|
|
85
|
+
/* we're using still using require instead of dynamic imports here because
|
|
86
|
+
* the modules webpack uses for non-native formats monkey-patch on the commonjs
|
|
87
|
+
* module system. If we'd use a dynamic import, these monkey-patches wouldn't
|
|
88
|
+
* be used.
|
|
89
|
+
*/
|
|
90
|
+
/* eslint node/global-require:0, security/detect-non-literal-require:0, import/no-dynamic-require:0 */
|
|
91
|
+
return require(pAbsoluteWebpackConfigFileName);
|
|
92
|
+
}
|
|
93
|
+
} catch (pError) {
|
|
94
|
+
throw new Error(
|
|
95
|
+
`The webpack config '${pAbsoluteWebpackConfigFileName}' seems to be not quite valid for use:` +
|
|
96
|
+
`\n\n "${pError}"\n`
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
74
101
|
/**
|
|
75
102
|
* Reads the file with name `pWebpackConfigFilename` and (applying the
|
|
76
103
|
* environment `pEnvironment` and the arguments `pArguments` (which can
|
|
@@ -84,42 +111,21 @@ function tryRegisterNonNative(pWebpackConfigFilename) {
|
|
|
84
111
|
* @throws {Error} when the webpack config isn't usable (e.g. because it
|
|
85
112
|
* doesn't exist, or because it's invalid)
|
|
86
113
|
*/
|
|
87
|
-
|
|
88
|
-
export default function extractWebpackResolveConfig(
|
|
114
|
+
export default async function extractWebpackResolveConfig(
|
|
89
115
|
pWebpackConfigFilename,
|
|
90
116
|
pEnvironment,
|
|
91
117
|
pArguments
|
|
92
118
|
) {
|
|
93
119
|
let lReturnValue = {};
|
|
94
|
-
const
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
* the modules webpack uses for non-native formats monkey-patch on the commonjs
|
|
104
|
-
* module system. If we'd use a dynamic import, these monkey-patches wouldn't
|
|
105
|
-
* be used.
|
|
106
|
-
*/
|
|
107
|
-
/* eslint node/global-require:0, security/detect-non-literal-require:0, import/no-dynamic-require:0 */
|
|
108
|
-
const lWebpackConfigModule = require(lWebpackConfigFilename);
|
|
109
|
-
const lWebpackConfig = pryConfigFromTheConfig(
|
|
110
|
-
lWebpackConfigModule,
|
|
111
|
-
pEnvironment,
|
|
112
|
-
pArguments
|
|
113
|
-
);
|
|
114
|
-
|
|
115
|
-
if (lWebpackConfig.resolve) {
|
|
116
|
-
lReturnValue = lWebpackConfig.resolve;
|
|
117
|
-
}
|
|
118
|
-
} catch (pError) {
|
|
119
|
-
throw new Error(
|
|
120
|
-
`The webpack config '${pWebpackConfigFilename}' seems to be not quite valid for use:` +
|
|
121
|
-
`\n\n "${pError}"\n`
|
|
122
|
-
);
|
|
120
|
+
const lAbsoluteConfigFilename = makeAbsolute(pWebpackConfigFilename);
|
|
121
|
+
const lWebpackConfig = pryConfigFromTheConfig(
|
|
122
|
+
await attemptImport(lAbsoluteConfigFilename),
|
|
123
|
+
pEnvironment,
|
|
124
|
+
pArguments
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
if (lWebpackConfig.resolve) {
|
|
128
|
+
lReturnValue = lWebpackConfig.resolve;
|
|
123
129
|
}
|
|
124
130
|
|
|
125
131
|
return lReturnValue;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* eslint-disable security/detect-object-injection */
|
|
2
|
-
import
|
|
2
|
+
import { dirname } from "node:path/posix";
|
|
3
3
|
import { calculateInstability, metricsAreCalculable } from "../module-utl.mjs";
|
|
4
4
|
import detectCycles from "../circular.mjs";
|
|
5
5
|
import IndexedModuleGraph from "../../../graph-utl/indexed-module-graph.mjs";
|
|
@@ -42,7 +42,7 @@ function upsertFolderAttributes(pAllMetrics, pModule, pDirname) {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
function aggregateToFolder(pAllFolders, pModule) {
|
|
45
|
-
getParentFolders(
|
|
45
|
+
getParentFolders(dirname(pModule.source)).forEach((pParentDirectory) =>
|
|
46
46
|
upsertFolderAttributes(pAllFolders, pModule, pParentDirectory)
|
|
47
47
|
);
|
|
48
48
|
return pAllFolders;
|
|
@@ -56,9 +56,9 @@ function getFolderLevelCouplings(pCouplingArray) {
|
|
|
56
56
|
return Array.from(
|
|
57
57
|
new Set(
|
|
58
58
|
pCouplingArray.map((pCoupling) =>
|
|
59
|
-
|
|
59
|
+
dirname(pCoupling.name) === "."
|
|
60
60
|
? pCoupling.name
|
|
61
|
-
:
|
|
61
|
+
: dirname(pCoupling.name)
|
|
62
62
|
)
|
|
63
63
|
)
|
|
64
64
|
).map((pCoupling) => ({ name: pCoupling }));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* eslint-disable security/detect-object-injection */
|
|
2
|
-
import
|
|
2
|
+
import { sep } from "node:path/posix";
|
|
3
3
|
|
|
4
4
|
export function findFolderByName(pAllFolders, pName) {
|
|
5
5
|
return pAllFolders.find((pFolder) => pFolder.name === pName);
|
|
@@ -7,13 +7,13 @@ export function findFolderByName(pAllFolders, pName) {
|
|
|
7
7
|
|
|
8
8
|
export function getAfferentCouplings(pModule, pDirname) {
|
|
9
9
|
return pModule.dependents.filter(
|
|
10
|
-
(pDependent) => !pDependent.startsWith(pDirname.concat(
|
|
10
|
+
(pDependent) => !pDependent.startsWith(pDirname.concat(sep))
|
|
11
11
|
);
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export function getEfferentCouplings(pModule, pDirname) {
|
|
15
15
|
return pModule.dependencies.filter(
|
|
16
|
-
(pDependency) => !pDependency.resolved.startsWith(pDirname.concat(
|
|
16
|
+
(pDependency) => !pDependency.resolved.startsWith(pDirname.concat(sep))
|
|
17
17
|
);
|
|
18
18
|
}
|
|
19
19
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { readdirSync, statSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { glob } from "glob";
|
|
4
|
-
import get from "lodash/get.js";
|
|
5
4
|
import { filenameMatchesPattern } from "../graph-utl/match-facade.mjs";
|
|
6
5
|
import getExtension from "../utl/get-extension.mjs";
|
|
7
6
|
import pathToPosix from "../utl/path-to-posix.mjs";
|
|
@@ -22,16 +21,16 @@ function fileIsScannable(pOptions, pPathToFile) {
|
|
|
22
21
|
|
|
23
22
|
function shouldBeIncluded(pFullPathToFile, pOptions) {
|
|
24
23
|
return (
|
|
25
|
-
!
|
|
24
|
+
!pOptions?.includeOnly?.path ||
|
|
26
25
|
filenameMatchesPattern(pFullPathToFile, pOptions.includeOnly.path)
|
|
27
26
|
);
|
|
28
27
|
}
|
|
29
28
|
|
|
30
29
|
function shouldNotBeExcluded(pFullPathToFile, pOptions) {
|
|
31
30
|
return (
|
|
32
|
-
(!
|
|
31
|
+
(!pOptions?.exclude?.path ||
|
|
33
32
|
!filenameMatchesPattern(pFullPathToFile, pOptions.exclude.path)) &&
|
|
34
|
-
(!
|
|
33
|
+
(!pOptions?.doNotFollow?.path ||
|
|
35
34
|
!filenameMatchesPattern(pFullPathToFile, pOptions.doNotFollow.path))
|
|
36
35
|
);
|
|
37
36
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { join, extname, dirname } from "node:path";
|
|
2
|
-
import get from "lodash/get.js";
|
|
3
2
|
import uniqBy from "lodash/uniqBy.js";
|
|
4
3
|
import { intersects } from "../utl/array-util.mjs";
|
|
5
4
|
import resolve from "./resolve/index.mjs";
|
|
@@ -235,9 +234,9 @@ export default function getDependencies(
|
|
|
235
234
|
.map(addResolutionAttributes(pCruiseOptions, pFileName, pResolveOptions))
|
|
236
235
|
.filter(
|
|
237
236
|
({ resolved }) =>
|
|
238
|
-
(!
|
|
237
|
+
(!pCruiseOptions?.exclude?.path ||
|
|
239
238
|
!matchesPattern(resolved, pCruiseOptions.exclude.path)) &&
|
|
240
|
-
(!
|
|
239
|
+
(!pCruiseOptions?.includeOnly?.path ||
|
|
241
240
|
matchesPattern(resolved, pCruiseOptions.includeOnly.path))
|
|
242
241
|
);
|
|
243
242
|
} catch (pError) {
|
package/src/main/helpers.mjs
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
|
-
import get from "lodash/get.js";
|
|
3
2
|
import has from "lodash/has.js";
|
|
4
3
|
import omit from "lodash/omit.js";
|
|
5
4
|
import enhancedResolve from "enhanced-resolve";
|
|
@@ -110,11 +109,8 @@ async function compileResolveOptions(
|
|
|
110
109
|
...omit(pResolveOptionsFromDCConfig, "cachedInputFileSystem"),
|
|
111
110
|
...pResolveOptions,
|
|
112
111
|
...getNonOverridableResolveOptions(
|
|
113
|
-
|
|
114
|
-
pResolveOptionsFromDCConfig,
|
|
115
|
-
"cachedInputFileSystem.cacheDuration",
|
|
112
|
+
pResolveOptionsFromDCConfig?.cachedInputFileSystem?.cacheDuration ??
|
|
116
113
|
DEFAULT_CACHE_DURATION
|
|
117
|
-
)
|
|
118
114
|
),
|
|
119
115
|
};
|
|
120
116
|
}
|
|
@@ -125,12 +121,13 @@ async function compileResolveOptions(
|
|
|
125
121
|
* @param {import("typescript").ParsedTsconfig} pTSConfig
|
|
126
122
|
* @returns
|
|
127
123
|
*/
|
|
124
|
+
// eslint-disable-next-line complexity
|
|
128
125
|
export default async function normalizeResolveOptions(
|
|
129
126
|
pResolveOptions,
|
|
130
127
|
pOptions,
|
|
131
128
|
pTSConfig
|
|
132
129
|
) {
|
|
133
|
-
const lRuleSet =
|
|
130
|
+
const lRuleSet = pOptions?.ruleSet ?? {};
|
|
134
131
|
// eslint-disable-next-line no-return-await
|
|
135
132
|
return await compileResolveOptions(
|
|
136
133
|
{
|
|
@@ -140,20 +137,20 @@ export default async function normalizeResolveOptions(
|
|
|
140
137
|
symlink === !preserveSymlinks - but using it that way
|
|
141
138
|
breaks backwards compatibility
|
|
142
139
|
*/
|
|
143
|
-
symlinks:
|
|
144
|
-
tsConfig:
|
|
140
|
+
symlinks: pOptions?.preserveSymlinks ?? null,
|
|
141
|
+
tsConfig: pOptions?.ruleSet?.options?.tsConfig?.fileName ?? null,
|
|
145
142
|
|
|
146
143
|
/* squirrel the externalModuleResolutionStrategy and combinedDependencies
|
|
147
144
|
thing into the resolve options
|
|
148
145
|
- they're not for enhanced resolve, but they are for what we consider
|
|
149
146
|
resolve options ...
|
|
150
147
|
*/
|
|
151
|
-
combinedDependencies:
|
|
148
|
+
combinedDependencies: pOptions?.combinedDependencies ?? false,
|
|
152
149
|
resolveLicenses: ruleSetHasLicenseRule(lRuleSet),
|
|
153
150
|
resolveDeprecations: ruleSetHasDeprecationRule(lRuleSet),
|
|
154
151
|
...(pResolveOptions || {}),
|
|
155
152
|
},
|
|
156
153
|
pTSConfig || {},
|
|
157
|
-
|
|
154
|
+
pOptions?.enhancedResolveOptions ?? {}
|
|
158
155
|
);
|
|
159
156
|
}
|
package/src/meta.js
CHANGED
package/src/report/csv.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { EOL } from "node:os";
|
|
1
2
|
import dependencyToIncidenceTransformer from "./utl/dependency-to-incidence-transformer.mjs";
|
|
2
3
|
|
|
3
4
|
function renderHeader(pModules) {
|
|
@@ -9,15 +10,15 @@ function mapIncidences(pIncidences) {
|
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
function renderBody(pModules) {
|
|
12
|
-
return pModules
|
|
13
|
-
(
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
return pModules
|
|
14
|
+
.map(
|
|
15
|
+
(pModule) => `"${pModule.source}",${mapIncidences(pModule.incidences)},""`
|
|
16
|
+
)
|
|
17
|
+
.join(EOL);
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
function report(pModules) {
|
|
20
|
-
return `"",${renderHeader(pModules)},""${renderBody(pModules)}
|
|
21
|
+
return `"",${renderHeader(pModules)},""${EOL}${renderBody(pModules)}${EOL}`;
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
/**
|
package/src/report/error.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { EOL } from "node:os";
|
|
1
2
|
import chalk from "chalk";
|
|
2
3
|
import figures from "figures";
|
|
3
4
|
import { findRuleByName } from "../graph-utl/rule-set.mjs";
|
|
@@ -17,9 +18,9 @@ const SEVERITY2CHALK = {
|
|
|
17
18
|
const EXTRA_PATH_INFORMATION_INDENT = 6;
|
|
18
19
|
|
|
19
20
|
function formatExtraPathInformation(pExtra) {
|
|
20
|
-
return
|
|
21
|
+
return EOL.concat(
|
|
21
22
|
wrapAndIndent(
|
|
22
|
-
pExtra.join(` ${figures.arrowRight}
|
|
23
|
+
pExtra.join(` ${figures.arrowRight} ${EOL}`),
|
|
23
24
|
EXTRA_PATH_INFORMATION_INDENT
|
|
24
25
|
)
|
|
25
26
|
);
|
|
@@ -48,7 +49,7 @@ function formatReachabilityViolation(pViolation) {
|
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
function formatInstabilityViolation(pViolation) {
|
|
51
|
-
return `${formatDependencyViolation(pViolation)}
|
|
52
|
+
return `${formatDependencyViolation(pViolation)}${EOL}${wrapAndIndent(
|
|
52
53
|
chalk.dim(
|
|
53
54
|
`instability: ${formatPercentage(pViolation.metrics.from.instability)} ${
|
|
54
55
|
figures.arrowRight
|
|
@@ -78,7 +79,7 @@ function formatViolation(pViolation) {
|
|
|
78
79
|
}: ${lFormattedViolators}` +
|
|
79
80
|
`${
|
|
80
81
|
pViolation.comment
|
|
81
|
-
?
|
|
82
|
+
? `${EOL}${wrapAndIndent(chalk.dim(pViolation.comment))}${EOL}`
|
|
82
83
|
: ""
|
|
83
84
|
}`
|
|
84
85
|
);
|
|
@@ -93,11 +94,11 @@ function sumMeta(pMeta) {
|
|
|
93
94
|
}
|
|
94
95
|
|
|
95
96
|
function formatSummary(pSummary) {
|
|
96
|
-
let lMessage =
|
|
97
|
+
let lMessage = `${EOL}${figures.cross} ${sumMeta(
|
|
97
98
|
pSummary
|
|
98
99
|
)} dependency violations (${formatMeta(pSummary)}). ${
|
|
99
100
|
pSummary.totalCruised
|
|
100
|
-
} modules, ${pSummary.totalDependenciesCruised} dependencies cruised
|
|
101
|
+
} modules, ${pSummary.totalDependenciesCruised} dependencies cruised.${EOL}`;
|
|
101
102
|
|
|
102
103
|
return pSummary.error > 0 ? chalk.red(lMessage) : lMessage;
|
|
103
104
|
}
|
|
@@ -114,7 +115,7 @@ function addExplanation(pRuleSet, pLong) {
|
|
|
114
115
|
function formatIgnoreWarning(pNumberOfIgnoredViolations) {
|
|
115
116
|
if (pNumberOfIgnoredViolations > 0) {
|
|
116
117
|
return chalk.yellow(
|
|
117
|
-
`${figures.warning} ${pNumberOfIgnoredViolations} known violations ignored. Run with --no-ignore-known to see them
|
|
118
|
+
`${figures.warning} ${pNumberOfIgnoredViolations} known violations ignored. Run with --no-ignore-known to see them.${EOL}`
|
|
118
119
|
);
|
|
119
120
|
}
|
|
120
121
|
return "";
|
|
@@ -126,22 +127,24 @@ function report(pResults, pLong) {
|
|
|
126
127
|
);
|
|
127
128
|
|
|
128
129
|
if (lNonIgnorableViolations.length === 0) {
|
|
129
|
-
return
|
|
130
|
+
return `${EOL}${chalk.green(
|
|
131
|
+
figures.tick
|
|
132
|
+
)} no dependency violations found (${
|
|
130
133
|
pResults.summary.totalCruised
|
|
131
134
|
} modules, ${
|
|
132
135
|
pResults.summary.totalDependenciesCruised
|
|
133
|
-
} dependencies cruised)
|
|
136
|
+
} dependencies cruised)${EOL}${formatIgnoreWarning(
|
|
134
137
|
pResults.summary.ignore
|
|
135
|
-
)}
|
|
138
|
+
)}${EOL}`;
|
|
136
139
|
}
|
|
137
140
|
|
|
138
141
|
return lNonIgnorableViolations
|
|
139
142
|
.reverse()
|
|
140
143
|
.map(addExplanation(pResults.summary.ruleSetUsed, pLong))
|
|
141
|
-
.reduce((pAll, pThis) => `${pAll} ${formatViolation(pThis)}
|
|
144
|
+
.reduce((pAll, pThis) => `${pAll} ${formatViolation(pThis)}${EOL}`, EOL)
|
|
142
145
|
.concat(formatSummary(pResults.summary))
|
|
143
146
|
.concat(formatIgnoreWarning(pResults.summary.ignore))
|
|
144
|
-
.concat(
|
|
147
|
+
.concat(EOL);
|
|
145
148
|
}
|
|
146
149
|
|
|
147
150
|
/**
|
package/src/report/text.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { EOL } from "node:os";
|
|
1
2
|
import figures from "figures";
|
|
2
3
|
import chalk from "chalk";
|
|
3
4
|
|
|
@@ -72,7 +73,7 @@ function report(pResults, pOptions) {
|
|
|
72
73
|
getModulesInFocus(pResults.modules),
|
|
73
74
|
lOptions.highlightFocused === true
|
|
74
75
|
).reduce(
|
|
75
|
-
(pAll, pDependency) => pAll.concat(stringify(pDependency)).concat(
|
|
76
|
+
(pAll, pDependency) => pAll.concat(stringify(pDependency)).concat(EOL),
|
|
76
77
|
""
|
|
77
78
|
);
|
|
78
79
|
}
|