diff --git a/.changeset/hot-trees-talk.md b/.changeset/hot-trees-talk.md new file mode 100644 index 0000000000..2955d579bf --- /dev/null +++ b/.changeset/hot-trees-talk.md @@ -0,0 +1,5 @@ +--- +'@sap-cloud-sdk/openapi-generator': minor +--- + +[Fix] Prevent query parameters from being optional when header parameters are required in signature. diff --git a/packages/openapi-generator/src/file-serializer/operation.spec.ts b/packages/openapi-generator/src/file-serializer/operation.spec.ts index 5cef761839..8b34637ceb 100644 --- a/packages/openapi-generator/src/file-serializer/operation.spec.ts +++ b/packages/openapi-generator/src/file-serializer/operation.spec.ts @@ -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( + 'get', + "test", + { + queryParameters, + headerParameters + } + )" + `); + }); + it('serializes operation with required query and optional header parameters', () => { const operation: OpenApiOperation = { operationId: 'getFn', diff --git a/packages/openapi-generator/src/file-serializer/operation.ts b/packages/openapi-generator/src/file-serializer/operation.ts index 73484369d0..51dad2cd3f 100644 --- a/packages/openapi-generator/src/file-serializer/operation.ts +++ b/packages/openapi-generator/src/file-serializer/operation.ts @@ -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] @@ -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) { @@ -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}}`; } }