| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| import { Metadata } from './metadata'; |
|
|
| export interface CallMetadataOptions { |
| method_name: string; |
| service_url: string; |
| } |
|
|
| export type CallMetadataGenerator = ( |
| options: CallMetadataOptions, |
| cb: (err: Error | null, metadata?: Metadata) => void |
| ) => void; |
|
|
| |
| |
| export interface OldOAuth2Client { |
| getRequestMetadata: ( |
| url: string, |
| callback: ( |
| err: Error | null, |
| headers?: { |
| [index: string]: string; |
| } |
| ) => void |
| ) => void; |
| } |
|
|
| export interface CurrentOAuth2Client { |
| getRequestHeaders: (url?: string) => Promise<{ [index: string]: string }>; |
| } |
|
|
| export type OAuth2Client = OldOAuth2Client | CurrentOAuth2Client; |
|
|
| function isCurrentOauth2Client( |
| client: OAuth2Client |
| ): client is CurrentOAuth2Client { |
| return ( |
| 'getRequestHeaders' in client && |
| typeof client.getRequestHeaders === 'function' |
| ); |
| } |
|
|
| |
| |
| |
| |
| export abstract class CallCredentials { |
| |
| |
| |
| |
| abstract generateMetadata(options: CallMetadataOptions): Promise<Metadata>; |
| |
| |
| |
| |
| |
| |
| abstract compose(callCredentials: CallCredentials): CallCredentials; |
|
|
| |
| |
| |
| |
| |
| |
| abstract _equals(other: CallCredentials): boolean; |
|
|
| |
| |
| |
| |
| |
| |
| |
| static createFromMetadataGenerator( |
| metadataGenerator: CallMetadataGenerator |
| ): CallCredentials { |
| return new SingleCallCredentials(metadataGenerator); |
| } |
|
|
| |
| |
| |
| |
| |
| static createFromGoogleCredential( |
| googleCredentials: OAuth2Client |
| ): CallCredentials { |
| return CallCredentials.createFromMetadataGenerator((options, callback) => { |
| let getHeaders: Promise<{ [index: string]: string }>; |
| if (isCurrentOauth2Client(googleCredentials)) { |
| getHeaders = googleCredentials.getRequestHeaders(options.service_url); |
| } else { |
| getHeaders = new Promise((resolve, reject) => { |
| googleCredentials.getRequestMetadata( |
| options.service_url, |
| (err, headers) => { |
| if (err) { |
| reject(err); |
| return; |
| } |
| if (!headers) { |
| reject(new Error('Headers not set by metadata plugin')); |
| return; |
| } |
| resolve(headers); |
| } |
| ); |
| }); |
| } |
| getHeaders.then( |
| headers => { |
| const metadata = new Metadata(); |
| for (const key of Object.keys(headers)) { |
| metadata.add(key, headers[key]); |
| } |
| callback(null, metadata); |
| }, |
| err => { |
| callback(err); |
| } |
| ); |
| }); |
| } |
|
|
| static createEmpty(): CallCredentials { |
| return new EmptyCallCredentials(); |
| } |
| } |
|
|
| class ComposedCallCredentials extends CallCredentials { |
| constructor(private creds: CallCredentials[]) { |
| super(); |
| } |
|
|
| async generateMetadata(options: CallMetadataOptions): Promise<Metadata> { |
| const base: Metadata = new Metadata(); |
| const generated: Metadata[] = await Promise.all( |
| this.creds.map(cred => cred.generateMetadata(options)) |
| ); |
| for (const gen of generated) { |
| base.merge(gen); |
| } |
| return base; |
| } |
|
|
| compose(other: CallCredentials): CallCredentials { |
| return new ComposedCallCredentials(this.creds.concat([other])); |
| } |
|
|
| _equals(other: CallCredentials): boolean { |
| if (this === other) { |
| return true; |
| } |
| if (other instanceof ComposedCallCredentials) { |
| return this.creds.every((value, index) => |
| value._equals(other.creds[index]) |
| ); |
| } else { |
| return false; |
| } |
| } |
| } |
|
|
| class SingleCallCredentials extends CallCredentials { |
| constructor(private metadataGenerator: CallMetadataGenerator) { |
| super(); |
| } |
|
|
| generateMetadata(options: CallMetadataOptions): Promise<Metadata> { |
| return new Promise<Metadata>((resolve, reject) => { |
| this.metadataGenerator(options, (err, metadata) => { |
| if (metadata !== undefined) { |
| resolve(metadata); |
| } else { |
| reject(err); |
| } |
| }); |
| }); |
| } |
|
|
| compose(other: CallCredentials): CallCredentials { |
| return new ComposedCallCredentials([this, other]); |
| } |
|
|
| _equals(other: CallCredentials): boolean { |
| if (this === other) { |
| return true; |
| } |
| if (other instanceof SingleCallCredentials) { |
| return this.metadataGenerator === other.metadataGenerator; |
| } else { |
| return false; |
| } |
| } |
| } |
|
|
| class EmptyCallCredentials extends CallCredentials { |
| generateMetadata(options: CallMetadataOptions): Promise<Metadata> { |
| return Promise.resolve(new Metadata()); |
| } |
|
|
| compose(other: CallCredentials): CallCredentials { |
| return other; |
| } |
|
|
| _equals(other: CallCredentials): boolean { |
| return other instanceof EmptyCallCredentials; |
| } |
| } |
|
|