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
@@ -2,48 +2,48 @@ import { uniq } from "#utl/array-util.mjs";
2
2
 
3
3
  /* eslint-disable security/detect-object-injection */
4
4
  function normalizeManifestKeys(pManifest) {
5
- let lReturnValue = pManifest;
5
+ let lReturnValue = pManifest;
6
6
 
7
- if (pManifest.bundleDependencies) {
8
- pManifest.bundledDependencies = structuredClone(
9
- pManifest.bundleDependencies,
10
- );
11
- Reflect.deleteProperty(pManifest, "bundleDependencies");
12
- }
13
- return lReturnValue;
7
+ if (pManifest.bundleDependencies) {
8
+ pManifest.bundledDependencies = structuredClone(
9
+ pManifest.bundleDependencies,
10
+ );
11
+ Reflect.deleteProperty(pManifest, "bundleDependencies");
12
+ }
13
+ return lReturnValue;
14
14
  }
15
15
 
16
16
  function mergeDependencyKey(pClosestDependencyKey, pFurtherDependencyKey) {
17
- return {
18
- ...pFurtherDependencyKey,
19
- ...pClosestDependencyKey,
20
- };
17
+ return {
18
+ ...pFurtherDependencyKey,
19
+ ...pClosestDependencyKey,
20
+ };
21
21
  }
22
22
 
23
23
  function mergeDependencyArray(pClosestDependencyKey, pFurtherDependencyKey) {
24
- return uniq(pClosestDependencyKey.concat(pFurtherDependencyKey));
24
+ return uniq(pClosestDependencyKey.concat(pFurtherDependencyKey));
25
25
  }
26
26
 
27
27
  function isInterestingKey(pKey) {
28
- return (
29
- pKey.endsWith("ependencies") || pKey === "workspaces" || pKey === "imports"
30
- );
28
+ return (
29
+ pKey.endsWith("ependencies") || pKey === "workspaces" || pKey === "imports"
30
+ );
31
31
  }
32
32
 
33
33
  function getDependencyKeys(pPackage) {
34
- return Object.keys(pPackage).filter(isInterestingKey);
34
+ return Object.keys(pPackage).filter(isInterestingKey);
35
35
  }
36
36
 
37
37
  function getJointUniqueDependencyKeys(pClosestPackage, pFurtherPackage) {
38
- return uniq(
39
- getDependencyKeys(pClosestPackage).concat(
40
- getDependencyKeys(pFurtherPackage),
41
- ),
42
- );
38
+ return uniq(
39
+ getDependencyKeys(pClosestPackage).concat(
40
+ getDependencyKeys(pFurtherPackage),
41
+ ),
42
+ );
43
43
  }
44
44
 
45
45
  function isAnArrayKey(pKey) {
46
- return pKey.startsWith("bundle") || pKey === "workspaces";
46
+ return pKey.startsWith("bundle") || pKey === "workspaces";
47
47
  }
48
48
 
49
49
  /**
@@ -63,24 +63,24 @@ function isAnArrayKey(pKey) {
63
63
  * @return {any} the combined dependency-keys within those manifests
64
64
  */
65
65
  export default function mergeManifests(pClosestManifest, pFurtherManifest) {
66
- return getJointUniqueDependencyKeys(
67
- normalizeManifestKeys(pClosestManifest),
68
- normalizeManifestKeys(pFurtherManifest),
69
- )
70
- .map((pKey) => ({
71
- key: pKey,
72
- value: isAnArrayKey(pKey)
73
- ? mergeDependencyArray(
74
- pClosestManifest?.[pKey] ?? [],
75
- pFurtherManifest?.[pKey] ?? [],
76
- )
77
- : mergeDependencyKey(
78
- pClosestManifest?.[pKey] ?? {},
79
- pFurtherManifest?.[pKey] ?? {},
80
- ),
81
- }))
82
- .reduce((pJoinedObject, pJoinedKey) => {
83
- pJoinedObject[pJoinedKey.key] = pJoinedKey.value;
84
- return pJoinedObject;
85
- }, {});
66
+ return getJointUniqueDependencyKeys(
67
+ normalizeManifestKeys(pClosestManifest),
68
+ normalizeManifestKeys(pFurtherManifest),
69
+ )
70
+ .map((pKey) => ({
71
+ key: pKey,
72
+ value: isAnArrayKey(pKey)
73
+ ? mergeDependencyArray(
74
+ pClosestManifest?.[pKey] ?? [],
75
+ pFurtherManifest?.[pKey] ?? [],
76
+ )
77
+ : mergeDependencyKey(
78
+ pClosestManifest?.[pKey] ?? {},
79
+ pFurtherManifest?.[pKey] ?? {},
80
+ ),
81
+ }))
82
+ .reduce((pJoinedObject, pJoinedKey) => {
83
+ pJoinedObject[pJoinedKey.key] = pJoinedKey.value;
84
+ return pJoinedObject;
85
+ }, {});
86
86
  }
