Skip to content

Commit

Permalink
fix: Prevent query parameters from being optional when header paramet…
Browse files Browse the repository at this point in the history
…ers are required. (#4935)

* add changelog

* conditionally order params

* update test-services

* revert & minimal fix

* Update packages/openapi-generator/src/file-serializer/operation.ts

---------

Co-authored-by: Tom Frenken <[email protected]>
Co-authored-by: Marika Marszalkowski <[email protected]>
  • Loading branch information
3 people authored Aug 23, 2024
1 parent 5847e0a commit a566fdd
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 7 deletions.
5 changes: 5 additions & 0 deletions .changeset/hot-trees-talk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sap-cloud-sdk/openapi-generator': minor
---

[Fix] Prevent query parameters from being optional when header parameters are required in signature.
65 changes: 65 additions & 0 deletions packages/openapi-generator/src/file-serializer/operation.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,71 @@ describe('serializeOperation', () => {
`);
});

it('serializes operation with optional query and optional + required header parameters', () => {
const operation: OpenApiOperation = {
operationId: 'getFn',
method: 'get',
tags: [],
pathParameters: [],
queryParameters: [
{
in: 'query',
name: 'limit',
originalName: 'limit',
schema: { type: 'number' },
schemaProperties: {},
required: false
},
{
in: 'query',
name: 'page',
originalName: 'page',
schema: { type: 'number' },
schemaProperties: {},
required: false
}
],
headerParameters: [
{
in: 'header',
name: 'authentication',
originalName: 'authentication',
schema: { type: 'string' },
schemaProperties: {},
required: true
},
{
in: 'header',
name: 'resource-group',
originalName: 'resource-group',
schema: { type: 'string' },
schemaProperties: {},
required: false
}
],
responses: { 200: { description: 'some response description' } },
response: { type: 'any' },
pathPattern: 'test'
};

expect(serializeOperation(operation)).toMatchInlineSnapshot(`
"/**
* Create a request builder for execution of get requests to the 'test' endpoint.
* @param queryParameters - Object containing the following keys: limit, page.
* @param headerParameters - Object containing the following keys: authentication, resource-group.
* @returns The request builder, use the \`execute()\` method to trigger the request.
*/
getFn: (queryParameters: {'limit'?: number, 'page'?: number}, headerParameters: {'authentication': string, 'resource-group'?: string}) => new OpenApiRequestBuilder<any>(
'get',
"test",
{
queryParameters,
headerParameters
}
)"
`);
});

it('serializes operation with required query and optional header parameters', () => {
const operation: OpenApiOperation = {
operationId: 'getFn',
Expand Down
20 changes: 13 additions & 7 deletions packages/openapi-generator/src/file-serializer/operation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,24 @@ ${operation.operationId}: (${serializeOperationSignature(
function serializeOperationSignature(operation: OpenApiOperation): string {
const pathParams = serializePathParamsForSignature(operation);
const requestBodyParam = serializeRequestBodyParamForSignature(operation);

const allOptionalHeaders = operation.headerParameters.every(
param => !param.required
);
const allOptionalQuery = operation.queryParameters.every(
param => !param.required
);

const headerParams = serializeParamsForSignature(
operation,
'headerParameters'
'headerParameters',
allOptionalHeaders
);

const queryParams = serializeParamsForSignature(
operation,
'queryParameters',
headerParams?.includes('?')
allOptionalHeaders && allOptionalQuery
);

return [pathParams, requestBodyParam, queryParams, headerParams]
Expand Down Expand Up @@ -75,7 +84,7 @@ function serializeRequestBodyParamForSignature(
function serializeParamsForSignature(
operation: OpenApiOperation,
paramType: 'queryParameters' | 'headerParameters',
canBeAllOptional = true
isAllOptional: boolean
): string | undefined {
const parameters = operation[paramType];
if (parameters.length) {
Expand All @@ -88,10 +97,7 @@ function serializeParamsForSignature(
)
.join(', ');

const allOptional = parameters.every(param => !param.required);
const optionalModifier = allOptional && canBeAllOptional ? '?' : '';

return `${paramType}${optionalModifier}: {${paramsString}}`;
return `${paramType}${isAllOptional ? '?' : ''}: {${paramsString}}`;
}
}

Expand Down

0 comments on commit a566fdd

Please sign in to comment.