feat: centralize grpc client registration
All checks were successful
Publish / Publish Job (push) Successful in 44s

This commit is contained in:
Дмитрий
2026-04-11 13:43:58 +03:00
parent ecf1704eb1
commit 4fc1514ed7
9 changed files with 1300 additions and 343 deletions

View File

@@ -0,0 +1 @@
export const GRPC_CLIENT_PREFIX = 'GRPC_CLIENT'

View File

@@ -0,0 +1 @@
export * from './inject-grpc-client.decorator'

View File

@@ -0,0 +1,6 @@
import { Inject } from '@nestjs/common'
import { GRPC_CLIENT_PREFIX } from '../constants/grpc.constants'
export const InjectGrpcClient = (name: string) =>
Inject(`${GRPC_CLIENT_PREFIX}_${name}`)

View File

@@ -0,0 +1,36 @@
import { Injectable } from '@nestjs/common'
import {
ClientGrpc,
ClientProxyFactory,
Transport
} from '@nestjs/microservices'
@Injectable()
export class GrpcClientFactory {
private clients = new Map<string, ClientGrpc>()
public createClient(options: {
package: string
protoPath: string
url: string
}) {
return ClientProxyFactory.create({
transport: Transport.GRPC,
options
}) as ClientGrpc
}
public register(token: string, client: ClientGrpc) {
this.clients.set(token, client)
}
public getClient<T extends ClientGrpc = ClientGrpc>(token: string): T {
const client = this.clients.get(token)
if (!client) {
throw new Error(`gRPC client with token ${token} not found`)
}
return client as T
}
}

46
lib/grpc/grpc.module.ts Normal file
View File

@@ -0,0 +1,46 @@
import { type DynamicModule, Module } from '@nestjs/common'
import { ConfigService } from '@nestjs/config'
import { GRPC_CLIENT_PREFIX } from './constants/grpc.constants'
import { GrpcClientFactory } from './factory/grpc-client.factory'
import { GRPC_CLIENTS } from './registry/grpc.registry'
@Module({})
export class GrpcModule {
public static register(
clients: Array<keyof typeof GRPC_CLIENTS>
): DynamicModule {
return {
module: GrpcModule,
providers: [
GrpcClientFactory,
...clients.map(token => {
const cfg = GRPC_CLIENTS[token]
return {
provide: `${GRPC_CLIENT_PREFIX}_${token}`,
useFactory: (
factory: GrpcClientFactory,
config: ConfigService
) => {
const url = config.getOrThrow(cfg.env)
const client = factory.createClient({
package: cfg.package,
protoPath: cfg.protoPath,
url
})
factory.register(token, client)
return client
},
inject: [GrpcClientFactory, ConfigService]
}
})
],
exports: [
GrpcClientFactory,
...clients.map(token => `${GRPC_CLIENT_PREFIX}_${token}`)
]
}
}
}

2
lib/grpc/index.ts Normal file
View File

@@ -0,0 +1,2 @@
export * from './decorators'
export * from './grpc.module'

View File

@@ -0,0 +1,39 @@
import { PROTO_PATHS } from '@lendry-erp/contracts'
export const GRPC_CLIENTS = {
AUTH_PACKAGE: {
package: 'auth.v1',
protoPath: PROTO_PATHS.AUTH,
env: 'AUTH_GRPC_URL'
},
ACCOUNT_PACKAGE: {
package: 'account.v1',
protoPath: PROTO_PATHS.ACCOUNT,
env: 'AUTH_GRPC_URL'
},
RBAC_PACKAGE: {
package: 'rbac.v1',
protoPath: PROTO_PATHS.ACCOUNT,
env: 'AUTH_GRPC_URL'
},
TWOFA_PACKAGE: {
package: 'two_fa.v1',
protoPath: PROTO_PATHS.TWOFA,
env: 'AUTH_GRPC_URL'
},
LDAP_AUTH_PACKAGE: {
package: 'ldap_auth.v1',
protoPath: PROTO_PATHS.LDAP_AUTH,
env: 'LDAP_AUTH_GRPC_URL'
},
LDAP_PACKAGE: {
package: 'ldap.v1',
protoPath: PROTO_PATHS.LDAP,
env: 'LDAP_GRPC_URL'
},
SEARCH_PACKAGE: {
package: 'search.v1',
protoPath: PROTO_PATHS.SEARCH,
env: 'SEARCH_GRPC_URL'
}
} as const

1504
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "@lendry-erp/common",
"version": "1.0.2",
"version": "1.1.0",
"description": "Core shared components for Lendry-ERP microservice ecosystem",
"main": "dist/index.js",
"type": "dist/index.d.ts",
@@ -19,5 +19,11 @@
"@types/node": "^25.5.0",
"prettier": "^3.8.1",
"typescript": "^6.0.2"
},
"dependencies": {
"@lendry-erp/contracts": "^1.1.10",
"@nestjs/common": "^11.1.18",
"@nestjs/config": "^4.0.4",
"@nestjs/microservices": "^11.1.18"
}
}