Skip to content

Commit c09fb48

Browse files
committed
Micro perf improvement
1 parent 2bbeb92 commit c09fb48

File tree

4 files changed

+44
-54
lines changed

4 files changed

+44
-54
lines changed

docs/openapi-fetch/api.md

+11-10
Original file line numberDiff line numberDiff line change
@@ -74,18 +74,19 @@ Sometimes your backend doesn’t use one of the standard serialization methods,
7474

7575
```ts
7676
const client = createClient({
77-
querySerializer(queryParam) {
78-
let s = [];
79-
for (const [k, v] of Object.entries(queryParam)) {
80-
if (Array.isArray(v)) {
81-
for (const i of v) {
82-
s.push(`${k}[]=${encodeURIComponent(i)}`);
77+
querySerializer(queryParams) {
78+
const search = [];
79+
for (const name in queryParams) {
80+
const value = queryParams[name];
81+
if (Array.isArray(value)) {
82+
for (const item of value) {
83+
s.push(`${name}[]=${encodeURIComponent(item)}`);
8384
}
8485
} else {
85-
s.push(`${k}=${encodeURLComponent(v)}`);
86+
s.push(`${name}=${encodeURLComponent(value)}`);
8687
}
8788
}
88-
return encodeURI(s.join(",")); // ?tags[]=food,tags[]=california,tags[]=healthy
89+
return search.join(","); // ?tags[]=food,tags[]=california,tags[]=healthy
8990
},
9091
});
9192
```
@@ -126,8 +127,8 @@ const { data, error } = await PUT("/submit", {
126127
},
127128
bodySerializer(body) {
128129
const fd = new FormData();
129-
for (const [k, v] of Object.entries(body)) {
130-
fd.append(k, v);
130+
for (const name in body) {
131+
fd.append(name, body[name]);
131132
}
132133
return fd;
133134
},

packages/openapi-fetch/src/index.js

+29-40
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ const DEFAULT_HEADERS = {
33
"Content-Type": "application/json",
44
};
55

6-
const LEADING_QUESTION_RE = /^\?+/;
76
const PATH_PARAM_RE = /\{[^{}]+\}/g;
87

98
/**
@@ -19,7 +18,7 @@ export default function createClient(clientOptions) {
1918
} = clientOptions ?? {};
2019
let baseUrl = baseOptions.baseUrl ?? "";
2120
if (baseUrl.endsWith("/")) {
22-
baseUrl = baseUrl.slice(0, -1); // remove trailing slash
21+
baseUrl = baseUrl.substring(0, baseUrl.length - 1);
2322
}
2423

2524
/**
@@ -293,12 +292,13 @@ export function createQuerySerializer(options) {
293292
const search = [];
294293
if (queryParams && typeof queryParams === "object") {
295294
for (const name in queryParams) {
296-
if (queryParams[name] === undefined || queryParams[name] === null) {
295+
const value = queryParams[name];
296+
if (value === undefined || value === null) {
297297
continue;
298298
}
299-
if (Array.isArray(queryParams[name])) {
299+
if (Array.isArray(value)) {
300300
search.push(
301-
serializeArrayParam(name, queryParams[name], {
301+
serializeArrayParam(name, value, {
302302
style: "form",
303303
explode: true,
304304
...options?.array,
@@ -307,9 +307,9 @@ export function createQuerySerializer(options) {
307307
);
308308
continue;
309309
}
310-
if (typeof queryParams[name] === "object") {
310+
if (typeof value === "object") {
311311
search.push(
312-
serializeObjectParam(name, queryParams[name], {
312+
serializeObjectParam(name, value, {
313313
style: "deepObject",
314314
explode: true,
315315
...options?.object,
@@ -318,7 +318,7 @@ export function createQuerySerializer(options) {
318318
);
319319
continue;
320320
}
321-
search.push(serializePrimitiveParam(name, queryParams[name], options));
321+
search.push(serializePrimitiveParam(name, value, options));
322322
}
323323
}
324324
return search.join("&");
@@ -331,64 +331,52 @@ export function createQuerySerializer(options) {
331331
* @see https://swagger.io/docs/specification/serialization/#path
332332
*/
333333
export function defaultPathSerializer(pathname, pathParams) {
334-
const matches = pathname.match(PATH_PARAM_RE);
335-
if (!matches || !matches.length) {
336-
return undefined;
337-
}
338334
let nextURL = pathname;
339-
for (const match of matches) {
340-
let paramName = match.substring(1, match.length - 1);
335+
for (const match of pathname.match(PATH_PARAM_RE) ?? []) {
336+
let name = match.substring(1, match.length - 1);
341337
let explode = false;
342338
let style = "simple";
343-
if (paramName.endsWith("*")) {
339+
if (name.endsWith("*")) {
344340
explode = true;
345-
paramName = paramName.substring(0, paramName.length - 1);
341+
name = name.substring(0, name.length - 1);
346342
}
347-
if (paramName.startsWith(".")) {
343+
if (name.startsWith(".")) {
348344
style = "label";
349-
paramName = paramName.substring(1);
350-
} else if (paramName.startsWith(";")) {
345+
name = name.substring(1);
346+
} else if (name.startsWith(";")) {
351347
style = "matrix";
352-
paramName = paramName.substring(1);
348+
name = name.substring(1);
353349
}
354350
if (
355351
!pathParams ||
356-
pathParams[paramName] === undefined ||
357-
pathParams[paramName] === null
352+
pathParams[name] === undefined ||
353+
pathParams[name] === null
358354
) {
359355
continue;
360356
}
361-
if (Array.isArray(pathParams[paramName])) {
357+
const value = pathParams[name];
358+
if (Array.isArray(value)) {
362359
nextURL = nextURL.replace(
363360
match,
364-
serializeArrayParam(paramName, pathParams[paramName], {
365-
style,
366-
explode,
367-
}),
361+
serializeArrayParam(name, value, { style, explode }),
368362
);
369363
continue;
370364
}
371-
if (typeof pathParams[paramName] === "object") {
365+
if (typeof value === "object") {
372366
nextURL = nextURL.replace(
373367
match,
374-
serializeObjectParam(paramName, pathParams[paramName], {
375-
style,
376-
explode,
377-
}),
368+
serializeObjectParam(name, value, { style, explode }),
378369
);
379370
continue;
380371
}
381372
if (style === "matrix") {
382373
nextURL = nextURL.replace(
383374
match,
384-
`;${serializePrimitiveParam(paramName, pathParams[paramName])}`,
375+
`;${serializePrimitiveParam(name, value)}`,
385376
);
386377
continue;
387378
}
388-
nextURL = nextURL.replace(
389-
match,
390-
style === "label" ? `.${pathParams[paramName]}` : pathParams[paramName],
391-
);
379+
nextURL = nextURL.replace(match, style === "label" ? `.${value}` : value);
392380
continue;
393381
}
394382
return nextURL;
@@ -411,9 +399,10 @@ export function createFinalURL(pathname, options) {
411399
if (options.params?.path) {
412400
finalURL = defaultPathSerializer(finalURL, options.params.path);
413401
}
414-
const search = options
415-
.querySerializer(options.params.query ?? {})
416-
.replace(LEADING_QUESTION_RE, "");
402+
let search = options.querySerializer(options.params.query ?? {});
403+
if (search.startsWith("?")) {
404+
search = search.substring(1);
405+
}
417406
if (search) {
418407
finalURL += `?${search}`;
419408
}

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -684,8 +684,8 @@ describe("client", () => {
684684
},
685685
bodySerializer(body) {
686686
const fd = new FormData();
687-
for (const [k, v] of Object.entries(body)) {
688-
fd.append(k, v);
687+
for (const name in body) {
688+
fd.append(name, body[name as keyof typeof body]);
689689
}
690690
return fd;
691691
},

packages/openapi-fetch/test/v7-beta.test.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -693,8 +693,8 @@ describe("client", () => {
693693
},
694694
bodySerializer(body) {
695695
const fd = new FormData();
696-
for (const [k, v] of Object.entries(body)) {
697-
fd.append(k, v);
696+
for (const name in body) {
697+
fd.append(name, body[name as keyof typeof body]);
698698
}
699699
return fd;
700700
},

0 commit comments

Comments
 (0)