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
@@ -11,36 +11,44 @@ import meta from "#meta.cjs";
11
11
 
12
12
  /** @type {typescript} */
13
13
  const typescript = await tryImport(
14
- "typescript",
15
- meta.supportedTranspilers.typescript,
14
+ "typescript",
15
+ meta.supportedTranspilers.typescript,
16
16
  );
17
17
 
18
+ const INTERESTING_NODE_KINDS = new Set([
19
+ typescript.SyntaxKind.CallExpression,
20
+ typescript.SyntaxKind.ExportDeclaration,
21
+ typescript.SyntaxKind.ImportDeclaration,
22
+ typescript.SyntaxKind.ImportEqualsDeclaration,
23
+ typescript.SyntaxKind.LastTypeNode,
24
+ ]);
25
+
18
26
  function isTypeOnlyImport(pStatement) {
19
- return (
20
- pStatement.importClause &&
21
- (pStatement.importClause.isTypeOnly ||
22
- (pStatement.importClause.namedBindings &&
23
- pStatement.importClause.namedBindings.elements &&
24
- pStatement.importClause.namedBindings.elements.every(
25
- (pElement) => pElement.isTypeOnly,
26
- )))
27
- );
27
+ return (
28
+ pStatement.importClause &&
29
+ (pStatement.importClause.isTypeOnly ||
30
+ (pStatement.importClause.namedBindings &&
31
+ pStatement.importClause.namedBindings.elements &&
32
+ pStatement.importClause.namedBindings.elements.every(
33
+ (pElement) => pElement.isTypeOnly,
34
+ )))
35
+ );
28
36
  }
29
37
 
30
38
  function isTypeOnlyExport(pStatement) {
31
- return (
32
- // for some reason the isTypeOnly indicator is on _statement_ level
33
- // and not in exportClause as it is in the importClause ¯\_(ツ)_/¯.
34
- // Also in the case of the omission of an alias the exportClause
35
- // is not there entirely. So regardless whether there is a
36
- // pStatement.exportClause or not, we can directly test for the
37
- // isTypeOnly attribute.
38
- pStatement.isTypeOnly ||
39
- // named reexports are per-element though
40
- (pStatement.exportClause &&
41
- pStatement.exportClause.elements &&
42
- pStatement.exportClause.elements.every((pElement) => pElement.isTypeOnly))
43
- );
39
+ return (
40
+ // for some reason the isTypeOnly indicator is on _statement_ level
41
+ // and not in exportClause as it is in the importClause ¯\_(ツ)_/¯.
42
+ // Also in the case of the omission of an alias the exportClause
43
+ // is not there entirely. So regardless whether there is a
44
+ // pStatement.exportClause or not, we can directly test for the
45
+ // isTypeOnly attribute.
46
+ pStatement.isTypeOnly ||
47
+ // named reexports are per-element though
48
+ (pStatement.exportClause &&
49
+ pStatement.exportClause.elements &&
50
+ pStatement.exportClause.elements.every((pElement) => pElement.isTypeOnly))
51
+ );
44
52
  }
45
53
 
46
54
  /*
@@ -57,20 +65,20 @@ function isTypeOnlyExport(pStatement) {
57
65
  * all import statements in the (top level) AST node
58
66
  */
59
67
  function extractImports(pAST) {
60
- return pAST.statements
61
- .filter(
62
- (pStatement) =>
63
- typescript.SyntaxKind[pStatement.kind] === "ImportDeclaration" &&
64
- pStatement.moduleSpecifier,
65
- )
66
- .map((pStatement) => ({
67
- module: pStatement.moduleSpecifier.text,
68
- moduleSystem: "es6",
69
- exoticallyRequired: false,
70
- ...(isTypeOnlyImport(pStatement)
71
- ? { dependencyTypes: ["type-only", "import"] }
72
- : { dependencyTypes: ["import"] }),
73
- }));
68
+ return pAST.statements
69
+ .filter(
70
+ (pStatement) =>
71
+ pStatement.kind === typescript.SyntaxKind.ImportDeclaration &&
72
+ pStatement.moduleSpecifier,
73
+ )
74
+ .map((pStatement) => ({
75
+ module: pStatement.moduleSpecifier.text,
76
+ moduleSystem: "es6",
77
+ exoticallyRequired: false,
78
+ ...(isTypeOnlyImport(pStatement)
79
+ ? { dependencyTypes: ["type-only", "import"] }
80
+ : { dependencyTypes: ["import"] }),
81
+ }));
74
82
  }
75
83
 
76
84
  /**
@@ -81,20 +89,20 @@ function extractImports(pAST) {
81
89
  * all export statements in the (top level) AST node
82
90
  */
