1- import type { Schema } from 'openapi-specification-types '
2- import { isArray , uniq } from '@hairy/utils '
1+ import type { StatementInterface } from '@genapi/shared '
2+ import type { StatementField } from '@genapi/shared/dist/index.mjs '
33
4+ import type { Properties , Schema } from 'openapi-specification-types'
5+ import { isArray , uniq } from '@hairy/utils'
46import { spliceEnumType , useRefMap , varName } from '../utils'
57
68/**
79 * parse schema to type
810 * @param propertie
911 */
10- export function parseSchemaType ( propertie : Schema ) : string {
12+ export function parseSchemaType ( propertie : Schema , interfaces : StatementInterface [ ] = [ ] ) : string {
1113 if ( ! propertie )
1214 return 'any'
1315 if ( propertie . originalRef )
@@ -16,9 +18,61 @@ export function parseSchemaType(propertie: Schema): string {
1618 if ( propertie . $ref )
1719 return varName ( useRefMap ( propertie . $ref ) )
1820
21+ // Handle allOf: merge multiple schemas, typically used for generic response types
22+ if ( propertie . allOf ) {
23+ const fields : Record < string , StatementField > = { }
24+ let base = 'Anonymous'
25+
26+ // Merge all schema attributes in allOf
27+ for ( const schema of propertie . allOf ) {
28+ // Handling $ref references: merging properties of reference interfaces
29+ assignBaseProperties ( schema )
30+ // Processing direct attributes of schema
31+ assignProperties ( schema . properties )
32+ }
33+
34+ assignProperties ( propertie . properties )
35+
36+ function assignBaseProperties ( schema : Schema ) {
37+ if ( ! schema . $ref )
38+ return
39+ const type = parseSchemaType ( schema , interfaces )
40+ const interfaceItem = interfaces . find ( v => v . name === type )
41+ if ( ! interfaceItem )
42+ return
43+ for ( const property of interfaceItem . properties || [ ] ) {
44+ fields [ property . name ] = property
45+ }
46+ base = interfaceItem . name
47+ }
48+ function assignProperties ( properties ?: Properties ) {
49+ for ( const [ field , item ] of Object . entries ( properties || { } ) ) {
50+ const type = parseSchemaType ( item , interfaces )
51+ if ( item . $ref )
52+ base = type
53+ fields [ field ] = {
54+ type,
55+ required : item . required ,
56+ description : item . description ,
57+ name : field ,
58+ }
59+ }
60+ }
61+
62+ // generate a unique interface name
63+ let name = `AllOf${ base } `
64+ let counter = 1
65+ while ( interfaces . some ( v => v . name === name ) ) {
66+ name = `AllOf${ base } ${ counter ++ } `
67+ }
68+ interfaces . push ( { name, properties : Object . values ( fields ) , export : true } )
69+ return name
70+ }
71+
1972 if ( propertie . schema )
20- return parseSchemaType ( propertie . schema )
73+ return parseSchemaType ( propertie . schema , interfaces )
2174
75+ // TODO: handle additionalProperties
2276 if ( propertie . additionalProperties )
2377 return `Record<string, ${ parseSchemaType ( propertie . additionalProperties ) } >`
2478
0 commit comments