dependency-cruiser 13.0.0-beta-4 → 13.0.0-beta-6

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/README.md CHANGED
@@ -59,6 +59,19 @@ a one liner:
59
59
  npx depcruise src --include-only "^src" --output-type dot | dot -T svg > dependency-graph.svg
60
60
  ```
61
61
 
62
+ > <details>
63
+ > <summary>dependency-cruiser v12 and older: add --config option</summary>
64
+ >
65
+ > While not necessary from dependency-cruiser v13, in v12 and older you'll have
66
+ > to pass the --config option to make it find the .dependency-cruiser.js
67
+ > configuration file:
68
+ >
69
+ > ```shell
70
+ > npx depcruise src --include-only "^src" --config --output-type dot | dot -T svg > dependency-graph.svg
71
+ > ```
72
+
73
+ </details>
74
+
62
75
  - You can read more about what you can do with `--include-only` and other command line
63
76
  options in the [command line interface](./doc/cli.md) documentation.
64
77
  - _[Real world samples](./doc/real-world-samples.md)_
@@ -110,6 +123,19 @@ Sample rule:
110
123
  npx depcruise src
111
124
  ```
112
125
 
126
+ > <details>
127
+ > <summary>dependency-cruiser v12 and older: add --config option</summary>
128
+ >
129
+ > While not necessary from dependency-cruiser v13, in v12 and older you'll have
130
+ > to pass the --config option to make it find the .dependency-cruiser.js
131
+ > configuration file:
132
+ >
133
+ > ```shell
134
+ > npx depcruise --config .dependency-cruiser.js src
135
+ > ```
136
+
137
+ </details>
138
+
113
139
  This will validate against your rules and shows any violations in an eslint-like format:
114
140
 
