1+ import { isObject , isUndefined } from '@nestjs/common/utils/shared.utils' ;
12import { fromEvent } from 'rxjs' ;
23import { takeUntil } from 'rxjs/operators' ;
3- import { CANCEL_EVENT , GRPC_DEFAULT_PROTO_LOADER , GRPC_DEFAULT_URL } from '../constants' ;
4+ import {
5+ CANCEL_EVENT ,
6+ GRPC_DEFAULT_PROTO_LOADER ,
7+ GRPC_DEFAULT_URL ,
8+ } from '../constants' ;
49import { InvalidGrpcPackageException } from '../exceptions/errors/invalid-grpc-package.exception' ;
510import { InvalidProtoDefinitionException } from '../exceptions/errors/invalid-proto-definition.exception' ;
611import { CustomTransportStrategy } from '../interfaces' ;
@@ -23,13 +28,11 @@ export class ServerGrpc extends Server implements CustomTransportStrategy {
2328 this . getOptionsProp < GrpcOptions > ( options , 'url' ) || GRPC_DEFAULT_URL ;
2429
2530 const protoLoader =
26- this . getOptionsProp < GrpcOptions > ( options , 'protoLoader' ) || GRPC_DEFAULT_PROTO_LOADER ;
31+ this . getOptionsProp < GrpcOptions > ( options , 'protoLoader' ) ||
32+ GRPC_DEFAULT_PROTO_LOADER ;
2733
2834 grpcPackage = this . loadPackage ( 'grpc' , ServerGrpc . name ) ;
29- grpcProtoLoaderPackage = this . loadPackage (
30- protoLoader ,
31- ServerGrpc . name ,
32- ) ;
35+ grpcProtoLoaderPackage = this . loadPackage ( protoLoader , ServerGrpc . name ) ;
3336 }
3437
3538 public async listen ( callback : ( ) => void ) {
@@ -55,31 +58,29 @@ export class ServerGrpc extends Server implements CustomTransportStrategy {
5558 this . logger . error ( invalidPackageError . message , invalidPackageError . stack ) ;
5659 throw invalidPackageError ;
5760 }
61+
5862 // Take all of the services defined in grpcPkg and assign them to
5963 // method handlers defined in Controllers
6064 for ( const definition of this . getServiceNames ( grpcPkg ) ) {
6165 this . grpcClient . addService (
6266 // First parameter requires exact service definition from proto
6367 definition . service . service ,
6468 // Here full proto definition required along with namespaced pattern name
65- await this . createService ( definition . service , definition . name )
69+ await this . createService ( definition . service , definition . name ) ,
6670 ) ;
6771 }
6872 }
6973
7074 /**
7175 * Will return all of the services along with their fully namespaced
7276 * names as an array of objects.
73- *
7477 * This method initiates recursive scan of grpcPkg object
75- *
76- * @param grpcPkg
7778 */
78- public getServiceNames ( grpcPkg : any ) : { name : string , service : any } [ ] {
79+ public getServiceNames ( grpcPkg : any ) : { name : string ; service : any } [ ] {
7980 // Define accumulator to collect all of the services available to load
80- const services : { name : string , service : any } [ ] = [ ] ;
81+ const services : { name : string ; service : any } [ ] = [ ] ;
8182 // Initiate recursive services collector starting with empty name
82- this . _getServiceNamesCollector ( '' , grpcPkg , services ) ;
83+ this . collectDeepServices ( '' , grpcPkg , services ) ;
8384 return services ;
8485 }
8586
@@ -206,45 +207,45 @@ export class ServerGrpc extends Server implements CustomTransportStrategy {
206207 * name: "FirstService.Events",
207208 * service: {Object}
208209 * }
209- *
210- * @param name
211- * @param grpcDefinition
212- * @param accumulator
213- * @private
214210 */
215- private _getServiceNamesCollector ( name , grpcDefinition , accumulator ) {
216- // Confirm that next definition to unwrap is an object
217- if ( typeof grpcDefinition !== 'object' )
218- // Exit for non objects
211+ private collectDeepServices (
212+ name : string ,
213+ grpcDefinition : any ,
214+ accumulator : { name : string ; service : any } [ ] ,
215+ ) {
216+ if ( ! isObject ( grpcDefinition ) ) {
219217 return ;
220- // Collect keys for traverse
221- const keys = Object . keys ( grpcDefinition ) ;
218+ }
219+ const keysToTraverse = Object . keys ( grpcDefinition ) ;
222220 // Traverse definitions or namespace extensions
223- for ( const key of keys ) {
224- // Define name extension variable
225- let nameExtended = '' ;
226- // If depth is zero then just add key
227- if ( name . length === 0 )
228- nameExtended = key ;
229- // If depth non-zero then add next through dot syntax
230- else
231- nameExtended = name + '.' + key ;
232- // Take nested object
233- const nested = grpcDefinition [ key ] ;
234- // Check if it's in depth with service definition available
235- const requirement1 = typeof nested . service !== 'undefined' ;
236- // Check if first requirement passable and service isn't a boolean value
237- const requirement2 = requirement1 ? nested . service !== false : false ;
238- // Check if both requirements satisfied
239- if ( requirement1 && requirement2 ) {
240- // Add new service object to accumulator
221+ for ( const key of keysToTraverse ) {
222+ const nameExtended = this . parseDeepServiceName ( name , key ) ;
223+ const deepDefinition = grpcDefinition [ key ] ;
224+
225+ const isServiceDefined = ! isUndefined ( deepDefinition . service ) ;
226+ const isServiceBoolean = isServiceDefined
227+ ? deepDefinition . service !== false
228+ : false ;
229+
230+ if ( isServiceDefined && isServiceBoolean ) {
241231 accumulator . push ( {
242232 name : nameExtended ,
243- service : nested
233+ service : deepDefinition ,
244234 } ) ;
245- } else
235+ }
246236 // Continue recursion until objects end or service definition found
247- this . _getServiceNamesCollector ( nameExtended , nested , accumulator ) ;
237+ else {
238+ this . collectDeepServices ( nameExtended , deepDefinition , accumulator ) ;
239+ }
240+ }
241+ }
242+
243+ private parseDeepServiceName ( name : string , key : string ) : string {
244+ // If depth is zero then just return key
245+ if ( name . length === 0 ) {
246+ return key ;
248247 }
248+ // Otherwise add next through dot syntax
249+ return name + '.' + key ;
249250 }
250251}
0 commit comments