prodex 1.1.0 → 1.2.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 (57) hide show
  1. package/README.md +174 -86
  2. package/bin/prodex.js +1 -17
  3. package/dist/cli/cli-input.js +86 -0
  4. package/dist/cli/flags.js +42 -0
  5. package/dist/cli/init.js +21 -0
  6. package/dist/cli/picker.js +82 -0
  7. package/dist/cli/summary.js +14 -0
  8. package/dist/constants/config-loader.js +90 -0
  9. package/dist/constants/config.js +17 -0
  10. package/dist/constants/default-config.js +48 -0
  11. package/dist/constants/render-constants.js +23 -0
  12. package/dist/core/combine.js +74 -0
  13. package/dist/core/dependency.js +51 -0
  14. package/dist/core/file-utils.js +44 -0
  15. package/dist/core/helpers.js +81 -0
  16. package/dist/core/parsers/extract-imports.js +51 -0
  17. package/dist/core/renderers.js +42 -0
  18. package/dist/index.js +29 -0
  19. package/dist/lib/logger.js +14 -0
  20. package/dist/lib/polyfills.js +12 -0
  21. package/dist/lib/utils.js +15 -0
  22. package/dist/resolvers/js/alias-loader.js +52 -0
  23. package/dist/resolvers/js/js-resolver.js +153 -0
  24. package/dist/resolvers/php/bindings.js +32 -0
  25. package/dist/resolvers/php/patterns.js +17 -0
  26. package/dist/resolvers/php/php-resolver.js +88 -0
  27. package/dist/resolvers/php/psr4.js +26 -0
  28. package/dist/resolvers/shared/excludes.js +11 -0
  29. package/dist/resolvers/shared/file-cache.js +29 -0
  30. package/dist/resolvers/shared/stats.js +17 -0
  31. package/dist/types/cli.types.js +12 -0
  32. package/dist/types/config.types.js +2 -0
  33. package/dist/types/core.types.js +2 -0
  34. package/dist/types/index.js +21 -0
  35. package/dist/types/resolver.types.js +2 -0
  36. package/dist/types/utils.types.js +2 -0
  37. package/package.json +16 -12
  38. package/dist/LICENSE +0 -21
  39. package/dist/README.md +0 -140
  40. package/dist/bin/prodex.js +0 -18
  41. package/dist/package.json +0 -45
  42. package/dist/src/cli/init.js +0 -18
  43. package/dist/src/cli/picker.js +0 -59
  44. package/dist/src/cli/summary.js +0 -6
  45. package/dist/src/constants/config-loader.js +0 -87
  46. package/dist/src/constants/config.js +0 -13
  47. package/dist/src/constants/default-config.js +0 -36
  48. package/dist/src/constants/render-constants.js +0 -22
  49. package/dist/src/core/alias-loader.js +0 -8
  50. package/dist/src/core/combine.js +0 -145
  51. package/dist/src/core/file-utils.js +0 -45
  52. package/dist/src/core/helpers.js +0 -77
  53. package/dist/src/core/renderers.js +0 -58
  54. package/dist/src/index.js +0 -15
  55. package/dist/src/resolvers/js-resolver.js +0 -180
  56. package/dist/src/resolvers/php-bindings.js +0 -31
  57. package/dist/src/resolvers/php-resolver.js +0 -155
package/README.md CHANGED
@@ -1,140 +1,228 @@
1
- # 🧩 Prodex — Unified Project Indexer & Dependency Extractor
2
1
 
3
- > **Prodex** *(short for “Project Index”)* — a cross-language dependency combiner for modern full-stack applications.
4
- > Traverses **Laravel + React + TypeScript** projects to generate a single, organized view of your project’s true dependency scope.
2
+ # 🧩 Prodex v1.2.0
3
+
4
+ > **Because every project deserves a clear map, not a maze.**
5
5
 
6
6
  ---
7
7
 
8
- ## 🧠 Recent Fixes & Updates — v1.0.8
9
- - ⭐ **Priority Files Support** — priority files will now appear **first** on the entry selection list.
8
+ ## 🧠 What’s New — v1.2.0
10
9
 