83
91
  function extractExports(pAST) {
84
- return pAST.statements
85
- .filter(
86
- (pStatement) =>
87
- typescript.SyntaxKind[pStatement.kind] === "ExportDeclaration" &&
88
- pStatement.moduleSpecifier,
89
- )
90
- .map((pStatement) => ({
91
- module: pStatement.moduleSpecifier.text,
92
- moduleSystem: "es6",
93
- exoticallyRequired: false,
94
- ...(isTypeOnlyExport(pStatement)
95
- ? { dependencyTypes: ["type-only", "export"] }
96
- : { dependencyTypes: ["export"] }),
97
- }));
92
+ return pAST.statements
93
+ .filter(
94
+ (pStatement) =>
95
+ pStatement.kind === typescript.SyntaxKind.ExportDeclaration &&
96
+ pStatement.moduleSpecifier,
97
+ )
98
+ .map((pStatement) => ({
99
+ module: pStatement.moduleSpecifier.text,
100
+ moduleSystem: "es6",
101
+ exoticallyRequired: false,
102
+ ...(isTypeOnlyExport(pStatement)
103
+ ? { dependencyTypes: ["type-only", "export"] }
104
+ : { dependencyTypes: ["export"] }),
105
+ }));
98
106
  }
99
107
 
100
108
  /**
@@ -109,282 +117,361 @@ function extractExports(pAST) {
109
117
  * (top level) AST node
110
118
  */
111
119
  function extractImportEquals(pAST) {
112
- return pAST.statements
113
- .filter(
114
- (pStatement) =>
115
- typescript.SyntaxKind[pStatement.kind] === "ImportEqualsDeclaration" &&
116
- pStatement.moduleReference &&
117
- pStatement.moduleReference.expression &&
118
- pStatement.moduleReference.expression.text,
119
- )
120
- .map((pStatement) => ({
121
- module: pStatement.moduleReference.expression.text,
122
- moduleSystem: "cjs",
123
- exoticallyRequired: false,
124
- dependencyTypes: ["import-equals"],
125
- }));
120
+ return pAST.statements
121
+ .filter(
122
+ (pStatement) =>
123
+ pStatement.kind === typescript.SyntaxKind.ImportEqualsDeclaration &&
124
+ pStatement.moduleReference &&
125
+ pStatement.moduleReference.expression &&
126
+ pStatement.moduleReference.expression.text,
127
+ )
128
+ .map((pStatement) => ({
129
+ module: pStatement.moduleReference.expression.text,
130
+ moduleSystem: "cjs",
131
+ exoticallyRequired: false,
132
+ dependencyTypes: ["import-equals"],
133
+ }));
126
134
  }
127
135
 
128
136
  /**
129
- * might be wise to distinguish the three types of /// directive that
130
- * can come out of this as the resolution algorithm might differ
137
+ * Extracts /// directives e.g.
138
+ * /// <reference path="beep-tee-boop" />
131
139
  *
132
140
  * @param {Node} pAST - typescript syntax tree
133
141
  * @returns {{module: string, moduleSystem: string}[]} - 'tripple slash' dependencies
134
142
  */
135
143
  function extractTripleSlashDirectives(pAST) {
136
- return pAST.referencedFiles
137
- .map((pReference) => ({
138
- module: pReference.fileName,
139
- moduleSystem: "tsd",
140
- exoticallyRequired: false,
141
- dependencyTypes: [
142
- "triple-slash-directive",
143
- "triple-slash-file-reference",
144
- ],
145
- }))
146
- .concat(
147
- pAST.typeReferenceDirectives.map((pReference) => ({
148
- module: pReference.fileName,
149
- moduleSystem: "tsd",
150
- exoticallyRequired: false,
151
- dependencyTypes: [
152
- "triple-slash-directive",
153
- "triple-slash-type-reference",
154
- ],
155
- })),
156
- )
157
- .concat(
158
- pAST.amdDependencies.map((pReference) => ({
159
- module: pReference.path,
160
- moduleSystem: "tsd",
161
- exoticallyRequired: false,
162
- dependencyTypes: [
163
- "triple-slash-directive",
164
- "triple-slash-amd-dependency",
165
- ],
166
- })),
167
- );
144
+ return pAST.referencedFiles
145
+ .map((pReference) => ({
146
+ module: pReference.fileName,
147
+ moduleSystem: "tsd",
148
+ exoticallyRequired: false,
149
+ dependencyTypes: [
150
+ "triple-slash-directive",
151
+ "triple-slash-file-reference",
152
+ ],
153
+ }))
154
+ .concat(
155
+ pAST.typeReferenceDirectives.map((pReference) => ({
156
+ module: pReference.fileName,
157
+ moduleSystem: "tsd",
158
+ exoticallyRequired: false,
159
+ dependencyTypes: [
160
+ "triple-slash-directive",
161
+ "triple-slash-type-reference",
162
+ ],
163
+ })),
164
+ )
165
+ .concat(
166
+ pAST.amdDependencies.map((pReference) => ({
167
+ module: pReference.path,
168
+ moduleSystem: "tsd",
169
+ exoticallyRequired: false,
170
+ dependencyTypes: [
171
+ "triple-slash-directive",
172
+ "triple-slash-amd-dependency",
173
+ ],
174
+ })),
175
+ );
168
176
  }
169
177
 
