prodex 1.4.10 → 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.
- package/LICENSE +20 -20
- package/README.md +238 -234
- package/bin/prodex.js +0 -0
- package/dist/app/execute-run.d.ts +2 -0
- package/dist/app/execute-run.js +73 -0
- package/dist/app/project-context.d.ts +12 -0
- package/dist/app/project-context.js +48 -0
- package/dist/app/run-plans.d.ts +11 -0
- package/dist/app/run-plans.js +61 -0
- package/dist/cache/cache-keys.d.ts +9 -0
- package/dist/cache/cache-manager.d.ts +9 -0
- package/dist/{core/managers/cache.js → cache/cache-manager.js} +5 -18
- package/dist/cli/cli-input.d.ts +2 -0
- package/dist/cli/cli-input.js +138 -124
- package/dist/cli/flag-specs.d.ts +12 -0
- package/dist/cli/flag-specs.js +27 -0
- package/dist/cli/help.d.ts +2 -0
- package/dist/cli/help.js +83 -0
- package/dist/cli/report-command.d.ts +2 -0
- package/dist/cli/report-command.js +80 -0
- package/dist/cli/reporter.d.ts +2 -0
- package/dist/cli/reporter.js +8 -0
- package/dist/commands/init-command.d.ts +1 -0
- package/dist/commands/init-command.js +9 -0
- package/dist/commands/migrate-command.d.ts +7 -0
- package/dist/commands/migrate-command.js +76 -0
- package/dist/commands/profiles-command.d.ts +6 -0
- package/dist/commands/profiles-command.js +16 -0
- package/dist/commands/run-command.d.ts +11 -0
- package/dist/commands/run-command.js +17 -0
- package/dist/config/build-config.d.ts +13 -0
- package/dist/config/build-config.js +127 -0
- package/dist/config/create-default-config.d.ts +9 -0
- package/dist/config/create-default-config.js +25 -0
- package/dist/config/default-config.d.ts +2 -0
- package/dist/config/default-config.js +23 -0
- package/dist/config/json.d.ts +2 -0
- package/dist/config/json.js +10 -0
- package/dist/config/load.d.ts +9 -0
- package/dist/config/load.js +48 -0
- package/dist/config/migration/detect.d.ts +4 -0
- package/dist/config/migration/detect.js +22 -0
- package/dist/config/migration/index.d.ts +4 -0
- package/dist/{shared → config/migration}/index.js +4 -3
- package/dist/config/migration/messages.d.ts +2 -0
- package/dist/config/migration/messages.js +35 -0
- package/dist/config/migration/transform.d.ts +2 -0
- package/dist/config/migration/transform.js +80 -0
- package/dist/config/migration/types.d.ts +16 -0
- package/dist/config/string-list.d.ts +2 -0
- package/dist/config/string-list.js +17 -0
- package/dist/diagnostics/logger.d.ts +3 -0
- package/dist/diagnostics/logger.js +33 -0
- package/dist/filesystem/glob-scan.d.ts +4 -0
- package/dist/filesystem/glob-scan.js +26 -0
- package/dist/filesystem/inspect.d.ts +1 -0
- package/dist/filesystem/inspect.js +15 -0
- package/dist/filesystem/path.d.ts +2 -0
- package/dist/filesystem/path.js +11 -0
- package/dist/filesystem/read-file.d.ts +8 -0
- package/dist/{shared/io.js → filesystem/read-file.js} +0 -25
- package/dist/filesystem/stat-cache.d.ts +1 -0
- package/dist/filesystem/stat-cache.js +22 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +76 -83
- package/dist/output/markdown.d.ts +12 -0
- package/dist/output/markdown.js +150 -0
- package/dist/output/naming.d.ts +2 -0
- package/dist/output/naming.js +30 -0
- package/dist/output/produce-output.d.ts +2 -0
- package/dist/output/produce-output.js +35 -0
- package/dist/output/render-constants.d.ts +21 -0
- package/dist/{constants → output}/render-constants.js +2 -1
- package/dist/output/text.d.ts +2 -0
- package/dist/output/text.js +14 -0
- package/dist/resolvers/js/extract-imports.d.ts +1 -0
- package/dist/resolvers/js/js-resolver.d.ts +2 -0
- package/dist/resolvers/js/js-resolver.js +45 -89
- package/dist/resolvers/js/resolve-alias.d.ts +2 -0
- package/dist/resolvers/js/resolve-alias.js +12 -20
- package/dist/resolvers/php/bindings.d.ts +8 -0
- package/dist/resolvers/php/bindings.js +8 -9
- package/dist/resolvers/php/extract-imports.d.ts +13 -0
- package/dist/resolvers/php/extract-imports.js +1 -1
- package/dist/resolvers/php/php-resolver.d.ts +2 -0
- package/dist/resolvers/php/php-resolver.js +61 -90
- package/dist/resolvers/php/psr4.d.ts +5 -0
- package/dist/resolvers/php/psr4.js +7 -7
- package/dist/resolvers/resolver-constants.d.ts +4 -0
- package/dist/resolvers/resolver-constants.js +7 -0
- package/dist/resolvers/resolver-result.d.ts +5 -0
- package/dist/resolvers/resolver-result.js +18 -0
- package/dist/tracing/exclude.d.ts +6 -0
- package/dist/{shared/patterns.js → tracing/exclude.js} +4 -4
- package/dist/tracing/follow-chain.d.ts +5 -0
- package/dist/tracing/follow-chain.js +63 -0
- package/dist/tracing/include-files.d.ts +2 -0
- package/dist/tracing/include-files.js +36 -0
- package/dist/tracing/resolver-registry.d.ts +5 -0
- package/dist/tracing/resolver-registry.js +20 -0
- package/dist/tracing/trace-run.d.ts +2 -0
- package/dist/tracing/trace-run.js +21 -0
- package/dist/tracing/trace-stats.d.ts +4 -0
- package/dist/tracing/trace-stats.js +16 -0
- package/dist/types/app.types.d.ts +61 -0
- package/dist/types/app.types.js +2 -0
- package/dist/types/cli.types.d.ts +22 -0
- package/dist/types/cli.types.js +0 -10
- package/dist/types/config.types.d.ts +34 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.js +3 -1
- package/dist/types/output.types.d.ts +6 -0
- package/dist/types/output.types.js +2 -0
- package/dist/types/resolver.types.d.ts +23 -0
- package/dist/types/tracing.types.d.ts +23 -0
- package/dist/types/tracing.types.js +2 -0
- package/dist/types/utils.types.d.ts +10 -0
- package/package.json +35 -12
- package/schema/prodex.schema.json +122 -0
- package/dist/cli/init.js +0 -21
- package/dist/cli/picker.js +0 -83
- package/dist/cli/summary.js +0 -32
- package/dist/constants/config.js +0 -27
- package/dist/constants/default-config.js +0 -43
- package/dist/constants/flags.js +0 -79
- package/dist/constants/index.js +0 -20
- package/dist/core/combine.js +0 -56
- package/dist/core/dependency.js +0 -98
- package/dist/core/helpers.js +0 -85
- package/dist/core/managers/config.js +0 -140
- package/dist/core/output.js +0 -49
- package/dist/core/renderers.js +0 -210
- package/dist/debug.js +0 -15
- package/dist/lib/logger.js +0 -42
- package/dist/lib/polyfills.js +0 -17
- package/dist/lib/prompt.js +0 -34
- package/dist/lib/questions.js +0 -28
- package/dist/lib/utils.js +0 -46
- package/dist/shared/collections.js +0 -33
- package/dist/store.js +0 -15
- /package/dist/{constants → cache}/cache-keys.js +0 -0
- /package/dist/{types/core.types.js → config/migration/types.js} +0 -0
|
@@ -0,0 +1,48 @@
|
|
|
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.loadProjectContext = loadProjectContext;
|
|
7
|
+
exports.resolveRoot = resolveRoot;
|
|
8
|
+
exports.validateRoot = validateRoot;
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const load_1 = require("../config/load");
|
|
12
|
+
function loadProjectContext(rootArg, cwd = process.cwd()) {
|
|
13
|
+
const root = resolveRoot(rootArg, cwd);
|
|
14
|
+
const warnings = [];
|
|
15
|
+
const errors = validateRoot(root, rootArg);
|
|
16
|
+
if (errors.length) {
|
|
17
|
+
return {
|
|
18
|
+
root,
|
|
19
|
+
config: {},
|
|
20
|
+
configPath: path_1.default.join(root, "prodex.json"),
|
|
21
|
+
configExists: false,
|
|
22
|
+
warnings,
|
|
23
|
+
errors,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
const loaded = (0, load_1.loadConfig)(root);
|
|
27
|
+
return fromLoadedConfig(root, loaded);
|
|
28
|
+
}
|
|
29
|
+
function resolveRoot(rootArg, cwd = process.cwd()) {
|
|
30
|
+
return rootArg ? path_1.default.resolve(cwd, rootArg) : cwd;
|
|
31
|
+
}
|
|
32
|
+
function validateRoot(root, rootArg) {
|
|
33
|
+
if (!fs_1.default.existsSync(root))
|
|
34
|
+
return [`Invalid root path "${rootArg}".`];
|
|
35
|
+
if (!fs_1.default.statSync(root).isDirectory())
|
|
36
|
+
return [`Root path "${rootArg}" is not a directory.`];
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
function fromLoadedConfig(root, loaded) {
|
|
40
|
+
return {
|
|
41
|
+
root,
|
|
42
|
+
config: loaded.config,
|
|
43
|
+
configPath: loaded.path,
|
|
44
|
+
configExists: loaded.exists,
|
|
45
|
+
warnings: [...loaded.warnings],
|
|
46
|
+
errors: [...loaded.errors],
|
|
47
|
+
};
|
|
48
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ProdexFlags, RunPlan } from "../types";
|
|
2
|
+
export interface CreateRunPlansResult {
|
|
3
|
+
plans: RunPlan[];
|
|
4
|
+
warnings: string[];
|
|
5
|
+
errors: string[];
|
|
6
|
+
}
|
|
7
|
+
export declare function createRunPlans(params: {
|
|
8
|
+
rootArg?: string;
|
|
9
|
+
flags?: Partial<ProdexFlags>;
|
|
10
|
+
cwd?: string;
|
|
11
|
+
}): CreateRunPlansResult;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createRunPlans = createRunPlans;
|
|
4
|
+
const build_config_1 = require("../config/build-config");
|
|
5
|
+
const project_context_1 = require("./project-context");
|
|
6
|
+
function createRunPlans(params) {
|
|
7
|
+
const project = (0, project_context_1.loadProjectContext)(params.rootArg, params.cwd);
|
|
8
|
+
const warnings = [...project.warnings];
|
|
9
|
+
const errors = [...project.errors];
|
|
10
|
+
const flags = params.flags ?? {};
|
|
11
|
+
if (errors.length)
|
|
12
|
+
return { plans: [], warnings, errors };
|
|
13
|
+
const profileNames = resolveProfileNames(flags, project.config.profiles ?? {}, errors);
|
|
14
|
+
if (errors.length)
|
|
15
|
+
return { plans: [], warnings, errors };
|
|
16
|
+
const plans = [];
|
|
17
|
+
for (const profileName of profileNames.length ? profileNames : [undefined]) {
|
|
18
|
+
const runFlags = flagsForProfileRun(flags, profileName);
|
|
19
|
+
const built = (0, build_config_1.buildConfig)({
|
|
20
|
+
root: project.root,
|
|
21
|
+
userConfig: project.config,
|
|
22
|
+
flags: runFlags,
|
|
23
|
+
profileName,
|
|
24
|
+
});
|
|
25
|
+
warnings.push(...built.warnings);
|
|
26
|
+
errors.push(...built.errors);
|
|
27
|
+
if (!built.config)
|
|
28
|
+
continue;
|
|
29
|
+
plans.push({
|
|
30
|
+
root: project.root,
|
|
31
|
+
config: built.config,
|
|
32
|
+
flags: runFlags,
|
|
33
|
+
outputName: built.config.name,
|
|
34
|
+
profile: profileName,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
return { plans, warnings, errors };
|
|
38
|
+
}
|
|
39
|
+
function resolveProfileNames(flags, profiles, errors) {
|
|
40
|
+
if (flags.allProfiles) {
|
|
41
|
+
const names = Object.keys(profiles);
|
|
42
|
+
if (!names.length)
|
|
43
|
+
errors.push("No profiles are defined in prodex.json.");
|
|
44
|
+
return names;
|
|
45
|
+
}
|
|
46
|
+
if (Array.isArray(flags.profiles) && flags.profiles.length)
|
|
47
|
+
return unique(flags.profiles);
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
function flagsForProfileRun(flags, profile) {
|
|
51
|
+
if (!profile)
|
|
52
|
+
return flags;
|
|
53
|
+
return {
|
|
54
|
+
...flags,
|
|
55
|
+
profiles: undefined,
|
|
56
|
+
allProfiles: false,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function unique(values) {
|
|
60
|
+
return [...new Set(values.map((value) => value.trim()).filter(Boolean))];
|
|
61
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const CACHE_KEYS: {
|
|
2
|
+
readonly ALIASES: "aliases";
|
|
3
|
+
readonly JS_IMPORTS: "js:imports";
|
|
4
|
+
readonly JS_STATS: "js:stats";
|
|
5
|
+
readonly PHP_PSR4: "php:psr4";
|
|
6
|
+
readonly PHP_BINDINGS: "php:bindings";
|
|
7
|
+
readonly PHP_FILECACHE: "php:fileCache";
|
|
8
|
+
};
|
|
9
|
+
export type CacheNamespace = (typeof CACHE_KEYS)[keyof typeof CACHE_KEYS];
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare class CacheManager {
|
|
2
|
+
private static registry;
|
|
3
|
+
private static ns;
|
|
4
|
+
static set<T = any>(ns: string, key: string, val: T): void;
|
|
5
|
+
static get<T = any>(ns: string, key: string): T | undefined;
|
|
6
|
+
static clear(ns?: string): void;
|
|
7
|
+
static dump(ns: string): Record<string, any>;
|
|
8
|
+
static stats(): Record<string, number>;
|
|
9
|
+
}
|
|
@@ -1,48 +1,35 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CacheManager = void 0;
|
|
4
|
-
const logger_1 = require("
|
|
5
|
-
|
|
6
|
-
* 🧩 CacheManager
|
|
7
|
-
* Unified in-memory registry for all runtime maps.
|
|
8
|
-
*
|
|
9
|
-
* - Namespaced storage (e.g., "aliases", "stats", "resolver")
|
|
10
|
-
* - Purely in-memory (no file I/O)
|
|
11
|
-
* - Static API for symmetry with ConfigManager
|
|
12
|
-
*/
|
|
4
|
+
const logger_1 = require("../diagnostics/logger");
|
|
5
|
+
const inspect_1 = require("../filesystem/inspect");
|
|
13
6
|
class CacheManager {
|
|
14
7
|
static registry = new Map();
|
|
15
|
-
/** Ensure namespace map exists and return it */
|
|
16
8
|
static ns(ns) {
|
|
17
9
|
if (!this.registry.has(ns))
|
|
18
10
|
this.registry.set(ns, new Map());
|
|
19
11
|
return this.registry.get(ns);
|
|
20
12
|
}
|
|
21
|
-
/** Set or update a cached entry */
|
|
22
13
|
static set(ns, key, val) {
|
|
23
14
|
this.ns(ns).set(key, val);
|
|
24
|
-
logger_1.logger.debug(
|
|
15
|
+
logger_1.logger.debug(`[cache:${ns}] set ${key}\n-> ${(0, inspect_1.inspectValue)(val)}`);
|
|
25
16
|
}
|
|
26
|
-
/** Retrieve a cached entry */
|
|
27
17
|
static get(ns, key) {
|
|
28
18
|
return this.ns(ns).get(key);
|
|
29
19
|
}
|
|
30
|
-
/** Remove all entries from one namespace or from all */
|
|
31
20
|
static clear(ns) {
|
|
32
21
|
if (ns) {
|
|
33
22
|
this.ns(ns).clear();
|
|
34
|
-
logger_1.logger.debug(
|
|
23
|
+
logger_1.logger.debug(`[cache:${ns}] cleared`);
|
|
35
24
|
}
|
|
36
25
|
else {
|
|
37
26
|
this.registry.forEach((m) => m.clear());
|
|
38
|
-
logger_1.logger.debug("
|
|
27
|
+
logger_1.logger.debug("[cache] cleared all namespaces");
|
|
39
28
|
}
|
|
40
29
|
}
|
|
41
|
-
/** Export a namespace as a plain object (for persistence or inspection) */
|
|
42
30
|
static dump(ns) {
|
|
43
31
|
return Object.fromEntries(this.ns(ns).entries());
|
|
44
32
|
}
|
|
45
|
-
/** Return count of entries per namespace */
|
|
46
33
|
static stats() {
|
|
47
34
|
const summary = {};
|
|
48
35
|
for (const [name, map] of this.registry)
|
package/dist/cli/cli-input.js
CHANGED
|
@@ -1,145 +1,159 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.parseCliInput = parseCliInput;
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
4
|
+
const string_list_1 = require("../config/string-list");
|
|
5
|
+
const flag_specs_1 = require("./flag-specs");
|
|
6
|
+
function parseCliInput(argv = process.argv) {
|
|
7
|
+
const tokens = stripExecutable(argv);
|
|
8
|
+
const warnings = [];
|
|
9
|
+
const errors = [];
|
|
10
|
+
const flags = {};
|
|
11
|
+
if (!tokens.length) {
|
|
12
|
+
errors.push("Missing command. Use `prodex run`, `prodex init`, `prodex profiles`, or `prodex migrate`.");
|
|
13
|
+
return { warnings, errors };
|
|
14
|
+
}
|
|
15
|
+
if (tokens.includes("--version") || tokens.includes("-v")) {
|
|
16
|
+
return { command: { kind: "version" }, warnings, errors };
|
|
17
|
+
}
|
|
18
|
+
if (tokens[0] === "--help" || tokens[0] === "-h") {
|
|
19
|
+
return { command: { kind: "help" }, warnings, errors };
|
|
20
|
+
}
|
|
21
|
+
const commandName = tokens[0];
|
|
22
|
+
if (!isCommand(commandName)) {
|
|
23
|
+
errors.push(`Unknown command "${commandName}". Use run, init, profiles, or migrate.`);
|
|
24
|
+
return { warnings, errors };
|
|
25
|
+
}
|
|
26
|
+
let rootArg;
|
|
27
|
+
for (let i = 1; i < tokens.length; i++) {
|
|
28
|
+
const token = tokens[i];
|
|
29
|
+
if (!token)
|
|
30
|
+
continue;
|
|
31
|
+
if (token.startsWith("--")) {
|
|
32
|
+
const consumed = readLongFlag(tokens, i, flags, errors);
|
|
33
|
+
i += consumed;
|
|
19
34
|
continue;
|
|
20
35
|
}
|
|
21
|
-
if (
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
shortcutAll = true;
|
|
25
|
-
else
|
|
26
|
-
shortcuts.push(name);
|
|
36
|
+
if (token.startsWith("-") && token !== "-") {
|
|
37
|
+
const consumed = readShortFlag(tokens, i, flags, errors);
|
|
38
|
+
i += consumed;
|
|
27
39
|
continue;
|
|
28
40
|
}
|
|
29
|
-
|
|
41
|
+
if (rootArg) {
|
|
42
|
+
errors.push(`Unexpected positional argument "${token}". Only one root path is accepted.`);
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
rootArg = token;
|
|
30
46
|
}
|
|
31
|
-
|
|
47
|
+
if (flags.help)
|
|
48
|
+
return { command: { kind: "help", topic: commandName }, warnings, errors };
|
|
49
|
+
if (commandName === "init")
|
|
50
|
+
return { command: { kind: "init", rootArg }, warnings, errors };
|
|
51
|
+
if (commandName === "profiles")
|
|
52
|
+
return { command: { kind: "profiles", rootArg }, warnings, errors };
|
|
53
|
+
if (commandName === "migrate") {
|
|
54
|
+
return { command: { kind: "migrate", rootArg, write: !!flags.write, check: !!flags.check }, warnings, errors };
|
|
55
|
+
}
|
|
56
|
+
return { command: { kind: "run", rootArg, flags }, warnings, errors };
|
|
32
57
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const program = (0, sade_1.default)("prodex [root]");
|
|
45
|
-
registerFlags(program);
|
|
46
|
-
let parsed = { rootArg: "", root: undefined, flags: {} };
|
|
47
|
-
program.action((root, opts) => {
|
|
48
|
-
const cwd = process.cwd();
|
|
49
|
-
parsed = {
|
|
50
|
-
rootArg: root,
|
|
51
|
-
root: root ? path_1.default.resolve(cwd, root) : cwd,
|
|
52
|
-
flags: { ...opts },
|
|
53
|
-
};
|
|
54
|
-
});
|
|
55
|
-
program.parse(argvCleaned);
|
|
56
|
-
// Merge shortcut tokens (@a @b @c / @) with existing --shortcut usage.
|
|
57
|
-
const fromTokens = extracted.shortcuts;
|
|
58
|
-
const shortcutAll = extracted.shortcutAll;
|
|
59
|
-
const fromFlag = typeof parsed.flags.shortcut === "string" ? parsed.flags.shortcut.trim() : "";
|
|
60
|
-
const selected = [...fromTokens, ...(fromFlag ? [fromFlag] : [])].filter(Boolean);
|
|
61
|
-
const uniq = Array.from(new Set(selected));
|
|
62
|
-
if (shortcutAll)
|
|
63
|
-
parsed.flags.shortcutAll = true;
|
|
64
|
-
if (uniq.length)
|
|
65
|
-
parsed.flags.shortcuts = uniq;
|
|
66
|
-
if (!shortcutAll && uniq.length === 1)
|
|
67
|
-
parsed.flags.shortcut = uniq[0];
|
|
68
|
-
else if (uniq.length > 1 || shortcutAll)
|
|
69
|
-
delete parsed.flags.shortcut;
|
|
70
|
-
const warnings = [];
|
|
71
|
-
const errors = [];
|
|
72
|
-
parsed.flags = normalizeFlags(parsed.flags, warnings, errors);
|
|
73
|
-
validateArgs(parsed, warnings, errors);
|
|
74
|
-
return { ...parsed, warnings, errors };
|
|
58
|
+
function stripExecutable(argv) {
|
|
59
|
+
const [first, second, ...rest] = argv;
|
|
60
|
+
const firstBase = first ? basename(first) : "";
|
|
61
|
+
const secondBase = second ? basename(second) : "";
|
|
62
|
+
if (/^node(\.exe)?$/.test(firstBase))
|
|
63
|
+
return rest;
|
|
64
|
+
if (secondBase.startsWith("prodex") && firstBase)
|
|
65
|
+
return rest;
|
|
66
|
+
if (firstBase.startsWith("prodex"))
|
|
67
|
+
return argv.slice(1);
|
|
68
|
+
return argv;
|
|
75
69
|
}
|
|
76
|
-
function
|
|
77
|
-
|
|
78
|
-
const short = meta.short ? `-${meta.short}, ` : "";
|
|
79
|
-
const defaultVal = meta.type === "boolean" ? false : "";
|
|
80
|
-
program.option(`${short}--${key}`, meta.description, defaultVal);
|
|
81
|
-
}
|
|
70
|
+
function basename(value) {
|
|
71
|
+
return value.split(/[\\/]/).pop()?.toLowerCase() ?? "";
|
|
82
72
|
}
|
|
83
|
-
function
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
73
|
+
function isCommand(token) {
|
|
74
|
+
return flag_specs_1.COMMANDS.includes(token);
|
|
75
|
+
}
|
|
76
|
+
function readLongFlag(tokens, index, flags, errors) {
|
|
77
|
+
const token = tokens[index];
|
|
78
|
+
const raw = token.slice(2);
|
|
79
|
+
const equalsAt = raw.indexOf("=");
|
|
80
|
+
const rawName = equalsAt === -1 ? raw : raw.slice(0, equalsAt);
|
|
81
|
+
const name = flag_specs_1.FLAG_ALIASES[rawName] ?? rawName;
|
|
82
|
+
const inlineValue = equalsAt === -1 ? undefined : raw.slice(equalsAt + 1);
|
|
83
|
+
const spec = flag_specs_1.FLAGS_BY_LONG.get(name);
|
|
84
|
+
if (!spec) {
|
|
85
|
+
errors.push(`Unknown flag "--${rawName}".`);
|
|
86
|
+
return 0;
|
|
90
87
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
flags[key] = Boolean(raw);
|
|
113
|
-
break;
|
|
88
|
+
if (spec.type === "boolean") {
|
|
89
|
+
flags[spec.long] = inlineValue === undefined ? true : coerceBoolean(inlineValue);
|
|
90
|
+
return 0;
|
|
91
|
+
}
|
|
92
|
+
const value = inlineValue ?? tokens[index + 1];
|
|
93
|
+
if (value === undefined || value.startsWith("-")) {
|
|
94
|
+
errors.push(`Flag "--${rawName}" expects a value.`);
|
|
95
|
+
return 0;
|
|
96
|
+
}
|
|
97
|
+
assignFlag(flags, spec, value, errors);
|
|
98
|
+
return inlineValue === undefined ? 1 : 0;
|
|
99
|
+
}
|
|
100
|
+
function readShortFlag(tokens, index, flags, errors) {
|
|
101
|
+
const token = tokens[index];
|
|
102
|
+
const cluster = token.slice(1);
|
|
103
|
+
if (cluster.length > 1) {
|
|
104
|
+
for (const ch of cluster) {
|
|
105
|
+
const spec = flag_specs_1.FLAGS_BY_SHORT.get(ch);
|
|
106
|
+
if (!spec) {
|
|
107
|
+
errors.push(`Unknown flag "-${ch}".`);
|
|
108
|
+
continue;
|
|
114
109
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
110
|
+
if (spec.type !== "boolean") {
|
|
111
|
+
errors.push(`Flag "-${ch}" expects a value and cannot be used in a short flag cluster.`);
|
|
112
|
+
continue;
|
|
118
113
|
}
|
|
114
|
+
flags[spec.long] = true;
|
|
119
115
|
}
|
|
116
|
+
return 0;
|
|
117
|
+
}
|
|
118
|
+
const spec = flag_specs_1.FLAGS_BY_SHORT.get(cluster);
|
|
119
|
+
if (!spec) {
|
|
120
|
+
errors.push(`Unknown flag "-${cluster}".`);
|
|
121
|
+
return 0;
|
|
122
|
+
}
|
|
123
|
+
if (spec.type === "boolean") {
|
|
124
|
+
flags[spec.long] = true;
|
|
125
|
+
return 0;
|
|
126
|
+
}
|
|
127
|
+
const value = tokens[index + 1];
|
|
128
|
+
if (value === undefined || value.startsWith("-")) {
|
|
129
|
+
errors.push(`Flag "-${cluster}" expects a value.`);
|
|
130
|
+
return 0;
|
|
120
131
|
}
|
|
121
|
-
|
|
132
|
+
assignFlag(flags, spec, value, errors);
|
|
133
|
+
return 1;
|
|
122
134
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
errors.push(`Path argument "${rootArg}" is not a directory.`);
|
|
132
|
-
}
|
|
135
|
+
function assignFlag(flags, spec, value, errors) {
|
|
136
|
+
if (spec.type === "number") {
|
|
137
|
+
const numeric = Number(value);
|
|
138
|
+
if (!Number.isFinite(numeric))
|
|
139
|
+
errors.push(`Flag "--${spec.long}" expected a number but got "${value}".`);
|
|
140
|
+
else
|
|
141
|
+
flags[spec.long] = numeric;
|
|
142
|
+
return;
|
|
133
143
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
144
|
+
if (spec.type === "list") {
|
|
145
|
+
const values = (0, string_list_1.splitStringList)(value);
|
|
146
|
+
const target = spec.long === "profile" ? "profiles" : spec.long;
|
|
147
|
+
const current = (flags[target] ?? []);
|
|
148
|
+
flags[target] = [...current, ...values];
|
|
149
|
+
return;
|
|
137
150
|
}
|
|
138
|
-
if (
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
for (const err of errors)
|
|
142
|
-
console.error(err);
|
|
143
|
-
process.exit(1);
|
|
151
|
+
if (spec.long === "format" && !["md", "txt"].includes(value)) {
|
|
152
|
+
errors.push(`Flag "--format" expected "md" or "txt" but got "${value}".`);
|
|
153
|
+
return;
|
|
144
154
|
}
|
|
155
|
+
flags[spec.long] = value;
|
|
156
|
+
}
|
|
157
|
+
function coerceBoolean(value) {
|
|
158
|
+
return !["0", "false", "no", "off"].includes(value.toLowerCase());
|
|
145
159
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ProdexFlags } from "../types";
|
|
2
|
+
export type FlagName = keyof ProdexFlags | "help" | "version" | "profile" | "write" | "check";
|
|
3
|
+
export type FlagSpec = {
|
|
4
|
+
long: FlagName;
|
|
5
|
+
short?: string;
|
|
6
|
+
type: "boolean" | "string" | "number" | "list";
|
|
7
|
+
};
|
|
8
|
+
export declare const COMMANDS: readonly ["run", "init", "profiles", "migrate"];
|
|
9
|
+
export declare const FLAGS: FlagSpec[];
|
|
10
|
+
export declare const FLAG_ALIASES: Record<string, FlagName>;
|
|
11
|
+
export declare const FLAGS_BY_LONG: Map<FlagName, FlagSpec>;
|
|
12
|
+
export declare const FLAGS_BY_SHORT: Map<string, FlagSpec>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FLAGS_BY_SHORT = exports.FLAGS_BY_LONG = exports.FLAG_ALIASES = exports.FLAGS = exports.COMMANDS = void 0;
|
|
4
|
+
exports.COMMANDS = ["run", "init", "profiles", "migrate"];
|
|
5
|
+
exports.FLAGS = [
|
|
6
|
+
{ long: "entry", short: "e", type: "list" },
|
|
7
|
+
{ long: "include", short: "i", type: "list" },
|
|
8
|
+
{ long: "exclude", short: "x", type: "list" },
|
|
9
|
+
{ long: "profile", short: "p", type: "list" },
|
|
10
|
+
{ long: "allProfiles", type: "boolean" },
|
|
11
|
+
{ long: "name", short: "n", type: "string" },
|
|
12
|
+
{ long: "format", short: "F", type: "string" },
|
|
13
|
+
{ long: "maxDepth", type: "number" },
|
|
14
|
+
{ long: "maxFiles", type: "number" },
|
|
15
|
+
{ long: "debug", short: "d", type: "boolean" },
|
|
16
|
+
{ long: "write", type: "boolean" },
|
|
17
|
+
{ long: "check", type: "boolean" },
|
|
18
|
+
{ long: "help", short: "h", type: "boolean" },
|
|
19
|
+
{ long: "version", short: "v", type: "boolean" },
|
|
20
|
+
];
|
|
21
|
+
exports.FLAG_ALIASES = {
|
|
22
|
+
"all-profiles": "allProfiles",
|
|
23
|
+
"max-depth": "maxDepth",
|
|
24
|
+
"max-files": "maxFiles",
|
|
25
|
+
};
|
|
26
|
+
exports.FLAGS_BY_LONG = new Map(exports.FLAGS.map((flag) => [flag.long, flag]));
|
|
27
|
+
exports.FLAGS_BY_SHORT = new Map(exports.FLAGS.filter((flag) => flag.short).map((flag) => [flag.short, flag]));
|
package/dist/cli/help.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
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.renderHelp = renderHelp;
|
|
7
|
+
exports.renderVersion = renderVersion;
|
|
8
|
+
const package_json_1 = __importDefault(require("../../package.json"));
|
|
9
|
+
function renderHelp(topic) {
|
|
10
|
+
if (topic === "run")
|
|
11
|
+
return renderRunHelp();
|
|
12
|
+
if (topic === "init")
|
|
13
|
+
return renderInitHelp();
|
|
14
|
+
if (topic === "profiles")
|
|
15
|
+
return renderProfilesHelp();
|
|
16
|
+
if (topic === "migrate")
|
|
17
|
+
return renderMigrateHelp();
|
|
18
|
+
return [
|
|
19
|
+
"Usage:",
|
|
20
|
+
" prodex run [root] [options]",
|
|
21
|
+
" prodex init [root]",
|
|
22
|
+
" prodex profiles [root]",
|
|
23
|
+
" prodex migrate [root] [--write|--check]",
|
|
24
|
+
"",
|
|
25
|
+
"Global options:",
|
|
26
|
+
" -h, --help Show help.",
|
|
27
|
+
" -v, --version Show version.",
|
|
28
|
+
"",
|
|
29
|
+
"Run `prodex <command> --help` for command-specific help.",
|
|
30
|
+
].join("\n");
|
|
31
|
+
}
|
|
32
|
+
function renderVersion() {
|
|
33
|
+
return `prodex v${package_json_1.default.version}`;
|
|
34
|
+
}
|
|
35
|
+
function renderRunHelp() {
|
|
36
|
+
return [
|
|
37
|
+
"Usage:",
|
|
38
|
+
" prodex run [root] [options]",
|
|
39
|
+
"",
|
|
40
|
+
"Options:",
|
|
41
|
+
" -e, --entry <glob> Entry file/glob. Repeatable and comma-aware.",
|
|
42
|
+
" -i, --include <glob> Extra file/glob to append. Repeatable and comma-aware.",
|
|
43
|
+
" -x, --exclude <glob> File/glob to skip. Repeatable and comma-aware.",
|
|
44
|
+
" -p, --profile <name> Run a named profile. Repeatable.",
|
|
45
|
+
" --all-profiles Run every configured profile.",
|
|
46
|
+
" -n, --name <name> Output basename for this run.",
|
|
47
|
+
" -F, --format <md|txt> Output format.",
|
|
48
|
+
" --max-depth <number> Maximum dependency traversal depth.",
|
|
49
|
+
" --max-files <number> Maximum traced file count.",
|
|
50
|
+
" -d, --debug Enable debug logs.",
|
|
51
|
+
" -h, --help Show run help.",
|
|
52
|
+
].join("\n");
|
|
53
|
+
}
|
|
54
|
+
function renderInitHelp() {
|
|
55
|
+
return [
|
|
56
|
+
"Usage:",
|
|
57
|
+
" prodex init [root]",
|
|
58
|
+
"",
|
|
59
|
+
"Create a prodex.json file in the target root.",
|
|
60
|
+
].join("\n");
|
|
61
|
+
}
|
|
62
|
+
function renderProfilesHelp() {
|
|
63
|
+
return [
|
|
64
|
+
"Usage:",
|
|
65
|
+
" prodex profiles [root]",
|
|
66
|
+
"",
|
|
67
|
+
"List configured profile keys without running Prodex.",
|
|
68
|
+
].join("\n");
|
|
69
|
+
}
|
|
70
|
+
function renderMigrateHelp() {
|
|
71
|
+
return [
|
|
72
|
+
"Usage:",
|
|
73
|
+
" prodex migrate [root]",
|
|
74
|
+
" prodex migrate [root] --write",
|
|
75
|
+
" prodex migrate [root] --check",
|
|
76
|
+
"",
|
|
77
|
+
"Preview, check, or write a prodex.json migration to config version 4.",
|
|
78
|
+
"",
|
|
79
|
+
"Options:",
|
|
80
|
+
" --write Back up and update prodex.json.",
|
|
81
|
+
" --check Exit nonzero if migration is required.",
|
|
82
|
+
].join("\n");
|
|
83
|
+
}
|