11
- - 🪟 **Windows path resolution fixed** now uses proper `file://` URLs for full ESM compatibility.
12
- - 🧾 **Improved output naming** automatic, context-aware filenames (e.g. `prodex-[entries]-combined.txt`).
13
- - ⚙️ **“Yes to all” confirmation added** skip repetitive prompts during CLI runs.
10
+ - 🆕 **Full CLI support with integrated [Sade](https://github.com/lukeed/sade).**
11
+ Prodex now runs entirely from the terminal no `prodex.json` required.
12
+ Supports short flags and native glob patterns for flexible targeting.
13
+ ```bash
14
+ prodex -f "**/web.php,**/app.tsx" -i "**/*.d.ts" -x "node_modules/**"
15
+ prodex --files **/web.php **/app.tsx --include **/*.interface.ts --exclude @shadcn/**
16
+ ```
14
17
 
15
- ---
18
+ - 🧾 **Markdown mode added and now default.**
19
+ Output is fully fenced and linkable — jump between the index and any code block.
20
+ Text mode remains available using `--txt` or `-t`.
21
+
22
+ - 🗂 **Output naming improved.**
23
+ Output files are now versioned by default.
24
+ Custom names are supported using `--name` or `-n`.
25
+ Naming conventions have been updated for cleaner, consistent results.
16
26
 
17
27
  ---
18
28
 
19
- ## 📦 Installation
29
+ ## ⚙️ Usage
30
+
31
+ Prodex v1.2.0 runs entirely from the command line.
32
+ Interactive mode is currently unstable — use CLI flags instead.
33
+
34
+ ### Installation
20
35
 
21
- ### Global install (recommended)
22
36
  ```bash
23
37
  npm install -g prodex
24
38
  ```
25
39
 
40
+ Or run without installing:
26
41
 
27
- ## 🚀 Features
28
-
29
- | Feature | Description |
30
- |----------|-------------|
31
- | ⚙️ **Cross-language resolver** | Parses JS/TS (`import`, `export`) and PHP (`use`, `require`, `include`) dependency trees. |
32
- | 🧭 **Alias detection** | Reads `tsconfig.json` and `vite.config.*` for alias paths (`@/components/...`). |
33
- | 🧩 **Laravel-aware** | Maps PSR-4 namespaces and detects providers under `app/Providers`. |
34
- | 🔄 **Recursive chain following** | Resolves dependency graphs up to a configurable depth and file limit. |
35
- | 🪶 **Clean unified output** | Merges all resolved files into a single `.txt` file with region markers for readability. |
36
- | 🧠 **Static & safe** | Fully static parsing — no runtime execution or file modification. |
37
- | 💬 **Interactive CLI** | Select files, confirm settings, or use “Yes to all” for streamlined automation. |
42
+ ```bash
43
+ npx prodex
44
+ ```
38
45
 
39
46
  ---
40
47
 
41
- ## ⚙️ Configuration
42
-
43
- Optional `.prodex.json` (in project root):
48
+ ### Basic Run
44
49
 
45
- ```json
46
- {
47
- "$schema": "https://raw.githubusercontent.com/emxhive/prodex/main/schema/prodex.schema.json",
48
- "output": "prodex",
49
- "scanDepth": 2,
50
- "limit": 200,
51
- "baseDirs": ["app", "routes", "resources/js"],
52
- "aliasOverrides": {
53
- "@hooks": "resources/js/hooks",
54
- "@data": "resources/js/data"
55
- },
56
- "entryExcludes": [
57
- "resources/js/components/ui/",
58
- "app/DTOs/"
59
- ],
60
- "importExcludes": [
61
- "node_modules",
62
- "@shadcn/"
63
- ],
64
- "priorityFiles": [
65
- "routes/web.php",
66
- "routes/api.php",
67
- "index.",
68
- "main.",
69
- "app."
70
- ]
71
- }
50
+ ```bash
51
+ prodex -f "**/web.php,**/app.tsx"
72
52
  ```
73
53
 
54
+ ### With Includes, exclude, and Custom Name
55
+
56
+ ```bash
57
+ prodex -f "**/web.php,**/app.tsx" -i "**/*.d.ts" -x "node_modules/**" -n "combined-output"
74
58
  ```
75
59
 
60
+ ### Flag Reference
76
61
 
62
+ | Flag | Short | Description |
63
+ |------|--------|-------------|
64
+ | `--files` | `-f` | Entry files — starting points for dependency resolution. Accepts multiple names or globs. |
65
+ | `--include` | `-i` | Adds extra files or patterns to include (e.g. `.d.ts`, interface, or type files). These files are **not dependency-resolved** — they’re appended as-is. |
66
+ | `--exclude` | `-x` | Patterns or folders to skip during the scan. |
67
+ | `--name` | `-n` | Custom output filename (without extension). Versioning still applies automatically. |
77
68
 
78
- ```
69
+ > Globs are powered by [Fast-Glob](https://github.com/mrmlnc/fast-glob).
70
+ > Use **comma-separated values** for multiple entries.
71
+ > Wrap globs in quotes when they include special characters like `|` or `&`.
79
72
 
73
+ ---
80
74
 
75
+ ## 🧭 Plans
81
76
 
82
- Files are matched using `.includes()` (case-insensitive), so `"index."` will match `src/index.js`, `app/index.tsx`, etc.
83
- Popular entries appear at the top of the picker.
77
+ - **Alias Resolution Improvements**
78
+ Planned overhaul of alias handling to support deeper nested paths, wildcard matching, and auto-mapped imports across mixed stacks.
84
79
 
80
+ - **Language Support**
81
+ Currently supports **JavaScript**, **React**, and **Laravel + React** stacks.
82
+ May work with other frameworks but remains untested.
83
+ Broader multi-language support is planned for future versions.
85
84
 
85
+ - **Combined Output**
86
+ All code from multiple entries is merged into a single output file.
87
+ There’s currently **no limit** on output size, but it’s advised to avoid combining *too many large entries* in a single run.
88
+ Future versions will include **smart naming** and **automatic splitting** for oversized outputs.
86
89
 
90
+ - **Performance Optimizations**
91
+ Planned improvements to resolver speed and dependency traversal for faster processing on large projects.
87
92
 
93
+ ---
94
+
95
+ ## 🧩 Features
96
+
97
+ | Status | Feature | Description |
98
+ |:--:|----------|--------------|
99
+ | ✅ | **Cross-language indexing** | Resolves imports across JS, TS, React, and PHP (Laravel) projects. |
100
+ | ✅ | **Markdown output** | Generates clean `.md` files with anchors, back-to-top links, and fenced code blocks. |
101
+ | ✅ | **Text output** | Optional `.txt` mode using `--txt` or `-t`. |
102
+ | ✅ | **Glob support** | Works with flexible glob patterns powered by [Fast-Glob](https://github.com/mrmlnc/fast-glob). |
103
+ | ✅ | **Custom output names** | Define your own output prefix using `--name` or `-n`. |
104
+ | ⚠️ | **Interactive picker (UI)** | Still unstable — not recommended for production use. |
105
+ | ⚠️ | **Alias resolution** | Basic alias mapping supported; advanced cases in progress. |
106
+ | 🚧 | **Smart file splitting** | Planned for large combined outputs. |
107
+ | 🚧 | **PSR-4 deep scan** | Planned to improve PHP dependency resolution. |
108
+ | 🚧 | **Speed optimization** | Further resolver and I/O improvements under development. |
88
109
 
89
110
  ---
90
111
 
91
- ## 🧱 Example: Laravel + React
112
+ ## 🧱 Use Cases
92
113
 
93
- ```bash
94
- prodex
95
- ```
114
+ Prodex can technically combine your entire codebase into one file —
115
+ but it’s **best used in parts**, focusing on specific sections or features.
116
+ Each run produces a clean, self-contained map showing all related files and dependencies.
96
117
 
97
- ```
98
- 🧩 Following dependency chain...
99
- ✅ prodex-app-routes-combined.txt written (24 file(s)).
100
- ```
118
+ ### 🧩 Common Scenarios
101
119
 
102
- Included files:
103
- ```
104
- resources/js/pages/accounts.tsx
105
- app/Http/Controllers/Shots/AccountsController.php
106
- app/Repositories/Shots/FireflyApiRepository.php
107
- app/Enums/Shots/Granularity.php
108
- app/Support/Shots/CacheKeys.php
109
- ...
110
- ```
120
+ - **🤖 Project Awareness for AI Assistants**
121
+ Generate compact `.md` summaries of key parts of your project.
122
+ These can be shared with AI tools (like ChatGPT, Claude, or Copilot) to give them structured context about your codebase — without exposing unnecessary files.
123
+
124
+ - **📦 Feature or Module Mapping**
125
+ Combine everything connected to a specific feature (e.g., `Checkout`, `Dashboard`, or `Payments`).
126
+ Prodex gathers all linked imports, helpers, and files into one readable document.
127
+
128
+ - **🔍 Dependency Insight**
129
+ Trace how a particular entry file connects through your stack — whether it’s `app.tsx` on the frontend or `routes/web.php` on the backend.
130
+ Great for debugging, refactoring, or understanding cross-stack dependencies.
131
+
132
+ - **📖 Documentation Bundles**
133
+ Create readable Markdown maps per module or domain instead of one large export.
134
+ Each output acts as a focused, navigable view of your code relationships.
135
+
136
+ - **🧠 Team Handoffs**
137
+ Share isolated code scopes (like `Auth`, `Payments`, or `User Management`) with full dependency context.
138
+ Makes onboarding and code reviews significantly faster.
111
139
 
112
140
  ---
113
141
 
114
- ## 🧠 Ideal Use Cases
142
+ ## 🧩 Recommended Workflow
143
+
144
+ Prodex works best when used to **map and export projects in logical parts** rather than all at once.
145
+ Each run focuses on one or more entry points, and Prodex automatically **loads all imports recursively** for those files —
146
+ then appends any files matched by the `--include` flag.
147
+
148
+ ### 🧠 Suggested Pattern
149
+
150
+ 1. **Pick a meaningful entry file**
151
+ Example:
152
+ - Frontend: `resources/js/**/dashboard.tsx`
153
+ - Backend: `routes/**/(web|api).php`
154
+ - Shared logic: `app/Services/**/PaymentService.php`
155
+
156
+ 2. **Run Prodex with includes for type or interface files**
157
+ ```bash
158
+ prodex -f "**/dashboard.tsx" -i "**/*.d.ts,**/*.interface.ts"
159
+ ```
160
+
161
+ 3. **Export separate maps for each major area**
162
+ ```bash
163
+ prodex -f "**/dashboard.tsx" -n "dashboard-map"
164
+ prodex -f "**/web|api.php" -n "backend-map"
165
+ ```
115
166
 
116
- - 📦 Generate single-file **project snapshots**
117
- - 🤖 Provide structured context for **AI assistants**
118
- - 🧩 Perform **dependency audits** or code reviews
119
- - 📄 Simplify documentation and onboarding
167
+ 4. **Use them together**
168
+ Store each output in `/prodex/` or `/docs/maps/`.
169
+ These maps can be shared with teammates or loaded into AI tools for structured, code-aware assistance.
170
+
171
+ > ⚡ Each run recursively resolves every import, applies includes, and outputs one complete dependency map for that section.
120
172
 
121
173
  ---
122
174
 
123
- ## 🔮 Upcoming Features
175
+ ## ⚙️ Optional — `prodex.json`
176
+
177
+ `prodex.json` is **fully optional** in v1.2.0.
178
+ You can run Prodex entirely from the command line, but the config file can be useful for saved defaults.
179
+
180
+ ### 🪄 Quick Setup
181
+
182
+ You can generate a ready-to-use config file with:
183
+
184
+ ```bash
185
+ prodex init
186
+ ```
187
+
188
+ This creates a `prodex.json` file in your project root with sensible defaults — including base directories, globs, and priority files.
189
+
190
+ ### 🧩 Running with a Config File
191
+
192
+ If you’ve defined your entry files in the config under `entry.files`,
193
+ you can run Prodex directly without specifying `--files`:
194
+
195
+ ```bash
196
+ prodex -c
197
+ ```
124
198
 
125
- - 📝 **Markdown export** (`.md`) with automatic code fences
126
- - 📦 **Configurable output formats** (txt / md)
127
- - ⚡ **Alias auto-discovery for Laravel Mix and Next.js**
199
+ The `-c` (or `--ci`) flag skips interactive mode and uses the config values automatically.
200
+ Specifying `-f` ( or `--files`) from the CLI also disables the picker by default.
201
+
202
+ You can permanently disable the picker in the config by setting:
203
+
204
+ ```json
205
+ "entry": {
206
+ "ui": {
207
+ "enablePicker": false
208
+ }
209
+ }
210
+ ```
128
211
 
129
212
  ---
130
213
 
131
- ## 🧾 License
214
+ ## 📜 License
132
215
 
133
- **MIT © 2025 [emxhive](https://github.com/emxhive)**
134
- Issues and contributions welcome:
135
- 👉 [github.com/emxhive/prodex/issues](https://github.com/emxhive/prodex/issues)
216
+ **MIT License**
217
+ © 2025 [emxhive](https://github.com/emxhive)
136
218
 
137
219
  ---
138
220
 
139
- **Prodex** *Codebase, decoded*
221
+ ## ⚠️ Note from the Author
222
+
223
+ Prodex is still a **work in progress**.
224
+ Some parts of the experience may be rough, especially around interactive mode and advanced resolvers.
225
+ Updates are released **multiple times per week — sometimes daily** — to keep improving stability and support.
140
226
 
227
+ Please stay up to date for the best experience.
228
+ Thank you for testing Prodex early. ❤️
package/bin/prodex.js CHANGED
@@ -1,18 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import fs from "fs";
3
- import path from "path";
4
- import { pathToFileURL, fileURLToPath } from "url";
5
-
6
- const __filename = fileURLToPath(import.meta.url);
7
- const __dirname = path.dirname(__filename);
8
-
9
- const devPath = path.resolve(__dirname, "../src/index.js");
10
- const distPath = path.resolve(__dirname, "../dist/src/index.js");
11
-
12
- // prefer dist in published package
13
- const entry = fs.existsSync(distPath) ? distPath : devPath;
14
-
15
- // convert to file:// URL for cross-platform ESM loading
16
- const entryUrl = pathToFileURL(entry).href;
17
-
18
- import(entryUrl).then(({ default: startProdex }) => startProdex());
2
+ require("../dist/index.js").default();
@@ -0,0 +1,86 @@
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.parseCliInput = parseCliInput;
7
+ const sade_1 = __importDefault(require("sade"));
8
+ const flags_1 = require("./flags");
9
+ const logger_1 = require("../lib/logger");
10
+ const path_1 = __importDefault(require("path"));
11
+ const package_json_1 = __importDefault(require("../../package.json"));
12
+ /**
13
+ * Unified CLI parser powered by Sade.
14
+ * Returns { root, entries (from --files), flags, warnings, errors }.
15
+ */
16
+ function parseCliInput(argv = process.argv) {
17
+ if (argv.includes("-v") || argv.includes("--version")) {
18
+ logger_1.logger.log(`prodex v${package_json_1.default.version}`);
19
+ process.exit(0);
20
+ }
21
+ const program = (0, sade_1.default)("prodex [root]");
22
+ // Register flags dynamically
23
+ for (const [key, meta] of Object.entries(flags_1.PRODEX_FLAGS)) {
24
+ const short = meta.short ? `-${meta.short}, ` : "";
25
+ const long = `--${key}`;
26
+ const desc = meta.description;
27
+ let defaultVal;
28
+ switch (meta.type) {
29
+ case "boolean":
30
+ defaultVal = false;
31
+ break;
32
+ default:
33
+ defaultVal = undefined; // defer strings/numbers/lists
34
+ }
35
+ if (defaultVal !== undefined) {
36
+ program.option(`${short}${long}`, desc, defaultVal);
37
+ }
38
+ else {
39
+ program.option(`${short}${long}`, desc);
40
+ }
41
+ }
42
+ let parsed = { root: undefined, flags: {} };
43
+ // Define default command (root optional)
44
+ program.action((root, opts) => {
45
+ const cwd = process.cwd();
46
+ parsed = {
47
+ root: root ? path_1.default.resolve(cwd, root) : cwd,
48
+ flags: { ...opts },
49
+ };
50
+ });
51
+ program.parse(argv);
52
+ const warnings = [];
53
+ const errors = [];
54
+ // Post-parse casting + normalization
55
+ for (const [key, meta] of Object.entries(flags_1.PRODEX_FLAGS)) {
56
+ const raw = parsed.flags[key];
57
+ if (raw === undefined)
58
+ continue;
59
+ const obj = {};
60
+ switch (meta.type) {
61
+ case "number": {
62
+ const num = Number(raw);
63
+ if (Number.isNaN(num)) {
64
+ errors.push(`Flag --${key} expected a number but got "${raw}"`);
65
+ }
66
+ else {
67
+ parsed.flags[key] = num;
68
+ }
69
+ break;
70
+ }
71
+ case "list": {
72
+ const arr = String(raw)
73
+ .split(",")
74
+ .map((v) => v.trim())
75
+ .filter(Boolean);
76
+ parsed.flags[key] = arr;
77
+ break;
78
+ }
79
+ }
80
+ }
81
+ return {
82
+ ...parsed,
83
+ warnings,
84
+ errors,
85
+ };
86
+ }
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CLI_USAGE = exports.FLAG_SHORT_MAP = exports.PRODEX_FLAGS = exports.FlagKey = void 0;
4
+ var FlagKey;
5
+ (function (FlagKey) {
6
+ FlagKey["Txt"] = "txt";
7
+ FlagKey["Ci"] = "ci";
8
+ FlagKey["Debug"] = "debug";
9
+ FlagKey["Name"] = "name";
10
+ FlagKey["Limit"] = "limit";
11
+ FlagKey["Inc"] = "include";
12
+ FlagKey["Exc"] = "exclude";
13
+ FlagKey["Help"] = "help";
14
+ FlagKey["Files"] = "files";
15
+ })(FlagKey || (exports.FlagKey = FlagKey = {}));
16
+ exports.PRODEX_FLAGS = {
17
+ [FlagKey.Files]: { short: "f", type: "list", description: "Comma-separated entry files." },
18
+ [FlagKey.Txt]: { short: "t", type: "boolean", description: "Output as .txt instead of .md." },
19
+ [FlagKey.Ci]: { short: "c", type: "boolean", description: "Headless/no-UI mode." },
20
+ [FlagKey.Debug]: { short: "d", type: "boolean", description: "Enable debug logs." },
21
+ [FlagKey.Name]: { short: "n", type: "string", description: "Custom output filename." },
22
+ [FlagKey.Limit]: { short: "l", type: "number", description: "Override traversal limit." },
23
+ [FlagKey.Inc]: { type: "list", short: "i", description: "Comma-separated include globs." },
24
+ [FlagKey.Exc]: { type: "list", short: "x", description: "Comma-separated exclude globs." },
25
+ [FlagKey.Help]: { short: "h", type: "boolean", description: "Show CLI help and exit." },
26
+ };
27
+ /** Reverse lookup for short aliases. */
28
+ exports.FLAG_SHORT_MAP = Object.entries(exports.PRODEX_FLAGS).reduce((acc, [key, meta]) => {
29
+ if (meta.short)
30
+ acc[meta.short] = key;
31
+ return acc;
32
+ }, {});
33
+ exports.CLI_USAGE = `
34
+ Usage: prodex [-fcdv]
35
+ [--files=<globs>|-f=<globs>]
36
+ [--include=<globs>|-i=<globs>]
37
+ [--exclude=<globs>|-x=<globs>]
38
+ [--txt|-t] [--ci|-c] [--debug|-d] [--version|-v]
39
+ [--name=<string>|-n=<string>]
40
+ [--limit=<int>|-l=<int>]
41
+ [--help|-h]
42
+ `;
@@ -0,0 +1,21 @@
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.initProdex = initProdex;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const default_config_1 = require("../constants/default-config");
10
+ const logger_1 = require("../lib/logger");
11
+ async function initProdex() {
12
+ logger_1.logger.log("🪄 Prodex Init — Configuration Wizard (v2)");
13
+ const dest = path_1.default.join(process.cwd(), "prodex.json");
14
+ if (fs_1.default.existsSync(dest)) {
15
+ logger_1.logger.error("prodex.json already exists. Delete or modify it manually.\n");
16
+ return;
17
+ }
18
+ fs_1.default.writeFileSync(dest, JSON.stringify(default_config_1.DEFAULT_PRODEX_CONFIG, null, 2) + "\n", "utf8");
19
+ logger_1.logger.log(`✅ Created ${dest}`);
20
+ logger_1.logger.log("💡 Globs supported everywhere (include, exclude, priority).");
21
+ }
@@ -0,0 +1,82 @@
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.pickEntries = pickEntries;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const inquirer_1 = __importDefault(require("inquirer"));
10
+ const config_1 = require("../constants/config");
11
+ const helpers_1 = require("../core/helpers");
12
+ const file_utils_1 = require("../core/file-utils");
13
+ const utils_1 = require("../lib/utils");
14
+ const logger_1 = require("../lib/logger");
15
+ async function pickEntries(baseDirs, depth = 2, cfg) {
16
+ const entryPatterns = cfg.entry?.files || [];
17
+ const priorities = [...entryPatterns, ...(cfg.entry?.priority || [])];
18
+ const verbose = !!cfg.verbose;
19
+ // 1) Resolve patterns to absolute files and preselect them
20
+ const resolvedEntries = (await (0, file_utils_1.globScan)(entryPatterns, { cwd: config_1.ROOT })).files;
21
+ let selected = [...resolvedEntries];
22
+ // cache: depth -> files[]
23
+ const scanCache = new Map();
24
+ for (;;) {
25
+ const files = await getFilesAtDepth({
26
+ baseDirs,
27
+ depth,
28
+ cfg,
29
+ scanCache,
30
+ verbose,
31
+ });
32
+ // Merge resolved entries with current scan results
33
+ const combined = (0, utils_1.unique)([...resolvedEntries, ...files]);
34
+ // Priority-aware ordering: entries first, then other priorities
35
+ const sorted = (0, helpers_1.orderByPriority)(combined, priorities);
36
+ // Build UI selection list
37
+ const choices = sorted.map(f => ({
38
+ name: path_1.default.relative(config_1.ROOT, f).norm(),
39
+ value: f,
40
+ checked: selected.includes(f),
41
+ }));
42
+ choices.push(new inquirer_1.default.Separator());
43
+ choices.push({ name: "🔽 Load more (go deeper)", value: "__loadmore" });
44
+ const { picks } = await inquirer_1.default.prompt([
45
+ {
46
+ type: "checkbox",
47
+ name: "picks",
48
+ message: `Select entry files (depth ${depth})`,
49
+ choices,
50
+ loop: false,
51
+ pageSize: 20,
52
+ }
53
+ ]);
54
+ if (picks.includes("__loadmore")) {
55
+ depth++;
56
+ selected = picks.filter(p => p !== "__loadmore");
57
+ continue;
58
+ }
59
+ selected = picks.filter(p => p !== "__loadmore");
60
+ break;
61
+ }
62
+ return (0, utils_1.unique)(selected);
63
+ }
64
+ async function getFilesAtDepth({ baseDirs, depth, cfg, scanCache, verbose }) {
65
+ if (scanCache.has(depth)) {
66
+ logger_1.logger.debug(`[cache] depth=${depth} ✓`);
67
+ return scanCache.get(depth);
68
+ }
69
+ logger_1.logger.debug(`[scan] depth=${depth} …`);
70
+ const files = [];
71
+ const effectiveCfg = { ...cfg, scanDepth: depth };
72
+ for (const base of baseDirs) {
73
+ const full = path_1.default.join(config_1.ROOT, base);
74
+ if (!fs_1.default.existsSync(full))
75
+ continue;
76
+ for (const f of (0, helpers_1.walk)(full, effectiveCfg, 0))
77
+ files.push(f.norm());
78
+ }
79
+ scanCache.set(depth, files);
80
+ logger_1.logger.debug(`[scan] depth=${depth} found=${files.length}`);
81
+ return files;
82
+ }
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.showSummary = showSummary;
4
+ exports.importSummary = importSummary;
5
+ const logger_1 = require("../lib/logger");
6
+ function showSummary({ outDir, fileName, entries }) {
7
+ logger_1.logger.debug(`🧩 Active Run → ${fileName} (${entries.length} entries)`);
8
+ }
9
+ function importSummary(result) {
10
+ logger_1.logger.debug(`\n🧩 Summary:
11
+ • Unique imports expected: ${result.stats.expected.size}
12
+ • Unique imports resolved: ${result.stats.resolved.size}
13
+ `);
14
+ }
@@ -0,0 +1,90 @@
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.loadProdexConfig = loadProdexConfig;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const default_config_1 = require("./default-config");
10
+ const logger_1 = require("../lib/logger");
11
+ /**
12
+ * 🧩 Load and merge Prodex configuration (v3)
13
+ *
14
+ * 1️⃣ Reads `prodex.json` if present.
15
+ * 2️⃣ Merges with `DEFAULT_PRODEX_CONFIG`.
16
+ * 3️⃣ Normalizes all path-like fields.
17
+ * 4️⃣ Applies CLI flag overrides.
18
+ */
19
+ async function loadProdexConfig(flags = {}, cwd) {
20
+ const configPath = path_1.default.join(cwd, "prodex.json");
21
+ let userConfig = {};
22
+ // 1️⃣ Load config if present
23
+ try {
24
+ const content = fs_1.default.readFileSync(configPath, "utf8");
25
+ userConfig = JSON.parse(content);
26
+ }
27
+ catch (err) {
28
+ logger_1.logger.info("No prodex.json found — using defaults.");
29
+ }
30
+ // 2️⃣ Merge defaults → user config
31
+ const { output, entry, resolve, debug } = default_config_1.DEFAULT_PRODEX_CONFIG;
32
+ const cfg = {
33
+ ...default_config_1.DEFAULT_PRODEX_CONFIG,
34
+ ...userConfig,
35
+ output: { ...output, ...userConfig.output },
36
+ entry: {
37
+ ...entry,
38
+ ...userConfig.entry,
39
+ ui: { ...entry.ui, ...userConfig.entry?.ui },
40
+ },
41
+ resolve: { ...resolve, ...userConfig.resolve },
42
+ debug: { ...debug, ...userConfig.debug },
43
+ root: cwd,
44
+ };
45
+ // 4️⃣ Apply CLI flag overrides (if any)
46
+ applyFlagOverrides(cfg, flags);
47
+ return cfg;
48
+ }
49
+ /** Merge CLI flags into config where relevant. */
50
+ /** Merge CLI flags into config where relevant. */
51
+ function applyFlagOverrides(cfg, flags) {
52
+ if (!flags)
53
+ return;
54
+ const outputOverrides = {
55
+ name: (cfg, v) => (cfg.output.prefix = v),
56
+ txt: (cfg) => (cfg.output.format = "txt"),
57
+ };
58
+ const resolveOverrides = {
59
+ limit: (cfg, v) => (cfg.resolve.limit = v),
60
+ include: (cfg, v) => (cfg.resolve.include = v),
61
+ exclude: (cfg, v) => (cfg.resolve.exclude = v),
62
+ };
63
+ const entryOverrides = {
64
+ files: (cfg, v) => (cfg.entry.files = v),
65
+ };
66
+ const envOverrides = {
67
+ debug: (_, v) => (process.env.PRODEX_DEBUG = v ? "1" : "0"),
68
+ verbose: (_, v) => (process.env.PRODEX_VERBOSE = v ? "1" : "0"),
69
+ };
70
+ const overrideMap = {
71
+ ...outputOverrides,
72
+ ...resolveOverrides,
73
+ ...entryOverrides,
74
+ ...envOverrides,
75
+ };
76
+ // Apply all flag overrides dynamically
77
+ for (const [flag, value] of Object.entries(flags)) {
78
+ if (value == undefined)
79
+ continue;
80
+ const apply = overrideMap[flag];
81
+ if (apply)
82
+ apply(cfg, value);
83
+ }
84
+ // Conditional override rule:
85
+ // If files exist and include was null/undefined → clear include array
86
+ const hasFiles = Array.isArray(flags.files) ? flags.files.length > 0 : !!flags.files;
87
+ if (hasFiles && flags.include == null) {
88
+ cfg.resolve.include = [];
89
+ }
90
+ }