prodex 1.4.11 → 2.0.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 (142) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +238 -234
  3. package/bin/prodex.js +0 -0
  4. package/dist/app/execute-run.d.ts +2 -0
  5. package/dist/app/execute-run.js +73 -0
  6. package/dist/app/project-context.d.ts +12 -0
  7. package/dist/app/project-context.js +48 -0
  8. package/dist/app/run-plans.d.ts +11 -0
  9. package/dist/app/run-plans.js +61 -0
  10. package/dist/cache/cache-keys.d.ts +9 -0
  11. package/dist/cache/cache-manager.d.ts +9 -0
  12. package/dist/{core/managers/cache.js → cache/cache-manager.js} +5 -18
  13. package/dist/cli/cli-input.d.ts +2 -0
  14. package/dist/cli/cli-input.js +138 -124
  15. package/dist/cli/flag-specs.d.ts +12 -0
  16. package/dist/cli/flag-specs.js +27 -0
  17. package/dist/cli/help.d.ts +2 -0
  18. package/dist/cli/help.js +83 -0
  19. package/dist/cli/report-command.d.ts +2 -0
  20. package/dist/cli/report-command.js +80 -0
  21. package/dist/cli/reporter.d.ts +2 -0
  22. package/dist/cli/reporter.js +8 -0
  23. package/dist/commands/init-command.d.ts +1 -0
  24. package/dist/commands/init-command.js +9 -0
  25. package/dist/commands/migrate-command.d.ts +7 -0
  26. package/dist/commands/migrate-command.js +76 -0
  27. package/dist/commands/profiles-command.d.ts +6 -0
  28. package/dist/commands/profiles-command.js +16 -0
  29. package/dist/commands/run-command.d.ts +11 -0
  30. package/dist/commands/run-command.js +17 -0
  31. package/dist/config/build-config.d.ts +13 -0
  32. package/dist/config/build-config.js +127 -0
  33. package/dist/config/create-default-config.d.ts +9 -0
  34. package/dist/config/create-default-config.js +25 -0
  35. package/dist/config/default-config.d.ts +2 -0
  36. package/dist/config/default-config.js +23 -0
  37. package/dist/config/json.d.ts +2 -0
  38. package/dist/config/json.js +10 -0
  39. package/dist/config/load.d.ts +9 -0
  40. package/dist/config/load.js +48 -0
  41. package/dist/config/migration/detect.d.ts +4 -0
  42. package/dist/config/migration/detect.js +22 -0
  43. package/dist/config/migration/index.d.ts +4 -0
  44. package/dist/{shared → config/migration}/index.js +4 -3
  45. package/dist/config/migration/messages.d.ts +2 -0
  46. package/dist/config/migration/messages.js +35 -0
  47. package/dist/config/migration/transform.d.ts +2 -0
  48. package/dist/config/migration/transform.js +80 -0
  49. package/dist/config/migration/types.d.ts +16 -0
  50. package/dist/config/string-list.d.ts +2 -0
  51. package/dist/config/string-list.js +17 -0
  52. package/dist/diagnostics/logger.d.ts +3 -0
  53. package/dist/diagnostics/logger.js +33 -0
  54. package/dist/filesystem/glob-scan.d.ts +4 -0
  55. package/dist/filesystem/glob-scan.js +26 -0
  56. package/dist/filesystem/inspect.d.ts +1 -0
  57. package/dist/filesystem/inspect.js +15 -0
  58. package/dist/filesystem/path.d.ts +2 -0
  59. package/dist/filesystem/path.js +11 -0
  60. package/dist/filesystem/read-file.d.ts +8 -0
  61. package/dist/{shared/io.js → filesystem/read-file.js} +0 -25
  62. package/dist/filesystem/stat-cache.d.ts +1 -0
  63. package/dist/filesystem/stat-cache.js +22 -0
  64. package/dist/index.d.ts +3 -0
  65. package/dist/index.js +76 -83
  66. package/dist/output/markdown.d.ts +12 -0
  67. package/dist/output/markdown.js +150 -0
  68. package/dist/output/naming.d.ts +2 -0
  69. package/dist/output/naming.js +30 -0
  70. package/dist/output/produce-output.d.ts +2 -0
  71. package/dist/output/produce-output.js +35 -0
  72. package/dist/output/render-constants.d.ts +21 -0
  73. package/dist/{constants → output}/render-constants.js +2 -1
  74. package/dist/output/text.d.ts +2 -0
  75. package/dist/output/text.js +14 -0
  76. package/dist/resolvers/js/extract-imports.d.ts +1 -0
  77. package/dist/resolvers/js/js-resolver.d.ts +2 -0
  78. package/dist/resolvers/js/js-resolver.js +45 -89
  79. package/dist/resolvers/js/resolve-alias.d.ts +2 -0
  80. package/dist/resolvers/js/resolve-alias.js +12 -20
  81. package/dist/resolvers/php/bindings.d.ts +8 -0
  82. package/dist/resolvers/php/bindings.js +8 -9
  83. package/dist/resolvers/php/extract-imports.d.ts +13 -0
  84. package/dist/resolvers/php/extract-imports.js +1 -1
  85. package/dist/resolvers/php/php-resolver.d.ts +2 -0
  86. package/dist/resolvers/php/php-resolver.js +61 -90
  87. package/dist/resolvers/php/psr4.d.ts +5 -0
  88. package/dist/resolvers/php/psr4.js +7 -7
  89. package/dist/resolvers/resolver-constants.d.ts +4 -0
  90. package/dist/resolvers/resolver-constants.js +7 -0
  91. package/dist/resolvers/resolver-result.d.ts +5 -0
  92. package/dist/resolvers/resolver-result.js +18 -0
  93. package/dist/tracing/exclude.d.ts +6 -0
  94. package/dist/{shared/patterns.js → tracing/exclude.js} +4 -4
  95. package/dist/tracing/follow-chain.d.ts +5 -0
  96. package/dist/tracing/follow-chain.js +63 -0
  97. package/dist/tracing/include-files.d.ts +2 -0
  98. package/dist/tracing/include-files.js +36 -0
  99. package/dist/tracing/resolver-registry.d.ts +5 -0
  100. package/dist/tracing/resolver-registry.js +20 -0
  101. package/dist/tracing/trace-run.d.ts +2 -0
  102. package/dist/tracing/trace-run.js +21 -0
  103. package/dist/tracing/trace-stats.d.ts +4 -0
  104. package/dist/tracing/trace-stats.js +16 -0
  105. package/dist/types/app.types.d.ts +61 -0
  106. package/dist/types/app.types.js +2 -0
  107. package/dist/types/cli.types.d.ts +22 -0
  108. package/dist/types/cli.types.js +0 -10
  109. package/dist/types/config.types.d.ts +34 -0
  110. package/dist/types/index.d.ts +7 -0
  111. package/dist/types/index.js +3 -1
  112. package/dist/types/output.types.d.ts +6 -0
  113. package/dist/types/output.types.js +2 -0
  114. package/dist/types/resolver.types.d.ts +23 -0
  115. package/dist/types/tracing.types.d.ts +23 -0
  116. package/dist/types/tracing.types.js +2 -0
  117. package/dist/types/utils.types.d.ts +10 -0
  118. package/package.json +35 -12
  119. package/schema/prodex.schema.json +122 -0
  120. package/dist/cli/init.js +0 -21
  121. package/dist/cli/picker.js +0 -83
  122. package/dist/cli/summary.js +0 -32
  123. package/dist/constants/config.js +0 -27
  124. package/dist/constants/default-config.js +0 -43
  125. package/dist/constants/flags.js +0 -79
  126. package/dist/constants/index.js +0 -20
  127. package/dist/core/combine.js +0 -56
  128. package/dist/core/dependency.js +0 -98
  129. package/dist/core/helpers.js +0 -85
  130. package/dist/core/managers/config.js +0 -140
  131. package/dist/core/output.js +0 -49
  132. package/dist/core/renderers.js +0 -210
  133. package/dist/debug.js +0 -15
  134. package/dist/lib/logger.js +0 -42
  135. package/dist/lib/polyfills.js +0 -17
  136. package/dist/lib/prompt.js +0 -34
  137. package/dist/lib/questions.js +0 -28
  138. package/dist/lib/utils.js +0 -46
  139. package/dist/shared/collections.js +0 -33
  140. package/dist/store.js +0 -15
  141. /package/dist/{constants → cache}/cache-keys.js +0 -0
  142. /package/dist/{types/core.types.js → config/migration/types.js} +0 -0