@@ -13,85 +13,85 @@ let gFollowableExtensionsCache = new Set();
13
13
  let gFollowableExtensionsCacheInitialized = false;
14
14
 
15
15
  export function isScoped(pModuleName) {
16
- return pModuleName.startsWith("@");
16
+ return pModuleName.startsWith("@");
17
17
  }
18
18
 
19
19
  export function isRelativeModuleName(pModuleName) {
20
- return (
21
- pModuleName.startsWith("./") ||
22
- pModuleName.startsWith("../") ||
23
- pModuleName === "." ||
24
- pModuleName === ".."
25
- // note ".blah" and "..blah" are _not_ relative
26
- );
20
+ return (
21
+ pModuleName.startsWith("./") ||
22
+ pModuleName.startsWith("../") ||
23
+ pModuleName === "." ||
24
+ pModuleName === ".."
25
+ // note ".blah" and "..blah" are _not_ relative
26
+ );
27
27
  }
28
28
 
29
29
  export function isExternalModule(
30
- pResolvedModuleName,
31
- pModuleFolderNames = ["node_modules"],
32
- pBaseDirectory = ".",
30
+ pResolvedModuleName,
31
+ pModuleFolderNames = ["node_modules"],
32
+ pBaseDirectory = ".",
33
33
  ) {
34
- return (
35
- Boolean(pResolvedModuleName) &&
36
- pModuleFolderNames.some(
37
- // pModules can contain relative paths, but also absolute ones.
38
- // WebPack treats these differently:
39
- // - absolute paths only match that exact path
40
- // - relative paths get a node lookup treatment so "turtle" matches
41
- // "turtle", "../turtle", "../../turtle", "../../../turtle"
42
- // hence we'll have to test for them in different fashion as well.
43
- // reference: https://webpack.js.org/configuration/resolve/#resolve-modules
44
- (pModuleFolderName) => {
45
- if (isAbsolute(pModuleFolderName)) {
46
- return path_resolve(pBaseDirectory, pResolvedModuleName).startsWith(
47
- pModuleFolderName,
48
- );
49
- }
50
- return pResolvedModuleName.includes(pModuleFolderName);
51
- },
52
- )
53
- );
34
+ return (
35
+ Boolean(pResolvedModuleName) &&
36
+ pModuleFolderNames.some(
37
+ // pModules can contain relative paths, but also absolute ones.
38
+ // WebPack treats these differently:
39
+ // - absolute paths only match that exact path
40
+ // - relative paths get a node lookup treatment so "turtle" matches
41
+ // "turtle", "../turtle", "../../turtle"
42
+ // hence we'll have to test for them in different fashion as well.
43
+ // reference: https://webpack.js.org/configuration/resolve/#resolve-modules
44
+ (pModuleFolderName) => {
45
+ if (isAbsolute(pModuleFolderName)) {
46
+ return path_resolve(pBaseDirectory, pResolvedModuleName).startsWith(
47
+ pModuleFolderName,
48
+ );
49
+ }
50
+ return pResolvedModuleName.includes(pModuleFolderName);
51
+ },
52
+ )
53
+ );
54
54
  }
55
55
 
