dependency-cruiser 18.0.0 → 18.1.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.
Files changed (111) hide show
  1. package/configs/plugins/3d-reporter-plugin.mjs +1 -1
  2. package/configs/plugins/stats-reporter-plugin.mjs +2 -2
  3. package/package.json +5 -5
  4. package/src/analyze/add-validations.mjs +1 -1
  5. package/src/analyze/derive/folders/utl.mjs +2 -2
  6. package/src/analyze/summarize/index.mjs +121 -4
  7. package/src/analyze/summarize/summarize-modules.mjs +1 -1
  8. package/src/cache/cache.mjs +5 -5
  9. package/src/cache/helpers.mjs +2 -2
  10. package/src/cli/format-meta-info.mjs +12 -14
  11. package/src/cli/index.mjs +3 -4
  12. package/src/cli/init-config/check-and-warn-inconsistencies.mjs +3 -3
  13. package/src/cli/init-config/environment-helpers.mjs +4 -4
  14. package/src/cli/init-config/get-user-input.mjs +1 -1
  15. package/src/cli/init-config/index.mjs +1 -1
  16. package/src/cli/init-config/normalize-init-options.mjs +3 -3
  17. package/src/cli/init-config/validators.mjs +1 -1
  18. package/src/cli/init-config/write-run-scripts-to-manifest.mjs +2 -2
  19. package/src/cli/listeners/ndjson.mjs +1 -1
  20. package/src/cli/listeners/performance-log/index.mjs +1 -1
  21. package/src/cli/normalize-cli-options.mjs +6 -4
  22. package/src/cli/utl/assert-file-existence.mjs +1 -1
  23. package/src/config-utl/extract-babel-config.mjs +3 -1
  24. package/src/config-utl/extract-depcruise-config/index.mjs +1 -1
  25. package/src/config-utl/extract-depcruise-config/merge-configs.mjs +5 -3
  26. package/src/config-utl/extract-ts-config.mjs +1 -1
  27. package/src/config-utl/extract-webpack-resolve-config.mjs +2 -2
  28. package/src/environment.mjs +17 -0
  29. package/src/extract/acorn/extract.mjs +1 -1
  30. package/src/extract/acorn/parse.mjs +2 -2
  31. package/src/extract/extract-dependencies.mjs +1 -1
  32. package/src/extract/extract-stats.mjs +1 -1
  33. package/src/extract/gather-initial-sources.mjs +1 -1
  34. package/src/extract/helpers.mjs +1 -1
  35. package/src/extract/index.mjs +1 -1
  36. package/src/extract/resolve/determine-dependency-types.mjs +3 -2
  37. package/src/extract/resolve/external-module-helpers.mjs +8 -8
  38. package/src/extract/resolve/get-manifest.mjs +7 -7
  39. package/src/extract/resolve/index.mjs +2 -1
  40. package/src/extract/resolve/merge-manifests.mjs +2 -2
  41. package/src/extract/resolve/module-classifiers.mjs +1 -1
  42. package/src/extract/resolve/resolve-amd.mjs +1 -1
  43. package/src/extract/resolve/resolve-cjs.mjs +2 -2
  44. package/src/extract/resolve/resolve-helpers.mjs +1 -1
  45. package/src/extract/resolve/resolve.mjs +2 -2
  46. package/src/extract/swc/dependency-visitor.mjs +1 -0
  47. package/src/extract/swc/parse.mjs +2 -2
  48. package/src/extract/transpile/index.mjs +1 -1
  49. package/src/extract/transpile/meta.mjs +1 -1
  50. package/src/extract/transpile/try-import-available.mjs +1 -1
  51. package/src/extract/transpile/typescript-wrap.mjs +1 -1
  52. package/src/extract/tsc/extract-typescript-deps.mjs +1 -1
  53. package/src/extract/tsc/parse.mjs +3 -3
  54. package/src/graph-utl/add-focus.mjs +1 -1
  55. package/src/graph-utl/consolidate-to-pattern.mjs +1 -0
  56. package/src/graph-utl/indexed-module-graph.mjs +6 -6
  57. package/src/graph-utl/module-graph-with-dependency-set.mjs +1 -1
  58. package/src/graph-utl/rule-set.mjs +3 -3
  59. package/src/main/cruise.mjs +1 -1
  60. package/src/main/helpers.mjs +1 -1
  61. package/src/main/options/normalize.mjs +2 -2
  62. package/src/main/report-wrap.mjs +1 -0
  63. package/src/main/resolve-options/normalize.mjs +2 -2
  64. package/src/main/rule-set/assert-validity.mjs +1 -1
  65. package/src/main/rule-set/normalize.mjs +1 -1
  66. package/src/meta.cjs +1 -1
  67. package/src/report/anon/anonymize-path-element.mjs +1 -1
  68. package/src/report/anon/index.mjs +1 -1
  69. package/src/report/anon/random-string.mjs +1 -1
  70. package/src/report/azure-devops.mjs +2 -2
  71. package/src/report/baseline.mjs +1 -1
  72. package/src/report/d2.mjs +3 -3
  73. package/src/report/dot/index.mjs +1 -1
  74. package/src/report/dot/module-utl.mjs +2 -2
  75. package/src/report/dot/theming.mjs +12 -6
  76. package/src/report/dot-webpage/svg-in-html-snippets/script.cjs +7 -7
  77. package/src/report/error-html/error-html-template.mjs +7 -0
  78. package/src/report/error.mjs +33 -2
  79. package/src/report/html/index.mjs +2 -2
  80. package/src/report/index.mjs +1 -0
  81. package/src/report/markdown.mjs +3 -3
  82. package/src/report/mermaid.mjs +3 -3
  83. package/src/report/metrics.mjs +2 -2
  84. package/src/report/plugins.mjs +2 -1
  85. package/src/report/teamcity.mjs +2 -2
  86. package/src/report/utl/dependency-to-incidence-transformer.mjs +1 -1
  87. package/src/report/utl/index.mjs +1 -1
  88. package/src/schema/cruise-result.validate.mjs +1 -1
  89. package/src/utl/array-util.mjs +1 -1
  90. package/src/utl/find-all-files.mjs +1 -1
  91. package/src/utl/get-extension.mjs +1 -1
  92. package/src/utl/path-to-posix.mjs +1 -1
  93. package/src/utl/regex-util.mjs +4 -2
  94. package/src/utl/try-import.mjs +1 -1
  95. package/src/utl/try-require.cjs +3 -3
  96. package/src/validate/index.mjs +2 -2
  97. package/types/config-utl/extract-babel-config.d.mts +1 -1
  98. package/types/config-utl/extract-depcruise-config.d.mts +1 -1
  99. package/types/config-utl/extract-depcruise-options.d.mts +1 -1
  100. package/types/config-utl/extract-ts-config.d.mts +1 -1
  101. package/types/config-utl/extract-webpack-resolve-config.d.mts +1 -1
  102. package/types/cruise-result.d.mts +27 -0
  103. package/types/dependency-cruiser.d.mts +5 -26
  104. package/types/environment.d.mts +29 -0
  105. package/types/options.d.mts +1 -4
  106. package/types/plugins/3d-reporter-plugin.d.mts +1 -1
  107. package/types/plugins/mermaid-reporter-plugin.d.mts +1 -1
  108. package/types/plugins/stats-reporter-plugin.d.mts +1 -1
  109. package/types/rule-set.d.mts +2 -5
  110. package/types/shared-types.d.mts +1 -5
  111. package/types/strict-rule-set.d.mts +2 -5