170
178
  function firstArgumentIsAString(pASTNode) {
171
- const lFirstArgument = pASTNode.arguments[0];
172
-
173
- return (
174
- lFirstArgument &&
175
- // "thing" or 'thing'
176
- (typescript.SyntaxKind[lFirstArgument.kind] === "StringLiteral" ||
177
- // `thing`
178
- typescript.SyntaxKind[lFirstArgument.kind] === "FirstTemplateToken")
179
- );
179
+ const lFirstArgument = pASTNode.arguments[0];
180
+
181
+ return (
182
+ lFirstArgument &&
183
+ // "thing" or 'thing'
184
+ (lFirstArgument.kind === typescript.SyntaxKind.StringLiteral ||
185
+ // `thing`
186
+ lFirstArgument.kind === typescript.SyntaxKind.FirstTemplateToken)
187
+ );
180
188
  }
181
189
 
182
190
  function isRequireCallExpression(pASTNode) {
183
- if (
184
- typescript.SyntaxKind[pASTNode.kind] === "CallExpression" &&
185
- pASTNode.expression
186
- ) {
187
- /*
188
- * from typescript 5.0.0 the `originalKeywordKind` attribute is deprecated
189
- * and from 5.2.0 it will be gone. However, in typescript < 5.0.0 (still used
190
- * heavily IRL) it's the only way to get it - hence this test for the
191
- * existence of the * identifierToKeywordKind function to remain backwards
192
- * compatible
193
- */
194
- const lSyntaxKind = typescript.identifierToKeywordKind
195
- ? typescript.SyntaxKind[
196
- typescript.identifierToKeywordKind(pASTNode.expression)
197
- ]
198
- : /* c8 ignore next 1 */
199
- typescript.SyntaxKind[pASTNode.expression.originalKeywordKind];
200
- return lSyntaxKind === "RequireKeyword" && firstArgumentIsAString(pASTNode);
201
- }
202
- return false;
191
+ if (
192
+ pASTNode.kind === typescript.SyntaxKind.CallExpression &&
193
+ pASTNode.expression
194
+ ) {
195
+ /*
196
+ * from typescript 5.0.0 the `originalKeywordKind` attribute is deprecated
197
+ * and from 5.2.0 it will be gone. However, in typescript < 5.0.0 (still used
198
+ * heavily IRL) it's the only way to get it - hence this test for the
199
+ * existence of the * identifierToKeywordKind function
200
+ */
201
+ const lSyntaxKind = typescript.identifierToKeywordKind
202
+ ? typescript.SyntaxKind[
203
+ typescript.identifierToKeywordKind(pASTNode.expression)
204
+ ]
205
+ : /* c8 ignore next 1 */
206
+ typescript.SyntaxKind[pASTNode.expression.originalKeywordKind];
207
+ return lSyntaxKind === "RequireKeyword" && firstArgumentIsAString(pASTNode);
208
+ }
209
+ return false;
203
210
  }
204
211
 
205
212
  function isSingleExoticRequire(pASTNode, pString) {
206
- return (
207
- typescript.SyntaxKind[pASTNode.kind] === "CallExpression" &&
208
- pASTNode.expression &&
209
- pASTNode.expression.text === pString &&
210
- firstArgumentIsAString(pASTNode)
211
- );
213
+ return (
214
+ pASTNode.kind === typescript.SyntaxKind.CallExpression &&
215
+ pASTNode.expression &&
216
+ pASTNode.expression.text === pString &&
217
+ firstArgumentIsAString(pASTNode)
218
+ );
212
219
  }
213
220
 
214
221
  /* eslint complexity:0 */
215
222
  function isCompositeExoticRequire(pASTNode, pObjectName, pPropertyName) {
216
- return (
217
- typescript.SyntaxKind[pASTNode.kind] === "CallExpression" &&
218
- pASTNode.expression &&
219
- typescript.SyntaxKind[pASTNode.expression.kind] ===
220
- "PropertyAccessExpression" &&
221
- pASTNode.expression.expression &&
222
- typescript.SyntaxKind[pASTNode.expression.expression.kind] ===
223
- "Identifier" &&
224
- pASTNode.expression.expression.escapedText === pObjectName &&
225
- pASTNode.expression.name &&
226
- typescript.SyntaxKind[pASTNode.expression.name.kind] === "Identifier" &&
227
- pASTNode.expression.name.escapedText === pPropertyName &&
228
- firstArgumentIsAString(pASTNode)
229
- );
223
+ return (
224
+ pASTNode.kind === typescript.SyntaxKind.CallExpression &&
225
+ pASTNode.expression &&
226
+ pASTNode.expression.kind ===
227
+ typescript.SyntaxKind.PropertyAccessExpression &&
228
+ pASTNode.expression.expression &&
229
+ pASTNode.expression.expression.kind === typescript.SyntaxKind.Identifier &&
230
+ pASTNode.expression.expression.escapedText === pObjectName &&
231
+ pASTNode.expression.name &&
232
+ pASTNode.expression.name.kind === typescript.SyntaxKind.Identifier &&
233
+ pASTNode.expression.name.escapedText === pPropertyName &&
234
+ firstArgumentIsAString(pASTNode)
235
+ );
230
236
  }
