diff --git a/src/Migration.ts b/src/Migration.ts index 53ab719a..50142440 100644 --- a/src/Migration.ts +++ b/src/Migration.ts @@ -1,4 +1,5 @@ import * as is from "./lib/isValue" +import { getOptionalLinkProperties } from "./lib/getOptionalLinkProperties" import { validateAssetMetadata } from "./lib/validateAssetMetadata" import type { Asset } from "./types/api/asset/asset" @@ -404,28 +405,32 @@ export class Migration { */ #migratePrismicDocumentData(input: unknown): unknown { if (is.filledContentRelationship(input)) { + const optionalLinkProperties = getOptionalLinkProperties(input) + if (input.isBroken) { return { + ...optionalLinkProperties, link_type: LinkType.Document, // ID needs to be 16 characters long to be considered valid by the API id: "_____broken_____", isBroken: true, - text: input.text, } } return { + ...optionalLinkProperties, link_type: LinkType.Document, id: () => this._getByOriginalID(input.id), - text: input.text, } } if (is.filledLinkToMedia(input)) { + const optionalLinkProperties = getOptionalLinkProperties(input) + return { + ...optionalLinkProperties, link_type: LinkType.Media, id: this.createAsset(input), - text: input.text, } } diff --git a/src/lib/getOptionalLinkProperties.ts b/src/lib/getOptionalLinkProperties.ts new file mode 100644 index 00000000..de83ea2a --- /dev/null +++ b/src/lib/getOptionalLinkProperties.ts @@ -0,0 +1,23 @@ +import type { OptionalLinkProperties } from "../types/value/link" + +/** + * Returns optional properties only available to link fields. Link fields can + * have the same shape as content relationship and link to media fields, + * requiring special treatment to extract link-specific properties. + * + * @param input - The content relationship or link to media field from which the + * link properties will be extracted. + * + * @returns Optional link properties that `input` might have. + */ +export const getOptionalLinkProperties = ( + input: OptionalLinkProperties, +): OptionalLinkProperties => { + const res: OptionalLinkProperties = {} + + if ("text" in input) { + res.text = input.text + } + + return res +} diff --git a/src/lib/isMigrationValue.ts b/src/lib/isMigrationValue.ts index 28a442e1..122f602d 100644 --- a/src/lib/isMigrationValue.ts +++ b/src/lib/isMigrationValue.ts @@ -12,6 +12,7 @@ import { import type { PrismicDocument } from "../types/value/document" import type { GroupField } from "../types/value/group" import { LinkType } from "../types/value/link" +import type { OptionalLinkProperties } from "../types/value/link" import { RichTextNodeType } from "../types/value/richText" import type { SliceZone } from "../types/value/sliceZone" import type { AnyRegularField } from "../types/value/types" @@ -32,6 +33,10 @@ type UnknownValue = /** * Checks if a value is a migration content relationship field. * + * @remarks + * `OptionalLinkProperties` is included because `MigrationContentRelationship` + * may be a link field, not strictly a content relationship field. + * * @param value - Value to check. * * @returns `true` if `value` is a migration content relationship field, `false` @@ -42,7 +47,7 @@ type UnknownValue = */ export const contentRelationship = ( value: UnknownValue, -): value is MigrationContentRelationship => { +): value is MigrationContentRelationship & OptionalLinkProperties => { return ( value instanceof PrismicMigrationDocument || is.prismicDocument(value) || @@ -80,6 +85,10 @@ export const image = (value: UnknownValue): value is MigrationImage => { /** * Checks if a value is a migration link to media field. * + * - @remarks `OptionalLinkProperties` is included because + * `MigrationContentRelationship` may be a link field, not strictly a content + * relationship field. + * * @param value - Value to check. * * @returns `true` if `value` is a migration link to media field, `false` @@ -90,7 +99,7 @@ export const image = (value: UnknownValue): value is MigrationImage => { */ export const linkToMedia = ( value: UnknownValue, -): value is MigrationLinkToMedia => { +): value is MigrationLinkToMedia & OptionalLinkProperties => { return ( typeof value === "object" && value !== null && diff --git a/src/lib/isValue.ts b/src/lib/isValue.ts index c4b5bd11..f0ac7989 100644 --- a/src/lib/isValue.ts +++ b/src/lib/isValue.ts @@ -4,6 +4,7 @@ import type { PrismicDocument } from "../types/value/document" import type { GroupField } from "../types/value/group" import type { ImageField } from "../types/value/image" import { LinkType } from "../types/value/link" +import type { OptionalLinkProperties } from "../types/value/link" import type { FilledLinkToMediaField } from "../types/value/linkToMedia" import { type RTImageNode, RichTextNodeType } from "../types/value/richText" import type { SliceZone } from "../types/value/sliceZone" @@ -23,6 +24,11 @@ type UnknownValue = /** * Checks if a value is a link to media field. * + * @remarks + * The return value includes `OptionalLinkProperties` because + * `FilledLinkToMediaField` may be a link field, not strictly a content + * relationship field. + * * @param value - Value to check. * * @returns `true` if `value` is a link to media field, `false` otherwise. @@ -32,7 +38,7 @@ type UnknownValue = */ export const filledLinkToMedia = ( value: UnknownValue, -): value is FilledLinkToMediaField => { +): value is FilledLinkToMediaField & OptionalLinkProperties => { if (value && typeof value === "object" && !("version" in value)) { if ( "link_type" in value && @@ -138,6 +144,11 @@ export const rtImageNode = (value: UnknownValue): value is RTImageNode => { /** * Checks if a value is a content relationship field. * + * @remarks + * The return value includes `OptionalLinkProperties` because + * `FilledContentRelationshipField` may be a link field, not strictly a content + * relationship field. + * * @param value - Value to check. * * @returns `true` if `value` is a content relationship, `false` otherwise. @@ -147,7 +158,7 @@ export const rtImageNode = (value: UnknownValue): value is RTImageNode => { */ export const filledContentRelationship = ( value: UnknownValue, -): value is FilledContentRelationshipField => { +): value is FilledContentRelationshipField & OptionalLinkProperties => { if (value && typeof value === "object" && !("version" in value)) { if ( "link_type" in value && diff --git a/src/lib/resolveMigrationDocumentData.ts b/src/lib/resolveMigrationDocumentData.ts index dded02c9..8f6e8c29 100644 --- a/src/lib/resolveMigrationDocumentData.ts +++ b/src/lib/resolveMigrationDocumentData.ts @@ -10,8 +10,9 @@ import type { MigrationContentRelationshipField, } from "../types/migration/ContentRelationship" import { PrismicMigrationDocument } from "../types/migration/Document" +import type { MaybeLink } from "../types/migration/Link" import type { FilledImageFieldImage } from "../types/value/image" -import type { LinkField } from "../types/value/link" +import type { LinkField, OptionalLinkProperties } from "../types/value/link" import { LinkType } from "../types/value/link" import type { RTImageNode } from "../types/value/richText" import { RichTextNodeType } from "../types/value/richText" @@ -20,6 +21,7 @@ import * as isFilled from "../helpers/isFilled" import type { Migration } from "../Migration" import * as isMigration from "./isMigrationValue" +import { getOptionalLinkProperties } from "./getOptionalLinkProperties" /** * Resolves a migration content relationship to a content relationship field. @@ -29,8 +31,8 @@ import * as isMigration from "./isMigrationValue" * @returns Resolved content relationship field. */ export async function resolveMigrationContentRelationship( - relation: MigrationContentRelationship, -): Promise { + relation: MaybeLink, +): Promise { if (typeof relation === "function") { return resolveMigrationContentRelationship(await relation()) } @@ -38,26 +40,39 @@ export async function resolveMigrationContentRelationship( if (relation instanceof PrismicMigrationDocument) { return relation.document.id ? { link_type: LinkType.Document, id: relation.document.id } - : { link_type: LinkType.Document } + : { link_type: LinkType.Any } } + const optionalLinkProperties = + relation && "link_type" in relation + ? getOptionalLinkProperties(relation) + : undefined + if (relation) { if ( isMigration.contentRelationship(relation.id) || - typeof relation.id === "function" + typeof relation.id !== "string" ) { return { + ...optionalLinkProperties, ...(await resolveMigrationContentRelationship(relation.id)), - // TODO: Remove when link text PR is merged - // @ts-expect-error - Future-proofing for link text - text: relation.text, } } - return { link_type: LinkType.Document, id: relation.id } + // This is only called when resolveMigrationContentRelationship recursively + // calls itself from the statement above and the resolved content relation + // is a Prismic document value. + return { + ...optionalLinkProperties, + link_type: LinkType.Document, + id: relation.id, + } } - return { link_type: LinkType.Document } + return { + ...optionalLinkProperties, + link_type: LinkType.Any, + } } /** @@ -154,20 +169,24 @@ export const resolveMigrationRTImageNode = async ( * @returns Resolved link to media field. */ export const resolveMigrationLinkToMedia = ( - linkToMedia: MigrationLinkToMedia, + linkToMedia: MaybeLink, migration: Migration, ): MigrationLinkToMediaField => { const asset = migration._assets.get(linkToMedia.id.config.id)?.asset + const optionalLinkProperties = getOptionalLinkProperties(linkToMedia) if (asset) { return { + ...optionalLinkProperties, id: asset.id, link_type: LinkType.Media, - text: linkToMedia.text, } } - return { link_type: LinkType.Media } + return { + ...optionalLinkProperties, + link_type: LinkType.Any, + } } /** diff --git a/src/types/migration/Asset.ts b/src/types/migration/Asset.ts index 386eb0ce..401a07f8 100644 --- a/src/types/migration/Asset.ts +++ b/src/types/migration/Asset.ts @@ -1,6 +1,5 @@ import type { Asset } from "../api/asset/asset" import type { FilledImageFieldImage } from "../value/image" -import type { EmptyLinkField } from "../value/link" import type { LinkToMediaField } from "../value/linkToMedia" import { type RTImageNode } from "../value/richText" @@ -73,15 +72,14 @@ export type MigrationImage = */ export type MigrationLinkToMedia = Pick< LinkToMediaField<"filled">, - "link_type" -> & - Partial, "text">> & { - /** - * A reference to the migration asset used to resolve the link to media - * field's value. - */ - id: PrismicMigrationAsset - } + "link_type" | "text" +> & { + /** + * A reference to the migration asset used to resolve the link to media + * field's value. + */ + id: PrismicMigrationAsset +} /** * The minimum amount of information needed to represent a link to media field @@ -89,7 +87,7 @@ export type MigrationLinkToMedia = Pick< */ export type MigrationLinkToMediaField = | Pick, "link_type" | "id" | "text"> - | EmptyLinkField<"Media"> + | LinkToMediaField<"empty"> /** * A rich text image node in a migration. diff --git a/src/types/migration/ContentRelationship.ts b/src/types/migration/ContentRelationship.ts index 667836f6..83f7c6bd 100644 --- a/src/types/migration/ContentRelationship.ts +++ b/src/types/migration/ContentRelationship.ts @@ -1,6 +1,9 @@ -import type { FilledContentRelationshipField } from "../value/contentRelationship" +import type { + ContentRelationshipField, + EmptyContentRelationshipField, + FilledContentRelationshipField, +} from "../value/contentRelationship" import type { PrismicDocument } from "../value/document" -import type { EmptyLinkField } from "../value/link" import type { PrismicMigrationDocument } from "./Document" @@ -13,12 +16,11 @@ export type MigrationContentRelationship< TDocuments extends PrismicDocument = PrismicDocument, > = | ValueOrThunk | undefined> - | (Pick & - Partial> & { - id: ValueOrThunk< - TDocuments | PrismicMigrationDocument | undefined - > - }) + | (Pick & { + id: ValueOrThunk< + TDocuments | PrismicMigrationDocument | undefined + > + }) /** * The minimum amount of information needed to represent a content relationship @@ -26,4 +28,4 @@ export type MigrationContentRelationship< */ export type MigrationContentRelationshipField = | Pick - | EmptyLinkField<"Document"> + | EmptyContentRelationshipField diff --git a/src/types/migration/Link.ts b/src/types/migration/Link.ts new file mode 100644 index 00000000..81f978c4 --- /dev/null +++ b/src/types/migration/Link.ts @@ -0,0 +1,19 @@ +import type { LinkType, OptionalLinkProperties } from "../value/link" + +/** + * Adds `OptionalLinkProperties` to any type that looks like a link object (one + * that includes a valid `link_type` property). + * + * @example + * + * ```ts + * type Example = MaybeLink + * // PrismicDocument | (LinkField & OptionalLinkProperties) + * ``` + * + * @typeParam T - The type to augment. + */ +export type MaybeLink = + | Exclude + | (Extract & + OptionalLinkProperties) diff --git a/src/types/model/contentRelationship.ts b/src/types/model/contentRelationship.ts index 4c542748..09f06294 100644 --- a/src/types/model/contentRelationship.ts +++ b/src/types/model/contentRelationship.ts @@ -18,6 +18,5 @@ export interface CustomTypeModelContentRelationshipField< select: typeof CustomTypeModelLinkSelectType.Document customtypes?: readonly CustomTypeIDs[] tags?: readonly Tags[] - allowText?: boolean } } diff --git a/src/types/value/contentRelationship.ts b/src/types/value/contentRelationship.ts index 18919c3a..773d6a32 100644 --- a/src/types/value/contentRelationship.ts +++ b/src/types/value/contentRelationship.ts @@ -1,7 +1,6 @@ import type { AnyRegularField, FieldState } from "./types" import type { GroupField } from "./group" -import type { EmptyLinkField, LinkType } from "./link" import type { SliceZone } from "./sliceZone" /** @@ -21,9 +20,13 @@ export type ContentRelationshipField< | unknown = unknown, State extends FieldState = FieldState, > = State extends "empty" - ? EmptyLinkField + ? EmptyContentRelationshipField : FilledContentRelationshipField +export type EmptyContentRelationshipField = { + link_type: "Any" +} + /** * Links that refer to documents */ @@ -34,7 +37,7 @@ export interface FilledContentRelationshipField< | Record | unknown = unknown, > { - link_type: typeof LinkType.Document + link_type: "Document" id: string uid?: string type: TypeEnum @@ -44,5 +47,4 @@ export interface FilledContentRelationshipField< slug?: string isBroken?: boolean data?: DataInterface - text?: string } diff --git a/src/types/value/link.ts b/src/types/value/link.ts index 870004b1..368c4398 100644 --- a/src/types/value/link.ts +++ b/src/types/value/link.ts @@ -1,8 +1,8 @@ import type { AnyRegularField, FieldState } from "./types" -import type { ContentRelationshipField } from "./contentRelationship" +import type { FilledContentRelationshipField } from "./contentRelationship" import type { GroupField } from "./group" -import type { LinkToMediaField } from "./linkToMedia" +import type { FilledLinkToMediaField } from "./linkToMedia" import type { SliceZone } from "./sliceZone" /** @@ -15,35 +15,13 @@ export const LinkType = { Web: "Web", } as const -/** - * For link fields that haven't been filled - * - * @typeParam Type - The type of link. - */ -export type EmptyLinkField< - Type extends (typeof LinkType)[keyof typeof LinkType] = typeof LinkType.Any, -> = { - link_type: Type | string - text?: string -} - -/** - * Link that points to external website - */ -export interface FilledLinkToWebField { - link_type: typeof LinkType.Web - url: string - target?: string - text?: string -} - /** * A link field. * * @typeParam TypeEnum - Type API ID of the document. * @typeParam LangEnum - Language API ID of the document. - * @typeParam DataInterface - Data fields for the document (filled in via - * GraphQuery of `fetchLinks`). + * @typeParam DataInterface - Data fields for the document (filled via the + * `fetchLinks` or `graphQuery` query parameter). * @typeParam State - State of the field which determines its shape. */ export type LinkField< @@ -54,8 +32,61 @@ export type LinkField< | unknown = unknown, State extends FieldState = FieldState, > = State extends "empty" - ? EmptyLinkField - : - | ContentRelationshipField - | FilledLinkToWebField - | LinkToMediaField + ? EmptyLinkField + : FilledLinkField + +/** + * A link field that is filled. + * + * @typeParam TypeEnum - Type API ID of the document. + * @typeParam LangEnum - Language API ID of the document. + * @typeParam DataInterface - Data fields for the document (filled via the + * `fetchLinks` or `graphQuery` query parameter). + */ +export type FilledLinkField< + TypeEnum = string, + LangEnum = string, + DataInterface extends + | Record + | unknown = unknown, +> = ( + | FilledContentRelationshipField + | FilledLinkToMediaField + | FilledLinkToWebField +) & + OptionalLinkProperties + +/** + * A link field that is not filled. + * + * @typeParam _Unused - THIS PARAMETER IS NOT USED. If you are passing a type, + * **please remove it**. + */ +export type EmptyLinkField< + _Unused extends + (typeof LinkType)[keyof typeof LinkType] = typeof LinkType.Any, +> = { + link_type: "Any" +} & OptionalLinkProperties + +/** + * A link field pointing to a relative or absolute URL. + */ +export type FilledLinkToWebField = { + link_type: "Web" + url: string + target?: string +} & OptionalLinkProperties + +/** + * Optional properties available to link fields. It is used to augment existing + * link-like fields (like content relationship fields) with field-specific + * properties. + * + * @internal + */ +// Remember to update the `getOptionalLinkProperties()` function when updating +// this type. The function should check for every property. +export type OptionalLinkProperties = { + text?: string +} diff --git a/src/types/value/linkToMedia.ts b/src/types/value/linkToMedia.ts index 85d1a92c..281989de 100644 --- a/src/types/value/linkToMedia.ts +++ b/src/types/value/linkToMedia.ts @@ -1,23 +1,24 @@ import type { FieldState } from "./types" -import type { EmptyLinkField, LinkType } from "./link" - /** * A link field that points to media. * * @typeParam State - State of the field which determines its shape. */ export type LinkToMediaField = - State extends "empty" - ? EmptyLinkField - : FilledLinkToMediaField + State extends "empty" ? EmptyLinkToMediaField : FilledLinkToMediaField + +type EmptyLinkToMediaField = { + link_type: "Any" + text?: string +} /** * A link that points to media. */ export interface FilledLinkToMediaField { id: string - link_type: typeof LinkType.Media + link_type: "Media" name: string kind: string url: string diff --git a/src/types/value/richText.ts b/src/types/value/richText.ts index 3156c4aa..f6e2a854 100644 --- a/src/types/value/richText.ts +++ b/src/types/value/richText.ts @@ -1,9 +1,7 @@ import type { FieldState } from "./types" -import type { FilledContentRelationshipField } from "./contentRelationship" import type { EmbedField } from "./embed" -import type { FilledLinkToWebField } from "./link" -import type { FilledLinkToMediaField } from "./linkToMedia" +import type { FilledLinkField } from "./link" /** * Types enum for RichTextNodes @@ -176,10 +174,7 @@ export type RTImageNode = { zoom: number background: string } - linkTo?: - | FilledContentRelationshipField - | FilledLinkToWebField - | FilledLinkToMediaField + linkTo?: FilledLinkField } /** @@ -199,10 +194,7 @@ export type RTEmbedNode = { */ export interface RTLinkNode extends RTSpanNodeBase { type: typeof RichTextNodeType.hyperlink - data: - | FilledContentRelationshipField - | FilledLinkToWebField - | FilledLinkToMediaField + data: FilledLinkField } // Serialization related nodes diff --git a/test/__snapshots__/writeClient-migrate-patch-contentRelationship.test.ts.snap b/test/__snapshots__/writeClient-migrate-patch-contentRelationship.test.ts.snap index 337e410a..3b2282d6 100644 --- a/test/__snapshots__/writeClient-migrate-patch-contentRelationship.test.ts.snap +++ b/test/__snapshots__/writeClient-migrate-patch-contentRelationship.test.ts.snap @@ -698,7 +698,7 @@ exports[`patches content relationship fields > lazyOtherCreateMissingID > group "group": [ { "field": { - "link_type": "Document", + "link_type": "Any", }, }, ], @@ -713,18 +713,18 @@ exports[`patches content relationship fields > lazyOtherCreateMissingID > shared "items": [ { "field": { - "link_type": "Document", + "link_type": "Any", }, }, ], "primary": { "field": { - "link_type": "Document", + "link_type": "Any", }, "group": [ { "field": { - "link_type": "Document", + "link_type": "Any", }, }, ], @@ -746,13 +746,13 @@ exports[`patches content relationship fields > lazyOtherCreateMissingID > slice "items": [ { "field": { - "link_type": "Document", + "link_type": "Any", }, }, ], "primary": { "field": { - "link_type": "Document", + "link_type": "Any", }, }, "slice_label": "Vel", @@ -765,7 +765,7 @@ exports[`patches content relationship fields > lazyOtherCreateMissingID > slice exports[`patches content relationship fields > lazyOtherCreateMissingID > static zone 1`] = ` { "field": { - "link_type": "Document", + "link_type": "Any", }, } `; diff --git a/test/__snapshots__/writeClient-migrate-patch-linkToMedia.test.ts.snap b/test/__snapshots__/writeClient-migrate-patch-linkToMedia.test.ts.snap index 9275be7f..c394567e 100644 --- a/test/__snapshots__/writeClient-migrate-patch-linkToMedia.test.ts.snap +++ b/test/__snapshots__/writeClient-migrate-patch-linkToMedia.test.ts.snap @@ -299,7 +299,7 @@ exports[`patches link to media fields > empty > group 1`] = ` "group": [ { "field": { - "link_type": "Media", + "link_type": "Any", }, }, ], @@ -314,18 +314,18 @@ exports[`patches link to media fields > empty > shared slice 1`] = ` "items": [ { "field": { - "link_type": "Media", + "link_type": "Any", }, }, ], "primary": { "field": { - "link_type": "Media", + "link_type": "Any", }, "group": [ { "field": { - "link_type": "Media", + "link_type": "Any", }, }, ], @@ -347,13 +347,13 @@ exports[`patches link to media fields > empty > slice 1`] = ` "items": [ { "field": { - "link_type": "Media", + "link_type": "Any", }, }, ], "primary": { "field": { - "link_type": "Media", + "link_type": "Any", }, }, "slice_label": "Vel", @@ -366,7 +366,7 @@ exports[`patches link to media fields > empty > slice 1`] = ` exports[`patches link to media fields > empty > static zone 1`] = ` { "field": { - "link_type": "Media", + "link_type": "Any", }, } `; diff --git a/test/helpers-asLink.test.ts b/test/helpers-asLink.test.ts index 80264fd7..cf8686b7 100644 --- a/test/helpers-asLink.test.ts +++ b/test/helpers-asLink.test.ts @@ -10,22 +10,6 @@ it("returns null for nullish inputs", () => { expect(asLink(undefined, linkResolver)).toBeNull() }) -it("returns null when link to document field is empty", () => { - const field = { - link_type: LinkType.Document, - } - - expect(asLink(field, linkResolver)).toBeNull() -}) - -it("returns null when link to media field is empty", () => { - const field = { - link_type: LinkType.Media, - } - - expect(asLink(field, linkResolver)).toBeNull() -}) - it("returns null when link field is empty", () => { const field = { link_type: LinkType.Any, @@ -102,8 +86,11 @@ it("resolves a link to document field with route resolver", () => { it("returns null when given a document field and linkResolver is not provided ", () => { const field = { - id: "XvoFFREAAM0WGBng", link_type: LinkType.Document, + id: "XvoFFREAAM0WGBng", + lang: "fr-fr", + tags: [], + type: "foo", } expect(asLink(field)).toBeNull() @@ -121,6 +108,7 @@ it("resolves a link to web field", () => { it("resolves a link to media field", () => { const field = { link_type: LinkType.Media, + id: "foo", name: "test.jpg", kind: "image", url: "https://prismic.io", diff --git a/test/helpers-asLinkAttrs.test.ts b/test/helpers-asLinkAttrs.test.ts index a37ee933..a8c21b87 100644 --- a/test/helpers-asLinkAttrs.test.ts +++ b/test/helpers-asLinkAttrs.test.ts @@ -1,32 +1,14 @@ import { expect, it, vi } from "vitest" -import { asLinkAttrs } from "../src" +import { LinkType, asLinkAttrs } from "../src" it("returns empty object for nullish inputs", () => { expect(asLinkAttrs(null)).toEqual({}) expect(asLinkAttrs(undefined)).toEqual({}) }) -it("returns empty object when link field is empty", (ctx) => { - const field = ctx.mock.value.link({ type: "Any", state: "empty" }) - - expect(asLinkAttrs(field)).toEqual({}) -}) - -it("returns empty object when link to document field is empty", (ctx) => { - const field = ctx.mock.value.link({ type: "Document", state: "empty" }) - - expect(asLinkAttrs(field)).toEqual({}) -}) - -it("returns empty object when link to media field is empty", (ctx) => { - const field = ctx.mock.value.link({ type: "Media", state: "empty" }) - - expect(asLinkAttrs(field)).toEqual({}) -}) - -it("returns empty object when link to web field is empty", (ctx) => { - const field = ctx.mock.value.link({ type: "Web", state: "empty" }) +it("returns empty object when link field is empty", () => { + const field = { link_type: LinkType.Any } expect(asLinkAttrs(field)).toEqual({}) }) diff --git a/test/helpers-isFilled.test.ts b/test/helpers-isFilled.test.ts index 4f7b7fcf..79958475 100644 --- a/test/helpers-isFilled.test.ts +++ b/test/helpers-isFilled.test.ts @@ -3,7 +3,9 @@ import { expect, it } from "vitest" import { documentFixture } from "./__fixtures__/document" import type { GroupField, SliceZone } from "../src" -import { isFilled } from "../src" +import { LinkType, isFilled } from "../src" + +const emptyLink = { link_type: LinkType.Any } it("color", (ctx) => { expect(isFilled.color(null)).toBe(false) @@ -14,13 +16,7 @@ it("color", (ctx) => { it("content relationship", (ctx) => { expect(isFilled.contentRelationship(null)).toBe(false) expect(isFilled.contentRelationship(undefined)).toBe(false) - expect( - isFilled.contentRelationship( - ctx.mock.value.contentRelationship({ - state: "empty", - }), - ), - ).toBe(false) + expect(isFilled.contentRelationship(emptyLink)).toBe(false) expect( isFilled.contentRelationship( ctx.mock.value.contentRelationship({ @@ -104,16 +100,14 @@ it("key text", (ctx) => { it("link", (ctx) => { expect(isFilled.link(null)).toBe(false) expect(isFilled.link(undefined)).toBe(false) - expect(isFilled.link(ctx.mock.value.link({ state: "empty" }))).toBe(false) + expect(isFilled.link(emptyLink)).toBe(false) expect(isFilled.link(ctx.mock.value.link({ state: "filled" }))).toBe(true) }) it("link to media", (ctx) => { expect(isFilled.linkToMedia(null)).toBe(false) expect(isFilled.linkToMedia(undefined)).toBe(false) - expect( - isFilled.linkToMedia(ctx.mock.value.linkToMedia({ state: "empty" })), - ).toBe(false) + expect(isFilled.linkToMedia(emptyLink)).toBe(false) expect( isFilled.linkToMedia(ctx.mock.value.linkToMedia({ state: "filled" })), ).toBe(true) diff --git a/test/types/customType-contentRelationship.types.ts b/test/types/customType-contentRelationship.types.ts index 0648933e..2789c2be 100644 --- a/test/types/customType-contentRelationship.types.ts +++ b/test/types/customType-contentRelationship.types.ts @@ -96,18 +96,6 @@ expectType>({ }, }) -/** - * Supports optional `allowText` property. - */ -expectType>({ - type: prismic.CustomTypeModelFieldType.Link, - config: { - label: "string", - select: prismic.CustomTypeModelLinkSelectType.Document, - allowText: true, - }, -}) - /** * `@prismicio/types` extends `@prismicio/types-internal` */ diff --git a/test/types/fields-contentRelationship.types.ts b/test/types/fields-contentRelationship.types.ts index 71f455f3..91e3b2c4 100644 --- a/test/types/fields-contentRelationship.types.ts +++ b/test/types/fields-contentRelationship.types.ts @@ -32,7 +32,6 @@ expectType({ slug: "string", isBroken: true, data: undefined, - text: "string", }) expectType>({ link_type: prismic.LinkType.Document, @@ -45,10 +44,9 @@ expectType>({ slug: "string", isBroken: true, data: undefined, - text: "string", }) expectType>({ - link_type: prismic.LinkType.Document, + link_type: prismic.LinkType.Any, // @ts-expect-error - Empty fields cannot contain a filled value. id: "string", uid: "string", @@ -59,43 +57,21 @@ expectType>({ slug: "string", isBroken: true, data: undefined, - text: "string", }) /** * Empty state. */ expectType({ - link_type: prismic.LinkType.Document, + link_type: prismic.LinkType.Any, }) expectType>({ - link_type: prismic.LinkType.Document, + link_type: prismic.LinkType.Any, }) -expectType>( +expectType>({ // @ts-expect-error - Filled fields cannot contain an empty value. - { - link_type: prismic.LinkType.Document, - }, -) - -/** - * Empty state with text. - */ -expectType({ - link_type: prismic.LinkType.Document, - text: "string", + link_type: prismic.LinkType.Any, }) -expectType>({ - link_type: prismic.LinkType.Document, - text: "string", -}) -expectType>( - // @ts-expect-error - Filled fields cannot contain an empty value. - { - link_type: prismic.LinkType.Document, - text: "string", - }, -) /** * Supports custom document type. diff --git a/test/types/fields-link.types.ts b/test/types/fields-link.types.ts index 2f8a3a5d..e444a914 100644 --- a/test/types/fields-link.types.ts +++ b/test/types/fields-link.types.ts @@ -36,14 +36,12 @@ expectType( /** * Filled state. */ -// Web link expectType({ link_type: prismic.LinkType.Web, url: "string", target: "string", text: "string", }) -// Content relationship link expectType({ link_type: prismic.LinkType.Document, id: "string", @@ -57,9 +55,9 @@ expectType({ data: undefined, text: "string", }) -// Media link expectType({ link_type: prismic.LinkType.Media, + id: "string", name: "string", kind: "string", url: "string", @@ -75,8 +73,8 @@ expectType>({ text: "string", }) expectType>({ + // @ts-expect-error - Empty fields cannot contain a filled link type. link_type: prismic.LinkType.Web, - // @ts-expect-error - Empty fields cannot contain a filled value. url: "string", target: "string", text: "string", @@ -92,70 +90,50 @@ expectType>({ // @ts-expect-error - Filled fields cannot contain an empty value. link_type: prismic.LinkType.Any, }) -expectType({ - link_type: prismic.LinkType.Web, -}) -expectType>( - // @ts-expect-error - Filled fields cannot contain an empty value. +expectType( + // @ts-expect-error - Filled fields must contain properties. { link_type: prismic.LinkType.Web, }, ) -expectType({ - link_type: prismic.LinkType.Document, -}) expectType>( - // @ts-expect-error - Filled fields cannot contain an empty value. + // @ts-expect-error - Filled fields must contain properties. { - link_type: prismic.LinkType.Document, + link_type: prismic.LinkType.Web, }, ) -expectType({ - link_type: prismic.LinkType.Media, -}) -expectType>( - // @ts-expect-error - Filled fields cannot contain an empty value. +expectType( + // @ts-expect-error - Filled fields must contain properties. { - link_type: prismic.LinkType.Media, + link_type: prismic.LinkType.Document, }, ) - -/** - * Empty state with text. - */ -expectType>({ - link_type: prismic.LinkType.Web, - text: "string", -}) expectType>( - // @ts-expect-error - Filled fields cannot contain an empty value. + // @ts-expect-error - Filled fields must contain properties. { - link_type: prismic.LinkType.Web, - text: "string", + link_type: prismic.LinkType.Document, }, ) -expectType>({ - link_type: prismic.LinkType.Document, - text: "string", -}) -expectType>( - // @ts-expect-error - Filled fields cannot contain an empty value. +expectType( + // @ts-expect-error - Filled fields must contain properties. { - link_type: prismic.LinkType.Document, - text: "string", + link_type: prismic.LinkType.Media, }, ) -expectType>({ - link_type: prismic.LinkType.Media, - text: "string", -}) expectType>( - // @ts-expect-error - Filled fields cannot contain an empty value. + // @ts-expect-error - Filled fields must contain properties. { link_type: prismic.LinkType.Media, - text: "string", }, ) + +/** + * Empty state with text. + */ +expectType({ + link_type: prismic.LinkType.Any, + text: "string", +}) expectType>({ link_type: prismic.LinkType.Any, text: "string", @@ -176,10 +154,10 @@ expectType>({ tags: [], lang: "string", }) -// @ts-expect-error - Document type must match the given type. expectType>({ link_type: prismic.LinkType.Document, id: "string", + // @ts-expect-error - Document type must match the given type. type: "string", tags: [], lang: "string", @@ -195,12 +173,12 @@ expectType>({ tags: [], lang: "fr-fr", }) -// @ts-expect-error - Document language must match the given type. expectType>({ link_type: prismic.LinkType.Document, id: "string", type: "string", tags: [], + // @ts-expect-error - Document language must match the given type. lang: "string", }) diff --git a/test/types/fields-linkToMedia.types.ts b/test/types/fields-linkToMedia.types.ts index c5b63fbf..671d6b66 100644 --- a/test/types/fields-linkToMedia.types.ts +++ b/test/types/fields-linkToMedia.types.ts @@ -44,7 +44,7 @@ expectType>({ text: "string", }) expectType>({ - link_type: prismic.LinkType.Media, + link_type: prismic.LinkType.Any, // @ts-expect-error - Empty fields cannot contain a filled value. id: "string", name: "string", @@ -60,33 +60,29 @@ expectType>({ * Empty state. */ expectType({ - link_type: prismic.LinkType.Media, + link_type: prismic.LinkType.Any, }) expectType>({ - link_type: prismic.LinkType.Media, + link_type: prismic.LinkType.Any, }) -expectType>( +expectType>({ // @ts-expect-error - Filled fields cannot contain an empty value. - { - link_type: prismic.LinkType.Media, - }, -) + link_type: prismic.LinkType.Any, +}) /** * Empty state with text. */ expectType({ - link_type: prismic.LinkType.Media, + link_type: prismic.LinkType.Any, text: "string", }) expectType>({ - link_type: prismic.LinkType.Media, + link_type: prismic.LinkType.Any, text: "string", }) -expectType>( +expectType>({ // @ts-expect-error - Filled fields cannot contain an empty value. - { - link_type: prismic.LinkType.Media, - text: "string", - }, -) + link_type: prismic.LinkType.Any, + text: "string", +})