115
141
  ![sample err output](https://raw.githubusercontent.com/sverweij/dependency-cruiser/master/doc/assets/sample-err-output.png)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dependency-cruiser",
3
- "version": "13.0.0-beta-4",
3
+ "version": "13.0.0-beta-6",
4
4
  "description": "Validate and visualize dependencies. With your rules. JavaScript, TypeScript, CoffeeScript. ES6, CommonJS, AMD.",
5
5
  "keywords": [
6
6
  "static analysis",
@@ -169,19 +169,19 @@
169
169
  "semver-try-require": "6.2.2",
170
170
  "teamcity-service-messages": "0.1.14",
171
171
  "tsconfig-paths-webpack-plugin": "4.0.1",
172
- "watskeburt": "0.10.2",
172
+ "watskeburt": "0.11.1",
173
173
  "wrap-ansi": "8.1.0"
174
174
  },
175
175
  "devDependencies": {
176
- "@babel/core": "7.21.4",
177
- "@babel/plugin-transform-modules-commonjs": "7.21.2",
178
- "@babel/preset-typescript": "7.21.4",
179
- "@swc/core": "1.3.53",
176
+ "@babel/core": "7.21.5",
177
+ "@babel/plugin-transform-modules-commonjs": "7.21.5",
178
+ "@babel/preset-typescript": "7.21.5",
179
+ "@swc/core": "1.3.55",
180
180
  "@types/lodash": "4.14.194",
181
- "@types/node": "18.16.0",
181
+ "@types/node": "18.16.3",
182
182
  "@types/prompts": "2.4.4",
183
- "@typescript-eslint/eslint-plugin": "5.59.0",
184
- "@typescript-eslint/parser": "5.59.0",
183
+ "@typescript-eslint/eslint-plugin": "5.59.1",
184
+ "@typescript-eslint/parser": "5.59.1",
185
185
  "@vue/compiler-sfc": "3.2.47",
186
186
  "c8": "7.13.0",
187
187
  "chai": "4.3.7",
@@ -199,7 +199,7 @@
199
199
  "eslint-plugin-unicorn": "^46.0.0",
200
200
  "husky": "8.0.3",
201
201
  "intercept-stdout": "0.1.2",
202
- "lint-staged": "13.2.1",
202
+ "lint-staged": "13.2.2",
203
203
  "mocha": "10.2.0",
204
204
  "normalize-newline": "4.1.0",
205
205
  "npm-run-all": "4.1.5",
@@ -1,6 +1,7 @@
1
- import { readFileSync, mkdirSync, writeFileSync } from "node:fs";
1
+ import { readFile, mkdir, writeFile } from "node:fs/promises";
2
2
  import { join } from "node:path";
3
3
  import { scannableExtensions } from "../extract/transpile/meta.mjs";
4
+ import { bus } from "../utl/bus.mjs";
4
5
  import { optionsAreCompatible } from "./options-compatible.mjs";
5
6
  import MetadataStrategy from "./metadata-strategy.mjs";
6
7
  import ContentStrategy from "./content-strategy.mjs";
@@ -25,10 +26,10 @@ export default class Cache {
25
26
  * @param {import("../../types/dependency-cruiser.js").IRevisionData=} pRevisionData
26
27
  * @returns {boolean}
27
28
  */
28
- canServeFromCache(pCruiseOptions, pCachedCruiseResult, pRevisionData) {
29
+ async canServeFromCache(pCruiseOptions, pCachedCruiseResult, pRevisionData) {
29
30
  this.revisionData =
30
31
  pRevisionData ??
31
- this.cacheStrategy.getRevisionData(
32
+ (await this.cacheStrategy.getRevisionData(
32
33
  ".",
33
34
  pCachedCruiseResult,
34
35
  pCruiseOptions,
@@ -37,7 +38,8 @@ export default class Cache {
37
38
  scannableExtensions.concat(pCruiseOptions.extraExtensionsToScan)
38
39
  ),
39
40
  }
40
- );
41
+ ));
42
+ bus.debug("cache: - comparing");
41
43
  return (
42
44
  this.cacheStrategy.revisionDataEqual(
43
45
  pCachedCruiseResult.revisionData,
@@ -54,10 +56,10 @@ export default class Cache {
54
56
  * @param {string} pCacheFolder
55
57
  * @returns {import("../../types/dependency-cruiser.js").ICruiseResult}
56
58
  */
57
- read(pCacheFolder) {
59
+ async read(pCacheFolder) {
58
60
  try {
59
61
  return JSON.parse(
60
- readFileSync(join(pCacheFolder, CACHE_FILE_NAME), "utf8")
62
+ await readFile(join(pCacheFolder, CACHE_FILE_NAME), "utf8")
61
63
  );
62
64
  } catch (pError) {
63
65
  return { modules: [], summary: {} };
@@ -69,11 +71,11 @@ export default class Cache {
69
71
  * @param {import("../../types/dependency-cruiser.js").ICruiseResult} pCruiseResult
70
72
  * @param {import("../../types/dependency-cruiser.js").IRevisionData=} pRevisionData
71
73
  */
72
- write(pCacheFolder, pCruiseResult, pRevisionData) {
74
+ async write(pCacheFolder, pCruiseResult, pRevisionData) {
73
75
  const lRevisionData = pRevisionData ?? this.revisionData;
74
76
 
75
- mkdirSync(pCacheFolder, { recursive: true });
76
- writeFileSync(
77
+ await mkdir(pCacheFolder, { recursive: true });
78
+ await writeFile(
77
79
  join(pCacheFolder, CACHE_FILE_NAME),
78
80
  JSON.stringify(
79
81
  this.cacheStrategy.prepareRevisionDataForSaving(
@@ -2,9 +2,8 @@ import { isDeepStrictEqual } from "node:util";
2
2
  import { join } from "node:path/posix";
3
3
  import findContentChanges from "./find-content-changes.mjs";
4
4
  import {
5
- getFileHash,
5
+ getFileHashSync,
6
6
  isInterestingChangeType,
7
- addCheckSumToChange,
8
7
  moduleIsInterestingForDiff,
9
8
  } from "./helpers.mjs";
10
9
 
@@ -17,7 +16,7 @@ function addCheckSumToModule(pBaseDirectory) {
17
16
  if (moduleIsInterestingForDiff(pModule)) {
18
17
  return {
19
18
  ...pModule,
20
- checksum: getFileHash(join(pBaseDirectory, pModule.source)),
19
+ checksum: getFileHashSync(join(pBaseDirectory, pModule.source)),
21
20
  };
22
21
  }
23
22
  return pModule;
@@ -56,7 +55,6 @@ export default class ContentStrategy {
56
55
  getRevisionData(pDirectory, pCachedCruiseResult, pCruiseOptions, pOptions) {
57
56
  const lOptions = {
58
57
  diffListFn: findContentChanges,
59
- checksumFn: addCheckSumToChange,
60
58
  baseDir: process.cwd(),
61
59
  ...pOptions,
62
60
  };
@@ -1,26 +1,23 @@
1
1
  import { join } from "node:path/posix";
2
- import bus from "../utl/bus.mjs";
3
- import busLogLevels from "../utl/bus-log-levels.mjs";
2
+ import { bus } from "../utl/bus.mjs";
4
3
  import findAllFiles from "../utl/find-all-files.mjs";
5
4
  import {
6
- getFileHash,
5
+ getFileHashSync,
7
6
  excludeFilter,
8
7
  includeOnlyFilter,
9
8
  hasInterestingExtension,
10
9
  moduleIsInterestingForDiff,
11
10
  } from "./helpers.mjs";
12
11
 
13
- const { DEBUG } = busLogLevels;
14
-
15
12
  /**
16
13
  * @param {Set<string>} pFileSet
17
- * @param {typeof getFileHash} pFileHashFunction
14
+ * @param {typeof getFileHashSync} pFileHashFunction
18
15
  * @returns {(pModule:import("../..").IModule) => import('../..').IRevisionChange}
19
16
  */
20
17
  function diffCachedModuleAgainstFileSet(
21
18
  pFileSet,
22
19
  pBaseDirectory,
23
- pFileHashFunction = getFileHash
20
+ pFileHashFunction = getFileHashSync
24
21
  ) {
25
22
  return (pModule) => {
26
23
  if (!moduleIsInterestingForDiff(pModule)) {
@@ -75,7 +72,7 @@ export default function findContentChanges(
75
72
  pCachedCruiseResult,
76
73
  pOptions
77
74
  ) {
78
- bus.emit("progress", "cache: - hauling revision data", { level: DEBUG });
75
+ bus.debug("cache: - getting revision data");
79
76
  const lFileSet = new Set(
80
77
  findAllFiles(pDirectory, {
81
78
  baseDir: pOptions.baseDir,
@@ -84,12 +81,12 @@ export default function findContentChanges(
84
81
  }).filter(hasInterestingExtension(pOptions.extensions))
85
82
  );
86
83
 
87
- bus.emit("progress", "cache: - determining cached vs new", { level: DEBUG });
84
+ bus.debug("cache: - getting (cached - new)");
88
85
  const lDiffCachedVsNew = pCachedCruiseResult.modules.map(
89
86
  diffCachedModuleAgainstFileSet(lFileSet, pOptions.baseDir)
90
87
  );
91
88
 
92
- bus.emit("progress", "cache: - determining new vs cached", { level: DEBUG });
89
+ bus.debug("cache: - getting (new - cached)");
93
90
  lDiffCachedVsNew.forEach(({ name }) => lFileSet.delete(name));
94
91
 
95
92
  const lDiffNewVsCached = [];
@@ -97,10 +94,10 @@ export default function findContentChanges(
97
94
  lDiffNewVsCached.push({
98
95
  name: lFileName,
99
96
  changeType: "added",
100
- checksum: getFileHash(join(pOptions.baseDir, lFileName)),
97
+ checksum: getFileHashSync(join(pOptions.baseDir, lFileName)),
101
98
  });
102
99
  }
103
100
 
104
- bus.emit("progress", "cache: - returning revision data", { level: DEBUG });
101
+ bus.debug("cache: - returning revision data");
105
102
  return lDiffCachedVsNew.concat(lDiffNewVsCached);
106
103
  }
@@ -1,6 +1,7 @@
1
1
  /* eslint-disable import/exports-last */
2
2
  import { createHash } from "node:crypto";
3
3
  import { readFileSync } from "node:fs";
4
+ import { readFile } from "node:fs/promises";
4
5
  import { extname } from "node:path";
5
6
  import memoize from "lodash/memoize.js";
6
7
  import { filenameMatchesPattern } from "../graph-utl/match-facade.mjs";
@@ -13,11 +14,32 @@ function hash(pString) {
13
14
  return createHash("sha1").update(pString).digest("base64");
14
15
  }
15
16
 
17
+ /**
18
+ * @param {import("fs").PathOrFileDescriptor} pFileName
19
+ * @returns {Promise<string>}
20
+ */
21
+ async function _getFileHash(pFileName) {
22
+ try {
23
+ return hash(await readFile(pFileName, "utf8"));
24
+ } catch (pError) {
25
+ return "file not found";
26
+ }
27
+ }
28
+
29
+ export const getFileHash = memoize(_getFileHash);
30
+
31
+ export async function addCheckSumToChange(pChange) {
32
+ return {
33
+ ...pChange,
34
+ checksum: await getFileHash(pChange.name),
35
+ };
36
+ }
37
+
16
38
  /**
17
39
  * @param {import("fs").PathOrFileDescriptor} pFileName
18
40
  * @returns {string}
19
41
  */
20
- function _getFileHash(pFileName) {
42
+ function _getFileHashSync(pFileName) {
21
43
  try {
22
44
  return hash(readFileSync(pFileName, "utf8"));
23
45
  } catch (pError) {
@@ -25,16 +47,16 @@ function _getFileHash(pFileName) {
25
47
  }
26
48
  }
27
49
 
28
- export const getFileHash = memoize(_getFileHash);
50
+ export const getFileHashSync = memoize(_getFileHashSync);
29
51
 
30
52
  /**
31
53
  * @param {import("watskeburt").IChange} pChange
32
54
  * @param {import("../../types/dependency-cruiser.js").IRevisionChange}
33
55
  */
34
- export function addCheckSumToChange(pChange) {
56
+ export function addCheckSumToChangeSync(pChange) {
35
57
  return {
36
58
  ...pChange,
37
- checksum: getFileHash(pChange.name),
59
+ checksum: getFileHashSync(pChange.name),
38
60
  };
39
61
  }
40
62
 
@@ -1,8 +1,9 @@
1
1
  import { isDeepStrictEqual } from "node:util";
2
- import { getSHASync, listSync } from "watskeburt";
2
+ import { getSHA, list } from "watskeburt";
3
+ import { bus } from "../utl/bus.mjs";
3
4
  import {
4
5
  isInterestingChangeType,
5
- addCheckSumToChange,
6
+ addCheckSumToChangeSync,
6
7
  excludeFilter,
7
8
  includeOnlyFilter,
8
9
  changeHasInterestingExtension,
@@ -21,26 +22,34 @@ export default class MetaDataStrategy {
21
22
  * @param {(import("watskeburt").IChange) => import("../..").IRevisionChange} pOptions.checksumFn
22
23
  * @returns {import("../../types/dependency-cruiser.js").IRevisionData}
23
24
  */
24
- getRevisionData(pDirectory, pCachedCruiseResult, pCruiseOptions, pOptions) {
25
+ async getRevisionData(
26
+ pDirectory,
27
+ pCachedCruiseResult,
28
+ pCruiseOptions,
29
+ pOptions
30
+ ) {
25
31
  const lOptions = {
26
- shaRetrievalFn: getSHASync,
27
- diffListFn: listSync,
28
- checksumFn: addCheckSumToChange,
32
+ shaRetrievalFn: getSHA,
33
+ diffListFn: list,
34
+ checksumFn: addCheckSumToChangeSync,
29
35
  ...pOptions,
30
36
  };
31
37
  try {
32
- const lSHA = lOptions.shaRetrievalFn();
38
+ bus.debug("cache: - getting sha");
39
+ const lSHA = await lOptions.shaRetrievalFn();
40
+ bus.debug("cache: - getting diff");
41
+ const lDiff = await lOptions.diffListFn(lSHA);
42
+ const lChanges = lDiff
43
+ .filter(({ name }) => excludeFilter(pCruiseOptions.exclude)(name))
44
+ .filter(({ name }) =>
45
+ includeOnlyFilter(pCruiseOptions.includeOnly)(name)
46
+ )
47
+ .filter(changeHasInterestingExtension(lOptions.extensions))
48
+ .filter(isInterestingChangeType(lOptions.interestingChangeTypes));
49
+ bus.debug("cache: - sha-summing diff");
33
50
  return {
34
51
  SHA1: lSHA,
35
- changes: lOptions
36
- .diffListFn(lSHA)
37
- .filter(({ name }) => excludeFilter(pCruiseOptions.exclude)(name))
38
- .filter(({ name }) =>
39
- includeOnlyFilter(pCruiseOptions.includeOnly)(name)
40
- )
41
- .filter(changeHasInterestingExtension(lOptions.extensions))
42
- .filter(isInterestingChangeType(lOptions.interestingChangeTypes))
43
- .map(lOptions.checksumFn),
52
+ changes: lChanges.map(lOptions.checksumFn),
44
53
  };
45
54
  } catch (pError) {
46
55
  throw new Error(
@@ -117,8 +117,8 @@ export function optionsAreCompatible(pOldOptions, pNewOptions) {
117
117
  filterOptionIsCompatible(pOldOptions.collapse, pNewOptions.collapse) &&
118
118
  limitIsCompatible(pOldOptions.maxDepth, pNewOptions.maxDepth) &&
119
119
  optionIsCompatible(
120
- pOldOptions.knownViolations,
121
- pNewOptions.knownViolations
120
+ pOldOptions.knownViolations || [],
121
+ pNewOptions.knownViolations || []
122
122
  ) &&
123
123
  optionIsCompatible(
124
124
  pOldOptions.enhancedResolveOptions,
@@ -1,5 +1,5 @@
1
1
  import getStream from "get-stream";
2
- import { format as _format } from "../main/index.mjs";
2
+ import _format from "../main/format.mjs";
3
3
  import validateFileExistence from "./utl/validate-file-existence.mjs";
4
4
  import normalizeOptions from "./normalize-cli-options.mjs";
5
5
  import { getInStream, write } from "./utl/io.mjs";
package/src/cli/index.mjs CHANGED
@@ -1,4 +1,3 @@
1
- /* eslint-disable import/max-dependencies */
2
1
  import { join } from "node:path";
3
2
  import { glob } from "glob";
4
3
  import cloneDeep from "lodash/cloneDeep.js";
@@ -6,10 +5,9 @@ import set from "lodash/set.js";
6
5
  import isInstalledGlobally from "is-installed-globally";
7
6
  import chalk from "chalk";
8
7
 
9
- import { cruise } from "../main/index.mjs";
10
- import bus from "../utl/bus.mjs";
8
+ import cruise from "../main/cruise.mjs";
9
+ import { INFO, bus } from "../utl/bus.mjs";
11
10
 
12
- import busLogLevels from "../utl/bus-log-levels.mjs";
13
11
  import validateFileExistence from "./utl/validate-file-existence.mjs";
14
12
  import normalizeCliOptions from "./normalize-cli-options.mjs";
15
13
  import { write } from "./utl/io.mjs";
@@ -23,10 +21,10 @@ async function extractResolveOptions(pCruiseOptions) {
23
21
  pCruiseOptions?.ruleSet?.options?.webpackConfig?.fileName ?? null;
24
22
 
25
23
  if (lWebPackConfigFileName) {
26
- const extractWebpackResolveConfig = await import(
24
+ const { default: extractWebpackResolveConfig } = await import(
27
25
  "../config-utl/extract-webpack-resolve-config.mjs"
28
26
  );
29
- lResolveOptions = await extractWebpackResolveConfig.default(
27
+ lResolveOptions = await extractWebpackResolveConfig(
30
28
  lWebPackConfigFileName,
31
29
  pCruiseOptions?.ruleSet?.options?.webpackConfig?.env ?? null,
32
30
  pCruiseOptions?.ruleSet?.options?.webpackConfig?.arguments ?? null
@@ -37,10 +35,10 @@ async function extractResolveOptions(pCruiseOptions) {
37
35
 
38
36
  async function addKnownViolations(pCruiseOptions) {
39
37
  if (pCruiseOptions.knownViolationsFile) {
40
- const extractKnownViolations = await import(
38
+ const { default: extractKnownViolations } = await import(
41
39
  "../config-utl/extract-known-violations.mjs"
42
40
  );
43
- const lKnownViolations = extractKnownViolations.default(
41
+ const lKnownViolations = await extractKnownViolations(
44
42
  pCruiseOptions.knownViolationsFile
45
43
  );
46
44
 
@@ -59,8 +57,10 @@ async function extractTSConfigOptions(pCruiseOptions) {
59
57
  pCruiseOptions?.ruleSet?.options?.tsConfig?.fileName ?? null;
60
58
 
61
59
  if (lTSConfigFileName) {
62
- const extractTSConfig = await import("../config-utl/extract-ts-config.mjs");
63
- lReturnValue = extractTSConfig.default(lTSConfigFileName);
60
+ const { default: extractTSConfig } = await import(
61
+ "../config-utl/extract-ts-config.mjs"
62
+ );
63
+ lReturnValue = extractTSConfig(lTSConfigFileName);
64
64
  }
65
65
 
66
66
  return lReturnValue;
@@ -71,10 +71,10 @@ async function extractBabelConfigOptions(pCruiseOptions) {
71
71
  const lBabelConfigFileName =
72
72
  pCruiseOptions?.ruleSet?.options?.babelConfig?.fileName ?? null;
73
73
  if (lBabelConfigFileName) {
74
- const extractBabelConfig = await import(
74
+ const { default: extractBabelConfig } = await import(
75
75
  "../config-utl/extract-babel-config.mjs"
76
76
  );
77
- lReturnValue = extractBabelConfig.default(lBabelConfigFileName);
77
+ lReturnValue = extractBabelConfig(lBabelConfigFileName);
78
78
  }
79
79
 
80
80
  return lReturnValue;
@@ -95,8 +95,7 @@ function setUpListener(pCruiseOptions) {
95
95
  if (Boolean(lListenerFunction)) {
96
96
  lListenerFunction(
97
97
  bus,
98
- pCruiseOptions?.ruleSet?.options?.progress?.maximumLevel ??
99
- busLogLevels.INFO
98
+ pCruiseOptions?.ruleSet?.options?.progress?.maximumLevel ?? INFO
100
99
  );
101
100
  }
102
101
  }
@@ -118,17 +117,19 @@ async function runCruise(pFileDirectoryArray, pCruiseOptions) {
118
117
  setUpListener(lCruiseOptions);
119
118
 
120
119
  bus.emit("start");
120
+ const [lResolveOptions, tsConfig, babelConfig] = await Promise.all([
121
+ extractResolveOptions(lCruiseOptions),
122
+ extractTSConfigOptions(lCruiseOptions),
123
+ extractBabelConfigOptions(lCruiseOptions),
124
+ ]);
121
125
  const lReportingResult = await cruise(
122
126
  pFileDirectoryArray,
123
127
  lCruiseOptions,
124
- await extractResolveOptions(lCruiseOptions),
125
- {
126
- tsConfig: await extractTSConfigOptions(lCruiseOptions),
127
- babelConfig: await extractBabelConfigOptions(lCruiseOptions),
128
- }
128
+ lResolveOptions,
129
+ { tsConfig, babelConfig }
129
130
  );
130
131
 
131
- bus.emit("progress", "cli: writing results", { complete: 1 });
132
+ bus.progress("cli: writing results", { complete: 1 });
132
133
  bus.emit("write-start");
133
134
  write(lCruiseOptions.outputTo, lReportingResult.output);
134
135
 
@@ -162,11 +163,13 @@ export default async function executeCli(pFileDirectoryArray, pCruiseOptions) {
162
163
  }
163
164
  /* c8 ignore stop */
164
165
  if (lCruiseOptions.info === true) {
165
- const formatMetaInfo = await import("./format-meta-info.mjs");
166
- process.stdout.write(await formatMetaInfo.default());
166
+ const { default: formatMetaInfo } = await import(
167
+ "./format-meta-info.mjs"
168
+ );
169
+ process.stdout.write(await formatMetaInfo());
167
170
  } else if (lCruiseOptions.init) {
168
- const initConfig = await import("./init-config/index.mjs");
169
- initConfig.default(lCruiseOptions.init);
171
+ const { default: initConfig } = await import("./init-config/index.mjs");
172
+ initConfig(lCruiseOptions.init);
170
173
  } else {
171
174
  lExitCode = await runCruise(pFileDirectoryArray, lCruiseOptions);
172
175
  }
@@ -1,6 +1,6 @@
1
1
  import chalk from "chalk";
2
2
  import figures from "figures";
3
- import busLogLevels from "../../utl/bus-log-levels.mjs";
3
+ import { SUMMARY } from "../../utl/bus.mjs";
4
4
 
5
5
  const FULL_ON = 100;
6
6
 
@@ -26,7 +26,7 @@ function getPercentageBar(pPercentage, pParameters) {
26
26
  function getProgressMessageWriter(pStream, pState, pMaxLogLevel) {
27
27
  return (pMessage, pOptions) => {
28
28
  const lOptions = {
29
- level: busLogLevels.SUMMARY,
29
+ level: SUMMARY,
30
30
  complete: pState.complete,
31
31
  ...(pOptions || {}),
32
32
  };
@@ -56,7 +56,7 @@ function getStartWriter(pStream) {
56
56
 
57
57
  export default function setUpCliFeedbackListener(
58
58
  pEventEmitter,
59
- pMaxLogLevel = busLogLevels.SUMMARY,
59
+ pMaxLogLevel = SUMMARY,
60
60
  pStream = process.stderr
61
61
  ) {
62
62
  const lState = {
@@ -1,5 +1,5 @@
1
1
  import { EOL } from "node:os";
2
- import busLogLevels from "../../utl/bus-log-levels.mjs";
2
+ import { INFO, SUMMARY } from "../../utl/bus.mjs";
3
3
 
4
4
  const MICRO_SECONDS_PER_SECOND = 1000000;
5
5
 
@@ -63,7 +63,7 @@ function getProgressLine(pMessage, pState, pLevel, pMaxLevel) {
63
63
 
64
64
  function getProgressWriter(pStream, pState, pMaxLevel) {
65
65
  return (pMessage, pOptions) => {
66
- const lOptions = { level: busLogLevels.SUMMARY, ...(pOptions || {}) };
66
+ const lOptions = { level: SUMMARY, ...(pOptions || {}) };
67
67
 
68
68
  pStream.write(getProgressLine(pMessage, pState, lOptions.level, pMaxLevel));
69
69
  };
@@ -71,12 +71,12 @@ function getProgressWriter(pStream, pState, pMaxLevel) {
71
71
 
72
72
  export default function setUpNDJSONListener(
73
73
  pEventEmitter,
74
- pMaxLevel = busLogLevels.INFO,
74
+ pMaxLevel = INFO,
75
75
  pStream = process.stderr
76
76
  ) {
77
77
  let lState = {
78
78
  runStartTime: new Date(Date.now()).toISOString(),
79
- previousMessage: "start of node process",
79
+ previousMessage: "starting nodejs",
80
80
  previousTime: 0,
81
81
  previousUserUsage: 0,
82
82
  previousSystemUsage: 0,
@@ -38,13 +38,13 @@ export function formatHeader() {
38
38
  return chalk
39
39
  .bold(
40
40
  `${
41
- pad("elapsed real") +
42
- pad("user") +
43
- pad("system") +
44
41
  pad("∆ rss") +
45
42
  pad("∆ heapTotal") +
46
43
  pad("∆ heapUsed") +
47
- pad("∆ external")
44
+ pad("∆ external") +
45
+ pad("⏱ system") +
46
+ pad("⏱ user") +
47
+ pad("⏱ real")
48
48
  }after step...\n`
49
49
  )
50
50
  .concat(formatDividerLine());
@@ -73,13 +73,13 @@ export function formatPerfLine({
73
73
  message,
74
74
  }) {
75
75
  return `${
76
- formatTime(elapsedTime) +
77
- formatTime(elapsedUser, MS_PER_MICRO_SECOND) +
78
- formatTime(elapsedSystem, MS_PER_MICRO_SECOND) +
79
76
  formatMemory(deltaRss) +
80
77
  formatMemory(deltaHeapTotal) +
81
78
  formatMemory(deltaHeapUsed) +
82
79
  formatMemory(deltaExternal) +
80
+ formatTime(elapsedSystem, MS_PER_MICRO_SECOND) +
81
+ formatTime(elapsedUser, MS_PER_MICRO_SECOND) +
82
+ formatTime(elapsedTime) +
83
83
  message
84
84
  }\n`;
85
85
  }
@@ -1,9 +1,9 @@
1
- import busLogLevels from "../../../utl/bus-log-levels.mjs";
1
+ import { INFO, SUMMARY } from "../../../utl/bus.mjs";
2
2
  import { getHeader, getProgressLine, getEndText } from "./handlers.mjs";
3
3
 
4
4
  function getHeaderWriter(pStream, pMaxLevel) {
5
5
  return (_pMessage, pOptions) => {
6
- const lOptions = { level: busLogLevels.SUMMARY, ...(pOptions || {}) };
6
+ const lOptions = { level: SUMMARY, ...(pOptions || {}) };
7
7
 
8
8
  pStream.write(getHeader(lOptions.level, pMaxLevel));
9
9
  };
@@ -11,14 +11,19 @@ function getHeaderWriter(pStream, pMaxLevel) {
11
11
 
12
12
  function getProgressWriter(pStream, pState, pMaxLevel) {
13
13
  return (pMessage, pOptions) => {
14
- const lOptions = { level: busLogLevels.SUMMARY, ...(pOptions || {}) };
15
-
16
- pStream.write(getProgressLine(pMessage, pState, lOptions.level, pMaxLevel));
14
+ const lOptions = { level: SUMMARY, ...(pOptions || {}) };
15
+ const lProgressLine = getProgressLine(
16
+ pMessage,
17
+ pState,
18
+ lOptions.level,
19
+ pMaxLevel
20
+ );
21
+ pStream.write(lProgressLine);
17
22
  };
18
23
  }
19
24
 
20
25
  function getEndWriter(pStream, pState, pMaxLevel) {
21
- return (_pMessage, pLevel = busLogLevels.SUMMARY) => {
26
+ return (_pMessage, pLevel = SUMMARY) => {
22
27
  pStream.write(getEndText(pState, pLevel, pMaxLevel));
23
28
  pStream.end();
24
29
  };
@@ -26,11 +31,11 @@ function getEndWriter(pStream, pState, pMaxLevel) {
26
31
 
27
32
  export default function setUpPerformanceLogListener(
28
33
  pEventEmitter,
29
- pMaxLevel = busLogLevels.INFO,
34
+ pMaxLevel = INFO,
30
35
  pStream = process.stderr
31
36
  ) {
32
37
  let lState = {
33
- previousMessage: "start of node process",
38
+ previousMessage: "starting nodejs",
34
39
  previousTime: 0,
35
40
  previousUserUsage: 0,
36
41
  previousSystemUsage: 0,
@@ -1,4 +1,4 @@
1
- import { readFileSync } from "node:fs";
1
+ import { readFile } from "node:fs/promises";
2
2
  import { fileURLToPath } from "node:url";
3
3
 
4
4
  const HEADER_FILE = fileURLToPath(
@@ -25,10 +25,13 @@ const FOOTER_FILE = fileURLToPath(
25
25
  * @param {readStream} pStream stream whose characters are to be slapped between header and footer
26
26
  * @param {writeStream} pOutStream stream to write to
27
27
  */
28
- export default function wrap(pInStream, pOutStream) {
29
- const lHeader = readFileSync(HEADER_FILE, "utf8");
30
- const lScript = readFileSync(SCRIPT_FILE, "utf8");
31
- const lEnd = readFileSync(FOOTER_FILE, "utf8");
28
+ export default async function wrap(pInStream, pOutStream) {
29
+ const [lHeader, lScript, lEnd] = await Promise.all([
30
+ readFile(HEADER_FILE, "utf8"),
31
+ readFile(SCRIPT_FILE, "utf8"),
32
+ readFile(FOOTER_FILE, "utf8"),
33
+ ]);
34
+
32
35
  const lFooter = `<script>${lScript}</script>${lEnd}`;
33
36
 
34
37
  pOutStream.write(lHeader);
@@ -1,4 +1,4 @@
1
- import { readFileSync } from "node:fs";
1
+ import { readFile } from "node:fs/promises";
2
2
 
3
3
  import { extname } from "node:path";
4
4
  import json5 from "json5";
@@ -11,10 +11,10 @@ async function getJSConfig(pBabelConfigFileName) {
11
11
  let lReturnValue = {};
12
12
 
13
13
  try {
14
- const lModule = await import(
14
+ const { default: lModule } = await import(
15
15
  `file://${makeAbsolute(pBabelConfigFileName)}`
16
16
  );
17
- lReturnValue = lModule.default;
17
+ lReturnValue = lModule;
18
18
  } catch (pError) {
19
19
  throw new Error(
20
20
  `${
@@ -35,11 +35,11 @@ async function getJSConfig(pBabelConfigFileName) {
35
35
  return lReturnValue;
36
36
  }
37
37
 
38
- function getJSON5Config(pBabelConfigFileName) {
38
+ async function getJSON5Config(pBabelConfigFileName) {
39
39
  let lReturnValue = {};
40
40
 
41
41
  try {
42
- lReturnValue = json5.parse(readFileSync(pBabelConfigFileName, "utf8"));
42
+ lReturnValue = json5.parse(await readFile(pBabelConfigFileName, "utf8"));
43
43
  } catch (pError) {
44
44
  throw new Error(
45
45
  `Encountered an error while parsing the babel config '${pBabelConfigFileName}':` +
@@ -1,4 +1,4 @@
1
- import { readFileSync } from "node:fs";
1
+ import { readFile } from "node:fs/promises";
2
2
  import { extname } from "node:path";
3
3
  import json5 from "json5";
4
4
 
@@ -6,8 +6,10 @@ export default async function readConfig(pAbsolutePathToConfigFile) {
6
6
  if (
7
7
  [".js", ".cjs", ".mjs", ""].includes(extname(pAbsolutePathToConfigFile))
8
8
  ) {
9
- const lConfig = await import(`file://${pAbsolutePathToConfigFile}`);
10
- return lConfig.default;
9
+ const { default: config } = await import(
10
+ `file://${pAbsolutePathToConfigFile}`
11
+ );
12
+ return config;
11
13
  }
12
- return json5.parse(readFileSync(pAbsolutePathToConfigFile, "utf8"));
14
+ return json5.parse(await readFile(pAbsolutePathToConfigFile, "utf8"));
13
15
  }
@@ -1,11 +1,11 @@
1
- import { readFileSync } from "node:fs";
1
+ import { readFile } from "node:fs/promises";
2
2
  import json5 from "json5";
3
3
  import makeAbsolute from "./make-absolute.mjs";
4
4
 
5
- export default function extractKnownViolations(pKnownViolationsFileName) {
5
+ export default async function extractKnownViolations(pKnownViolationsFileName) {
6
6
  try {
7
7
  return json5.parse(
8
- readFileSync(makeAbsolute(pKnownViolationsFileName), "utf8")
8
+ await readFile(makeAbsolute(pKnownViolationsFileName), "utf8")
9
9
  );
10
10
  } catch (pError) {
11
11
  if (pError instanceof SyntaxError) {
@@ -78,8 +78,10 @@ function isNativelySupported(pWebpackConfigFilename) {
78
78
  async function attemptImport(pAbsoluteWebpackConfigFileName) {
79
79
  try {
80
80
  if (isNativelySupported(pAbsoluteWebpackConfigFileName)) {
81
- const lModule = await import(`file://${pAbsoluteWebpackConfigFileName}`);
82
- return lModule.default;
81
+ const { default: lModule } = await import(
82
+ `file://${pAbsoluteWebpackConfigFileName}`
83
+ );
84
+ return lModule;
83
85
  } else {
84
86
  tryRegisterNonNative(pAbsoluteWebpackConfigFileName);
85
87
  /* we're using still using require instead of dynamic imports here because
@@ -1,5 +1,4 @@
1
- import bus from "../utl/bus.mjs";
2
- import busLogLevels from "../utl/bus-log-levels.mjs";
1
+ import { bus } from "../utl/bus.mjs";
3
2
  import addFocus from "../graph-utl/add-focus.mjs";
4
3
  import IndexedModuleGraph from "../graph-utl/indexed-module-graph.mjs";
5
4
  import deriveCycles from "./derive/circular.mjs";
@@ -11,31 +10,27 @@ import softenKnownViolations from "./soften-known-violations.mjs";
11
10
  import deriveModuleMetrics from "./derive/metrics/index.mjs";
12
11
 
13
12
  export default function enrichModules(pModules, pOptions) {
14
- bus.emit("progress", "analyzing: cycles", { level: busLogLevels.INFO });
13
+ bus.info("analyzing: cycles");
15
14
  const lIndexedModules = new IndexedModuleGraph(pModules);
16
15
  let lModules = deriveCycles(pModules, lIndexedModules, {
17
16
  pSourceAttribute: "source",
18
17
  pDependencyName: "resolved",
19
18
  });
20
- bus.emit("progress", "analyzing: dependents", { level: busLogLevels.INFO });
21
- lModules = addDependents(lModules, pOptions);
22
- bus.emit("progress", "analyzing: orphans", { level: busLogLevels.INFO });
19
+ bus.info("analyzing: dependents");
20
+ lModules = addDependents(lModules);
21
+ bus.info("analyzing: orphans");
23
22
  lModules = deriveOrphans(lModules);
24
- bus.emit("progress", "analyzing: reachables", { level: busLogLevels.INFO });
23
+ bus.info("analyzing: reachables");
25
24
  lModules = deriveReachable(lModules, pOptions.ruleSet);
26
- bus.emit("progress", "analyzing: module metrics", {
27
- level: busLogLevels.INFO,
28
- });
25
+ bus.info("analyzing: module metrics");
29
26
  lModules = deriveModuleMetrics(lModules, pOptions);
30
- bus.emit("progress", "analyzing: add focus (if any)", {
31
- level: busLogLevels.INFO,
32
- });
27
+ bus.info("analyzing: add focus (if any)");
33
28
  lModules = addFocus(lModules, pOptions.focus);
34
29
 
35
30
  // when validate === false we might want to skip the addValidations.
36
31
  // We don't at this time, however, as "valid" is a mandatory
37
32
  // attribute (to simplify reporter logic)
38
- bus.emit("progress", "analyzing: validations", { level: busLogLevels.INFO });
33
+ bus.info("analyzing: validations");
39
34
  lModules = addValidations(lModules, pOptions.ruleSet, pOptions.validate);
40
35
 
41
36
  lModules = softenKnownViolations(lModules, pOptions.knownViolations);
@@ -1,5 +1,4 @@
1
- import bus from "../utl/bus.mjs";
2
- import busLogLevels from "../utl/bus-log-levels.mjs";
1
+ import { bus } from "../utl/bus.mjs";
3
2
  import isSameViolation from "./summarize/is-same-violation.mjs";
4
3
 
5
4
  function softenModuleViolation(
@@ -118,9 +117,7 @@ export default function softenKnownViolations(
118
117
  pSoftenedSeverity = "ignore"
119
118
  ) {
120
119
  if (Boolean(pKnownViolations)) {
121
- bus.emit("progress", "analyzing: comparing against known errors", {
122
- level: busLogLevels.INFO,
123
- });
120
+ bus.info("analyzing: comparing against known errors");
124
121
  return pModules.map((pModule) =>
125
122
  softenKnownViolation(pModule, pKnownViolations, pSoftenedSeverity)
126
123
  );
@@ -1,6 +1,5 @@
1
1
  import has from "lodash/has.js";
2
- import bus from "../utl/bus.mjs";
3
- import busLogLevels from "../utl/bus-log-levels.mjs";
2
+ import { bus } from "../utl/bus.mjs";
4
3
  import getDependencies from "./get-dependencies.mjs";
5
4
  import gatherInitialSources from "./gather-initial-sources.mjs";
6
5
  import clearCaches from "./clear-caches.mjs";
@@ -62,17 +61,13 @@ function extractFileDirectoryArray(
62
61
  ) {
63
62
  let lVisited = new Set();
64
63
 
65
- bus.emit("progress", "reading files: gathering initial sources", {
66
- level: busLogLevels.INFO,
67
- });
64
+ bus.info("reading files: gathering initial sources");
68
65
  const lInitialSources = gatherInitialSources(
69
66
  pFileDirectoryArray,
70
67
  pCruiseOptions
71
68
  );
72
69
 
73
- bus.emit("progress", "reading files: visiting dependencies", {
74
- level: busLogLevels.INFO,
75
- });
70
+ bus.info("reading files: visiting dependencies");
76
71
  return lInitialSources.reduce((pDependencies, pFilename) => {
77
72
  if (!lVisited.has(pFilename)) {
78
73
  lVisited.add(pFilename);
@@ -1,3 +1,8 @@
1
+ import {
2
+ IAvailableExtension,
3
+ IAvailableTranspiler,
4
+ } from "../../../types/dependency-cruiser.d.ts";
5
+
1
6
  export interface ITranspilerWrapper {
2
7
  isAvailable: () => boolean;
3
8
  transpile: (
@@ -11,12 +16,6 @@ export function getWrapper(pExtension, pTranspileOptions): ITranspilerWrapper;
11
16
 
12
17
  export const scannableExtensions: string[];
13
18
 
14
- export const allExtensions: string[];
15
-
16
- export interface IAvailableTranspiler {
17
- name: string;
18
- version: string;
19
- available: boolean;
20
- }
19
+ export const allExtensions: IAvailableExtension[];
21
20
 
22
21
  export function getAvailableTranspilers(): IAvailableTranspiler[];
@@ -0,0 +1,105 @@
1
+ /* eslint-disable no-return-await */
2
+ /* eslint-disable no-magic-numbers */
3
+ import { bus } from "../utl/bus.mjs";
4
+ import { validateCruiseOptions } from "./options/validate.mjs";
5
+ import { normalizeCruiseOptions } from "./options/normalize.mjs";
6
+ import reportWrap from "./report-wrap.mjs";
7
+
8
+ const TOTAL_STEPS = 10;
9
+
10
+ export function c(pComplete, pTotal = TOTAL_STEPS) {
11
+ return { complete: pComplete / pTotal };
12
+ }
13
+
14
+ /** @type {import("../../types/dependency-cruiser.js").cruise} */
15
+ // eslint-disable-next-line max-lines-per-function, max-statements
16
+ export default async function cruise(
17
+ pFileAndDirectoryArray,
18
+ pCruiseOptions,
19
+ pResolveOptions,
20
+ pTranspileOptions
21
+ ) {
22
+ bus.summary("parsing options", c(1));
23
+ /** @type {import("../../types/strict-options.js").IStrictCruiseOptions} */
24
+ let lCruiseOptions = normalizeCruiseOptions(
25
+ validateCruiseOptions(pCruiseOptions),
26
+ pFileAndDirectoryArray
27
+ );
28
+ let lCache = null;
29
+
30
+ if (lCruiseOptions.cache) {
31
+ bus.summary(
32
+ `cache: checking freshness with ${lCruiseOptions.cache.strategy}`,
33
+ c(2)
34
+ );
35
+
36
+ const { default: Cache } = await import("../cache/cache.mjs");
37
+ lCache = new Cache(lCruiseOptions.cache.strategy);
38
+ const lCachedResults = await lCache.read(lCruiseOptions.cache.folder);
39
+
40
+ if (await lCache.canServeFromCache(lCruiseOptions, lCachedResults)) {
41
+ bus.summary("cache: reporting from cache", c(8));
42
+ return await reportWrap(lCachedResults, lCruiseOptions);
43
+ }
44
+ }
45
+
46
+ bus.summary("importing analytical modules", c(3));
47
+ const [
48
+ { default: normalizeRuleSet },
49
+ { default: validateRuleSet },
50
+ { default: normalizeFilesAndDirectories },
51
+ { default: normalizeResolveOptions },
52
+ { default: extract },
53
+ { default: enrich },
54
+ ] = await Promise.all([
55
+ // despite rule set parsing being behind an if, it's the 'normal' use case
56
+ // for dependency-cruiser, so import it unconditionally nonetheless
57
+ import("./rule-set/normalize.mjs"),
58
+ import("./rule-set/validate.mjs"),
59
+ import("./files-and-dirs/normalize.mjs"),
60
+ import("./resolve-options/normalize.mjs"),
61
+ import("../extract/index.mjs"),
62
+ import("../enrich/index.mjs"),
63
+ ]);
64
+
65
+ if (Boolean(lCruiseOptions.ruleSet)) {
66
+ bus.summary("parsing rule set", c(4));
67
+ lCruiseOptions.ruleSet = normalizeRuleSet(
68
+ validateRuleSet(lCruiseOptions.ruleSet)
69
+ );
70
+ }
71
+
72
+ const lNormalizedFileAndDirectoryArray = normalizeFilesAndDirectories(
73
+ pFileAndDirectoryArray
74
+ );
75
+
76
+ bus.summary("determining how to resolve", c(5));
77
+ const lNormalizedResolveOptions = await normalizeResolveOptions(
78
+ pResolveOptions,
79
+ lCruiseOptions,
80
+ pTranspileOptions?.tsConfig
81
+ );
82
+
83
+ bus.summary("reading files", c(6));
84
+ const lExtractionResult = extract(
85
+ lNormalizedFileAndDirectoryArray,
86
+ lCruiseOptions,
87
+ lNormalizedResolveOptions,
88
+ pTranspileOptions
89
+ );
90
+
91
+ bus.summary("analyzing", c(7));
92
+ const lCruiseResult = enrich(
93
+ lExtractionResult,
94
+ lCruiseOptions,
95
+ lNormalizedFileAndDirectoryArray
96
+ );
97
+
98
+ if (lCruiseOptions.cache) {
99
+ bus.summary("cache: saving", c(8));
100
+ await lCache.write(lCruiseOptions.cache.folder, lCruiseResult);
101
+ }
102
+
103
+ bus.summary("reporting", c(9));
104
+ return await reportWrap(lCruiseResult, lCruiseOptions);
105
+ }
@@ -0,0 +1,26 @@
1
+ import Ajv from "ajv";
2
+
3
+ import cruiseResultSchema from "../schema/cruise-result.schema.mjs";
4
+ import { validateFormatOptions } from "./options/validate.mjs";
5
+ import { normalizeFormatOptions } from "./options/normalize.mjs";
6
+ import reportWrap from "./report-wrap.mjs";
7
+
8
+ function validateResultAgainstSchema(pResult) {
9
+ const ajv = new Ajv();
10
+
11
+ if (!ajv.validate(cruiseResultSchema, pResult)) {
12
+ throw new Error(
13
+ `The supplied dependency-cruiser result is not valid: ${ajv.errorsText()}.\n`
14
+ );
15
+ }
16
+ }
17
+ /** @type {import("../../types/dependency-cruiser.js").format} */
18
+ export default async function format(pResult, pFormatOptions = {}) {
19
+ const lFormatOptions = normalizeFormatOptions(pFormatOptions);
20
+ validateFormatOptions(lFormatOptions);
21
+
22
+ validateResultAgainstSchema(pResult);
23
+
24
+ // eslint-disable-next-line no-return-await
25
+ return await reportWrap(pResult, lFormatOptions);
26
+ }
@@ -1,135 +1,16 @@
1
- /* eslint-disable no-return-await */
2
- /* eslint-disable no-magic-numbers */
3
-
4
- import Ajv from "ajv";
5
-
6
- import cruiseResultSchema from "../schema/cruise-result.schema.mjs";
7
- import bus from "../utl/bus.mjs";
8
1
  import {
9
2
  allExtensions,
10
3
  getAvailableTranspilers,
11
4
  } from "../extract/transpile/meta.mjs";
12
- import normalizeFilesAndDirectories from "./files-and-dirs/normalize.mjs";
13
- import validateRuleSet from "./rule-set/validate.mjs";
14
- import {
15
- validateCruiseOptions,
16
- validateFormatOptions,
17
- } from "./options/validate.mjs";
18
- import {
19
- normalizeCruiseOptions,
20
- normalizeFormatOptions,
21
- } from "./options/normalize.mjs";
22
- import reportWrap from "./report-wrap.mjs";
23
-
24
- const TOTAL_STEPS = 9;
25
-
26
- function c(pComplete, pTotal = TOTAL_STEPS) {
27
- return { complete: pComplete / pTotal };
28
- }
29
-
30
- function validateResultAgainstSchema(pResult) {
31
- const ajv = new Ajv();
32
-
33
- if (!ajv.validate(cruiseResultSchema, pResult)) {
34
- throw new Error(
35
- `The supplied dependency-cruiser result is not valid: ${ajv.errorsText()}.\n`
36
- );
37
- }
38
- }
39
- /** @type {import("../../types/dependency-cruiser.js").format} */
40
- export async function format(pResult, pFormatOptions = {}) {
41
- const lFormatOptions = normalizeFormatOptions(pFormatOptions);
42
- validateFormatOptions(lFormatOptions);
43
-
44
- validateResultAgainstSchema(pResult);
45
-
46
- return await reportWrap(pResult, lFormatOptions);
47
- }
48
-
49
- /** @type {import("../../types/dependency-cruiser.js").cruise} */
50
- // eslint-disable-next-line max-lines-per-function, max-statements
51
- export async function cruise(
52
- pFileAndDirectoryArray,
53
- pCruiseOptions,
54
- pResolveOptions,
55
- pTranspileOptions
56
- ) {
57
- bus.emit("progress", "parsing options", c(1));
58
- /** @type {import("../../types/strict-options.js").IStrictCruiseOptions} */
59
- let lCruiseOptions = normalizeCruiseOptions(
60
- validateCruiseOptions(pCruiseOptions),
61
- pFileAndDirectoryArray
62
- );
63
- let lCache = null;
64
-
65
- if (lCruiseOptions.cache) {
66
- bus.emit(
67
- "progress",
68
- `cache: check freshness with ${lCruiseOptions.cache.strategy}`,
69
- c(2)
70
- );
71
-
72
- const CacheModule = await import("../cache/cache.mjs");
73
- const Cache = CacheModule.default;
74
- lCache = new Cache(lCruiseOptions.cache.strategy);
75
- const lCachedResults = lCache.read(lCruiseOptions.cache.folder);
76
-
77
- if (lCache.canServeFromCache(lCruiseOptions, lCachedResults)) {
78
- bus.emit("progress", "cache: reporting from cache", c(8));
79
- return await reportWrap(lCachedResults, lCruiseOptions);
80
- }
81
- }
82
-
83
- if (Boolean(lCruiseOptions.ruleSet)) {
84
- bus.emit("progress", "parsing rule set", c(3));
85
- const normalizeRuleSet = await import("./rule-set/normalize.mjs");
86
- lCruiseOptions.ruleSet = normalizeRuleSet.default(
87
- validateRuleSet(lCruiseOptions.ruleSet)
88
- );
89
- }
90
-
91
- const lNormalizedFileAndDirectoryArray = normalizeFilesAndDirectories(
92
- pFileAndDirectoryArray
93
- );
94
-
95
- bus.emit("progress", "determining how to resolve", c(4));
96
- let normalizeResolveOptions = await import("./resolve-options/normalize.mjs");
97
- const lNormalizedResolveOptions = await normalizeResolveOptions.default(
98
- pResolveOptions,
99
- lCruiseOptions,
100
- pTranspileOptions?.tsConfig
101
- );
102
-
103
- bus.emit("progress", "reading files", c(5));
104
- const extract = await import("../extract/index.mjs");
105
- const lExtractionResult = extract.default(
106
- lNormalizedFileAndDirectoryArray,
107
- lCruiseOptions,
108
- lNormalizedResolveOptions,
109
- pTranspileOptions
110
- );
111
-
112
- bus.emit("progress", "analyzing", c(6));
113
- const enrich = await import("../enrich/index.mjs");
114
- const lCruiseResult = enrich.default(
115
- lExtractionResult,
116
- lCruiseOptions,
117
- lNormalizedFileAndDirectoryArray
118
- );
119
-
120
- if (lCruiseOptions.cache) {
121
- bus.emit("progress", "cache: save", c(7));
122
- lCache.write(lCruiseOptions.cache.folder, lCruiseResult);
123
- }
124
-
125
- bus.emit("progress", "reporting", c(8));
126
- return await reportWrap(lCruiseResult, lCruiseOptions);
127
- }
5
+ import format from "./format.mjs";
6
+ import cruise from "./cruise.mjs";
128
7
 
129
8
  export {
130
9
  allExtensions,
131
10
  getAvailableTranspilers,
132
11
  } from "../extract/transpile/meta.mjs";
12
+ export { default as cruise } from "./cruise.mjs";
13
+ export { default as format } from "./format.mjs";
133
14
 
134
15
  export default {
135
16
  cruise,
@@ -84,10 +84,9 @@ async function compileResolveOptions(
84
84
  // Also: requiring the plugin only when it's necessary will save some
85
85
  // startup time (especially on a cold require cache)
86
86
  if (pResolveOptions.tsConfig && isTsConfigPathsEligible(pTSConfig)) {
87
- const TsConfigPathsPluginModule = await import(
87
+ const { default: TsConfigPathsPlugin } = await import(
88
88
  "tsconfig-paths-webpack-plugin"
89
89
  );
90
- const TsConfigPathsPlugin = TsConfigPathsPluginModule.default;
91
90
  lResolveOptions.plugins = pushPlugin(
92
91
  lResolveOptions.plugins,
93
92
  // @ts-expect-error TS2351 "TsConfPathsPlugin is not constructable" - is unjustified
package/src/meta.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /* generated - don't edit */
2
2
 
3
3
  module.exports = {
4
- version: "13.0.0-beta-4",
4
+ version: "13.0.0-beta-6",
5
5
  engines: {
6
6
  node: "^16.14||>=18",
7
7
  },
@@ -127,6 +127,10 @@ export default {
127
127
  criteria: { "rules[0].severity": "info" },
128
128
  attributes: { fontcolor: "blue", color: "blue" },
129
129
  },
130
+ {
131
+ criteria: { dynamic: true },
132
+ attributes: { style: "dashed" },
133
+ },
130
134
  {
131
135
  criteria: { valid: false },
132
136
  attributes: { fontcolor: "red", color: "red" },
@@ -20,6 +20,7 @@ const TYPE2MODULE = {
20
20
  baseline: "./baseline.mjs",
21
21
  metrics: "./metrics.mjs",
22
22
  mermaid: "./mermaid.mjs",
23
+ null: "./null.mjs",
23
24
  };
24
25
 
25
26
  /**
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Returns the results of a cruise in JSON
3
+ *
4
+ * @param {import("../../types/cruise-result").ICruiseResult} pResults
5
+ * @returns {import("../../types/dependency-cruiser").IReporterOutput}
6
+ */
7
+ export default function nullReporter(pResults) {
8
+ return {
9
+ output: "",
10
+ exitCode: pResults.summary.error,
11
+ };
12
+ }
package/src/utl/bus.mjs CHANGED
@@ -1,5 +1,30 @@
1
+ /* eslint-disable import/exports-last */
1
2
  import EventEmitter from "node:events";
2
3
 
3
- const gBus = new EventEmitter();
4
+ export const OFF = -1;
5
+ export const SUMMARY = 40;
6
+ export const INFO = 50;
7
+ export const DEBUG = 60;
8
+ export const TRACE = 70;
9
+ export const EXTRA_STRONG = 80;
10
+ export const ALL = 99;
4
11
 
5
- export default gBus;
12
+ class Bus extends EventEmitter {
13
+ progress(pMessage, pOptions, ...pArguments) {
14
+ this.emit("progress", pMessage, pOptions, pArguments);
15
+ }
16
+
17
+ summary(pMessage, pOptions, ...pArguments) {
18
+ this.progress(pMessage, { ...pOptions, level: SUMMARY }, pArguments);
19
+ }
20
+
21
+ info(pMessage, pOptions, ...pArguments) {
22
+ this.progress(pMessage, { ...pOptions, level: INFO }, pArguments);
23
+ }
24
+
25
+ debug(pMessage, pOptions, ...pArguments) {
26
+ this.progress(pMessage, { ...pOptions, level: DEBUG }, pArguments);
27
+ }
28
+ }
29
+
30
+ export const bus = new Bus();
@@ -1,9 +0,0 @@
1
- export default {
2
- OFF: -1,
3
- SUMMARY: 40,
4
- INFO: 50,
5
- DEBUG: 60,
6
- TRACE: 70,
7
- EXTRA_STRONG: 80,
8
- ALL: 99,
9
- };