Skip to content

Commit

Permalink
feat(openapi-fetch): allow usage of custom Request class (#1907)
Browse files Browse the repository at this point in the history
* feat(openapi-fetch): allow usage of custom Request class

* chore: added changeset

* fix: make linter happy

* Update brave-days-invent.md

Co-authored-by: Drew Powers <[email protected]>

---------

Co-authored-by: Drew Powers <[email protected]>
  • Loading branch information
tobiasdcl and drwpow authored Sep 20, 2024
1 parent cc83541 commit efaa1e2
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 15 deletions.
5 changes: 5 additions & 0 deletions .changeset/brave-days-invent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"openapi-fetch": patch
---

allow usage of custom Request class
2 changes: 2 additions & 0 deletions packages/openapi-fetch/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export interface ClientOptions extends Omit<RequestInit, "headers"> {
baseUrl?: string;
/** custom fetch (defaults to globalThis.fetch) */
fetch?: (input: Request) => Promise<Response>;
/** custom Request (defaults to globalThis.Request) */
Request?: typeof Request;
/** global querySerializer */
querySerializer?: QuerySerializer<unknown> | QuerySerializerOptions;
/** global bodySerializer */
Expand Down
25 changes: 10 additions & 15 deletions packages/openapi-fetch/src/index.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,6 @@
// settings & const
const PATH_PARAM_RE = /\{[^{}]+\}/g;

/** Add custom parameters to Request object */
class CustomRequest extends Request {
constructor(input, init) {
super(input, init);

// add custom parameters
for (const key in init) {
if (!(key in this)) {
this[key] = init[key];
}
}
}
}

/**
* Returns a cheap, non-cryptographically-secure random ID
* Courtesy of @imranbarbhuiya (https://github.com/imranbarbhuiya)
Expand All @@ -30,6 +16,7 @@ export function randomID() {
export default function createClient(clientOptions) {
let {
baseUrl = "",
Request: CustomRequest = globalThis.Request,
fetch: baseFetch = globalThis.fetch,
querySerializer: globalQuerySerializer,
bodySerializer: globalBodySerializer,
Expand All @@ -48,6 +35,7 @@ export default function createClient(clientOptions) {
const {
baseUrl: localBaseUrl,
fetch = baseFetch,
Request = CustomRequest,
headers,
params = {},
parseAs = "json",
Expand Down Expand Up @@ -98,6 +86,13 @@ export default function createClient(clientOptions) {
let options;
let request = new CustomRequest(createFinalURL(schemaPath, { baseUrl, params, querySerializer }), requestInit);

/** Add custom parameters to Request object */
for (const key in init) {
if (!(key in request)) {
request[key] = init[key];
}
}

if (middlewares.length) {
id = randomID();

Expand All @@ -119,7 +114,7 @@ export default function createClient(clientOptions) {
id,
});
if (result) {
if (!(result instanceof Request)) {
if (!(result instanceof CustomRequest)) {
throw new Error("onRequest: must return new Request() when modifying the request");
}
request = result;
Expand Down
21 changes: 21 additions & 0 deletions packages/openapi-fetch/test/common/request.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,27 @@ describe("request", () => {
expect(headers.get("cookie")).toEqual("session=1234");
});

test("uses provided Request class", async () => {
// santity check to make sure the profided fetch function is actually called
expect.assertions(1);

class SpecialRequestImplementation extends Request {}

const specialFetch = async (input: Request) => {
// make sure that the request is actually an instance of the custom request we provided
expect(input).instanceOf(SpecialRequestImplementation);
return Promise.resolve(Response.json({ hello: "world" }));
};

const client = createClient<paths>({
baseUrl: "https://fakeurl.example",
fetch: specialFetch,
Request: SpecialRequestImplementation,
});

await client.GET("/resources");
});

test("can attach custom properties to request", async () => {
function createCustomFetch(data: any) {
const response = {
Expand Down

0 comments on commit efaa1e2

Please sign in to comment.