prodex 1.2.0 → 1.4.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/README.md +55 -49
- package/dist/cli/cli-input.js +58 -43
- package/dist/cli/cli-input.js.map +1 -0
- package/dist/cli/flags.js +1 -0
- package/dist/cli/flags.js.map +1 -0
- package/dist/cli/init.js +5 -5
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/picker.js +43 -41
- package/dist/cli/picker.js.map +1 -0
- package/dist/cli/summary.js +28 -9
- package/dist/cli/summary.js.map +1 -0
- package/dist/constants/cache-keys.js +12 -0
- package/dist/constants/cache-keys.js.map +1 -0
- package/dist/constants/config-loader.js +12 -7
- package/dist/constants/config-loader.js.map +1 -0
- package/dist/constants/config.js +17 -6
- package/dist/constants/config.js.map +1 -0
- package/dist/constants/default-config.js +4 -17
- package/dist/constants/default-config.js.map +1 -0
- package/dist/constants/flags.js +74 -0
- package/dist/constants/flags.js.map +1 -0
- package/dist/constants/index.js +21 -0
- package/dist/constants/index.js.map +1 -0
- package/dist/constants/render-constants.js +11 -9
- package/dist/constants/render-constants.js.map +1 -0
- package/dist/core/cache.js +54 -0
- package/dist/core/cache.js.map +1 -0
- package/dist/core/combine.js +42 -59
- package/dist/core/combine.js.map +1 -0
- package/dist/core/config-manager.js +104 -0
- package/dist/core/config-manager.js.map +1 -0
- package/dist/core/dependency.js +42 -17
- package/dist/core/dependency.js.map +1 -0
- package/dist/core/file-utils.js +1 -44
- package/dist/core/file-utils.js.map +1 -0
- package/dist/core/helpers.js +43 -38
- package/dist/core/helpers.js.map +1 -0
- package/dist/core/managers/cache.js +54 -0
- package/dist/core/managers/cache.js.map +1 -0
- package/dist/core/managers/config-manager.js +104 -0
- package/dist/core/managers/config-manager.js.map +1 -0
- package/dist/core/managers/config.js +104 -0
- package/dist/core/managers/config.js.map +1 -0
- package/dist/core/output.js +49 -0
- package/dist/core/output.js.map +1 -0
- package/dist/core/parsers/extract-imports.js +2 -7
- package/dist/core/parsers/extract-imports.js.map +1 -0
- package/dist/core/renderers.js +10 -8
- package/dist/core/renderers.js.map +1 -0
- package/dist/debug.js +14 -0
- package/dist/debug.js.map +1 -0
- package/dist/index.js +49 -22
- package/dist/index.js.map +1 -0
- package/dist/lib/logger.js +38 -9
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/polyfills.js +6 -0
- package/dist/lib/polyfills.js.map +1 -0
- package/dist/lib/prompt.js +35 -0
- package/dist/lib/prompt.js.map +1 -0
- package/dist/lib/questions.js +29 -0
- package/dist/lib/questions.js.map +1 -0
- package/dist/lib/utils.js +35 -11
- package/dist/lib/utils.js.map +1 -0
- package/dist/resolvers/js/alias-loader.js +1 -0
- package/dist/resolvers/js/alias-loader.js.map +1 -0
- package/dist/resolvers/js/extract-imports.js +46 -0
- package/dist/resolvers/js/extract-imports.js.map +1 -0
- package/dist/resolvers/js/js-resolver.js +93 -116
- package/dist/resolvers/js/js-resolver.js.map +1 -0
- package/dist/resolvers/js/resolve-alias.js +58 -0
- package/dist/resolvers/js/resolve-alias.js.map +1 -0
- package/dist/resolvers/php/bindings.js +21 -9
- package/dist/resolvers/php/bindings.js.map +1 -0
- package/dist/resolvers/php/extract-imports.js +50 -0
- package/dist/resolvers/php/extract-imports.js.map +1 -0
- package/dist/resolvers/php/patterns.js +37 -4
- package/dist/resolvers/php/patterns.js.map +1 -0
- package/dist/resolvers/php/php-resolver.js +99 -59
- package/dist/resolvers/php/php-resolver.js.map +1 -0
- package/dist/resolvers/php/psr4.js +19 -5
- package/dist/resolvers/php/psr4.js.map +1 -0
- package/dist/resolvers/shared/excludes.js +1 -0
- package/dist/resolvers/shared/excludes.js.map +1 -0
- package/dist/resolvers/shared/file-cache.js +1 -29
- package/dist/resolvers/shared/file-cache.js.map +1 -0
- package/dist/resolvers/shared/resolve-alias.js +62 -0
- package/dist/resolvers/shared/resolve-alias.js.map +1 -0
- package/dist/resolvers/shared/stats.js +3 -3
- package/dist/resolvers/shared/stats.js.map +1 -0
- package/dist/shared/collections.js +34 -0
- package/dist/shared/collections.js.map +1 -0
- package/dist/shared/index.js +20 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/shared/io.js +52 -0
- package/dist/shared/io.js.map +1 -0
- package/dist/shared/patterns.js +30 -0
- package/dist/shared/patterns.js.map +1 -0
- package/dist/shared/stats.js +32 -0
- package/dist/shared/stats.js.map +1 -0
- package/dist/store.js +16 -0
- package/dist/store.js.map +1 -0
- package/dist/types/cli.types.js +1 -0
- package/dist/types/cli.types.js.map +1 -0
- package/dist/types/config.types.js +1 -0
- package/dist/types/config.types.js.map +1 -0
- package/dist/types/core.types.js +1 -0
- package/dist/types/core.types.js.map +1 -0
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/resolver.types.js +1 -0
- package/dist/types/resolver.types.js.map +1 -0
- package/dist/types/utils.types.js +1 -0
- package/dist/types/utils.types.js.map +1 -0
- package/package.json +5 -4
|
@@ -1,153 +1,130 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// @ts-nocheck
|
|
3
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
4
|
};
|
|
6
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
6
|
exports.resolveJsImports = resolveJsImports;
|
|
8
|
-
const promises_1 = __importDefault(require("fs/promises"));
|
|
9
7
|
const path_1 = __importDefault(require("path"));
|
|
10
|
-
const
|
|
11
|
-
const extract_imports_1 = require("../../core/parsers/extract-imports");
|
|
12
|
-
const alias_loader_1 = require("./alias-loader");
|
|
8
|
+
const extract_imports_1 = require("./extract-imports");
|
|
13
9
|
const config_1 = require("../../constants/config");
|
|
14
|
-
const
|
|
10
|
+
const collections_1 = require("../../shared/collections");
|
|
15
11
|
const logger_1 = require("../../lib/logger");
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
|
|
12
|
+
const store_1 = require("../../store");
|
|
13
|
+
const resolve_alias_1 = require("./resolve-alias"); // alias: config + cache + fast-glob
|
|
14
|
+
const cache_1 = require("../../core/managers/cache");
|
|
15
|
+
const cache_keys_1 = require("../../constants/cache-keys");
|
|
16
|
+
const shared_1 = require("../../shared");
|
|
17
|
+
const shared_2 = require("../../shared");
|
|
18
|
+
const { JS_STATS, JS_IMPORTS } = cache_keys_1.CACHE_KEYS;
|
|
19
|
+
async function resolveJsImports({ filePath, visited = new Set(), depth = 0, maxDepth }) {
|
|
20
|
+
const limitDepth = maxDepth;
|
|
21
|
+
if (depth >= limitDepth)
|
|
22
|
+
return (0, collections_1.emptyResult)(visited);
|
|
26
23
|
if (visited.has(filePath))
|
|
27
|
-
return
|
|
24
|
+
return (0, collections_1.emptyResult)(visited);
|
|
28
25
|
visited.add(filePath);
|
|
26
|
+
const { root: ROOT, resolve: { exclude: excludePatterns }, } = (0, store_1.getConfig)();
|
|
29
27
|
const ext = path_1.default.extname(filePath).toLowerCase();
|
|
30
28
|
const isDts = ext === config_1.DTS_EXT;
|
|
31
29
|
if (!config_1.BASE_EXTS.includes(ext) && !isDts)
|
|
32
|
-
return
|
|
33
|
-
let code;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
ctx.aliases = { ...(0, alias_loader_1.loadProjectAliases)(ROOT), ...(resolveCfg.aliases || {}) };
|
|
42
|
-
}
|
|
43
|
-
const aliases = ctx.aliases;
|
|
44
|
-
const matches = await getImportsCached(filePath, code);
|
|
45
|
-
if (!matches.size)
|
|
46
|
-
return empty(visited);
|
|
47
|
-
const filesOut = [];
|
|
30
|
+
return (0, collections_1.emptyResult)(visited);
|
|
31
|
+
let code = (0, shared_1.readFileSafe)(filePath);
|
|
32
|
+
if (!code)
|
|
33
|
+
return (0, collections_1.emptyResult)(visited);
|
|
34
|
+
// Extract imports ---------------------------------------
|
|
35
|
+
const imports = await getImportsCached(filePath, code);
|
|
36
|
+
if (!imports.size)
|
|
37
|
+
return (0, collections_1.emptyResult)(visited);
|
|
38
|
+
// Trackers ----------------------------------------------
|
|
48
39
|
const expected = new Set();
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
40
|
+
const resolved = new Set();
|
|
41
|
+
const files = [];
|
|
42
|
+
// Main resolution loop ----------------------------------
|
|
43
|
+
for (const imp of imports) {
|
|
44
|
+
// skip bare packages (react, lodash, etc.)
|
|
45
|
+
if (!imp.startsWith(".") && !imp.startsWith("/") && !imp.startsWith("@"))
|
|
53
46
|
continue;
|
|
54
|
-
|
|
55
|
-
// Apply single exclude matcher to the RAW specifier
|
|
56
|
-
if (isExcluded(imp))
|
|
47
|
+
if ((0, shared_1.isExcluded)(imp, excludePatterns))
|
|
57
48
|
continue;
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
49
|
+
let base = null;
|
|
50
|
+
if (imp.startsWith(".")) {
|
|
51
|
+
// relative → like original resolver
|
|
52
|
+
base = path_1.default.resolve(path_1.default.dirname(filePath), imp);
|
|
53
|
+
}
|
|
54
|
+
else if (imp.startsWith("/")) {
|
|
55
|
+
// absolute path import → like original resolver
|
|
56
|
+
base = path_1.default.resolve(imp);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
// alias (@...) → unified resolver (config + cache + glob)
|
|
60
|
+
base = await (0, resolve_alias_1.resolveAliasPath)(imp, ROOT, (0, store_1.getConfig)());
|
|
61
|
+
}
|
|
62
|
+
if (!base)
|
|
62
63
|
continue;
|
|
63
|
-
const
|
|
64
|
+
const absBase = path_1.default.resolve(base);
|
|
65
|
+
expected.add(absBase);
|
|
66
|
+
const resolvedPath = await tryResolveImport(absBase);
|
|
64
67
|
if (!resolvedPath)
|
|
65
68
|
continue;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
//
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
for (const
|
|
77
|
-
expected.add(
|
|
69
|
+
resolved.add(absBase);
|
|
70
|
+
files.push(resolvedPath);
|
|
71
|
+
// Recursive traversal
|
|
72
|
+
const sub = await resolveJsImports({
|
|
73
|
+
filePath: resolvedPath,
|
|
74
|
+
visited,
|
|
75
|
+
depth: depth + 1,
|
|
76
|
+
maxDepth: limitDepth,
|
|
77
|
+
});
|
|
78
|
+
files.push(...sub.files);
|
|
79
|
+
for (const e of sub.stats.expected)
|
|
80
|
+
expected.add(e);
|
|
78
81
|
for (const r of sub.stats.resolved)
|
|
79
|
-
|
|
82
|
+
resolved.add(r);
|
|
80
83
|
}
|
|
81
|
-
const uniqueFiles =
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
logger_1.logger.debug([...diff], "🔴THE diff");
|
|
88
|
-
return { files: uniqueFiles, visited, stats: { expected, resolved: resolvedSet } };
|
|
89
|
-
}
|
|
90
|
-
// ---------- helpers ----------
|
|
91
|
-
function startsWithAnyAlias(imp, aliases) {
|
|
92
|
-
return Object.keys(aliases).some((a) => imp === a || imp.startsWith(a + "/"));
|
|
84
|
+
const uniqueFiles = (0, collections_1.unique)(files);
|
|
85
|
+
const diff = (0, shared_2.setDiff)(expected, resolved);
|
|
86
|
+
logger_1.logger.debug(`🪶 [js-resolver] ${filePath} → expected: ${expected.size}, resolved: ${resolved.size}`);
|
|
87
|
+
if (diff.size)
|
|
88
|
+
logger_1.logger.debug([...diff], "🔴 THE diff");
|
|
89
|
+
return { files: uniqueFiles, visited, stats: { expected, resolved } };
|
|
93
90
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
.sort((a, b) => b.length - a.length)[0];
|
|
99
|
-
if (!key)
|
|
100
|
-
return null;
|
|
101
|
-
const relPart = specifier.slice(key.length).replace(/^\/+/, "");
|
|
102
|
-
return path_1.default.resolve(aliases[key], relPart);
|
|
103
|
-
}
|
|
104
|
-
if (specifier.startsWith(".")) {
|
|
105
|
-
return path_1.default.resolve(path_1.default.dirname(fromFile), specifier);
|
|
106
|
-
}
|
|
107
|
-
if (specifier.startsWith("/")) {
|
|
108
|
-
return path_1.default.resolve(specifier);
|
|
109
|
-
}
|
|
110
|
-
return null;
|
|
111
|
-
}
|
|
112
|
-
async function tryResolveImport(basePath, ROOT) {
|
|
91
|
+
// ---------------------------------------------------------
|
|
92
|
+
// tryResolveImport (pure)
|
|
93
|
+
// ---------------------------------------------------------
|
|
94
|
+
async function tryResolveImport(basePath) {
|
|
113
95
|
const candidates = [];
|
|
114
|
-
|
|
96
|
+
const ext = path_1.default.extname(basePath).toLowerCase();
|
|
97
|
+
if (ext && config_1.REAL_EXTS.has(ext)) {
|
|
115
98
|
candidates.push(basePath);
|
|
116
99
|
}
|
|
117
100
|
else {
|
|
118
|
-
for (const
|
|
119
|
-
candidates.push(basePath +
|
|
120
|
-
candidates.push(path_1.default.join(basePath, "index" +
|
|
101
|
+
for (const e of [...config_1.BASE_EXTS, config_1.DTS_EXT]) {
|
|
102
|
+
candidates.push(basePath + e);
|
|
103
|
+
candidates.push(path_1.default.join(basePath, "index" + e));
|
|
121
104
|
}
|
|
122
105
|
}
|
|
123
|
-
|
|
106
|
+
// Run all stat checks in parallel
|
|
107
|
+
const results = await Promise.allSettled(candidates.map(async (c) => {
|
|
124
108
|
const abs = path_1.default.resolve(c);
|
|
125
|
-
const st = await
|
|
126
|
-
|
|
127
|
-
|
|
109
|
+
const st = await (0, shared_1.safeStatCached)(JS_STATS, abs);
|
|
110
|
+
return st && st.isFile() ? abs : null;
|
|
111
|
+
}));
|
|
112
|
+
// Find the first fulfilled non-null result
|
|
113
|
+
for (const r of results) {
|
|
114
|
+
if (r.status === "fulfilled" && r.value)
|
|
115
|
+
return r.value;
|
|
128
116
|
}
|
|
129
117
|
return null;
|
|
130
118
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
try {
|
|
135
|
-
const st = await promises_1.default.stat(p);
|
|
136
|
-
STAT_CACHE.set(p, st);
|
|
137
|
-
return st;
|
|
138
|
-
}
|
|
139
|
-
catch {
|
|
140
|
-
STAT_CACHE.set(p, null);
|
|
141
|
-
return null;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
119
|
+
// ---------------------------------------------------------
|
|
120
|
+
// Cached stat + import scanners
|
|
121
|
+
// ---------------------------------------------------------
|
|
144
122
|
async function getImportsCached(filePath, code) {
|
|
145
|
-
|
|
146
|
-
|
|
123
|
+
const cached = cache_1.CacheManager.get(JS_IMPORTS, filePath);
|
|
124
|
+
if (cached)
|
|
125
|
+
return cached;
|
|
147
126
|
const set = await (0, extract_imports_1.extractImports)(filePath, code);
|
|
148
|
-
|
|
127
|
+
cache_1.CacheManager.set(JS_IMPORTS, filePath, set);
|
|
149
128
|
return set;
|
|
150
129
|
}
|
|
151
|
-
|
|
152
|
-
return { files: [], visited, stats: { expected: new Set(), resolved: new Set() } };
|
|
153
|
-
}
|
|
130
|
+
//# sourceMappingURL=js-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"js-resolver.js","sourceRoot":"","sources":["../../../src/resolvers/js/js-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"path\";\r\nimport { extractImports } from \"./extract-imports\";\r\nimport { BASE_EXTS, DTS_EXT, REAL_EXTS } from \"../../constants/config\";\r\nimport { emptyResult, unique } from \"../../shared/collections\";\r\nimport { logger } from \"../../lib/logger\";\r\nimport { getConfig } from \"../../store\";\r\nimport { resolveAliasPath } from \"./resolve-alias\"; // alias: config + cache + fast-glob\r\nimport type { ResolverParams, ResolverResult } from \"../../types\";\r\nimport { CacheManager } from \"../../core/managers/cache\";\r\nimport { CACHE_KEYS } from \"../../constants/cache-keys\";\r\nimport { isExcluded, readFileSafe, safeStatCached } from \"../../shared\";\r\nimport { setDiff } from \"../../shared\";\r\n\r\nconst { JS_STATS, JS_IMPORTS } = CACHE_KEYS;\r\n\r\nexport async function resolveJsImports({ filePath, visited = new Set(), depth = 0, maxDepth }: ResolverParams): Promise<ResolverResult> {\r\n\tconst limitDepth = maxDepth;\r\n\r\n\tif (depth >= limitDepth) return emptyResult(visited);\r\n\tif (visited.has(filePath)) return emptyResult(visited);\r\n\tvisited.add(filePath);\r\n\r\n\tconst {\r\n\t\troot: ROOT,\r\n\t\tresolve: { exclude: excludePatterns },\r\n\t} = getConfig();\r\n\r\n\tconst ext = path.extname(filePath).toLowerCase();\r\n\tconst isDts = ext === DTS_EXT;\r\n\tif (!BASE_EXTS.includes(ext) && !isDts) return emptyResult(visited);\r\n\r\n\tlet code = readFileSafe(filePath);\r\n\tif (!code) return emptyResult(visited);\r\n\r\n\t// Extract imports ---------------------------------------\r\n\tconst imports = await getImportsCached(filePath, code);\r\n\tif (!imports.size) return emptyResult(visited);\r\n\r\n\t// Trackers ----------------------------------------------\r\n\tconst expected = new Set<string>();\r\n\tconst resolved = new Set<string>();\r\n\tconst files: string[] = [];\r\n\r\n\t// Main resolution loop ----------------------------------\r\n\tfor (const imp of imports) {\r\n\t\t// skip bare packages (react, lodash, etc.)\r\n\t\tif (!imp.startsWith(\".\") && !imp.startsWith(\"/\") && !imp.startsWith(\"@\")) continue;\r\n\t\tif (isExcluded(imp, excludePatterns)) continue;\r\n\r\n\t\tlet base: string | null = null;\r\n\r\n\t\tif (imp.startsWith(\".\")) {\r\n\t\t\t// relative → like original resolver\r\n\t\t\tbase = path.resolve(path.dirname(filePath), imp);\r\n\t\t} else if (imp.startsWith(\"/\")) {\r\n\t\t\t// absolute path import → like original resolver\r\n\t\t\tbase = path.resolve(imp);\r\n\t\t} else {\r\n\t\t\t// alias (@...) → unified resolver (config + cache + glob)\r\n\t\t\tbase = await resolveAliasPath(imp, ROOT, getConfig());\r\n\t\t}\r\n\r\n\t\tif (!base) continue;\r\n\r\n\t\tconst absBase = path.resolve(base);\r\n\t\texpected.add(absBase);\r\n\r\n\t\tconst resolvedPath = await tryResolveImport(absBase);\r\n\t\tif (!resolvedPath) continue;\r\n\r\n\t\tresolved.add(absBase);\r\n\t\tfiles.push(resolvedPath);\r\n\r\n\t\t// Recursive traversal\r\n\t\tconst sub = await resolveJsImports({\r\n\t\t\tfilePath: resolvedPath,\r\n\t\t\tvisited,\r\n\t\t\tdepth: depth + 1,\r\n\t\t\tmaxDepth: limitDepth,\r\n\t\t});\r\n\r\n\t\tfiles.push(...sub.files);\r\n\t\tfor (const e of sub.stats.expected) expected.add(e);\r\n\t\tfor (const r of sub.stats.resolved) resolved.add(r);\r\n\t}\r\n\r\n\tconst uniqueFiles = unique(files);\r\n\tconst diff = setDiff(expected, resolved);\r\n\r\n\tlogger.debug(`🪶 [js-resolver] ${filePath} → expected: ${expected.size}, resolved: ${resolved.size}`);\r\n\tif (diff.size) logger.debug([...diff], \"🔴 THE diff\");\r\n\r\n\treturn { files: uniqueFiles, visited, stats: { expected, resolved } };\r\n}\r\n\r\n// ---------------------------------------------------------\r\n// tryResolveImport (pure)\r\n// ---------------------------------------------------------\r\nasync function tryResolveImport(basePath: string): Promise<string | null> {\r\n\tconst candidates: string[] = [];\r\n\r\n\tconst ext = path.extname(basePath).toLowerCase();\r\n\tif (ext && REAL_EXTS.has(ext)) {\r\n\t\tcandidates.push(basePath);\r\n\t} else {\r\n\t\tfor (const e of [...BASE_EXTS, DTS_EXT]) {\r\n\t\t\tcandidates.push(basePath + e);\r\n\t\t\tcandidates.push(path.join(basePath, \"index\" + e));\r\n\t\t}\r\n\t}\r\n\t// Run all stat checks in parallel\r\n\tconst results = await Promise.allSettled(\r\n\t\tcandidates.map(async (c) => {\r\n\t\t\tconst abs = path.resolve(c);\r\n\t\t\tconst st = await safeStatCached(JS_STATS, abs);\r\n\t\t\treturn st && st.isFile() ? abs : null;\r\n\t\t})\r\n\t);\r\n\r\n\t// Find the first fulfilled non-null result\r\n\tfor (const r of results) {\r\n\t\tif (r.status === \"fulfilled\" && r.value) return r.value;\r\n\t}\r\n\r\n\treturn null;\r\n}\r\n\r\n// ---------------------------------------------------------\r\n// Cached stat + import scanners\r\n// ---------------------------------------------------------\r\n\r\nasync function getImportsCached(filePath: string, code: string): Promise<Set<string>> {\r\n\tconst cached = CacheManager.get(JS_IMPORTS, filePath);\r\n\tif (cached) return cached;\r\n\tconst set = await extractImports(filePath, code);\r\n\tCacheManager.set(JS_IMPORTS, filePath, set);\r\n\treturn set;\r\n}\r\n"]}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.resolveAliasPath = resolveAliasPath;
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const cache_1 = require("../../core/managers/cache");
|
|
9
|
+
const constants_1 = require("../../constants");
|
|
10
|
+
const helpers_1 = require("../../core/helpers");
|
|
11
|
+
/**
|
|
12
|
+
* 🧩 resolveAliasPath()
|
|
13
|
+
* Unifies alias lookup across config, cache, and fallback discovery.
|
|
14
|
+
*
|
|
15
|
+
* - Checks cfg.resolve.aliases first.
|
|
16
|
+
* - Then cached aliases (from Cache Manager).
|
|
17
|
+
* - If still unresolved, runs Fast-Glob to discover and cache new alias root.
|
|
18
|
+
*/
|
|
19
|
+
async function resolveAliasPath(specifier, root, cfg) {
|
|
20
|
+
if (!specifier.includes("/"))
|
|
21
|
+
return null;
|
|
22
|
+
const [aliasName, ...rest] = specifier.split("/");
|
|
23
|
+
const remainder = rest.join("/");
|
|
24
|
+
const knownAliases = cfg.resolve.aliases || {};
|
|
25
|
+
const aliasKey = aliasName.startsWith("@") ? aliasName : `@${aliasName}`;
|
|
26
|
+
// 1️⃣ Check config-defined aliases
|
|
27
|
+
if (knownAliases[aliasKey]) {
|
|
28
|
+
const relPart = remainder.replace(/^\/+/, "");
|
|
29
|
+
return path_1.default.resolve(root, knownAliases[aliasKey], relPart);
|
|
30
|
+
}
|
|
31
|
+
// 2️⃣ Check cached aliases
|
|
32
|
+
const cached = cache_1.CacheManager.get(constants_1.CACHE_KEYS.ALIASES, aliasKey);
|
|
33
|
+
if (cached) {
|
|
34
|
+
const relPart = remainder.replace(/^\/+/, "");
|
|
35
|
+
return path_1.default.resolve(root, cached, relPart);
|
|
36
|
+
}
|
|
37
|
+
// 3️⃣ Fallback discovery with Fast-Glob
|
|
38
|
+
const stripped = remainder; // remove prefix before first '/'
|
|
39
|
+
const hasExt = /\.[a-z0-9]+$/i.test(stripped);
|
|
40
|
+
const patterns = hasExt ? [`**/${stripped}`] : [`**/${stripped}.*`, `**/${stripped}/index.*`];
|
|
41
|
+
const { files: matches } = await (0, helpers_1.globScan)(patterns, { cwd: root });
|
|
42
|
+
if (matches.length === 1) {
|
|
43
|
+
return resolveMatches(matches, remainder, aliasKey);
|
|
44
|
+
}
|
|
45
|
+
//There are multiple matches, Assuming they match the target approximate folder.
|
|
46
|
+
if (matches.length > 1) {
|
|
47
|
+
const resolvedMatch = resolveMatches(matches, remainder, aliasKey);
|
|
48
|
+
return resolvedMatch.replace(/\.[^/.]+$/, "");
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
function resolveMatches(matches, remainder, aliasKey) {
|
|
53
|
+
const foundFile = matches[0];
|
|
54
|
+
const aliasRoot = foundFile.split(remainder)[0].replace(/\\/g, "/");
|
|
55
|
+
cache_1.CacheManager.set(constants_1.CACHE_KEYS.ALIASES, aliasKey, aliasRoot);
|
|
56
|
+
return foundFile;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=resolve-alias.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-alias.js","sourceRoot":"","sources":["../../../src/resolvers/js/resolve-alias.ts"],"names":[],"mappings":";;;;;AAcA,4CAwCC;AAtDD,gDAAwB;AACxB,qDAAyD;AAEzD,+CAA6C;AAC7C,gDAA8C;AAE9C;;;;;;;GAOG;AACI,KAAK,UAAU,gBAAgB,CAAC,SAAiB,EAAE,IAAY,EAAE,GAAiB;IACxF,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAE1C,MAAM,CAAC,SAAS,EAAE,GAAG,IAAI,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjC,MAAM,YAAY,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;IAC/C,MAAM,QAAQ,GAAG,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,SAAS,EAAE,CAAC;IAEzE,mCAAmC;IACnC,IAAI,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC9C,OAAO,cAAI,CAAC,OAAO,CAAC,IAAI,EAAE,YAAY,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;IAC5D,CAAC;IAED,2BAA2B;IAC3B,MAAM,MAAM,GAAG,oBAAY,CAAC,GAAG,CAAC,sBAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAE9D,IAAI,MAAM,EAAE,CAAC;QACZ,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC9C,OAAO,cAAI,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;IAED,wCAAwC;IACxC,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,iCAAiC;IAC7D,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,QAAQ,IAAI,EAAE,MAAM,QAAQ,UAAU,CAAC,CAAC;IAE9F,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,IAAA,kBAAQ,EAAC,QAAQ,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;IAEnE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,cAAc,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;IACrD,CAAC;IAED,gFAAgF;IAChF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,aAAa,GAAG,cAAc,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;QACnE,OAAO,aAAa,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO,IAAI,CAAC;AACb,CAAC;AAED,SAAS,cAAc,CAAC,OAAiB,EAAE,SAAiB,EAAE,QAAgB;IAC7E,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC7B,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACpE,oBAAY,CAAC,GAAG,CAAC,sBAAU,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC1D,OAAO,SAAS,CAAC;AAClB,CAAC","sourcesContent":["import path from \"path\";\r\nimport { CacheManager } from \"../../core/managers/cache\";\r\nimport type { ProdexConfig } from \"../../types\";\r\nimport { CACHE_KEYS } from \"../../constants\";\r\nimport { globScan } from \"../../core/helpers\";\r\n\r\n/**\r\n * 🧩 resolveAliasPath()\r\n * Unifies alias lookup across config, cache, and fallback discovery.\r\n *\r\n * - Checks cfg.resolve.aliases first.\r\n * - Then cached aliases (from Cache Manager).\r\n * - If still unresolved, runs Fast-Glob to discover and cache new alias root.\r\n */\r\nexport async function resolveAliasPath(specifier: string, root: string, cfg: ProdexConfig): Promise<string | null> {\r\n\tif (!specifier.includes(\"/\")) return null;\r\n\r\n\tconst [aliasName, ...rest] = specifier.split(\"/\");\r\n\tconst remainder = rest.join(\"/\");\r\n\tconst knownAliases = cfg.resolve.aliases || {};\r\n\tconst aliasKey = aliasName.startsWith(\"@\") ? aliasName : `@${aliasName}`;\r\n\r\n\t// 1️⃣ Check config-defined aliases\r\n\tif (knownAliases[aliasKey]) {\r\n\t\tconst relPart = remainder.replace(/^\\/+/, \"\");\r\n\t\treturn path.resolve(root, knownAliases[aliasKey], relPart);\r\n\t}\r\n\r\n\t// 2️⃣ Check cached aliases\r\n\tconst cached = CacheManager.get(CACHE_KEYS.ALIASES, aliasKey);\r\n\r\n\tif (cached) {\r\n\t\tconst relPart = remainder.replace(/^\\/+/, \"\");\r\n\t\treturn path.resolve(root, cached, relPart);\r\n\t}\r\n\r\n\t// 3️⃣ Fallback discovery with Fast-Glob\r\n\tconst stripped = remainder; // remove prefix before first '/'\r\n\tconst hasExt = /\\.[a-z0-9]+$/i.test(stripped);\r\n\tconst patterns = hasExt ? [`**/${stripped}`] : [`**/${stripped}.*`, `**/${stripped}/index.*`];\r\n\r\n\tconst { files: matches } = await globScan(patterns, { cwd: root });\r\n\r\n\tif (matches.length === 1) {\r\n\t\treturn resolveMatches(matches, remainder, aliasKey);\r\n\t}\r\n\r\n\t//There are multiple matches, Assuming they match the target approximate folder.\r\n\tif (matches.length > 1) {\r\n\t\tconst resolvedMatch = resolveMatches(matches, remainder, aliasKey);\r\n\t\treturn resolvedMatch.replace(/\\.[^/.]+$/, \"\");\r\n\t}\r\n\r\n\treturn null;\r\n}\r\n\r\nfunction resolveMatches(matches: string[], remainder: string, aliasKey: string) {\r\n\tconst foundFile = matches[0];\r\n\tconst aliasRoot = foundFile.split(remainder)[0].replace(/\\\\/g, \"/\");\r\n\tCacheManager.set(CACHE_KEYS.ALIASES, aliasKey, aliasRoot);\r\n\treturn foundFile;\r\n}\r\n"]}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// @ts-nocheck
|
|
3
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
4
|
};
|
|
@@ -7,18 +6,29 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
6
|
exports.loadLaravelBindings = loadLaravelBindings;
|
|
8
7
|
const fs_1 = __importDefault(require("fs"));
|
|
9
8
|
const path_1 = __importDefault(require("path"));
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
const cache_1 = require("../../core/managers/cache");
|
|
10
|
+
const cache_keys_1 = require("../../constants/cache-keys");
|
|
11
|
+
/**
|
|
12
|
+
* Scans app/Providers/*.php for `$this->app->bind()` / `singleton()` calls
|
|
13
|
+
* and returns a map of Interface::class → Implementation::class (FQCN strings).
|
|
14
|
+
*/
|
|
15
|
+
function loadLaravelBindings(root) {
|
|
16
|
+
const cached = cache_1.CacheManager.get(cache_keys_1.CACHE_KEYS.PHP_BINDINGS, root);
|
|
17
|
+
if (cached)
|
|
18
|
+
return cached;
|
|
19
|
+
const providersDir = path_1.default.join(root, "app", "Providers");
|
|
13
20
|
const bindings = {};
|
|
14
|
-
if (!fs_1.default.existsSync(providersDir))
|
|
21
|
+
if (!fs_1.default.existsSync(providersDir)) {
|
|
22
|
+
cache_1.CacheManager.set(cache_keys_1.CACHE_KEYS.PHP_BINDINGS, root, bindings);
|
|
15
23
|
return bindings;
|
|
24
|
+
}
|
|
16
25
|
const files = fs_1.default
|
|
17
26
|
.readdirSync(providersDir)
|
|
18
|
-
.filter(f => f.endsWith(".php"))
|
|
19
|
-
.map(f => path_1.default.join(providersDir, f));
|
|
20
|
-
//
|
|
21
|
-
|
|
27
|
+
.filter((f) => f.endsWith(".php"))
|
|
28
|
+
.map((f) => path_1.default.join(providersDir, f));
|
|
29
|
+
// $this->app->bind(Interface::class, Implementation::class)
|
|
30
|
+
// $this->app->singleton(Interface::class, Implementation::class)
|
|
31
|
+
const re = /\$this->app->(?:bind|singleton)\s*\(\s*([A-Za-z0-9_:\\\\]+)::class\s*,\s*([A-Za-z0-9_:\\\\]+)::class/g;
|
|
22
32
|
for (const file of files) {
|
|
23
33
|
const code = fs_1.default.readFileSync(file, "utf8");
|
|
24
34
|
let m;
|
|
@@ -28,5 +38,7 @@ function loadLaravelBindings() {
|
|
|
28
38
|
bindings[iface] = impl;
|
|
29
39
|
}
|
|
30
40
|
}
|
|
41
|
+
cache_1.CacheManager.set(cache_keys_1.CACHE_KEYS.PHP_BINDINGS, root, bindings);
|
|
31
42
|
return bindings;
|
|
32
43
|
}
|
|
44
|
+
//# sourceMappingURL=bindings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bindings.js","sourceRoot":"","sources":["../../../src/resolvers/php/bindings.ts"],"names":[],"mappings":";;;;;AASA,kDAkCC;AA3CD,4CAAoB;AACpB,gDAAwB;AACxB,qDAAyD;AACzD,2DAAwD;AAExD;;;GAGG;AACH,SAAgB,mBAAmB,CAAC,IAAY;IAC/C,MAAM,MAAM,GAAG,oBAAY,CAAC,GAAG,CAAC,uBAAU,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;IAC/D,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,MAAM,YAAY,GAAG,cAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;IACzD,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAE5C,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAClC,oBAAY,CAAC,GAAG,CAAC,uBAAU,CAAC,YAAY,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC1D,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED,MAAM,KAAK,GAAG,YAAE;SACd,WAAW,CAAC,YAAY,CAAC;SACzB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;SACjC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC;IAEzC,4DAA4D;IAC5D,iEAAiE;IACjE,MAAM,EAAE,GAAG,uGAAuG,CAAC;IAEnH,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,YAAE,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC3C,IAAI,CAAyB,CAAC;QAC9B,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YAC1C,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YACzC,QAAQ,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;QACxB,CAAC;IACF,CAAC;IAED,oBAAY,CAAC,GAAG,CAAC,uBAAU,CAAC,YAAY,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IAE1D,OAAO,QAAQ,CAAC;AACjB,CAAC","sourcesContent":["import fs from \"fs\";\r\nimport path from \"path\";\r\nimport { CacheManager } from \"../../core/managers/cache\";\r\nimport { CACHE_KEYS } from \"../../constants/cache-keys\";\r\n\r\n/**\r\n * Scans app/Providers/*.php for `$this->app->bind()` / `singleton()` calls\r\n * and returns a map of Interface::class → Implementation::class (FQCN strings).\r\n */\r\nexport function loadLaravelBindings(root: string): Record<string, string> {\r\n\tconst cached = CacheManager.get(CACHE_KEYS.PHP_BINDINGS, root);\r\n\tif (cached) return cached;\r\n\r\n\tconst providersDir = path.join(root, \"app\", \"Providers\");\r\n\tconst bindings: Record<string, string> = {};\r\n\r\n\tif (!fs.existsSync(providersDir)) {\r\n\t\tCacheManager.set(CACHE_KEYS.PHP_BINDINGS, root, bindings);\r\n\t\treturn bindings;\r\n\t}\r\n\r\n\tconst files = fs\r\n\t\t.readdirSync(providersDir)\r\n\t\t.filter((f) => f.endsWith(\".php\"))\r\n\t\t.map((f) => path.join(providersDir, f));\r\n\r\n\t// $this->app->bind(Interface::class, Implementation::class)\r\n\t// $this->app->singleton(Interface::class, Implementation::class)\r\n\tconst re = /\\$this->app->(?:bind|singleton)\\s*\\(\\s*([A-Za-z0-9_:\\\\\\\\]+)::class\\s*,\\s*([A-Za-z0-9_:\\\\\\\\]+)::class/g;\r\n\r\n\tfor (const file of files) {\r\n\t\tconst code = fs.readFileSync(file, \"utf8\");\r\n\t\tlet m: RegExpExecArray | null;\r\n\t\twhile ((m = re.exec(code))) {\r\n\t\t\tconst iface = m[1].replace(/\\\\\\\\/g, \"\\\\\");\r\n\t\t\tconst impl = m[2].replace(/\\\\\\\\/g, \"\\\\\");\r\n\t\t\tbindings[iface] = impl;\r\n\t\t}\r\n\t}\r\n\r\n\tCacheManager.set(CACHE_KEYS.PHP_BINDINGS, root, bindings);\r\n\r\n\treturn bindings;\r\n}\r\n"]}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractPhpImports = extractPhpImports;
|
|
4
|
+
exports.expandGroupedUses = expandGroupedUses;
|
|
5
|
+
/**
|
|
6
|
+
* Extracts import-like references from PHP code.
|
|
7
|
+
* Supports:
|
|
8
|
+
* - require/include/require_once/include_once
|
|
9
|
+
* - use statements (including grouped imports like `use App\Models\{User, Team};`)
|
|
10
|
+
*/
|
|
11
|
+
function extractPhpImports(code) {
|
|
12
|
+
const out = new Set();
|
|
13
|
+
const patterns = [
|
|
14
|
+
/\b(?:require|include|require_once|include_once)\s*\(?['"]([^'"]+)['"]\)?/g,
|
|
15
|
+
/\buse\s+([A-Z][\w\\]+(?:\s*{[^}]+})?)/g,
|
|
16
|
+
];
|
|
17
|
+
for (const r of patterns) {
|
|
18
|
+
let m;
|
|
19
|
+
while ((m = r.exec(code))) {
|
|
20
|
+
const val = m[1];
|
|
21
|
+
if (val)
|
|
22
|
+
out.add(val);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return out;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Expands grouped `use` imports into individual fully qualified names.
|
|
29
|
+
* Example:
|
|
30
|
+
* "App\\Models\\{User, Team}" → ["App\\Models\\User", "App\\Models\\Team"]
|
|
31
|
+
*/
|
|
32
|
+
function expandGroupedUses(raw) {
|
|
33
|
+
const out = new Set();
|
|
34
|
+
for (const imp of raw) {
|
|
35
|
+
const g = imp.match(/^(.+?)\s*{([^}]+)}/);
|
|
36
|
+
if (g) {
|
|
37
|
+
const base = g[1].trim().replace(/\\+$/, "");
|
|
38
|
+
g[2]
|
|
39
|
+
.split(",")
|
|
40
|
+
.map((x) => x.trim())
|
|
41
|
+
.filter(Boolean)
|
|
42
|
+
.forEach((p) => out.add(`${base}\\${p}`));
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
out.add(imp.trim());
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return out;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=extract-imports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract-imports.js","sourceRoot":"","sources":["../../../src/resolvers/php/extract-imports.ts"],"names":[],"mappings":";;AAQA,8CAgBC;AAOD,8CAgBC;AA7CD;;;;;GAKG;AACH,SAAgB,iBAAiB,CAAC,IAAY;IAC5C,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAE9B,MAAM,QAAQ,GAAa;QACzB,2EAA2E;QAC3E,wCAAwC;KACzC,CAAC;IAEF,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,IAAI,CAAyB,CAAC;QAC9B,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YAC1B,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACjB,IAAI,GAAG;gBAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,SAAgB,iBAAiB,CAAC,GAAgB;IAChD,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,KAAK,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;QACtB,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;QAC1C,IAAI,CAAC,EAAE,CAAC;YACN,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YAC7C,CAAC,CAAC,CAAC,CAAC;iBACD,KAAK,CAAC,GAAG,CAAC;iBACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;iBACpB,MAAM,CAAC,OAAO,CAAC;iBACf,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9C,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["import type { PhpResolverCtx } from \"../../types\";\r\n\r\n/**\r\n * Extracts import-like references from PHP code.\r\n * Supports:\r\n * - require/include/require_once/include_once\r\n * - use statements (including grouped imports like `use App\\Models\\{User, Team};`)\r\n */\r\nexport function extractPhpImports(code: string): Set<string> {\r\n const out = new Set<string>();\r\n\r\n const patterns: RegExp[] = [\r\n /\\b(?:require|include|require_once|include_once)\\s*\\(?['\"]([^'\"]+)['\"]\\)?/g,\r\n /\\buse\\s+([A-Z][\\w\\\\]+(?:\\s*{[^}]+})?)/g,\r\n ];\r\n\r\n for (const r of patterns) {\r\n let m: RegExpExecArray | null;\r\n while ((m = r.exec(code))) {\r\n const val = m[1];\r\n if (val) out.add(val);\r\n }\r\n }\r\n return out;\r\n}\r\n\r\n/**\r\n * Expands grouped `use` imports into individual fully qualified names.\r\n * Example:\r\n * \"App\\\\Models\\\\{User, Team}\" → [\"App\\\\Models\\\\User\", \"App\\\\Models\\\\Team\"]\r\n */\r\nexport function expandGroupedUses(raw: Set<string>): Set<string> {\r\n const out = new Set<string>();\r\n for (const imp of raw) {\r\n const g = imp.match(/^(.+?)\\s*{([^}]+)}/);\r\n if (g) {\r\n const base = g[1].trim().replace(/\\\\+$/, \"\");\r\n g[2]\r\n .split(\",\")\r\n .map((x) => x.trim())\r\n .filter(Boolean)\r\n .forEach((p) => out.add(`${base}\\\\${p}`));\r\n } else {\r\n out.add(imp.trim());\r\n }\r\n }\r\n return out;\r\n}\r\n"]}
|
|
@@ -1,17 +1,50 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// @ts-nocheck
|
|
3
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
3
|
exports.extractPhpImports = extractPhpImports;
|
|
4
|
+
exports.expandGroupedUses = expandGroupedUses;
|
|
5
|
+
/**
|
|
6
|
+
* Extracts import-like references from PHP code.
|
|
7
|
+
* Supports:
|
|
8
|
+
* - require/include/require_once/include_once
|
|
9
|
+
* - use statements (including grouped imports like `use App\Models\{User, Team};`)
|
|
10
|
+
*/
|
|
5
11
|
function extractPhpImports(code) {
|
|
6
12
|
const out = new Set();
|
|
7
13
|
const patterns = [
|
|
8
14
|
/\b(?:require|include|require_once|include_once)\s*\(?['"]([^'"]+)['"]\)?/g,
|
|
9
|
-
/\buse\s+([A-Z][\w\\]+(?:\s*{[^}]+})?)/g
|
|
15
|
+
/\buse\s+([A-Z][\w\\]+(?:\s*{[^}]+})?)/g,
|
|
10
16
|
];
|
|
11
17
|
for (const r of patterns) {
|
|
12
18
|
let m;
|
|
13
|
-
while ((m = r.exec(code)))
|
|
14
|
-
|
|
19
|
+
while ((m = r.exec(code))) {
|
|
20
|
+
const val = m[1];
|
|
21
|
+
if (val)
|
|
22
|
+
out.add(val);
|
|
23
|
+
}
|
|
15
24
|
}
|
|
16
25
|
return out;
|
|
17
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Expands grouped `use` imports into individual fully qualified names.
|
|
29
|
+
* Example:
|
|
30
|
+
* "App\\Models\\{User, Team}" → ["App\\Models\\User", "App\\Models\\Team"]
|
|
31
|
+
*/
|
|
32
|
+
function expandGroupedUses(raw) {
|
|
33
|
+
const out = new Set();
|
|
34
|
+
for (const imp of raw) {
|
|
35
|
+
const g = imp.match(/^(.+?)\s*{([^}]+)}/);
|
|
36
|
+
if (g) {
|
|
37
|
+
const base = g[1].trim().replace(/\\+$/, "");
|
|
38
|
+
g[2]
|
|
39
|
+
.split(",")
|
|
40
|
+
.map((x) => x.trim())
|
|
41
|
+
.filter(Boolean)
|
|
42
|
+
.forEach((p) => out.add(`${base}\\${p}`));
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
out.add(imp.trim());
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return out;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=patterns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patterns.js","sourceRoot":"","sources":["../../../src/resolvers/php/patterns.ts"],"names":[],"mappings":";;AAQA,8CAgBC;AAOD,8CAgBC;AA7CD;;;;;GAKG;AACH,SAAgB,iBAAiB,CAAC,IAAY;IAC5C,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAE9B,MAAM,QAAQ,GAAa;QACzB,2EAA2E;QAC3E,wCAAwC;KACzC,CAAC;IAEF,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,IAAI,CAAyB,CAAC;QAC9B,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YAC1B,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACjB,IAAI,GAAG;gBAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,SAAgB,iBAAiB,CAAC,GAAgB;IAChD,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,KAAK,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;QACtB,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;QAC1C,IAAI,CAAC,EAAE,CAAC;YACN,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YAC7C,CAAC,CAAC,CAAC,CAAC;iBACD,KAAK,CAAC,GAAG,CAAC;iBACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;iBACpB,MAAM,CAAC,OAAO,CAAC;iBACf,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9C,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["import type { PhpResolverCtx } from \"../../types\";\r\n\r\n/**\r\n * Extracts import-like references from PHP code.\r\n * Supports:\r\n * - require/include/require_once/include_once\r\n * - use statements (including grouped imports like `use App\\Models\\{User, Team};`)\r\n */\r\nexport function extractPhpImports(code: string): Set<string> {\r\n const out = new Set<string>();\r\n\r\n const patterns: RegExp[] = [\r\n /\\b(?:require|include|require_once|include_once)\\s*\\(?['\"]([^'\"]+)['\"]\\)?/g,\r\n /\\buse\\s+([A-Z][\\w\\\\]+(?:\\s*{[^}]+})?)/g,\r\n ];\r\n\r\n for (const r of patterns) {\r\n let m: RegExpExecArray | null;\r\n while ((m = r.exec(code))) {\r\n const val = m[1];\r\n if (val) out.add(val);\r\n }\r\n }\r\n return out;\r\n}\r\n\r\n/**\r\n * Expands grouped `use` imports into individual fully qualified names.\r\n * Example:\r\n * \"App\\\\Models\\\\{User, Team}\" → [\"App\\\\Models\\\\User\", \"App\\\\Models\\\\Team\"]\r\n */\r\nexport function expandGroupedUses(raw: Set<string>): Set<string> {\r\n const out = new Set<string>();\r\n for (const imp of raw) {\r\n const g = imp.match(/^(.+?)\\s*{([^}]+)}/);\r\n if (g) {\r\n const base = g[1].trim().replace(/\\\\+$/, \"\");\r\n g[2]\r\n .split(\",\")\r\n .map((x) => x.trim())\r\n .filter(Boolean)\r\n .forEach((p) => out.add(`${base}\\\\${p}`));\r\n } else {\r\n out.add(imp.trim());\r\n }\r\n }\r\n return out;\r\n}\r\n"]}
|