Merge 3f71943196b08e333f4d3ebcb45fc538385ddbf5 into 9fb78453e088cd7b553d7779faa0de5c83708e70

This commit is contained in:
tianxingleo 2026-03-21 13:02:45 +08:00 committed by GitHub
commit 0c8b3c6943
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 38 additions and 8 deletions

View File

@ -200,6 +200,23 @@ describe("createFeishuClient HTTP timeout", () => {
);
});
it("normalizes axios-style response wrappers to raw payload objects", async () => {
mockBaseHttpInstance.post.mockResolvedValueOnce({
data: { tenant_access_token: "tenant_token", expire: 7200 },
});
createFeishuClient({ appId: "app_3b", appSecret: "secret_3b", accountId: "timeout-shape" }); // pragma: allowlist secret
const calls = (LarkClient as unknown as ReturnType<typeof vi.fn>).mock.calls;
const lastCall = calls[calls.length - 1][0] as {
httpInstance: { post: (...args: unknown[]) => Promise<unknown> };
};
const httpInstance = lastCall.httpInstance;
const res = await httpInstance.post("https://example.com/api", { data: 1 });
expect(res).toEqual({ tenant_access_token: "tenant_token", expire: 7200 });
});
it("uses config-configured default timeout when provided", async () => {
createFeishuClient({
appId: "app_4",

View File

@ -73,15 +73,28 @@ function createTimeoutHttpInstance(defaultTimeoutMs: number): Lark.HttpInstance
return { timeout: defaultTimeoutMs, ...opts } as Lark.HttpRequestOptions<D>;
}
function normalizeResponse<T>(value: T): T {
if (value && typeof value === "object" && "data" in (value as Record<string, unknown>)) {
const data = (value as { data?: unknown }).data;
if (data !== undefined) {
return data as T;
}
}
return value;
}
return {
request: (opts) => base.request(injectTimeout(opts)),
get: (url, opts) => base.get(url, injectTimeout(opts)),
post: (url, data, opts) => base.post(url, data, injectTimeout(opts)),
put: (url, data, opts) => base.put(url, data, injectTimeout(opts)),
patch: (url, data, opts) => base.patch(url, data, injectTimeout(opts)),
delete: (url, opts) => base.delete(url, injectTimeout(opts)),
head: (url, opts) => base.head(url, injectTimeout(opts)),
options: (url, opts) => base.options(url, injectTimeout(opts)),
request: async (opts) => normalizeResponse(await base.request(injectTimeout(opts))),
get: async (url, opts) => normalizeResponse(await base.get(url, injectTimeout(opts))),
post: async (url, data, opts) =>
normalizeResponse(await base.post(url, data, injectTimeout(opts))),
put: async (url, data, opts) =>
normalizeResponse(await base.put(url, data, injectTimeout(opts))),
patch: async (url, data, opts) =>
normalizeResponse(await base.patch(url, data, injectTimeout(opts))),
delete: async (url, opts) => normalizeResponse(await base.delete(url, injectTimeout(opts))),
head: async (url, opts) => normalizeResponse(await base.head(url, injectTimeout(opts))),
options: async (url, opts) => normalizeResponse(await base.options(url, injectTimeout(opts))),
};
}