Skip to content

Commit

Permalink
test: type test migration types
Browse files Browse the repository at this point in the history
  • Loading branch information
lihbr committed Aug 23, 2024
1 parent 956d6f6 commit ba2c733
Show file tree
Hide file tree
Showing 5 changed files with 380 additions and 2 deletions.
21 changes: 20 additions & 1 deletion src/Migration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,23 @@ import {
} from "./types/migration/fields"
import type { PrismicDocument } from "./types/value/document"

/**
* Extracts one or more Prismic document types that match a given Prismic
* document type. If no matches are found, no extraction is performed and the
* union of all provided Prismic document types are returned.
*
* @typeParam TMigrationDocuments - Prismic migration document types from which
* to extract.
* @typeParam TType - Type(s) to match `TMigrationDocuments` against.
*/
type ExtractMigrationDocumentType<
TMigrationDocuments extends MigrationPrismicDocument,
TType extends TMigrationDocuments["type"],
> =
Extract<TMigrationDocuments, { type: TType }> extends never
? TMigrationDocuments
: Extract<TMigrationDocuments, { type: TType }>

type CreateAssetReturnType = MigrationImageField & {
image: MigrationImageField
linkToMedia: MigrationLinkToMediaField
Expand Down Expand Up @@ -98,7 +115,9 @@ export class Migration<
}
}

