core-compat-api: add support for converting new route refs to legacy

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2024-08-04 11:28:38 +02:00
parent 9ade0f99e5
commit ef1b2f4033
3 changed files with 207 additions and 5 deletions
+18
View File
@@ -44,6 +44,24 @@ export function convertLegacyRouteRef<
ref: ExternalRouteRef<TParams, TOptional>,
): ExternalRouteRef_2<TParams, TOptional>;
// @public
export function convertLegacyRouteRef<TParams extends AnyRouteRefParams>(
ref: RouteRef_2<TParams>,
): RouteRef<TParams>;
// @public
export function convertLegacyRouteRef<TParams extends AnyRouteRefParams>(
ref: SubRouteRef_2<TParams>,
): SubRouteRef<TParams>;
// @public
export function convertLegacyRouteRef<
TParams extends AnyRouteRefParams,
TOptional extends boolean,
>(
ref: ExternalRouteRef_2<TParams, TOptional>,
): ExternalRouteRef<TParams, TOptional>;
// @public
export function convertLegacyRouteRefs<
TRefs extends {
@@ -15,6 +15,9 @@
*/
import {
RouteRef as OldRouteRef,
SubRouteRef as OldSubRouteRef,
ExternalRouteRef as OldExternalRouteRef,
createRouteRef as createOldRouteRef,
createSubRouteRef as createOldSubRouteRef,
createExternalRouteRef as createOldExternalRouteRef,
@@ -23,6 +26,9 @@ import {
RouteRef as NewRouteRef,
SubRouteRef as NewSubRouteRef,
ExternalRouteRef as NewExternalRouteRef,
createRouteRef as createNewRouteRef,
createSubRouteRef as createNewSubRouteRef,
createExternalRouteRef as createNewExternalRouteRef,
} from '@backstage/frontend-plugin-api';
import { convertLegacyRouteRef } from './convertLegacyRouteRef';
@@ -70,6 +76,15 @@ describe('convertLegacyRouteRef', () => {
const ref3Converted: NewExternalRouteRef = convertLegacyRouteRef(ref3);
const ref4Converted: NewExternalRouteRef = convertLegacyRouteRef(ref4);
// Check for reference equality
expect(ref1).toBe(ref1Converted);
expect(ref2).toBe(ref2Converted);
expect(ref1sub1).toBe(ref1sub1Converted);
expect(ref1sub2).toBe(ref1sub2Converted);
expect(ref2sub1).toBe(ref2sub1Converted);
expect(ref3).toBe(ref3Converted);
expect(ref4).toBe(ref4Converted);
const ref1Internal = toInternalNewRouteRef(ref1Converted);
const ref2Internal = toInternalNewRouteRef(ref2Converted);
const ref1sub1Internal = toInternalNewSubRouteRef(ref1sub1Converted);
@@ -116,4 +131,76 @@ describe('convertLegacyRouteRef', () => {
expect(ref4Internal.getParams()).toEqual(['p1', 'p2']);
expect(ref4Internal.optional).toBe(true);
});
it('converts new to old', () => {
const ref1 = createNewRouteRef();
const ref2 = createNewRouteRef({ params: ['p1', 'p2'] });
const ref1sub1 = createNewSubRouteRef({
parent: ref1,
path: '/sub1',
});
const ref1sub2 = createNewSubRouteRef({
parent: ref1,
path: '/sub2/:p3',
});
const ref2sub1 = createNewSubRouteRef({
parent: ref2,
path: '/sub1/:p3',
});
const ref3 = createNewExternalRouteRef();
const ref4 = createNewExternalRouteRef({
optional: true,
defaultTarget: 'ref2',
params: ['p1', 'p2'],
});
const ref1Converted: OldRouteRef = convertLegacyRouteRef(ref1);
const ref2Converted: OldRouteRef = convertLegacyRouteRef(ref2);
const ref1sub1Converted: OldSubRouteRef = convertLegacyRouteRef(ref1sub1);
const ref1sub2Converted: OldSubRouteRef = convertLegacyRouteRef(ref1sub2);
const ref2sub1Converted: OldSubRouteRef = convertLegacyRouteRef(ref2sub1);
const ref3Converted: OldExternalRouteRef = convertLegacyRouteRef(ref3);
const ref4Converted: OldExternalRouteRef = convertLegacyRouteRef(ref4);
// Check for reference equality
expect(ref1).toBe(ref1Converted);
expect(ref2).toBe(ref2Converted);
expect(ref1sub1).toBe(ref1sub1Converted);
expect(ref1sub2).toBe(ref1sub2Converted);
expect(ref2sub1).toBe(ref2sub1Converted);
expect(ref3).toBe(ref3Converted);
expect(ref4).toBe(ref4Converted);
expect(String(ref1Converted)).toMatch(/^RouteRef\{created at '.*'\}$/);
expect(ref1Converted.params).toEqual([]);
expect(String(ref2Converted)).toMatch(/^RouteRef\{created at '.*'\}$/);
expect(ref2Converted.params).toEqual(['p1', 'p2']);
expect(String(ref1sub1Converted)).toMatch(
/^SubRouteRef\{at \/sub1 with parent created at '.*'\}$/,
);
expect(ref1sub1Converted.params).toEqual([]);
expect(ref1sub1Converted.parent).toBe(ref1);
expect(String(ref1sub2Converted)).toMatch(
/^SubRouteRef\{at \/sub2\/:p3 with parent created at '.*'\}$/,
);
expect(ref1sub2Converted.params).toEqual(['p3']);
expect(ref1sub2Converted.parent).toBe(ref1);
expect(String(ref2sub1Converted)).toMatch(
/^SubRouteRef\{at \/sub1\/:p3 with parent created at '.*'\}$/,
);
expect(ref2sub1Converted.params).toEqual(['p1', 'p2', 'p3']);
expect(ref2sub1Converted.parent).toBe(ref2);
expect(String(ref3Converted)).toMatch(
/^ExternalRouteRef\{created at '.*'\}$/,
);
expect(ref3Converted.params).toEqual([]);
expect(ref3Converted.optional).toBe(false);
expect(String(ref4Converted)).toMatch(
/^ExternalRouteRef\{created at '.*'\}$/,
);
expect(ref4Converted.params).toEqual(['p1', 'p2']);
expect(ref4Converted.optional).toBe(true);
});
});
@@ -116,16 +116,113 @@ export function convertLegacyRouteRef<
ref: LegacyExternalRouteRef<TParams, TOptional>,
): ExternalRouteRef<TParams, TOptional>;
/**
* A temporary helper to convert a new route ref to the legacy system.
*
* @public
* @remarks
*
* In the future the legacy createRouteRef will instead create refs compatible with both systems.
*/
export function convertLegacyRouteRef<TParams extends AnyRouteRefParams>(
ref: RouteRef<TParams>,
): LegacyRouteRef<TParams>;
/**
* A temporary helper to convert a new sub route ref to the legacy system.
*
* @public
* @remarks
*
* In the future the legacy createSubRouteRef will instead create refs compatible with both systems.
*/
export function convertLegacyRouteRef<TParams extends AnyRouteRefParams>(
ref: SubRouteRef<TParams>,
): LegacySubRouteRef<TParams>;
/**
* A temporary helper to convert a new external route ref to the legacy system.
*
* @public
* @remarks
*
* In the future the legacy createExternalRouteRef will instead create refs compatible with both systems.
*/
export function convertLegacyRouteRef<
TParams extends AnyRouteRefParams,
TOptional extends boolean,
>(
ref: ExternalRouteRef<TParams, TOptional>,
): LegacyExternalRouteRef<TParams, TOptional>;
export function convertLegacyRouteRef(
ref: LegacyRouteRef | LegacySubRouteRef | LegacyExternalRouteRef,
): RouteRef | SubRouteRef | ExternalRouteRef {
ref:
| LegacyRouteRef
| LegacySubRouteRef
| LegacyExternalRouteRef
| RouteRef
| SubRouteRef
| ExternalRouteRef,
):
| RouteRef
| SubRouteRef
| ExternalRouteRef
| LegacyRouteRef
| LegacySubRouteRef
| LegacyExternalRouteRef {
const isNew = '$$type' in ref;
const oldType = (ref as unknown as { [routeRefType]: unknown })[routeRefType];
// Ref has already been converted
if ('$$type' in ref) {
return ref as unknown as RouteRef | SubRouteRef | ExternalRouteRef;
if (isNew && oldType) {
return ref as any;
}
const type = (ref as unknown as { [routeRefType]: unknown })[routeRefType];
if (isNew) {
return convertNewToOld(
ref as unknown as RouteRef | SubRouteRef | ExternalRouteRef,
);
}
return convertOldToNew(ref, oldType);
}
function convertNewToOld(
ref: RouteRef | SubRouteRef | ExternalRouteRef,
): LegacyRouteRef | LegacySubRouteRef | LegacyExternalRouteRef {
if (ref.$$type === '@backstage/RouteRef') {
const newRef = toInternalRouteRef(ref);
return Object.assign(ref, {
[routeRefType]: 'absolute',
params: newRef.getParams(),
title: newRef.getDescription(),
} as Omit<LegacyRouteRef, '$$routeRefType'>) as unknown as LegacyRouteRef;
}
if (ref.$$type === '@backstage/SubRouteRef') {
const newRef = toInternalSubRouteRef(ref);
return Object.assign(ref, {
[routeRefType]: 'sub',
parent: convertLegacyRouteRef(newRef.getParent()),
params: newRef.getParams(),
} as Omit<LegacySubRouteRef, '$$routeRefType' | 'path'>) as unknown as LegacySubRouteRef;
}
if (ref.$$type === '@backstage/ExternalRouteRef') {
const newRef = toInternalExternalRouteRef(ref);
return Object.assign(ref, {
[routeRefType]: 'external',
params: newRef.getParams(),
defaultTarget: newRef.getDefaultTarget(),
} as Omit<LegacyExternalRouteRef, '$$routeRefType' | 'optional'>) as unknown as LegacyExternalRouteRef;
}
throw new Error(
`Failed to convert route ref, unknown type '${(ref as any).$$type}'`,
);
}
function convertOldToNew(
ref: LegacyRouteRef | LegacySubRouteRef | LegacyExternalRouteRef,
type: unknown,
): RouteRef | SubRouteRef | ExternalRouteRef {
if (type === 'absolute') {
const legacyRef = ref as LegacyRouteRef;
const legacyRefStr = String(legacyRef);