Skip to content

Commit

Permalink
Allow to select the response content type (#1597)
Browse files Browse the repository at this point in the history
  • Loading branch information
armandabric authored Mar 27, 2024
1 parent 92f4b96 commit 1f7ad9d
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 15 deletions.
5 changes: 5 additions & 0 deletions .changeset/few-tomatoes-try.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"openapi-fetch": patch
---

Allow to select the response content type
30 changes: 17 additions & 13 deletions packages/openapi-fetch/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,18 +111,18 @@ export type RequestBodyOption<T> =
export type FetchOptions<T> = RequestOptions<T> &
Omit<RequestInit, "body" | "headers">;

export type FetchResponse<T, O> =
export type FetchResponse<T, O, Media extends MediaType> =
| {
data: ParseAsResponse<
FilterKeys<SuccessResponse<ResponseObjectMap<T>>, MediaType>,
FilterKeys<SuccessResponse<ResponseObjectMap<T>>, Media>,
O
>;
error?: never;
response: Response;
}
| {
data?: never;
error: FilterKeys<ErrorResponse<ResponseObjectMap<T>>, MediaType>;
error: FilterKeys<ErrorResponse<ResponseObjectMap<T>>, Media>;
response: Response;
};

Expand Down Expand Up @@ -180,33 +180,37 @@ export type MaybeOptionalInit<P extends PathMethods, M extends keyof P> =
export type ClientMethod<
Paths extends Record<string, PathMethods>,
M extends HttpMethod,
Media extends MediaType,
> = <
P extends PathsWithMethod<Paths, M>,
I extends MaybeOptionalInit<Paths[P], M>,
>(
url: P,
...init: I
) => Promise<FetchResponse<Paths[P][M], I[0]>>;
) => Promise<FetchResponse<Paths[P][M], I[0], Media>>;

export default function createClient<Paths extends {}>(
export default function createClient<
Paths extends {},
Media extends MediaType = MediaType,
>(
clientOptions?: ClientOptions,
): {
/** Call a GET endpoint */
GET: ClientMethod<Paths, "get">;
GET: ClientMethod<Paths, "get", Media>;
/** Call a PUT endpoint */
PUT: ClientMethod<Paths, "put">;
PUT: ClientMethod<Paths, "put", Media>;
/** Call a POST endpoint */
POST: ClientMethod<Paths, "post">;
POST: ClientMethod<Paths, "post", Media>;
/** Call a DELETE endpoint */
DELETE: ClientMethod<Paths, "delete">;
DELETE: ClientMethod<Paths, "delete", Media>;
/** Call a OPTIONS endpoint */
OPTIONS: ClientMethod<Paths, "options">;
OPTIONS: ClientMethod<Paths, "options", Media>;
/** Call a HEAD endpoint */
HEAD: ClientMethod<Paths, "head">;
HEAD: ClientMethod<Paths, "head", Media>;
/** Call a PATCH endpoint */
PATCH: ClientMethod<Paths, "patch">;
PATCH: ClientMethod<Paths, "patch", Media>;
/** Call a TRACE endpoint */
TRACE: ClientMethod<Paths, "trace">;
TRACE: ClientMethod<Paths, "trace", Media>;
/** Register middleware */
use(...middleware: Middleware[]): void;
/** Unregister middleware */
Expand Down
23 changes: 21 additions & 2 deletions packages/openapi-fetch/test/fixtures/api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
* Do not make direct changes to the file.
*/


export interface paths {
"/comment": {
put: {
Expand Down Expand Up @@ -396,6 +395,13 @@ export interface paths {
};
};
};
"/multiple-response-content": {
get: {
responses: {
200: components["responses"]["MultipleResponse"];
};
};
};
}

export type webhooks = Record<string, never>;
Expand Down Expand Up @@ -492,6 +498,20 @@ export interface components {
"application/json": components["schemas"]["User"];
};
};
MultipleResponse: {
content: {
"application/json": {
id: string;
email: string;
name?: string;
};
"application/ld+json": {
"@id": string;
email: string;
name?: string;
};
};
};
};
parameters: never;
requestBodies: {
Expand Down Expand Up @@ -557,7 +577,6 @@ export type $defs = Record<string, never>;
export type external = Record<string, never>;

export interface operations {

getHeaderParams: {
parameters: {
header: {
Expand Down
36 changes: 36 additions & 0 deletions packages/openapi-fetch/test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1049,6 +1049,42 @@ describe("client", () => {

expect(data.byteLength).toBe(2);
});

it("use the selected content", async () => {
const client = createClient<paths, "application/ld+json">();
mockFetchOnce({
status: 200,
headers: { "Content-Type": "application/ld+json" },
body: JSON.stringify({
"@id": "some-resource-identifier",
email: "[email protected]",
name: null,
}),
});
const { data } = await client.GET("/multiple-response-content", {
headers: {
Accept: "application/ld+json",
},
});

data satisfies
| {
"@id": string;
email: string;
name?: string;
}
| undefined;

if (!data) {
throw new Error(`Missing response`);
}

expect(data).toEqual({
"@id": "some-resource-identifier",
email: "[email protected]",
name: null,
});
});
});
});

Expand Down

0 comments on commit 1f7ad9d

Please sign in to comment.