@mf-toolkit/shared-inspector 0.1.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.
Files changed (70) hide show
  1. package/README.md +254 -0
  2. package/dist/analyzer/analyze-project.d.ts +9 -0
  3. package/dist/analyzer/analyze-project.d.ts.map +1 -0
  4. package/dist/analyzer/analyze-project.js +38 -0
  5. package/dist/analyzer/analyze-project.js.map +1 -0
  6. package/dist/analyzer/detect-issues.d.ts +33 -0
  7. package/dist/analyzer/detect-issues.d.ts.map +1 -0
  8. package/dist/analyzer/detect-issues.js +69 -0
  9. package/dist/analyzer/detect-issues.js.map +1 -0
  10. package/dist/analyzer/policy.d.ts +27 -0
  11. package/dist/analyzer/policy.d.ts.map +1 -0
  12. package/dist/analyzer/policy.js +84 -0
  13. package/dist/analyzer/policy.js.map +1 -0
  14. package/dist/collector/build-project-manifest.d.ts +10 -0
  15. package/dist/collector/build-project-manifest.d.ts.map +1 -0
  16. package/dist/collector/build-project-manifest.js +82 -0
  17. package/dist/collector/build-project-manifest.js.map +1 -0
  18. package/dist/collector/collect-imports.d.ts +17 -0
  19. package/dist/collector/collect-imports.d.ts.map +1 -0
  20. package/dist/collector/collect-imports.js +87 -0
  21. package/dist/collector/collect-imports.js.map +1 -0
  22. package/dist/collector/parse-declarations.d.ts +26 -0
  23. package/dist/collector/parse-declarations.d.ts.map +1 -0
  24. package/dist/collector/parse-declarations.js +134 -0
  25. package/dist/collector/parse-declarations.js.map +1 -0
  26. package/dist/collector/parse-shared-config.d.ts +12 -0
  27. package/dist/collector/parse-shared-config.d.ts.map +1 -0
  28. package/dist/collector/parse-shared-config.js +56 -0
  29. package/dist/collector/parse-shared-config.js.map +1 -0
  30. package/dist/collector/resolve-tsconfig-paths.d.ts +39 -0
  31. package/dist/collector/resolve-tsconfig-paths.d.ts.map +1 -0
  32. package/dist/collector/resolve-tsconfig-paths.js +89 -0
  33. package/dist/collector/resolve-tsconfig-paths.js.map +1 -0
  34. package/dist/collector/resolve-versions.d.ts +15 -0
  35. package/dist/collector/resolve-versions.d.ts.map +1 -0
  36. package/dist/collector/resolve-versions.js +49 -0
  37. package/dist/collector/resolve-versions.js.map +1 -0
  38. package/dist/collector/traverse-local-modules.d.ts +27 -0
  39. package/dist/collector/traverse-local-modules.d.ts.map +1 -0
  40. package/dist/collector/traverse-local-modules.js +119 -0
  41. package/dist/collector/traverse-local-modules.js.map +1 -0
  42. package/dist/index.d.ts +7 -0
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +9 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/inspect.d.ts +12 -0
  47. package/dist/inspect.d.ts.map +1 -0
  48. package/dist/inspect.js +15 -0
  49. package/dist/inspect.js.map +1 -0
  50. package/dist/plugins/webpack.d.ts +40 -0
  51. package/dist/plugins/webpack.d.ts.map +1 -0
  52. package/dist/plugins/webpack.js +95 -0
  53. package/dist/plugins/webpack.js.map +1 -0
  54. package/dist/reporter/format-report.d.ts +18 -0
  55. package/dist/reporter/format-report.d.ts.map +1 -0
  56. package/dist/reporter/format-report.js +87 -0
  57. package/dist/reporter/format-report.js.map +1 -0
  58. package/dist/reporter/write-report.d.ts +12 -0
  59. package/dist/reporter/write-report.d.ts.map +1 -0
  60. package/dist/reporter/write-report.js +19 -0
  61. package/dist/reporter/write-report.js.map +1 -0
  62. package/dist/types.d.ts +179 -0
  63. package/dist/types.d.ts.map +1 -0
  64. package/dist/types.js +3 -0
  65. package/dist/types.js.map +1 -0
  66. package/dist/webpack.d.ts +3 -0
  67. package/dist/webpack.d.ts.map +1 -0
  68. package/dist/webpack.js +2 -0
  69. package/dist/webpack.js.map +1 -0
  70. package/package.json +55 -0
