@@ -28,8 +28,10 @@ import {
28
28
import { getDiscriminator } from "@cadl-lang/rest" ;
29
29
import {
30
30
getAllRoutes ,
31
+ getAuthentication ,
31
32
getContentTypes ,
32
33
getServers ,
34
+ HttpAuth ,
33
35
HttpOperationParameter ,
34
36
HttpOperationParameters ,
35
37
HttpOperationResponse ,
@@ -49,6 +51,11 @@ interface HttpServerParameter {
49
51
param : ModelTypeProperty ;
50
52
}
51
53
54
+ interface CredentialType {
55
+ kind : "Credential" ,
56
+ scheme : HttpAuth ;
57
+ }
58
+
52
59
export async function $onEmit ( program : Program ) {
53
60
const yamlMap = createYamlEmitter ( program ) ;
54
61
const yamlPath = resolvePath ( program . compilerOptions . outputPath ! , "output.yaml" ) ;
@@ -75,7 +82,7 @@ function camelToSnakeCase(name: string): string {
75
82
return camelToSnakeCaseRe ( name [ 0 ] . toLowerCase ( ) + name . slice ( 1 ) ) ;
76
83
}
77
84
78
- const typesMap = new Map < Type , Record < string , any > > ( ) ;
85
+ const typesMap = new Map < Type | CredentialType , Record < string , any > > ( ) ;
79
86
const simpleTypesMap = new Map < string , Record < string , any > > ( ) ;
80
87
const endpointPathParameters : Record < string , any > [ ] = [ ] ;
81
88
@@ -129,7 +136,7 @@ function handleDiscriminator(program: Program, type: ModelType, model: Record<st
129
136
}
130
137
}
131
138
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 {
133
140
// don't cache simple type(string, int, etc) since decorators may change the result
134
141
const enableCache = ! isSimpleType ( program , modelTypeProperty ) ;
135
142
if ( enableCache ) {
@@ -617,9 +624,32 @@ function constantType(value: any, valueType: string): Record<string, any> {
617
624
return { type : "constant" , value : value , valueType : { type : valueType } } ;
618
625
}
619
626
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
+
620
650
function emitType (
621
651
program : Program ,
622
- type : Type ,
652
+ type : Type | CredentialType ,
623
653
modelTypeProperty : ModelTypeProperty | undefined = undefined ,
624
654
) : Record < string , any > {
625
655
switch ( type . kind ) {
@@ -633,6 +663,8 @@ function emitType(
633
663
return emitModel ( program , type , modelTypeProperty ) ;
634
664
case "Enum" :
635
665
return emitEnum ( program , type ) ;
666
+ case "Credential" :
667
+ return emitCredential ( type . scheme ) ;
636
668
default :
637
669
throw Error ( `Not supported ${ type . kind } ` ) ;
638
670
}
@@ -675,7 +707,7 @@ function getServerHelper(program: Program, namespace: NamespaceType): HttpServer
675
707
return servers [ 0 ] ;
676
708
}
677
709
678
- function emitGlobalParameters ( program : Program , namespace : NamespaceType ) : Record < string , any > [ ] {
710
+ function emitServerParams ( program : Program , namespace : NamespaceType ) : Record < string , any > [ ] {
679
711
const server = getServerHelper ( program , namespace ) ;
680
712
if ( server === undefined ) {
681
713
return [
@@ -721,6 +753,44 @@ function emitGlobalParameters(program: Program, namespace: NamespaceType): Recor
721
753
}
722
754
}
723
755
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
+
724
794
function createYamlEmitter ( program : Program ) {
725
795
const serviceNamespace = getServiceNamespace ( program ) ;
726
796
if ( serviceNamespace === undefined ) {
0 commit comments