core/resolvers/link.resolver.ts
core/resolvers/link.resolver.ts is a file in Bane's Lab Build Scripts. 80 lines of code and 20 definitions.
import type { Canonical, Identity, Link, Linker, Unresolved } from "#types/catalog.types";
import { MARKDOWN_EXTENSION } from "#configuration/constants/site.constants";
import { rewriteTargets } from "#core/converters/link.converter";
const ROOT = "/";
const FRAGMENT = "#";
const EXTENSION_MARK = ".";
const isPageLink = function isPageLink(target: string): boolean {
return target.startsWith(ROOT) && !target.includes(FRAGMENT) && !target.includes(EXTENSION_MARK);
};
const absoluteOf = function absoluteOf(target: string, base: string): string | null {
if (target.startsWith(FRAGMENT)) {
return base + target;
}
return target.startsWith(ROOT) ? target : null;
};
const pageOf = function pageOf(identity: Identity): string | null {
const { markdown } = identity.address;
return markdown?.endsWith(MARKDOWN_EXTENSION) === true ? markdown.slice(0, -MARKDOWN_EXTENSION.length) : null;
};
export const linkOf = function linkOf(identity: Identity, site: string, label: string): Link {
const { address, href } = identity;
return {
href: href === null ? null : site + href,
json: site + address.json,
label,
markdown: address.markdown === null ? null : site + address.markdown,
ref: identity.ref,
};
};
export const createLinker = function createLinker(
identities: readonly Identity[],
site: string,
canonical: Canonical,
routes: ReadonlySet<string> | null = null,
): Linker {
const byRef = new Map(identities.map((identity) => [identity.ref, identity]));
const byHref = new Map<string, Identity>();
for (const identity of identities) {
for (const address of [identity.href, pageOf(identity)]) {
if (address !== null && !byHref.has(canonical(address))) {
byHref.set(canonical(address), identity);
}
}
}
const missed: Unresolved[] = [];
const link = function link(label: string, ref: string | null): Link {
const identity = ref === null ? undefined : byRef.get(ref);
if (identity === undefined) {
if (ref !== null) {
missed.push({ from: null, label, target: ref });
}
return { href: null, json: null, label, markdown: null, ref };
}
return linkOf(identity, site, label);
};
const relink = function relink(markdown: string, base: string): string {
return rewriteTargets(markdown, (target) => {
const href = absoluteOf(target, base);
if (href === null) {
return target;
}
const identity = byHref.get(canonical(href));
const leaf = identity?.address.markdown ?? identity?.address.json;
const crossPage = target.startsWith(ROOT) && target.includes(FRAGMENT);
const unrouted = isPageLink(target) && routes !== null && !routes.has(href);
if (leaf === undefined && (crossPage || unrouted)) {
missed.push({ from: base, label: target, target: href });
}
return leaf === undefined ? site + href : site + leaf;
});
};
return {
byHref: (href) => byHref.get(canonical(href)) ?? null,
byRef: (ref) => byRef.get(ref) ?? null,
link,
relink,
site,
unresolved: () => missed,
};
};