@zrhsh/wukong-cli 0.4.25 → 0.4.27
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 +1 -1
- package/dist/cli.js +178 -116
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
package/dist/cli.js
CHANGED
|
@@ -2463,6 +2463,48 @@ import ora4 from "ora";
|
|
|
2463
2463
|
import chalk6 from "chalk";
|
|
2464
2464
|
init_oceanet();
|
|
2465
2465
|
init_config_file_error();
|
|
2466
|
+
|
|
2467
|
+
// src/core/http/request-body.ts
|
|
2468
|
+
init_esm_shims();
|
|
2469
|
+
function parseRequestBody(raw) {
|
|
2470
|
+
if (!raw.trim()) {
|
|
2471
|
+
return {};
|
|
2472
|
+
}
|
|
2473
|
+
try {
|
|
2474
|
+
return { data: JSON.parse(raw) };
|
|
2475
|
+
} catch (error2) {
|
|
2476
|
+
return { error: error2 instanceof Error ? error2.message : String(error2) };
|
|
2477
|
+
}
|
|
2478
|
+
}
|
|
2479
|
+
function detectPageQueryEnvelope(body) {
|
|
2480
|
+
if (!isPlainObject(body)) {
|
|
2481
|
+
return null;
|
|
2482
|
+
}
|
|
2483
|
+
const hasPagingField = typeof body.current === "number" || typeof body.size === "number";
|
|
2484
|
+
if (!hasPagingField) {
|
|
2485
|
+
return null;
|
|
2486
|
+
}
|
|
2487
|
+
const envelope = body.param;
|
|
2488
|
+
if (isPlainObject(envelope) && isPlainObject(envelope.param)) {
|
|
2489
|
+
return null;
|
|
2490
|
+
}
|
|
2491
|
+
return {
|
|
2492
|
+
code: "PAGEQUERY_ENVELOPE",
|
|
2493
|
+
message: 'current/size \u51FA\u73B0\u5728\u8BF7\u6C42\u4F53\u9876\u5C42\uFF0C\u4F46 param \u5185\u6CA1\u6709\u5D4C\u5957\u7684\u4E1A\u52A1\u6761\u4EF6\u3002\u672C\u6846\u67B6\u7684\u5206\u9875\u67E5\u8BE2\u63A5\u53E3\u9700\u8981\u53CC\u5C42 param\uFF1A{"param":{"current":1,"size":20,"param":{...\u4E1A\u52A1\u6761\u4EF6}}}\u3002\u5199\u6210\u5355\u5C42\u65F6\u63A5\u53E3\u4ECD\u8FD4\u56DE 200\uFF0C\u4F46\u67E5\u8BE2\u6761\u4EF6\u4F1A\u88AB\u9759\u9ED8\u4E22\u5F03\u5E76\u8FD4\u56DE\u5168\u91CF\u6570\u636E\u3002'
|
|
2494
|
+
};
|
|
2495
|
+
}
|
|
2496
|
+
|
|
2497
|
+
// src/commands/http.ts
|
|
2498
|
+
function fail(message, jsonMode, errorCode = null) {
|
|
2499
|
+
if (jsonMode) {
|
|
2500
|
+
process.stderr.write(
|
|
2501
|
+
JSON.stringify({ error: { code: errorCode, message } }, null, 2) + "\n"
|
|
2502
|
+
);
|
|
2503
|
+
} else {
|
|
2504
|
+
console.error(chalk6.red(message));
|
|
2505
|
+
}
|
|
2506
|
+
process.exit(1);
|
|
2507
|
+
}
|
|
2466
2508
|
function fixGitBashPath(url) {
|
|
2467
2509
|
if (url.includes(":") && !url.startsWith("http")) {
|
|
2468
2510
|
const oceanetIndex = url.indexOf("/oceanet-");
|
|
@@ -2503,138 +2545,158 @@ function parseParams(params) {
|
|
|
2503
2545
|
}
|
|
2504
2546
|
return `?${searchParams.toString()}`;
|
|
2505
2547
|
}
|
|
2548
|
+
function warnOnPageQueryEnvelope(context) {
|
|
2549
|
+
if (!["POST", "PUT", "PATCH"].includes(context.method.toUpperCase())) {
|
|
2550
|
+
return;
|
|
2551
|
+
}
|
|
2552
|
+
const issue = detectPageQueryEnvelope(context.data);
|
|
2553
|
+
if (!issue) {
|
|
2554
|
+
return;
|
|
2555
|
+
}
|
|
2556
|
+
if (context.jsonMode) {
|
|
2557
|
+
process.stderr.write(JSON.stringify({ warning: issue }, null, 2) + "\n");
|
|
2558
|
+
return;
|
|
2559
|
+
}
|
|
2560
|
+
console.error("");
|
|
2561
|
+
console.error(chalk6.yellow(`[WARNING] ${issue.message}`));
|
|
2562
|
+
console.error("");
|
|
2563
|
+
}
|
|
2564
|
+
async function sendWithYstToken(context) {
|
|
2565
|
+
const ystAccessToken = await getYstAccessToken();
|
|
2566
|
+
if (!ystAccessToken) {
|
|
2567
|
+
fail("YST token not found. Please re-login: wukong-cli auth login", context.jsonMode);
|
|
2568
|
+
}
|
|
2569
|
+
context.spinner.text = `${context.method} ${chalk6.cyan(context.fullUrl)} (using YST token)`;
|
|
2570
|
+
const fetchOptions = {
|
|
2571
|
+
method: context.method.toUpperCase(),
|
|
2572
|
+
headers: {
|
|
2573
|
+
"Authorization": `Bearer ${ystAccessToken}`,
|
|
2574
|
+
"Content-Type": "application/json",
|
|
2575
|
+
...context.headers
|
|
2576
|
+
}
|
|
2577
|
+
};
|
|
2578
|
+
if (context.data !== void 0) {
|
|
2579
|
+
fetchOptions.body = JSON.stringify(context.data);
|
|
2580
|
+
}
|
|
2581
|
+
const finalUrl = context.fullUrl + parseParams(context.params);
|
|
2582
|
+
const startTime = Date.now();
|
|
2583
|
+
let response;
|
|
2584
|
+
try {
|
|
2585
|
+
response = await fetch(finalUrl, fetchOptions);
|
|
2586
|
+
} catch (fetchError) {
|
|
2587
|
+
const detail = JSON.stringify(fetchError.cause) || fetchError.message;
|
|
2588
|
+
throw new Error(`Request failed: ${finalUrl}
|
|
2589
|
+
${detail}`);
|
|
2590
|
+
}
|
|
2591
|
+
const duration = Date.now() - startTime;
|
|
2592
|
+
if (!response.ok) {
|
|
2593
|
+
const errText = await response.text().catch(() => "");
|
|
2594
|
+
throw new ApiError(
|
|
2595
|
+
response.status,
|
|
2596
|
+
`HTTP ${response.status}: ${errText.substring(0, 200)}`
|
|
2597
|
+
);
|
|
2598
|
+
}
|
|
2599
|
+
const body = await response.json();
|
|
2600
|
+
getApiErrorHandler().handle(body);
|
|
2601
|
+
return { data: unwrapResponse(body), duration, tokenKind: "yst" };
|
|
2602
|
+
}
|
|
2603
|
+
async function sendWithMainToken(context) {
|
|
2604
|
+
const client = getClient();
|
|
2605
|
+
context.spinner.text = `${context.method} ${chalk6.cyan(context.fullUrl)}`;
|
|
2606
|
+
const startTime = Date.now();
|
|
2607
|
+
let payload;
|
|
2608
|
+
switch (context.method.toUpperCase()) {
|
|
2609
|
+
case "GET":
|
|
2610
|
+
payload = await client.get(context.fullUrl + parseParams(context.params));
|
|
2611
|
+
break;
|
|
2612
|
+
case "POST":
|
|
2613
|
+
payload = await client.post(context.fullUrl, context.data, context.headers);
|
|
2614
|
+
break;
|
|
2615
|
+
case "PUT":
|
|
2616
|
+
payload = await client.put(context.fullUrl, context.data, context.headers);
|
|
2617
|
+
break;
|
|
2618
|
+
case "DELETE":
|
|
2619
|
+
payload = await client.delete(context.fullUrl);
|
|
2620
|
+
break;
|
|
2621
|
+
case "PATCH":
|
|
2622
|
+
payload = await client.patch(context.fullUrl, context.data, context.headers);
|
|
2623
|
+
break;
|
|
2624
|
+
default:
|
|
2625
|
+
throw new Error(`Unsupported method: ${context.method}`);
|
|
2626
|
+
}
|
|
2627
|
+
return { data: payload, duration: Date.now() - startTime, tokenKind: "main" };
|
|
2628
|
+
}
|
|
2629
|
+
function renderResult(result, jsonMode) {
|
|
2630
|
+
if (jsonMode) {
|
|
2631
|
+
process.stdout.write(JSON.stringify(result.data, null, 2) + "\n");
|
|
2632
|
+
return;
|
|
2633
|
+
}
|
|
2634
|
+
console.log("");
|
|
2635
|
+
console.log(chalk6.dim("Token:"), result.tokenKind === "yst" ? "YST" : "main");
|
|
2636
|
+
console.log(chalk6.dim("Duration:"), `${result.duration}ms`);
|
|
2637
|
+
console.log("");
|
|
2638
|
+
console.log(chalk6.dim("Response:"));
|
|
2639
|
+
console.log(JSON.stringify(result.data, null, 2));
|
|
2640
|
+
}
|
|
2641
|
+
function handleError(error2, jsonMode) {
|
|
2642
|
+
if (error2 instanceof ConfigFileError) {
|
|
2643
|
+
return fail(`Configuration Error
|
|
2644
|
+
${error2.toUserMessage()}`, jsonMode);
|
|
2645
|
+
}
|
|
2646
|
+
if (error2 instanceof ApiError) {
|
|
2647
|
+
return fail(`API Error (code: ${error2.code}): ${error2.message}`, jsonMode, error2.code);
|
|
2648
|
+
}
|
|
2649
|
+
return fail(error2 instanceof Error ? error2.message : String(error2), jsonMode);
|
|
2650
|
+
}
|
|
2506
2651
|
async function executeRequest(method, url, options) {
|
|
2507
|
-
const
|
|
2652
|
+
const jsonMode = options.json === true;
|
|
2653
|
+
const spinner = ora4({ text: "Sending request...", isSilent: jsonMode }).start();
|
|
2508
2654
|
try {
|
|
2509
2655
|
const accessToken = await getAccessToken();
|
|
2510
2656
|
if (!accessToken) {
|
|
2511
2657
|
spinner.fail("Not authenticated");
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
}
|
|
2535
|
-
};
|
|
2536
|
-
if (requestData) {
|
|
2537
|
-
fetchOptions.body = JSON.stringify(requestData);
|
|
2538
|
-
}
|
|
2539
|
-
const finalUrl = fullUrl + parseParams(options.params);
|
|
2540
|
-
let response;
|
|
2541
|
-
try {
|
|
2542
|
-
response = await fetch(finalUrl, fetchOptions);
|
|
2543
|
-
} catch (fetchError) {
|
|
2544
|
-
spinner.fail(`Request failed`);
|
|
2545
|
-
console.error(chalk6.red(`URL: ${finalUrl}`));
|
|
2546
|
-
console.error(chalk6.red(`Error: ${JSON.stringify(fetchError.cause) || fetchError.message}`));
|
|
2547
|
-
process.exit(1);
|
|
2548
|
-
}
|
|
2549
|
-
const duration2 = Date.now() - startTime2;
|
|
2550
|
-
if (!response.ok) {
|
|
2551
|
-
const errText = await response.text().catch(() => "");
|
|
2552
|
-
spinner.fail(`Request failed (${response.status})`);
|
|
2553
|
-
console.error(chalk6.red(`HTTP ${response.status}: ${errText.substring(0, 200)}`));
|
|
2554
|
-
process.exit(1);
|
|
2555
|
-
}
|
|
2556
|
-
const body = await response.json();
|
|
2557
|
-
getApiErrorHandler().handle(body);
|
|
2558
|
-
const data2 = unwrapResponse(body);
|
|
2559
|
-
spinner.succeed("Response received");
|
|
2560
|
-
console.log("");
|
|
2561
|
-
console.log(chalk6.dim("Status:"), `${response.status} ${response.statusText}`);
|
|
2562
|
-
console.log(chalk6.dim("Token:"), "YST");
|
|
2563
|
-
console.log(chalk6.dim("Duration:"), `${duration2}ms`);
|
|
2564
|
-
console.log("");
|
|
2565
|
-
console.log(chalk6.dim("Response:"));
|
|
2566
|
-
console.log(JSON.stringify(data2, null, 2));
|
|
2567
|
-
return;
|
|
2568
|
-
}
|
|
2569
|
-
const client = getClient();
|
|
2570
|
-
spinner.text = `${method} ${chalk6.cyan(fullUrl)}`;
|
|
2571
|
-
const startTime = Date.now();
|
|
2572
|
-
let data;
|
|
2573
|
-
switch (method.toUpperCase()) {
|
|
2574
|
-
case "GET":
|
|
2575
|
-
const getUrl = fullUrl + parseParams(options.params);
|
|
2576
|
-
data = await client.get(getUrl);
|
|
2577
|
-
break;
|
|
2578
|
-
case "POST":
|
|
2579
|
-
data = await client.post(fullUrl, requestData, customHeaders);
|
|
2580
|
-
break;
|
|
2581
|
-
case "PUT":
|
|
2582
|
-
data = await client.put(fullUrl, requestData, customHeaders);
|
|
2583
|
-
break;
|
|
2584
|
-
case "DELETE":
|
|
2585
|
-
data = await client.delete(fullUrl);
|
|
2586
|
-
break;
|
|
2587
|
-
case "PATCH":
|
|
2588
|
-
data = await client.patch(fullUrl, requestData, customHeaders);
|
|
2589
|
-
break;
|
|
2590
|
-
default:
|
|
2591
|
-
throw new Error(`Unsupported method: ${method}`);
|
|
2592
|
-
}
|
|
2593
|
-
const duration = Date.now() - startTime;
|
|
2594
|
-
spinner.succeed("Response received");
|
|
2595
|
-
console.log("");
|
|
2596
|
-
console.log(chalk6.dim("Status:"), "200 OK");
|
|
2597
|
-
console.log("");
|
|
2598
|
-
console.log(chalk6.dim("Response:"));
|
|
2599
|
-
console.log(JSON.stringify(data, null, 2));
|
|
2658
|
+
fail("Not authenticated. Please run: wukong-cli auth login", jsonMode);
|
|
2659
|
+
}
|
|
2660
|
+
const parsed = parseRequestBody(options.data ?? "");
|
|
2661
|
+
if (parsed.error) {
|
|
2662
|
+
spinner.fail("Invalid request body");
|
|
2663
|
+
const received = (options.data ?? "").replace(/\s+/g, " ").trim();
|
|
2664
|
+
fail(`Invalid JSON in -d: ${parsed.error}
|
|
2665
|
+
Received: ${received}`, jsonMode);
|
|
2666
|
+
}
|
|
2667
|
+
const context = {
|
|
2668
|
+
method,
|
|
2669
|
+
fullUrl: buildUrl2(url, options.baseUrl),
|
|
2670
|
+
data: parsed.data,
|
|
2671
|
+
headers: parseHeaders(options.headers),
|
|
2672
|
+
params: options.params,
|
|
2673
|
+
jsonMode,
|
|
2674
|
+
spinner
|
|
2675
|
+
};
|
|
2676
|
+
warnOnPageQueryEnvelope(context);
|
|
2677
|
+
const result = context.fullUrl.includes("/yst-") ? await sendWithYstToken(context) : await sendWithMainToken(context);
|
|
2678
|
+
spinner.succeed(`Response received (${result.duration}ms)`);
|
|
2679
|
+
renderResult(result, jsonMode);
|
|
2600
2680
|
} catch (error2) {
|
|
2601
2681
|
spinner.fail("Request failed");
|
|
2602
|
-
|
|
2603
|
-
console.log("");
|
|
2604
|
-
console.log(chalk6.red(`[ERROR] Configuration Error`));
|
|
2605
|
-
console.log("");
|
|
2606
|
-
console.log(chalk6.red(error2.toUserMessage()));
|
|
2607
|
-
console.log("");
|
|
2608
|
-
process.exit(1);
|
|
2609
|
-
}
|
|
2610
|
-
if (error2 instanceof ApiError) {
|
|
2611
|
-
console.log("");
|
|
2612
|
-
console.log(chalk6.red(`API Error (code: ${error2.code})`));
|
|
2613
|
-
console.log(chalk6.red(error2.message));
|
|
2614
|
-
console.log("");
|
|
2615
|
-
process.exit(1);
|
|
2616
|
-
}
|
|
2617
|
-
if (error2 instanceof Error) {
|
|
2618
|
-
console.error(chalk6.red(error2.message));
|
|
2619
|
-
}
|
|
2620
|
-
process.exit(1);
|
|
2682
|
+
handleError(error2, jsonMode);
|
|
2621
2683
|
}
|
|
2622
2684
|
}
|
|
2623
2685
|
var httpCommand = new Command2("http");
|
|
2624
2686
|
httpCommand.description("HTTP commands for making API requests");
|
|
2625
|
-
httpCommand.command("get <url>").description("Send GET request (uses configured base URL or override with -b)").option("-b, --base-url <url>", "Override base URL").option("-H, --header <key:value>", "Custom header (can be used multiple times)", []).action(async (url, options) => {
|
|
2687
|
+
httpCommand.command("get <url>").description("Send GET request (uses configured base URL or override with -b)").option("-b, --base-url <url>", "Override base URL").option("-H, --header <key:value>", "Custom header (can be used multiple times)", []).option("--json", "Print only the response body as JSON").action(async (url, options) => {
|
|
2626
2688
|
await executeRequest("GET", url, options);
|
|
2627
2689
|
});
|
|
2628
|
-
httpCommand.command("post <url>").description("Send POST request with JSON data").option("-b, --base-url <url>", "Override base URL").option("-H, --header <key:value>", "Custom header (can be used multiple times)", []).option("-d, --data <json>", "Request body as JSON string").action(async (url, options) => {
|
|
2690
|
+
httpCommand.command("post <url>").description("Send POST request with JSON data").option("-b, --base-url <url>", "Override base URL").option("-H, --header <key:value>", "Custom header (can be used multiple times)", []).option("-d, --data <json>", "Request body as JSON string").option("--json", "Print only the response body as JSON").action(async (url, options) => {
|
|
2629
2691
|
await executeRequest("POST", url, options);
|
|
2630
2692
|
});
|
|
2631
|
-
httpCommand.command("put <url>").description("Send PUT request with JSON data").option("-b, --base-url <url>", "Override base URL").option("-H, --header <key:value>", "Custom header (can be used multiple times)", []).option("-d, --data <json>", "Request body as JSON string").action(async (url, options) => {
|
|
2693
|
+
httpCommand.command("put <url>").description("Send PUT request with JSON data").option("-b, --base-url <url>", "Override base URL").option("-H, --header <key:value>", "Custom header (can be used multiple times)", []).option("-d, --data <json>", "Request body as JSON string").option("--json", "Print only the response body as JSON").action(async (url, options) => {
|
|
2632
2694
|
await executeRequest("PUT", url, options);
|
|
2633
2695
|
});
|
|
2634
|
-
httpCommand.command("patch <url>").description("Send PATCH request with JSON data").option("-b, --base-url <url>", "Override base URL").option("-H, --header <key:value>", "Custom header (can be used multiple times)", []).option("-d, --data <json>", "Request body as JSON string").action(async (url, options) => {
|
|
2696
|
+
httpCommand.command("patch <url>").description("Send PATCH request with JSON data").option("-b, --base-url <url>", "Override base URL").option("-H, --header <key:value>", "Custom header (can be used multiple times)", []).option("-d, --data <json>", "Request body as JSON string").option("--json", "Print only the response body as JSON").action(async (url, options) => {
|
|
2635
2697
|
await executeRequest("PATCH", url, options);
|
|
2636
2698
|
});
|
|
2637
|
-
httpCommand.command("delete <url>").description("Send DELETE request").option("-b, --base-url <url>", "Override base URL").option("-H, --header <key:value>", "Custom header (can be used multiple times)", []).action(async (url, options) => {
|
|
2699
|
+
httpCommand.command("delete <url>").description("Send DELETE request").option("-b, --base-url <url>", "Override base URL").option("-H, --header <key:value>", "Custom header (can be used multiple times)", []).option("--json", "Print only the response body as JSON").action(async (url, options) => {
|
|
2638
2700
|
await executeRequest("DELETE", url, options);
|
|
2639
2701
|
});
|
|
2640
2702
|
|
|
@@ -3120,7 +3182,7 @@ async function runUpdateCommand({
|
|
|
3120
3182
|
}
|
|
3121
3183
|
var updateCommand = new Command5("update").description("Update wukong-cli to the latest npm version").action(async () => {
|
|
3122
3184
|
const exitCode = await runUpdateCommand({
|
|
3123
|
-
currentVersion: "0.4.
|
|
3185
|
+
currentVersion: "0.4.27",
|
|
3124
3186
|
versionProvider: new NpmVersionProvider(
|
|
3125
3187
|
"@zrhsh/wukong-cli",
|
|
3126
3188
|
"https://registry.npmjs.org"
|
|
@@ -3135,7 +3197,7 @@ var updateCommand = new Command5("update").description("Update wukong-cli to the
|
|
|
3135
3197
|
|
|
3136
3198
|
// src/cli.ts
|
|
3137
3199
|
var program = new Command6();
|
|
3138
|
-
program.name("wukong-cli").description("Wukong CLI - TypeScript implementation").version("0.4.
|
|
3200
|
+
program.name("wukong-cli").description("Wukong CLI - TypeScript implementation").version("0.4.27").option("--debug", "Enable debug mode (show HTTP requests)").hook("preAction", (thisCommand) => {
|
|
3139
3201
|
const options = thisCommand.opts();
|
|
3140
3202
|
if (options.debug === true) {
|
|
3141
3203
|
setDebugMode(true, true);
|
|
@@ -3154,7 +3216,7 @@ if (process.argv.length === 2) {
|
|
|
3154
3216
|
program.parse();
|
|
3155
3217
|
setImmediate(() => {
|
|
3156
3218
|
try {
|
|
3157
|
-
const versionChecker = getVersionChecker("0.4.
|
|
3219
|
+
const versionChecker = getVersionChecker("0.4.27");
|
|
3158
3220
|
const notifier = new ConsoleNotifier();
|
|
3159
3221
|
versionChecker.checkInBackground(notifier).catch(() => {
|
|
3160
3222
|
});
|