@@ -0,0 +1,30 @@
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.smartNaming = smartNaming;
7
+ exports.shortTimestamp = shortTimestamp;
8
+ const path_1 = __importDefault(require("path"));
9
+ function smartNaming(entries) {
10
+ const names = unique(entries.map((file) => path_1.default.basename(file, path_1.default.extname(file))));
11
+ if (names.length === 1)
12
+ return names[0];
13
+ if (names.length === 2)
14
+ return `${names[0]}-${names[1]}`;
15
+ if (names.length > 2)
16
+ return `${names[0]}-and-${names.length - 1}more`;
17
+ return "prodex";
18
+ }
19
+ function shortTimestamp() {
20
+ const d = new Date();
21
+ const yy = String(d.getFullYear()).slice(-2);
22
+ const MM = String(d.getMonth() + 1).padStart(2, "0");
23
+ const dd = String(d.getDate()).padStart(2, "0");
24
+ const hh = String(d.getHours()).padStart(2, "0");
25
+ const mm = String(d.getMinutes()).padStart(2, "0");
26
+ return `${yy}${MM}${dd}-${hh}${mm}`;
27
+ }
28
+ function unique(items) {
29
+ return [...new Set(items)];
30
+ }
@@ -0,0 +1,2 @@
1
+ import type { OutputParams } from "../types";
2
+ export declare function produceOutput({ name, files, cfg }: OutputParams): Promise<string>;
@@ -0,0 +1,35 @@
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.produceOutput = produceOutput;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const logger_1 = require("../diagnostics/logger");
10
+ const naming_1 = require("./naming");
11
+ const render_constants_1 = require("./render-constants");
12
+ const markdown_1 = require("./markdown");
13
+ const text_1 = require("./text");
14
+ const path_2 = require("../filesystem/path");
15
+ async function produceOutput({ name, files, cfg }) {
16
+ const { output: { format, versioned, dir }, } = cfg;
17
+ let outputBase = (0, path_2.sanitizeFileName)(name || "combined");
18
+ outputBase = `${outputBase}-${render_constants_1.SUFFIX}`;
19
+ if (versioned)
20
+ outputBase = `${outputBase}_${(0, naming_1.shortTimestamp)()}`;
21
+ const outputDir = path_1.default.isAbsolute(dir) ? dir : path_1.default.join(cfg.root, dir);
22
+ try {
23
+ fs_1.default.mkdirSync(outputDir, { recursive: true });
24
+ }
25
+ catch {
26
+ logger_1.logger.warn("Could not create output directory:", outputDir);
27
+ }
28
+ const outputPath = path_1.default.join(outputDir, `${outputBase}.${format}`);
29
+ const sorted = [...files].sort((a, b) => a.localeCompare(b));
30
+ const content = format === "txt"
31
+ ? [(0, text_1.tocTxt)(sorted, cfg.root), ...sorted.map((file) => (0, text_1.renderTxt)(file, cfg.root))].join("")
32
+ : (0, markdown_1.renderTraceMd)(sorted, cfg.root).content;
33
+ fs_1.default.writeFileSync(outputPath, content, "utf8");
34
+ return outputPath;
35
+ }
@@ -0,0 +1,21 @@
1
+ export declare const LANG_MAP: {
2
+ "": string;
3
+ ".mjs": string;
4
+ ".jsx": string;
5
+ ".ts": string;
6
+ ".tsx": string;
7
+ ".php": string;
8
+ ".json": string;
9
+ ".d.ts": string;
10
+ };
11
+ export declare const TEXT_HEADERS: {
12
+ toc: string;
13
+ path: (p: any) => string;
14
+ regionStart: (p: any) => string;
15
+ regionEnd: string;
16
+ };
17
+ export declare const MD_FOOTER: string;
18
+ export declare const MD_HEADER = "*Generated by [Prodex](https://github.com/emxhive/prodex#readme)*";
19
+ export declare const INDEX_RANGE_PLACEHOLDER = "L?-L?";
20
+ export declare const LLM_NOTE = "> Note for LLMs: `Lx-Ly` ranges refer to lines in this Prodex trace file, not the original source files. Index metadata is provided via the HTML comment markers in this section.";
21
+ export declare const SUFFIX = "trace";
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.LLM_NOTE = exports.INDEX_RANGE_PLACEHOLDER = exports.MD_HEADER = exports.MD_FOOTER = exports.TEXT_HEADERS = exports.LANG_MAP = void 0;
6
+ exports.SUFFIX = exports.LLM_NOTE = exports.INDEX_RANGE_PLACEHOLDER = exports.MD_HEADER = exports.MD_FOOTER = exports.TEXT_HEADERS = exports.LANG_MAP = void 0;
7
7
  const package_json_1 = __importDefault(require("../../package.json"));
