@@ -14,28 +14,41 @@ export function transformDefinitions(definitions: Definitions) {
1414 const transformDef = config . transform ?. definition
1515 const patchDefinitions = config . patch ?. definitions || { }
1616
17+ // Map from original interface name to renamed interface name
18+ // Used by parseSchemaType to resolve $ref to renamed interfaces
19+ const nameMapping : Record < string , string > = { }
20+
1721 for ( const [ name , definition ] of Object . entries ( definitions ) ) {
1822 const { properties = { } } = definition
1923
2024 const interfaceName = varName ( name )
2125
22- interfaces . push ( {
23- export : true ,
24- name : interfaceName ,
25- properties : Object . keys ( properties ) . map ( name => defToFields ( name , properties [ name ] ) ) ,
26- } )
27-
2826 // Build a structural type string for this definition so `transform.definition`
2927 // and `patch.definitions` can operate on it.
3028 const baseType = buildDefinitionType ( interfaceName , properties )
31- applyDefinitionTransformsAndPatches ( {
29+ const patchResult = applyDefinitionTransformsAndPatches ( {
3230 baseName : interfaceName ,
3331 baseType,
3432 configRead,
3533 transformDef,
3634 patchDefinitions,
3735 } )
3836
37+ // If patch only renames (no type override), use the new name for the interface
38+ // Otherwise, keep original name and create type alias
39+ const finalInterfaceName = patchResult . shouldRename ? patchResult . aliasName : interfaceName
40+
41+ // Store mapping for parseSchemaType to use
42+ if ( finalInterfaceName !== interfaceName ) {
43+ nameMapping [ interfaceName ] = finalInterfaceName
44+ }
45+
46+ interfaces . push ( {
47+ export : true ,
48+ name : finalInterfaceName ,
49+ properties : Object . keys ( properties ) . map ( name => defToFields ( name , properties [ name ] ) ) ,
50+ } )
51+
3952 function defToFields ( name : string , propertie : Schema ) {
4053 const required = Array . isArray ( definition ?. required ) ? definition . required . includes ( name ) : undefined
4154 const description = propertie . description ? `@description ${ propertie . description } ` : undefined
@@ -47,6 +60,11 @@ export function transformDefinitions(definitions: Definitions) {
4760 }
4861 }
4962 }
63+
64+ // Store name mapping in config for parseSchemaType to use
65+ if ( configRead ?. config ) {
66+ ( configRead . config as any ) . __definitionNameMapping = nameMapping
67+ }
5068}
5169
5270function buildDefinitionType ( interfaceName : string , properties : Definitions [ string ] [ 'properties' ] = { } ) {
@@ -75,13 +93,14 @@ interface DefinitionPatchContext {
7593 * to a single Swagger/OpenAPI definition.
7694 *
7795 * Semantics:
78- * - Rename only: `'UserDto ': 'User '` → `export type User = UserDto `
96+ * - Rename only (string or name only) : `'Order ': 'OrderDTO '` → interface renamed to `OrderDTO `
7997 * - Rename + override type:
8098 * `'SessionDto': { name: 'Session', type: '{ name: string }' }`
81- * → `export type Session = { name: string }`
99+ * → interface stays `SessionDto`, creates `export type Session = { name: string }`
82100 *
83- * The original interface (e.g. `UserDto`) is preserved so existing references
84- * from schemas remain valid; patches add friendly alias types on top.
101+ * When only renaming, the interface itself is renamed so all references automatically
102+ * use the new name. When type is overridden, the original interface is preserved
103+ * and a type alias is created.
85104 */
86105function applyDefinitionTransformsAndPatches ( ctx : DefinitionPatchContext ) {
87106 const {
@@ -94,6 +113,7 @@ function applyDefinitionTransformsAndPatches(ctx: DefinitionPatchContext) {
94113
95114 let aliasName = baseName
96115 let aliasType = baseType
116+ let hasTypeOverride = false
97117
98118 function applyPatch ( patch ?: ApiPipeline . Definition ) {
99119 if ( ! patch )
@@ -106,8 +126,10 @@ function applyDefinitionTransformsAndPatches(ctx: DefinitionPatchContext) {
106126
107127 if ( patch . name )
108128 aliasName = patch . name
109- if ( patch . type )
129+ if ( patch . type ) {
110130 aliasType = patch . type
131+ hasTypeOverride = true
132+ }
111133 }
112134
113135 // Global transform first.
@@ -124,14 +146,22 @@ function applyDefinitionTransformsAndPatches(ctx: DefinitionPatchContext) {
124146 const hasTypeChange = aliasType !== baseType
125147
126148 if ( ! hasNameChange && ! hasTypeChange )
127- return
149+ return { aliasName : baseName , shouldRename : false }
128150
129- const aliasValue = hasTypeChange ? aliasType : baseName
151+ // If only renaming (no type override), rename the interface itself
152+ // Otherwise, create a type alias
153+ const shouldRename = hasNameChange && ! hasTypeOverride
130154
131- configRead . graphs . typings = configRead . graphs . typings || [ ]
132- configRead . graphs . typings . push ( {
133- export : true ,
134- name : aliasName ,
135- value : aliasValue ,
136- } )
155+ if ( ! shouldRename ) {
156+ // Create type alias when type is overridden
157+ const aliasValue = hasTypeChange ? aliasType : baseName
158+ configRead . graphs . typings = configRead . graphs . typings || [ ]
159+ configRead . graphs . typings . push ( {
160+ export : true ,
161+ name : aliasName ,
162+ value : aliasValue ,
163+ } )
164+ }
165+
166+ return { aliasName, shouldRename }
137167}
0 commit comments