Skip to content

Commit

Permalink
feat(client): add and export a module that allows the client proxy to…
Browse files Browse the repository at this point in the history
… be injected

Provide a GooglePubSubModule that exports a client proxy instance, allowing it to be injected

re #2
  • Loading branch information
harrietwaters committed Apr 17, 2021
1 parent c796068 commit 07a5820
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 0 deletions.
9 changes: 9 additions & 0 deletions lib/client/client-google-pubsub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ export class ClientGooglePubSub extends ClientProxy {
this.googlePubSubClient = options?.pubSubClient ?? new PubSub(options?.pubSubClientConfig);
}

/**
* Create and return a new ClientGooglePubSub instance
* @param options
* @returns
*/
public static create(options?: GooglePubSubOptions): ClientGooglePubSub {
return new this(options);
}

/**
* Since the client on starts listening for messages when event subscribers are added, this
* method does nothing
Expand Down
88 changes: 88 additions & 0 deletions lib/client/google-pubsub.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { DynamicModule, Module, Provider } from '@nestjs/common';
import { GOOGLE_PUBSUB_CLIENT_TOKEN, GOOGLE_PUBSUB_MODULE_OPTIONS } from '../constants';
import {
GooglePubSubModuleAsyncOptions,
GooglePubSubModuleOptionsFactory,
GooglePubSubOptions,
} from '../interfaces';
import { ClientGooglePubSub } from './client-google-pubsub';

// This bit is adapted from the built from http-service:
// https://github.com/nestjs/nest/tree/6a61a593b9d388144ea5497909c03612c298214c/packages/common/http
@Module({
providers: [
{
provide: GOOGLE_PUBSUB_CLIENT_TOKEN,
useValue: ClientGooglePubSub,
},
],
exports: [GOOGLE_PUBSUB_CLIENT_TOKEN],
})
export class GooglePubSubModule {
static register(options: GooglePubSubOptions): DynamicModule {
return {
module: GooglePubSubModule,
providers: [
{
provide: GOOGLE_PUBSUB_CLIENT_TOKEN,
useValue: ClientGooglePubSub.create(options),
},
],
};
}

static registerAsync(options: GooglePubSubModuleAsyncOptions): DynamicModule {
return {
module: GooglePubSubModule,
imports: options.imports,
providers: [
...this.createAsyncProviders(options),
{
provide: GOOGLE_PUBSUB_CLIENT_TOKEN,
useFactory: (config: GooglePubSubOptions) => ClientGooglePubSub.create(config),
inject: [GOOGLE_PUBSUB_MODULE_OPTIONS],
},
...(options.extraProviders || []),
],
};
}

private static createAsyncProviders(options: GooglePubSubModuleAsyncOptions): Provider[] {
if (options.useExisting || options.useFactory) {
return [this.createAsyncOptionsProvider(options)];
}
return [
this.createAsyncOptionsProvider(options),
{
// TODO: Change the options to a conditional type so we can be assured _at least_
// one of these is present
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
provide: options.useClass,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
useClass: options.useClass,
},
];
}

private static createAsyncOptionsProvider(options: GooglePubSubModuleAsyncOptions): Provider {
if (options.useFactory) {
return {
provide: GOOGLE_PUBSUB_MODULE_OPTIONS,
useFactory: options.useFactory,
inject: options.inject || [],
};
}
return {
provide: GOOGLE_PUBSUB_MODULE_OPTIONS,
useFactory: async (optionsFactory: GooglePubSubModuleOptionsFactory) =>
optionsFactory.createGooglePubSubOptions(),
// TODO: Change the options to a conditional type so we can be assured _at least_
// one of these is present
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
inject: [options.useExisting || options.useClass],
};
}
}
2 changes: 2 additions & 0 deletions lib/constants.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export const GOOGLE_PUBSUB_SUBSCRIPTION_MESSAGE_EVENT = 'message';
export const GOOGLE_PUBSUB_CLIENT_TOKEN = 'GOOGLE_PUBSUB_INSTANCE_TOKEN';
export const GOOGLE_PUBSUB_MODULE_OPTIONS = 'GOOGLE_PUBSUB_MODULE_OPTIONS';
13 changes: 13 additions & 0 deletions lib/interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ClientConfig, Message, PubSub, Subscription, Topic } from '@google-cloud/pubsub';
import { ModuleMetadata, Provider, Type } from '@nestjs/common';
import { ClientGooglePubSub } from './client';
import { GooglePubSubContext } from './ctx-host';

Expand Down Expand Up @@ -66,3 +67,15 @@ export interface GooglePubSubOptions {
pubSubClient?: PubSub;
pubSubClientConfig?: ClientConfig;
}

export interface GooglePubSubModuleOptionsFactory {
createGooglePubSubOptions(): Promise<GooglePubSubOptions> | GooglePubSubOptions;
}

export interface GooglePubSubModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
useExisting?: Type<GooglePubSubModuleOptionsFactory>;
useClass?: Type<GooglePubSubModuleOptionsFactory>;
useFactory?: (...args: any[]) => Promise<GooglePubSubOptions> | GooglePubSubOptions;
inject?: any[];
extraProviders?: Provider[];
}

0 comments on commit 07a5820

Please sign in to comment.