231
237
 
232
238
  function isTripleCursedCompositeExoticRequire(
233
- pASTNode,
234
- pObjectName1,
235
- pObjectName2,
236
- pPropertyName,
239
+ pASTNode,
240
+ pObjectName1,
241
+ pObjectName2,
242
+ pPropertyName,
237
243
  ) {
238
- return (
239
- typescript.SyntaxKind[pASTNode.kind] === "CallExpression" &&
240
- pASTNode.expression &&
241
- typescript.SyntaxKind[pASTNode.expression.kind] ===
242
- "PropertyAccessExpression" &&
243
- pASTNode.expression.expression &&
244
- typescript.SyntaxKind[pASTNode.expression.expression.kind] ===
245
- "PropertyAccessExpression" &&
246
- // globalThis
247
- pASTNode.expression.expression.expression &&
248
- typescript.SyntaxKind[pASTNode.expression.expression.expression.kind] ===
249
- "Identifier" &&
250
- pASTNode.expression.expression.expression.escapedText === pObjectName1 &&
251
- // process
252
- typescript.SyntaxKind[pASTNode.expression.expression.name.kind] ===
253
- "Identifier" &&
254
- pASTNode.expression.expression.name.escapedText === pObjectName2 &&
255
- // getBuiltinModule
256
- pASTNode.expression.name &&
257
- typescript.SyntaxKind[pASTNode.expression.name.kind] === "Identifier" &&
258
- pASTNode.expression.name.escapedText === pPropertyName &&
259
- firstArgumentIsAString(pASTNode)
260
- );
244
+ return (
245
+ pASTNode.kind === typescript.SyntaxKind.CallExpression &&
246
+ pASTNode.expression &&
247
+ pASTNode.expression.kind ===
248
+ typescript.SyntaxKind.PropertyAccessExpression &&
249
+ pASTNode.expression.expression &&
250
+ pASTNode.expression.expression.kind ===
251
+ typescript.SyntaxKind.PropertyAccessExpression &&
252
+ // globalThis
253
+ pASTNode.expression.expression.expression &&
254
+ pASTNode.expression.expression.expression.kind ===
255
+ typescript.SyntaxKind.Identifier &&
256
+ pASTNode.expression.expression.expression.escapedText === pObjectName1 &&
257
+ // process
258
+ pASTNode.expression.expression.name.kind ===
259
+ typescript.SyntaxKind.Identifier &&
260
+ pASTNode.expression.expression.name.escapedText === pObjectName2 &&
261
+ // getBuiltinModule
262
+ pASTNode.expression.name &&
263
+ pASTNode.expression.name.kind === typescript.SyntaxKind.Identifier &&
264
+ pASTNode.expression.name.escapedText === pPropertyName &&
265
+ firstArgumentIsAString(pASTNode)
266
+ );
261
267
  }
262
268
 
263
269
  function isExoticRequire(pASTNode, pString) {
264
- const lRequireStringElements = pString.split(".");
270
+ const lRequireStringElements = pString.split(".");
265
271
 
266
- return lRequireStringElements.length > 1
267
- ? isCompositeExoticRequire(pASTNode, ...lRequireStringElements)
268
- : isSingleExoticRequire(pASTNode, pString);
272
+ return lRequireStringElements.length > 1
273
+ ? isCompositeExoticRequire(pASTNode, ...lRequireStringElements)
274
+ : isSingleExoticRequire(pASTNode, pString);
269
275
  }
270
276
 
271
277
  function isDynamicImportExpression(pASTNode) {
272
- return (
273
- typescript.SyntaxKind[pASTNode.kind] === "CallExpression" &&
274
- pASTNode.expression &&
275
- typescript.SyntaxKind[pASTNode.expression.kind] === "ImportKeyword" &&
276
- firstArgumentIsAString(pASTNode)
277
- );
278
+ return (
279
+ pASTNode.kind === typescript.SyntaxKind.CallExpression &&
280
+ pASTNode.expression &&
281
+ pASTNode.expression.kind === typescript.SyntaxKind.ImportKeyword &&
282
+ firstArgumentIsAString(pASTNode)
283
+ );
278
284
  }
279
285
 
280
286
  function isTypeImport(pASTNode) {
281
- return (
282
- typescript.SyntaxKind[pASTNode.kind] === "LastTypeNode" &&
283
- pASTNode.argument &&
284
- typescript.SyntaxKind[pASTNode.argument.kind] === "LiteralType" &&
285
- ((pASTNode.argument.literal &&
286
- typescript.SyntaxKind[pASTNode.argument.literal.kind] ===
287
- "StringLiteral") ||
288
- typescript.SyntaxKind[pASTNode.argument.literal.kind] ===
289
- "FirstTemplateToken")
290
- );
287
+ return (
288
+ pASTNode.kind === typescript.SyntaxKind.LastTypeNode &&
289
+ pASTNode.argument &&
290
+ pASTNode.argument.kind === typescript.SyntaxKind.LiteralType &&
291
+ ((pASTNode.argument.literal &&
292
+ pASTNode.argument.literal.kind === typescript.SyntaxKind.StringLiteral) ||
293
+ pASTNode.argument.literal.kind ===
294
+ typescript.SyntaxKind.FirstTemplateToken)
295
+ );
291
296
  }
