@@ -3,6 +3,8 @@ const _ = require("lodash");
33const { SchemaFormatters } = require ( "./schema-formatters" ) ;
44const { internalCase } = require ( "../util/internal-case" ) ;
55const { SchemaUtils } = require ( "./schema-utils" ) ;
6+ const { camelCase } = require ( "lodash" ) ;
7+ const { pascalCase } = require ( "../util/pascal-case" ) ;
68
79class SchemaParser {
810 /**
@@ -28,6 +30,8 @@ class SchemaParser {
2830 */
2931 schemaUtils ;
3032
33+ $processingSchemaPath = [ ] ;
34+
3135 constructor ( config , logger , templates , schemaComponentsMap , typeName ) {
3236 this . config = config ;
3337 this . schemaComponentsMap = schemaComponentsMap ;
@@ -87,13 +91,16 @@ class SchemaParser {
8791
8892 baseSchemaParsers = {
8993 [ SCHEMA_TYPES . ENUM ] : ( schema , typeName ) => {
94+ if ( this . config . extractEnums && ! typeName ) {
95+ const generatedTypeName = this . config . componentTypeNameResolver . resolve ( [ this . buildTypeNameFromPath ( ) ] ) ;
96+ const schemaComponent = this . schemaComponentsMap . createComponent ( "schemas" , generatedTypeName , { ...schema } ) ;
97+ return this . parseSchema ( schemaComponent , generatedTypeName ) ;
98+ }
99+
90100 const refType = this . schemaUtils . getSchemaRefType ( schema ) ;
91101 const $ref = ( refType && refType . $ref ) || null ;
92- const enumNamesAsValues = this . config . enumNamesAsValues ;
93102 const keyType = this . getSchemaType ( schema ) ;
94103 const enumNames = this . schemaUtils . getEnumNames ( schema ) ;
95- const isIntegerOrBooleanEnum =
96- keyType === this . getSchemaType ( { type : "number" } ) || keyType === this . getSchemaType ( { type : "boolean" } ) ;
97104 let content = null ;
98105
99106 const formatValue = ( value ) => {
@@ -114,10 +121,19 @@ class SchemaParser {
114121 content = _ . map ( enumNames , ( enumName , index ) => {
115122 const enumValue = _ . get ( schema . enum , index ) ;
116123 const formattedKey =
117- ( enumName && this . typeName . format ( enumName , { ignorePrefix : true , ignoreSuffix : true } ) ) ||
118- this . typeName . format ( enumValue , { ignorePrefix : true , ignoreSuffix : true } ) ;
119-
120- if ( enumNamesAsValues || _ . isUndefined ( enumValue ) ) {
124+ ( enumName &&
125+ this . typeName . format ( enumName , {
126+ ignorePrefix : true ,
127+ ignoreSuffix : true ,
128+ type : "enum-key" ,
129+ } ) ) ||
130+ this . typeName . format ( `${ enumValue } ` , {
131+ ignorePrefix : true ,
132+ ignoreSuffix : true ,
133+ type : "enum-key" ,
134+ } ) ;
135+
136+ if ( this . config . enumNamesAsValues || _ . isUndefined ( enumValue ) ) {
121137 return {
122138 key : formattedKey ,
123139 type : this . config . Ts . Keyword . String ,
@@ -134,7 +150,11 @@ class SchemaParser {
134150 } else {
135151 content = _ . map ( schema . enum , ( key ) => {
136152 return {
137- key : isIntegerOrBooleanEnum ? key : this . typeName . format ( key , { ignorePrefix : true , ignoreSuffix : true } ) ,
153+ key : this . typeName . format ( `${ key } ` , {
154+ ignorePrefix : true ,
155+ ignoreSuffix : true ,
156+ type : "enum-key" ,
157+ } ) ,
138158 type : keyType ,
139159 value : formatValue ( key ) ,
140160 } ;
@@ -149,10 +169,7 @@ class SchemaParser {
149169 schemaType : SCHEMA_TYPES . ENUM ,
150170 type : SCHEMA_TYPES . ENUM ,
151171 keyType : keyType ,
152- typeIdentifier :
153- this . config . generateUnionEnums || ( ! enumNames && isIntegerOrBooleanEnum )
154- ? this . config . Ts . Keyword . Type
155- : this . config . Ts . Keyword . Enum ,
172+ typeIdentifier : this . config . generateUnionEnums ? this . config . Ts . Keyword . Type : this . config . Ts . Keyword . Enum ,
156173 name : typeName ,
157174 description : this . schemaFormatters . formatDescription ( schema . description ) ,
158175 content,
@@ -276,13 +293,16 @@ class SchemaParser {
276293 const { properties, additionalProperties } = schema || { } ;
277294
278295 const propertiesContent = _ . map ( properties , ( property , name ) => {
296+ this . $processingSchemaPath . push ( name ) ;
279297 const required = this . schemaUtils . isPropertyRequired ( name , property , schema ) ;
280298 const rawTypeData = _ . get ( this . schemaUtils . getSchemaRefType ( property ) , "rawTypeData" , { } ) ;
281299 const nullable = ! ! ( rawTypeData . nullable || property . nullable ) ;
282300 const fieldName = this . typeName . isValidName ( name ) ? name : this . config . Ts . StringValue ( name ) ;
283301 const fieldValue = this . getInlineParseContent ( property ) ;
284302 const readOnly = property . readOnly ;
285303
304+ this . $processingSchemaPath . pop ( ) ;
305+
286306 return {
287307 ...property ,
288308 $$raw : property ,
@@ -353,12 +373,17 @@ class SchemaParser {
353373 if ( schema . items && ! schema . type ) {
354374 schema . type = SCHEMA_TYPES . ARRAY ;
355375 }
356-
357376 schemaType = this . getInternalSchemaType ( schema ) ;
377+
378+ this . $processingSchemaPath . push ( typeName ) ;
379+
380+ _ . merge ( schema , this . config . hooks . onPreParseSchema ( schema , typeName , schemaType ) ) ;
358381 parsedSchema = this . baseSchemaParsers [ schemaType ] ( schema , typeName ) ;
359382 schema . $parsed = this . config . hooks . onParseSchema ( schema , parsedSchema ) || parsedSchema ;
360383 }
361384
385+ this . $processingSchemaPath . pop ( ) ;
386+
362387 return schema . $parsed ;
363388 } ;
364389
@@ -373,6 +398,14 @@ class SchemaParser {
373398 const formattedSchema = this . schemaFormatters . formatSchema ( parsedSchema , "base" ) ;
374399 return formattedSchema . content ;
375400 } ;
401+
402+ buildTypeNameFromPath = ( ) => {
403+ const schemaPath = _ . uniq ( _ . compact ( this . $processingSchemaPath ) ) ;
404+
405+ if ( ! schemaPath || ! schemaPath [ 0 ] ) return null ;
406+
407+ return internalCase ( camelCase ( `${ schemaPath [ 0 ] } _${ schemaPath [ schemaPath . length - 1 ] } ` ) ) ;
408+ } ;
376409}
377410
378411module . exports = {
0 commit comments