56
56
  function determineFollowableExtensions(pResolveOptions) {
57
- let lReturnValue = new Set(pResolveOptions.extensions);
57
+ let lReturnValue = new Set(pResolveOptions.extensions);
58
58
 
59
- // we could include things like pictures, movies, html, xml etc in
60
- // lKnownUnfollowables as well. Typically in javascript-like sources you don't
61
- // import non-javascript stuff without mentioning the extension
62
- // (`import 'styles.scss` is more clear than`import 'styles'` as you'd expect
63
- // that to resolve to something javascript-like. Defensively added the
64
- // stylesheetlanguages here explicitly nonetheless - they can contain import
65
- // statements and the fallback javascript parser will happily parse them, which
66
- // will result in false positives.
67
- const lKnownUnfollowables = [
68
- ".json",
69
- ".node",
70
- ".css",
71
- ".sass",
72
- ".scss",
73
- ".stylus",
74
- ".less",
75
- ];
59
+ // we could include things like pictures, movies, html, xml etc in
60
+ // lKnownUnfollowables as well. Ijavascript-like sources you don't
61
+ // import non-javascript stuff without mentioning the extension
62
+ // (`import 'styles.scss` is more clear than`import 'styles'` as you'd expect
63
+ // that to resolve to something javascript-like. Defensively added the
64
+ // stylesheetlanguages here explicitly nonetheless - they can contain import
65
+ // statements and the fallback javascript parser will happily parse them, which
66
+ // will result in false positives.
67
+ const lKnownUnfollowables = [
68
+ ".json",
69
+ ".node",
70
+ ".css",
71
+ ".sass",
72
+ ".scss",
73
+ ".stylus",
74
+ ".less",
75
+ ];
76
76
 
77
- for (const lUnfollowable of lKnownUnfollowables) {
78
- lReturnValue.delete(lUnfollowable);
79
- }
80
- return lReturnValue;
77
+ for (const lUnfollowable of lKnownUnfollowables) {
78
+ lReturnValue.delete(lUnfollowable);
79
+ }
80
+ return lReturnValue;
81
81
  }
82
82
 
83
83
  function getFollowableExtensions(pResolveOptions) {
84
- if (!gFollowableExtensionsCacheInitialized || pResolveOptions.bustTheCache) {
85
- gFollowableExtensionsCache = determineFollowableExtensions(pResolveOptions);
86
- gFollowableExtensionsCacheInitialized = true;
87
- }
88
- return gFollowableExtensionsCache;
84
+ if (!gFollowableExtensionsCacheInitialized || pResolveOptions.bustTheCache) {
85
+ gFollowableExtensionsCache = determineFollowableExtensions(pResolveOptions);
86
+ gFollowableExtensionsCacheInitialized = true;
87
+ }
88
+ return gFollowableExtensionsCache;
89
89
  }
90
90
 
91
91
  export function isFollowable(pResolvedFilename, pResolveOptions) {
92
- return getFollowableExtensions(pResolveOptions).has(
93
- getExtension(pResolvedFilename),
94
- );
92
+ return getFollowableExtensions(pResolveOptions).has(
93
+ getExtension(pResolvedFilename),
94
+ );
95
95
  }
96
96
 
97
97
  /**
@@ -100,20 +100,20 @@ export function isFollowable(pResolvedFilename, pResolveOptions) {
100
100
  * @returns {boolean}
101
101
  */
102
102
  function isSubpathImport(pModuleName, pManifest) {
103
- return (
104
- pModuleName.startsWith("#") &&
105
- Object.keys(pManifest?.imports ?? {}).some((pImportLHS) => {
106
- // Although they might look as such, the LHS of an import statement
107
- // (a 'subpath pattern') is not a glob. The * functions as string
108
- // replacement only.
109
- // Quoting https://nodejs.org/api/packages.html#subpath-imports :
110
- // > "* maps expose nested subpaths as it is a string replacement syntax only"
111
- const lMatchREasString = pImportLHS.replace(/\*/g, ".+");
112
- // eslint-disable-next-line security/detect-non-literal-regexp
113
- const lMatchRE = new RegExp(`^${lMatchREasString}$`);
114
- return lMatchRE.test(pModuleName);
115
- })
116
- );
103
+ return (
104
+ pModuleName.startsWith("#") &&
105
+ Object.keys(pManifest?.imports ?? {}).some((pImportLHS) => {
106
+ // Although they might look as such, the LHS of an import statement
107
+ // (a 'subpath pattern') is not a glob. The * functions as string
108
+ // replacement only.
109
+ // Quoting https://nodejs.org/api/packages.html#subpath-imports :
110
+ // > "* maps expose nested subpaths as it is a string replacement syntax only"
111
+ const lMatchREasString = pImportLHS.replace(/\*/g, ".+");
112
+ // eslint-disable-next-line security/detect-non-literal-regexp
113
+ const lMatchRE = new RegExp(`^${lMatchREasString}$`);
114
+ return lMatchRE.test(pModuleName);
115
+ })
116
+ );
117
117
  }
118
118
 
119
119
  /**
@@ -122,19 +122,19 @@ function isSubpathImport(pModuleName, pManifest) {
122
122
  * @returns {boolean}
123
123
  */
124
124
  function isWebPackAliased(pModuleName, pAliasObject) {
125
- return Object.keys(pAliasObject || {}).some((pAliasLHS) =>
126
- pModuleName.startsWith(pAliasLHS),
127
- );
125
+ return Object.keys(pAliasObject || {}).some((pAliasLHS) =>
126
+ pModuleName.startsWith(pAliasLHS),
127
+ );
128
128
  }
129
129
 
130
130
  function getWorkspacesArray(pManifestWorkspacesField) {
131
- if (Array.isArray(pManifestWorkspacesField)) {
132
- return pManifestWorkspacesField;
133
- }
134
- if (pManifestWorkspacesField?.packages) {
135
- return pManifestWorkspacesField.packages;
136
- }
137
- return [];
131
+ if (Array.isArray(pManifestWorkspacesField)) {
132
+ return pManifestWorkspacesField;
133
+ }
134
+ if (pManifestWorkspacesField?.packages) {
135
+ return pManifestWorkspacesField.packages;
136
+ }
137
+ return [];
138
138
  }
139
139
 
140
140
  /**
@@ -145,68 +145,68 @@ function getWorkspacesArray(pManifestWorkspacesField) {
145
145
  */
146
146
  // eslint-disable-next-line max-lines-per-function