292
297
 
293
298
  function extractJSDocImportTags(pJSDocTags) {
294
- return pJSDocTags
295
- .filter(
296
- (pTag) =>
297
- pTag.tagName.escapedText === "import" &&
298
- pTag.moduleSpecifier &&
299
- typescript.SyntaxKind[pTag.moduleSpecifier.kind] === "StringLiteral" &&
300
- pTag.moduleSpecifier.text,
301
- )
302
- .map((pTag) => ({
303
- module: pTag.moduleSpecifier.text,
304
- moduleSystem: "es6",
305
- exoticallyRequired: false,
306
- dependencyTypes: ["type-only", "import", "jsdoc", "jsdoc-import-tag"],
307
- }));
299
+ return pJSDocTags
300
+ .filter(
301
+ (pTag) =>
302
+ pTag.tagName.escapedText === "import" &&
303
+ pTag.moduleSpecifier &&
304
+ pTag.moduleSpecifier.kind === typescript.SyntaxKind.StringLiteral &&
305
+ pTag.moduleSpecifier.text,
306
+ )
307
+ .map((pTag) => ({
308
+ module: pTag.moduleSpecifier.text,
309
+ moduleSystem: "es6",
310
+ exoticallyRequired: false,
311
+ dependencyTypes: ["type-only", "import", "jsdoc", "jsdoc-import-tag"],
312
+ }));
308
313
  }
309
314
 
310
315
  function isJSDocImport(pTypeNode) {
311
- // import('./hello.mjs') within jsdoc
312
- return (
313
- typescript.SyntaxKind[pTypeNode?.kind] === "LastTypeNode" &&
314
- typescript.SyntaxKind[pTypeNode.argument?.kind] === "LiteralType" &&
315
- typescript.SyntaxKind[pTypeNode.argument?.literal?.kind] ===
316
- "StringLiteral" &&
317
- pTypeNode.argument.literal.text
318
- );
316
+ // import('./hello.mjs') within jsdoc
317
+ return (
318
+ pTypeNode?.kind === typescript.SyntaxKind.LastTypeNode &&
319
+ pTypeNode.argument?.kind === typescript.SyntaxKind.LiteralType &&
320
+ pTypeNode.argument?.literal?.kind === typescript.SyntaxKind.StringLiteral &&
321
+ pTypeNode.argument.literal.text
322
+ );
319
323
  }
320
324
 
321
- function keyInJSDocIsIgnorable(pKey) {
322
- return [
323
- "parent",
324
- "pos",
325
- "end",
326
- "flags",
327
- "emitNode",
328
- "modifierFlagsCache",
329
- "transformFlags",
330
- "id",
331
- "flowNode",
332
- "symbol",
333
- "original",
334
- ].includes(pKey);
335
- }
325
+ const IGNORABLE_JSDOC_KEYS = new Set([
326
+ "parent",
327
+ "pos",
328
+ "end",
329
+ "flags",
330
+ "emitNode",
331
+ "modifierFlagsCache",
332
+ "transformFlags",
333
+ "id",
334
+ "flowNode",
335
+ "symbol",
336
+ "original",
337
+ ]);
336
338
 
337
339
  export function walkJSDoc(pObject, pCollection = new Set()) {
338
- if (isJSDocImport(pObject)) {
339
- pCollection.add(pObject.argument.literal.text);
340
- } else if (Array.isArray(pObject)) {
341
- for (const lValue of pObject) {
342
- walkJSDoc(lValue, pCollection);
343
- }
344
- } else if (typeof pObject === "object") {
345
- for (const lKey in pObject) {
346
- if (!keyInJSDocIsIgnorable(lKey) && pObject[lKey]) {
347
- walkJSDoc(pObject[lKey], pCollection);
348
- }
349
- }
350
- }
340
+ if (isJSDocImport(pObject)) {
341
+ pCollection.add(pObject.argument.literal.text);
342
+ } else if (Array.isArray(pObject)) {
343
+ for (const lValue of pObject) {
344
+ walkJSDoc(lValue, pCollection);
345
+ }
346
+ } else if (typeof pObject === "object") {
347
+ for (const lKey in pObject) {
348
+ if (!IGNORABLE_JSDOC_KEYS.has(lKey) && pObject[lKey]) {
349
+ walkJSDoc(pObject[lKey], pCollection);
350
+ }
351
+ }
352
+ }
351
353
  }
352
354
 