@@ -114,7 +114,7 @@ function render3DThing(pCruiseResult) {
114
114
  * @param {import('../../types/dependency-cruiser').ICruiseResult} pCruiseResult -
115
115
  * the output of a dependency-cruise adhering to dependency-cruiser's
116
116
  * cruise result schema
117
- * @return {import('../../types/dependency-cruiser').IReporterOutput} -
117
+ * @returns {import('../../types/dependency-cruiser').IReporterOutput} -
118
118
  * output: a string
119
119
  * exitCode: 0
120
120
  */
@@ -34,7 +34,7 @@ function doMagic(pCruiseResult) {
34
34
  * got passed
35
35
  *
36
36
  * @param {import('../../types/dependency-cruiser').ICruiseResult} pCruiseResult - a result from a cruise.
37
- * @return {string} an object with some stats
37
+ * @returns {string} an object with some stats
38
38
  */
39
39
  function samplePluginReporter(pCruiseResult) {
40
40
  const lDependencyCounts = pCruiseResult.modules
@@ -68,7 +68,7 @@ function samplePluginReporter(pCruiseResult) {
68
68
  * @param {import('../../types/dependency-cruiser').ICruiseResult} pCruiseResult -
69
69
  * the output of a dependency-cruise adhering to dependency-cruiser's
70
70
  * cruise result schema
71
- * @return {import('../../types/dependency-cruiser').IReporterOutput} -
71
+ * @returns {import('../../types/dependency-cruiser').IReporterOutput} -
72
72
  * output: some stats on modules and dependencies in json format
73
73
  * exitCode: 0
74
74
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dependency-cruiser",
3
- "version": "18.0.0",
3
+ "version": "18.1.1",
4
4
  "description": "Validate and visualize dependencies. With your rules. JavaScript, TypeScript, CoffeeScript. ES6, CommonJS, AMD.",
5
5
  "keywords": [
6
6
  "static analysis",
@@ -143,18 +143,18 @@
143
143
  "README.md"
144
144
  ],
145
145
  "dependencies": {
146
- "acorn": "8.17.0",
146
+ "acorn": "8.18.0",
147
147
  "acorn-jsx": "5.3.2",
148
148
  "acorn-jsx-walk": "2.0.0",
149
149
  "acorn-loose": "8.5.2",
150
150
  "acorn-walk": "8.3.5",
151
151
  "commander": "15.0.0",
152
- "enhanced-resolve": "5.24.1",
153
- "ignore": "7.0.5",
152
+ "enhanced-resolve": "5.24.5",
153
+ "ignore": "7.0.6",
154
154
  "interpret": "3.1.1",
155
155
  "is-installed-globally": "1.0.0",
156
156
  "json5": "2.2.3",
157
- "picomatch": "4.0.4",
157
+ "picomatch": "4.0.5",
158
158
  "prompts": "2.4.2",
159
159
  "rechoir": "0.8.0",
160
160
  "safe-regex": "2.1.1",
@@ -17,7 +17,7 @@ function addDependencyViolations(pModule, pDependency, pRuleSet, pValidate) {
17
17
  * @param {Partial<import("../../types/cruise-result.mjs").IModule>[]} pModules array of modules
18
18
  * @param {import("../../types/rule-set.mjs").IFlattenedRuleSet} pRuleSet normalized & validated rule set
19
19
  * @param {boolean} pValidate - whether or not to validate (typically you want to pass 'true' here)
20
- * @return {import("../../types/cruise-result.mjs").IModule[]} the same array of modules, with for each
20
+ * @returns {import("../../types/cruise-result.mjs").IModule[]} the same array of modules, with for each
21
21
  * of them added whether or not it is
22
22
  * valid and if not which rules were violated
23
23
  */
@@ -23,8 +23,8 @@ export function getEfferentCouplings(pModule, pDirname) {
23
23
  * @returns string[]
24
24
  */
25
25
  export function getParentFolders(pPath) {
26
- let lFragments = pPath.split("/");
27
- let lReturnValue = [];
26
+ const lFragments = pPath.split("/");
27
+ const lReturnValue = [];
28
28
 
29
29
  while (lFragments.length > 0) {
30
30
  lReturnValue.push(lFragments.join("/"));
@@ -1,3 +1,4 @@
1
+ import { EOL } from "node:os";
1
2
  import addRuleSetUsed from "./add-rule-set-used.mjs";
2
3
  import summarizeModules from "./summarize-modules.mjs";
3
4
  import summarizeFolders from "./summarize-folders.mjs";
@@ -8,31 +9,146 @@ import {
8
9
  getDependenciesCruised,
9
10
  } from "./get-stats.mjs";
10
11
  import { compareViolations } from "#graph-utl/compare.mjs";
12
+ import { getEnvironmentInfo } from "#environment.mjs";
13
+
14
+ /**
15
+ * @import { IOptions, IEnvironmentIssue, ISummary, IModule, IFolder } from "../../../types/cruise-result.mjs"
16
+ * @import { IAvailableTranspiler } from "../../../types/environment.mjs"
17
+ * @import { IStrictCruiseOptions } from "../../../types/strict-options.mjs"
18
+ */
19
+
20
+ /**
21
+ * @param { IOptions } pOptions
22
+ * @param { IAvailableTranspiler[] } pAvailableTranspilers
23
+ * @returns { boolean }
24
+ */
25
+ function swcIsConsistent(pOptions, pAvailableTranspilers) {
26
+ const lSWCNeeded = (pOptions?.parser ?? "acorn") === "swc";
27
+ return lSWCNeeded
28
+ ? pAvailableTranspilers.some(
29
+ (pTranspiler) => pTranspiler.name === "swc" && pTranspiler.available,
30
+ )
31
+ : true;
32
+ }
33
+
34
+ /**
35
+ * @param { IOptions } pOptions
36
+ * @param { IAvailableTranspiler[] } pAvailableTranspilers
37
+ * @returns { boolean }
38
+ */
39
+ function typescriptIsConsistent(pOptions, pAvailableTranspilers) {
40
+ const lTypeScriptNeeded =
41
+ Boolean(pOptions?.tsConfig) ||
42
+ Boolean(pOptions?.tsPreCompilationDeps) ||
43
+ Boolean(pOptions?.detectJSDocImports) ||
44
+ (pOptions?.parser ?? "acorn") === "tsc";
45
+ return lTypeScriptNeeded
46
+ ? pAvailableTranspilers.some(
47
+ (pTranspiler) =>
48
+ pTranspiler.name === "typescript" && pTranspiler.available,
49
+ )
50
+ : true;
51
+ }
52
+ /**
53
+ * @param { IOptions } pOptions
54
+ * @param { IAvailableTranspiler[] } pAvailableTranspilers
55
+ * @returns { boolean }
56
+ */
57
+ function babelIsConsistent(pOptions, pAvailableTranspilers) {
58
+ return Boolean(pOptions?.babelConfig)
59
+ ? pAvailableTranspilers.some(
60
+ (pTranspiler) => pTranspiler.name === "babel" && pTranspiler.available,
61
+ )
62
+ : true;
63
+ }
64
+
65
+ /**
66
+ * @param {IOptions} pOptions
67
+ * @param {IAvailableTranspiler[]} pAvailableTranspilers
68
+ * @returns {{issues?: IEnvironmentIssue[]}}
69
+ */
70
+ function determineEnvironmentIssues(pOptions, pAvailableTranspilers) {
71
+ const lIssues = [];
72
+ if (!typescriptIsConsistent(pOptions, pAvailableTranspilers)) {
73
+ const tsTranspiler = pAvailableTranspilers.find(
74
+ (pTranspiler) => pTranspiler.name === "typescript",
75
+ );
76
+
77
+ lIssues.push({
78
+ severity: "warn",
79
+ name: "missing-typescript-transpiler",
80
+ description:
81
+ `dependency-cruiser detected a TypeScript environment,${EOL}` +
82
+ ` but not a compatible TypeScript compiler (${tsTranspiler.name}: ${tsTranspiler.version}). This means${EOL}` +
83
+ ` it's likely to have missed TypeScript sources and dependencies.${EOL}${EOL}` +
84
+ ` Install typescript to get better results (e.g. npm i -D typescript@^6).${EOL}${EOL}` +
85
+ ` => Support for typescript@>=7 will follow when its API is published and stable.${EOL}`,
86
+ });
87
+ }
88
+ if (!swcIsConsistent(pOptions, pAvailableTranspilers)) {
89
+ const swcTranspiler = pAvailableTranspilers.find(
90
+ (pTranspiler) => pTranspiler.name === "swc",
91
+ );
92
+
93
+ lIssues.push({
94
+ severity: "warn",
95
+ name: "missing-swc-transpiler",
96
+ description:
97
+ `dependency-cruiser found swc configured as parser, but ${EOL}` +
98
+ ` it did not find a compatible version of swc (${swcTranspiler.name}: ${swcTranspiler.version}).${EOL}` +
99
+ ` dependency-cruiser might have missed some sources or dependencies.${EOL}${EOL}` +
100
+ ` Install swc (e.g. npm i -D @swc/core) to get better results.${EOL}`,
101
+ });
102
+ }
103
+ if (!babelIsConsistent(pOptions, pAvailableTranspilers)) {
104
+ const babelTranspiler = pAvailableTranspilers.find(
105
+ (pTranspiler) => pTranspiler.name === "babel",
106
+ );
107
+
108
+ lIssues.push({
109
+ severity: "warn",
110
+ name: "missing-babel-transpiler",
111
+ description:
112
+ `dependency-cruiser detected a babel configuration, but not a${EOL}` +
113
+ ` compatible babel transpiler (${babelTranspiler.name}: ${babelTranspiler.version}). If you indeed use babel,${EOL}` +
114
+ ` dependency-cruiser might have missed some sources or dependencies.${EOL}${EOL}` +
115
+ ` Install babel (e.g. npm i -D @babel/core@^7) to get better results.${EOL}`,
116
+ });
117
+ }
118
+ return lIssues.length > 0 ? { issues: lIssues } : {};
119
+ }
11
120
 
12
121
  /**
13
122
  *
14
- * @param {import("../../../types/cruise-result.mjs").IModule[]} pModules -
123
+ * @param {IModule[]} pModules -
15
124
  * cruised modules that have been enriched with mandatory attributes &
16
125
  * have been validated against rules as passed in the options
17
- * @param {import("../../../types/options.mjs").IStrictCruiseOptions} pOptions -
126
+ * @param {IStrictCruiseOptions} pOptions -
18
127
  * @param {string[]} pFileDirectoryArray -
19
128
  * the files/ directories originally passed to be cruised
20
- * @param {import("../../../types/dependency-cruiser.js").IFolder[]} pFolders -
129
+ * @param {IFolder[]} pFolders -
21
130
  * the pModules collapsed to folders, with their own metrics & deps
22
131
  *
23
- * @returns {import("../../../types/cruise-result.mjs").ISummary} -
132
+ * @returns {ISummary} -
24
133
  * a summary of the found modules, dependencies and any violations
25
134
  */
135
+ // eslint-disable-next-line max-params
26
136
  export default function summarize(
27
137
  pModules,
28
138
  pOptions,
29
139
  pFileDirectoryArray,
30
140
  pFolders,
141
+ pGetEnvironmentInfoFunction = getEnvironmentInfo,
31
142
  ) {
32
143
  const lViolations = summarizeModules(pModules, pOptions.ruleSet)
33
144
  .concat(summarizeFolders(pFolders || [], pOptions.ruleSet))
34
145
  .sort(compareViolations);
35
146
 
147
+ const lEnvironment = pGetEnvironmentInfoFunction();
148
+ const lEnvironmentWithIssues = {
149
+ ...lEnvironment,
150
+ ...determineEnvironmentIssues(pOptions, lEnvironment.transpilersFound),
151
+ };
36
152
  return {
37
153
  violations: lViolations,
38
154
  ...getViolationStats(lViolations),
@@ -40,5 +156,6 @@ export default function summarize(
40
156
  totalDependenciesCruised: getDependenciesCruised(pModules),
41
157
  ...summarizeOptions(pFileDirectoryArray, pOptions),
42
158
  ...(pOptions.ruleSet ? { ruleSetUsed: addRuleSetUsed(pOptions) } : {}),
159
+ environment: lEnvironmentWithIssues,
43
160
  };
44
161
  }
@@ -69,7 +69,7 @@ function toDependencyViolationSummary(pRule, pModule, pDependency, pRuleSet) {
69
69
  *
70
70
  * @param {any} pModules an array of modules
71
71
  * @param {any} pRuleSet? a rule set
72
- * @return {any} an array of violations
72
+ * @returns {any} an array of violations
73
73
  */
74
74
  function extractDependencyViolations(pModules, pRuleSet) {
75
75
  return pModules
@@ -33,7 +33,7 @@ const EMPTY_CACHE = {
33
33
  };
34
34
 
35
35
  // see ./cache-rationales.md#cache-format-versioning for rationale & bump instructions
36
- const CACHE_FORMAT_VERSION = 16.2;
36
+ const CACHE_FORMAT_VERSION = 18.1;
37
37
 
38
38
  export default class Cache {
39
39
  /** @type {(IRevisionData | null)=} */
@@ -115,7 +115,7 @@ export default class Cache {
115
115
  lPayload = await readFile(join(pCacheFolder, CACHE_FILE_NAME), "utf8");
116
116
  }
117
117
  return JSON.parse(lPayload);
118
- } catch (pError) {
118
+ } catch {
119
119
  return EMPTY_CACHE;
120
120
  }
121
121
  }
@@ -123,7 +123,7 @@ export default class Cache {
123
123
  /**
124
124
  * @param {string} pPayload
125
125
  * @param {boolean} pCompress
126
- * @return {Buffer|string}
126
+ * @returns {Buffer|string}
127
127
  */
128
128
  #compact(pPayload, pCompress) {
129
129
  if (pCompress) {
@@ -144,7 +144,7 @@ export default class Cache {
144
144
  * @param {IRevisionData=} pRevisionData
145
145
  */
146
146
  async write(pCacheFolder, pCruiseResult, pRevisionData) {
147
- let lRevisionData = pRevisionData ?? this.#revisionData;
147
+ const lRevisionData = pRevisionData ?? this.#revisionData;
148
148
 
149
149
  await mkdir(pCacheFolder, { recursive: true });
150
150
  const lUncompressedPayload = JSON.stringify(
@@ -153,7 +153,7 @@ export default class Cache {
153
153
  lRevisionData,
154
154
  ),
155
155
  );
156
- let lPayload = this.#compact(lUncompressedPayload, this.#compress);
156
+ const lPayload = this.#compact(lUncompressedPayload, this.#compress);
157
157
 
158
158
  // relying on writeFile defaults to 'do the right thing' (i.e. utf8
159
159
  // when the payload is a string; raw buffer otherwise)
@@ -37,7 +37,7 @@ export function getFileHashSync(pFileName) {
37
37
  let lHashedFileName = "file not found";
38
38
  try {
39
39
  lHashedFileName = hash(readFileSync(pFileName, "utf8"));
40
- } catch (pError) {
40
+ } catch {
41
41
  // will return "file not found" as per default
42
42
  }
43
43
  HASHES_CACHE.set(pFileName, lHashedFileName);
@@ -46,7 +46,7 @@ export function getFileHashSync(pFileName) {
46
46
 
47
47
  /**
48
48
  * @param {IChange} pChange
49
- * @return {IRevisionChange}
49
+ * @returns {IRevisionChange}
50
50
  */
51
51
  export function addCheckSumToChangeSync(pChange) {
52
52
  return {
@@ -1,8 +1,5 @@
1
- import { release, platform, arch } from "node:os";
2
1
  import { styleText } from "node:util";
3
-
4
- import { getAvailableTranspilers, allExtensions } from "#main/index.mjs";
5
- import meta from "#meta.cjs";
2
+ import { getEnvironmentInfo } from "#environment.mjs";
6
3
 
7
4
  function bool2Symbol(pBool) {
8
5
  return pBool ? styleText("green", "✔") : styleText("red", "x");
@@ -12,13 +9,13 @@ const MAX_VERSION_RANGE_STRING_LENGTH = 19;
12
9
  const MAX_TRANSPILER_NAME_LENGTH = 22;
13
10
  const MAX_VERSION_STRING_LENGTH = 24;
14
11
 
15
- function formatTranspilers() {
16
- let lTranspilerTableHeader = styleText(
12
+ function formatTranspilers(pAvailableTranspilers) {
13
+ const lTranspilerTableHeader = styleText(
17
14
  "bold",
18
15
  ` ✔ ${"transpiler".padEnd(MAX_TRANSPILER_NAME_LENGTH)} ${"versions supported".padEnd(MAX_VERSION_RANGE_STRING_LENGTH)} version found`,
19
16
  );
20
- let lTranspilerTableDivider = ` - ${"-".repeat(MAX_TRANSPILER_NAME_LENGTH)} ${"-".repeat(MAX_VERSION_RANGE_STRING_LENGTH)} ${"-".repeat(MAX_VERSION_STRING_LENGTH)}`;
21
- let lTranspilerTable = getAvailableTranspilers()
17
+ const lTranspilerTableDivider = ` - ${"-".repeat(MAX_TRANSPILER_NAME_LENGTH)} ${"-".repeat(MAX_VERSION_RANGE_STRING_LENGTH)} ${"-".repeat(MAX_VERSION_STRING_LENGTH)}`;
18
+ const lTranspilerTable = pAvailableTranspilers
22
19
  .map(
23
20
  (pTranspiler) =>
24
21
  ` ${bool2Symbol(pTranspiler.available)} ${pTranspiler.name.padEnd(MAX_TRANSPILER_NAME_LENGTH)} ${pTranspiler.version.padEnd(MAX_VERSION_RANGE_STRING_LENGTH)} ${pTranspiler.currentVersion}`,
@@ -36,12 +33,13 @@ function formatExtensions(pExtensions) {
36
33
  }
37
34
 
38
35
  export default function formatMetaInfo() {
36
+ const lMetaInfo = getEnvironmentInfo();
39
37
  return `
40
- ${styleText("bold", "dependency-cruiser")}@${meta.version}
38
+ ${styleText("bold", "dependency-cruiser")}@${lMetaInfo.version}
41
39
 
42
- node version supported : ${meta.engines.node}
43
- node version found : ${process.version}
44
- os version found : ${arch()} ${platform()}@${release()}
40
+ node version supported : ${lMetaInfo.nodeVersionSupported}
41
+ node version found : ${lMetaInfo.nodeVersionFound}
42
+ os version found : ${lMetaInfo.osVersionFound}
45
43
 
46
44
  If you need a supported, but not enabled transpiler ('${styleText(
47
45
  "red",
@@ -50,10 +48,10 @@ export default function formatMetaInfo() {
50
48
  it in the same folder dependency-cruiser is installed. E.g. 'npm i livescript'
51
49
  will enable livescript support if it's installed in your project folder.
52
50
 
53
- ${formatTranspilers()}
51
+ ${formatTranspilers(lMetaInfo.transpilersFound)}
54
52
  ${styleText("bold", "✔ extension")}
55
53
  - ---------
56
- ${formatExtensions(allExtensions)}
54
+ ${formatExtensions(lMetaInfo.extensionsFound)}
57
55
  `;
58
56
  }
59
57
 
package/src/cli/index.mjs CHANGED
@@ -41,7 +41,7 @@ async function addKnownViolations(pCruiseOptions) {
41
41
 
42
42
  // Check against json schema is already done in src/main/options/validate
43
43
  // so here we can just concentrate on the io
44
- let lCruiseOptions = structuredClone(pCruiseOptions);
44
+ const lCruiseOptions = structuredClone(pCruiseOptions);
45
45
  set(lCruiseOptions, "ruleSet.options.knownViolations", lKnownViolations);
46
46
  return lCruiseOptions;
47
47
  }
@@ -135,11 +135,10 @@ async function runCruise(pFileDirectoryArray, pCruiseOptions) {
135
135
  /**
136
136
  *
137
137
  * @param {string[]} pFileDirectoryArray
138
- * @param {import("../../types/options.mjs").ICruiseOptions} lCruiseOptions
138
+ * @param {import("../../types/options.mjs").ICruiseOptions} pCruiseOptions
139
139
  * @param {{stdout: NodeJS.WritableStream, stderr: NodeJS.WritableStream}=} pStreams
140
140
  * @returns {number}
141
141
  */
142
-
143
142
  // eslint-disable-next-line max-lines-per-function
144
143
  export default async function executeCli(
145
144
  pFileDirectoryArray,
@@ -151,7 +150,7 @@ export default async function executeCli(
151
150
  stderr: process.stderr,
152
151
  ...(pStreams || {}),
153
152
  };
154
- let lCruiseOptions = pCruiseOptions || {};
153
+ const lCruiseOptions = pCruiseOptions || {};
155
154
  let lExitCode = 0;
156
155
 
157
156
  try {
@@ -16,7 +16,7 @@ import { getAvailableTranspilers } from "#extract/transpile/meta.mjs";
16
16
  *
17
17
  * @param {IInitConfig} pInitOptions
18
18
  * @param {IAvailableTranspiler[]} pAvailableTranspilers
19
- * @return {boolean}
19
+ * @returns {boolean}
20
20
  */
21
21
  function typescriptIsConsistent(pInitOptions, pAvailableTranspilers) {
22
22
  if (pInitOptions.usesTypeScript) {
@@ -37,7 +37,7 @@ function typescriptIsConsistent(pInitOptions, pAvailableTranspilers) {
37
37
  *
38
38
  * @param {IInitConfig} pInitOptions
39
39
  * @param {IAvailableTranspiler[]} pAvailableTranspilers
40
- * @return {boolean}
40
+ * @returns {boolean}
41
41
  */
42
42
  function babelIsConsistent(pInitOptions, pAvailableTranspilers) {
43
43
  if (pInitOptions.babelConfig) {
@@ -57,7 +57,7 @@ function babelIsConsistent(pInitOptions, pAvailableTranspilers) {
57
57
  * @param {IInitConfig} pInitOptions
58
58
  * @param {NodeJS.WritableStream} [pErrorStream]
59
59
  * @param {typeof getAvailableTranspilers} [pAvailableTranspilerFunction]
60
- * @return {IInitConfig} pInitOptions
60
+ * @returns {IInitConfig} pInitOptions
61
61
  */
62
62
  export function checkAndWarnInconsistencies(
63
63
  pInitOptions,
@@ -38,7 +38,7 @@ export function readManifest(pManifestFileName = "./package.json") {
38
38
  export function fileExists(pFile) {
39
39
  try {
40
40
  accessSync(pFile, constants.R_OK);
41
- } catch (pError) {
41
+ } catch {
42
42
  return false;
43
43
  }
44
44
  return true;
@@ -53,7 +53,7 @@ function babelIsConfiguredInManifest() {
53
53
  try {
54
54
  // @ts-expect-error defaultly tsc doesn't know about newfangled stuff like hasOwn
55
55
  lReturnValue = Object.hasOwn(readManifest(), "babel");
56
- } catch (pError) {
56
+ } catch {
57
57
  // silently ignore - we'll return false anyway then
58
58
  }
59
59
  return lReturnValue;
@@ -67,7 +67,7 @@ export function isTypeModule() {
67
67
 
68
68
  try {
69
69
  lReturnValue = (readManifest()?.type ?? "commonjs") === "module";
70
- } catch (pError) {
70
+ } catch {
71
71
  // silently ignore - we'll return false anyway then
72
72
  }
73
73
 
@@ -112,7 +112,7 @@ function getPackageManager(pManifest) {
112
112
  if (Object.hasOwn(lManifest, "packageManager")) {
113
113
  lReturnValue = lManifest.packageManager;
114
114
  }
115
- } catch (pError) {
115
+ } catch {
116
116
  // silently ignore - we'll return the empty string anyway then
117
117
  }
118
118
  return lReturnValue;
@@ -163,7 +163,7 @@ const QUESTIONS = [
163
163
  ];
164
164
 
165
165
  /**
166
- * @return {Promise<import("./types.d.mts").IPartialInitConfig>}
166
+ * @returns {Promise<import("./types.d.mts").IPartialInitConfig>}
167
167
  */
168
168
  export default function getUserInput() {
169
169
  return prompts(QUESTIONS);
@@ -33,7 +33,7 @@ const PACKAGE_MANIFEST = `./${_PACKAGE_MANIFEST}`;
33
33
  * (e.g. a tsconfig exists => use it and assume typescript is used)
34
34
  *
35
35
  * @param {OneShotConfigIDType} pOneShotConfigId
36
- * @return {IPartialInitConfig} an initialization configuration
36
+ * @returns {IPartialInitConfig} an initialization configuration
37
37
  */
38
38
  function getOneShotConfig(pOneShotConfigId) {
39
39
  /** @type {IPartialInitConfig} */
@@ -43,7 +43,7 @@ function getExtensions(pInitOptions) {
43
43
 
44
44
  /**
45
45
  * @param {IPartialInitConfig} pInitOptions
46
- * @return {IPartialInitConfig}
46
+ * @returns {IPartialInitConfig}
47
47
  */
48
48
  function populate(pInitOptions) {
49
49
  const lReturnValue = {
@@ -71,10 +71,10 @@ function populate(pInitOptions) {
71
71
  /**
72
72
  *
73
73
  * @param {IPartialInitConfig} pInitOptions
74
- * @return {IInitConfig}
74
+ * @returns {IInitConfig}
75
75
  */
76
76
  export default function normalizeInitOptions(pInitOptions) {
77
- let lReturnValue = populate(pInitOptions);
77
+ const lReturnValue = populate(pInitOptions);
78
78
  if (!Object.hasOwn(lReturnValue, "hasTestsOutsideSource")) {
79
79
  lReturnValue.hasTestsOutsideSource =
80
80
  !pInitOptions.isMonoRepo &&
@@ -7,7 +7,7 @@ export function validateLocation(pLocations) {
7
7
  if (!statSync(lLocation).isDirectory()) {
8
8
  return `'${lLocation}' doesn't seem to be a folder - please try again`;
9
9
  }
10
- } catch (pError) {
10
+ } catch {
11
11
  return `'${lLocation}' doesn't seem to exist - please try again`;
12
12
  }
13
13
  }
@@ -60,7 +60,7 @@ const EXPERIMENTAL_SCRIPT_DOC = [
60
60
 
61
61
  /**
62
62
  * @param {import("./types.d.mts").IInitConfig} pInitOptions
63
- * @return {any} an bunch of key value pairs that can be plonked into a `scripts` attribute in a package.json
63
+ * @returns {any} an bunch of key value pairs that can be plonked into a `scripts` attribute in a package.json
64
64
  */
65
65
  export function compileRunScripts(pInitOptions) {
66
66
  let lReturnValue = {};
@@ -91,7 +91,7 @@ export function compileRunScripts(pInitOptions) {
91
91
  * @param {any} pAdditionalRunScripts
92
92
  * @param {any} pExistingRunScripts
93
93
  *
94
- * @return {any} the scripts in pAdditionalRunScripts that don't yet exist in
94
+ * @returns {any} the scripts in pAdditionalRunScripts that don't yet exist in
95
95
  * pExistingRunScripts
96
96
  */
97
97
  function filterNewScriptEntries(pExistingRunScripts, pAdditionalRunScripts) {
@@ -88,7 +88,7 @@ export default function setUpNDJSONListener(
88
88
  pMaxLevel = INFO,
89
89
  pStream = process.stderr,
90
90
  ) {
91
- let lState = {
91
+ const lState = {
92
92
  runStartTime: new Date(Date.now()).toISOString(),
93
93
  runId: randomInt(MIN_RUN_ID, MAX_RUN_ID),
94
94
  previousMessage: "startup: nodejs loading",
@@ -34,7 +34,7 @@ export default function setUpPerformanceLogListener(
34
34
  pMaxLevel = INFO,
35
35
  pStream = process.stderr,
36
36
  ) {
37
- let lState = {
37
+ const lState = {
38
38
  previousMessage: "startup: nodejs loading",
39
39
  previousTime: 0,
40
40
  previousUserUsage: 0,
@@ -19,7 +19,7 @@ function getOptionValue(pDefault) {
19
19
 
20
20
  // eslint-disable-next-line complexity
21
21
  function normalizeConfigFileName(pCliOptions, pConfigWrapperName, pDefault) {
22
- let lOptions = structuredClone(pCliOptions);
22
+ const lOptions = structuredClone(pCliOptions);
23
23
 
24
24
  if (Object.hasOwn(lOptions, pConfigWrapperName)) {
25
25
  set(
@@ -45,12 +45,13 @@ function fileExists(pFileName) {
45
45
  try {
46
46
  accessSync(pFileName, constants.R_OK);
47
47
  return true;
48
- } catch (pError) {
48
+ } catch {
49
49
  return false;
50
50
  }
51
51
  }
52
52
 
53
53
  function validateAndGetCustomRulesFileName(pValidate) {
54
+ /* oxlint-disable-next-line no-useless-assignment */
54
55
  let lReturnValue = "";
55
56
 
56
57
  if (fileExists(pValidate)) {
@@ -66,7 +67,7 @@ function validateAndGetCustomRulesFileName(pValidate) {
66
67
  }
67
68
 
68
69
  function validateAndGetDefaultRulesFileName() {
69
- let lReturnValue = RULES_FILE_NAME_SEARCH_ARRAY.find(fileExists);
70
+ const lReturnValue = RULES_FILE_NAME_SEARCH_ARRAY.find(fileExists);
70
71
 
71
72
  if (typeof lReturnValue === "undefined") {
72
73
  throw new TypeError(
@@ -79,6 +80,7 @@ function validateAndGetDefaultRulesFileName() {
79
80
  }
80
81
 
81
82
  function validateAndNormalizeRulesFileName(pValidate) {
83
+ /* oxlint-disable-next-line no-useless-assignment */
82
84
  let lReturnValue = "";
83
85
 
84
86
  if (typeof pValidate === "string") {
@@ -196,7 +198,7 @@ function normalizeCache(pCliOptions) {
196
198
  *
197
199
  * @param {object} pOptionsAsPassedFromCommander [description]
198
200
  * @param {any} pKnownCliOptions [description]
199
- * @return {object} [description]
201
+ * @returns {import("../../types/options.mjs").ICruiseOptions} [description]
200
202
  */
201
203
  export default async function normalizeOptions(pOptionsAsPassedFromCommander) {
202
204
  let lOptions = {
@@ -3,7 +3,7 @@ import { accessSync, constants } from "node:fs";
3
3
  export default function assertFileExistence(pDirectoryOrFile) {
4
4
  try {
5
5
  accessSync(pDirectoryOrFile, constants.R_OK);
6
- } catch (pError) {
6
+ } catch {
7
7
  throw new Error(
8
8
  `Can't open '${pDirectoryOrFile}' for reading. Does it exist?\n`,
9
9
  );
@@ -6,6 +6,7 @@ import tryImport from "#utl/try-import.mjs";
6
6
  import meta from "#meta.cjs";
7
7
 
8
8
  async function getJSConfig(pBabelConfigFileName) {
9
+ /* oxlint-disable-next-line no-useless-assignment */
9
10
  let lReturnValue = {};
10
11
 
11
12
  try {
@@ -34,6 +35,7 @@ async function getJSConfig(pBabelConfigFileName) {
34
35
  }
35
36
 
36
37
  async function getJSON5Config(pBabelConfigFileName) {
38
+ /* oxlint-disable-next-line no-useless-assignment */
37
39
  let lReturnValue = {};
38
40
  const { default: json5 } = await import("json5");
39
41
 
@@ -78,7 +80,7 @@ async function getConfig(pBabelConfigFileName) {
78
80
  * Silently fails if a supported @babel/core version can't be found
79
81
  *
80
82
  * @param {string} pBabelConfigFileName
81
- * @return {object} babel config as an object
83
+ * @returns {object} babel config as an object
82
84
  * @throws {Error} when the babel config has an unknown extension OR
83
85
  * when the babel config is invalid OR
84
86
  * when dependency-cruiser can't yet process it
@@ -47,7 +47,7 @@ async function processExtends(pReturnValue, pAlreadyVisited, pBaseDirectory) {
47
47
  * @param {string} pConfigFileName
48
48
  * @param {Set?} pAlreadyVisited
49
49
  * @param {string?} pBaseDirectory
50
- * @return {import('../../../types/configuration.mjs').IConfiguration} dependency-cruiser options
50
+ * @returns {import('../../../types/configuration.mjs').IConfiguration} dependency-cruiser options
51
51
  * @throws {Error} when the config is not valid (/ does not exist/ isn't readable)
52
52
  */
53
53
  export default async function extractDepcruiseConfig(