147
147
  function isWorkspaceAliased(pModuleName, pResolvedModuleName, pManifest) {
148
- // reference: https://docs.npmjs.com/cli/v10/using-npm/workspaces
149
- // for yarn the workspaces field might be either an array or
150
- // an object. To prevent the code from borking we check whether it's an array
151
- // see https://github.com/sverweij/dependency-cruiser/issues/919
152
- const lWorkspaces = getWorkspacesArray(pManifest?.workspaces);
153
- if (lWorkspaces.length > 0) {
154
- // workspaces are an array of globs that match the (sub) workspace
155
- // folder itself only.
156
- //
157
- // workspaces: [
158
- // "packages/*", -> matches packages/a, packages/b, packages/c, ...
159
- // "libs/x", -> matches libs/x
160
- // "libs/y", -> matches libs/y
161
- // "apps" -> matches apps
162
- // ]
163
- //
164
- // By definition this will _never_ match resolved module names.
165
- // E.g. in packages/a => packages/a/dist/main/index.js or
166
- // in libs/x => libs/x/index.js
167
- //
168
- // This is why we chuck a `/**` at the end of each workspace glob, which
169
- // transforms it into a 'starts with' glob. And yeah, you can have a /
170
- // at the end of a glob. And because double slashes are taken literally
171
- // we have a ternary operator to prevent those.
172
- //
173
- // oh and: ```picomatch.isMatch('asdf', 'asdf/**') === true``` so
174
- // in case it's only 'asdf' that's in the resolved module name for some reason
175
- // we're good as well.
176
- //
177
- // workspaces is supposed to be array of strings, where each string is
178
- // a glob pattern. However, in the field there's occasions where it's
179
- // not a string. We'll just ignore those for now, hence the presence of
180
- // the `typeof pWorkspace === "string"` check.
181
- const lModuleFriendlyWorkspaceGlobs = lWorkspaces.map((pWorkspace) =>
182
- typeof pWorkspace === "string" && pWorkspace.endsWith("/")
183
- ? `${pWorkspace}**`
184
- : `${pWorkspace}/**`,
185
- );
186
- if (picomatch.isMatch(pResolvedModuleName, lModuleFriendlyWorkspaceGlobs)) {
187
- return true;
188
- }
189
- // it's possible to run node with --preserve-symlinks, in which case
190
- // the symlinked workspace folders are not resolved to their realpath.
191
- // So we need to check both the thing in node_modules _and_ the resolved
192
- // thing. Annoyingly, the symlink in node_modules is the `name` attribute
193
- // of the workspace, not the path of the workspace itself. So if it's
194
- // in node_modules we need to check against the unresolved modulename.
195
- //
196
- // Other than the detection for when symlinks are resolved to their realpath
197
- // (the if above), this is a 'best effort' detection only for now; there's
198
- // guaranteed to be scenarios where this will fail. How often is the
199
- // --preserve-symlinks flag used in practice, though?
200
- const lModuleFriendlyWorkspaceGlobsWithNodeModules =
201
- lModuleFriendlyWorkspaceGlobs.map(
202
- (pWorkspace) => `(node_modules/)?${pWorkspace}`,
203
- );
204
- return picomatch.isMatch(
205
- pModuleName,
206
- lModuleFriendlyWorkspaceGlobsWithNodeModules,
207
- );
208
- }
209
- return false;
148
+ // reference: https://docs.npmjs.com/cli/v10/using-npm/workspaces
149
+ // for yarn the workspaces field might be either an array or
150
+ // an object. To prevent the code from borking we check whether it's an array
151
+ // see https://github.com/sverweij/dependency-cruiser/issues/919
152
+ const lWorkspaces = getWorkspacesArray(pManifest?.workspaces);
153
+ if (lWorkspaces.length > 0) {
154
+ // workspaces are an array of globs that match the (sub) workspace
155
+ // folder itself only.
156
+ //
157
+ // workspaces: [
158
+ // "packages/*", -> matches packages/a, packages/b, packages/c, ...
159
+ // "libs/x", -> matches libs/x
160
+ // "libs/y", -> matches libs/y
161
+ // "apps" -> matches apps
162
+ // ]
163
+ //
164
+ // By definition this will _never_ match resolved module names.
165
+ // E.g. in packages/a => packages/a/dist/main/index.js or
166
+ // in libs/x => libs/x/index.js
167
+ //
168
+ // This is why we chuck a `/**` at the end of each workspace glob, which
169
+ // transforms it into a 'starts with' glob. And yeah, you can have a /
170
+ // at the end of a glob. And because double slashes are taken literally
171
+ // we have a ternary operator to prevent those.
172
+ //
173
+ // oh and: ```picomatch.isMatch('asdf', 'asdf/**') === true``` so
174
+ // in case it's only 'asdf' that's in the resolved module name for some reason
175
+ // we're good as well.
176
+ //
177
+ // workspaces is supposed to be array of strings, where each string is
178
+ // a glob pattern. However, in the field there's occasions where it's
179
+ // not a string. We'll just ignore those for now, hence the presence of
180
+ // the `typeof pWorkspace === "string"` check.
181
+ const lModuleFriendlyWorkspaceGlobs = lWorkspaces.map((pWorkspace) =>
182
+ typeof pWorkspace === "string" && pWorkspace.endsWith("/")
183
+ ? `${pWorkspace}**`
184
+ : `${pWorkspace}/**`,
185
+ );
186
+ if (picomatch.isMatch(pResolvedModuleName, lModuleFriendlyWorkspaceGlobs)) {
187
+ return true;
188
+ }
189
+ // it's possible to run node with --preserve-symlinks. The symlinked workspace folders
190
+ // then are not resolved to their realpath.
191
+ // So we need to check both the thing in node_modules _and_ the resolved
192
+ // thing. Annoyingly, the symlink in node_modules is the `name` attribute
193
+ // of the workspace, not the path of the workspace itself. So if it's
194
+ // in node_modules we need to check against the unresolved modulename.
195
+ //
196
+ // Other than the detection for when symlinks are resolved to their realpath
197
+ // (the if above), this is a 'best effort' detection only for now; there's
198
+ // guaranteed to be scenarios where this will fail. How often is the
199
+ // --preserve-symlinks flag used in practice, though?
200
+ const lModuleFriendlyWorkspaceGlobsWithNodeModules =
201
+ lModuleFriendlyWorkspaceGlobs.map(
202
+ (pWorkspace) => `(node_modules/)?${pWorkspace}`,
203
+ );
204
+ return picomatch.isMatch(
205
+ pModuleName,
206
+ lModuleFriendlyWorkspaceGlobsWithNodeModules,
207
+ );
208
+ }
209
+ return false;
210
210
  }
211
211
 
212
212
  /**
@@ -216,32 +216,32 @@ function isWorkspaceAliased(pModuleName, pResolvedModuleName, pManifest) {
216
216
  * @returns {boolean}
217
217
  */
