deslop-js 0.7.1 → 0.7.3
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/dist/entries-worker.mjs +12 -3
- package/dist/index.cjs +261 -20
- package/dist/index.mjs +261 -20
- package/dist/{parse-xkrZfjHl.mjs → parse-CDdo_Ppt.mjs} +151 -1
- package/dist/parse-worker.mjs +2 -1
- package/package.json +1 -1
package/dist/entries-worker.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as OUTPUT_DIRECTORIES, c as SCRIPT_ENTRY_PATTERNS, d as SOURCE_EXTENSIONS$3, f as STANDALONE_PROJECT_LOCKFILES, i as MONOREPO_ROOT_MARKERS, l as SCRIPT_EXTENSIONLESS_FILE_PATTERN, o as RESOLVER_EXTENSIONS, r as LOCKFILE_MARKERS, s as SCRIPT_CONFIG_FILE_PATTERN, t as extractReactRouterRouteModuleEntries, u as SCRIPT_FILE_PATTERN } from "./parse-
|
|
1
|
+
import { a as OUTPUT_DIRECTORIES, c as SCRIPT_ENTRY_PATTERNS, d as SOURCE_EXTENSIONS$3, f as STANDALONE_PROJECT_LOCKFILES, i as MONOREPO_ROOT_MARKERS, l as SCRIPT_EXTENSIONLESS_FILE_PATTERN, o as RESOLVER_EXTENSIONS, r as LOCKFILE_MARKERS, s as SCRIPT_CONFIG_FILE_PATTERN, t as extractReactRouterRouteModuleEntries, u as SCRIPT_FILE_PATTERN } from "./parse-CDdo_Ppt.mjs";
|
|
2
2
|
import { parentPort } from "node:worker_threads";
|
|
3
3
|
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
4
4
|
import fg from "fast-glob";
|
|
@@ -1916,6 +1916,13 @@ const extractCiWorkflowEntries = (rootDir) => {
|
|
|
1916
1916
|
const entries = [];
|
|
1917
1917
|
const workflowsDir = join(rootDir, ".github", "workflows");
|
|
1918
1918
|
if (!existsSync(workflowsDir)) return entries;
|
|
1919
|
+
const nestedToolPackageJsonPaths = fg.sync("**/package.json", {
|
|
1920
|
+
cwd: join(rootDir, ".github"),
|
|
1921
|
+
absolute: true,
|
|
1922
|
+
onlyFiles: true,
|
|
1923
|
+
ignore: ["**/node_modules/**"]
|
|
1924
|
+
});
|
|
1925
|
+
for (const nestedPackageJsonPath of nestedToolPackageJsonPaths) entries.push(...extractScriptEntries(dirname(nestedPackageJsonPath)));
|
|
1919
1926
|
const workflowFiles = fg.sync("*.{yml,yaml}", {
|
|
1920
1927
|
cwd: workflowsDir,
|
|
1921
1928
|
absolute: true,
|
|
@@ -3518,8 +3525,10 @@ const discoverTestRunnerEntryPoints = (rootDir, workspacePackages) => {
|
|
|
3518
3525
|
customPatterns = extractJestTestMatchPatterns(directory);
|
|
3519
3526
|
if (customPatterns.length === 0 && monorepoRoot) customPatterns = extractJestTestMatchPatterns(monorepoRoot);
|
|
3520
3527
|
}
|
|
3521
|
-
if (customPatterns.length > 0)
|
|
3522
|
-
|
|
3528
|
+
if (customPatterns.length > 0) {
|
|
3529
|
+
activatedPatterns.push(...customPatterns);
|
|
3530
|
+
if (isJestRunner) activatedPatterns.push("**/__mocks__/**/*.{ts,tsx,js,jsx,mjs,cjs}");
|
|
3531
|
+
} else activatedPatterns.push(...runner.entryPatterns);
|
|
3523
3532
|
activatedFixturePatterns.push(...runner.fixturePatterns);
|
|
3524
3533
|
activatedAlwaysUsed.push(...runner.alwaysUsed);
|
|
3525
3534
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -1355,6 +1355,7 @@ const parseCssImports = (filePath) => {
|
|
|
1355
1355
|
memberAccesses: [],
|
|
1356
1356
|
wholeObjectUses: [],
|
|
1357
1357
|
localIdentifierReferences: [],
|
|
1358
|
+
topLevelImportReferences: [],
|
|
1358
1359
|
referencedFilenames: [],
|
|
1359
1360
|
redundantTypePatterns: [],
|
|
1360
1361
|
identityWrappers: [],
|
|
@@ -1383,18 +1384,142 @@ const collectLocalIdentifierReferences = (statements) => {
|
|
|
1383
1384
|
for (const value of Object.values(record)) if (Array.isArray(value)) for (const innerValue of value) visitNode(innerValue);
|
|
1384
1385
|
else if (value && typeof value === "object") visitNode(value);
|
|
1385
1386
|
};
|
|
1387
|
+
const visitExportedDeclarationValues = (declaration) => {
|
|
1388
|
+
if (!declaration || typeof declaration !== "object") return;
|
|
1389
|
+
const record = declaration;
|
|
1390
|
+
if (record.type === "VariableDeclaration" && Array.isArray(record.declarations)) {
|
|
1391
|
+
for (const declarator of record.declarations) if (declarator && typeof declarator === "object") visitNode(declarator.init);
|
|
1392
|
+
return;
|
|
1393
|
+
}
|
|
1394
|
+
if (record.type === "FunctionDeclaration" || record.type === "ClassDeclaration") {
|
|
1395
|
+
visitNode(record.params);
|
|
1396
|
+
visitNode(record.superClass);
|
|
1397
|
+
visitNode(record.body);
|
|
1398
|
+
return;
|
|
1399
|
+
}
|
|
1400
|
+
if (typeof record.type === "string" && !record.type.startsWith("TS")) visitNode(declaration);
|
|
1401
|
+
};
|
|
1386
1402
|
for (const statement of statements) {
|
|
1387
|
-
if (statement.type === "ImportDeclaration" || statement.type === "
|
|
1403
|
+
if (statement.type === "ImportDeclaration" || statement.type === "ExportAllDeclaration") continue;
|
|
1404
|
+
if (statement.type === "ExportNamedDeclaration") {
|
|
1405
|
+
visitExportedDeclarationValues(statement.declaration);
|
|
1406
|
+
continue;
|
|
1407
|
+
}
|
|
1408
|
+
if (statement.type === "ExportDefaultDeclaration") {
|
|
1409
|
+
visitExportedDeclarationValues(statement.declaration);
|
|
1410
|
+
continue;
|
|
1411
|
+
}
|
|
1388
1412
|
visitNode(statement);
|
|
1389
1413
|
}
|
|
1390
1414
|
return references;
|
|
1391
1415
|
};
|
|
1416
|
+
const TS_VALUE_WRAPPER_NODE_TYPES = new Set([
|
|
1417
|
+
"TSAsExpression",
|
|
1418
|
+
"TSSatisfiesExpression",
|
|
1419
|
+
"TSNonNullExpression",
|
|
1420
|
+
"TSInstantiationExpression",
|
|
1421
|
+
"TSTypeAssertion"
|
|
1422
|
+
]);
|
|
1423
|
+
const TS_RUNTIME_DECLARATION_NODE_TYPES = new Set([
|
|
1424
|
+
"TSEnumDeclaration",
|
|
1425
|
+
"TSModuleDeclaration",
|
|
1426
|
+
"TSExportAssignment"
|
|
1427
|
+
]);
|
|
1428
|
+
const FUNCTION_NODE_TYPES = new Set([
|
|
1429
|
+
"FunctionDeclaration",
|
|
1430
|
+
"FunctionExpression",
|
|
1431
|
+
"ArrowFunctionExpression"
|
|
1432
|
+
]);
|
|
1433
|
+
const collectStaticImportLocalNames = (imports) => {
|
|
1434
|
+
const localNames = /* @__PURE__ */ new Set();
|
|
1435
|
+
for (const importInfo of imports) {
|
|
1436
|
+
if (importInfo.isDynamic || importInfo.isTypeOnly) continue;
|
|
1437
|
+
for (const binding of importInfo.importedNames) {
|
|
1438
|
+
if (binding.isTypeOnly) continue;
|
|
1439
|
+
const localName = binding.alias ?? binding.name;
|
|
1440
|
+
if (localName && localName !== "*") localNames.add(localName);
|
|
1441
|
+
}
|
|
1442
|
+
}
|
|
1443
|
+
return localNames;
|
|
1444
|
+
};
|
|
1445
|
+
const collectTopLevelImportReferences = (bodyNodes, importLocalNames) => {
|
|
1446
|
+
const referencedNames = /* @__PURE__ */ new Set();
|
|
1447
|
+
if (importLocalNames.size === 0) return [];
|
|
1448
|
+
const visitClassBody = (classBody) => {
|
|
1449
|
+
const bodyElements = classBody.body ?? [];
|
|
1450
|
+
for (const element of bodyElements) {
|
|
1451
|
+
if (element.type === "StaticBlock") {
|
|
1452
|
+
visitValueNode(element.body);
|
|
1453
|
+
continue;
|
|
1454
|
+
}
|
|
1455
|
+
if (Boolean(element.computed)) visitValueNode(element.key);
|
|
1456
|
+
const isStatic = Boolean(element.static);
|
|
1457
|
+
if (element.type === "PropertyDefinition" && isStatic) visitValueNode(element.value);
|
|
1458
|
+
visitValueNode(element.decorators);
|
|
1459
|
+
}
|
|
1460
|
+
};
|
|
1461
|
+
const visitValueNode = (node) => {
|
|
1462
|
+
if (Array.isArray(node)) {
|
|
1463
|
+
for (const element of node) visitValueNode(element);
|
|
1464
|
+
return;
|
|
1465
|
+
}
|
|
1466
|
+
if (!isWalkableNode(node)) return;
|
|
1467
|
+
if (node.type === "Identifier" || node.type === "JSXIdentifier") {
|
|
1468
|
+
const identifierName = node.name;
|
|
1469
|
+
if (identifierName && importLocalNames.has(identifierName)) referencedNames.add(identifierName);
|
|
1470
|
+
return;
|
|
1471
|
+
}
|
|
1472
|
+
if (node.type.startsWith("TS")) {
|
|
1473
|
+
if (TS_VALUE_WRAPPER_NODE_TYPES.has(node.type)) {
|
|
1474
|
+
visitValueNode(node.expression);
|
|
1475
|
+
return;
|
|
1476
|
+
}
|
|
1477
|
+
if (!TS_RUNTIME_DECLARATION_NODE_TYPES.has(node.type)) return;
|
|
1478
|
+
}
|
|
1479
|
+
if (FUNCTION_NODE_TYPES.has(node.type)) return;
|
|
1480
|
+
if (node.type === "ClassDeclaration" || node.type === "ClassExpression") {
|
|
1481
|
+
visitValueNode(node.superClass);
|
|
1482
|
+
visitValueNode(node.decorators);
|
|
1483
|
+
const classBody = node.body;
|
|
1484
|
+
if (classBody) visitClassBody(classBody);
|
|
1485
|
+
return;
|
|
1486
|
+
}
|
|
1487
|
+
if (node.type === "CallExpression" || node.type === "NewExpression") {
|
|
1488
|
+
const callee = node.callee;
|
|
1489
|
+
if (callee && FUNCTION_NODE_TYPES.has(callee.type)) visitValueNode(callee.body);
|
|
1490
|
+
}
|
|
1491
|
+
if (node.type === "MemberExpression" || node.type === "JSXMemberExpression") {
|
|
1492
|
+
const memberNode = node;
|
|
1493
|
+
visitValueNode(memberNode.object);
|
|
1494
|
+
if (node.computed) visitValueNode(memberNode.property);
|
|
1495
|
+
return;
|
|
1496
|
+
}
|
|
1497
|
+
if (node.type === "Property") {
|
|
1498
|
+
const propertyNode = node;
|
|
1499
|
+
if (node.computed) visitValueNode(propertyNode.key);
|
|
1500
|
+
visitValueNode(propertyNode.value);
|
|
1501
|
+
return;
|
|
1502
|
+
}
|
|
1503
|
+
for (const value of Object.values(node)) if (Array.isArray(value)) for (const element of value) visitValueNode(element);
|
|
1504
|
+
else if (value && typeof value === "object") visitValueNode(value);
|
|
1505
|
+
};
|
|
1506
|
+
for (const statement of bodyNodes) {
|
|
1507
|
+
if (statement.type === "ImportDeclaration" || statement.type === "ExportAllDeclaration") continue;
|
|
1508
|
+
if (statement.type === "ExportNamedDeclaration" || statement.type === "ExportDefaultDeclaration") {
|
|
1509
|
+
visitValueNode(statement.declaration);
|
|
1510
|
+
continue;
|
|
1511
|
+
}
|
|
1512
|
+
visitValueNode(statement);
|
|
1513
|
+
}
|
|
1514
|
+
return [...referencedNames];
|
|
1515
|
+
};
|
|
1392
1516
|
const createEmptyParsedSource = () => ({
|
|
1393
1517
|
imports: [],
|
|
1394
1518
|
exports: [],
|
|
1395
1519
|
memberAccesses: [],
|
|
1396
1520
|
wholeObjectUses: [],
|
|
1397
1521
|
localIdentifierReferences: [],
|
|
1522
|
+
topLevelImportReferences: [],
|
|
1398
1523
|
referencedFilenames: [],
|
|
1399
1524
|
redundantTypePatterns: [],
|
|
1400
1525
|
identityWrappers: [],
|
|
@@ -1606,6 +1731,7 @@ const parseSourceFile = (filePath) => {
|
|
|
1606
1731
|
collectMemberAccesses(program.body, namespaceLocalNames, memberAccesses, wholeObjectUses);
|
|
1607
1732
|
}, void 0);
|
|
1608
1733
|
const localIdentifierReferences = safeWalk("collectLocalIdentifierReferences", () => collectLocalIdentifierReferences(program.body), []);
|
|
1734
|
+
const topLevelImportReferences = safeWalk("collectTopLevelImportReferences", () => collectTopLevelImportReferences(program.body, collectStaticImportLocalNames(imports)), []);
|
|
1609
1735
|
const redundantTypePatterns = [];
|
|
1610
1736
|
const identityWrappers = [];
|
|
1611
1737
|
const typeDefinitionHashes = [];
|
|
@@ -1650,6 +1776,7 @@ const parseSourceFile = (filePath) => {
|
|
|
1650
1776
|
memberAccesses,
|
|
1651
1777
|
wholeObjectUses,
|
|
1652
1778
|
localIdentifierReferences,
|
|
1779
|
+
topLevelImportReferences,
|
|
1653
1780
|
referencedFilenames: extractReferencedFilenames(sourceText),
|
|
1654
1781
|
redundantTypePatterns,
|
|
1655
1782
|
identityWrappers,
|
|
@@ -1790,6 +1917,29 @@ const collectMemberAccesses = (bodyNodes, namespaceLocalNames, memberAccesses, w
|
|
|
1790
1917
|
const spreadArgument = node.argument;
|
|
1791
1918
|
if (spreadArgument?.type === "Identifier" && namespaceLocalNames.has(spreadArgument.name)) wholeObjectUses.push(spreadArgument.name);
|
|
1792
1919
|
}
|
|
1920
|
+
if (node.type === "VariableDeclarator") {
|
|
1921
|
+
const declarator = node;
|
|
1922
|
+
if (declarator.init?.type === "Identifier" && namespaceLocalNames.has(declarator.init.name) && declarator.id?.type === "ObjectPattern") {
|
|
1923
|
+
const namespaceName = declarator.init.name;
|
|
1924
|
+
const patternProperties = declarator.id.properties;
|
|
1925
|
+
for (const property of patternProperties) {
|
|
1926
|
+
if (property.type === "RestElement") {
|
|
1927
|
+
wholeObjectUses.push(namespaceName);
|
|
1928
|
+
continue;
|
|
1929
|
+
}
|
|
1930
|
+
const propertyKey = property.key;
|
|
1931
|
+
if (Boolean(property.computed)) wholeObjectUses.push(namespaceName);
|
|
1932
|
+
else if (propertyKey?.type === "Identifier" && propertyKey.name) memberAccesses.push({
|
|
1933
|
+
objectName: namespaceName,
|
|
1934
|
+
memberName: propertyKey.name
|
|
1935
|
+
});
|
|
1936
|
+
else if (propertyKey?.type === "Literal" && typeof propertyKey.value === "string") memberAccesses.push({
|
|
1937
|
+
objectName: namespaceName,
|
|
1938
|
+
memberName: propertyKey.value
|
|
1939
|
+
});
|
|
1940
|
+
}
|
|
1941
|
+
}
|
|
1942
|
+
}
|
|
1793
1943
|
if (node.type === "ForInStatement") {
|
|
1794
1944
|
const forInRight = node.right;
|
|
1795
1945
|
if (forInRight?.type === "Identifier" && namespaceLocalNames.has(forInRight.name)) wholeObjectUses.push(forInRight.name);
|
|
@@ -5123,6 +5273,13 @@ const extractCiWorkflowEntries = (rootDir) => {
|
|
|
5123
5273
|
const entries = [];
|
|
5124
5274
|
const workflowsDir = (0, node_path.join)(rootDir, ".github", "workflows");
|
|
5125
5275
|
if (!(0, node_fs.existsSync)(workflowsDir)) return entries;
|
|
5276
|
+
const nestedToolPackageJsonPaths = fast_glob.default.sync("**/package.json", {
|
|
5277
|
+
cwd: (0, node_path.join)(rootDir, ".github"),
|
|
5278
|
+
absolute: true,
|
|
5279
|
+
onlyFiles: true,
|
|
5280
|
+
ignore: ["**/node_modules/**"]
|
|
5281
|
+
});
|
|
5282
|
+
for (const nestedPackageJsonPath of nestedToolPackageJsonPaths) entries.push(...extractScriptEntries((0, node_path.dirname)(nestedPackageJsonPath)));
|
|
5126
5283
|
const workflowFiles = fast_glob.default.sync("*.{yml,yaml}", {
|
|
5127
5284
|
cwd: workflowsDir,
|
|
5128
5285
|
absolute: true,
|
|
@@ -6725,8 +6882,10 @@ const discoverTestRunnerEntryPoints = (rootDir, workspacePackages) => {
|
|
|
6725
6882
|
customPatterns = extractJestTestMatchPatterns(directory);
|
|
6726
6883
|
if (customPatterns.length === 0 && monorepoRoot) customPatterns = extractJestTestMatchPatterns(monorepoRoot);
|
|
6727
6884
|
}
|
|
6728
|
-
if (customPatterns.length > 0)
|
|
6729
|
-
|
|
6885
|
+
if (customPatterns.length > 0) {
|
|
6886
|
+
activatedPatterns.push(...customPatterns);
|
|
6887
|
+
if (isJestRunner) activatedPatterns.push("**/__mocks__/**/*.{ts,tsx,js,jsx,mjs,cjs}");
|
|
6888
|
+
} else activatedPatterns.push(...runner.entryPatterns);
|
|
6730
6889
|
activatedFixturePatterns.push(...runner.fixturePatterns);
|
|
6731
6890
|
activatedAlwaysUsed.push(...runner.alwaysUsed);
|
|
6732
6891
|
}
|
|
@@ -6957,6 +7116,7 @@ const deserializeParsedSource = (serialized) => ({
|
|
|
6957
7116
|
memberAccesses: serialized.memberAccesses,
|
|
6958
7117
|
wholeObjectUses: serialized.wholeObjectUses,
|
|
6959
7118
|
localIdentifierReferences: serialized.localIdentifierReferences,
|
|
7119
|
+
topLevelImportReferences: serialized.topLevelImportReferences,
|
|
6960
7120
|
referencedFilenames: serialized.referencedFilenames,
|
|
6961
7121
|
redundantTypePatterns: serialized.redundantTypePatterns,
|
|
6962
7122
|
identityWrappers: serialized.identityWrappers,
|
|
@@ -7021,6 +7181,7 @@ const parseFilesWithWorkerPool = async (files, workerCount) => {
|
|
|
7021
7181
|
memberAccesses: [],
|
|
7022
7182
|
wholeObjectUses: [],
|
|
7023
7183
|
localIdentifierReferences: [],
|
|
7184
|
+
topLevelImportReferences: [],
|
|
7024
7185
|
referencedFilenames: [],
|
|
7025
7186
|
redundantTypePatterns: [],
|
|
7026
7187
|
identityWrappers: [],
|
|
@@ -7095,6 +7256,7 @@ const buildDependencyGraph = (inputs) => {
|
|
|
7095
7256
|
memberAccesses: input.parsed.memberAccesses,
|
|
7096
7257
|
wholeObjectUses: input.parsed.wholeObjectUses,
|
|
7097
7258
|
localIdentifierReferences: input.parsed.localIdentifierReferences,
|
|
7259
|
+
topLevelImportReferences: input.parsed.topLevelImportReferences,
|
|
7098
7260
|
referencedFilenames: input.parsed.referencedFilenames,
|
|
7099
7261
|
redundantTypePatterns: input.parsed.redundantTypePatterns,
|
|
7100
7262
|
identityWrappers: input.parsed.identityWrappers,
|
|
@@ -7113,12 +7275,13 @@ const buildDependencyGraph = (inputs) => {
|
|
|
7113
7275
|
}));
|
|
7114
7276
|
const edges = [];
|
|
7115
7277
|
const reverseEdges = /* @__PURE__ */ new Map();
|
|
7116
|
-
const addEdge = (sourceIndex, targetIndex, symbols, isReExportEdge = false, reExportedNames = [], reExportMappings = []) => {
|
|
7278
|
+
const addEdge = (sourceIndex, targetIndex, symbols, isReExportEdge = false, reExportedNames = [], reExportMappings = [], isDynamic = false) => {
|
|
7117
7279
|
edges.push({
|
|
7118
7280
|
source: sourceIndex,
|
|
7119
7281
|
target: targetIndex,
|
|
7120
7282
|
importedSymbols: symbols,
|
|
7121
7283
|
isReExportEdge,
|
|
7284
|
+
isDynamic,
|
|
7122
7285
|
reExportedNames,
|
|
7123
7286
|
reExportMappings
|
|
7124
7287
|
});
|
|
@@ -7137,7 +7300,7 @@ const buildDependencyGraph = (inputs) => {
|
|
|
7137
7300
|
const relativePath = toPosixPath(node_path.default.relative(sourceDir, filePath));
|
|
7138
7301
|
if ((0, minimatch.minimatch)(relativePath.startsWith(".") ? relativePath : `./${relativePath}`, globPattern)) {
|
|
7139
7302
|
const targetIndex = fileIdMap.get(filePath);
|
|
7140
|
-
if (targetIndex !== void 0) addEdge(sourceIndex, targetIndex, []);
|
|
7303
|
+
if (targetIndex !== void 0) addEdge(sourceIndex, targetIndex, [], false, [], [], true);
|
|
7141
7304
|
}
|
|
7142
7305
|
}
|
|
7143
7306
|
continue;
|
|
@@ -7152,7 +7315,7 @@ const buildDependencyGraph = (inputs) => {
|
|
|
7152
7315
|
isTypeOnly: importedName.isTypeOnly,
|
|
7153
7316
|
isNamespace: importedName.isNamespace,
|
|
7154
7317
|
isDefault: importedName.isDefault
|
|
7155
|
-
})));
|
|
7318
|
+
})), false, [], [], importInfo.isDynamic);
|
|
7156
7319
|
}
|
|
7157
7320
|
const reExportsByTarget = /* @__PURE__ */ new Map();
|
|
7158
7321
|
for (const exportInfo of input.parsed.exports) {
|
|
@@ -7394,6 +7557,7 @@ const resolveReExportChains = (graph) => {
|
|
|
7394
7557
|
const buildSourceTargetMap = (graph) => {
|
|
7395
7558
|
const sourceTargets = /* @__PURE__ */ new Map();
|
|
7396
7559
|
for (const edge of graph.edges) {
|
|
7560
|
+
if (!edge.isReExportEdge) continue;
|
|
7397
7561
|
const existing = sourceTargets.get(edge.source);
|
|
7398
7562
|
if (existing) {
|
|
7399
7563
|
if (!existing.includes(edge.target)) existing.push(edge.target);
|
|
@@ -7415,9 +7579,9 @@ const EXCLUDED_EXTENSIONS = new Set([
|
|
|
7415
7579
|
".graphql",
|
|
7416
7580
|
".gql"
|
|
7417
7581
|
]);
|
|
7418
|
-
const TEST_FILE_PATTERN = /(?:\.(?:test|spec|stories|story|cy)\.|(?:^|\/)__tests__\/)/;
|
|
7419
|
-
const EXCLUDED_DIRECTORY_PATTERN = /(?:^|\/)(?:e2e|cypress|playwright|__fixtures__|__snapshots__|scripts)\/(?!.*node_modules)/;
|
|
7420
|
-
const CONFIG_FILE_PATTERN = /(?:^|\/)(?:[^/]+\.config\.[tj]sx?$|[^/]+\.setup\.[tj]sx?$|setupTests\.[tj]sx?$|jest\.setup\.[tj]sx?$|vitest\.setup\.[tj]sx?$)/;
|
|
7582
|
+
const TEST_FILE_PATTERN = /(?:\.(?:test|spec|stories|story|cy|test-d)\.|(?:^|\/)__tests__\/)/;
|
|
7583
|
+
const EXCLUDED_DIRECTORY_PATTERN = /(?:^|\/)(?:e2e|cypress|playwright|__fixtures__|__snapshots__|public|scripts)\/(?!.*node_modules)/;
|
|
7584
|
+
const CONFIG_FILE_PATTERN = /(?:^|\/)(?:[^/]+\.config\.[tj]sx?$|[^/]+\.config\.[^/]+\.[tj]sx?$|[^/]+\.setup\.[tj]sx?$|setupTests\.[tj]sx?$|jest\.setup\.[tj]sx?$|vitest\.setup\.[tj]sx?$)/;
|
|
7421
7585
|
const hasExcludedExtension = (filePath) => {
|
|
7422
7586
|
const lastDot = filePath.lastIndexOf(".");
|
|
7423
7587
|
if (lastDot === -1) return false;
|
|
@@ -7493,6 +7657,7 @@ const detectDeadExports = (graph, config) => {
|
|
|
7493
7657
|
if (usageMap.has(usageKey)) continue;
|
|
7494
7658
|
if (module.localIdentifierReferences.includes(exportInfo.name)) continue;
|
|
7495
7659
|
if (!exportInfo.isDefault && defaultExportLinkedNames.has(exportInfo.name)) continue;
|
|
7660
|
+
if (exportInfo.isDefault && exportInfo.defaultExportLocalName && usageMap.has(`${module.fileId.path}::${exportInfo.defaultExportLocalName}`)) continue;
|
|
7496
7661
|
unusedExports.push({
|
|
7497
7662
|
path: module.fileId.path,
|
|
7498
7663
|
name: exportInfo.name,
|
|
@@ -7527,6 +7692,10 @@ const buildUsageMap = (graph) => {
|
|
|
7527
7692
|
const targetModule = graph.modules[edge.target];
|
|
7528
7693
|
if (!targetModule) continue;
|
|
7529
7694
|
const sourceModule = graph.modules[edge.source];
|
|
7695
|
+
if (edge.isDynamic && edge.importedSymbols.length === 0) {
|
|
7696
|
+
markAllExportsUsedRecursive(targetModule, graph, sourceToTargetMap, usedExportKeys, /* @__PURE__ */ new Set());
|
|
7697
|
+
continue;
|
|
7698
|
+
}
|
|
7530
7699
|
for (const symbol of edge.importedSymbols) if (symbol.isNamespace) handleNamespaceImport(sourceModule, targetModule, symbol.localName, graph, sourceToTargetMap, usedExportKeys);
|
|
7531
7700
|
else {
|
|
7532
7701
|
const importName = symbol.isDefault ? "default" : symbol.importedName;
|
|
@@ -7573,6 +7742,7 @@ const extractAccessedMemberNames = (memberAccesses, objectName) => {
|
|
|
7573
7742
|
const buildSourceToTargetsMap = (graph) => {
|
|
7574
7743
|
const sourceToTargets = /* @__PURE__ */ new Map();
|
|
7575
7744
|
for (const edge of graph.edges) {
|
|
7745
|
+
if (!edge.isReExportEdge) continue;
|
|
7576
7746
|
const existing = sourceToTargets.get(edge.source);
|
|
7577
7747
|
if (existing) {
|
|
7578
7748
|
if (!existing.includes(edge.target)) existing.push(edge.target);
|
|
@@ -7916,10 +8086,12 @@ const hasJsxFiles = (graph) => graph.modules.some((module) => {
|
|
|
7916
8086
|
const filePath = module.fileId.path;
|
|
7917
8087
|
return filePath.endsWith(".tsx") || filePath.endsWith(".jsx");
|
|
7918
8088
|
});
|
|
8089
|
+
const KNOWN_PEER_DEPENDENCY_NAMES = new Map([["vitest-axe", ["axe-core"]], ["jest-axe", ["axe-core"]]]);
|
|
7919
8090
|
const collectPeerSatisfiedPackages = (nodeModulesSearchRoots, declaredNames, confirmedUsedNames) => {
|
|
7920
8091
|
const peerSatisfied = /* @__PURE__ */ new Set();
|
|
7921
8092
|
for (const installedName of declaredNames) {
|
|
7922
8093
|
if (!confirmedUsedNames.has(installedName)) continue;
|
|
8094
|
+
for (const knownPeerName of KNOWN_PEER_DEPENDENCY_NAMES.get(installedName) ?? []) if (declaredNames.has(knownPeerName)) peerSatisfied.add(knownPeerName);
|
|
7923
8095
|
const installedPackageJsonPath = findInstalledPackageJsonPath(installedName, nodeModulesSearchRoots);
|
|
7924
8096
|
if (!installedPackageJsonPath) continue;
|
|
7925
8097
|
try {
|
|
@@ -7942,22 +8114,41 @@ const findInstalledPackageJsonPath = (packageName, nodeModulesSearchRoots) => {
|
|
|
7942
8114
|
};
|
|
7943
8115
|
const SHELL_SPLIT_PATTERN = /\s*(?:&&|\|\||[;&|])\s*/;
|
|
7944
8116
|
const INLINE_ENV_VAR_PATTERN = /^[A-Z_][A-Z0-9_]*=/;
|
|
8117
|
+
const KNOWN_PACKAGE_BIN_NAMES = new Map([
|
|
8118
|
+
["@tauri-apps/cli", ["tauri"]],
|
|
8119
|
+
["@typescript/native-preview", ["tsgo"]],
|
|
8120
|
+
["playwright-chromium", ["playwright"]],
|
|
8121
|
+
["playwright-firefox", ["playwright"]],
|
|
8122
|
+
["playwright-webkit", ["playwright"]]
|
|
8123
|
+
]);
|
|
8124
|
+
const staticBinNamesForPackage = (packageName) => {
|
|
8125
|
+
const binNames = [...KNOWN_PACKAGE_BIN_NAMES.get(packageName) ?? []];
|
|
8126
|
+
const unscopedName = packageName.split("/").pop();
|
|
8127
|
+
if (unscopedName.endsWith("-cli") && unscopedName.length > 4) binNames.push(unscopedName.slice(0, -4));
|
|
8128
|
+
return binNames;
|
|
8129
|
+
};
|
|
7945
8130
|
const buildBinaryPackageIndex = (nodeModulesSearchRoots, declaredNames) => {
|
|
7946
8131
|
const binToPackage = /* @__PURE__ */ new Map();
|
|
7947
8132
|
const packagesProvidingBinary = /* @__PURE__ */ new Set();
|
|
8133
|
+
const addBinMapping = (binaryName, packageName) => {
|
|
8134
|
+
const mappedPackages = binToPackage.get(binaryName) ?? /* @__PURE__ */ new Set();
|
|
8135
|
+
mappedPackages.add(packageName);
|
|
8136
|
+
binToPackage.set(binaryName, mappedPackages);
|
|
8137
|
+
};
|
|
7948
8138
|
for (const packageName of declaredNames) {
|
|
8139
|
+
for (const staticBinName of staticBinNamesForPackage(packageName)) addBinMapping(staticBinName, packageName);
|
|
7949
8140
|
const packageBinJsonPath = findInstalledPackageJsonPath(packageName, nodeModulesSearchRoots);
|
|
7950
8141
|
if (!packageBinJsonPath) continue;
|
|
7951
8142
|
try {
|
|
7952
8143
|
const binContent = (0, node_fs.readFileSync)(packageBinJsonPath, "utf-8");
|
|
7953
8144
|
const binField = JSON.parse(binContent).bin;
|
|
7954
8145
|
if (typeof binField === "string" && binField.length > 0) {
|
|
7955
|
-
|
|
8146
|
+
addBinMapping(packageName.split("/").pop(), packageName);
|
|
7956
8147
|
packagesProvidingBinary.add(packageName);
|
|
7957
8148
|
} else if (typeof binField === "object" && binField !== null) {
|
|
7958
8149
|
const binaryNames = Object.keys(binField);
|
|
7959
8150
|
if (binaryNames.length === 0) continue;
|
|
7960
|
-
for (const binaryName of binaryNames)
|
|
8151
|
+
for (const binaryName of binaryNames) addBinMapping(binaryName, packageName);
|
|
7961
8152
|
packagesProvidingBinary.add(packageName);
|
|
7962
8153
|
}
|
|
7963
8154
|
} catch {
|
|
@@ -8002,8 +8193,7 @@ const collectCommandReferencedPackages = (command, declaredNames, binToPackage)
|
|
|
8002
8193
|
const effectiveBinary = binaryToken === "npx" || binaryToken === "pnpx" || binaryToken === "bunx" ? tokens[binaryIndex + 1]?.replace(/^.*\//, "") ?? "" : binaryToken;
|
|
8003
8194
|
for (const candidateBinary of [binaryToken, effectiveBinary]) {
|
|
8004
8195
|
if (!candidateBinary) continue;
|
|
8005
|
-
const mappedPackage
|
|
8006
|
-
if (mappedPackage && declaredNames.has(mappedPackage)) referenced.add(mappedPackage);
|
|
8196
|
+
for (const mappedPackage of binToPackage.get(candidateBinary) ?? []) if (declaredNames.has(mappedPackage)) referenced.add(mappedPackage);
|
|
8007
8197
|
if (declaredNames.has(candidateBinary)) referenced.add(candidateBinary);
|
|
8008
8198
|
}
|
|
8009
8199
|
}
|
|
@@ -8083,6 +8273,12 @@ const collectConfigReferencedPackages = (rootDir, graph, declaredNames, summaryC
|
|
|
8083
8273
|
deep: 6
|
|
8084
8274
|
}, summaryCache);
|
|
8085
8275
|
for (const documentationPath of documentationFiles) addMatchesFromFile(documentationPath, "importReference", matchesPackageImportReference);
|
|
8276
|
+
const toolingSourceFiles = globPackageFiles(rootDir, ["**/{.dumi,.storybook,.docz,.styleguidist}/**/*.{ts,tsx,js,jsx,mts,mjs}"], {
|
|
8277
|
+
ignore: ["**/node_modules/**"],
|
|
8278
|
+
dot: true,
|
|
8279
|
+
deep: 8
|
|
8280
|
+
}, summaryCache);
|
|
8281
|
+
for (const toolingSourcePath of toolingSourceFiles) addMatchesFromFile(toolingSourcePath, "importReference", matchesPackageImportReference);
|
|
8086
8282
|
return referenced;
|
|
8087
8283
|
};
|
|
8088
8284
|
const PACKAGE_JSON_CONFIG_SECTIONS = [
|
|
@@ -8335,14 +8531,47 @@ const isAlwaysConsideredUsed = (dependencyName) => {
|
|
|
8335
8531
|
//#endregion
|
|
8336
8532
|
//#region src/report/cycles.ts
|
|
8337
8533
|
const UNDEFINED_INDEX = -1;
|
|
8534
|
+
const isCompileTimeErasedEdge = (edge, graph) => {
|
|
8535
|
+
if (edge.isReExportEdge) return false;
|
|
8536
|
+
if (edge.importedSymbols.length === 0) return false;
|
|
8537
|
+
const targetModule = graph.modules[edge.target];
|
|
8538
|
+
if (!targetModule) return false;
|
|
8539
|
+
return edge.importedSymbols.every((symbol) => {
|
|
8540
|
+
if (symbol.isTypeOnly) return true;
|
|
8541
|
+
if (symbol.isNamespace) return false;
|
|
8542
|
+
const exportName = symbol.isDefault ? "default" : symbol.importedName;
|
|
8543
|
+
const matchingExports = targetModule.exports.filter((exportInfo) => exportInfo.name === exportName);
|
|
8544
|
+
return matchingExports.length > 0 && matchingExports.every((exportInfo) => exportInfo.isTypeOnly);
|
|
8545
|
+
});
|
|
8546
|
+
};
|
|
8338
8547
|
const buildAdjacencyList = (graph) => {
|
|
8339
8548
|
const targetSets = Array.from({ length: graph.modules.length }, () => /* @__PURE__ */ new Set());
|
|
8340
8549
|
for (const edge of graph.edges) {
|
|
8550
|
+
if (edge.isDynamic) continue;
|
|
8341
8551
|
if (edge.importedSymbols.every((symbol) => symbol.isTypeOnly)) continue;
|
|
8552
|
+
if (isCompileTimeErasedEdge(edge, graph)) continue;
|
|
8342
8553
|
if (edge.target < graph.modules.length) targetSets[edge.source].add(edge.target);
|
|
8343
8554
|
}
|
|
8344
8555
|
return targetSets.map((targets) => [...targets]);
|
|
8345
8556
|
};
|
|
8557
|
+
const buildModuleInitAccessEdgeSet = (graph) => {
|
|
8558
|
+
const initAccessEdges = /* @__PURE__ */ new Set();
|
|
8559
|
+
for (const edge of graph.edges) {
|
|
8560
|
+
if (edge.isDynamic || edge.isReExportEdge) continue;
|
|
8561
|
+
const topLevelReferences = graph.modules[edge.source]?.topLevelImportReferences;
|
|
8562
|
+
if (!topLevelReferences || topLevelReferences.length === 0) continue;
|
|
8563
|
+
if (edge.importedSymbols.some((symbol) => !symbol.isTypeOnly && topLevelReferences.includes(symbol.localName))) initAccessEdges.add(`${edge.source}:${edge.target}`);
|
|
8564
|
+
}
|
|
8565
|
+
return initAccessEdges;
|
|
8566
|
+
};
|
|
8567
|
+
const cycleHasModuleInitAccess = (cycle, initAccessEdges) => {
|
|
8568
|
+
for (let position = 0; position < cycle.length; position++) {
|
|
8569
|
+
const source = cycle[position];
|
|
8570
|
+
const target = cycle[(position + 1) % cycle.length];
|
|
8571
|
+
if (initAccessEdges.has(`${source}:${target}`)) return true;
|
|
8572
|
+
}
|
|
8573
|
+
return false;
|
|
8574
|
+
};
|
|
8346
8575
|
const findStronglyConnectedComponents = (adjacencyList) => {
|
|
8347
8576
|
const nodeCount = adjacencyList.length;
|
|
8348
8577
|
if (nodeCount === 0) return [];
|
|
@@ -8463,6 +8692,7 @@ const enumerateElementaryCycles = (componentNodes, adjacencyList, graph) => {
|
|
|
8463
8692
|
};
|
|
8464
8693
|
const detectCycles = (graph) => {
|
|
8465
8694
|
const adjacencyList = buildAdjacencyList(graph);
|
|
8695
|
+
const initAccessEdges = buildModuleInitAccessEdgeSet(graph);
|
|
8466
8696
|
const components = findStronglyConnectedComponents(adjacencyList);
|
|
8467
8697
|
const allCycles = [];
|
|
8468
8698
|
const seenKeys = /* @__PURE__ */ new Set();
|
|
@@ -8472,6 +8702,7 @@ const detectCycles = (graph) => {
|
|
|
8472
8702
|
if (component.length > 50) continue;
|
|
8473
8703
|
const elementaryCycles = enumerateElementaryCycles(component, adjacencyList, graph);
|
|
8474
8704
|
for (const cycle of elementaryCycles) {
|
|
8705
|
+
if (!cycleHasModuleInitAccess(cycle, initAccessEdges)) continue;
|
|
8475
8706
|
const key = cycle.join(",");
|
|
8476
8707
|
if (!seenKeys.has(key)) {
|
|
8477
8708
|
seenKeys.add(key);
|
|
@@ -12496,7 +12727,7 @@ const isRecordValue = (value) => typeof value === "object" && value !== null &&
|
|
|
12496
12727
|
const isStringArray = (value) => Array.isArray(value) && value.every((entry) => typeof entry === "string");
|
|
12497
12728
|
const isOptionalArray = (value) => value === void 0 || Array.isArray(value);
|
|
12498
12729
|
const emptyStore = (scopeHash) => ({
|
|
12499
|
-
version:
|
|
12730
|
+
version: 3,
|
|
12500
12731
|
scopeHash,
|
|
12501
12732
|
fileList: null,
|
|
12502
12733
|
resolutions: null,
|
|
@@ -12506,10 +12737,10 @@ const emptyStore = (scopeHash) => ({
|
|
|
12506
12737
|
const readPersistedStore = (cachePath, scopeHash) => {
|
|
12507
12738
|
try {
|
|
12508
12739
|
const parsed = JSON.parse((0, node_fs.readFileSync)(cachePath, "utf-8"));
|
|
12509
|
-
if (isRecordValue(parsed) && parsed.version ===
|
|
12740
|
+
if (isRecordValue(parsed) && parsed.version === 3 && parsed.scopeHash === scopeHash && isRecordValue(parsed.summaries) && isRecordValue(parsed.packageFacts)) {
|
|
12510
12741
|
const persisted = parsed;
|
|
12511
12742
|
return {
|
|
12512
|
-
version:
|
|
12743
|
+
version: 3,
|
|
12513
12744
|
scopeHash,
|
|
12514
12745
|
fileList: isRecordValue(persisted.fileList) ? persisted.fileList : null,
|
|
12515
12746
|
resolutions: isRecordValue(persisted.resolutions) && typeof persisted.resolutions.hash === "string" && isRecordValue(persisted.resolutions.entries) ? persisted.resolutions : null,
|
|
@@ -12532,6 +12763,7 @@ const serializeParsedSource = (parsed, shouldPersistDryPatternFields) => ({
|
|
|
12532
12763
|
memberAccesses: toPersistedArray(parsed.memberAccesses),
|
|
12533
12764
|
wholeObjectUses: toPersistedArray(parsed.wholeObjectUses),
|
|
12534
12765
|
localIdentifierReferences: toPersistedArray(intersectLocalReferencesWithOwnExports(parsed)),
|
|
12766
|
+
topLevelImportReferences: toPersistedArray(parsed.topLevelImportReferences),
|
|
12535
12767
|
referencedFilenames: toPersistedArray(parsed.referencedFilenames),
|
|
12536
12768
|
...shouldPersistDryPatternFields ? {
|
|
12537
12769
|
redundantTypePatterns: toPersistedArray(parsed.redundantTypePatterns),
|
|
@@ -12551,6 +12783,7 @@ const PERSISTED_SOURCE_ARRAY_FIELDS = [
|
|
|
12551
12783
|
"memberAccesses",
|
|
12552
12784
|
"wholeObjectUses",
|
|
12553
12785
|
"localIdentifierReferences",
|
|
12786
|
+
"topLevelImportReferences",
|
|
12554
12787
|
"referencedFilenames",
|
|
12555
12788
|
"redundantTypePatterns",
|
|
12556
12789
|
"identityWrappers",
|
|
@@ -12573,6 +12806,7 @@ const reviveParsedSource = (persisted) => {
|
|
|
12573
12806
|
memberAccesses: source.memberAccesses ?? [],
|
|
12574
12807
|
wholeObjectUses: source.wholeObjectUses ?? [],
|
|
12575
12808
|
localIdentifierReferences: source.localIdentifierReferences ?? [],
|
|
12809
|
+
topLevelImportReferences: source.topLevelImportReferences ?? [],
|
|
12576
12810
|
referencedFilenames: source.referencedFilenames ?? [],
|
|
12577
12811
|
redundantTypePatterns: source.redundantTypePatterns ?? [],
|
|
12578
12812
|
identityWrappers: source.identityWrappers ?? [],
|
|
@@ -12776,7 +13010,7 @@ const createSummaryCache = (cachePath, config) => {
|
|
|
12776
13010
|
if (resolutionEntry !== void 0) compactedResolutions[resolutionKey] = resolutionEntry;
|
|
12777
13011
|
}
|
|
12778
13012
|
const serialized = JSON.stringify({
|
|
12779
|
-
version:
|
|
13013
|
+
version: 3,
|
|
12780
13014
|
scopeHash,
|
|
12781
13015
|
fileList: store.fileList,
|
|
12782
13016
|
resolutions: {
|
|
@@ -13291,9 +13525,13 @@ const analyze = async (config) => {
|
|
|
13291
13525
|
if (discoveredFilePaths.has(resolvedImport.resolvedPath)) continue;
|
|
13292
13526
|
if (STYLE_EXTENSIONS.some((ext) => resolvedImport.resolvedPath.endsWith(ext)) && (0, node_fs.existsSync)(resolvedImport.resolvedPath)) styleFilesToAdd.add(resolvedImport.resolvedPath);
|
|
13293
13527
|
}
|
|
13294
|
-
const
|
|
13528
|
+
const styleFileQueue = [...styleFilesToAdd].sort();
|
|
13295
13529
|
let nextFileIndex = files.length;
|
|
13296
|
-
|
|
13530
|
+
let styleFileQueueIndex = 0;
|
|
13531
|
+
while (styleFileQueueIndex < styleFileQueue.length) {
|
|
13532
|
+
const styleFilePath = styleFileQueue[styleFileQueueIndex];
|
|
13533
|
+
styleFileQueueIndex++;
|
|
13534
|
+
if (discoveredFilePaths.has(styleFilePath)) continue;
|
|
13297
13535
|
const styleSourceFile = {
|
|
13298
13536
|
index: nextFileIndex,
|
|
13299
13537
|
path: styleFilePath
|
|
@@ -13319,7 +13557,10 @@ const analyze = async (config) => {
|
|
|
13319
13557
|
}
|
|
13320
13558
|
resolvedStyleImportMap.set(importInfo.specifier, resolvedImport);
|
|
13321
13559
|
if (resolvedImport.resolvedPath && !discoveredFilePaths.has(resolvedImport.resolvedPath)) {
|
|
13322
|
-
if (STYLE_EXTENSIONS.some((ext) => resolvedImport.resolvedPath.endsWith(ext)) && (0, node_fs.existsSync)(resolvedImport.resolvedPath))
|
|
13560
|
+
if (STYLE_EXTENSIONS.some((ext) => resolvedImport.resolvedPath.endsWith(ext)) && !styleFilesToAdd.has(resolvedImport.resolvedPath) && (0, node_fs.existsSync)(resolvedImport.resolvedPath)) {
|
|
13561
|
+
styleFilesToAdd.add(resolvedImport.resolvedPath);
|
|
13562
|
+
styleFileQueue.push(resolvedImport.resolvedPath);
|
|
13563
|
+
}
|
|
13323
13564
|
}
|
|
13324
13565
|
}
|
|
13325
13566
|
graphInputs.push({
|
package/dist/index.mjs
CHANGED
|
@@ -1322,6 +1322,7 @@ const parseCssImports = (filePath) => {
|
|
|
1322
1322
|
memberAccesses: [],
|
|
1323
1323
|
wholeObjectUses: [],
|
|
1324
1324
|
localIdentifierReferences: [],
|
|
1325
|
+
topLevelImportReferences: [],
|
|
1325
1326
|
referencedFilenames: [],
|
|
1326
1327
|
redundantTypePatterns: [],
|
|
1327
1328
|
identityWrappers: [],
|
|
@@ -1350,18 +1351,142 @@ const collectLocalIdentifierReferences = (statements) => {
|
|
|
1350
1351
|
for (const value of Object.values(record)) if (Array.isArray(value)) for (const innerValue of value) visitNode(innerValue);
|
|
1351
1352
|
else if (value && typeof value === "object") visitNode(value);
|
|
1352
1353
|
};
|
|
1354
|
+
const visitExportedDeclarationValues = (declaration) => {
|
|
1355
|
+
if (!declaration || typeof declaration !== "object") return;
|
|
1356
|
+
const record = declaration;
|
|
1357
|
+
if (record.type === "VariableDeclaration" && Array.isArray(record.declarations)) {
|
|
1358
|
+
for (const declarator of record.declarations) if (declarator && typeof declarator === "object") visitNode(declarator.init);
|
|
1359
|
+
return;
|
|
1360
|
+
}
|
|
1361
|
+
if (record.type === "FunctionDeclaration" || record.type === "ClassDeclaration") {
|
|
1362
|
+
visitNode(record.params);
|
|
1363
|
+
visitNode(record.superClass);
|
|
1364
|
+
visitNode(record.body);
|
|
1365
|
+
return;
|
|
1366
|
+
}
|
|
1367
|
+
if (typeof record.type === "string" && !record.type.startsWith("TS")) visitNode(declaration);
|
|
1368
|
+
};
|
|
1353
1369
|
for (const statement of statements) {
|
|
1354
|
-
if (statement.type === "ImportDeclaration" || statement.type === "
|
|
1370
|
+
if (statement.type === "ImportDeclaration" || statement.type === "ExportAllDeclaration") continue;
|
|
1371
|
+
if (statement.type === "ExportNamedDeclaration") {
|
|
1372
|
+
visitExportedDeclarationValues(statement.declaration);
|
|
1373
|
+
continue;
|
|
1374
|
+
}
|
|
1375
|
+
if (statement.type === "ExportDefaultDeclaration") {
|
|
1376
|
+
visitExportedDeclarationValues(statement.declaration);
|
|
1377
|
+
continue;
|
|
1378
|
+
}
|
|
1355
1379
|
visitNode(statement);
|
|
1356
1380
|
}
|
|
1357
1381
|
return references;
|
|
1358
1382
|
};
|
|
1383
|
+
const TS_VALUE_WRAPPER_NODE_TYPES = new Set([
|
|
1384
|
+
"TSAsExpression",
|
|
1385
|
+
"TSSatisfiesExpression",
|
|
1386
|
+
"TSNonNullExpression",
|
|
1387
|
+
"TSInstantiationExpression",
|
|
1388
|
+
"TSTypeAssertion"
|
|
1389
|
+
]);
|
|
1390
|
+
const TS_RUNTIME_DECLARATION_NODE_TYPES = new Set([
|
|
1391
|
+
"TSEnumDeclaration",
|
|
1392
|
+
"TSModuleDeclaration",
|
|
1393
|
+
"TSExportAssignment"
|
|
1394
|
+
]);
|
|
1395
|
+
const FUNCTION_NODE_TYPES = new Set([
|
|
1396
|
+
"FunctionDeclaration",
|
|
1397
|
+
"FunctionExpression",
|
|
1398
|
+
"ArrowFunctionExpression"
|
|
1399
|
+
]);
|
|
1400
|
+
const collectStaticImportLocalNames = (imports) => {
|
|
1401
|
+
const localNames = /* @__PURE__ */ new Set();
|
|
1402
|
+
for (const importInfo of imports) {
|
|
1403
|
+
if (importInfo.isDynamic || importInfo.isTypeOnly) continue;
|
|
1404
|
+
for (const binding of importInfo.importedNames) {
|
|
1405
|
+
if (binding.isTypeOnly) continue;
|
|
1406
|
+
const localName = binding.alias ?? binding.name;
|
|
1407
|
+
if (localName && localName !== "*") localNames.add(localName);
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
return localNames;
|
|
1411
|
+
};
|
|
1412
|
+
const collectTopLevelImportReferences = (bodyNodes, importLocalNames) => {
|
|
1413
|
+
const referencedNames = /* @__PURE__ */ new Set();
|
|
1414
|
+
if (importLocalNames.size === 0) return [];
|
|
1415
|
+
const visitClassBody = (classBody) => {
|
|
1416
|
+
const bodyElements = classBody.body ?? [];
|
|
1417
|
+
for (const element of bodyElements) {
|
|
1418
|
+
if (element.type === "StaticBlock") {
|
|
1419
|
+
visitValueNode(element.body);
|
|
1420
|
+
continue;
|
|
1421
|
+
}
|
|
1422
|
+
if (Boolean(element.computed)) visitValueNode(element.key);
|
|
1423
|
+
const isStatic = Boolean(element.static);
|
|
1424
|
+
if (element.type === "PropertyDefinition" && isStatic) visitValueNode(element.value);
|
|
1425
|
+
visitValueNode(element.decorators);
|
|
1426
|
+
}
|
|
1427
|
+
};
|
|
1428
|
+
const visitValueNode = (node) => {
|
|
1429
|
+
if (Array.isArray(node)) {
|
|
1430
|
+
for (const element of node) visitValueNode(element);
|
|
1431
|
+
return;
|
|
1432
|
+
}
|
|
1433
|
+
if (!isWalkableNode(node)) return;
|
|
1434
|
+
if (node.type === "Identifier" || node.type === "JSXIdentifier") {
|
|
1435
|
+
const identifierName = node.name;
|
|
1436
|
+
if (identifierName && importLocalNames.has(identifierName)) referencedNames.add(identifierName);
|
|
1437
|
+
return;
|
|
1438
|
+
}
|
|
1439
|
+
if (node.type.startsWith("TS")) {
|
|
1440
|
+
if (TS_VALUE_WRAPPER_NODE_TYPES.has(node.type)) {
|
|
1441
|
+
visitValueNode(node.expression);
|
|
1442
|
+
return;
|
|
1443
|
+
}
|
|
1444
|
+
if (!TS_RUNTIME_DECLARATION_NODE_TYPES.has(node.type)) return;
|
|
1445
|
+
}
|
|
1446
|
+
if (FUNCTION_NODE_TYPES.has(node.type)) return;
|
|
1447
|
+
if (node.type === "ClassDeclaration" || node.type === "ClassExpression") {
|
|
1448
|
+
visitValueNode(node.superClass);
|
|
1449
|
+
visitValueNode(node.decorators);
|
|
1450
|
+
const classBody = node.body;
|
|
1451
|
+
if (classBody) visitClassBody(classBody);
|
|
1452
|
+
return;
|
|
1453
|
+
}
|
|
1454
|
+
if (node.type === "CallExpression" || node.type === "NewExpression") {
|
|
1455
|
+
const callee = node.callee;
|
|
1456
|
+
if (callee && FUNCTION_NODE_TYPES.has(callee.type)) visitValueNode(callee.body);
|
|
1457
|
+
}
|
|
1458
|
+
if (node.type === "MemberExpression" || node.type === "JSXMemberExpression") {
|
|
1459
|
+
const memberNode = node;
|
|
1460
|
+
visitValueNode(memberNode.object);
|
|
1461
|
+
if (node.computed) visitValueNode(memberNode.property);
|
|
1462
|
+
return;
|
|
1463
|
+
}
|
|
1464
|
+
if (node.type === "Property") {
|
|
1465
|
+
const propertyNode = node;
|
|
1466
|
+
if (node.computed) visitValueNode(propertyNode.key);
|
|
1467
|
+
visitValueNode(propertyNode.value);
|
|
1468
|
+
return;
|
|
1469
|
+
}
|
|
1470
|
+
for (const value of Object.values(node)) if (Array.isArray(value)) for (const element of value) visitValueNode(element);
|
|
1471
|
+
else if (value && typeof value === "object") visitValueNode(value);
|
|
1472
|
+
};
|
|
1473
|
+
for (const statement of bodyNodes) {
|
|
1474
|
+
if (statement.type === "ImportDeclaration" || statement.type === "ExportAllDeclaration") continue;
|
|
1475
|
+
if (statement.type === "ExportNamedDeclaration" || statement.type === "ExportDefaultDeclaration") {
|
|
1476
|
+
visitValueNode(statement.declaration);
|
|
1477
|
+
continue;
|
|
1478
|
+
}
|
|
1479
|
+
visitValueNode(statement);
|
|
1480
|
+
}
|
|
1481
|
+
return [...referencedNames];
|
|
1482
|
+
};
|
|
1359
1483
|
const createEmptyParsedSource = () => ({
|
|
1360
1484
|
imports: [],
|
|
1361
1485
|
exports: [],
|
|
1362
1486
|
memberAccesses: [],
|
|
1363
1487
|
wholeObjectUses: [],
|
|
1364
1488
|
localIdentifierReferences: [],
|
|
1489
|
+
topLevelImportReferences: [],
|
|
1365
1490
|
referencedFilenames: [],
|
|
1366
1491
|
redundantTypePatterns: [],
|
|
1367
1492
|
identityWrappers: [],
|
|
@@ -1573,6 +1698,7 @@ const parseSourceFile = (filePath) => {
|
|
|
1573
1698
|
collectMemberAccesses(program.body, namespaceLocalNames, memberAccesses, wholeObjectUses);
|
|
1574
1699
|
}, void 0);
|
|
1575
1700
|
const localIdentifierReferences = safeWalk("collectLocalIdentifierReferences", () => collectLocalIdentifierReferences(program.body), []);
|
|
1701
|
+
const topLevelImportReferences = safeWalk("collectTopLevelImportReferences", () => collectTopLevelImportReferences(program.body, collectStaticImportLocalNames(imports)), []);
|
|
1576
1702
|
const redundantTypePatterns = [];
|
|
1577
1703
|
const identityWrappers = [];
|
|
1578
1704
|
const typeDefinitionHashes = [];
|
|
@@ -1617,6 +1743,7 @@ const parseSourceFile = (filePath) => {
|
|
|
1617
1743
|
memberAccesses,
|
|
1618
1744
|
wholeObjectUses,
|
|
1619
1745
|
localIdentifierReferences,
|
|
1746
|
+
topLevelImportReferences,
|
|
1620
1747
|
referencedFilenames: extractReferencedFilenames(sourceText),
|
|
1621
1748
|
redundantTypePatterns,
|
|
1622
1749
|
identityWrappers,
|
|
@@ -1757,6 +1884,29 @@ const collectMemberAccesses = (bodyNodes, namespaceLocalNames, memberAccesses, w
|
|
|
1757
1884
|
const spreadArgument = node.argument;
|
|
1758
1885
|
if (spreadArgument?.type === "Identifier" && namespaceLocalNames.has(spreadArgument.name)) wholeObjectUses.push(spreadArgument.name);
|
|
1759
1886
|
}
|
|
1887
|
+
if (node.type === "VariableDeclarator") {
|
|
1888
|
+
const declarator = node;
|
|
1889
|
+
if (declarator.init?.type === "Identifier" && namespaceLocalNames.has(declarator.init.name) && declarator.id?.type === "ObjectPattern") {
|
|
1890
|
+
const namespaceName = declarator.init.name;
|
|
1891
|
+
const patternProperties = declarator.id.properties;
|
|
1892
|
+
for (const property of patternProperties) {
|
|
1893
|
+
if (property.type === "RestElement") {
|
|
1894
|
+
wholeObjectUses.push(namespaceName);
|
|
1895
|
+
continue;
|
|
1896
|
+
}
|
|
1897
|
+
const propertyKey = property.key;
|
|
1898
|
+
if (Boolean(property.computed)) wholeObjectUses.push(namespaceName);
|
|
1899
|
+
else if (propertyKey?.type === "Identifier" && propertyKey.name) memberAccesses.push({
|
|
1900
|
+
objectName: namespaceName,
|
|
1901
|
+
memberName: propertyKey.name
|
|
1902
|
+
});
|
|
1903
|
+
else if (propertyKey?.type === "Literal" && typeof propertyKey.value === "string") memberAccesses.push({
|
|
1904
|
+
objectName: namespaceName,
|
|
1905
|
+
memberName: propertyKey.value
|
|
1906
|
+
});
|
|
1907
|
+
}
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1760
1910
|
if (node.type === "ForInStatement") {
|
|
1761
1911
|
const forInRight = node.right;
|
|
1762
1912
|
if (forInRight?.type === "Identifier" && namespaceLocalNames.has(forInRight.name)) wholeObjectUses.push(forInRight.name);
|
|
@@ -5090,6 +5240,13 @@ const extractCiWorkflowEntries = (rootDir) => {
|
|
|
5090
5240
|
const entries = [];
|
|
5091
5241
|
const workflowsDir = join(rootDir, ".github", "workflows");
|
|
5092
5242
|
if (!existsSync(workflowsDir)) return entries;
|
|
5243
|
+
const nestedToolPackageJsonPaths = fg.sync("**/package.json", {
|
|
5244
|
+
cwd: join(rootDir, ".github"),
|
|
5245
|
+
absolute: true,
|
|
5246
|
+
onlyFiles: true,
|
|
5247
|
+
ignore: ["**/node_modules/**"]
|
|
5248
|
+
});
|
|
5249
|
+
for (const nestedPackageJsonPath of nestedToolPackageJsonPaths) entries.push(...extractScriptEntries(dirname(nestedPackageJsonPath)));
|
|
5093
5250
|
const workflowFiles = fg.sync("*.{yml,yaml}", {
|
|
5094
5251
|
cwd: workflowsDir,
|
|
5095
5252
|
absolute: true,
|
|
@@ -6692,8 +6849,10 @@ const discoverTestRunnerEntryPoints = (rootDir, workspacePackages) => {
|
|
|
6692
6849
|
customPatterns = extractJestTestMatchPatterns(directory);
|
|
6693
6850
|
if (customPatterns.length === 0 && monorepoRoot) customPatterns = extractJestTestMatchPatterns(monorepoRoot);
|
|
6694
6851
|
}
|
|
6695
|
-
if (customPatterns.length > 0)
|
|
6696
|
-
|
|
6852
|
+
if (customPatterns.length > 0) {
|
|
6853
|
+
activatedPatterns.push(...customPatterns);
|
|
6854
|
+
if (isJestRunner) activatedPatterns.push("**/__mocks__/**/*.{ts,tsx,js,jsx,mjs,cjs}");
|
|
6855
|
+
} else activatedPatterns.push(...runner.entryPatterns);
|
|
6697
6856
|
activatedFixturePatterns.push(...runner.fixturePatterns);
|
|
6698
6857
|
activatedAlwaysUsed.push(...runner.alwaysUsed);
|
|
6699
6858
|
}
|
|
@@ -6924,6 +7083,7 @@ const deserializeParsedSource = (serialized) => ({
|
|
|
6924
7083
|
memberAccesses: serialized.memberAccesses,
|
|
6925
7084
|
wholeObjectUses: serialized.wholeObjectUses,
|
|
6926
7085
|
localIdentifierReferences: serialized.localIdentifierReferences,
|
|
7086
|
+
topLevelImportReferences: serialized.topLevelImportReferences,
|
|
6927
7087
|
referencedFilenames: serialized.referencedFilenames,
|
|
6928
7088
|
redundantTypePatterns: serialized.redundantTypePatterns,
|
|
6929
7089
|
identityWrappers: serialized.identityWrappers,
|
|
@@ -6988,6 +7148,7 @@ const parseFilesWithWorkerPool = async (files, workerCount) => {
|
|
|
6988
7148
|
memberAccesses: [],
|
|
6989
7149
|
wholeObjectUses: [],
|
|
6990
7150
|
localIdentifierReferences: [],
|
|
7151
|
+
topLevelImportReferences: [],
|
|
6991
7152
|
referencedFilenames: [],
|
|
6992
7153
|
redundantTypePatterns: [],
|
|
6993
7154
|
identityWrappers: [],
|
|
@@ -7062,6 +7223,7 @@ const buildDependencyGraph = (inputs) => {
|
|
|
7062
7223
|
memberAccesses: input.parsed.memberAccesses,
|
|
7063
7224
|
wholeObjectUses: input.parsed.wholeObjectUses,
|
|
7064
7225
|
localIdentifierReferences: input.parsed.localIdentifierReferences,
|
|
7226
|
+
topLevelImportReferences: input.parsed.topLevelImportReferences,
|
|
7065
7227
|
referencedFilenames: input.parsed.referencedFilenames,
|
|
7066
7228
|
redundantTypePatterns: input.parsed.redundantTypePatterns,
|
|
7067
7229
|
identityWrappers: input.parsed.identityWrappers,
|
|
@@ -7080,12 +7242,13 @@ const buildDependencyGraph = (inputs) => {
|
|
|
7080
7242
|
}));
|
|
7081
7243
|
const edges = [];
|
|
7082
7244
|
const reverseEdges = /* @__PURE__ */ new Map();
|
|
7083
|
-
const addEdge = (sourceIndex, targetIndex, symbols, isReExportEdge = false, reExportedNames = [], reExportMappings = []) => {
|
|
7245
|
+
const addEdge = (sourceIndex, targetIndex, symbols, isReExportEdge = false, reExportedNames = [], reExportMappings = [], isDynamic = false) => {
|
|
7084
7246
|
edges.push({
|
|
7085
7247
|
source: sourceIndex,
|
|
7086
7248
|
target: targetIndex,
|
|
7087
7249
|
importedSymbols: symbols,
|
|
7088
7250
|
isReExportEdge,
|
|
7251
|
+
isDynamic,
|
|
7089
7252
|
reExportedNames,
|
|
7090
7253
|
reExportMappings
|
|
7091
7254
|
});
|
|
@@ -7104,7 +7267,7 @@ const buildDependencyGraph = (inputs) => {
|
|
|
7104
7267
|
const relativePath = toPosixPath(path.relative(sourceDir, filePath));
|
|
7105
7268
|
if (minimatch(relativePath.startsWith(".") ? relativePath : `./${relativePath}`, globPattern)) {
|
|
7106
7269
|
const targetIndex = fileIdMap.get(filePath);
|
|
7107
|
-
if (targetIndex !== void 0) addEdge(sourceIndex, targetIndex, []);
|
|
7270
|
+
if (targetIndex !== void 0) addEdge(sourceIndex, targetIndex, [], false, [], [], true);
|
|
7108
7271
|
}
|
|
7109
7272
|
}
|
|
7110
7273
|
continue;
|
|
@@ -7119,7 +7282,7 @@ const buildDependencyGraph = (inputs) => {
|
|
|
7119
7282
|
isTypeOnly: importedName.isTypeOnly,
|
|
7120
7283
|
isNamespace: importedName.isNamespace,
|
|
7121
7284
|
isDefault: importedName.isDefault
|
|
7122
|
-
})));
|
|
7285
|
+
})), false, [], [], importInfo.isDynamic);
|
|
7123
7286
|
}
|
|
7124
7287
|
const reExportsByTarget = /* @__PURE__ */ new Map();
|
|
7125
7288
|
for (const exportInfo of input.parsed.exports) {
|
|
@@ -7361,6 +7524,7 @@ const resolveReExportChains = (graph) => {
|
|
|
7361
7524
|
const buildSourceTargetMap = (graph) => {
|
|
7362
7525
|
const sourceTargets = /* @__PURE__ */ new Map();
|
|
7363
7526
|
for (const edge of graph.edges) {
|
|
7527
|
+
if (!edge.isReExportEdge) continue;
|
|
7364
7528
|
const existing = sourceTargets.get(edge.source);
|
|
7365
7529
|
if (existing) {
|
|
7366
7530
|
if (!existing.includes(edge.target)) existing.push(edge.target);
|
|
@@ -7382,9 +7546,9 @@ const EXCLUDED_EXTENSIONS = new Set([
|
|
|
7382
7546
|
".graphql",
|
|
7383
7547
|
".gql"
|
|
7384
7548
|
]);
|
|
7385
|
-
const TEST_FILE_PATTERN = /(?:\.(?:test|spec|stories|story|cy)\.|(?:^|\/)__tests__\/)/;
|
|
7386
|
-
const EXCLUDED_DIRECTORY_PATTERN = /(?:^|\/)(?:e2e|cypress|playwright|__fixtures__|__snapshots__|scripts)\/(?!.*node_modules)/;
|
|
7387
|
-
const CONFIG_FILE_PATTERN = /(?:^|\/)(?:[^/]+\.config\.[tj]sx?$|[^/]+\.setup\.[tj]sx?$|setupTests\.[tj]sx?$|jest\.setup\.[tj]sx?$|vitest\.setup\.[tj]sx?$)/;
|
|
7549
|
+
const TEST_FILE_PATTERN = /(?:\.(?:test|spec|stories|story|cy|test-d)\.|(?:^|\/)__tests__\/)/;
|
|
7550
|
+
const EXCLUDED_DIRECTORY_PATTERN = /(?:^|\/)(?:e2e|cypress|playwright|__fixtures__|__snapshots__|public|scripts)\/(?!.*node_modules)/;
|
|
7551
|
+
const CONFIG_FILE_PATTERN = /(?:^|\/)(?:[^/]+\.config\.[tj]sx?$|[^/]+\.config\.[^/]+\.[tj]sx?$|[^/]+\.setup\.[tj]sx?$|setupTests\.[tj]sx?$|jest\.setup\.[tj]sx?$|vitest\.setup\.[tj]sx?$)/;
|
|
7388
7552
|
const hasExcludedExtension = (filePath) => {
|
|
7389
7553
|
const lastDot = filePath.lastIndexOf(".");
|
|
7390
7554
|
if (lastDot === -1) return false;
|
|
@@ -7460,6 +7624,7 @@ const detectDeadExports = (graph, config) => {
|
|
|
7460
7624
|
if (usageMap.has(usageKey)) continue;
|
|
7461
7625
|
if (module.localIdentifierReferences.includes(exportInfo.name)) continue;
|
|
7462
7626
|
if (!exportInfo.isDefault && defaultExportLinkedNames.has(exportInfo.name)) continue;
|
|
7627
|
+
if (exportInfo.isDefault && exportInfo.defaultExportLocalName && usageMap.has(`${module.fileId.path}::${exportInfo.defaultExportLocalName}`)) continue;
|
|
7463
7628
|
unusedExports.push({
|
|
7464
7629
|
path: module.fileId.path,
|
|
7465
7630
|
name: exportInfo.name,
|
|
@@ -7494,6 +7659,10 @@ const buildUsageMap = (graph) => {
|
|
|
7494
7659
|
const targetModule = graph.modules[edge.target];
|
|
7495
7660
|
if (!targetModule) continue;
|
|
7496
7661
|
const sourceModule = graph.modules[edge.source];
|
|
7662
|
+
if (edge.isDynamic && edge.importedSymbols.length === 0) {
|
|
7663
|
+
markAllExportsUsedRecursive(targetModule, graph, sourceToTargetMap, usedExportKeys, /* @__PURE__ */ new Set());
|
|
7664
|
+
continue;
|
|
7665
|
+
}
|
|
7497
7666
|
for (const symbol of edge.importedSymbols) if (symbol.isNamespace) handleNamespaceImport(sourceModule, targetModule, symbol.localName, graph, sourceToTargetMap, usedExportKeys);
|
|
7498
7667
|
else {
|
|
7499
7668
|
const importName = symbol.isDefault ? "default" : symbol.importedName;
|
|
@@ -7540,6 +7709,7 @@ const extractAccessedMemberNames = (memberAccesses, objectName) => {
|
|
|
7540
7709
|
const buildSourceToTargetsMap = (graph) => {
|
|
7541
7710
|
const sourceToTargets = /* @__PURE__ */ new Map();
|
|
7542
7711
|
for (const edge of graph.edges) {
|
|
7712
|
+
if (!edge.isReExportEdge) continue;
|
|
7543
7713
|
const existing = sourceToTargets.get(edge.source);
|
|
7544
7714
|
if (existing) {
|
|
7545
7715
|
if (!existing.includes(edge.target)) existing.push(edge.target);
|
|
@@ -7883,10 +8053,12 @@ const hasJsxFiles = (graph) => graph.modules.some((module) => {
|
|
|
7883
8053
|
const filePath = module.fileId.path;
|
|
7884
8054
|
return filePath.endsWith(".tsx") || filePath.endsWith(".jsx");
|
|
7885
8055
|
});
|
|
8056
|
+
const KNOWN_PEER_DEPENDENCY_NAMES = new Map([["vitest-axe", ["axe-core"]], ["jest-axe", ["axe-core"]]]);
|
|
7886
8057
|
const collectPeerSatisfiedPackages = (nodeModulesSearchRoots, declaredNames, confirmedUsedNames) => {
|
|
7887
8058
|
const peerSatisfied = /* @__PURE__ */ new Set();
|
|
7888
8059
|
for (const installedName of declaredNames) {
|
|
7889
8060
|
if (!confirmedUsedNames.has(installedName)) continue;
|
|
8061
|
+
for (const knownPeerName of KNOWN_PEER_DEPENDENCY_NAMES.get(installedName) ?? []) if (declaredNames.has(knownPeerName)) peerSatisfied.add(knownPeerName);
|
|
7890
8062
|
const installedPackageJsonPath = findInstalledPackageJsonPath(installedName, nodeModulesSearchRoots);
|
|
7891
8063
|
if (!installedPackageJsonPath) continue;
|
|
7892
8064
|
try {
|
|
@@ -7909,22 +8081,41 @@ const findInstalledPackageJsonPath = (packageName, nodeModulesSearchRoots) => {
|
|
|
7909
8081
|
};
|
|
7910
8082
|
const SHELL_SPLIT_PATTERN = /\s*(?:&&|\|\||[;&|])\s*/;
|
|
7911
8083
|
const INLINE_ENV_VAR_PATTERN = /^[A-Z_][A-Z0-9_]*=/;
|
|
8084
|
+
const KNOWN_PACKAGE_BIN_NAMES = new Map([
|
|
8085
|
+
["@tauri-apps/cli", ["tauri"]],
|
|
8086
|
+
["@typescript/native-preview", ["tsgo"]],
|
|
8087
|
+
["playwright-chromium", ["playwright"]],
|
|
8088
|
+
["playwright-firefox", ["playwright"]],
|
|
8089
|
+
["playwright-webkit", ["playwright"]]
|
|
8090
|
+
]);
|
|
8091
|
+
const staticBinNamesForPackage = (packageName) => {
|
|
8092
|
+
const binNames = [...KNOWN_PACKAGE_BIN_NAMES.get(packageName) ?? []];
|
|
8093
|
+
const unscopedName = packageName.split("/").pop();
|
|
8094
|
+
if (unscopedName.endsWith("-cli") && unscopedName.length > 4) binNames.push(unscopedName.slice(0, -4));
|
|
8095
|
+
return binNames;
|
|
8096
|
+
};
|
|
7912
8097
|
const buildBinaryPackageIndex = (nodeModulesSearchRoots, declaredNames) => {
|
|
7913
8098
|
const binToPackage = /* @__PURE__ */ new Map();
|
|
7914
8099
|
const packagesProvidingBinary = /* @__PURE__ */ new Set();
|
|
8100
|
+
const addBinMapping = (binaryName, packageName) => {
|
|
8101
|
+
const mappedPackages = binToPackage.get(binaryName) ?? /* @__PURE__ */ new Set();
|
|
8102
|
+
mappedPackages.add(packageName);
|
|
8103
|
+
binToPackage.set(binaryName, mappedPackages);
|
|
8104
|
+
};
|
|
7915
8105
|
for (const packageName of declaredNames) {
|
|
8106
|
+
for (const staticBinName of staticBinNamesForPackage(packageName)) addBinMapping(staticBinName, packageName);
|
|
7916
8107
|
const packageBinJsonPath = findInstalledPackageJsonPath(packageName, nodeModulesSearchRoots);
|
|
7917
8108
|
if (!packageBinJsonPath) continue;
|
|
7918
8109
|
try {
|
|
7919
8110
|
const binContent = readFileSync(packageBinJsonPath, "utf-8");
|
|
7920
8111
|
const binField = JSON.parse(binContent).bin;
|
|
7921
8112
|
if (typeof binField === "string" && binField.length > 0) {
|
|
7922
|
-
|
|
8113
|
+
addBinMapping(packageName.split("/").pop(), packageName);
|
|
7923
8114
|
packagesProvidingBinary.add(packageName);
|
|
7924
8115
|
} else if (typeof binField === "object" && binField !== null) {
|
|
7925
8116
|
const binaryNames = Object.keys(binField);
|
|
7926
8117
|
if (binaryNames.length === 0) continue;
|
|
7927
|
-
for (const binaryName of binaryNames)
|
|
8118
|
+
for (const binaryName of binaryNames) addBinMapping(binaryName, packageName);
|
|
7928
8119
|
packagesProvidingBinary.add(packageName);
|
|
7929
8120
|
}
|
|
7930
8121
|
} catch {
|
|
@@ -7969,8 +8160,7 @@ const collectCommandReferencedPackages = (command, declaredNames, binToPackage)
|
|
|
7969
8160
|
const effectiveBinary = binaryToken === "npx" || binaryToken === "pnpx" || binaryToken === "bunx" ? tokens[binaryIndex + 1]?.replace(/^.*\//, "") ?? "" : binaryToken;
|
|
7970
8161
|
for (const candidateBinary of [binaryToken, effectiveBinary]) {
|
|
7971
8162
|
if (!candidateBinary) continue;
|
|
7972
|
-
const mappedPackage
|
|
7973
|
-
if (mappedPackage && declaredNames.has(mappedPackage)) referenced.add(mappedPackage);
|
|
8163
|
+
for (const mappedPackage of binToPackage.get(candidateBinary) ?? []) if (declaredNames.has(mappedPackage)) referenced.add(mappedPackage);
|
|
7974
8164
|
if (declaredNames.has(candidateBinary)) referenced.add(candidateBinary);
|
|
7975
8165
|
}
|
|
7976
8166
|
}
|
|
@@ -8050,6 +8240,12 @@ const collectConfigReferencedPackages = (rootDir, graph, declaredNames, summaryC
|
|
|
8050
8240
|
deep: 6
|
|
8051
8241
|
}, summaryCache);
|
|
8052
8242
|
for (const documentationPath of documentationFiles) addMatchesFromFile(documentationPath, "importReference", matchesPackageImportReference);
|
|
8243
|
+
const toolingSourceFiles = globPackageFiles(rootDir, ["**/{.dumi,.storybook,.docz,.styleguidist}/**/*.{ts,tsx,js,jsx,mts,mjs}"], {
|
|
8244
|
+
ignore: ["**/node_modules/**"],
|
|
8245
|
+
dot: true,
|
|
8246
|
+
deep: 8
|
|
8247
|
+
}, summaryCache);
|
|
8248
|
+
for (const toolingSourcePath of toolingSourceFiles) addMatchesFromFile(toolingSourcePath, "importReference", matchesPackageImportReference);
|
|
8053
8249
|
return referenced;
|
|
8054
8250
|
};
|
|
8055
8251
|
const PACKAGE_JSON_CONFIG_SECTIONS = [
|
|
@@ -8302,14 +8498,47 @@ const isAlwaysConsideredUsed = (dependencyName) => {
|
|
|
8302
8498
|
//#endregion
|
|
8303
8499
|
//#region src/report/cycles.ts
|
|
8304
8500
|
const UNDEFINED_INDEX = -1;
|
|
8501
|
+
const isCompileTimeErasedEdge = (edge, graph) => {
|
|
8502
|
+
if (edge.isReExportEdge) return false;
|
|
8503
|
+
if (edge.importedSymbols.length === 0) return false;
|
|
8504
|
+
const targetModule = graph.modules[edge.target];
|
|
8505
|
+
if (!targetModule) return false;
|
|
8506
|
+
return edge.importedSymbols.every((symbol) => {
|
|
8507
|
+
if (symbol.isTypeOnly) return true;
|
|
8508
|
+
if (symbol.isNamespace) return false;
|
|
8509
|
+
const exportName = symbol.isDefault ? "default" : symbol.importedName;
|
|
8510
|
+
const matchingExports = targetModule.exports.filter((exportInfo) => exportInfo.name === exportName);
|
|
8511
|
+
return matchingExports.length > 0 && matchingExports.every((exportInfo) => exportInfo.isTypeOnly);
|
|
8512
|
+
});
|
|
8513
|
+
};
|
|
8305
8514
|
const buildAdjacencyList = (graph) => {
|
|
8306
8515
|
const targetSets = Array.from({ length: graph.modules.length }, () => /* @__PURE__ */ new Set());
|
|
8307
8516
|
for (const edge of graph.edges) {
|
|
8517
|
+
if (edge.isDynamic) continue;
|
|
8308
8518
|
if (edge.importedSymbols.every((symbol) => symbol.isTypeOnly)) continue;
|
|
8519
|
+
if (isCompileTimeErasedEdge(edge, graph)) continue;
|
|
8309
8520
|
if (edge.target < graph.modules.length) targetSets[edge.source].add(edge.target);
|
|
8310
8521
|
}
|
|
8311
8522
|
return targetSets.map((targets) => [...targets]);
|
|
8312
8523
|
};
|
|
8524
|
+
const buildModuleInitAccessEdgeSet = (graph) => {
|
|
8525
|
+
const initAccessEdges = /* @__PURE__ */ new Set();
|
|
8526
|
+
for (const edge of graph.edges) {
|
|
8527
|
+
if (edge.isDynamic || edge.isReExportEdge) continue;
|
|
8528
|
+
const topLevelReferences = graph.modules[edge.source]?.topLevelImportReferences;
|
|
8529
|
+
if (!topLevelReferences || topLevelReferences.length === 0) continue;
|
|
8530
|
+
if (edge.importedSymbols.some((symbol) => !symbol.isTypeOnly && topLevelReferences.includes(symbol.localName))) initAccessEdges.add(`${edge.source}:${edge.target}`);
|
|
8531
|
+
}
|
|
8532
|
+
return initAccessEdges;
|
|
8533
|
+
};
|
|
8534
|
+
const cycleHasModuleInitAccess = (cycle, initAccessEdges) => {
|
|
8535
|
+
for (let position = 0; position < cycle.length; position++) {
|
|
8536
|
+
const source = cycle[position];
|
|
8537
|
+
const target = cycle[(position + 1) % cycle.length];
|
|
8538
|
+
if (initAccessEdges.has(`${source}:${target}`)) return true;
|
|
8539
|
+
}
|
|
8540
|
+
return false;
|
|
8541
|
+
};
|
|
8313
8542
|
const findStronglyConnectedComponents = (adjacencyList) => {
|
|
8314
8543
|
const nodeCount = adjacencyList.length;
|
|
8315
8544
|
if (nodeCount === 0) return [];
|
|
@@ -8430,6 +8659,7 @@ const enumerateElementaryCycles = (componentNodes, adjacencyList, graph) => {
|
|
|
8430
8659
|
};
|
|
8431
8660
|
const detectCycles = (graph) => {
|
|
8432
8661
|
const adjacencyList = buildAdjacencyList(graph);
|
|
8662
|
+
const initAccessEdges = buildModuleInitAccessEdgeSet(graph);
|
|
8433
8663
|
const components = findStronglyConnectedComponents(adjacencyList);
|
|
8434
8664
|
const allCycles = [];
|
|
8435
8665
|
const seenKeys = /* @__PURE__ */ new Set();
|
|
@@ -8439,6 +8669,7 @@ const detectCycles = (graph) => {
|
|
|
8439
8669
|
if (component.length > 50) continue;
|
|
8440
8670
|
const elementaryCycles = enumerateElementaryCycles(component, adjacencyList, graph);
|
|
8441
8671
|
for (const cycle of elementaryCycles) {
|
|
8672
|
+
if (!cycleHasModuleInitAccess(cycle, initAccessEdges)) continue;
|
|
8442
8673
|
const key = cycle.join(",");
|
|
8443
8674
|
if (!seenKeys.has(key)) {
|
|
8444
8675
|
seenKeys.add(key);
|
|
@@ -12463,7 +12694,7 @@ const isRecordValue = (value) => typeof value === "object" && value !== null &&
|
|
|
12463
12694
|
const isStringArray = (value) => Array.isArray(value) && value.every((entry) => typeof entry === "string");
|
|
12464
12695
|
const isOptionalArray = (value) => value === void 0 || Array.isArray(value);
|
|
12465
12696
|
const emptyStore = (scopeHash) => ({
|
|
12466
|
-
version:
|
|
12697
|
+
version: 3,
|
|
12467
12698
|
scopeHash,
|
|
12468
12699
|
fileList: null,
|
|
12469
12700
|
resolutions: null,
|
|
@@ -12473,10 +12704,10 @@ const emptyStore = (scopeHash) => ({
|
|
|
12473
12704
|
const readPersistedStore = (cachePath, scopeHash) => {
|
|
12474
12705
|
try {
|
|
12475
12706
|
const parsed = JSON.parse(readFileSync(cachePath, "utf-8"));
|
|
12476
|
-
if (isRecordValue(parsed) && parsed.version ===
|
|
12707
|
+
if (isRecordValue(parsed) && parsed.version === 3 && parsed.scopeHash === scopeHash && isRecordValue(parsed.summaries) && isRecordValue(parsed.packageFacts)) {
|
|
12477
12708
|
const persisted = parsed;
|
|
12478
12709
|
return {
|
|
12479
|
-
version:
|
|
12710
|
+
version: 3,
|
|
12480
12711
|
scopeHash,
|
|
12481
12712
|
fileList: isRecordValue(persisted.fileList) ? persisted.fileList : null,
|
|
12482
12713
|
resolutions: isRecordValue(persisted.resolutions) && typeof persisted.resolutions.hash === "string" && isRecordValue(persisted.resolutions.entries) ? persisted.resolutions : null,
|
|
@@ -12499,6 +12730,7 @@ const serializeParsedSource = (parsed, shouldPersistDryPatternFields) => ({
|
|
|
12499
12730
|
memberAccesses: toPersistedArray(parsed.memberAccesses),
|
|
12500
12731
|
wholeObjectUses: toPersistedArray(parsed.wholeObjectUses),
|
|
12501
12732
|
localIdentifierReferences: toPersistedArray(intersectLocalReferencesWithOwnExports(parsed)),
|
|
12733
|
+
topLevelImportReferences: toPersistedArray(parsed.topLevelImportReferences),
|
|
12502
12734
|
referencedFilenames: toPersistedArray(parsed.referencedFilenames),
|
|
12503
12735
|
...shouldPersistDryPatternFields ? {
|
|
12504
12736
|
redundantTypePatterns: toPersistedArray(parsed.redundantTypePatterns),
|
|
@@ -12518,6 +12750,7 @@ const PERSISTED_SOURCE_ARRAY_FIELDS = [
|
|
|
12518
12750
|
"memberAccesses",
|
|
12519
12751
|
"wholeObjectUses",
|
|
12520
12752
|
"localIdentifierReferences",
|
|
12753
|
+
"topLevelImportReferences",
|
|
12521
12754
|
"referencedFilenames",
|
|
12522
12755
|
"redundantTypePatterns",
|
|
12523
12756
|
"identityWrappers",
|
|
@@ -12540,6 +12773,7 @@ const reviveParsedSource = (persisted) => {
|
|
|
12540
12773
|
memberAccesses: source.memberAccesses ?? [],
|
|
12541
12774
|
wholeObjectUses: source.wholeObjectUses ?? [],
|
|
12542
12775
|
localIdentifierReferences: source.localIdentifierReferences ?? [],
|
|
12776
|
+
topLevelImportReferences: source.topLevelImportReferences ?? [],
|
|
12543
12777
|
referencedFilenames: source.referencedFilenames ?? [],
|
|
12544
12778
|
redundantTypePatterns: source.redundantTypePatterns ?? [],
|
|
12545
12779
|
identityWrappers: source.identityWrappers ?? [],
|
|
@@ -12743,7 +12977,7 @@ const createSummaryCache = (cachePath, config) => {
|
|
|
12743
12977
|
if (resolutionEntry !== void 0) compactedResolutions[resolutionKey] = resolutionEntry;
|
|
12744
12978
|
}
|
|
12745
12979
|
const serialized = JSON.stringify({
|
|
12746
|
-
version:
|
|
12980
|
+
version: 3,
|
|
12747
12981
|
scopeHash,
|
|
12748
12982
|
fileList: store.fileList,
|
|
12749
12983
|
resolutions: {
|
|
@@ -13258,9 +13492,13 @@ const analyze = async (config) => {
|
|
|
13258
13492
|
if (discoveredFilePaths.has(resolvedImport.resolvedPath)) continue;
|
|
13259
13493
|
if (STYLE_EXTENSIONS.some((ext) => resolvedImport.resolvedPath.endsWith(ext)) && existsSync(resolvedImport.resolvedPath)) styleFilesToAdd.add(resolvedImport.resolvedPath);
|
|
13260
13494
|
}
|
|
13261
|
-
const
|
|
13495
|
+
const styleFileQueue = [...styleFilesToAdd].sort();
|
|
13262
13496
|
let nextFileIndex = files.length;
|
|
13263
|
-
|
|
13497
|
+
let styleFileQueueIndex = 0;
|
|
13498
|
+
while (styleFileQueueIndex < styleFileQueue.length) {
|
|
13499
|
+
const styleFilePath = styleFileQueue[styleFileQueueIndex];
|
|
13500
|
+
styleFileQueueIndex++;
|
|
13501
|
+
if (discoveredFilePaths.has(styleFilePath)) continue;
|
|
13264
13502
|
const styleSourceFile = {
|
|
13265
13503
|
index: nextFileIndex,
|
|
13266
13504
|
path: styleFilePath
|
|
@@ -13286,7 +13524,10 @@ const analyze = async (config) => {
|
|
|
13286
13524
|
}
|
|
13287
13525
|
resolvedStyleImportMap.set(importInfo.specifier, resolvedImport);
|
|
13288
13526
|
if (resolvedImport.resolvedPath && !discoveredFilePaths.has(resolvedImport.resolvedPath)) {
|
|
13289
|
-
if (STYLE_EXTENSIONS.some((ext) => resolvedImport.resolvedPath.endsWith(ext)) &&
|
|
13527
|
+
if (STYLE_EXTENSIONS.some((ext) => resolvedImport.resolvedPath.endsWith(ext)) && !styleFilesToAdd.has(resolvedImport.resolvedPath) && existsSync(resolvedImport.resolvedPath)) {
|
|
13528
|
+
styleFilesToAdd.add(resolvedImport.resolvedPath);
|
|
13529
|
+
styleFileQueue.push(resolvedImport.resolvedPath);
|
|
13530
|
+
}
|
|
13290
13531
|
}
|
|
13291
13532
|
}
|
|
13292
13533
|
graphInputs.push({
|
|
@@ -1365,6 +1365,7 @@ const parseCssImports = (filePath) => {
|
|
|
1365
1365
|
memberAccesses: [],
|
|
1366
1366
|
wholeObjectUses: [],
|
|
1367
1367
|
localIdentifierReferences: [],
|
|
1368
|
+
topLevelImportReferences: [],
|
|
1368
1369
|
referencedFilenames: [],
|
|
1369
1370
|
redundantTypePatterns: [],
|
|
1370
1371
|
identityWrappers: [],
|
|
@@ -1393,18 +1394,142 @@ const collectLocalIdentifierReferences = (statements) => {
|
|
|
1393
1394
|
for (const value of Object.values(record)) if (Array.isArray(value)) for (const innerValue of value) visitNode(innerValue);
|
|
1394
1395
|
else if (value && typeof value === "object") visitNode(value);
|
|
1395
1396
|
};
|
|
1397
|
+
const visitExportedDeclarationValues = (declaration) => {
|
|
1398
|
+
if (!declaration || typeof declaration !== "object") return;
|
|
1399
|
+
const record = declaration;
|
|
1400
|
+
if (record.type === "VariableDeclaration" && Array.isArray(record.declarations)) {
|
|
1401
|
+
for (const declarator of record.declarations) if (declarator && typeof declarator === "object") visitNode(declarator.init);
|
|
1402
|
+
return;
|
|
1403
|
+
}
|
|
1404
|
+
if (record.type === "FunctionDeclaration" || record.type === "ClassDeclaration") {
|
|
1405
|
+
visitNode(record.params);
|
|
1406
|
+
visitNode(record.superClass);
|
|
1407
|
+
visitNode(record.body);
|
|
1408
|
+
return;
|
|
1409
|
+
}
|
|
1410
|
+
if (typeof record.type === "string" && !record.type.startsWith("TS")) visitNode(declaration);
|
|
1411
|
+
};
|
|
1396
1412
|
for (const statement of statements) {
|
|
1397
|
-
if (statement.type === "ImportDeclaration" || statement.type === "
|
|
1413
|
+
if (statement.type === "ImportDeclaration" || statement.type === "ExportAllDeclaration") continue;
|
|
1414
|
+
if (statement.type === "ExportNamedDeclaration") {
|
|
1415
|
+
visitExportedDeclarationValues(statement.declaration);
|
|
1416
|
+
continue;
|
|
1417
|
+
}
|
|
1418
|
+
if (statement.type === "ExportDefaultDeclaration") {
|
|
1419
|
+
visitExportedDeclarationValues(statement.declaration);
|
|
1420
|
+
continue;
|
|
1421
|
+
}
|
|
1398
1422
|
visitNode(statement);
|
|
1399
1423
|
}
|
|
1400
1424
|
return references;
|
|
1401
1425
|
};
|
|
1426
|
+
const TS_VALUE_WRAPPER_NODE_TYPES = new Set([
|
|
1427
|
+
"TSAsExpression",
|
|
1428
|
+
"TSSatisfiesExpression",
|
|
1429
|
+
"TSNonNullExpression",
|
|
1430
|
+
"TSInstantiationExpression",
|
|
1431
|
+
"TSTypeAssertion"
|
|
1432
|
+
]);
|
|
1433
|
+
const TS_RUNTIME_DECLARATION_NODE_TYPES = new Set([
|
|
1434
|
+
"TSEnumDeclaration",
|
|
1435
|
+
"TSModuleDeclaration",
|
|
1436
|
+
"TSExportAssignment"
|
|
1437
|
+
]);
|
|
1438
|
+
const FUNCTION_NODE_TYPES = new Set([
|
|
1439
|
+
"FunctionDeclaration",
|
|
1440
|
+
"FunctionExpression",
|
|
1441
|
+
"ArrowFunctionExpression"
|
|
1442
|
+
]);
|
|
1443
|
+
const collectStaticImportLocalNames = (imports) => {
|
|
1444
|
+
const localNames = /* @__PURE__ */ new Set();
|
|
1445
|
+
for (const importInfo of imports) {
|
|
1446
|
+
if (importInfo.isDynamic || importInfo.isTypeOnly) continue;
|
|
1447
|
+
for (const binding of importInfo.importedNames) {
|
|
1448
|
+
if (binding.isTypeOnly) continue;
|
|
1449
|
+
const localName = binding.alias ?? binding.name;
|
|
1450
|
+
if (localName && localName !== "*") localNames.add(localName);
|
|
1451
|
+
}
|
|
1452
|
+
}
|
|
1453
|
+
return localNames;
|
|
1454
|
+
};
|
|
1455
|
+
const collectTopLevelImportReferences = (bodyNodes, importLocalNames) => {
|
|
1456
|
+
const referencedNames = /* @__PURE__ */ new Set();
|
|
1457
|
+
if (importLocalNames.size === 0) return [];
|
|
1458
|
+
const visitClassBody = (classBody) => {
|
|
1459
|
+
const bodyElements = classBody.body ?? [];
|
|
1460
|
+
for (const element of bodyElements) {
|
|
1461
|
+
if (element.type === "StaticBlock") {
|
|
1462
|
+
visitValueNode(element.body);
|
|
1463
|
+
continue;
|
|
1464
|
+
}
|
|
1465
|
+
if (Boolean(element.computed)) visitValueNode(element.key);
|
|
1466
|
+
const isStatic = Boolean(element.static);
|
|
1467
|
+
if (element.type === "PropertyDefinition" && isStatic) visitValueNode(element.value);
|
|
1468
|
+
visitValueNode(element.decorators);
|
|
1469
|
+
}
|
|
1470
|
+
};
|
|
1471
|
+
const visitValueNode = (node) => {
|
|
1472
|
+
if (Array.isArray(node)) {
|
|
1473
|
+
for (const element of node) visitValueNode(element);
|
|
1474
|
+
return;
|
|
1475
|
+
}
|
|
1476
|
+
if (!isWalkableNode(node)) return;
|
|
1477
|
+
if (node.type === "Identifier" || node.type === "JSXIdentifier") {
|
|
1478
|
+
const identifierName = node.name;
|
|
1479
|
+
if (identifierName && importLocalNames.has(identifierName)) referencedNames.add(identifierName);
|
|
1480
|
+
return;
|
|
1481
|
+
}
|
|
1482
|
+
if (node.type.startsWith("TS")) {
|
|
1483
|
+
if (TS_VALUE_WRAPPER_NODE_TYPES.has(node.type)) {
|
|
1484
|
+
visitValueNode(node.expression);
|
|
1485
|
+
return;
|
|
1486
|
+
}
|
|
1487
|
+
if (!TS_RUNTIME_DECLARATION_NODE_TYPES.has(node.type)) return;
|
|
1488
|
+
}
|
|
1489
|
+
if (FUNCTION_NODE_TYPES.has(node.type)) return;
|
|
1490
|
+
if (node.type === "ClassDeclaration" || node.type === "ClassExpression") {
|
|
1491
|
+
visitValueNode(node.superClass);
|
|
1492
|
+
visitValueNode(node.decorators);
|
|
1493
|
+
const classBody = node.body;
|
|
1494
|
+
if (classBody) visitClassBody(classBody);
|
|
1495
|
+
return;
|
|
1496
|
+
}
|
|
1497
|
+
if (node.type === "CallExpression" || node.type === "NewExpression") {
|
|
1498
|
+
const callee = node.callee;
|
|
1499
|
+
if (callee && FUNCTION_NODE_TYPES.has(callee.type)) visitValueNode(callee.body);
|
|
1500
|
+
}
|
|
1501
|
+
if (node.type === "MemberExpression" || node.type === "JSXMemberExpression") {
|
|
1502
|
+
const memberNode = node;
|
|
1503
|
+
visitValueNode(memberNode.object);
|
|
1504
|
+
if (node.computed) visitValueNode(memberNode.property);
|
|
1505
|
+
return;
|
|
1506
|
+
}
|
|
1507
|
+
if (node.type === "Property") {
|
|
1508
|
+
const propertyNode = node;
|
|
1509
|
+
if (node.computed) visitValueNode(propertyNode.key);
|
|
1510
|
+
visitValueNode(propertyNode.value);
|
|
1511
|
+
return;
|
|
1512
|
+
}
|
|
1513
|
+
for (const value of Object.values(node)) if (Array.isArray(value)) for (const element of value) visitValueNode(element);
|
|
1514
|
+
else if (value && typeof value === "object") visitValueNode(value);
|
|
1515
|
+
};
|
|
1516
|
+
for (const statement of bodyNodes) {
|
|
1517
|
+
if (statement.type === "ImportDeclaration" || statement.type === "ExportAllDeclaration") continue;
|
|
1518
|
+
if (statement.type === "ExportNamedDeclaration" || statement.type === "ExportDefaultDeclaration") {
|
|
1519
|
+
visitValueNode(statement.declaration);
|
|
1520
|
+
continue;
|
|
1521
|
+
}
|
|
1522
|
+
visitValueNode(statement);
|
|
1523
|
+
}
|
|
1524
|
+
return [...referencedNames];
|
|
1525
|
+
};
|
|
1402
1526
|
const createEmptyParsedSource = () => ({
|
|
1403
1527
|
imports: [],
|
|
1404
1528
|
exports: [],
|
|
1405
1529
|
memberAccesses: [],
|
|
1406
1530
|
wholeObjectUses: [],
|
|
1407
1531
|
localIdentifierReferences: [],
|
|
1532
|
+
topLevelImportReferences: [],
|
|
1408
1533
|
referencedFilenames: [],
|
|
1409
1534
|
redundantTypePatterns: [],
|
|
1410
1535
|
identityWrappers: [],
|
|
@@ -1616,6 +1741,7 @@ const parseSourceFile = (filePath) => {
|
|
|
1616
1741
|
collectMemberAccesses(program.body, namespaceLocalNames, memberAccesses, wholeObjectUses);
|
|
1617
1742
|
}, void 0);
|
|
1618
1743
|
const localIdentifierReferences = safeWalk("collectLocalIdentifierReferences", () => collectLocalIdentifierReferences(program.body), []);
|
|
1744
|
+
const topLevelImportReferences = safeWalk("collectTopLevelImportReferences", () => collectTopLevelImportReferences(program.body, collectStaticImportLocalNames(imports)), []);
|
|
1619
1745
|
const redundantTypePatterns = [];
|
|
1620
1746
|
const identityWrappers = [];
|
|
1621
1747
|
const typeDefinitionHashes = [];
|
|
@@ -1660,6 +1786,7 @@ const parseSourceFile = (filePath) => {
|
|
|
1660
1786
|
memberAccesses,
|
|
1661
1787
|
wholeObjectUses,
|
|
1662
1788
|
localIdentifierReferences,
|
|
1789
|
+
topLevelImportReferences,
|
|
1663
1790
|
referencedFilenames: extractReferencedFilenames(sourceText),
|
|
1664
1791
|
redundantTypePatterns,
|
|
1665
1792
|
identityWrappers,
|
|
@@ -1800,6 +1927,29 @@ const collectMemberAccesses = (bodyNodes, namespaceLocalNames, memberAccesses, w
|
|
|
1800
1927
|
const spreadArgument = node.argument;
|
|
1801
1928
|
if (spreadArgument?.type === "Identifier" && namespaceLocalNames.has(spreadArgument.name)) wholeObjectUses.push(spreadArgument.name);
|
|
1802
1929
|
}
|
|
1930
|
+
if (node.type === "VariableDeclarator") {
|
|
1931
|
+
const declarator = node;
|
|
1932
|
+
if (declarator.init?.type === "Identifier" && namespaceLocalNames.has(declarator.init.name) && declarator.id?.type === "ObjectPattern") {
|
|
1933
|
+
const namespaceName = declarator.init.name;
|
|
1934
|
+
const patternProperties = declarator.id.properties;
|
|
1935
|
+
for (const property of patternProperties) {
|
|
1936
|
+
if (property.type === "RestElement") {
|
|
1937
|
+
wholeObjectUses.push(namespaceName);
|
|
1938
|
+
continue;
|
|
1939
|
+
}
|
|
1940
|
+
const propertyKey = property.key;
|
|
1941
|
+
if (Boolean(property.computed)) wholeObjectUses.push(namespaceName);
|
|
1942
|
+
else if (propertyKey?.type === "Identifier" && propertyKey.name) memberAccesses.push({
|
|
1943
|
+
objectName: namespaceName,
|
|
1944
|
+
memberName: propertyKey.name
|
|
1945
|
+
});
|
|
1946
|
+
else if (propertyKey?.type === "Literal" && typeof propertyKey.value === "string") memberAccesses.push({
|
|
1947
|
+
objectName: namespaceName,
|
|
1948
|
+
memberName: propertyKey.value
|
|
1949
|
+
});
|
|
1950
|
+
}
|
|
1951
|
+
}
|
|
1952
|
+
}
|
|
1803
1953
|
if (node.type === "ForInStatement") {
|
|
1804
1954
|
const forInRight = node.right;
|
|
1805
1955
|
if (forInRight?.type === "Identifier" && namespaceLocalNames.has(forInRight.name)) wholeObjectUses.push(forInRight.name);
|
package/dist/parse-worker.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as parseSourceFile } from "./parse-
|
|
1
|
+
import { n as parseSourceFile } from "./parse-CDdo_Ppt.mjs";
|
|
2
2
|
import { parentPort } from "node:worker_threads";
|
|
3
3
|
|
|
4
4
|
//#region src/collect/parse-worker.ts
|
|
@@ -16,6 +16,7 @@ port.on("message", (message) => {
|
|
|
16
16
|
memberAccesses: parsed.memberAccesses,
|
|
17
17
|
wholeObjectUses: parsed.wholeObjectUses,
|
|
18
18
|
localIdentifierReferences: parsed.localIdentifierReferences,
|
|
19
|
+
topLevelImportReferences: parsed.topLevelImportReferences,
|
|
19
20
|
referencedFilenames: parsed.referencedFilenames,
|
|
20
21
|
redundantTypePatterns: parsed.redundantTypePatterns,
|
|
21
22
|
identityWrappers: parsed.identityWrappers,
|