dependency-cruiser 17.3.2 → 17.3.3-beta-2

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 (232) hide show
  1. package/bin/depcruise-baseline.mjs +43 -43
  2. package/bin/depcruise-fmt.mjs +89 -89
  3. package/bin/dependency-cruise.mjs +171 -171
  4. package/configs/plugins/3d-reporter-plugin.mjs +36 -36
  5. package/configs/plugins/stats-reporter-plugin.mjs +51 -51
  6. package/configs/recommended-strict.cjs +5 -5
  7. package/configs/recommended-warn-only.cjs +5 -5
  8. package/configs/recommended.cjs +22 -22
  9. package/configs/rules/no-circular.cjs +10 -10
  10. package/configs/rules/no-deprecated-core.cjs +10 -10
  11. package/configs/rules/no-duplicate-dependency-types.cjs +17 -17
  12. package/configs/rules/no-non-package-json.cjs +11 -11
  13. package/configs/rules/no-orphans.cjs +18 -18
  14. package/configs/rules/not-to-deprecated.cjs +10 -10
  15. package/configs/rules/not-to-unresolvable.cjs +10 -10
  16. package/package.json +170 -170
  17. package/src/cache/cache.mjs +139 -139
  18. package/src/cache/content-strategy.mjs +88 -88
  19. package/src/cache/find-content-changes.mjs +58 -58
  20. package/src/cache/helpers.mjs +52 -52
  21. package/src/cache/metadata-strategy.mjs +83 -83
  22. package/src/cache/options-compatible.mjs +56 -109
  23. package/src/cli/assert-node-environment-suitable.mjs +7 -7
  24. package/src/cli/defaults.mjs +5 -5
  25. package/src/cli/format-meta-info.mjs +22 -22
  26. package/src/cli/format.mjs +28 -28
  27. package/src/cli/index.mjs +145 -145
  28. package/src/cli/init-config/build-config.mjs +94 -94
  29. package/src/cli/init-config/environment-helpers.mjs +77 -77
  30. package/src/cli/init-config/find-extensions.mjs +27 -27
  31. package/src/cli/init-config/get-user-input.mjs +151 -151
  32. package/src/cli/init-config/index.mjs +88 -88
  33. package/src/cli/init-config/normalize-init-options.mjs +47 -47
  34. package/src/cli/init-config/utl.mjs +4 -4
  35. package/src/cli/init-config/validators.mjs +10 -10
  36. package/src/cli/init-config/write-config.mjs +21 -21
  37. package/src/cli/init-config/write-run-scripts-to-manifest.mjs +103 -107
  38. package/src/cli/listeners/cli-feedback.mjs +49 -49
  39. package/src/cli/listeners/ndjson.mjs +66 -66
  40. package/src/cli/listeners/performance-log/format-helpers.mjs +63 -63
  41. package/src/cli/listeners/performance-log/handlers.mjs +56 -56
  42. package/src/cli/listeners/performance-log/index.mjs +37 -37
  43. package/src/cli/normalize-cli-options.mjs +182 -182
  44. package/src/cli/tools/wrap-stream-in-html.mjs +37 -37
  45. package/src/cli/utl/assert-file-existence.mjs +7 -7
  46. package/src/cli/utl/io.mjs +28 -31
  47. package/src/config-utl/extract-babel-config.mjs +69 -69
  48. package/src/config-utl/extract-depcruise-config/index.mjs +54 -54
  49. package/src/config-utl/extract-depcruise-config/merge-configs.mjs +63 -63
  50. package/src/config-utl/extract-depcruise-config/read-config.mjs +9 -9
  51. package/src/config-utl/extract-depcruise-options.mjs +9 -9
  52. package/src/config-utl/extract-known-violations.mjs +49 -49
  53. package/src/config-utl/extract-ts-config.mjs +46 -48
  54. package/src/config-utl/extract-webpack-resolve-config.mjs +88 -88
  55. package/src/config-utl/make-absolute.mjs +5 -5
  56. package/src/enrich/add-validations.mjs +13 -13
  57. package/src/enrich/derive/circular.mjs +49 -49
  58. package/src/enrich/derive/dependents.mjs +27 -27
  59. package/src/enrich/derive/folders/aggregate-to-folders.mjs +104 -104
  60. package/src/enrich/derive/folders/index.mjs +19 -19
  61. package/src/enrich/derive/folders/utl.mjs +18 -18
  62. package/src/enrich/derive/metrics/get-module-metrics.mjs +27 -27
  63. package/src/enrich/derive/metrics/index.mjs +8 -8
  64. package/src/enrich/derive/module-utl.mjs +18 -18
  65. package/src/enrich/derive/orphan/index.mjs +18 -18
  66. package/src/enrich/derive/orphan/is-orphan.mjs +9 -9
  67. package/src/enrich/derive/reachable.mjs +165 -168
  68. package/src/enrich/enrich-modules.mjs +25 -25
  69. package/src/enrich/index.mjs +15 -15
  70. package/src/enrich/soften-known-violations.mjs +90 -90
  71. package/src/enrich/summarize/add-rule-set-used.mjs +13 -13
  72. package/src/enrich/summarize/get-stats.mjs +17 -17
  73. package/src/enrich/summarize/index.mjs +18 -18
  74. package/src/enrich/summarize/is-same-violation.mjs +30 -30
  75. package/src/enrich/summarize/summarize-folders.mjs +35 -35
  76. package/src/enrich/summarize/summarize-modules.mjs +97 -97
  77. package/src/enrich/summarize/summarize-options.mjs +71 -71
  78. package/src/extract/acorn/estree-helpers.mjs +66 -66
  79. package/src/extract/acorn/extract-amd-deps.mjs +63 -64
  80. package/src/extract/acorn/extract-cjs-deps.mjs +83 -83
  81. package/src/extract/acorn/extract-es6-deps.mjs +54 -54
  82. package/src/extract/acorn/extract-stats.mjs +4 -4
  83. package/src/extract/acorn/extract.mjs +28 -28
  84. package/src/extract/acorn/parse.mjs +37 -37
  85. package/src/extract/clear-caches.mjs +7 -7
  86. package/src/extract/extract-dependencies.mjs +109 -109
  87. package/src/extract/extract-stats.mjs +21 -21
  88. package/src/extract/gather-initial-sources.mjs +64 -64
  89. package/src/extract/helpers.mjs +73 -71
  90. package/src/extract/index.mjs +120 -120
  91. package/src/extract/resolve/determine-dependency-types.mjs +166 -169
  92. package/src/extract/resolve/external-module-helpers.mjs +76 -76
  93. package/src/extract/resolve/get-manifest.mjs +79 -79
  94. package/src/extract/resolve/index.mjs +175 -164
  95. package/src/extract/resolve/is-built-in.mjs +22 -24
  96. package/src/extract/resolve/merge-manifests.mjs +43 -43
  97. package/src/extract/resolve/module-classifiers.mjs +229 -229
  98. package/src/extract/resolve/resolve-amd.mjs +44 -44
  99. package/src/extract/resolve/resolve-cjs.mjs +40 -40
  100. package/src/extract/resolve/resolve-helpers.mjs +20 -20
  101. package/src/extract/resolve/resolve.mjs +26 -26
  102. package/src/extract/swc/dependency-visitor.mjs +211 -211
  103. package/src/extract/swc/extract-swc-deps.mjs +4 -4
  104. package/src/extract/swc/extract.mjs +7 -7
  105. package/src/extract/swc/parse.mjs +12 -12
  106. package/src/extract/transpile/babel-wrap.mjs +9 -9
  107. package/src/extract/transpile/coffeescript-wrap.mjs +21 -21
  108. package/src/extract/transpile/index.mjs +47 -47
  109. package/src/extract/transpile/javascript-wrap.mjs +6 -6
  110. package/src/extract/transpile/livescript-wrap.mjs +5 -5
  111. package/src/extract/transpile/meta.mjs +80 -80
  112. package/src/extract/transpile/svelte-preprocess.mjs +73 -73
  113. package/src/extract/transpile/svelte-wrap.mjs +19 -19
  114. package/src/extract/transpile/try-import-available.mjs +26 -27
  115. package/src/extract/transpile/typescript-wrap.mjs +39 -39
  116. package/src/extract/transpile/vue-template-wrap.cjs +43 -43
  117. package/src/extract/tsc/extract-stats.mjs +4 -4
  118. package/src/extract/tsc/extract-typescript-deps.mjs +429 -398
  119. package/src/extract/tsc/extract.mjs +22 -22
  120. package/src/extract/tsc/parse.mjs +21 -21
  121. package/src/graph-utl/add-focus.mjs +35 -35
  122. package/src/graph-utl/compare.mjs +24 -24
  123. package/src/graph-utl/consolidate-module-dependencies.mjs +35 -35
  124. package/src/graph-utl/consolidate-modules.mjs +33 -33
  125. package/src/graph-utl/consolidate-to-folder.mjs +13 -13
  126. package/src/graph-utl/consolidate-to-pattern.mjs +34 -34
  127. package/src/graph-utl/filter-bank.mjs +74 -69
  128. package/src/graph-utl/indexed-module-graph.mjs +227 -225
  129. package/src/graph-utl/match-facade.mjs +3 -3
  130. package/src/graph-utl/rule-set.mjs +20 -20
  131. package/src/graph-utl/strip-self-transitions.mjs +6 -6
  132. package/src/main/cruise.mjs +81 -81
  133. package/src/main/files-and-dirs/normalize.mjs +7 -7
  134. package/src/main/format.mjs +11 -14
  135. package/src/main/helpers.mjs +25 -25
  136. package/src/main/index.mjs +8 -8
  137. package/src/main/options/assert-validity.mjs +100 -100
  138. package/src/main/options/defaults.mjs +11 -11
  139. package/src/main/options/normalize.mjs +158 -160
  140. package/src/main/report-wrap.mjs +37 -37
  141. package/src/main/resolve-options/normalize.mjs +127 -128
  142. package/src/main/rule-set/assert-validity.mjs +67 -73
  143. package/src/main/rule-set/normalize.mjs +81 -79
  144. package/src/meta.cjs +15 -16
  145. package/src/report/anon/anonymize-path-element.mjs +20 -34
  146. package/src/report/anon/anonymize-path.mjs +11 -11
  147. package/src/report/anon/index.mjs +119 -119
  148. package/src/report/anon/random-string.mjs +23 -23
  149. package/src/report/azure-devops.mjs +75 -99
  150. package/src/report/baseline.mjs +9 -9
  151. package/src/report/csv.mjs +13 -13
  152. package/src/report/d2.mjs +105 -105
  153. package/src/report/dot/default-theme.mjs +152 -152
  154. package/src/report/dot/index.mjs +146 -146
  155. package/src/report/dot/module-utl.mjs +72 -72
  156. package/src/report/dot/prepare-custom-level.mjs +20 -20
  157. package/src/report/dot/prepare-flat-level.mjs +11 -11
  158. package/src/report/dot/prepare-folder-level.mjs +12 -13
  159. package/src/report/dot/theming.mjs +73 -73
  160. package/src/report/dot-webpage/dot-module.mjs +36 -36
  161. package/src/report/dot-webpage/svg-in-html-snippets/script.cjs +208 -210
  162. package/src/report/dot-webpage/svg-in-html-snippets/style.css +51 -51
  163. package/src/report/dot-webpage/wrap-in-html.mjs +7 -7
  164. package/src/report/error-html/index.mjs +49 -49
  165. package/src/report/error-html/utl.mjs +99 -99
  166. package/src/report/error-long.mjs +1 -1
  167. package/src/report/error.mjs +93 -93
  168. package/src/report/html/index.mjs +48 -48
  169. package/src/report/identity.mjs +4 -4
  170. package/src/report/index.mjs +33 -33
  171. package/src/report/json.mjs +4 -4
  172. package/src/report/markdown.mjs +120 -120
  173. package/src/report/mermaid.mjs +111 -111
  174. package/src/report/metrics.mjs +185 -185
  175. package/src/report/null.mjs +4 -4
  176. package/src/report/plugins.mjs +41 -41
  177. package/src/report/teamcity.mjs +150 -150
  178. package/src/report/text.mjs +42 -42
  179. package/src/report/utl/dependency-to-incidence-transformer.mjs +32 -32
  180. package/src/report/utl/index.mjs +53 -53
  181. package/src/schema/configuration.validate.mjs +1 -0
  182. package/src/schema/cruise-result.validate.mjs +1 -0
  183. package/src/schema/utl.mjs +6 -0
  184. package/src/utl/array-util.mjs +25 -25
  185. package/src/utl/bus.mjs +12 -12
  186. package/src/utl/extract-root-module-name.cjs +8 -8
  187. package/src/utl/find-all-files.mjs +54 -54
  188. package/src/utl/get-extension.mjs +2 -2
  189. package/src/utl/object-util.mjs +21 -22
  190. package/src/utl/path-to-posix.mjs +5 -5
  191. package/src/utl/regex-util.mjs +20 -20
  192. package/src/utl/try-import.mjs +42 -41
  193. package/src/utl/try-require.cjs +23 -23
  194. package/src/utl/wrap-and-indent.mjs +33 -33
  195. package/src/validate/index.mjs +65 -65
  196. package/src/validate/match-dependency-rule.mjs +47 -47
  197. package/src/validate/match-folder-dependency-rule.mjs +27 -27
  198. package/src/validate/match-module-rule-helpers.mjs +76 -76
  199. package/src/validate/match-module-rule.mjs +12 -12
  200. package/src/validate/matchers.mjs +162 -162
  201. package/src/validate/rule-classifiers.mjs +9 -9
  202. package/src/validate/violates-required-rule.mjs +23 -23
  203. package/types/cache-options.d.mts +27 -27
  204. package/types/config-utl/extract-babel-config.d.mts +1 -1
  205. package/types/config-utl/extract-depcruise-config.d.mts +3 -3
  206. package/types/config-utl/extract-depcruise-options.d.mts +1 -1
  207. package/types/config-utl/extract-ts-config.d.mts +1 -1
  208. package/types/config-utl/extract-webpack-resolve-config.d.mts +3 -3
  209. package/types/configuration.d.mts +10 -10
  210. package/types/cruise-result.d.mts +414 -414
  211. package/types/dependency-cruiser.d.mts +52 -52
  212. package/types/filter-types.d.mts +45 -45
  213. package/types/options.d.mts +430 -430
  214. package/types/plugins/3d-reporter-plugin.d.mts +9 -9
  215. package/types/plugins/mermaid-reporter-plugin.d.mts +10 -10
  216. package/types/plugins/stats-reporter-plugin.d.mts +9 -9
  217. package/types/reporter-options.d.mts +196 -196
  218. package/types/resolve-options.d.mts +23 -23
  219. package/types/restrictions.d.mts +174 -174
  220. package/types/rule-set.d.mts +132 -132
  221. package/types/rule-summary.d.mts +14 -14
  222. package/types/shared-types.d.mts +89 -89
  223. package/types/strict-filter-types.d.mts +52 -52
  224. package/types/strict-options.d.mts +34 -34
  225. package/types/strict-restrictions.d.mts +25 -25
  226. package/types/strict-rule-set.d.mts +36 -36
  227. package/types/violations.d.mts +40 -40
  228. package/src/schema/README.md +0 -5
  229. package/src/schema/baseline-violations.schema.mjs +0 -1
  230. package/src/schema/configuration.schema.mjs +0 -1
  231. package/src/schema/cruise-result.schema.mjs +0 -1
  232. package/types/README.md +0 -1
