Created
June 13, 2024 15:19
-
-
Save essejmclean/25c340cef75a9e69a87070b83e161a89 to your computer and use it in GitHub Desktop.
Type-safe wrapper around Prismic's `isFilled.contentRelationship` function to make link fields more type-safe.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Type-safe wrapper around Prismic's `isFilled.contentRelationship` function to make link fields more type-safe. | |
* You'll want to make sure that your Prismic client is set up to handle typed content. | |
* | |
* If using Next.js and Slice Machine, you can use the `@prismicio/client` package to set up typed content. | |
* @see {@link https://prismic.io/docs/typescript-nextjs} for more information. | |
* | |
* Prismic also offers support via the `prismic-ts-codegen` package. | |
* @see {@link https://prismic.io/docs/technical-reference/prismic-ts-codegen} for more information. | |
*/ | |
import { | |
type Content, | |
type FilledContentRelationshipField, | |
isFilled, | |
type LinkField, | |
} from "@prismicio/client"; | |
// Extracts the data of a specific document type from Prismic content | |
type DocumentData<TDocumentType extends Content.AllDocumentTypes["type"]> = | |
Extract<Content.AllDocumentTypes, { type: TDocumentType }>["data"]; | |
/** | |
* Checks if a link field in Prismic is a filled content relationship field and contains the specified field IDs. | |
* This is useful for checking if a link field is a valid link to a specific document type and contains the specified field IDs. | |
* This acts as a wrapper around the `isFilled.contentRelationship` function from Prismic to make link fields more type-safe. | |
* | |
* @template TDocumentType - The type of the document. | |
* @template TFieldID - The field IDs to check within the document data. | |
* @param {LinkField} linkField - The link field to check. | |
* @param {TDocumentType} documentType - The type of the document to match against. | |
* @param {TFieldID[]} fieldIDs - The field IDs to check within the document data. | |
* @returns {linkField is FilledContentRelationshipField & { data: { [P in keyof DocumentData<TDocumentType> as P extends TFieldID ? P : never]: DocumentData<TDocumentType>[P]; } }} - Returns true if the link field is a filled content relationship field and contains the specified field IDs. | |
* | |
* @example | |
* ```ts | |
* import { isFilledLinkedContent } from "./is-filled-linked-content"; | |
* | |
* const isValidLink = isFilledLinkedContent(linkField, "article", ["title"]); | |
* ``` | |
*/ | |
export function isFilledLinkedContent< | |
TDocumentType extends Content.AllDocumentTypes["type"], | |
TFieldID extends keyof DocumentData<TDocumentType>, | |
>( | |
linkField: LinkField, | |
documentType: TDocumentType, | |
fieldIDs: TFieldID[] | |
): linkField is FilledContentRelationshipField & { | |
data: { | |
[P in keyof DocumentData<TDocumentType> as P extends TFieldID | |
? P | |
: never]: DocumentData<TDocumentType>[P]; | |
}; | |
} { | |
return ( | |
// Check if the link field is a filled content relationship field | |
isFilled.contentRelationship(linkField) && | |
// Check if the link field's type matches the specified document type | |
linkField.type === documentType && | |
// Ensure the link field's data is an object and not null | |
typeof linkField.data === "object" && | |
linkField.data !== null && | |
// Check if all specified field IDs exist in the link field's data | |
fieldIDs.every( | |
(fieldID) => fieldID in (linkField.data as Record<string, unknown>) | |
) | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment