@depxray/core 1.3.0
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/buildGraph.d.ts +11 -0
- package/dist/buildGraph.d.ts.map +1 -0
- package/dist/buildGraph.js +111 -0
- package/dist/buildGraph.js.map +1 -0
- package/dist/buildStructureGraph.d.ts +3 -0
- package/dist/buildStructureGraph.d.ts.map +1 -0
- package/dist/buildStructureGraph.js +45 -0
- package/dist/buildStructureGraph.js.map +1 -0
- package/dist/configLoader.d.ts +18 -0
- package/dist/configLoader.d.ts.map +1 -0
- package/dist/configLoader.js +188 -0
- package/dist/configLoader.js.map +1 -0
- package/dist/detectCircularDeps.d.ts +21 -0
- package/dist/detectCircularDeps.d.ts.map +1 -0
- package/dist/detectCircularDeps.js +159 -0
- package/dist/detectCircularDeps.js.map +1 -0
- package/dist/detectOrphanFiles.d.ts +4 -0
- package/dist/detectOrphanFiles.d.ts.map +1 -0
- package/dist/detectOrphanFiles.js +58 -0
- package/dist/detectOrphanFiles.js.map +1 -0
- package/dist/exportGraph.d.ts +16 -0
- package/dist/exportGraph.d.ts.map +1 -0
- package/dist/exportGraph.js +50 -0
- package/dist/exportGraph.js.map +1 -0
- package/dist/fileDiscovery.d.ts +21 -0
- package/dist/fileDiscovery.d.ts.map +1 -0
- package/dist/fileDiscovery.js +119 -0
- package/dist/fileDiscovery.js.map +1 -0
- package/dist/filterTreeByDepth.d.ts +3 -0
- package/dist/filterTreeByDepth.d.ts.map +1 -0
- package/dist/filterTreeByDepth.js +22 -0
- package/dist/filterTreeByDepth.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -0
- package/dist/parseImports.d.ts +30 -0
- package/dist/parseImports.d.ts.map +1 -0
- package/dist/parseImports.js +196 -0
- package/dist/parseImports.js.map +1 -0
- package/dist/resolveImports.d.ts +25 -0
- package/dist/resolveImports.d.ts.map +1 -0
- package/dist/resolveImports.js +189 -0
- package/dist/resolveImports.js.map +1 -0
- package/dist/scanFileTree.d.ts +3 -0
- package/dist/scanFileTree.d.ts.map +1 -0
- package/dist/scanFileTree.js +118 -0
- package/dist/scanFileTree.js.map +1 -0
- package/dist/scanProject.d.ts +39 -0
- package/dist/scanProject.d.ts.map +1 -0
- package/dist/scanProject.js +224 -0
- package/dist/scanProject.js.map +1 -0
- package/dist/types.d.ts +316 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +45 -0
- package/dist/types.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { RawImportInfo, ResolvedImport, AliasMapping } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Resolve a single import specifier to an absolute file path.
|
|
4
|
+
*
|
|
5
|
+
* @param importInfo - The raw import extracted from the AST
|
|
6
|
+
* @param importingFile - Absolute path of the file containing the import
|
|
7
|
+
* @param aliases - Path alias mappings from tsconfig.json
|
|
8
|
+
* @param extensions - File extensions to try during resolution
|
|
9
|
+
* @returns A ResolvedImport with the resolved path (or null if unresolvable)
|
|
10
|
+
*/
|
|
11
|
+
export declare function resolveImport(importInfo: RawImportInfo, importingFile: string, aliases: AliasMapping[], extensions?: string[]): ResolvedImport;
|
|
12
|
+
/**
|
|
13
|
+
* Resolve all imports from a single file.
|
|
14
|
+
*
|
|
15
|
+
* Filters out external packages and returns only local (project-internal)
|
|
16
|
+
* resolved imports.
|
|
17
|
+
*
|
|
18
|
+
* @param imports - Raw imports extracted by parseImports()
|
|
19
|
+
* @param importingFile - Absolute path of the file containing the imports
|
|
20
|
+
* @param aliases - Path alias mappings from tsconfig.json
|
|
21
|
+
* @param extensions - File extensions to try during resolution
|
|
22
|
+
* @returns Array of resolved imports (only those with resolvedPath !== null)
|
|
23
|
+
*/
|
|
24
|
+
export declare function resolveImports(imports: RawImportInfo[], importingFile: string, aliases: AliasMapping[], extensions?: string[]): ResolvedImport[];
|
|
25
|
+
//# sourceMappingURL=resolveImports.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveImports.d.ts","sourceRoot":"","sources":["../src/resolveImports.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAqG9E;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,UAAU,EAAE,aAAa,EACzB,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,YAAY,EAAE,EACvB,UAAU,GAAE,MAAM,EAAuB,GACxC,cAAc,CAwChB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,aAAa,EAAE,EACxB,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,YAAY,EAAE,EACvB,UAAU,GAAE,MAAM,EAAuB,GACxC,cAAc,EAAE,CAIlB"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================================
|
|
3
|
+
// resolveImports — Resolve import specifiers to absolute file paths
|
|
4
|
+
// ============================================================================
|
|
5
|
+
// Takes raw import specifiers (like './Button' or '@/utils') and resolves them
|
|
6
|
+
// to actual files on disk. Handles:
|
|
7
|
+
// - Relative paths (./foo, ../bar)
|
|
8
|
+
// - Extension resolution (.ts, .tsx, .js, .jsx)
|
|
9
|
+
// - Index file resolution (./dir → ./dir/index.ts)
|
|
10
|
+
// - Path aliases from tsconfig.json (@/ → src/)
|
|
11
|
+
// - Skipping external packages (react, lodash)
|
|
12
|
+
// ============================================================================
|
|
13
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
16
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
17
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
18
|
+
}
|
|
19
|
+
Object.defineProperty(o, k2, desc);
|
|
20
|
+
}) : (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
o[k2] = m[k];
|
|
23
|
+
}));
|
|
24
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
25
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
26
|
+
}) : function(o, v) {
|
|
27
|
+
o["default"] = v;
|
|
28
|
+
});
|
|
29
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
30
|
+
var ownKeys = function(o) {
|
|
31
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
32
|
+
var ar = [];
|
|
33
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
34
|
+
return ar;
|
|
35
|
+
};
|
|
36
|
+
return ownKeys(o);
|
|
37
|
+
};
|
|
38
|
+
return function (mod) {
|
|
39
|
+
if (mod && mod.__esModule) return mod;
|
|
40
|
+
var result = {};
|
|
41
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
42
|
+
__setModuleDefault(result, mod);
|
|
43
|
+
return result;
|
|
44
|
+
};
|
|
45
|
+
})();
|
|
46
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
47
|
+
exports.resolveImport = resolveImport;
|
|
48
|
+
exports.resolveImports = resolveImports;
|
|
49
|
+
const path = __importStar(require("path"));
|
|
50
|
+
const fs = __importStar(require("fs"));
|
|
51
|
+
const types_js_1 = require("./types.js");
|
|
52
|
+
/**
|
|
53
|
+
* Check if an import specifier refers to an external package (not a local file).
|
|
54
|
+
*
|
|
55
|
+
* External packages are identified by:
|
|
56
|
+
* - Not starting with '.' or '..'
|
|
57
|
+
* - Not matching any configured alias prefix
|
|
58
|
+
*/
|
|
59
|
+
function isExternalImport(specifier, aliases) {
|
|
60
|
+
// Relative imports are always local
|
|
61
|
+
if (specifier.startsWith('.')) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
// Check if it matches an alias
|
|
65
|
+
for (const alias of aliases) {
|
|
66
|
+
if (specifier.startsWith(alias.prefix)) {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// Everything else is external (react, lodash, @mui/material, etc.)
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Try to resolve a file path by testing various extensions and index files.
|
|
75
|
+
*
|
|
76
|
+
* Resolution order:
|
|
77
|
+
* 1. Exact match (the path as-is)
|
|
78
|
+
* 2. Path + each extension (.ts, .tsx, .js, .jsx)
|
|
79
|
+
* 3. Path as directory + index + each extension
|
|
80
|
+
*
|
|
81
|
+
* @returns The resolved absolute path, or null if not found
|
|
82
|
+
*/
|
|
83
|
+
function tryResolveFile(basePath, extensions) {
|
|
84
|
+
// 1. Try exact match (e.g., importing a .json or .css file with extension)
|
|
85
|
+
if (fs.existsSync(basePath) && fs.statSync(basePath).isFile()) {
|
|
86
|
+
return basePath;
|
|
87
|
+
}
|
|
88
|
+
// 2. Try appending each extension
|
|
89
|
+
for (const ext of extensions) {
|
|
90
|
+
const withExt = basePath + ext;
|
|
91
|
+
if (fs.existsSync(withExt) && fs.statSync(withExt).isFile()) {
|
|
92
|
+
return withExt;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// 3. Try as a directory with index file
|
|
96
|
+
if (fs.existsSync(basePath) && fs.statSync(basePath).isDirectory()) {
|
|
97
|
+
for (const ext of extensions) {
|
|
98
|
+
const indexPath = path.join(basePath, `index${ext}`);
|
|
99
|
+
if (fs.existsSync(indexPath) && fs.statSync(indexPath).isFile()) {
|
|
100
|
+
return indexPath;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Resolve an alias-prefixed specifier to an absolute path.
|
|
108
|
+
*
|
|
109
|
+
* For example, if the alias is `@/ → /project/src/`:
|
|
110
|
+
* `@/components/Button` → `/project/src/components/Button`
|
|
111
|
+
*
|
|
112
|
+
* Then tries extension resolution on the resulting path.
|
|
113
|
+
*/
|
|
114
|
+
function resolveAlias(specifier, aliases, extensions) {
|
|
115
|
+
for (const alias of aliases) {
|
|
116
|
+
if (specifier.startsWith(alias.prefix)) {
|
|
117
|
+
const remainder = specifier.slice(alias.prefix.length);
|
|
118
|
+
// Try each alias target path
|
|
119
|
+
for (const aliasPath of alias.paths) {
|
|
120
|
+
const fullPath = path.join(aliasPath, remainder);
|
|
121
|
+
const resolved = tryResolveFile(fullPath, extensions);
|
|
122
|
+
if (resolved) {
|
|
123
|
+
return resolved;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Resolve a single import specifier to an absolute file path.
|
|
132
|
+
*
|
|
133
|
+
* @param importInfo - The raw import extracted from the AST
|
|
134
|
+
* @param importingFile - Absolute path of the file containing the import
|
|
135
|
+
* @param aliases - Path alias mappings from tsconfig.json
|
|
136
|
+
* @param extensions - File extensions to try during resolution
|
|
137
|
+
* @returns A ResolvedImport with the resolved path (or null if unresolvable)
|
|
138
|
+
*/
|
|
139
|
+
function resolveImport(importInfo, importingFile, aliases, extensions = types_js_1.DEFAULT_EXTENSIONS) {
|
|
140
|
+
const { source } = importInfo;
|
|
141
|
+
// Skip external packages — they're not part of the project graph
|
|
142
|
+
if (isExternalImport(source, aliases)) {
|
|
143
|
+
return {
|
|
144
|
+
raw: importInfo,
|
|
145
|
+
resolvedPath: null,
|
|
146
|
+
error: 'external_package',
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
// Try alias resolution first
|
|
150
|
+
if (!source.startsWith('.')) {
|
|
151
|
+
const aliasResolved = resolveAlias(source, aliases, extensions);
|
|
152
|
+
if (aliasResolved) {
|
|
153
|
+
return { raw: importInfo, resolvedPath: path.resolve(aliasResolved) };
|
|
154
|
+
}
|
|
155
|
+
return {
|
|
156
|
+
raw: importInfo,
|
|
157
|
+
resolvedPath: null,
|
|
158
|
+
error: `Could not resolve alias import: ${source}`,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
// Relative import resolution
|
|
162
|
+
const importDir = path.dirname(importingFile);
|
|
163
|
+
const absoluteTarget = path.resolve(importDir, source);
|
|
164
|
+
const resolved = tryResolveFile(absoluteTarget, extensions);
|
|
165
|
+
if (resolved) {
|
|
166
|
+
return { raw: importInfo, resolvedPath: path.resolve(resolved) };
|
|
167
|
+
}
|
|
168
|
+
return {
|
|
169
|
+
raw: importInfo,
|
|
170
|
+
resolvedPath: null,
|
|
171
|
+
error: `Could not resolve: ${source} (from ${importingFile})`,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Resolve all imports from a single file.
|
|
176
|
+
*
|
|
177
|
+
* Filters out external packages and returns only local (project-internal)
|
|
178
|
+
* resolved imports.
|
|
179
|
+
*
|
|
180
|
+
* @param imports - Raw imports extracted by parseImports()
|
|
181
|
+
* @param importingFile - Absolute path of the file containing the imports
|
|
182
|
+
* @param aliases - Path alias mappings from tsconfig.json
|
|
183
|
+
* @param extensions - File extensions to try during resolution
|
|
184
|
+
* @returns Array of resolved imports (only those with resolvedPath !== null)
|
|
185
|
+
*/
|
|
186
|
+
function resolveImports(imports, importingFile, aliases, extensions = types_js_1.DEFAULT_EXTENSIONS) {
|
|
187
|
+
return imports.map((imp) => resolveImport(imp, importingFile, aliases, extensions));
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=resolveImports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveImports.js","sourceRoot":"","sources":["../src/resolveImports.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanFileTree.d.ts","sourceRoot":"","sources":["../src/scanFileTree.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAoBpE,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,YAAY,CAAC,CAoFvB"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.scanFileTree = scanFileTree;
|
|
37
|
+
const fs = __importStar(require("fs/promises"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const types_js_1 = require("./types.js");
|
|
40
|
+
function shouldIgnoreEntry(name, ignorePatterns) {
|
|
41
|
+
return ignorePatterns.some((pattern) => (name === pattern || name.startsWith(pattern)));
|
|
42
|
+
}
|
|
43
|
+
function compareEntries(left, right) {
|
|
44
|
+
if (left.isDirectory() !== right.isDirectory()) {
|
|
45
|
+
return left.isDirectory() ? -1 : 1;
|
|
46
|
+
}
|
|
47
|
+
return left.name.localeCompare(right.name);
|
|
48
|
+
}
|
|
49
|
+
async function scanFileTree(rootDir, options = {}) {
|
|
50
|
+
const resolvedRoot = path.resolve(rootDir);
|
|
51
|
+
const { ignorePatterns: userIgnorePatterns = [], maxDepth = Infinity, } = options;
|
|
52
|
+
const ignorePatterns = [
|
|
53
|
+
...types_js_1.DEFAULT_IGNORE_PATTERNS,
|
|
54
|
+
...userIgnorePatterns,
|
|
55
|
+
];
|
|
56
|
+
let rootStat;
|
|
57
|
+
try {
|
|
58
|
+
rootStat = await fs.stat(resolvedRoot);
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
throw new Error(`Cannot access project root: ${resolvedRoot} — ${err.message}`);
|
|
62
|
+
}
|
|
63
|
+
if (!rootStat.isDirectory()) {
|
|
64
|
+
throw new Error(`Not a directory: ${resolvedRoot}`);
|
|
65
|
+
}
|
|
66
|
+
async function walkDirectory(absolutePath, depth) {
|
|
67
|
+
if (depth > maxDepth) {
|
|
68
|
+
return [];
|
|
69
|
+
}
|
|
70
|
+
let entries;
|
|
71
|
+
try {
|
|
72
|
+
entries = await fs.readdir(absolutePath, { withFileTypes: true });
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return [];
|
|
76
|
+
}
|
|
77
|
+
const visibleEntries = entries
|
|
78
|
+
.filter((entry) => !shouldIgnoreEntry(entry.name, ignorePatterns))
|
|
79
|
+
.sort(compareEntries);
|
|
80
|
+
const children = await Promise.all(visibleEntries.map(async (entry) => {
|
|
81
|
+
const entryPath = path.join(absolutePath, entry.name);
|
|
82
|
+
const relativePath = path.relative(resolvedRoot, entryPath);
|
|
83
|
+
const baseNode = {
|
|
84
|
+
id: entryPath,
|
|
85
|
+
name: entry.name,
|
|
86
|
+
relativePath,
|
|
87
|
+
absolutePath: entryPath,
|
|
88
|
+
kind: entry.isDirectory() ? 'directory' : 'file',
|
|
89
|
+
extension: entry.isDirectory() ? null : path.extname(entry.name) || null,
|
|
90
|
+
depth,
|
|
91
|
+
};
|
|
92
|
+
if (entry.isDirectory()) {
|
|
93
|
+
return {
|
|
94
|
+
...baseNode,
|
|
95
|
+
children: depth >= maxDepth ? [] : await walkDirectory(entryPath, depth + 1),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
const stat = await fs.stat(entryPath);
|
|
99
|
+
return {
|
|
100
|
+
...baseNode,
|
|
101
|
+
children: [],
|
|
102
|
+
sizeBytes: stat.size,
|
|
103
|
+
};
|
|
104
|
+
}));
|
|
105
|
+
return children;
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
id: resolvedRoot,
|
|
109
|
+
name: path.basename(resolvedRoot),
|
|
110
|
+
relativePath: '.',
|
|
111
|
+
absolutePath: resolvedRoot,
|
|
112
|
+
kind: 'directory',
|
|
113
|
+
extension: null,
|
|
114
|
+
depth: 0,
|
|
115
|
+
children: await walkDirectory(resolvedRoot, 1),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=scanFileTree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanFileTree.js","sourceRoot":"","sources":["../src/scanFileTree.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { ScanOptions, ScanResult } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Scan a React project and build its dependency graph.
|
|
4
|
+
*
|
|
5
|
+
* This is the main entry point for the `@depxray/core` package. It performs a
|
|
6
|
+
* complete scan of the given project directory, parsing all React/TypeScript
|
|
7
|
+
* files and building a graph of their import relationships.
|
|
8
|
+
*
|
|
9
|
+
* @param options - Configuration for the scan (rootDir is required)
|
|
10
|
+
* @returns A complete ScanResult with the graph, statistics, and any errors
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* import { scanProject } from '@depxray/core';
|
|
15
|
+
*
|
|
16
|
+
* const result = await scanProject({
|
|
17
|
+
* rootDir: '/path/to/my-react-app',
|
|
18
|
+
* detectCircular: true,
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* console.log(`Scanned ${result.totalFiles} files`);
|
|
22
|
+
* console.log(`Found ${result.totalImports} imports`);
|
|
23
|
+
* console.log(`Circular dependencies: ${result.circularCount}`);
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* // With custom options
|
|
29
|
+
* const result = await scanProject({
|
|
30
|
+
* rootDir: '/path/to/project',
|
|
31
|
+
* extensions: ['.ts', '.tsx'], // Only TypeScript files
|
|
32
|
+
* ignorePatterns: ['__tests__', 'e2e'], // Skip test directories
|
|
33
|
+
* detectCircular: true,
|
|
34
|
+
* resolveAliases: true,
|
|
35
|
+
* });
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare function scanProject(options: ScanOptions): Promise<ScanResult>;
|
|
39
|
+
//# sourceMappingURL=scanProject.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanProject.d.ts","sourceRoot":"","sources":["../src/scanProject.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EAIX,MAAM,YAAY,CAAC;AAUpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAkK3E"}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================================
|
|
3
|
+
// scanProject — Main entry point for the dependency graph scanner
|
|
4
|
+
// ============================================================================
|
|
5
|
+
// This is the primary API for the core package. It orchestrates the full
|
|
6
|
+
// scanning pipeline:
|
|
7
|
+
//
|
|
8
|
+
// 1. Load config (tsconfig aliases)
|
|
9
|
+
// 2. Discover files
|
|
10
|
+
// 3. Parse imports from each file
|
|
11
|
+
// 4. Resolve import paths
|
|
12
|
+
// 5. Build the dependency graph
|
|
13
|
+
// 6. Detect circular dependencies (optional)
|
|
14
|
+
// 7. Detect orphan files
|
|
15
|
+
// 8. Return the complete ScanResult
|
|
16
|
+
//
|
|
17
|
+
// This function is platform-agnostic — it works in Node.js without any
|
|
18
|
+
// dependency on CLI frameworks or browser APIs.
|
|
19
|
+
// ============================================================================
|
|
20
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
23
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
24
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
25
|
+
}
|
|
26
|
+
Object.defineProperty(o, k2, desc);
|
|
27
|
+
}) : (function(o, m, k, k2) {
|
|
28
|
+
if (k2 === undefined) k2 = k;
|
|
29
|
+
o[k2] = m[k];
|
|
30
|
+
}));
|
|
31
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
32
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
33
|
+
}) : function(o, v) {
|
|
34
|
+
o["default"] = v;
|
|
35
|
+
});
|
|
36
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
37
|
+
var ownKeys = function(o) {
|
|
38
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
39
|
+
var ar = [];
|
|
40
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
41
|
+
return ar;
|
|
42
|
+
};
|
|
43
|
+
return ownKeys(o);
|
|
44
|
+
};
|
|
45
|
+
return function (mod) {
|
|
46
|
+
if (mod && mod.__esModule) return mod;
|
|
47
|
+
var result = {};
|
|
48
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
49
|
+
__setModuleDefault(result, mod);
|
|
50
|
+
return result;
|
|
51
|
+
};
|
|
52
|
+
})();
|
|
53
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
54
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
55
|
+
};
|
|
56
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
57
|
+
exports.scanProject = scanProject;
|
|
58
|
+
const fs = __importStar(require("fs/promises"));
|
|
59
|
+
const path = __importStar(require("path"));
|
|
60
|
+
const package_json_1 = __importDefault(require("../package.json"));
|
|
61
|
+
const types_js_1 = require("./types.js");
|
|
62
|
+
const fileDiscovery_js_1 = require("./fileDiscovery.js");
|
|
63
|
+
const parseImports_js_1 = require("./parseImports.js");
|
|
64
|
+
const resolveImports_js_1 = require("./resolveImports.js");
|
|
65
|
+
const buildGraph_js_1 = require("./buildGraph.js");
|
|
66
|
+
const detectCircularDeps_js_1 = require("./detectCircularDeps.js");
|
|
67
|
+
const detectOrphanFiles_js_1 = require("./detectOrphanFiles.js");
|
|
68
|
+
const configLoader_js_1 = require("./configLoader.js");
|
|
69
|
+
/**
|
|
70
|
+
* Scan a React project and build its dependency graph.
|
|
71
|
+
*
|
|
72
|
+
* This is the main entry point for the `@depxray/core` package. It performs a
|
|
73
|
+
* complete scan of the given project directory, parsing all React/TypeScript
|
|
74
|
+
* files and building a graph of their import relationships.
|
|
75
|
+
*
|
|
76
|
+
* @param options - Configuration for the scan (rootDir is required)
|
|
77
|
+
* @returns A complete ScanResult with the graph, statistics, and any errors
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* import { scanProject } from '@depxray/core';
|
|
82
|
+
*
|
|
83
|
+
* const result = await scanProject({
|
|
84
|
+
* rootDir: '/path/to/my-react-app',
|
|
85
|
+
* detectCircular: true,
|
|
86
|
+
* });
|
|
87
|
+
*
|
|
88
|
+
* console.log(`Scanned ${result.totalFiles} files`);
|
|
89
|
+
* console.log(`Found ${result.totalImports} imports`);
|
|
90
|
+
* console.log(`Circular dependencies: ${result.circularCount}`);
|
|
91
|
+
* ```
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```typescript
|
|
95
|
+
* // With custom options
|
|
96
|
+
* const result = await scanProject({
|
|
97
|
+
* rootDir: '/path/to/project',
|
|
98
|
+
* extensions: ['.ts', '.tsx'], // Only TypeScript files
|
|
99
|
+
* ignorePatterns: ['__tests__', 'e2e'], // Skip test directories
|
|
100
|
+
* detectCircular: true,
|
|
101
|
+
* resolveAliases: true,
|
|
102
|
+
* });
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
async function scanProject(options) {
|
|
106
|
+
const startTime = performance.now();
|
|
107
|
+
const errors = [];
|
|
108
|
+
// ── Merge options with defaults ──────────────────────────────────────
|
|
109
|
+
const { rootDir, extensions = types_js_1.DEFAULT_EXTENSIONS, ignorePatterns: userIgnorePatterns = [], detectCircular = true, resolveAliases = true, maxDepth = Infinity, includeTypeImports = true, includeDynamicImports = true, entryPointPatterns, } = options;
|
|
110
|
+
// Validate rootDir
|
|
111
|
+
const resolvedRoot = path.resolve(rootDir);
|
|
112
|
+
try {
|
|
113
|
+
const stat = await fs.stat(resolvedRoot);
|
|
114
|
+
if (!stat.isDirectory()) {
|
|
115
|
+
throw new Error(`Not a directory: ${resolvedRoot}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
catch (err) {
|
|
119
|
+
throw new Error(`Cannot access project root: ${resolvedRoot} — ${err.message}`);
|
|
120
|
+
}
|
|
121
|
+
// Merge ignore patterns (user patterns + defaults)
|
|
122
|
+
const ignorePatterns = [
|
|
123
|
+
...types_js_1.DEFAULT_IGNORE_PATTERNS,
|
|
124
|
+
...userIgnorePatterns,
|
|
125
|
+
];
|
|
126
|
+
// ── Step 1: Load aliases from tsconfig.json ──────────────────────────
|
|
127
|
+
const aliases = resolveAliases ? (0, configLoader_js_1.loadAliases)(resolvedRoot) : [];
|
|
128
|
+
// ── Step 2: Discover all scannable files ─────────────────────────────
|
|
129
|
+
const filePaths = await (0, fileDiscovery_js_1.discoverFiles)(resolvedRoot, extensions, ignorePatterns, maxDepth);
|
|
130
|
+
if (filePaths.length === 0) {
|
|
131
|
+
// No files found — return an empty result instead of crashing
|
|
132
|
+
const emptyMetadata = {
|
|
133
|
+
scannedAt: new Date().toISOString(),
|
|
134
|
+
scanDurationMs: performance.now() - startTime,
|
|
135
|
+
projectRoot: resolvedRoot,
|
|
136
|
+
totalFiles: 0,
|
|
137
|
+
totalEdges: 0,
|
|
138
|
+
circularCount: 0,
|
|
139
|
+
depxrayVersion: package_json_1.default.version,
|
|
140
|
+
};
|
|
141
|
+
return {
|
|
142
|
+
graph: {
|
|
143
|
+
rootDir: resolvedRoot,
|
|
144
|
+
nodes: [],
|
|
145
|
+
edges: [],
|
|
146
|
+
circularDependencies: [],
|
|
147
|
+
metadata: emptyMetadata,
|
|
148
|
+
},
|
|
149
|
+
totalFiles: 0,
|
|
150
|
+
totalImports: 0,
|
|
151
|
+
circularCount: 0,
|
|
152
|
+
orphanFiles: [],
|
|
153
|
+
errors: [],
|
|
154
|
+
durationMs: emptyMetadata.scanDurationMs,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
// ── Step 3 & 4: Parse imports and resolve paths for each file ────────
|
|
158
|
+
const fileImportsMap = new Map();
|
|
159
|
+
// Process files concurrently for performance, but limit concurrency
|
|
160
|
+
// to avoid opening too many file handles at once
|
|
161
|
+
const BATCH_SIZE = 50;
|
|
162
|
+
for (let i = 0; i < filePaths.length; i += BATCH_SIZE) {
|
|
163
|
+
const batch = filePaths.slice(i, i + BATCH_SIZE);
|
|
164
|
+
await Promise.all(batch.map(async (filePath) => {
|
|
165
|
+
try {
|
|
166
|
+
// Read the file content
|
|
167
|
+
const sourceCode = await fs.readFile(filePath, 'utf-8');
|
|
168
|
+
// Parse imports from the AST
|
|
169
|
+
let rawImports = (0, parseImports_js_1.parseImports)(sourceCode, filePath);
|
|
170
|
+
// Filter based on options
|
|
171
|
+
if (!includeTypeImports) {
|
|
172
|
+
rawImports = rawImports.filter((imp) => !imp.isTypeOnly);
|
|
173
|
+
}
|
|
174
|
+
if (!includeDynamicImports) {
|
|
175
|
+
rawImports = rawImports.filter((imp) => !imp.isDynamic);
|
|
176
|
+
}
|
|
177
|
+
// Resolve import paths to absolute file paths
|
|
178
|
+
const resolved = (0, resolveImports_js_1.resolveImports)(rawImports, filePath, aliases, extensions);
|
|
179
|
+
fileImportsMap.set(filePath, resolved);
|
|
180
|
+
}
|
|
181
|
+
catch (err) {
|
|
182
|
+
errors.push({
|
|
183
|
+
filePath,
|
|
184
|
+
error: err.message,
|
|
185
|
+
});
|
|
186
|
+
// Still add the file to the map so it appears as a node
|
|
187
|
+
fileImportsMap.set(filePath, []);
|
|
188
|
+
}
|
|
189
|
+
}));
|
|
190
|
+
}
|
|
191
|
+
// ── Step 5: Build the dependency graph ───────────────────────────────
|
|
192
|
+
const durationMs = performance.now() - startTime;
|
|
193
|
+
const metadata = {
|
|
194
|
+
scannedAt: new Date().toISOString(),
|
|
195
|
+
scanDurationMs: durationMs,
|
|
196
|
+
projectRoot: resolvedRoot,
|
|
197
|
+
totalFiles: filePaths.length,
|
|
198
|
+
totalEdges: 0, // Will be updated after buildGraph
|
|
199
|
+
circularCount: 0, // Will be updated after detectCircularDeps
|
|
200
|
+
depxrayVersion: package_json_1.default.version,
|
|
201
|
+
};
|
|
202
|
+
let graph = (0, buildGraph_js_1.buildGraph)(fileImportsMap, resolvedRoot, metadata);
|
|
203
|
+
// Update metadata with actual edge count
|
|
204
|
+
graph.metadata.totalEdges = graph.edges.length;
|
|
205
|
+
// ── Step 6: Detect circular dependencies ─────────────────────────────
|
|
206
|
+
if (detectCircular) {
|
|
207
|
+
graph = (0, detectCircularDeps_js_1.detectCircularDeps)(graph);
|
|
208
|
+
}
|
|
209
|
+
// ── Step 7: Detect orphan files ─────────────────────────────────────
|
|
210
|
+
const orphanFiles = (0, detectOrphanFiles_js_1.detectOrphanFiles)(graph, { entryPointPatterns });
|
|
211
|
+
// ── Return the complete result ───────────────────────────────────────
|
|
212
|
+
const finalDurationMs = performance.now() - startTime;
|
|
213
|
+
graph.metadata.scanDurationMs = finalDurationMs;
|
|
214
|
+
return {
|
|
215
|
+
graph,
|
|
216
|
+
totalFiles: graph.nodes.length,
|
|
217
|
+
totalImports: graph.edges.length,
|
|
218
|
+
circularCount: graph.circularDependencies.length,
|
|
219
|
+
orphanFiles,
|
|
220
|
+
errors,
|
|
221
|
+
durationMs: finalDurationMs,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
//# sourceMappingURL=scanProject.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanProject.js","sourceRoot":"","sources":["../src/scanProject.ts"],"names":[],"mappings":"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"}
|