diff --git a/integration/async-iterable-services-abort-signal/simple.ts b/integration/async-iterable-services-abort-signal/simple.ts index cf0c89c2f..5431d0dd3 100644 --- a/integration/async-iterable-services-abort-signal/simple.ts +++ b/integration/async-iterable-services-abort-signal/simple.ts @@ -108,11 +108,12 @@ export interface Echoer { EchoBidiStream(request: AsyncIterable, abortSignal?: AbortSignal): AsyncIterable; } +export const EchoerServiceName = "simple.Echoer"; export class EchoerClientImpl implements Echoer { private readonly rpc: Rpc; private readonly service: string; constructor(rpc: Rpc, opts?: { service?: string }) { - this.service = opts?.service || "simple.Echoer"; + this.service = opts?.service || EchoerServiceName; this.rpc = rpc; this.Echo = this.Echo.bind(this); this.EchoServerStream = this.EchoServerStream.bind(this); diff --git a/integration/async-iterable-services/simple.ts b/integration/async-iterable-services/simple.ts index 63394ee7a..816ccf49e 100644 --- a/integration/async-iterable-services/simple.ts +++ b/integration/async-iterable-services/simple.ts @@ -108,11 +108,12 @@ export interface Echoer { EchoBidiStream(request: AsyncIterable): AsyncIterable; } +export const EchoerServiceName = "simple.Echoer"; export class EchoerClientImpl implements Echoer { private readonly rpc: Rpc; private readonly service: string; constructor(rpc: Rpc, opts?: { service?: string }) { - this.service = opts?.service || "simple.Echoer"; + this.service = opts?.service || EchoerServiceName; this.rpc = rpc; this.Echo = this.Echo.bind(this); this.EchoServerStream = this.EchoServerStream.bind(this); diff --git a/integration/avoid-import-conflicts/simple.ts b/integration/avoid-import-conflicts/simple.ts index b537744ac..41ebd16ca 100644 --- a/integration/avoid-import-conflicts/simple.ts +++ b/integration/avoid-import-conflicts/simple.ts @@ -330,11 +330,12 @@ export interface FooService { Create(request: FooServiceCreateRequest): Promise; } +export const FooServiceServiceName = "simple.FooService"; export class FooServiceClientImpl implements FooService { private readonly rpc: Rpc; private readonly service: string; constructor(rpc: Rpc, opts?: { service?: string }) { - this.service = opts?.service || "simple.FooService"; + this.service = opts?.service || FooServiceServiceName; this.rpc = rpc; this.Create = this.Create.bind(this); } diff --git a/integration/batching-with-context-esModuleInterop/batching.ts b/integration/batching-with-context-esModuleInterop/batching.ts index 962d521b2..b6a1f28e7 100644 --- a/integration/batching-with-context-esModuleInterop/batching.ts +++ b/integration/batching-with-context-esModuleInterop/batching.ts @@ -672,11 +672,12 @@ export interface EntityService { WriteMethod(ctx: Context, request: WriteMethodRequest): Promise; } +export const EntityServiceServiceName = "batching.EntityService"; export class EntityServiceClientImpl implements EntityService { private readonly rpc: Rpc; private readonly service: string; constructor(rpc: Rpc, opts?: { service?: string }) { - this.service = opts?.service || "batching.EntityService"; + this.service = opts?.service || EntityServiceServiceName; this.rpc = rpc; this.BatchQuery = this.BatchQuery.bind(this); this.BatchMapQuery = this.BatchMapQuery.bind(this); diff --git a/integration/batching-with-context/batching.ts b/integration/batching-with-context/batching.ts index f88d63cc8..6ea9a0cb5 100644 --- a/integration/batching-with-context/batching.ts +++ b/integration/batching-with-context/batching.ts @@ -672,11 +672,12 @@ export interface EntityService { WriteMethod(ctx: Context, request: WriteMethodRequest): Promise; } +export const EntityServiceServiceName = "batching.EntityService"; export class EntityServiceClientImpl implements EntityService { private readonly rpc: Rpc; private readonly service: string; constructor(rpc: Rpc, opts?: { service?: string }) { - this.service = opts?.service || "batching.EntityService"; + this.service = opts?.service || EntityServiceServiceName; this.rpc = rpc; this.BatchQuery = this.BatchQuery.bind(this); this.BatchMapQuery = this.BatchMapQuery.bind(this); diff --git a/integration/batching/batching.ts b/integration/batching/batching.ts index 207e99f90..8af8cef8b 100644 --- a/integration/batching/batching.ts +++ b/integration/batching/batching.ts @@ -668,11 +668,12 @@ export interface EntityService { WriteMethod(request: WriteMethodRequest): Promise; } +export const EntityServiceServiceName = "batching.EntityService"; export class EntityServiceClientImpl implements EntityService { private readonly rpc: Rpc; private readonly service: string; constructor(rpc: Rpc, opts?: { service?: string }) { - this.service = opts?.service || "batching.EntityService"; + this.service = opts?.service || EntityServiceServiceName; this.rpc = rpc; this.BatchQuery = this.BatchQuery.bind(this); this.BatchMapQuery = this.BatchMapQuery.bind(this); diff --git a/integration/generic-metadata/hero.ts b/integration/generic-metadata/hero.ts index ff60a24cf..c2eb9fb9a 100644 --- a/integration/generic-metadata/hero.ts +++ b/integration/generic-metadata/hero.ts @@ -278,11 +278,12 @@ export interface HeroService { FindManyVillain(request: Observable, metadata?: Foo): Observable; } +export const HeroServiceServiceName = "hero.HeroService"; export class HeroServiceClientImpl implements HeroService { private readonly rpc: Rpc; private readonly service: string; constructor(rpc: Rpc, opts?: { service?: string }) { - this.service = opts?.service || "hero.HeroService"; + this.service = opts?.service || HeroServiceServiceName; this.rpc = rpc; this.FindOneHero = this.FindOneHero.bind(this); this.FindOneVillain = this.FindOneVillain.bind(this); diff --git a/integration/grpc-web-go-server/example.ts b/integration/grpc-web-go-server/example.ts index 15845be42..159bfdae1 100644 --- a/integration/grpc-web-go-server/example.ts +++ b/integration/grpc-web-go-server/example.ts @@ -711,11 +711,12 @@ export interface DashState { ActiveUserSettingsStream(request: Empty): Observable; } +export const DashStateServiceName = "rpx.DashState"; export class DashStateClientImpl implements DashState { private readonly rpc: Rpc; private readonly service: string; constructor(rpc: Rpc, opts?: { service?: string }) { - this.service = opts?.service || "rpx.DashState"; + this.service = opts?.service || DashStateServiceName; this.rpc = rpc; this.UserSettings = this.UserSettings.bind(this); this.ActiveUserSettingsStream = this.ActiveUserSettingsStream.bind(this); @@ -744,11 +745,12 @@ export interface DashAPICreds { Delete(request: DashAPICredsDeleteReq): Promise; } +export const DashAPICredsServiceName = "rpx.DashAPICreds"; export class DashAPICredsClientImpl implements DashAPICreds { private readonly rpc: Rpc; private readonly service: string; constructor(rpc: Rpc, opts?: { service?: string }) { - this.service = opts?.service || "rpx.DashAPICreds"; + this.service = opts?.service || DashAPICredsServiceName; this.rpc = rpc; this.Create = this.Create.bind(this); this.Update = this.Update.bind(this); diff --git a/integration/lower-case-svc-methods/math.ts b/integration/lower-case-svc-methods/math.ts index 3fd9b0a23..46e107b41 100644 --- a/integration/lower-case-svc-methods/math.ts +++ b/integration/lower-case-svc-methods/math.ts @@ -221,11 +221,12 @@ export interface MathService { getDouble(ctx: Context, nu: number): Promise; } +export const MathServiceServiceName = "MathService"; export class MathServiceClientImpl implements MathService { private readonly rpc: Rpc; private readonly service: string; constructor(rpc: Rpc, opts?: { service?: string }) { - this.service = opts?.service || "MathService"; + this.service = opts?.service || MathServiceServiceName; this.rpc = rpc; this.add = this.add.bind(this); this.absoluteValue = this.absoluteValue.bind(this); diff --git a/integration/meta-typings/simple.ts b/integration/meta-typings/simple.ts index b1b306daf..5602bb820 100644 --- a/integration/meta-typings/simple.ts +++ b/integration/meta-typings/simple.ts @@ -1584,11 +1584,12 @@ export interface PingService { ping(request: PingRequest): Promise; } +export const PingServiceServiceName = "simple.PingService"; export class PingServiceClientImpl implements PingService { private readonly rpc: Rpc; private readonly service: string; constructor(rpc: Rpc, opts?: { service?: string }) { - this.service = opts?.service || "simple.PingService"; + this.service = opts?.service || PingServiceServiceName; this.rpc = rpc; this.ping = this.ping.bind(this); } diff --git a/integration/no-proto-package/no-proto-package.ts b/integration/no-proto-package/no-proto-package.ts index 8cc8b665f..4ceca7346 100644 --- a/integration/no-proto-package/no-proto-package.ts +++ b/integration/no-proto-package/no-proto-package.ts @@ -116,11 +116,12 @@ export interface UserState { GetUsers(request: Empty): Observable; } +export const UserStateServiceName = "UserState"; export class UserStateClientImpl implements UserState { private readonly rpc: Rpc; private readonly service: string; constructor(rpc: Rpc, opts?: { service?: string }) { - this.service = opts?.service || "UserState"; + this.service = opts?.service || UserStateServiceName; this.rpc = rpc; this.GetUsers = this.GetUsers.bind(this); } diff --git a/integration/options/options.ts b/integration/options/options.ts index 26a79ebaa..3fe6f9dd0 100644 --- a/integration/options/options.ts +++ b/integration/options/options.ts @@ -147,11 +147,12 @@ export interface MyService { MyMethod(request: RequestType): Promise; } +export const MyServiceServiceName = "MyService"; export class MyServiceClientImpl implements MyService { private readonly rpc: Rpc; private readonly service: string; constructor(rpc: Rpc, opts?: { service?: string }) { - this.service = opts?.service || "MyService"; + this.service = opts?.service || MyServiceServiceName; this.rpc = rpc; this.MyMethod = this.MyMethod.bind(this); } diff --git a/integration/simple-optionals/simple.ts b/integration/simple-optionals/simple.ts index 13ba7fd19..edf6bf894 100644 --- a/integration/simple-optionals/simple.ts +++ b/integration/simple-optionals/simple.ts @@ -1849,11 +1849,12 @@ export interface PingService { ping(request: PingRequest): Promise; } +export const PingServiceServiceName = "simple.PingService"; export class PingServiceClientImpl implements PingService { private readonly rpc: Rpc; private readonly service: string; constructor(rpc: Rpc, opts?: { service?: string }) { - this.service = opts?.service || "simple.PingService"; + this.service = opts?.service || PingServiceServiceName; this.rpc = rpc; this.ping = this.ping.bind(this); } diff --git a/integration/simple-prototype-defaults/simple.ts b/integration/simple-prototype-defaults/simple.ts index 499b433c1..48504179e 100644 --- a/integration/simple-prototype-defaults/simple.ts +++ b/integration/simple-prototype-defaults/simple.ts @@ -2776,11 +2776,12 @@ export interface PingService { ping(request: PingRequest): Promise; } +export const PingServiceServiceName = "simple.PingService"; export class PingServiceClientImpl implements PingService { private readonly rpc: Rpc; private readonly service: string; constructor(rpc: Rpc, opts?: { service?: string }) { - this.service = opts?.service || "simple.PingService"; + this.service = opts?.service || PingServiceServiceName; this.rpc = rpc; this.ping = this.ping.bind(this); } diff --git a/integration/simple-snake/simple.ts b/integration/simple-snake/simple.ts index 8a0c345e8..ac4c22521 100644 --- a/integration/simple-snake/simple.ts +++ b/integration/simple-snake/simple.ts @@ -1910,11 +1910,12 @@ export interface PingService { ping(request: PingRequest): Promise; } +export const PingServiceServiceName = "simple.PingService"; export class PingServiceClientImpl implements PingService { private readonly rpc: Rpc; private readonly service: string; constructor(rpc: Rpc, opts?: { service?: string }) { - this.service = opts?.service || "simple.PingService"; + this.service = opts?.service || PingServiceServiceName; this.rpc = rpc; this.ping = this.ping.bind(this); } diff --git a/integration/simple-unrecognized-enum/simple.ts b/integration/simple-unrecognized-enum/simple.ts index db76f5e6d..fb4ff8498 100644 --- a/integration/simple-unrecognized-enum/simple.ts +++ b/integration/simple-unrecognized-enum/simple.ts @@ -1837,11 +1837,12 @@ export interface PingService { ping(request: PingRequest): Promise; } +export const PingServiceServiceName = "simple.PingService"; export class PingServiceClientImpl implements PingService { private readonly rpc: Rpc; private readonly service: string; constructor(rpc: Rpc, opts?: { service?: string }) { - this.service = opts?.service || "simple.PingService"; + this.service = opts?.service || PingServiceServiceName; this.rpc = rpc; this.ping = this.ping.bind(this); } diff --git a/integration/simple/simple.ts b/integration/simple/simple.ts index 037da2435..ed5fa6b30 100644 --- a/integration/simple/simple.ts +++ b/integration/simple/simple.ts @@ -2779,11 +2779,12 @@ export interface PingService { ping(request: PingRequest): Promise; } +export const PingServiceServiceName = "simple.PingService"; export class PingServiceClientImpl implements PingService { private readonly rpc: Rpc; private readonly service: string; constructor(rpc: Rpc, opts?: { service?: string }) { - this.service = opts?.service || "simple.PingService"; + this.service = opts?.service || PingServiceServiceName; this.rpc = rpc; this.ping = this.ping.bind(this); } diff --git a/integration/unknown-fields/options.ts b/integration/unknown-fields/options.ts index 02caa930e..a11f42149 100644 --- a/integration/unknown-fields/options.ts +++ b/integration/unknown-fields/options.ts @@ -219,11 +219,12 @@ export interface MyService { MyMethod(request: RequestType): Promise; } +export const MyServiceServiceName = "MyService"; export class MyServiceClientImpl implements MyService { private readonly rpc: Rpc; private readonly service: string; constructor(rpc: Rpc, opts?: { service?: string }) { - this.service = opts?.service || "MyService"; + this.service = opts?.service || MyServiceServiceName; this.rpc = rpc; this.MyMethod = this.MyMethod.bind(this); } diff --git a/integration/use-date-true/use-date-true.ts b/integration/use-date-true/use-date-true.ts index 5b40d1969..27cb61142 100644 --- a/integration/use-date-true/use-date-true.ts +++ b/integration/use-date-true/use-date-true.ts @@ -230,11 +230,12 @@ export interface Clock { Now(request: Empty): Promise; } +export const ClockServiceName = "Clock"; export class ClockClientImpl implements Clock { private readonly rpc: Rpc; private readonly service: string; constructor(rpc: Rpc, opts?: { service?: string }) { - this.service = opts?.service || "Clock"; + this.service = opts?.service || ClockServiceName; this.rpc = rpc; this.Now = this.Now.bind(this); } diff --git a/integration/wrappers-regression/wrappers-regression.ts b/integration/wrappers-regression/wrappers-regression.ts index 9a9dcb540..1b343440a 100644 --- a/integration/wrappers-regression/wrappers-regression.ts +++ b/integration/wrappers-regression/wrappers-regression.ts @@ -15,11 +15,12 @@ export interface Clock { NowBool(request: Empty): Promise; } +export const ClockServiceName = "Clock"; export class ClockClientImpl implements Clock { private readonly rpc: Rpc; private readonly service: string; constructor(rpc: Rpc, opts?: { service?: string }) { - this.service = opts?.service || "Clock"; + this.service = opts?.service || ClockServiceName; this.rpc = rpc; this.Now = this.Now.bind(this); this.NowString = this.NowString.bind(this); diff --git a/src/generate-services.ts b/src/generate-services.ts index 15b2dcd33..3deb8bb7b 100644 --- a/src/generate-services.ts +++ b/src/generate-services.ts @@ -181,8 +181,15 @@ export function generateServiceClientImpl( const { options } = ctx; const chunks: Code[] = []; - // Define the FooServiceImpl class + // Determine information about the service. const { name } = serviceDesc; + const serviceName = maybePrefixPackage(fileDesc, serviceDesc.name); + + // Define the service name constant. + const serviceNameConst = `${name}ServiceName`; + chunks.push(code`export const ${serviceNameConst} = "${serviceName}";`); + + // Define the FooServiceImpl class const i = options.context ? `${name}` : name; const t = options.context ? `<${contextTypeVar}>` : ""; chunks.push(code`export class ${name}ClientImpl${t} implements ${def(i)} {`); @@ -192,8 +199,7 @@ export function generateServiceClientImpl( chunks.push(code`private readonly rpc: ${rpcType};`); chunks.push(code`private readonly service: string;`); chunks.push(code`constructor(rpc: ${rpcType}, opts?: {service?: string}) {`); - const serviceID = maybePrefixPackage(fileDesc, serviceDesc.name); - chunks.push(code`this.service = opts?.service || "${serviceID}";`); + chunks.push(code`this.service = opts?.service || ${serviceNameConst};`); chunks.push(code`this.rpc = rpc;`); // Bind each FooService method to the FooServiceImpl class