UNPKG

@prismicio/client

Version:

The official JavaScript + TypeScript client library for Prismic

207 lines (191 loc) 6.91 kB
import type { FilledContentRelationshipField } from "../types/value/contentRelationship" import type { PrismicDocument } from "../types/value/document" import type { FilledLinkToWebField, LinkField } from "../types/value/link" import { LinkType } from "../types/value/link" import type { FilledLinkToMediaField } from "../types/value/linkToMedia" import { documentToLinkField } from "./documentToLinkField" /** * Resolves a link to a Prismic document to a URL * * @typeParam ReturnType - Return type of your link resolver function, useful if * you prefer to return a complex object * * @param linkToDocumentField - A document link field to resolve * * @returns Resolved URL * * @see Prismic link resolver documentation: {@link https://prismic.io/docs/route-resolver#link-resolver} */ export type LinkResolverFunction<ReturnType = string | null | undefined> = ( linkToDocumentField: FilledContentRelationshipField, ) => ReturnType /** * Configuration that determines the output of `asLink()`. */ type AsLinkConfig<LinkResolverFunctionReturnType = string | null | undefined> = { /** * An optional link resolver function. Without it, you are expected to use * the `routes` options from the API. */ linkResolver?: LinkResolverFunction<LinkResolverFunctionReturnType> | null } // TODO: Remove when we remove support for deprecated tuple-style configuration. /** * @deprecated Use object-style configuration instead. */ type AsLinkDeprecatedTupleConfig< LinkResolverFunctionReturnType = string | null | undefined, > = [linkResolver?: LinkResolverFunction<LinkResolverFunctionReturnType> | null] /** * The return type of `asLink()`. */ export type AsLinkReturnType< LinkResolverFunctionReturnType = string | null | undefined, Field extends LinkField | PrismicDocument | null | undefined = | LinkField | PrismicDocument | null | undefined, > = Field extends | FilledLinkToWebField | FilledLinkToMediaField | FilledContentRelationshipField | PrismicDocument ? LinkResolverFunctionReturnType | string | null : null // TODO: Remove overload when we remove support for deprecated tuple-style configuration. export const asLink: { /** * Resolves any type of link field or Prismic document to a URL. * * @typeParam LinkResolverFunctionReturnType - link resolver function return * type * @typeParam Field - Link field or Prismic document to resolve to a URL * * @param linkFieldOrDocument - Any kind of link field or a document to * resolve * @param config - Configuration that determines the output of `asLink()` * * @returns Resolved URL or, if the provided link field or document is empty, * `null` * * @see Prismic link resolver documentation: {@link https://prismic.io/docs/route-resolver#link-resolver} * @see Prismic API `routes` options documentation: {@link https://prismic.io/docs/route-resolver} */ < LinkResolverFunctionReturnType = string | null | undefined, Field extends LinkField | PrismicDocument | null | undefined = | LinkField | PrismicDocument | null | undefined, >( linkFieldOrDocument: Field, config?: AsLinkConfig<LinkResolverFunctionReturnType>, ): AsLinkReturnType<LinkResolverFunctionReturnType, Field> /** * Resolves any type of link field or Prismic document to a URL. * * @deprecated Use object-style configuration instead. * * @typeParam LinkResolverFunctionReturnType - link resolver function return * type * @typeParam Field - Link field or Prismic document to resolve to a URL * * @param linkFieldOrDocument - Any kind of link field or a document to * resolve * @param linkResolver - An optional link resolver function. Without it, you * are expected to use the `routes` options from the API * * @returns Resolved URL or, if the provided link field or document is empty, * `null` * * @see Prismic link resolver documentation: {@link https://prismic.io/docs/route-resolver#link-resolver} * @see Prismic API `routes` options documentation: {@link https://prismic.io/docs/route-resolver} */ < LinkResolverFunctionReturnType = string | null | undefined, Field extends LinkField | PrismicDocument | null | undefined = | LinkField | PrismicDocument | null | undefined, >( linkFieldOrDocument: Field, ...config: AsLinkDeprecatedTupleConfig<LinkResolverFunctionReturnType> ): AsLinkReturnType<LinkResolverFunctionReturnType, Field> } = < LinkResolverFunctionReturnType = string | null | undefined, Field extends LinkField | PrismicDocument | null | undefined = | LinkField | PrismicDocument | null | undefined, >( linkFieldOrDocument: Field, // TODO: Rename to `config` when we remove support for deprecated tuple-style configuration. ...configObjectOrTuple: | [config?: AsLinkConfig<LinkResolverFunctionReturnType>] | AsLinkDeprecatedTupleConfig<LinkResolverFunctionReturnType> ): AsLinkReturnType<LinkResolverFunctionReturnType, Field> => { if (!linkFieldOrDocument) { return null as AsLinkReturnType<LinkResolverFunctionReturnType, Field> } // Converts document to link field if needed const linkField = // prettier-ignore ( // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - 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 // TODO: Remove when we remove support for deprecated tuple-style configuration. const [configObjectOrLinkResolver] = configObjectOrTuple let config: AsLinkConfig<LinkResolverFunctionReturnType> if ( typeof configObjectOrLinkResolver === "function" || configObjectOrLinkResolver == null ) { config = { linkResolver: configObjectOrLinkResolver, } } else { config = { ...configObjectOrLinkResolver } } 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 && config.linkResolver) { // When using link resolver... const resolvedURL = config.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<LinkResolverFunctionReturnType, Field> } case LinkType.Any: default: return null as AsLinkReturnType<LinkResolverFunctionReturnType, Field> } }