353
355
  export function getJSDocImports(pTagNode) {
354
- const lCollection = new Set();
355
- walkJSDoc(pTagNode, lCollection);
356
- return Array.from(lCollection);
356
+ const lCollection = new Set();
357
+ walkJSDoc(pTagNode, lCollection);
358
+ return Array.from(lCollection);
357
359
  }
358
360
 
359
361
  function extractJSDocBracketImports(pJSDocTags) {
360
- // https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html
361
- return pJSDocTags
362
- .filter(
363
- (pTag) =>
364
- pTag.tagName.escapedText !== "import" &&
365
- typescript.SyntaxKind[pTag.typeExpression?.kind] === "FirstJSDocNode",
366
- )
367
- .flatMap((pTag) => getJSDocImports(pTag))
368
- .map((pImportName) => ({
369
- module: pImportName,
370
- moduleSystem: "es6",
371
- exoticallyRequired: false,
372
- dependencyTypes: ["type-only", "import", "jsdoc", "jsdoc-bracket-import"],
373
- }));
362
+ // https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html
363
+ return pJSDocTags
364
+ .filter(
365
+ (pTag) =>
366
+ pTag.tagName.escapedText !== "import" &&
367
+ pTag.typeExpression?.kind === typescript.SyntaxKind.FirstJSDocNode,
368
+ )
369
+ .flatMap((pTag) => getJSDocImports(pTag))
370
+ .map((pImportName) => ({
371
+ module: pImportName,
372
+ moduleSystem: "es6",
373
+ exoticallyRequired: false,
374
+ dependencyTypes: ["type-only", "import", "jsdoc", "jsdoc-bracket-import"],
375
+ }));
374
376
  }
375
377
 
376
378
  function extractJSDocImports(pJSDocNodes) {
377
- // https://devblogs.microsoft.com/typescript/announcing-typescript-5-5/#the-jsdoc-import-tag
378
- const lJSDocNodesWithTags = pJSDocNodes.filter(
379
- (pJSDocLine) => pJSDocLine.tags,
380
- );
381
- const lJSDocImportTags = lJSDocNodesWithTags.flatMap((pJSDocLine) =>
382
- extractJSDocImportTags(pJSDocLine.tags),
383
- );
384
- const lJSDocBracketImports = lJSDocNodesWithTags.flatMap((pJSDocLine) =>
385
- extractJSDocBracketImports(pJSDocLine.tags),
386
- );
387
- return lJSDocImportTags.concat(lJSDocBracketImports);
379
+ // https://devblogs.microsoft.com/typescript/announcing-typescript-5-5/#the-jsdoc-import-tag
380
+ const lJSDocNodesWithTags = pJSDocNodes.filter(
381
+ (pJSDocLine) => pJSDocLine.tags,
382
+ );
383
+ const lJSDocImportTags = lJSDocNodesWithTags.flatMap((pJSDocLine) =>
384
+ extractJSDocImportTags(pJSDocLine.tags),
385
+ );
386
+ const lJSDocBracketImports = lJSDocNodesWithTags.flatMap((pJSDocLine) =>
387
+ extractJSDocBracketImports(pJSDocLine.tags),
388
+ );
389
+ return lJSDocImportTags.concat(lJSDocBracketImports);
390
+ }
391
+
392
+ // eslint-disable-next-line max-lines-per-function
393
+ function visitNode(
394
+ pResult,
395
+ pASTNode,
396
+ pExoticRequireStrings,
397
+ pDetectProcessBuiltinModuleCalls,
398
+ ) {
399
+ // checks are in order of ~expected frequency
400
+
401
+ // early returns as these types of dependencyTypes cannot occur at the same
402
+ // time in a single AST node
403
+ // require('a-string'), require(`a-template-literal`)
404
+ if (isRequireCallExpression(pASTNode)) {
405
+ pResult.push({
406
+ module: pASTNode.arguments[0].text,
407
+ moduleSystem: "cjs",
408
+ exoticallyRequired: false,
409
+ dependencyTypes: ["require"],
410
+ });
411
+ return;
412
+ }
413
+
414
+ // import('a-string'), import(`a-template-literal`)
415
+ if (isDynamicImportExpression(pASTNode)) {
416
+ pResult.push({
417
+ module: pASTNode.arguments[0].text,
418
+ moduleSystem: "es6",
419
+ dynamic: true,
420
+ exoticallyRequired: false,
421
+ dependencyTypes: ["dynamic-import"],
422
+ });
423
+ return;
424
+ }
425
+
426
+ // const atype: import('./types').T
427
+ // const atype: import(`./types`).T
428
+ if (isTypeImport(pASTNode)) {
429
+ pResult.push({
430
+ module: pASTNode.argument.literal.text,
431
+ moduleSystem: "es6",
432
+ exoticallyRequired: false,
433
+ dependencyTypes: ["type-import"],
434
+ });
435
+ return;
436
+ }
437
+
438
+ // const want = require; {lalala} = want('yudelyo'), window.require('elektron')
439
+ // strictly speaking checking whether kind is CallExpression is not necessary as
440
+ // the functions inside the loop will do that as well. However, it saves quite a
441
+ // of computation when the list of exotic require strings is not empty
442
+ if (pASTNode.kind === typescript.SyntaxKind.CallExpression) {
443
+ for (const lExoticRequireString of pExoticRequireStrings) {
444
+ if (isExoticRequire(pASTNode, lExoticRequireString)) {
445
+ pResult.push({
446
+ module: pASTNode.arguments[0].text,
447
+ moduleSystem: "cjs",
448
+ exoticallyRequired: true,
449
+ exoticRequire: lExoticRequireString,
450
+ dependencyTypes: ["exotic-require"],
451
+ });
452
+ return;
453
+ }
454
+ }
455
+ }
456
+
457
+ // const path = process.getBuiltinModule('node:path'); const fs = globalThis.process.getBuiltinModule(`node:fs`);
458
+ if (
459
+ pDetectProcessBuiltinModuleCalls &&
460
+ (isCompositeExoticRequire(pASTNode, "process", "getBuiltinModule") ||
461
+ isTripleCursedCompositeExoticRequire(
462
+ pASTNode,
463
+ "globalThis",
464
+ "process",
465
+ "getBuiltinModule",
466
+ ))
467
+ ) {
468
+ pResult.push({
469
+ module: pASTNode.arguments[0].text,
470
+ moduleSystem: "cjs",
471
+ exoticallyRequired: false,
472
+ dependencyTypes: ["process-get-builtin-module"],
473
+ });
474
+ }
388
475
  }
