@redocly/theme
Version:
Shared UI components lib
47 lines (38 loc) • 1.65 kB
text/typescript
import { useMemo } from 'react';
import type { EntitiesCatalogConfig } from '@redocly/config';
export type EntityWithTypeAndKey = { type?: string; key?: string };
function isEntityExcluded(
excludes: Array<{ key: string }> | undefined,
entityKey: string,
): boolean {
return excludes?.some((ex) => ex.key === entityKey) ?? false;
}
function doesCatalogIncludeEntityType(
config: { includes?: Array<{ type: string }> },
entityType: string,
): boolean {
const hasNoIncludes = !config.includes || config.includes.length === 0;
if (hasNoIncludes) return true;
return config.includes?.some((inc) => inc.type === entityType) ?? false;
}
export function useCatalogEntityLink(entitiesCatalogConfig: EntitiesCatalogConfig | undefined) {
const catalogEntries = useMemo(() => {
const catalogs = entitiesCatalogConfig?.catalogs;
if (!catalogs) return [];
return Object.entries(catalogs)
.filter((entry): entry is [string, NonNullable<(typeof entry)[1]>] => entry[1] != null)
.sort(([keyA], [keyB]) => (keyA === 'all' ? 1 : 0) - (keyB === 'all' ? 1 : 0));
}, [entitiesCatalogConfig]);
const getEntityLink = (entity: EntityWithTypeAndKey): string | undefined => {
if (!entity?.key) return undefined;
const entityType = entity.type ?? '';
for (const [catalogKey, config] of catalogEntries) {
if (isEntityExcluded(config.excludes, entity.key)) continue;
if (!doesCatalogIncludeEntityType(config, entityType)) continue;
const slug = config.slug ?? catalogKey;
return `catalogs/${slug}/entities/${entity.key}`;
}
return undefined;
};
return { getEntityLink };
}