├── .size-limit.cjs ├── src ├── value │ ├── boolean.ts │ ├── number.ts │ ├── color.ts │ ├── keyText.ts │ ├── date.ts │ ├── timestamp.ts │ ├── group.ts │ ├── sharedSlice.ts │ ├── select.ts │ ├── geoPoint.ts │ ├── sharedSliceVariation.ts │ ├── integration.ts │ ├── slice.ts │ ├── linkToMedia.ts │ ├── title.ts │ ├── sliceZone.ts │ ├── contentRelationship.ts │ ├── link.ts │ ├── image.ts │ ├── types.ts │ ├── document.ts │ ├── embed.ts │ └── richText.ts ├── model │ ├── title.ts │ ├── separator.ts │ ├── geoPoint.ts │ ├── uid.ts │ ├── color.ts │ ├── embed.ts │ ├── keyText.ts │ ├── date.ts │ ├── range.ts │ ├── number.ts │ ├── timestamp.ts │ ├── integration.ts │ ├── boolean.ts │ ├── linkToMedia.ts │ ├── group.ts │ ├── select.ts │ ├── contentRelationship.ts │ ├── sharedSlice.ts │ ├── link.ts │ ├── sharedSliceVariation.ts │ ├── image.ts │ ├── richText.ts │ ├── slice.ts │ ├── sliceZone.ts │ ├── customType.ts │ └── types.ts ├── graphql │ ├── index.ts │ └── fields.ts ├── api │ ├── release.ts │ ├── tags.ts │ ├── ref.ts │ ├── query.ts │ └── repository.ts └── webhook │ ├── testTrigger.ts │ ├── types.ts │ └── apiUpdate.ts ├── test ├── api-release.types.ts ├── fields-boolean.types.ts ├── webhook.types.ts ├── api-language.types.ts ├── webhook-testTrigger.types.ts ├── api-ref.types.ts ├── api-tags.types.ts ├── fields-number.types.ts ├── fields-keyText.types.ts ├── api-formField.types.ts ├── customType-sharedSlice.types.ts ├── api-form.types.ts ├── fields-date.types.ts ├── fields-geoPoint.types.ts ├── fields-timestamp.types.ts ├── api-repository.types.ts ├── customType-uid.types.ts ├── fields-color.types.ts ├── customType-date.types.ts ├── fields-select.types.ts ├── customType-color.types.ts ├── customType-embed.types.ts ├── customType-keyText.types.ts ├── customType-number.types.ts ├── customType-timestamp.types.ts ├── customType-title.types.ts ├── customType-boolean.types.ts ├── customType-geoPoint.types.ts ├── customType-integration.types.ts ├── fields-integration.types.ts ├── document-alternativeLanguage.types.ts ├── customType-linkToMedia.types.ts ├── fields-sharedSlice.types.ts ├── fields-linkToMedia.types.ts ├── customType-link.types.ts ├── fields-sharedSliceVariation.types.ts ├── fields-group.types.ts ├── fields.types.ts ├── customType-group.types.ts ├── webhook-apiUpdate.types.ts ├── customType-richText.types.ts ├── index.test.ts ├── fields-sliceZone.types.ts ├── api-query.types.ts ├── customType-sliceZone.types.ts ├── customType-sharedSliceModel.types.ts ├── customType-slice.types.ts ├── customType-select.types.ts ├── customType-contentRelationship.types.ts ├── customType-image.types.ts ├── fields-contentRelationship.types.ts ├── fields-slice.types.ts ├── customType-sharedSliceModelVariation.types.ts ├── fields-embed.types.ts ├── fields-link.types.ts ├── document-prismicDocument.types.ts ├── fields-title.types.ts ├── document-prismicDocumentWithUID.types.ts ├── document-prismicDocumentWithoutUID.types.ts └── fields-richText.types.ts ├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── feature_request.md │ └── bug_report.md ├── workflows │ ├── issues.yml │ ├── ci.yml │ ├── issues--feature_request.md │ └── issues--bug_report.md └── PULL_REQUEST_TEMPLATE.md ├── .gitattributes ├── .editorconfig ├── vite.config.ts ├── .versionrc ├── tsconfig.json ├── .gitignore ├── .eslintignore ├── .prettierignore ├── .prettierrc ├── .eslintrc.cjs ├── package.json └── README.md /.size-limit.cjs: -------------------------------------------------------------------------------- 1 | const pkg = require("./package.json"); 2 | 3 | module.exports = [pkg.module, pkg.main] 4 | .filter(Boolean) 5 | .map((path) => ({ path })); 6 | -------------------------------------------------------------------------------- /src/value/boolean.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A Boolean field. 3 | * 4 | * @see More details: {@link https://prismic.io/docs/core-concepts/boolean} 5 | */ 6 | export type BooleanField = boolean; 7 | -------------------------------------------------------------------------------- /test/api-release.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, TypeEqual } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | /** 6 | * Equivelant to Ref. 7 | */ 8 | expectType>(true); 9 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: 👪 Prismic Community Forum 4 | url: https://community.prismic.io 5 | about: Ask a question about the package or raise an issue directly related to Prismic. You will usually get support there more quickly! 6 | -------------------------------------------------------------------------------- /src/model/title.ts: -------------------------------------------------------------------------------- 1 | import { CustomTypeModelRichTextSingleField } from "./richText"; 2 | 3 | /** 4 | * A Title Custom Type field. 5 | * 6 | * More details: {@link https://prismic.io/docs/core-concepts/rich-text-title} 7 | */ 8 | export type CustomTypeModelTitleField = CustomTypeModelRichTextSingleField; 9 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # asserts everything is text 2 | * text eol=lf 3 | 4 | # treats lock files as binaries to prevent merge headache 5 | package-lock.json -diff 6 | yarn.lock -diff 7 | 8 | # treats assets as binaries 9 | *.png binary 10 | *.jpg binary 11 | *.jpeg binary 12 | *.gif binary 13 | *.ico binary 14 | -------------------------------------------------------------------------------- /src/graphql/index.ts: -------------------------------------------------------------------------------- 1 | export { LinkType } from "./fields"; 2 | 3 | export type { 4 | // Links 5 | EmptyLinkField, 6 | FilledMinimalLinkToDocumentField, 7 | FilledMinimalLinkToWebField, 8 | FilledMinimalLinkToMediaField, 9 | RelationField, 10 | LinkField, 11 | LinkToMediaField, 12 | } from "./fields"; 13 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = tab 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | 14 | [*.yml] 15 | indent_style = space 16 | indent_size = 2 17 | -------------------------------------------------------------------------------- /src/model/separator.ts: -------------------------------------------------------------------------------- 1 | import type { CustomTypeModelFieldType } from "./types"; 2 | 3 | /** 4 | * @deprecated - Legacy field. Do not use. 5 | */ 6 | export interface CustomTypeModelSeparatorField { 7 | type: typeof CustomTypeModelFieldType.Separator; 8 | config?: { 9 | label?: string | null; 10 | }; 11 | } 12 | -------------------------------------------------------------------------------- /test/fields-boolean.types.ts: -------------------------------------------------------------------------------- 1 | import { expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.BooleanField): true => { 6 | switch (typeof value) { 7 | case "boolean": { 8 | return true; 9 | } 10 | 11 | default: { 12 | return expectNever(value); 13 | } 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /src/api/release.ts: -------------------------------------------------------------------------------- 1 | import { Ref } from "./ref"; 2 | 3 | /** 4 | * Metadata for a Release. 5 | * 6 | * @remarks 7 | * This is an alias for `Ref`. 8 | * @see {@link Ref} 9 | * @see More details on Releases: {@link https://prismic.io/docs/core-concepts/draft-plan-and-schedule-content#releases} 10 | */ 11 | export type Release = Ref; 12 | -------------------------------------------------------------------------------- /test/webhook.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, TypeOf } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | /** 6 | * WebhookBody supports any webhook body. 7 | */ 8 | expectType>(true); 9 | expectType>(true); 10 | -------------------------------------------------------------------------------- /src/value/number.ts: -------------------------------------------------------------------------------- 1 | import type { FieldState } from "./types"; 2 | 3 | /** 4 | * A Number field 5 | * 6 | * @typeParam State - State of the field which determines its shape. 7 | * @see More details: {@link https://prismic.io/docs/core-concepts/number} 8 | */ 9 | export type NumberField = 10 | State extends "empty" ? null : number; 11 | -------------------------------------------------------------------------------- /src/value/color.ts: -------------------------------------------------------------------------------- 1 | import type { FieldState } from "./types"; 2 | 3 | /** 4 | * A Color field. 5 | * 6 | * @typeParam State - State of the field which determines its shape. 7 | * @see More details: {@link https://prismic.io/docs/core-concepts/color} 8 | */ 9 | export type ColorField = 10 | State extends "empty" ? null : `#${string}`; 11 | -------------------------------------------------------------------------------- /src/webhook/testTrigger.ts: -------------------------------------------------------------------------------- 1 | import { WebhookBodyBase, WebhookType } from "./types"; 2 | 3 | /** 4 | * Webhook payload sent when a test webhook action is triggered. 5 | * 6 | * @see More details: {@link https://prismic.io/docs/core-concepts/webhooks} 7 | */ 8 | export interface WebhookBodyTestTrigger extends WebhookBodyBase { 9 | type: typeof WebhookType.TestTrigger; 10 | } 11 | -------------------------------------------------------------------------------- /src/model/geoPoint.ts: -------------------------------------------------------------------------------- 1 | import type { CustomTypeModelFieldType } from "./types"; 2 | 3 | /** 4 | * A GeoPoint Custom Type field. 5 | * 6 | * More details: {@link https://prismic.io/docs/core-concepts/geopoint} 7 | */ 8 | export interface CustomTypeModelGeoPointField { 9 | type: typeof CustomTypeModelFieldType.GeoPoint; 10 | config?: { 11 | label?: string | null; 12 | }; 13 | } 14 | -------------------------------------------------------------------------------- /src/value/keyText.ts: -------------------------------------------------------------------------------- 1 | import type { FieldState } from "./types"; 2 | 3 | /** 4 | * A Key text field 5 | * 6 | * @typeParam State - State of the field which determines its shape. 7 | * @see More details: {@link https://prismic.io/docs/core-concepts/key-text} 8 | */ 9 | export type KeyTextField = 10 | State extends "empty" ? null | "" : string; 11 | -------------------------------------------------------------------------------- /src/model/uid.ts: -------------------------------------------------------------------------------- 1 | import type { CustomTypeModelFieldType } from "./types"; 2 | 3 | /** 4 | * A UID Custom Type field. 5 | * 6 | * More details: {@link https://prismic.io/docs/core-concepts/uid} 7 | */ 8 | export interface CustomTypeModelUIDField { 9 | type: typeof CustomTypeModelFieldType.UID; 10 | config?: { 11 | label?: string | null; 12 | placeholder?: string; 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /src/value/date.ts: -------------------------------------------------------------------------------- 1 | import type { FieldState } from "./types"; 2 | 3 | /** 4 | * A Date field. 5 | * 6 | * @typeParam State - State of the field which determines its shape. 7 | * @see More details: {@link https://prismic.io/docs/core-concepts/date} 8 | */ 9 | export type DateField = 10 | State extends "empty" ? null : `${number}-${number}-${number}`; 11 | -------------------------------------------------------------------------------- /src/model/color.ts: -------------------------------------------------------------------------------- 1 | import type { CustomTypeModelFieldType } from "./types"; 2 | 3 | /** 4 | * A Color Custom Type field. 5 | * 6 | * More details: {@link https://prismic.io/docs/core-concepts/color} 7 | */ 8 | export interface CustomTypeModelColorField { 9 | type: typeof CustomTypeModelFieldType.Color; 10 | config?: { 11 | label?: string | null; 12 | placeholder?: string; 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /src/model/embed.ts: -------------------------------------------------------------------------------- 1 | import type { CustomTypeModelFieldType } from "./types"; 2 | 3 | /** 4 | * An Embed Custom Type field. 5 | * 6 | * More details: {@link https://prismic.io/docs/core-concepts/embed} 7 | */ 8 | export interface CustomTypeModelEmbedField { 9 | type: typeof CustomTypeModelFieldType.Embed; 10 | config?: { 11 | label?: string | null; 12 | placeholder?: string; 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import sdk from "vite-plugin-sdk"; 3 | 4 | export default defineConfig({ 5 | build: { 6 | lib: { 7 | entry: { 8 | index: "./src/index.ts", 9 | graphql: "./src/graphql/index.ts", 10 | }, 11 | }, 12 | }, 13 | plugins: [sdk()], 14 | test: { 15 | coverage: { 16 | reporter: ["lcovonly", "text"], 17 | }, 18 | }, 19 | }); 20 | -------------------------------------------------------------------------------- /.versionrc: -------------------------------------------------------------------------------- 1 | { 2 | "types": [ 3 | { 4 | "type": "feat", 5 | "section": "Features" 6 | }, 7 | { 8 | "type": "fix", 9 | "section": "Bug Fixes" 10 | }, 11 | { 12 | "type": "refactor", 13 | "section": "Refactor" 14 | }, 15 | { 16 | "type": "docs", 17 | "section": "Documentation" 18 | }, 19 | { 20 | "type": "chore", 21 | "section": "Chore" 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /src/model/keyText.ts: -------------------------------------------------------------------------------- 1 | import type { CustomTypeModelFieldType } from "./types"; 2 | 3 | /** 4 | * A Key Text Custom Type field. 5 | * 6 | * More details: {@link https://prismic.io/docs/core-concepts/key-text} 7 | */ 8 | export interface CustomTypeModelKeyTextField { 9 | type: typeof CustomTypeModelFieldType.Text; 10 | config?: { 11 | label?: string | null; 12 | placeholder?: string; 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /src/api/tags.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * List of tags returned from the Prismic Tags API. This data can be fetched by 3 | * sending a `GET` request to a repository's `/api/tags` endpoint. 4 | * 5 | * @typeParam Tag - Tags that are returned by the Tags API. 6 | * @see More details on the Tags API: {@link https://prismic.io/docs/technologies/tags-api-technical-reference} 7 | */ 8 | export type Tags = Tag[]; 9 | -------------------------------------------------------------------------------- /src/model/date.ts: -------------------------------------------------------------------------------- 1 | import type { CustomTypeModelFieldType } from "./types"; 2 | 3 | /** 4 | * A Date Custom Type field. 5 | * 6 | * More details: {@link https://prismic.io/docs/core-concepts/date} 7 | */ 8 | export interface CustomTypeModelDateField { 9 | type: typeof CustomTypeModelFieldType.Date; 10 | config?: { 11 | label?: string | null; 12 | placeholder?: string; 13 | default?: string; 14 | }; 15 | } 16 | -------------------------------------------------------------------------------- /src/model/range.ts: -------------------------------------------------------------------------------- 1 | import type { CustomTypeModelFieldType } from "./types"; 2 | 3 | /** 4 | * @deprecated - Legacy field. Use `CustomTypeModelNumberField` instead. 5 | */ 6 | export interface CustomTypeModelRangeField { 7 | type: typeof CustomTypeModelFieldType.Range; 8 | config?: { 9 | label?: string | null; 10 | placeholder?: string; 11 | min?: number; 12 | max?: number; 13 | step?: number; 14 | }; 15 | } 16 | -------------------------------------------------------------------------------- /src/value/timestamp.ts: -------------------------------------------------------------------------------- 1 | import type { FieldState } from "./types"; 2 | import type { DateField } from "./date"; 3 | 4 | /** 5 | * Simple Timestamp Field 6 | * 7 | * @typeParam State - State of the field which determines its shape. 8 | */ 9 | export type TimestampField = 10 | State extends "empty" 11 | ? null 12 | : `${DateField<"filled">}T${number}:${number}:${number}+${number}`; 13 | -------------------------------------------------------------------------------- /src/value/group.ts: -------------------------------------------------------------------------------- 1 | import type { FieldState, AnyRegularField } from "./types"; 2 | 3 | /** 4 | * A Group field. 5 | * 6 | * More details: {@link https://prismic.io/docs/core-concepts/group} 7 | */ 8 | export type GroupField< 9 | Fields extends Record = Record< 10 | string, 11 | AnyRegularField 12 | >, 13 | State extends FieldState = FieldState, 14 | > = State extends "empty" ? [] : [Fields, ...Fields[]]; 15 | -------------------------------------------------------------------------------- /src/model/number.ts: -------------------------------------------------------------------------------- 1 | import type { CustomTypeModelFieldType } from "./types"; 2 | 3 | /** 4 | * A Number Custom Type field. 5 | * 6 | * More details: {@link https://prismic.io/docs/core-concepts/number} 7 | */ 8 | export interface CustomTypeModelNumberField { 9 | type: typeof CustomTypeModelFieldType.Number; 10 | config?: { 11 | label?: string | null; 12 | placeholder?: string; 13 | min?: number; 14 | max?: number; 15 | }; 16 | } 17 | -------------------------------------------------------------------------------- /src/model/timestamp.ts: -------------------------------------------------------------------------------- 1 | import type { CustomTypeModelFieldType } from "./types"; 2 | 3 | /** 4 | * A Timestamp Custom Type field. 5 | * 6 | * More details: {@link https://prismic.io/docs/core-concepts/timestamp} 7 | */ 8 | export interface CustomTypeModelTimestampField { 9 | type: typeof CustomTypeModelFieldType.Timestamp; 10 | config?: { 11 | label?: string | null; 12 | placeholder?: string; 13 | default?: string; 14 | }; 15 | } 16 | -------------------------------------------------------------------------------- /src/model/integration.ts: -------------------------------------------------------------------------------- 1 | import type { CustomTypeModelFieldType } from "./types"; 2 | 3 | /** 4 | * An Integration Fields Custom Type field. 5 | * 6 | * More details: {@link https://prismic.io/docs/core-concepts/integration-fields} 7 | */ 8 | export interface CustomTypeModelIntegrationField { 9 | type: typeof CustomTypeModelFieldType.Integration; 10 | config?: { 11 | label?: string | null; 12 | placeholder?: string; 13 | catalog?: string; 14 | }; 15 | } 16 | -------------------------------------------------------------------------------- /src/value/sharedSlice.ts: -------------------------------------------------------------------------------- 1 | import type { SharedSliceVariation } from "./sharedSliceVariation"; 2 | 3 | /** 4 | * Shared Slice 5 | * 6 | * @see More details: {@link https://prismic.io/docs/core-concepts/reusing-slices#shared-slices} 7 | */ 8 | export type SharedSlice< 9 | SliceType = string, 10 | Variations extends SharedSliceVariation = SharedSliceVariation, 11 | > = { 12 | slice_type: SliceType; 13 | slice_label: null; 14 | id?: string; 15 | } & Variations; 16 | -------------------------------------------------------------------------------- /src/model/boolean.ts: -------------------------------------------------------------------------------- 1 | import type { CustomTypeModelFieldType } from "./types"; 2 | 3 | /** 4 | * A Boolean Custom Type field. 5 | * 6 | * More details: {@link https://prismic.io/docs/core-concepts/boolean} 7 | */ 8 | export interface CustomTypeModelBooleanField { 9 | type: typeof CustomTypeModelFieldType.Boolean; 10 | config?: { 11 | label?: string | null; 12 | default_value?: boolean; 13 | placeholder_true?: string; 14 | placeholder_false?: string; 15 | }; 16 | } 17 | -------------------------------------------------------------------------------- /src/value/select.ts: -------------------------------------------------------------------------------- 1 | import type { FieldState } from "./types"; 2 | 3 | /** 4 | * A Select field 5 | * 6 | * @typeParam Enum - Selectable options for the field. 7 | * @typeParam State - State of the field which determines its shape. 8 | * @see More details: {@link https://prismic.io/docs/core-concepts/select} 9 | */ 10 | export type SelectField< 11 | Enum extends string = string, 12 | State extends FieldState = FieldState, 13 | > = State extends "empty" ? null : Enum; 14 | -------------------------------------------------------------------------------- /src/value/geoPoint.ts: -------------------------------------------------------------------------------- 1 | import type { EmptyObjectField, FieldState } from "./types"; 2 | 3 | /** 4 | * A Geopoint field. 5 | * 6 | * @typeParam State - State of the field which determines its shape. 7 | * @see More details: {@link https://prismic.io/docs/core-concepts/geopoint} 8 | */ 9 | export type GeoPointField = 10 | State extends "empty" 11 | ? EmptyObjectField 12 | : { 13 | latitude: number; 14 | longitude: number; 15 | }; 16 | -------------------------------------------------------------------------------- /test/api-language.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.Language): true => { 6 | switch (typeof value) { 7 | case "object": { 8 | if (value === null) { 9 | expectNever(value); 10 | } 11 | 12 | return true; 13 | } 14 | 15 | default: { 16 | return expectNever(value); 17 | } 18 | } 19 | }; 20 | 21 | expectType({ 22 | id: "string", 23 | name: "string", 24 | }); 25 | -------------------------------------------------------------------------------- /src/value/sharedSliceVariation.ts: -------------------------------------------------------------------------------- 1 | import type { AnyRegularField } from "./types"; 2 | 3 | export interface SharedSliceVariation< 4 | Variation = string, 5 | PrimaryFields extends Record = Record< 6 | string, 7 | AnyRegularField 8 | >, 9 | ItemsFields extends Record = Record< 10 | string, 11 | AnyRegularField 12 | >, 13 | > { 14 | variation: Variation; 15 | version: string; 16 | primary: PrimaryFields; 17 | items: ItemsFields[]; 18 | } 19 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": true, 4 | "skipLibCheck": true, 5 | 6 | "target": "esnext", 7 | "module": "esnext", 8 | "declaration": false, 9 | "moduleResolution": "node", 10 | "resolveJsonModule": true, 11 | "allowSyntheticDefaultImports": true, 12 | "esModuleInterop": true, 13 | 14 | "forceConsistentCasingInFileNames": true, 15 | "jsx": "preserve", 16 | "lib": ["esnext", "dom"], 17 | "types": ["node"] 18 | }, 19 | "exclude": ["node_modules", "dist", "examples"] 20 | } 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # custom 2 | dist 3 | examples/**/package-lock.json 4 | 5 | # os 6 | .DS_Store 7 | ._* 8 | 9 | # node 10 | logs 11 | *.log 12 | node_modules 13 | 14 | # yarn 15 | yarn-debug.log* 16 | yarn-error.log* 17 | lerna-debug.log* 18 | .yarn-integrity 19 | yarn.lock 20 | 21 | # npm 22 | npm-debug.log* 23 | 24 | # tests 25 | coverage 26 | .eslintcache 27 | .nyc_output 28 | 29 | # .env 30 | .env 31 | .env.test 32 | .env*.local 33 | 34 | # vscode 35 | .vscode/* 36 | !.vscode/tasks.json 37 | !.vscode/launch.json 38 | *.code-workspace 39 | -------------------------------------------------------------------------------- /src/value/integration.ts: -------------------------------------------------------------------------------- 1 | import type { FieldState } from "./types"; 2 | 3 | /** 4 | * Integration Fields for Custom APIs 5 | * 6 | * @typeParam Data - Data from the integrated API. 7 | * @typeParam State - State of the field which determines its shape. 8 | * @see More details: {@link https://prismic.io/docs/core-concepts/integration-fields-setup} 9 | */ 10 | export type IntegrationField< 11 | Data extends Record = Record, 12 | State extends FieldState = FieldState, 13 | > = State extends "empty" ? null : Data; 14 | -------------------------------------------------------------------------------- /src/model/linkToMedia.ts: -------------------------------------------------------------------------------- 1 | import type { CustomTypeModelFieldType } from "./types"; 2 | import type { CustomTypeModelLinkSelectType } from "./link"; 3 | 4 | /** 5 | * A Link to Media Custom Type field. 6 | * 7 | * More details: 8 | * {@link https://prismic.io/docs/core-concepts/link-content-relationship} 9 | */ 10 | export interface CustomTypeModelLinkToMediaField { 11 | type: typeof CustomTypeModelFieldType.Link; 12 | config?: { 13 | label?: string | null; 14 | placeholder?: string; 15 | select: typeof CustomTypeModelLinkSelectType.Media; 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | # .gitignore copy 2 | 3 | # custom 4 | dist 5 | examples/**/package-lock.json 6 | 7 | # os 8 | .DS_Store 9 | ._* 10 | 11 | # node 12 | logs 13 | *.log 14 | node_modules 15 | 16 | # yarn 17 | yarn-debug.log* 18 | yarn-error.log* 19 | lerna-debug.log* 20 | .yarn-integrity 21 | yarn.lock 22 | 23 | # npm 24 | npm-debug.log* 25 | 26 | # tests 27 | coverage 28 | .eslintcache 29 | .nyc_output 30 | 31 | # .env 32 | .env 33 | .env.test 34 | .env*.local 35 | 36 | # vscode 37 | .vscode/* 38 | !.vscode/tasks.json 39 | !.vscode/launch.json 40 | *.code-workspace 41 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # .gitignore copy 2 | 3 | # custom 4 | dist 5 | examples/**/package-lock.json 6 | CHANGELOG.md 7 | 8 | # os 9 | .DS_Store 10 | ._* 11 | 12 | # node 13 | logs 14 | *.log 15 | node_modules 16 | 17 | # yarn 18 | yarn-debug.log* 19 | yarn-error.log* 20 | lerna-debug.log* 21 | .yarn-integrity 22 | yarn.lock 23 | 24 | # npm 25 | npm-debug.log* 26 | 27 | # tests 28 | coverage 29 | .eslintcache 30 | .nyc_output 31 | 32 | # .env 33 | .env 34 | .env.test 35 | .env*.local 36 | 37 | # vscode 38 | .vscode/* 39 | !.vscode/tasks.json 40 | !.vscode/launch.json 41 | *.code-workspace 42 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["prettier-plugin-jsdoc"], 3 | "jsdocCapitalizeDescription": false, 4 | "jsdocSeparateReturnsFromParam": true, 5 | "jsdocSingleLineComment": false, 6 | "tsdoc": true, 7 | "printWidth": 80, 8 | "useTabs": true, 9 | "semi": true, 10 | "singleQuote": false, 11 | "quoteProps": "as-needed", 12 | "jsxSingleQuote": false, 13 | "trailingComma": "all", 14 | "bracketSpacing": true, 15 | "bracketSameLine": false, 16 | "arrowParens": "always", 17 | "requirePragma": false, 18 | "insertPragma": false, 19 | "htmlWhitespaceSensitivity": "css", 20 | "endOfLine": "lf" 21 | } 22 | -------------------------------------------------------------------------------- /src/value/slice.ts: -------------------------------------------------------------------------------- 1 | import type { AnyRegularField } from "./types"; 2 | 3 | /** 4 | * Slice - Sections of your website 5 | * 6 | * @see More details: {@link https://prismic.io/docs/core-concepts/slices} 7 | */ 8 | export interface Slice< 9 | SliceType = string, 10 | PrimaryFields extends Record = Record< 11 | string, 12 | AnyRegularField 13 | >, 14 | ItemsFields extends Record = Record< 15 | string, 16 | AnyRegularField 17 | >, 18 | > { 19 | slice_type: SliceType; 20 | slice_label: string | null; 21 | id?: string; 22 | primary: PrimaryFields; 23 | items: ItemsFields[]; 24 | } 25 | -------------------------------------------------------------------------------- /src/webhook/types.ts: -------------------------------------------------------------------------------- 1 | import { WebhookBodyAPIUpdate } from "./apiUpdate"; 2 | import { WebhookBodyTestTrigger } from "./testTrigger"; 3 | 4 | export type WebhookBody = WebhookBodyAPIUpdate | WebhookBodyTestTrigger; 5 | 6 | /** 7 | * Types of Prismic Webhooks. 8 | * 9 | * @see More details: {@link https://prismic.io/docs/core-concepts/webhooks} 10 | */ 11 | export const WebhookType = { 12 | APIUpdate: "api-update", 13 | TestTrigger: "test-trigger", 14 | } as const; 15 | 16 | export interface WebhookBodyBase { 17 | type: typeof WebhookType[keyof typeof WebhookType]; 18 | domain: string; 19 | apiUrl: string; 20 | secret: string | null; 21 | } 22 | -------------------------------------------------------------------------------- /src/model/group.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | CustomTypeModelFieldType, 3 | CustomTypeModelFieldForGroup, 4 | } from "./types"; 5 | 6 | /** 7 | * A Group Custom Type field. 8 | * 9 | * More details: {@link https://prismic.io/docs/core-concepts/group} 10 | * 11 | * @typeParam Fields - A record of fields that can be repeated. 12 | */ 13 | export interface CustomTypeModelGroupField< 14 | Fields extends Record = Record< 15 | string, 16 | CustomTypeModelFieldForGroup 17 | >, 18 | > { 19 | type: typeof CustomTypeModelFieldType.Group; 20 | config?: { 21 | label?: string | null; 22 | fields?: Fields; 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /src/model/select.ts: -------------------------------------------------------------------------------- 1 | import type { CustomTypeModelFieldType } from "./types"; 2 | 3 | /** 4 | * A Select Custom Type field. 5 | * 6 | * More details: {@link https://prismic.io/docs/core-concepts/select} 7 | * 8 | * @typeParam Options - Options for the field. 9 | * @typeParam DefaultValue - Default value for the field. 10 | */ 11 | export interface CustomTypeModelSelectField< 12 | Option extends string = string, 13 | DefaultValue extends Option = Option, 14 | > { 15 | type: typeof CustomTypeModelFieldType.Select; 16 | config?: { 17 | label?: string | null; 18 | placeholder?: string; 19 | options?: readonly Option[]; 20 | default_value?: DefaultValue; 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /test/webhook-testTrigger.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.WebhookBodyTestTrigger): true => { 6 | switch (typeof value) { 7 | case "object": { 8 | if (value === null) { 9 | expectNever(value); 10 | } 11 | 12 | return true; 13 | } 14 | 15 | default: { 16 | return expectNever(value); 17 | } 18 | } 19 | }; 20 | 21 | expectType({ 22 | type: "test-trigger", 23 | domain: "string", 24 | apiUrl: "string", 25 | secret: "string", 26 | }); 27 | 28 | /** 29 | * Secret is nullable. 30 | */ 31 | expectType(null); 32 | -------------------------------------------------------------------------------- /src/value/linkToMedia.ts: -------------------------------------------------------------------------------- 1 | import type { EmptyLinkField, LinkType } from "./link"; 2 | import type { FieldState } from "./types"; 3 | 4 | /** 5 | * Link field that points to media 6 | * 7 | * @typeParam State - State of the field which determines its shape. 8 | */ 9 | export type LinkToMediaField = 10 | State extends "empty" 11 | ? EmptyLinkField 12 | : FilledLinkToMediaField; 13 | 14 | /** 15 | * Link that points to media 16 | */ 17 | export interface FilledLinkToMediaField { 18 | id: string; 19 | link_type: typeof LinkType.Media; 20 | name: string; 21 | kind: string; 22 | url: string; 23 | size: string; 24 | height?: string | null; 25 | width?: string | null; 26 | } 27 | -------------------------------------------------------------------------------- /src/value/title.ts: -------------------------------------------------------------------------------- 1 | import type { FieldState } from "./types"; 2 | import type { 3 | RTHeading1Node, 4 | RTHeading2Node, 5 | RTHeading3Node, 6 | RTHeading4Node, 7 | RTHeading5Node, 8 | RTHeading6Node, 9 | } from "./richText"; 10 | 11 | /** 12 | * Title Field 13 | * 14 | * @see Title field documentation: {@link https://prismic.io/docs/core-concepts/rich-text-title} 15 | */ 16 | export type TitleField = 17 | State extends "empty" 18 | ? [] 19 | : [ 20 | Omit< 21 | | RTHeading1Node 22 | | RTHeading2Node 23 | | RTHeading3Node 24 | | RTHeading4Node 25 | | RTHeading5Node 26 | | RTHeading6Node, 27 | "spans" 28 | > & { 29 | spans: []; 30 | }, 31 | ]; 32 | -------------------------------------------------------------------------------- /src/model/contentRelationship.ts: -------------------------------------------------------------------------------- 1 | import type { CustomTypeModelFieldType } from "./types"; 2 | import type { CustomTypeModelLinkSelectType } from "./link"; 3 | 4 | /** 5 | * A Content Relationship Custom Type field. 6 | * 7 | * More details: 8 | * {@link https://prismic.io/docs/core-concepts/link-content-relationship} 9 | */ 10 | export interface CustomTypeModelContentRelationshipField< 11 | CustomTypeIDs extends string = string, 12 | Tags extends string = string, 13 | > { 14 | type: typeof CustomTypeModelFieldType.Link; 15 | config?: { 16 | label?: string | null; 17 | placeholder?: string; 18 | select: typeof CustomTypeModelLinkSelectType.Document; 19 | customtypes?: readonly CustomTypeIDs[]; 20 | tags?: readonly Tags[]; 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /test/api-ref.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.Ref): true => { 6 | switch (typeof value) { 7 | case "object": { 8 | if (value === null) { 9 | expectNever(value); 10 | } 11 | 12 | return true; 13 | } 14 | 15 | default: { 16 | return expectNever(value); 17 | } 18 | } 19 | }; 20 | 21 | expectType({ 22 | id: "string", 23 | ref: "string", 24 | label: "string", 25 | isMasterRef: true, 26 | scheduledAt: "string", 27 | }); 28 | 29 | /** 30 | * Supports optional `scheduledAt` property. 31 | */ 32 | expectType({ 33 | id: "string", 34 | ref: "string", 35 | label: "string", 36 | isMasterRef: true, 37 | }); 38 | -------------------------------------------------------------------------------- /src/model/sharedSlice.ts: -------------------------------------------------------------------------------- 1 | import type { CustomTypeModelSliceType } from "./sliceZone"; 2 | import type { SharedSliceModelVariation } from "./sharedSliceVariation"; 3 | 4 | /** 5 | * A Prismic Shared Slice model. 6 | * 7 | * More details: 8 | * 9 | * - {@link https://prismic.io/docs/core-concepts/slices} 10 | * - {@link https://prismic.io/docs/core-concepts/reusing-slices} 11 | * 12 | * @typeParam Variation - A variation for the Shared Slice. 13 | */ 14 | export interface SharedSliceModel< 15 | ID extends string = string, 16 | Variation extends SharedSliceModelVariation = SharedSliceModelVariation, 17 | > { 18 | type: typeof CustomTypeModelSliceType.SharedSlice; 19 | id: ID; 20 | name: string; 21 | description?: string; 22 | variations: readonly Variation[]; 23 | } 24 | -------------------------------------------------------------------------------- /src/value/sliceZone.ts: -------------------------------------------------------------------------------- 1 | import type { FieldState } from "./types"; 2 | import type { SharedSlice } from "./sharedSlice"; 3 | import type { Slice } from "./slice"; 4 | 5 | /** 6 | * Prismic Slices are sections of your website. Prismic documents contain a 7 | * dynamic "Slice Zone" that allows content creators to add, edit, and rearrange 8 | * Slices to compose dynamic layouts for any page design, such as blog posts, 9 | * landing pages, case studies, and tutorials. 10 | * 11 | * @see More details: {@link https://prismic.io/docs/technologies/adding-the-slicezone-component-nextjs} 12 | */ 13 | export type SliceZone< 14 | Slices extends Slice | SharedSlice = Slice | SharedSlice, 15 | State extends FieldState = FieldState, 16 | > = State extends "empty" ? [] : [Slices, ...Slices[]]; 17 | -------------------------------------------------------------------------------- /test/api-tags.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.Tags): true => { 6 | if (!Array.isArray(value)) { 7 | return expectNever(value); 8 | } 9 | 10 | switch (typeof value[0]) { 11 | case "string": { 12 | return true; 13 | } 14 | 15 | default: { 16 | return expectNever(value[0]); 17 | } 18 | } 19 | }; 20 | 21 | expectType(["string"]); 22 | 23 | /** 24 | * Supports empty lists. 25 | */ 26 | expectType([]); 27 | 28 | /** 29 | * Supports custom tag enum-like (string union). 30 | */ 31 | expectType>(["foo", "bar"]); 32 | expectType>([ 33 | // @ts-expect-error - Only given tags are valid. 34 | "string", 35 | ]); 36 | -------------------------------------------------------------------------------- /src/model/link.ts: -------------------------------------------------------------------------------- 1 | import type { CustomTypeModelFieldType } from "./types"; 2 | 3 | /** 4 | * A Link Custom Type field. 5 | * 6 | * More details: 7 | * {@link https://prismic.io/docs/core-concepts/link-content-relationship} 8 | */ 9 | export interface CustomTypeModelLinkField { 10 | type: typeof CustomTypeModelFieldType.Link; 11 | config?: { 12 | label?: string | null; 13 | placeholder?: string; 14 | select?: 15 | | null 16 | | typeof CustomTypeModelLinkSelectType[keyof typeof CustomTypeModelLinkSelectType]; 17 | allowTargetBlank?: boolean; 18 | }; 19 | } 20 | 21 | /** 22 | * Type of a Link Custom Type field. 23 | * 24 | * More details: 25 | * {@link https://prismic.io/docs/core-concepts/link-content-relationship} 26 | */ 27 | export const CustomTypeModelLinkSelectType = { 28 | Document: "document", 29 | Media: "media", 30 | Web: "web", 31 | } as const; 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🙋‍♀️ Feature request 3 | about: Suggest an idea or enhancement for the package. 4 | title: "" 5 | labels: "enhancement" 6 | assignees: "" 7 | --- 8 | 9 | 10 | 11 | ### Is your feature request related to a problem? Please describe. 12 | 13 | 14 | 15 | ### Describe the solution you'd like 16 | 17 | 18 | 19 | ### Describe alternatives you've considered 20 | 21 | 22 | 23 | ### Additional context 24 | 25 | 26 | -------------------------------------------------------------------------------- /test/fields-number.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.NumberField): true => { 6 | switch (typeof value) { 7 | case "number": { 8 | return true; 9 | } 10 | 11 | default: { 12 | if (value === null) { 13 | return true; 14 | } 15 | 16 | return expectNever(value); 17 | } 18 | } 19 | }; 20 | 21 | /** 22 | * Filled state. 23 | */ 24 | expectType(0); 25 | expectType>(0); 26 | expectType>( 27 | // @ts-expect-error - Empty fields cannot contain a filled value. 28 | 0, 29 | ); 30 | 31 | /** 32 | * Empty state. 33 | */ 34 | expectType(null); 35 | expectType>(null); 36 | expectType>( 37 | // @ts-expect-error - Filled fields cannot contain an empty value. 38 | null, 39 | ); 40 | -------------------------------------------------------------------------------- /test/fields-keyText.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.KeyTextField): true => { 6 | switch (typeof value) { 7 | case "string": { 8 | return true; 9 | } 10 | 11 | default: { 12 | if (value === null) { 13 | return true; 14 | } 15 | 16 | return expectNever(value); 17 | } 18 | } 19 | }; 20 | 21 | /** 22 | * Filled state. 23 | */ 24 | expectType("foo"); 25 | expectType>("foo"); 26 | expectType>( 27 | // @ts-expect-error - Empty fields cannot contain a filled value. 28 | "foo", 29 | ); 30 | 31 | /** 32 | * Empty state. 33 | */ 34 | expectType(null); 35 | expectType>(null); 36 | expectType>( 37 | // @ts-expect-error - Filled fields cannot contain an empty value. 38 | null, 39 | ); 40 | -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | browser: true, 5 | node: true, 6 | }, 7 | parserOptions: { 8 | parser: "@typescript-eslint/parser", 9 | ecmaVersion: 2020, 10 | }, 11 | extends: [ 12 | "plugin:@typescript-eslint/eslint-recommended", 13 | "plugin:@typescript-eslint/recommended", 14 | "plugin:prettier/recommended", 15 | ], 16 | plugins: ["eslint-plugin-tsdoc"], 17 | rules: { 18 | "no-console": ["warn", { allow: ["info", "warn", "error"] }], 19 | "no-debugger": "warn", 20 | "no-undef": "off", 21 | curly: "error", 22 | "prefer-const": "error", 23 | "padding-line-between-statements": [ 24 | "error", 25 | { blankLine: "always", prev: "*", next: "return" }, 26 | ], 27 | "@typescript-eslint/no-unused-vars": [ 28 | "error", 29 | { 30 | argsIgnorePattern: "^_", 31 | varsIgnorePattern: "^_", 32 | }, 33 | ], 34 | "@typescript-eslint/no-var-requires": "off", 35 | "tsdoc/syntax": "warn", 36 | }, 37 | }; 38 | -------------------------------------------------------------------------------- /.github/workflows/issues.yml: -------------------------------------------------------------------------------- 1 | name: issues 2 | 3 | on: 4 | issues: 5 | types: 6 | - opened 7 | 8 | jobs: 9 | issues: 10 | if: github.event.issue.author_association == 'NONE' 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: Checkout 15 | uses: actions/checkout@master 16 | 17 | - name: Reply bug report 18 | if: contains(github.event.issue.labels.*.name, 'bug') 19 | env: 20 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 21 | ISSUE_URL: ${{ github.event.issue.html_url }} 22 | run: gh issue comment $ISSUE_URL --body-file ./.github/workflows/issues--bug_report.md 23 | 24 | - name: Reply feature request 25 | if: contains(github.event.issue.labels.*.name, 'enhancement') 26 | env: 27 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 28 | ISSUE_URL: ${{ github.event.issue.html_url }} 29 | run: gh issue comment $ISSUE_URL --body-file ./.github/workflows/issues--feature_request.md 30 | -------------------------------------------------------------------------------- /src/model/sharedSliceVariation.ts: -------------------------------------------------------------------------------- 1 | import type { CustomTypeModelFieldForGroup } from "./types"; 2 | 3 | /** 4 | * A Shared Slice variation. 5 | * 6 | * More details: 7 | * 8 | * - {@link https://prismic.io/docs/core-concepts/slices} 9 | * - {@link https://prismic.io/docs/core-concepts/reusing-slices} 10 | * 11 | * @typeParam PrimaryFields - A record of fields that cannnot be repeated. 12 | * @typeParam ItemFields - A record of fields that can be repeated. 13 | */ 14 | export interface SharedSliceModelVariation< 15 | ID extends string = string, 16 | PrimaryFields extends Record = Record< 17 | string, 18 | CustomTypeModelFieldForGroup 19 | >, 20 | ItemFields extends Record = Record< 21 | string, 22 | CustomTypeModelFieldForGroup 23 | >, 24 | > { 25 | id: ID; 26 | name: string; 27 | docURL: string; 28 | version: string; 29 | description: string; 30 | primary?: PrimaryFields; 31 | items?: ItemFields; 32 | imageUrl: string; 33 | } 34 | -------------------------------------------------------------------------------- /test/api-formField.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.FormField): true => { 6 | switch (typeof value) { 7 | case "object": { 8 | if (value === null) { 9 | expectNever(value); 10 | } 11 | 12 | return true; 13 | } 14 | 15 | default: { 16 | return expectNever(value); 17 | } 18 | } 19 | }; 20 | 21 | expectType({ 22 | type: "String", 23 | multiple: true, 24 | default: "string", 25 | }); 26 | expectType({ 27 | type: "Integer", 28 | multiple: true, 29 | default: "string", 30 | }); 31 | 32 | /** 33 | * `type` must be "String" or "Integer". 34 | */ 35 | expectType({ 36 | // @ts-expect-error - `type` must be "String" or "Integer". 37 | type: "string", 38 | multiple: true, 39 | default: "string", 40 | }); 41 | 42 | /** 43 | * Supports optional `default` property. 44 | */ 45 | expectType({ 46 | type: "String", 47 | multiple: true, 48 | }); 49 | -------------------------------------------------------------------------------- /test/customType-sharedSlice.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicTI from "@prismicio/types-internal"; 4 | 5 | import * as prismicT from "../src"; 6 | 7 | (value: prismicT.CustomTypeModelSharedSlice): true => { 8 | switch (typeof value) { 9 | case "object": { 10 | if (value === null) { 11 | expectNever(value); 12 | } 13 | 14 | return true; 15 | } 16 | 17 | default: { 18 | return expectNever(value); 19 | } 20 | } 21 | }; 22 | 23 | expectType({ 24 | type: prismicT.CustomTypeModelSliceType.SharedSlice, 25 | }); 26 | 27 | /** 28 | * `@prismicio/types` extends `@prismicio/types-internal` 29 | */ 30 | expectType( 31 | {} as prismicTI.CustomTypes.Widgets.Slices.SharedSliceRef, 32 | ); 33 | 34 | /** 35 | * `@prismicio/types-internal` extends `@prismicio/types` 36 | */ 37 | expectType( 38 | {} as prismicT.CustomTypeModelSharedSlice, 39 | ); 40 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🚨 Bug report 3 | about: Report a bug report to help improve the package. 4 | title: "" 5 | labels: "bug" 6 | assignees: "" 7 | --- 8 | 9 | 16 | 17 | ### Versions 18 | 19 | - @prismicio/types: 20 | - node: 21 | 22 | ### Reproduction 23 | 24 | 25 | 26 |
27 | Additional Details 28 |
29 | 30 |
31 | 32 | ### Steps to reproduce 33 | 34 | ### What is expected? 35 | 36 | ### What is actually happening? 37 | -------------------------------------------------------------------------------- /src/api/ref.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Metadata for a reference to a version of a repository's content. 3 | * 4 | * @see More details on refs: {@link https://prismic.io/docs/technologies/introduction-to-the-content-query-api#prismic-api-ref} 5 | */ 6 | export interface Ref { 7 | /** 8 | * The unique identifier for the ref. 9 | */ 10 | id: string; 11 | 12 | /** 13 | * The identifier that should be provided to the API to select a content 14 | * version. 15 | */ 16 | ref: string; 17 | 18 | /** 19 | * A human-readable name for the ref. The master ref is always named "Master". 20 | */ 21 | label: string; 22 | 23 | /** 24 | * Determines if the ref is the master ref. The master ref contains the latest 25 | * published content. 26 | */ 27 | isMasterRef: boolean; 28 | 29 | /** 30 | * If the ref is associated with a Release, this field contains the timestamp 31 | * at which the Release will be automatically published, if set. 32 | * 33 | * @see More details on Releases: {@link https://prismic.io/docs/core-concepts/draft-plan-and-schedule-content#releases} 34 | */ 35 | scheduledAt?: string; 36 | } 37 | -------------------------------------------------------------------------------- /src/model/image.ts: -------------------------------------------------------------------------------- 1 | import type { CustomTypeModelFieldType } from "./types"; 2 | 3 | /** 4 | * Dimension constraints for an Image Custom Type field. 5 | * 6 | * More details: {@link https://prismic.io/docs/core-concepts/image} 7 | */ 8 | export interface CustomTypeModelImageConstraint { 9 | width?: number | null; 10 | height?: number | null; 11 | } 12 | 13 | /** 14 | * A thumbnail for an Image Custom Type field. 15 | * 16 | * More details: {@link https://prismic.io/docs/core-concepts/image} 17 | */ 18 | export interface CustomTypeModelImageThumbnail 19 | extends CustomTypeModelImageConstraint { 20 | name: Name; 21 | } 22 | 23 | /** 24 | * An Image Custom Type field. 25 | * 26 | * More details: {@link https://prismic.io/docs/core-concepts/image} 27 | */ 28 | export interface CustomTypeModelImageField< 29 | ThumbnailNames extends string = string, 30 | > { 31 | type: typeof CustomTypeModelFieldType.Image; 32 | config?: { 33 | label?: string | null; 34 | constraint?: CustomTypeModelImageConstraint; 35 | thumbnails?: readonly CustomTypeModelImageThumbnail[]; 36 | }; 37 | } 38 | -------------------------------------------------------------------------------- /test/api-form.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.Form): true => { 6 | switch (typeof value) { 7 | case "object": { 8 | if (value === null) { 9 | expectNever(value); 10 | } 11 | 12 | return true; 13 | } 14 | 15 | default: { 16 | return expectNever(value); 17 | } 18 | } 19 | }; 20 | 21 | expectType({ 22 | method: "GET", 23 | enctype: "string", 24 | action: "string", 25 | name: "string", 26 | rel: "string", 27 | fields: { 28 | foo: { 29 | type: "String", 30 | multiple: true, 31 | default: "string", 32 | }, 33 | }, 34 | }); 35 | 36 | /** 37 | * `method` must be "GET". 38 | */ 39 | expectType({ 40 | // @ts-expect-error -`method` must be "GET". 41 | method: "string", 42 | enctype: "string", 43 | action: "string", 44 | name: "string", 45 | rel: "string", 46 | fields: {}, 47 | }); 48 | 49 | /** 50 | * Supports optional `name` and `rel` properties. 51 | */ 52 | expectType({ 53 | method: "GET", 54 | enctype: "string", 55 | action: "string", 56 | fields: {}, 57 | }); 58 | -------------------------------------------------------------------------------- /test/fields-date.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.DateField): true => { 6 | switch (typeof value) { 7 | case "string": { 8 | return true; 9 | } 10 | 11 | default: { 12 | if (value === null) { 13 | return true; 14 | } 15 | 16 | return expectNever(value); 17 | } 18 | } 19 | }; 20 | 21 | /** 22 | * Filled state. 23 | */ 24 | expectType("1984-01-24"); 25 | expectType>("1984-01-24"); 26 | expectType>( 27 | // @ts-expect-error - Empty fields cannot contain a filled value. 28 | "1984-01-24", 29 | ); 30 | 31 | /** 32 | * Empty state. 33 | */ 34 | expectType(null); 35 | expectType>(null); 36 | expectType>( 37 | // @ts-expect-error - Filled fields cannot contain an empty value. 38 | null, 39 | ); 40 | 41 | /** 42 | * Must be in YYYY-MM-DD format. 43 | */ 44 | expectType( 45 | // @ts-expect-error - Arbitrary strings are invalid. 46 | "Jan 24, 1984", 47 | ); 48 | -------------------------------------------------------------------------------- /test/fields-geoPoint.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.GeoPointField): true => { 6 | switch (typeof value) { 7 | case "object": { 8 | if (value === null) { 9 | expectNever(value); 10 | } 11 | 12 | return true; 13 | } 14 | 15 | default: { 16 | return expectNever(value); 17 | } 18 | } 19 | }; 20 | 21 | /** 22 | * Filled state. 23 | */ 24 | expectType({ 25 | longitude: 0, 26 | latitude: 0, 27 | }); 28 | expectType>({ 29 | longitude: 0, 30 | latitude: 0, 31 | }); 32 | expectType>({ 33 | // @ts-expect-error - Empty fields cannot contain a filled value. 34 | longitude: 0, 35 | // @ts-expect-error - Empty fields cannot contain a filled value. 36 | latitude: 0, 37 | }); 38 | 39 | /** 40 | * Empty state. 41 | */ 42 | expectType({}); 43 | expectType>({}); 44 | expectType>( 45 | // @ts-expect-error - Filled fields cannot contain an empty value. 46 | {}, 47 | ); 48 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | branches: 9 | - master 10 | 11 | jobs: 12 | ci: 13 | runs-on: ${{ matrix.os }} 14 | 15 | strategy: 16 | matrix: 17 | os: [ubuntu-latest] 18 | node: [14] 19 | 20 | steps: 21 | - uses: actions/setup-node@v2 22 | with: 23 | node-version: ${{ matrix.node }} 24 | 25 | - name: Checkout 26 | uses: actions/checkout@master 27 | 28 | - name: Cache node_modules 29 | uses: actions/cache@v2 30 | with: 31 | path: node_modules 32 | key: ${{ matrix.os }}-node-v${{ matrix.node }}-deps-${{ hashFiles(format('{0}{1}', github.workspace, '/package-lock.json')) }} 33 | 34 | - name: Install dependencies 35 | if: steps.cache.outputs.cache-hit != 'true' 36 | run: npm ci 37 | 38 | - name: Lint 39 | run: npm run lint 40 | 41 | - name: Types 42 | run: npm run types 43 | 44 | - name: Unit 45 | run: npm run unit 46 | 47 | - name: Build 48 | run: npm run build 49 | 50 | - name: Coverage 51 | uses: codecov/codecov-action@v1 52 | -------------------------------------------------------------------------------- /.github/workflows/issues--feature_request.md: -------------------------------------------------------------------------------- 1 | > This issue has been labeled as a **feature request** since it was created using the [🙋‍♀️ **Feature Request Template**](./new?assignees=&labels=enhancement&template=feature_request.md&title=). 2 | 3 | Hi there, thank you so much for your request! 4 | 5 | Following our [Maintenance Process](../blob/HEAD/CONTRIBUTING.md#maintaining), we will review your request and get back to you soon. If we decide to implement it, will proceed to implement the feature during the _last week of the month_. In the meantime, feel free to provide any details to help us better understand your request, such as: 6 | 7 | - The context that made you think of this feature request 8 | - As many details about the solution you'd like to see implemented, how it should behave, etc. 9 | - Any alternative solution you have considered 10 | 11 | If you think you can implement the proposed change yourself, you're more than welcome to [open a pull request](../pulls) implementing the new feature. Check out our [quick start guide](../blob/HEAD/CONTRIBUTING.md#quick-start) for a simple contribution process. Please note that submitting a pull request does not guarantee the feature will be merged. 12 | 13 | _- The Prismic Open-Source Team_ 14 | -------------------------------------------------------------------------------- /test/fields-timestamp.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.TimestampField): true => { 6 | switch (typeof value) { 7 | case "string": { 8 | return true; 9 | } 10 | 11 | default: { 12 | if (value === null) { 13 | return true; 14 | } 15 | 16 | return expectNever(value); 17 | } 18 | } 19 | }; 20 | 21 | /** 22 | * Filled state. 23 | */ 24 | expectType("1984-01-24T05:00:00+0000"); 25 | expectType>("1984-01-24T05:00:00+0000"); 26 | expectType>( 27 | // @ts-expect-error - Empty fields cannot contain a filled value. 28 | "1984-01-24T05:00:00+0000", 29 | ); 30 | 31 | /** 32 | * Empty state. 33 | */ 34 | expectType(null); 35 | expectType>(null); 36 | expectType>( 37 | // @ts-expect-error - Filled fields cannot contain an empty value. 38 | null, 39 | ); 40 | 41 | /** 42 | * Must be in YYYY-MM-DDTHH:MM:SS+ZZZZ format. 43 | */ 44 | expectType( 45 | // @ts-expect-error - Arbitrary strings are invalid. 46 | "1984-01-24", 47 | ); 48 | -------------------------------------------------------------------------------- /test/api-repository.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.Repository): true => { 6 | switch (typeof value) { 7 | case "object": { 8 | if (value === null) { 9 | expectNever(value); 10 | } 11 | 12 | return true; 13 | } 14 | 15 | default: { 16 | return expectNever(value); 17 | } 18 | } 19 | }; 20 | 21 | expectType({ 22 | refs: [ 23 | { 24 | id: "string", 25 | ref: "string", 26 | label: "string", 27 | isMasterRef: true, 28 | scheduledAt: "string", 29 | }, 30 | ], 31 | integrationFieldsRef: "string", 32 | languages: [{ id: "string", name: "string" }], 33 | types: { foo: "string" }, 34 | tags: ["string"], 35 | forms: { 36 | foo: { 37 | method: "GET", 38 | action: "string", 39 | fields: { 40 | foo: { 41 | type: "String", 42 | multiple: true, 43 | default: "string", 44 | }, 45 | }, 46 | enctype: "string", 47 | name: "string", 48 | rel: "string", 49 | }, 50 | }, 51 | oauth_initiate: "string", 52 | oauth_token: "string", 53 | version: "string", 54 | license: "string", 55 | experiments: {}, 56 | bookmarks: { 57 | foo: "string", 58 | }, 59 | }); 60 | -------------------------------------------------------------------------------- /src/model/richText.ts: -------------------------------------------------------------------------------- 1 | import type { CustomTypeModelFieldType } from "./types"; 2 | 3 | /** 4 | * A Rich Text Custom Type field. 5 | * 6 | * More details: {@link https://prismic.io/docs/core-concepts/rich-text-title} 7 | */ 8 | export type CustomTypeModelRichTextField = 9 | | CustomTypeModelRichTextMultiField 10 | | CustomTypeModelRichTextSingleField; 11 | 12 | /** 13 | * A Rich Text Custom Type field which supports multiple blocks of content. 14 | * 15 | * More details: {@link https://prismic.io/docs/core-concepts/rich-text-title} 16 | */ 17 | export interface CustomTypeModelRichTextMultiField { 18 | type: typeof CustomTypeModelFieldType.StructuredText; 19 | config?: { 20 | label?: string | null; 21 | placeholder?: string; 22 | allowTargetBlank?: boolean; 23 | multi?: string; 24 | }; 25 | } 26 | 27 | /** 28 | * A Rich Text Custom Type field which supports one block of content. 29 | * 30 | * More details: {@link https://prismic.io/docs/core-concepts/rich-text-title} 31 | */ 32 | export interface CustomTypeModelRichTextSingleField { 33 | type: typeof CustomTypeModelFieldType.StructuredText; 34 | config?: { 35 | label?: string | null; 36 | placeholder?: string; 37 | allowTargetBlank?: boolean; 38 | single?: string; 39 | }; 40 | } 41 | -------------------------------------------------------------------------------- /test/customType-uid.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicTI from "@prismicio/types-internal"; 4 | 5 | import * as prismicT from "../src"; 6 | 7 | (value: prismicT.CustomTypeModelUIDField): true => { 8 | switch (typeof value) { 9 | case "object": { 10 | if (value === null) { 11 | expectNever(value); 12 | } 13 | 14 | return true; 15 | } 16 | 17 | default: { 18 | return expectNever(value); 19 | } 20 | } 21 | }; 22 | 23 | expectType({ 24 | type: prismicT.CustomTypeModelFieldType.UID, 25 | config: { 26 | label: "string", 27 | }, 28 | }); 29 | 30 | /** 31 | * Supports optional placeholder. 32 | */ 33 | expectType({ 34 | type: prismicT.CustomTypeModelFieldType.UID, 35 | config: { 36 | label: "string", 37 | placeholder: "string", 38 | }, 39 | }); 40 | 41 | /** 42 | * `@prismicio/types` extends `@prismicio/types-internal` 43 | */ 44 | expectType( 45 | {} as prismicTI.CustomTypes.Widgets.UID, 46 | ); 47 | 48 | /** 49 | * `@prismicio/types-internal` extends `@prismicio/types` 50 | */ 51 | expectType( 52 | {} as prismicT.CustomTypeModelUIDField, 53 | ); 54 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Types of changes 4 | 5 | 6 | 7 | - [ ] Chore (a non-breaking change which is related to package maintenance) 8 | - [ ] Bug fix (a non-breaking change which fixes an issue) 9 | - [ ] New feature (a non-breaking change which adds functionality) 10 | - [ ] Breaking change (fix or feature that would cause existing functionality to change) 11 | 12 | ## Description 13 | 14 | 15 | 16 | 17 | 18 | ## Checklist: 19 | 20 | 21 | 22 | 23 | - [ ] My change requires an update to the official documentation. 24 | - [ ] All [TSDoc](https://tsdoc.org) comments are up-to-date and new ones have been added where necessary. 25 | - [ ] All new and existing tests are passing. 26 | 27 | 28 | -------------------------------------------------------------------------------- /test/fields-color.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.ColorField): true => { 6 | switch (typeof value) { 7 | case "string": { 8 | return true; 9 | } 10 | 11 | default: { 12 | if (value === null) { 13 | return true; 14 | } 15 | 16 | return expectNever(value); 17 | } 18 | } 19 | }; 20 | 21 | /** 22 | * Filled state. 23 | */ 24 | expectType("#FF00FF"); 25 | expectType>("#FF00FF"); 26 | expectType>( 27 | // @ts-expect-error - Empty fields cannot contain a filled value. 28 | "#FF00FF", 29 | ); 30 | 31 | /** 32 | * Empty state. 33 | */ 34 | expectType(null); 35 | expectType>(null); 36 | expectType>( 37 | // @ts-expect-error - Filled fields cannot contain an empty value. 38 | null, 39 | ); 40 | 41 | /** 42 | * Must be in hex triplet format. 43 | */ 44 | expectType( 45 | // @ts-expect-error - Arbitrary strings are invalid. 46 | "yellow", 47 | ); 48 | expectType( 49 | // @ts-expect-error - Non-hex-triplet color formats are invalid. 50 | "rgb(255, 0, 255)", 51 | ); 52 | -------------------------------------------------------------------------------- /test/customType-date.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicTI from "@prismicio/types-internal"; 4 | 5 | import * as prismicT from "../src"; 6 | 7 | (value: prismicT.CustomTypeModelDateField): true => { 8 | switch (typeof value) { 9 | case "object": { 10 | if (value === null) { 11 | expectNever(value); 12 | } 13 | 14 | return true; 15 | } 16 | 17 | default: { 18 | return expectNever(value); 19 | } 20 | } 21 | }; 22 | 23 | expectType({ 24 | type: prismicT.CustomTypeModelFieldType.Date, 25 | config: { 26 | label: "string", 27 | }, 28 | }); 29 | 30 | /** 31 | * Supports optional placeholder. 32 | */ 33 | expectType({ 34 | type: prismicT.CustomTypeModelFieldType.Date, 35 | config: { 36 | label: "string", 37 | placeholder: "string", 38 | }, 39 | }); 40 | 41 | /** 42 | * `@prismicio/types` extends `@prismicio/types-internal` 43 | */ 44 | expectType( 45 | {} as prismicTI.CustomTypes.Widgets.Nestable.Date, 46 | ); 47 | 48 | /** 49 | * `@prismicio/types-internal` extends `@prismicio/types` 50 | */ 51 | expectType( 52 | {} as prismicT.CustomTypeModelDateField, 53 | ); 54 | -------------------------------------------------------------------------------- /test/fields-select.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.SelectField): true => { 6 | switch (typeof value) { 7 | case "string": { 8 | return true; 9 | } 10 | 11 | default: { 12 | if (value === null) { 13 | return true; 14 | } 15 | 16 | return expectNever(value); 17 | } 18 | } 19 | }; 20 | 21 | /** 22 | * Filled state. 23 | */ 24 | expectType("foo"); 25 | expectType>("foo"); 26 | expectType>( 27 | // @ts-expect-error - Empty fields cannot contain a filled value. 28 | "foo", 29 | ); 30 | 31 | /** 32 | * Empty state. 33 | */ 34 | expectType(null); 35 | expectType>(null); 36 | expectType>( 37 | // @ts-expect-error - Filled fields cannot contain an empty value. 38 | null, 39 | ); 40 | 41 | /** 42 | * Supports options enum (loosely typed using string union). 43 | */ 44 | (value: prismicT.SelectField<"foo" | "bar", "filled">) => { 45 | switch (value) { 46 | case "foo": 47 | case "bar": { 48 | break; 49 | } 50 | 51 | default: { 52 | expectNever(value); 53 | } 54 | } 55 | }; 56 | -------------------------------------------------------------------------------- /test/customType-color.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicTI from "@prismicio/types-internal"; 4 | 5 | import * as prismicT from "../src"; 6 | 7 | (value: prismicT.CustomTypeModelColorField): true => { 8 | switch (typeof value) { 9 | case "object": { 10 | if (value === null) { 11 | expectNever(value); 12 | } 13 | 14 | return true; 15 | } 16 | 17 | default: { 18 | return expectNever(value); 19 | } 20 | } 21 | }; 22 | 23 | expectType({ 24 | type: prismicT.CustomTypeModelFieldType.Color, 25 | config: { 26 | label: "string", 27 | }, 28 | }); 29 | 30 | /** 31 | * Supports optional placeholder. 32 | */ 33 | expectType({ 34 | type: prismicT.CustomTypeModelFieldType.Color, 35 | config: { 36 | label: "string", 37 | placeholder: "string", 38 | }, 39 | }); 40 | 41 | /** 42 | * `@prismicio/types` extends `@prismicio/types-internal` 43 | */ 44 | expectType( 45 | {} as prismicTI.CustomTypes.Widgets.Nestable.Color, 46 | ); 47 | 48 | /** 49 | * `@prismicio/types-internal` extends `@prismicio/types` 50 | */ 51 | expectType( 52 | {} as prismicT.CustomTypeModelColorField, 53 | ); 54 | -------------------------------------------------------------------------------- /test/customType-embed.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicTI from "@prismicio/types-internal"; 4 | 5 | import * as prismicT from "../src"; 6 | 7 | (value: prismicT.CustomTypeModelEmbedField): true => { 8 | switch (typeof value) { 9 | case "object": { 10 | if (value === null) { 11 | expectNever(value); 12 | } 13 | 14 | return true; 15 | } 16 | 17 | default: { 18 | return expectNever(value); 19 | } 20 | } 21 | }; 22 | 23 | expectType({ 24 | type: prismicT.CustomTypeModelFieldType.Embed, 25 | config: { 26 | label: "string", 27 | }, 28 | }); 29 | 30 | /** 31 | * Supports optional placeholder 32 | */ 33 | expectType({ 34 | type: prismicT.CustomTypeModelFieldType.Embed, 35 | config: { 36 | label: "string", 37 | placeholder: "string", 38 | }, 39 | }); 40 | 41 | /** 42 | * `@prismicio/types` extends `@prismicio/types-internal` 43 | */ 44 | expectType( 45 | {} as prismicTI.CustomTypes.Widgets.Nestable.Embed, 46 | ); 47 | 48 | /** 49 | * `@prismicio/types-internal` extends `@prismicio/types` 50 | */ 51 | expectType( 52 | {} as prismicT.CustomTypeModelEmbedField, 53 | ); 54 | -------------------------------------------------------------------------------- /test/customType-keyText.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicTI from "@prismicio/types-internal"; 4 | 5 | import * as prismicT from "../src"; 6 | 7 | (value: prismicT.CustomTypeModelKeyTextField): true => { 8 | switch (typeof value) { 9 | case "object": { 10 | if (value === null) { 11 | expectNever(value); 12 | } 13 | 14 | return true; 15 | } 16 | 17 | default: { 18 | return expectNever(value); 19 | } 20 | } 21 | }; 22 | 23 | expectType({ 24 | type: prismicT.CustomTypeModelFieldType.Text, 25 | config: { 26 | label: "string", 27 | }, 28 | }); 29 | 30 | /** 31 | * Supports optional placeholder. 32 | */ 33 | expectType({ 34 | type: prismicT.CustomTypeModelFieldType.Text, 35 | config: { 36 | label: "string", 37 | placeholder: "string", 38 | }, 39 | }); 40 | 41 | /** 42 | * `@prismicio/types` extends `@prismicio/types-internal` 43 | */ 44 | expectType( 45 | {} as prismicTI.CustomTypes.Widgets.Nestable.Text, 46 | ); 47 | 48 | /** 49 | * `@prismicio/types-internal` extends `@prismicio/types` 50 | */ 51 | expectType( 52 | {} as prismicT.CustomTypeModelKeyTextField, 53 | ); 54 | -------------------------------------------------------------------------------- /test/customType-number.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicTI from "@prismicio/types-internal"; 4 | 5 | import * as prismicT from "../src"; 6 | 7 | (value: prismicT.CustomTypeModelNumberField): true => { 8 | switch (typeof value) { 9 | case "object": { 10 | if (value === null) { 11 | expectNever(value); 12 | } 13 | 14 | return true; 15 | } 16 | 17 | default: { 18 | return expectNever(value); 19 | } 20 | } 21 | }; 22 | 23 | expectType({ 24 | type: prismicT.CustomTypeModelFieldType.Number, 25 | config: { 26 | label: "string", 27 | }, 28 | }); 29 | 30 | /** 31 | * Supports optional placeholder. 32 | */ 33 | expectType({ 34 | type: prismicT.CustomTypeModelFieldType.Number, 35 | config: { 36 | label: "string", 37 | placeholder: "string", 38 | }, 39 | }); 40 | 41 | /** 42 | * `@prismicio/types` extends `@prismicio/types-internal` 43 | */ 44 | expectType( 45 | {} as prismicTI.CustomTypes.Widgets.Nestable.Number, 46 | ); 47 | 48 | /** 49 | * `@prismicio/types-internal` extends `@prismicio/types` 50 | */ 51 | expectType( 52 | {} as prismicT.CustomTypeModelNumberField, 53 | ); 54 | -------------------------------------------------------------------------------- /test/customType-timestamp.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicTI from "@prismicio/types-internal"; 4 | 5 | import * as prismicT from "../src"; 6 | 7 | (value: prismicT.CustomTypeModelTimestampField): true => { 8 | switch (typeof value) { 9 | case "object": { 10 | if (value === null) { 11 | expectNever(value); 12 | } 13 | 14 | return true; 15 | } 16 | 17 | default: { 18 | return expectNever(value); 19 | } 20 | } 21 | }; 22 | 23 | expectType({ 24 | type: prismicT.CustomTypeModelFieldType.Timestamp, 25 | config: { 26 | label: "string", 27 | }, 28 | }); 29 | 30 | /** 31 | * Supports optional placeholder. 32 | */ 33 | expectType({ 34 | type: prismicT.CustomTypeModelFieldType.Timestamp, 35 | config: { 36 | label: "string", 37 | placeholder: "string", 38 | }, 39 | }); 40 | 41 | /** 42 | * `@prismicio/types` extends `@prismicio/types-internal` 43 | */ 44 | expectType( 45 | {} as prismicTI.CustomTypes.Widgets.Nestable.Timestamp, 46 | ); 47 | 48 | /** 49 | * `@prismicio/types-internal` extends `@prismicio/types` 50 | */ 51 | expectType( 52 | {} as prismicT.CustomTypeModelTimestampField, 53 | ); 54 | -------------------------------------------------------------------------------- /src/api/query.ts: -------------------------------------------------------------------------------- 1 | import { PrismicDocument } from "../value/document"; 2 | 3 | /** 4 | * A query response from the Prismic REST API V2. The response contains 5 | * paginated metadata and a list of matching results for the query. 6 | * 7 | * @typeParam Document - The type(s) of Prismic document that can be returned. 8 | * @see More details on querying: {@link https://prismic.io/docs/technologies/introduction-to-the-content-query-api} 9 | */ 10 | export interface Query { 11 | /** 12 | * The page number for this page of results. 13 | */ 14 | page: number; 15 | 16 | /** 17 | * Maximum number of results per page. 18 | */ 19 | results_per_page: number; 20 | 21 | /** 22 | * Number of results in this page. 23 | */ 24 | results_size: number; 25 | 26 | /** 27 | * Total number of results within all pages. 28 | */ 29 | total_results_size: number; 30 | 31 | /** 32 | * Total number of pages. 33 | */ 34 | total_pages: number; 35 | 36 | /** 37 | * The Prismic REST API V2 URL to the next page, if one exists. 38 | */ 39 | next_page: string | null; 40 | 41 | /** 42 | * The Prismic REST API V2 URL to the previous page, if one exists. 43 | */ 44 | prev_page: string | null; 45 | 46 | /** 47 | * A paginated list of documents matching the query. 48 | */ 49 | results: Document[]; 50 | } 51 | -------------------------------------------------------------------------------- /test/customType-title.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicTI from "@prismicio/types-internal"; 4 | 5 | import * as prismicT from "../src"; 6 | 7 | (value: prismicT.CustomTypeModelTitleField): true => { 8 | switch (typeof value) { 9 | case "object": { 10 | if (value === null) { 11 | expectNever(value); 12 | } 13 | 14 | return true; 15 | } 16 | 17 | default: { 18 | return expectNever(value); 19 | } 20 | } 21 | }; 22 | 23 | expectType({ 24 | type: prismicT.CustomTypeModelFieldType.StructuredText, 25 | config: { 26 | label: "string", 27 | single: "string", 28 | }, 29 | }); 30 | 31 | /** 32 | * Supports optional placeholder. 33 | */ 34 | expectType({ 35 | type: prismicT.CustomTypeModelFieldType.StructuredText, 36 | config: { 37 | label: "string", 38 | placeholder: "string", 39 | single: "string", 40 | }, 41 | }); 42 | 43 | /** 44 | * `@prismicio/types` extends `@prismicio/types-internal` 45 | */ 46 | expectType( 47 | {} as prismicTI.CustomTypes.Widgets.Nestable.RichText, 48 | ); 49 | 50 | /** 51 | * `@prismicio/types-internal` extends `@prismicio/types` 52 | */ 53 | expectType( 54 | {} as prismicT.CustomTypeModelTitleField, 55 | ); 56 | -------------------------------------------------------------------------------- /.github/workflows/issues--bug_report.md: -------------------------------------------------------------------------------- 1 | > This issue has been labeled as a **bug** since it was created using the [🚨 **Bug Report Template**](./new?assignees=&labels=bug&template=bug_report.md&title=). 2 | 3 | Hi there, thank you so much for the report! 4 | 5 | Following our [Maintenance Process](../blob/HEAD/CONTRIBUTING.md#maintaining), we will review your bug report and get back to you _next Wednesday_. To ensure a smooth review of your issue and avoid unnecessary delays, please make sure your issue includes the following: 6 | 7 | - Information about your environment and packages you use (Node.js version, package names and their versions, etc.) 8 | _Feel free to attach a copy of your `package.json` file._ 9 | - Any troubleshooting steps you already went through 10 | - A minimal reproduction of the issue, and/or instructions on how to reproduce it 11 | 12 | If you have identified the cause of the bug described in your report and know how to fix it, you're more than welcome to [open a pull request](../pulls) addressing it. Check out our [quick start guide](../blob/HEAD/CONTRIBUTING.md#quick-start) for a simple contribution process. 13 | 14 | If you think your issue is a _question_ (not a bug) and would like quicker support, please _close this issue_ and forward it to an appropriate section on our community forum: https://community.prismic.io 15 | 16 | _- The Prismic Open-Source Team_ 17 | -------------------------------------------------------------------------------- /test/customType-boolean.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicTI from "@prismicio/types-internal"; 4 | 5 | import * as prismicT from "../src"; 6 | 7 | (value: prismicT.CustomTypeModelBooleanField): true => { 8 | switch (typeof value) { 9 | case "object": { 10 | if (value === null) { 11 | expectNever(value); 12 | } 13 | 14 | return true; 15 | } 16 | 17 | default: { 18 | return expectNever(value); 19 | } 20 | } 21 | }; 22 | 23 | expectType({ 24 | type: prismicT.CustomTypeModelFieldType.Boolean, 25 | config: { 26 | label: "string", 27 | }, 28 | }); 29 | 30 | /** 31 | * Does not support a placeholder. 32 | */ 33 | expectType({ 34 | type: prismicT.CustomTypeModelFieldType.Boolean, 35 | config: { 36 | label: "string", 37 | // @ts-expect-error - Does not support a placeholder. 38 | placeholder: "string", 39 | }, 40 | }); 41 | 42 | /** 43 | * `@prismicio/types` extends `@prismicio/types-internal` 44 | */ 45 | expectType( 46 | {} as prismicTI.CustomTypes.Widgets.Nestable.BooleanField, 47 | ); 48 | 49 | /** 50 | * `@prismicio/types-internal` extends `@prismicio/types` 51 | */ 52 | expectType( 53 | {} as prismicT.CustomTypeModelBooleanField, 54 | ); 55 | -------------------------------------------------------------------------------- /test/customType-geoPoint.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicTI from "@prismicio/types-internal"; 4 | 5 | import * as prismicT from "../src"; 6 | 7 | (value: prismicT.CustomTypeModelGeoPointField): true => { 8 | switch (typeof value) { 9 | case "object": { 10 | if (value === null) { 11 | expectNever(value); 12 | } 13 | 14 | return true; 15 | } 16 | 17 | default: { 18 | return expectNever(value); 19 | } 20 | } 21 | }; 22 | 23 | expectType({ 24 | type: prismicT.CustomTypeModelFieldType.GeoPoint, 25 | config: { 26 | label: "string", 27 | }, 28 | }); 29 | 30 | /** 31 | * Does not support a placeholder. 32 | */ 33 | expectType({ 34 | type: prismicT.CustomTypeModelFieldType.GeoPoint, 35 | config: { 36 | label: "string", 37 | // @ts-expect-error - Does not support a placeholder. 38 | placeholder: "string", 39 | }, 40 | }); 41 | 42 | /** 43 | * `@prismicio/types` extends `@prismicio/types-internal` 44 | */ 45 | expectType( 46 | {} as prismicTI.CustomTypes.Widgets.Nestable.GeoPoint, 47 | ); 48 | 49 | /** 50 | * `@prismicio/types-internal` extends `@prismicio/types` 51 | */ 52 | expectType( 53 | {} as prismicT.CustomTypeModelGeoPointField, 54 | ); 55 | -------------------------------------------------------------------------------- /test/customType-integration.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicTI from "@prismicio/types-internal"; 4 | 5 | import * as prismicT from "../src"; 6 | 7 | (value: prismicT.CustomTypeModelIntegrationField): true => { 8 | switch (typeof value) { 9 | case "object": { 10 | if (value === null) { 11 | expectNever(value); 12 | } 13 | 14 | return true; 15 | } 16 | 17 | default: { 18 | return expectNever(value); 19 | } 20 | } 21 | }; 22 | 23 | expectType({ 24 | type: prismicT.CustomTypeModelFieldType.Integration, 25 | config: { 26 | label: "string", 27 | catalog: "string", 28 | }, 29 | }); 30 | 31 | /** 32 | * Supports optional placeholder. 33 | */ 34 | expectType({ 35 | type: prismicT.CustomTypeModelFieldType.Integration, 36 | config: { 37 | label: "string", 38 | placeholder: "string", 39 | catalog: "string", 40 | }, 41 | }); 42 | 43 | /** 44 | * `@prismicio/types` extends `@prismicio/types-internal` 45 | */ 46 | expectType( 47 | {} as prismicTI.CustomTypes.Widgets.Nestable.IntegrationField, 48 | ); 49 | 50 | /** 51 | * `@prismicio/types-internal` extends `@prismicio/types` 52 | */ 53 | expectType( 54 | {} as prismicT.CustomTypeModelIntegrationField, 55 | ); 56 | -------------------------------------------------------------------------------- /test/fields-integration.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.IntegrationField): true => { 6 | switch (typeof value) { 7 | case "object": { 8 | if (value === null) { 9 | return true; 10 | } 11 | 12 | return true; 13 | } 14 | 15 | default: { 16 | return expectNever(value); 17 | } 18 | } 19 | }; 20 | 21 | /** 22 | * Filled state. 23 | */ 24 | expectType({ 25 | foo: "bar", 26 | }); 27 | expectType, "filled">>({ 28 | foo: "bar", 29 | }); 30 | expectType, "empty">>( 31 | // @ts-expect-error - Empty fields cannot contain a filled value. 32 | { 33 | foo: "bar", 34 | }, 35 | ); 36 | 37 | /** 38 | * Empty state. 39 | */ 40 | expectType(null); 41 | expectType, "empty">>(null); 42 | expectType, "filled">>( 43 | // @ts-expect-error - Filled fields cannot contain an empty value. 44 | null, 45 | ); 46 | 47 | /** 48 | * Supports custom blob type. 49 | */ 50 | expectType>({ 51 | foo: "bar", 52 | }); 53 | expectType>({ 54 | // @ts-expect-error - Blob should match the given type. 55 | baz: "qux", 56 | }); 57 | -------------------------------------------------------------------------------- /test/document-alternativeLanguage.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.AlternateLanguage): true => { 6 | switch (typeof value) { 7 | case "object": { 8 | if (value === null) { 9 | expectNever(value); 10 | } 11 | 12 | return true; 13 | } 14 | 15 | default: { 16 | return expectNever(value); 17 | } 18 | } 19 | }; 20 | 21 | expectType({ 22 | id: "string", 23 | uid: "string", 24 | type: "string", 25 | lang: "string", 26 | }); 27 | 28 | /** 29 | * Supports optional UID. 30 | */ 31 | expectType({ 32 | id: "string", 33 | type: "string", 34 | lang: "string", 35 | }); 36 | 37 | /** 38 | * Supports custom type. 39 | */ 40 | expectType>({ 41 | id: "string", 42 | type: "foo", 43 | lang: "string", 44 | }); 45 | expectType>({ 46 | id: "string", 47 | // @ts-expect-error - Document type must match the given type. 48 | type: "string", 49 | lang: "string", 50 | }); 51 | 52 | /** 53 | * Supports custom language. 54 | */ 55 | expectType>({ 56 | id: "string", 57 | type: "string", 58 | lang: "fr-fr", 59 | }); 60 | expectType>({ 61 | id: "string", 62 | type: "string", 63 | // @ts-expect-error - Document lang must match the given language. 64 | lang: "string", 65 | }); 66 | -------------------------------------------------------------------------------- /src/value/contentRelationship.ts: -------------------------------------------------------------------------------- 1 | import type { AnyRegularField, FieldState } from "./types"; 2 | import type { EmptyLinkField, LinkType } from "./link"; 3 | import type { GroupField } from "./group"; 4 | import type { SliceZone } from "./sliceZone"; 5 | 6 | /** 7 | * Field for related documents 8 | * 9 | * @typeParam TypeEnum - Type API ID of the document. 10 | * @typeParam LangEnum - Language API ID of the document. 11 | * @typeParam DataInterface - Data fields for the document (filled in via 12 | * GraphQuery of `fetchLinks`). 13 | * @typeParam State - State of the field which determines its shape. 14 | */ 15 | export type ContentRelationshipField< 16 | TypeEnum = string, 17 | LangEnum = string, 18 | DataInterface extends 19 | | Record 20 | | unknown = unknown, 21 | State extends FieldState = FieldState, 22 | > = State extends "empty" 23 | ? EmptyLinkField 24 | : FilledContentRelationshipField; 25 | 26 | /** 27 | * Links that refer to Documents 28 | */ 29 | export interface FilledContentRelationshipField< 30 | TypeEnum = string, 31 | LangEnum = string, 32 | DataInterface extends 33 | | Record 34 | | unknown = unknown, 35 | > { 36 | link_type: typeof LinkType.Document; 37 | id: string; 38 | uid?: string; 39 | type: TypeEnum; 40 | tags: string[]; 41 | lang: LangEnum; 42 | url?: string; 43 | slug?: string; 44 | isBroken?: boolean; 45 | data?: DataInterface; 46 | } 47 | -------------------------------------------------------------------------------- /src/model/slice.ts: -------------------------------------------------------------------------------- 1 | import type { CustomTypeModelGroupField } from "./group"; 2 | import type { CustomTypeModelSliceType } from "./sliceZone"; 3 | import type { CustomTypeModelFieldForGroup } from "./types"; 4 | 5 | /** 6 | * A Slice for a Custom Type. 7 | * 8 | * More details: {@link https://prismic.io/docs/core-concepts/slices} 9 | * 10 | * @typeParam NonRepeatFields - A record of fields that cannnot be repeated. 11 | * @typeParam RepeatFields - A record of fields that can be repeated. 12 | */ 13 | export interface CustomTypeModelSlice< 14 | NonRepeatFields extends Record = Record< 15 | string, 16 | CustomTypeModelFieldForGroup 17 | >, 18 | RepeatFields extends Record = Record< 19 | string, 20 | CustomTypeModelFieldForGroup 21 | >, 22 | > { 23 | type: typeof CustomTypeModelSliceType.Slice; 24 | fieldset?: string | null; 25 | description?: string; 26 | icon?: string; 27 | display?: 28 | | typeof CustomTypeModelSliceDisplay[keyof typeof CustomTypeModelSliceDisplay] 29 | | string; 30 | "non-repeat"?: NonRepeatFields; 31 | repeat?: RepeatFields; 32 | } 33 | 34 | /** 35 | * Display type for a Slice. 36 | * 37 | * More details: {@link https://prismic.io/docs/core-concepts/slices} 38 | */ 39 | export const CustomTypeModelSliceDisplay = { 40 | List: "list", 41 | Grid: "grid", 42 | } as const; 43 | 44 | /** 45 | * @deprecated - Legacy slice type. Do not use. 46 | */ 47 | export type CustomTypeModelLegacySlice = 48 | | CustomTypeModelGroupField 49 | | CustomTypeModelFieldForGroup; 50 | -------------------------------------------------------------------------------- /test/customType-linkToMedia.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicTI from "@prismicio/types-internal"; 4 | 5 | import * as prismicT from "../src"; 6 | 7 | (value: prismicT.CustomTypeModelLinkToMediaField): true => { 8 | switch (typeof value) { 9 | case "object": { 10 | if (value === null) { 11 | expectNever(value); 12 | } 13 | 14 | return true; 15 | } 16 | 17 | default: { 18 | return expectNever(value); 19 | } 20 | } 21 | }; 22 | 23 | expectType({ 24 | type: prismicT.CustomTypeModelFieldType.Link, 25 | config: { 26 | label: "string", 27 | select: prismicT.CustomTypeModelLinkSelectType.Media, 28 | }, 29 | }); 30 | 31 | /** 32 | * Supports optional placeholder. 33 | */ 34 | expectType({ 35 | type: prismicT.CustomTypeModelFieldType.Link, 36 | config: { 37 | label: "string", 38 | placeholder: "string", 39 | select: prismicT.CustomTypeModelLinkSelectType.Media, 40 | }, 41 | }); 42 | 43 | /** 44 | * `@prismicio/types` extends `@prismicio/types-internal` 45 | */ 46 | expectType( 47 | {} as prismicTI.CustomTypes.Widgets.Nestable.Link & { 48 | // We must manually narrow `@prismicio/types-internal`'s type 49 | // to match a Link to Media field; `@prismicio/types-internal` 50 | // does not contain a Link to Media-specific type. 51 | config?: { select: "media" }; 52 | }, 53 | ); 54 | 55 | /** 56 | * `@prismicio/types-internal` extends `@prismicio/types` 57 | */ 58 | expectType( 59 | {} as prismicT.CustomTypeModelLinkToMediaField, 60 | ); 61 | -------------------------------------------------------------------------------- /src/webhook/apiUpdate.ts: -------------------------------------------------------------------------------- 1 | import { WebhookBodyBase, WebhookType } from "./types"; 2 | 3 | /** 4 | * Webhook payload sent when a Prismic repository content is updated. 5 | * 6 | * @see More details: {@link https://prismic.io/docs/core-concepts/webhooks} 7 | */ 8 | export interface WebhookBodyAPIUpdate extends WebhookBodyBase { 9 | type: typeof WebhookType.APIUpdate; 10 | masterRef?: string; 11 | releases: WebhookBodyAPIUpdateOperations; 12 | masks: WebhookBodyAPIUpdateOperations; 13 | tags: WebhookBodyAPIUpdateOperations; 14 | documents: string[]; 15 | /** 16 | * @deprecated Experiments are no longer supported by Prismic. 17 | */ 18 | experiments?: WebhookBodyAPIUpdateOperations; 19 | } 20 | 21 | interface WebhookBodyAPIUpdateOperations { 22 | update?: T[]; 23 | addition?: T[]; 24 | deletion?: T[]; 25 | } 26 | 27 | /** 28 | * Metadata representing a mask (also called a Custom Type). 29 | * 30 | * @see More details: {@link https://prismic.io/docs/core-concepts/custom-types} 31 | */ 32 | interface WebhookBodyAPIUpdateMask { 33 | id: string; 34 | label: string; 35 | } 36 | 37 | /** 38 | * Metadata representing a tag. 39 | * 40 | * @see More details: {@link https://prismic.io/docs/core-concepts/document-tags} 41 | */ 42 | interface WebhookBodyAPIUpdateTag { 43 | id: string; 44 | } 45 | 46 | /** 47 | * Metadata representing a Release. 48 | * 49 | * @see More details: {@link https://prismic.io/docs/core-concepts/draft-plan-and-schedule-content#releases} 50 | */ 51 | interface WebhookBodyAPIUpdateRelease { 52 | id: string; 53 | ref: string; 54 | label: string; 55 | documents: string[]; 56 | } 57 | -------------------------------------------------------------------------------- /test/fields-sharedSlice.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.SharedSlice): true => { 6 | switch (typeof value) { 7 | case "object": { 8 | if (value === null) { 9 | expectNever(value); 10 | } 11 | 12 | return true; 13 | } 14 | 15 | default: { 16 | return expectNever(value); 17 | } 18 | } 19 | }; 20 | 21 | expectType({ 22 | slice_type: "string", 23 | slice_label: null, 24 | variation: "string", 25 | version: "string", 26 | primary: {}, 27 | items: [], 28 | }); 29 | 30 | /** 31 | * Supports custom Shared Slice type API ID. 32 | */ 33 | expectType>({ 34 | slice_type: "foo", 35 | slice_label: null, 36 | variation: "string", 37 | version: "string", 38 | primary: {}, 39 | items: [], 40 | }); 41 | expectType>({ 42 | // @ts-expect-error - Slice type must match the given type. 43 | slice_type: "string", 44 | slice_label: null, 45 | variation: "string", 46 | version: "string", 47 | primary: {}, 48 | items: [], 49 | }); 50 | 51 | /** 52 | * Supports custom variation types. 53 | */ 54 | expectType>>({ 55 | slice_type: "string", 56 | slice_label: null, 57 | variation: "foo", 58 | version: "string", 59 | primary: {}, 60 | items: [], 61 | }); 62 | expectType>>({ 63 | slice_type: "string", 64 | slice_label: null, 65 | // @ts-expect-error - Variation type must match the given type. 66 | variation: "string", 67 | version: "string", 68 | primary: {}, 69 | items: [], 70 | }); 71 | -------------------------------------------------------------------------------- /test/fields-linkToMedia.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.LinkToMediaField): true => { 6 | switch (typeof value) { 7 | case "object": { 8 | if (value === null) { 9 | return expectNever(value); 10 | } 11 | 12 | return true; 13 | } 14 | 15 | default: { 16 | return expectNever(value); 17 | } 18 | } 19 | }; 20 | 21 | /** 22 | * Filled state. 23 | */ 24 | expectType({ 25 | link_type: prismicT.LinkType.Media, 26 | id: "string", 27 | name: "string", 28 | kind: "string", 29 | url: "string", 30 | size: "string", 31 | height: "string", 32 | width: "string", 33 | }); 34 | expectType>({ 35 | link_type: prismicT.LinkType.Media, 36 | id: "string", 37 | name: "string", 38 | kind: "string", 39 | url: "string", 40 | size: "string", 41 | height: "string", 42 | width: "string", 43 | }); 44 | expectType>({ 45 | link_type: prismicT.LinkType.Media, 46 | // @ts-expect-error - Empty fields cannot contain a filled value. 47 | id: "string", 48 | name: "string", 49 | kind: "string", 50 | url: "string", 51 | size: "string", 52 | height: "string", 53 | width: "string", 54 | }); 55 | 56 | /** 57 | * Empty state. 58 | */ 59 | expectType({ 60 | link_type: prismicT.LinkType.Media, 61 | }); 62 | expectType>({ 63 | link_type: prismicT.LinkType.Media, 64 | }); 65 | expectType>( 66 | // @ts-expect-error - Filled fields cannot contain an empty value. 67 | { 68 | link_type: prismicT.LinkType.Media, 69 | }, 70 | ); 71 | -------------------------------------------------------------------------------- /src/model/sliceZone.ts: -------------------------------------------------------------------------------- 1 | import type { CustomTypeModelFieldType } from "./types"; 2 | import type { CustomTypeModelLegacySlice, CustomTypeModelSlice } from "./slice"; 3 | 4 | /** 5 | * A Slice Zone Custom Type field. 6 | * 7 | * More details: {@link https://prismic.io/docs/core-concepts/slices} 8 | */ 9 | export interface CustomTypeModelSliceZoneField< 10 | Slices extends Record< 11 | string, 12 | | CustomTypeModelSlice 13 | | CustomTypeModelSharedSlice 14 | | CustomTypeModelLegacySlice 15 | > = Record< 16 | string, 17 | | CustomTypeModelSlice 18 | | CustomTypeModelSharedSlice 19 | | CustomTypeModelLegacySlice 20 | >, 21 | > { 22 | type: 23 | | typeof CustomTypeModelFieldType.Slices 24 | | typeof CustomTypeModelFieldType.LegacySlices; 25 | fieldset?: string | null; 26 | config?: { 27 | labels?: Record | null; 28 | choices?: Slices; 29 | }; 30 | } 31 | 32 | /** 33 | * Label for a Slice. 34 | * 35 | * More details: {@link https://prismic.io/docs/core-concepts/slices} 36 | */ 37 | export interface CustomTypeModelSliceLabel { 38 | name: string; 39 | display?: string; 40 | } 41 | 42 | /** 43 | * Type identifier for a Slice. 44 | * 45 | * More details: {@link https://prismic.io/docs/core-concepts/slices} 46 | */ 47 | export const CustomTypeModelSliceType = { 48 | Slice: "Slice", 49 | SharedSlice: "SharedSlice", 50 | } as const; 51 | 52 | /** 53 | * A Shared Slice for a Custom Type. 54 | * 55 | * More details: 56 | * 57 | * - {@link https://prismic.io/docs/core-concepts/slices} 58 | * - {@link https://prismic.io/docs/core-concepts/reusing-slices} 59 | */ 60 | export interface CustomTypeModelSharedSlice { 61 | type: typeof CustomTypeModelSliceType.SharedSlice; 62 | } 63 | -------------------------------------------------------------------------------- /src/model/customType.ts: -------------------------------------------------------------------------------- 1 | import { CustomTypeModelField } from "./types"; 2 | 3 | /** 4 | * A Prismic Custom Type model. 5 | * 6 | * @typeParam ID - API ID of the Custom Type. 7 | * @typeParam Definition - The Custom Type's tabs and their fields. 8 | */ 9 | export interface CustomTypeModel< 10 | ID extends string = string, 11 | Definition extends CustomTypeModelDefinition = CustomTypeModelDefinition, 12 | > { 13 | /** 14 | * The ID of the Custom Type model. 15 | */ 16 | id: ID; 17 | 18 | /** 19 | * The human readable name of the Custom Type Model. 20 | */ 21 | // TODO: Revert to `label?: string | null` if `label` can be partial in: https://github.com/prismicio/prismic-types-internal/blob/HEAD/src/customtypes/CustomType.ts#L39 22 | label: string | null | undefined; 23 | 24 | /** 25 | * Determines if more than one document for the Custom Type can be created. 26 | */ 27 | repeatable: boolean; 28 | 29 | /** 30 | * The Custom Type model definition. 31 | */ 32 | json: Definition; 33 | 34 | /** 35 | * Determines if new documents for the Custom Type can be created. 36 | */ 37 | status: boolean; 38 | } 39 | 40 | /** 41 | * A Prismic Custom Type's tabs and their fields. 42 | * 43 | * @typeParam TabName - Names of Custom Type tabs. 44 | */ 45 | export type CustomTypeModelDefinition = Record< 46 | TabName, 47 | CustomTypeModelTab 48 | >; 49 | 50 | /** 51 | * A Custom Type's tab. Each tab can contain any number of fields but is limited 52 | * to one Slice Zone. 53 | * 54 | * @typeParam FieldName - API IDs of the fields. 55 | */ 56 | export type CustomTypeModelTab< 57 | Fields extends Record = Record< 58 | string, 59 | CustomTypeModelField 60 | >, 61 | > = Fields; 62 | -------------------------------------------------------------------------------- /src/value/link.ts: -------------------------------------------------------------------------------- 1 | import type { FieldState, AnyRegularField } from "./types"; 2 | import type { GroupField } from "./group"; 3 | import type { SliceZone } from "./sliceZone"; 4 | import type { ContentRelationshipField } from "./contentRelationship"; 5 | import type { LinkToMediaField } from "./linkToMedia"; 6 | 7 | /** 8 | * Link Types 9 | */ 10 | export const LinkType = { 11 | Any: "Any", 12 | Document: "Document", 13 | Media: "Media", 14 | Web: "Web", 15 | } as const; 16 | 17 | /** 18 | * For link fields that haven't been filled 19 | * 20 | * @typeParam Type - The type of link. 21 | */ 22 | export type EmptyLinkField< 23 | Type extends typeof LinkType[keyof typeof LinkType] = typeof LinkType.Any, 24 | > = { 25 | link_type: Type | string; 26 | }; 27 | 28 | /** 29 | * Link that points to external website 30 | */ 31 | export interface FilledLinkToWebField { 32 | link_type: typeof LinkType.Web; 33 | url: string; 34 | target?: string; 35 | } 36 | 37 | /** 38 | * Link Field 39 | * 40 | * @typeParam TypeEnum - Type API ID of the document. 41 | * @typeParam LangEnum - Language API ID of the document. 42 | * @typeParam DataInterface - Data fields for the document (filled in via 43 | * GraphQuery of `fetchLinks`). 44 | * @typeParam State - State of the field which determines its shape. 45 | */ 46 | export type LinkField< 47 | TypeEnum = string, 48 | LangEnum = string, 49 | DataInterface extends 50 | | Record 51 | | unknown = unknown, 52 | State extends FieldState = FieldState, 53 | > = State extends "empty" 54 | ? EmptyLinkField 55 | : 56 | | ContentRelationshipField 57 | | FilledLinkToWebField 58 | | LinkToMediaField; 59 | -------------------------------------------------------------------------------- /test/customType-link.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicTI from "@prismicio/types-internal"; 4 | 5 | import * as prismicT from "../src"; 6 | 7 | (value: prismicT.CustomTypeModelLinkField): true => { 8 | switch (typeof value) { 9 | case "object": { 10 | if (value === null) { 11 | expectNever(value); 12 | } 13 | 14 | return true; 15 | } 16 | 17 | default: { 18 | return expectNever(value); 19 | } 20 | } 21 | }; 22 | 23 | expectType({ 24 | type: prismicT.CustomTypeModelFieldType.Link, 25 | config: { 26 | label: "string", 27 | }, 28 | }); 29 | 30 | /** 31 | * Supports optional placeholder. 32 | */ 33 | expectType({ 34 | type: prismicT.CustomTypeModelFieldType.Link, 35 | config: { 36 | label: "string", 37 | placeholder: "string", 38 | }, 39 | }); 40 | 41 | /** 42 | * Supports optional null `select` option. 43 | */ 44 | expectType({ 45 | type: prismicT.CustomTypeModelFieldType.Link, 46 | config: { 47 | label: "string", 48 | select: null, 49 | }, 50 | }); 51 | 52 | /** 53 | * Supports optional allowTargetBlank. 54 | */ 55 | expectType({ 56 | type: prismicT.CustomTypeModelFieldType.Link, 57 | config: { 58 | label: "string", 59 | allowTargetBlank: true, 60 | }, 61 | }); 62 | 63 | /** 64 | * `@prismicio/types` extends `@prismicio/types-internal` 65 | */ 66 | expectType( 67 | {} as prismicTI.CustomTypes.Widgets.Nestable.Link, 68 | ); 69 | 70 | /** 71 | * `@prismicio/types-internal` extends `@prismicio/types` 72 | */ 73 | expectType( 74 | {} as prismicT.CustomTypeModelLinkField, 75 | ); 76 | -------------------------------------------------------------------------------- /test/fields-sharedSliceVariation.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.SharedSliceVariation): true => { 6 | switch (typeof value) { 7 | case "object": { 8 | if (value === null) { 9 | expectNever(value); 10 | } 11 | 12 | return true; 13 | } 14 | 15 | default: { 16 | return expectNever(value); 17 | } 18 | } 19 | }; 20 | 21 | expectType({ 22 | variation: "string", 23 | version: "string", 24 | primary: {}, 25 | items: [], 26 | }); 27 | 28 | /** 29 | * Supports custom API ID. 30 | */ 31 | expectType>({ 32 | variation: "foo", 33 | version: "string", 34 | primary: {}, 35 | items: [], 36 | }); 37 | expectType>({ 38 | // @ts-expect-error - Variation type must match the given type. 39 | variation: "string", 40 | version: "string", 41 | primary: {}, 42 | items: [], 43 | }); 44 | 45 | /** 46 | * Supports custom primary fields type. 47 | */ 48 | expectType< 49 | prismicT.SharedSliceVariation 50 | >({ 51 | variation: "string", 52 | version: "string", 53 | primary: { 54 | foo: true, 55 | // @ts-expect-error - Only given fields are valid. 56 | bar: false, 57 | }, 58 | items: [], 59 | }); 60 | 61 | /** 62 | * Supports custom items fields type. 63 | */ 64 | expectType< 65 | prismicT.SharedSliceVariation< 66 | string, 67 | { foo: prismicT.BooleanField }, 68 | { bar: prismicT.KeyTextField } 69 | > 70 | >({ 71 | variation: "string", 72 | version: "string", 73 | primary: { 74 | foo: true, 75 | }, 76 | items: [ 77 | { 78 | bar: "string", 79 | // @ts-expect-error - Only given fields are valid. 80 | baz: false, 81 | }, 82 | ], 83 | }); 84 | -------------------------------------------------------------------------------- /test/fields-group.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.GroupField): true => { 6 | if (!Array.isArray(value)) { 7 | return expectNever(value); 8 | } 9 | 10 | switch (typeof value[0]) { 11 | case "object": { 12 | if (value[0] === null) { 13 | expectNever(value[0]); 14 | } 15 | 16 | return true; 17 | } 18 | 19 | // When the field is empty, value[0] is undefined. 20 | case "undefined": { 21 | return true; 22 | } 23 | 24 | default: { 25 | return expectNever(value[0]); 26 | } 27 | } 28 | }; 29 | 30 | /** 31 | * Filled state. It does not use FieldState like other fields; an array with 32 | * elements implicity signals a filled state. 33 | */ 34 | expectType([ 35 | { 36 | boolean: true, 37 | }, 38 | ]); 39 | 40 | /** 41 | * Empty state. It does not use FieldState like other fields; an empty array 42 | * implicity signals an empty state. 43 | */ 44 | expectType([]); 45 | 46 | /** 47 | * Supports custom fields definition. 48 | */ 49 | expectType>([ 50 | { 51 | boolean: true, 52 | }, 53 | ]); 54 | expectType>([ 55 | { 56 | // @ts-expect-error - Fields must match the given type definition. 57 | boolean: "string", 58 | }, 59 | ]); 60 | 61 | /** 62 | * Custom fields may only contain group-compatible fields. 63 | */ 64 | expectType< 65 | prismicT.GroupField 69 | >([]); 70 | expectType< 71 | prismicT.GroupField 75 | >([]); 76 | -------------------------------------------------------------------------------- /test/fields.types.ts: -------------------------------------------------------------------------------- 1 | import { expectNever, expectType, TypeOf } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | /** 6 | * FieldState 7 | */ 8 | (value: prismicT.FieldState): true => { 9 | switch (value) { 10 | case "filled": 11 | case "empty": { 12 | return true; 13 | } 14 | 15 | default: { 16 | return expectNever(value); 17 | } 18 | } 19 | }; 20 | 21 | /** 22 | * AnyRegularField supports any field compatible with a Group. 23 | */ 24 | expectType>(true); 25 | expectType>(true); 26 | expectType>(true); 27 | expectType>(true); 28 | expectType>(true); 29 | expectType>(true); 30 | expectType>(true); 31 | expectType>(true); 32 | expectType>(true); 33 | expectType>(true); 34 | expectType>(true); 35 | expectType>(true); 36 | expectType>(true); 37 | expectType>(true); 38 | expectType>(true); 39 | expectType>(true); 40 | 41 | /** 42 | * AnyRegularField excludes any fields not compatible with a Group. 43 | */ 44 | expectType>(false); 45 | expectType>(false); 46 | -------------------------------------------------------------------------------- /src/value/image.ts: -------------------------------------------------------------------------------- 1 | import type { FieldState, Simplify } from "./types"; 2 | 3 | /** 4 | * An individual image within an Image field. The base image and each thumbnail 5 | * uses this type. 6 | * 7 | * @typeParam State - State of the field which determines its shape. 8 | * @see {@link ImageField} for a full Image field type. 9 | */ 10 | export type ImageFieldImage = 11 | State extends "empty" ? EmptyImageFieldImage : FilledImageFieldImage; 12 | 13 | export interface FilledImageFieldImage { 14 | id: string; 15 | url: string; 16 | dimensions: { 17 | width: number; 18 | height: number; 19 | }; 20 | edit: { 21 | x: number; 22 | y: number; 23 | zoom: number; 24 | background: string; 25 | }; 26 | alt: string | null; 27 | copyright: string | null; 28 | } 29 | 30 | export interface EmptyImageFieldImage { 31 | id?: null; 32 | url?: null; 33 | dimensions?: null; 34 | edit?: null; 35 | alt?: null; 36 | copyright?: null; 37 | } 38 | 39 | /** 40 | * Image Field 41 | * 42 | * **Note**: Passing `null` to the `ThumbnailNames` parameter is deprecated and 43 | * will be removed in a future version. Use `never` instead. 44 | * 45 | * @typeParam ThumbnailNames - Names of thumbnails. If the field does not 46 | * contain thumbnails, `never` can be used to "disable" thumbnail fields. 47 | * @typeParam State - State of the field which determines its shape. 48 | * @see Image field documentation: {@link https://prismic.io/docs/core-concepts/image} 49 | */ 50 | export type ImageField< 51 | // `null` is included for backwards compatibility with older versions of 52 | // this package. `null` should be treated as deprecated. `never` is 53 | // preferred. 54 | ThumbnailNames extends string | null = never, 55 | State extends FieldState = FieldState, 56 | > = Simplify< 57 | ImageFieldImage & 58 | Record< 59 | Exclude, keyof ImageFieldImage>, 60 | ImageFieldImage 61 | > 62 | >; 63 | -------------------------------------------------------------------------------- /src/value/types.ts: -------------------------------------------------------------------------------- 1 | import type { RichTextField } from "./richText"; 2 | import type { TitleField } from "./title"; 3 | import type { ImageField } from "./image"; 4 | import type { ContentRelationshipField } from "./contentRelationship"; 5 | import type { LinkField } from "./link"; 6 | import type { LinkToMediaField } from "./linkToMedia"; 7 | import type { EmbedField } from "./embed"; 8 | 9 | import type { BooleanField } from "./boolean"; 10 | import type { ColorField } from "./color"; 11 | import type { DateField } from "./date"; 12 | import type { KeyTextField } from "./keyText"; 13 | import type { NumberField } from "./number"; 14 | import type { SelectField } from "./select"; 15 | import type { TimestampField } from "./timestamp"; 16 | import type { GeoPointField } from "./geoPoint"; 17 | 18 | import type { IntegrationField } from "./integration"; 19 | 20 | /** 21 | * Empty state for object-shaped fields. 22 | */ 23 | export type EmptyObjectField = Record; 24 | 25 | /** 26 | * Valid states for fields. Not all fields use this type (e.g. BooleanField). 27 | */ 28 | export type FieldState = "empty" | "filled"; 29 | 30 | /** 31 | * Any regular field that can be nested in a group-like field. 32 | */ 33 | export type AnyRegularField = 34 | | TitleField 35 | | RichTextField 36 | | ImageField 37 | | ContentRelationshipField 38 | | LinkField 39 | | LinkToMediaField 40 | | EmbedField 41 | | DateField 42 | | TimestampField 43 | | ColorField 44 | | NumberField 45 | | KeyTextField 46 | | SelectField 47 | | BooleanField 48 | | GeoPointField 49 | | IntegrationField; 50 | 51 | /** 52 | * Useful to flatten the type output to improve type hints shown in editors. And 53 | * also to transform an interface into a type to aide with assignability. 54 | * 55 | * Taken from the `type-fest` package. 56 | * 57 | * @typeParam T - The type to simplify. 58 | * @see https://github.com/sindresorhus/type-fest/blob/cbd7ec510bd136ac045bbc74e391ee686b8a9a2f/source/simplify.d.ts 59 | */ 60 | export type Simplify = { [P in keyof T]: T[P] }; 61 | -------------------------------------------------------------------------------- /src/graphql/fields.ts: -------------------------------------------------------------------------------- 1 | export const LinkType = { 2 | Document: "Link.document", 3 | File: "Link.file", 4 | Image: "Link.image", 5 | Web: "Link.web", 6 | } as const; 7 | 8 | /** 9 | * Represents a link field without a value. 10 | */ 11 | export type EmptyLinkField = null; 12 | 13 | /** 14 | * Link that point to Documents 15 | */ 16 | export interface FilledMinimalLinkToDocumentField { 17 | _linkType: typeof LinkType.Document | string; 18 | } 19 | 20 | /** 21 | * Link that points to external website 22 | */ 23 | export interface FilledMinimalLinkToWebField { 24 | _linkType: typeof LinkType.Web | string; 25 | url: string; 26 | } 27 | 28 | /** 29 | * Link that points to media (images, PDFs, or any file in the Media Library) 30 | */ 31 | export interface FilledMinimalLinkToMediaField { 32 | _linkType: typeof LinkType.File | typeof LinkType.Image | string; 33 | url: string; 34 | } 35 | 36 | /** 37 | * Field for related documents 38 | */ 39 | export type RelationField< 40 | ExtendedLinkToDocumentField extends FilledMinimalLinkToWebField = FilledMinimalLinkToWebField, 41 | IsEmpty extends boolean = boolean, 42 | > = IsEmpty extends true ? EmptyLinkField : ExtendedLinkToDocumentField; 43 | 44 | /** 45 | * Link Field 46 | */ 47 | export type LinkField< 48 | ExtendedLinkToDocumentField extends FilledMinimalLinkToDocumentField = FilledMinimalLinkToDocumentField, 49 | ExtendedLinkToWebField extends FilledMinimalLinkToWebField = FilledMinimalLinkToWebField, 50 | ExtendedLinkToMediaField extends FilledMinimalLinkToMediaField = FilledMinimalLinkToMediaField, 51 | IsEmpty extends boolean = boolean, 52 | > = IsEmpty extends true 53 | ? EmptyLinkField 54 | : 55 | | ExtendedLinkToDocumentField 56 | | ExtendedLinkToWebField 57 | | ExtendedLinkToMediaField; 58 | 59 | /** 60 | * Link field that points to media 61 | */ 62 | export type LinkToMediaField< 63 | ExtendedLinkToMediaField extends FilledMinimalLinkToMediaField = FilledMinimalLinkToMediaField, 64 | IsEmpty extends boolean = boolean, 65 | > = IsEmpty extends true ? EmptyLinkField : ExtendedLinkToMediaField; 66 | -------------------------------------------------------------------------------- /test/customType-group.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicTI from "@prismicio/types-internal"; 4 | 5 | import * as prismicT from "../src"; 6 | 7 | (value: prismicT.CustomTypeModelGroupField): true => { 8 | switch (typeof value) { 9 | case "object": { 10 | if (value === null) { 11 | expectNever(value); 12 | } 13 | 14 | return true; 15 | } 16 | 17 | default: { 18 | return expectNever(value); 19 | } 20 | } 21 | }; 22 | 23 | expectType({ 24 | type: prismicT.CustomTypeModelFieldType.Group, 25 | config: { 26 | label: "string", 27 | fields: { 28 | foo: { 29 | type: prismicT.CustomTypeModelFieldType.Boolean, 30 | config: { 31 | label: "string", 32 | }, 33 | }, 34 | }, 35 | }, 36 | }); 37 | 38 | /** 39 | * Does not support a placeholder. 40 | */ 41 | expectType({ 42 | type: prismicT.CustomTypeModelFieldType.Group, 43 | config: { 44 | label: "string", 45 | // @ts-expect-error - Does not support a placeholder. 46 | placeholder: "string", 47 | fields: {}, 48 | }, 49 | }); 50 | 51 | /** 52 | * Supports custom fields. 53 | */ 54 | expectType< 55 | prismicT.CustomTypeModelGroupField<{ 56 | foo: prismicT.CustomTypeModelBooleanField; 57 | }> 58 | >({ 59 | type: prismicT.CustomTypeModelFieldType.Group, 60 | config: { 61 | label: "string", 62 | fields: { 63 | foo: { 64 | type: prismicT.CustomTypeModelFieldType.Boolean, 65 | config: { 66 | label: "string", 67 | }, 68 | }, 69 | // @ts-expect-error - Only given fields are valid. 70 | bar: { 71 | type: prismicT.CustomTypeModelFieldType.Boolean, 72 | config: { 73 | label: "string", 74 | }, 75 | }, 76 | }, 77 | }, 78 | }); 79 | 80 | /** 81 | * `@prismicio/types` extends `@prismicio/types-internal` 82 | */ 83 | expectType( 84 | {} as prismicTI.CustomTypes.Widgets.Group, 85 | ); 86 | 87 | /** 88 | * `@prismicio/types-internal` extends `@prismicio/types` 89 | */ 90 | expectType( 91 | {} as prismicT.CustomTypeModelGroupField, 92 | ); 93 | -------------------------------------------------------------------------------- /test/webhook-apiUpdate.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.WebhookBodyAPIUpdate): true => { 6 | switch (typeof value) { 7 | case "object": { 8 | if (value === null) { 9 | expectNever(value); 10 | } 11 | 12 | return true; 13 | } 14 | 15 | default: { 16 | return expectNever(value); 17 | } 18 | } 19 | }; 20 | 21 | expectType({ 22 | type: "api-update", 23 | domain: "string", 24 | apiUrl: "string", 25 | secret: "string", 26 | masterRef: "string", 27 | releases: { 28 | update: [ 29 | { 30 | id: "string", 31 | ref: "string", 32 | label: "string", 33 | documents: ["string"], 34 | }, 35 | ], 36 | addition: [ 37 | { 38 | id: "string", 39 | ref: "string", 40 | label: "string", 41 | documents: ["string"], 42 | }, 43 | ], 44 | deletion: [ 45 | { 46 | id: "string", 47 | ref: "string", 48 | label: "string", 49 | documents: ["string"], 50 | }, 51 | ], 52 | }, 53 | masks: { 54 | update: [ 55 | { 56 | id: "string", 57 | label: "string", 58 | }, 59 | ], 60 | addition: [ 61 | { 62 | id: "string", 63 | label: "string", 64 | }, 65 | ], 66 | deletion: [ 67 | { 68 | id: "string", 69 | label: "string", 70 | }, 71 | ], 72 | }, 73 | tags: { 74 | update: [ 75 | { 76 | id: "string", 77 | }, 78 | ], 79 | addition: [ 80 | { 81 | id: "string", 82 | }, 83 | ], 84 | deletion: [ 85 | { 86 | id: "string", 87 | }, 88 | ], 89 | }, 90 | documents: ["string"], 91 | experiments: { 92 | update: ["unknown"], 93 | addition: ["unknown"], 94 | deletion: ["unknown"], 95 | }, 96 | }); 97 | 98 | /** 99 | * Secret is nullable. 100 | */ 101 | expectType(null); 102 | 103 | /** 104 | * MasterRef is optional. 105 | */ 106 | expectType(undefined); 107 | 108 | /** 109 | * Experiments is optional 110 | */ 111 | expectType(undefined); 112 | -------------------------------------------------------------------------------- /test/customType-richText.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever, TypeOf } from "ts-expect"; 2 | 3 | import * as prismicTI from "@prismicio/types-internal"; 4 | 5 | import * as prismicT from "../src"; 6 | 7 | (value: prismicT.CustomTypeModelRichTextField): true => { 8 | switch (typeof value) { 9 | case "object": { 10 | if (value === null) { 11 | expectNever(value); 12 | } 13 | 14 | return true; 15 | } 16 | 17 | default: { 18 | return expectNever(value); 19 | } 20 | } 21 | }; 22 | 23 | /** 24 | * Supports multi block fields. 25 | */ 26 | expectType< 27 | TypeOf< 28 | prismicT.CustomTypeModelRichTextField, 29 | prismicT.CustomTypeModelRichTextMultiField 30 | > 31 | >(true); 32 | expectType({ 33 | type: prismicT.CustomTypeModelFieldType.StructuredText, 34 | config: { 35 | label: "string", 36 | multi: "string", 37 | }, 38 | }); 39 | 40 | /** 41 | * Supports single block fields. 42 | */ 43 | expectType< 44 | TypeOf< 45 | prismicT.CustomTypeModelRichTextField, 46 | prismicT.CustomTypeModelRichTextSingleField 47 | > 48 | >(true); 49 | expectType({ 50 | type: prismicT.CustomTypeModelFieldType.StructuredText, 51 | config: { 52 | label: "string", 53 | single: "string", 54 | }, 55 | }); 56 | 57 | /** 58 | * Supports optional placeholder. 59 | */ 60 | expectType({ 61 | type: prismicT.CustomTypeModelFieldType.StructuredText, 62 | config: { 63 | label: "string", 64 | placeholder: "string", 65 | multi: "string", 66 | }, 67 | }); 68 | 69 | /** 70 | * Supports optional allowTargetBlank. 71 | */ 72 | expectType({ 73 | type: prismicT.CustomTypeModelFieldType.StructuredText, 74 | config: { 75 | label: "string", 76 | multi: "string", 77 | allowTargetBlank: true, 78 | }, 79 | }); 80 | 81 | /** 82 | * `@prismicio/types` extends `@prismicio/types-internal` 83 | */ 84 | expectType( 85 | {} as prismicTI.CustomTypes.Widgets.Nestable.RichText, 86 | ); 87 | 88 | /** 89 | * `@prismicio/types-internal` extends `@prismicio/types` 90 | */ 91 | expectType( 92 | {} as prismicT.CustomTypeModelRichTextField, 93 | ); 94 | -------------------------------------------------------------------------------- /test/index.test.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from "vitest"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | test("rich text node type mapping", () => { 6 | expect(prismicT.RichTextNodeType).toMatchObject({ 7 | heading1: "heading1", 8 | heading2: "heading2", 9 | heading3: "heading3", 10 | heading4: "heading4", 11 | heading5: "heading5", 12 | heading6: "heading6", 13 | paragraph: "paragraph", 14 | preformatted: "preformatted", 15 | strong: "strong", 16 | em: "em", 17 | listItem: "list-item", 18 | oListItem: "o-list-item", 19 | list: "group-list-item", 20 | oList: "group-o-list-item", 21 | image: "image", 22 | embed: "embed", 23 | hyperlink: "hyperlink", 24 | label: "label", 25 | span: "span", 26 | }); 27 | }); 28 | 29 | test("link type mapping", () => { 30 | expect(prismicT.LinkType).toMatchObject({ 31 | Any: "Any", 32 | Web: "Web", 33 | Media: "Media", 34 | Document: "Document", 35 | }); 36 | }); 37 | 38 | test("embed type mapping", () => { 39 | expect(prismicT.OEmbedType).toMatchObject({ 40 | Photo: "photo", 41 | Video: "video", 42 | Link: "link", 43 | Rich: "rich", 44 | }); 45 | }); 46 | 47 | test("custom type field type mapping", () => { 48 | expect(prismicT.CustomTypeModelFieldType).toMatchObject({ 49 | Boolean: "Boolean", 50 | Color: "Color", 51 | Date: "Date", 52 | Embed: "Embed", 53 | GeoPoint: "GeoPoint", 54 | Group: "Group", 55 | Image: "Image", 56 | Integration: "IntegrationFields", 57 | IntegrationFields: "IntegrationFields", 58 | Link: "Link", 59 | Number: "Number", 60 | Select: "Select", 61 | Slices: "Slices", 62 | StructuredText: "StructuredText", 63 | Text: "Text", 64 | Timestamp: "Timestamp", 65 | UID: "UID", 66 | }); 67 | }); 68 | 69 | test("custom type link select mapping", () => { 70 | expect(prismicT.CustomTypeModelLinkSelectType).toMatchObject({ 71 | Document: "document", 72 | Media: "media", 73 | }); 74 | }); 75 | 76 | test("custom type slice display mapping", () => { 77 | expect(prismicT.CustomTypeModelSliceDisplay).toMatchObject({ 78 | Grid: "grid", 79 | List: "list", 80 | }); 81 | }); 82 | 83 | test("custom type slice type mapping", () => { 84 | expect(prismicT.CustomTypeModelSliceType).toMatchObject({ 85 | Slice: "Slice", 86 | SharedSlice: "SharedSlice", 87 | }); 88 | }); 89 | 90 | test("webhook type mapping", () => { 91 | expect(prismicT.WebhookType).toMatchObject({ 92 | APIUpdate: "api-update", 93 | TestTrigger: "test-trigger", 94 | }); 95 | }); 96 | -------------------------------------------------------------------------------- /test/fields-sliceZone.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.SliceZone): true => { 6 | if (!Array.isArray(value)) { 7 | return expectNever(value); 8 | } 9 | 10 | switch (typeof value[0]) { 11 | case "object": { 12 | if (value[0] === null) { 13 | expectNever(value[0]); 14 | } 15 | 16 | return true; 17 | } 18 | 19 | // When the field is empty, value[0] is undefined. 20 | case "undefined": { 21 | return true; 22 | } 23 | 24 | default: { 25 | return expectNever(value[0]); 26 | } 27 | } 28 | }; 29 | 30 | /** 31 | * Filled state. It does not use FieldState like other fields; an array with 32 | * elements implicity signals a filled state. 33 | */ 34 | expectType([ 35 | // Slice 36 | { 37 | slice_type: "string", 38 | slice_label: "string", 39 | primary: {}, 40 | items: [], 41 | }, 42 | // Shared Slice 43 | { 44 | slice_type: "string", 45 | slice_label: null, 46 | variation: "string", 47 | version: "string", 48 | primary: {}, 49 | items: [], 50 | }, 51 | ]); 52 | 53 | /** 54 | * Empty state. It does not use FieldState like other fields; an empty array 55 | * implicity signals an empty state. 56 | */ 57 | expectType([]); 58 | 59 | /** 60 | * Supports custom Slice definitions. 61 | */ 62 | expectType>>([ 63 | { 64 | slice_type: "foo", 65 | slice_label: "string", 66 | primary: {}, 67 | items: [], 68 | }, 69 | ]); 70 | expectType>>([ 71 | { 72 | // @ts-expect-error - Slice must match the given type. 73 | slice_type: "string", 74 | slice_label: "string", 75 | primary: {}, 76 | items: [], 77 | }, 78 | ]); 79 | 80 | /** 81 | * Supports custom Shared Slice definitions. 82 | */ 83 | expectType>>([ 84 | { 85 | slice_type: "foo", 86 | slice_label: null, 87 | variation: "string", 88 | version: "string", 89 | primary: {}, 90 | items: [], 91 | }, 92 | ]); 93 | expectType>>([ 94 | { 95 | // @ts-expect-error - Slice must match the given type. 96 | slice_type: "string", 97 | slice_label: null, 98 | variation: "string", 99 | version: "string", 100 | primary: {}, 101 | items: [], 102 | }, 103 | ]); 104 | -------------------------------------------------------------------------------- /test/api-query.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.Query): true => { 6 | switch (typeof value) { 7 | case "object": { 8 | if (value === null) { 9 | expectNever(value); 10 | } 11 | 12 | return true; 13 | } 14 | 15 | default: { 16 | return expectNever(value); 17 | } 18 | } 19 | }; 20 | 21 | expectType({ 22 | page: 0, 23 | results_per_page: 0, 24 | results_size: 0, 25 | total_results_size: 0, 26 | total_pages: 0, 27 | next_page: "string", 28 | prev_page: "string", 29 | results: [ 30 | { 31 | id: "string", 32 | uid: "string", 33 | url: "string", 34 | type: "string", 35 | href: "string", 36 | tags: ["string"], 37 | first_publication_date: "string", 38 | last_publication_date: "string", 39 | slugs: ["string"], 40 | linked_documents: [], 41 | lang: "string", 42 | alternate_languages: [ 43 | { 44 | id: "string", 45 | lang: "string", 46 | type: "string", 47 | uid: "string", 48 | }, 49 | ], 50 | data: {}, 51 | }, 52 | ], 53 | }); 54 | 55 | /** 56 | * Supports nullable `next_page` and `prev_page` properties. 57 | */ 58 | expectType({ 59 | page: 0, 60 | results_per_page: 0, 61 | results_size: 0, 62 | total_results_size: 0, 63 | total_pages: 0, 64 | next_page: null, 65 | prev_page: null, 66 | results: [], 67 | }); 68 | 69 | /** 70 | * Supports custom document type. 71 | */ 72 | expectType< 73 | prismicT.Query< 74 | prismicT.PrismicDocument<{ 75 | foo: prismicT.BooleanField; 76 | }> 77 | > 78 | >({ 79 | page: 0, 80 | results_per_page: 0, 81 | results_size: 0, 82 | total_results_size: 0, 83 | total_pages: 0, 84 | next_page: null, 85 | prev_page: null, 86 | results: [ 87 | { 88 | id: "string", 89 | uid: "string", 90 | url: "string", 91 | type: "string", 92 | href: "string", 93 | tags: ["string"], 94 | first_publication_date: "string", 95 | last_publication_date: "string", 96 | slugs: ["string"], 97 | linked_documents: [], 98 | lang: "string", 99 | alternate_languages: [ 100 | { 101 | id: "string", 102 | lang: "string", 103 | type: "string", 104 | uid: "string", 105 | }, 106 | ], 107 | data: { 108 | foo: true, 109 | // @ts-expect-error - Only given fields are valid. 110 | bar: false, 111 | }, 112 | }, 113 | ], 114 | }); 115 | -------------------------------------------------------------------------------- /test/customType-sliceZone.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicTI from "@prismicio/types-internal"; 4 | 5 | import * as prismicT from "../src"; 6 | 7 | (value: prismicT.CustomTypeModelSliceZoneField): true => { 8 | switch (typeof value) { 9 | case "object": { 10 | if (value === null) { 11 | expectNever(value); 12 | } 13 | 14 | return true; 15 | } 16 | 17 | default: { 18 | return expectNever(value); 19 | } 20 | } 21 | }; 22 | 23 | expectType({ 24 | type: prismicT.CustomTypeModelFieldType.Slices, 25 | fieldset: "Slice zone", 26 | config: { 27 | labels: { 28 | foo: [ 29 | { 30 | name: "string", 31 | display: "string", 32 | }, 33 | ], 34 | }, 35 | choices: { 36 | foo: { 37 | type: prismicT.CustomTypeModelSliceType.Slice, 38 | fieldset: "string", 39 | description: "string", 40 | icon: "string", 41 | display: prismicT.CustomTypeModelSliceDisplay.List, 42 | "non-repeat": { 43 | foo: { 44 | type: prismicT.CustomTypeModelFieldType.Boolean, 45 | config: { 46 | label: "string", 47 | }, 48 | }, 49 | }, 50 | repeat: { 51 | foo: { 52 | type: prismicT.CustomTypeModelFieldType.Boolean, 53 | config: { 54 | label: "string", 55 | }, 56 | }, 57 | }, 58 | }, 59 | }, 60 | }, 61 | }); 62 | 63 | /** 64 | * Supports custom Slice types. 65 | */ 66 | expectType< 67 | prismicT.CustomTypeModelSliceZoneField<{ 68 | foo: prismicT.CustomTypeModelSlice; 69 | bar: prismicT.CustomTypeModelSharedSlice; 70 | }> 71 | >({ 72 | type: prismicT.CustomTypeModelFieldType.Slices, 73 | fieldset: "Slice zone", 74 | config: { 75 | labels: {}, 76 | choices: { 77 | foo: { 78 | type: prismicT.CustomTypeModelSliceType.Slice, 79 | fieldset: "string", 80 | display: prismicT.CustomTypeModelSliceDisplay.List, 81 | description: "string", 82 | icon: "string", 83 | repeat: {}, 84 | "non-repeat": {}, 85 | }, 86 | bar: { 87 | type: prismicT.CustomTypeModelSliceType.SharedSlice, 88 | }, 89 | }, 90 | }, 91 | }); 92 | 93 | /** 94 | * `@prismicio/types` extends `@prismicio/types-internal` 95 | */ 96 | expectType( 97 | {} as prismicTI.CustomTypes.Widgets.Slices.SliceZone.DynamicSlices, 98 | ); 99 | 100 | /** 101 | * `@prismicio/types-internal` extends `@prismicio/types` 102 | */ 103 | expectType( 104 | {} as prismicT.CustomTypeModelSliceZoneField, 105 | ); 106 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@prismicio/types", 3 | "version": "0.2.9", 4 | "description": "Type definitions for Prismic related structure", 5 | "keywords": [ 6 | "typescript", 7 | "types", 8 | "utils", 9 | "toolbox", 10 | "prismic" 11 | ], 12 | "repository": { 13 | "type": "git", 14 | "url": "ssh://git@github.com/prismicio/prismic-types.git" 15 | }, 16 | "license": "Apache-2.0", 17 | "author": "Prismic (https://prismic.io)", 18 | "sideEffects": false, 19 | "type": "module", 20 | "exports": { 21 | ".": { 22 | "require": "./dist/index.cjs", 23 | "import": "./dist/index.js" 24 | }, 25 | "./graphql": { 26 | "require": "./dist/graphql.cjs", 27 | "import": "./dist/graphql.js" 28 | }, 29 | "./dist/graphql": { 30 | "require": "./dist/graphql.cjs", 31 | "import": "./dist/graphql.js" 32 | }, 33 | "./package.json": "./package.json" 34 | }, 35 | "main": "dist/index.cjs", 36 | "module": "dist/index.js", 37 | "react-native": "dist/index.js", 38 | "types": "dist/index.d.ts", 39 | "files": [ 40 | "dist", 41 | "src" 42 | ], 43 | "scripts": { 44 | "build": "vite build", 45 | "dev": "vite build --watch", 46 | "format": "prettier --write .", 47 | "lint": "eslint --ext .js,.ts .", 48 | "prepare": "npm run build", 49 | "release": "npm run build && npm run test && standard-version && git push --follow-tags && npm run build && npm publish", 50 | "release:alpha": "npm run build && npm run test && standard-version --release-as patch --prerelease alpha && git push --follow-tags && npm run build && npm publish --tag alpha", 51 | "release:alpha:dry": "standard-version --release-as patch --prerelease alpha --dry-run", 52 | "release:dry": "standard-version --dry-run", 53 | "size": "size-limit", 54 | "test": "npm run lint && npm run types && npm run unit", 55 | "types": "tsc --noEmit", 56 | "unit": "vitest run --coverage", 57 | "unit:watch": "vitest watch" 58 | }, 59 | "devDependencies": { 60 | "@prismicio/types-internal": "^1.5.3", 61 | "@size-limit/preset-small-lib": "^8.1.0", 62 | "@typescript-eslint/eslint-plugin": "^5.46.1", 63 | "@typescript-eslint/parser": "^5.46.1", 64 | "@vitest/coverage-c8": "^0.26.0", 65 | "eslint": "^8.30.0", 66 | "eslint-config-prettier": "^8.5.0", 67 | "eslint-plugin-prettier": "^4.2.1", 68 | "eslint-plugin-tsdoc": "^0.2.17", 69 | "prettier": "^2.8.1", 70 | "prettier-plugin-jsdoc": "^0.4.2", 71 | "size-limit": "^8.1.0", 72 | "standard-version": "^9.5.0", 73 | "ts-expect": "^1.3.0", 74 | "typescript": "^4.9.4", 75 | "vite": "^4.0.2", 76 | "vite-plugin-sdk": "^0.1.0", 77 | "vitest": "^0.26.0" 78 | }, 79 | "engines": { 80 | "node": ">=12.7.0" 81 | }, 82 | "publishConfig": { 83 | "access": "public" 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/api/repository.ts: -------------------------------------------------------------------------------- 1 | import { Ref } from "./ref"; 2 | 3 | /** 4 | * Repository metadata returned from the Prismic REST API V2. This data can be 5 | * fetched by sending a `GET` a request to a repository's `/api/v2` endpoint. 6 | * 7 | * @see More details on the `/api/v2` endpoint: {@link https://prismic.io/docs/technologies/introduction-to-the-content-query-api#the-api-endpoint-2} 8 | */ 9 | export interface Repository { 10 | /** 11 | * A list of refs for the repository. 12 | * 13 | * @see {@link Ref} 14 | */ 15 | refs: Ref[]; 16 | 17 | /** 18 | * An identifier used to query content with the latest Integration Fields 19 | * data. 20 | */ 21 | integrationFieldsRef: string | null; 22 | 23 | /** 24 | * A list of languages for the repository. 25 | * 26 | * @see {@link Language} 27 | */ 28 | languages: Language[]; 29 | 30 | /** 31 | * A list of the repository's Custom Type API IDs mapped to their 32 | * human-readable name. 33 | */ 34 | types: Record; 35 | 36 | /** 37 | * A list of tags for the repository. 38 | */ 39 | tags: string[]; 40 | 41 | /** 42 | * An internally-used list of REST API features for the repository. 43 | * 44 | * @internal 45 | */ 46 | forms: Record; 47 | 48 | /** 49 | * The URL used to begin the OAuth process for the repository. 50 | */ 51 | oauth_initiate: string; 52 | 53 | // TODO: Describe this field 54 | oauth_token: string; 55 | 56 | /** 57 | * The version of the API. 58 | */ 59 | version: string; 60 | 61 | /** 62 | * Licensing information for the repository content. 63 | */ 64 | license: string; 65 | 66 | /** 67 | * @deprecated Experiments are no longer part of Prismic. 68 | */ 69 | experiments: unknown; 70 | 71 | /** 72 | * @deprecated Bookmarks are not longer part of Prismic. 73 | */ 74 | bookmarks: Record; 75 | } 76 | 77 | /** 78 | * Metadata for a language that has been configured for a repository. 79 | */ 80 | export interface Language { 81 | /** 82 | * A unique identifier for the language. 83 | */ 84 | id: string; 85 | 86 | /** 87 | * The name of the language. 88 | */ 89 | name: string; 90 | } 91 | 92 | /** 93 | * A Prismic REST API V2 feature supported by the repository. It contains 94 | * metadata about the feature and how to interact with it via the API. 95 | * 96 | * @internal 97 | */ 98 | export interface Form { 99 | method: "GET"; 100 | enctype: string; 101 | action: string; 102 | name?: string; 103 | rel?: string; 104 | fields: Record; 105 | } 106 | 107 | /** 108 | * A field for a feature of the Prismic REST API V2. It contains metadata about 109 | * the feature's field and how to interact with it via the API. 110 | * 111 | * @internal 112 | */ 113 | export interface FormField { 114 | type: "String" | "Integer"; 115 | multiple: boolean; 116 | default?: string; 117 | } 118 | -------------------------------------------------------------------------------- /test/customType-sharedSliceModel.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicTI from "@prismicio/types-internal"; 4 | 5 | import * as prismicT from "../src"; 6 | 7 | (value: prismicT.SharedSliceModel): true => { 8 | switch (typeof value) { 9 | case "object": { 10 | if (value === null) { 11 | expectNever(value); 12 | } 13 | 14 | return true; 15 | } 16 | 17 | default: { 18 | return expectNever(value); 19 | } 20 | } 21 | }; 22 | 23 | expectType({ 24 | type: prismicT.CustomTypeModelSliceType.SharedSlice, 25 | id: "string", 26 | name: "string", 27 | description: "string", 28 | variations: [ 29 | { 30 | id: "string", 31 | name: "string", 32 | docURL: "string", 33 | version: "string", 34 | description: "string", 35 | primary: { 36 | foo: { 37 | type: prismicT.CustomTypeModelFieldType.Boolean, 38 | config: { 39 | label: "string", 40 | }, 41 | }, 42 | }, 43 | items: { 44 | foo: { 45 | type: prismicT.CustomTypeModelFieldType.Boolean, 46 | config: { 47 | label: "string", 48 | }, 49 | }, 50 | }, 51 | imageUrl: "string", 52 | }, 53 | ], 54 | }); 55 | 56 | /** 57 | * Supports custom ID. 58 | */ 59 | expectType>({ 60 | type: prismicT.CustomTypeModelSliceType.SharedSlice, 61 | id: "foo", 62 | name: "string", 63 | description: "string", 64 | variations: [], 65 | }); 66 | expectType>({ 67 | type: prismicT.CustomTypeModelSliceType.SharedSlice, 68 | // @ts-expect-error - Slice ID must match the given ID. 69 | id: "string", 70 | name: "string", 71 | description: "string", 72 | variations: [], 73 | }); 74 | 75 | /** 76 | * Supports custom variations. 77 | */ 78 | expectType< 79 | prismicT.SharedSliceModel> 80 | >({ 81 | type: prismicT.CustomTypeModelSliceType.SharedSlice, 82 | id: "string", 83 | name: "string", 84 | description: "string", 85 | variations: [ 86 | { 87 | id: "foo", 88 | name: "string", 89 | docURL: "string", 90 | version: "string", 91 | description: "string", 92 | primary: {}, 93 | items: {}, 94 | imageUrl: "string", 95 | }, 96 | { 97 | // @ts-expect-error - Slice must match the given type. 98 | id: "bar", 99 | name: "string", 100 | docURL: "string", 101 | version: "string", 102 | description: "string", 103 | primary: {}, 104 | items: {}, 105 | imageUrl: "string", 106 | }, 107 | ], 108 | }); 109 | 110 | /** 111 | * `@prismicio/types` extends `@prismicio/types-internal` 112 | */ 113 | expectType( 114 | {} as prismicTI.CustomTypes.Widgets.Slices.SharedSlice, 115 | ); 116 | 117 | /** 118 | * `@prismicio/types-internal` extends `@prismicio/types` 119 | */ 120 | expectType( 121 | {} as prismicT.SharedSliceModel, 122 | ); 123 | -------------------------------------------------------------------------------- /test/customType-slice.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicTI from "@prismicio/types-internal"; 4 | 5 | import * as prismicT from "../src"; 6 | 7 | (value: prismicT.CustomTypeModelSlice): true => { 8 | switch (typeof value) { 9 | case "object": { 10 | if (value === null) { 11 | expectNever(value); 12 | } 13 | 14 | return true; 15 | } 16 | 17 | default: { 18 | return expectNever(value); 19 | } 20 | } 21 | }; 22 | 23 | expectType({ 24 | type: prismicT.CustomTypeModelSliceType.Slice, 25 | fieldset: "string", 26 | description: "string", 27 | icon: "string", 28 | display: prismicT.CustomTypeModelSliceDisplay.List, 29 | "non-repeat": { 30 | foo: { 31 | type: prismicT.CustomTypeModelFieldType.Boolean, 32 | config: { 33 | label: "string", 34 | }, 35 | }, 36 | }, 37 | repeat: { 38 | foo: { 39 | type: prismicT.CustomTypeModelFieldType.Boolean, 40 | config: { 41 | label: "string", 42 | }, 43 | }, 44 | }, 45 | }); 46 | 47 | /** 48 | * Supports custom non-repeat fields. 49 | */ 50 | expectType< 51 | prismicT.CustomTypeModelSlice<{ foo: prismicT.CustomTypeModelBooleanField }> 52 | >({ 53 | type: prismicT.CustomTypeModelSliceType.Slice, 54 | fieldset: "string", 55 | display: prismicT.CustomTypeModelSliceDisplay.List, 56 | description: "string", 57 | icon: "string", 58 | "non-repeat": { 59 | foo: { 60 | type: prismicT.CustomTypeModelFieldType.Boolean, 61 | config: { 62 | label: "string", 63 | }, 64 | }, 65 | // @ts-expect-error - Only given fields are valid. 66 | bar: { 67 | type: prismicT.CustomTypeModelFieldType.Boolean, 68 | config: { 69 | label: "string", 70 | }, 71 | }, 72 | }, 73 | repeat: {}, 74 | }); 75 | 76 | /** 77 | * Supports custom repeat fields. 78 | */ 79 | expectType< 80 | prismicT.CustomTypeModelSlice< 81 | Record, 82 | { foo: prismicT.CustomTypeModelBooleanField } 83 | > 84 | >({ 85 | type: prismicT.CustomTypeModelSliceType.Slice, 86 | fieldset: "string", 87 | display: prismicT.CustomTypeModelSliceDisplay.List, 88 | description: "string", 89 | icon: "string", 90 | "non-repeat": {}, 91 | repeat: { 92 | foo: { 93 | type: prismicT.CustomTypeModelFieldType.Boolean, 94 | config: { 95 | label: "string", 96 | }, 97 | }, 98 | // @ts-expect-error - Only given fields are valid. 99 | bar: { 100 | type: prismicT.CustomTypeModelFieldType.Boolean, 101 | config: { 102 | label: "string", 103 | }, 104 | }, 105 | }, 106 | }); 107 | 108 | /** 109 | * `@prismicio/types` extends `@prismicio/types-internal` 110 | */ 111 | expectType( 112 | {} as prismicTI.CustomTypes.Widgets.Slices.CompositeSlice, 113 | ); 114 | 115 | /** 116 | * `@prismicio/types-internal` extends `@prismicio/types` 117 | */ 118 | expectType( 119 | {} as prismicT.CustomTypeModelSlice, 120 | ); 121 | -------------------------------------------------------------------------------- /test/customType-select.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicTI from "@prismicio/types-internal"; 4 | 5 | import * as prismicT from "../src"; 6 | 7 | (value: prismicT.CustomTypeModelSelectField): true => { 8 | switch (typeof value) { 9 | case "object": { 10 | if (value === null) { 11 | expectNever(value); 12 | } 13 | 14 | return true; 15 | } 16 | 17 | default: { 18 | return expectNever(value); 19 | } 20 | } 21 | }; 22 | 23 | expectType({ 24 | type: prismicT.CustomTypeModelFieldType.Select, 25 | config: { 26 | label: "string", 27 | options: ["string"], 28 | }, 29 | }); 30 | 31 | /** 32 | * Supports optional placeholder. 33 | */ 34 | expectType({ 35 | type: prismicT.CustomTypeModelFieldType.Select, 36 | config: { 37 | label: "string", 38 | placeholder: "string", 39 | options: ["string"], 40 | }, 41 | }); 42 | 43 | /** 44 | * Supports optional default value. 45 | */ 46 | expectType({ 47 | type: prismicT.CustomTypeModelFieldType.Select, 48 | config: { 49 | label: "string", 50 | placeholder: "string", 51 | options: ["string"], 52 | default_value: "string", 53 | }, 54 | }); 55 | 56 | /** 57 | * Supports custom options type. 58 | */ 59 | expectType>({ 60 | type: prismicT.CustomTypeModelFieldType.Select, 61 | config: { 62 | label: "string", 63 | placeholder: "string", 64 | options: [ 65 | "foo", 66 | // @ts-expect-error - Only given options are valid. 67 | "bar", 68 | ], 69 | }, 70 | }); 71 | 72 | /** 73 | * Supports custom default value type. 74 | */ 75 | expectType>({ 76 | type: prismicT.CustomTypeModelFieldType.Select, 77 | config: { 78 | label: "string", 79 | placeholder: "string", 80 | options: ["string"], 81 | default_value: "foo", 82 | }, 83 | }); 84 | 85 | /** 86 | * Default value must be one of the given options. 87 | */ 88 | expectType>({ 89 | type: prismicT.CustomTypeModelFieldType.Select, 90 | config: { 91 | label: "string", 92 | placeholder: "string", 93 | options: ["foo"], 94 | default_value: "foo", 95 | }, 96 | }); 97 | expectType>({ 98 | type: prismicT.CustomTypeModelFieldType.Select, 99 | config: { 100 | label: "string", 101 | placeholder: "string", 102 | options: ["foo"], 103 | // @ts-expect-error - Default value must be one of the given options. 104 | default_value: "bar", 105 | }, 106 | }); 107 | 108 | /** 109 | * `@prismicio/types` extends `@prismicio/types-internal` 110 | */ 111 | expectType( 112 | {} as prismicTI.CustomTypes.Widgets.Nestable.Select, 113 | ); 114 | 115 | /** 116 | * `@prismicio/types-internal` extends `@prismicio/types` 117 | */ 118 | expectType( 119 | {} as prismicT.CustomTypeModelSelectField, 120 | ); 121 | -------------------------------------------------------------------------------- /src/model/types.ts: -------------------------------------------------------------------------------- 1 | import type { CustomTypeModelContentRelationshipField } from "./contentRelationship"; 2 | import type { CustomTypeModelEmbedField } from "./embed"; 3 | import type { CustomTypeModelImageField } from "./image"; 4 | import type { CustomTypeModelLinkField } from "./link"; 5 | import type { CustomTypeModelLinkToMediaField } from "./linkToMedia"; 6 | import type { CustomTypeModelRichTextField } from "./richText"; 7 | import type { CustomTypeModelTitleField } from "./title"; 8 | 9 | import type { CustomTypeModelBooleanField } from "./boolean"; 10 | import type { CustomTypeModelColorField } from "./color"; 11 | import type { CustomTypeModelDateField } from "./date"; 12 | import type { CustomTypeModelKeyTextField } from "./keyText"; 13 | import type { CustomTypeModelNumberField } from "./number"; 14 | import type { CustomTypeModelSelectField } from "./select"; 15 | import type { CustomTypeModelTimestampField } from "./timestamp"; 16 | import type { CustomTypeModelGeoPointField } from "./geoPoint"; 17 | 18 | import type { CustomTypeModelIntegrationField } from "./integration"; 19 | import type { CustomTypeModelGroupField } from "./group"; 20 | import type { CustomTypeModelSliceZoneField } from "./sliceZone"; 21 | 22 | import type { CustomTypeModelUIDField } from "./uid"; 23 | 24 | import type { CustomTypeModelRangeField } from "./range"; 25 | import type { CustomTypeModelSeparatorField } from "./separator"; 26 | 27 | /** 28 | * Type identifier for a Custom Type field. 29 | */ 30 | export const CustomTypeModelFieldType = { 31 | Boolean: "Boolean", 32 | Color: "Color", 33 | Date: "Date", 34 | Embed: "Embed", 35 | GeoPoint: "GeoPoint", 36 | Group: "Group", 37 | Image: "Image", 38 | Integration: "IntegrationFields", 39 | Link: "Link", 40 | Number: "Number", 41 | Select: "Select", 42 | Slices: "Slices", 43 | StructuredText: "StructuredText", 44 | Text: "Text", 45 | Timestamp: "Timestamp", 46 | UID: "UID", 47 | /** 48 | * @deprecated - Renamed to `Integration`. 49 | */ 50 | IntegrationFields: "IntegrationFields", 51 | /** 52 | * @deprecated - Legacy field type. Use `Number` instead. 53 | */ 54 | Range: "Range", 55 | /** 56 | * @deprecated - Legacy field type. Do not use. 57 | */ 58 | Separator: "Separator", 59 | /** 60 | * @deprecated - Legacy field type. Use `Slices` instead. 61 | */ 62 | LegacySlices: "Choice", 63 | } as const; 64 | 65 | /** 66 | * A Custom Type field. 67 | */ 68 | export type CustomTypeModelField = 69 | | CustomTypeModelUIDField 70 | | CustomTypeModelGroupField 71 | | CustomTypeModelSliceZoneField 72 | | CustomTypeModelFieldForGroup; 73 | 74 | /** 75 | * Any Custom Type field that is valid for a Group field. 76 | */ 77 | export type CustomTypeModelFieldForGroup = 78 | | CustomTypeModelBooleanField 79 | | CustomTypeModelColorField 80 | | CustomTypeModelDateField 81 | | CustomTypeModelEmbedField 82 | | CustomTypeModelGeoPointField 83 | | CustomTypeModelImageField 84 | | CustomTypeModelIntegrationField 85 | | CustomTypeModelContentRelationshipField 86 | | CustomTypeModelLinkField 87 | | CustomTypeModelLinkToMediaField 88 | | CustomTypeModelNumberField 89 | | CustomTypeModelRangeField 90 | | CustomTypeModelSelectField 91 | | CustomTypeModelRichTextField 92 | | CustomTypeModelTitleField 93 | | CustomTypeModelKeyTextField 94 | | CustomTypeModelTimestampField 95 | | CustomTypeModelSeparatorField; 96 | -------------------------------------------------------------------------------- /test/customType-contentRelationship.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicTI from "@prismicio/types-internal"; 4 | 5 | import * as prismicT from "../src"; 6 | 7 | (value: prismicT.CustomTypeModelContentRelationshipField): true => { 8 | switch (typeof value) { 9 | case "object": { 10 | if (value === null) { 11 | expectNever(value); 12 | } 13 | 14 | return true; 15 | } 16 | 17 | default: { 18 | return expectNever(value); 19 | } 20 | } 21 | }; 22 | 23 | expectType({ 24 | type: prismicT.CustomTypeModelFieldType.Link, 25 | config: { 26 | label: "string", 27 | select: prismicT.CustomTypeModelLinkSelectType.Document, 28 | }, 29 | }); 30 | 31 | /** 32 | * Supports optional placeholder. 33 | */ 34 | expectType({ 35 | type: prismicT.CustomTypeModelFieldType.Link, 36 | config: { 37 | label: "string", 38 | placeholder: "string", 39 | select: prismicT.CustomTypeModelLinkSelectType.Document, 40 | }, 41 | }); 42 | 43 | /** 44 | * Supports optional `customtypes` property. 45 | */ 46 | expectType({ 47 | type: prismicT.CustomTypeModelFieldType.Link, 48 | config: { 49 | label: "string", 50 | select: prismicT.CustomTypeModelLinkSelectType.Document, 51 | customtypes: ["string"], 52 | }, 53 | }); 54 | 55 | /** 56 | * Supports custom `customtypes` values. 57 | */ 58 | expectType>({ 59 | type: prismicT.CustomTypeModelFieldType.Link, 60 | config: { 61 | label: "string", 62 | select: prismicT.CustomTypeModelLinkSelectType.Document, 63 | customtypes: [ 64 | "foo", 65 | // @ts-expect-error - Only given types are valid. 66 | "bar", 67 | ], 68 | }, 69 | }); 70 | 71 | /** 72 | * Supports optional `tags` property. 73 | */ 74 | expectType({ 75 | type: prismicT.CustomTypeModelFieldType.Link, 76 | config: { 77 | label: "string", 78 | select: prismicT.CustomTypeModelLinkSelectType.Document, 79 | tags: ["string"], 80 | }, 81 | }); 82 | 83 | /** 84 | * Supports custom `tags` values. 85 | */ 86 | expectType>({ 87 | type: prismicT.CustomTypeModelFieldType.Link, 88 | config: { 89 | label: "string", 90 | select: prismicT.CustomTypeModelLinkSelectType.Document, 91 | tags: [ 92 | "foo", 93 | // @ts-expect-error - Only given tags are valid. 94 | "bar", 95 | ], 96 | }, 97 | }); 98 | 99 | /** 100 | * `@prismicio/types` extends `@prismicio/types-internal` 101 | */ 102 | expectType( 103 | {} as prismicTI.CustomTypes.Widgets.Nestable.Link & { 104 | // We must manually narrow `@prismicio/types-internal`'s type 105 | // to match a Content Relationship field; 106 | // `@prismicio/types-internal` does not contain a Content 107 | // Relationship-specific type. 108 | config?: { select: "document" }; 109 | }, 110 | ); 111 | 112 | /** 113 | * `@prismicio/types-internal` extends `@prismicio/types` 114 | */ 115 | expectType( 116 | {} as prismicT.CustomTypeModelContentRelationshipField, 117 | ); 118 | -------------------------------------------------------------------------------- /test/customType-image.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicTI from "@prismicio/types-internal"; 4 | 5 | import * as prismicT from "../src"; 6 | 7 | (value: prismicT.CustomTypeModelImageField): true => { 8 | switch (typeof value) { 9 | case "object": { 10 | if (value === null) { 11 | expectNever(value); 12 | } 13 | 14 | return true; 15 | } 16 | 17 | default: { 18 | return expectNever(value); 19 | } 20 | } 21 | }; 22 | 23 | expectType({ 24 | type: prismicT.CustomTypeModelFieldType.Image, 25 | config: { 26 | label: "string", 27 | constraint: {}, 28 | thumbnails: [ 29 | { 30 | name: "string", 31 | width: 1, 32 | height: 1, 33 | }, 34 | ], 35 | }, 36 | }); 37 | 38 | /** 39 | * Does not support a placeholder. 40 | */ 41 | expectType({ 42 | type: prismicT.CustomTypeModelFieldType.Image, 43 | config: { 44 | label: "string", 45 | // @ts-expect-error - Does not support a placeholder. 46 | placeholder: "string", 47 | constraint: { 48 | width: 1, 49 | height: 1, 50 | }, 51 | thumbnails: [ 52 | { 53 | name: "string", 54 | width: 1, 55 | height: 1, 56 | }, 57 | ], 58 | }, 59 | }); 60 | 61 | /** 62 | * Supports optional constraint. 63 | */ 64 | expectType({ 65 | type: prismicT.CustomTypeModelFieldType.Image, 66 | config: { 67 | label: "string", 68 | constraint: { 69 | width: 1, 70 | height: 1, 71 | }, 72 | thumbnails: [], 73 | }, 74 | }); 75 | 76 | /** 77 | * Supports custom thumbnail names. 78 | */ 79 | expectType>({ 80 | type: prismicT.CustomTypeModelFieldType.Image, 81 | config: { 82 | label: "string", 83 | constraint: {}, 84 | thumbnails: [ 85 | { 86 | name: "Foo", 87 | width: 1, 88 | height: 1, 89 | }, 90 | { 91 | // @ts-expect-error - Only given thumbnail names are valid. 92 | name: "string", 93 | width: 1, 94 | height: 1, 95 | }, 96 | ], 97 | }, 98 | }); 99 | 100 | /** 101 | * Constraint supports nullable width and height to represent no constraint. 102 | */ 103 | expectType({ 104 | width: null, 105 | height: null, 106 | }); 107 | expectType({ 108 | width: 1, 109 | height: null, 110 | }); 111 | expectType({ 112 | width: null, 113 | height: 1, 114 | }); 115 | 116 | /** 117 | * Thumbnail supports configurable name. 118 | */ 119 | expectType>({ 120 | name: "Foo", 121 | width: null, 122 | height: null, 123 | }); 124 | expectType>({ 125 | // @ts-expect-error - Name must match the given name. 126 | name: "string", 127 | width: null, 128 | height: null, 129 | }); 130 | 131 | /** 132 | * `@prismicio/types` extends `@prismicio/types-internal` 133 | */ 134 | expectType( 135 | {} as prismicTI.CustomTypes.Widgets.Nestable.Image, 136 | ); 137 | 138 | /** 139 | * `@prismicio/types-internal` extends `@prismicio/types` 140 | */ 141 | expectType( 142 | {} as prismicT.CustomTypeModelImageField, 143 | ); 144 | -------------------------------------------------------------------------------- /test/fields-contentRelationship.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.RelationField): true => { 6 | switch (typeof value) { 7 | case "object": { 8 | if (value === null) { 9 | return expectNever(value); 10 | } 11 | 12 | return true; 13 | } 14 | 15 | default: { 16 | return expectNever(value); 17 | } 18 | } 19 | }; 20 | 21 | /** 22 | * Filled state. 23 | */ 24 | expectType({ 25 | link_type: prismicT.LinkType.Document, 26 | id: "string", 27 | uid: "string", 28 | type: "string", 29 | tags: ["string"], 30 | lang: "string", 31 | url: "string", 32 | slug: "string", 33 | isBroken: true, 34 | data: undefined, 35 | }); 36 | expectType>({ 37 | link_type: prismicT.LinkType.Document, 38 | id: "string", 39 | uid: "string", 40 | type: "string", 41 | tags: ["string"], 42 | lang: "string", 43 | url: "string", 44 | slug: "string", 45 | isBroken: true, 46 | data: undefined, 47 | }); 48 | expectType>({ 49 | link_type: prismicT.LinkType.Document, 50 | // @ts-expect-error - Empty fields cannot contain a filled value. 51 | id: "string", 52 | uid: "string", 53 | type: "string", 54 | tags: ["string"], 55 | lang: "string", 56 | url: "string", 57 | slug: "string", 58 | isBroken: true, 59 | data: undefined, 60 | }); 61 | 62 | /** 63 | * Empty state. 64 | */ 65 | expectType({ 66 | link_type: prismicT.LinkType.Document, 67 | }); 68 | expectType>({ 69 | link_type: prismicT.LinkType.Document, 70 | }); 71 | expectType>( 72 | // @ts-expect-error - Filled fields cannot contain an empty value. 73 | { 74 | link_type: prismicT.LinkType.Document, 75 | }, 76 | ); 77 | 78 | /** 79 | * Supports custom document type. 80 | */ 81 | expectType>({ 82 | link_type: prismicT.LinkType.Document, 83 | id: "string", 84 | type: "foo", 85 | tags: [], 86 | lang: "string", 87 | }); 88 | expectType>({ 89 | link_type: prismicT.LinkType.Document, 90 | id: "string", 91 | // @ts-expect-error - Document type must match the given type. 92 | type: "string", 93 | tags: [], 94 | lang: "string", 95 | }); 96 | 97 | /** 98 | * Supports custom document language. 99 | */ 100 | expectType>({ 101 | link_type: prismicT.LinkType.Document, 102 | id: "string", 103 | type: "string", 104 | tags: [], 105 | lang: "fr-fr", 106 | }); 107 | expectType>({ 108 | link_type: prismicT.LinkType.Document, 109 | id: "string", 110 | type: "string", 111 | tags: [], 112 | // @ts-expect-error - Document language must match the given type. 113 | lang: "string", 114 | }); 115 | 116 | /** 117 | * Supports custom document data. 118 | */ 119 | expectType< 120 | prismicT.RelationField 121 | >({ 122 | link_type: prismicT.LinkType.Document, 123 | id: "string", 124 | type: "string", 125 | tags: [], 126 | lang: "fr-fr", 127 | data: { 128 | foo: true, 129 | // @ts-expect-error - Only given fields are valid. 130 | bar: false, 131 | }, 132 | }); 133 | -------------------------------------------------------------------------------- /test/fields-slice.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.Slice): true => { 6 | switch (typeof value) { 7 | case "object": { 8 | if (value === null) { 9 | expectNever(value); 10 | } 11 | 12 | return true; 13 | } 14 | 15 | default: { 16 | return expectNever(value); 17 | } 18 | } 19 | }; 20 | 21 | expectType({ 22 | slice_type: "string", 23 | slice_label: null, 24 | primary: {}, 25 | items: [], 26 | }); 27 | 28 | /** 29 | * Supports Slice labels. 30 | */ 31 | expectType({ 32 | slice_type: "string", 33 | slice_label: "string", 34 | primary: {}, 35 | items: [], 36 | }); 37 | 38 | /** 39 | * Supports custom Slice type API ID. 40 | */ 41 | expectType>({ 42 | slice_type: "foo", 43 | slice_label: "string", 44 | primary: {}, 45 | items: [], 46 | }); 47 | expectType>({ 48 | // @ts-expect-error - Slice type must match the given type. 49 | slice_type: "string", 50 | slice_label: "string", 51 | primary: {}, 52 | items: [], 53 | }); 54 | 55 | /** 56 | * Supports custom primary fields type. 57 | */ 58 | expectType>({ 59 | slice_type: "string", 60 | slice_label: "string", 61 | primary: { 62 | foo: true, 63 | // @ts-expect-error - Only given fields are valid. 64 | bar: false, 65 | }, 66 | items: [], 67 | }); 68 | 69 | /** 70 | * Custom primary fields may only contain group-compatible fields. 71 | */ 72 | expectType< 73 | prismicT.Slice< 74 | string, 75 | // @ts-expect-error - Groups are invalid within primary fields. 76 | { 77 | group: prismicT.GroupField; 78 | } 79 | > 80 | >({ 81 | slice_type: "string", 82 | slice_label: "string", 83 | primary: { 84 | group: [], 85 | }, 86 | items: [], 87 | }); 88 | expectType< 89 | prismicT.Slice< 90 | string, 91 | // @ts-expect-error - Slice Zones are invalid within primary fields. 92 | { 93 | sliceZone: prismicT.SliceZone; 94 | } 95 | > 96 | >({ 97 | slice_type: "string", 98 | slice_label: "string", 99 | primary: { 100 | sliceZone: [], 101 | }, 102 | items: [], 103 | }); 104 | 105 | /** 106 | * Supports custom items fields type. 107 | */ 108 | expectType< 109 | prismicT.Slice< 110 | string, 111 | { foo: prismicT.BooleanField }, 112 | { bar: prismicT.KeyTextField } 113 | > 114 | >({ 115 | slice_type: "string", 116 | slice_label: "string", 117 | primary: { 118 | foo: true, 119 | }, 120 | items: [ 121 | { 122 | bar: "string", 123 | // @ts-expect-error - Only given fields are valid. 124 | baz: false, 125 | }, 126 | ], 127 | }); 128 | 129 | /** 130 | * Custom item fields may only contain group-compatible fields. 131 | */ 132 | expectType< 133 | prismicT.Slice< 134 | string, 135 | { foo: prismicT.BooleanField }, 136 | // @ts-expect-error - Groups are invalid within item fields. 137 | { 138 | group: prismicT.GroupField; 139 | } 140 | > 141 | >({ 142 | slice_type: "string", 143 | slice_label: "string", 144 | primary: { 145 | foo: true, 146 | }, 147 | items: [], 148 | }); 149 | expectType< 150 | prismicT.Slice< 151 | string, 152 | { foo: prismicT.BooleanField }, 153 | // @ts-expect-error - Slice Zones are invalid within item fields. 154 | { 155 | sliceZone: prismicT.SliceZone; 156 | } 157 | > 158 | >({ 159 | slice_type: "string", 160 | slice_label: "string", 161 | primary: { 162 | foo: true, 163 | }, 164 | items: [], 165 | }); 166 | -------------------------------------------------------------------------------- /test/customType-sharedSliceModelVariation.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicTI from "@prismicio/types-internal"; 4 | 5 | import * as prismicT from "../src"; 6 | 7 | (value: prismicT.SharedSliceModelVariation): true => { 8 | switch (typeof value) { 9 | case "object": { 10 | if (value === null) { 11 | expectNever(value); 12 | } 13 | 14 | return true; 15 | } 16 | 17 | default: { 18 | return expectNever(value); 19 | } 20 | } 21 | }; 22 | 23 | expectType({ 24 | id: "string", 25 | name: "string", 26 | docURL: "string", 27 | version: "string", 28 | description: "string", 29 | primary: { 30 | foo: { 31 | type: prismicT.CustomTypeModelFieldType.Boolean, 32 | config: { 33 | label: "string", 34 | }, 35 | }, 36 | }, 37 | items: { 38 | foo: { 39 | type: prismicT.CustomTypeModelFieldType.Boolean, 40 | config: { 41 | label: "string", 42 | }, 43 | }, 44 | }, 45 | imageUrl: "string", 46 | }); 47 | 48 | /** 49 | * Supports custom ID. 50 | */ 51 | expectType>({ 52 | id: "foo", 53 | name: "string", 54 | docURL: "string", 55 | version: "string", 56 | description: "string", 57 | primary: {}, 58 | items: {}, 59 | imageUrl: "string", 60 | }); 61 | expectType>({ 62 | // @ts-expect-error - Slice ID must match the given ID. 63 | id: "string", 64 | name: "string", 65 | docURL: "string", 66 | version: "string", 67 | description: "string", 68 | primary: {}, 69 | items: {}, 70 | imageUrl: "string", 71 | }); 72 | 73 | /** 74 | * Supports custom primary fields. 75 | */ 76 | expectType< 77 | prismicT.SharedSliceModelVariation< 78 | string, 79 | { foo: prismicT.CustomTypeModelBooleanField } 80 | > 81 | >({ 82 | id: "foo", 83 | name: "string", 84 | docURL: "string", 85 | version: "string", 86 | description: "string", 87 | primary: { 88 | foo: { 89 | type: prismicT.CustomTypeModelFieldType.Boolean, 90 | config: { 91 | label: "string", 92 | }, 93 | }, 94 | // @ts-expect-error - Only given fields are valid. 95 | bar: { 96 | type: prismicT.CustomTypeModelFieldType.Boolean, 97 | config: { 98 | label: "string", 99 | }, 100 | }, 101 | }, 102 | items: {}, 103 | imageUrl: "string", 104 | }); 105 | 106 | /** 107 | * Supports custom items fields. 108 | */ 109 | expectType< 110 | prismicT.SharedSliceModelVariation< 111 | string, 112 | Record, 113 | { foo: prismicT.CustomTypeModelBooleanField } 114 | > 115 | >({ 116 | id: "foo", 117 | name: "string", 118 | docURL: "string", 119 | version: "string", 120 | description: "string", 121 | primary: {}, 122 | items: { 123 | foo: { 124 | type: prismicT.CustomTypeModelFieldType.Boolean, 125 | config: { 126 | label: "string", 127 | }, 128 | }, 129 | // @ts-expect-error - Only given fields are valid. 130 | bar: { 131 | type: prismicT.CustomTypeModelFieldType.Boolean, 132 | config: { 133 | label: "string", 134 | }, 135 | }, 136 | }, 137 | imageUrl: "string", 138 | }); 139 | 140 | /** 141 | * `@prismicio/types` extends `@prismicio/types-internal` 142 | */ 143 | expectType( 144 | {} as prismicTI.CustomTypes.Widgets.Slices.Variation, 145 | ); 146 | 147 | /** 148 | * `@prismicio/types-internal` extends `@prismicio/types` 149 | */ 150 | expectType( 151 | {} as prismicT.SharedSliceModelVariation, 152 | ); 153 | -------------------------------------------------------------------------------- /test/fields-embed.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.EmbedField): true => { 6 | switch (typeof value) { 7 | case "object": { 8 | if (value === null) { 9 | expectNever(value); 10 | } 11 | 12 | return true; 13 | } 14 | 15 | default: { 16 | return expectNever(value); 17 | } 18 | } 19 | }; 20 | 21 | /** 22 | * `EmbedType` keeps compatibility with other versions. 23 | * 24 | * @see Related issue {@link https://github.com/prismicio/prismic-types/issues/16} 25 | */ 26 | const ForeignEmbedType = { 27 | Link: "link", 28 | Breaking: "breaking", 29 | } as const; 30 | expectType(ForeignEmbedType.Link); 31 | expectType( 32 | // @ts-expect-error - `EmbedType` should still fail with breaking changes 33 | ForeignEmbedType.Breaking, 34 | ); 35 | 36 | /** 37 | * Filled state. 38 | */ 39 | expectType({ 40 | embed_url: "https://example.com", 41 | type: prismicT.OEmbedType.Link, 42 | version: "1.0", 43 | title: null, 44 | author_name: null, 45 | author_url: null, 46 | provider_name: null, 47 | provider_url: null, 48 | cache_age: null, 49 | thumbnail_url: null, 50 | thumbnail_width: null, 51 | thumbnail_height: null, 52 | html: null, 53 | }); 54 | expectType>({ 55 | embed_url: "https://example.com", 56 | type: prismicT.OEmbedType.Link, 57 | version: "1.0", 58 | html: null, 59 | }); 60 | expectType>({ 61 | // @ts-expect-error - Empty fields cannot contain a filled value. 62 | embed_url: "https://example.com", 63 | // @ts-expect-error - Empty fields cannot contain a filled value. 64 | type: prismicT.OEmbedType.Link, 65 | // @ts-expect-error - Empty fields cannot contain a filled value. 66 | version: "1.0", 67 | // @ts-expect-error - Empty fields cannot contain a filled value. 68 | html: null, 69 | }); 70 | 71 | /** 72 | * Empty state. 73 | */ 74 | expectType({}); 75 | expectType>({}); 76 | expectType>( 77 | // @ts-expect-error - Filled fields cannot contain an empty value. 78 | {}, 79 | ); 80 | 81 | /** 82 | * Includes common oEmbed data by default. 83 | */ 84 | expectType({ 85 | embed_url: "https://example.com", 86 | type: prismicT.OEmbedType.Link, 87 | version: "1.0", 88 | title: "title", 89 | author_name: "author_name", 90 | author_url: "author_url", 91 | provider_name: "provider_name", 92 | provider_url: "provider_url", 93 | cache_age: 42, 94 | thumbnail_url: "thumbnail_url", 95 | thumbnail_width: 666, 96 | thumbnail_height: 999, 97 | html: "html", 98 | }); 99 | 100 | /** 101 | * Supports unknown keys by default. 102 | */ 103 | expectType({ 104 | embed_url: "https://example.com", 105 | type: prismicT.OEmbedType.Link, 106 | version: "1.0", 107 | title: null, 108 | author_name: null, 109 | author_url: null, 110 | provider_name: null, 111 | provider_url: null, 112 | cache_age: null, 113 | thumbnail_url: null, 114 | thumbnail_width: null, 115 | thumbnail_height: null, 116 | html: null, 117 | unknown_key: "string", 118 | }); 119 | 120 | /** 121 | * Supports custom oEmbed data. 122 | */ 123 | expectType>({ 124 | embed_url: "https://example.com", 125 | type: prismicT.OEmbedType.Link, 126 | version: "1.0", 127 | html: null, 128 | foo: "bar", 129 | }); 130 | 131 | /** 132 | * Gives priority to custom oEmbed data. 133 | */ 134 | expectType>({ 135 | embed_url: "https://example.com", 136 | type: prismicT.OEmbedType.Link, 137 | version: "1.0", 138 | html: null, 139 | // @ts-expect-error - Now expects `foo` to be `"bar"`. 140 | foo: "baz", 141 | }); 142 | -------------------------------------------------------------------------------- /test/fields-link.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.LinkField): true => { 6 | switch (typeof value) { 7 | case "object": { 8 | if (value === null) { 9 | return expectNever(value); 10 | } 11 | 12 | return true; 13 | } 14 | 15 | default: { 16 | return expectNever(value); 17 | } 18 | } 19 | }; 20 | 21 | /** 22 | * `LinkType` keeps compatibility with other versions. 23 | * 24 | * @see Related issue {@link https://github.com/prismicio/prismic-types/issues/16} 25 | */ 26 | const ForeignLinkType = { 27 | Document: "Document", 28 | Breaking: "Breaking", 29 | } as const; 30 | expectType(ForeignLinkType.Document); 31 | expectType( 32 | // @ts-expect-error - `LinkType` should still fail with breaking changes 33 | ForeignLinkType.Breaking, 34 | ); 35 | 36 | /** 37 | * Filled state. 38 | */ 39 | // Web link 40 | expectType({ 41 | link_type: prismicT.LinkType.Web, 42 | url: "string", 43 | target: "string", 44 | }); 45 | // Content relationship link 46 | expectType({ 47 | link_type: prismicT.LinkType.Document, 48 | id: "string", 49 | uid: "string", 50 | type: "string", 51 | tags: ["string"], 52 | lang: "string", 53 | url: "string", 54 | slug: "string", 55 | isBroken: true, 56 | data: undefined, 57 | }); 58 | // Media link 59 | expectType({ 60 | link_type: prismicT.LinkType.Media, 61 | name: "string", 62 | kind: "string", 63 | url: "string", 64 | size: "string", 65 | height: "string", 66 | width: "string", 67 | }); 68 | expectType>({ 69 | link_type: prismicT.LinkType.Web, 70 | url: "string", 71 | target: "string", 72 | }); 73 | expectType>({ 74 | link_type: prismicT.LinkType.Web, 75 | // @ts-expect-error - Empty fields cannot contain a filled value. 76 | url: "string", 77 | target: "string", 78 | }); 79 | 80 | /** 81 | * Empty state. 82 | */ 83 | expectType({ 84 | link_type: prismicT.LinkType.Any, 85 | }); 86 | expectType>({ 87 | link_type: prismicT.LinkType.Any, 88 | }); 89 | expectType>({ 90 | // @ts-expect-error - Filled fields cannot contain an empty value. 91 | link_type: prismicT.LinkType.Any, 92 | }); 93 | 94 | /** 95 | * Supports custom document type for document links. 96 | */ 97 | expectType>({ 98 | link_type: prismicT.LinkType.Document, 99 | id: "string", 100 | type: "foo", 101 | tags: [], 102 | lang: "string", 103 | }); 104 | expectType>({ 105 | link_type: prismicT.LinkType.Document, 106 | id: "string", 107 | // @ts-expect-error - Document type must match the given type. 108 | type: "string", 109 | tags: [], 110 | lang: "string", 111 | }); 112 | 113 | /** 114 | * Supports custom document language for document links. 115 | */ 116 | expectType>({ 117 | link_type: prismicT.LinkType.Document, 118 | id: "string", 119 | type: "string", 120 | tags: [], 121 | lang: "fr-fr", 122 | }); 123 | expectType>({ 124 | link_type: prismicT.LinkType.Document, 125 | id: "string", 126 | type: "string", 127 | tags: [], 128 | // @ts-expect-error - Document language must match the given type. 129 | lang: "string", 130 | }); 131 | 132 | /** 133 | * Supports custom document data for document links. 134 | */ 135 | expectType>({ 136 | link_type: prismicT.LinkType.Document, 137 | id: "string", 138 | type: "string", 139 | tags: [], 140 | lang: "fr-fr", 141 | data: { 142 | foo: true, 143 | // @ts-expect-error - Only given fields are valid. 144 | bar: false, 145 | }, 146 | }); 147 | -------------------------------------------------------------------------------- /test/document-prismicDocument.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.PrismicDocument): true => { 6 | switch (typeof value) { 7 | case "object": { 8 | if (value === null) { 9 | expectNever(value); 10 | } 11 | 12 | return true; 13 | } 14 | 15 | default: { 16 | return expectNever(value); 17 | } 18 | } 19 | }; 20 | 21 | expectType({ 22 | id: "string", 23 | uid: "string", 24 | url: "string", 25 | type: "string", 26 | href: "string", 27 | tags: ["string"], 28 | first_publication_date: "string", 29 | last_publication_date: "string", 30 | slugs: ["string"], 31 | linked_documents: [], 32 | lang: "string", 33 | alternate_languages: [ 34 | { 35 | id: "string", 36 | lang: "string", 37 | type: "string", 38 | uid: "string", 39 | }, 40 | ], 41 | data: {}, 42 | }); 43 | 44 | /** 45 | * Supports nullable UID and URL. 46 | */ 47 | expectType({ 48 | id: "string", 49 | uid: null, 50 | url: null, 51 | type: "string", 52 | href: "string", 53 | tags: [], 54 | first_publication_date: "string", 55 | last_publication_date: "string", 56 | slugs: [], 57 | linked_documents: [], 58 | lang: "string", 59 | alternate_languages: [], 60 | data: {}, 61 | }); 62 | 63 | /** 64 | * Supports custom data interface. 65 | */ 66 | expectType>({ 67 | id: "string", 68 | uid: "string", 69 | url: "string", 70 | type: "string", 71 | href: "string", 72 | tags: [], 73 | first_publication_date: "string", 74 | last_publication_date: "string", 75 | slugs: [], 76 | linked_documents: [], 77 | lang: "string", 78 | alternate_languages: [], 79 | data: { 80 | foo: true, 81 | // @ts-expect-error - Only given fields are valid. 82 | bar: false, 83 | }, 84 | }); 85 | 86 | /** 87 | * Custom data interface supports Group and Slice Zone fields. 88 | */ 89 | expectType< 90 | prismicT.PrismicDocument<{ 91 | group: prismicT.GroupField; 92 | sliceZone: prismicT.SliceZone; 93 | }> 94 | >({ 95 | id: "string", 96 | uid: "string", 97 | url: "string", 98 | type: "string", 99 | href: "string", 100 | tags: [], 101 | first_publication_date: "string", 102 | last_publication_date: "string", 103 | slugs: [], 104 | linked_documents: [], 105 | lang: "string", 106 | alternate_languages: [], 107 | data: { 108 | group: [], 109 | sliceZone: [], 110 | }, 111 | }); 112 | 113 | /** 114 | * Supports custom type. 115 | */ 116 | expectType, "foo">>({ 117 | id: "string", 118 | uid: "string", 119 | url: "string", 120 | type: "foo", 121 | href: "string", 122 | tags: [], 123 | first_publication_date: "string", 124 | last_publication_date: "string", 125 | slugs: [], 126 | linked_documents: [], 127 | lang: "string", 128 | alternate_languages: [], 129 | data: {}, 130 | }); 131 | expectType, "foo">>({ 132 | id: "string", 133 | uid: "string", 134 | url: "string", 135 | // @ts-expect-error - Document type must match the given type. 136 | type: "string", 137 | href: "string", 138 | tags: [], 139 | first_publication_date: "string", 140 | last_publication_date: "string", 141 | slugs: [], 142 | linked_documents: [], 143 | lang: "string", 144 | alternate_languages: [], 145 | data: {}, 146 | }); 147 | 148 | /** 149 | * Supports custom language. 150 | */ 151 | expectType, string, "fr-fr">>({ 152 | id: "string", 153 | uid: "string", 154 | url: "string", 155 | type: "foo", 156 | href: "string", 157 | tags: [], 158 | first_publication_date: "string", 159 | last_publication_date: "string", 160 | slugs: [], 161 | linked_documents: [], 162 | lang: "fr-fr", 163 | alternate_languages: [], 164 | data: {}, 165 | }); 166 | expectType, string, "fr-fr">>({ 167 | id: "string", 168 | uid: "string", 169 | url: "string", 170 | type: "string", 171 | href: "string", 172 | tags: [], 173 | first_publication_date: "string", 174 | last_publication_date: "string", 175 | slugs: [], 176 | linked_documents: [], 177 | // @ts-expect-error - Document lang must match the given language. 178 | lang: "string", 179 | alternate_languages: [], 180 | data: {}, 181 | }); 182 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > **Note**: **This package has been merged into [`@prismicio/client`](https://github.com/prismicio/prismic-client) ≥ v7.** 2 | > 3 | > This package and repository will no longer be updated, except in special circumstances. 4 | 5 | # @prismicio/types 6 | 7 | [![npm version][npm-version-src]][npm-version-href] 8 | [![npm downloads][npm-downloads-src]][npm-downloads-href] 9 | [![Github Actions CI][github-actions-ci-src]][github-actions-ci-href] 10 | [![Codecov][codecov-src]][codecov-href] 11 | [![Conventional Commits][conventional-commits-src]][conventional-commits-href] 12 | [![License][license-src]][license-href] 13 | 14 | > ⚠ This project is in an experimental state and therefore primarily meant to be used by Prismic kits. Use it at your own risks or stay tuned for the official release! 15 | 16 | Type definitions for [Prismic][prismic] related structure. 17 | 18 | - 📄  Per-field type definitions; 19 | - 🌐  Dedicated GraphQL API support. 20 | 21 | ## Install 22 | 23 | ```bash 24 | npm install --save-dev @prismicio/types 25 | ``` 26 | 27 | ## Documentation 28 | 29 | To discover what's new on this package check out [the changelog][changelog]. For full documentation, visit the [official Prismic documentation][prismic-docs]. 30 | 31 | ## Contributing 32 | 33 | Whether you're helping us fix bugs, improve the docs, or spread the word, we'd love to have you as part of the Prismic developer community! 34 | 35 | **Asking a question**: [Open a new topic][forum-question] on our community forum explaining what you want to achieve / your question. Our support team will get back to you shortly. 36 | 37 | **Reporting a bug**: [Open an issue][repo-bug-report] explaining your application's setup and the bug you're encountering. 38 | 39 | **Suggesting an improvement**: [Open an issue][repo-feature-request] explaining your improvement or feature so we can discuss and learn more. 40 | 41 | **Submitting code changes**: For small fixes, feel free to [open a pull request][repo-pull-requests] with a description of your changes. For large changes, please first [open an issue][repo-feature-request] so we can discuss if and how the changes should be implemented. 42 | 43 | For more clarity on this project and its structure you can also check out the detailed [CONTRIBUTING.md][contributing] document. 44 | 45 | ## License 46 | 47 | ``` 48 | Copyright 2013-2022 Prismic (https://prismic.io) 49 | 50 | Licensed under the Apache License, Version 2.0 (the "License"); 51 | you may not use this file except in compliance with the License. 52 | You may obtain a copy of the License at 53 | 54 | http://www.apache.org/licenses/LICENSE-2.0 55 | 56 | Unless required by applicable law or agreed to in writing, software 57 | distributed under the License is distributed on an "AS IS" BASIS, 58 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 59 | See the License for the specific language governing permissions and 60 | limitations under the License. 61 | ``` 62 | 63 | 64 | 65 | [prismic]: https://prismic.io 66 | [prismic-docs]: https://prismic.io/docs/technologies/javascript 67 | [changelog]: ./CHANGELOG.md 68 | [contributing]: ./CONTRIBUTING.md 69 | [forum-question]: https://community.prismic.io/c/kits-and-dev-languages/javascript/14 70 | [repo-bug-report]: https://github.com/prismicio/prismic-types/issues/new?assignees=&labels=bug&template=bug_report.md&title= 71 | [repo-feature-request]: https://github.com/prismicio/prismic-types/issues/new?assignees=&labels=enhancement&template=feature_request.md&title= 72 | [repo-pull-requests]: https://github.com/prismicio/prismic-types/pulls 73 | 74 | 75 | 76 | [npm-version-src]: https://img.shields.io/npm/v/@prismicio/types/latest.svg 77 | [npm-version-href]: https://npmjs.com/package/@prismicio/types 78 | [npm-downloads-src]: https://img.shields.io/npm/dm/@prismicio/types.svg 79 | [npm-downloads-href]: https://npmjs.com/package/@prismicio/types 80 | [github-actions-ci-src]: https://github.com/prismicio/prismic-types/workflows/ci/badge.svg 81 | [github-actions-ci-href]: https://github.com/prismicio/prismic-types/actions?query=workflow%3Aci 82 | [codecov-src]: https://img.shields.io/codecov/c/github/prismicio/prismic-types.svg 83 | [codecov-href]: https://codecov.io/gh/prismicio/prismic-types 84 | [conventional-commits-src]: https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg 85 | [conventional-commits-href]: https://conventionalcommits.org 86 | [license-src]: https://img.shields.io/npm/l/@prismicio/types.svg 87 | [license-href]: https://npmjs.com/package/@prismicio/types 88 | -------------------------------------------------------------------------------- /src/value/document.ts: -------------------------------------------------------------------------------- 1 | import { AnyRegularField } from "./types"; 2 | import { GroupField } from "./group"; 3 | import { SliceZone } from "./sliceZone"; 4 | 5 | /** 6 | * Document metadata for a translation of a Prismic document. 7 | */ 8 | export interface AlternateLanguage { 9 | id: string; 10 | uid?: string; 11 | type: TypeEnum; 12 | lang: LangEnum; 13 | } 14 | 15 | /** 16 | * Metadata for Prismic Document 17 | */ 18 | export interface PrismicDocumentHeader { 19 | /** 20 | * The unique identifier for the document. Guaranteed to be unique among all 21 | * documents in the Prismic repository. 22 | */ 23 | id: string; 24 | /** 25 | * The unique identifier for the document. Guaranteed to be unique among all 26 | * Prismic documents of the same type. 27 | */ 28 | uid: string | null; 29 | /** 30 | * Url that refers to document. 31 | */ 32 | url: string | null; 33 | /** 34 | * Type of the document. 35 | */ 36 | type: TypeEnum; 37 | /** 38 | * Href for document. 39 | */ 40 | href: string; 41 | /** 42 | * Tags associated with document. 43 | */ 44 | tags: string[]; 45 | /** 46 | * The timestamp at which the document was first published. 47 | */ 48 | first_publication_date: string; 49 | /** 50 | * The timestamp at which the document was last published. 51 | */ 52 | last_publication_date: string; 53 | /** 54 | * Slugs associated with document. 55 | * 56 | * @deprecated Slugs are a deprecated feature used before the UID field was 57 | * introduced. Migrate to the UID field. For more details, see 58 | * https://community.prismic.io/t/what-are-slugs/6493 59 | */ 60 | slugs: string[]; 61 | /** 62 | * Documents that are related to this document. 63 | */ 64 | linked_documents: unknown[]; // TODO: Not sure of the type for this one 65 | /** 66 | * Language of document. 67 | */ 68 | lang: LangEnum; 69 | /** 70 | * Array to access alternate language versions for document. 71 | */ 72 | alternate_languages: AlternateLanguage[]; 73 | } 74 | 75 | /** 76 | * A Prismic document served through REST API v2. 77 | * 78 | * @see More details on Custom Types: {@link https://prismic.io/docs/technologies/introduction-to-the-content-query-api} 79 | */ 80 | export interface PrismicDocument< 81 | DataInterface extends Record< 82 | string, 83 | AnyRegularField | GroupField | SliceZone 84 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 85 | > = Record, 86 | TypeEnum = string, 87 | LangEnum = string, 88 | > extends PrismicDocumentHeader { 89 | /** 90 | * Data contained in the document. 91 | */ 92 | data: DataInterface; 93 | } 94 | 95 | /** 96 | * A Prismic document served through REST API v2. Does not contain a UID (a 97 | * unique identifier). 98 | * 99 | * @see More details on Custom Types: {@link https://prismic.io/docs/technologies/introduction-to-the-content-query-api} 100 | * @see More details on the UID field: {@link https://prismic.io/docs/core-concepts/uid} 101 | */ 102 | export interface PrismicDocumentWithoutUID< 103 | DataInterface extends Record< 104 | string, 105 | AnyRegularField | GroupField | SliceZone 106 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 107 | > = Record, 108 | TypeEnum = string, 109 | LangEnum = string, 110 | > extends PrismicDocument { 111 | /** 112 | * This document does not have a UID field. This property will always be 113 | * `null`. 114 | * 115 | * The unique identifier for the document. Guaranteed to be unique among all 116 | * Prismic documents of the same type. 117 | */ 118 | uid: null; 119 | } 120 | 121 | /** 122 | * A Prismic document served through REST API v2. Contains a UID (a unique 123 | * identifier). 124 | * 125 | * @see More details on Custom Types: {@link https://prismic.io/docs/technologies/introduction-to-the-content-query-api} 126 | * @see More details on the UID field: {@link https://prismic.io/docs/core-concepts/uid} 127 | */ 128 | export interface PrismicDocumentWithUID< 129 | DataInterface extends Record< 130 | string, 131 | AnyRegularField | GroupField | SliceZone 132 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 133 | > = Record, 134 | TypeEnum = string, 135 | LangEnum = string, 136 | > extends PrismicDocument { 137 | /** 138 | * The unique identifier for the document. Guaranteed to be unique among all 139 | * Prismic documents of the same type. 140 | */ 141 | uid: string; 142 | } 143 | -------------------------------------------------------------------------------- /test/fields-title.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.TitleField): true => { 6 | if (!Array.isArray(value)) { 7 | return expectNever(value); 8 | } 9 | 10 | switch (typeof value[0]) { 11 | case "object": { 12 | if (value[0] === null) { 13 | expectNever(value[0]); 14 | } 15 | 16 | return true; 17 | } 18 | 19 | // When the field is empty, value[0] is undefined. 20 | case "undefined": { 21 | return true; 22 | } 23 | 24 | default: { 25 | return expectNever(value[0]); 26 | } 27 | } 28 | }; 29 | 30 | /** 31 | * Filled state. 32 | */ 33 | expectType([ 34 | { 35 | type: prismicT.RichTextNodeType.heading1, 36 | text: "string", 37 | spans: [], 38 | }, 39 | ]); 40 | expectType>([ 41 | { 42 | type: prismicT.RichTextNodeType.heading1, 43 | text: "string", 44 | spans: [], 45 | }, 46 | ]); 47 | expectType>( 48 | // @ts-expect-error - Empty fields cannot contain a filled value. 49 | [ 50 | { 51 | type: prismicT.RichTextNodeType.heading1, 52 | text: "string", 53 | spans: [], 54 | }, 55 | ], 56 | ); 57 | 58 | /** 59 | * Empty state. 60 | */ 61 | expectType([]); 62 | expectType>([]); 63 | expectType>( 64 | // @ts-expect-error - Filled fields cannot contain an empty value. 65 | [], 66 | ); 67 | 68 | /** 69 | * Supports all heading Structured Text block types. 70 | */ 71 | expectType([ 72 | { type: prismicT.RichTextNodeType.heading1, text: "string", spans: [] }, 73 | ]); 74 | expectType([ 75 | { type: prismicT.RichTextNodeType.heading2, text: "string", spans: [] }, 76 | ]); 77 | expectType([ 78 | { type: prismicT.RichTextNodeType.heading3, text: "string", spans: [] }, 79 | ]); 80 | expectType([ 81 | { type: prismicT.RichTextNodeType.heading4, text: "string", spans: [] }, 82 | ]); 83 | expectType([ 84 | { type: prismicT.RichTextNodeType.heading5, text: "string", spans: [] }, 85 | ]); 86 | expectType([ 87 | { type: prismicT.RichTextNodeType.heading5, text: "string", spans: [] }, 88 | ]); 89 | 90 | /** 91 | * Does not allow non-heading Structured Text block types. 92 | */ 93 | expectType([ 94 | { 95 | // @ts-expect-error Not a heading block type. 96 | type: prismicT.RichTextNodeType.paragraph, 97 | }, 98 | ]); 99 | expectType([ 100 | { 101 | // @ts-expect-error Not a heading block type. 102 | type: prismicT.RichTextNodeType.preformatted, 103 | }, 104 | ]); 105 | expectType([ 106 | { 107 | // @ts-expect-error Not a heading block type. 108 | type: prismicT.RichTextNodeType.listItem, 109 | }, 110 | ]); 111 | expectType([ 112 | { 113 | // @ts-expect-error Not a heading block type. 114 | type: prismicT.RichTextNodeType.oListItem, 115 | }, 116 | ]); 117 | expectType([ 118 | { 119 | // @ts-expect-error Not a heading block type. 120 | type: prismicT.RichTextNodeType.image, 121 | }, 122 | ]); 123 | expectType([ 124 | { 125 | // @ts-expect-error Not a heading block type. 126 | type: prismicT.RichTextNodeType.embed, 127 | }, 128 | ]); 129 | expectType([ 130 | { 131 | // @ts-expect-error Not a heading block type. 132 | type: prismicT.RichTextNodeType.strong, 133 | }, 134 | ]); 135 | expectType([ 136 | { 137 | // @ts-expect-error Not a heading block type. 138 | type: prismicT.RichTextNodeType.em, 139 | }, 140 | ]); 141 | expectType([ 142 | { 143 | // @ts-expect-error Not a heading block type. 144 | type: prismicT.RichTextNodeType.label, 145 | }, 146 | ]); 147 | expectType([ 148 | { 149 | // @ts-expect-error Not a heading block type. 150 | type: prismicT.RichTextNodeType.hyperlink, 151 | }, 152 | ]); 153 | expectType([ 154 | { 155 | // @ts-expect-error - Not a root-label block type (meta block for internal use only). 156 | type: prismicT.RichTextNodeType.list, 157 | }, 158 | ]); 159 | expectType([ 160 | { 161 | // @ts-expect-error - Not a root-label block type (meta block for internal use only). 162 | type: prismicT.RichTextNodeType.oList, 163 | }, 164 | ]); 165 | 166 | /** 167 | * Does not allow spans elements. 168 | */ 169 | expectType([ 170 | { 171 | type: prismicT.RichTextNodeType.heading1, 172 | text: "string", 173 | // @ts-expect-error - Does not allow span elements. 174 | spans: [ 175 | { 176 | type: prismicT.RichTextNodeType.strong, 177 | start: 0, 178 | end: 1, 179 | }, 180 | ], 181 | }, 182 | ]); 183 | -------------------------------------------------------------------------------- /test/document-prismicDocumentWithUID.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.PrismicDocumentWithUID): true => { 6 | switch (typeof value) { 7 | case "object": { 8 | if (value === null) { 9 | expectNever(value); 10 | } 11 | 12 | return true; 13 | } 14 | 15 | default: { 16 | return expectNever(value); 17 | } 18 | } 19 | }; 20 | 21 | expectType({ 22 | id: "string", 23 | uid: "string", 24 | url: "string", 25 | type: "string", 26 | href: "string", 27 | tags: ["string"], 28 | first_publication_date: "string", 29 | last_publication_date: "string", 30 | slugs: ["string"], 31 | linked_documents: [], 32 | lang: "string", 33 | alternate_languages: [ 34 | { 35 | id: "string", 36 | lang: "string", 37 | type: "string", 38 | uid: "string", 39 | }, 40 | ], 41 | data: {}, 42 | }); 43 | 44 | /** 45 | * Does not support null UID value. 46 | */ 47 | expectType({ 48 | id: "string", 49 | // @ts-expect-error - Does not support string URL value. 50 | uid: null, 51 | url: "string", 52 | type: "string", 53 | href: "string", 54 | tags: [], 55 | first_publication_date: "string", 56 | last_publication_date: "string", 57 | slugs: [], 58 | linked_documents: [], 59 | lang: "string", 60 | alternate_languages: [], 61 | data: {}, 62 | }); 63 | 64 | /** 65 | * Supports nullable URL. 66 | */ 67 | expectType({ 68 | id: "string", 69 | uid: "string", 70 | url: null, 71 | type: "string", 72 | href: "string", 73 | tags: [], 74 | first_publication_date: "string", 75 | last_publication_date: "string", 76 | slugs: [], 77 | linked_documents: [], 78 | lang: "string", 79 | alternate_languages: [], 80 | data: {}, 81 | }); 82 | 83 | /** 84 | * Supports custom data interface. 85 | */ 86 | expectType>({ 87 | id: "string", 88 | uid: "string", 89 | url: "string", 90 | type: "string", 91 | href: "string", 92 | tags: [], 93 | first_publication_date: "string", 94 | last_publication_date: "string", 95 | slugs: [], 96 | linked_documents: [], 97 | lang: "string", 98 | alternate_languages: [], 99 | data: { 100 | foo: true, 101 | // @ts-expect-error - Only given fields are valid. 102 | bar: false, 103 | }, 104 | }); 105 | 106 | /** 107 | * Custom data interface supports Group and Slice Zone fields. 108 | */ 109 | expectType< 110 | prismicT.PrismicDocumentWithUID<{ 111 | group: prismicT.GroupField; 112 | sliceZone: prismicT.SliceZone; 113 | }> 114 | >({ 115 | id: "string", 116 | uid: "string", 117 | url: "string", 118 | type: "string", 119 | href: "string", 120 | tags: [], 121 | first_publication_date: "string", 122 | last_publication_date: "string", 123 | slugs: [], 124 | linked_documents: [], 125 | lang: "string", 126 | alternate_languages: [], 127 | data: { 128 | group: [], 129 | sliceZone: [], 130 | }, 131 | }); 132 | 133 | /** 134 | * Supports custom type. 135 | */ 136 | expectType, "foo">>({ 137 | id: "string", 138 | uid: "string", 139 | url: "string", 140 | type: "foo", 141 | href: "string", 142 | tags: [], 143 | first_publication_date: "string", 144 | last_publication_date: "string", 145 | slugs: [], 146 | linked_documents: [], 147 | lang: "string", 148 | alternate_languages: [], 149 | data: {}, 150 | }); 151 | expectType, "foo">>({ 152 | id: "string", 153 | uid: "string", 154 | url: "string", 155 | // @ts-expect-error - Document type must match the given type. 156 | type: "string", 157 | href: "string", 158 | tags: [], 159 | first_publication_date: "string", 160 | last_publication_date: "string", 161 | slugs: [], 162 | linked_documents: [], 163 | lang: "string", 164 | alternate_languages: [], 165 | data: {}, 166 | }); 167 | 168 | /** 169 | * Supports custom language. 170 | */ 171 | expectType< 172 | prismicT.PrismicDocumentWithUID, string, "fr-fr"> 173 | >({ 174 | id: "string", 175 | uid: "string", 176 | url: "string", 177 | type: "foo", 178 | href: "string", 179 | tags: [], 180 | first_publication_date: "string", 181 | last_publication_date: "string", 182 | slugs: [], 183 | linked_documents: [], 184 | lang: "fr-fr", 185 | alternate_languages: [], 186 | data: {}, 187 | }); 188 | expectType< 189 | prismicT.PrismicDocumentWithUID, string, "fr-fr"> 190 | >({ 191 | id: "string", 192 | uid: "string", 193 | url: "string", 194 | type: "string", 195 | href: "string", 196 | tags: [], 197 | first_publication_date: "string", 198 | last_publication_date: "string", 199 | slugs: [], 200 | linked_documents: [], 201 | // @ts-expect-error - Document lang must match the given language. 202 | lang: "string", 203 | alternate_languages: [], 204 | data: {}, 205 | }); 206 | -------------------------------------------------------------------------------- /test/document-prismicDocumentWithoutUID.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.PrismicDocumentWithoutUID): true => { 6 | switch (typeof value) { 7 | case "object": { 8 | if (value === null) { 9 | expectNever(value); 10 | } 11 | 12 | return true; 13 | } 14 | 15 | default: { 16 | return expectNever(value); 17 | } 18 | } 19 | }; 20 | 21 | expectType({ 22 | id: "string", 23 | uid: null, 24 | url: "string", 25 | type: "string", 26 | href: "string", 27 | tags: ["string"], 28 | first_publication_date: "string", 29 | last_publication_date: "string", 30 | slugs: ["string"], 31 | linked_documents: [], 32 | lang: "string", 33 | alternate_languages: [ 34 | { 35 | id: "string", 36 | lang: "string", 37 | type: "string", 38 | uid: "string", 39 | }, 40 | ], 41 | data: {}, 42 | }); 43 | 44 | /** 45 | * Does not support string UID value. 46 | */ 47 | expectType({ 48 | id: "string", 49 | // @ts-expect-error - Does not support string URL value. 50 | uid: "string", 51 | url: "string", 52 | type: "string", 53 | href: "string", 54 | tags: [], 55 | first_publication_date: "string", 56 | last_publication_date: "string", 57 | slugs: [], 58 | linked_documents: [], 59 | lang: "string", 60 | alternate_languages: [], 61 | data: {}, 62 | }); 63 | 64 | /** 65 | * Supports nullable URL. 66 | */ 67 | expectType({ 68 | id: "string", 69 | uid: null, 70 | url: null, 71 | type: "string", 72 | href: "string", 73 | tags: [], 74 | first_publication_date: "string", 75 | last_publication_date: "string", 76 | slugs: [], 77 | linked_documents: [], 78 | lang: "string", 79 | alternate_languages: [], 80 | data: {}, 81 | }); 82 | 83 | /** 84 | * Supports custom data interface. 85 | */ 86 | expectType>({ 87 | id: "string", 88 | uid: null, 89 | url: "string", 90 | type: "string", 91 | href: "string", 92 | tags: [], 93 | first_publication_date: "string", 94 | last_publication_date: "string", 95 | slugs: [], 96 | linked_documents: [], 97 | lang: "string", 98 | alternate_languages: [], 99 | data: { 100 | foo: true, 101 | // @ts-expect-error - Only given fields are valid. 102 | bar: false, 103 | }, 104 | }); 105 | 106 | /** 107 | * Custom data interface supports Group and Slice Zone fields. 108 | */ 109 | expectType< 110 | prismicT.PrismicDocumentWithoutUID<{ 111 | group: prismicT.GroupField; 112 | sliceZone: prismicT.SliceZone; 113 | }> 114 | >({ 115 | id: "string", 116 | uid: null, 117 | url: "string", 118 | type: "string", 119 | href: "string", 120 | tags: [], 121 | first_publication_date: "string", 122 | last_publication_date: "string", 123 | slugs: [], 124 | linked_documents: [], 125 | lang: "string", 126 | alternate_languages: [], 127 | data: { 128 | group: [], 129 | sliceZone: [], 130 | }, 131 | }); 132 | 133 | /** 134 | * Supports custom type. 135 | */ 136 | expectType, "foo">>({ 137 | id: "string", 138 | uid: null, 139 | url: "string", 140 | type: "foo", 141 | href: "string", 142 | tags: [], 143 | first_publication_date: "string", 144 | last_publication_date: "string", 145 | slugs: [], 146 | linked_documents: [], 147 | lang: "string", 148 | alternate_languages: [], 149 | data: {}, 150 | }); 151 | expectType, "foo">>({ 152 | id: "string", 153 | uid: null, 154 | url: "string", 155 | // @ts-expect-error - Document type must match the given type. 156 | type: "string", 157 | href: "string", 158 | tags: [], 159 | first_publication_date: "string", 160 | last_publication_date: "string", 161 | slugs: [], 162 | linked_documents: [], 163 | lang: "string", 164 | alternate_languages: [], 165 | data: {}, 166 | }); 167 | 168 | /** 169 | * Supports custom language. 170 | */ 171 | expectType< 172 | prismicT.PrismicDocumentWithoutUID, string, "fr-fr"> 173 | >({ 174 | id: "string", 175 | uid: null, 176 | url: "string", 177 | type: "foo", 178 | href: "string", 179 | tags: [], 180 | first_publication_date: "string", 181 | last_publication_date: "string", 182 | slugs: [], 183 | linked_documents: [], 184 | lang: "fr-fr", 185 | alternate_languages: [], 186 | data: {}, 187 | }); 188 | expectType< 189 | prismicT.PrismicDocumentWithoutUID, string, "fr-fr"> 190 | >({ 191 | id: "string", 192 | uid: null, 193 | url: "string", 194 | type: "string", 195 | href: "string", 196 | tags: [], 197 | first_publication_date: "string", 198 | last_publication_date: "string", 199 | slugs: [], 200 | linked_documents: [], 201 | // @ts-expect-error - Document lang must match the given language. 202 | lang: "string", 203 | alternate_languages: [], 204 | data: {}, 205 | }); 206 | -------------------------------------------------------------------------------- /src/value/embed.ts: -------------------------------------------------------------------------------- 1 | import type { EmptyObjectField, FieldState } from "./types"; 2 | 3 | /** 4 | * oEmbed 1.0 possible types. 5 | * 6 | * @see oEmbed specification: {@link https://oembed.com} 7 | */ 8 | export const OEmbedType = { 9 | Photo: "photo", 10 | Video: "video", 11 | Link: "link", 12 | Rich: "rich", 13 | } as const; 14 | 15 | /** 16 | * oEmbed response base fields. Those are every mandatory fields an oEmbed 17 | * response must feature. 18 | * 19 | * @see oEmbed specification: {@link https://oembed.com} 20 | */ 21 | type OEmbedBase = { 22 | /** 23 | * oEmbed resource type. 24 | */ 25 | type: TType; 26 | 27 | /** 28 | * oEmbed version number, this must be "1.0". 29 | */ 30 | version: string; 31 | }; 32 | 33 | /** 34 | * oEmbed response extra fields. Those are every non-mandatory and unknown 35 | * fields an oEmbed response can feature. 36 | * 37 | * @see oEmbed specification: {@link https://oembed.com} 38 | */ 39 | export type OEmbedExtra = { 40 | /** 41 | * oEmbed text title, describing the resource. 42 | */ 43 | title?: string | null; 44 | 45 | /** 46 | * oEmbed resource author/owner name. 47 | */ 48 | author_name?: string | null; 49 | 50 | /** 51 | * oEmbed resource author/owner URL. 52 | */ 53 | author_url?: string | null; 54 | 55 | /** 56 | * oEmbed resource provider name. 57 | */ 58 | provider_name?: string | null; 59 | 60 | /** 61 | * oEmbed resource provider URL. 62 | */ 63 | provider_url?: string | null; 64 | 65 | /** 66 | * oEmbed suggested cache lifetime for the resource, in seconds. 67 | */ 68 | cache_age?: number | null; 69 | 70 | /** 71 | * oEmbed resource thumbnail URL. 72 | */ 73 | thumbnail_url?: string | null; 74 | 75 | /** 76 | * oEmbed resource thumbnail width. 77 | */ 78 | thumbnail_width?: number | null; 79 | 80 | /** 81 | * oEmbed resource thumbnail height. 82 | */ 83 | thumbnail_height?: number | null; 84 | 85 | /** 86 | * Providers may optionally include any parameters not specified in this 87 | * document (so long as they use the same key-value format) and consumers may 88 | * choose to ignore these. Consumers must ignore parameters they do not 89 | * understand. 90 | * 91 | * @see oEmbed specification: {@link https://oembed.com} 92 | */ 93 | [key: string]: unknown | null; 94 | }; 95 | 96 | /** 97 | * oEmbed photo type. Those are every mandatory fields an oEmbed photo response 98 | * must feature. 99 | * 100 | * @see oEmbed specification: {@link https://oembed.com} 101 | */ 102 | export type PhotoOEmbed = OEmbedBase & { 103 | /** 104 | * oEmbed source URL of the image. 105 | */ 106 | url: string; 107 | 108 | /** 109 | * oEmbed width in pixels of the image. 110 | */ 111 | width: number; 112 | 113 | /** 114 | * oEmbed height in pixels of the image. 115 | */ 116 | height: number; 117 | }; 118 | 119 | /** 120 | * oEmbed video type. Those are every mandatory fields an oEmbed video response 121 | * must feature. 122 | * 123 | * @see oEmbed specification: {@link https://oembed.com} 124 | */ 125 | export type VideoOEmbed = OEmbedBase & { 126 | /** 127 | * oEmbed HTML required to embed a video player. 128 | */ 129 | html: string; 130 | 131 | /** 132 | * oEmbed width in pixels required to display the HTML. 133 | */ 134 | width: number; 135 | 136 | /** 137 | * oEmbed height in pixels required to display the HTML. 138 | */ 139 | height: number; 140 | }; 141 | 142 | /** 143 | * oEmbed link type. Those are every mandatory fields an oEmbed link response 144 | * must feature. 145 | * 146 | * @see oEmbed specification: {@link https://oembed.com} 147 | */ 148 | export type LinkOEmbed = OEmbedBase; 149 | 150 | /** 151 | * oEmbed rich type. Those are every mandatory fields an oEmbed rich response 152 | * must feature. 153 | * 154 | * @see oEmbed specification: {@link https://oembed.com} 155 | */ 156 | export type RichOEmbed = OEmbedBase & { 157 | /** 158 | * oEmbed HTML required to display the resource. 159 | */ 160 | html: string; 161 | 162 | /** 163 | * oEmbed width in pixels required to display the HTML. 164 | */ 165 | width: number; 166 | 167 | /** 168 | * oEmbed height in pixels required to display the HTML. 169 | */ 170 | height: number; 171 | }; 172 | 173 | /** 174 | * Any of the possible types of oEmbed response. Those contains only mandatory 175 | * fields their respective oEmbed response type must feature. 176 | * 177 | * @see oEmbed specification: {@link https://oembed.com} 178 | */ 179 | export type AnyOEmbed = PhotoOEmbed | VideoOEmbed | LinkOEmbed | RichOEmbed; 180 | 181 | /** 182 | * An Embed field. 183 | * 184 | * @typeParam Data - Data provided by the URL's oEmbed provider. 185 | * @typeParam State - State of the field which determines its shape. 186 | * @see More details: {@link https://prismic.io/docs/core-concepts/embed} 187 | */ 188 | export type EmbedField< 189 | Data extends AnyOEmbed = AnyOEmbed & OEmbedExtra, 190 | State extends FieldState = FieldState, 191 | > = State extends "empty" 192 | ? EmptyObjectField 193 | : Data & { 194 | embed_url: string; 195 | html: string | null; 196 | }; 197 | -------------------------------------------------------------------------------- /test/fields-richText.types.ts: -------------------------------------------------------------------------------- 1 | import { expectType, expectNever } from "ts-expect"; 2 | 3 | import * as prismicT from "../src"; 4 | 5 | (value: prismicT.RichTextField): true => { 6 | if (!Array.isArray(value)) { 7 | return expectNever(value); 8 | } 9 | 10 | switch (typeof value[0]) { 11 | case "object": { 12 | if (value[0] === null) { 13 | expectNever(value[0]); 14 | } 15 | 16 | return true; 17 | } 18 | 19 | // When the field is empty, value[0] is undefined. 20 | case "undefined": { 21 | return true; 22 | } 23 | 24 | default: { 25 | return expectNever(value[0]); 26 | } 27 | } 28 | }; 29 | 30 | /** 31 | * `RichTextNodeType` keeps compatibility with other versions. 32 | * 33 | * @see Related issue {@link https://github.com/prismicio/prismic-types/issues/16} 34 | */ 35 | const ForeignRichTextNodeType = { 36 | heading1: "heading1", 37 | breaking: "breaking", 38 | } as const; 39 | expectType( 40 | ForeignRichTextNodeType.heading1, 41 | ); 42 | expectType( 43 | // @ts-expect-error - `RichTextNodeType` should still fail with breaking changes 44 | ForeignRichTextNodeType.breaking, 45 | ); 46 | 47 | /** 48 | * Filled state. 49 | */ 50 | expectType([ 51 | { 52 | type: prismicT.RichTextNodeType.paragraph, 53 | text: "string", 54 | spans: [ 55 | { 56 | type: prismicT.RichTextNodeType.strong, 57 | start: 0, 58 | end: 1, 59 | }, 60 | ], 61 | }, 62 | ]); 63 | expectType>([ 64 | { 65 | type: prismicT.RichTextNodeType.paragraph, 66 | text: "string", 67 | spans: [ 68 | { 69 | type: prismicT.RichTextNodeType.strong, 70 | start: 0, 71 | end: 1, 72 | }, 73 | ], 74 | }, 75 | ]); 76 | expectType>( 77 | // @ts-expect-error - Empty fields cannot contain a filled value. 78 | [ 79 | { 80 | type: prismicT.RichTextNodeType.paragraph, 81 | text: "string", 82 | spans: [ 83 | { 84 | type: prismicT.RichTextNodeType.strong, 85 | start: 0, 86 | end: 1, 87 | }, 88 | ], 89 | }, 90 | ], 91 | ); 92 | 93 | /** 94 | * Empty state. 95 | */ 96 | expectType([]); 97 | expectType>([]); 98 | expectType>( 99 | // @ts-expect-error - Filled fields cannot contain an empty value. 100 | [], 101 | ); 102 | 103 | /** 104 | * Supports all root-level Structured Text block types. 105 | */ 106 | expectType([ 107 | { type: prismicT.RichTextNodeType.heading1, text: "string", spans: [] }, 108 | { type: prismicT.RichTextNodeType.heading2, text: "string", spans: [] }, 109 | { type: prismicT.RichTextNodeType.heading3, text: "string", spans: [] }, 110 | { type: prismicT.RichTextNodeType.heading4, text: "string", spans: [] }, 111 | { type: prismicT.RichTextNodeType.heading5, text: "string", spans: [] }, 112 | { type: prismicT.RichTextNodeType.heading5, text: "string", spans: [] }, 113 | { type: prismicT.RichTextNodeType.paragraph, text: "string", spans: [] }, 114 | { type: prismicT.RichTextNodeType.preformatted, text: "string", spans: [] }, 115 | { type: prismicT.RichTextNodeType.listItem, text: "string", spans: [] }, 116 | { type: prismicT.RichTextNodeType.oListItem, text: "string", spans: [] }, 117 | { 118 | type: prismicT.RichTextNodeType.image, 119 | id: "string", 120 | alt: "string", 121 | url: "string", 122 | copyright: "string", 123 | dimensions: { 124 | width: 0, 125 | height: 0, 126 | }, 127 | edit: { x: 0, y: 0, zoom: 1, background: "background" }, 128 | linkTo: { 129 | link_type: prismicT.LinkType.Web, 130 | url: "string", 131 | target: "string", 132 | }, 133 | }, 134 | { 135 | type: prismicT.RichTextNodeType.embed, 136 | oembed: { 137 | embed_url: "https://example.com", 138 | type: prismicT.OEmbedType.Link, 139 | version: "1.0", 140 | title: null, 141 | author_name: null, 142 | author_url: null, 143 | provider_name: null, 144 | provider_url: null, 145 | cache_age: null, 146 | thumbnail_url: null, 147 | thumbnail_width: null, 148 | thumbnail_height: null, 149 | html: null, 150 | }, 151 | }, 152 | ]); 153 | expectType([ 154 | { 155 | // @ts-expect-error - Not a root-level block type. 156 | type: prismicT.RichTextNodeType.strong, 157 | }, 158 | ]); 159 | expectType([ 160 | { 161 | // @ts-expect-error - Not a root-level block type. 162 | type: prismicT.RichTextNodeType.em, 163 | }, 164 | ]); 165 | expectType([ 166 | { 167 | // @ts-expect-error - Not a root-level block type. 168 | type: prismicT.RichTextNodeType.label, 169 | }, 170 | ]); 171 | expectType([ 172 | { 173 | // @ts-expect-error - Not a root-level block type. 174 | type: prismicT.RichTextNodeType.hyperlink, 175 | }, 176 | ]); 177 | expectType([ 178 | { 179 | // @ts-expect-error - Not a root-label block type (meta block for internal use only). 180 | type: prismicT.RichTextNodeType.list, 181 | }, 182 | ]); 183 | expectType([ 184 | { 185 | // @ts-expect-error - Not a root-label block type (meta block for internal use only). 186 | type: prismicT.RichTextNodeType.oList, 187 | }, 188 | ]); 189 | 190 | /** 191 | * Text blocks support spans. 192 | */ 193 | expectType([ 194 | { 195 | type: prismicT.RichTextNodeType.paragraph, 196 | text: "string", 197 | spans: [ 198 | { 199 | type: prismicT.RichTextNodeType.strong, 200 | start: 0, 201 | end: 0, 202 | }, 203 | { 204 | type: prismicT.RichTextNodeType.em, 205 | start: 0, 206 | end: 0, 207 | }, 208 | { 209 | type: prismicT.RichTextNodeType.label, 210 | start: 0, 211 | end: 0, 212 | data: { 213 | label: "string", 214 | }, 215 | }, 216 | { 217 | type: prismicT.RichTextNodeType.hyperlink, 218 | start: 0, 219 | end: 0, 220 | data: { 221 | link_type: prismicT.LinkType.Web, 222 | url: "string", 223 | target: "string", 224 | }, 225 | }, 226 | ], 227 | }, 228 | ]); 229 | -------------------------------------------------------------------------------- /src/value/richText.ts: -------------------------------------------------------------------------------- 1 | import type { EmbedField } from "./embed"; 2 | import type { FieldState } from "./types"; 3 | import type { FilledContentRelationshipField } from "./contentRelationship"; 4 | import type { FilledLinkToMediaField } from "./linkToMedia"; 5 | import type { FilledLinkToWebField } from "./link"; 6 | 7 | /** 8 | * Types for RichTextNodes 9 | * 10 | * @see More details: {@link https://prismic.io/docs/core-concepts/rich-text-title} 11 | */ 12 | export const RichTextNodeType = { 13 | heading1: "heading1", 14 | heading2: "heading2", 15 | heading3: "heading3", 16 | heading4: "heading4", 17 | heading5: "heading5", 18 | heading6: "heading6", 19 | paragraph: "paragraph", 20 | preformatted: "preformatted", 21 | strong: "strong", 22 | em: "em", 23 | listItem: "list-item", 24 | oListItem: "o-list-item", 25 | list: "group-list-item", 26 | oList: "group-o-list-item", 27 | image: "image", 28 | embed: "embed", 29 | hyperlink: "hyperlink", 30 | label: "label", 31 | span: "span", 32 | } as const; 33 | 34 | // Text nodes 35 | 36 | /** 37 | * Base to be extended by other RT Nodes. 38 | */ 39 | export interface RTTextNodeBase { 40 | text: string; 41 | spans: RTInlineNode[]; 42 | } 43 | 44 | /** 45 | * Rich Text `heading1` node 46 | */ 47 | export interface RTHeading1Node extends RTTextNodeBase { 48 | type: typeof RichTextNodeType.heading1; 49 | } 50 | 51 | /** 52 | * Rich Text `heading2` node 53 | */ 54 | export interface RTHeading2Node extends RTTextNodeBase { 55 | type: typeof RichTextNodeType.heading2; 56 | } 57 | 58 | /** 59 | * Rich Text `heading3` node 60 | */ 61 | export interface RTHeading3Node extends RTTextNodeBase { 62 | type: typeof RichTextNodeType.heading3; 63 | } 64 | 65 | /** 66 | * Rich Text `heading4` node 67 | */ 68 | export interface RTHeading4Node extends RTTextNodeBase { 69 | type: typeof RichTextNodeType.heading4; 70 | } 71 | 72 | /** 73 | * Rich Text `heading5` node 74 | */ 75 | export interface RTHeading5Node extends RTTextNodeBase { 76 | type: typeof RichTextNodeType.heading5; 77 | } 78 | 79 | /** 80 | * Rich Text `heading6` node 81 | */ 82 | export interface RTHeading6Node extends RTTextNodeBase { 83 | type: typeof RichTextNodeType.heading6; 84 | } 85 | 86 | /** 87 | * Rich Text `paragraph` node 88 | */ 89 | export interface RTParagraphNode extends RTTextNodeBase { 90 | type: typeof RichTextNodeType.paragraph; 91 | } 92 | 93 | /** 94 | * Rich Text `preformatted` node 95 | */ 96 | export interface RTPreformattedNode extends RTTextNodeBase { 97 | type: typeof RichTextNodeType.preformatted; 98 | } 99 | 100 | /** 101 | * Rich Text `list-item` node 102 | */ 103 | export interface RTListItemNode extends RTTextNodeBase { 104 | type: typeof RichTextNodeType.listItem; 105 | } 106 | 107 | /** 108 | * Rich Text `o-list-item` node for ordered lists 109 | */ 110 | export interface RTOListItemNode extends RTTextNodeBase { 111 | type: typeof RichTextNodeType.oListItem; 112 | } 113 | 114 | // Span nodes 115 | 116 | /** 117 | * @internal Span Node base to be extended for other Span nodes 118 | */ 119 | export interface RTSpanNodeBase { 120 | start: number; 121 | end: number; 122 | } 123 | /** 124 | * Rich Text `strong` node 125 | */ 126 | export interface RTStrongNode extends RTSpanNodeBase { 127 | type: typeof RichTextNodeType.strong; 128 | } 129 | 130 | /** 131 | * Rich Text `embed` node 132 | */ 133 | export interface RTEmNode extends RTSpanNodeBase { 134 | type: typeof RichTextNodeType.em; 135 | } 136 | 137 | /** 138 | * Rich Text `label` node 139 | */ 140 | export interface RTLabelNode extends RTSpanNodeBase { 141 | type: typeof RichTextNodeType.label; 142 | data: { 143 | label: string; 144 | }; 145 | } 146 | 147 | // Media nodes 148 | 149 | /** 150 | * Rich Text `image` nodes. They could link to other documents, external web 151 | * links and media fields 152 | */ 153 | export type RTImageNode = { 154 | type: typeof RichTextNodeType.image; 155 | id: string; 156 | url: string; 157 | alt: string | null; 158 | copyright: string | null; 159 | dimensions: { 160 | width: number; 161 | height: number; 162 | }; 163 | edit: { 164 | x: number; 165 | y: number; 166 | zoom: number; 167 | background: string; 168 | }; 169 | linkTo?: 170 | | FilledContentRelationshipField 171 | | FilledLinkToWebField 172 | | FilledLinkToMediaField; 173 | }; 174 | 175 | /** 176 | * Rich Text `embed` node 177 | */ 178 | export type RTEmbedNode = { 179 | type: typeof RichTextNodeType.embed; 180 | oembed: EmbedField; 181 | }; 182 | 183 | // Link nodes 184 | 185 | /** 186 | * Rich Text `a` node 187 | * 188 | * @see More details: {@link https://prismic.io/docs/core-concepts/edit-rich-text#add-links} 189 | */ 190 | export interface RTLinkNode extends RTSpanNodeBase { 191 | type: typeof RichTextNodeType.hyperlink; 192 | data: 193 | | FilledContentRelationshipField 194 | | FilledLinkToWebField 195 | | FilledLinkToMediaField; 196 | } 197 | 198 | // Serialization related nodes 199 | 200 | /** 201 | * Rich Text `list` node 202 | */ 203 | export interface RTListNode { 204 | type: typeof RichTextNodeType.list; 205 | items: RTListItemNode[]; 206 | } 207 | 208 | /** 209 | * Rich Text o-lost node 210 | */ 211 | export interface RTOListNode { 212 | type: typeof RichTextNodeType.oList; 213 | items: RTOListItemNode[]; 214 | } 215 | 216 | // This one is confusing but it's actually the inner content of a block 217 | /** 218 | * Rich Text `span` node 219 | */ 220 | export interface RTSpanNode extends RTTextNodeBase { 221 | type: typeof RichTextNodeType.span; 222 | } 223 | 224 | // Helpers 225 | 226 | /** 227 | * Nodes from a Rich Text Field 228 | */ 229 | export type RTNode = 230 | | RTHeading1Node 231 | | RTHeading2Node 232 | | RTHeading3Node 233 | | RTHeading4Node 234 | | RTHeading5Node 235 | | RTHeading6Node 236 | | RTParagraphNode 237 | | RTPreformattedNode 238 | | RTListItemNode 239 | | RTOListItemNode 240 | | RTImageNode 241 | | RTEmbedNode; 242 | 243 | /** 244 | * Rich text nodes with text 245 | */ 246 | export type RTTextNode = 247 | | RTHeading1Node 248 | | RTHeading2Node 249 | | RTHeading3Node 250 | | RTHeading4Node 251 | | RTHeading5Node 252 | | RTHeading6Node 253 | | RTParagraphNode 254 | | RTPreformattedNode 255 | | RTListItemNode 256 | | RTOListItemNode; 257 | 258 | /** 259 | * Rich Text block nodes 260 | */ 261 | export type RTBlockNode = 262 | | RTHeading1Node 263 | | RTHeading2Node 264 | | RTHeading3Node 265 | | RTHeading4Node 266 | | RTHeading5Node 267 | | RTHeading6Node 268 | | RTParagraphNode 269 | | RTPreformattedNode 270 | | RTListItemNode 271 | | RTOListItemNode 272 | | RTListNode 273 | | RTOListNode 274 | | RTImageNode 275 | | RTEmbedNode; 276 | 277 | /** 278 | * Inline Rich Text Nodes 279 | */ 280 | export type RTInlineNode = RTStrongNode | RTEmNode | RTLabelNode | RTLinkNode; 281 | 282 | /** 283 | * All Rich Text nodes 284 | */ 285 | export type RTAnyNode = RTBlockNode | RTInlineNode | RTSpanNode; 286 | 287 | /** 288 | * Rich Text Field 289 | * 290 | * @see Rich Text field documentation: {@link https://prismic.io/docs/core-concepts/rich-text-title} 291 | */ 292 | export type RichTextField = 293 | State extends "empty" ? [] : [RTNode, ...RTNode[]]; 294 | --------------------------------------------------------------------------------