218
218
  function matchesTSConfigPaths(pModuleName, pPaths) {
219
- // "paths patterns can contain a single * wildcard, which matches any string.
220
- // The * token can then be used in the file path values to substitute the
221
- // matched string."
222
- // https://www.typescriptlang.org/docs/handbook/modules/reference.html#wildcard-substitutions
223
- //
224
- // So, just like with subpath imports, the LHS of a path pattern is not a glob
225
- // and the '*' functions as a string replacement only.
226
- //
227
- // TODO: 'any string' - does this include the empty string as well? Checks seem
228
- // to indicate it doesn't, so we use `.+` instead of `.*`
229
- return Object.keys(pPaths).some((pPathLHS) => {
230
- // eslint-disable-next-line security/detect-non-literal-regexp
231
- const lMatchRE = new RegExp(`^${pPathLHS.replace(/\*/g, ".+")}$`);
232
- return lMatchRE.test(pModuleName);
233
- });
219
+ // "paths patterns can contain a single * wildcard, which matches any string.
220
+ // The * token can then be used in the file path values to substitute the
221
+ // matched string."
222
+ // https://www.typescriptlang.org/docs/handbook/modules/reference.html#wildcard-substitutions
223
+ //
224
+ // So, just like with subpath imports, the LHS of a path pattern is not a glob
225
+ // and the '*' functions as a string replacement only.
226
+ //
227
+ // TODO: 'any string' - does this include the empty string as well? Checks seem
228
+ // to indicate it doesn't, so we use `.+` instead of `.*`
229
+ return Object.keys(pPaths).some((pPathLHS) => {
230
+ // eslint-disable-next-line security/detect-non-literal-regexp
231
+ const lMatchRE = new RegExp(`^${pPathLHS.replace(/\*/g, ".+")}$`);
232
+ return lMatchRE.test(pModuleName);
233
+ });
234
234
  }
235
235
 
236
236
  function stripExtension(pModulePath) {
237
- const lExtension = getExtension(pModulePath);
238
- return lExtension ? pModulePath.slice(0, -lExtension.length) : pModulePath;
237
+ const lExtension = getExtension(pModulePath);
238
+ return lExtension ? pModulePath.slice(0, -lExtension.length) : pModulePath;
239
239
  }
240
240
 
241
241
  function stripIndex(pModulePath) {
242
- return pModulePath.endsWith("/index")
243
- ? pModulePath.slice(0, -"/index".length)
244
- : pModulePath;
242
+ return pModulePath.endsWith("/index")
243
+ ? pModulePath.slice(0, -"/index".length)
244
+ : pModulePath;
245
245
  }
246
246
 
247
247
  /**
@@ -255,29 +255,29 @@ function stripIndex(pModulePath) {
255
255
  * @param {string} pTSConfigBaseURL
256
256
  */
257
257
  function matchesTSConfigBaseURL(
258
- pModuleName,
259
- pResolvedModuleName,
260
- pTSConfigBaseURL,
258
+ pModuleName,
259
+ pResolvedModuleName,
260
+ pTSConfigBaseURL,
261
261
  ) {
262
- // the pModuleName === pResolvedModuleName check is there to prevent
263
- // false positives for core modules ('fs' resolved === 'fs') and modules that
264
- // we couldn't resolve at all (e.g. 'this/does/not/exist' => 'this/does/not/exist')
265
- //
266
- // we could also check whether the moduleName is relative, but that's
267
- // not efficient as that was already done before this function was called.
268
- if (!pTSConfigBaseURL || pModuleName === pResolvedModuleName) {
269
- return false;
270
- }
271
- // "If baseUrl is set, TypeScript will resolve non-relative module names
272
- // relative to the baseUrl."
273
- // https://www.typescriptlang.org/docs/handbook/modules.html#base-url
274
- const strippedModuleNameJoinedToBaseURL = stripIndex(
275
- stripExtension(posix_join(pTSConfigBaseURL, pModuleName)),
276
- );
277
- const strippedResolvedModuleName = stripIndex(
278
- stripExtension(pResolvedModuleName),
279
- );
280
- return strippedModuleNameJoinedToBaseURL.endsWith(strippedResolvedModuleName);
262
+ // the pModuleName === pResolvedModuleName check is there to prevent
263
+ // false positives for core modules ('fs' resolved === 'fs') and modules that
264
+ // we couldn't resolve at all (e.g. 'this/does/not/exist' => 'this/does/not/exist')
265
+ //
266
+ // we could also check whether the moduleName is relative, but that's
267
+ // not efficient as that was already done before this function was called.
268
+ if (!pTSConfigBaseURL || pModuleName === pResolvedModuleName) {
269
+ return false;
270
+ }
271
+ // "If baseUrl is set, TypeScript will resolve non-relative module names
272
+ // relative to the baseUrl."
273
+ // https://www.typescriptlang.org/docs/handbook/modules.html#base-url
274
+ const strippedModuleNameJoinedToBaseURL = stripIndex(
275
+ stripExtension(posix_join(pTSConfigBaseURL, pModuleName)),
276
+ );
277
+ const strippedResolvedModuleName = stripIndex(
278
+ stripExtension(pResolvedModuleName),
279
+ );
280
+ return strippedModuleNameJoinedToBaseURL.endsWith(strippedResolvedModuleName);
281
281
  }