@@ -17,67 +17,67 @@ import mergePackages from "./merge-manifests.mjs";
17
17
  * found or is invalid
18
18
  */
19
19
  const getSingleManifest = memoize((pFileDirectory) => {
20
- let lReturnValue = null;
20
+ let lReturnValue = null;
21
21
 
22
- try {
23
- // find the closest package.json from pFileDirectory
24
- const lPackageContent = readFileSync(
25
- join(pFileDirectory, "package.json"),
26
- "utf8",
27
- );
22
+ try {
23
+ // find the closest package.json from pFileDirectory
24
+ const lPackageContent = readFileSync(
25
+ join(pFileDirectory, "package.json"),
26
+ "utf8",
27
+ );
28
28
 
29
- try {
30
- lReturnValue = JSON.parse(lPackageContent);
31
- } catch (pError) {
32
- // left empty on purpose
33
- }
34
- } catch (pError) {
35
- const lNextDirectory = dirname(pFileDirectory);
29
+ try {
30
+ lReturnValue = JSON.parse(lPackageContent);
31
+ } catch (pError) {
32
+ // left empty on purpose
33
+ }
34
+ } catch (pError) {
35
+ const lNextDirectory = dirname(pFileDirectory);
36
36
 
37
- if (lNextDirectory !== pFileDirectory) {
38
- // not yet reached root directory
39
- lReturnValue = getSingleManifest(lNextDirectory);
40
- }
41
- }
42
- return lReturnValue;
37
+ if (lNextDirectory !== pFileDirectory) {
38
+ // not yet reached root directory
39
+ lReturnValue = getSingleManifest(lNextDirectory);
40
+ }
41
+ }
42
+ return lReturnValue;
43
43
  });
