11/* eslint-disable no-restricted-syntax */
22
3- import { join , relative } from "node:path" ;
3+ import { join } from "node:path" ;
44import { $RefParser } from "@apidevtools/json-schema-ref-parser" ;
55import type { oas30 , oas31 } from "openapi3-ts" ;
66import toposort from "toposort" ;
@@ -79,13 +79,16 @@ function createUnion(...types: (string | undefined)[]) {
7979 // create a type of all the inputs
8080 const [ type1 , type2 , ...typeX ] = types
8181 . filter ( ( t ) : t is string => ! ! t )
82- . sort ( ( a , b ) => a . localeCompare ( b ) ) ;
82+ . toSorted ( ( a , b ) => a . localeCompare ( b ) ) ;
8383 return (
8484 ( type1 && type2 ? Writers . unionType ( type1 , type2 , ...typeX ) : type1 ) ||
8585 neverKeyword
8686 ) ;
8787}
8888
89+ const isInput = ( t : TypeAliasDeclaration | InterfaceDeclaration ) =>
90+ t . getName ( ) ?. endsWith ( "Input" ) ;
91+
8992export async function processOpenApiDocument (
9093 outputDir : string ,
9194 schema : Simplify < oas31 . OpenAPIObject > ,
@@ -187,9 +190,7 @@ export async function processOpenApiDocument(
187190 const valibotModuleSpecifier = `./${ valibotFile . getBaseNameWithoutExtension ( ) } .js` ;
188191 const commandValibotImports = new Set < string > ( ) ;
189192
190- const typesModuleSpecifier =
191- `./${ typesFile . getBaseNameWithoutExtension ( ) } .js` ||
192- relative ( commandsFile . getDirectoryPath ( ) , typesFile . getFilePath ( ) ) ;
193+ const typesModuleSpecifier = `./${ typesFile . getBaseNameWithoutExtension ( ) } .js` ;
193194
194195 const typesImportDecl =
195196 commandsFile
@@ -236,9 +237,11 @@ export async function processOpenApiDocument(
236237 } ,
237238 ) ;
238239
239- const sorted = toposort ( schemaGraph ) . reverse ( ) ;
240+ const sorted = toposort ( schemaGraph ) . toReversed ( ) ;
240241
241- const sortedSchemas = Object . entries ( schema . components ?. schemas || { } ) . sort (
242+ const sortedSchemas = Object . entries (
243+ schema . components ?. schemas || { } ,
244+ ) . toSorted (
242245 ( [ a ] , [ b ] ) =>
243246 sorted . indexOf ( `#/components/schemas/${ a } ` ) -
244247 sorted . indexOf ( `#/components/schemas/${ b } ` ) ,
@@ -276,11 +279,10 @@ export async function processOpenApiDocument(
276279 ? [
277280 {
278281 description : wordWrap ( schemaObject . description ) ,
279- tags : [
280- ...( schemaObject . deprecated
281- ? [ { tagName : "deprecated" } ]
282- : [ ] ) ,
283- ] . filter ( Boolean ) ,
282+ tags : ( schemaObject . deprecated
283+ ? [ { tagName : "deprecated" } ]
284+ : [ ]
285+ ) . filter ( Boolean ) ,
284286 } ,
285287 ]
286288 : [ ] ,
@@ -291,7 +293,9 @@ export async function processOpenApiDocument(
291293 writer . write ( "[" ) ;
292294 values . forEach ( ( value , index ) => {
293295 writer . write ( JSON . stringify ( value ) ) ;
294- if ( index < values . length - 1 ) writer . write ( ", " ) ;
296+ if ( index < values . length - 1 ) {
297+ writer . write ( ", " ) ;
298+ }
295299 } ) ;
296300 writer . write ( "]" ) ;
297301 } , "const" ) ,
@@ -359,16 +363,14 @@ export async function processOpenApiDocument(
359363 operationObject . description || commandName ,
360364 ) } \n`,
361365
362- tags : [
363- ...( operationObject . summary
364- ? [
365- {
366- tagName : "summary" ,
367- text : wordWrap ( operationObject . summary ) ,
368- } ,
369- ]
370- : [ ] ) ,
371- ] ,
366+ tags : operationObject . summary
367+ ? [
368+ {
369+ tagName : "summary" ,
370+ text : wordWrap ( operationObject . summary ) ,
371+ } ,
372+ ]
373+ : [ ] ,
372374 } ;
373375
374376 const jsdoc = commandClassDeclaration . addJsDoc ( jsDocStructure ) ;
@@ -489,13 +491,18 @@ export async function processOpenApiDocument(
489491 } ,
490492 ) ;
491493
492- const resolvedType = qp . required
493- ? type . type
494- : typeof type . type === "function"
495- ? type . type
496- : type . type
497- ? Writers . unionType ( `${ type . type } ` , "undefined" )
498- : undefined ;
494+ const resolvedType = iife ( ( ) => {
495+ if ( qp . required ) {
496+ return type . type ;
497+ }
498+ if ( typeof type . type === "function" ) {
499+ return type . type ;
500+ }
501+ if ( type . type ) {
502+ return Writers . unionType ( `${ type . type } ` , "undefined" ) ;
503+ }
504+ return undefined ;
505+ } ) ;
499506
500507 return {
501508 ...type ,
@@ -963,34 +970,43 @@ export async function processOpenApiDocument(
963970 } ) ;
964971 }
965972
966- // Resolve response schema from the 2xx response $ref
973+ // Resolve response schema from the first 2xx response $ref
967974 const responseRef = iife ( ( ) => {
968- for ( const [ statusCode , response ] of Object . entries (
975+ const firstSuccess = Object . entries (
969976 operationObject . responses ?? { } ,
970- ) . filter ( ( [ s ] ) => s . startsWith ( "2" ) ) ) {
971- if ( statusCode === "204" || "$ref" in response ) return undefined ;
972- const jsonResp = response . content ?. [ "application/json" ] ;
973- if ( ! jsonResp ?. schema ) return undefined ;
974- if ( "$ref" in jsonResp . schema ) return jsonResp . schema . $ref ;
975- if (
976- "items" in jsonResp . schema &&
977- "$ref" in jsonResp . schema . items
978- ) {
979- return jsonResp . schema . items . $ref ;
980- }
977+ ) . find ( ( [ s ] ) => s . startsWith ( "2" ) ) ;
978+ if ( ! firstSuccess ) {
979+ return undefined ;
980+ }
981+ const [ statusCode , response ] = firstSuccess ;
982+ if ( statusCode === "204" || "$ref" in response ) {
981983 return undefined ;
982984 }
985+ const responseSchema =
986+ response . content ?. [ "application/json" ] ?. schema ;
987+ if ( ! responseSchema ) {
988+ return undefined ;
989+ }
990+ if ( "$ref" in responseSchema ) {
991+ return responseSchema . $ref ;
992+ }
993+ if ( "items" in responseSchema && "$ref" in responseSchema . items ) {
994+ return responseSchema . items . $ref ;
995+ }
983996 return undefined ;
984997 } ) ;
985998
986999 const responseSchemaEntry = responseRef
9871000 ? validators . get ( responseRef )
9881001 : undefined ;
989- const responseSchemaName = responseSchemaEntry
990- ? options ?. exactOnly
1002+ const responseSchemaName = iife ( ( ) => {
1003+ if ( ! responseSchemaEntry ) {
1004+ return undefined ;
1005+ }
1006+ return options ?. exactOnly
9911007 ? responseSchemaEntry . exact
992- : responseSchemaEntry . coerced
993- : undefined ;
1008+ : responseSchemaEntry . coerced ;
1009+ } ) ;
9941010
9951011 if ( responseSchemaName ) {
9961012 staticSchemaProps . push ( {
@@ -1145,28 +1161,30 @@ export async function processOpenApiDocument(
11451161
11461162 const headersArg = hasHeaders ? "headers" : undefined ;
11471163
1164+ const queryOrHeaderArgs = iife ( ( ) => {
1165+ if ( hasQuery ) {
1166+ return [ `stripUndefined({${ queryParameterNames . join ( ", " ) } })` ] ;
1167+ }
1168+ if ( hasHeaders ) {
1169+ return [ emptyKeyword ] ;
1170+ }
1171+ return [ ] ;
1172+ } ) ;
1173+
11481174 // type narrowing
11491175 if ( Node . isCallExpression ( callExpr ) ) {
11501176 if ( hasJsonBody ) {
11511177 callExpr . addArguments ( [
11521178 pathname ,
11531179 `jsonStringify(${ inputBodyName } )` ,
1154- ...( hasQuery
1155- ? [ `stripUndefined({${ queryParameterNames . join ( ", " ) } })` ]
1156- : hasHeaders
1157- ? [ emptyKeyword ]
1158- : [ ] ) ,
1180+ ...queryOrHeaderArgs ,
11591181 ...( headersArg ? [ headersArg ] : [ ] ) ,
11601182 ] ) ;
11611183 } else if ( hasNonJsonBody ) {
11621184 callExpr . addArguments ( [
11631185 pathname ,
11641186 nonJsonBodyPropName ,
1165- ...( hasQuery
1166- ? [ `stripUndefined({${ queryParameterNames . join ( ", " ) } })` ]
1167- : hasHeaders
1168- ? [ emptyKeyword ]
1169- : [ ] ) ,
1187+ ...queryOrHeaderArgs ,
11701188 ...( headersArg ? [ headersArg ] : [ ] ) ,
11711189 ] ) ;
11721190 } else if ( hasQuery ) {
@@ -1196,13 +1214,9 @@ export async function processOpenApiDocument(
11961214 }
11971215 }
11981216
1199- const isInput = ( t : TypeAliasDeclaration | InterfaceDeclaration ) =>
1200- t . getName ( ) ?. endsWith ( "Input" ) ;
1201- // const isOutput = (t: string) => t.endsWith('Output');
1202-
12031217 const inputTypes = typesFile . getTypeAliases ( ) . filter ( ( t ) => isInput ( t ) ) ;
12041218 const inputUnion = createUnion (
1205- ...new Set ( inputTypes . sort ( ) . map ( ( t ) => t . getName ( ) ) ) ,
1219+ ...new Set ( inputTypes . toSorted ( ) . map ( ( t ) => t . getName ( ) ) ) ,
12061220 ) ;
12071221 const outputUnion = createUnion (
12081222 ...[ ...outputTypes ] . map ( ( t ) => ( typeof t === "string" ? t : t . getName ( ) ) ) ,
@@ -1247,7 +1261,7 @@ export async function processOpenApiDocument(
12471261 mainFile . addImportDeclaration ( {
12481262 moduleSpecifier : typesModuleSpecifier ,
12491263 namedImports : namedImports
1250- . sort ( ( a , b ) => a . getName ( ) . localeCompare ( b . getName ( ) ) )
1264+ . toSorted ( ( a , b ) => a . getName ( ) . localeCompare ( b . getName ( ) ) )
12511265 . map ( ( t ) => ( {
12521266 name : t . getName ( ) ,
12531267 } ) ) ,
@@ -1305,7 +1319,9 @@ export async function processOpenApiDocument(
13051319 if ( commandValibotImports . size > 0 ) {
13061320 commandsFile . addImportDeclaration ( {
13071321 moduleSpecifier : valibotModuleSpecifier ,
1308- namedImports : [ ...commandValibotImports ] . sort ( ) . map ( ( name ) => ( { name } ) ) ,
1322+ namedImports : [ ...commandValibotImports ]
1323+ . toSorted ( )
1324+ . map ( ( name ) => ( { name } ) ) ,
13091325 } ) ;
13101326 }
13111327
0 commit comments