389
476
 
390
477
  /**
@@ -395,100 +482,44 @@ function extractJSDocImports(pJSDocNodes) {
395
482
  * @param {boolean} pDetectJSDocImports - whether to detect jsdoc imports
396
483
  * @returns {(pASTNode: Node) => void} - the walker function
397
484
  */
398
- // eslint-disable-next-line max-lines-per-function
399
485
  function walk(
400
- pResult,
401
- pExoticRequireStrings,
402
- pDetectJSDocImports,
403
- pDetectProcessBuiltinModuleCalls,
486
+ pResult,
487
+ pExoticRequireStrings,
488
+ pDetectJSDocImports,
489
+ pDetectProcessBuiltinModuleCalls,
404
490
  ) {
405
- // eslint-disable-next-line max-lines-per-function
406
- return (pASTNode) => {
407
- // require('a-string'), require(`a-template-literal`)
408
- if (isRequireCallExpression(pASTNode)) {
409
- pResult.push({
410
- module: pASTNode.arguments[0].text,
411
- moduleSystem: "cjs",
412
- exoticallyRequired: false,
413
- dependencyTypes: ["require"],
414
- });
415
- }
416
-
417
- // const want = require; {lalala} = want('yudelyo'), window.require('elektron')
418
- for (const lExoticRequireString of pExoticRequireStrings) {
419
- if (isExoticRequire(pASTNode, lExoticRequireString)) {
420
- pResult.push({
421
- module: pASTNode.arguments[0].text,
422
- moduleSystem: "cjs",
423
- exoticallyRequired: true,
424
- exoticRequire: lExoticRequireString,
425
- dependencyTypes: ["exotic-require"],
426
- });
427
- }
428
- }
429
-
430
- // const path = process.getBuiltinModule('node:path'); const fs = globalThis.process.getBuiltinModule(`node:fs`);
431
- if (
432
- pDetectProcessBuiltinModuleCalls &&
433
- (isCompositeExoticRequire(pASTNode, "process", "getBuiltinModule") ||
434
- isTripleCursedCompositeExoticRequire(
435
- pASTNode,
436
- "globalThis",
437
- "process",
438
- "getBuiltinModule",
439
- ))
440
- ) {
441
- pResult.push({
442
- module: pASTNode.arguments[0].text,
443
- moduleSystem: "cjs",
444
- exoticallyRequired: false,
445
- dependencyTypes: ["process-get-builtin-module"],
446
- });
447
- }
448
-
449
- // import('a-string'), import(`a-template-literal`)
450
- if (isDynamicImportExpression(pASTNode)) {
451
- pResult.push({
452
- module: pASTNode.arguments[0].text,
453
- moduleSystem: "es6",
454
- dynamic: true,
455
- exoticallyRequired: false,
456
- dependencyTypes: ["dynamic-import"],
457
- });
458
- }
459
-
460
- // const atype: import('./types').T
461
- // const atype: import(`./types`).T
462
- if (isTypeImport(pASTNode)) {
463
- pResult.push({
464
- module: pASTNode.argument.literal.text,
465
- moduleSystem: "es6",
466
- exoticallyRequired: false,
467
- dependencyTypes: ["type-import"],
468
- });
469
- }
470
-
471
- // /** @import thing from './module' */ etc
472
- // /** @type {import('module').thing}*/ etc
473
- if (pDetectJSDocImports && pASTNode.jsDoc) {
474
- const lJSDocImports = extractJSDocImports(pASTNode.jsDoc);
475
-
476
- // pResult = pResult.concat(lJSDocImports) looks like the more obvious
477
- // way to do this, but it re-assigns the pResult parameter
478
- for (const lImport of lJSDocImports) {
479
- pResult.push(lImport);
480
- }
481
- }
482
- typescript.forEachChild(
483
- pASTNode,
484
- walk(
485
- pResult,
486
- pExoticRequireStrings,
487
- pDetectJSDocImports,
488
- pDetectProcessBuiltinModuleCalls,
489
- ),
490
- );
491
- };
491
+ return (pASTNode) => {
492
+ // /** @import thing from './module' */ etc
493
+ // /** @type {import('module').thing}*/ etc
494
+ if (pDetectJSDocImports && pASTNode.jsDoc) {
495
+ const lJSDocImports = extractJSDocImports(pASTNode.jsDoc);
496
+
497
+ // pResult = pResult.concat(lJSDocImports) looks like the more obvious
498
+ // way to do this, but it re-assigns the pResult parameter
499
+ for (const lImport of lJSDocImports) {
500
+ pResult.push(lImport);
501
+ }
502
+ }
503
+
504
+ if (INTERESTING_NODE_KINDS.has(pASTNode.kind)) {
505
+ visitNode(
506
+ pResult,
507
+ pASTNode,
508
+ pExoticRequireStrings,
509
+ pDetectProcessBuiltinModuleCalls,
510
+ );
511
+ }
512
+
513
+ typescript.forEachChild(
514
+ pASTNode,
515
+ walk(
516
+ pResult,
517
+ pExoticRequireStrings,
518
+ pDetectJSDocImports,
519
+ pDetectProcessBuiltinModuleCalls,
520
+ ),
521
+ );
522
+ };
492
523
  }
