dependency-cruiser 14.0.0 → 14.1.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/bin/depcruise-baseline.mjs +2 -2
- package/bin/depcruise-fmt.mjs +2 -2
- package/bin/dependency-cruise.mjs +2 -2
- package/package.json +18 -16
- package/src/cli/{validate-node-environment.mjs → assert-node-environment-suitable.mjs} +1 -1
- package/src/cli/index.mjs +1 -2
- package/src/cli/init-config/build-config.mjs +4 -3
- package/src/cli/init-config/get-user-input.mjs +8 -1
- package/src/cli/init-config/index.mjs +2 -0
- package/src/cli/init-config/types.d.ts +6 -0
- package/src/cli/normalize-cli-options.mjs +9 -10
- package/src/config-utl/extract-depcruise-config/index.mjs +10 -11
- package/src/config-utl/extract-depcruise-config/merge-configs.mjs +9 -9
- package/src/enrich/derive/reachable.mjs +12 -13
- package/src/enrich/summarize/add-rule-set-used.mjs +2 -4
- package/src/extract/gather-initial-sources.mjs +6 -8
- package/src/extract/resolve/index.mjs +19 -18
- package/src/extract/resolve/is-built-in.mjs +28 -0
- package/src/extract/resolve/merge-manifests.mjs +8 -7
- package/src/extract/resolve/resolve-amd.mjs +4 -11
- package/src/extract/resolve/resolve-cjs.mjs +2 -10
- package/src/graph-utl/consolidate-module-dependencies.mjs +4 -5
- package/src/graph-utl/consolidate-modules.mjs +3 -4
- package/src/graph-utl/filter-bank.mjs +5 -6
- package/src/main/cruise.mjs +12 -12
- package/src/main/format.mjs +3 -3
- package/src/main/helpers.mjs +3 -4
- package/src/main/options/{validate.mjs → assert-validity.mjs} +35 -35
- package/src/main/options/normalize.mjs +6 -7
- package/src/main/resolve-options/normalize.mjs +9 -5
- package/src/main/rule-set/{validate.mjs → assert-validity.mjs} +14 -13
- package/src/main/rule-set/normalize.mjs +1 -2
- package/src/meta.js +1 -1
- package/src/report/anon/index.mjs +5 -6
- package/src/report/dot/theming.mjs +5 -6
- package/src/schema/configuration.schema.mjs +1 -1
- package/src/schema/cruise-result.schema.mjs +1 -1
- package/types/options.d.ts +21 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { program } from "commander";
|
|
3
|
-
import
|
|
3
|
+
import assertNodeEnvironmentSuitable from "../src/cli/assert-node-environment-suitable.mjs";
|
|
4
4
|
import meta from "../src/meta.js";
|
|
5
5
|
import cli from "../src/cli/index.mjs";
|
|
6
6
|
|
|
@@ -10,7 +10,7 @@ function formatError(pError) {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
try {
|
|
13
|
-
|
|
13
|
+
assertNodeEnvironmentSuitable();
|
|
14
14
|
|
|
15
15
|
program
|
|
16
16
|
.description(
|
package/bin/depcruise-fmt.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { program } from "commander";
|
|
4
|
-
import
|
|
4
|
+
import assertNodeEnvironmentSuitable from "../src/cli/assert-node-environment-suitable.mjs";
|
|
5
5
|
import meta from "../src/meta.js";
|
|
6
6
|
import format from "../src/cli/format.mjs";
|
|
7
7
|
|
|
@@ -11,7 +11,7 @@ function formatError(pError) {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
try {
|
|
14
|
-
|
|
14
|
+
assertNodeEnvironmentSuitable();
|
|
15
15
|
|
|
16
16
|
program
|
|
17
17
|
.description(
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { EOL } from "node:os";
|
|
3
3
|
import { program } from "commander";
|
|
4
|
-
import
|
|
4
|
+
import assertNodeEnvironmentSuitable from "../src/cli/assert-node-environment-suitable.mjs";
|
|
5
5
|
import meta from "../src/meta.js";
|
|
6
6
|
import cli from "../src/cli/index.mjs";
|
|
7
7
|
|
|
8
8
|
try {
|
|
9
|
-
|
|
9
|
+
assertNodeEnvironmentSuitable();
|
|
10
10
|
|
|
11
11
|
program
|
|
12
12
|
.description(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dependency-cruiser",
|
|
3
|
-
"version": "14.
|
|
3
|
+
"version": "14.1.1",
|
|
4
4
|
"description": "Validate and visualize dependencies. With your rules. JavaScript, TypeScript, CoffeeScript. ES6, CommonJS, AMD.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"static analysis",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"license": "MIT",
|
|
30
30
|
"repository": {
|
|
31
31
|
"type": "git",
|
|
32
|
-
"url": "git+https://github.com/sverweij/dependency-cruiser"
|
|
32
|
+
"url": "git+https://github.com/sverweij/dependency-cruiser.git"
|
|
33
33
|
},
|
|
34
34
|
"bugs": {
|
|
35
35
|
"url": "https://github.com/sverweij/dependency-cruiser/issues"
|
|
@@ -172,29 +172,29 @@
|
|
|
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": "
|
|
175
|
+
"watskeburt": "2.0.0",
|
|
176
176
|
"wrap-ansi": "8.1.0"
|
|
177
177
|
},
|
|
178
178
|
"devDependencies": {
|
|
179
|
-
"@babel/core": "7.
|
|
180
|
-
"@babel/plugin-transform-modules-commonjs": "7.
|
|
181
|
-
"@babel/preset-typescript": "7.
|
|
182
|
-
"@swc/core": "1.3.
|
|
179
|
+
"@babel/core": "7.23.0",
|
|
180
|
+
"@babel/plugin-transform-modules-commonjs": "7.23.0",
|
|
181
|
+
"@babel/preset-typescript": "7.23.0",
|
|
182
|
+
"@swc/core": "1.3.92",
|
|
183
183
|
"@types/lodash": "4.14.199",
|
|
184
|
-
"@types/node": "20.
|
|
185
|
-
"@types/prompts": "2.4.
|
|
186
|
-
"@typescript-eslint/eslint-plugin": "6.7.
|
|
187
|
-
"@typescript-eslint/parser": "6.7.
|
|
184
|
+
"@types/node": "20.8.3",
|
|
185
|
+
"@types/prompts": "2.4.5",
|
|
186
|
+
"@typescript-eslint/eslint-plugin": "6.7.4",
|
|
187
|
+
"@typescript-eslint/parser": "6.7.4",
|
|
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.51.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",
|
|
195
195
|
"eslint-plugin-eslint-comments": "3.2.0",
|
|
196
196
|
"eslint-plugin-import": "2.28.1",
|
|
197
|
-
"eslint-plugin-mocha": "10.
|
|
197
|
+
"eslint-plugin-mocha": "10.2.0",
|
|
198
198
|
"eslint-plugin-node": "11.1.0",
|
|
199
199
|
"eslint-plugin-security": "1.7.1",
|
|
200
200
|
"eslint-plugin-unicorn": "^48.0.1",
|
|
@@ -210,15 +210,17 @@
|
|
|
210
210
|
"svelte": "3.59.1",
|
|
211
211
|
"symlink-dir": "5.2.0",
|
|
212
212
|
"typescript": "5.2.2",
|
|
213
|
-
"upem": "
|
|
213
|
+
"upem": "9.0.2",
|
|
214
214
|
"vue-template-compiler": "2.7.14",
|
|
215
215
|
"yarn": "1.22.19"
|
|
216
216
|
},
|
|
217
217
|
"overrides": {
|
|
218
|
-
"semver": "^7.5.4"
|
|
218
|
+
"semver": "^7.5.4",
|
|
219
|
+
"postcss": "^8.4.31"
|
|
219
220
|
},
|
|
220
221
|
"resolutions": {
|
|
221
|
-
"semver": "^7.5.4"
|
|
222
|
+
"semver": "^7.5.4",
|
|
223
|
+
"postcss": "^8.4.31"
|
|
222
224
|
},
|
|
223
225
|
"upem": {
|
|
224
226
|
"policies": [
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import satisfies from "semver/functions/satisfies.js";
|
|
2
2
|
import meta from "../meta.js";
|
|
3
3
|
|
|
4
|
-
export default function
|
|
4
|
+
export default function assertNodeEnvironmentSuitable(pNodeVersion) {
|
|
5
5
|
// not using default parameter here because the check should run
|
|
6
6
|
// run on node 4 as well
|
|
7
7
|
const lNodeVersion = pNodeVersion || process.versions.node;
|
package/src/cli/index.mjs
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
2
|
import picomatch from "picomatch";
|
|
3
|
-
import cloneDeep from "lodash/cloneDeep.js";
|
|
4
3
|
import set from "lodash/set.js";
|
|
5
4
|
import isInstalledGlobally from "is-installed-globally";
|
|
6
5
|
import chalk from "chalk";
|
|
@@ -44,7 +43,7 @@ async function addKnownViolations(pCruiseOptions) {
|
|
|
44
43
|
|
|
45
44
|
// Check against json schema is already done in src/main/options/validate
|
|
46
45
|
// so here we can just concentrate on the io
|
|
47
|
-
let lCruiseOptions =
|
|
46
|
+
let lCruiseOptions = structuredClone(pCruiseOptions);
|
|
48
47
|
set(lCruiseOptions, "ruleSet.options.knownViolations", lKnownViolations);
|
|
49
48
|
return lCruiseOptions;
|
|
50
49
|
}
|
|
@@ -135,9 +135,10 @@ function buildExtensionsAttribute(pInitOptions) {
|
|
|
135
135
|
* @returns {string}
|
|
136
136
|
*/
|
|
137
137
|
function buildMainFieldsAttribute(pInitOptions) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
138
|
+
if (pInitOptions.isTypeModule) {
|
|
139
|
+
return `mainFields: ["module", "main", "types", "typings"],`;
|
|
140
|
+
}
|
|
141
|
+
return `mainFields: ["main", "types", "typings"],`;
|
|
141
142
|
}
|
|
142
143
|
|
|
143
144
|
/**
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import prompts from "prompts";
|
|
3
3
|
import {
|
|
4
4
|
isLikelyMonoRepo,
|
|
5
|
+
isTypeModule,
|
|
5
6
|
getMonoRepoPackagesCandidates,
|
|
6
7
|
getSourceFolderCandidates,
|
|
7
8
|
getTestFolderCandidates,
|
|
@@ -33,6 +34,12 @@ const QUESTIONS = [
|
|
|
33
34
|
message: "This looks like mono repo. Is that correct?",
|
|
34
35
|
initial: isLikelyMonoRepo(),
|
|
35
36
|
},
|
|
37
|
+
{
|
|
38
|
+
name: "isTypeModule",
|
|
39
|
+
type: () => (isTypeModule() ? "confirm" : false),
|
|
40
|
+
message: "It looks like this is an ESM package. Is that correct?",
|
|
41
|
+
initial: isTypeModule(),
|
|
42
|
+
},
|
|
36
43
|
{
|
|
37
44
|
name: "sourceLocation",
|
|
38
45
|
type: (_, pAnswers) => (pAnswers.isMonoRepo ? "list" : false),
|
|
@@ -61,7 +68,7 @@ const QUESTIONS = [
|
|
|
61
68
|
initial: (_, pAnswers) => {
|
|
62
69
|
return !hasTestsWithinSource(
|
|
63
70
|
getTestFolderCandidates(),
|
|
64
|
-
toSourceLocationArray(pAnswers.sourceLocation)
|
|
71
|
+
toSourceLocationArray(pAnswers.sourceLocation),
|
|
65
72
|
);
|
|
66
73
|
},
|
|
67
74
|
},
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
getDefaultConfigFileName,
|
|
17
17
|
hasJSConfigCandidates,
|
|
18
18
|
getJSConfigCandidates,
|
|
19
|
+
isTypeModule,
|
|
19
20
|
} from "./environment-helpers.mjs";
|
|
20
21
|
import { writeRunScriptsToManifest } from "./write-run-scripts-to-manifest.mjs";
|
|
21
22
|
|
|
@@ -32,6 +33,7 @@ function getOneShotConfig(pOneShotConfigId) {
|
|
|
32
33
|
/** @type {import("./types").IPartialInitConfig} */
|
|
33
34
|
const lBaseConfig = {
|
|
34
35
|
isMonoRepo: isLikelyMonoRepo(),
|
|
36
|
+
isTypeModule: isTypeModule(),
|
|
35
37
|
combinedDependencies: false,
|
|
36
38
|
useJsConfig: hasJSConfigCandidates() && !hasTSConfigCandidates(),
|
|
37
39
|
jsConfig: getJSConfigCandidates().shift(),
|
|
@@ -5,6 +5,12 @@ export interface IInitConfig {
|
|
|
5
5
|
* Whether or not the current folder houses a mono repo
|
|
6
6
|
*/
|
|
7
7
|
isMonoRepo: boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Whether or not the current folder is a package is an ESM package
|
|
10
|
+
* by default (and resolutions of external dependencies should be
|
|
11
|
+
* treated as such)
|
|
12
|
+
*/
|
|
13
|
+
isTypeModule: boolean;
|
|
8
14
|
/**
|
|
9
15
|
* Whether or not you allow usage of external dependencies declared in
|
|
10
16
|
* package.jsons of parent folders
|
|
@@ -3,7 +3,6 @@ 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";
|
|
6
|
-
import clone from "lodash/clone.js";
|
|
7
6
|
import loadConfig from "../config-utl/extract-depcruise-config/index.mjs";
|
|
8
7
|
import {
|
|
9
8
|
RULES_FILE_NAME_SEARCH_ARRAY,
|
|
@@ -21,13 +20,13 @@ function getOptionValue(pDefault) {
|
|
|
21
20
|
}
|
|
22
21
|
|
|
23
22
|
function normalizeConfigFileName(pCliOptions, pConfigWrapperName, pDefault) {
|
|
24
|
-
let lOptions =
|
|
23
|
+
let lOptions = structuredClone(pCliOptions);
|
|
25
24
|
|
|
26
25
|
if (has(lOptions, pConfigWrapperName)) {
|
|
27
26
|
set(
|
|
28
27
|
lOptions,
|
|
29
28
|
`ruleSet.options.${pConfigWrapperName}.fileName`,
|
|
30
|
-
getOptionValue(pDefault)(lOptions[pConfigWrapperName])
|
|
29
|
+
getOptionValue(pDefault)(lOptions[pConfigWrapperName]),
|
|
31
30
|
/* eslint security/detect-object-injection: 0 */
|
|
32
31
|
);
|
|
33
32
|
Reflect.deleteProperty(lOptions, pConfigWrapperName);
|
|
@@ -61,7 +60,7 @@ function validateAndGetCustomRulesFileName(pValidate) {
|
|
|
61
60
|
throw new Error(
|
|
62
61
|
`Can't open config file '${pValidate}' for reading. Does it exist?\n` +
|
|
63
62
|
` - You can create a config file by running 'npx dependency-cruiser --init'\n` +
|
|
64
|
-
` - If you intended to run without a config file use --no-config\n
|
|
63
|
+
` - If you intended to run without a config file use --no-config\n`,
|
|
65
64
|
);
|
|
66
65
|
}
|
|
67
66
|
return lReturnValue;
|
|
@@ -74,7 +73,7 @@ function validateAndGetDefaultRulesFileName() {
|
|
|
74
73
|
throw new TypeError(
|
|
75
74
|
`Can't open a config file (.dependency-cruiser.(c)js) at the default location. Does it exist?\n` +
|
|
76
75
|
` - You can create one by running 'npx dependency-cruiser --init'\n` +
|
|
77
|
-
` - Want to run a without a config file? Use --no-config\n
|
|
76
|
+
` - Want to run a without a config file? Use --no-config\n`,
|
|
78
77
|
);
|
|
79
78
|
}
|
|
80
79
|
return lReturnValue;
|
|
@@ -103,7 +102,7 @@ function validateAndGetKnownViolationsFileName(pKnownViolations) {
|
|
|
103
102
|
} else {
|
|
104
103
|
throw new Error(
|
|
105
104
|
`Can't open '${lKnownViolationsFileName}' for reading. Does it exist?\n` +
|
|
106
|
-
` (You can create a .dependency-cruiser-known-violations.json with --output-type baseline)\n
|
|
105
|
+
` (You can create a .dependency-cruiser-known-violations.json with --output-type baseline)\n`,
|
|
107
106
|
);
|
|
108
107
|
}
|
|
109
108
|
}
|
|
@@ -114,7 +113,7 @@ function normalizeKnownViolationsOption(pCliOptions) {
|
|
|
114
113
|
}
|
|
115
114
|
return {
|
|
116
115
|
knownViolationsFile: validateAndGetKnownViolationsFileName(
|
|
117
|
-
pCliOptions.ignoreKnown
|
|
116
|
+
pCliOptions.ignoreKnown,
|
|
118
117
|
),
|
|
119
118
|
};
|
|
120
119
|
}
|
|
@@ -129,7 +128,7 @@ async function normalizeValidationOption(pCliOptions) {
|
|
|
129
128
|
return {
|
|
130
129
|
rulesFile,
|
|
131
130
|
ruleSet: await loadConfig(
|
|
132
|
-
isAbsolute(rulesFile) ? rulesFile : `./${rulesFile}
|
|
131
|
+
isAbsolute(rulesFile) ? rulesFile : `./${rulesFile}`,
|
|
133
132
|
),
|
|
134
133
|
validate: true,
|
|
135
134
|
};
|
|
@@ -157,7 +156,7 @@ function normalizeCacheStrategy(pCliOptions) {
|
|
|
157
156
|
let lReturnValue = {};
|
|
158
157
|
|
|
159
158
|
if (pCliOptions.cache && typeof pCliOptions.cache === "object") {
|
|
160
|
-
lReturnValue.cache =
|
|
159
|
+
lReturnValue.cache = structuredClone(pCliOptions.cache);
|
|
161
160
|
lReturnValue.cache.strategy = lStrategy;
|
|
162
161
|
} else {
|
|
163
162
|
lReturnValue = {
|
|
@@ -227,5 +226,5 @@ export default async function normalizeOptions(pOptionsAsPassedFromCommander) {
|
|
|
227
226
|
}
|
|
228
227
|
|
|
229
228
|
export const determineRulesFileName = getOptionValue(
|
|
230
|
-
OLD_DEFAULT_RULES_FILE_NAME
|
|
229
|
+
OLD_DEFAULT_RULES_FILE_NAME,
|
|
231
230
|
);
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { dirname } from "node:path";
|
|
2
|
-
import cloneDeep from "lodash/cloneDeep.js";
|
|
3
2
|
import has from "lodash/has.js";
|
|
4
3
|
import { resolve } from "../../extract/resolve/resolve.mjs";
|
|
5
4
|
import normalizeResolveOptions from "../../main/resolve-options/normalize.mjs";
|
|
@@ -8,7 +7,7 @@ import mergeConfigs from "./merge-configs.mjs";
|
|
|
8
7
|
|
|
9
8
|
/* eslint no-use-before-define: 0 */
|
|
10
9
|
async function processExtends(pReturnValue, pAlreadyVisited, pBaseDirectory) {
|
|
11
|
-
let lReturnValue =
|
|
10
|
+
let lReturnValue = structuredClone(pReturnValue);
|
|
12
11
|
|
|
13
12
|
if (typeof lReturnValue.extends === "string") {
|
|
14
13
|
lReturnValue = mergeConfigs(
|
|
@@ -16,8 +15,8 @@ async function processExtends(pReturnValue, pAlreadyVisited, pBaseDirectory) {
|
|
|
16
15
|
await extractDepcruiseConfig(
|
|
17
16
|
lReturnValue.extends,
|
|
18
17
|
pAlreadyVisited,
|
|
19
|
-
pBaseDirectory
|
|
20
|
-
)
|
|
18
|
+
pBaseDirectory,
|
|
19
|
+
),
|
|
21
20
|
);
|
|
22
21
|
}
|
|
23
22
|
|
|
@@ -26,7 +25,7 @@ async function processExtends(pReturnValue, pAlreadyVisited, pBaseDirectory) {
|
|
|
26
25
|
lReturnValue = mergeConfigs(
|
|
27
26
|
lReturnValue,
|
|
28
27
|
// eslint-disable-next-line no-await-in-loop
|
|
29
|
-
await extractDepcruiseConfig(lExtends, pAlreadyVisited, pBaseDirectory)
|
|
28
|
+
await extractDepcruiseConfig(lExtends, pAlreadyVisited, pBaseDirectory),
|
|
30
29
|
);
|
|
31
30
|
}
|
|
32
31
|
}
|
|
@@ -54,7 +53,7 @@ async function processExtends(pReturnValue, pAlreadyVisited, pBaseDirectory) {
|
|
|
54
53
|
export default async function extractDepcruiseConfig(
|
|
55
54
|
pConfigFileName,
|
|
56
55
|
pAlreadyVisited = new Set(),
|
|
57
|
-
pBaseDirectory = process.cwd()
|
|
56
|
+
pBaseDirectory = process.cwd(),
|
|
58
57
|
) {
|
|
59
58
|
const lResolvedFileName = resolve(
|
|
60
59
|
pConfigFileName,
|
|
@@ -63,17 +62,17 @@ export default async function extractDepcruiseConfig(
|
|
|
63
62
|
{
|
|
64
63
|
extensions: [".js", ".json", ".cjs", ".mjs"],
|
|
65
64
|
},
|
|
66
|
-
{}
|
|
65
|
+
{},
|
|
67
66
|
),
|
|
68
|
-
"cli"
|
|
67
|
+
"cli",
|
|
69
68
|
);
|
|
70
69
|
const lBaseDirectory = dirname(lResolvedFileName);
|
|
71
70
|
|
|
72
71
|
if (pAlreadyVisited.has(lResolvedFileName)) {
|
|
73
72
|
throw new Error(
|
|
74
73
|
`config is circular - ${[...pAlreadyVisited].join(
|
|
75
|
-
" -> "
|
|
76
|
-
)} -> ${lResolvedFileName}.\n
|
|
74
|
+
" -> ",
|
|
75
|
+
)} -> ${lResolvedFileName}.\n`,
|
|
77
76
|
);
|
|
78
77
|
}
|
|
79
78
|
pAlreadyVisited.add(lResolvedFileName);
|
|
@@ -84,7 +83,7 @@ export default async function extractDepcruiseConfig(
|
|
|
84
83
|
lReturnValue = await processExtends(
|
|
85
84
|
lReturnValue,
|
|
86
85
|
pAlreadyVisited,
|
|
87
|
-
lBaseDirectory
|
|
86
|
+
lBaseDirectory,
|
|
88
87
|
);
|
|
89
88
|
}
|
|
90
89
|
|
|
@@ -10,7 +10,7 @@ function extendNamedRule(pExtendedRule, pForbiddenArrayBase) {
|
|
|
10
10
|
...pBaseRule,
|
|
11
11
|
...pAll,
|
|
12
12
|
}),
|
|
13
|
-
pExtendedRule
|
|
13
|
+
pExtendedRule,
|
|
14
14
|
);
|
|
15
15
|
}
|
|
16
16
|
|
|
@@ -23,7 +23,7 @@ function extendNamedRule(pExtendedRule, pForbiddenArrayBase) {
|
|
|
23
23
|
* rules get merged, where individual attributes of the named rules
|
|
24
24
|
* in pForbiddenArrayExtended win)
|
|
25
25
|
*
|
|
26
|
-
* @param {*} pRuleArrayExtended - array of '
|
|
26
|
+
* @param {*} pRuleArrayExtended - array of 'forbidden' rules that extend the ...
|
|
27
27
|
* @param {*} pRuleArrayBase - array of 'forbidden' rules to extend
|
|
28
28
|
*
|
|
29
29
|
* @return {Array} - the merged array
|
|
@@ -32,7 +32,7 @@ function mergeRules(pRuleArrayExtended, pRuleArrayBase) {
|
|
|
32
32
|
// merge anonymous on 100% equality
|
|
33
33
|
let lAnonymousRules = uniqWith(
|
|
34
34
|
pRuleArrayExtended.concat(pRuleArrayBase).filter(({ name }) => !name),
|
|
35
|
-
isDeepStrictEqual
|
|
35
|
+
isDeepStrictEqual,
|
|
36
36
|
);
|
|
37
37
|
|
|
38
38
|
let lNamedRules = pRuleArrayExtended
|
|
@@ -48,7 +48,7 @@ function mergeRules(pRuleArrayExtended, pRuleArrayBase) {
|
|
|
48
48
|
// the other concats (anonymous, allowed) don't need it
|
|
49
49
|
// but have it to be consistent with this
|
|
50
50
|
lNamedRules.concat(pRuleArrayBase).filter(({ name }) => name),
|
|
51
|
-
({ name }) => name
|
|
51
|
+
({ name }) => name,
|
|
52
52
|
);
|
|
53
53
|
|
|
54
54
|
return lNamedRules.concat(lAnonymousRules);
|
|
@@ -67,7 +67,7 @@ function mergeRules(pRuleArrayExtended, pRuleArrayBase) {
|
|
|
67
67
|
function mergeAllowedRules(pAllowedArrayExtended, pAllowedArrayBase) {
|
|
68
68
|
return uniqWith(
|
|
69
69
|
pAllowedArrayExtended.concat(pAllowedArrayBase),
|
|
70
|
-
isDeepStrictEqual
|
|
70
|
+
isDeepStrictEqual,
|
|
71
71
|
);
|
|
72
72
|
}
|
|
73
73
|
|
|
@@ -109,15 +109,15 @@ function mergeAllowedSeverities(pConfigExtended, pConfigBase) {
|
|
|
109
109
|
export default (pConfigExtended, pConfigBase) => {
|
|
110
110
|
const lForbidden = mergeRules(
|
|
111
111
|
pConfigExtended?.forbidden ?? [],
|
|
112
|
-
pConfigBase?.forbidden ?? []
|
|
112
|
+
pConfigBase?.forbidden ?? [],
|
|
113
113
|
);
|
|
114
114
|
const lRequired = mergeRules(
|
|
115
115
|
pConfigExtended?.required ?? [],
|
|
116
|
-
pConfigBase?.required ?? []
|
|
116
|
+
pConfigBase?.required ?? [],
|
|
117
117
|
);
|
|
118
118
|
const lAllowed = mergeAllowedRules(
|
|
119
119
|
pConfigExtended?.allowed ?? [],
|
|
120
|
-
pConfigBase?.allowed ?? []
|
|
120
|
+
pConfigBase?.allowed ?? [],
|
|
121
121
|
);
|
|
122
122
|
|
|
123
123
|
return {
|
|
@@ -131,7 +131,7 @@ export default (pConfigExtended, pConfigBase) => {
|
|
|
131
131
|
: {}),
|
|
132
132
|
options: mergeOptions(
|
|
133
133
|
pConfigExtended?.options ?? {},
|
|
134
|
-
pConfigBase?.options ?? {}
|
|
134
|
+
pConfigBase?.options ?? {},
|
|
135
135
|
),
|
|
136
136
|
};
|
|
137
137
|
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
/* eslint-disable security/detect-object-injection, no-inline-comments */
|
|
2
|
-
import cloneDeep from "lodash/cloneDeep.js";
|
|
3
2
|
import has from "lodash/has.js";
|
|
4
3
|
import matchers from "../../validate/matchers.mjs";
|
|
5
4
|
import { extractGroups } from "../../utl/regex-util.mjs";
|
|
@@ -9,7 +8,7 @@ function getReachableRules(pRuleSet) {
|
|
|
9
8
|
return (pRuleSet?.forbidden ?? [])
|
|
10
9
|
.filter((pRule) => has(pRule.to, "reachable"))
|
|
11
10
|
.concat(
|
|
12
|
-
(pRuleSet?.allowed ?? []).filter((pRule) => has(pRule.to, "reachable"))
|
|
11
|
+
(pRuleSet?.allowed ?? []).filter((pRule) => has(pRule.to, "reachable")),
|
|
13
12
|
);
|
|
14
13
|
}
|
|
15
14
|
|
|
@@ -33,7 +32,7 @@ function isModuleInRuleTo(pRule, pModuleTo, pModuleFrom) {
|
|
|
33
32
|
function mergeReachableProperties(pModule, pRule, pPath, pModuleFrom) {
|
|
34
33
|
const lReachables = pModule.reachable || [];
|
|
35
34
|
const lIndexExistingReachable = lReachables.findIndex(
|
|
36
|
-
(pReachable) => pReachable.asDefinedInRule === pRule.name
|
|
35
|
+
(pReachable) => pReachable.asDefinedInRule === pRule.name,
|
|
37
36
|
);
|
|
38
37
|
const lIsReachable = pPath.length > 1;
|
|
39
38
|
|
|
@@ -53,7 +52,7 @@ function mergeReachableProperties(pModule, pRule, pPath, pModuleFrom) {
|
|
|
53
52
|
function mergeReachesProperties(pFromModule, pToModule, pRule, pPath) {
|
|
54
53
|
const lReaches = pFromModule.reaches || [];
|
|
55
54
|
const lIndexExistingReachable = lReaches.findIndex(
|
|
56
|
-
(pReachable) => pReachable.asDefinedInRule === pRule.name
|
|
55
|
+
(pReachable) => pReachable.asDefinedInRule === pRule.name,
|
|
57
56
|
);
|
|
58
57
|
|
|
59
58
|
if (lIndexExistingReachable > -1) {
|
|
@@ -84,7 +83,7 @@ function hasCapturingGroups(pRule) {
|
|
|
84
83
|
|
|
85
84
|
return Boolean(
|
|
86
85
|
(pRule?.to?.path ?? "").match(lCapturingGroupPlaceholderRe) ||
|
|
87
|
-
(pRule?.to?.pathNot ?? "").match(lCapturingGroupPlaceholderRe)
|
|
86
|
+
(pRule?.to?.pathNot ?? "").match(lCapturingGroupPlaceholderRe),
|
|
88
87
|
);
|
|
89
88
|
}
|
|
90
89
|
function shouldAddReachable(pRule, pModuleTo, pGraph) {
|
|
@@ -95,7 +94,7 @@ function shouldAddReachable(pRule, pModuleTo, pGraph) {
|
|
|
95
94
|
const lModulesFrom = pGraph.filter(isModuleInRuleFrom(pRule));
|
|
96
95
|
|
|
97
96
|
lReturnValue = lModulesFrom.some((pModuleFrom) =>
|
|
98
|
-
isModuleInRuleTo(pRule, pModuleTo, pModuleFrom)
|
|
97
|
+
isModuleInRuleTo(pRule, pModuleTo, pModuleFrom),
|
|
99
98
|
);
|
|
100
99
|
} else {
|
|
101
100
|
lReturnValue = isModuleInRuleTo(pRule, pModuleTo);
|
|
@@ -106,7 +105,7 @@ function shouldAddReachable(pRule, pModuleTo, pGraph) {
|
|
|
106
105
|
|
|
107
106
|
function addReachesToModule(pModule, pGraph, pIndexedGraph, pReachableRule) {
|
|
108
107
|
const lToModules = pGraph.filter((pToModule) =>
|
|
109
|
-
isModuleInRuleTo(pReachableRule, pToModule, pModule)
|
|
108
|
+
isModuleInRuleTo(pReachableRule, pToModule, pModule),
|
|
110
109
|
);
|
|
111
110
|
|
|
112
111
|
for (let lToModule of lToModules) {
|
|
@@ -118,7 +117,7 @@ function addReachesToModule(pModule, pGraph, pIndexedGraph, pReachableRule) {
|
|
|
118
117
|
pModule,
|
|
119
118
|
lToModule,
|
|
120
119
|
pReachableRule,
|
|
121
|
-
lPath
|
|
120
|
+
lPath,
|
|
122
121
|
);
|
|
123
122
|
}
|
|
124
123
|
}
|
|
@@ -143,7 +142,7 @@ function addReachableToModule(pModule, pGraph, pIndexedGraph, pReachableRule) {
|
|
|
143
142
|
pModule,
|
|
144
143
|
pReachableRule,
|
|
145
144
|
lPath,
|
|
146
|
-
lFromModule.source
|
|
145
|
+
lFromModule.source,
|
|
147
146
|
);
|
|
148
147
|
}
|
|
149
148
|
}
|
|
@@ -152,14 +151,14 @@ function addReachableToModule(pModule, pGraph, pIndexedGraph, pReachableRule) {
|
|
|
152
151
|
|
|
153
152
|
function addReachabilityToGraph(pGraph, pIndexedGraph, pReachableRule) {
|
|
154
153
|
return pGraph.map((pModule) => {
|
|
155
|
-
let lClonedModule =
|
|
154
|
+
let lClonedModule = structuredClone(pModule);
|
|
156
155
|
|
|
157
156
|
if (shouldAddReaches(pReachableRule, lClonedModule)) {
|
|
158
157
|
lClonedModule = addReachesToModule(
|
|
159
158
|
lClonedModule,
|
|
160
159
|
pGraph,
|
|
161
160
|
pIndexedGraph,
|
|
162
|
-
pReachableRule
|
|
161
|
+
pReachableRule,
|
|
163
162
|
);
|
|
164
163
|
}
|
|
165
164
|
if (shouldAddReachable(pReachableRule, lClonedModule, pGraph)) {
|
|
@@ -167,7 +166,7 @@ function addReachabilityToGraph(pGraph, pIndexedGraph, pReachableRule) {
|
|
|
167
166
|
lClonedModule,
|
|
168
167
|
pGraph,
|
|
169
168
|
pIndexedGraph,
|
|
170
|
-
pReachableRule
|
|
169
|
+
pReachableRule,
|
|
171
170
|
);
|
|
172
171
|
}
|
|
173
172
|
return lClonedModule;
|
|
@@ -182,6 +181,6 @@ export default function deriveReachables(pGraph, pRuleSet) {
|
|
|
182
181
|
return lReachableRules.reduce(
|
|
183
182
|
(pReturnGraph, pRule) =>
|
|
184
183
|
addReachabilityToGraph(pReturnGraph, lIndexedGraph, pRule),
|
|
185
|
-
|
|
184
|
+
structuredClone(pGraph),
|
|
186
185
|
);
|
|
187
186
|
}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import clone from "lodash/clone.js";
|
|
2
|
-
|
|
3
1
|
// the fixed name for allowed rules served a purpose during the extraction
|
|
4
2
|
// process - but it's not necessary to reflect it in the output.
|
|
5
3
|
function removeNames(pRule) {
|
|
6
|
-
const lReturnValue =
|
|
4
|
+
const lReturnValue = structuredClone(pRule);
|
|
7
5
|
|
|
8
6
|
Reflect.deleteProperty(lReturnValue, "name");
|
|
9
7
|
return lReturnValue;
|
|
@@ -19,6 +17,6 @@ export default function addRuleSetUsed(pOptions) {
|
|
|
19
17
|
lForbidden ? { forbidden: lForbidden } : {},
|
|
20
18
|
lAllowed ? { allowed: lAllowed.map(removeNames) } : {},
|
|
21
19
|
lAllowedSeverity ? { allowedSeverity: lAllowedSeverity } : {},
|
|
22
|
-
lRequired ? { required: lRequired } : {}
|
|
20
|
+
lRequired ? { required: lRequired } : {},
|
|
23
21
|
);
|
|
24
22
|
}
|
|
@@ -47,23 +47,21 @@ function gatherScannableFilesFromDirectory(pDirectoryName, pOptions) {
|
|
|
47
47
|
.filter((pFullPathToFile) =>
|
|
48
48
|
shouldNotBeExcluded(pathToPosix(pFullPathToFile), pOptions),
|
|
49
49
|
)
|
|
50
|
-
.
|
|
50
|
+
.flatMap((pFullPathToFile) => {
|
|
51
51
|
let lStat = statSync(join(pOptions.baseDir, pFullPathToFile), {
|
|
52
52
|
throwIfNoEntry: false,
|
|
53
53
|
});
|
|
54
54
|
|
|
55
55
|
if (lStat) {
|
|
56
56
|
if (lStat.isDirectory()) {
|
|
57
|
-
return
|
|
58
|
-
gatherScannableFilesFromDirectory(pFullPathToFile, pOptions),
|
|
59
|
-
);
|
|
57
|
+
return gatherScannableFilesFromDirectory(pFullPathToFile, pOptions);
|
|
60
58
|
}
|
|
61
59
|
if (fileIsScannable(pOptions, pFullPathToFile)) {
|
|
62
|
-
return
|
|
60
|
+
return pFullPathToFile;
|
|
63
61
|
}
|
|
64
62
|
}
|
|
65
|
-
return
|
|
66
|
-
}
|
|
63
|
+
return [];
|
|
64
|
+
})
|
|
67
65
|
.map((pFullPathToFile) => pathToPosix(pFullPathToFile))
|
|
68
66
|
.filter((pFullPathToFile) => shouldBeIncluded(pFullPathToFile, pOptions));
|
|
69
67
|
}
|
|
@@ -108,7 +106,7 @@ export default function gatherInitialSources(
|
|
|
108
106
|
if (lScannedGlob.isGlob) {
|
|
109
107
|
return expandGlob(lOptions.baseDir, lScannedGlob);
|
|
110
108
|
}
|
|
111
|
-
return
|
|
109
|
+
return normalize(pFileDirectoryOrGlob);
|
|
112
110
|
})
|
|
113
111
|
.flatMap((pFileOrDirectory) => {
|
|
114
112
|
if (statSync(join(lOptions.baseDir, pFileOrDirectory)).isDirectory()) {
|