@@ -0,0 +1,17 @@
1
+ import type { PackageOccurrence } from '../types.js';
2
+ export declare function scanFiles(dirs: string[], extensions: string[]): Promise<string[]>;
3
+ export interface CollectImportsOptions {
4
+ sourceDirs: string[];
5
+ extensions?: string[];
6
+ ignore?: string[];
7
+ workspacePackages?: string[];
8
+ }
9
+ /**
10
+ * Direct mode collector.
11
+ *
12
+ * Scans all source files and extracts explicitly imported package names.
13
+ * Counts only `import` and `require` declarations — re-exports are NOT counted
14
+ * (they are the domain of traverse-local-modules in local-graph mode).
15
+ */
16
+ export declare function collectImports(options: CollectImportsOptions): Promise<PackageOccurrence[]>;
17
+ //# sourceMappingURL=collect-imports.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collect-imports.d.ts","sourceRoot":"","sources":["../../src/collector/collect-imports.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAarD,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAkBvF;AAID,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC9B;AAID;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,iBAAiB,EAAE,CAAC,CA4C9B"}
@@ -0,0 +1,87 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { readdir } from 'node:fs/promises';
3
+ import { join, extname } from 'node:path';
4
+ import { parseDeclarations, isRelativeSpecifier, isNodeBuiltin, normalizePackageName, } from './parse-declarations.js';
5
+ const DEFAULT_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx'];
6
+ const IGNORED_DIRS = ['node_modules', '.git', 'dist', 'build', 'coverage'];
7
+ // ─── File scanner ─────────────────────────────────────────────────────────────
8
+ export async function scanFiles(dirs, extensions) {
9
+ const files = [];
10
+ for (const dir of dirs) {
11
+ try {
12
+ const entries = await readdir(dir, { recursive: true });
13
+ for (const entry of entries) {
14
+ if (typeof entry !== 'string')
15
+ continue;
16
+ if (!extensions.includes(extname(entry)))
17
+ continue;
18
+ if (entry.split('/').some((seg) => IGNORED_DIRS.includes(seg)))
19
+ continue;
20
+ files.push(join(dir, entry));
21
+ }
22
+ }
23
+ catch {
24
+ // Directory does not exist — skip silently
25
+ }
26
+ }
27
+ return files;
28
+ }
29
+ // ─── Main ─────────────────────────────────────────────────────────────────────
30
+ /**
31
+ * Direct mode collector.
32
+ *
33
+ * Scans all source files and extracts explicitly imported package names.
34
+ * Counts only `import` and `require` declarations — re-exports are NOT counted
35
+ * (they are the domain of traverse-local-modules in local-graph mode).
36
+ */
37
+ export async function collectImports(options) {
38
+ const extensions = options.extensions ?? DEFAULT_EXTENSIONS;
39
+ const files = await scanFiles(options.sourceDirs, extensions);
40
+ /** package → Set of files that import it */
41
+ const pkgFiles = new Map();
42
+ for (const file of files) {
43
+ let content;
44
+ try {
45
+ content = await readFile(file, 'utf-8');
46
+ }
47
+ catch {
48
+ continue;
49
+ }
50
+ const declarations = parseDeclarations(content);
51
+ for (const decl of declarations) {
52
+ // Direct mode: only explicit imports, no re-exports
53
+ if (decl.kind !== 'import')
54
+ continue;
55
+ const { specifier } = decl;
56
+ if (isRelativeSpecifier(specifier))
57
+ continue;
58
+ if (isNodeBuiltin(specifier))
59
+ continue;
60
+ const pkg = normalizePackageName(specifier);
61
+ if (options.ignore?.some((pattern) => matchesIgnorePattern(pkg, pattern)))
62
+ continue;
63
+ if (options.workspacePackages?.some((pattern) => matchesIgnorePattern(pkg, pattern)))
64
+ continue;
65
+ if (!pkgFiles.has(pkg))
66
+ pkgFiles.set(pkg, new Set());
67
+ pkgFiles.get(pkg).add(file);
68
+ }
69
+ }
70
+ // Return one PackageOccurrence per (package, file) pair so callers
71
+ // can aggregate importCount and files[] accurately.
72
+ return Array.from(pkgFiles.entries()).flatMap(([pkg, fileSet]) => [...fileSet].map((file) => ({
73
+ package: pkg,
74
+ file,
75
+ via: 'direct',
76
+ })));
77
+ }
78
+ // ─── Ignore pattern matching ──────────────────────────────────────────────────
79
+ /** Supports exact match and simple glob: '@company/*' */
80
+ function matchesIgnorePattern(pkg, pattern) {
81
+ if (pattern.endsWith('/*')) {
82
+ const scope = pattern.slice(0, -2);
83
+ return pkg.startsWith(scope + '/');
84
+ }
85
+ return pkg === pattern;
86
+ }
87
+ //# sourceMappingURL=collect-imports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collect-imports.js","sourceRoot":"","sources":["../../src/collector/collect-imports.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Shared low-level parser: extracts import/export specifiers from JS/TS source.
3
+ * Used by both collect-imports (direct mode) and traverse-local-modules (local-graph).
4
+ *
5
+ * Adapted from packages/sprite-plugin/src/analyzer/parse-imports.ts.
6
+ */
7
+ export type DeclarationKind = 'import' | 'reexport';
8
+ export interface Declaration {
9
+ specifier: string;
10
+ kind: DeclarationKind;
11
+ }
12
+ export declare function isRelativeSpecifier(specifier: string): boolean;
13
+ export declare function isNodeBuiltin(specifier: string): boolean;
14
+ /**
15
+ * Normalizes a module specifier to its package name.
16
+ * lodash/get → lodash
17
+ * @scope/name/deep → @scope/name
18
+ * react → react
19
+ */
20
+ export declare function normalizePackageName(specifier: string): string;
21
+ /**
22
+ * Parse all import/export declarations from JS/TS source text.
23
+ * Returns one entry per specifier occurrence.
24
+ */
25
+ export declare function parseDeclarations(fileContent: string): Declaration[];
26
+ //# sourceMappingURL=parse-declarations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-declarations.d.ts","sourceRoot":"","sources":["../../src/collector/parse-declarations.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEpD,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,eAAe,CAAC;CACvB;AAgBD,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAGxD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAM9D;AAmFD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,EAAE,CAoBpE"}
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Shared low-level parser: extracts import/export specifiers from JS/TS source.
3
+ * Used by both collect-imports (direct mode) and traverse-local-modules (local-graph).
4
+ *
5
+ * Adapted from packages/sprite-plugin/src/analyzer/parse-imports.ts.
6
+ */
7
+ // ─── Node.js built-ins ────────────────────────────────────────────────────────
8
+ const NODE_BUILTINS = new Set([
9
+ 'assert', 'async_hooks', 'buffer', 'child_process', 'cluster', 'console',
10
+ 'constants', 'crypto', 'dgram', 'diagnostics_channel', 'dns', 'domain',
11
+ 'events', 'fs', 'http', 'http2', 'https', 'inspector', 'module', 'net',
12
+ 'os', 'path', 'perf_hooks', 'process', 'punycode', 'querystring',
13
+ 'readline', 'repl', 'stream', 'string_decoder', 'sys', 'timers', 'tls',
14
+ 'trace_events', 'tty', 'url', 'util', 'v8', 'vm', 'wasi', 'worker_threads',
15
+ 'zlib',
16
+ ]);
17
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
18
+ export function isRelativeSpecifier(specifier) {
19
+ return specifier.startsWith('./') || specifier.startsWith('../');
20
+ }
21
+ export function isNodeBuiltin(specifier) {
22
+ if (specifier.startsWith('node:'))
23
+ return true;
24
+ return NODE_BUILTINS.has(specifier.split('/')[0]);
25
+ }
26
+ /**
27
+ * Normalizes a module specifier to its package name.
28
+ * lodash/get → lodash
29
+ * @scope/name/deep → @scope/name
30
+ * react → react
31
+ */
32
+ export function normalizePackageName(specifier) {
33
+ if (specifier.startsWith('@')) {
34
+ const parts = specifier.split('/');
35
+ return parts.slice(0, 2).join('/');
36
+ }
37
+ return specifier.split('/')[0];
38
+ }
39
+ // ─── Source preprocessing ─────────────────────────────────────────────────────
40
+ /** Strips // and block comments while preserving string literals. */
41
+ function stripComments(source) {
42
+ // Use an array of chunks instead of string concatenation to avoid
43
+ // O(N²) string allocation behaviour in tight loops over large files.
44
+ const chunks = [];
45
+ let i = 0;
46
+ let segStart = i;
47
+ const flush = (end) => {
48
+ if (end > segStart)
49
+ chunks.push(source.slice(segStart, end));
50
+ };
51
+ while (i < source.length) {
52
+ if (source[i] === '"' || source[i] === "'" || source[i] === '`') {
53
+ const quote = source[i];
54
+ i++;
55
+ while (i < source.length && source[i] !== quote) {
56
+ if (source[i] === '\\')
57
+ i++;
58
+ if (i < source.length)
59
+ i++;
60
+ }
61
+ if (i < source.length)
62
+ i++;
63
+ }
64
+ else if (source[i] === '/' && source[i + 1] === '*') {
65
+ flush(i);
66
+ i += 2;
67
+ while (i < source.length && !(source[i] === '*' && source[i + 1] === '/'))
68
+ i++;
69
+ i += 2;
70
+ chunks.push(' ');
71
+ segStart = i;
72
+ }
73
+ else if (source[i] === '/' && source[i + 1] === '/') {
74
+ flush(i);
75
+ i += 2;
76
+ while (i < source.length && source[i] !== '\n')
77
+ i++;
78
+ segStart = i;
79
+ }
80
+ else {
81
+ i++;
82
+ }
83
+ }
84
+ flush(i);
85
+ return chunks.join('');
86
+ }
87
+ /** Collapses multiline import/export statements to single lines. */
88
+ function normalizeMultiline(source) {
89
+ // [^;{}]* is bounded by statement terminators — avoids catastrophic
90
+ // backtracking that [\s\S]*? causes on files with many import keywords.
91
+ return source.replace(/(?:import|export)\s[^;{}]*?from\s+['"][^'"]+['"]/g, (match) => match.replace(/\s+/g, ' '));
92
+ }
93
+ // ─── Regex patterns ───────────────────────────────────────────────────────────
94
+ /**
95
+ * Static imports — excludes:
96
+ * - dynamic import('pkg') via (?!\s*\()
97
+ * - type-only imports via (?!\s+type[\s{])
98
+ */
99
+ const STATIC_IMPORT_RE = /\bimport(?!\s*\()(?!\s+type[\s{])\s+(?:[^'"]*?\bfrom\s+)?['"]([^'"]+)['"]/gm;
100
+ /**
101
+ * Re-exports — matches:
102
+ * export { X } from 'pkg'
103
+ * export * from 'pkg'
104
+ * Excludes export type { X } from 'pkg' via (?!type[\s{])
105
+ */
106
+ const REEXPORT_RE = /\bexport\s+(?!type[\s{])(?:\*|\{[^}]*\})\s+from\s+['"]([^'"]+)['"]/gm;
107
+ /** CommonJS require — require('pkg') */
108
+ const REQUIRE_RE = /\brequire\s*\(\s*['"]([^'"]+)['"]\s*\)/gm;
109
+ /** Dynamic import with a literal string — import('pkg') */
110
+ const DYNAMIC_IMPORT_RE = /\bimport\s*\(\s*['"]([^'"]+)['"]\s*\)/gm;
111
+ // ─── Main parser ──────────────────────────────────────────────────────────────
112
+ /**
113
+ * Parse all import/export declarations from JS/TS source text.
114
+ * Returns one entry per specifier occurrence.
115
+ */
116
+ export function parseDeclarations(fileContent) {
117
+ const src = normalizeMultiline(stripComments(fileContent));
118
+ const results = [];
119
+ const patterns = [
120
+ [STATIC_IMPORT_RE, 'import'],
121
+ [REQUIRE_RE, 'import'],
122
+ [DYNAMIC_IMPORT_RE, 'import'],
123
+ [REEXPORT_RE, 'reexport'],
124
+ ];
125
+ for (const [pattern, kind] of patterns) {
126
+ pattern.lastIndex = 0;
127
+ let match;
128
+ while ((match = pattern.exec(src)) !== null) {
129
+ results.push({ specifier: match[1], kind });
130
+ }
131
+ }
132
+ return results;
133
+ }
134
+ //# sourceMappingURL=parse-declarations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-declarations.js","sourceRoot":"","sources":["../../src/collector/parse-declarations.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,iFAAiF;AAEjF,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC;IAC5B,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,eAAe,EAAE,SAAS,EAAE,SAAS;IACxE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,qBAAqB,EAAE,KAAK,EAAE,QAAQ;IACtE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK;IACtE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa;IAChE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK;IACtE,cAAc,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,gBAAgB;IAC1E,MAAM;CACP,CAAC,CAAC;AAEH,iFAAiF;AAEjF,MAAM,UAAU,mBAAmB,CAAC,SAAiB;IACnD,OAAO,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,SAAiB;IAC7C,IAAI,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/C,OAAO,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,SAAiB;IACpD,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACnC,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AACjC,CAAC;AAED,iFAAiF;AAEjF,qEAAqE;AACrE,SAAS,aAAa,CAAC,MAAc;IACnC,kEAAkE;IAClE,qEAAqE;IACrE,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,IAAI,QAAQ,GAAG,CAAC,CAAC;IAEjB,MAAM,KAAK,GAAG,CAAC,GAAW,EAAE,EAAE;QAC5B,IAAI,GAAG,GAAG,QAAQ;YAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC;IAC/D,CAAC,CAAC;IAEF,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;QACzB,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YAChE,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YACxB,CAAC,EAAE,CAAC;YACJ,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC;gBAChD,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI;oBAAE,CAAC,EAAE,CAAC;gBAC5B,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM;oBAAE,CAAC,EAAE,CAAC;YAC7B,CAAC;YACD,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM;gBAAE,CAAC,EAAE,CAAC;QAC7B,CAAC;aAAM,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YACtD,KAAK,CAAC,CAAC,CAAC,CAAC;YACT,CAAC,IAAI,CAAC,CAAC;YACP,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC;gBAAE,CAAC,EAAE,CAAC;YAC/E,CAAC,IAAI,CAAC,CAAC;YACP,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACjB,QAAQ,GAAG,CAAC,CAAC;QACf,CAAC;aAAM,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YACtD,KAAK,CAAC,CAAC,CAAC,CAAC;YACT,CAAC,IAAI,CAAC,CAAC;YACP,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI;gBAAE,CAAC,EAAE,CAAC;YACpD,QAAQ,GAAG,CAAC,CAAC;QACf,CAAC;aAAM,CAAC;YACN,CAAC,EAAE,CAAC;QACN,CAAC;IACH,CAAC;IAED,KAAK,CAAC,CAAC,CAAC,CAAC;IACT,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACzB,CAAC;AAED,oEAAoE;AACpE,SAAS,kBAAkB,CAAC,MAAc;IACxC,oEAAoE;IACpE,wEAAwE;IACxE,OAAO,MAAM,CAAC,OAAO,CACnB,mDAAmD,EACnD,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CACtC,CAAC;AACJ,CAAC;AAED,iFAAiF;AAEjF;;;;GAIG;AACH,MAAM,gBAAgB,GACpB,6EAA6E,CAAC;AAEhF;;;;;GAKG;AACH,MAAM,WAAW,GACf,sEAAsE,CAAC;AAEzE,wCAAwC;AACxC,MAAM,UAAU,GAAG,0CAA0C,CAAC;AAE9D,2DAA2D;AAC3D,MAAM,iBAAiB,GAAG,yCAAyC,CAAC;AAEpE,iFAAiF;AAEjF;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,WAAmB;IACnD,MAAM,GAAG,GAAG,kBAAkB,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAkB,EAAE,CAAC;IAElC,MAAM,QAAQ,GAAqC;QACjD,CAAC,gBAAgB,EAAE,QAAQ,CAAC;QAC5B,CAAC,UAAU,EAAE,QAAQ,CAAC;QACtB,CAAC,iBAAiB,EAAE,QAAQ,CAAC;QAC7B,CAAC,WAAW,EAAE,UAAU,CAAC;KAC1B,CAAC;IAEF,KAAK,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,QAAQ,EAAE,CAAC;QACvC,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC;QACtB,IAAI,KAA6B,CAAC;QAClC,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YAC5C,OAAO,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { SharedDepConfig } from '../types.js';
2
+ /**
3
+ * Module Federation accepts shared config in multiple formats:
4
+ *
5
+ * string[] → ['react', 'react-dom']
6
+ * Record<string, SharedDepConfig> → { react: { singleton: true } }
7
+ * Array<string | Record<...>> → [{ react: { singleton: true } }, 'lodash']
8
+ *
9
+ * This function normalises all formats to Record<string, SharedDepConfig>.
10
+ */
11
+ export declare function parseSharedConfig(raw: unknown): Record<string, SharedDepConfig>;
12
+ //# sourceMappingURL=parse-shared-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-shared-config.d.ts","sourceRoot":"","sources":["../../src/collector/parse-shared-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,OAAO,GACX,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAsBjC"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Module Federation accepts shared config in multiple formats:
3
+ *
4
+ * string[] → ['react', 'react-dom']
5
+ * Record<string, SharedDepConfig> → { react: { singleton: true } }
6
+ * Array<string | Record<...>> → [{ react: { singleton: true } }, 'lodash']
7
+ *
8
+ * This function normalises all formats to Record<string, SharedDepConfig>.
9
+ */
10
+ export function parseSharedConfig(raw) {
11
+ if (!raw)
12
+ return {};
13
+ // Object format: { react: { singleton: true }, lodash: {} }
14
+ if (isPlainObject(raw)) {
15
+ return normaliseObjectConfig(raw);
16
+ }
17
+ // Array format: string[] | Array<string | Record<...>>
18
+ if (Array.isArray(raw)) {
19
+ const result = {};
20
+ for (const item of raw) {
21
+ if (typeof item === 'string') {
22
+ result[item] = {};
23
+ }
24
+ else if (isPlainObject(item)) {
25
+ Object.assign(result, normaliseObjectConfig(item));
26
+ }
27
+ }
28
+ return result;
29
+ }
30
+ return {};
31
+ }
32
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
33
+ function isPlainObject(value) {
34
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
35
+ }
36
+ function normaliseObjectConfig(obj) {
37
+ const result = {};
38
+ for (const [pkg, config] of Object.entries(obj)) {
39
+ if (!isPlainObject(config) && config !== undefined) {
40
+ // Unexpected value — treat package as present with empty config
41
+ result[pkg] = {};
42
+ continue;
43
+ }
44
+ const cfg = (config ?? {});
45
+ const normalised = {};
46
+ if (typeof cfg['singleton'] === 'boolean')
47
+ normalised.singleton = cfg['singleton'];
48
+ if (typeof cfg['eager'] === 'boolean')
49
+ normalised.eager = cfg['eager'];
50
+ if (typeof cfg['requiredVersion'] === 'string')
51
+ normalised.requiredVersion = cfg['requiredVersion'];
52
+ result[pkg] = normalised;
53
+ }
54
+ return result;
55
+ }
56
+ //# sourceMappingURL=parse-shared-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-shared-config.js","sourceRoot":"","sources":["../../src/collector/parse-shared-config.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAC/B,GAAY;IAEZ,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IAEpB,4DAA4D;IAC5D,IAAI,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,qBAAqB,CAAC,GAA8B,CAAC,CAAC;IAC/D,CAAC;IAED,uDAAuD;IACvD,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,MAAM,GAAoC,EAAE,CAAC;QACnD,KAAK,MAAM,IAAI,IAAI,GAAG,EAAE,CAAC;YACvB,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC7B,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YACpB,CAAC;iBAAM,IAAI,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC/B,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,IAA+B,CAAC,CAAC,CAAC;YAChF,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,iFAAiF;AAEjF,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,qBAAqB,CAC5B,GAA4B;IAE5B,MAAM,MAAM,GAAoC,EAAE,CAAC;IAEnD,KAAK,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAChD,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACnD,gEAAgE;YAChE,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;YACjB,SAAS;QACX,CAAC;QAED,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,EAAE,CAA4B,CAAC;QACtD,MAAM,UAAU,GAAoB,EAAE,CAAC;QAEvC,IAAI,OAAO,GAAG,CAAC,WAAW,CAAC,KAAK,SAAS;YAAE,UAAU,CAAC,SAAS,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC;QACnF,IAAI,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,SAAS;YAAE,UAAU,CAAC,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC;QACvE,IAAI,OAAO,GAAG,CAAC,iBAAiB,CAAC,KAAK,QAAQ;YAAE,UAAU,CAAC,eAAe,GAAG,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAEpG,MAAM,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC;IAC3B,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Resolved tsconfig path aliases.
3
+ * Each alias pattern maps to one or more local directory roots.
4
+ *
5
+ * Example tsconfig.json:
6
+ * { "compilerOptions": { "baseUrl": ".", "paths": { "@app/*": ["src/*"] } } }
7
+ *
8
+ * Produces:
9
+ * { aliases: [{ pattern: '@app/', roots: ['/project/src/'] }] }
10
+ */
11
+ export interface ResolvedTsConfigPaths {
12
+ /** Absolute base directory (compilerOptions.baseUrl resolved against tsconfig location) */
13
+ baseDir: string;
14
+ aliases: Array<{
15
+ /** The alias prefix without the trailing '*', e.g. '@app/' */
16
+ pattern: string;
17
+ /** Resolved absolute directory roots (trailing '*' stripped from each mapping) */
18
+ roots: string[];
19
+ }>;
20
+ }
21
+ /**
22
+ * Loads tsconfig.json and extracts path alias mappings.
23
+ * Returns null when tsconfig is absent, unreadable, or has no paths defined.
24
+ *
25
+ * Only handles the common `"alias/*": ["dir/*"]` wildcard pattern.
26
+ * Exact aliases (no wildcard) are not currently supported.
27
+ */
28
+ export declare function loadTsConfigPaths(tsconfigPath: string): ResolvedTsConfigPaths | null;
29
+ /**
30
+ * Resolves a TypeScript path alias specifier to an absolute file path.
31
+ * Returns null when the specifier does not match any alias or the file
32
+ * cannot be found on disk.
33
+ *
34
+ * @param specifier - e.g. '@app/components/Button'
35
+ * @param paths - result of loadTsConfigPaths
36
+ * @param contentMap - pre-read file map; used for O(1) existence checks
37
+ */
38
+ export declare function resolveAliasedSpecifier(specifier: string, paths: ResolvedTsConfigPaths, contentMap: Map<string, string>): string | null;
39
+ //# sourceMappingURL=resolve-tsconfig-paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-tsconfig-paths.d.ts","sourceRoot":"","sources":["../../src/collector/resolve-tsconfig-paths.ts"],"names":[],"mappings":"AAGA;;;;;;;;;GASG;AACH,MAAM,WAAW,qBAAqB;IACpC,2FAA2F;IAC3F,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,KAAK,CAAC;QACb,8DAA8D;QAC9D,OAAO,EAAE,MAAM,CAAC;QAChB,kFAAkF;QAClF,KAAK,EAAE,MAAM,EAAE,CAAC;KACjB,CAAC,CAAC;CACJ;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,qBAAqB,GAAG,IAAI,CAkDpF;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,qBAAqB,EAC5B,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,MAAM,GAAG,IAAI,CAsBf"}
@@ -0,0 +1,89 @@
1
+ import { readFileSync, existsSync } from 'node:fs';
2
+ import { resolve, dirname, join } from 'node:path';
3
+ /**
4
+ * Loads tsconfig.json and extracts path alias mappings.
5
+ * Returns null when tsconfig is absent, unreadable, or has no paths defined.
6
+ *
7
+ * Only handles the common `"alias/*": ["dir/*"]` wildcard pattern.
8
+ * Exact aliases (no wildcard) are not currently supported.
9
+ */
10
+ export function loadTsConfigPaths(tsconfigPath) {
11
+ if (!existsSync(tsconfigPath))
12
+ return null;
13
+ let raw;
14
+ try {
15
+ raw = readFileSync(tsconfigPath, 'utf-8');
16
+ }
17
+ catch {
18
+ return null;
19
+ }
20
+ // Strip single-line comments so JSON.parse can handle tsconfig files
21
+ const stripped = raw.replace(/\/\/[^\n]*/g, '');
22
+ let config;
23
+ try {
24
+ config = JSON.parse(stripped);
25
+ }
26
+ catch {
27
+ return null;
28
+ }
29
+ const compilerOptions = config['compilerOptions'];
30
+ if (!compilerOptions)
31
+ return null;
32
+ const tsconfigDir = dirname(resolve(tsconfigPath));
33
+ const baseUrl = typeof compilerOptions['baseUrl'] === 'string'
34
+ ? resolve(tsconfigDir, compilerOptions['baseUrl'])
35
+ : tsconfigDir;
36
+ const rawPaths = compilerOptions['paths'];
37
+ if (!rawPaths || typeof rawPaths !== 'object')
38
+ return null;
39
+ const aliases = [];
40
+ for (const [aliasPattern, mappings] of Object.entries(rawPaths)) {
41
+ // Only handle wildcard aliases: "@alias/*" → ["dir/*"]
42
+ if (!aliasPattern.endsWith('/*'))
43
+ continue;
44
+ if (!Array.isArray(mappings) || mappings.length === 0)
45
+ continue;
46
+ const prefix = aliasPattern.slice(0, -1); // "@alias/" (remove trailing *)
47
+ const roots = mappings
48
+ .filter((m) => typeof m === 'string' && m.endsWith('/*'))
49
+ .map((m) => join(baseUrl, m.slice(0, -1))); // resolve to absolute, remove trailing *
50
+ if (roots.length > 0) {
51
+ aliases.push({ pattern: prefix, roots });
52
+ }
53
+ }
54
+ if (aliases.length === 0)
55
+ return null;
56
+ return { baseDir: baseUrl, aliases };
57
+ }
58
+ /**
59
+ * Resolves a TypeScript path alias specifier to an absolute file path.
60
+ * Returns null when the specifier does not match any alias or the file
61
+ * cannot be found on disk.
62
+ *
63
+ * @param specifier - e.g. '@app/components/Button'
64
+ * @param paths - result of loadTsConfigPaths
65
+ * @param contentMap - pre-read file map; used for O(1) existence checks
66
+ */
67
+ export function resolveAliasedSpecifier(specifier, paths, contentMap) {
68
+ for (const alias of paths.aliases) {
69
+ if (!specifier.startsWith(alias.pattern))
70
+ continue;
71
+ const rest = specifier.slice(alias.pattern.length); // 'components/Button'
72
+ for (const root of alias.roots) {
73
+ const base = join(root, rest); // '/project/src/components/Button'
74
+ // Try direct extensions, then index files
75
+ for (const ext of ['.ts', '.tsx', '.js', '.jsx']) {
76
+ const candidate = base + ext;
77
+ if (contentMap.has(candidate))
78
+ return candidate;
79
+ }
80
+ for (const ext of ['.ts', '.tsx', '.js', '.jsx']) {
81
+ const candidate = join(base, 'index' + ext);
82
+ if (contentMap.has(candidate))
83
+ return candidate;
84
+ }
85
+ }
86
+ }
87
+ return null;
88
+ }
89
+ //# sourceMappingURL=resolve-tsconfig-paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-tsconfig-paths.js","sourceRoot":"","sources":["../../src/collector/resolve-tsconfig-paths.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ export interface ResolvedVersions {
2
+ /** Versions from package.json dependencies + devDependencies */
3
+ declared: Record<string, string>;
4
+ /**
5
+ * Versions from node_modules/<pkg>/package.json.
6
+ * Empty object when node_modules is not accessible —
7
+ * mismatch checks are skipped for packages absent from this map.
8
+ */
9
+ installed: Record<string, string>;
10
+ }
11
+ /**
12
+ * Reads declared and installed versions for all packages listed in package.json.
13
+ */
14
+ export declare function resolveVersions(packageJsonPath: string): Promise<ResolvedVersions>;
15
+ //# sourceMappingURL=resolve-versions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-versions.d.ts","sourceRoot":"","sources":["../../src/collector/resolve-versions.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,gBAAgB;IAC/B,gEAAgE;IAChE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAIxF"}
@@ -0,0 +1,49 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { join, dirname } from 'node:path';
3
+ /**
4
+ * Reads declared and installed versions for all packages listed in package.json.
5
+ */
6
+ export async function resolveVersions(packageJsonPath) {
7
+ const declared = await readDeclaredVersions(packageJsonPath);
8
+ const installed = await readInstalledVersions(packageJsonPath, Object.keys(declared));
9
+ return { declared, installed };
10
+ }
11
+ // ─── Internals ────────────────────────────────────────────────────────────────
12
+ async function readDeclaredVersions(packageJsonPath) {
13
+ let raw;
14
+ try {
15
+ raw = await readFile(packageJsonPath, 'utf-8');
16
+ }
17
+ catch {
18
+ return {};
19
+ }
20
+ let pkg;
21
+ try {
22
+ pkg = JSON.parse(raw);
23
+ }
24
+ catch {
25
+ return {};
26
+ }
27
+ const deps = (pkg['dependencies'] ?? {});
28
+ const devDeps = (pkg['devDependencies'] ?? {});
29
+ return { ...deps, ...devDeps };
30
+ }
31
+ async function readInstalledVersions(packageJsonPath, packages) {
32
+ const nodeModulesDir = join(dirname(packageJsonPath), 'node_modules');
33
+ const installed = {};
34
+ await Promise.all(packages.map(async (pkg) => {
35
+ try {
36
+ const pkgJsonPath = join(nodeModulesDir, pkg, 'package.json');
37
+ const raw = await readFile(pkgJsonPath, 'utf-8');
38
+ const parsed = JSON.parse(raw);
39
+ if (typeof parsed['version'] === 'string') {
40
+ installed[pkg] = parsed['version'];
41
+ }
42
+ }
43
+ catch {
44
+ // Package not found in node_modules — skip silently
45
+ }
46
+ }));
47
+ return installed;
48
+ }
49
+ //# sourceMappingURL=resolve-versions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-versions.js","sourceRoot":"","sources":["../../src/collector/resolve-versions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAa1C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,eAAuB;IAC3D,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,eAAe,CAAC,CAAC;IAC7D,MAAM,SAAS,GAAG,MAAM,qBAAqB,CAAC,eAAe,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IACtF,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AACjC,CAAC;AAED,iFAAiF;AAEjF,KAAK,UAAU,oBAAoB,CAAC,eAAuB;IACzD,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,GAA4B,CAAC;IACjC,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4B,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAA2B,CAAC;IACnE,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAA2B,CAAC;IAEzE,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,EAAE,CAAC;AACjC,CAAC;AAED,KAAK,UAAU,qBAAqB,CAClC,eAAuB,EACvB,QAAkB;IAElB,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,cAAc,CAAC,CAAC;IACtE,MAAM,SAAS,GAA2B,EAAE,CAAC;IAE7C,MAAM,OAAO,CAAC,GAAG,CACf,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACzB,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,EAAE,GAAG,EAAE,cAAc,CAAC,CAAC;YAC9D,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YACjD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4B,CAAC;YAC1D,IAAI,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,QAAQ,EAAE,CAAC;gBAC1C,SAAS,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;YACrC,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,oDAAoD;QACtD,CAAC;IACH,CAAC,CAAC,CACH,CAAC;IAEF,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,27 @@
1
+ import type { PackageOccurrence } from '../types.js';
2
+ export interface TraverseLocalModulesOptions {
3
+ sourceDirs: string[];
4
+ extensions?: string[];
5
+ ignore?: string[];
6
+ /** Path to tsconfig.json for resolving path aliases (e.g. '@app/*'). */
7
+ tsconfigPath?: string;
8
+ /** Workspace package names/globs to skip (e.g. '@my-org/*'). */
9
+ workspacePackages?: string[];
10
+ }
11
+ /**
12
+ * Local-graph mode collector.
13
+ *
14
+ * Scans all files in sourceDirs and follows relative import/export chains
15
+ * recursively within those directories. Finds external packages reachable
16
+ * through barrel re-exports and local module wrappers.
17
+ *
18
+ * When tsconfigPath is provided, TypeScript path aliases (e.g. '@app/*') are
19
+ * resolved to local files and followed in the same DFS — packages behind
20
+ * aliases become visible.
21
+ *
22
+ * Uses two-phase approach:
23
+ * Phase 1 — parallel async reads of all source files into contentMap
24
+ * Phase 2 — synchronous DFS over in-memory content (zero disk I/O)
25
+ */
26
+ export declare function traverseLocalModules(options: TraverseLocalModulesOptions): Promise<PackageOccurrence[]>;
27
+ //# sourceMappingURL=traverse-local-modules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traverse-local-modules.d.ts","sourceRoot":"","sources":["../../src/collector/traverse-local-modules.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAgBrD,MAAM,WAAW,2BAA2B;IAC1C,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gEAAgE;IAChE,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAgF9B"}