Skip to content

Commit

Permalink
Merge pull request #4595 from bayasdev/split-encodeparams
Browse files Browse the repository at this point in the history
  • Loading branch information
markerikson authored Sep 2, 2024
2 parents c9d7b92 + 9d50bc7 commit c3b0b0f
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 29 deletions.
47 changes: 32 additions & 15 deletions packages/rtk-query-codegen-openapi/src/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ export async function generateApi(
filterEndpoints,
endpointOverrides,
unionUndefined,
encodeParams = false,
encodePathParams = false,
encodeQueryParams = false,
flattenArg = false,
includeDefault = false,
useEnumType = false,
Expand Down Expand Up @@ -398,7 +399,14 @@ export async function generateApi(
type: isQuery ? 'query' : 'mutation',
Response: ResponseTypeName,
QueryArg,
queryFn: generateQueryFn({ operationDefinition, queryArg, isQuery, isFlatArg, encodeParams }),
queryFn: generateQueryFn({
operationDefinition,
queryArg,
isQuery,
isFlatArg,
encodePathParams,
encodeQueryParams,
}),
extraEndpointsProps: isQuery
? generateQueryEndpointProps({ operationDefinition })
: generateMutationEndpointProps({ operationDefinition }),
Expand All @@ -411,13 +419,15 @@ export async function generateApi(
queryArg,
isFlatArg,
isQuery,
encodeParams,
encodePathParams,
encodeQueryParams,
}: {
operationDefinition: OperationDefinition;
queryArg: QueryArgDefinitions;
isFlatArg: boolean;
isQuery: boolean;
encodeParams: boolean;
encodePathParams: boolean;
encodeQueryParams: boolean;
}) {
const { path, verb } = operationDefinition;

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

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
);

const encodedValue =
encodeQueryParams && param.param?.in === 'query'
? factory.createConditionalExpression(
value,
undefined,
factory.createCallExpression(factory.createIdentifier('encodeURIComponent'), undefined, [
factory.createCallExpression(factory.createIdentifier('String'), undefined, [value]),
]),
undefined,
factory.createIdentifier('undefined')
)
: value;

return createPropertyAssignment(param.originalName, encodedValue);
});

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

Expand All @@ -529,7 +546,7 @@ function generatePathExpression(
factory.createTemplateHead(head),
expressions.map(([prop, literal], index) => {
const value = isFlatArg ? rootObject : accessProperty(rootObject, prop);
const encodedValue = encodeParams
const encodedValue = encodePathParams
? factory.createCallExpression(factory.createIdentifier('encodeURIComponent'), undefined, [
factory.createCallExpression(factory.createIdentifier('String'), undefined, [value]),
])
Expand Down
9 changes: 7 additions & 2 deletions packages/rtk-query-codegen-openapi/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,14 @@ export interface CommonOptions {
tag?: boolean;
/**
* defaults to false
* `true` will add `encodeURIComponent` to the generated query params
* `true` will add `encodeURIComponent` to the generated path parameters
*/
encodeParams?: boolean;
encodePathParams?: boolean;
/**
* defaults to false
* `true` will add `encodeURIComponent` to the generated query parameters
*/
encodeQueryParams?: 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
69 changes: 57 additions & 12 deletions packages/rtk-query-codegen-openapi/test/generateEndpoints.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,28 +174,28 @@ describe('endpoint overrides', () => {
});
});

describe('option encodeParams', () => {
describe('option encodePathParams', () => {
const config = {
apiFile: './fixtures/emptyApi.ts',
schemaFile: resolve(__dirname, 'fixtures/petstore.json'),
encodeParams: true,
encodePathParams: true,
};

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

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

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

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

describe('option encodeQueryParams', () => {
const config = {
apiFile: './fixtures/emptyApi.ts',
schemaFile: resolve(__dirname, 'fixtures/petstore.json'),
encodeQueryParams: true,
};

it('should conditionally encode query parameters', async () => {
const api = await generateEndpoints({
...config,
filterEndpoints: ['findPetsByStatus'],
});

expect(api).toMatch(
/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
);
});

it('should not encode path parameters', async () => {
const api = await generateEndpoints({
...config,
filterEndpoints: ['getOrderById'],
});
// eslint-disable-next-line no-template-curly-in-string
expect(api).toContain('`/store/order/${queryArg.orderId}`');
});

it('should not encode body parameters', async () => {
const api = await generateEndpoints({
...config,
filterEndpoints: ['addPet'],
});
expect(api).toContain('body: queryArg.pet');
expect(api).not.toContain('body: encodeURIComponent(String(queryArg.pet))');
});

it('should not encode query parameters when encodeQueryParams is false', async () => {
const api = await generateEndpoints({
...config,
encodeQueryParams: false,
filterEndpoints: ['findPetsByStatus', 'getOrderById'],
});
expect(api).toContain('status: queryArg.status');
});
});

describe('option flattenArg', () => {
const config = {
apiFile: './fixtures/emptyApi.ts',
Expand Down

0 comments on commit c3b0b0f

Please sign in to comment.