prodex 1.3.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.
Files changed (114) hide show
  1. package/README.md +234 -234
  2. package/dist/cli/cli-input.js +21 -26
  3. package/dist/cli/cli-input.js.map +1 -0
  4. package/dist/cli/flags.js +1 -0
  5. package/dist/cli/flags.js.map +1 -0
  6. package/dist/cli/init.js +5 -5
  7. package/dist/cli/init.js.map +1 -0
  8. package/dist/cli/picker.js +9 -7
  9. package/dist/cli/picker.js.map +1 -0
  10. package/dist/cli/summary.js +16 -9
  11. package/dist/cli/summary.js.map +1 -0
  12. package/dist/constants/cache-keys.js +12 -0
  13. package/dist/constants/cache-keys.js.map +1 -0
  14. package/dist/constants/config-loader.js +2 -2
  15. package/dist/constants/config-loader.js.map +1 -0
  16. package/dist/constants/config.js +7 -5
  17. package/dist/constants/config.js.map +1 -0
  18. package/dist/constants/default-config.js +1 -0
  19. package/dist/constants/default-config.js.map +1 -0
  20. package/dist/constants/flags.js +74 -0
  21. package/dist/constants/flags.js.map +1 -0
  22. package/dist/constants/index.js +21 -0
  23. package/dist/constants/index.js.map +1 -0
  24. package/dist/constants/render-constants.js +1 -4
  25. package/dist/constants/render-constants.js.map +1 -0
  26. package/dist/core/cache.js +54 -0
  27. package/dist/core/cache.js.map +1 -0
  28. package/dist/core/combine.js +32 -13
  29. package/dist/core/combine.js.map +1 -0
  30. package/dist/core/config-manager.js +104 -0
  31. package/dist/core/config-manager.js.map +1 -0
  32. package/dist/core/dependency.js +40 -19
  33. package/dist/core/dependency.js.map +1 -0
  34. package/dist/core/file-utils.js +1 -41
  35. package/dist/core/file-utils.js.map +1 -0
  36. package/dist/core/helpers.js +43 -38
  37. package/dist/core/helpers.js.map +1 -0
  38. package/dist/core/managers/cache.js +54 -0
  39. package/dist/core/managers/cache.js.map +1 -0
  40. package/dist/core/managers/config-manager.js +104 -0
  41. package/dist/core/managers/config-manager.js.map +1 -0
  42. package/dist/core/managers/config.js +104 -0
  43. package/dist/core/managers/config.js.map +1 -0
  44. package/dist/core/output.js +1 -0
  45. package/dist/core/output.js.map +1 -0
  46. package/dist/core/parsers/extract-imports.js +2 -7
  47. package/dist/core/parsers/extract-imports.js.map +1 -0
  48. package/dist/core/renderers.js +10 -8
  49. package/dist/core/renderers.js.map +1 -0
  50. package/dist/debug.js +14 -0
  51. package/dist/debug.js.map +1 -0
  52. package/dist/index.js +43 -13
  53. package/dist/index.js.map +1 -0
  54. package/dist/lib/logger.js +38 -9
  55. package/dist/lib/logger.js.map +1 -0
  56. package/dist/lib/polyfills.js +1 -10
  57. package/dist/lib/polyfills.js.map +1 -0
  58. package/dist/lib/prompt.js +1 -0
  59. package/dist/lib/prompt.js.map +1 -0
  60. package/dist/lib/questions.js +1 -0
  61. package/dist/lib/questions.js.map +1 -0
  62. package/dist/lib/utils.js +1 -13
  63. package/dist/lib/utils.js.map +1 -0
  64. package/dist/resolvers/js/alias-loader.js +1 -0
  65. package/dist/resolvers/js/alias-loader.js.map +1 -0
  66. package/dist/resolvers/js/extract-imports.js +46 -0
  67. package/dist/resolvers/js/extract-imports.js.map +1 -0
  68. package/dist/resolvers/js/js-resolver.js +93 -116
  69. package/dist/resolvers/js/js-resolver.js.map +1 -0
  70. package/dist/resolvers/js/resolve-alias.js +58 -0
  71. package/dist/resolvers/js/resolve-alias.js.map +1 -0
  72. package/dist/resolvers/php/bindings.js +21 -9
  73. package/dist/resolvers/php/bindings.js.map +1 -0
  74. package/dist/resolvers/php/extract-imports.js +50 -0
  75. package/dist/resolvers/php/extract-imports.js.map +1 -0
  76. package/dist/resolvers/php/patterns.js +37 -4
  77. package/dist/resolvers/php/patterns.js.map +1 -0
  78. package/dist/resolvers/php/php-resolver.js +99 -59
  79. package/dist/resolvers/php/php-resolver.js.map +1 -0
  80. package/dist/resolvers/php/psr4.js +19 -5
  81. package/dist/resolvers/php/psr4.js.map +1 -0
  82. package/dist/resolvers/shared/excludes.js +1 -0
  83. package/dist/resolvers/shared/excludes.js.map +1 -0
  84. package/dist/resolvers/shared/file-cache.js +1 -29
  85. package/dist/resolvers/shared/file-cache.js.map +1 -0
  86. package/dist/resolvers/shared/resolve-alias.js +62 -0
  87. package/dist/resolvers/shared/resolve-alias.js.map +1 -0
  88. package/dist/resolvers/shared/stats.js +3 -3
  89. package/dist/resolvers/shared/stats.js.map +1 -0
  90. package/dist/shared/collections.js +34 -0
  91. package/dist/shared/collections.js.map +1 -0
  92. package/dist/shared/index.js +20 -0
  93. package/dist/shared/index.js.map +1 -0
  94. package/dist/shared/io.js +52 -0
  95. package/dist/shared/io.js.map +1 -0
  96. package/dist/shared/patterns.js +30 -0
  97. package/dist/shared/patterns.js.map +1 -0
  98. package/dist/shared/stats.js +32 -0
  99. package/dist/shared/stats.js.map +1 -0
  100. package/dist/store.js +16 -0
  101. package/dist/store.js.map +1 -0
  102. package/dist/types/cli.types.js +1 -0
  103. package/dist/types/cli.types.js.map +1 -0
  104. package/dist/types/config.types.js +1 -0
  105. package/dist/types/config.types.js.map +1 -0
  106. package/dist/types/core.types.js +1 -0
  107. package/dist/types/core.types.js.map +1 -0
  108. package/dist/types/index.js +1 -0
  109. package/dist/types/index.js.map +1 -0
  110. package/dist/types/resolver.types.js +1 -0
  111. package/dist/types/resolver.types.js.map +1 -0
  112. package/dist/types/utils.types.js +1 -0
  113. package/dist/types/utils.types.js.map +1 -0
  114. 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 micromatch_1 = __importDefault(require("micromatch"));
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 utils_1 = require("../../lib/utils");
10
+ const collections_1 = require("../../shared/collections");
15
11
  const logger_1 = require("../../lib/logger");
