declaratively disable external routes

Signed-off-by: Fredrik Adelöw <freben@gmail.com>
This commit is contained in:
Fredrik Adelöw
2024-06-24 15:46:20 +02:00
parent 0c5aa5a007
commit d3c39fc71c
5 changed files with 133 additions and 26 deletions
@@ -161,4 +161,31 @@ describe('resolveRouteBindings', () => {
expect(result.get(source)).toBe(target2);
});
it('can disable external routes that have defaults', () => {
const source = createExternalRouteRef({ defaultTarget: 'target1' });
const target1 = createRouteRef();
const routesById = {
routes: new Map([['target1', target1]]),
externalRoutes: new Map([['source', source]]),
};
// resolves normally with no config
let result = resolveRouteBindings(
() => {},
new ConfigReader({}),
routesById,
);
expect(result.get(source)).toBe(target1);
// can be disabled
result = resolveRouteBindings(
() => {},
new ConfigReader({ app: { routes: { bindings: { source: false } } } }),
routesById,
);
expect(result.get(source)).toBe(undefined);
});
});
@@ -112,11 +112,12 @@ export function resolveRouteBindings(
const bindings = config
.getOptionalConfig('app.routes.bindings')
?.get<JsonObject>();
const disabledExternalRefs = new Set<ExternalRouteRef>();
if (bindings) {
for (const [externalRefId, targetRefId] of Object.entries(bindings)) {
if (typeof targetRefId !== 'string' || targetRefId === '') {
if (!isValidTargetRefId(targetRefId)) {
throw new Error(
`Invalid config at app.routes.bindings['${externalRefId}'], value must be a non-empty string`,
`Invalid config at app.routes.bindings['${externalRefId}'], value must be a non-empty string or false`,
);
}
@@ -126,23 +127,27 @@ export function resolveRouteBindings(
`Invalid config at app.routes.bindings, '${externalRefId}' is not a valid external route`,
);
}
if (result.has(externalRef)) {
continue;
}
const targetRef = routesById.routes.get(targetRefId);
if (!targetRef) {
throw new Error(
`Invalid config at app.routes.bindings['${externalRefId}'], '${targetRefId}' is not a valid route`,
);
}
result.set(externalRef, targetRef);
if (targetRefId === false) {
disabledExternalRefs.add(externalRef);
result.delete(externalRef);
} else if (!result.has(externalRef)) {
const targetRef = routesById.routes.get(targetRefId);
if (!targetRef) {
throw new Error(
`Invalid config at app.routes.bindings['${externalRefId}'], '${targetRefId}' is not a valid route`,
);
}
result.set(externalRef, targetRef);
}
}
}
// Finally fall back to attempting to map defaults, at lowest priority
for (const externalRef of routesById.externalRoutes.values()) {
if (!result.has(externalRef)) {
if (!result.has(externalRef) && !disabledExternalRefs.has(externalRef)) {
const defaultRefId =
toInternalExternalRouteRef(externalRef).getDefaultTarget();
if (defaultRefId) {
@@ -156,3 +161,15 @@ export function resolveRouteBindings(
return result;
}
function isValidTargetRefId(value: unknown): value is string | false {
if (value === false) {
return true;
}
if (typeof value === 'string' && value) {
return true;
}
return false;
}