prodex 1.4.5 → 1.4.7
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.
|
@@ -21,7 +21,7 @@ class CacheManager {
|
|
|
21
21
|
/** Set or update a cached entry */
|
|
22
22
|
static set(ns, key, val) {
|
|
23
23
|
this.ns(ns).set(key, val);
|
|
24
|
-
logger_1.logger.debug(`🧩 [cache:${ns}] set ${key} → ${
|
|
24
|
+
logger_1.logger.debug(`🧩 [cache:${ns}] set ${key} \n→ ${_2j(val)}`);
|
|
25
25
|
}
|
|
26
26
|
/** Retrieve a cached entry */
|
|
27
27
|
static get(ns, key) {
|
|
@@ -16,7 +16,7 @@ const store_1 = require("../../store");
|
|
|
16
16
|
*/
|
|
17
17
|
class ConfigManager {
|
|
18
18
|
static rawFile = null;
|
|
19
|
-
static load(cwd) {
|
|
19
|
+
static load(cwd = process.cwd()) {
|
|
20
20
|
const file = path_1.default.join(cwd, "prodex.json");
|
|
21
21
|
if (!fs_1.default.existsSync(file))
|
|
22
22
|
return default_config_1.DEFAULT_PRODEX_CONFIG;
|
|
@@ -43,7 +43,7 @@ async function resolveJsImports({ filePath, visited = new Set(), depth = 0, maxD
|
|
|
43
43
|
// skip bare packages (react, lodash, etc.)
|
|
44
44
|
if (!imp.startsWith(".") && !imp.startsWith("/") && !imp.startsWith("@"))
|
|
45
45
|
continue;
|
|
46
|
-
if ((0, shared_1.isExcluded)(imp, excludePatterns))
|
|
46
|
+
if ((0, shared_1.isExcluded)(imp, excludePatterns, ROOT))
|
|
47
47
|
continue;
|
|
48
48
|
let base = null;
|
|
49
49
|
if (imp.startsWith(".")) {
|
|
@@ -62,11 +62,11 @@ async function resolveJsImports({ filePath, visited = new Set(), depth = 0, maxD
|
|
|
62
62
|
continue;
|
|
63
63
|
const absBase = path_1.default.resolve(base);
|
|
64
64
|
// Exclusion check after alias resolution
|
|
65
|
-
if ((0, shared_1.isExcluded)(absBase, excludePatterns))
|
|
65
|
+
if ((0, shared_1.isExcluded)(absBase, excludePatterns, ROOT))
|
|
66
66
|
continue;
|
|
67
67
|
const resolvedPath = await tryResolveImport(absBase);
|
|
68
68
|
// Exclusion check after final resolution
|
|
69
|
-
if ((0, shared_1.isExcluded)(resolvedPath, excludePatterns))
|
|
69
|
+
if ((0, shared_1.isExcluded)(resolvedPath, excludePatterns, ROOT))
|
|
70
70
|
continue;
|
|
71
71
|
stats.expected.add(absBase);
|
|
72
72
|
if (!resolvedPath)
|
|
@@ -8,9 +8,14 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
9
|
const cache_1 = require("../../core/managers/cache");
|
|
10
10
|
const cache_keys_1 = require("../../constants/cache-keys");
|
|
11
|
+
const extract_imports_1 = require("./extract-imports");
|
|
12
|
+
const logger_1 = require("../../lib/logger");
|
|
11
13
|
/**
|
|
12
|
-
* Scans app/Providers/*.php for
|
|
13
|
-
* and returns a map of
|
|
14
|
+
* Scans app/Providers/*.php for $this->app->bind() / singleton() calls
|
|
15
|
+
* and returns a map of InterfaceFQCN → ImplementationFQCN.
|
|
16
|
+
*
|
|
17
|
+
* Uses existing extractPhpImports + expandGroupedUses to correctly
|
|
18
|
+
* resolve namespaces and short class names.
|
|
14
19
|
*/
|
|
15
20
|
function loadLaravelBindings(root) {
|
|
16
21
|
const cached = cache_1.CacheManager.get(cache_keys_1.CACHE_KEYS.PHP_BINDINGS, root);
|
|
@@ -26,16 +31,27 @@ function loadLaravelBindings(root) {
|
|
|
26
31
|
.readdirSync(providersDir)
|
|
27
32
|
.filter((f) => f.endsWith(".php"))
|
|
28
33
|
.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;
|
|
32
34
|
for (const file of files) {
|
|
33
35
|
const code = fs_1.default.readFileSync(file, "utf8");
|
|
36
|
+
// 1️⃣ Extract all imports in the provider
|
|
37
|
+
const rawImports = (0, extract_imports_1.extractPhpImports)(code);
|
|
38
|
+
const expanded = (0, extract_imports_1.expandGroupedUses)(rawImports);
|
|
39
|
+
// Build ShortName → FQCN map
|
|
40
|
+
const importMap = {};
|
|
41
|
+
for (const fqcn of expanded) {
|
|
42
|
+
const short = fqcn.split("\\").pop();
|
|
43
|
+
importMap[short] = fqcn;
|
|
44
|
+
}
|
|
45
|
+
// 2️⃣ Extract bindings (short class names only)
|
|
46
|
+
const bindRe = /\$this->app->(?:bind|singleton)\s*\(\s*([A-Za-z0-9_]+)::class\s*,\s*([A-Za-z0-9_]+)::class/g;
|
|
34
47
|
let m;
|
|
35
|
-
while ((m =
|
|
36
|
-
const
|
|
37
|
-
const
|
|
38
|
-
|
|
48
|
+
while ((m = bindRe.exec(code))) {
|
|
49
|
+
const ifaceShort = m[1];
|
|
50
|
+
const implShort = m[2];
|
|
51
|
+
const ifaceFull = importMap[ifaceShort] || ifaceShort;
|
|
52
|
+
const implFull = importMap[implShort] || implShort;
|
|
53
|
+
logger_1.logger.debug(`[laravel-bindings] ${file} => ${ifaceFull} → ${implFull}`);
|
|
54
|
+
bindings[ifaceFull] = implFull;
|
|
39
55
|
}
|
|
40
56
|
}
|
|
41
57
|
cache_1.CacheManager.set(cache_keys_1.CACHE_KEYS.PHP_BINDINGS, root, bindings);
|
|
@@ -64,18 +64,17 @@ async function resolvePhpImports({ filePath, visited = new Set(), depth = 0, max
|
|
|
64
64
|
let imp = imp0;
|
|
65
65
|
// Respect Laravel container bindings (Interface → Implementation)
|
|
66
66
|
if (phpCtx.bindings[imp]) {
|
|
67
|
-
|
|
67
|
+
// logger.debug("[php-resolver] binding:", imp, "→", _2j(phpCtx.bindings[imp]));
|
|
68
68
|
imp = phpCtx.bindings[imp];
|
|
69
69
|
}
|
|
70
70
|
// Only resolve PSR-4 mapped namespaces
|
|
71
71
|
if (!startsWithAnyNamespace(imp, phpCtx.nsKeys))
|
|
72
72
|
continue;
|
|
73
|
-
if (
|
|
74
|
-
continue;
|
|
73
|
+
// if (isExcluded(imp, excludePatterns, ROOT)) continue;
|
|
75
74
|
// Resolve namespace → file path (sync helper retained)
|
|
76
75
|
const resolvedPath = await tryResolvePhpFile(imp, filePath, phpCtx.psr4);
|
|
77
76
|
// Exclusion check after final resolution
|
|
78
|
-
if ((0, shared_1.isExcluded)(resolvedPath, excludePatterns))
|
|
77
|
+
if ((0, shared_1.isExcluded)(resolvedPath, excludePatterns, ROOT))
|
|
79
78
|
continue;
|
|
80
79
|
stats.expected.add(imp);
|
|
81
80
|
if (!resolvedPath)
|
|
@@ -110,7 +109,7 @@ async function tryResolvePhpFile(imp, fromFile, psr4) {
|
|
|
110
109
|
cache_1.CacheManager.set(constants_1.CACHE_KEYS.PHP_FILECACHE, key, null);
|
|
111
110
|
return null;
|
|
112
111
|
}
|
|
113
|
-
const rel = imp.
|
|
112
|
+
const rel = imp.replace(nsKey, "").norm();
|
|
114
113
|
const tries = [path_1.default.join(psr4[nsKey], rel), path_1.default.join(psr4[nsKey], rel + ".php"), path_1.default.join(psr4[nsKey], rel, "index.php")];
|
|
115
114
|
// 🔹 Run all stats concurrently
|
|
116
115
|
const results = await Promise.allSettled(tries.map(async (p) => {
|
package/dist/shared/patterns.js
CHANGED
|
@@ -4,28 +4,24 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.isExcluded = isExcluded;
|
|
7
|
-
exports.makeExcludeMatcher = makeExcludeMatcher;
|
|
8
7
|
// File: src/shared/patterns.ts
|
|
9
8
|
const micromatch_1 = __importDefault(require("micromatch"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const _1 = require(".");
|
|
10
11
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
12
|
+
* Centralized exclusion logic.
|
|
13
|
+
* Accepts namespaces, absolute paths, or relative paths
|
|
14
|
+
* and converts everything to a normalized, root-relative glob target.
|
|
13
15
|
*/
|
|
14
|
-
function isExcluded(p
|
|
16
|
+
function isExcluded(p, patterns = [], root = process.cwd()) {
|
|
15
17
|
if (!patterns?.length)
|
|
16
18
|
return false;
|
|
17
19
|
if (!p)
|
|
18
20
|
return false;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
*/
|
|
26
|
-
function makeExcludeMatcher(patterns = []) {
|
|
27
|
-
if (!patterns?.length)
|
|
28
|
-
return () => false;
|
|
29
|
-
const mm = micromatch_1.default.matcher(patterns);
|
|
30
|
-
return (s) => mm(String(s).replace(/\\/g, "/"));
|
|
21
|
+
let norm = p.norm();
|
|
22
|
+
if (!path_1.default.isAbsolute(norm) && /^[A-Z]/.test(norm))
|
|
23
|
+
return false;
|
|
24
|
+
if (path_1.default.isAbsolute(norm))
|
|
25
|
+
norm = (0, _1.rel)(norm, root).norm();
|
|
26
|
+
return micromatch_1.default.isMatch(norm, patterns);
|
|
31
27
|
}
|