282
282
 
283
283
  /**
@@ -290,45 +290,45 @@ function matchesTSConfigBaseURL(
290
290
  */
291
291
  // eslint-disable-next-line max-params, complexity
292
292
  export function getAliasTypes(
293
- pModuleName,
294
- pResolvedModuleName,
295
- pResolveOptions,
296
- pManifest,
297
- pTranspileOptions,
293
+ pModuleName,
294
+ pResolvedModuleName,
295
+ pResolveOptions,
296
+ pManifest,
297
+ pTranspileOptions,
298
298
  ) {
299
- if (isRelativeModuleName(pModuleName)) {
300
- return [];
301
- }
302
- // the order of these ifs is deliberate. First stuff bolted on by bundlers & transpilers.
303
- if (isWebPackAliased(pModuleName, pResolveOptions.alias)) {
304
- return ["aliased", "aliased-webpack"];
305
- }
306
- if (
307
- matchesTSConfigBaseURL(
308
- pModuleName,
309
- pResolvedModuleName,
310
- pTranspileOptions?.tsConfig?.options?.baseUrl,
311
- )
312
- ) {
313
- return ["aliased", "aliased-tsconfig", "aliased-tsconfig-base-url"];
314
- }
315
- if (
316
- matchesTSConfigPaths(
317
- pModuleName,
318
- pTranspileOptions?.tsConfig?.options?.paths ?? {},
319
- )
320
- ) {
321
- return ["aliased", "aliased-tsconfig", "aliased-tsconfig-paths"];
322
- }
323
- // The order of subpath imports and workspaces isn't _that_ important, as they
324
- // can't be confused
325
- // - subpath imports _must_ start with a #
326
- // - workspaces (or, more precise: package names) are forbidden to even _contain_ a #
327
- if (isSubpathImport(pModuleName, pManifest)) {
328
- return ["aliased", "aliased-subpath-import"];
329
- }
330
- if (isWorkspaceAliased(pModuleName, pResolvedModuleName, pManifest)) {
331
- return ["aliased", "aliased-workspace"];
332
- }
333
- return [];
299
+ if (isRelativeModuleName(pModuleName)) {
300
+ return [];
301
+ }
302
+ // the order of these ifs is deliberate. First stuff bolted on by bundlers & transpilers.
303
+ if (isWebPackAliased(pModuleName, pResolveOptions.alias)) {
304
+ return ["aliased", "aliased-webpack"];
305
+ }
306
+ if (
307
+ matchesTSConfigBaseURL(
308
+ pModuleName,
309
+ pResolvedModuleName,
310
+ pTranspileOptions?.tsConfig?.options?.baseUrl,
311
+ )
312
+ ) {
313
+ return ["aliased", "aliased-tsconfig", "aliased-tsconfig-base-url"];
314
+ }
315
+ if (
316
+ matchesTSConfigPaths(
317
+ pModuleName,
318
+ pTranspileOptions?.tsConfig?.options?.paths ?? {},
319
+ )
320
+ ) {
321
+ return ["aliased", "aliased-tsconfig", "aliased-tsconfig-paths"];
322
+ }
323
+ // The order of subpath imports and workspaces isn't _that_ important, as they
324
+ // can't be confused
325
+ // - subpath imports _must_ start with a #
326
+ // - workspaces (or, more precise: package names) are forbidden to even _contain_ a #
327
+ if (isSubpathImport(pModuleName, pManifest)) {
328
+ return ["aliased", "aliased-subpath-import"];
329
+ }
330
+ if (isWorkspaceAliased(pModuleName, pResolvedModuleName, pManifest)) {
331
+ return ["aliased", "aliased-workspace"];
332
+ }
333
+ return [];
334
334
  }