Skip to content

Commit

Permalink
Use official grpc types instead of any in the index.ts
Browse files Browse the repository at this point in the history
  • Loading branch information
kondi committed Mar 4, 2019
1 parent ddcf901 commit e890f36
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 20 deletions.
46 changes: 28 additions & 18 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ import { Observable } from 'rxjs';
import { lookupPackage } from './utils';

type DynamicMethods = { [name: string]: any };
type GrpcService<T> = typeof grpc.Client & {
service: grpc.ServiceDefinition<T>;
};

export interface GenericServerBuilder<T> {
start(address: string, credentials?: any): void;
start(address: string, credentials?: grpc.ServerCredentials): void;
forceShutdown(): void;
}

Expand All @@ -18,7 +21,7 @@ export function serverBuilder<T>(
const server = new grpc.Server();

const builder: DynamicMethods = <GenericServerBuilder<T>>{
start(address: string, credentials?: any) {
start(address, credentials) {
server.bind(address, credentials || grpc.ServerCredentials.createInsecure());
server.start();
},
Expand All @@ -30,7 +33,8 @@ export function serverBuilder<T>(
const pkg = lookupPackage(grpcLoad(protoPath), packageName);
for (const name of getServiceNames(pkg)) {
builder[`add${name}`] = function(rxImpl: DynamicMethods) {
server.addService(pkg[name].service, createService(pkg[name], rxImpl));
const serviceData = (pkg[name] as any) as GrpcService<any>;
server.addService(serviceData.service, createService(serviceData, rxImpl));
return this;
};
}
Expand All @@ -47,7 +51,7 @@ function grpcLoad(protoPath: string) {
return grpc.loadPackageDefinition(packageDefinition);
}

function createService(Service: any, rxImpl: DynamicMethods) {
function createService(Service: GrpcService<any>, rxImpl: DynamicMethods) {
const service: DynamicMethods = {};
for (const name in Service.prototype) {
if (typeof rxImpl[name] === 'function') {
Expand All @@ -63,19 +67,22 @@ function createMethod(rxImpl: DynamicMethods, name: string, serviceMethods: Dyna
: createUnaryMethod(rxImpl, name);
}

function createUnaryMethod(rxImpl: DynamicMethods, name: string) {
return function(call: any, callback: any) {
function createUnaryMethod(rxImpl: DynamicMethods, name: string): grpc.handleUnaryCall<any, any> {
return function(call, callback) {
try {
const response: Observable<any> = rxImpl[name](call.request, call.metadata);
response.subscribe(data => callback(null, data), error => callback(error));
response.subscribe(data => callback(null, data), error => callback(error, null));
} catch (error) {
callback(error);
callback(error, null);
}
};
}

function createStreamingMethod(rxImpl: DynamicMethods, name: string) {
return async function(call: any) {
function createStreamingMethod(
rxImpl: DynamicMethods,
name: string,
): grpc.handleServerStreamingCall<any, any> {
return async function(call) {
try {
const response: Observable<any> = rxImpl[name](call.request, call.metadata);
await response.forEach(data => call.write(data));
Expand All @@ -88,14 +95,14 @@ function createStreamingMethod(rxImpl: DynamicMethods, name: string) {

export type ClientFactoryConstructor<T> = new (
address: string,
credentials?: any,
credentials?: grpc.ChannelCredentials,
options?: any,
) => T;

export function clientFactory<T>(protoPath: string, packageName: string) {
class Constructor {
readonly __args: any[];
constructor(address: string, credentials?: any, options: any = undefined) {
readonly __args: [string, grpc.ChannelCredentials, any | undefined];
constructor(address: string, credentials?: grpc.ChannelCredentials, options: any = undefined) {
this.__args = [address, credentials || grpc.credentials.createInsecure(), options];
}
}
Expand All @@ -104,19 +111,22 @@ export function clientFactory<T>(protoPath: string, packageName: string) {
const pkg = lookupPackage(grpcLoad(protoPath), packageName);
for (const name of getServiceNames(pkg)) {
prototype[`get${name}`] = function(this: Constructor) {
return createServiceClient(pkg[name], this.__args);
return createServiceClient((pkg[name] as any) as GrpcService<any>, this.__args);
};
}

return (Constructor as any) as ClientFactoryConstructor<T>;
}

function getServiceNames(pkg: any) {
return Object.keys(pkg).filter(name => pkg[name].service);
function getServiceNames(pkg: grpc.GrpcObject) {
return Object.keys(pkg).filter(name => (pkg[name] as GrpcService<any>).service);
}

function createServiceClient(GrpcClient: any, args: any[]) {
const grpcClient = new GrpcClient(...args);
function createServiceClient(
GrpcClient: GrpcService<any>,
args: [string, grpc.ChannelCredentials, any | undefined],
) {
const grpcClient = new GrpcClient(args[0], args[1], args[2]);
const rxClient: DynamicMethods = {};
for (const name of Object.keys(GrpcClient.prototype)) {
rxClient[name] = createClientMethod(grpcClient, name);
Expand Down
6 changes: 4 additions & 2 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
export function lookupPackage(root: any, packageName: string) {
import { GrpcObject } from 'grpc';

export function lookupPackage(root: GrpcObject, packageName: string) {
let pkg = root;
for (const name of packageName.split(/\./)) {
pkg = pkg[name];
pkg = pkg[name] as GrpcObject;
}
return pkg;
}

0 comments on commit e890f36

Please sign in to comment.