@nicolasmondain/cli-agent 3.0.2
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/README.md +183 -0
- package/dist/cli/commands/list.command.d.ts +48 -0
- package/dist/cli/commands/list.command.d.ts.map +1 -0
- package/dist/cli/commands/list.command.js +87 -0
- package/dist/cli/commands/list.command.js.map +1 -0
- package/dist/cli/commands/mcp-serve.command.d.ts +13 -0
- package/dist/cli/commands/mcp-serve.command.d.ts.map +1 -0
- package/dist/cli/commands/mcp-serve.command.js +42 -0
- package/dist/cli/commands/mcp-serve.command.js.map +1 -0
- package/dist/cli/index.d.ts +8 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +111 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/command/dynamic-command.factory.d.ts +16 -0
- package/dist/command/dynamic-command.factory.d.ts.map +1 -0
- package/dist/command/dynamic-command.factory.js +161 -0
- package/dist/command/dynamic-command.factory.js.map +1 -0
- package/dist/config/config-loader.d.ts +24 -0
- package/dist/config/config-loader.d.ts.map +1 -0
- package/dist/config/config-loader.js +95 -0
- package/dist/config/config-loader.js.map +1 -0
- package/dist/config/config-schema.d.ts +73 -0
- package/dist/config/config-schema.d.ts.map +1 -0
- package/dist/config/config-schema.js +7 -0
- package/dist/config/config-schema.js.map +1 -0
- package/dist/config/config-validator.d.ts +20 -0
- package/dist/config/config-validator.d.ts.map +1 -0
- package/dist/config/config-validator.js +162 -0
- package/dist/config/config-validator.js.map +1 -0
- package/dist/executor/js-executor.d.ts +29 -0
- package/dist/executor/js-executor.d.ts.map +1 -0
- package/dist/executor/js-executor.js +77 -0
- package/dist/executor/js-executor.js.map +1 -0
- package/dist/executor/script-executor.d.ts +33 -0
- package/dist/executor/script-executor.d.ts.map +1 -0
- package/dist/executor/script-executor.js +45 -0
- package/dist/executor/script-executor.js.map +1 -0
- package/dist/executor/shell-executor.d.ts +33 -0
- package/dist/executor/shell-executor.d.ts.map +1 -0
- package/dist/executor/shell-executor.js +126 -0
- package/dist/executor/shell-executor.js.map +1 -0
- package/dist/executor/ts-executor.d.ts +33 -0
- package/dist/executor/ts-executor.d.ts.map +1 -0
- package/dist/executor/ts-executor.js +134 -0
- package/dist/executor/ts-executor.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/infra/logger.d.ts +42 -0
- package/dist/infra/logger.d.ts.map +1 -0
- package/dist/infra/logger.js +96 -0
- package/dist/infra/logger.js.map +1 -0
- package/dist/infra/output.d.ts +11 -0
- package/dist/infra/output.d.ts.map +1 -0
- package/dist/infra/output.js +70 -0
- package/dist/infra/output.js.map +1 -0
- package/dist/mcp/mcp-server.d.ts +21 -0
- package/dist/mcp/mcp-server.d.ts.map +1 -0
- package/dist/mcp/mcp-server.js +183 -0
- package/dist/mcp/mcp-server.js.map +1 -0
- package/dist/services/file-system.service.d.ts +53 -0
- package/dist/services/file-system.service.d.ts.map +1 -0
- package/dist/services/file-system.service.js +100 -0
- package/dist/services/file-system.service.js.map +1 -0
- package/dist/services/naming.service.d.ts +40 -0
- package/dist/services/naming.service.d.ts.map +1 -0
- package/dist/services/naming.service.js +86 -0
- package/dist/services/naming.service.js.map +1 -0
- package/dist/services/naming.service.test.d.ts +2 -0
- package/dist/services/naming.service.test.d.ts.map +1 -0
- package/dist/services/naming.service.test.js +99 -0
- package/dist/services/naming.service.test.js.map +1 -0
- package/dist/types/index.d.ts +51 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +14 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dynamic Command Factory
|
|
3
|
+
*
|
|
4
|
+
* Creates Commander.js commands from configuration.
|
|
5
|
+
*/
|
|
6
|
+
import { Command } from "commander";
|
|
7
|
+
import { executeScript, } from "../executor/script-executor.js";
|
|
8
|
+
import { outputResult } from "../infra/output.js";
|
|
9
|
+
import { setLogLevel, logDebug, logError } from "../infra/logger.js";
|
|
10
|
+
/**
|
|
11
|
+
* Create a Commander command from configuration
|
|
12
|
+
*
|
|
13
|
+
* @param config - Command configuration from CLI config file
|
|
14
|
+
* @param configDir - Directory containing the configuration file
|
|
15
|
+
* @returns Configured Commander command
|
|
16
|
+
*/
|
|
17
|
+
export function createDynamicCommand(config, configDir) {
|
|
18
|
+
const command = new Command(config.name);
|
|
19
|
+
// Set description
|
|
20
|
+
if (config.description) {
|
|
21
|
+
command.description(config.description);
|
|
22
|
+
}
|
|
23
|
+
// Add positional arguments
|
|
24
|
+
if (config.arguments) {
|
|
25
|
+
for (const arg of config.arguments) {
|
|
26
|
+
const argSyntax = buildArgumentSyntax(arg);
|
|
27
|
+
command.argument(argSyntax, arg.description ?? "");
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// Add options
|
|
31
|
+
if (config.options) {
|
|
32
|
+
for (const opt of config.options) {
|
|
33
|
+
if (opt.required) {
|
|
34
|
+
command.requiredOption(opt.flags, opt.description ?? "", opt.default);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
const option = command.createOption(opt.flags, opt.description ?? "");
|
|
38
|
+
if (opt.default !== undefined) {
|
|
39
|
+
option.default(opt.default);
|
|
40
|
+
}
|
|
41
|
+
if (opt.choices) {
|
|
42
|
+
option.choices(opt.choices);
|
|
43
|
+
}
|
|
44
|
+
command.addOption(option);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// Add standard options (only if not already defined in config)
|
|
49
|
+
const existingFlags = new Set((config.options ?? []).flatMap((opt) => opt.flags.split(",").map((f) => f.trim().split(/[\s<[]/)[0])));
|
|
50
|
+
if (!existingFlags.has("--format")) {
|
|
51
|
+
command.option("--format <format>", "Output format: human or json", "human");
|
|
52
|
+
}
|
|
53
|
+
if (!existingFlags.has("--quiet")) {
|
|
54
|
+
command.option("--quiet", "Suppress all output except errors");
|
|
55
|
+
}
|
|
56
|
+
if (!existingFlags.has("--verbose")) {
|
|
57
|
+
command.option("--verbose", "Show detailed output");
|
|
58
|
+
}
|
|
59
|
+
if (!existingFlags.has("--debug")) {
|
|
60
|
+
command.option("--debug", "Show debug information");
|
|
61
|
+
}
|
|
62
|
+
// Add action handler
|
|
63
|
+
command.action(async (...actionArgs) => {
|
|
64
|
+
try {
|
|
65
|
+
// Parse arguments and options from Commander
|
|
66
|
+
const { args, options } = parseActionArgs(config, actionArgs);
|
|
67
|
+
// Set log level based on options
|
|
68
|
+
const logLevel = resolveLogLevel(options);
|
|
69
|
+
setLogLevel(logLevel);
|
|
70
|
+
logDebug("Executing command", {
|
|
71
|
+
name: config.name,
|
|
72
|
+
script: config.script,
|
|
73
|
+
args,
|
|
74
|
+
options: { ...options, format: options.format },
|
|
75
|
+
});
|
|
76
|
+
// Build script context
|
|
77
|
+
const context = {
|
|
78
|
+
args,
|
|
79
|
+
options,
|
|
80
|
+
cwd: process.cwd(),
|
|
81
|
+
format: validateFormat(options.format),
|
|
82
|
+
};
|
|
83
|
+
// Execute the script
|
|
84
|
+
const result = await executeScript(config.script, context, configDir);
|
|
85
|
+
logDebug("Script result", result);
|
|
86
|
+
// Output result
|
|
87
|
+
outputResult(result, context.format);
|
|
88
|
+
// Exit with appropriate code
|
|
89
|
+
if (!result.success) {
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
logError("Command execution failed", error);
|
|
95
|
+
outputResult({
|
|
96
|
+
success: false,
|
|
97
|
+
error: error instanceof Error ? error.message : String(error),
|
|
98
|
+
}, "human");
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
return command;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Build Commander argument syntax from configuration
|
|
106
|
+
*/
|
|
107
|
+
function buildArgumentSyntax(arg) {
|
|
108
|
+
const name = arg.name;
|
|
109
|
+
const required = arg.required !== false; // Default to required
|
|
110
|
+
if (arg.variadic) {
|
|
111
|
+
return required ? `<${name}...>` : `[${name}...]`;
|
|
112
|
+
}
|
|
113
|
+
return required ? `<${name}>` : `[${name}]`;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Parse action arguments from Commander callback
|
|
117
|
+
*
|
|
118
|
+
* Commander.js passes arguments to action handlers in this order:
|
|
119
|
+
* 1. Positional arguments (in order)
|
|
120
|
+
* 2. Options object (from command.opts())
|
|
121
|
+
* 3. Command instance itself
|
|
122
|
+
*
|
|
123
|
+
* However, when using .action(), the last argument is always the Command instance.
|
|
124
|
+
* Options must be retrieved via command.opts() method.
|
|
125
|
+
*/
|
|
126
|
+
function parseActionArgs(config, actionArgs) {
|
|
127
|
+
const args = {};
|
|
128
|
+
// The last argument is always the Command instance
|
|
129
|
+
const commandInstance = actionArgs[actionArgs.length - 1];
|
|
130
|
+
// Get options from the Command instance
|
|
131
|
+
const options = commandInstance.opts();
|
|
132
|
+
// Positional arguments are all items except the last one (Command instance)
|
|
133
|
+
const positionalArgs = actionArgs.slice(0, -1);
|
|
134
|
+
if (config.arguments) {
|
|
135
|
+
config.arguments.forEach((argConfig, index) => {
|
|
136
|
+
if (index < positionalArgs.length) {
|
|
137
|
+
args[argConfig.name] = positionalArgs[index];
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
return { args, options };
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Resolve log level from command options
|
|
145
|
+
*/
|
|
146
|
+
function resolveLogLevel(options) {
|
|
147
|
+
if (options.debug)
|
|
148
|
+
return "debug";
|
|
149
|
+
if (options.verbose)
|
|
150
|
+
return "verbose";
|
|
151
|
+
if (options.quiet)
|
|
152
|
+
return "quiet";
|
|
153
|
+
return "normal";
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Validate and normalize output format
|
|
157
|
+
*/
|
|
158
|
+
function validateFormat(format) {
|
|
159
|
+
return format === "json" ? "json" : "human";
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=dynamic-command.factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dynamic-command.factory.js","sourceRoot":"","sources":["../../src/command/dynamic-command.factory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration Loader
|
|
3
|
+
*
|
|
4
|
+
* Finds and loads CLI configuration from multiple sources.
|
|
5
|
+
*/
|
|
6
|
+
import type { LoadConfigResult } from "./config-schema.js";
|
|
7
|
+
/**
|
|
8
|
+
* Load configuration from multiple sources (in order of precedence)
|
|
9
|
+
*
|
|
10
|
+
* 1. Explicit path via --config flag
|
|
11
|
+
* 2. .cli-agent.json in current working directory
|
|
12
|
+
* 3. cli-agent field in package.json
|
|
13
|
+
* 4. ~/.cli-agent.json for global commands
|
|
14
|
+
*
|
|
15
|
+
* @param explicitPath - Optional explicit path to configuration file
|
|
16
|
+
* @returns Configuration result or null if no configuration found
|
|
17
|
+
*/
|
|
18
|
+
export declare function loadConfig(explicitPath?: string): Promise<LoadConfigResult | null>;
|
|
19
|
+
/**
|
|
20
|
+
* Get the configuration file path from command line args
|
|
21
|
+
* Looks for -c or --config flags
|
|
22
|
+
*/
|
|
23
|
+
export declare function getExplicitConfigPath(): string | undefined;
|
|
24
|
+
//# sourceMappingURL=config-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../src/config/config-loader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAI3D;;;;;;;;;;GAUG;AACH,wBAAsB,UAAU,CAC9B,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAuBlC;AAgDD;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,GAAG,SAAS,CAe1D"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration Loader
|
|
3
|
+
*
|
|
4
|
+
* Finds and loads CLI configuration from multiple sources.
|
|
5
|
+
*/
|
|
6
|
+
import { readFile } from "node:fs/promises";
|
|
7
|
+
import { resolve, dirname } from "node:path";
|
|
8
|
+
import { homedir } from "node:os";
|
|
9
|
+
import { validateConfig, ConfigValidationError } from "./config-validator.js";
|
|
10
|
+
import { pathExists } from "../services/file-system.service.js";
|
|
11
|
+
/**
|
|
12
|
+
* Load configuration from multiple sources (in order of precedence)
|
|
13
|
+
*
|
|
14
|
+
* 1. Explicit path via --config flag
|
|
15
|
+
* 2. .cli-agent.json in current working directory
|
|
16
|
+
* 3. cli-agent field in package.json
|
|
17
|
+
* 4. ~/.cli-agent.json for global commands
|
|
18
|
+
*
|
|
19
|
+
* @param explicitPath - Optional explicit path to configuration file
|
|
20
|
+
* @returns Configuration result or null if no configuration found
|
|
21
|
+
*/
|
|
22
|
+
export async function loadConfig(explicitPath) {
|
|
23
|
+
const sources = [];
|
|
24
|
+
// Add explicit path first if provided
|
|
25
|
+
if (explicitPath) {
|
|
26
|
+
sources.push(resolve(process.cwd(), explicitPath));
|
|
27
|
+
}
|
|
28
|
+
// Add standard configuration locations
|
|
29
|
+
sources.push(resolve(process.cwd(), ".cli-agent.json"), resolve(process.cwd(), "package.json"), resolve(homedir(), ".cli-agent.json"));
|
|
30
|
+
for (const source of sources) {
|
|
31
|
+
const result = await tryLoadConfig(source);
|
|
32
|
+
if (result) {
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Try to load configuration from a specific file
|
|
40
|
+
*/
|
|
41
|
+
async function tryLoadConfig(filePath) {
|
|
42
|
+
if (!(await pathExists(filePath))) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
const content = await readFile(filePath, "utf-8");
|
|
47
|
+
const parsed = JSON.parse(content);
|
|
48
|
+
// Handle package.json case
|
|
49
|
+
if (filePath.endsWith("package.json")) {
|
|
50
|
+
if (!parsed["cli-agent"]) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
const config = validateConfig(parsed["cli-agent"]);
|
|
54
|
+
return {
|
|
55
|
+
config,
|
|
56
|
+
configPath: filePath,
|
|
57
|
+
configDir: dirname(filePath),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
// Handle .cli-agent.json
|
|
61
|
+
const config = validateConfig(parsed);
|
|
62
|
+
return {
|
|
63
|
+
config,
|
|
64
|
+
configPath: filePath,
|
|
65
|
+
configDir: dirname(filePath),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
if (error instanceof ConfigValidationError) {
|
|
70
|
+
throw error;
|
|
71
|
+
}
|
|
72
|
+
if (error instanceof SyntaxError) {
|
|
73
|
+
throw new Error(`Invalid JSON in ${filePath}: ${error.message}`);
|
|
74
|
+
}
|
|
75
|
+
// File read errors or other issues - skip this source
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Get the configuration file path from command line args
|
|
81
|
+
* Looks for -c or --config flags
|
|
82
|
+
*/
|
|
83
|
+
export function getExplicitConfigPath() {
|
|
84
|
+
const args = process.argv;
|
|
85
|
+
const configIndex = args.findIndex((arg) => arg === "-c" || arg === "--config");
|
|
86
|
+
if (configIndex !== -1) {
|
|
87
|
+
// Make sure the next arg is not another flag
|
|
88
|
+
const nextArg = args[configIndex + 1];
|
|
89
|
+
if (nextArg && !nextArg.startsWith("-")) {
|
|
90
|
+
return nextArg;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=config-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../../src/config/config-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration Schema
|
|
3
|
+
*
|
|
4
|
+
* TypeScript types for CLI configuration.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Root configuration for cli-agent
|
|
8
|
+
*/
|
|
9
|
+
export interface CliConfig {
|
|
10
|
+
/** CLI name (defaults to 'cli-agent') */
|
|
11
|
+
name?: string;
|
|
12
|
+
/** CLI version (defaults to package.json version) */
|
|
13
|
+
version?: string;
|
|
14
|
+
/** CLI description */
|
|
15
|
+
description?: string;
|
|
16
|
+
/** List of commands */
|
|
17
|
+
commands: CommandConfig[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Configuration for a single command
|
|
21
|
+
*/
|
|
22
|
+
export interface CommandConfig {
|
|
23
|
+
/** Command name (e.g., 'feature-folder') */
|
|
24
|
+
name: string;
|
|
25
|
+
/** Command description for help text */
|
|
26
|
+
description?: string;
|
|
27
|
+
/** Path to script file (.js, .ts, or .sh) relative to config file */
|
|
28
|
+
script: string;
|
|
29
|
+
/** Positional arguments */
|
|
30
|
+
arguments?: ArgumentConfig[];
|
|
31
|
+
/** Command options */
|
|
32
|
+
options?: OptionConfig[];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Configuration for a positional argument
|
|
36
|
+
*/
|
|
37
|
+
export interface ArgumentConfig {
|
|
38
|
+
/** Argument name */
|
|
39
|
+
name: string;
|
|
40
|
+
/** Argument description */
|
|
41
|
+
description?: string;
|
|
42
|
+
/** Whether the argument is required (default: true) */
|
|
43
|
+
required?: boolean;
|
|
44
|
+
/** Whether the argument accepts multiple values (e.g., <files...>) */
|
|
45
|
+
variadic?: boolean;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Configuration for a command option
|
|
49
|
+
*/
|
|
50
|
+
export interface OptionConfig {
|
|
51
|
+
/** Option flags (e.g., '-n, --name <name>') */
|
|
52
|
+
flags: string;
|
|
53
|
+
/** Option description */
|
|
54
|
+
description?: string;
|
|
55
|
+
/** Default value */
|
|
56
|
+
default?: unknown;
|
|
57
|
+
/** Whether the option is required */
|
|
58
|
+
required?: boolean;
|
|
59
|
+
/** Allowed values */
|
|
60
|
+
choices?: string[];
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Result of loading configuration
|
|
64
|
+
*/
|
|
65
|
+
export interface LoadConfigResult {
|
|
66
|
+
/** Parsed and validated configuration */
|
|
67
|
+
config: CliConfig;
|
|
68
|
+
/** Absolute path to the configuration file */
|
|
69
|
+
configPath: string;
|
|
70
|
+
/** Directory containing the configuration file */
|
|
71
|
+
configDir: string;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=config-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-schema.d.ts","sourceRoot":"","sources":["../../src/config/config-schema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sBAAsB;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uBAAuB;IACvB,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAC;IACf,2BAA2B;IAC3B,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC;IAC7B,sBAAsB;IACtB,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,yBAAyB;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qBAAqB;IACrB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,yCAAyC;IACzC,MAAM,EAAE,SAAS,CAAC;IAClB,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,SAAS,EAAE,MAAM,CAAC;CACnB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-schema.js","sourceRoot":"","sources":["../../src/config/config-schema.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration Validator
|
|
3
|
+
*
|
|
4
|
+
* Validates CLI configuration structure.
|
|
5
|
+
*/
|
|
6
|
+
import type { CliConfig } from './config-schema.js';
|
|
7
|
+
/**
|
|
8
|
+
* Validation error with details
|
|
9
|
+
*/
|
|
10
|
+
export declare class ConfigValidationError extends Error {
|
|
11
|
+
readonly path: string;
|
|
12
|
+
readonly value?: unknown | undefined;
|
|
13
|
+
constructor(message: string, path: string, value?: unknown | undefined);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Validate a configuration object
|
|
17
|
+
* @throws ConfigValidationError if validation fails
|
|
18
|
+
*/
|
|
19
|
+
export declare function validateConfig(config: unknown): CliConfig;
|
|
20
|
+
//# sourceMappingURL=config-validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-validator.d.ts","sourceRoot":"","sources":["../../src/config/config-validator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAA+C,MAAM,oBAAoB,CAAC;AAEjG;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;aAG5B,IAAI,EAAE,MAAM;aACZ,KAAK,CAAC,EAAE,OAAO;gBAF/B,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,OAAO,YAAA;CAKlC;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,CAiCzD"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration Validator
|
|
3
|
+
*
|
|
4
|
+
* Validates CLI configuration structure.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Validation error with details
|
|
8
|
+
*/
|
|
9
|
+
export class ConfigValidationError extends Error {
|
|
10
|
+
path;
|
|
11
|
+
value;
|
|
12
|
+
constructor(message, path, value) {
|
|
13
|
+
super(`Configuration error at '${path}': ${message}`);
|
|
14
|
+
this.path = path;
|
|
15
|
+
this.value = value;
|
|
16
|
+
this.name = 'ConfigValidationError';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Validate a configuration object
|
|
21
|
+
* @throws ConfigValidationError if validation fails
|
|
22
|
+
*/
|
|
23
|
+
export function validateConfig(config) {
|
|
24
|
+
if (!config || typeof config !== 'object') {
|
|
25
|
+
throw new ConfigValidationError('Configuration must be an object', 'root', config);
|
|
26
|
+
}
|
|
27
|
+
const cfg = config;
|
|
28
|
+
// Validate optional string fields
|
|
29
|
+
if (cfg.name !== undefined && typeof cfg.name !== 'string') {
|
|
30
|
+
throw new ConfigValidationError('Must be a string', 'name', cfg.name);
|
|
31
|
+
}
|
|
32
|
+
if (cfg.version !== undefined && typeof cfg.version !== 'string') {
|
|
33
|
+
throw new ConfigValidationError('Must be a string', 'version', cfg.version);
|
|
34
|
+
}
|
|
35
|
+
if (cfg.description !== undefined && typeof cfg.description !== 'string') {
|
|
36
|
+
throw new ConfigValidationError('Must be a string', 'description', cfg.description);
|
|
37
|
+
}
|
|
38
|
+
// Validate commands array
|
|
39
|
+
if (!Array.isArray(cfg.commands)) {
|
|
40
|
+
throw new ConfigValidationError('Must be an array', 'commands', cfg.commands);
|
|
41
|
+
}
|
|
42
|
+
const commands = cfg.commands.map((cmd, index) => validateCommand(cmd, `commands[${index}]`));
|
|
43
|
+
return {
|
|
44
|
+
name: cfg.name,
|
|
45
|
+
version: cfg.version,
|
|
46
|
+
description: cfg.description,
|
|
47
|
+
commands,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Validate a command configuration
|
|
52
|
+
*/
|
|
53
|
+
function validateCommand(cmd, path) {
|
|
54
|
+
if (!cmd || typeof cmd !== 'object') {
|
|
55
|
+
throw new ConfigValidationError('Must be an object', path, cmd);
|
|
56
|
+
}
|
|
57
|
+
const command = cmd;
|
|
58
|
+
// Required: name
|
|
59
|
+
if (typeof command.name !== 'string' || command.name.trim() === '') {
|
|
60
|
+
throw new ConfigValidationError('Must be a non-empty string', `${path}.name`, command.name);
|
|
61
|
+
}
|
|
62
|
+
// Required: script
|
|
63
|
+
if (typeof command.script !== 'string' || command.script.trim() === '') {
|
|
64
|
+
throw new ConfigValidationError('Must be a non-empty string', `${path}.script`, command.script);
|
|
65
|
+
}
|
|
66
|
+
// Optional: description
|
|
67
|
+
if (command.description !== undefined && typeof command.description !== 'string') {
|
|
68
|
+
throw new ConfigValidationError('Must be a string', `${path}.description`, command.description);
|
|
69
|
+
}
|
|
70
|
+
// Optional: arguments
|
|
71
|
+
let args;
|
|
72
|
+
if (command.arguments !== undefined) {
|
|
73
|
+
if (!Array.isArray(command.arguments)) {
|
|
74
|
+
throw new ConfigValidationError('Must be an array', `${path}.arguments`, command.arguments);
|
|
75
|
+
}
|
|
76
|
+
args = command.arguments.map((arg, index) => validateArgument(arg, `${path}.arguments[${index}]`));
|
|
77
|
+
}
|
|
78
|
+
// Optional: options
|
|
79
|
+
let options;
|
|
80
|
+
if (command.options !== undefined) {
|
|
81
|
+
if (!Array.isArray(command.options)) {
|
|
82
|
+
throw new ConfigValidationError('Must be an array', `${path}.options`, command.options);
|
|
83
|
+
}
|
|
84
|
+
options = command.options.map((opt, index) => validateOption(opt, `${path}.options[${index}]`));
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
name: command.name,
|
|
88
|
+
description: command.description,
|
|
89
|
+
script: command.script,
|
|
90
|
+
arguments: args,
|
|
91
|
+
options,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Validate an argument configuration
|
|
96
|
+
*/
|
|
97
|
+
function validateArgument(arg, path) {
|
|
98
|
+
if (!arg || typeof arg !== 'object') {
|
|
99
|
+
throw new ConfigValidationError('Must be an object', path, arg);
|
|
100
|
+
}
|
|
101
|
+
const argument = arg;
|
|
102
|
+
// Required: name
|
|
103
|
+
if (typeof argument.name !== 'string' || argument.name.trim() === '') {
|
|
104
|
+
throw new ConfigValidationError('Must be a non-empty string', `${path}.name`, argument.name);
|
|
105
|
+
}
|
|
106
|
+
// Optional: description
|
|
107
|
+
if (argument.description !== undefined && typeof argument.description !== 'string') {
|
|
108
|
+
throw new ConfigValidationError('Must be a string', `${path}.description`, argument.description);
|
|
109
|
+
}
|
|
110
|
+
// Optional: required (default: true)
|
|
111
|
+
if (argument.required !== undefined && typeof argument.required !== 'boolean') {
|
|
112
|
+
throw new ConfigValidationError('Must be a boolean', `${path}.required`, argument.required);
|
|
113
|
+
}
|
|
114
|
+
// Optional: variadic (default: false)
|
|
115
|
+
if (argument.variadic !== undefined && typeof argument.variadic !== 'boolean') {
|
|
116
|
+
throw new ConfigValidationError('Must be a boolean', `${path}.variadic`, argument.variadic);
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
name: argument.name,
|
|
120
|
+
description: argument.description,
|
|
121
|
+
required: argument.required,
|
|
122
|
+
variadic: argument.variadic,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Validate an option configuration
|
|
127
|
+
*/
|
|
128
|
+
function validateOption(opt, path) {
|
|
129
|
+
if (!opt || typeof opt !== 'object') {
|
|
130
|
+
throw new ConfigValidationError('Must be an object', path, opt);
|
|
131
|
+
}
|
|
132
|
+
const option = opt;
|
|
133
|
+
// Required: flags
|
|
134
|
+
if (typeof option.flags !== 'string' || option.flags.trim() === '') {
|
|
135
|
+
throw new ConfigValidationError('Must be a non-empty string', `${path}.flags`, option.flags);
|
|
136
|
+
}
|
|
137
|
+
// Optional: description
|
|
138
|
+
if (option.description !== undefined && typeof option.description !== 'string') {
|
|
139
|
+
throw new ConfigValidationError('Must be a string', `${path}.description`, option.description);
|
|
140
|
+
}
|
|
141
|
+
// Optional: required
|
|
142
|
+
if (option.required !== undefined && typeof option.required !== 'boolean') {
|
|
143
|
+
throw new ConfigValidationError('Must be a boolean', `${path}.required`, option.required);
|
|
144
|
+
}
|
|
145
|
+
// Optional: choices
|
|
146
|
+
if (option.choices !== undefined) {
|
|
147
|
+
if (!Array.isArray(option.choices)) {
|
|
148
|
+
throw new ConfigValidationError('Must be an array', `${path}.choices`, option.choices);
|
|
149
|
+
}
|
|
150
|
+
if (!option.choices.every((c) => typeof c === 'string')) {
|
|
151
|
+
throw new ConfigValidationError('All choices must be strings', `${path}.choices`, option.choices);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
flags: option.flags,
|
|
156
|
+
description: option.description,
|
|
157
|
+
default: option.default,
|
|
158
|
+
required: option.required,
|
|
159
|
+
choices: option.choices,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=config-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-validator.js","sourceRoot":"","sources":["../../src/config/config-validator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;GAEG;AACH,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAG5B;IACA;IAHlB,YACE,OAAe,EACC,IAAY,EACZ,KAAe;QAE/B,KAAK,CAAC,2BAA2B,IAAI,MAAM,OAAO,EAAE,CAAC,CAAC;QAHtC,SAAI,GAAJ,IAAI,CAAQ;QACZ,UAAK,GAAL,KAAK,CAAU;QAG/B,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;IACtC,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,MAAe;IAC5C,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC1C,MAAM,IAAI,qBAAqB,CAAC,iCAAiC,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACrF,CAAC;IAED,MAAM,GAAG,GAAG,MAAiC,CAAC;IAE9C,kCAAkC;IAClC,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC3D,MAAM,IAAI,qBAAqB,CAAC,kBAAkB,EAAE,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;IACxE,CAAC;IAED,IAAI,GAAG,CAAC,OAAO,KAAK,SAAS,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QACjE,MAAM,IAAI,qBAAqB,CAAC,kBAAkB,EAAE,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IAC9E,CAAC;IAED,IAAI,GAAG,CAAC,WAAW,KAAK,SAAS,IAAI,OAAO,GAAG,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;QACzE,MAAM,IAAI,qBAAqB,CAAC,kBAAkB,EAAE,aAAa,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC;IACtF,CAAC;IAED,0BAA0B;IAC1B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,qBAAqB,CAAC,kBAAkB,EAAE,UAAU,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;IAChF,CAAC;IAED,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,eAAe,CAAC,GAAG,EAAE,YAAY,KAAK,GAAG,CAAC,CAAC,CAAC;IAE9F,OAAO;QACL,IAAI,EAAE,GAAG,CAAC,IAA0B;QACpC,OAAO,EAAE,GAAG,CAAC,OAA6B;QAC1C,WAAW,EAAE,GAAG,CAAC,WAAiC;QAClD,QAAQ;KACT,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,GAAY,EAAE,IAAY;IACjD,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACpC,MAAM,IAAI,qBAAqB,CAAC,mBAAmB,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,OAAO,GAAG,GAA8B,CAAC;IAE/C,iBAAiB;IACjB,IAAI,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACnE,MAAM,IAAI,qBAAqB,CAAC,4BAA4B,EAAE,GAAG,IAAI,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9F,CAAC;IAED,mBAAmB;IACnB,IAAI,OAAO,OAAO,CAAC,MAAM,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACvE,MAAM,IAAI,qBAAqB,CAAC,4BAA4B,EAAE,GAAG,IAAI,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAClG,CAAC;IAED,wBAAwB;IACxB,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS,IAAI,OAAO,OAAO,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;QACjF,MAAM,IAAI,qBAAqB,CAAC,kBAAkB,EAAE,GAAG,IAAI,cAAc,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAClG,CAAC;IAED,sBAAsB;IACtB,IAAI,IAAkC,CAAC;IACvC,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QACpC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;YACtC,MAAM,IAAI,qBAAqB,CAAC,kBAAkB,EAAE,GAAG,IAAI,YAAY,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;QAC9F,CAAC;QACD,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAC1C,gBAAgB,CAAC,GAAG,EAAE,GAAG,IAAI,cAAc,KAAK,GAAG,CAAC,CACrD,CAAC;IACJ,CAAC;IAED,oBAAoB;IACpB,IAAI,OAAmC,CAAC;IACxC,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAClC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACpC,MAAM,IAAI,qBAAqB,CAAC,kBAAkB,EAAE,GAAG,IAAI,UAAU,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QAC1F,CAAC;QACD,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAC3C,cAAc,CAAC,GAAG,EAAE,GAAG,IAAI,YAAY,KAAK,GAAG,CAAC,CACjD,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,WAAW,EAAE,OAAO,CAAC,WAAiC;QACtD,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,SAAS,EAAE,IAAI;QACf,OAAO;KACR,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CAAC,GAAY,EAAE,IAAY;IAClD,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACpC,MAAM,IAAI,qBAAqB,CAAC,mBAAmB,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,QAAQ,GAAG,GAA8B,CAAC;IAEhD,iBAAiB;IACjB,IAAI,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACrE,MAAM,IAAI,qBAAqB,CAAC,4BAA4B,EAAE,GAAG,IAAI,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC/F,CAAC;IAED,wBAAwB;IACxB,IAAI,QAAQ,CAAC,WAAW,KAAK,SAAS,IAAI,OAAO,QAAQ,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;QACnF,MAAM,IAAI,qBAAqB,CAAC,kBAAkB,EAAE,GAAG,IAAI,cAAc,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;IACnG,CAAC;IAED,qCAAqC;IACrC,IAAI,QAAQ,CAAC,QAAQ,KAAK,SAAS,IAAI,OAAO,QAAQ,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC9E,MAAM,IAAI,qBAAqB,CAAC,mBAAmB,EAAE,GAAG,IAAI,WAAW,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC9F,CAAC;IAED,sCAAsC;IACtC,IAAI,QAAQ,CAAC,QAAQ,KAAK,SAAS,IAAI,OAAO,QAAQ,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC9E,MAAM,IAAI,qBAAqB,CAAC,mBAAmB,EAAE,GAAG,IAAI,WAAW,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC9F,CAAC;IAED,OAAO;QACL,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,WAAW,EAAE,QAAQ,CAAC,WAAiC;QACvD,QAAQ,EAAE,QAAQ,CAAC,QAA+B;QAClD,QAAQ,EAAE,QAAQ,CAAC,QAA+B;KACnD,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,GAAY,EAAE,IAAY;IAChD,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACpC,MAAM,IAAI,qBAAqB,CAAC,mBAAmB,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,MAAM,GAAG,GAA8B,CAAC;IAE9C,kBAAkB;IAClB,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACnE,MAAM,IAAI,qBAAqB,CAAC,4BAA4B,EAAE,GAAG,IAAI,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC/F,CAAC;IAED,wBAAwB;IACxB,IAAI,MAAM,CAAC,WAAW,KAAK,SAAS,IAAI,OAAO,MAAM,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;QAC/E,MAAM,IAAI,qBAAqB,CAAC,kBAAkB,EAAE,GAAG,IAAI,cAAc,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;IACjG,CAAC;IAED,qBAAqB;IACrB,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC1E,MAAM,IAAI,qBAAqB,CAAC,mBAAmB,EAAE,GAAG,IAAI,WAAW,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC5F,CAAC;IAED,oBAAoB;IACpB,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QACjC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YACnC,MAAM,IAAI,qBAAqB,CAAC,kBAAkB,EAAE,GAAG,IAAI,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;QACzF,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,EAAE,CAAC;YACxD,MAAM,IAAI,qBAAqB,CAAC,6BAA6B,EAAE,GAAG,IAAI,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;QACpG,CAAC;IACH,CAAC;IAED,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,WAAW,EAAE,MAAM,CAAC,WAAiC;QACrD,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,QAAQ,EAAE,MAAM,CAAC,QAA+B;QAChD,OAAO,EAAE,MAAM,CAAC,OAA+B;KAChD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JavaScript Executor
|
|
3
|
+
*
|
|
4
|
+
* Executes .js files by importing and calling their default export.
|
|
5
|
+
*/
|
|
6
|
+
import type { ScriptContext, ScriptResult } from './script-executor.js';
|
|
7
|
+
/**
|
|
8
|
+
* Execute a JavaScript file
|
|
9
|
+
*
|
|
10
|
+
* The script must export a default async function that accepts ScriptContext
|
|
11
|
+
* and returns a CommandResult.
|
|
12
|
+
*
|
|
13
|
+
* Example script:
|
|
14
|
+
* ```javascript
|
|
15
|
+
* export default async function(context) {
|
|
16
|
+
* return {
|
|
17
|
+
* success: true,
|
|
18
|
+
* message: 'Hello!',
|
|
19
|
+
* data: { greeting: 'Hello!' }
|
|
20
|
+
* };
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* @param scriptPath - Absolute path to the JavaScript file
|
|
25
|
+
* @param context - Execution context
|
|
26
|
+
* @returns Script execution result
|
|
27
|
+
*/
|
|
28
|
+
export declare function executeJavaScript(scriptPath: string, context: ScriptContext): Promise<ScriptResult>;
|
|
29
|
+
//# sourceMappingURL=js-executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"js-executor.d.ts","sourceRoot":"","sources":["../../src/executor/js-executor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGxE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,YAAY,CAAC,CA2CvB"}
|