493
524
 
494
525
  /**
@@ -501,21 +532,21 @@ function walk(
501
532
  * @returns {{module: string, moduleSystem: string}[]} - all commonJS dependencies
502
533
  */
503
534
  function extractNestedDependencies(
504
- pAST,
505
- pExoticRequireStrings,
506
- pDetectJSDocImports,
507
- pDetectProcessBuiltinModuleCalls,
535
+ pAST,
536
+ pExoticRequireStrings,
537
+ pDetectJSDocImports,
538
+ pDetectProcessBuiltinModuleCalls,
508
539
  ) {
509
- let lResult = [];
540
+ let lResult = [];
510
541
 
511
- walk(
512
- lResult,
513
- pExoticRequireStrings,
514
- pDetectJSDocImports,
515
- pDetectProcessBuiltinModuleCalls,
516
- )(pAST);
542
+ walk(
543
+ lResult,
544
+ pExoticRequireStrings,
545
+ pDetectJSDocImports,
546
+ pDetectProcessBuiltinModuleCalls,
547
+ )(pAST);
517
548
 
518
- return lResult;
549
+ return lResult;
519
550
  }
520
551
 
521
552
  /**
@@ -524,25 +555,25 @@ function extractNestedDependencies(
524
555
  * @type {(pTypeScriptAST: (Node), pExoticRequireStrings: string[], pDetectJSDocImports: boolean) => {module: string, moduleSystem: string, dynamic: boolean}[]}
525
556
  */
526
557
  export default function extractTypeScriptDependencies(
527
- pTypeScriptAST,
528
- pExoticRequireStrings,
529
- pDetectJSDocImports,
530
- pDetectProcessBuiltinModuleCalls,
558
+ pTypeScriptAST,
559
+ pExoticRequireStrings,
560
+ pDetectJSDocImports,
561
+ pDetectProcessBuiltinModuleCalls,
531
562
  ) {
532
- // console.dir(pTypeScriptAST, { depth: 100 });
533
- return typescript
534
- ? extractImports(pTypeScriptAST)
535
- .concat(extractExports(pTypeScriptAST))
536
- .concat(extractImportEquals(pTypeScriptAST))
537
- .concat(extractTripleSlashDirectives(pTypeScriptAST))
538
- .concat(
539
- extractNestedDependencies(
540
- pTypeScriptAST,
541
- pExoticRequireStrings,
542
- pDetectJSDocImports,
543
- pDetectProcessBuiltinModuleCalls,
544
- ),
545
- )
546
- .map((pModule) => ({ dynamic: false, ...pModule }))
547
- : /* c8 ignore next */ [];
563
+ // console.dir(pTypeScriptAST, { depth: 100 });
564
+ return typescript
565
+ ? extractImports(pTypeScriptAST)
566
+ .concat(extractExports(pTypeScriptAST))
567
+ .concat(extractImportEquals(pTypeScriptAST))
568
+ .concat(extractTripleSlashDirectives(pTypeScriptAST))
569
+ .concat(
570
+ extractNestedDependencies(
571
+ pTypeScriptAST,
572
+ pExoticRequireStrings,
573
+ pDetectJSDocImports,
574
+ pDetectProcessBuiltinModuleCalls,
575
+ ),
576
+ )
577
+ .map((pModule) => ({ dynamic: false, ...pModule }))
578
+ : /* c8 ignore next */ [];
548
579
  }