dependency-cruiser 17.3.2 → 17.3.3-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/bin/depcruise-baseline.mjs +43 -43
- package/bin/depcruise-fmt.mjs +89 -89
- package/bin/dependency-cruise.mjs +171 -171
- package/configs/plugins/3d-reporter-plugin.mjs +36 -36
- package/configs/plugins/stats-reporter-plugin.mjs +51 -51
- package/configs/recommended-strict.cjs +5 -5
- package/configs/recommended-warn-only.cjs +5 -5
- package/configs/recommended.cjs +22 -22
- package/configs/rules/no-circular.cjs +10 -10
- package/configs/rules/no-deprecated-core.cjs +10 -10
- package/configs/rules/no-duplicate-dependency-types.cjs +17 -17
- package/configs/rules/no-non-package-json.cjs +11 -11
- package/configs/rules/no-orphans.cjs +18 -18
- package/configs/rules/not-to-deprecated.cjs +10 -10
- package/configs/rules/not-to-unresolvable.cjs +10 -10
- package/package.json +170 -170
- package/src/cache/cache.mjs +139 -139
- package/src/cache/content-strategy.mjs +88 -88
- package/src/cache/find-content-changes.mjs +58 -58
- package/src/cache/helpers.mjs +52 -52
- package/src/cache/metadata-strategy.mjs +83 -83
- package/src/cache/options-compatible.mjs +56 -109
- package/src/cli/assert-node-environment-suitable.mjs +7 -7
- package/src/cli/defaults.mjs +5 -5
- package/src/cli/format-meta-info.mjs +22 -22
- package/src/cli/format.mjs +28 -28
- package/src/cli/index.mjs +145 -145
- package/src/cli/init-config/build-config.mjs +94 -94
- package/src/cli/init-config/environment-helpers.mjs +77 -77
- package/src/cli/init-config/find-extensions.mjs +27 -27
- package/src/cli/init-config/get-user-input.mjs +151 -151
- package/src/cli/init-config/index.mjs +88 -88
- package/src/cli/init-config/normalize-init-options.mjs +47 -47
- package/src/cli/init-config/utl.mjs +4 -4
- package/src/cli/init-config/validators.mjs +10 -10
- package/src/cli/init-config/write-config.mjs +21 -21
- package/src/cli/init-config/write-run-scripts-to-manifest.mjs +103 -107
- package/src/cli/listeners/cli-feedback.mjs +49 -49
- package/src/cli/listeners/ndjson.mjs +66 -66
- package/src/cli/listeners/performance-log/format-helpers.mjs +63 -63
- package/src/cli/listeners/performance-log/handlers.mjs +56 -56
- package/src/cli/listeners/performance-log/index.mjs +37 -37
- package/src/cli/normalize-cli-options.mjs +182 -182
- package/src/cli/tools/wrap-stream-in-html.mjs +37 -37
- package/src/cli/utl/assert-file-existence.mjs +7 -7
- package/src/cli/utl/io.mjs +28 -31
- package/src/config-utl/extract-babel-config.mjs +69 -69
- package/src/config-utl/extract-depcruise-config/index.mjs +54 -54
- package/src/config-utl/extract-depcruise-config/merge-configs.mjs +63 -63
- package/src/config-utl/extract-depcruise-config/read-config.mjs +9 -9
- package/src/config-utl/extract-depcruise-options.mjs +9 -9
- package/src/config-utl/extract-known-violations.mjs +49 -49
- package/src/config-utl/extract-ts-config.mjs +46 -48
- package/src/config-utl/extract-webpack-resolve-config.mjs +88 -88
- package/src/config-utl/make-absolute.mjs +5 -5
- package/src/enrich/add-validations.mjs +13 -13
- package/src/enrich/derive/circular.mjs +49 -49
- package/src/enrich/derive/dependents.mjs +27 -27
- package/src/enrich/derive/folders/aggregate-to-folders.mjs +104 -104
- package/src/enrich/derive/folders/index.mjs +19 -19
- package/src/enrich/derive/folders/utl.mjs +18 -18
- package/src/enrich/derive/metrics/get-module-metrics.mjs +27 -27
- package/src/enrich/derive/metrics/index.mjs +8 -8
- package/src/enrich/derive/module-utl.mjs +18 -18
- package/src/enrich/derive/orphan/index.mjs +18 -18
- package/src/enrich/derive/orphan/is-orphan.mjs +9 -9
- package/src/enrich/derive/reachable.mjs +165 -168
- package/src/enrich/enrich-modules.mjs +25 -25
- package/src/enrich/index.mjs +15 -15
- package/src/enrich/soften-known-violations.mjs +90 -90
- package/src/enrich/summarize/add-rule-set-used.mjs +13 -13
- package/src/enrich/summarize/get-stats.mjs +17 -17
- package/src/enrich/summarize/index.mjs +18 -18
- package/src/enrich/summarize/is-same-violation.mjs +30 -30
- package/src/enrich/summarize/summarize-folders.mjs +35 -35
- package/src/enrich/summarize/summarize-modules.mjs +97 -97
- package/src/enrich/summarize/summarize-options.mjs +71 -71
- package/src/extract/acorn/estree-helpers.mjs +66 -66
- package/src/extract/acorn/extract-amd-deps.mjs +63 -64
- package/src/extract/acorn/extract-cjs-deps.mjs +83 -83
- package/src/extract/acorn/extract-es6-deps.mjs +54 -54
- package/src/extract/acorn/extract-stats.mjs +4 -4
- package/src/extract/acorn/extract.mjs +28 -28
- package/src/extract/acorn/parse.mjs +37 -37
- package/src/extract/clear-caches.mjs +7 -7
- package/src/extract/extract-dependencies.mjs +109 -109
- package/src/extract/extract-stats.mjs +21 -21
- package/src/extract/gather-initial-sources.mjs +64 -64
- package/src/extract/helpers.mjs +73 -71
- package/src/extract/index.mjs +120 -120
- package/src/extract/resolve/determine-dependency-types.mjs +166 -169
- package/src/extract/resolve/external-module-helpers.mjs +76 -76
- package/src/extract/resolve/get-manifest.mjs +79 -79
- package/src/extract/resolve/index.mjs +175 -164
- package/src/extract/resolve/is-built-in.mjs +22 -24
- package/src/extract/resolve/merge-manifests.mjs +43 -43
- package/src/extract/resolve/module-classifiers.mjs +229 -229
- package/src/extract/resolve/resolve-amd.mjs +44 -44
- package/src/extract/resolve/resolve-cjs.mjs +40 -40
- package/src/extract/resolve/resolve-helpers.mjs +20 -20
- package/src/extract/resolve/resolve.mjs +26 -26
- package/src/extract/swc/dependency-visitor.mjs +211 -211
- package/src/extract/swc/extract-swc-deps.mjs +4 -4
- package/src/extract/swc/extract.mjs +7 -7
- package/src/extract/swc/parse.mjs +12 -12
- package/src/extract/transpile/babel-wrap.mjs +9 -9
- package/src/extract/transpile/coffeescript-wrap.mjs +21 -21
- package/src/extract/transpile/index.mjs +47 -47
- package/src/extract/transpile/javascript-wrap.mjs +6 -6
- package/src/extract/transpile/livescript-wrap.mjs +5 -5
- package/src/extract/transpile/meta.mjs +80 -80
- package/src/extract/transpile/svelte-preprocess.mjs +73 -73
- package/src/extract/transpile/svelte-wrap.mjs +19 -19
- package/src/extract/transpile/try-import-available.mjs +26 -27
- package/src/extract/transpile/typescript-wrap.mjs +39 -39
- package/src/extract/transpile/vue-template-wrap.cjs +43 -43
- package/src/extract/tsc/extract-stats.mjs +4 -4
- package/src/extract/tsc/extract-typescript-deps.mjs +429 -398
- package/src/extract/tsc/extract.mjs +22 -22
- package/src/extract/tsc/parse.mjs +21 -21
- package/src/graph-utl/add-focus.mjs +35 -35
- package/src/graph-utl/compare.mjs +24 -24
- package/src/graph-utl/consolidate-module-dependencies.mjs +35 -35
- package/src/graph-utl/consolidate-modules.mjs +33 -33
- package/src/graph-utl/consolidate-to-folder.mjs +13 -13
- package/src/graph-utl/consolidate-to-pattern.mjs +34 -34
- package/src/graph-utl/filter-bank.mjs +74 -69
- package/src/graph-utl/indexed-module-graph.mjs +227 -225
- package/src/graph-utl/match-facade.mjs +3 -3
- package/src/graph-utl/rule-set.mjs +20 -20
- package/src/graph-utl/strip-self-transitions.mjs +6 -6
- package/src/main/cruise.mjs +81 -81
- package/src/main/files-and-dirs/normalize.mjs +7 -7
- package/src/main/format.mjs +11 -14
- package/src/main/helpers.mjs +25 -25
- package/src/main/index.mjs +8 -8
- package/src/main/options/assert-validity.mjs +100 -100
- package/src/main/options/defaults.mjs +11 -11
- package/src/main/options/normalize.mjs +158 -160
- package/src/main/report-wrap.mjs +37 -37
- package/src/main/resolve-options/normalize.mjs +127 -128
- package/src/main/rule-set/assert-validity.mjs +67 -73
- package/src/main/rule-set/normalize.mjs +81 -79
- package/src/meta.cjs +15 -16
- package/src/report/anon/anonymize-path-element.mjs +20 -34
- package/src/report/anon/anonymize-path.mjs +11 -11
- package/src/report/anon/index.mjs +119 -119
- package/src/report/anon/random-string.mjs +23 -23
- package/src/report/azure-devops.mjs +75 -99
- package/src/report/baseline.mjs +9 -9
- package/src/report/csv.mjs +13 -13
- package/src/report/d2.mjs +105 -105
- package/src/report/dot/default-theme.mjs +152 -152
- package/src/report/dot/index.mjs +146 -146
- package/src/report/dot/module-utl.mjs +72 -72
- package/src/report/dot/prepare-custom-level.mjs +20 -20
- package/src/report/dot/prepare-flat-level.mjs +11 -11
- package/src/report/dot/prepare-folder-level.mjs +12 -13
- package/src/report/dot/theming.mjs +73 -73
- package/src/report/dot-webpage/dot-module.mjs +36 -36
- package/src/report/dot-webpage/svg-in-html-snippets/script.cjs +208 -210
- package/src/report/dot-webpage/svg-in-html-snippets/style.css +51 -51
- package/src/report/dot-webpage/wrap-in-html.mjs +7 -7
- package/src/report/error-html/index.mjs +49 -49
- package/src/report/error-html/utl.mjs +99 -99
- package/src/report/error-long.mjs +1 -1
- package/src/report/error.mjs +93 -93
- package/src/report/html/index.mjs +48 -48
- package/src/report/identity.mjs +4 -4
- package/src/report/index.mjs +33 -33
- package/src/report/json.mjs +4 -4
- package/src/report/markdown.mjs +120 -120
- package/src/report/mermaid.mjs +111 -111
- package/src/report/metrics.mjs +185 -185
- package/src/report/null.mjs +4 -4
- package/src/report/plugins.mjs +41 -41
- package/src/report/teamcity.mjs +150 -150
- package/src/report/text.mjs +42 -42
- package/src/report/utl/dependency-to-incidence-transformer.mjs +32 -32
- package/src/report/utl/index.mjs +53 -53
- package/src/schema/configuration.validate.mjs +1 -0
- package/src/schema/cruise-result.validate.mjs +1 -0
- package/src/schema/utl.mjs +6 -0
- package/src/utl/array-util.mjs +25 -25
- package/src/utl/bus.mjs +12 -12
- package/src/utl/extract-root-module-name.cjs +8 -8
- package/src/utl/find-all-files.mjs +54 -54
- package/src/utl/get-extension.mjs +2 -2
- package/src/utl/object-util.mjs +21 -22
- package/src/utl/path-to-posix.mjs +5 -5
- package/src/utl/regex-util.mjs +20 -20
- package/src/utl/try-import.mjs +42 -41
- package/src/utl/try-require.cjs +23 -23
- package/src/utl/wrap-and-indent.mjs +33 -33
- package/src/validate/index.mjs +65 -65
- package/src/validate/match-dependency-rule.mjs +47 -47
- package/src/validate/match-folder-dependency-rule.mjs +27 -27
- package/src/validate/match-module-rule-helpers.mjs +76 -76
- package/src/validate/match-module-rule.mjs +12 -12
- package/src/validate/matchers.mjs +162 -162
- package/src/validate/rule-classifiers.mjs +9 -9
- package/src/validate/violates-required-rule.mjs +23 -23
- package/types/cache-options.d.mts +27 -27
- package/types/config-utl/extract-babel-config.d.mts +1 -1
- package/types/config-utl/extract-depcruise-config.d.mts +3 -3
- package/types/config-utl/extract-depcruise-options.d.mts +1 -1
- package/types/config-utl/extract-ts-config.d.mts +1 -1
- package/types/config-utl/extract-webpack-resolve-config.d.mts +3 -3
- package/types/configuration.d.mts +10 -10
- package/types/cruise-result.d.mts +414 -414
- package/types/dependency-cruiser.d.mts +52 -52
- package/types/filter-types.d.mts +45 -45
- package/types/options.d.mts +430 -430
- package/types/plugins/3d-reporter-plugin.d.mts +9 -9
- package/types/plugins/mermaid-reporter-plugin.d.mts +10 -10
- package/types/plugins/stats-reporter-plugin.d.mts +9 -9
- package/types/reporter-options.d.mts +196 -196
- package/types/resolve-options.d.mts +23 -23
- package/types/restrictions.d.mts +174 -174
- package/types/rule-set.d.mts +132 -132
- package/types/rule-summary.d.mts +14 -14
- package/types/shared-types.d.mts +89 -89
- package/types/strict-filter-types.d.mts +52 -52
- package/types/strict-options.d.mts +34 -34
- package/types/strict-restrictions.d.mts +25 -25
- package/types/strict-rule-set.d.mts +36 -36
- package/types/violations.d.mts +40 -40
- package/src/schema/README.md +0 -5
- package/src/schema/baseline-violations.schema.mjs +0 -1
- package/src/schema/configuration.schema.mjs +0 -1
- package/src/schema/cruise-result.schema.mjs +0 -1
- package/types/README.md +0 -1
|
@@ -7,68 +7,68 @@ import tryImport from "#utl/try-import.mjs";
|
|
|
7
7
|
import meta from "#meta.cjs";
|
|
8
8
|
|
|
9
9
|
async function getJSConfig(pBabelConfigFileName) {
|
|
10
|
-
|
|
10
|
+
let lReturnValue = {};
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
12
|
+
try {
|
|
13
|
+
const { default: lModule } = await import(
|
|
14
|
+
`file://${makeAbsolute(pBabelConfigFileName)}`
|
|
15
|
+
);
|
|
16
|
+
lReturnValue = lModule;
|
|
17
|
+
} catch (pError) {
|
|
18
|
+
throw new Error(
|
|
19
|
+
`${
|
|
20
|
+
`Encountered an error while parsing babel config '${pBabelConfigFileName}':` +
|
|
21
|
+
`\n\n ${pError}`
|
|
22
|
+
}\n\n At this time dependency-cruiser only supports babel configurations\n in either commonjs or json5.\n`,
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
26
|
+
if (typeof lReturnValue === "function") {
|
|
27
|
+
// Function format configs not supported yet. Will need calling the
|
|
28
|
+
// function with a bunch of params (lReturnValue = lReturnValue(APIPAPI))
|
|
29
|
+
throw new TypeError(
|
|
30
|
+
`The babel config '${pBabelConfigFileName}' returns a function. At this time\n` +
|
|
31
|
+
` dependency-cruiser doesn't support that yet.`,
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
return lReturnValue;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
async function getJSON5Config(pBabelConfigFileName) {
|
|
38
|
-
|
|
38
|
+
let lReturnValue = {};
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
40
|
+
try {
|
|
41
|
+
lReturnValue = json5.parse(await readFile(pBabelConfigFileName, "utf8"));
|
|
42
|
+
} catch (pError) {
|
|
43
|
+
throw new Error(
|
|
44
|
+
`Encountered an error while parsing the babel config '${pBabelConfigFileName}':` +
|
|
45
|
+
`\n\n ${pError}\n`,
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
if (pBabelConfigFileName.endsWith("package.json")) {
|
|
50
|
+
lReturnValue = lReturnValue?.babel ?? {};
|
|
51
|
+
}
|
|
52
|
+
return lReturnValue;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
async function getConfig(pBabelConfigFileName) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
56
|
+
const lExtensionToParseFunction = new Map([
|
|
57
|
+
[".js", getJSConfig],
|
|
58
|
+
[".cjs", getJSConfig],
|
|
59
|
+
[".mjs", getJSConfig],
|
|
60
|
+
["", getJSON5Config],
|
|
61
|
+
[".json", getJSON5Config],
|
|
62
|
+
[".json5", getJSON5Config],
|
|
63
|
+
]);
|
|
64
|
+
const lExtension = extname(pBabelConfigFileName);
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
66
|
+
if (!lExtensionToParseFunction.has(lExtension)) {
|
|
67
|
+
throw new Error(
|
|
68
|
+
`${`The babel config '${pBabelConfigFileName}' is in a format ('${lExtension}')\n`} dependency-cruiser doesn't support yet.\n`,
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
return await lExtensionToParseFunction.get(lExtension)(pBabelConfigFileName);
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
/**
|
|
@@ -84,24 +84,24 @@ async function getConfig(pBabelConfigFileName) {
|
|
|
84
84
|
* when dependency-cruiser can't yet process it
|
|
85
85
|
*/
|
|
86
86
|
export default async function extractBabelConfig(pBabelConfigFileName) {
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
let lReturnValue = {};
|
|
88
|
+
const babel = await tryImport("@babel/core", meta.supportedTranspilers.babel);
|
|
89
89
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
90
|
+
if (babel) {
|
|
91
|
+
const lConfig = {
|
|
92
|
+
...(await getConfig(pBabelConfigFileName)),
|
|
93
|
+
// under some circumstances babel (and/ or its plugins) needs
|
|
94
|
+
// a filename to go with the config - so we pass it
|
|
95
|
+
filename: pBabelConfigFileName,
|
|
96
|
+
};
|
|
97
|
+
lReturnValue = {
|
|
98
|
+
...babel.loadOptions(lConfig),
|
|
99
|
+
// according to the babel documentation a config parsed & expanded through
|
|
100
|
+
// loadOptions can be passed to the parser. With some plugins/ presets
|
|
101
|
+
// this does not seem to be true anymore, though
|
|
102
|
+
...(lConfig.presets ? { presets: lConfig.presets } : {}),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
105
|
|
|
106
|
-
|
|
106
|
+
return lReturnValue;
|
|
107
107
|
}
|
|
@@ -6,30 +6,30 @@ import { resolve } from "#extract/resolve/resolve.mjs";
|
|
|
6
6
|
|
|
7
7
|
/* eslint no-use-before-define: 0 */
|
|
8
8
|
async function processExtends(pReturnValue, pAlreadyVisited, pBaseDirectory) {
|
|
9
|
-
|
|
9
|
+
let lReturnValue = structuredClone(pReturnValue);
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
11
|
+
if (typeof lReturnValue.extends === "string") {
|
|
12
|
+
lReturnValue = mergeConfigs(
|
|
13
|
+
lReturnValue,
|
|
14
|
+
await extractDepcruiseConfig(
|
|
15
|
+
lReturnValue.extends,
|
|
16
|
+
pAlreadyVisited,
|
|
17
|
+
pBaseDirectory,
|
|
18
|
+
),
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
22
|
+
if (Array.isArray(lReturnValue.extends)) {
|
|
23
|
+
for (const lExtends of lReturnValue.extends) {
|
|
24
|
+
lReturnValue = mergeConfigs(
|
|
25
|
+
lReturnValue,
|
|
26
|
+
// eslint-disable-next-line no-await-in-loop
|
|
27
|
+
await extractDepcruiseConfig(lExtends, pAlreadyVisited, pBaseDirectory),
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
Reflect.deleteProperty(lReturnValue, "extends");
|
|
32
|
+
return lReturnValue;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
/**
|
|
@@ -51,41 +51,41 @@ async function processExtends(pReturnValue, pAlreadyVisited, pBaseDirectory) {
|
|
|
51
51
|
* @throws {Error} when the config is not valid (/ does not exist/ isn't readable)
|
|
52
52
|
*/
|
|
53
53
|
export default async function extractDepcruiseConfig(
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
pConfigFileName,
|
|
55
|
+
pAlreadyVisited = new Set(),
|
|
56
|
+
pBaseDirectory = process.cwd(),
|
|
57
57
|
) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
58
|
+
const lResolvedFileName = resolve(
|
|
59
|
+
pConfigFileName,
|
|
60
|
+
pBaseDirectory,
|
|
61
|
+
await normalizeResolveOptions(
|
|
62
|
+
{
|
|
63
|
+
extensions: [".js", ".json", ".cjs", ".mjs"],
|
|
64
|
+
},
|
|
65
|
+
{},
|
|
66
|
+
),
|
|
67
|
+
"cli",
|
|
68
|
+
);
|
|
69
|
+
const lBaseDirectory = dirname(lResolvedFileName);
|
|
70
70
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
71
|
+
if (pAlreadyVisited.has(lResolvedFileName)) {
|
|
72
|
+
throw new Error(
|
|
73
|
+
`config is circular - ${[...pAlreadyVisited].join(
|
|
74
|
+
" -> ",
|
|
75
|
+
)} -> ${lResolvedFileName}.\n`,
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
pAlreadyVisited.add(lResolvedFileName);
|
|
79
79
|
|
|
80
|
-
|
|
80
|
+
let lReturnValue = await readConfig(lResolvedFileName);
|
|
81
81
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
82
|
+
if (lReturnValue?.extends) {
|
|
83
|
+
lReturnValue = await processExtends(
|
|
84
|
+
lReturnValue,
|
|
85
|
+
pAlreadyVisited,
|
|
86
|
+
lBaseDirectory,
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
return lReturnValue;
|
|
91
91
|
}
|
|
@@ -2,15 +2,15 @@ import { isDeepStrictEqual } from "node:util";
|
|
|
2
2
|
import { uniqBy, uniqWith } from "#utl/array-util.mjs";
|
|
3
3
|
|
|
4
4
|
function extendNamedRule(pExtendedRule, pForbiddenArrayBase) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
5
|
+
return pForbiddenArrayBase
|
|
6
|
+
.filter(({ name }) => name === pExtendedRule.name)
|
|
7
|
+
.reduce(
|
|
8
|
+
(pAll, pBaseRule) => ({
|
|
9
|
+
...pBaseRule,
|
|
10
|
+
...pAll,
|
|
11
|
+
}),
|
|
12
|
+
pExtendedRule,
|
|
13
|
+
);
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
/**
|
|
@@ -28,29 +28,29 @@ function extendNamedRule(pExtendedRule, pForbiddenArrayBase) {
|
|
|
28
28
|
* @return {Array} - the merged array
|
|
29
29
|
*/
|
|
30
30
|
function mergeRules(pRuleArrayExtended, pRuleArrayBase) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
// merge anonymous on 100% equality
|
|
32
|
+
let lAnonymousRules = uniqWith(
|
|
33
|
+
pRuleArrayExtended.concat(pRuleArrayBase).filter(({ name }) => !name),
|
|
34
|
+
isDeepStrictEqual,
|
|
35
|
+
);
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
let lNamedRules = pRuleArrayExtended
|
|
38
|
+
.filter(({ name }) => name)
|
|
39
|
+
.map((pNamedRule) => extendNamedRule(pNamedRule, pRuleArrayBase));
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
// merge named rules based on unique name
|
|
42
|
+
lNamedRules = uniqBy(
|
|
43
|
+
// ordered extended => base because the uniqBy picks the
|
|
44
|
+
// first it encounters and we want the ones from the
|
|
45
|
+
// extended in case of a conflict
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
// the other concats (anonymous, allowed) don't need it
|
|
48
|
+
// but have it to be consistent with this
|
|
49
|
+
lNamedRules.concat(pRuleArrayBase).filter(({ name }) => name),
|
|
50
|
+
({ name }) => name,
|
|
51
|
+
);
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
return lNamedRules.concat(lAnonymousRules);
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
/**
|
|
@@ -64,15 +64,15 @@ function mergeRules(pRuleArrayExtended, pRuleArrayBase) {
|
|
|
64
64
|
* @return {Array} - the merged array
|
|
65
65
|
*/
|
|
66
66
|
function mergeAllowedRules(pAllowedArrayExtended, pAllowedArrayBase) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
return uniqWith(
|
|
68
|
+
pAllowedArrayExtended.concat(pAllowedArrayBase),
|
|
69
|
+
isDeepStrictEqual,
|
|
70
|
+
);
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
function mergeOptions(pOptionsExtended, pOptionsBase) {
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
// TODO: make implementation less naive (?)
|
|
75
|
+
return { ...pOptionsBase, ...pOptionsExtended };
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
/**
|
|
@@ -85,9 +85,9 @@ function mergeOptions(pOptionsExtended, pOptionsBase) {
|
|
|
85
85
|
* @returns {string} - a string from the SeverityType value set
|
|
86
86
|
*/
|
|
87
87
|
function mergeAllowedSeverities(pConfigExtended, pConfigBase) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
return (
|
|
89
|
+
pConfigExtended?.allowedSeverity ?? pConfigBase?.allowedSeverity ?? "warn"
|
|
90
|
+
);
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
/**
|
|
@@ -106,31 +106,31 @@ function mergeAllowedSeverities(pConfigExtended, pConfigBase) {
|
|
|
106
106
|
*/
|
|
107
107
|
// eslint-disable-next-line complexity
|
|
108
108
|
export default (pConfigExtended, pConfigBase) => {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
109
|
+
const lForbidden = mergeRules(
|
|
110
|
+
pConfigExtended?.forbidden ?? [],
|
|
111
|
+
pConfigBase?.forbidden ?? [],
|
|
112
|
+
);
|
|
113
|
+
const lRequired = mergeRules(
|
|
114
|
+
pConfigExtended?.required ?? [],
|
|
115
|
+
pConfigBase?.required ?? [],
|
|
116
|
+
);
|
|
117
|
+
const lAllowed = mergeAllowedRules(
|
|
118
|
+
pConfigExtended?.allowed ?? [],
|
|
119
|
+
pConfigBase?.allowed ?? [],
|
|
120
|
+
);
|
|
121
121
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
122
|
+
return {
|
|
123
|
+
...(lForbidden.length > 0 ? { forbidden: lForbidden } : {}),
|
|
124
|
+
...(lRequired.length > 0 ? { required: lRequired } : {}),
|
|
125
|
+
...(lAllowed.length > 0
|
|
126
|
+
? {
|
|
127
|
+
allowed: lAllowed,
|
|
128
|
+
allowedSeverity: mergeAllowedSeverities(pConfigExtended, pConfigBase),
|
|
129
|
+
}
|
|
130
|
+
: {}),
|
|
131
|
+
options: mergeOptions(
|
|
132
|
+
pConfigExtended?.options ?? {},
|
|
133
|
+
pConfigBase?.options ?? {},
|
|
134
|
+
),
|
|
135
|
+
};
|
|
136
136
|
};
|
|
@@ -8,13 +8,13 @@ import json5 from "json5";
|
|
|
8
8
|
* @returns {Promise<import('../../../types/configuration.mjs').IConfiguration>}
|
|
9
9
|
*/
|
|
10
10
|
export default async function readConfig(pAbsolutePathToConfigFile) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
11
|
+
if (
|
|
12
|
+
[".js", ".cjs", ".mjs", ""].includes(extname(pAbsolutePathToConfigFile))
|
|
13
|
+
) {
|
|
14
|
+
const { default: config } = await import(
|
|
15
|
+
`file://${pAbsolutePathToConfigFile}`
|
|
16
|
+
);
|
|
17
|
+
return config;
|
|
18
|
+
}
|
|
19
|
+
return json5.parse(await readFile(pAbsolutePathToConfigFile, "utf8"));
|
|
20
20
|
}
|
|
@@ -10,15 +10,15 @@ import extractDepcruiseConfig from "./extract-depcruise-config/index.mjs";
|
|
|
10
10
|
* @returns {ICruiseOptions}
|
|
11
11
|
*/
|
|
12
12
|
function configuration2options(pConfiguration) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
/* c8 ignore next 1 */
|
|
14
|
+
const lConfiguration = structuredClone(pConfiguration || {});
|
|
15
|
+
const lReturnValue = structuredClone(lConfiguration?.options ?? {});
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
delete lConfiguration.options;
|
|
18
|
+
lReturnValue.ruleSet = structuredClone(lConfiguration);
|
|
19
|
+
lReturnValue.validate = Object.keys(lReturnValue.ruleSet).length > 0;
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
return lReturnValue;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
/**
|
|
@@ -27,6 +27,6 @@ function configuration2options(pConfiguration) {
|
|
|
27
27
|
* @returns {Promise<ICruiseOptions>}
|
|
28
28
|
*/
|
|
29
29
|
export default async function extractDepcruiseOptions(pConfigFileName) {
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
const lReturnValue = await extractDepcruiseConfig(pConfigFileName);
|
|
31
|
+
return configuration2options(lReturnValue);
|
|
32
32
|
}
|
|
@@ -20,58 +20,58 @@ import makeAbsolute from "./make-absolute.mjs";
|
|
|
20
20
|
* @returns {IViolation}
|
|
21
21
|
*/
|
|
22
22
|
function makeForwardCompatible(pKnownViolation) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
23
|
+
let lReturnValue = pKnownViolation;
|
|
24
|
+
if (pKnownViolation.cycle) {
|
|
25
|
+
lReturnValue = {
|
|
26
|
+
...pKnownViolation,
|
|
27
|
+
cycle: pKnownViolation.cycle.map((pModule) => {
|
|
28
|
+
if (pModule.name) {
|
|
29
|
+
return pModule;
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
name: pModule,
|
|
33
|
+
dependencyTypes: [],
|
|
34
|
+
};
|
|
35
|
+
}),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
if (pKnownViolation.via) {
|
|
39
|
+
lReturnValue = {
|
|
40
|
+
...pKnownViolation,
|
|
41
|
+
via: pKnownViolation.via.map((pModule) => {
|
|
42
|
+
if (pModule.name) {
|
|
43
|
+
return pModule;
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
name: pModule,
|
|
47
|
+
dependencyTypes: [],
|
|
48
|
+
};
|
|
49
|
+
}),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
return lReturnValue;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
export default async function extractKnownViolations(pKnownViolationsFileName) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
56
|
+
try {
|
|
57
|
+
const lFileContents = await readFile(
|
|
58
|
+
makeAbsolute(pKnownViolationsFileName),
|
|
59
|
+
"utf8",
|
|
60
|
+
);
|
|
61
|
+
const lKnownViolations = json5.parse(lFileContents);
|
|
62
|
+
const lForwardCompatible = lKnownViolations.map(makeForwardCompatible);
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
64
|
+
return lForwardCompatible;
|
|
65
|
+
} catch (pError) {
|
|
66
|
+
if (pError instanceof SyntaxError) {
|
|
67
|
+
throw new SyntaxError(
|
|
68
|
+
`'${pKnownViolationsFileName}' should be valid json\n ${pError}`,
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
throw pError;
|
|
72
|
+
}
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
// TODO: validate the json against the schema? (might be more clear to do it here,
|
|
75
|
+
// even if (in context of the cli) it's done again when validating the whole
|
|
76
|
+
// config
|
|
77
77
|
}
|