8
8
  exports.LANG_MAP = {
9
9
  "": "js",
@@ -25,3 +25,4 @@ exports.MD_FOOTER = ["\n---", "*Generated with [Prodex](https://github.com/emxhi
25
25
  exports.MD_HEADER = "*Generated by [Prodex](https://github.com/emxhive/prodex#readme)*";
26
26
  exports.INDEX_RANGE_PLACEHOLDER = "L?-L?";
27
27
  exports.LLM_NOTE = "> Note for LLMs: `Lx-Ly` ranges refer to lines in this Prodex trace file, not the original source files. Index metadata is provided via the HTML comment markers in this section.";
28
+ exports.SUFFIX = "trace";
@@ -0,0 +1,2 @@
1
+ export declare function tocTxt(files: string[], root?: string): string;
2
+ export declare function renderTxt(filePath: string, root?: string): string;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.tocTxt = tocTxt;
4
+ exports.renderTxt = renderTxt;
5
+ const read_file_1 = require("../filesystem/read-file");
6
+ function tocTxt(files, root = process.cwd()) {
7
+ const sorted = [...files].sort((a, b) => a.localeCompare(b));
8
+ return ["##==== Combined Scope ====", ...sorted.map((file) => "## - " + (0, read_file_1.rel)(file, root))].join("\n") + "\n\n";
9
+ }
10
+ function renderTxt(filePath, root = process.cwd()) {
11
+ const relativePath = (0, read_file_1.rel)(filePath, root);
12
+ const code = (0, read_file_1.readFileSafe)(filePath);
13
+ return ["##==== path: " + relativePath + " ====", "##region " + relativePath, code, "##endregion", ""].join("\n");
14
+ }
@@ -0,0 +1 @@
1
+ export declare function extractImports(filePath: any, code: any): Promise<Set<string>>;
@@ -0,0 +1,2 @@
1
+ import type { ResolverParams, ResolverResult } from "../../types";
2
+ export declare function resolveJsImports({ cfg, filePath }: ResolverParams): Promise<ResolverResult>;
@@ -5,127 +5,83 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.resolveJsImports = resolveJsImports;
7
7
  const path_1 = __importDefault(require("path"));
8
+ const resolver_constants_1 = require("../resolver-constants");
9
+ const cache_keys_1 = require("../../cache/cache-keys");
10
+ const stat_cache_1 = require("../../filesystem/stat-cache");
11
+ const logger_1 = require("../../diagnostics/logger");
12
+ const cache_manager_1 = require("../../cache/cache-manager");
13
+ const read_file_1 = require("../../filesystem/read-file");
14
+ const resolver_result_1 = require("../resolver-result");
8
15
  const extract_imports_1 = require("./extract-imports");
9
- const config_1 = require("../../constants/config");
10
- const collections_1 = require("../../shared/collections");
11
- const logger_1 = require("../../lib/logger");
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");
16
+ const resolve_alias_1 = require("./resolve-alias");
18
17
  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);
23
- if (visited.has(filePath))
24
- return (0, collections_1.emptyResult)(visited);
25
- visited.add(filePath);
26
- const { root: ROOT, resolve: { exclude: excludePatterns }, } = (0, store_1.getConfig)();
18
+ async function resolveJsImports({ cfg, filePath }) {
27
19
  const ext = path_1.default.extname(filePath).toLowerCase();
28
- const isDts = ext === config_1.DTS_EXT;
29
- if (!config_1.BASE_EXTS.includes(ext) && !isDts)
30
- return (0, collections_1.emptyResult)(visited);
31
- let code = (0, shared_1.readFileSafe)(filePath);
20
+ const isDts = ext === resolver_constants_1.DTS_EXT;
21
+ if (!resolver_constants_1.BASE_EXTS.includes(ext) && !isDts)
22
+ return (0, resolver_result_1.emptyResolverResult)();
23
+ const code = (0, read_file_1.readFileSafe)(filePath);
32
24
  if (!code)
33
- return (0, collections_1.emptyResult)(visited);
34
- // Extract imports ---------------------------------------
25
+ return (0, resolver_result_1.emptyResolverResult)();
35
26
  const imports = await getImportsCached(filePath, code);
36
27
  if (!imports.size)
37
- return (0, collections_1.emptyResult)(visited);
38
- // Trackers ----------------------------------------------
39
- const stats = (0, collections_1.newStats)();
28
+ return (0, resolver_result_1.emptyResolverResult)();
29
+ const stats = (0, resolver_result_1.newResolverStats)();
40
30
  const files = [];
41
- // Main resolution loop ----------------------------------
42
31
  for (const imp of imports) {
43
- // skip bare packages (react, lodash, etc.)
44
32
  if (!imp.startsWith(".") && !imp.startsWith("/") && !imp.startsWith("@"))
45
33
  continue;
46
- if ((0, shared_1.isExcluded)(imp, excludePatterns, ROOT))
47
- continue;
48
- let base = null;
49
- if (imp.startsWith(".")) {
50
- // relative → like original resolver
51
- base = path_1.default.resolve(path_1.default.dirname(filePath), imp);
52
- }
53
- else if (imp.startsWith("/")) {
54
- // absolute path import → like original resolver
55
- base = path_1.default.resolve(imp);
56
- }
57
- else {
58
- // alias (@...) → unified resolver (config + cache + glob)
59
- base = await (0, resolve_alias_1.resolveAliasPath)(imp, ROOT, (0, store_1.getConfig)());
60
- }
34
+ const base = await resolveImportBase(imp, filePath, cfg.root, cfg);
61
35
  if (!base)
62
36
  continue;
63
37
  const absBase = path_1.default.resolve(base);
64
- // Exclusion check after alias resolution
65
- if ((0, shared_1.isExcluded)(absBase, excludePatterns, ROOT))
66
- continue;
67
38
  const resolvedPath = await tryResolveImport(absBase);
68
- // Exclusion check after final resolution
69
- if ((0, shared_1.isExcluded)(resolvedPath, excludePatterns, ROOT))
70
- continue;
71
39
  stats.expected.add(absBase);
72
40
  if (!resolvedPath)
73
41
  continue;
74
42
  stats.resolved.add(absBase);
75
43
  files.push(resolvedPath);
76
- // Recursive traversal
77
- const sub = await resolveJsImports({
78
- filePath: resolvedPath,
79
- visited,
80
- depth: depth + 1,
81
- maxDepth: limitDepth,
82
- });
83
- files.push(...sub.files);
84
- (0, collections_1.mergeStats)(stats, sub.stats);
85
44
  }
86
- const uniqueFiles = (0, collections_1.unique)(files);
87
- const diff = (0, shared_2.setDiff)(stats.expected, stats.resolved);
88
- logger_1.logger.debug(`🪶 [js-resolver] ${filePath} → expected: ${stats.expected.size}, resolved: ${stats.resolved.size}`);
89
- if (diff.size)
90
- logger_1.logger.debug([...diff], "🔴 THE diff");
91
- return { files: uniqueFiles, visited, stats };
45
+ const unresolved = (0, resolver_result_1.resolverSetDiff)(stats.expected, stats.resolved);
46
+ logger_1.logger.debug(`[js-resolver] ${filePath} -> expected: ${stats.expected.size}, resolved: ${stats.resolved.size}`);
47
+ if (unresolved.size)
48
+ logger_1.logger.debug("[js-resolver] unresolved:", [...unresolved]);
49
+ return { files: (0, resolver_result_1.uniqueResolvedFiles)(files), stats };
50
+ }
51
+ async function resolveImportBase(imp, filePath, root, cfg) {
52
+ if (imp.startsWith("."))
53
+ return path_1.default.resolve(path_1.default.dirname(filePath), imp);
54
+ if (imp.startsWith("/"))
55
+ return path_1.default.resolve(imp);
56
+ return (0, resolve_alias_1.resolveAliasPath)(imp, root, cfg);
92
57
  }
93
- // ---------------------------------------------------------
94
- // tryResolveImport (pure)
95
- // ---------------------------------------------------------
96
58
  async function tryResolveImport(basePath) {
97
59
  const candidates = [];
98
60
  const ext = path_1.default.extname(basePath).toLowerCase();
99
- if (ext && config_1.REAL_EXTS.has(ext)) {
61
+ if (ext && resolver_constants_1.REAL_EXTS.has(ext)) {
100
62
  candidates.push(basePath);
101
63
  }
102
64
  else {
103
- for (const e of [...config_1.BASE_EXTS, config_1.DTS_EXT]) {
104
- candidates.push(basePath + e);
105
- candidates.push(path_1.default.join(basePath, "index" + e));
65
+ for (const candidateExt of [...resolver_constants_1.BASE_EXTS, resolver_constants_1.DTS_EXT]) {
66
+ candidates.push(basePath + candidateExt);
67
+ candidates.push(path_1.default.join(basePath, "index" + candidateExt));
106
68
  }
107
69
  }
108
- // Run all stat checks in parallel
109
- const results = await Promise.allSettled(candidates.map(async (c) => {
110
- const abs = path_1.default.resolve(c);
111
- const st = await (0, shared_1.safeStatCached)(JS_STATS, abs);
112
- return st && st.isFile() ? abs : null;
70
+ const results = await Promise.allSettled(candidates.map(async (candidate) => {
71
+ const abs = path_1.default.resolve(candidate);
72
+ const stats = await (0, stat_cache_1.safeStatCached)(JS_STATS, abs);
73
+ return stats?.isFile() ? abs : null;
113
74
  }));
114
- // Find the first fulfilled non-null result
115
- for (const r of results) {
116
- if (r.status === "fulfilled" && r.value)
117
- return r.value;
118
- }
119
- return null;
75
+ return results.find(isFulfilledPath)?.value ?? null;
120
76
  }
121
- // ---------------------------------------------------------
122
- // Cached stat + import scanners
123
- // ---------------------------------------------------------
124
77
  async function getImportsCached(filePath, code) {
125
- const cached = cache_1.CacheManager.get(JS_IMPORTS, filePath);
78
+ const cached = cache_manager_1.CacheManager.get(JS_IMPORTS, filePath);
126
79
  if (cached)
127
80
  return cached;
128
- const set = await (0, extract_imports_1.extractImports)(filePath, code);
129
- cache_1.CacheManager.set(JS_IMPORTS, filePath, set);
130
- return set;
81
+ const imports = await (0, extract_imports_1.extractImports)(filePath, code);
82
+ cache_manager_1.CacheManager.set(JS_IMPORTS, filePath, imports);
83
+ return imports;
84
+ }
85
+ function isFulfilledPath(result) {
86
+ return result.status === "fulfilled" && !!result.value;
131
87
  }
@@ -0,0 +1,2 @@
1
+ import type { ProdexConfig } from "../../types";
2
+ export declare function resolveAliasPath(specifier: string, root: string, cfg: ProdexConfig): Promise<string | null>;
@@ -5,18 +5,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.resolveAliasPath = resolveAliasPath;
7
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
- const shared_1 = require("../../shared");
12
- /**
13
- * 🧩 resolveAliasPath()
14
- * Unifies alias lookup across config, cache, and fallback discovery.
15
- *
16
- * - Checks cfg.resolve.aliases first.
17
- * - Then cached aliases (from Cache Manager).
18
- * - If still unresolved, runs Fast-Glob to discover and cache new alias root.
19
- */
8
+ const cache_manager_1 = require("../../cache/cache-manager");
9
+ const cache_keys_1 = require("../../cache/cache-keys");
10
+ const glob_scan_1 = require("../../filesystem/glob-scan");
11
+ const read_file_1 = require("../../filesystem/read-file");
12
+ const path_2 = require("../../filesystem/path");
20
13
  async function resolveAliasPath(specifier, root, cfg) {
21
14
  if (!specifier.includes("/"))
22
15
  return null;
@@ -30,31 +23,30 @@ async function resolveAliasPath(specifier, root, cfg) {
30
23
  return path_1.default.resolve(root, knownAliases[aliasKey], relPart);
31
24
  }
32
25
  // 2️⃣ Check cached aliases
33
- const cached = cache_1.CacheManager.get(constants_1.CACHE_KEYS.ALIASES, aliasKey);
26
+ const cached = cache_manager_1.CacheManager.get(cache_keys_1.CACHE_KEYS.ALIASES, aliasKey);
34
27
  if (cached) {
35
28
  const relPart = remainder.replace(/^\/+/, "");
36
29
  return path_1.default.resolve(root, cached, relPart);
37
30
  }
38
31
  // 3️⃣ Fallback discovery with Fast-Glob
39
- const stripped = remainder; // remove prefix before first '/'
32
+ const stripped = remainder;
40
33
  const hasExt = /\.[a-z0-9]+$/i.test(stripped);
41
34
  const patterns = hasExt ? [`**/${stripped}`] : [`**/${stripped}.*`, `**/${stripped}/index.*`];
42
- const { files: matches } = await (0, helpers_1.globScan)(patterns, { cwd: root });
35
+ const { files: matches } = await (0, glob_scan_1.globScan)(patterns, { cwd: root });
43
36
  if (matches.length) {
44
37
  const resolvedMatch = resolveMatches(matches, remainder);
45
- // .replace(/\.[^/.]+$/, "")
46
38
  if (!resolvedMatch)
47
39
  return null;
48
- const relPath = (0, shared_1.rel)(resolvedMatch, cfg.root);
49
- cache_1.CacheManager.set(constants_1.CACHE_KEYS.ALIASES, aliasKey, relPath);
40
+ const relPath = (0, read_file_1.rel)(resolvedMatch, cfg.root);
41
+ cache_manager_1.CacheManager.set(cache_keys_1.CACHE_KEYS.ALIASES, aliasKey, relPath);
50
42
  return relPath;
51
43
  }
52
44
  return null;
53
45
  }
54
46
  function resolveMatches(matches, remainder) {
55
- const foundFile = matches[0].norm();
47
+ const foundFile = (0, path_2.normalizePath)(matches[0]);
56
48
  const dSplit = foundFile.split(remainder);
57
49
  if (dSplit.length < 2)
58
50
  return "";
59
- return dSplit[0].replace(/\\/g, "/");
51
+ return (0, path_2.normalizePath)(dSplit[0]);
60
52
  }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Scans app/Providers/*.php for $this->app->bind() / singleton() calls
3
+ * and returns a map of InterfaceFQCN to ImplementationFQCN.
4
+ *
5
+ * Uses existing extractPhpImports + expandGroupedUses to correctly
6
+ * resolve namespaces and short class names.
7
+ */
8
+ export declare function loadLaravelBindings(root: string): Record<string, string>;
@@ -6,25 +6,25 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.loadLaravelBindings = loadLaravelBindings;
7
7
  const fs_1 = __importDefault(require("fs"));
8
8
  const path_1 = __importDefault(require("path"));
9
- const cache_1 = require("../../core/managers/cache");
10
- const cache_keys_1 = require("../../constants/cache-keys");
9
+ const cache_manager_1 = require("../../cache/cache-manager");
10
+ const cache_keys_1 = require("../../cache/cache-keys");
11
11
  const extract_imports_1 = require("./extract-imports");
12
- const logger_1 = require("../../lib/logger");
12
+ const logger_1 = require("../../diagnostics/logger");
13
13
  /**
14
14
  * Scans app/Providers/*.php for $this->app->bind() / singleton() calls
15
- * and returns a map of InterfaceFQCN ImplementationFQCN.
15
+ * and returns a map of InterfaceFQCN to ImplementationFQCN.
16
16
  *
17
17
  * Uses existing extractPhpImports + expandGroupedUses to correctly
18
18
  * resolve namespaces and short class names.
19
19
  */
20
20
  function loadLaravelBindings(root) {
21
- const cached = cache_1.CacheManager.get(cache_keys_1.CACHE_KEYS.PHP_BINDINGS, root);
21
+ const cached = cache_manager_1.CacheManager.get(cache_keys_1.CACHE_KEYS.PHP_BINDINGS, root);
22
22
  if (cached)
23
23
  return cached;
24
24
  const providersDir = path_1.default.join(root, "app", "Providers");
25
25
  const bindings = {};
26
26
  if (!fs_1.default.existsSync(providersDir)) {
27
- cache_1.CacheManager.set(cache_keys_1.CACHE_KEYS.PHP_BINDINGS, root, bindings);
27
+ cache_manager_1.CacheManager.set(cache_keys_1.CACHE_KEYS.PHP_BINDINGS, root, bindings);
28
28
  return bindings;
29
29
  }
30
30
  const files = fs_1.default
@@ -36,7 +36,6 @@ function loadLaravelBindings(root) {
36
36
  // 1️⃣ Extract all imports in the provider
37
37
  const rawImports = (0, extract_imports_1.extractPhpImports)(code);
38
38
  const expanded = (0, extract_imports_1.expandGroupedUses)(rawImports);
39
- // Build ShortName → FQCN map
40
39
  const importMap = {};
41
40
  for (const fqcn of expanded) {
42
41
  const short = fqcn.split("\\").pop();
@@ -50,10 +49,10 @@ function loadLaravelBindings(root) {
50
49
  const implShort = m[2];
51
50
  const ifaceFull = importMap[ifaceShort] || ifaceShort;
52
51
  const implFull = importMap[implShort] || implShort;
53
- logger_1.logger.debug(`[laravel-bindings] ${file} => ${ifaceFull} ${implFull}`);
52
+ logger_1.logger.debug(`[laravel-bindings] ${file} => ${ifaceFull} => ${implFull}`);
54
53
  bindings[ifaceFull] = implFull;
55
54
  }
56
55
  }
57
- cache_1.CacheManager.set(cache_keys_1.CACHE_KEYS.PHP_BINDINGS, root, bindings);
56
+ cache_manager_1.CacheManager.set(cache_keys_1.CACHE_KEYS.PHP_BINDINGS, root, bindings);
58
57
  return bindings;
59
58
  }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Extracts import-like references from PHP code.
3
+ * Supports:
4
+ * - require/include/require_once/include_once
5
+ * - use statements (including grouped imports like `use App\Models\{User, Team};`)
6
+ */
7
+ export declare function extractPhpImports(code: string): Set<string>;
8
+ /**
9
+ * Expands grouped `use` imports into individual fully qualified names.
10
+ * Example:
11
+ * "App\\Models\\{User, Team}" to ["App\\Models\\User", "App\\Models\\Team"]
12
+ */
13
+ export declare function expandGroupedUses(raw: Set<string>): Set<string>;
@@ -41,7 +41,7 @@ function extractPhpImports(code) {
41
41
  /**
42
42
  * Expands grouped `use` imports into individual fully qualified names.
43
43
  * Example:
44
- * "App\\Models\\{User, Team}" ["App\\Models\\User", "App\\Models\\Team"]
44
+ * "App\\Models\\{User, Team}" to ["App\\Models\\User", "App\\Models\\Team"]
45
45
  */
46
46
  function expandGroupedUses(raw) {
47
47
  const out = new Set();
@@ -0,0 +1,2 @@
1
+ import type { ResolverParams, ResolverResult } from "../../types";
2
+ export declare function resolvePhpImports({ cfg, filePath, ctx }: ResolverParams): Promise<ResolverResult>;