16
- const IMPORTS_CACHE = new Map();
17
- const STAT_CACHE = new Map();
18
- async function resolveJsImports(filePath, cfg, visited = new Set(), depth = 0, maxDepth = cfg?.resolve?.depth ?? 8, ctx = {}) {
19
- if (depth >= maxDepth)
20
- return empty(visited);
21
- const ROOT = cfg.root;
22
- const resolveCfg = cfg.resolve ?? {};
23
- // Single exclude list, applied to RAW SPECIFIERS only.
24
- const exclude = resolveCfg.exclude ?? [];
25
- const isExcluded = micromatch_1.default.matcher(exclude);
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 empty(visited);
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 empty(visited);
33
- let code;
34
- try {
35
- code = await promises_1.default.readFile(filePath, "utf8");
36
- }
37
- catch {
38
- return empty(visited);
39
- }
40
- if (!ctx.aliases) {
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 resolvedSet = new Set();
50
- for (const imp of matches) {
51
- // Only consider relative, absolute, or known-alias specifiers
52
- if (!imp.startsWith(".") && !imp.startsWith("/") && !startsWithAnyAlias(imp, aliases)) {
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
- // Always count valid, non-excluded specifiers as "expected"
59
- expected.add(imp);
60
- const basePath = resolveBasePath(filePath, imp, aliases);
61
- if (!basePath)
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 resolvedPath = await tryResolveImport(basePath, ROOT);
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
- filesOut.push(resolvedPath);
67
- resolvedSet.add(imp);
68
- // Never recurse into `.d.ts`
69
- if (resolvedPath.toLowerCase().endsWith(config_1.DTS_EXT)) {
70
- continue;
71
- logger_1.logger.debug("HERE HERE");
72
- }
73
- const sub = await resolveJsImports(resolvedPath, cfg, visited, depth + 1, maxDepth, ctx);
74
- if (sub.files.length)
75
- filesOut.push(...sub.files);
76
- for (const s of sub.stats.expected)
77
- expected.add(s);
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
- resolvedSet.add(r);
82
+ resolved.add(r);
80
83
  }
81
- const uniqueFiles = [...new Set(filesOut)];
82
- //Stat Log
83
- const expCount = expected.size;
84
- const resCount = resolvedSet.size;
85
- const diff = (0, utils_1.setDiff)(expected, resolvedSet);
86
- logger_1.logger.debug(`🪶 [js-resolver] ${filePath} expected: ${expCount}, resolved: ${resCount}`);
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
- function resolveBasePath(fromFile, specifier, aliases) {
95
- if (specifier.startsWith("@")) {
96
- const key = Object.keys(aliases)
97
- .filter((a) => specifier === a || specifier.startsWith(a + "/"))
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
- if (path_1.default.extname(basePath)) {
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 ext of [...config_1.BASE_EXTS, config_1.DTS_EXT]) {
119
- candidates.push(basePath + ext);
120
- candidates.push(path_1.default.join(basePath, "index" + ext));
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
- for (const c of candidates) {
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 safeStat(abs);
126
- if (st && st.isFile())
127
- return abs;
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
- async function safeStat(p) {
132
- if (STAT_CACHE.has(p))
133
- return STAT_CACHE.get(p);
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
- if (IMPORTS_CACHE.has(filePath))
146
- return IMPORTS_CACHE.get(filePath);
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
- IMPORTS_CACHE.set(filePath, set);
127
+ cache_1.CacheManager.set(JS_IMPORTS, filePath, set);
149
128
  return set;
150
129
  }
151
- function empty(visited) {
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 config_1 = require("../../constants/config");
11
- function loadLaravelBindings() {
12
- const providersDir = path_1.default.join(config_1.ROOT, "app", "Providers");
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
- // Match: $this->app->bind(Interface::class, Implementation::class)
21
- const re = /$this->app->(?:bind|singleton)\s*\(\s*([A-Za-z0-9_:\\\\]+)::class\s*,\s*([A-Za-z0-9_:\\\\]+)::class/g;
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
- out.add(m[1]);
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"]}