@@ -79,6 +79,11 @@ function convertVueTypeToJsonSchema(vueType: string, vueSchema: PropertyMetaSche
7979 return convertEnumToJsonSchema ( vueType , vueSchema )
8080 }
8181
82+ // Handle union types when schema is a string (e.g., "string | number | symbol")
83+ if ( typeof vueSchema === 'string' && vueSchema . includes ( '|' ) ) {
84+ return convertUnionTypeFromString ( vueSchema )
85+ }
86+
8287 // Unwrap enums for optionals/unions
8388 const { type : unwrappedType , schema : unwrappedSchema , enumValues } = unwrapEnumSchema ( vueType , vueSchema )
8489 if ( enumValues && unwrappedType === 'boolean' ) {
@@ -238,6 +243,8 @@ function convertSimpleType(type: string): any {
238243 return { type : 'number' }
239244 case 'boolean' :
240245 return { type : 'boolean' }
246+ case 'symbol' :
247+ return { type : 'string' } // JSON Schema doesn't have symbol type, map to string
241248 case 'object' :
242249 return { type : 'object' }
243250 case 'array' :
@@ -366,7 +373,13 @@ function isEnumType(vueType: string, vueSchema: PropertyMetaSchema): boolean {
366373 v !== 'undefined' &&
367374 ( v === 'true' || v === 'false' )
368375 )
369- return stringLiterals . length > 0 || booleanLiterals . length > 0
376+ // Check if all non-undefined values are primitive types
377+ const primitiveTypes = values . filter ( v =>
378+ v !== 'undefined' &&
379+ typeof v === 'string' &&
380+ [ 'string' , 'number' , 'boolean' , 'symbol' ] . includes ( v )
381+ )
382+ return stringLiterals . length > 0 || booleanLiterals . length > 0 || primitiveTypes . length > 0
370383 }
371384 }
372385
@@ -408,6 +421,8 @@ function convertEnumToJsonSchema(vueType: string, vueSchema: PropertyMetaSchema)
408421 types . add ( 'number' )
409422 } else if ( value === 'boolean' ) {
410423 types . add ( 'boolean' )
424+ } else if ( value === 'symbol' ) {
425+ types . add ( 'symbol' ) // Keep symbol as distinct type for now
411426 }
412427 } else if ( typeof value === 'object' && value !== null ) {
413428 // Complex type like (string & {}) - convert to allOf schema
@@ -452,9 +467,13 @@ function convertEnumToJsonSchema(vueType: string, vueSchema: PropertyMetaSchema)
452467
453468 // Add type if it's consistent
454469 if ( types . size === 1 ) {
455- result . type = Array . from ( types ) [ 0 ]
470+ const type = Array . from ( types ) [ 0 ]
471+ result . type = type === 'symbol' ? 'string' : type
456472 } else if ( types . size > 1 ) {
457- result . type = Array . from ( types )
473+ const mappedTypes = Array . from ( types ) . map ( type => type === 'symbol' ? 'string' : type )
474+ // Remove duplicates after mapping
475+ const uniqueTypes = [ ...new Set ( mappedTypes ) ]
476+ result . type = uniqueTypes . length === 1 ? uniqueTypes [ 0 ] : uniqueTypes
458477 }
459478
460479 // Special case: if it's a boolean enum with just true/false, treat as regular boolean
@@ -468,9 +487,13 @@ function convertEnumToJsonSchema(vueType: string, vueSchema: PropertyMetaSchema)
468487
469488 // If no enum values but we have types, create a union type
470489 if ( types . size > 1 ) {
471- return { type : Array . from ( types ) }
490+ const mappedTypes = Array . from ( types ) . map ( type => type === 'symbol' ? 'string' : type )
491+ // Remove duplicates after mapping
492+ const uniqueTypes = [ ...new Set ( mappedTypes ) ]
493+ return { type : uniqueTypes . length === 1 ? uniqueTypes [ 0 ] : uniqueTypes }
472494 } else if ( types . size === 1 ) {
473- return { type : Array . from ( types ) [ 0 ] }
495+ const type = Array . from ( types ) [ 0 ]
496+ return { type : type === 'symbol' ? 'string' : type }
474497 }
475498 }
476499 }
@@ -575,4 +598,26 @@ function convertIntersectionType(typeString: string): any | null {
575598 }
576599
577600 return null
601+ }
602+
603+ /**
604+ * Convert union type from string to JSON Schema
605+ */
606+ function convertUnionTypeFromString ( unionString : string ) : any {
607+ const types = unionString . split ( '|' ) . map ( t => t . trim ( ) )
608+ const jsonTypes = types . map ( type => {
609+ if ( type === 'symbol' ) {
610+ return 'string' // JSON Schema doesn't have symbol type, map to string
611+ }
612+ return type
613+ } )
614+
615+ // Remove duplicates
616+ const uniqueTypes = [ ...new Set ( jsonTypes ) ]
617+
618+ if ( uniqueTypes . length === 1 ) {
619+ return { type : uniqueTypes [ 0 ] }
620+ } else {
621+ return { type : uniqueTypes }
622+ }
578623}
0 commit comments