chrome-cdp-cli 2.1.1 â 2.1.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/dist/cli/EnhancedCLIInterface.js +48 -38
- package/dist/cli/OutputFormatter.js +77 -75
- package/dist/cli/OutputManager.js +20 -20
- package/dist/client/index.js +0 -1
- package/dist/handlers/EvaluateScriptHandler.js +74 -270
- package/package.json +1 -1
- package/dist/client/ProxyClient.js +0 -278
- package/dist/handlers/RestartProxyHandler.js +0 -97
- package/dist/proxy/ProxyManager.js +0 -270
- package/dist/proxy/index.js +0 -60
- package/dist/proxy/server/CDPEventMonitor.js +0 -263
- package/dist/proxy/server/CDPProxyServer.js +0 -441
- package/dist/proxy/server/CommandExecutionService.js +0 -297
- package/dist/proxy/server/ConnectionPool.js +0 -437
- package/dist/proxy/server/FileSystemSecurity.js +0 -358
- package/dist/proxy/server/HealthMonitor.js +0 -242
- package/dist/proxy/server/MessageStore.js +0 -291
- package/dist/proxy/server/PerformanceMonitor.js +0 -277
- package/dist/proxy/server/ProxyAPIServer.js +0 -1125
- package/dist/proxy/server/SecurityManager.js +0 -337
- package/dist/proxy/server/WSProxy.js +0 -468
- package/dist/proxy/types/ProxyTypes.js +0 -2
|
@@ -6,7 +6,7 @@ const CommandSchemaRegistry_1 = require("./CommandSchemaRegistry");
|
|
|
6
6
|
const CLIInterface_1 = require("../interfaces/CLIInterface");
|
|
7
7
|
const CommandRegistry_1 = require("./CommandRegistry");
|
|
8
8
|
const CommandRouter_1 = require("./CommandRouter");
|
|
9
|
-
const packageJson = require(
|
|
9
|
+
const packageJson = require("../../package.json");
|
|
10
10
|
class EnhancedCLIInterface {
|
|
11
11
|
constructor() {
|
|
12
12
|
this.argumentParser = new ArgumentParser_1.ArgumentParser();
|
|
@@ -25,40 +25,40 @@ class EnhancedCLIInterface {
|
|
|
25
25
|
try {
|
|
26
26
|
const parseResult = this.argumentParser.parseArguments(argv);
|
|
27
27
|
if (!parseResult.success) {
|
|
28
|
-
const errorMessage = parseResult.errors.join(
|
|
28
|
+
const errorMessage = parseResult.errors.join("\n");
|
|
29
29
|
const contextualHelp = this.argumentParser.generateContextualHelp(errorMessage, parseResult.command);
|
|
30
30
|
throw new Error(`Parse error: ${errorMessage}\n\n${contextualHelp}`);
|
|
31
31
|
}
|
|
32
|
-
if (parseResult.command ===
|
|
32
|
+
if (parseResult.command === "version") {
|
|
33
33
|
console.log(packageJson.version);
|
|
34
|
-
if (process.env.NODE_ENV !==
|
|
34
|
+
if (process.env.NODE_ENV !== "test") {
|
|
35
35
|
process.exit(0);
|
|
36
36
|
}
|
|
37
|
-
throw new Error(
|
|
37
|
+
throw new Error("VERSION_COMMAND_EXECUTED");
|
|
38
38
|
}
|
|
39
|
-
if (parseResult.command ===
|
|
39
|
+
if (parseResult.command === "help") {
|
|
40
40
|
const helpArg = parseResult.arguments[0];
|
|
41
41
|
const helpText = this.argumentParser.generateHelp(helpArg);
|
|
42
42
|
console.log(helpText);
|
|
43
|
-
if (process.env.NODE_ENV !==
|
|
43
|
+
if (process.env.NODE_ENV !== "test") {
|
|
44
44
|
process.exit(0);
|
|
45
45
|
}
|
|
46
|
-
throw new Error(
|
|
46
|
+
throw new Error("HELP_COMMAND_EXECUTED");
|
|
47
47
|
}
|
|
48
48
|
const config = this.buildConfiguration(parseResult.options);
|
|
49
49
|
const args = this.buildCommandArguments(parseResult);
|
|
50
50
|
return {
|
|
51
51
|
name: parseResult.command,
|
|
52
52
|
args,
|
|
53
|
-
config
|
|
53
|
+
config,
|
|
54
54
|
};
|
|
55
55
|
}
|
|
56
56
|
catch (error) {
|
|
57
57
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
58
|
-
if (errorMessage.includes(
|
|
59
|
-
console.error(
|
|
58
|
+
if (errorMessage.includes("Invalid count value")) {
|
|
59
|
+
console.error("Error details:", error);
|
|
60
60
|
if (error instanceof Error && error.stack) {
|
|
61
|
-
console.error(
|
|
61
|
+
console.error("Stack trace:", error.stack);
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
throw new Error(`Failed to parse arguments: ${errorMessage}`);
|
|
@@ -68,18 +68,30 @@ class EnhancedCLIInterface {
|
|
|
68
68
|
return {
|
|
69
69
|
host: globalOptions.host || CLIInterface_1.DEFAULT_CLI_CONFIG.host,
|
|
70
70
|
port: globalOptions.port || CLIInterface_1.DEFAULT_CLI_CONFIG.port,
|
|
71
|
-
outputFormat: globalOptions.format ||
|
|
71
|
+
outputFormat: globalOptions.format ||
|
|
72
|
+
CLIInterface_1.DEFAULT_CLI_CONFIG.outputFormat,
|
|
72
73
|
verbose: globalOptions.verbose || CLIInterface_1.DEFAULT_CLI_CONFIG.verbose,
|
|
73
74
|
quiet: globalOptions.quiet || CLIInterface_1.DEFAULT_CLI_CONFIG.quiet,
|
|
74
75
|
timeout: globalOptions.timeout || CLIInterface_1.DEFAULT_CLI_CONFIG.timeout,
|
|
75
76
|
debug: globalOptions.debug || CLIInterface_1.DEFAULT_CLI_CONFIG.debug,
|
|
76
|
-
targetIndex: globalOptions[
|
|
77
|
+
targetIndex: globalOptions["target-index"] !== undefined
|
|
78
|
+
? globalOptions["target-index"]
|
|
79
|
+
: undefined,
|
|
77
80
|
};
|
|
78
81
|
}
|
|
79
82
|
buildCommandArguments(parseResult) {
|
|
80
83
|
const args = {};
|
|
81
84
|
for (const [key, value] of Object.entries(parseResult.options)) {
|
|
82
|
-
const globalOptions = [
|
|
85
|
+
const globalOptions = [
|
|
86
|
+
"host",
|
|
87
|
+
"port",
|
|
88
|
+
"format",
|
|
89
|
+
"verbose",
|
|
90
|
+
"quiet",
|
|
91
|
+
"timeout",
|
|
92
|
+
"debug",
|
|
93
|
+
"config",
|
|
94
|
+
];
|
|
83
95
|
if (!globalOptions.includes(key)) {
|
|
84
96
|
args[key] = value;
|
|
85
97
|
}
|
|
@@ -99,19 +111,19 @@ class EnhancedCLIInterface {
|
|
|
99
111
|
if (commandDef) {
|
|
100
112
|
const validation = this.argumentParser.validateArguments(command.name, {
|
|
101
113
|
options: command.args,
|
|
102
|
-
arguments: Object.values(command.args)
|
|
114
|
+
arguments: Object.values(command.args),
|
|
103
115
|
});
|
|
104
116
|
if (!validation.valid) {
|
|
105
|
-
const errorMessage = `Validation failed: ${validation.errors.join(
|
|
117
|
+
const errorMessage = `Validation failed: ${validation.errors.join(", ")}`;
|
|
106
118
|
const contextualHelp = this.argumentParser.generateContextualHelp(errorMessage, command.name);
|
|
107
119
|
return {
|
|
108
120
|
success: false,
|
|
109
121
|
error: `${errorMessage}\n\n${contextualHelp}`,
|
|
110
|
-
exitCode: 5
|
|
122
|
+
exitCode: 5,
|
|
111
123
|
};
|
|
112
124
|
}
|
|
113
125
|
if (validation.warnings.length > 0 && command.config.verbose) {
|
|
114
|
-
console.warn(
|
|
126
|
+
console.warn("Warnings:", validation.warnings.join(", "));
|
|
115
127
|
}
|
|
116
128
|
}
|
|
117
129
|
return await this.router.execute(command);
|
|
@@ -122,37 +134,35 @@ class EnhancedCLIInterface {
|
|
|
122
134
|
return {
|
|
123
135
|
success: false,
|
|
124
136
|
error: `${errorMessage}\n\n${contextualHelp}`,
|
|
125
|
-
exitCode: 1
|
|
137
|
+
exitCode: 1,
|
|
126
138
|
};
|
|
127
139
|
}
|
|
128
140
|
}
|
|
129
141
|
formatOutput(result, format) {
|
|
130
|
-
if (format ===
|
|
142
|
+
if (format === "json") {
|
|
131
143
|
return JSON.stringify(result, null, 2);
|
|
132
144
|
}
|
|
133
145
|
if (!result.success) {
|
|
134
146
|
return `Error: ${result.error}`;
|
|
135
147
|
}
|
|
136
148
|
if (result.data === undefined || result.data === null) {
|
|
137
|
-
return
|
|
149
|
+
return "Success";
|
|
138
150
|
}
|
|
139
|
-
let output =
|
|
140
|
-
let dataSourceInfo =
|
|
141
|
-
if (result.dataSource ===
|
|
142
|
-
dataSourceInfo =
|
|
151
|
+
let output = "";
|
|
152
|
+
let dataSourceInfo = "";
|
|
153
|
+
if (result.dataSource === "direct" && result.hasHistoricalData === false) {
|
|
154
|
+
dataSourceInfo =
|
|
155
|
+
"â ī¸ Data from direct connection (new messages only, no historical data)\n";
|
|
143
156
|
}
|
|
144
|
-
|
|
145
|
-
dataSourceInfo = 'â ī¸ Data from direct connection (new messages only, no historical data)\n';
|
|
146
|
-
}
|
|
147
|
-
if (result.data && typeof result.data === 'object') {
|
|
157
|
+
if (result.data && typeof result.data === "object") {
|
|
148
158
|
const data = result.data;
|
|
149
|
-
if (data.snapshot && typeof data.snapshot ===
|
|
159
|
+
if (data.snapshot && typeof data.snapshot === "string") {
|
|
150
160
|
return data.snapshot;
|
|
151
161
|
}
|
|
152
162
|
if (data.messages && Array.isArray(data.messages)) {
|
|
153
163
|
output += dataSourceInfo;
|
|
154
164
|
if (data.messages.length === 0) {
|
|
155
|
-
output +=
|
|
165
|
+
output += "No console messages found.";
|
|
156
166
|
}
|
|
157
167
|
else {
|
|
158
168
|
output += `Found ${data.messages.length} console message(s):\n\n`;
|
|
@@ -166,13 +176,13 @@ class EnhancedCLIInterface {
|
|
|
166
176
|
if (data.requests && Array.isArray(data.requests)) {
|
|
167
177
|
output += dataSourceInfo;
|
|
168
178
|
if (data.requests.length === 0) {
|
|
169
|
-
output +=
|
|
179
|
+
output += "No network requests found.";
|
|
170
180
|
}
|
|
171
181
|
else {
|
|
172
182
|
output += `Found ${data.requests.length} network request(s):\n\n`;
|
|
173
183
|
data.requests.forEach((req, index) => {
|
|
174
184
|
const timestamp = new Date(req.timestamp).toISOString();
|
|
175
|
-
const status = req.status ? ` [${req.status}]` :
|
|
185
|
+
const status = req.status ? ` [${req.status}]` : " [pending]";
|
|
176
186
|
output += `[${index + 1}] ${timestamp} ${req.method} ${req.url}${status}\n`;
|
|
177
187
|
});
|
|
178
188
|
}
|
|
@@ -187,15 +197,15 @@ class EnhancedCLIInterface {
|
|
|
187
197
|
if (data.requestId && data.url && data.method) {
|
|
188
198
|
output += dataSourceInfo;
|
|
189
199
|
const timestamp = new Date(data.timestamp).toISOString();
|
|
190
|
-
const status = data.status ? ` [${data.status}]` :
|
|
200
|
+
const status = data.status ? ` [${data.status}]` : " [pending]";
|
|
191
201
|
output += `${timestamp} ${data.method} ${data.url}${status}`;
|
|
192
202
|
return output;
|
|
193
203
|
}
|
|
194
204
|
}
|
|
195
|
-
if (typeof result.data ===
|
|
205
|
+
if (typeof result.data === "string") {
|
|
196
206
|
return result.data;
|
|
197
207
|
}
|
|
198
|
-
if (typeof result.data ===
|
|
208
|
+
if (typeof result.data === "object") {
|
|
199
209
|
return JSON.stringify(result.data, null, 2);
|
|
200
210
|
}
|
|
201
211
|
return String(result.data);
|
|
@@ -204,7 +214,7 @@ class EnhancedCLIInterface {
|
|
|
204
214
|
return this.argumentParser.generateHelp(commandName);
|
|
205
215
|
}
|
|
206
216
|
getAvailableCommands() {
|
|
207
|
-
return this.argumentParser.getCommands().map(cmd => cmd.name);
|
|
217
|
+
return this.argumentParser.getCommands().map((cmd) => cmd.name);
|
|
208
218
|
}
|
|
209
219
|
registerHandler(handler) {
|
|
210
220
|
this.commandRegistry.register(handler);
|
|
@@ -20,11 +20,11 @@ class OutputFormatter {
|
|
|
20
20
|
return this.applyTemplate(result, options.template);
|
|
21
21
|
}
|
|
22
22
|
switch (options.format) {
|
|
23
|
-
case
|
|
23
|
+
case "json":
|
|
24
24
|
return this.formatJsonOutput(result, options);
|
|
25
|
-
case
|
|
25
|
+
case "yaml":
|
|
26
26
|
return this.formatYamlOutput(result, options);
|
|
27
|
-
case
|
|
27
|
+
case "text":
|
|
28
28
|
default:
|
|
29
29
|
return this.formatTextOutput(result, options);
|
|
30
30
|
}
|
|
@@ -32,7 +32,7 @@ class OutputFormatter {
|
|
|
32
32
|
formatJsonOutput(result, options) {
|
|
33
33
|
const output = {
|
|
34
34
|
success: result.success,
|
|
35
|
-
data: result.data
|
|
35
|
+
data: result.data,
|
|
36
36
|
};
|
|
37
37
|
if (options.mode.verbose && options.includeMetadata && result.metadata) {
|
|
38
38
|
output.metadata = result.metadata;
|
|
@@ -42,14 +42,14 @@ class OutputFormatter {
|
|
|
42
42
|
operation: result.timing.operationName,
|
|
43
43
|
duration: `${result.timing.duration}ms`,
|
|
44
44
|
startTime: new Date(result.timing.startTime).toISOString(),
|
|
45
|
-
endTime: new Date(result.timing.endTime).toISOString()
|
|
45
|
+
endTime: new Date(result.timing.endTime).toISOString(),
|
|
46
46
|
};
|
|
47
47
|
}
|
|
48
48
|
if (options.mode.debug) {
|
|
49
49
|
output.debug = {
|
|
50
50
|
exitCode: result.exitCode,
|
|
51
51
|
dataSource: result.dataSource,
|
|
52
|
-
hasHistoricalData: result.hasHistoricalData
|
|
52
|
+
hasHistoricalData: result.hasHistoricalData,
|
|
53
53
|
};
|
|
54
54
|
}
|
|
55
55
|
return JSON.stringify(output, null, 2);
|
|
@@ -58,8 +58,8 @@ class OutputFormatter {
|
|
|
58
58
|
const lines = [];
|
|
59
59
|
lines.push(`success: ${result.success}`);
|
|
60
60
|
if (result.data !== undefined) {
|
|
61
|
-
if (typeof result.data ===
|
|
62
|
-
lines.push(
|
|
61
|
+
if (typeof result.data === "object" && result.data !== null) {
|
|
62
|
+
lines.push("data:");
|
|
63
63
|
lines.push(this.objectToYaml(result.data, 1));
|
|
64
64
|
}
|
|
65
65
|
else {
|
|
@@ -67,49 +67,47 @@ class OutputFormatter {
|
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
if (options.mode.verbose && result.timing) {
|
|
70
|
-
lines.push(
|
|
70
|
+
lines.push("timing:");
|
|
71
71
|
lines.push(` operation: ${result.timing.operationName}`);
|
|
72
72
|
lines.push(` duration: ${result.timing.duration}ms`);
|
|
73
73
|
lines.push(` startTime: ${new Date(result.timing.startTime).toISOString()}`);
|
|
74
74
|
lines.push(` endTime: ${new Date(result.timing.endTime).toISOString()}`);
|
|
75
75
|
}
|
|
76
|
-
return lines.join(
|
|
76
|
+
return lines.join("\n");
|
|
77
77
|
}
|
|
78
78
|
formatTextOutput(result, options) {
|
|
79
|
-
let output =
|
|
79
|
+
let output = "";
|
|
80
80
|
if (options.mode.verbose && result.timing) {
|
|
81
81
|
output += `âąī¸ Operation: ${result.timing.operationName} (${result.timing.duration}ms)\n`;
|
|
82
82
|
if (options.mode.debug) {
|
|
83
83
|
output += ` Started: ${new Date(result.timing.startTime).toISOString()}\n`;
|
|
84
84
|
output += ` Ended: ${new Date(result.timing.endTime).toISOString()}\n`;
|
|
85
85
|
}
|
|
86
|
-
output +=
|
|
86
|
+
output += "\n";
|
|
87
87
|
}
|
|
88
88
|
if (result.dataSource && options.mode.verbose) {
|
|
89
|
-
const sourceIcon =
|
|
90
|
-
const sourceText =
|
|
91
|
-
? 'Data from proxy server'
|
|
92
|
-
: 'Data from direct connection';
|
|
89
|
+
const sourceIcon = "â ī¸";
|
|
90
|
+
const sourceText = "Data from direct connection";
|
|
93
91
|
const historyText = result.hasHistoricalData
|
|
94
|
-
?
|
|
95
|
-
:
|
|
92
|
+
? "(includes historical data)"
|
|
93
|
+
: "(new data only)";
|
|
96
94
|
output += `${sourceIcon} ${sourceText} ${historyText}\n\n`;
|
|
97
95
|
}
|
|
98
96
|
if (result.data === undefined || result.data === null) {
|
|
99
|
-
output +=
|
|
97
|
+
output += "Success";
|
|
100
98
|
}
|
|
101
99
|
else {
|
|
102
100
|
output += this.formatDataForText(result.data, options);
|
|
103
101
|
}
|
|
104
102
|
if (options.mode.verbose && options.includeMetadata && result.metadata) {
|
|
105
|
-
output +=
|
|
103
|
+
output += "\n\nđ Command Details:\n";
|
|
106
104
|
output += ` Command: ${result.metadata.command}\n`;
|
|
107
105
|
if (Object.keys(result.metadata.args).length > 0) {
|
|
108
106
|
output += ` Arguments: ${JSON.stringify(result.metadata.args)}\n`;
|
|
109
107
|
}
|
|
110
108
|
}
|
|
111
109
|
if (options.mode.debug) {
|
|
112
|
-
output +=
|
|
110
|
+
output += "\n\nđ§ Debug Information:\n";
|
|
113
111
|
output += ` Exit Code: ${result.exitCode || 0}\n`;
|
|
114
112
|
if (result.dataSource) {
|
|
115
113
|
output += ` Data Source: ${result.dataSource}\n`;
|
|
@@ -121,17 +119,17 @@ class OutputFormatter {
|
|
|
121
119
|
return output.trim();
|
|
122
120
|
}
|
|
123
121
|
formatDataForText(data, options) {
|
|
124
|
-
if (typeof data ===
|
|
122
|
+
if (typeof data === "string") {
|
|
125
123
|
return data;
|
|
126
124
|
}
|
|
127
|
-
if (typeof data ===
|
|
125
|
+
if (typeof data === "object" && data !== null) {
|
|
128
126
|
const obj = data;
|
|
129
|
-
if (obj.snapshot && typeof obj.snapshot ===
|
|
127
|
+
if (obj.snapshot && typeof obj.snapshot === "string") {
|
|
130
128
|
return obj.snapshot;
|
|
131
129
|
}
|
|
132
130
|
if (obj.messages && Array.isArray(obj.messages)) {
|
|
133
131
|
if (obj.messages.length === 0) {
|
|
134
|
-
return
|
|
132
|
+
return "No console messages found.";
|
|
135
133
|
}
|
|
136
134
|
let output = `Found ${obj.messages.length} console message(s):\n\n`;
|
|
137
135
|
obj.messages.forEach((msg, index) => {
|
|
@@ -146,12 +144,12 @@ class OutputFormatter {
|
|
|
146
144
|
}
|
|
147
145
|
if (obj.requests && Array.isArray(obj.requests)) {
|
|
148
146
|
if (obj.requests.length === 0) {
|
|
149
|
-
return
|
|
147
|
+
return "No network requests found.";
|
|
150
148
|
}
|
|
151
149
|
let output = `Found ${obj.requests.length} network request(s):\n\n`;
|
|
152
150
|
obj.requests.forEach((req, index) => {
|
|
153
151
|
const timestamp = new Date(req.timestamp).toISOString();
|
|
154
|
-
const status = req.status ? ` [${req.status}]` :
|
|
152
|
+
const status = req.status ? ` [${req.status}]` : " [pending]";
|
|
155
153
|
const methodIcon = this.getHttpMethodIcon(req.method);
|
|
156
154
|
output += `[${index + 1}] ${timestamp} ${methodIcon} ${req.method} ${req.url}${status}\n`;
|
|
157
155
|
if (options.mode.verbose && req.headers) {
|
|
@@ -159,7 +157,7 @@ class OutputFormatter {
|
|
|
159
157
|
}
|
|
160
158
|
if (options.mode.debug && req.responseBody) {
|
|
161
159
|
const bodyPreview = req.responseBody.substring(0, 100);
|
|
162
|
-
output += ` Response: ${bodyPreview}${req.responseBody.length > 100 ?
|
|
160
|
+
output += ` Response: ${bodyPreview}${req.responseBody.length > 100 ? "..." : ""}\n`;
|
|
163
161
|
}
|
|
164
162
|
});
|
|
165
163
|
return output.trim();
|
|
@@ -172,7 +170,7 @@ class OutputFormatter {
|
|
|
172
170
|
}
|
|
173
171
|
if (obj.requestId && obj.url && obj.method) {
|
|
174
172
|
const timestamp = new Date(obj.timestamp).toISOString();
|
|
175
|
-
const status = obj.status ? ` [${obj.status}]` :
|
|
173
|
+
const status = obj.status ? ` [${obj.status}]` : " [pending]";
|
|
176
174
|
const methodIcon = this.getHttpMethodIcon(obj.method);
|
|
177
175
|
return `${timestamp} ${methodIcon} ${obj.method} ${obj.url}${status}`;
|
|
178
176
|
}
|
|
@@ -181,21 +179,21 @@ class OutputFormatter {
|
|
|
181
179
|
}
|
|
182
180
|
else {
|
|
183
181
|
const keys = Object.keys(obj);
|
|
184
|
-
return `Object with ${keys.length} properties: ${keys.slice(0, 3).join(
|
|
182
|
+
return `Object with ${keys.length} properties: ${keys.slice(0, 3).join(", ")}${keys.length > 3 ? "..." : ""}`;
|
|
185
183
|
}
|
|
186
184
|
}
|
|
187
185
|
return String(data);
|
|
188
186
|
}
|
|
189
187
|
formatQuietOutput(result) {
|
|
190
188
|
if (result.data === undefined || result.data === null) {
|
|
191
|
-
return
|
|
189
|
+
return "";
|
|
192
190
|
}
|
|
193
|
-
if (typeof result.data ===
|
|
191
|
+
if (typeof result.data === "string") {
|
|
194
192
|
return result.data;
|
|
195
193
|
}
|
|
196
|
-
if (typeof result.data ===
|
|
194
|
+
if (typeof result.data === "object" && result.data !== null) {
|
|
197
195
|
const obj = result.data;
|
|
198
|
-
if (obj.snapshot && typeof obj.snapshot ===
|
|
196
|
+
if (obj.snapshot && typeof obj.snapshot === "string") {
|
|
199
197
|
return obj.snapshot;
|
|
200
198
|
}
|
|
201
199
|
if (Array.isArray(obj)) {
|
|
@@ -208,19 +206,19 @@ class OutputFormatter {
|
|
|
208
206
|
return `${obj.requests.length}`;
|
|
209
207
|
}
|
|
210
208
|
}
|
|
211
|
-
return
|
|
209
|
+
return "";
|
|
212
210
|
}
|
|
213
211
|
formatErrorOutput(result, options) {
|
|
214
|
-
if (options.format ===
|
|
212
|
+
if (options.format === "json") {
|
|
215
213
|
const errorOutput = {
|
|
216
214
|
success: false,
|
|
217
215
|
error: result.error,
|
|
218
|
-
exitCode: result.exitCode || 1
|
|
216
|
+
exitCode: result.exitCode || 1,
|
|
219
217
|
};
|
|
220
218
|
if (options.mode.debug && result.timing) {
|
|
221
219
|
errorOutput.timing = {
|
|
222
220
|
operation: result.timing.operationName,
|
|
223
|
-
duration: `${result.timing.duration}ms
|
|
221
|
+
duration: `${result.timing.duration}ms`,
|
|
224
222
|
};
|
|
225
223
|
}
|
|
226
224
|
return JSON.stringify(errorOutput, null, 2);
|
|
@@ -248,13 +246,15 @@ class OutputFormatter {
|
|
|
248
246
|
timing: result.timing,
|
|
249
247
|
metadata: result.metadata,
|
|
250
248
|
dataSource: result.dataSource,
|
|
251
|
-
hasHistoricalData: result.hasHistoricalData
|
|
249
|
+
hasHistoricalData: result.hasHistoricalData,
|
|
252
250
|
};
|
|
253
251
|
for (const [key, value] of Object.entries(variables)) {
|
|
254
252
|
const placeholder = `{{${key}}}`;
|
|
255
253
|
if (output.includes(placeholder)) {
|
|
256
|
-
const replacement = typeof value ===
|
|
257
|
-
|
|
254
|
+
const replacement = typeof value === "object"
|
|
255
|
+
? JSON.stringify(value)
|
|
256
|
+
: String(value || "");
|
|
257
|
+
output = output.replace(new RegExp(placeholder, "g"), replacement);
|
|
258
258
|
}
|
|
259
259
|
}
|
|
260
260
|
return output;
|
|
@@ -270,58 +270,60 @@ class OutputFormatter {
|
|
|
270
270
|
}
|
|
271
271
|
registerDefaultTemplates() {
|
|
272
272
|
this.registerTemplate({
|
|
273
|
-
name:
|
|
274
|
-
description:
|
|
275
|
-
template:
|
|
276
|
-
variables: [
|
|
273
|
+
name: "minimal",
|
|
274
|
+
description: "Minimal output with just the result",
|
|
275
|
+
template: "{{data}}",
|
|
276
|
+
variables: ["data"],
|
|
277
277
|
});
|
|
278
278
|
this.registerTemplate({
|
|
279
|
-
name:
|
|
280
|
-
description:
|
|
281
|
-
template:
|
|
282
|
-
variables: [
|
|
279
|
+
name: "status",
|
|
280
|
+
description: "Status-focused output",
|
|
281
|
+
template: "Status: {{success}}\n{{#if error}}Error: {{error}}{{/if}}",
|
|
282
|
+
variables: ["success", "error"],
|
|
283
283
|
});
|
|
284
284
|
this.registerTemplate({
|
|
285
|
-
name:
|
|
286
|
-
description:
|
|
287
|
-
template:
|
|
288
|
-
variables: [
|
|
285
|
+
name: "detailed",
|
|
286
|
+
description: "Detailed output with metadata and timing",
|
|
287
|
+
template: "Result: {{success}}\nData: {{data}}\nTiming: {{timing.duration}}ms\nCommand: {{metadata.command}}",
|
|
288
|
+
variables: ["success", "data", "timing", "metadata"],
|
|
289
289
|
});
|
|
290
290
|
}
|
|
291
291
|
getConsoleTypeIcon(type) {
|
|
292
292
|
const icons = {
|
|
293
|
-
log:
|
|
294
|
-
info:
|
|
295
|
-
warn:
|
|
296
|
-
error:
|
|
297
|
-
debug:
|
|
293
|
+
log: "đ",
|
|
294
|
+
info: "âšī¸",
|
|
295
|
+
warn: "â ī¸",
|
|
296
|
+
error: "â",
|
|
297
|
+
debug: "đ",
|
|
298
298
|
};
|
|
299
|
-
return icons[type] ||
|
|
299
|
+
return icons[type] || "đ";
|
|
300
300
|
}
|
|
301
301
|
getHttpMethodIcon(method) {
|
|
302
302
|
const icons = {
|
|
303
|
-
GET:
|
|
304
|
-
POST:
|
|
305
|
-
PUT:
|
|
306
|
-
DELETE:
|
|
307
|
-
PATCH:
|
|
308
|
-
HEAD:
|
|
309
|
-
OPTIONS:
|
|
303
|
+
GET: "đĨ",
|
|
304
|
+
POST: "đ¤",
|
|
305
|
+
PUT: "đ",
|
|
306
|
+
DELETE: "đī¸",
|
|
307
|
+
PATCH: "đ§",
|
|
308
|
+
HEAD: "đī¸",
|
|
309
|
+
OPTIONS: "âī¸",
|
|
310
310
|
};
|
|
311
|
-
return icons[method.toUpperCase()] ||
|
|
311
|
+
return icons[method.toUpperCase()] || "đ";
|
|
312
312
|
}
|
|
313
313
|
objectToYaml(obj, indent = 0) {
|
|
314
|
-
const spaces =
|
|
314
|
+
const spaces = " ".repeat(indent);
|
|
315
315
|
const lines = [];
|
|
316
316
|
for (const [key, value] of Object.entries(obj)) {
|
|
317
|
-
if (typeof value ===
|
|
317
|
+
if (typeof value === "object" &&
|
|
318
|
+
value !== null &&
|
|
319
|
+
!Array.isArray(value)) {
|
|
318
320
|
lines.push(`${spaces}${key}:`);
|
|
319
321
|
lines.push(this.objectToYaml(value, indent + 1));
|
|
320
322
|
}
|
|
321
323
|
else if (Array.isArray(value)) {
|
|
322
324
|
lines.push(`${spaces}${key}:`);
|
|
323
325
|
value.forEach((item) => {
|
|
324
|
-
if (typeof item ===
|
|
326
|
+
if (typeof item === "object" && item !== null) {
|
|
325
327
|
lines.push(`${spaces} - `);
|
|
326
328
|
lines.push(this.objectToYaml(item, indent + 2));
|
|
327
329
|
}
|
|
@@ -334,7 +336,7 @@ class OutputFormatter {
|
|
|
334
336
|
lines.push(`${spaces}${key}: ${JSON.stringify(value)}`);
|
|
335
337
|
}
|
|
336
338
|
}
|
|
337
|
-
return lines.join(
|
|
339
|
+
return lines.join("\n");
|
|
338
340
|
}
|
|
339
341
|
}
|
|
340
342
|
exports.OutputFormatter = OutputFormatter;
|
|
@@ -344,10 +346,10 @@ function createOutputOptions(config, includeMetadata = false, includeTiming = fa
|
|
|
344
346
|
mode: {
|
|
345
347
|
quiet: config.quiet,
|
|
346
348
|
verbose: config.verbose,
|
|
347
|
-
debug: config.debug
|
|
349
|
+
debug: config.debug,
|
|
348
350
|
},
|
|
349
351
|
includeMetadata,
|
|
350
|
-
includeTiming
|
|
352
|
+
includeTiming,
|
|
351
353
|
};
|
|
352
354
|
}
|
|
353
355
|
function createTimingInfo(operationName, startTime, endTime) {
|
|
@@ -355,13 +357,13 @@ function createTimingInfo(operationName, startTime, endTime) {
|
|
|
355
357
|
operationName,
|
|
356
358
|
startTime,
|
|
357
359
|
endTime,
|
|
358
|
-
duration: endTime - startTime
|
|
360
|
+
duration: endTime - startTime,
|
|
359
361
|
};
|
|
360
362
|
}
|
|
361
363
|
function enhanceCommandResult(result, timing, metadata) {
|
|
362
364
|
return {
|
|
363
365
|
...result,
|
|
364
366
|
timing,
|
|
365
|
-
metadata
|
|
367
|
+
metadata,
|
|
366
368
|
};
|
|
367
369
|
}
|