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
|
@@ -3,22 +3,22 @@ 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 {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
findFolderByName,
|
|
7
|
+
getAfferentCouplings,
|
|
8
|
+
getEfferentCouplings,
|
|
9
|
+
getParentFolders,
|
|
10
|
+
object2Array,
|
|
11
11
|
} from "./utl.mjs";
|
|
12
12
|
import IndexedModuleGraph from "#graph-utl/indexed-module-graph.mjs";
|
|
13
13
|
import { uniq } from "#utl/array-util.mjs";
|
|
14
14
|
|
|
15
15
|
function upsertCouplings(pAllDependents, pNewDependents) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
for (const lNewDependent of pNewDependents) {
|
|
17
|
+
pAllDependents[lNewDependent] = pAllDependents[lNewDependent] || {
|
|
18
|
+
count: 0,
|
|
19
|
+
};
|
|
20
|
+
pAllDependents[lNewDependent].count += 1;
|
|
21
|
+
}
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
/**
|
|
@@ -30,108 +30,108 @@ function upsertCouplings(pAllDependents, pNewDependents) {
|
|
|
30
30
|
*/
|
|
31
31
|
|
|
32
32
|
function upsertFolderAttributes(pAllMetrics, pModule, pDirname) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
pAllMetrics[pDirname] = pAllMetrics[pDirname] || {
|
|
34
|
+
dependencies: {},
|
|
35
|
+
dependents: {},
|
|
36
|
+
moduleCount: 0,
|
|
37
|
+
};
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
39
|
+
upsertCouplings(
|
|
40
|
+
pAllMetrics[pDirname].dependents,
|
|
41
|
+
getAfferentCouplings(pModule, pDirname),
|
|
42
|
+
);
|
|
43
|
+
upsertCouplings(
|
|
44
|
+
pAllMetrics[pDirname].dependencies,
|
|
45
|
+
getEfferentCouplings(pModule, pDirname).map(
|
|
46
|
+
(pDependency) => pDependency.resolved,
|
|
47
|
+
),
|
|
48
|
+
);
|
|
49
|
+
pAllMetrics[pDirname].moduleCount += 1;
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
51
|
+
if (pModule.experimentalStats) {
|
|
52
|
+
if (!Object.hasOwn(pAllMetrics[pDirname], "experimentalStats")) {
|
|
53
|
+
pAllMetrics[pDirname].experimentalStats = {
|
|
54
|
+
size: 0,
|
|
55
|
+
topLevelStatementCount: 0,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
pAllMetrics[pDirname].experimentalStats.size +=
|
|
59
|
+
pModule.experimentalStats.size;
|
|
60
|
+
pAllMetrics[pDirname].experimentalStats.topLevelStatementCount +=
|
|
61
|
+
pModule.experimentalStats.topLevelStatementCount;
|
|
62
|
+
}
|
|
63
|
+
return pAllMetrics;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
function aggregateToFolder(pAllFolders, pModule) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
for (const lParentDirectory of getParentFolders(dirname(pModule.source))) {
|
|
68
|
+
upsertFolderAttributes(pAllFolders, pModule, lParentDirectory);
|
|
69
|
+
}
|
|
70
|
+
return pAllFolders;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
function sumCounts(pAll, pCurrent) {
|
|
74
|
-
|
|
74
|
+
return pAll + pCurrent.count;
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
function getFolderLevelCouplings(pCouplingArray) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
78
|
+
return uniq(
|
|
79
|
+
pCouplingArray.map((pCoupling) =>
|
|
80
|
+
dirname(pCoupling.name) === "."
|
|
81
|
+
? pCoupling.name
|
|
82
|
+
: dirname(pCoupling.name),
|
|
83
|
+
),
|
|
84
|
+
).map((pCoupling) => ({ name: pCoupling }));
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
function calculateFolderMetrics(pFolder) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
88
|
+
const lModuleDependents = object2Array(pFolder.dependents);
|
|
89
|
+
const lModuleDependencies = object2Array(pFolder.dependencies);
|
|
90
|
+
// this calculation might look superfluous (why not just .length the dependents
|
|
91
|
+
// and dependencies?), but it isn't because there can be > 1 relation between
|
|
92
|
+
// two folders
|
|
93
|
+
const lAfferentCouplings = lModuleDependents.reduce(sumCounts, 0);
|
|
94
|
+
const lEfferentCouplings = lModuleDependencies.reduce(sumCounts, 0);
|
|
95
95
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
96
|
+
return {
|
|
97
|
+
...pFolder,
|
|
98
|
+
afferentCouplings: lAfferentCouplings,
|
|
99
|
+
efferentCouplings: lEfferentCouplings,
|
|
100
|
+
instability: calculateInstability(lEfferentCouplings, lAfferentCouplings),
|
|
101
|
+
dependents: getFolderLevelCouplings(lModuleDependents),
|
|
102
|
+
dependencies: getFolderLevelCouplings(lModuleDependencies),
|
|
103
|
+
};
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
function deNormalizeInstability(pFolder, _, pAllFolders) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
107
|
+
return {
|
|
108
|
+
...pFolder,
|
|
109
|
+
dependencies: pFolder.dependencies.map((pDependency) => {
|
|
110
|
+
const lFolder = findFolderByName(pAllFolders, pDependency.name) || {};
|
|
111
|
+
return {
|
|
112
|
+
...pDependency,
|
|
113
|
+
instability: lFolder.instability >= 0 ? lFolder.instability : 0,
|
|
114
|
+
};
|
|
115
|
+
}),
|
|
116
|
+
};
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
function getSinks(pFolders) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
120
|
+
const lKnownFolders = new Set(pFolders.map(({ name }) => name));
|
|
121
|
+
const lAllFolders = uniq(
|
|
122
|
+
pFolders.flatMap(({ dependencies }) =>
|
|
123
|
+
dependencies.map(({ name }) => name),
|
|
124
|
+
),
|
|
125
|
+
);
|
|
126
|
+
const lReturnValue = lAllFolders
|
|
127
|
+
.filter((pFolder) => !lKnownFolders.has(pFolder))
|
|
128
|
+
.map((pFolder) => ({
|
|
129
|
+
name: pFolder,
|
|
130
|
+
moduleCount: -1,
|
|
131
|
+
dependencies: [],
|
|
132
|
+
dependents: [],
|
|
133
|
+
}));
|
|
134
|
+
return lReturnValue;
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
/**
|
|
@@ -141,17 +141,17 @@ function getSinks(pFolders) {
|
|
|
141
141
|
* @returns
|
|
142
142
|
*/
|
|
143
143
|
export default function aggregateToFolders(pModules, pOptions = {}) {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
144
|
+
let lFolders = object2Array(
|
|
145
|
+
pModules.filter(metricsAreCalculable).reduce(aggregateToFolder, {}),
|
|
146
|
+
)
|
|
147
|
+
.map(calculateFolderMetrics)
|
|
148
|
+
.map(deNormalizeInstability);
|
|
149
|
+
lFolders = lFolders.concat(getSinks(lFolders));
|
|
150
150
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
151
|
+
return detectCycles(lFolders, new IndexedModuleGraph(lFolders, "name"), {
|
|
152
|
+
pSourceAttribute: "name",
|
|
153
|
+
pDependencyName: "name",
|
|
154
|
+
pSkipAnalysisNotInRules: pOptions.skipAnalysisNotInRules,
|
|
155
|
+
pRuleSet: pOptions.ruleSet,
|
|
156
|
+
});
|
|
157
157
|
}
|
|
@@ -7,20 +7,20 @@ import { validateFolder } from "#validate/index.mjs";
|
|
|
7
7
|
* @returns
|
|
8
8
|
*/
|
|
9
9
|
function validateFolderDependency(pFolder, pOptions) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
return (pDependency) => ({
|
|
11
|
+
...pDependency,
|
|
12
|
+
...validateFolder(pOptions.ruleSet || {}, pFolder, pDependency),
|
|
13
|
+
});
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
function addFolderDependencyViolations(pOptions) {
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
return (pFolder) => ({
|
|
18
|
+
...pFolder,
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
dependencies: pFolder.dependencies.map(
|
|
21
|
+
validateFolderDependency(pFolder, pOptions),
|
|
22
|
+
),
|
|
23
|
+
});
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
/**
|
|
@@ -30,13 +30,13 @@ function addFolderDependencyViolations(pOptions) {
|
|
|
30
30
|
* @returns {any}
|
|
31
31
|
*/
|
|
32
32
|
export default function deriveFolderMetrics(pModules, pOptions) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
33
|
+
let lReturnValue = {};
|
|
34
|
+
if (pOptions.metrics) {
|
|
35
|
+
lReturnValue = {
|
|
36
|
+
folders: aggregateToFolders(pModules, pOptions).map(
|
|
37
|
+
addFolderDependencyViolations(pOptions),
|
|
38
|
+
),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
return lReturnValue;
|
|
42
42
|
}
|
|
@@ -2,19 +2,19 @@
|
|
|
2
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);
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
export function getAfferentCouplings(pModule, pDirname) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
return pModule.dependents.filter(
|
|
10
|
+
(pDependent) => !pDependent.startsWith(pDirname.concat(sep)),
|
|
11
|
+
);
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export function getEfferentCouplings(pModule, pDirname) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
return pModule.dependencies.filter(
|
|
16
|
+
(pDependency) => !pDependency.resolved.startsWith(pDirname.concat(sep)),
|
|
17
|
+
);
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
/**
|
|
@@ -23,19 +23,19 @@ export function getEfferentCouplings(pModule, pDirname) {
|
|
|
23
23
|
* @returns string[]
|
|
24
24
|
*/
|
|
25
25
|
export function getParentFolders(pPath) {
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
let lFragments = pPath.split("/");
|
|
27
|
+
let lReturnValue = [];
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
while (lFragments.length > 0) {
|
|
30
|
+
lReturnValue.push(lFragments.join("/"));
|
|
31
|
+
lFragments.pop();
|
|
32
|
+
}
|
|
33
|
+
return lReturnValue.reverse();
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
export function object2Array(pObject) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
return Object.keys(pObject).map((pKey) => ({
|
|
38
|
+
name: pKey,
|
|
39
|
+
...pObject[pKey],
|
|
40
|
+
}));
|
|
41
41
|
}
|
|
@@ -2,38 +2,38 @@ import { calculateInstability, metricsAreCalculable } from "../module-utl.mjs";
|
|
|
2
2
|
import IndexedModuleGraph from "#graph-utl/indexed-module-graph.mjs";
|
|
3
3
|
|
|
4
4
|
export function addInstabilityMetric(pModule) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
5
|
+
return {
|
|
6
|
+
...pModule,
|
|
7
|
+
...(metricsAreCalculable(pModule)
|
|
8
|
+
? {
|
|
9
|
+
instability: calculateInstability(
|
|
10
|
+
pModule.dependencies.length,
|
|
11
|
+
pModule.dependents.length,
|
|
12
|
+
),
|
|
13
|
+
}
|
|
14
|
+
: {}),
|
|
15
|
+
};
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
function addInstabilityToDependency(pAllModules) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
const lIndexedModules = new IndexedModuleGraph(pAllModules);
|
|
20
|
+
return (pDependency) => ({
|
|
21
|
+
...pDependency,
|
|
22
|
+
instability:
|
|
23
|
+
(lIndexedModules.findVertexByName(pDependency.resolved) || {})
|
|
24
|
+
.instability || 0,
|
|
25
|
+
});
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
export function deNormalizeInstabilityMetricsToDependencies(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
pModule,
|
|
30
|
+
_,
|
|
31
|
+
pAllModules,
|
|
32
32
|
) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
return {
|
|
34
|
+
...pModule,
|
|
35
|
+
dependencies: pModule.dependencies.map(
|
|
36
|
+
addInstabilityToDependency(pAllModules),
|
|
37
|
+
),
|
|
38
|
+
};
|
|
39
39
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
addInstabilityMetric,
|
|
3
|
+
deNormalizeInstabilityMetricsToDependencies,
|
|
4
4
|
} from "./get-module-metrics.mjs";
|
|
5
5
|
|
|
6
6
|
export default function deriveModulesMetrics(pModules, pOptions) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
if (pOptions.metrics) {
|
|
8
|
+
return pModules
|
|
9
|
+
.map(addInstabilityMetric)
|
|
10
|
+
.map(deNormalizeInstabilityMetricsToDependencies);
|
|
11
|
+
}
|
|
12
|
+
return pModules;
|
|
13
13
|
}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
export function isDependent(pResolvedName) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
return (pModule) =>
|
|
3
|
+
pModule.dependencies.some(
|
|
4
|
+
(pDependency) => pDependency.resolved === pResolvedName,
|
|
5
|
+
);
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
export function metricsAreCalculable(pModule) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
return (
|
|
10
|
+
!pModule.coreModule &&
|
|
11
|
+
!pModule.couldNotResolve &&
|
|
12
|
+
!pModule.matchesDoNotFollow
|
|
13
|
+
);
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
/**
|
|
@@ -22,14 +22,14 @@ export function metricsAreCalculable(pModule) {
|
|
|
22
22
|
* @returns number
|
|
23
23
|
*/
|
|
24
24
|
export function calculateInstability(
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
pEfferentCouplingCount,
|
|
26
|
+
pAfferentCouplingCount,
|
|
27
27
|
) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
28
|
+
// when both afferentCouplings and efferentCouplings equal 0 instability will
|
|
29
|
+
// yield NaN. Judging Bob Martin's intention, a component with no outgoing
|
|
30
|
+
// dependencies is maximum stable (0)
|
|
31
|
+
return (
|
|
32
|
+
pEfferentCouplingCount /
|
|
33
|
+
(pEfferentCouplingCount + pAfferentCouplingCount) || 0
|
|
34
|
+
);
|
|
35
35
|
}
|
|
@@ -3,32 +3,32 @@ import isOrphan from "./is-orphan.mjs";
|
|
|
3
3
|
/** @import { IFlattenedRuleSet } from "../../../../types/rule-set.mjs" */
|
|
4
4
|
|
|
5
5
|
function isOrphanRule(pRule) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
return (
|
|
7
|
+
/* c8 ignore start */
|
|
8
|
+
Object.hasOwn(pRule?.from ?? {}, "orphan")
|
|
9
|
+
/* c8 ignore stop */
|
|
10
|
+
);
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
13
|
* @param {IFlattenedRuleSet} pRuleSet
|
|
14
14
|
* @returns {boolean}
|
|
15
15
|
*/
|
|
16
16
|
export function hasOrphanRule(pRuleSet) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
return (
|
|
18
|
+
(pRuleSet?.forbidden ?? []).some(isOrphanRule) ||
|
|
19
|
+
(pRuleSet?.allowed ?? []).some(isOrphanRule)
|
|
20
|
+
);
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
export default function deriveOrphans(
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
pModules,
|
|
25
|
+
{ skipAnalysisNotInRules, ruleSet },
|
|
26
26
|
) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
27
|
+
if (!skipAnalysisNotInRules || hasOrphanRule(ruleSet)) {
|
|
28
|
+
return pModules.map((pModule) => ({
|
|
29
|
+
...pModule,
|
|
30
|
+
orphan: isOrphan(pModule, pModules),
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
33
|
+
return pModules;
|
|
34
34
|
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { isDependent } from "../module-utl.mjs";
|
|
2
2
|
|
|
3
3
|
export default function isOrphan(pModule, pGraph) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
if (pModule.dependencies.length > 0) {
|
|
5
|
+
return false;
|
|
6
|
+
}
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
// when dependents already calculated take those
|
|
9
|
+
if (pModule.dependents) {
|
|
10
|
+
return pModule.dependents.length === 0;
|
|
11
|
+
}
|
|
12
|
+
// ... otherwise calculate them
|
|
13
|
+
return !pGraph.some(isDependent(pModule.source));
|
|
14
14
|
}
|