dependency-cruiser 13.1.4 → 14.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dependency-cruiser",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "14.0.0",
|
|
4
4
|
"description": "Validate and visualize dependencies. With your rules. JavaScript, TypeScript, CoffeeScript. ES6, CommonJS, AMD.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"static analysis",
|
|
@@ -158,13 +158,13 @@
|
|
|
158
158
|
"commander": "11.0.0",
|
|
159
159
|
"enhanced-resolve": "5.15.0",
|
|
160
160
|
"figures": "5.0.0",
|
|
161
|
-
"glob": "10.3.3",
|
|
162
161
|
"ignore": "5.2.4",
|
|
163
162
|
"indent-string": "5.0.0",
|
|
164
163
|
"interpret": "^3.1.1",
|
|
165
164
|
"is-installed-globally": "0.4.0",
|
|
166
165
|
"json5": "2.2.3",
|
|
167
166
|
"lodash": "4.17.21",
|
|
167
|
+
"picomatch": "2.3.1",
|
|
168
168
|
"prompts": "2.4.2",
|
|
169
169
|
"rechoir": "^0.8.0",
|
|
170
170
|
"safe-regex": "2.1.1",
|
|
@@ -172,23 +172,23 @@
|
|
|
172
172
|
"semver-try-require": "6.2.3",
|
|
173
173
|
"teamcity-service-messages": "0.1.14",
|
|
174
174
|
"tsconfig-paths-webpack-plugin": "4.1.0",
|
|
175
|
-
"watskeburt": "0.
|
|
175
|
+
"watskeburt": "1.0.1",
|
|
176
176
|
"wrap-ansi": "8.1.0"
|
|
177
177
|
},
|
|
178
178
|
"devDependencies": {
|
|
179
|
-
"@babel/core": "7.22.
|
|
180
|
-
"@babel/plugin-transform-modules-commonjs": "7.22.
|
|
181
|
-
"@babel/preset-typescript": "7.22.
|
|
182
|
-
"@swc/core": "1.3.
|
|
183
|
-
"@types/lodash": "4.14.
|
|
184
|
-
"@types/node": "20.
|
|
179
|
+
"@babel/core": "7.22.20",
|
|
180
|
+
"@babel/plugin-transform-modules-commonjs": "7.22.15",
|
|
181
|
+
"@babel/preset-typescript": "7.22.15",
|
|
182
|
+
"@swc/core": "1.3.87",
|
|
183
|
+
"@types/lodash": "4.14.199",
|
|
184
|
+
"@types/node": "20.6.3",
|
|
185
185
|
"@types/prompts": "2.4.4",
|
|
186
|
-
"@typescript-eslint/eslint-plugin": "6.
|
|
187
|
-
"@typescript-eslint/parser": "6.
|
|
186
|
+
"@typescript-eslint/eslint-plugin": "6.7.2",
|
|
187
|
+
"@typescript-eslint/parser": "6.7.2",
|
|
188
188
|
"@vue/compiler-sfc": "3.3.4",
|
|
189
189
|
"c8": "8.0.1",
|
|
190
190
|
"coffeescript": "2.7.0",
|
|
191
|
-
"eslint": "8.
|
|
191
|
+
"eslint": "8.50.0",
|
|
192
192
|
"eslint-config-moving-meadow": "4.0.2",
|
|
193
193
|
"eslint-config-prettier": "9.0.0",
|
|
194
194
|
"eslint-plugin-budapestian": "5.0.1",
|
|
@@ -200,16 +200,16 @@
|
|
|
200
200
|
"eslint-plugin-unicorn": "^48.0.1",
|
|
201
201
|
"husky": "8.0.3",
|
|
202
202
|
"intercept-stdout": "0.1.2",
|
|
203
|
-
"lint-staged": "14.0.
|
|
203
|
+
"lint-staged": "14.0.1",
|
|
204
204
|
"mocha": "10.2.0",
|
|
205
205
|
"normalize-newline": "4.1.0",
|
|
206
206
|
"npm-run-all": "4.1.5",
|
|
207
|
-
"prettier": "3.0.
|
|
207
|
+
"prettier": "3.0.3",
|
|
208
208
|
"proxyquire": "2.1.3",
|
|
209
209
|
"shx": "0.3.4",
|
|
210
210
|
"svelte": "3.59.1",
|
|
211
|
-
"symlink-dir": "5.
|
|
212
|
-
"typescript": "5.
|
|
211
|
+
"symlink-dir": "5.2.0",
|
|
212
|
+
"typescript": "5.2.2",
|
|
213
213
|
"upem": "8.0.0",
|
|
214
214
|
"vue-template-compiler": "2.7.14",
|
|
215
215
|
"yarn": "1.22.19"
|
|
@@ -240,7 +240,7 @@
|
|
|
240
240
|
]
|
|
241
241
|
},
|
|
242
242
|
"engines": {
|
|
243
|
-
"node": "^
|
|
243
|
+
"node": "^18.17||>=20"
|
|
244
244
|
},
|
|
245
245
|
"supportedTranspilers": {
|
|
246
246
|
"babel": ">=7.0.0 <8.0.0",
|
package/src/cli/format.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import _format from "../main/format.mjs";
|
|
2
|
-
import
|
|
2
|
+
import assertFileExistence from "./utl/assert-file-existence.mjs";
|
|
3
3
|
import normalizeOptions from "./normalize-cli-options.mjs";
|
|
4
4
|
import { getInStream, write } from "./utl/io.mjs";
|
|
5
5
|
|
|
@@ -13,7 +13,7 @@ export default async function format(pResultFile, pOptions) {
|
|
|
13
13
|
const lOptions = await normalizeOptions(pOptions);
|
|
14
14
|
|
|
15
15
|
if (pResultFile !== "-") {
|
|
16
|
-
|
|
16
|
+
assertFileExistence(pResultFile);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
return new Promise((pResolve, pReject) => {
|
|
@@ -29,13 +29,13 @@ export default async function format(pResultFile, pOptions) {
|
|
|
29
29
|
/* c8 ignore start */
|
|
30
30
|
(pError) => {
|
|
31
31
|
pReject(pError);
|
|
32
|
-
}
|
|
32
|
+
},
|
|
33
33
|
/* c8 ignore stop */
|
|
34
34
|
)
|
|
35
35
|
.on("end", async () => {
|
|
36
36
|
const lReportingResult = await _format(
|
|
37
37
|
JSON.parse(lInputAsString),
|
|
38
|
-
lOptions
|
|
38
|
+
lOptions,
|
|
39
39
|
);
|
|
40
40
|
|
|
41
41
|
write(lOptions.outputTo, lReportingResult.output);
|
package/src/cli/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
|
-
import
|
|
2
|
+
import picomatch from "picomatch";
|
|
3
3
|
import cloneDeep from "lodash/cloneDeep.js";
|
|
4
4
|
import set from "lodash/set.js";
|
|
5
5
|
import isInstalledGlobally from "is-installed-globally";
|
|
@@ -8,7 +8,7 @@ import chalk from "chalk";
|
|
|
8
8
|
import cruise from "../main/cruise.mjs";
|
|
9
9
|
import { INFO, bus } from "../utl/bus.mjs";
|
|
10
10
|
|
|
11
|
-
import
|
|
11
|
+
import assertFileExistence from "./utl/assert-file-existence.mjs";
|
|
12
12
|
import normalizeCliOptions from "./normalize-cli-options.mjs";
|
|
13
13
|
import { write } from "./utl/io.mjs";
|
|
14
14
|
import setUpCliFeedbackListener from "./listeners/cli-feedback.mjs";
|
|
@@ -27,7 +27,7 @@ async function extractResolveOptions(pCruiseOptions) {
|
|
|
27
27
|
lResolveOptions = await extractWebpackResolveConfig(
|
|
28
28
|
lWebPackConfigFileName,
|
|
29
29
|
pCruiseOptions?.ruleSet?.options?.webpackConfig?.env ?? null,
|
|
30
|
-
pCruiseOptions?.ruleSet?.options?.webpackConfig?.arguments ?? null
|
|
30
|
+
pCruiseOptions?.ruleSet?.options?.webpackConfig?.arguments ?? null,
|
|
31
31
|
);
|
|
32
32
|
}
|
|
33
33
|
return lResolveOptions;
|
|
@@ -39,7 +39,7 @@ async function addKnownViolations(pCruiseOptions) {
|
|
|
39
39
|
"../config-utl/extract-known-violations.mjs"
|
|
40
40
|
);
|
|
41
41
|
const lKnownViolations = await extractKnownViolations(
|
|
42
|
-
pCruiseOptions.knownViolationsFile
|
|
42
|
+
pCruiseOptions.knownViolationsFile,
|
|
43
43
|
);
|
|
44
44
|
|
|
45
45
|
// Check against json schema is already done in src/main/options/validate
|
|
@@ -95,24 +95,24 @@ function setUpListener(pCruiseOptions) {
|
|
|
95
95
|
if (Boolean(lListenerFunction)) {
|
|
96
96
|
lListenerFunction(
|
|
97
97
|
bus,
|
|
98
|
-
pCruiseOptions?.ruleSet?.options?.progress?.maximumLevel ?? INFO
|
|
98
|
+
pCruiseOptions?.ruleSet?.options?.progress?.maximumLevel ?? INFO,
|
|
99
99
|
);
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
async function runCruise(pFileDirectoryArray, pCruiseOptions) {
|
|
104
104
|
const lCruiseOptions = await addKnownViolations(
|
|
105
|
-
await normalizeCliOptions(pCruiseOptions)
|
|
105
|
+
await normalizeCliOptions(pCruiseOptions),
|
|
106
106
|
);
|
|
107
107
|
|
|
108
108
|
pFileDirectoryArray
|
|
109
|
-
.filter((pFileOrDirectory) => !
|
|
109
|
+
.filter((pFileOrDirectory) => !picomatch.scan(pFileOrDirectory).isGlob)
|
|
110
110
|
.map((pFileOrDirectory) =>
|
|
111
111
|
lCruiseOptions?.ruleSet?.options?.baseDir
|
|
112
112
|
? join(lCruiseOptions.ruleSet.options.baseDir, pFileOrDirectory)
|
|
113
|
-
: pFileOrDirectory
|
|
113
|
+
: pFileOrDirectory,
|
|
114
114
|
)
|
|
115
|
-
.forEach(
|
|
115
|
+
.forEach(assertFileExistence);
|
|
116
116
|
|
|
117
117
|
setUpListener(lCruiseOptions);
|
|
118
118
|
|
|
@@ -126,7 +126,7 @@ async function runCruise(pFileDirectoryArray, pCruiseOptions) {
|
|
|
126
126
|
pFileDirectoryArray,
|
|
127
127
|
lCruiseOptions,
|
|
128
128
|
lResolveOptions,
|
|
129
|
-
{ tsConfig, babelConfig }
|
|
129
|
+
{ tsConfig, babelConfig },
|
|
130
130
|
);
|
|
131
131
|
|
|
132
132
|
bus.progress("cli: writing results", { complete: 1 });
|
|
@@ -151,14 +151,14 @@ export default async function executeCli(pFileDirectoryArray, pCruiseOptions) {
|
|
|
151
151
|
if (isInstalledGlobally) {
|
|
152
152
|
process.stderr.write(
|
|
153
153
|
`\n ${chalk.yellow(
|
|
154
|
-
"WARNING"
|
|
154
|
+
"WARNING",
|
|
155
155
|
)}: You're running a globally installed dependency-cruiser.\n\n` +
|
|
156
156
|
` We recommend to ${chalk.bold.italic.underline(
|
|
157
|
-
"install and run it as a local devDependency"
|
|
157
|
+
"install and run it as a local devDependency",
|
|
158
158
|
)} in\n` +
|
|
159
159
|
` your project instead. There it has your project's environment and\n` +
|
|
160
160
|
` transpilers at its disposal. That will ensure it can find e.g.\n` +
|
|
161
|
-
` TypeScript, Vue or Svelte modules and dependencies.\n\n
|
|
161
|
+
` TypeScript, Vue or Svelte modules and dependencies.\n\n`,
|
|
162
162
|
);
|
|
163
163
|
}
|
|
164
164
|
/* c8 ignore stop */
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { accessSync, R_OK } from "node:fs";
|
|
2
2
|
|
|
3
|
-
export default function
|
|
3
|
+
export default function assertFileExistence(pDirectoryOrFile) {
|
|
4
4
|
try {
|
|
5
5
|
accessSync(pDirectoryOrFile, R_OK);
|
|
6
6
|
} catch (pError) {
|
|
7
7
|
throw new Error(
|
|
8
|
-
`Can't open '${pDirectoryOrFile}' for reading. Does it exist?\n
|
|
8
|
+
`Can't open '${pDirectoryOrFile}' for reading. Does it exist?\n`,
|
|
9
9
|
);
|
|
10
10
|
}
|
|
11
11
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readdirSync, statSync } from "node:fs";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
import
|
|
2
|
+
import { join, normalize } from "node:path";
|
|
3
|
+
import picomatch from "picomatch";
|
|
4
4
|
import { filenameMatchesPattern } from "../graph-utl/match-facade.mjs";
|
|
5
5
|
import getExtension from "../utl/get-extension.mjs";
|
|
6
6
|
import pathToPosix from "../utl/path-to-posix.mjs";
|
|
@@ -45,7 +45,7 @@ function gatherScannableFilesFromDirectory(pDirectoryName, pOptions) {
|
|
|
45
45
|
return readdirSync(join(pOptions.baseDir, pDirectoryName))
|
|
46
46
|
.map((pFileName) => join(pDirectoryName, pFileName))
|
|
47
47
|
.filter((pFullPathToFile) =>
|
|
48
|
-
shouldNotBeExcluded(pathToPosix(pFullPathToFile), pOptions)
|
|
48
|
+
shouldNotBeExcluded(pathToPosix(pFullPathToFile), pOptions),
|
|
49
49
|
)
|
|
50
50
|
.reduce((pSum, pFullPathToFile) => {
|
|
51
51
|
let lStat = statSync(join(pOptions.baseDir, pFullPathToFile), {
|
|
@@ -55,7 +55,7 @@ function gatherScannableFilesFromDirectory(pDirectoryName, pOptions) {
|
|
|
55
55
|
if (lStat) {
|
|
56
56
|
if (lStat.isDirectory()) {
|
|
57
57
|
return pSum.concat(
|
|
58
|
-
gatherScannableFilesFromDirectory(pFullPathToFile, pOptions)
|
|
58
|
+
gatherScannableFilesFromDirectory(pFullPathToFile, pOptions),
|
|
59
59
|
);
|
|
60
60
|
}
|
|
61
61
|
if (fileIsScannable(pOptions, pFullPathToFile)) {
|
|
@@ -68,6 +68,15 @@ function gatherScannableFilesFromDirectory(pDirectoryName, pOptions) {
|
|
|
68
68
|
.filter((pFullPathToFile) => shouldBeIncluded(pFullPathToFile, pOptions));
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
function expandGlob(pBaseDirectory, pScannedGlob) {
|
|
72
|
+
const isMatch = picomatch(pathToPosix(pScannedGlob.glob));
|
|
73
|
+
return readdirSync(join(pBaseDirectory, pScannedGlob.base), {
|
|
74
|
+
recursive: true,
|
|
75
|
+
})
|
|
76
|
+
.filter((pFile) => isMatch(pFile))
|
|
77
|
+
.map((pFile) => pathToPosix(join(pScannedGlob.base, pFile)));
|
|
78
|
+
}
|
|
79
|
+
|
|
71
80
|
/**
|
|
72
81
|
* Returns an array of strings, representing paths to files to be gathered
|
|
73
82
|
*
|
|
@@ -78,7 +87,7 @@ function gatherScannableFilesFromDirectory(pDirectoryName, pOptions) {
|
|
|
78
87
|
* Files and directories are assumed to be either absolute, or relative to the
|
|
79
88
|
* current working directory.
|
|
80
89
|
*
|
|
81
|
-
* @param {string[]}
|
|
90
|
+
* @param {string[]} pFileDirectoryAndGlobArray globs and/ or paths to files or
|
|
82
91
|
* directories to be gathered
|
|
83
92
|
* @param {import('../../types/dependency-cruiser.js').IStrictCruiseOptions} pOptions options that
|
|
84
93
|
* influence what needs to be gathered/ scanned
|
|
@@ -87,31 +96,26 @@ function gatherScannableFilesFromDirectory(pDirectoryName, pOptions) {
|
|
|
87
96
|
* - includeOnly - regexp what to include
|
|
88
97
|
* @return {string[]} paths to files to be gathered.
|
|
89
98
|
*/
|
|
90
|
-
export default function gatherInitialSources(
|
|
99
|
+
export default function gatherInitialSources(
|
|
100
|
+
pFileDirectoryAndGlobArray,
|
|
101
|
+
pOptions,
|
|
102
|
+
) {
|
|
91
103
|
const lOptions = { baseDir: process.cwd(), ...pOptions };
|
|
92
104
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
(
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
cwd: pathToPosix(lOptions.baseDir),
|
|
103
|
-
})
|
|
104
|
-
),
|
|
105
|
-
[]
|
|
106
|
-
)
|
|
107
|
-
.reduce((pAll, pFileOrDirectory) => {
|
|
105
|
+
return pFileDirectoryAndGlobArray
|
|
106
|
+
.flatMap((pFileDirectoryOrGlob) => {
|
|
107
|
+
const lScannedGlob = picomatch.scan(pFileDirectoryOrGlob);
|
|
108
|
+
if (lScannedGlob.isGlob) {
|
|
109
|
+
return expandGlob(lOptions.baseDir, lScannedGlob);
|
|
110
|
+
}
|
|
111
|
+
return pathToPosix(normalize(pFileDirectoryOrGlob));
|
|
112
|
+
})
|
|
113
|
+
.flatMap((pFileOrDirectory) => {
|
|
108
114
|
if (statSync(join(lOptions.baseDir, pFileOrDirectory)).isDirectory()) {
|
|
109
|
-
return
|
|
110
|
-
gatherScannableFilesFromDirectory(pFileOrDirectory, lOptions)
|
|
111
|
-
);
|
|
112
|
-
} else {
|
|
113
|
-
return pAll.concat(pathToPosix(pFileOrDirectory));
|
|
115
|
+
return gatherScannableFilesFromDirectory(pFileOrDirectory, lOptions);
|
|
114
116
|
}
|
|
115
|
-
|
|
117
|
+
// Not a glob anymore, and not a directory => it's a file
|
|
118
|
+
return pathToPosix(pFileOrDirectory);
|
|
119
|
+
})
|
|
116
120
|
.sort();
|
|
117
121
|
}
|