@@ -73,6 +73,53 @@ interface OpenAPIGeneratorOptions {
73
73
* ! be careful that the folder will be removed after the process ends
74
74
*/
75
75
tmpRoot ?: string
76
+
77
+ /**
78
+ * disable log
79
+ * @default false
80
+ */
81
+ silent ?: boolean
82
+ }
83
+
84
+ function extractRootObjects ( code : string ) {
85
+ const results = [ ]
86
+ let i = 0
87
+
88
+ while ( i < code . length ) {
89
+ // find the next colon
90
+ const colonIdx = code . indexOf ( ':' , i )
91
+ if ( colonIdx === - 1 ) break
92
+
93
+ // backtrack to find the key (simple word characters)
94
+ let keyEnd = colonIdx - 1
95
+ while ( keyEnd >= 0 && / \s / . test ( code [ keyEnd ] ) ) keyEnd --
96
+ let keyStart = keyEnd
97
+ while ( keyStart >= 0 && / \w / . test ( code [ keyStart ] ) ) keyStart --
98
+
99
+ // find the opening brace after colon
100
+ const braceIdx = code . indexOf ( '{' , colonIdx )
101
+ if ( braceIdx === - 1 ) break
102
+
103
+ // scan braces
104
+ let depth = 0
105
+ let end = braceIdx
106
+ for ( ; end < code . length ; end ++ ) {
107
+ if ( code [ end ] === '{' ) depth ++
108
+ else if ( code [ end ] === '}' ) {
109
+ depth --
110
+ if ( depth === 0 ) {
111
+ end ++ // move past closing brace
112
+ break
113
+ }
114
+ }
115
+ }
116
+
117
+ results . push ( `{${ code . slice ( keyStart + 1 , end ) } ;}` )
118
+
119
+ i = end
120
+ }
121
+
122
+ return results
76
123
}
77
124
78
125
/**
@@ -97,7 +144,8 @@ export const fromTypes =
97
144
overrideOutputPath,
98
145
debug = false ,
99
146
compilerOptions,
100
- tmpRoot = join ( tmpdir ( ) , '.ElysiaAutoOpenAPI' )
147
+ tmpRoot = join ( tmpdir ( ) , '.ElysiaAutoOpenAPI' ) ,
148
+ silent = false
101
149
} : OpenAPIGeneratorOptions = { }
102
150
) =>
103
151
( ) => {
@@ -177,7 +225,7 @@ export const fromTypes =
177
225
spawnSync ( `tsc` , {
178
226
shell : true ,
179
227
cwd : tmpRoot ,
180
- stdio : debug ? 'inherit' : undefined
228
+ stdio : silent ? undefined : 'inherit'
181
229
} )
182
230
183
231
const fileName = targetFilePath
@@ -235,7 +283,7 @@ export const fromTypes =
235
283
console . warn ( tempFiles )
236
284
}
237
285
} else {
238
- console . log (
286
+ console . warn (
239
287
"reason: root folder doesn't exists" ,
240
288
join ( tmpRoot , 'dist' )
241
289
)
@@ -247,8 +295,10 @@ export const fromTypes =
247
295
248
296
const declaration = readFileSync ( targetFile , 'utf8' )
249
297
298
+ // console.log(declaration, targetFile)
299
+
250
300
// Check just in case of race-condition
251
- if ( existsSync ( tmpRoot ) )
301
+ if ( ! debug && existsSync ( tmpRoot ) )
252
302
rmSync ( tmpRoot , { recursive : true , force : true } )
253
303
254
304
let instance = declaration . match (
@@ -282,11 +332,8 @@ export const fromTypes =
282
332
const routes : AdditionalReference = { }
283
333
284
334
// Treaty is a collection of { ... } & { ... } & { ... }
285
- // Each route will be intersected with each other
286
- // instead of being nested in a route object
287
- for ( const route of routesString . slice ( 1 ) . split ( '} & {' ) ) {
288
- // as ' } & {' is removed, we need to add it back
289
- let schema = TypeBox ( `{${ route } }` )
335
+ for ( const route of extractRootObjects ( routesString ) ) {
336
+ let schema = TypeBox ( route )
290
337
if ( schema . type !== 'object' ) continue
291
338
292
339
const paths = [ ]
@@ -302,6 +349,9 @@ export const fromTypes =
302
349
}
303
350
304
351
const method = paths . pop ( ) !
352
+ // For whatever reason, if failed to infer route correctly
353
+ if ( ! method ) continue
354
+
305
355
const path = '/' + paths . join ( '/' )
306
356
schema = schema . properties
307
357
0 commit comments