@@ -130,6 +130,16 @@ export interface ConnectionOptions {
130130 * @default 10 seconds
131131 */
132132 connectTimeout ?: Duration ;
133+
134+ /**
135+ * List of plugins to register with the connection.
136+ *
137+ * Plugins allow you to configure the connection options.
138+ * Any plugins provided will also be passed to any client built from this connection.
139+ *
140+ * @experimental Plugins is an experimental feature; APIs may change without notice.
141+ */
142+ plugins ?: ConnectionPlugin [ ] ;
133143}
134144
135145export type ConnectionOptionsWithDefaults = Required <
@@ -172,6 +182,7 @@ function addDefaults(options: ConnectionOptions): ConnectionOptionsWithDefaults
172182 interceptors : interceptors ?? [ makeGrpcRetryInterceptor ( defaultGrpcRetryOptions ( ) ) ] ,
173183 metadata : { } ,
174184 connectTimeoutMs : msOptionalToNumber ( connectTimeout ) ?? 10_000 ,
185+ plugins : [ ] ,
175186 ...filterNullAndUndefined ( rest ) ,
176187 } ;
177188}
@@ -182,8 +193,8 @@ function addDefaults(options: ConnectionOptions): ConnectionOptionsWithDefaults
182193 * - Add default port to address if port not specified
183194 * - Set `Authorization` header based on {@link ConnectionOptions.apiKey}
184195 */
185- function normalizeGRPCConfig ( options ? : ConnectionOptions ) : ConnectionOptions {
186- const { tls : tlsFromConfig , credentials, callCredentials, ...rest } = options || { } ;
196+ function normalizeGRPCConfig ( options : ConnectionOptions ) : ConnectionOptions {
197+ const { tls : tlsFromConfig , credentials, callCredentials, ...rest } = options ;
187198 if ( rest . apiKey ) {
188199 if ( rest . metadata ?. [ 'Authorization' ] ) {
189200 throw new TypeError (
@@ -325,10 +336,12 @@ export class Connection {
325336 */
326337 public readonly healthService : HealthService ;
327338
339+ public readonly plugins : ConnectionPlugin [ ] ;
340+
328341 readonly callContextStorage : AsyncLocalStorage < CallContext > ;
329342 private readonly apiKeyFnRef : { fn ?: ( ) => string } ;
330343
331- protected static createCtorOptions ( options ? : ConnectionOptions ) : ConnectionCtorOptions {
344+ protected static createCtorOptions ( options : ConnectionOptions ) : ConnectionCtorOptions {
332345 const normalizedOptions = normalizeGRPCConfig ( options ) ;
333346 const apiKeyFnRef : { fn ?: ( ) => string } = { } ;
334347 if ( normalizedOptions . apiKey ) {
@@ -444,6 +457,12 @@ export class Connection {
444457 * This method does not verify connectivity with the server. We recommend using {@link connect} instead.
445458 */
446459 static lazy ( options ?: ConnectionOptions ) : Connection {
460+ options = options ?? { } ;
461+ for ( const plugin of options . plugins ?? [ ] ) {
462+ if ( plugin . configureConnection !== undefined ) {
463+ options = plugin . configureConnection ( options ) ;
464+ }
465+ }
447466 return new this ( this . createCtorOptions ( options ) ) ;
448467 }
449468
@@ -477,6 +496,7 @@ export class Connection {
477496 this . healthService = healthService ;
478497 this . callContextStorage = callContextStorage ;
479498 this . apiKeyFnRef = apiKeyFnRef ;
499+ this . plugins = options . plugins ?? [ ] ;
480500 }
481501
482502 protected static generateRPCImplementation ( {
@@ -532,7 +552,7 @@ export class Connection {
532552 * this will locally result in the request call throwing a {@link grpc.ServiceError|ServiceError}
533553 * with code {@link grpc.status.DEADLINE_EXCEEDED|DEADLINE_EXCEEDED}; see {@link isGrpcDeadlineError}.
534554 *
535- * It is stronly recommended to explicitly set deadlines. If no deadline is set, then it is
555+ * It is strongly recommended to explicitly set deadlines. If no deadline is set, then it is
536556 * possible for the client to end up waiting forever for a response.
537557 *
538558 * @param deadline a point in time after which the request will be considered as failed; either a
@@ -688,3 +708,20 @@ export class Connection {
688708 return wrapper as WorkflowService ;
689709 }
690710}
711+
712+ /**
713+ * Plugin to control the configuration of a connection.
714+ *
715+ * @experimental Plugins is an experimental feature; APIs may change without notice.
716+ */
717+ export interface ConnectionPlugin {
718+ /**
719+ * Gets the name of this plugin.
720+ */
721+ get name ( ) : string ;
722+
723+ /**
724+ * Hook called when creating a connection to allow modification of configuration.
725+ */
726+ configureConnection ?( options : ConnectionOptions ) : ConnectionOptions ;
727+ }
0 commit comments