44
44
 
45
45
  function maybeReadPackage(pFileDirectory) {
46
- let lReturnValue = {};
46
+ let lReturnValue = {};
47
47
 
48
- try {
49
- const lPackageContent = readFileSync(
50
- join(pFileDirectory, "package.json"),
51
- "utf8",
52
- );
48
+ try {
49
+ const lPackageContent = readFileSync(
50
+ join(pFileDirectory, "package.json"),
51
+ "utf8",
52
+ );
53
53
 
54
- try {
55
- lReturnValue = JSON.parse(lPackageContent);
56
- } catch (pError) {
57
- // left empty on purpose
58
- }
59
- } catch (pError) {
60
- // left empty on purpose
61
- }
62
- return lReturnValue;
54
+ try {
55
+ lReturnValue = JSON.parse(lPackageContent);
56
+ } catch (pError) {
57
+ // left empty on purpose
58
+ }
59
+ } catch (pError) {
60
+ // left empty on purpose
61
+ }
62
+ return lReturnValue;
63
63
  }
64
64
 
65
65
  function getIntermediatePaths(pFileDirectory, pBaseDirectory) {
66
- let lReturnValue = [];
67
- let lIntermediate = pFileDirectory;
66
+ let lReturnValue = [];
67
+ let lIntermediate = pFileDirectory;
68
68
 
69
- while (
70
- lIntermediate !== pBaseDirectory &&
71
- // safety hatch in case pBaseDirectory is either not a part of
72
- // pFileDirectory or not something uniquely comparable to a
73
- // dirname
74
- lIntermediate !== dirname(lIntermediate)
75
- ) {
76
- lReturnValue.push(lIntermediate);
77
- lIntermediate = dirname(lIntermediate);
78
- }
79
- lReturnValue.push(pBaseDirectory);
80
- return lReturnValue;
69
+ while (
70
+ lIntermediate !== pBaseDirectory &&
71
+ // safety hatch in case pBaseDirectory is either not a part of
72
+ // pFileDirectory or not something uniquely comparable to a
73
+ // dirname
74
+ lIntermediate !== dirname(lIntermediate)
75
+ ) {
76
+ lReturnValue.push(lIntermediate);
77
+ lIntermediate = dirname(lIntermediate);
78
+ }
79
+ lReturnValue.push(pBaseDirectory);
80
+ return lReturnValue;
81
81
  }
