dependency-cruiser 17.3.2 → 17.3.3-beta-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/extract/tsc/extract-typescript-deps.mjs +110 -99
- package/src/meta.cjs +1 -1
package/package.json
CHANGED
|
@@ -15,6 +15,14 @@ const typescript = await tryImport(
|
|
|
15
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
27
|
return (
|
|
20
28
|
pStatement.importClause &&
|
|
@@ -60,7 +68,7 @@ function extractImports(pAST) {
|
|
|
60
68
|
return pAST.statements
|
|
61
69
|
.filter(
|
|
62
70
|
(pStatement) =>
|
|
63
|
-
|
|
71
|
+
pStatement.kind === typescript.SyntaxKind.ImportDeclaration &&
|
|
64
72
|
pStatement.moduleSpecifier,
|
|
65
73
|
)
|
|
66
74
|
.map((pStatement) => ({
|
|
@@ -84,7 +92,7 @@ function extractExports(pAST) {
|
|
|
84
92
|
return pAST.statements
|
|
85
93
|
.filter(
|
|
86
94
|
(pStatement) =>
|
|
87
|
-
|
|
95
|
+
pStatement.kind === typescript.SyntaxKind.ExportDeclaration &&
|
|
88
96
|
pStatement.moduleSpecifier,
|
|
89
97
|
)
|
|
90
98
|
.map((pStatement) => ({
|
|
@@ -112,7 +120,7 @@ function extractImportEquals(pAST) {
|
|
|
112
120
|
return pAST.statements
|
|
113
121
|
.filter(
|
|
114
122
|
(pStatement) =>
|
|
115
|
-
|
|
123
|
+
pStatement.kind === typescript.SyntaxKind.ImportEqualsDeclaration &&
|
|
116
124
|
pStatement.moduleReference &&
|
|
117
125
|
pStatement.moduleReference.expression &&
|
|
118
126
|
pStatement.moduleReference.expression.text,
|
|
@@ -173,15 +181,15 @@ function firstArgumentIsAString(pASTNode) {
|
|
|
173
181
|
return (
|
|
174
182
|
lFirstArgument &&
|
|
175
183
|
// "thing" or 'thing'
|
|
176
|
-
(
|
|
184
|
+
(lFirstArgument.kind === typescript.SyntaxKind.StringLiteral ||
|
|
177
185
|
// `thing`
|
|
178
|
-
|
|
186
|
+
lFirstArgument.kind === typescript.SyntaxKind.FirstTemplateToken)
|
|
179
187
|
);
|
|
180
188
|
}
|
|
181
189
|
|
|
182
190
|
function isRequireCallExpression(pASTNode) {
|
|
183
191
|
if (
|
|
184
|
-
|
|
192
|
+
pASTNode.kind === typescript.SyntaxKind.CallExpression &&
|
|
185
193
|
pASTNode.expression
|
|
186
194
|
) {
|
|
187
195
|
/*
|
|
@@ -204,7 +212,7 @@ function isRequireCallExpression(pASTNode) {
|
|
|
204
212
|
|
|
205
213
|
function isSingleExoticRequire(pASTNode, pString) {
|
|
206
214
|
return (
|
|
207
|
-
|
|
215
|
+
pASTNode.kind === typescript.SyntaxKind.CallExpression &&
|
|
208
216
|
pASTNode.expression &&
|
|
209
217
|
pASTNode.expression.text === pString &&
|
|
210
218
|
firstArgumentIsAString(pASTNode)
|
|
@@ -214,16 +222,15 @@ function isSingleExoticRequire(pASTNode, pString) {
|
|
|
214
222
|
/* eslint complexity:0 */
|
|
215
223
|
function isCompositeExoticRequire(pASTNode, pObjectName, pPropertyName) {
|
|
216
224
|
return (
|
|
217
|
-
|
|
225
|
+
pASTNode.kind === typescript.SyntaxKind.CallExpression &&
|
|
218
226
|
pASTNode.expression &&
|
|
219
|
-
|
|
220
|
-
|
|
227
|
+
pASTNode.expression.kind ===
|
|
228
|
+
typescript.SyntaxKind.PropertyAccessExpression &&
|
|
221
229
|
pASTNode.expression.expression &&
|
|
222
|
-
|
|
223
|
-
"Identifier" &&
|
|
230
|
+
pASTNode.expression.expression.kind === typescript.SyntaxKind.Identifier &&
|
|
224
231
|
pASTNode.expression.expression.escapedText === pObjectName &&
|
|
225
232
|
pASTNode.expression.name &&
|
|
226
|
-
|
|
233
|
+
pASTNode.expression.name.kind === typescript.SyntaxKind.Identifier &&
|
|
227
234
|
pASTNode.expression.name.escapedText === pPropertyName &&
|
|
228
235
|
firstArgumentIsAString(pASTNode)
|
|
229
236
|
);
|
|
@@ -236,25 +243,25 @@ function isTripleCursedCompositeExoticRequire(
|
|
|
236
243
|
pPropertyName,
|
|
237
244
|
) {
|
|
238
245
|
return (
|
|
239
|
-
|
|
246
|
+
pASTNode.kind === typescript.SyntaxKind.CallExpression &&
|
|
240
247
|
pASTNode.expression &&
|
|
241
|
-
|
|
242
|
-
|
|
248
|
+
pASTNode.expression.kind ===
|
|
249
|
+
typescript.SyntaxKind.PropertyAccessExpression &&
|
|
243
250
|
pASTNode.expression.expression &&
|
|
244
|
-
|
|
245
|
-
|
|
251
|
+
pASTNode.expression.expression.kind ===
|
|
252
|
+
typescript.SyntaxKind.PropertyAccessExpression &&
|
|
246
253
|
// globalThis
|
|
247
254
|
pASTNode.expression.expression.expression &&
|
|
248
|
-
|
|
249
|
-
|
|
255
|
+
pASTNode.expression.expression.expression.kind ===
|
|
256
|
+
typescript.SyntaxKind.Identifier &&
|
|
250
257
|
pASTNode.expression.expression.expression.escapedText === pObjectName1 &&
|
|
251
258
|
// process
|
|
252
|
-
|
|
253
|
-
|
|
259
|
+
pASTNode.expression.expression.name.kind ===
|
|
260
|
+
typescript.SyntaxKind.Identifier &&
|
|
254
261
|
pASTNode.expression.expression.name.escapedText === pObjectName2 &&
|
|
255
262
|
// getBuiltinModule
|
|
256
263
|
pASTNode.expression.name &&
|
|
257
|
-
|
|
264
|
+
pASTNode.expression.name.kind === typescript.SyntaxKind.Identifier &&
|
|
258
265
|
pASTNode.expression.name.escapedText === pPropertyName &&
|
|
259
266
|
firstArgumentIsAString(pASTNode)
|
|
260
267
|
);
|
|
@@ -270,23 +277,22 @@ function isExoticRequire(pASTNode, pString) {
|
|
|
270
277
|
|
|
271
278
|
function isDynamicImportExpression(pASTNode) {
|
|
272
279
|
return (
|
|
273
|
-
|
|
280
|
+
pASTNode.kind === typescript.SyntaxKind.CallExpression &&
|
|
274
281
|
pASTNode.expression &&
|
|
275
|
-
|
|
282
|
+
pASTNode.expression.kind === typescript.SyntaxKind.ImportKeyword &&
|
|
276
283
|
firstArgumentIsAString(pASTNode)
|
|
277
284
|
);
|
|
278
285
|
}
|
|
279
286
|
|
|
280
287
|
function isTypeImport(pASTNode) {
|
|
281
288
|
return (
|
|
282
|
-
|
|
289
|
+
pASTNode.kind === typescript.SyntaxKind.LastTypeNode &&
|
|
283
290
|
pASTNode.argument &&
|
|
284
|
-
|
|
291
|
+
pASTNode.argument.kind === typescript.SyntaxKind.LiteralType &&
|
|
285
292
|
((pASTNode.argument.literal &&
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
"FirstTemplateToken")
|
|
293
|
+
pASTNode.argument.literal.kind === typescript.SyntaxKind.StringLiteral) ||
|
|
294
|
+
pASTNode.argument.literal.kind ===
|
|
295
|
+
typescript.SyntaxKind.FirstTemplateToken)
|
|
290
296
|
);
|
|
291
297
|
}
|
|
292
298
|
|
|
@@ -296,7 +302,7 @@ function extractJSDocImportTags(pJSDocTags) {
|
|
|
296
302
|
(pTag) =>
|
|
297
303
|
pTag.tagName.escapedText === "import" &&
|
|
298
304
|
pTag.moduleSpecifier &&
|
|
299
|
-
|
|
305
|
+
pTag.moduleSpecifier.kind === typescript.SyntaxKind.StringLiteral &&
|
|
300
306
|
pTag.moduleSpecifier.text,
|
|
301
307
|
)
|
|
302
308
|
.map((pTag) => ({
|
|
@@ -310,10 +316,9 @@ function extractJSDocImportTags(pJSDocTags) {
|
|
|
310
316
|
function isJSDocImport(pTypeNode) {
|
|
311
317
|
// import('./hello.mjs') within jsdoc
|
|
312
318
|
return (
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
"StringLiteral" &&
|
|
319
|
+
pTypeNode?.kind === typescript.SyntaxKind.LastTypeNode &&
|
|
320
|
+
pTypeNode.argument?.kind === typescript.SyntaxKind.LiteralType &&
|
|
321
|
+
pTypeNode.argument?.literal?.kind === typescript.SyntaxKind.StringLiteral &&
|
|
317
322
|
pTypeNode.argument.literal.text
|
|
318
323
|
);
|
|
319
324
|
}
|
|
@@ -362,7 +367,7 @@ function extractJSDocBracketImports(pJSDocTags) {
|
|
|
362
367
|
.filter(
|
|
363
368
|
(pTag) =>
|
|
364
369
|
pTag.tagName.escapedText !== "import" &&
|
|
365
|
-
|
|
370
|
+
pTag.typeExpression?.kind === typescript.SyntaxKind.FirstJSDocNode,
|
|
366
371
|
)
|
|
367
372
|
.flatMap((pTag) => getJSDocImports(pTag))
|
|
368
373
|
.map((pImportName) => ({
|
|
@@ -404,81 +409,87 @@ function walk(
|
|
|
404
409
|
) {
|
|
405
410
|
// eslint-disable-next-line max-lines-per-function
|
|
406
411
|
return (pASTNode) => {
|
|
407
|
-
//
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
412
|
+
// /** @import thing from './module' */ etc
|
|
413
|
+
// /** @type {import('module').thing}*/ etc
|
|
414
|
+
if (pDetectJSDocImports && pASTNode.jsDoc) {
|
|
415
|
+
const lJSDocImports = extractJSDocImports(pASTNode.jsDoc);
|
|
416
|
+
|
|
417
|
+
// pResult = pResult.concat(lJSDocImports) looks like the more obvious
|
|
418
|
+
// way to do this, but it re-assigns the pResult parameter
|
|
419
|
+
for (const lImport of lJSDocImports) {
|
|
420
|
+
pResult.push(lImport);
|
|
421
|
+
}
|
|
415
422
|
}
|
|
416
423
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
if (
|
|
424
|
+
if (INTERESTING_NODE_KINDS.has(pASTNode.kind)) {
|
|
425
|
+
// require('a-string'), require(`a-template-literal`)
|
|
426
|
+
if (isRequireCallExpression(pASTNode)) {
|
|
420
427
|
pResult.push({
|
|
421
428
|
module: pASTNode.arguments[0].text,
|
|
422
429
|
moduleSystem: "cjs",
|
|
423
|
-
exoticallyRequired:
|
|
424
|
-
|
|
425
|
-
dependencyTypes: ["exotic-require"],
|
|
430
|
+
exoticallyRequired: false,
|
|
431
|
+
dependencyTypes: ["require"],
|
|
426
432
|
});
|
|
427
433
|
}
|
|
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
434
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
435
|
+
// const want = require; {lalala} = want('yudelyo'), window.require('elektron')
|
|
436
|
+
if (pASTNode.kind === typescript.SyntaxKind.CallExpression) {
|
|
437
|
+
for (const lExoticRequireString of pExoticRequireStrings) {
|
|
438
|
+
// eslint-disable-next-line max-depth
|
|
439
|
+
if (isExoticRequire(pASTNode, lExoticRequireString)) {
|
|
440
|
+
pResult.push({
|
|
441
|
+
module: pASTNode.arguments[0].text,
|
|
442
|
+
moduleSystem: "cjs",
|
|
443
|
+
exoticallyRequired: true,
|
|
444
|
+
exoticRequire: lExoticRequireString,
|
|
445
|
+
dependencyTypes: ["exotic-require"],
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
}
|
|
459
450
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
451
|
+
// const path = process.getBuiltinModule('node:path'); const fs = globalThis.process.getBuiltinModule(`node:fs`);
|
|
452
|
+
if (
|
|
453
|
+
pDetectProcessBuiltinModuleCalls &&
|
|
454
|
+
(isCompositeExoticRequire(pASTNode, "process", "getBuiltinModule") ||
|
|
455
|
+
isTripleCursedCompositeExoticRequire(
|
|
456
|
+
pASTNode,
|
|
457
|
+
"globalThis",
|
|
458
|
+
"process",
|
|
459
|
+
"getBuiltinModule",
|
|
460
|
+
))
|
|
461
|
+
) {
|
|
462
|
+
pResult.push({
|
|
463
|
+
module: pASTNode.arguments[0].text,
|
|
464
|
+
moduleSystem: "cjs",
|
|
465
|
+
exoticallyRequired: false,
|
|
466
|
+
dependencyTypes: ["process-get-builtin-module"],
|
|
467
|
+
});
|
|
468
|
+
}
|
|
470
469
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
470
|
+
// import('a-string'), import(`a-template-literal`)
|
|
471
|
+
if (isDynamicImportExpression(pASTNode)) {
|
|
472
|
+
pResult.push({
|
|
473
|
+
module: pASTNode.arguments[0].text,
|
|
474
|
+
moduleSystem: "es6",
|
|
475
|
+
dynamic: true,
|
|
476
|
+
exoticallyRequired: false,
|
|
477
|
+
dependencyTypes: ["dynamic-import"],
|
|
478
|
+
});
|
|
479
|
+
}
|
|
475
480
|
|
|
476
|
-
//
|
|
477
|
-
//
|
|
478
|
-
|
|
479
|
-
pResult.push(
|
|
481
|
+
// const atype: import('./types').T
|
|
482
|
+
// const atype: import(`./types`).T
|
|
483
|
+
if (isTypeImport(pASTNode)) {
|
|
484
|
+
pResult.push({
|
|
485
|
+
module: pASTNode.argument.literal.text,
|
|
486
|
+
moduleSystem: "es6",
|
|
487
|
+
exoticallyRequired: false,
|
|
488
|
+
dependencyTypes: ["type-import"],
|
|
489
|
+
});
|
|
480
490
|
}
|
|
481
491
|
}
|
|
492
|
+
|
|
482
493
|
typescript.forEachChild(
|
|
483
494
|
pASTNode,
|
|
484
495
|
walk(
|