frontend-plugin-api: add ID and description for RouteRef
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -15,13 +15,30 @@
|
||||
*/
|
||||
|
||||
import { AnyRouteParams } from './types';
|
||||
import { RouteRef, createRouteRef } from './RouteRef';
|
||||
import { RouteRef, createRouteRef, toInternalRouteRef } from './RouteRef';
|
||||
|
||||
describe('RouteRef', () => {
|
||||
it('should be created', () => {
|
||||
it('should be created and have a mutable ID', () => {
|
||||
const routeRef: RouteRef<undefined> = createRouteRef();
|
||||
expect(() => routeRef.T).toThrow();
|
||||
expect(String(routeRef)).toBe('RouteRef{}');
|
||||
const internal = toInternalRouteRef(routeRef);
|
||||
expect(() => internal.T).toThrow();
|
||||
expect(internal.getParams()).toEqual([]);
|
||||
expect(internal.getDescription()).toMatch(/RouteRef\.test\.ts/);
|
||||
|
||||
expect(String(internal)).toMatch(
|
||||
/^RouteRef\{created at .*RouteRef\.test\.ts.*\}$/,
|
||||
);
|
||||
|
||||
expect(() => internal.setId('')).toThrow(
|
||||
'RouteRef id must be a non-empty string',
|
||||
);
|
||||
|
||||
internal.setId('some-id');
|
||||
expect(String(internal)).toBe('RouteRef{some-id}');
|
||||
|
||||
expect(() => internal.setId('some-other-id')).toThrow(
|
||||
"RouteRef was referenced twice as both 'some-id' and 'some-other-id'",
|
||||
);
|
||||
});
|
||||
|
||||
it('should be created with params', () => {
|
||||
@@ -31,7 +48,10 @@ describe('RouteRef', () => {
|
||||
}> = createRouteRef({
|
||||
params: ['x', 'y'],
|
||||
});
|
||||
expect(() => routeRef.T).toThrow();
|
||||
const internal = toInternalRouteRef(routeRef);
|
||||
expect(internal.getParams()).toEqual(['x', 'y']);
|
||||
expect(internal.getDescription()).toMatch(/RouteRef\.test\.ts/);
|
||||
expect(() => internal.T).toThrow();
|
||||
});
|
||||
|
||||
it('should properly infer and validate parameter types and assignments', () => {
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { describeParentCallSite } from './describeParentCallSite';
|
||||
import { AnyRouteParams } from './types';
|
||||
|
||||
/**
|
||||
@@ -36,6 +37,9 @@ export interface InternalRouteRef<
|
||||
> extends RouteRef<TParams> {
|
||||
readonly version: 'v1';
|
||||
getParams(): string[];
|
||||
getDescription(): string;
|
||||
|
||||
setId(id: string): void;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
@@ -60,10 +64,13 @@ export class RouteRefImpl implements InternalRouteRef {
|
||||
readonly $$type = '@backstage/RouteRef';
|
||||
readonly version = 'v1';
|
||||
|
||||
#id?: string;
|
||||
#params: string[];
|
||||
#creationSite: string;
|
||||
|
||||
constructor(readonly params: string[] = []) {
|
||||
constructor(readonly params: string[] = [], creationSite: string) {
|
||||
this.#params = params;
|
||||
this.#creationSite = creationSite;
|
||||
}
|
||||
|
||||
get T(): never {
|
||||
@@ -74,8 +81,27 @@ export class RouteRefImpl implements InternalRouteRef {
|
||||
return this.#params;
|
||||
}
|
||||
|
||||
getDescription(): string {
|
||||
if (this.#id) {
|
||||
return this.#id;
|
||||
}
|
||||
return `created at '${this.#creationSite}'`;
|
||||
}
|
||||
|
||||
setId(id: string): void {
|
||||
if (!id) {
|
||||
throw new Error('RouteRef id must be a non-empty string');
|
||||
}
|
||||
if (this.#id) {
|
||||
throw new Error(
|
||||
`RouteRef was referenced twice as both '${this.#id}' and '${id}'`,
|
||||
);
|
||||
}
|
||||
this.#id = id;
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `RouteRef{}`;
|
||||
return `RouteRef{${this.getDescription()}}`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,7 +126,9 @@ export function createRouteRef<
|
||||
? TParams
|
||||
: { [param in TParamKeys]: string }
|
||||
> {
|
||||
const creationSite = describeParentCallSite();
|
||||
return new RouteRefImpl(
|
||||
config?.params as string[] | undefined,
|
||||
creationSite,
|
||||
) as RouteRef<any>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user