Skip to content

Commit c3b0b0f

Browse files
authored
Merge pull request #4595 from bayasdev/split-encodeparams
2 parents c9d7b92 + 9d50bc7 commit c3b0b0f

File tree

3 files changed

+96
-29
lines changed

3 files changed

+96
-29
lines changed

packages/rtk-query-codegen-openapi/src/generate.ts

+32-15
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,8 @@ export async function generateApi(
110110
filterEndpoints,
111111
endpointOverrides,
112112
unionUndefined,
113-
encodeParams = false,
113+
encodePathParams = false,
114+
encodeQueryParams = false,
114115
flattenArg = false,
115116
includeDefault = false,
116117
useEnumType = false,
@@ -398,7 +399,14 @@ export async function generateApi(
398399
type: isQuery ? 'query' : 'mutation',
399400
Response: ResponseTypeName,
400401
QueryArg,
401-
queryFn: generateQueryFn({ operationDefinition, queryArg, isQuery, isFlatArg, encodeParams }),
402+
queryFn: generateQueryFn({
403+
operationDefinition,
404+
queryArg,
405+
isQuery,
406+
isFlatArg,
407+
encodePathParams,
408+
encodeQueryParams,
409+
}),
402410
extraEndpointsProps: isQuery
403411
? generateQueryEndpointProps({ operationDefinition })
404412
: generateMutationEndpointProps({ operationDefinition }),
@@ -411,13 +419,15 @@ export async function generateApi(
411419
queryArg,
412420
isFlatArg,
413421
isQuery,
414-
encodeParams,
422+
encodePathParams,
423+
encodeQueryParams,
415424
}: {
416425
operationDefinition: OperationDefinition;
417426
queryArg: QueryArgDefinitions;
418427
isFlatArg: boolean;
419428
isQuery: boolean;
420-
encodeParams: boolean;
429+
encodePathParams: boolean;
430+
encodeQueryParams: boolean;
421431
}) {
422432
const { path, verb } = operationDefinition;
423433

@@ -434,14 +444,21 @@ export async function generateApi(
434444

435445
const properties = parameters.map((param) => {
436446
const value = isFlatArg ? rootObject : accessProperty(rootObject, param.name);
437-
return createPropertyAssignment(
438-
param.originalName,
439-
encodeParams && param.param?.in === 'query'
440-
? factory.createCallExpression(factory.createIdentifier('encodeURIComponent'), undefined, [
441-
factory.createCallExpression(factory.createIdentifier('String'), undefined, [value]),
442-
])
443-
: value
444-
);
447+
448+
const encodedValue =
449+
encodeQueryParams && param.param?.in === 'query'
450+
? factory.createConditionalExpression(
451+
value,
452+
undefined,
453+
factory.createCallExpression(factory.createIdentifier('encodeURIComponent'), undefined, [
454+
factory.createCallExpression(factory.createIdentifier('String'), undefined, [value]),
455+
]),
456+
undefined,
457+
factory.createIdentifier('undefined')
458+
)
459+
: value;
460+
461+
return createPropertyAssignment(param.originalName, encodedValue);
445462
});
446463

447464
return factory.createPropertyAssignment(
@@ -463,7 +480,7 @@ export async function generateApi(
463480
[
464481
factory.createPropertyAssignment(
465482
factory.createIdentifier('url'),
466-
generatePathExpression(path, pickParams('path'), rootObject, isFlatArg, encodeParams)
483+
generatePathExpression(path, pickParams('path'), rootObject, isFlatArg, encodePathParams)
467484
),
468485
isQuery && verb.toUpperCase() === 'GET'
469486
? undefined
@@ -511,7 +528,7 @@ function generatePathExpression(
511528
pathParameters: QueryArgDefinition[],
512529
rootObject: ts.Identifier,
513530
isFlatArg: boolean,
514-
encodeParams: boolean
531+
encodePathParams: boolean
515532
) {
516533
const expressions: Array<[string, string]> = [];
517534

@@ -529,7 +546,7 @@ function generatePathExpression(
529546
factory.createTemplateHead(head),
530547
expressions.map(([prop, literal], index) => {
531548
const value = isFlatArg ? rootObject : accessProperty(rootObject, prop);
532-
const encodedValue = encodeParams
549+
const encodedValue = encodePathParams
533550
? factory.createCallExpression(factory.createIdentifier('encodeURIComponent'), undefined, [
534551
factory.createCallExpression(factory.createIdentifier('String'), undefined, [value]),
535552
])

packages/rtk-query-codegen-openapi/src/types.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,14 @@ export interface CommonOptions {
7575
tag?: boolean;
7676
/**
7777
* defaults to false
78-
* `true` will add `encodeURIComponent` to the generated query params
78+
* `true` will add `encodeURIComponent` to the generated path parameters
7979
*/
80-
encodeParams?: boolean;
80+
encodePathParams?: boolean;
81+
/**
82+
* defaults to false
83+
* `true` will add `encodeURIComponent` to the generated query parameters
84+
*/
85+
encodeQueryParams?: boolean;
8186
/**
8287
* defaults to false
8388
* `true` will "flatten" the arg so that you can do things like `useGetEntityById(1)` instead of `useGetEntityById({ entityId: 1 })`

packages/rtk-query-codegen-openapi/test/generateEndpoints.test.ts

+57-12
Original file line numberDiff line numberDiff line change
@@ -174,28 +174,28 @@ describe('endpoint overrides', () => {
174174
});
175175
});
176176

177-
describe('option encodeParams', () => {
177+
describe('option encodePathParams', () => {
178178
const config = {
179179
apiFile: './fixtures/emptyApi.ts',
180180
schemaFile: resolve(__dirname, 'fixtures/petstore.json'),
181-
encodeParams: true,
181+
encodePathParams: true,
182182
};
183183

184-
it('should encode query parameters', async () => {
184+
it('should encode path parameters', async () => {
185185
const api = await generateEndpoints({
186186
...config,
187-
filterEndpoints: ['findPetsByStatus'],
187+
filterEndpoints: ['getOrderById'],
188188
});
189-
expect(api).toContain('status: encodeURIComponent(String(queryArg.status))');
189+
// eslint-disable-next-line no-template-curly-in-string
190+
expect(api).toContain('`/store/order/${encodeURIComponent(String(queryArg.orderId))}`');
190191
});
191192

192-
it('should encode path parameters', async () => {
193+
it('should not encode query parameters', async () => {
193194
const api = await generateEndpoints({
194195
...config,
195-
filterEndpoints: ['getOrderById'],
196+
filterEndpoints: ['findPetsByStatus'],
196197
});
197-
// eslint-disable-next-line no-template-curly-in-string
198-
expect(api).toContain('`/store/order/${encodeURIComponent(String(queryArg.orderId))}`');
198+
expect(api).toContain('status: queryArg.status');
199199
});
200200

201201
it('should not encode body parameters', async () => {
@@ -217,18 +217,63 @@ describe('option encodeParams', () => {
217217
expect(api).toContain('`/store/order/${encodeURIComponent(String(queryArg))}`');
218218
});
219219

220-
it('should not encode parameters when encodeParams is false', async () => {
220+
it('should not encode path parameters when encodePathParams is false', async () => {
221221
const api = await generateEndpoints({
222222
...config,
223-
encodeParams: false,
223+
encodePathParams: false,
224224
filterEndpoints: ['findPetsByStatus', 'getOrderById'],
225225
});
226-
expect(api).toContain('status: queryArg.status');
227226
// eslint-disable-next-line no-template-curly-in-string
228227
expect(api).toContain('`/store/order/${queryArg.orderId}`');
229228
});
230229
});
231230

231+
describe('option encodeQueryParams', () => {
232+
const config = {
233+
apiFile: './fixtures/emptyApi.ts',
234+
schemaFile: resolve(__dirname, 'fixtures/petstore.json'),
235+
encodeQueryParams: true,
236+
};
237+
238+
it('should conditionally encode query parameters', async () => {
239+
const api = await generateEndpoints({
240+
...config,
241+
filterEndpoints: ['findPetsByStatus'],
242+
});
243+
244+
expect(api).toMatch(
245+
/params:\s*{\s*\n\s*status:\s*queryArg\.status\s*\?\s*encodeURIComponent\(\s*String\(queryArg\.status\)\s*\)\s*:\s*undefined\s*,?\s*\n\s*}/s
246+
);
247+
});
248+
249+
it('should not encode path parameters', async () => {
250+
const api = await generateEndpoints({
251+
...config,
252+
filterEndpoints: ['getOrderById'],
253+
});
254+
// eslint-disable-next-line no-template-curly-in-string
255+
expect(api).toContain('`/store/order/${queryArg.orderId}`');
256+
});
257+
258+
it('should not encode body parameters', async () => {
259+
const api = await generateEndpoints({
260+
...config,
261+
filterEndpoints: ['addPet'],
262+
});
263+
expect(api).toContain('body: queryArg.pet');
264+
expect(api).not.toContain('body: encodeURIComponent(String(queryArg.pet))');
265+
});
266+
267+
it('should not encode query parameters when encodeQueryParams is false', async () => {
268+
const api = await generateEndpoints({
269+
...config,
270+
encodeQueryParams: false,
271+
filterEndpoints: ['findPetsByStatus', 'getOrderById'],
272+
});
273+
expect(api).toContain('status: queryArg.status');
274+
});
275+
});
276+
232277
describe('option flattenArg', () => {
233278
const config = {
234279
apiFile: './fixtures/emptyApi.ts',

0 commit comments

Comments
 (0)