dependency-cruiser 15.3.1-beta-2 → 15.5.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/configs/plugins/3d-reporter-plugin.mjs +127 -0
- package/configs/plugins/stats-reporter-plugin.mjs +82 -0
- package/package.json +44 -34
- package/src/cache/metadata-strategy.mjs +1 -1
- package/src/cli/init-config/config-template.mjs +15 -7
- package/src/cli/tools/svg-in-html-snippets/{script.snippet.js → script.js} +47 -12
- package/src/cli/tools/svg-in-html-snippets/style.css +101 -0
- package/src/cli/tools/wrap-stream-in-html.mjs +57 -15
- package/src/config-utl/extract-depcruise-config/index.mjs +1 -1
- package/src/config-utl/extract-webpack-resolve-config.mjs +14 -11
- package/src/enrich/add-validations.mjs +3 -3
- package/src/enrich/soften-known-violations.mjs +4 -4
- package/src/enrich/summarize/index.mjs +3 -3
- package/src/extract/gather-initial-sources.mjs +2 -2
- package/src/extract/get-dependencies.mjs +2 -2
- package/src/extract/resolve/determine-dependency-types.mjs +3 -3
- package/src/extract/resolve/index.mjs +3 -3
- package/src/extract/resolve/merge-manifests.mjs +4 -8
- package/src/extract/resolve/module-classifiers.mjs +2 -10
- package/src/extract/transpile/meta.d.ts +1 -1
- package/src/graph-utl/filter-bank.mjs +2 -2
- package/src/main/index.d.ts +1 -1
- package/src/main/options/normalize.mjs +1 -1
- package/src/main/rule-set/normalize.mjs +1 -1
- package/src/meta.js +1 -1
- package/src/report/anon/index.mjs +7 -7
- package/src/report/azure-devops.mjs +11 -11
- package/src/report/csv.mjs +3 -2
- package/src/report/dot/default-theme.mjs +1 -1
- package/src/report/error-html/index.mjs +6 -6
- package/src/report/error.mjs +1 -1
- package/src/report/html/index.mjs +1 -1
- package/src/report/markdown.mjs +5 -5
- package/src/validate/index.d.ts +4 -4
- package/src/validate/match-folder-dependency-rule.mjs +2 -2
- package/src/validate/match-module-rule.mjs +12 -12
- package/src/validate/violates-required-rule.mjs +2 -2
- package/types/baseline-violations.d.mts +3 -0
- package/types/{extract-babel-config.d.ts → config-utl/extract-babel-config.d.mts} +1 -1
- package/types/{extract-depcruise-config.d.ts → config-utl/extract-depcruise-config.d.mts} +2 -2
- package/types/{extract-ts-config.d.ts → config-utl/extract-ts-config.d.mts} +1 -1
- package/types/{extract-webpack-resolve-config.d.ts → config-utl/extract-webpack-resolve-config.d.mts} +4 -3
- package/types/{configuration.d.ts → configuration.d.mts} +2 -2
- package/types/{cruise-result.d.ts → cruise-result.d.mts} +12 -8
- package/types/{dependency-cruiser.d.ts → dependency-cruiser.d.mts} +9 -9
- package/types/{filter-types.d.ts → filter-types.d.mts} +1 -1
- package/types/{options.d.ts → options.d.mts} +7 -7
- package/types/plugins/3d-reporter-plugin.d.mts +13 -0
- package/types/plugins/mermaid-reporter-plugin.d.mts +14 -0
- package/types/plugins/stats-reporter-plugin.d.mts +13 -0
- package/types/{reporter-options.d.ts → reporter-options.d.mts} +2 -2
- package/types/{resolve-options.d.ts → resolve-options.d.mts} +1 -1
- package/types/{restrictions.d.ts → restrictions.d.mts} +1 -1
- package/types/{rule-set.d.ts → rule-set.d.mts} +3 -3
- package/types/{rule-summary.d.ts → rule-summary.d.mts} +1 -1
- package/types/{strict-filter-types.d.ts → strict-filter-types.d.mts} +3 -3
- package/types/{strict-options.d.ts → strict-options.d.mts} +7 -7
- package/types/{strict-restrictions.d.ts → strict-restrictions.d.mts} +2 -2
- package/types/{strict-rule-set.d.ts → strict-rule-set.d.mts} +5 -5
- package/types/{violations.d.ts → violations.d.mts} +2 -2
- package/src/cli/tools/svg-in-html-snippets/footer.snippet.html +0 -2
- package/src/cli/tools/svg-in-html-snippets/header.snippet.html +0 -108
- package/types/baseline-violations.d.ts +0 -3
- /package/types/{cache-options.d.ts → cache-options.d.mts} +0 -0
- /package/types/{shared-types.d.ts → shared-types.d.mts} +0 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
import figures from "figures";
|
|
3
|
+
|
|
4
|
+
const TEMPLATE = `
|
|
5
|
+
<html>
|
|
6
|
+
<head>
|
|
7
|
+
<style> body { margin: 0; } </style>
|
|
8
|
+
<script type="text/javascript" src="https://unpkg.com/three"></script>
|
|
9
|
+
<script type="text/javascript" src="https://unpkg.com/three-spritetext"></script>
|
|
10
|
+
<script type="text/javascript" src="https://unpkg.com/3d-force-graph"></script>
|
|
11
|
+
</head>
|
|
12
|
+
|
|
13
|
+
<body>
|
|
14
|
+
<div id="3d-graph"></div>
|
|
15
|
+
|
|
16
|
+
<script>
|
|
17
|
+
const gData = {
|
|
18
|
+
nodes: @@NODES@@,
|
|
19
|
+
links: @@LINKS@@
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const elem = document.getElementById('3d-graph')
|
|
23
|
+
const Graph = ForceGraph3D()
|
|
24
|
+
(elem)
|
|
25
|
+
.graphData(gData)
|
|
26
|
+
.nodeAutoColorBy('group')
|
|
27
|
+
.nodeLabel(node => node.label)
|
|
28
|
+
.onNodeHover(node => elem.style.cursor = node ? 'pointer' : null)
|
|
29
|
+
.onNodeClick(node => {
|
|
30
|
+
// Aim at node from outside it
|
|
31
|
+
const distance = 40;
|
|
32
|
+
const distRatio = 1 + distance/Math.hypot(node.x, node.y, node.z);
|
|
33
|
+
|
|
34
|
+
Graph.cameraPosition(
|
|
35
|
+
{ x: node.x * distRatio, y: node.y * distRatio, z: node.z * distRatio }, // new position
|
|
36
|
+
node, // lookAt ({ x, y, z })
|
|
37
|
+
3000 // ms transition duration
|
|
38
|
+
)
|
|
39
|
+
})
|
|
40
|
+
/* nice idea, but the 3D graph tends to look cluttered. Also GPU/ CPU
|
|
41
|
+
intensive when run on a serious code base (e.g. react that has
|
|
42
|
+
~4500 nodes and ~10000 links
|
|
43
|
+
*/
|
|
44
|
+
.nodeThreeObject(node => {
|
|
45
|
+
const sprite = new SpriteText(node.displayname);
|
|
46
|
+
sprite.material.depthWrite = true; // make sprite background transparent
|
|
47
|
+
sprite.color = node.color;
|
|
48
|
+
sprite.textHeight = 6;
|
|
49
|
+
return sprite;
|
|
50
|
+
})
|
|
51
|
+
.linkOpacity(0.2)
|
|
52
|
+
.linkWidth(2)
|
|
53
|
+
.linkDirectionalArrowLength(4)
|
|
54
|
+
.linkDirectionalParticles(7) // cool but a bit GPU intensive
|
|
55
|
+
.linkLabel(link => link.label)
|
|
56
|
+
.onLinkHover(link => elem.style.cursor = link ? 'pointer' : null)
|
|
57
|
+
|
|
58
|
+
</script>
|
|
59
|
+
</body>
|
|
60
|
+
</html>`;
|
|
61
|
+
|
|
62
|
+
function deriveGroup(pFileName) {
|
|
63
|
+
let lReturnValue = "unknown";
|
|
64
|
+
const lGroupPositionInRe = 2;
|
|
65
|
+
const lMatch = path.dirname(pFileName).match(/^([^/]+)\/([^/]+)/);
|
|
66
|
+
if (lMatch) {
|
|
67
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
68
|
+
lReturnValue = lMatch[lGroupPositionInRe];
|
|
69
|
+
}
|
|
70
|
+
return lReturnValue;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function formatFileName(pFileName) {
|
|
74
|
+
return `${path.dirname(pFileName)}/<b>${path.basename(pFileName)}</b>`;
|
|
75
|
+
}
|
|
76
|
+
function formatDependency(pFrom, pTo) {
|
|
77
|
+
return `${formatFileName(pFrom)} ${figures.arrowRight}</br>${formatFileName(
|
|
78
|
+
pTo
|
|
79
|
+
)}`;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
*
|
|
84
|
+
* @param {import('../../types/dependency-cruiser').ICruiseResult} pCruiseResult
|
|
85
|
+
*/
|
|
86
|
+
function render3DThing(pCruiseResult) {
|
|
87
|
+
const lNodes = pCruiseResult.modules.map((pModule) => {
|
|
88
|
+
return {
|
|
89
|
+
id: pModule.source,
|
|
90
|
+
displayname: path.basename(pModule.source),
|
|
91
|
+
dirname: path.dirname(pModule.source),
|
|
92
|
+
label: formatFileName(pModule.source),
|
|
93
|
+
group: deriveGroup(pModule.source),
|
|
94
|
+
};
|
|
95
|
+
});
|
|
96
|
+
const lLinks = pCruiseResult.modules.reduce(
|
|
97
|
+
(pAll, pCurrentModule) =>
|
|
98
|
+
pAll.concat(
|
|
99
|
+
pCurrentModule.dependencies.map((pDependency) => ({
|
|
100
|
+
source: pCurrentModule.source,
|
|
101
|
+
target: pDependency.resolved,
|
|
102
|
+
label: formatDependency(pCurrentModule.source, pDependency.resolved),
|
|
103
|
+
}))
|
|
104
|
+
),
|
|
105
|
+
[]
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
return TEMPLATE.replace(/@@NODES@@/g, JSON.stringify(lNodes)).replace(
|
|
109
|
+
/@@LINKS@@/g,
|
|
110
|
+
JSON.stringify(lLinks)
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Sample plugin: 3d representation
|
|
116
|
+
*
|
|
117
|
+
* @param {import('../../types/dependency-cruiser').ICruiseResult} pCruiseResult -
|
|
118
|
+
* the output of a dependency-cruise adhering to dependency-cruiser's
|
|
119
|
+
* cruise result schema
|
|
120
|
+
* @return {import('../../types/dependency-cruiser').IReporterOutput} -
|
|
121
|
+
* output: a string
|
|
122
|
+
* exitCode: 0
|
|
123
|
+
*/
|
|
124
|
+
export default (pCruiseResult) => ({
|
|
125
|
+
output: render3DThing(pCruiseResult),
|
|
126
|
+
exitCode: 0,
|
|
127
|
+
});
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
const MEDIAN = 0.5;
|
|
2
|
+
const P75 = 0.75;
|
|
3
|
+
const DEFAULT_JSON_INDENT = 2;
|
|
4
|
+
|
|
5
|
+
function doMagic(pCruiseResult) {
|
|
6
|
+
let lReturnValue = {};
|
|
7
|
+
|
|
8
|
+
if (pCruiseResult.modules.some((pModule) => pModule.dependents)) {
|
|
9
|
+
const lDependentCounts = pCruiseResult.modules
|
|
10
|
+
.map((pModule) => pModule.dependents.length)
|
|
11
|
+
.sort();
|
|
12
|
+
|
|
13
|
+
lReturnValue = {
|
|
14
|
+
minDependentsPerModule: lDependentCounts[0] || 0,
|
|
15
|
+
maxDependentsPerModule:
|
|
16
|
+
lDependentCounts[Math.max(lDependentCounts.length - 1, 0)] || 0,
|
|
17
|
+
meanDependentsPerModule:
|
|
18
|
+
lDependentCounts.reduce((pAll, pCurrent) => pAll + pCurrent, 0) /
|
|
19
|
+
pCruiseResult.summary.totalCruised,
|
|
20
|
+
medianDependentsPerModule:
|
|
21
|
+
lDependentCounts[
|
|
22
|
+
Math.max(0, Math.floor(lDependentCounts.length * MEDIAN))
|
|
23
|
+
],
|
|
24
|
+
p75DependentsPerModule:
|
|
25
|
+
lDependentCounts[
|
|
26
|
+
Math.max(0, Math.floor(lDependentCounts.length * P75))
|
|
27
|
+
],
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
return lReturnValue;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* returns an object with some stats from the ICruiseResult pCruiseResult it
|
|
34
|
+
* got passed
|
|
35
|
+
*
|
|
36
|
+
* @param {import('../../types/dependency-cruiser').ICruiseResult} pCruiseResult - a result from a cruise.
|
|
37
|
+
* @return {string} an object with some stats
|
|
38
|
+
*/
|
|
39
|
+
function samplePluginReporter(pCruiseResult) {
|
|
40
|
+
const lDependencyCounts = pCruiseResult.modules
|
|
41
|
+
.map((pModule) => pModule.dependencies.length)
|
|
42
|
+
.sort();
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
moduleCount: pCruiseResult.summary.totalCruised,
|
|
46
|
+
dependencyCount: pCruiseResult.summary.totalDependenciesCruised,
|
|
47
|
+
minDependenciesPerModule: lDependencyCounts[0] || 0,
|
|
48
|
+
maxDependenciesPerModule:
|
|
49
|
+
lDependencyCounts[Math.max(lDependencyCounts.length - 1, 0)] || 0,
|
|
50
|
+
meanDependenciesPerModule:
|
|
51
|
+
pCruiseResult.summary.totalDependenciesCruised /
|
|
52
|
+
pCruiseResult.summary.totalCruised,
|
|
53
|
+
medianDependenciesPerModule:
|
|
54
|
+
lDependencyCounts[
|
|
55
|
+
Math.max(0, Math.floor(lDependencyCounts.length * MEDIAN))
|
|
56
|
+
],
|
|
57
|
+
p75DependenciesPerModule:
|
|
58
|
+
lDependencyCounts[
|
|
59
|
+
Math.max(0, Math.floor(lDependencyCounts.length * P75))
|
|
60
|
+
],
|
|
61
|
+
...doMagic(pCruiseResult),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Sample plugin
|
|
67
|
+
*
|
|
68
|
+
* @param {import('../../types/dependency-cruiser').ICruiseResult} pCruiseResult -
|
|
69
|
+
* the output of a dependency-cruise adhering to dependency-cruiser's
|
|
70
|
+
* cruise result schema
|
|
71
|
+
* @return {import('../../types/dependency-cruiser').IReporterOutput} -
|
|
72
|
+
* output: some stats on modules and dependencies in json format
|
|
73
|
+
* exitCode: 0
|
|
74
|
+
*/
|
|
75
|
+
export default (pCruiseResult) => ({
|
|
76
|
+
output: JSON.stringify(
|
|
77
|
+
samplePluginReporter(pCruiseResult),
|
|
78
|
+
null,
|
|
79
|
+
DEFAULT_JSON_INDENT
|
|
80
|
+
),
|
|
81
|
+
exitCode: 0,
|
|
82
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dependency-cruiser",
|
|
3
|
-
"version": "15.
|
|
3
|
+
"version": "15.5.0",
|
|
4
4
|
"description": "Validate and visualize dependencies. With your rules. JavaScript, TypeScript, CoffeeScript. ES6, CommonJS, AMD.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"static analysis",
|
|
@@ -51,39 +51,49 @@
|
|
|
51
51
|
},
|
|
52
52
|
"exports": {
|
|
53
53
|
".": {
|
|
54
|
-
"
|
|
55
|
-
"
|
|
54
|
+
"types": "./types/dependency-cruiser.d.mts",
|
|
55
|
+
"import": "./src/main/index.mjs"
|
|
56
56
|
},
|
|
57
57
|
"./config-utl/extract-babel-config": {
|
|
58
|
-
"
|
|
59
|
-
"
|
|
58
|
+
"types": "./types/config-utl/extract-babel-config.d.mts",
|
|
59
|
+
"import": "./src/config-utl/extract-babel-config.mjs"
|
|
60
60
|
},
|
|
61
61
|
"./config-utl/extract-depcruise-config": {
|
|
62
|
-
"
|
|
63
|
-
"
|
|
62
|
+
"types": "./types/config-utl/extract-depcruise-config.d.mts",
|
|
63
|
+
"import": "./src/config-utl/extract-depcruise-config/index.mjs"
|
|
64
64
|
},
|
|
65
65
|
"./config-utl/extract-ts-config": {
|
|
66
|
-
"
|
|
67
|
-
"
|
|
66
|
+
"types": "./types/config-utl/extract-ts-config.d.mts",
|
|
67
|
+
"import": "./src/config-utl/extract-ts-config.mjs"
|
|
68
68
|
},
|
|
69
69
|
"./config-utl/extract-webpack-resolve-config": {
|
|
70
|
-
"
|
|
71
|
-
"
|
|
70
|
+
"types": "./types/config-utl/extract-webpack-resolve-config.d.mts",
|
|
71
|
+
"import": "./src/config-utl/extract-webpack-resolve-config.mjs"
|
|
72
72
|
},
|
|
73
|
-
"./sample-reporter-plugin":
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
"./sample-reporter-plugin": {
|
|
74
|
+
"types": "./types/plugins/stats-reporter-plugin.d.mts",
|
|
75
|
+
"import": "./configs/plugins/stats-reporter-plugin.mjs"
|
|
76
|
+
},
|
|
77
|
+
"./sample-3d-reporter-plugin": {
|
|
78
|
+
"types": "./types/plugins/3d-reporter-plugin.d.mts",
|
|
79
|
+
"import": "./configs/plugins/3d-reporter-plugin.mjs"
|
|
80
|
+
},
|
|
81
|
+
"./mermaid-reporter-plugin": {
|
|
82
|
+
"types": "./types/plugins/mermaid-reporter-plugin.d.mts",
|
|
83
|
+
"import": "./src/report/mermaid.mjs"
|
|
84
|
+
}
|
|
76
85
|
},
|
|
77
|
-
"types": "types/dependency-cruiser.d.
|
|
86
|
+
"types": "types/dependency-cruiser.d.mts",
|
|
78
87
|
"files": [
|
|
79
88
|
"bin",
|
|
80
89
|
"configs/**/*.js",
|
|
90
|
+
"configs/plugins/",
|
|
81
91
|
"src",
|
|
82
92
|
"!src/**/*.json",
|
|
83
93
|
"!src/**/*.hbs",
|
|
84
94
|
"!src/**/*.md",
|
|
85
95
|
"!**/*.DS_Store",
|
|
86
|
-
"types
|
|
96
|
+
"types/**/*.d.mts",
|
|
87
97
|
"LICENSE",
|
|
88
98
|
"package.json",
|
|
89
99
|
"README.md"
|
|
@@ -103,7 +113,7 @@
|
|
|
103
113
|
"depcruise:graph:doc:fmt-archi": "./bin/depcruise-fmt.mjs -T archi -f - node_modules/.cache/tmp_graph_deps.json | dot -T svg -Gordering=in -Grankdir=TD | tee doc/real-world-samples/dependency-cruiser-archi-graph.svg | node bin/wrap-stream-in-html.mjs > docs/dependency-cruiser-archi-graph.html",
|
|
104
114
|
"depcruise:graph:doc:fmt-dir": "./bin/depcruise-fmt.mjs -T ddot -f - node_modules/.cache/tmp_graph_deps.json | dot -T svg -Grankdir=TD | tee doc/real-world-samples/dependency-cruiser-dir-graph.svg | node bin/wrap-stream-in-html.mjs > docs/dependency-cruiser-dir-graph.html",
|
|
105
115
|
"depcruise:graph:doc:fmt-schema": "cd tools/schema && node ../../bin/dependency-cruise.mjs . --output-type dot | dot -T svg | tee ../overview.svg | node ../../bin/wrap-stream-in-html.mjs > ../../docs/schema-overview.html && cd -",
|
|
106
|
-
"depcruise:graph:doc:fmt-types": "cd types && node ../bin/dependency-cruise.mjs . --output-type dot | dot -T svg
|
|
116
|
+
"depcruise:graph:doc:fmt-types": "cd types && node ../bin/dependency-cruise.mjs . --output-type dot | dot -T svg | tee overview.svg | ../bin/wrap-stream-in-html.mjs > overview.html && cd -",
|
|
107
117
|
"depcruise:graph:doc:samples": "sh tools/generate-samples.sh",
|
|
108
118
|
"depcruise:graph:mermaid": "node ./bin/dependency-cruise.mjs bin src --include-only ^src/ --collapse 2 --output-type mermaid",
|
|
109
119
|
"depcruise:graph:mermaid:diff": "node ./bin/dependency-cruise.mjs bin src test types tools --config configs/.dependency-cruiser-unlimited.mjs --output-type mermaid --reaches \"$(watskeburt $SHA)\"",
|
|
@@ -113,8 +123,8 @@
|
|
|
113
123
|
"depcruise:report:view": "node ./bin/dependency-cruise.mjs src bin test configs types --output-type err-html --config configs/.dependency-cruiser-show-metrics-config.mjs --output-to - | browser",
|
|
114
124
|
"depcruise:focus": "node ./bin/dependency-cruise.mjs src bin test configs types tools --progress --no-cache --output-type text --focus",
|
|
115
125
|
"depcruise:reaches": "node ./bin/dependency-cruise.mjs src bin test configs types tools --progress --no-cache --config configs/.dependency-cruiser-unlimited.mjs --output-type text --reaches",
|
|
116
|
-
"format": "prettier --log-level warn --write \"src/**/*.js\" \"configs/**/*.js\" \"tools/**/*.mjs\" \"bin/*\" \"types/*.d.
|
|
117
|
-
"format:check": "prettier --log-level warn --check \"src/**/*.js\" \"configs/**/*.js\" \"tools/**/*.mjs\" \"bin/*\" \"types/*.d.
|
|
126
|
+
"format": "prettier --log-level warn --write \"src/**/*.js\" \"configs/**/*.js\" \"tools/**/*.mjs\" \"bin/*\" \"types/*.d.mts\" \"test/**/*.spec.{cjs,js}\" \"test/**/*.{spec,utl}.mjs\"",
|
|
127
|
+
"format:check": "prettier --log-level warn --check \"src/**/*.js\" \"configs/**/*.js\" \"tools/**/*.mjs\" \"bin/*\" \"types/*.d.mts\" \"test/**/*.spec.{cjs,js}\" \"test/**/*.{spec,utl}.mjs\"",
|
|
118
128
|
"lint": "npm-run-all --parallel --aggregate-output lint:eslint format:check lint:types",
|
|
119
129
|
"lint:eslint": "eslint bin/dependency-cruise.mjs bin src test configs tools/**/*.mjs --cache --cache-location node_modules/.cache/eslint/",
|
|
120
130
|
"lint:eslint:fix": "eslint --fix bin src test configs tools/**/*.mjs --cache --cache-location node_modules/.cache/eslint/",
|
|
@@ -122,8 +132,8 @@
|
|
|
122
132
|
"lint:fix": "npm-run-all lint:eslint:fix format lint:types:fix",
|
|
123
133
|
"lint:types": "npm-run-all lint:types:tsc lint:types:lint",
|
|
124
134
|
"lint:types:tsc": "tsc --project types/tsconfig.json",
|
|
125
|
-
"lint:types:lint": "eslint --no-ignore --config types/.eslintrc.json types/*.d.
|
|
126
|
-
"lint:types:fix": "eslint --no-ignore --config types/.eslintrc.json --fix types/*.d.
|
|
135
|
+
"lint:types:lint": "eslint --no-ignore --config types/.eslintrc.json types/*.d.mts",
|
|
136
|
+
"lint:types:fix": "eslint --no-ignore --config types/.eslintrc.json --fix types/*.d.mts",
|
|
127
137
|
"prepare": "husky install",
|
|
128
138
|
"scm:push": "run-p --aggregate-output scm:push:*",
|
|
129
139
|
"scm:push:bitbucket-mirror": "run-p --aggregate-output scm:push:bitbucket-mirror:*",
|
|
@@ -163,7 +173,7 @@
|
|
|
163
173
|
"commander": "11.1.0",
|
|
164
174
|
"enhanced-resolve": "5.15.0",
|
|
165
175
|
"figures": "6.0.1",
|
|
166
|
-
"ignore": "5.
|
|
176
|
+
"ignore": "5.3.0",
|
|
167
177
|
"indent-string": "5.0.0",
|
|
168
178
|
"interpret": "^3.1.1",
|
|
169
179
|
"is-installed-globally": "1.0.0",
|
|
@@ -177,23 +187,23 @@
|
|
|
177
187
|
"semver-try-require": "6.2.3",
|
|
178
188
|
"teamcity-service-messages": "0.1.14",
|
|
179
189
|
"tsconfig-paths-webpack-plugin": "4.1.0",
|
|
180
|
-
"watskeburt": "2.0.
|
|
190
|
+
"watskeburt": "2.0.2",
|
|
181
191
|
"wrap-ansi": "9.0.0"
|
|
182
192
|
},
|
|
183
193
|
"devDependencies": {
|
|
184
194
|
"@babel/core": "7.23.3",
|
|
185
195
|
"@babel/plugin-transform-modules-commonjs": "7.23.3",
|
|
186
196
|
"@babel/preset-typescript": "7.23.3",
|
|
187
|
-
"@swc/core": "1.3.
|
|
188
|
-
"@types/lodash": "4.14.
|
|
189
|
-
"@types/node": "20.
|
|
190
|
-
"@types/prompts": "2.4.
|
|
191
|
-
"@typescript-eslint/eslint-plugin": "6.
|
|
192
|
-
"@typescript-eslint/parser": "6.
|
|
193
|
-
"@vue/compiler-sfc": "3.3.
|
|
197
|
+
"@swc/core": "1.3.99",
|
|
198
|
+
"@types/lodash": "4.14.202",
|
|
199
|
+
"@types/node": "20.10.0",
|
|
200
|
+
"@types/prompts": "2.4.9",
|
|
201
|
+
"@typescript-eslint/eslint-plugin": "6.12.0",
|
|
202
|
+
"@typescript-eslint/parser": "6.12.0",
|
|
203
|
+
"@vue/compiler-sfc": "3.3.9",
|
|
194
204
|
"c8": "8.0.1",
|
|
195
205
|
"coffeescript": "2.7.0",
|
|
196
|
-
"eslint": "8.
|
|
206
|
+
"eslint": "8.54.0",
|
|
197
207
|
"eslint-config-moving-meadow": "4.0.2",
|
|
198
208
|
"eslint-config-prettier": "9.0.0",
|
|
199
209
|
"eslint-plugin-budapestian": "6.0.0",
|
|
@@ -209,15 +219,15 @@
|
|
|
209
219
|
"mocha": "10.2.0",
|
|
210
220
|
"normalize-newline": "4.1.0",
|
|
211
221
|
"npm-run-all": "4.1.5",
|
|
212
|
-
"prettier": "3.0
|
|
222
|
+
"prettier": "3.1.0",
|
|
213
223
|
"proxyquire": "2.1.3",
|
|
214
224
|
"shx": "0.3.4",
|
|
215
225
|
"svelte": "3.59.1",
|
|
216
226
|
"symlink-dir": "5.2.0",
|
|
217
|
-
"typescript": "5.
|
|
227
|
+
"typescript": "5.3.2",
|
|
218
228
|
"upem": "9.0.2",
|
|
219
229
|
"vue-template-compiler": "2.7.15",
|
|
220
|
-
"yarn": "1.22.
|
|
230
|
+
"yarn": "1.22.21"
|
|
221
231
|
},
|
|
222
232
|
"overrides": {
|
|
223
233
|
"semver": "^7.5.4",
|
|
@@ -15,7 +15,7 @@ import { bus } from "#utl/bus.mjs";
|
|
|
15
15
|
export default class MetaDataStrategy {
|
|
16
16
|
/**
|
|
17
17
|
* @param {string} _pDirectory
|
|
18
|
-
* @param {import("../../types/cruise-result.
|
|
18
|
+
* @param {import("../../types/cruise-result.mjs").ICruiseResult} _pCachedCruiseResult
|
|
19
19
|
* @param {Object} pOptions
|
|
20
20
|
* @param {Set<string>} pOptions.extensions
|
|
21
21
|
* @param {Set<import("watskeburt").changeTypeType>=} pOptions.interestingChangeTypes
|
|
@@ -25,10 +25,10 @@ module.exports = {
|
|
|
25
25
|
from: {
|
|
26
26
|
orphan: true,
|
|
27
27
|
pathNot: [
|
|
28
|
-
'(^|/)
|
|
29
|
-
'
|
|
30
|
-
'(^|/)tsconfig
|
|
31
|
-
'(^|/)(babel|webpack)
|
|
28
|
+
'(^|/)[.][^/]+[.](js|cjs|mjs|ts|json)$', // dot files
|
|
29
|
+
'[.]d[.]ts$', // TypeScript declaration files
|
|
30
|
+
'(^|/)tsconfig[.]json$', // TypeScript config
|
|
31
|
+
'(^|/)(babel|webpack)[.]config[.](js|cjs|mjs|ts|json)$' // other configs
|
|
32
32
|
]
|
|
33
33
|
},
|
|
34
34
|
to: {},
|
|
@@ -136,7 +136,7 @@ module.exports = {
|
|
|
136
136
|
severity: 'error',
|
|
137
137
|
from: {},
|
|
138
138
|
to: {
|
|
139
|
-
path: '
|
|
139
|
+
path: '[.](spec|test)[.](js|mjs|cjs|ts|ls|coffee|litcoffee|coffee[.]md)$'
|
|
140
140
|
}
|
|
141
141
|
},
|
|
142
142
|
{
|
|
@@ -150,11 +150,19 @@ module.exports = {
|
|
|
150
150
|
'from.pathNot re of the not-to-dev-dep rule in the dependency-cruiser configuration',
|
|
151
151
|
from: {
|
|
152
152
|
path: '{{sourceLocationRE}}',
|
|
153
|
-
pathNot: '
|
|
153
|
+
pathNot: '[.](spec|test)[.](js|mjs|cjs|ts|ls|coffee|litcoffee|coffee[.]md)$'
|
|
154
154
|
},
|
|
155
155
|
to: {
|
|
156
156
|
dependencyTypes: [
|
|
157
|
-
'npm-dev'
|
|
157
|
+
'npm-dev',
|
|
158
|
+
],
|
|
159
|
+
// type only dependencies are not a problem as they don't end up in the
|
|
160
|
+
// production code or are ignored by the runtime.
|
|
161
|
+
dependencyTypesNot: [
|
|
162
|
+
'type-only'
|
|
163
|
+
],
|
|
164
|
+
pathNot: [
|
|
165
|
+
'node_modules/@types/'
|
|
158
166
|
]
|
|
159
167
|
}
|
|
160
168
|
},
|
|
@@ -10,7 +10,7 @@ var title2ElementMap = (function makeElementMap() {
|
|
|
10
10
|
|
|
11
11
|
function getHoverHandler(pTitle2ElementMap) {
|
|
12
12
|
/** @type {string} */
|
|
13
|
-
var currentHighlightedTitle;
|
|
13
|
+
var currentHighlightedTitle = "";
|
|
14
14
|
|
|
15
15
|
/** @param {MouseEvent} pMouseEvent */
|
|
16
16
|
return function hoverHighlightHandler(pMouseEvent) {
|
|
@@ -31,7 +31,7 @@ function getHoverHandler(pTitle2ElementMap) {
|
|
|
31
31
|
|
|
32
32
|
function getSelectHandler(pTitle2ElementMap) {
|
|
33
33
|
/** @type {string} */
|
|
34
|
-
var currentHighlightedTitle;
|
|
34
|
+
var currentHighlightedTitle = "";
|
|
35
35
|
|
|
36
36
|
/** @param {MouseEvent} pMouseEvent */
|
|
37
37
|
return function selectHighlightHandler(pMouseEvent) {
|
|
@@ -64,6 +64,9 @@ function Mode() {
|
|
|
64
64
|
this._mode = SELECT;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
/**
|
|
68
|
+
* @returns {number}
|
|
69
|
+
*/
|
|
67
70
|
function get() {
|
|
68
71
|
return this._mode || HOVER;
|
|
69
72
|
}
|
|
@@ -210,23 +213,23 @@ function addHighlight(pGroup) {
|
|
|
210
213
|
}
|
|
211
214
|
}
|
|
212
215
|
|
|
213
|
-
var
|
|
216
|
+
var gHints = {
|
|
214
217
|
HIDDEN: 1,
|
|
215
218
|
SHOWN: 2,
|
|
216
219
|
state: this.HIDDEN,
|
|
217
220
|
show: function () {
|
|
218
221
|
document.getElementById("hints").removeAttribute("style");
|
|
219
|
-
|
|
222
|
+
gHints.state = gHints.SHOWN;
|
|
220
223
|
},
|
|
221
224
|
hide: function () {
|
|
222
225
|
document.getElementById("hints").style = "display:none";
|
|
223
|
-
|
|
226
|
+
gHints.state = gHints.HIDDEN;
|
|
224
227
|
},
|
|
225
228
|
toggle: function () {
|
|
226
|
-
if ((
|
|
227
|
-
|
|
229
|
+
if ((gHints.state || gHints.HIDDEN) === gHints.HIDDEN) {
|
|
230
|
+
gHints.show();
|
|
228
231
|
} else {
|
|
229
|
-
|
|
232
|
+
gHints.hide();
|
|
230
233
|
}
|
|
231
234
|
},
|
|
232
235
|
};
|
|
@@ -236,16 +239,48 @@ function keyboardEventHandler(pKeyboardEvent) {
|
|
|
236
239
|
if (pKeyboardEvent.key === "Escape") {
|
|
237
240
|
resetNodesAndEdges();
|
|
238
241
|
gMode.setToHover();
|
|
239
|
-
|
|
242
|
+
gHints.hide();
|
|
240
243
|
}
|
|
241
244
|
if (pKeyboardEvent.key === "F1") {
|
|
242
245
|
pKeyboardEvent.preventDefault();
|
|
243
|
-
|
|
246
|
+
gHints.toggle();
|
|
244
247
|
}
|
|
245
248
|
}
|
|
246
249
|
|
|
247
250
|
document.addEventListener("contextmenu", getSelectHandler(title2ElementMap));
|
|
248
251
|
document.addEventListener("mouseover", getHoverHandler(title2ElementMap));
|
|
249
252
|
document.addEventListener("keydown", keyboardEventHandler);
|
|
250
|
-
document.getElementById("close-hints").addEventListener("click",
|
|
251
|
-
document.getElementById("button_help").addEventListener("click",
|
|
253
|
+
document.getElementById("close-hints").addEventListener("click", gHints.hide);
|
|
254
|
+
document.getElementById("button_help").addEventListener("click", gHints.toggle);
|
|
255
|
+
document.querySelector("svg").insertAdjacentHTML(
|
|
256
|
+
"afterbegin",
|
|
257
|
+
`<linearGradient id="edgeGradient">
|
|
258
|
+
<stop offset="0%" stop-color="fuchsia"/>
|
|
259
|
+
<stop offset="100%" stop-color="purple"/>
|
|
260
|
+
</linearGradient>
|
|
261
|
+
`,
|
|
262
|
+
);
|
|
263
|
+
|
|
264
|
+
// Add a small increment to the last value of the path to make gradients on
|
|
265
|
+
// horizontal paths work. Without them all browsers I tested with (firefox,
|
|
266
|
+
// chrome) do not render the gradient, but instead make the line transparent
|
|
267
|
+
// (or the color of the background, I haven't looked into it that deeply,
|
|
268
|
+
// but for the hack it doesn't matter which).
|
|
269
|
+
function skewLineABit(lDrawingInstructions) {
|
|
270
|
+
var lLastValue = lDrawingInstructions.match(/(\d+\.?\d*)$/)[0];
|
|
271
|
+
// Smaller values than .001 _should_ work as well, but don't in all
|
|
272
|
+
// cases. Even this value is so small that it is not visible to the
|
|
273
|
+
// human eye (tested with the two I have at my disposal).
|
|
274
|
+
var lIncrement = 0.001;
|
|
275
|
+
var lNewLastValue = parseFloat(lLastValue) + lIncrement;
|
|
276
|
+
|
|
277
|
+
return lDrawingInstructions.replace(lLastValue, lNewLastValue);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
nodeListToArray(document.querySelectorAll("path"))
|
|
281
|
+
.filter(function (pElement) {
|
|
282
|
+
return pElement.parentElement.classList.contains("edge");
|
|
283
|
+
})
|
|
284
|
+
.forEach(function (pElement) {
|
|
285
|
+
pElement.attributes.d.value = skewLineABit(pElement.attributes.d.value);
|
|
286
|
+
});
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
.node:active path,
|
|
2
|
+
.node:hover path,
|
|
3
|
+
.node.current path,
|
|
4
|
+
.node:active polygon,
|
|
5
|
+
.node:hover polygon,
|
|
6
|
+
.node.current polygon {
|
|
7
|
+
stroke: fuchsia;
|
|
8
|
+
stroke-width: 2;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.edge:active path,
|
|
12
|
+
.edge:hover path,
|
|
13
|
+
.edge.current path,
|
|
14
|
+
.edge:active ellipse,
|
|
15
|
+
.edge:hover ellipse,
|
|
16
|
+
.edge.current ellipse {
|
|
17
|
+
stroke: url(#edgeGradient);
|
|
18
|
+
stroke-width: 3;
|
|
19
|
+
stroke-opacity: 1;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.edge:active polygon,
|
|
23
|
+
.edge:hover polygon,
|
|
24
|
+
.edge.current polygon {
|
|
25
|
+
stroke: fuchsia;
|
|
26
|
+
stroke-width: 3;
|
|
27
|
+
fill: fuchsia;
|
|
28
|
+
stroke-opacity: 1;
|
|
29
|
+
fill-opacity: 1;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.edge:active text,
|
|
33
|
+
.edge:hover text {
|
|
34
|
+
fill: fuchsia;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.cluster path {
|
|
38
|
+
stroke-width: 3;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.cluster:active path,
|
|
42
|
+
.cluster:hover path {
|
|
43
|
+
fill: #ffff0011;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
div.hint {
|
|
47
|
+
background-color: #000000aa;
|
|
48
|
+
color: white;
|
|
49
|
+
font-family: Arial, Helvetica, sans-serif;
|
|
50
|
+
border-radius: 1rem;
|
|
51
|
+
position: fixed;
|
|
52
|
+
top: calc(50% - 4em);
|
|
53
|
+
right: calc(50% - 10em);
|
|
54
|
+
border: none;
|
|
55
|
+
padding: 1em 3em 1em 1em;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.hint button {
|
|
59
|
+
position: absolute;
|
|
60
|
+
font-weight: bolder;
|
|
61
|
+
right: 0.6em;
|
|
62
|
+
top: 0.6em;
|
|
63
|
+
color: inherit;
|
|
64
|
+
background-color: inherit;
|
|
65
|
+
border: 1px solid currentColor;
|
|
66
|
+
border-radius: 1em;
|
|
67
|
+
margin-left: 0.6em;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.hint a {
|
|
71
|
+
color: inherit;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
#button_help {
|
|
75
|
+
color: white;
|
|
76
|
+
background-color: #00000011;
|
|
77
|
+
border-radius: 1em;
|
|
78
|
+
position: fixed;
|
|
79
|
+
top: 1em;
|
|
80
|
+
right: 1em;
|
|
81
|
+
font-size: 24pt;
|
|
82
|
+
font-weight: bolder;
|
|
83
|
+
width: 2em;
|
|
84
|
+
height: 2em;
|
|
85
|
+
border: none;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
#button_help:hover {
|
|
89
|
+
cursor: pointer;
|
|
90
|
+
background-color: #00000077;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
@media print {
|
|
94
|
+
#button_help {
|
|
95
|
+
display: none;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
div.hint {
|
|
99
|
+
display: none;
|
|
100
|
+
}
|
|
101
|
+
}
|