| #!/usr/bin/env node
|
|
|
| |
| |
| |
| |
| |
|
|
|
|
| import fs from "fs";
|
| import path from "path";
|
|
|
| const args = process.argv.slice(2);
|
|
|
| if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
|
| console.log("");
|
| console.log("π§ͺ Test From File - Send converted request to provider");
|
| console.log("");
|
| console.log("Usage:");
|
| console.log(" node testFromFile.js <file-path>");
|
| console.log("");
|
| console.log("Examples:");
|
| console.log(" node testFromFile.js data/claude-to-kiro/3_converted_request.json");
|
| console.log(" node testFromFile.js ../logs/openai_codex_xxx/3_converted_request.json");
|
| console.log("");
|
| console.log("File format:");
|
| console.log(" {");
|
| console.log(' "url": "https://api.provider.com/...",');
|
| console.log(' "headers": { ... },');
|
| console.log(' "body": { ... }');
|
| console.log(" }");
|
| console.log("");
|
| process.exit(0);
|
| }
|
|
|
| const filePath = args[0];
|
| const fullPath = path.isAbsolute(filePath) ? filePath : path.join(process.cwd(), filePath);
|
|
|
| if (!fs.existsSync(fullPath)) {
|
| console.error(`β File not found: ${fullPath}`);
|
| process.exit(1);
|
| }
|
|
|
|
|
| let data;
|
| try {
|
| data = JSON.parse(fs.readFileSync(fullPath, "utf8"));
|
| } catch (err: any) {
|
| console.error(`β Failed to parse JSON: ${err.message}`);
|
| process.exit(1);
|
| }
|
|
|
| const { url, headers, body } = data;
|
|
|
| if (!url || !headers || !body) {
|
| console.error("β Invalid file format. Expected: { url, headers, body }");
|
| process.exit(1);
|
| }
|
|
|
|
|
| console.log("\nπ Sending Request from File\n");
|
| console.log(`π File: ${filePath}`);
|
| console.log(`π URL: ${url}`);
|
| console.log(`π Headers:`);
|
| Object.entries(headers).forEach(([k, v]) => {
|
| if (
|
| k.toLowerCase().includes("auth") ||
|
| k.toLowerCase().includes("key") ||
|
| k.toLowerCase().includes("bearer")
|
| ) {
|
| const str = String(v);
|
| if (str.length > 20) {
|
| console.log(` ${k}: ${str.slice(0, 20)}...`);
|
| } else {
|
| console.log(` ${k}: ${str}`);
|
| }
|
| } else {
|
| console.log(` ${k}: ${v}`);
|
| }
|
| });
|
|
|
| console.log(`\nπ Request Body:`);
|
| console.log(` Model: ${body.model || "N/A"}`);
|
| console.log(` Messages: ${body.messages?.length || 0}`);
|
| console.log(` Tools: ${body.tools?.length || 0}`);
|
| console.log(` Stream: ${body.stream || false}`);
|
|
|
|
|
| (async () => {
|
| try {
|
| console.log("\nπ Sending request...");
|
|
|
| const response = await fetch(url, {
|
| method: "POST",
|
| headers,
|
| body: JSON.stringify(body),
|
| });
|
|
|
| console.log(`\nπ₯ Response: ${response.status} ${response.statusText}`);
|
|
|
| if (!response.ok) {
|
| const errorText = await response.text();
|
| console.error(`\nβ Error response:\n${errorText}`);
|
| process.exit(1);
|
| }
|
|
|
| const isStreaming =
|
| body.stream || response.headers.get("content-type")?.includes("text/event-stream");
|
|
|
| if (isStreaming) {
|
| console.log("\nπ‘ Streaming response...\n");
|
|
|
| const reader = response.body?.getReader();
|
| if (!reader) throw new Error("No response body");
|
| const decoder = new TextDecoder();
|
| let chunkCount = 0;
|
| let buffer = "";
|
|
|
| while (true) {
|
| const { done, value } = await reader.read();
|
| if (done) break;
|
|
|
| buffer += decoder.decode(value, { stream: true });
|
| const lines = buffer.split("\n");
|
| buffer = lines.pop() || "";
|
|
|
| for (const line of lines) {
|
| if (line.trim()) {
|
| process.stdout.write(line + "\n");
|
| chunkCount++;
|
| }
|
| }
|
| }
|
|
|
|
|
| if (buffer.trim()) {
|
| process.stdout.write(buffer + "\n");
|
| }
|
|
|
| console.log(`\n\nβ
Received ${chunkCount} chunks`);
|
| } else {
|
| const responseData = (await response.json()) as any;
|
| console.log("\nπ¦ Response:");
|
| console.log(JSON.stringify(responseData, null, 2));
|
| }
|
| } catch (err: any) {
|
| console.error("\nβ Request failed:", err.message);
|
| if (process.env.DEBUG) {
|
| console.error(err.stack);
|
| }
|
| process.exit(1);
|
| }
|
| })();
|
|
|