Skip to content

Commit 760d5e8

Browse files
authored
[normalizer] Better handling of schema with just description (any type) (#20461)
* better handling of schema with just description * update
1 parent 4259e92 commit 760d5e8

File tree

5 files changed

+53
-25
lines changed

5 files changed

+53
-25
lines changed

modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java

+7-4
Original file line numberDiff line numberDiff line change
@@ -1935,7 +1935,7 @@ private static void setNumericValidations(Schema schema, BigDecimal multipleOf,
19351935
private static void logWarnMessagesForIneffectiveValidations(Set<String> setValidations, Schema schema, Set<String> effectiveValidations) {
19361936
setValidations.removeAll(effectiveValidations);
19371937
setValidations.stream().forEach(validation -> {
1938-
LOGGER.warn("Validation '" + validation + "' has no effect on schema '" + getType(schema) +"'. Ignoring!");
1938+
LOGGER.warn("Validation '" + validation + "' has no effect on schema '" + getType(schema) + "'. Ignoring!");
19391939
});
19401940
}
19411941

@@ -2260,11 +2260,14 @@ public static boolean isNullTypeSchema(OpenAPI openAPI, Schema schema) {
22602260
}
22612261

22622262
// for `type: null`
2263-
if (schema.getTypes() == null && schema.get$ref() == null) {
2263+
if (schema.getTypes() == null && schema.get$ref() == null
2264+
&& schema.getDescription() == null) { // ensure it's not schema with just a description)
22642265
return true;
22652266
}
22662267
} else { // 3.0.x or 2.x spec
2267-
if ((schema.getType() == null || schema.getType().equals("null")) && schema.get$ref() == null) {
2268+
if ((schema.getType() == null || schema.getType().equals("null"))
2269+
&& schema.get$ref() == null
2270+
&& schema.getDescription() == null) { // ensure it's not schema with just a description)
22682271
return true;
22692272
}
22702273
}
@@ -2290,7 +2293,7 @@ public static boolean isUnsupportedSchema(OpenAPI openAPI, Schema schema) {
22902293
// dereference the schema
22912294
schema = ModelUtils.getReferencedSchema(openAPI, schema);
22922295

2293-
if (schema.getTypes() == null && hasValidation(schema)) {
2296+
if (schema.getTypes() == null && hasValidation(schema)) {
22942297
// just validation without type
22952298
return true;
22962299
} else if (schema.getIf() != null && schema.getThen() != null) {

modules/openapi-generator/src/test/java/org/openapitools/codegen/utils/ModelUtilsTest.java

+13
Original file line numberDiff line numberDiff line change
@@ -497,9 +497,22 @@ public void isNullTypeSchemaTest() {
497497

498498
schema = openAPI.getComponents().getSchemas().get("AnyOfTest");
499499
assertFalse(ModelUtils.isNullTypeSchema(openAPI, schema));
500+
// first element (getAnyOf().get(0)) is a string. no need to test
500501
assertTrue(ModelUtils.isNullTypeSchema(openAPI, (Schema) schema.getAnyOf().get(1)));
501502
assertTrue(ModelUtils.isNullTypeSchema(openAPI, (Schema) schema.getAnyOf().get(2)));
502503
assertTrue(ModelUtils.isNullTypeSchema(openAPI, (Schema) schema.getAnyOf().get(3)));
504+
505+
schema = openAPI.getComponents().getSchemas().get("OneOfRef");
506+
assertFalse(ModelUtils.isNullTypeSchema(openAPI, schema));
507+
assertFalse(ModelUtils.isNullTypeSchema(openAPI, (Schema) schema.getOneOf().get(0)));
508+
509+
schema = openAPI.getComponents().getSchemas().get("OneOfMultiRef");
510+
assertFalse(ModelUtils.isNullTypeSchema(openAPI, schema));
511+
assertFalse(ModelUtils.isNullTypeSchema(openAPI, (Schema) schema.getOneOf().get(0)));
512+
assertFalse(ModelUtils.isNullTypeSchema(openAPI, (Schema) schema.getOneOf().get(1)));
513+
514+
schema = openAPI.getComponents().getSchemas().get("JustDescription");
515+
assertFalse(ModelUtils.isNullTypeSchema(openAPI, schema));
503516
}
504517

505518
@Test

modules/openapi-generator/src/test/resources/3_0/null_schema_test.yaml

+14-3
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ components:
5656
properties:
5757
dummy:
5858
$ref: '#/components/schemas/IntegerRef'
59-
number:
59+
string_ref:
6060
anyOf:
61-
- $ref: '#/components/schemas/Number'
61+
- $ref: '#/components/schemas/StringRef'
6262
AnyOfStringArrayOfString:
6363
anyOf:
6464
- type: string
@@ -85,6 +85,8 @@ components:
8585
- $ref: '#/components/schemas/IntegerRef'
8686
IntegerRef:
8787
type: integer
88+
StringRef:
89+
type: string
8890
OneOfAnyType:
8991
oneOf:
9092
- type: object
@@ -93,4 +95,13 @@ components:
9395
- type: string
9496
- type: integer
9597
- type: array
96-
items: {}
98+
items: {}
99+
OneOfRef:
100+
oneOf:
101+
- $ref: '#/components/schemas/IntegerRef'
102+
OneOfMultiRef:
103+
oneOf:
104+
- $ref: '#/components/schemas/IntegerRef'
105+
- $ref: '#/components/schemas/StringRef'
106+
JustDescription:
107+
description: A schema with just description

samples/client/petstore/typescript-axios/builds/composed-schemas/api.ts

+17-17
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ export type PetsFilteredPatchRequestPetTypeEnum = typeof PetsFilteredPatchReques
173173
* @type PetsPatchRequest
174174
* @export
175175
*/
176-
export type PetsPatchRequest = Cat | Dog;
176+
export type PetsPatchRequest = Cat | Dog | any;
177177

178178

179179
/**
@@ -217,11 +217,11 @@ export const DefaultApiAxiosParamCreator = function (configuration?: Configurati
217217
},
218218
/**
219219
*
220-
* @param {PetsFilteredPatchRequest | null} [petsFilteredPatchRequest]
220+
* @param {PetsFilteredPatchRequest} [petsFilteredPatchRequest]
221221
* @param {*} [options] Override http request option.
222222
* @throws {RequiredError}
223223
*/
224-
petsFilteredPatch: async (petsFilteredPatchRequest?: PetsFilteredPatchRequest | null, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
224+
petsFilteredPatch: async (petsFilteredPatchRequest?: PetsFilteredPatchRequest, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
225225
const localVarPath = `/pets-filtered`;
226226
// use dummy base URL string because the URL constructor only accepts absolute URLs.
227227
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@@ -250,11 +250,11 @@ export const DefaultApiAxiosParamCreator = function (configuration?: Configurati
250250
},
251251
/**
252252
*
253-
* @param {PetsPatchRequest | null} [petsPatchRequest]
253+
* @param {PetsPatchRequest} [petsPatchRequest]
254254
* @param {*} [options] Override http request option.
255255
* @throws {RequiredError}
256256
*/
257-
petsPatch: async (petsPatchRequest?: PetsPatchRequest | null, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
257+
petsPatch: async (petsPatchRequest?: PetsPatchRequest, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
258258
const localVarPath = `/pets`;
259259
// use dummy base URL string because the URL constructor only accepts absolute URLs.
260260
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@@ -305,23 +305,23 @@ export const DefaultApiFp = function(configuration?: Configuration) {
305305
},
306306
/**
307307
*
308-
* @param {PetsFilteredPatchRequest | null} [petsFilteredPatchRequest]
308+
* @param {PetsFilteredPatchRequest} [petsFilteredPatchRequest]
309309
* @param {*} [options] Override http request option.
310310
* @throws {RequiredError}
311311
*/
312-
async petsFilteredPatch(petsFilteredPatchRequest?: PetsFilteredPatchRequest | null, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
312+
async petsFilteredPatch(petsFilteredPatchRequest?: PetsFilteredPatchRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
313313
const localVarAxiosArgs = await localVarAxiosParamCreator.petsFilteredPatch(petsFilteredPatchRequest, options);
314314
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
315315
const localVarOperationServerBasePath = operationServerMap['DefaultApi.petsFilteredPatch']?.[localVarOperationServerIndex]?.url;
316316
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
317317
},
318318
/**
319319
*
320-
* @param {PetsPatchRequest | null} [petsPatchRequest]
320+
* @param {PetsPatchRequest} [petsPatchRequest]
321321
* @param {*} [options] Override http request option.
322322
* @throws {RequiredError}
323323
*/
324-
async petsPatch(petsPatchRequest?: PetsPatchRequest | null, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
324+
async petsPatch(petsPatchRequest?: PetsPatchRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
325325
const localVarAxiosArgs = await localVarAxiosParamCreator.petsPatch(petsPatchRequest, options);
326326
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
327327
const localVarOperationServerBasePath = operationServerMap['DefaultApi.petsPatch']?.[localVarOperationServerIndex]?.url;
@@ -348,20 +348,20 @@ export const DefaultApiFactory = function (configuration?: Configuration, basePa
348348
},
349349
/**
350350
*
351-
* @param {PetsFilteredPatchRequest | null} [petsFilteredPatchRequest]
351+
* @param {PetsFilteredPatchRequest} [petsFilteredPatchRequest]
352352
* @param {*} [options] Override http request option.
353353
* @throws {RequiredError}
354354
*/
355-
petsFilteredPatch(petsFilteredPatchRequest?: PetsFilteredPatchRequest | null, options?: RawAxiosRequestConfig): AxiosPromise<void> {
355+
petsFilteredPatch(petsFilteredPatchRequest?: PetsFilteredPatchRequest, options?: RawAxiosRequestConfig): AxiosPromise<void> {
356356
return localVarFp.petsFilteredPatch(petsFilteredPatchRequest, options).then((request) => request(axios, basePath));
357357
},
358358
/**
359359
*
360-
* @param {PetsPatchRequest | null} [petsPatchRequest]
360+
* @param {PetsPatchRequest} [petsPatchRequest]
361361
* @param {*} [options] Override http request option.
362362
* @throws {RequiredError}
363363
*/
364-
petsPatch(petsPatchRequest?: PetsPatchRequest | null, options?: RawAxiosRequestConfig): AxiosPromise<void> {
364+
petsPatch(petsPatchRequest?: PetsPatchRequest, options?: RawAxiosRequestConfig): AxiosPromise<void> {
365365
return localVarFp.petsPatch(petsPatchRequest, options).then((request) => request(axios, basePath));
366366
},
367367
};
@@ -387,23 +387,23 @@ export class DefaultApi extends BaseAPI {
387387

388388
/**
389389
*
390-
* @param {PetsFilteredPatchRequest | null} [petsFilteredPatchRequest]
390+
* @param {PetsFilteredPatchRequest} [petsFilteredPatchRequest]
391391
* @param {*} [options] Override http request option.
392392
* @throws {RequiredError}
393393
* @memberof DefaultApi
394394
*/
395-
public petsFilteredPatch(petsFilteredPatchRequest?: PetsFilteredPatchRequest | null, options?: RawAxiosRequestConfig) {
395+
public petsFilteredPatch(petsFilteredPatchRequest?: PetsFilteredPatchRequest, options?: RawAxiosRequestConfig) {
396396
return DefaultApiFp(this.configuration).petsFilteredPatch(petsFilteredPatchRequest, options).then((request) => request(this.axios, this.basePath));
397397
}
398398

399399
/**
400400
*
401-
* @param {PetsPatchRequest | null} [petsPatchRequest]
401+
* @param {PetsPatchRequest} [petsPatchRequest]
402402
* @param {*} [options] Override http request option.
403403
* @throws {RequiredError}
404404
* @memberof DefaultApi
405405
*/
406-
public petsPatch(petsPatchRequest?: PetsPatchRequest | null, options?: RawAxiosRequestConfig) {
406+
public petsPatch(petsPatchRequest?: PetsPatchRequest, options?: RawAxiosRequestConfig) {
407407
return DefaultApiFp(this.configuration).petsPatch(petsPatchRequest, options).then((request) => request(this.axios, this.basePath));
408408
}
409409
}

samples/openapi3/client/petstore/typescript/builds/composed-schemas/models/PetsPatchRequest.ts

+2-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)