import { DefInfo , getRef , isReferenceObject , isRequestBodyObject , lastPart , lcFirst , resolveSchemaType , } from './util.js' ; import { OpenAPIObject , ParameterObject , PathItemObject , ReferenceObject , RequestBodyObject , } from 'openapi3-ts' ; import { addImport , docComment , generateHeader , generateImports , indent , writeOutFile , } from './generate-common.js' ; const httpClientType = `import { HttpClient } from '../http';` ; export function generateServiceDefinition ( tag , paths , doc , componentByDef ) { const importFiles = { } ; const pathDefinitions = paths . map ( ( [ path , pathDef ] ) => generatePathDefinition ( path , pathDef , doc , componentByDef , importFiles ) ) ; const filename = `generated-src/${ tag . toLowerCase ( ) }/api.ts` ; const imports = generateImports ( filename , importFiles ) ; const definition = [ generateHeader ( doc ) , httpClientType , imports , ... pathDefinitions ] . join ( '\n\n' ) + '\n' ; writeOutFile ( filename , definition ) ; } function generatePathDefinition ( path , pathDef , doc , componentByDef , importFiles ) { let server = doc . servers ! [ 0 ] . url ; if ( server === 'https://www.bungie.net/Platform' && path . includes ( '/Stats/PostGameCarnageReport/' ) ) server = 'https://stats.bungie.net/Platform' ; const interfaceName = lastPart ( pathDef . summary ! ) ; const functionName = lcFirst ( interfaceName ) ; const method = pathDef . get ? 'GET' : 'POST' ; const methodDef = pathDef . get || pathDef . post ! ; const params = ( methodDef . parameters || [ ] ) as ParameterObject [ ] ; const queryParameterNames = params . filter ( ( param ) => param . in === 'query' ) . map ( ( param ) => param . name ) ; const parameterArgs = [ 'http: HttpClient' ] ; let interfaceDefinition = '' ; if ( params . length ) { interfaceDefinition = generateInterfaceSchema ( interfaceName + 'Params' , params , doc , componentByDef , importFiles ) + '\n\n' ; parameterArgs . push ( `params: ${ interfaceName }Params` ) ; } if ( methodDef . requestBody ) { if ( isRequestBodyObject ( methodDef . requestBody ) ) { const schema = methodDef . requestBody . content [ 'application/json' ] . schema ! ; const paramType = resolveSchemaType ( schema , doc ) ; addImport ( doc , schema , componentByDef , importFiles ) ; const docString = methodDef . requestBody . description ? docComment ( methodDef . requestBody . description ) + '\n' : '' ; parameterArgs . push ( `${ docString }body${ methodDef . requestBody . required ? '' : '?' }: ${ paramType }` ) ; } else if ( isReferenceObject ( methodDef . requestBody ) ) { throw new Error ( "didn't expect this" ) ; } } const templatizedPath = path . includes ( '{' ) ? `\`${ server }${ path . replace ( /{/g , '${params.' ) }\`` : `'${ server }${ path }'` ; let paramsObject = '' ; if ( queryParameterNames . length ) { const paramInitializers = queryParameterNames . map ( ( p ) => { const param = params . find ( ( pa ) => pa . name === p ) ! ; const paramType = resolveSchemaType ( param . schema ! , doc ) ; if ( paramType . endsWith ( '[]' ) ) { if ( ! param . required ) { return `${ p }: params.${ p } ? params.${ p }.join(',') : undefined` ; } return `${ p }: params.${ p }.join(',')` ; } return `${ p }: params.${ p }` ; } ) ; paramsObject = `,
    params: {
${ indent ( paramInitializers . join ( ',\n' ) , 3 ) }
    }` ; } let requestBodyParam = '' ; if ( methodDef . requestBody && isRequestBodyObject ( methodDef . requestBody ) ) { requestBodyParam = `,
    body` ; } const returnValue = resolveSchemaType ( methodDef . responses [ '200' ] , doc ) ; addImport ( doc , methodDef . responses [ '200' ] , componentByDef , importFiles ) ; return `${ interfaceDefinition }${ docComment ( methodDef . description ! ) }
export function ${ functionName }(${ parameterArgs . join ( ', ' ) }): Promise<${ returnValue }> {
  return http({
    method: '${ method }',
    url: ${ templatizedPath }${ paramsObject }${ requestBodyParam }
  });
}` ; } function generateInterfaceSchema ( interfaceName , params , doc , componentByDef , importFiles ) { const parameterArgs = params . map ( ( param ) => { const paramType = resolveSchemaType ( param . schema ! , doc ) ; addImport ( doc , param . schema ! , componentByDef , importFiles ) ; const docString = param . description ? docComment ( param . description ) + '\n' : '' ; return `${ docString }${ param . name }${ param . required || ( param . name === 'components' && paramType === 'DestinyComponentType[]' ) ? '' : '?' }: ${ paramType };` ; } ) ; return `export interface ${ interfaceName } {
${ indent ( parameterArgs . join ( '\n' ) , 1 ) }
}` ; }