From 4e498d3d1c7153f6815864085a59fd6f902d00af Mon Sep 17 00:00:00 2001 From: seekskyworld Date: Tue, 13 Jan 2026 00:38:56 +0800 Subject: [PATCH] fix: handle empty JSON responses in sdk client --- packages/sdk/js/script/build.ts | 49 +++++++++++++++++++ packages/sdk/js/src/gen/client/client.gen.ts | 10 +++- .../sdk/js/src/v2/gen/client/client.gen.ts | 10 +++- 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/packages/sdk/js/script/build.ts b/packages/sdk/js/script/build.ts index 7568c54b0f2..f7ba5b917a7 100755 --- a/packages/sdk/js/script/build.ts +++ b/packages/sdk/js/script/build.ts @@ -5,9 +5,55 @@ process.chdir(dir) import { $ } from "bun" import path from "path" +import fs from "fs/promises" import { createClient } from "@hey-api/openapi-ts" +const patchClient = async (filepath: string, options?: { required?: boolean }) => { + const required = options?.required ?? true + const content = await fs.readFile(filepath, "utf8").catch(() => "") + if (!content) { + if (required) throw new Error(`patch target missing: ${filepath}`) + return + } + + const oldLines = [ + ' case "formData":', + ' case "json":', + ' case "text":', + " data = await response[parseAs]()", + " break", + ] + const newLines = [ + ' case "formData":', + ' case "text":', + " data = await response[parseAs]()", + " break", + ' case "json": {', + " const text = await response.text()", + " if (!text.trim()) {", + " data = {}", + " } else {", + " data = JSON.parse(text)", + " }", + " break", + " }", + ] + + const newline = content.includes("\r\n") ? "\r\n" : "\n" + const oldBlock = oldLines.join(newline) + newline + const newBlock = newLines.join(newline) + newline + + if (!content.includes(oldBlock)) { + if (required) { + throw new Error(`patch pattern not found in ${filepath}`) + } + return + } + + await fs.writeFile(filepath, content.replace(oldBlock, newBlock), "utf8") +} + await $`bun dev generate > ${dir}/openapi.json`.cwd(path.resolve(dir, "../../opencode")) await createClient({ @@ -37,6 +83,9 @@ await createClient({ ], }) +await patchClient(path.join(dir, "src/v2/gen/client/client.gen.ts")) +await patchClient(path.join(dir, "src/gen/client/client.gen.ts"), { required: false }) + await $`bun prettier --write src/gen` await $`bun prettier --write src/v2` await $`rm -rf dist` diff --git a/packages/sdk/js/src/gen/client/client.gen.ts b/packages/sdk/js/src/gen/client/client.gen.ts index 34a8d0beceb..ea064226a94 100644 --- a/packages/sdk/js/src/gen/client/client.gen.ts +++ b/packages/sdk/js/src/gen/client/client.gen.ts @@ -114,10 +114,18 @@ export const createClient = (config: Config = {}): Client => { case "arrayBuffer": case "blob": case "formData": - case "json": case "text": data = await response[parseAs]() break + case "json": { + const text = await response.text() + if (!text.trim()) { + data = {} + } else { + data = JSON.parse(text) + } + break + } case "stream": return opts.responseStyle === "data" ? response.body diff --git a/packages/sdk/js/src/v2/gen/client/client.gen.ts b/packages/sdk/js/src/v2/gen/client/client.gen.ts index 47f1403429d..3b654a7b74a 100644 --- a/packages/sdk/js/src/v2/gen/client/client.gen.ts +++ b/packages/sdk/js/src/v2/gen/client/client.gen.ts @@ -162,10 +162,18 @@ export const createClient = (config: Config = {}): Client => { case "arrayBuffer": case "blob": case "formData": - case "json": case "text": data = await response[parseAs]() break + case "json": { + const text = await response.text() + if (!text.trim()) { + data = {} + } else { + data = JSON.parse(text) + } + break + } case "stream": return opts.responseStyle === "data" ? response.body