dependency-cruiser 16.10.4 → 17.0.1-beta-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // eslint-disable-next-line n/no-unsupported-features/node-builtins
2
+
3
3
  import { parseArgs } from "node:util";
4
4
  import assertNodeEnvironmentSuitable from "#cli/assert-node-environment-suitable.mjs";
5
5
  import cli from "#cli/index.mjs";
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // eslint-disable-next-line n/no-unsupported-features/node-builtins
2
+
3
3
  import { parseArgs } from "node:util";
4
4
  import assertNodeEnvironmentSuitable from "#cli/assert-node-environment-suitable.mjs";
5
5
  import format from "#cli/format.mjs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dependency-cruiser",
3
- "version": "16.10.4",
3
+ "version": "17.0.1-beta-1",
4
4
  "description": "Validate and visualize dependencies. With your rules. JavaScript, TypeScript, CoffeeScript. ES6, CommonJS, AMD.",
5
5
  "keywords": [
6
6
  "static analysis",
@@ -146,20 +146,18 @@
146
146
  "acorn-loose": "^8.5.2",
147
147
  "acorn-walk": "^8.3.4",
148
148
  "ajv": "^8.17.1",
149
- "commander": "^13.1.0",
150
- "enhanced-resolve": "^5.18.2",
149
+ "commander": "^14.0.1",
150
+ "enhanced-resolve": "^5.18.3",
151
151
  "ignore": "^7.0.5",
152
152
  "interpret": "^3.1.1",
153
153
  "is-installed-globally": "^1.0.0",
154
154
  "json5": "^2.2.3",
155
155
  "memoize": "^10.1.0",
156
- "picocolors": "^1.1.1",
157
- "picomatch": "^4.0.2",
156
+ "picomatch": "^4.0.3",
158
157
  "prompts": "^2.4.2",
159
158
  "rechoir": "^0.8.0",
160
159
  "safe-regex": "^2.1.1",
161
160
  "semver": "^7.7.2",
162
- "teamcity-service-messages": "^0.1.14",
163
161
  "tsconfig-paths-webpack-plugin": "^4.2.0",
164
162
  "watskeburt": "^4.2.3"
165
163
  },
@@ -172,7 +170,7 @@
172
170
  "nanoid": "^3.3.8"
173
171
  },
174
172
  "engines": {
175
- "node": "^18.17||>=20"
173
+ "node": "^20.12||^22||>=24"
176
174
  },
