@@ -63,12 +63,7 @@ const getTypeAlias = (rawSchema) => {
6363} ;
6464
6565const getEnumNames = ( schema ) => {
66- return (
67- schema [ "x-enumNames" ] ||
68- schema [ "xEnumNames" ] ||
69- schema [ "x-enumnames" ] ||
70- schema [ "x-enum-varnames" ]
71- ) ;
66+ return schema [ "x-enumNames" ] || schema [ "xEnumNames" ] || schema [ "x-enumnames" ] || schema [ "x-enum-varnames" ] ;
7267} ;
7368
7469const getInternalSchemaType = ( schema ) => {
@@ -151,9 +146,7 @@ const getObjectTypeContent = (schema) => {
151146 ! _ . isUndefined ( property . maximum ) && `@max ${ property . maximum } ` ,
152147 ! _ . isUndefined ( property . pattern ) && `@pattern ${ property . pattern } ` ,
153148 ! _ . isUndefined ( property . example ) &&
154- `@example ${
155- _ . isObject ( property . example ) ? JSON . stringify ( property . example ) : property . example
156- } `,
149+ `@example ${ _ . isObject ( property . example ) ? JSON . stringify ( property . example ) : property . example } ` ,
157150 ] ) . join ( "\n" ) ,
158151 isRequired : required ,
159152 isNullable : nullable ,
@@ -178,44 +171,69 @@ const getObjectTypeContent = (schema) => {
178171const complexTypeGetter = ( schema ) => getInlineParseContent ( schema ) ;
179172const filterContents = ( contents , types ) => _ . filter ( contents , ( type ) => ! _ . includes ( types , type ) ) ;
180173
174+ const makeAddRequiredToChildSchema = ( parentSchema ) => ( childSchema ) => {
175+ let required = childSchema . required || [ ] ;
176+ let properties = childSchema . properties || { } ;
177+
178+ // Inherit all the required fields from the parent schema that are defined
179+ // either on the parent schema or on the child schema
180+ // TODO: any that are defined at grandparents or higher are ignored
181+ required = required . concat (
182+ ( parentSchema . required || [ ] ) . filter (
183+ ( key ) =>
184+ ! required . includes ( key ) && ( _ . keys ( properties ) . includes ( key ) || _ . keys ( parentSchema . properties ) . includes ( key ) ) ,
185+ ) ,
186+ ) ;
187+
188+ // Identify properties that are required in the child schema, but
189+ // defined only in the parent schema (TODO: this only works one level deep)
190+ const parentPropertiesRequiredByChild = required . filter (
191+ ( key ) => ! _ . keys ( childSchema . properties ) . includes ( key ) && _ . keys ( parentSchema . properties ) . includes ( key ) ,
192+ ) ;
193+
194+ // Add such properties to the child so that they can be overriden and made required
195+ properties = {
196+ ...properties ,
197+ ...parentPropertiesRequiredByChild . reduce (
198+ ( additionalProperties , key ) => ( {
199+ ...additionalProperties ,
200+ [ key ] : ( parentSchema . properties || { } ) [ key ] ,
201+ } ) ,
202+ { } ,
203+ ) ,
204+ } ;
205+
206+ return _ . merge (
207+ {
208+ required : required ,
209+ properties : properties ,
210+ } ,
211+ childSchema ,
212+ ) ;
213+ } ;
214+
181215const complexSchemaParsers = {
182216 [ SCHEMA_TYPES . COMPLEX_ONE_OF ] : ( schema ) => {
183217 // T1 | T2
184- const combined = _ . map (
185- schema . oneOf . map ( ( s ) => _ . merge ( { required : schema . required } , s ) ) ,
186- complexTypeGetter ,
187- ) ;
218+ const combined = _ . map ( schema . oneOf . map ( makeAddRequiredToChildSchema ( schema ) ) , complexTypeGetter ) ;
188219
189220 return checkAndAddNull ( schema , filterContents ( combined , [ TS_KEYWORDS . ANY ] ) . join ( " | " ) ) ;
190221 } ,
191222 [ SCHEMA_TYPES . COMPLEX_ALL_OF ] : ( schema ) => {
192223 // T1 & T2
193- const combined = _ . map (
194- schema . allOf . map ( ( s ) => _ . merge ( { required : schema . required } , s ) ) ,
195- complexTypeGetter ,
196- ) ;
224+ const combined = _ . map ( schema . allOf . map ( makeAddRequiredToChildSchema ( schema ) ) , complexTypeGetter ) ;
197225 return checkAndAddNull (
198226 schema ,
199- filterContents ( combined , [ ...JS_EMPTY_TYPES , ...JS_PRIMITIVE_TYPES , TS_KEYWORDS . ANY ] ) . join (
200- " & " ,
201- ) ,
227+ filterContents ( combined , [ ...JS_EMPTY_TYPES , ...JS_PRIMITIVE_TYPES , TS_KEYWORDS . ANY ] ) . join ( " & " ) ,
202228 ) ;
203229 } ,
204230 [ SCHEMA_TYPES . COMPLEX_ANY_OF ] : ( schema ) => {
205231 // T1 | T2 | (T1 & T2)
206- const combined = _ . map (
207- schema . anyOf . map ( ( s ) => _ . merge ( { required : schema . required } , s ) ) ,
208- complexTypeGetter ,
209- ) ;
210- const nonEmptyTypesCombined = filterContents ( combined , [
211- ...JS_EMPTY_TYPES ,
212- ...JS_PRIMITIVE_TYPES ,
213- TS_KEYWORDS . ANY ,
214- ] ) ;
232+ const combined = _ . map ( schema . anyOf . map ( makeAddRequiredToChildSchema ( schema ) ) , complexTypeGetter ) ;
233+ const nonEmptyTypesCombined = filterContents ( combined , [ ...JS_EMPTY_TYPES , ...JS_PRIMITIVE_TYPES , TS_KEYWORDS . ANY ] ) ;
215234 return checkAndAddNull (
216235 schema ,
217- `${ combined . join ( " | " ) } ` +
218- ( nonEmptyTypesCombined . length > 1 ? ` | (${ nonEmptyTypesCombined . join ( " & " ) } )` : "" ) ,
236+ `${ combined . join ( " | " ) } ` + ( nonEmptyTypesCombined . length > 1 ? ` | (${ nonEmptyTypesCombined . join ( " & " ) } )` : "" ) ,
219237 ) ;
220238 } ,
221239 // TODO
@@ -236,8 +254,7 @@ const getComplexType = (schema) => {
236254} ;
237255
238256const attachParsedRef = ( originalSchema , parsedSchema ) => {
239- const parsedSchemaAfterHook =
240- config . hooks . onParseSchema ( originalSchema , parsedSchema ) || parsedSchema ;
257+ const parsedSchemaAfterHook = config . hooks . onParseSchema ( originalSchema , parsedSchema ) || parsedSchema ;
241258
242259 if ( originalSchema ) {
243260 originalSchema . $parsed = parsedSchemaAfterHook ;
@@ -272,12 +289,7 @@ const schemaParsers = {
272289 return {
273290 key : formattedKey ,
274291 type : keyType ,
275- value :
276- enumValue === null
277- ? enumValue
278- : isIntegerOrBooleanEnum
279- ? `${ enumValue } `
280- : `"${ enumValue } "` ,
292+ value : enumValue === null ? enumValue : isIntegerOrBooleanEnum ? `${ enumValue } ` : `"${ enumValue } "` ,
281293 } ;
282294 } ) ;
283295 } else {
@@ -299,9 +311,7 @@ const schemaParsers = {
299311 type : SCHEMA_TYPES . ENUM ,
300312 keyType : keyType ,
301313 typeIdentifier :
302- config . generateUnionEnums || ( ! enumNames && isIntegerOrBooleanEnum )
303- ? TS_KEYWORDS . TYPE
304- : TS_KEYWORDS . ENUM ,
314+ config . generateUnionEnums || ( ! enumNames && isIntegerOrBooleanEnum ) ? TS_KEYWORDS . TYPE : TS_KEYWORDS . ENUM ,
305315 name : typeName ,
306316 description : formatDescription ( schema . description ) ,
307317 content,
@@ -340,8 +350,7 @@ const schemaParsers = {
340350 content :
341351 _ . compact ( [
342352 complexSchemaContent && `(${ complexSchemaContent } )` ,
343- getInternalSchemaType ( simpleSchema ) === TS_KEYWORDS . OBJECT &&
344- getInlineParseContent ( simpleSchema ) ,
353+ getInternalSchemaType ( simpleSchema ) === TS_KEYWORDS . OBJECT && getInlineParseContent ( simpleSchema ) ,
345354 ] ) . join ( " & " ) || TS_KEYWORDS . ANY ,
346355 } ) ;
347356 } ,
@@ -409,10 +418,7 @@ const parseSchema = (rawSchema, typeName, formattersMap) => {
409418 parsedSchema = schemaParsers [ schemaType ] ( fixedRawSchema , typeName ) ;
410419 }
411420
412- return (
413- ( formattersMap && formattersMap [ schemaType ] && formattersMap [ schemaType ] ( parsedSchema ) ) ||
414- parsedSchema
415- ) ;
421+ return ( formattersMap && formattersMap [ schemaType ] && formattersMap [ schemaType ] ( parsedSchema ) ) || parsedSchema ;
416422} ;
417423
418424const parseSchemas = ( components ) =>
@@ -421,8 +427,7 @@ const parseSchemas = (components) =>
421427const getInlineParseContent = ( rawTypeData , typeName = null ) =>
422428 parseSchema ( rawTypeData , typeName , inlineExtraFormatters ) . content ;
423429
424- const getParseContent = ( rawTypeData , typeName = null ) =>
425- parseSchema ( rawTypeData , typeName ) . content ;
430+ const getParseContent = ( rawTypeData , typeName = null ) => parseSchema ( rawTypeData , typeName ) . content ;
426431
427432module . exports = {
428433 types,
0 commit comments