dependency-cruiser 11.5.0 → 11.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dependency-cruiser",
3
- "version": "11.5.0",
3
+ "version": "11.6.0",
4
4
  "description": "Validate and visualize dependencies. With your rules. JavaScript, TypeScript, CoffeeScript. ES6, CommonJS, AMD.",
5
5
  "keywords": [
6
6
  "static analysis",
@@ -142,8 +142,8 @@
142
142
  "acorn-walk": "8.2.0",
143
143
  "ajv": "8.11.0",
144
144
  "chalk": "^4.1.2",
145
- "commander": "9.1.0",
146
- "enhanced-resolve": "5.9.2",
145
+ "commander": "9.2.0",
146
+ "enhanced-resolve": "5.9.3",
147
147
  "figures": "^3.2.0",
148
148
  "get-stream": "^6.0.1",
149
149
  "glob": "7.2.0",
@@ -153,7 +153,7 @@
153
153
  "json5": "2.2.1",
154
154
  "lodash": "4.17.21",
155
155
  "safe-regex": "2.1.1",
156
- "semver": "^7.3.6",
156
+ "semver": "^7.3.7",
157
157
  "semver-try-require": "^5.0.2",
158
158
  "teamcity-service-messages": "0.1.12",
159
159
  "tsconfig-paths-webpack-plugin": "3.5.2",
@@ -163,10 +163,10 @@
163
163
  "@babel/core": "7.17.9",
164
164
  "@babel/plugin-transform-modules-commonjs": "7.17.9",
165
165
  "@babel/preset-typescript": "7.16.7",
166
- "@swc/core": "1.2.165",
167
- "@typescript-eslint/eslint-plugin": "5.18.0",
168
- "@typescript-eslint/parser": "5.18.0",
169
- "@vue/compiler-sfc": "3.2.31",
166
+ "@swc/core": "1.2.167",
167
+ "@typescript-eslint/eslint-plugin": "5.19.0",
168
+ "@typescript-eslint/parser": "5.19.0",
169
+ "@vue/compiler-sfc": "3.2.33",
170
170
  "c8": "7.11.0",
171
171
  "chai": "4.3.6",
172
172
  "chai-json-schema": "1.5.1",
@@ -213,6 +213,11 @@
213
213
  "policy": "wanted",
214
214
  "because": "version 4 only exports ejs - and we use cjs and don't transpile"
215
215
  },
216
+ {
217
+ "package": "glob",
218
+ "policy": "pin",
219
+ "because": "from version 7.2.1 behavior on windows changes - in a potentially breaking fashion. Wait with upgrading until we're majoring or from when there's a vuln in 7.2.0"
220
+ },
216
221
  {
217
222
  "package": "husky",
218
223
  "policy": "wanted",
@@ -9,8 +9,7 @@
9
9
  .node.current path,
10
10
  .node:active polygon,
11
11
  .node:hover polygon,
12
- .node.current polygon
13
- {
12
+ .node.current polygon {
14
13
  stroke: fuchsia;
15
14
  stroke-width: 2;
16
15
  }
@@ -44,6 +43,66 @@
44
43
  .cluster:hover path {
45
44
  fill: #ffff0011;
46
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
+ .hint button {
58
+ position: absolute;
59
+ font-weight: bolder;
60
+ right: 0.6em;
61
+ top: 0.6em;
62
+ color: inherit;
63
+ background-color: inherit;
64
+ border: 1px solid currentColor;
65
+ border-radius: 1em;
66
+ margin-left: 0.6em;
67
+ }
68
+ .hint a {
69
+ color: inherit;
70
+ }
71
+ #button_help {
72
+ color: white;
73
+ background-color: #00000011;
74
+ border-radius: 1em;
75
+ position: fixed;
76
+ top: 1em;
77
+ right: 1em;
78
+ font-size: 24pt;
79
+ font-weight: bolder;
80
+ width: 2em;
81
+ height: 2em;
82
+ border: none;
83
+ }
84
+ #button_help:hover {
85
+ cursor: pointer;
86
+ background-color: #00000077;
87
+ }
88
+ @media print {
89
+ #button_help {
90
+ display: none;
91
+ }
92
+ div.hint {
93
+ display: none;
94
+ }
95
+ }
47
96
  </style>
48
97
  </head>
49
98
  <body>
