diff --git a/packages/frontend-plugin-api/src/routing/ExternalRouteRef.test.ts b/packages/frontend-plugin-api/src/routing/ExternalRouteRef.test.ts index a38937775c..ad47941833 100644 --- a/packages/frontend-plugin-api/src/routing/ExternalRouteRef.test.ts +++ b/packages/frontend-plugin-api/src/routing/ExternalRouteRef.test.ts @@ -27,7 +27,12 @@ describe('ExternalRouteRef', () => { const internal = toInternalExternalRouteRef(routeRef); expect(internal.getParams()).toEqual([]); expect(internal.optional).toBe(false); - expect(String(internal)).toBe('routeRef{type=external,id=my-route-ref}'); + + expect(String(internal)).toMatch( + /^ExternalRouteRef\{created at '.*ExternalRouteRef\.test\.ts.*'\}$/, + ); + internal.setId('some-id'); + expect(String(internal)).toBe('ExternalRouteRef{some-id}'); }); it('should be created as optional', () => { diff --git a/packages/frontend-plugin-api/src/routing/ExternalRouteRef.ts b/packages/frontend-plugin-api/src/routing/ExternalRouteRef.ts index edc546ee23..ad5ad05f05 100644 --- a/packages/frontend-plugin-api/src/routing/ExternalRouteRef.ts +++ b/packages/frontend-plugin-api/src/routing/ExternalRouteRef.ts @@ -14,6 +14,8 @@ * limitations under the License. */ +import { RouteRefImpl } from './RouteRef'; +import { describeParentCallSite } from './describeParentCallSite'; import { AnyRouteParams } from './types'; /** @@ -41,6 +43,9 @@ export interface InternalExternalRouteRef< > extends ExternalRouteRef { readonly version: 'v1'; getParams(): string[]; + getDescription(): string; + + setId(id: string): void; } /** @internal */ @@ -66,26 +71,18 @@ export function isExternalRouteRef(opaque: { } /** @internal */ -export class ExternalRouteRefImpl implements InternalExternalRouteRef { - readonly $$type = '@backstage/ExternalRouteRef'; - readonly version = 'v1'; +class ExternalRouteRefImpl + extends RouteRefImpl + implements InternalExternalRouteRef +{ + readonly $$type = '@backstage/ExternalRouteRef' as any; - #params: string[]; - - constructor(readonly optional: boolean, readonly params: string[] = []) { - this.#params = params; - } - - get T(): never { - throw new Error(`tried to read ExternalRouteRef.T of ${this}`); - } - - getParams(): string[] { - return this.#params; - } - - toString(): string { - return `ExternalRouteRef{}`; + constructor( + readonly optional: boolean, + readonly params: string[] = [], + creationSite: string, + ) { + super(params, creationSite); } } @@ -129,5 +126,6 @@ export function createExternalRouteRef< return new ExternalRouteRefImpl( Boolean(options?.optional), options?.params as string[] | undefined, + describeParentCallSite(), ) as ExternalRouteRef; } diff --git a/packages/frontend-plugin-api/src/routing/RouteRef.ts b/packages/frontend-plugin-api/src/routing/RouteRef.ts index 5f1f7a135d..f8ca088d0f 100644 --- a/packages/frontend-plugin-api/src/routing/RouteRef.ts +++ b/packages/frontend-plugin-api/src/routing/RouteRef.ts @@ -88,20 +88,24 @@ export class RouteRefImpl implements InternalRouteRef { return `created at '${this.#creationSite}'`; } + get #name() { + return this.$$type.slice('@backstage/'.length); + } + setId(id: string): void { if (!id) { - throw new Error('RouteRef id must be a non-empty string'); + throw new Error(`${this.#name} id must be a non-empty string`); } if (this.#id) { throw new Error( - `RouteRef was referenced twice as both '${this.#id}' and '${id}'`, + `${this.#name} was referenced twice as both '${this.#id}' and '${id}'`, ); } this.#id = id; } toString(): string { - return `RouteRef{${this.getDescription()}}`; + return `${this.#name}{${this.getDescription()}}`; } } @@ -126,9 +130,8 @@ export function createRouteRef< ? TParams : { [param in TParamKeys]: string } > { - const creationSite = describeParentCallSite(); return new RouteRefImpl( config?.params as string[] | undefined, - creationSite, + describeParentCallSite(), ) as RouteRef; }