Skip to content

Commit 1951228

Browse files
committed
feat(openapi-fetch): baseUrl per request
1 parent 224bf22 commit 1951228

File tree

3 files changed

+70
-3
lines changed

3 files changed

+70
-3
lines changed

packages/openapi-fetch/src/index.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ export type FetchResponse<T, Options, Media extends MediaType> =
109109

110110
export type RequestOptions<T> = ParamsOption<T> &
111111
RequestBodyOption<T> & {
112+
baseUrl?: string;
112113
querySerializer?: QuerySerializer<T> | QuerySerializerOptions;
113114
bodySerializer?: BodySerializer<T>;
114115
parseAs?: ParseAs;
@@ -253,3 +254,6 @@ export declare function createFinalURL<O>(
253254

254255
/** Merge headers a and b, with b taking priority */
255256
export declare function mergeHeaders(...allHeaders: (HeadersOptions | undefined)[]): Headers;
257+
258+
/** Remove trailing slash from url */
259+
export declare function removeTrailingSlash(url: string): string;

packages/openapi-fetch/src/index.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,7 @@ export default function createClient(clientOptions) {
4040
headers: baseHeaders,
4141
...baseOptions
4242
} = { ...clientOptions };
43-
if (baseUrl.endsWith("/")) {
44-
baseUrl = baseUrl.substring(0, baseUrl.length - 1);
45-
}
43+
baseUrl = removeTrailingSlash(baseUrl);
4644
baseHeaders = mergeHeaders(DEFAULT_HEADERS, baseHeaders);
4745
const middlewares = [];
4846

@@ -53,6 +51,7 @@ export default function createClient(clientOptions) {
5351
*/
5452
async function coreFetch(schemaPath, fetchOptions) {
5553
const {
54+
baseUrl: localBaseUrl,
5655
fetch = baseFetch,
5756
headers,
5857
params = {},
@@ -61,6 +60,9 @@ export default function createClient(clientOptions) {
6160
bodySerializer = globalBodySerializer ?? defaultBodySerializer,
6261
...init
6362
} = fetchOptions || {};
63+
if (localBaseUrl) {
64+
baseUrl = removeTrailingSlash(localBaseUrl);
65+
}
6466

6567
let querySerializer =
6668
typeof globalQuerySerializer === "function"
@@ -484,3 +486,14 @@ export function mergeHeaders(...allHeaders) {
484486
}
485487
return finalHeaders;
486488
}
489+
490+
/**
491+
* Remove trailing slash from url
492+
* @type {import("./index.js").removeTrailingSlash}
493+
*/
494+
export function removeTrailingSlash(url) {
495+
if (url.endsWith("/")) {
496+
return url.substring(0, url.length - 1);
497+
}
498+
return url;
499+
}

packages/openapi-fetch/test/index.test.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,29 @@ describe("client", () => {
767767
expect(getRequestUrl().href).toBe(toAbsoluteURL("/self"));
768768
});
769769

770+
it("baseUrl per request", async () => {
771+
const localBaseUrl = "https://api.foo.bar/v1";
772+
let client = createClient<paths>({ baseUrl });
773+
774+
const { getRequestUrl } = useMockRequestHandler({
775+
baseUrl: localBaseUrl,
776+
method: "get",
777+
path: "/self",
778+
status: 200,
779+
body: { message: "OK" },
780+
});
781+
782+
await client.GET("/self", { baseUrl: localBaseUrl });
783+
784+
// assert baseUrl and path mesh as expected
785+
expect(getRequestUrl().href).toBe(toAbsoluteURL("/self", localBaseUrl));
786+
787+
client = createClient<paths>({ baseUrl });
788+
await client.GET("/self", { baseUrl: localBaseUrl });
789+
// assert trailing '/' was removed
790+
expect(getRequestUrl().href).toBe(toAbsoluteURL("/self", localBaseUrl));
791+
});
792+
770793
describe("headers", () => {
771794
it("persist", async () => {
772795
const headers: HeadersInit = { Authorization: "Bearer secrettoken" };
@@ -1272,6 +1295,33 @@ describe("client", () => {
12721295
expect(req.headers.get("onFetch")).toBe("exists");
12731296
expect(req.headers.get("onRequest")).toBe("exists");
12741297
});
1298+
1299+
it("baseUrl can be overriden", async () => {
1300+
useMockRequestHandler({
1301+
baseUrl: "https://api.foo.bar/v1/",
1302+
method: "get",
1303+
path: "/self",
1304+
status: 200,
1305+
body: {},
1306+
});
1307+
1308+
let requestBaseUrl = "";
1309+
1310+
const client = createClient<paths>({
1311+
baseUrl,
1312+
});
1313+
client.use({
1314+
onRequest({ options }) {
1315+
requestBaseUrl = options.baseUrl;
1316+
return undefined;
1317+
},
1318+
});
1319+
1320+
await client.GET("/self", {
1321+
baseUrl: "https://api.foo.bar/v1/"
1322+
});
1323+
expect(requestBaseUrl).toBe("https://api.foo.bar/v1");
1324+
});
12751325
});
12761326
});
12771327

0 commit comments

Comments
 (0)