99
+ <button id="button_help">?</button>
100
+ <div id="hints" class="hint" style="display: none">
101
+ <button id="close-hints">x</button>
102
+ <span id="hint-text"></span>
103
+ <ul>
104
+ <li><b>Hover</b> - highlight</li>
105
+ <li><b>Left-click</b> - pin highlight</li>
106
+ <li><b>ESC</b> - clear</li>
107
+ </ul>
108
+ </div>
@@ -1,27 +1,85 @@
1
- document.body.onmouseover = getHighlightHandler();
1
+ document.addEventListener("contextmenu", getSelectHandler(title2ElementMap));
2
+ document.addEventListener("mouseover", getHoverHandler(title2ElementMap));
3
+ document.addEventListener("keydown", keyboardEventHandler);
2
4
 
3
- function getHighlightHandler() {
4
- /** @type {string} */
5
- var currentHighlightedTitle;
5
+ var gMode = new Mode();
6
6
 
7
+ var title2ElementMap = (function makeElementMap() {
7
8
  /** @type {NodeListOf<SVGGElement>} */
8
9
  var nodes = document.querySelectorAll(".node");
9
10
  /** @type {NodeListOf<SVGGElement>} */
10
11
  var edges = document.querySelectorAll(".edge");
11
- var title2ElementMap = new Title2ElementMap(edges, nodes);
12
+ return new Title2ElementMap(edges, nodes);
13
+ })();
14
+
15
+ function getHoverHandler() {
16
+ /** @type {string} */
17
+ var currentHighlightedTitle;
12
18
 
13
19
  /** @param {MouseEvent} pMouseEvent */
14
- return function highlightHandler(pMouseEvent) {
20
+ return function hoverHighlightHandler(pMouseEvent) {
21
+ var closestNodeOrEdge = pMouseEvent.target.closest(".edge, .node");
22
+ var closestTitleText = getTitleText(closestNodeOrEdge);
23
+
24
+ if (
25
+ !(currentHighlightedTitle === closestTitleText) &&
26
+ gMode.get() === gMode.HOVER
27
+ ) {
28
+ resetNodesAndEdges();
29
+ addHighlight(closestNodeOrEdge);
30
+ title2ElementMap.get(closestTitleText).forEach(addHighlight);
31
+ currentHighlightedTitle = closestTitleText;
32
+ }
33
+ };
34
+ }
35
+
36
+ function getSelectHandler() {
37
+ /** @type {string} */
38
+ var currentHighlightedTitle;
39
+
40
+ /** @param {MouseEvent} pMouseEvent */
41
+ return function selectHighlightHandler(pMouseEvent) {
42
+ pMouseEvent.preventDefault();
43
+
15
44
  var closestNodeOrEdge = pMouseEvent.target.closest(".edge, .node");
16
45
  var closestTitleText = getTitleText(closestNodeOrEdge);
17
46
 
47
+ if (!!closestNodeOrEdge) {
48
+ gMode.setToSelect();
49
+ } else {
50
+ gMode.setToHover();
51
+ }
18
52
  if (!(currentHighlightedTitle === closestTitleText)) {
19
- title2ElementMap.get(currentHighlightedTitle).forEach(removeHighlight);
53
+ resetNodesAndEdges();
54
+ addHighlight(closestNodeOrEdge);
20
55
  title2ElementMap.get(closestTitleText).forEach(addHighlight);
21
56
  currentHighlightedTitle = closestTitleText;
22
57
  }
23
58
  };
24
59
  }
60
+ function Mode() {
61
+ var HOVER = 1;
62
+ var SELECT = 2;
63
+
64
+ function setToHover() {
65
+ this._mode = HOVER;
66
+ }
67
+ function setToSelect() {
68
+ this._mode = SELECT;
69
+ }
70
+
71
+ function get() {
72
+ return this._mode || HOVER;
73
+ }
74
+
75
+ return {
76
+ HOVER: HOVER,
77
+ SELECT: SELECT,
78
+ setToHover: setToHover,
79
+ setToSelect: setToSelect,
80
+ get: get,
81
+ };
82
+ }
25
83
 
26
84
  /**
27
85
  *
@@ -132,6 +190,12 @@ function nodeListToArray(pNodeList) {
132
190
  return lReturnValue;
133
191
  }
134
192
 
193
+ function resetNodesAndEdges() {
194
+ nodeListToArray(document.querySelectorAll(".current")).forEach(
195
+ removeHighlight
196
+ );
197
+ }
198
+
135
199
  /**
136
200
  * @param {SVGGElement} pGElement
137
201
  */
@@ -149,3 +213,39 @@ function addHighlight(pGroup) {
149
213
  pGroup.classList.add("current");
150
214
  }
151
215
  }
216
+
217
+ var hints = {
218
+ HIDDEN: 1,
219
+ SHOWN: 2,
220
+ state: this.HIDDEN,
221
+ show: function () {
222
+ document.getElementById("hints").removeAttribute("style");
223
+ hints.state = hints.SHOWN;
224
+ },
225
+ hide: function () {
226
+ document.getElementById("hints").style = "display:none";
227
+ hints.state = hints.HIDDEN;
228
+ },
229
+ toggle: function () {
230
+ if ((hints.state || hints.HIDDEN) === hints.HIDDEN) {
231
+ hints.show();
232
+ } else {
233
+ hints.hide();
234
+ }
235
+ },
236
+ };
237
+
238
+ /** @param {KeyboardEvent} pKeyboardEvent */
239
+ function keyboardEventHandler(pKeyboardEvent) {
240
+ if (pKeyboardEvent.key === "Escape") {
241
+ resetNodesAndEdges();
242
+ gMode.setToHover();
243
+ hints.hide();
244
+ }
245
+ if (pKeyboardEvent.key === "F1") {
246
+ pKeyboardEvent.preventDefault();
247
+ hints.toggle();
248
+ }
249
+ }
250
+ document.getElementById("close-hints").addEventListener("click", hints.hide);
251
+ document.getElementById("button_help").addEventListener("click", hints.toggle);
@@ -31,7 +31,7 @@ const FOOTER_FILE = path.join(
31
31
  * @param {readStream} pStream stream whose characters are to be slapped between header and footer
32
32
  * @param {writeStream} pOutStream stream to write to
33
33
  */
34
- function wrap(pInStream, pOutStream) {
34
+ module.exports = function wrap(pInStream, pOutStream) {
35
35
  const lHeader = fs.readFileSync(HEADER_FILE, "utf8");
36
36
  const lScript = fs.readFileSync(SCRIPT_FILE, "utf8");
37
37
  const lEnd = fs.readFileSync(FOOTER_FILE, "utf8");
@@ -54,6 +54,4 @@ function wrap(pInStream, pOutStream) {
54
54
  .on("data", (pChunk) => {
55
55
  pOutStream.write(pChunk);
56
56
  });
57
- }
58
-
59
- module.exports = (pInStream, pOutStream) => wrap(pInStream, pOutStream);
57
+ };
package/src/meta.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /* generated - don't edit */
2
2
 
3
3
  module.exports = {
4
- version: "11.5.0",
4
+ version: "11.6.0",
5
5
  engines: {
6
6
  node: "^12.20||^14||>=16",
7
7
  },
@@ -1,10 +1,32 @@
1
1
  const { isModuleOnlyRule, isFolderScope } = require("./rule-classifiers");
2
2
  const matchers = require("./matchers");
3
3
 
4
+ function fromFolderPath(pRule, pFromFolder) {
5
+ return Boolean(!pRule.from.path || pFromFolder.name.match(pRule.from.path));
6
+ }
7
+
8
+ function fromFolderPathNot(pRule, pFromFolder) {
9
+ return Boolean(
10
+ !pRule.from.pathNot || !pFromFolder.name.match(pRule.from.pathNot)
11
+ );
12
+ }
13
+
14
+ function toFolderPath(pRule, pToFolder) {
15
+ return Boolean(!pRule.to.path || pToFolder.name.match(pRule.to.path));
16
+ }
17
+
18
+ function toFolderPathNot(pRule, pToFolder) {
19
+ return Boolean(!pRule.to.pathNot || !pToFolder.name.match(pRule.to.pathNot));
20
+ }
21
+
4
22
  function match(pFromFolder, pToFolder) {
5
23
  return (pRule) =>
6
- // TODO: add path rules - they need to be frippled from the ones
24
+ // TODO: to path rules - they need to be frippled from the ones
7
25
  // already in place for modules
26
+ fromFolderPath(pRule, pFromFolder) &&
27
+ fromFolderPathNot(pRule, pFromFolder) &&
28
+ toFolderPath(pRule, pToFolder) &&
29
+ toFolderPathNot(pRule, pToFolder) &&
8
30
  matchers.toIsMoreUnstable(pRule, pFromFolder, pToFolder) &&
9
31
  matchers.propertyEquals(pRule, pToFolder, "circular");
10
32
  }
@@ -47,8 +47,9 @@ export interface IRegularForbiddenRuleType extends IBaseRuleType {
47
47
  * to note when you decide to use 'folder' level scope: (1) the 'scope' attribute
48
48
  * is experimental - the way to indicate the scope of a rule can change
49
49
  * over time without dependency-cruiser undergoing a major bump. (2) Only
50
- * the to.moreUnstable attribute works at the moment. Other attributes will
51
- * follow suit in releases after 11.3.0."
50
+ * the to.moreUnstable, to.circular, and path (both from and to) attributes
51
+ * work at the moment. Other attributes will follow suit in releases
52
+ * after 11.6.0.
52
53
  */
53
54
  scope?: RuleScopeType;
54
55
  }