177
175
  "scripts": {
178
176
  "test": "echo see github for test, build and analysis scripts"
@@ -1,11 +1,11 @@
1
1
  import { release, platform, arch } from "node:os";
2
- import pc from "picocolors";
2
+ import { styleText } from "node:util";
3
3
 
4
4
  import { getAvailableTranspilers, allExtensions } from "#main/index.mjs";
5
5
  import meta from "#meta.cjs";
6
6
 
7
7
  function bool2Symbol(pBool) {
8
- return pBool ? pc.green("✔") : pc.red("x");
8
+ return pBool ? styleText("green", "✔") : styleText("red", "x");
9
9
  }
10
10
 
11
11
  const MAX_VERSION_RANGE_STRING_LENGTH = 19;
@@ -13,7 +13,8 @@ const MAX_TRANSPILER_NAME_LENGTH = 22;
13
13
  const MAX_VERSION_STRING_LENGTH = 24;
14
14
 
15
15
  function formatTranspilers() {
16
- let lTranspilerTableHeader = pc.bold(
16
+ let lTranspilerTableHeader = styleText(
17
+ "bold",
17
18
  ` ✔ ${"transpiler".padEnd(MAX_TRANSPILER_NAME_LENGTH)} ${"versions supported".padEnd(MAX_VERSION_RANGE_STRING_LENGTH)} version found`,
18
19
  );
19
20
  let lTranspilerTableDivider = ` - ${"-".repeat(MAX_TRANSPILER_NAME_LENGTH)} ${"-".repeat(MAX_VERSION_RANGE_STRING_LENGTH)} ${"-".repeat(MAX_VERSION_STRING_LENGTH)}`;
@@ -36,20 +37,21 @@ function formatExtensions(pExtensions) {
36
37
 
37
38
  export default function formatMetaInfo() {
38
39
  return `
39
- ${pc.bold("dependency-cruiser")}@${meta.version}
40
+ ${styleText("bold", "dependency-cruiser")}@${meta.version}
40
41
 
41
42
  node version supported : ${meta.engines.node}
42
43
  node version found : ${process.version}
43
44
  os version found : ${arch()} ${platform()}@${release()}
44
45
 
45
- If you need a supported, but not enabled transpiler ('${pc.red(
46
+ If you need a supported, but not enabled transpiler ('${styleText(
47
+ "red",
46
48
  "x",
47
49
  )}' below), just install
48
50
  it in the same folder dependency-cruiser is installed. E.g. 'npm i livescript'
49
51
  will enable livescript support if it's installed in your project folder.
50
52
 
51
53
  ${formatTranspilers()}
52
- ${pc.bold("✔ extension")}
54
+ ${styleText("bold", "✔ extension")}
53
55
  - ---------
54
56
  ${formatExtensions(allExtensions)}
55
57
  `;
package/src/cli/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { join } from "node:path";
2
+ import { styleText } from "node:util";
2
3
  import picomatch from "picomatch";
3
4
  import isInstalledGlobally from "is-installed-globally";
4
- import pc from "picocolors";
5
5
 
6
6
  import assertFileExistence from "./utl/assert-file-existence.mjs";
7
7
  import normalizeCliOptions from "./normalize-cli-options.mjs";
@@ -144,6 +144,7 @@ async function runCruise(pFileDirectoryArray, pCruiseOptions) {
144
144
  * @returns {number}
145
145
  */
146
146
 
147
+ // eslint-disable-next-line max-lines-per-function
147
148
  export default async function executeCli(
148
149
  pFileDirectoryArray,
149
150
  pCruiseOptions,
@@ -161,13 +162,13 @@ export default async function executeCli(
161
162
  /* c8 ignore start */
162
163
  if (isInstalledGlobally) {
163
164
  lStreams.stderr.write(
164
- `\n ${pc.yellow(
165
+ `\n ${styleText(
166
+ "yellow",
165
167
  "WARNING",
166
168
  )}: You're running a globally installed dependency-cruiser.\n\n` +
167
- ` We recommend to ${pc.bold(
168
- pc.italic(
169
- pc.underline("install and run it as a local devDependency"),
170
- ),
169
+ ` We recommend to ${styleText(
170
+ "underline",
171
+ "install and run it as a local devDependency",
171
172
  )} in\n` +
172
173
  ` your project instead. There it has your project's environment and\n` +
173
174
  ` transpilers at its disposal. That will ensure it can find e.g.\n` +
@@ -187,7 +188,9 @@ export default async function executeCli(
187
188
  lExitCode = await runCruise(pFileDirectoryArray, lCruiseOptions);
188
189
  }
189
190
  } catch (pError) {
190
- lStreams.stderr.write(`\n ${pc.red("ERROR")}: ${pError.message}\n`);
191
+ lStreams.stderr.write(
192
+ `\n ${styleText("red", "ERROR")}: ${pError.message}\n`,
193
+ );
191
194
  bus.emit("end");
192
195
  lExitCode = 1;
193
196
  }
@@ -1,5 +1,5 @@
1
1
  import { writeFileSync } from "node:fs";
2
- import pc from "picocolors";
2
+ import { styleText } from "node:util";
3
3
  import {
4
4
  fileExists,
5
5
  getDefaultConfigFileName,
@@ -29,7 +29,7 @@ export default function writeConfig(
29
29
  try {
30
30
  writeFileSync(pFileName, pConfig);
31
31
  pOutStream.write(
32
- `\n ${pc.green("✔")} Successfully created '${pFileName}'\n\n`,
32
+ `\n ${styleText("green", "✔")} Successfully created '${pFileName}'\n\n`,
33
33
  );
34
34
  /* c8 ignore start */
35
35
  } catch (pError) {
@@ -1,8 +1,8 @@
1
1
  /* eslint-disable prefer-template */
2
2
  /* eslint-disable security/detect-object-injection */
3
3
  import { writeFileSync } from "node:fs";
4
+ import { styleText } from "node:util";
4
5
  import { EOL } from "node:os";
5
- import pc from "picocolors";
6
6
  import { PACKAGE_MANIFEST as _PACKAGE_MANIFEST } from "../defaults.mjs";
7
7
  import { readManifest } from "./environment-helpers.mjs";
8
8
  import { folderNameArrayToRE } from "./utl.mjs";
@@ -124,11 +124,11 @@ function getSuccessMessage(pDestinationManifestFileName) {
124
124
  return EXPERIMENTAL_SCRIPT_DOC.reduce(
125
125
  (pAll, pScript) => {
126
126
  return `${pAll}${
127
- `\n ${pc.green("►")} ${pScript.headline}` +
127
+ `\n ${styleText("green", "►")} ${pScript.headline}` +
128
128
  `\n${pScript.description}\n\n`
129
129
  }`;
130
130
  },
131
- ` ${pc.green("✔")} Run scripts added to '${pDestinationManifestFileName}':\n`,
131
+ ` ${styleText("green", "✔")} Run scripts added to '${pDestinationManifestFileName}':\n`,
132
132
  );
133
133
  }
134
134
 
@@ -1,4 +1,4 @@
1
- import pc from "picocolors";
1
+ import { styleText } from "node:util";
2
2
  import { SUMMARY } from "#utl/bus.mjs";
3
3
 
4
4
  const FULL_ON = 100;
@@ -17,7 +17,8 @@ function getPercentageBar(pPercentage, pParameters) {
17
17
  const lBlocks = Math.floor(lParameters.barSize * lPercentage);
18
18
  const lBlanks = lParameters.barSize - lBlocks;
19
19
 
20
- return `${pc.green(lParameters.block.repeat(lBlocks))}${pc.green(
20
+ return `${styleText("green", lParameters.block.repeat(lBlocks))}${styleText(
21
+ "green",
21
22
  lParameters.blank.repeat(lBlanks),
22
23
  )} ${Math.round(FULL_ON * lPercentage)}%`;
23
24
  }
@@ -1,4 +1,4 @@
1
- import pc from "picocolors";
1
+ import { styleText } from "node:util";
2
2
  import { INFO } from "#utl/bus.mjs";
3
3
 
4
4
  const MS_PER_SECOND = 1000;
@@ -43,23 +43,22 @@ export function formatDividerLine() {
43
43
  }
44
44
 
45
45
  export function formatHeader() {
46
- return pc
47
- .bold(
48
- `${
49
- pad("∆ rss") +
50
- pad("∆ heapTotal") +
51
- pad("∆ heapUsed") +
52
- pad("∆ external") +
53
- pad("⏱ system") +
54
- pad("⏱ user") +
55
- pad("⏱ real")
56
- }after step...\n`,
57
- )
58
- .concat(formatDividerLine());
46
+ return styleText(
47
+ "bold",
48
+ `${
49
+ pad("∆ rss") +
50
+ pad("∆ heapTotal") +
51
+ pad("∆ heapUsed") +
52
+ pad("∆ external") +
53
+ pad("⏱ system") +
54
+ pad("⏱ user") +
55
+ pad("⏱ real")
56
+ }after step...\n`,
57
+ ).concat(formatDividerLine());
59
58
  }
60
59
 
61
60
  function formatMessage(pMessage, pLevel) {
62
- return pLevel >= INFO ? pc.dim(pMessage) : pMessage;
61
+ return pLevel >= INFO ? styleText("dim", pMessage) : pMessage;
63
62
  }
64
63
 
65
64
  export function formatTime(
@@ -81,7 +80,7 @@ export function formatMemory(pBytes, pLevel) {
81
80
  );
82
81
 
83
82
  return formatMessage(
84
- (pBytes < 0 ? pc.blue(lReturnValue) : lReturnValue).concat(" "),
83
+ (pBytes < 0 ? styleText("blue", lReturnValue) : lReturnValue).concat(" "),
85
84
  pLevel,
86
85
  );
87
86
  }
@@ -116,7 +116,9 @@ async function compileResolveOptions(
116
116
  // so we do it ourselves - either with the extensions passed
117
117
  // or with the supported ones.
118
118
  extensions:
119
- pResolveOptions.extensions || DEFAULT_RESOLVE_OPTIONS.extensions,
119
+ pResolveOptionsFromDCConfig.extensions ||
120
+ pResolveOptions.extensions ||
121
+ DEFAULT_RESOLVE_OPTIONS.extensions,
120
122
  }),
121
123
  );
122
124
  }
package/src/meta.cjs CHANGED
@@ -1,9 +1,9 @@
1
1
  /* generated - don't edit */
2
2
 
3
3
  module.exports = {
4
- version: "16.10.4",
4
+ version: "17.0.1-beta-1",
5
5
  engines: {
6
- node: "^18.17||>=20",
6
+ node: "^20.12||^22||>=24",
7
7
  },
8
8
  supportedTranspilers: {
9
9
  babel: ">=7.0.0 <8.0.0",
@@ -1,5 +1,5 @@
1
1
  import { EOL } from "node:os";
2
- import pc from "picocolors";
2
+ import { styleText } from "node:util";
3
3
  import {
4
4
  formatPercentage,
5
5
  formatViolation as _formatViolation,
@@ -7,11 +7,11 @@ import {
7
7
  import { findRuleByName } from "#graph-utl/rule-set.mjs";
8
8
  import wrapAndIndent from "#utl/wrap-and-indent.mjs";
9
9
 
10
- const SEVERITY2COLOR_FN = new Map([
11
- ["error", pc.red],
12
- ["warn", pc.yellow],
13
- ["info", pc.cyan],
14
- ["ignore", pc.gray],
10
+ const SEVERITY2COLOR = new Map([
11
+ ["error", "red"],
12
+ ["warn", "yellow"],
13
+ ["info", "cyan"],
14
+ ["ignore", "gray"],
15
15
  ]);
16
16
 
17
17
  const EXTRA_PATH_INFORMATION_INDENT = 6;
@@ -26,25 +26,24 @@ function formatMiniDependency(pMiniDependency) {
26
26
  }
27
27
 
28
28
  function formatModuleViolation(pViolation) {
29
- return pc.bold(pViolation.from);
29
+ return styleText("bold", pViolation.from);
30
30
  }
31
31
 
32
32
  function formatDependencyViolation(pViolation) {
33
- return `${pc.bold(pViolation.from)} → ${pc.bold(pViolation.to)}`;
33
+ return `${styleText("bold", pViolation.from)} → ${styleText("bold", pViolation.to)}`;
34
34
  }
35
35
 
36
36
  function formatCycleViolation(pViolation) {
37
- return `${pc.bold(pViolation.from)} → ${formatMiniDependency(pViolation.cycle)}`;
37
+ return `${styleText("bold", pViolation.from)} → ${formatMiniDependency(pViolation.cycle)}`;
38
38
  }
39
39
 
40
40
  function formatReachabilityViolation(pViolation) {
41
- return `${pc.bold(pViolation.from)} → ${pc.bold(
42
- pViolation.to,
43
- )}${formatMiniDependency(pViolation.via)}`;
41
+ return `${styleText("bold", pViolation.from)} → ${styleText("bold", pViolation.to)}${formatMiniDependency(pViolation.via)}`;
44
42
  }
45
43
 
46
44
  function formatInstabilityViolation(pViolation) {
47
- return `${formatDependencyViolation(pViolation)}${EOL}${pc.dim(
45
+ return `${formatDependencyViolation(pViolation)}${EOL}${styleText(
46
+ "dim",
48
47
  wrapAndIndent(
49
48
  `instability: ${formatPercentage(pViolation.metrics.from.instability)} → ${formatPercentage(pViolation.metrics.to.instability)}`,
50
49
  EXTRA_PATH_INFORMATION_INDENT,
@@ -67,12 +66,13 @@ function formatViolation(pViolation) {
67
66
  );
68
67
 
69
68
  return (
70
- `${SEVERITY2COLOR_FN.get(pViolation.rule.severity)(
69
+ `${styleText(
70
+ SEVERITY2COLOR.get(pViolation.rule.severity),
71
71
  pViolation.rule.severity,
72
72
  )} ${pViolation.rule.name}: ${lFormattedViolators}` +
73
73
  `${
74
74
  pViolation.comment
75
- ? `${EOL}${pc.dim(wrapAndIndent(pViolation.comment))}${EOL}`
75
+ ? `${EOL}${styleText("dim", wrapAndIndent(pViolation.comment))}${EOL}`
76
76
  : ""
77
77
  }`
78
78
  );
@@ -93,7 +93,7 @@ function formatSummary(pSummary) {
93
93
  pSummary.totalCruised
94
94
  } modules, ${pSummary.totalDependenciesCruised} dependencies cruised.${EOL}`;
95
95
 
96
- return pSummary.error > 0 ? pc.red(lMessage) : lMessage;
96
+ return pSummary.error > 0 ? styleText("red", lMessage) : lMessage;
97
97
  }
98
98
 
99
99
  function addExplanation(pRuleSet, pLong) {
@@ -107,7 +107,8 @@ function addExplanation(pRuleSet, pLong) {
107
107
 
108
108
  function formatIgnoreWarning(pNumberOfIgnoredViolations) {
109
109
  if (pNumberOfIgnoredViolations > 0) {
110
- return pc.yellow(
110
+ return styleText(
111
+ "yellow",
111
112
  `‼ ${pNumberOfIgnoredViolations} known violations ignored. Run with --no-ignore-known to see them.${EOL}`,
112
113
  );
113
114
  }
@@ -120,7 +121,7 @@ function report(pResults, pLong) {
120
121
  );
121
122
 
122
123
  if (lNonIgnorableViolations.length === 0) {
123
- return `${EOL}${pc.green("✔")} no dependency violations found (${
124
+ return `${EOL}${styleText("green", "✔")} no dependency violations found (${
124
125
  pResults.summary.totalCruised
125
126
  } modules, ${
126
127
  pResults.summary.totalDependenciesCruised
@@ -1,5 +1,5 @@
1
1
  import { EOL } from "node:os";
2
- import pc from "picocolors";
2
+ import { styleText } from "node:util";
3
3
  import { formatNumber, formatPercentage } from "./utl/index.mjs";
4
4
 
5
5
  /**
@@ -224,7 +224,7 @@ function formatToTextData(pData, pMetaData) {
224
224
  * @returns {string}
225
225
  */
226
226
  function formatToTextTable(pData, pMetaData) {
227
- return [pc.bold(formatToTextHeader(pMetaData))]
227
+ return [styleText("bold", formatToTextHeader(pMetaData))]
228
228
  .concat(formatToTextDemarcationLine(pMetaData))
229
229
  .concat(formatToTextData(pData, pMetaData))
230
230
  .join(EOL)
@@ -1,6 +1,100 @@
1
- import tsm from "teamcity-service-messages";
1
+ import { randomInt } from "node:crypto";
2
+ import memoize, { memoizeClear } from "memoize";
3
+
2
4
  import { formatPercentage, formatViolation } from "./utl/index.mjs";
3
5
 
6
+ /**
7
+ * Escape string for TeamCity output.
8
+ * @see https://confluence.jetbrains.com/display/TCD65/Build+Script+Interaction+with+TeamCity#BuildScriptInteractionwithTeamCity-servMsgsServiceMessages
9
+ * Copied from https://github.com/pifantastic/teamcity-service-messages/blob/master/lib/message.js#L72
10
+ *
11
+ * @param {String} pMessageString the string to escape
12
+ * @return {String}
13
+ */
14
+ function escape(pMessageString) {
15
+ if (pMessageString === null) {
16
+ return "";
17
+ }
18
+
19
+ return (
20
+ pMessageString
21
+ .toString()
22
+ .replace(/\|/g, "||")
23
+ .replace(/\n/g, "|n")
24
+ .replace(/\r/g, "|r")
25
+ .replace(/\[/g, "|[")
26
+ .replace(/\]/g, "|]")
27
+ // next line
28
+ .replace(/\u0085/g, "|x")
29
+ // line separator
30
+ .replace(/\u2028/g, "|l")
31
+ // paragraph separator
32
+ .replace(/\u2029/g, "|p")
33
+ .replace(/'/g, "|'")
34
+ );
35
+ }
36
+
37
+ /**
38
+ * Returns a random flowId consisting of 10 numeric digits. TeamCity doesn't
39
+ * currently seem to have demands on the format (it's just a string as far
40
+ * as I can tell), but this is what teamcity-service-messages used, so as
41
+ * per the rule of least surprise, this is what we use.
42
+ *
43
+ * @return {string} a random flowId consisting of 10 numeric digits
44
+ */
45
+ function getRandomFlowIdBare() {
46
+ const lFlowIdLength = 10;
47
+ // eslint-disable-next-line no-magic-numbers
48
+ const lFlowIdMax = 10 ** lFlowIdLength;
49
+
50
+ return randomInt(1, lFlowIdMax).toString().padStart(lFlowIdLength, "0");
51
+ }
52
+
53
+ const getRandomFlowId = memoize(getRandomFlowIdBare);
54
+
55
+ /**
56
+ * Returns a timestamp in ISO format without the trailing 'Z'. It used to be
57
+ * an issue with TeamCity that it didn't use the trailing 'Z' (this is
58
+ * documented in the teamcity-service-messages source code) - not sure whether
59
+ * this is still the case, but this is what we do to be on the safe side.
60
+ *
61
+ * @returns {string} a timestamp in ISO format without the trailing 'Z'
62
+ */
63
+ function getTimeStamp() {
64
+ return new Date().toISOString().slice(0, -1);
65
+ }
66
+
67
+ function inspectionType(pData) {
68
+ const lAttributes = [];
69
+ lAttributes.push(
70
+ `id='${pData.id}'`,
71
+ `name='${pData.name}'`,
72
+ `description='${escape(pData.description)}'`,
73
+ `category='${pData.category}'`,
74
+ `flowId='${getRandomFlowId()}'`,
75
+ `timestamp='${getTimeStamp()}'`,
76
+ );
77
+ return `##teamcity[inspectionType ${lAttributes.join(" ")}]`;
78
+ }
79
+
80
+ function inspection(pData) {
81
+ const lAttributes = [];
82
+ lAttributes.push(
83
+ `typeId='${pData.typeId}'`,
84
+ `message='${escape(pData.message)}'`,
85
+ );
86
+ if (pData.file) {
87
+ lAttributes.push(`file='${pData.file}'`);
88
+ }
89
+ lAttributes.push(
90
+ `SEVERITY='${pData.SEVERITY}'`,
91
+ `flowId='${getRandomFlowId()}'`,
92
+ `timestamp='${getTimeStamp()}'`,
93
+ );
94
+
95
+ return `##teamcity[inspection ${lAttributes.join(" ")}]`;
96
+ }
97
+
4
98
  const CATEGORY = "dependency-cruiser";
5
99
  const SEVERITY2TEAMCITY_SEVERITY = new Map([
6
100
  ["error", "ERROR"],
@@ -19,7 +113,7 @@ function reportRules(pRules, pViolations) {
19
113
  pViolations.some((pViolation) => pRule.name === pViolation.rule.name),
20
114
  )
21
115
  .map((pRule) =>
22
- tsm.inspectionType({
116
+ inspectionType({
23
117
  id: pRule.name,
24
118
  name: pRule.name,
25
119
  description: pRule.comment || pRule.name,
@@ -35,7 +129,7 @@ function reportAllowedRule(pAllowedRule, pViolations) {
35
129
  pAllowedRule.length > 0 &&
36
130
  pViolations.some((pViolation) => pViolation.rule.name === "not-in-allowed")
37
131
  ) {
38
- lReturnValue = tsm.inspectionType({
132
+ lReturnValue = inspectionType({
39
133
  id: "not-in-allowed",
40
134
  name: "not-in-allowed",
41
135
  description: "dependency is not in the 'allowed' set of rules",
@@ -49,7 +143,7 @@ function reportIgnoredRules(pIgnoredCount) {
49
143
  let lReturnValue = [];
50
144
 
51
145
  if (pIgnoredCount > 0) {
52
- lReturnValue = tsm.inspectionType({
146
+ lReturnValue = inspectionType({
53
147
  id: "ignored-known-violations",
54
148
  name: "ignored-known-violations",
55
149
  description:
@@ -114,7 +208,7 @@ function reportIgnoredViolation(pIgnoredCount) {
114
208
  let lReturnValue = [];
115
209
 
116
210
  if (pIgnoredCount > 0) {
117
- lReturnValue = tsm.inspection({
211
+ lReturnValue = inspection({
118
212
  typeId: "ignored-known-violations",
119
213
  message: `${pIgnoredCount} known violations ignored. Run with --no-ignore-known to see them.`,
120
214
  SEVERITY: "WARNING",
@@ -126,7 +220,7 @@ function reportIgnoredViolation(pIgnoredCount) {
126
220
  function reportViolations(pViolations, pIgnoredCount) {
127
221
  return pViolations
128
222
  .map((pViolation) =>
129
- tsm.inspection({
223
+ inspection({
130
224
  typeId: pViolation.rule.name,
131
225
  message: bakeViolationMessage(pViolation),
132
226
  file: pViolation.from,
@@ -138,21 +232,17 @@ function reportViolations(pViolations, pIgnoredCount) {
138
232
 
139
233
  /**
140
234
  * Returns a bunch of TeamCity service messages:
141
- * - for each violated rule in the passed results: an `inspectionType` with the name and comment of that rule
142
- * - for each violation in the passed results: an `inspection` with the violated rule name and the tos and froms
235
+ * - for each violated rule in the passed results: an `inspectionType` with the
236
+ * name and comment of that rule
237
+ * - for each violation in the passed results: an `inspection` with the
238
+ * violated rule name and the tos and froms
143
239
  *
144
240
  * @param {import("../../types/dependency-cruiser.js").ICruiseResult} pResults
145
241
  * @returns {import("../../types/dependency-cruiser.js").IReporterOutput}
146
242
  */
147
243
  // eslint-disable-next-line complexity
148
244
  export default function teamcity(pResults) {
149
- // this is the documented way to get tsm to emit strings
150
- // Alternatively we could've used the 'low level API', which
151
- // involves creating new `Message`s and stringifying those.
152
- // The abstraction of the 'higher level API' makes this
153
- // reporter more easy to implement and maintain, despite
154
- // setting this property directly
155
- tsm.stdout = false;
245
+ memoizeClear(getRandomFlowId);
156
246
 
157
247
  const lRuleSet = pResults?.summary?.ruleSetUsed ?? [];
158
248
  const lViolations = (pResults?.summary?.violations ?? []).filter(
@@ -1,4 +1,4 @@
1
- import pc from "picocolors";
1
+ import { styleText } from "node:util";
2
2
 
3
3
  const DEFAULT_OPTIONS = {
4
4
  highlightFocused: false,
@@ -36,7 +36,9 @@ function toFlatDependencies(pModules, pModulesInFocus, pHighlightFocused) {
36
36
  }
37
37
 
38
38
  function stringifyModule(pModule) {
39
- return pModule.highlight ? pc.underline(pModule.name) : pModule.name;
39
+ return pModule.highlight
40
+ ? styleText("underline", pModule.name)
41
+ : pModule.name;
40
42
  }
41
43
 
42
44
  function stringify(pFlatDependency) {
@@ -2,10 +2,6 @@
2
2
  export type ModuleSystemType = "cjs" | "amd" | "es6" | "tsd";
3
3
 
4
4
  // cruise options, dependency-cruiser
5
- /* as we don't care about types beyond code completion, we ignore the
6
- * eslint warning that the 'string' type is redundant here.
7
- */
8
- /* eslint-disable @typescript-eslint/no-redundant-type-constituents */
9
5
  export type OutputType =
10
6
  | "json"
11
7
  | "html"
@@ -29,7 +25,7 @@ export type OutputType =
29
25
  | "null"
30
26
  // for plugins: string. TODO: research whether it's possible to
31
27
  // tie this down to the `^plugin:[^:]+-reporter-plugin.[cm]?js$` regex
32
- | string;
28
+ | (string & {}); // autocompletion hack
33
29
 
34
30
  export type SeverityType = "error" | "warn" | "info" | "ignore";
35
31