@@ -28,8 +28,10 @@ import {
2828import { getDiscriminator } from "@cadl-lang/rest" ;
2929import {
3030 getAllRoutes ,
31+ getAuthentication ,
3132 getContentTypes ,
3233 getServers ,
34+ HttpAuth ,
3335 HttpOperationParameter ,
3436 HttpOperationParameters ,
3537 HttpOperationResponse ,
@@ -49,6 +51,11 @@ interface HttpServerParameter {
4951 param : ModelTypeProperty ;
5052}
5153
54+ interface CredentialType {
55+ kind : "Credential" ,
56+ scheme : HttpAuth ;
57+ }
58+
5259export async function $onEmit ( program : Program ) {
5360 const yamlMap = createYamlEmitter ( program ) ;
5461 const yamlPath = resolvePath ( program . compilerOptions . outputPath ! , "output.yaml" ) ;
@@ -75,7 +82,7 @@ function camelToSnakeCase(name: string): string {
7582 return camelToSnakeCaseRe ( name [ 0 ] . toLowerCase ( ) + name . slice ( 1 ) ) ;
7683}
7784
78- const typesMap = new Map < Type , Record < string , any > > ( ) ;
85+ const typesMap = new Map < Type | CredentialType , Record < string , any > > ( ) ;
7986const simpleTypesMap = new Map < string , Record < string , any > > ( ) ;
8087const endpointPathParameters : Record < string , any > [ ] = [ ] ;
8188
@@ -129,7 +136,7 @@ function handleDiscriminator(program: Program, type: ModelType, model: Record<st
129136 }
130137}
131138
132- function getType ( program : Program , type : Type , modelTypeProperty : ModelTypeProperty | undefined = undefined ) : any {
139+ function getType ( program : Program , type : Type | CredentialType , modelTypeProperty : ModelTypeProperty | undefined = undefined ) : any {
133140 // don't cache simple type(string, int, etc) since decorators may change the result
134141 const enableCache = ! isSimpleType ( program , modelTypeProperty ) ;
135142 if ( enableCache ) {
@@ -617,9 +624,32 @@ function constantType(value: any, valueType: string): Record<string, any> {
617624 return { type : "constant" , value : value , valueType : { type : valueType } } ;
618625}
619626
627+ function emitCredential ( auth : HttpAuth ) : Record < string , any > {
628+ let credential_type : Record < string , any > = { } ;
629+ if ( auth . type === "oauth2" ) {
630+ credential_type = {
631+ type : "OAuth2" ,
632+ policy : {
633+ type : "BearerTokenCredentialPolicy" ,
634+ credentialScopes : [ ]
635+ }
636+ }
637+ auth . flows . forEach ( it => credential_type . policy . credentialScopes . push ( ...it . scopes ) ) ;
638+ } else if ( auth . type === "apiKey" ) {
639+ credential_type = {
640+ type : "Key" ,
641+ policy : {
642+ type : "AzureKeyCredentialPolicy" ,
643+ key : auth . name
644+ }
645+ }
646+ }
647+ return credential_type ;
648+ }
649+
620650function emitType (
621651 program : Program ,
622- type : Type ,
652+ type : Type | CredentialType ,
623653 modelTypeProperty : ModelTypeProperty | undefined = undefined ,
624654) : Record < string , any > {
625655 switch ( type . kind ) {
@@ -633,6 +663,8 @@ function emitType(
633663 return emitModel ( program , type , modelTypeProperty ) ;
634664 case "Enum" :
635665 return emitEnum ( program , type ) ;
666+ case "Credential" :
667+ return emitCredential ( type . scheme ) ;
636668 default :
637669 throw Error ( `Not supported ${ type . kind } ` ) ;
638670 }
@@ -675,7 +707,7 @@ function getServerHelper(program: Program, namespace: NamespaceType): HttpServer
675707 return servers [ 0 ] ;
676708}
677709
678- function emitGlobalParameters ( program : Program , namespace : NamespaceType ) : Record < string , any > [ ] {
710+ function emitServerParams ( program : Program , namespace : NamespaceType ) : Record < string , any > [ ] {
679711 const server = getServerHelper ( program , namespace ) ;
680712 if ( server === undefined ) {
681713 return [
@@ -721,6 +753,44 @@ function emitGlobalParameters(program: Program, namespace: NamespaceType): Recor
721753 }
722754}
723755
756+ function emitCredentialParam ( program : Program , namespace : NamespaceType ) : Record < string , any > | undefined {
757+ const auth = getAuthentication ( program , namespace ) ;
758+ if ( auth ) {
759+ for ( const option of auth . options ) {
760+ for ( const scheme of option . schemes ) {
761+ const type : CredentialType = {
762+ kind : "Credential" ,
763+ scheme : scheme ,
764+ }
765+ const credential_type = getType ( program , type ) ;
766+ if ( credential_type ) {
767+ return {
768+ type : credential_type ,
769+ optional : false ,
770+ description : "Credential needed for the client to connect to Azure." ,
771+ clientName : "credential" ,
772+ location : "other" ,
773+ restApiName : "credential" ,
774+ implementation : "Client" ,
775+ skipUrlEncoding : true ,
776+ inOverload : false
777+ } ;
778+ }
779+ }
780+ }
781+ }
782+ return undefined
783+ }
784+
785+ function emitGlobalParameters ( program : Program , serviceNamespace : NamespaceType ) : Record < string , any > [ ] {
786+ const clientParameters = emitServerParams ( program , serviceNamespace ) ;
787+ const credentialParam = emitCredentialParam ( program , serviceNamespace ) ;
788+ if ( credentialParam ) {
789+ clientParameters . push ( credentialParam ) ;
790+ }
791+ return clientParameters ;
792+ }
793+
724794function createYamlEmitter ( program : Program ) {
725795 const serviceNamespace = getServiceNamespace ( program ) ;
726796 if ( serviceNamespace === undefined ) {
0 commit comments