import { FilledLinkToDocumentField, FilledLinkToMediaField, FilledLinkToWebField, LinkField, LinkType, PrismicDocument, } from "@prismicio/types"; import { documentToLinkField } from "./documentToLinkField"; import { LinkResolverFunction } from "./types"; /** * The return type of `asLink()`. */ type AsLinkReturnType< LinkResolverFunctionReturnType = string, Field extends LinkField | PrismicDocument | null | undefined = | LinkField | PrismicDocument | null | undefined, > = Field extends | FilledLinkToWebField | FilledLinkToMediaField | FilledLinkToDocumentField | PrismicDocument ? LinkResolverFunctionReturnType | string | null : null; /** * Resolves any type of link field or document to a URL * * @typeParam LinkResolverFunctionReturnType - Link resolver function return * type * @param linkFieldOrDocument - Any kind of link field or a document to resolve * @param linkResolver - An optional link resolver function, without it you're * expected to use the `routes` options from the API * * @returns Resolved URL, null if provided link is empty * @see Prismic link resolver documentation: {@link https://prismic.io/docs/technologies/link-resolver-javascript} * @see Prismic API `routes` options documentation: {@link https://prismic.io/docs/technologies/route-resolver-nuxtjs} */ export const asLink = < LinkResolverFunctionReturnType = string, Field extends LinkField | PrismicDocument | null | undefined = | LinkField | PrismicDocument | null | undefined, >( linkFieldOrDocument: Field, linkResolver?: LinkResolverFunction | null, ): AsLinkReturnType => { if (!linkFieldOrDocument) { return null as AsLinkReturnType; } // Converts document to link field if needed const linkField = // prettier-ignore ( // @ts-expect-error - Bug in TypeScript 4.9: https://github.com/microsoft/TypeScript/issues/51501 // TODO: Remove the `prettier-ignore` comment when this bug is fixed. "link_type" in linkFieldOrDocument ? linkFieldOrDocument : documentToLinkField(linkFieldOrDocument) ) as LinkField; switch (linkField.link_type) { case LinkType.Media: case LinkType.Web: return ("url" in linkField ? linkField.url : null) as AsLinkReturnType< LinkResolverFunctionReturnType, Field >; case LinkType.Document: { if ("id" in linkField && linkResolver) { // When using Link Resolver... const resolvedURL = linkResolver(linkField); if (resolvedURL != null) { return resolvedURL as AsLinkReturnType< LinkResolverFunctionReturnType, Field >; } } if ("url" in linkField && linkField.url) { // When using Route Resolver... return linkField.url as AsLinkReturnType< LinkResolverFunctionReturnType, Field >; } // When empty or Link Resolver and Route Resolver are not used... return null as AsLinkReturnType; } case LinkType.Any: default: return null as AsLinkReturnType; } };