@@ -79,6 +79,11 @@ function convertVueTypeToJsonSchema(vueType: string, vueSchema: PropertyMetaSche
79
79
return convertEnumToJsonSchema ( vueType , vueSchema )
80
80
}
81
81
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
+
82
87
// Unwrap enums for optionals/unions
83
88
const { type : unwrappedType , schema : unwrappedSchema , enumValues } = unwrapEnumSchema ( vueType , vueSchema )
84
89
if ( enumValues && unwrappedType === 'boolean' ) {
@@ -238,6 +243,8 @@ function convertSimpleType(type: string): any {
238
243
return { type : 'number' }
239
244
case 'boolean' :
240
245
return { type : 'boolean' }
246
+ case 'symbol' :
247
+ return { type : 'string' } // JSON Schema doesn't have symbol type, map to string
241
248
case 'object' :
242
249
return { type : 'object' }
243
250
case 'array' :
@@ -366,7 +373,13 @@ function isEnumType(vueType: string, vueSchema: PropertyMetaSchema): boolean {
366
373
v !== 'undefined' &&
367
374
( v === 'true' || v === 'false' )
368
375
)
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
370
383
}
371
384
}
372
385
@@ -408,6 +421,8 @@ function convertEnumToJsonSchema(vueType: string, vueSchema: PropertyMetaSchema)
408
421
types . add ( 'number' )
409
422
} else if ( value === 'boolean' ) {
410
423
types . add ( 'boolean' )
424
+ } else if ( value === 'symbol' ) {
425
+ types . add ( 'symbol' ) // Keep symbol as distinct type for now
411
426
}
412
427
} else if ( typeof value === 'object' && value !== null ) {
413
428
// Complex type like (string & {}) - convert to allOf schema
@@ -452,9 +467,13 @@ function convertEnumToJsonSchema(vueType: string, vueSchema: PropertyMetaSchema)
452
467
453
468
// Add type if it's consistent
454
469
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
456
472
} 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
458
477
}
459
478
460
479
// 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)
468
487
469
488
// If no enum values but we have types, create a union type
470
489
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 }
472
494
} 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 }
474
497
}
475
498
}
476
499
}
@@ -575,4 +598,26 @@ function convertIntersectionType(typeString: string): any | null {
575
598
}
576
599
577
600
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
+ }
578
623
}
0 commit comments