createDocument(document: TMigrationDocuments): TMigrationDocuments {
createDocument<TType extends TMigrationDocuments["type"]>(
document: ExtractMigrationDocumentType<TMigrationDocuments, TType>,
): ExtractMigrationDocumentType<TMigrationDocuments, TType> {
this.#documents.push(document)

if (!(document.type in this.#documentsByUID)) {
Expand Down
20 changes: 20 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,26 @@ export type {
CustomTypeModelFieldForSlicePrimary,
} from "./types/model/types"

// Migrations - Types representing Prismic migration API content values.
export { MigrationFieldType } from "./types/migration/fields"

export type {
MigrationPrismicDocument,
RichTextFieldToMigrationField,
} from "./types/migration/document"

export type {
MigrationImageField,
MigrationLinkToMediaField,
MigrationContentRelationshipField,
MigrationLinkField,
} from "./types/migration/fields"

export type {
MigrationRTImageNode,
MigrationRTLinkNode,
} from "./types/migration/richText"

// API - Types representing Prismic Rest API V2 responses.
export type { Query } from "./types/api/query"

Expand Down
2 changes: 1 addition & 1 deletion src/types/migration/document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ type FieldsToMigrationFields<
type MakeUIDOptional<TMigrationDocument extends { uid: string | null }> =
TMigrationDocument["uid"] extends string
? TMigrationDocument
: Omit<TMigrationDocument, "uid"> & { uid?: TMigrationDocument["uid"] }
: Omit<TMigrationDocument, "uid"> & Partial<Pick<TMigrationDocument, "uid">>

/**
* A Prismic document compatible with the migration API.
Expand Down
234 changes: 234 additions & 0 deletions test/types/migration-document.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
import type { TypeOf } from "ts-expect"
import { expectNever, expectType } from "ts-expect"

import type * as prismic from "../../src"

;(value: prismic.MigrationPrismicDocument): true => {
switch (typeof value) {
case "object": {
if (value === null) {
expectNever(value)
}

return true
}

default: {
return expectNever(value)
}
}
}

expectType<prismic.MigrationPrismicDocument>({
title: "",
uid: "",
type: "",
lang: "",
data: {},
})

/**
* Supports any field when generic.
*/
expectType<prismic.MigrationPrismicDocument>({
title: "",
uid: "",
type: "",
lang: "",
data: {
any: "",
},
})

/**
* `PrismicDocument` is assignable to `MigrationPrismicDocument` with added
* `title`.
*/
expectType<
TypeOf<
prismic.MigrationPrismicDocument,
prismic.PrismicDocument & { title: string }
>
>(true)

// Migration Documents
type FooDocument = prismic.PrismicDocument<Record<string, never>, "foo">
type BarDocument = prismic.PrismicDocument<{ bar: prismic.KeyTextField }, "bar">
type BazDocument = prismic.PrismicDocument<Record<string, never>, "baz">
type Documents = FooDocument | BarDocument | BazDocument

type MigrationDocuments = prismic.MigrationPrismicDocument<Documents>

/**
* Infers data type from document type.
*/
expectType<MigrationDocuments>({
title: "",
uid: "",
type: "foo",
lang: "",
data: {},
})

// @ts-expect-error - `FooDocument` has no `bar` field in `data`
expectType<MigrationDocuments>({
title: "",
uid: "",
type: "foo",
lang: "",
data: {
bar: "",
},
})

expectType<MigrationDocuments>({
title: "",
uid: "",
type: "bar",
lang: "",
data: {
bar: "",
},
})

// @ts-expect-error - `bar` is missing in `data`
expectType<MigrationDocuments>({
title: "",
uid: "",
type: "bar",
lang: "",
data: {},
})

/**
* Accepts migration field types.
*/
type Fields = {
image: prismic.ImageField
migrationImage: prismic.ImageField
link: prismic.LinkField
migrationLink: prismic.LinkField
linkToMedia: prismic.LinkToMediaField
migrationLinkToMedia: prismic.LinkToMediaField
contentRelationship: prismic.ContentRelationshipField
migrationContentRelationship: prismic.ContentRelationshipField
}

type StaticDocument = prismic.PrismicDocument<Fields, "static">
type GroupDocument = prismic.PrismicDocument<
{ group: prismic.GroupField<Fields> },
"group"
>
type SliceDocument = prismic.PrismicDocument<
{
slices: prismic.SliceZone<
prismic.SharedSlice<
"default",
prismic.SharedSliceVariation<
"default",
Fields & { group: prismic.GroupField<Fields> },
Fields
>
>
>
},
"slice"
>
type AdvancedDocuments = StaticDocument | GroupDocument | SliceDocument
type MigrationAdvancedDocuments =
prismic.MigrationPrismicDocument<AdvancedDocuments>

// Static
expectType<MigrationAdvancedDocuments>({
title: "",
uid: "",
type: "static",
lang: "",
data: {
image: {} as prismic.ImageField,
migrationImage: {} as prismic.MigrationImageField,
link: {} as prismic.LinkField,
migrationLink: {} as prismic.MigrationLinkField,
linkToMedia: {} as prismic.LinkToMediaField,
migrationLinkToMedia: {} as prismic.MigrationLinkToMediaField,
contentRelationship: {} as prismic.ContentRelationshipField,
migrationContentRelationship: {} as prismic.ContentRelationshipField,
},
})

// Group
expectType<MigrationAdvancedDocuments>({
title: "",
uid: "",
type: "group",
lang: "",
data: {
group: [
{
image: {} as prismic.ImageField,
migrationImage: {} as prismic.MigrationImageField,
link: {} as prismic.LinkField,
migrationLink: {} as prismic.MigrationLinkField,
linkToMedia: {} as prismic.LinkToMediaField,
migrationLinkToMedia: {} as prismic.MigrationLinkToMediaField,
contentRelationship: {} as prismic.ContentRelationshipField,
migrationContentRelationship: {} as prismic.ContentRelationshipField,
},
],
},
})

// Slice
expectType<MigrationAdvancedDocuments>({
title: "",
uid: "",
type: "slice",
lang: "",
data: {
slices: [
{
slice_type: "default",
slice_label: null,
id: "",
variation: "default",
version: "",
primary: {
image: {} as prismic.ImageField,
migrationImage: {} as prismic.MigrationImageField,
link: {} as prismic.LinkField,
migrationLink: {} as prismic.MigrationLinkField,
linkToMedia: {} as prismic.LinkToMediaField,
migrationLinkToMedia: {} as prismic.MigrationLinkToMediaField,
contentRelationship: {} as prismic.ContentRelationshipField,
migrationContentRelationship: {} as prismic.ContentRelationshipField,
group: [
{
image: {} as prismic.ImageField,
migrationImage: {} as prismic.MigrationImageField,
link: {} as prismic.LinkField,
migrationLink: {} as prismic.MigrationLinkField,
linkToMedia: {} as prismic.LinkToMediaField,
migrationLinkToMedia: {} as prismic.MigrationLinkToMediaField,
contentRelationship: {} as prismic.ContentRelationshipField,
migrationContentRelationship:
{} as prismic.ContentRelationshipField,
},
],
},
items: [
{
image: {} as prismic.ImageField,
migrationImage: {} as prismic.MigrationImageField,
link: {} as prismic.LinkField,
migrationLink: {} as prismic.MigrationLinkField,
linkToMedia: {} as prismic.LinkToMediaField,
migrationLinkToMedia: {} as prismic.MigrationLinkToMediaField,
contentRelationship: {} as prismic.ContentRelationshipField,
migrationContentRelationship:
{} as prismic.ContentRelationshipField,
},
],
},
],
},
})
Loading

0 comments on commit ba2c733

Please sign in to comment.