diff --git a/src/schema.js b/src/schema.js index a932a6477..3e531e584 100644 --- a/src/schema.js +++ b/src/schema.js @@ -186,16 +186,57 @@ const getObjectTypeContent = (schema) => { const complexTypeGetter = (schema) => getInlineParseContent(schema); const filterContents = (contents, types) => _.filter(contents, (type) => !_.includes(types, type)); +const makeAddRequiredToChildSchema = (parentSchema) => (childSchema) => { + let required = childSchema.required || []; + let properties = childSchema.properties || {}; + + // Inherit all the required fields from the parent schema that are defined + // either on the parent schema or on the child schema + // TODO: any that are defined at grandparents or higher are ignored + required = required.concat( + (parentSchema.required || []).filter( + (key) => + !required.includes(key) && (_.keys(properties).includes(key) || _.keys(parentSchema.properties).includes(key)), + ), + ); + + // Identify properties that are required in the child schema, but + // defined only in the parent schema (TODO: this only works one level deep) + const parentPropertiesRequiredByChild = required.filter( + (key) => !_.keys(childSchema.properties).includes(key) && _.keys(parentSchema.properties).includes(key), + ); + + // Add such properties to the child so that they can be overriden and made required + properties = { + ...properties, + ...parentPropertiesRequiredByChild.reduce( + (additionalProperties, key) => ({ + ...additionalProperties, + [key]: (parentSchema.properties || {})[key], + }), + {}, + ), + }; + + return _.merge( + { + required: required, + properties: properties, + }, + childSchema, + ); +}; + const complexSchemaParsers = { [SCHEMA_TYPES.COMPLEX_ONE_OF]: (schema) => { // T1 | T2 - const combined = _.map(schema.oneOf, complexTypeGetter); + const combined = _.map(schema.oneOf.map(makeAddRequiredToChildSchema(schema)), complexTypeGetter); return checkAndAddNull(schema, filterContents(combined, [TS_KEYWORDS.ANY]).join(" | ")); }, [SCHEMA_TYPES.COMPLEX_ALL_OF]: (schema) => { // T1 & T2 - const combined = _.map(schema.allOf, complexTypeGetter); + const combined = _.map(schema.allOf.map(makeAddRequiredToChildSchema(schema)), complexTypeGetter); return checkAndAddNull( schema, filterContents(combined, [...JS_EMPTY_TYPES, ...JS_PRIMITIVE_TYPES, TS_KEYWORDS.ANY]).join( @@ -205,7 +246,7 @@ const complexSchemaParsers = { }, [SCHEMA_TYPES.COMPLEX_ANY_OF]: (schema) => { // T1 | T2 | (T1 & T2) - const combined = _.map(schema.anyOf, complexTypeGetter); + const combined = _.map(makeAddRequiredToChildSchema(schema), complexTypeGetter); const nonEmptyTypesCombined = filterContents(combined, [ ...JS_EMPTY_TYPES, ...JS_PRIMITIVE_TYPES, diff --git a/tests/generated/v3.0/allof-example.ts b/tests/generated/v3.0/allof-example.ts index 136e591b1..db24ff594 100644 --- a/tests/generated/v3.0/allof-example.ts +++ b/tests/generated/v3.0/allof-example.ts @@ -13,7 +13,7 @@ export interface Pet { pet_type: string; } -export type Dog = Pet & { bark?: boolean; breed?: "Dingo" | "Husky" | "Retriever" | "Shepherd" }; +export type Dog = Pet & { bark?: boolean; breed: "Dingo" | "Husky" | "Retriever" | "Shepherd" }; export type Cat = Pet & { hunts?: boolean; age?: number }; diff --git a/tests/generated/v3.0/full-swagger-scheme.ts b/tests/generated/v3.0/full-swagger-scheme.ts index 54dc34d52..ccb30cdf4 100644 --- a/tests/generated/v3.0/full-swagger-scheme.ts +++ b/tests/generated/v3.0/full-swagger-scheme.ts @@ -10610,9 +10610,41 @@ export class Api extends HttpClient; + } + | ({ description: string } & { + files: Record< + string, + ( + | { content: string } + | { filename: string | null } + | object + | ({ content: string } & { filename: string | null } & object) + ) & { content?: string; filename?: string | null } + >; + }) + ) & { description?: string; - files?: Record; + files?: Record< + string, + ( + | { content: string } + | { filename: string | null } + | object + | ({ content: string } & { filename: string | null } & object) + ) & { content?: string; filename?: string | null } + >; }, params: RequestParams = {}, ) => @@ -15917,9 +15949,21 @@ export class Api extends HttpClient extends HttpClient