Skip to content

Commit

Permalink
Merge pull request #4568 from bayasdev/encode-params
Browse files Browse the repository at this point in the history
  • Loading branch information
markerikson authored Aug 30, 2024
2 parents 6353756 + a989ed9 commit ac4d85e
Show file tree
Hide file tree
Showing 5 changed files with 298 additions and 72 deletions.
59 changes: 36 additions & 23 deletions packages/rtk-query-codegen-openapi/src/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export async function generateApi(
filterEndpoints,
endpointOverrides,
unionUndefined,
encodeParams = false,
flattenArg = false,
useEnumType = false,
mergeReadWriteOnly = false,
Expand Down Expand Up @@ -356,7 +357,7 @@ export async function generateApi(
type: isQuery ? 'query' : 'mutation',
Response: ResponseTypeName,
QueryArg,
queryFn: generateQueryFn({ operationDefinition, queryArg, isQuery, isFlatArg }),
queryFn: generateQueryFn({ operationDefinition, queryArg, isQuery, isFlatArg, encodeParams }),
extraEndpointsProps: isQuery
? generateQueryEndpointProps({ operationDefinition })
: generateMutationEndpointProps({ operationDefinition }),
Expand All @@ -369,11 +370,13 @@ export async function generateApi(
queryArg,
isFlatArg,
isQuery,
encodeParams,
}: {
operationDefinition: OperationDefinition;
queryArg: QueryArgDefinitions;
isFlatArg: boolean;
isQuery: boolean;
encodeParams: boolean;
}) {
const { path, verb } = operationDefinition;

Expand All @@ -386,21 +389,24 @@ export async function generateApi(
}

function createObjectLiteralProperty(parameters: QueryArgDefinition[], propertyName: string) {
return parameters.length === 0
? undefined
: factory.createPropertyAssignment(
factory.createIdentifier(propertyName),
factory.createObjectLiteralExpression(
parameters.map(
(param) =>
createPropertyAssignment(
param.originalName,
isFlatArg ? rootObject : accessProperty(rootObject, param.name)
),
true
)
)
);
if (parameters.length === 0) return undefined;

const properties = parameters.map((param) => {
const value = isFlatArg ? rootObject : accessProperty(rootObject, param.name);
return createPropertyAssignment(
param.originalName,
encodeParams && param.param?.in === 'query'
? factory.createCallExpression(factory.createIdentifier('encodeURIComponent'), undefined, [
factory.createCallExpression(factory.createIdentifier('String'), undefined, [value]),
])
: value
);
});

return factory.createPropertyAssignment(
factory.createIdentifier(propertyName),
factory.createObjectLiteralExpression(properties, true)
);
}

return factory.createArrowFunction(
Expand All @@ -416,7 +422,7 @@ export async function generateApi(
[
factory.createPropertyAssignment(
factory.createIdentifier('url'),
generatePathExpression(path, pickParams('path'), rootObject, isFlatArg)
generatePathExpression(path, pickParams('path'), rootObject, isFlatArg, encodeParams)
),
isQuery && verb.toUpperCase() === 'GET'
? undefined
Expand Down Expand Up @@ -463,7 +469,8 @@ function generatePathExpression(
path: string,
pathParameters: QueryArgDefinition[],
rootObject: ts.Identifier,
isFlatArg: boolean
isFlatArg: boolean,
encodeParams: boolean
) {
const expressions: Array<[string, string]> = [];

Expand All @@ -479,14 +486,20 @@ function generatePathExpression(
return expressions.length
? factory.createTemplateExpression(
factory.createTemplateHead(head),
expressions.map(([prop, literal], index) =>
factory.createTemplateSpan(
isFlatArg ? rootObject : accessProperty(rootObject, prop),
expressions.map(([prop, literal], index) => {
const value = isFlatArg ? rootObject : accessProperty(rootObject, prop);
const encodedValue = encodeParams
? factory.createCallExpression(factory.createIdentifier('encodeURIComponent'), undefined, [
factory.createCallExpression(factory.createIdentifier('String'), undefined, [value]),
])
: value;
return factory.createTemplateSpan(
encodedValue,
index === expressions.length - 1
? factory.createTemplateTail(literal)
: factory.createTemplateMiddle(literal)
)
)
);
})
)
: factory.createNoSubstitutionTemplateLiteral(head);
}
Expand Down
5 changes: 5 additions & 0 deletions packages/rtk-query-codegen-openapi/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ export interface CommonOptions {
* @see https://redux-toolkit.js.org/rtk-query/usage/code-generation for more information
*/
tag?: boolean;
/**
* defaults to false
* `true` will add `encodeURIComponent` to the generated query params
*/
encodeParams?: boolean;
/**
* defaults to false
* `true` will "flatten" the arg so that you can do things like `useGetEntityById(1)` instead of `useGetEntityById({ entityId: 1 })`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,20 @@ const injectedRtkApi = api.injectEndpoints({
query: (queryArg) => ({ url: \`/pet\`, method: 'POST', body: queryArg.pet }),
}),
findPetsByStatus: build.query<FindPetsByStatusApiResponse, FindPetsByStatusApiArg>({
query: (queryArg) => ({ url: \`/pet/findByStatus\`, params: { status: queryArg.status } }),
query: (queryArg) => ({
url: \`/pet/findByStatus\`,
params: {
status: queryArg.status,
},
}),
}),
findPetsByTags: build.query<FindPetsByTagsApiResponse, FindPetsByTagsApiArg>({
query: (queryArg) => ({ url: \`/pet/findByTags\`, params: { tags: queryArg.tags } }),
query: (queryArg) => ({
url: \`/pet/findByTags\`,
params: {
tags: queryArg.tags,
},
}),
}),
getPetById: build.query<GetPetByIdApiResponse, GetPetByIdApiArg>({
query: (queryArg) => ({ url: \`/pet/\${queryArg.petId}\` }),
Expand All @@ -23,18 +33,29 @@ const injectedRtkApi = api.injectEndpoints({
query: (queryArg) => ({
url: \`/pet/\${queryArg.petId}\`,
method: 'POST',
params: { name: queryArg.name, status: queryArg.status },
params: {
name: queryArg.name,
status: queryArg.status,
},
}),
}),
deletePet: build.mutation<DeletePetApiResponse, DeletePetApiArg>({
query: (queryArg) => ({ url: \`/pet/\${queryArg.petId}\`, method: 'DELETE', headers: { api_key: queryArg.apiKey } }),
query: (queryArg) => ({
url: \`/pet/\${queryArg.petId}\`,
method: 'DELETE',
headers: {
api_key: queryArg.apiKey,
},
}),
}),
uploadFile: build.mutation<UploadFileApiResponse, UploadFileApiArg>({
query: (queryArg) => ({
url: \`/pet/\${queryArg.petId}/uploadImage\`,
method: 'POST',
body: queryArg.body,
params: { additionalMetadata: queryArg.additionalMetadata },
params: {
additionalMetadata: queryArg.additionalMetadata,
},
}),
}),
getInventory: build.query<GetInventoryApiResponse, GetInventoryApiArg>({
Expand All @@ -58,7 +79,10 @@ const injectedRtkApi = api.injectEndpoints({
loginUser: build.query<LoginUserApiResponse, LoginUserApiArg>({
query: (queryArg) => ({
url: \`/user/login\`,
params: { username: queryArg.username, password: queryArg.password },
params: {
username: queryArg.username,
password: queryArg.password,
},
}),
}),
logoutUser: build.query<LogoutUserApiResponse, LogoutUserApiArg>({
Expand Down Expand Up @@ -234,10 +258,20 @@ const injectedRtkApi = api.injectEndpoints({
query: (queryArg) => ({ url: \`/pet\`, method: 'POST', body: queryArg.pet }),
}),
findPetsByStatus: build.query<FindPetsByStatusApiResponse, FindPetsByStatusApiArg>({
query: (queryArg) => ({ url: \`/pet/findByStatus\`, params: { status: queryArg.status } }),
query: (queryArg) => ({
url: \`/pet/findByStatus\`,
params: {
status: queryArg.status,
},
}),
}),
findPetsByTags: build.query<FindPetsByTagsApiResponse, FindPetsByTagsApiArg>({
query: (queryArg) => ({ url: \`/pet/findByTags\`, params: { tags: queryArg.tags } }),
query: (queryArg) => ({
url: \`/pet/findByTags\`,
params: {
tags: queryArg.tags,
},
}),
}),
getPetById: build.query<GetPetByIdApiResponse, GetPetByIdApiArg>({
query: (queryArg) => ({ url: \`/pet/\${queryArg.petId}\` }),
Expand All @@ -246,18 +280,29 @@ const injectedRtkApi = api.injectEndpoints({
query: (queryArg) => ({
url: \`/pet/\${queryArg.petId}\`,
method: 'POST',
params: { name: queryArg.name, status: queryArg.status },
params: {
name: queryArg.name,
status: queryArg.status,
},
}),
}),
deletePet: build.mutation<DeletePetApiResponse, DeletePetApiArg>({
query: (queryArg) => ({ url: \`/pet/\${queryArg.petId}\`, method: 'DELETE', headers: { api_key: queryArg.apiKey } }),
query: (queryArg) => ({
url: \`/pet/\${queryArg.petId}\`,
method: 'DELETE',
headers: {
api_key: queryArg.apiKey,
},
}),
}),
uploadFile: build.mutation<UploadFileApiResponse, UploadFileApiArg>({
query: (queryArg) => ({
url: \`/pet/\${queryArg.petId}/uploadImage\`,
method: 'POST',
body: queryArg.body,
params: { additionalMetadata: queryArg.additionalMetadata },
params: {
additionalMetadata: queryArg.additionalMetadata,
},
}),
}),
getInventory: build.query<GetInventoryApiResponse, GetInventoryApiArg>({
Expand All @@ -281,7 +326,10 @@ const injectedRtkApi = api.injectEndpoints({
loginUser: build.query<LoginUserApiResponse, LoginUserApiArg>({
query: (queryArg) => ({
url: \`/user/login\`,
params: { username: queryArg.username, password: queryArg.password },
params: {
username: queryArg.username,
password: queryArg.password,
},
}),
}),
logoutUser: build.query<LogoutUserApiResponse, LogoutUserApiArg>({
Expand Down
Loading

0 comments on commit ac4d85e

Please sign in to comment.