82
82
 
83
83
  // despite the two parameters there's no resolver function provided
@@ -85,28 +85,28 @@ function getIntermediatePaths(pFileDirectory, pBaseDirectory) {
85
85
  // be the same for each call in a typical cruise, so the default
86
86
  // memoize resolver (the first param) will suffice.
87
87
  const getCombinedManifests = memoize((pFileDirectory, pBaseDirectory) => {
88
- // The way this is called, this shouldn't happen. If it is, there's
89
- // something gone terribly awry
90
- if (
91
- !pFileDirectory.startsWith(pBaseDirectory) ||
92
- pBaseDirectory.endsWith(sep)
93
- ) {
94
- throw new Error(
95
- `Unexpected Error: Unusual baseDir passed to package reading function: '${pBaseDirectory}'\n` +
96
- `Please file a bug: https://github.com/sverweij/dependency-cruiser/issues/new?template=bug-report.md` +
97
- `&title=Unexpected Error: Unusual baseDir passed to package reading function: '${pBaseDirectory}'`,
98
- );
99
- }
88
+ // The way this is called, this shouldn't happen. If it is, there's
89
+ // something gone terribly awry
90
+ if (
91
+ !pFileDirectory.startsWith(pBaseDirectory) ||
92
+ pBaseDirectory.endsWith(sep)
93
+ ) {
94
+ throw new Error(
95
+ `Unexpected Error: Unusual baseDir passed to package reading function: '${pBaseDirectory}'\n` +
96
+ `Please file a bug: https://github.com/sverweij/dependency-cruiser/issues/new?template=bug-report.md` +
97
+ `&title=Unexpected Error: Unusual baseDir passed to package reading function: '${pBaseDirectory}'`,
98
+ );
99
+ }
100
100
 
101
- const lReturnValue = getIntermediatePaths(
102
- pFileDirectory,
103
- pBaseDirectory,
104
- ).reduce(
105
- (pAll, pCurrent) => mergePackages(pAll, maybeReadPackage(pCurrent)),
106
- {},
107
- );
101
+ const lReturnValue = getIntermediatePaths(
102
+ pFileDirectory,
103
+ pBaseDirectory,
104
+ ).reduce(
105
+ (pAll, pCurrent) => mergePackages(pAll, maybeReadPackage(pCurrent)),
106
+ {},
107
+ );
108
108
 
109
- return Object.keys(lReturnValue).length > 0 ? lReturnValue : null;
109
+ return Object.keys(lReturnValue).length > 0 ? lReturnValue : null;
110
110
  });
111
111
 
112
112
  /**
@@ -126,18 +126,18 @@ const getCombinedManifests = memoize((pFileDirectory, pBaseDirectory) => {
126
126
  * found or is invalid
127
127
  */
128
128
  export function getManifest(
129
- pFileDirectory,
130
- pBaseDirectory,
131
- pCombinedDependencies = false,
129
+ pFileDirectory,
130
+ pBaseDirectory,
131
+ pCombinedDependencies = false,
132
132
  ) {
133
- if (pCombinedDependencies) {
134
- return getCombinedManifests(pFileDirectory, pBaseDirectory);
135
- } else {
136
- return getSingleManifest(pFileDirectory);
137
- }
133
+ if (pCombinedDependencies) {
134
+ return getCombinedManifests(pFileDirectory, pBaseDirectory);
135
+ } else {
136
+ return getSingleManifest(pFileDirectory);
137
+ }
138
138
  }
139
139
 
140
140
  export function clearCache() {
141
- memoizeClear(getCombinedManifests);
142
- memoizeClear(getSingleManifest);
141
+ memoizeClear(getCombinedManifests);
142
+ memoizeClear(getSingleManifest);
143
143
  }
@@ -14,6 +14,8 @@ import pathToPosix from "#utl/path-to-posix.mjs";
14
14
  * @import { IDependency } from "../../../types/cruise-result.mjs";
15
15
  */
16
16
 
17
+ const COMMONJS_RESOLVABLE_MODULE_SYSTEMS = new Set(["cjs", "es6", "tsd"]);
18
+
17
19
  /**
18
20
  *
19
21
  * @param {IModule} pModule
@@ -23,138 +25,147 @@ import pathToPosix from "#utl/path-to-posix.mjs";
23
25
  * @returns {any}
24
26
  */
25
27
  function resolveModule(
26
- pModule,
27
- pBaseDirectory,
28
- pFileDirectory,
29
- pResolveOptions,
28
+ pModule,
29
+ pBaseDirectory,
30
+ pFileDirectory,
31
+ pResolveOptions,
30
32
  ) {
31
- let lReturnValue = null;
32
-
33
- const lStrippedModuleName = stripToModuleName(pModule.module);
34
- if (
35
- isRelativeModuleName(lStrippedModuleName) ||
36
- ["cjs", "es6", "tsd"].includes(pModule.moduleSystem)
37
- ) {
38
- lReturnValue = resolveCommonJS(
39
- lStrippedModuleName,
40
- pBaseDirectory,
41
- pFileDirectory,
42
- pResolveOptions,
43
- );
44
- } else {
45
- lReturnValue = resolveAMD(
46
- lStrippedModuleName,
47
- pBaseDirectory,
48
- pFileDirectory,
49
- pResolveOptions,
50
- );
51
- }
52
- return lReturnValue;
33
+ let lReturnValue = null;
34
+
35
+ const lStrippedModuleName = stripToModuleName(pModule.module);
36
+ if (
37
+ isRelativeModuleName(lStrippedModuleName) ||
38
+ COMMONJS_RESOLVABLE_MODULE_SYSTEMS.has(pModule.moduleSystem)
39
+ ) {
40
+ lReturnValue = resolveCommonJS(
41
+ lStrippedModuleName,
42
+ pBaseDirectory,
43
+ pFileDirectory,
44
+ pResolveOptions,
45
+ );
46
+ } else {
47
+ lReturnValue = resolveAMD(
48
+ lStrippedModuleName,
49
+ pBaseDirectory,
50
+ pFileDirectory,
51
+ pResolveOptions,
52
+ );
53
+ }
54
+ return lReturnValue;
53
55
  }
54
56
 
57
+ const RESOLVABLE_TO_TS_VARIANT_EXTENSIONS = new Set([
58
+ ".js",
59
+ ".jsx",
60
+ ".mjs",
61
+ ".cjs",
62
+ ]);
63
+
55
64
  function canBeResolvedToTsVariant(pModuleName) {
56
- return [".js", ".jsx", ".mjs", ".cjs"].includes(extname(pModuleName));
65
+ return RESOLVABLE_TO_TS_VARIANT_EXTENSIONS.has(extname(pModuleName));
57
66
  }
58
67
 
68
+ const TYPESCRIPT_ISH_EXTENSIONS = new Set([".ts", ".tsx", ".cts", ".mts"]);
69
+
59
70
  function isTypeScriptIshExtension(pModuleName) {
60
- return [".ts", ".tsx", ".cts", ".mts"].includes(extname(pModuleName));
71
+ return TYPESCRIPT_ISH_EXTENSIONS.has(extname(pModuleName));
61
72
  }
62
73
  function resolveYarnVirtual(pBaseDirectory, pPath) {
63
- const pnpAPI = (monkeyPatchedModule?.findPnpApi ?? (() => false))(pPath);
64
-
65
- // the pnp api only works in plug'n play environments, and resolveVirtual
66
- // only under yarn(berry). As we can't run a 'regular' nodejs environment
67
- // and a yarn(berry) one at the same time, ignore in the test coverage and
68
- // cover it in a separate integration test.
69
- /* c8 ignore start */
70
- if (pnpAPI && (pnpAPI?.VERSIONS?.resolveVirtual ?? 0) === 1) {
71
- // resolveVirtual takes absolute paths, hence the path.resolve:
72
- const lResolvedAbsolute = path_resolve(pBaseDirectory, pPath);
73
- const lResolvedVirtual = pnpAPI.resolveVirtual(lResolvedAbsolute);
74
- if (lResolvedVirtual) {
75
- const lResolvedRelative = relative(pBaseDirectory, lResolvedVirtual);
76
- // in win32 environments resolveVirtual might return win32 paths,
77
- // so we have to convert them to posix paths again
78
- return pathToPosix(lResolvedRelative);
79
- }
80
- }
81
- /* c8 ignore stop */
82
- return pPath;
74
+ const pnpAPI = (monkeyPatchedModule?.findPnpApi ?? (() => false))(pPath);
75
+
76
+ // the pnp api only works in plug'n play environments, and resolveVirtual
77
+ // only under yarn(berry). As we can't run a 'regular' nodejs environment
78
+ // and a yarn(berry) one at the same time, ignore in the test coverage and
79
+ // cover it in a separate integration test.
80
+ /* c8 ignore start */
81
+ if (pnpAPI && (pnpAPI?.VERSIONS?.resolveVirtual ?? 0) === 1) {
82
+ // resolveVirtual takes absolute paths, hence the path.resolve:
83
+ const lResolvedAbsolute = path_resolve(pBaseDirectory, pPath);
84
+ const lResolvedVirtual = pnpAPI.resolveVirtual(lResolvedAbsolute);
85
+ if (lResolvedVirtual) {
86
+ const lResolvedRelative = relative(pBaseDirectory, lResolvedVirtual);
87
+ // in win32 environments resolveVirtual might return win32 paths,
88
+ // so we have to convert them to posix paths again
89
+ return pathToPosix(lResolvedRelative);
90
+ }
91
+ }
92
+ /* c8 ignore stop */
93
+ return pPath;
83
94
  }
84
95
 
96
+ const JS_TO_TS_MAP = new Map([
97
+ [".js", [".ts", ".tsx", ".d.ts"]],
98
+ [".jsx", [".ts", ".tsx", ".d.ts"]],
99
+ [".cjs", [".cts", ".d.cts"]],
100
+ [".mjs", [".mts", ".d.mts"]],
101
+ ]);
102
+
85
103
  /**
86
104
  *
87
105
  * @param {string} pJavaScriptExtension
88
- * @returns {string}
106
+ * @returns {string[]}
89
107
  */
90
108
  function getTypeScriptExtensionsToTry(pJavaScriptExtension) {
91
- const lJS2TSMap = new Map([
92
- [".js", [".ts", ".tsx", ".d.ts"]],
93
- [".jsx", [".ts", ".tsx", ".d.ts"]],
94
- [".cjs", [".cts", ".d.cts"]],
95
- [".mjs", [".mts", ".d.mts"]],
96
- ]);
97
-
98
- return lJS2TSMap.get(pJavaScriptExtension) ?? [];
109
+ return JS_TO_TS_MAP.get(pJavaScriptExtension) ?? [];
99
110
  }
100
111
 
101
112
  // eslint-disable-next-line max-lines-per-function
102
113
  function resolveWithRetry(
103
- pModule,
104
- pBaseDirectory,
105
- pFileDirectory,
106
- pResolveOptions,
114
+ pModule,
115
+ pBaseDirectory,
116
+ pFileDirectory,
117
+ pResolveOptions,
107
118
  ) {
108
- let lReturnValue = resolveModule(
109
- pModule,
110
- pBaseDirectory,
111
- pFileDirectory,
112
- pResolveOptions,
113
- );
114
- const lStrippedModuleName = stripToModuleName(pModule.module);
115
-
116
- // when we feed the typescript compiler an import with an explicit .js(x) extension
117
- // and the .js(x) file does not exist, it tries files with the .ts, .tsx or
118
- // .d.ts extensions (this a.o. means ./hello.jsx can resolve to ./hello.ts and
119
- // ./wut.js to ./wut.tsx).
120
- //
121
- // This behavior is very specific:
122
- // - tsc only (doesn't work in ts-node for instance)
123
- // - until TypeScript 4.6 only for the .js and .jsx extensions
124
- // - since TypeScript 4.7 also for .cjs and .mjs (=> .cts, .mts) extensions,
125
- // which work subtly different;
126
- // .cjs resolves to .cts or .d.cts (in that order)
127
- // .mjs resolves to .mts or .d.mts (in that order)
128
- // ref: https://www.typescriptlang.org/docs/handbook/esm-node.html#new-file-extensions
129
- //
130
- // Hence also this oddly specific looking check & retry.
131
- //
132
- // This should eventually probably land in either enhanced_resolve or in a
133
- // plugin/ extension for it (tsconfig-paths-webpack-plugin?)
134
- if (
135
- lReturnValue.couldNotResolve &&
136
- canBeResolvedToTsVariant(lStrippedModuleName)
137
- ) {
138
- const lModuleWithoutExtension = lStrippedModuleName.replace(
139
- /\.(js|jsx|cjs|mjs)$/g,
140
- "",
141
- );
142
- const lExtensionsToTry = getTypeScriptExtensionsToTry(
143
- extname(lStrippedModuleName),
144
- );
145
-
146
- const lReturnValueCandidate = resolveModule(
147
- { ...pModule, module: lModuleWithoutExtension },
148
- pBaseDirectory,
149
- pFileDirectory,
150
- { ...pResolveOptions, extensions: lExtensionsToTry },
151
- );
152
-
153
- if (isTypeScriptIshExtension(lReturnValueCandidate.resolved)) {
154
- lReturnValue = lReturnValueCandidate;
155
- }
156
- }
157
- return lReturnValue;
119
+ let lReturnValue = resolveModule(
120
+ pModule,
121
+ pBaseDirectory,
122
+ pFileDirectory,
123
+ pResolveOptions,
124
+ );
125
+ const lStrippedModuleName = stripToModuleName(pModule.module);
126
+
127
+ // when we feed the typescript compiler an import with an explicit .js(x) extension
128
+ // and the .js(x) file does not exist, it tries files with the .ts, .tsx or
129
+ // .d.ts extensions (this a.o. means ./hello.jsx can resolve to ./hello.ts and
130
+ // ./wut.js to ./wut.tsx).
131
+ //
132
+ // This behavior is very specific:
133
+ // - tsc only (doesn't work in ts-node for instance)
134
+ // - until TypeScript 4.6 only for the .js and .jsx extensions
135
+ // - since TypeScript 4.7 also for .cjs and .mjs (=> .cts, .mts) extensions,
136
+ // which work subtly different;
137
+ // .cjs resolves to .cts or .d.cts (in that order)
138
+ // .mjs resolves to .mts or .d.mts (in that order)
139
+ // ref: https://www.typescriptlang.org/docs/handbook/esm-node.html#new-file-extensions
140
+ //
141
+ // Hence also this oddly specific looking check & retry.
142
+ //
143
+ // This should eventually probably land in either enhanced_resolve or in a
144
+ // plugin/ extension for it (tsconfig-paths-webpack-plugin?)
145
+ if (
146
+ lReturnValue.couldNotResolve &&
147
+ canBeResolvedToTsVariant(lStrippedModuleName)
148
+ ) {
149
+ const lModuleWithoutExtension = lStrippedModuleName.replace(
150
+ /\.(js|jsx|cjs|mjs)$/g,
151
+ "",
152
+ );
153
+ const lExtensionsToTry = getTypeScriptExtensionsToTry(
154
+ extname(lStrippedModuleName),
155
+ );
156
+
157
+ const lReturnValueCandidate = resolveModule(
158
+ { ...pModule, module: lModuleWithoutExtension },
159
+ pBaseDirectory,
160
+ pFileDirectory,
161
+ { ...pResolveOptions, extensions: lExtensionsToTry },
162
+ );
163
+
164
+ if (isTypeScriptIshExtension(lReturnValueCandidate.resolved)) {
165
+ lReturnValue = lReturnValueCandidate;
166
+ }
167
+ }
168
+ return lReturnValue;
158
169
  }
159
170
 
160
171
  /**
@@ -173,58 +184,58 @@ function resolveWithRetry(
173
184
  */
174
185
  // eslint-disable-next-line max-lines-per-function, max-params
175
186
  export default function resolve(
176
- pDependency,
177
- pBaseDirectory,
178
- pFileDirectory,
179
- pResolveOptions,
180
- pTranspileOptions,
187
+ pDependency,
188
+ pBaseDirectory,
189
+ pFileDirectory,
190
+ pResolveOptions,
191
+ pTranspileOptions,
181
192
  ) {
182
- let lResolvedDependency = resolveWithRetry(
183
- pDependency,
184
- pBaseDirectory,
185
- pFileDirectory,
186
- pResolveOptions,
187
- );
188
- const lStrippedModuleName = stripToModuleName(pDependency.module);
189
-
190
- lResolvedDependency = {
191
- ...lResolvedDependency,
192
- ...addLicenseAttribute(
193
- lStrippedModuleName,
194
- lResolvedDependency.resolved,
195
- { baseDirectory: pBaseDirectory, fileDirectory: pFileDirectory },
196
- pResolveOptions,
197
- ),
198
- dependencyTypes: determineDependencyTypes(
199
- { ...pDependency, ...lResolvedDependency },
200
- lStrippedModuleName,
201
- getManifest(
202
- pFileDirectory,
203
- pBaseDirectory,
204
- pResolveOptions.combinedDependencies,
205
- ),
206
- pFileDirectory,
207
- pResolveOptions,
208
- pBaseDirectory,
209
- pTranspileOptions,
210
- ),
211
- };
212
-
213
- if (!lResolvedDependency.coreModule && !lResolvedDependency.couldNotResolve) {
214
- // enhanced-resolve inserts a NULL character in front of any `#` character.
215
- // This wonky replace corrects that that so the filename again corresponds
216
- // with a real file on disk
217
- const lResolvedEHRCorrected = lResolvedDependency.resolved.replace(
218
- // eslint-disable-next-line no-control-regex
219
- /\u0000#/g,
220
- "#",
221
- );
222
- const lResolvedYarnVirtual = resolveYarnVirtual(
223
- pBaseDirectory,
224
- lResolvedEHRCorrected,
225
- );
226
-
227
- lResolvedDependency.resolved = lResolvedYarnVirtual;
228
- }
229
- return lResolvedDependency;
193
+ let lResolvedDependency = resolveWithRetry(
194
+ pDependency,
195
+ pBaseDirectory,
196
+ pFileDirectory,
197
+ pResolveOptions,
198
+ );
199
+ const lStrippedModuleName = stripToModuleName(pDependency.module);
200
+
201
+ lResolvedDependency = {
202
+ ...lResolvedDependency,
203
+ ...addLicenseAttribute(
204
+ lStrippedModuleName,
205
+ lResolvedDependency.resolved,
206
+ { baseDirectory: pBaseDirectory, fileDirectory: pFileDirectory },
207
+ pResolveOptions,
208
+ ),
209
+ dependencyTypes: determineDependencyTypes(
210
+ { ...pDependency, ...lResolvedDependency },
211
+ lStrippedModuleName,
212
+ getManifest(
213
+ pFileDirectory,
214
+ pBaseDirectory,
215
+ pResolveOptions.combinedDependencies,
216
+ ),
217
+ pFileDirectory,
218
+ pResolveOptions,
219
+ pBaseDirectory,
220
+ pTranspileOptions,
221
+ ),
222
+ };
223
+
224
+ if (!lResolvedDependency.coreModule && !lResolvedDependency.couldNotResolve) {
225
+ // enhanced-resolve inserts a NULL character in front of any `#` character.
226
+ // This wonky replace corrects that so the filename again corresponds
227
+ // with a real file on disk
228
+ const lResolvedEHRCorrected = lResolvedDependency.resolved.replace(
229
+ // eslint-disable-next-line no-control-regex
230
+ /\u0000#/g,
231
+ "#",
232
+ );
233
+ const lResolvedYarnVirtual = resolveYarnVirtual(
234
+ pBaseDirectory,
235
+ lResolvedEHRCorrected,
236
+ );
237
+
238
+ lResolvedDependency.resolved = lResolvedYarnVirtual;
239
+ }
240
+ return lResolvedDependency;
230
241
  }
@@ -6,29 +6,27 @@ import { isBuiltin as moduleIsBuiltin } from "node:module";
6
6
  * @returns {boolean} - true if the module is a built-in module
7
7
  */
8
8
  export function isBuiltin(pModuleName, pResolveOptions) {
9
- if (pResolveOptions?.builtInModules?.override) {
10
- return pResolveOptions.builtInModules.override.includes(pModuleName);
11
- }
9
+ if (pResolveOptions?.builtInModules?.override) {
10
+ return pResolveOptions.builtInModules.override.includes(pModuleName);
11
+ }
12
12
 
13
- // bun, as it turns out, has some additional builtin modules. Even when running
14
- // dependency-cruiser with bunx, bunx will use node by default. To cover that scenario
15
- // there's three options
16
- // - tell everyone to run bunx with the --bun option, so bun uses bun instead of node
17
- // and hope everyone actually does that and it doesn't lead to a bunch of questions
18
- // in the issues section. I don't expect that to happen anytime soon => other options
19
- // - add the bun builtins here.
20
- // this sounds attractive, but some of the modules ('undici', 'ws') are
21
- // also npm packages. In nodejs context that will lead to a.o. false
22
- // classifications.
23
- // - add the bun builtins in dependency-cruiser.js
24
- // Current approach. The --init command will try to detect whether it's
25
- // in a bun repo and add the bun builtins to the config.
26
- //
27
- // Update: We now also detect modules with the 'bun:' protocol prefix as built-ins
28
- // automatically, as they're unambiguous (unlike bare module names like 'undici').
29
- return (
30
- moduleIsBuiltin(pModuleName) ||
31
- pModuleName.startsWith("bun:") ||
32
- (pResolveOptions?.builtInModules?.add ?? []).includes(pModuleName)
33
- );
13
+ // bun, as it turns out, has some additional builtin modules. Even when running
14
+ // dependency-cruiser with bunx, bunx will use node by default. To cover that scenario
15
+ // there's three options
16
+ // - tell everyone to run bunx with the --bun option, so bun uses bun instead of node
17
+ // and hope everyone actually does that and it doesn't lead to a bunch of questions
18
+ // in the issues section. I don't expect that to happen anytime soon => other options
19
+ // - add the bun builtins without prefix here.
20
+ // this sounds attractive, but some of the modules ('undici', 'ws') are
21
+ // also npm packages. In nodejs context that will lead to a.o. false
22
+ // classifications.
23
+ // - add the bun builtins in dependency-cruiser.js + automatically detect modules with the
24
+ // bun: protocol (which are unambiguous) as built-ins.
25
+ // Current approach. The --init command will try to detect whether it's
26
+ // in a bun repo and add the bun builtins to the config.
27
+ return (
28
+ moduleIsBuiltin(pModuleName) ||
29
+ pModuleName.startsWith("bun:") ||
30
+ (pResolveOptions?.builtInModules?.add ?? []).includes(pModuleName)
31
+ );
34
32
  }