@prismicio/types-internal 2.2.0-traverse.alpha-1 → 2.2.0-traverse.alpha-3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/lib/_internal/utils.d.ts +21 -4
  2. package/lib/_internal/utils.js +11 -0
  3. package/lib/content/Document.d.ts +2194 -13
  4. package/lib/content/Document.js +64 -36
  5. package/lib/content/fields/GroupContent.d.ts +6 -4
  6. package/lib/content/fields/GroupContent.js +13 -9
  7. package/lib/content/fields/slices/Slice/CompositeSliceContent.d.ts +9 -6
  8. package/lib/content/fields/slices/Slice/CompositeSliceContent.js +61 -17
  9. package/lib/content/fields/slices/Slice/SharedSliceContent.d.ts +8 -6
  10. package/lib/content/fields/slices/Slice/SharedSliceContent.js +26 -18
  11. package/lib/content/fields/slices/Slice/SimpleSliceContent.d.ts +11 -0
  12. package/lib/content/fields/slices/Slice/SimpleSliceContent.js +100 -1
  13. package/lib/content/fields/slices/SliceItem.d.ts +15 -0
  14. package/lib/content/fields/slices/SliceItem.js +15 -1
  15. package/lib/content/fields/slices/SlicesContent.d.ts +4 -3
  16. package/lib/content/fields/slices/SlicesContent.js +125 -60
  17. package/lib/customtypes/CustomType.d.ts +8 -1
  18. package/lib/customtypes/CustomType.js +18 -1
  19. package/lib/customtypes/Section.d.ts +3 -0
  20. package/lib/customtypes/diff/SharedSlice.d.ts +6 -0
  21. package/lib/customtypes/widgets/Widget.d.ts +3 -0
  22. package/lib/customtypes/widgets/slices/CompositeSlice.d.ts +5 -0
  23. package/lib/customtypes/widgets/slices/SharedSlice.d.ts +8 -0
  24. package/lib/customtypes/widgets/slices/SharedSlice.js +3 -0
  25. package/lib/customtypes/widgets/slices/Slices.d.ts +6 -0
  26. package/lib/import/converters/fields/nestable/Image.d.ts +3 -1
  27. package/lib/import/converters/fields/nestable/Image.js +18 -2
  28. package/lib/import/converters/fields/nestable/Nestable.js +2 -0
  29. package/lib/import/converters/fields/nestable/RichText.d.ts +4 -0
  30. package/lib/import/converters/fields/nestable/RichText.js +55 -0
  31. package/lib/import/converters/fields/nestable/index.d.ts +1 -0
  32. package/lib/import/converters/fields/nestable/index.js +1 -0
  33. package/lib/import/validators/fields/ImportField.d.ts +6 -0
  34. package/lib/import/validators/fields/ImportSlices/SharedSlice/SharedSlice.js +1 -1
  35. package/lib/import/validators/fields/ImportSlices/SharedSlice/fields/SharedSliceType.js +1 -1
  36. package/lib/import/validators/fields/ImportSlices/SharedSlice/fields/SharedSliceVariation.js +1 -1
  37. package/lib/import/validators/fields/ImportSlices/SharedSlice/utils.d.ts +3 -0
  38. package/lib/import/validators/fields/nestable/Embed.d.ts +3 -0
  39. package/lib/import/validators/fields/nestable/Embed.js +3 -8
  40. package/lib/import/validators/fields/nestable/GeoPoint.js +2 -2
  41. package/lib/import/validators/fields/nestable/Image/default.d.ts +22 -0
  42. package/lib/import/validators/fields/nestable/Image/default.js +19 -0
  43. package/lib/import/validators/fields/nestable/Image/index.d.ts +19 -0
  44. package/lib/import/validators/fields/nestable/Image/index.js +22 -22
  45. package/lib/import/validators/fields/nestable/Image/merge.d.ts +23 -0
  46. package/lib/import/validators/fields/nestable/Image/{Decoder.js → merge.js} +18 -14
  47. package/lib/import/validators/fields/nestable/Image/{Validator.d.ts → validators.d.ts} +4 -2
  48. package/lib/import/validators/fields/nestable/Image/{Validator.js → validators.js} +7 -3
  49. package/lib/import/validators/fields/nestable/ImportRichText/ImportBlock.d.ts +6 -0
  50. package/lib/import/validators/fields/nestable/ImportRichText/ImportBlock.js +25 -0
  51. package/lib/import/validators/fields/nestable/ImportRichText/ImportRichText.d.ts +24 -0
  52. package/lib/import/validators/fields/nestable/ImportRichText/ImportRichText.js +26 -0
  53. package/lib/import/validators/fields/nestable/ImportRichText/blocks/ImportBlockType.d.ts +6 -0
  54. package/lib/import/validators/fields/nestable/ImportRichText/blocks/ImportBlockType.js +18 -0
  55. package/lib/import/validators/fields/nestable/ImportRichText/blocks/ImportEmbedBlock.d.ts +10 -0
  56. package/lib/import/validators/fields/nestable/ImportRichText/blocks/ImportEmbedBlock.js +11 -0
  57. package/lib/import/validators/fields/nestable/ImportRichText/blocks/ImportImageBlock.d.ts +8 -0
  58. package/lib/import/validators/fields/nestable/ImportRichText/blocks/ImportImageBlock.js +11 -0
  59. package/lib/import/validators/fields/nestable/ImportRichText/blocks/ImportTextBlock.d.ts +70 -0
  60. package/lib/import/validators/fields/nestable/ImportRichText/blocks/ImportTextBlock.js +43 -0
  61. package/lib/import/validators/fields/nestable/ImportRichText/blocks/Span.d.ts +65 -0
  62. package/lib/import/validators/fields/nestable/ImportRichText/blocks/Span.js +20 -0
  63. package/lib/import/validators/fields/nestable/ImportRichText/blocks/index.d.ts +4 -0
  64. package/lib/import/validators/fields/nestable/ImportRichText/blocks/index.js +7 -0
  65. package/lib/import/validators/fields/nestable/ImportRichText/blocks/spans/HyperlinkSpan.d.ts +24 -0
  66. package/lib/import/validators/fields/nestable/ImportRichText/blocks/spans/HyperlinkSpan.js +18 -0
  67. package/lib/import/validators/fields/nestable/ImportRichText/blocks/spans/SpanLocation.d.ts +5 -0
  68. package/lib/import/validators/fields/nestable/ImportRichText/blocks/spans/SpanLocation.js +10 -0
  69. package/lib/import/validators/fields/nestable/ImportRichText/blocks/spans/TextSpan.d.ts +17 -0
  70. package/lib/import/validators/fields/nestable/ImportRichText/blocks/spans/TextSpan.js +22 -0
  71. package/lib/import/validators/fields/nestable/ImportRichText/blocks/spans/index.d.ts +2 -0
  72. package/lib/import/validators/fields/nestable/ImportRichText/blocks/spans/index.js +5 -0
  73. package/lib/import/validators/fields/nestable/ImportRichText/index.d.ts +2 -0
  74. package/lib/import/validators/fields/nestable/ImportRichText/index.js +7 -0
  75. package/lib/import/validators/fields/nestable/Link.d.ts +21 -6
  76. package/lib/import/validators/fields/nestable/Link.js +8 -8
  77. package/lib/import/validators/fields/nestable/Nestable.d.ts +8 -1
  78. package/lib/import/validators/fields/nestable/Nestable.js +5 -1
  79. package/lib/import/validators/fields/nestable/index.d.ts +2 -1
  80. package/lib/import/validators/fields/nestable/index.js +4 -1
  81. package/package.json +1 -1
  82. package/src/_internal/utils.ts +63 -7
  83. package/src/content/Document.ts +106 -47
  84. package/src/content/fields/GroupContent.ts +25 -12
  85. package/src/content/fields/slices/Slice/CompositeSliceContent.ts +91 -22
  86. package/src/content/fields/slices/Slice/SharedSliceContent.ts +42 -26
  87. package/src/content/fields/slices/Slice/SimpleSliceContent.ts +144 -1
  88. package/src/content/fields/slices/SliceItem.ts +39 -3
  89. package/src/content/fields/slices/SlicesContent.ts +172 -67
  90. package/src/customtypes/CustomType.ts +23 -1
  91. package/src/customtypes/widgets/slices/CompositeSlice.ts +6 -0
  92. package/src/customtypes/widgets/slices/SharedSlice.ts +12 -0
  93. package/src/import/converters/fields/nestable/Image.ts +34 -4
  94. package/src/import/converters/fields/nestable/Nestable.ts +3 -0
  95. package/src/import/converters/fields/nestable/RichText.ts +62 -0
  96. package/src/import/converters/fields/nestable/index.ts +1 -0
  97. package/src/import/validators/fields/ImportSlices/SharedSlice/SharedSlice.ts +1 -1
  98. package/src/import/validators/fields/ImportSlices/SharedSlice/fields/SharedSliceType.ts +1 -1
  99. package/src/import/validators/fields/ImportSlices/SharedSlice/fields/SharedSliceVariation.ts +1 -1
  100. package/src/import/validators/fields/nestable/Embed.ts +4 -17
  101. package/src/import/validators/fields/nestable/GeoPoint.ts +2 -2
  102. package/src/import/validators/fields/nestable/Image/default.ts +25 -0
  103. package/src/import/validators/fields/nestable/Image/index.ts +34 -36
  104. package/src/import/validators/fields/nestable/Image/{Decoder.ts → merge.ts} +23 -20
  105. package/src/import/validators/fields/nestable/Image/{Validator.ts → validators.ts} +9 -2
  106. package/src/import/validators/fields/nestable/ImportRichText/ImportBlock.ts +39 -0
  107. package/src/import/validators/fields/nestable/ImportRichText/ImportRichText.ts +41 -0
  108. package/src/import/validators/fields/nestable/ImportRichText/blocks/ImportBlockType.ts +44 -0
  109. package/src/import/validators/fields/nestable/ImportRichText/blocks/ImportEmbedBlock.ts +13 -0
  110. package/src/import/validators/fields/nestable/ImportRichText/blocks/ImportImageBlock.ts +13 -0
  111. package/src/import/validators/fields/nestable/ImportRichText/blocks/ImportTextBlock.ts +56 -0
  112. package/src/import/validators/fields/nestable/ImportRichText/blocks/Span.ts +44 -0
  113. package/src/import/validators/fields/nestable/ImportRichText/blocks/index.ts +4 -0
  114. package/src/import/validators/fields/nestable/ImportRichText/blocks/spans/HyperlinkSpan.ts +24 -0
  115. package/src/import/validators/fields/nestable/ImportRichText/blocks/spans/SpanLocation.ts +8 -0
  116. package/src/import/validators/fields/nestable/ImportRichText/blocks/spans/TextSpan.ts +26 -0
  117. package/src/import/validators/fields/nestable/ImportRichText/blocks/spans/index.ts +2 -0
  118. package/src/import/validators/fields/nestable/ImportRichText/index.ts +2 -0
  119. package/src/import/validators/fields/nestable/Link.ts +18 -13
  120. package/src/import/validators/fields/nestable/Nestable.ts +6 -1
  121. package/src/import/validators/fields/nestable/index.ts +2 -1
  122. package/lib/import/validators/fields/nestable/Image/Decoder.d.ts +0 -26
@@ -4,55 +4,52 @@ import type { Validation } from "io-ts"
4
4
  import * as t from "io-ts"
5
5
 
6
6
  import type { Image as ImageDefinition } from "../../../../../customtypes"
7
- import { DefaultOrElse, EmptyObject } from "../../../../../validators"
7
+ import { DefaultOrElse } from "../../../../../validators"
8
8
  import { withCustomError } from "../../../../../validators/function"
9
9
  import { ImportContent } from "../../ImportContent"
10
- import { decodeImageField, decodeThumbnails } from "./Decoder"
10
+ import { defaultImportImage } from "./default"
11
+ import {
12
+ mergeImageViewWithCtConstraints,
13
+ mergeThumbnailsWithCtConstraints,
14
+ } from "./merge"
11
15
  import type { ImageFieldWithThumbnails } from "./model"
12
- import { ImageFieldValidator, ThumbnailsValidator } from "./Validator"
16
+ import { ImportImageView, ImportThumbnails } from "./validators"
13
17
 
14
- const defaultImage = (field?: ImageDefinition) => {
15
- // If there is not thumbnails we expect an empty object
16
- if (!field?.config?.thumbnails || !field.config.thumbnails.length)
17
- return EmptyObject
18
+ /* For code clarity, the output of this validator will be simplified
19
+ *
20
+ * Input -> type ImageAPIV2 = ImportImageView & ImportThumbnails
21
+ * Output -> type ImageWithThumbnails 👇
22
+ */
18
23
 
19
- // If there are thumbnails, we expect an object with thumbnails as empty objects
20
- return withCustomError(
21
- t.strict(
22
- field.config.thumbnails.reduce(
23
- (acc, thumbnail) => ({
24
- ...acc,
25
- [thumbnail.name]: EmptyObject,
26
- }),
27
- {},
28
- ),
29
- ),
30
- () => "The value must be an object",
31
- )
32
- }
33
-
34
- const ImageField = (field?: ImageDefinition) =>
24
+ export const ImageFieldCodec = (field?: ImageDefinition) =>
35
25
  new t.Type<ImageFieldWithThumbnails>(
36
26
  "ImageField",
37
27
  (u: unknown): u is ImageFieldWithThumbnails =>
38
- ImageFieldValidator.is(u) &&
28
+ ImportImageView.is(u) &&
39
29
  "thumbnails" in u &&
40
- ThumbnailsValidator.is(u["thumbnails"]),
30
+ ImportThumbnails.is(u["thumbnails"]),
41
31
  (u: unknown, ctx): Validation<ImageFieldWithThumbnails> => {
42
32
  return pipe(
43
- ImageFieldValidator.validate(u, ctx),
44
- chain((mainImage) => {
45
- const { id, dimensions, edit, copyright, alt, ...maybeThumbnails } =
46
- mainImage
33
+ // Validating the higher level image
34
+ ImportImageView.validate(u, ctx),
35
+ chain((imageApiV2) => {
36
+ const { id, dimensions, edit, copyright, alt, ...thumbnails } =
37
+ imageApiV2
38
+
47
39
  return pipe(
48
- ThumbnailsValidator.validate(maybeThumbnails, ctx),
40
+ // Validating the thumbnails
41
+ ImportThumbnails.validate(thumbnails, ctx),
49
42
  map((thumbnails) => ({
50
- ...decodeImageField(
51
- mainImage,
52
- mainImage,
43
+ ...mergeImageViewWithCtConstraints(
44
+ imageApiV2,
45
+ imageApiV2,
53
46
  field?.config?.constraint,
54
47
  ),
55
- thumbnails: decodeThumbnails(mainImage, thumbnails, field),
48
+ thumbnails: mergeThumbnailsWithCtConstraints(
49
+ thumbnails,
50
+ imageApiV2,
51
+ field,
52
+ ),
56
53
  })),
57
54
  )
58
55
  }),
@@ -64,12 +61,13 @@ const ImageField = (field?: ImageDefinition) =>
64
61
  const ImageCodec = (field?: ImageDefinition) =>
65
62
  withCustomError(
66
63
  DefaultOrElse<Record<never, never>, ImageFieldWithThumbnails>(
67
- defaultImage(field),
68
- )(ImageField(field)),
64
+ defaultImportImage(field),
65
+ )(ImageFieldCodec(field)),
69
66
  () => "An image field must be an object",
70
67
  )
71
68
 
72
69
  export const ImportImage = (field?: ImageDefinition) =>
73
70
  ImportContent("Image", ImageCodec(field))
74
71
  export type ImportImage = t.TypeOf<ReturnType<typeof ImportImage>>
72
+
75
73
  export * from "./model"
@@ -1,32 +1,30 @@
1
- import type { TypeOf } from "io-ts"
2
-
3
1
  import type { Image } from "../../../../../customtypes"
4
2
  import type ImageConstraint from "../../../../../customtypes/widgets/shared/ImageConstraint"
5
3
  import type { ImageField } from "./model"
6
- import type { ImageFieldValidator, ThumbnailsValidator } from "./Validator"
4
+ import type { ImportImageView, ImportThumbnails } from "./validators"
7
5
 
8
- // This function merges user input with custom type constraints.
9
- // If `image` is missing, `mainImage` is used for the encoding
10
- // (case when user input lacks thumbnail definition)
11
- export const decodeImageField = (
12
- image: TypeOf<typeof ImageFieldValidator> | undefined,
13
- mainImage: TypeOf<typeof ImageFieldValidator>,
14
- constraints?: ImageConstraint,
6
+ /* This function merges user input with custom type constraints.
7
+ * If a thumbnails' data are missing (`image`) then the default is used (`defaultImage`)
8
+ */
9
+ export const mergeImageViewWithCtConstraints = (
10
+ image: ImportImageView | undefined,
11
+ defaultImage: ImportImageView,
12
+ constraints: ImageConstraint | undefined,
15
13
  ): ImageField => {
16
14
  const background = image?.edit?.background
17
15
  const width =
18
16
  constraints?.width ??
19
17
  image?.dimensions?.width ??
20
- mainImage.dimensions?.width
18
+ defaultImage?.dimensions?.width
21
19
  const height =
22
20
  constraints?.height ??
23
21
  image?.dimensions?.height ??
24
- mainImage.dimensions?.height
22
+ defaultImage?.dimensions?.height
25
23
  const alt = image?.alt
26
24
  const copyright = image?.copyright
27
25
 
28
26
  return {
29
- id: image?.id ?? mainImage?.id,
27
+ id: image?.id ?? defaultImage?.id,
30
28
  edit: {
31
29
  x: image?.edit?.x ?? 0,
32
30
  y: image?.edit?.y ?? 0,
@@ -41,19 +39,24 @@ export const decodeImageField = (
41
39
  ...(copyright !== undefined ? { copyright } : {}),
42
40
  }
43
41
  }
44
- // Merges provided thumbnails with custom type constraints.
45
- // If any thumbnail is missing, it is created using the origin image (`mainImage`)
46
- export const decodeThumbnails = (
47
- mainImage: TypeOf<typeof ImageFieldValidator>,
48
- thumbnails: TypeOf<typeof ThumbnailsValidator>,
42
+
43
+ /* This function handles each thumbnail defined in the custom type.
44
+ *
45
+ * For each of them it merges the user input with custom type constraints.
46
+ *
47
+ * If a thumbnail is missing, the data from the default image is used.
48
+ */
49
+ export const mergeThumbnailsWithCtConstraints = (
50
+ thumbnails: ImportThumbnails,
51
+ defaultImage: ImportImageView,
49
52
  field?: Image,
50
53
  ) =>
51
54
  field?.config?.thumbnails?.reduce(
52
55
  (acc, thumbnail) => ({
53
56
  ...acc,
54
- [thumbnail.name]: decodeImageField(
57
+ [thumbnail.name]: mergeImageViewWithCtConstraints(
55
58
  thumbnails[thumbnail.name],
56
- mainImage,
59
+ defaultImage,
57
60
  thumbnail,
58
61
  ),
59
62
  }),
@@ -7,12 +7,14 @@ import {
7
7
  } from "../../../../../validators/BasicTypes"
8
8
  import { withCustomError } from "../../../../../validators/function"
9
9
 
10
- export const ImageFieldValidator = withCustomError(
10
+ export const ImportImageView = withCustomError(
11
11
  t.intersection([
12
12
  t.type({
13
+ // Image Id
13
14
  id: String,
14
15
  }),
15
16
  t.partial({
17
+ // Dimensions here will be used if they are not defined in the custom type
16
18
  dimensions: withCustomError(
17
19
  t.partial({
18
20
  width: Number,
@@ -20,6 +22,7 @@ export const ImageFieldValidator = withCustomError(
20
22
  }),
21
23
  () => "The value must be an object",
22
24
  ),
25
+ // Crop information
23
26
  edit: withCustomError(
24
27
  t.partial({
25
28
  x: Number,
@@ -29,10 +32,14 @@ export const ImageFieldValidator = withCustomError(
29
32
  }),
30
33
  () => "The value must be an object",
31
34
  ),
35
+ // Copyrights and alt are set in the Asset by default but they can be overrided
32
36
  copyright: StringOrNull,
33
37
  alt: StringOrNull,
34
38
  }),
35
39
  ]),
36
40
  () => "The value must be an object",
37
41
  )
38
- export const ThumbnailsValidator = t.record(t.string, ImageFieldValidator)
42
+ export type ImportImageView = t.TypeOf<typeof ImportImageView>
43
+
44
+ export const ImportThumbnails = t.record(t.string, ImportImageView)
45
+ export type ImportThumbnails = t.TypeOf<typeof ImportThumbnails>
@@ -0,0 +1,39 @@
1
+ import * as t from "io-ts"
2
+
3
+ import { withCustomError } from "../../../../../validators/function"
4
+ import {
5
+ ImportBlockType,
6
+ ImportEmbedBlock,
7
+ ImportImageBlock,
8
+ ImportTextBlock,
9
+ } from "./blocks"
10
+
11
+ export type ImportBlock = ImportTextBlock | ImportImageBlock | ImportEmbedBlock
12
+
13
+ export const ImportBlock = (allowedBlockTypes: string[]) =>
14
+ withCustomError(
15
+ t
16
+ .type({
17
+ type: ImportBlockType(allowedBlockTypes),
18
+ })
19
+ .pipe(
20
+ new t.Type<ImportBlock, ImportBlock, { type: ImportBlockType }>(
21
+ "ImportBlock",
22
+ (u): u is ImportBlock =>
23
+ t
24
+ .union([ImportTextBlock, ImportImageBlock, ImportEmbedBlock])
25
+ .is(u),
26
+ (u, c) => {
27
+ if (u.type === "image") {
28
+ return ImportImageBlock.validate(u, c)
29
+ } else if (u.type === "embed") {
30
+ return ImportEmbedBlock.validate(u, c)
31
+ } else {
32
+ return ImportTextBlock.validate(u, c)
33
+ }
34
+ },
35
+ t.identity,
36
+ ),
37
+ ),
38
+ () => "Rich text block must be an object",
39
+ )
@@ -0,0 +1,41 @@
1
+ import * as t from "io-ts"
2
+
3
+ import type { RichText as RichTextCustomType } from "../../../../../customtypes"
4
+ import { EmptyArrayOrElse } from "../../../../../validators"
5
+ import { withCustomError } from "../../../../../validators/function"
6
+ import { ImportContent } from "../../ImportContent"
7
+ import { ImportBlock } from "./ImportBlock"
8
+
9
+ export const ImportRichText = (customType?: RichTextCustomType) =>
10
+ ImportContent(
11
+ "StructuredText",
12
+ EmptyArrayOrElse(
13
+ withCustomError(
14
+ t.array(t.unknown).pipe(
15
+ new t.Type<ImportBlock[], ImportBlock[], unknown[]>(
16
+ "RichTextField",
17
+ (u): u is ImportBlock[] => t.array(ImportBlock([])).is(u),
18
+ (u, c) => {
19
+ const single = customType?.config?.single?.split(",")
20
+ const multi = customType?.config?.multi?.split(",")
21
+
22
+ if (multi) {
23
+ return t.array(ImportBlock(multi)).validate(u, c)
24
+ } else if (single) {
25
+ return u.length > 1
26
+ ? t.failure(u, c, "This field only allows one block")
27
+ : t.array(ImportBlock(single)).validate(u, c)
28
+ } else {
29
+ throw new Error(
30
+ "Rich text config must have either a 'single' or 'multi' field defined",
31
+ )
32
+ }
33
+ },
34
+ t.identity,
35
+ ),
36
+ ),
37
+ () => "Rich text field must be an array",
38
+ ),
39
+ ),
40
+ )
41
+ export type ImportRichText = t.TypeOf<ReturnType<typeof ImportRichText>>
@@ -0,0 +1,44 @@
1
+ import * as E from "fp-ts/Either"
2
+ import { pipe } from "fp-ts/function"
3
+ import * as t from "io-ts"
4
+
5
+ import { withCustomError } from "../../../../../../validators/function"
6
+ import { ImportEmbedBlockType } from "./ImportEmbedBlock"
7
+ import { ImportImageBlockType } from "./ImportImageBlock"
8
+ import { ImportTextBlockType } from "./ImportTextBlock"
9
+
10
+ export type ImportBlockType =
11
+ | ImportTextBlockType
12
+ | ImportImageBlockType
13
+ | ImportEmbedBlockType
14
+
15
+ const ImportBlockTypeValidator = withCustomError(
16
+ t.union([ImportTextBlockType, ImportImageBlockType, ImportEmbedBlockType]),
17
+ () =>
18
+ `Invalid block type. Supported block types are: ${Object.keys(
19
+ ImportTextBlockType.keys,
20
+ ).join(", ")}, ${ImportImageBlockType.value}, ${
21
+ ImportEmbedBlockType.value
22
+ }`,
23
+ )
24
+
25
+ export const ImportBlockType = (allowedBlockTypes: string[]) =>
26
+ new t.Type<ImportBlockType>(
27
+ "ImportBlockType",
28
+ (u): u is ImportBlockType => ImportBlockTypeValidator.is(u),
29
+ (u, c) => {
30
+ return pipe(
31
+ ImportBlockTypeValidator.validate(u, c),
32
+ E.chain((validBlockType) =>
33
+ allowedBlockTypes.includes(validBlockType)
34
+ ? t.success(validBlockType)
35
+ : t.failure(
36
+ u,
37
+ c,
38
+ `The block type '${validBlockType}' is not allowed in your document type. Enable the type for this rich text field to create the document.`,
39
+ ),
40
+ ),
41
+ )
42
+ },
43
+ t.identity,
44
+ )
@@ -0,0 +1,13 @@
1
+ import * as t from "io-ts"
2
+
3
+ import { ImportEmbedValue } from "../../Embed"
4
+
5
+ export const ImportEmbedBlockType = t.literal("embed")
6
+ export type ImportEmbedBlockType = t.TypeOf<typeof ImportEmbedBlockType>
7
+
8
+ export const ImportEmbedBlock = t.strict({
9
+ type: ImportEmbedBlockType,
10
+ oembed: ImportEmbedValue,
11
+ })
12
+
13
+ export type ImportEmbedBlock = t.TypeOf<typeof ImportEmbedBlock>
@@ -0,0 +1,13 @@
1
+ import * as t from "io-ts"
2
+
3
+ import { String } from "../../../../../../validators"
4
+
5
+ export const ImportImageBlockType = t.literal("image")
6
+ export type ImportImageBlockType = t.TypeOf<typeof ImportImageBlockType>
7
+
8
+ export const ImportImageBlock = t.strict({
9
+ type: ImportImageBlockType,
10
+ id: String,
11
+ })
12
+
13
+ export type ImportImageBlock = t.TypeOf<typeof ImportImageBlock>
@@ -0,0 +1,56 @@
1
+ import * as t from "io-ts"
2
+
3
+ import { String } from "../../../../../../validators"
4
+ import { withCustomError } from "../../../../../../validators/function"
5
+ import { Span } from "./Span"
6
+
7
+ export const ImportTextBlockTypes = {
8
+ Paragraph: "paragraph",
9
+ OListItem: "o-list-item",
10
+ ListItem: "list-item",
11
+ Heading1: "heading1",
12
+ Heading2: "heading2",
13
+ Heading3: "heading3",
14
+ Heading4: "heading4",
15
+ Heading5: "heading5",
16
+ Heading6: "heading6",
17
+ Preformatted: "preformatted",
18
+ } as const
19
+
20
+ export const ImportTextBlockType = t.keyof({
21
+ [ImportTextBlockTypes.Paragraph]: null,
22
+ [ImportTextBlockTypes.OListItem]: null,
23
+ [ImportTextBlockTypes.ListItem]: null,
24
+ [ImportTextBlockTypes.Heading1]: null,
25
+ [ImportTextBlockTypes.Heading2]: null,
26
+ [ImportTextBlockTypes.Heading3]: null,
27
+ [ImportTextBlockTypes.Heading4]: null,
28
+ [ImportTextBlockTypes.Heading5]: null,
29
+ [ImportTextBlockTypes.Heading6]: null,
30
+ [ImportTextBlockTypes.Preformatted]: null,
31
+ })
32
+
33
+ export type ImportTextBlockType = t.TypeOf<typeof ImportTextBlockType>
34
+
35
+ const TextDirection = withCustomError(
36
+ t.union([t.literal("ltr"), t.literal("rtl")]),
37
+ () => "The 'direction' property must be one of the following: ltr, rtl",
38
+ )
39
+
40
+ export const ImportTextBlock = t.exact(
41
+ t.intersection([
42
+ t.type({
43
+ type: ImportTextBlockType,
44
+ text: String,
45
+ }),
46
+ t.partial({
47
+ spans: withCustomError(
48
+ t.array(Span),
49
+ () => "The 'spans' field must be an array",
50
+ ),
51
+ direction: TextDirection,
52
+ }),
53
+ ]),
54
+ )
55
+
56
+ export type ImportTextBlock = t.TypeOf<typeof ImportTextBlock>
@@ -0,0 +1,44 @@
1
+ import * as t from "io-ts"
2
+
3
+ import { withCustomError } from "../../../../../../validators/function"
4
+ import {
5
+ HyperlinkSpan,
6
+ HyperlinkSpanType,
7
+ TextSpan,
8
+ TextSpanType,
9
+ } from "./spans"
10
+
11
+ const SpanType = withCustomError(
12
+ t.union([HyperlinkSpanType, TextSpanType]),
13
+ () =>
14
+ `Span 'type' field must be specified and have one of the following values: ${Object.keys(
15
+ TextSpanType.keys,
16
+ ).join(", ")} or ${HyperlinkSpanType.value}`,
17
+ )
18
+ export type SpanType = t.TypeOf<typeof SpanType>
19
+
20
+ const SpanTypeValidator = withCustomError(
21
+ t.type({
22
+ type: SpanType,
23
+ }),
24
+ () => "Span must be an object",
25
+ )
26
+
27
+ const SpanShape = t.union([HyperlinkSpan, TextSpan])
28
+
29
+ export type Span = t.TypeOf<typeof SpanShape>
30
+
31
+ export const Span = SpanTypeValidator.pipe(
32
+ new t.Type<Span, Span, { type: SpanType }>(
33
+ "Span",
34
+ (u): u is Span => SpanShape.is(u),
35
+ (u, c) => {
36
+ if (HyperlinkSpanType.is(u.type)) {
37
+ return HyperlinkSpan.validate(u, c)
38
+ } else {
39
+ return TextSpan.validate(u, c)
40
+ }
41
+ },
42
+ t.identity,
43
+ ),
44
+ )
@@ -0,0 +1,4 @@
1
+ export * from "./ImportBlockType"
2
+ export * from "./ImportEmbedBlock"
3
+ export * from "./ImportImageBlock"
4
+ export * from "./ImportTextBlock"
@@ -0,0 +1,24 @@
1
+ import * as t from "io-ts"
2
+
3
+ import { withCustomError } from "../../../../../../../validators/function"
4
+ import { Link } from "../../../Link"
5
+ import { SpanLocation } from "./SpanLocation"
6
+
7
+ export const HyperlinkSpanType = t.literal("hyperlink")
8
+
9
+ export type HyperlinkSpanType = t.TypeOf<typeof HyperlinkSpanType>
10
+
11
+ export const HyperlinkSpan = t.exact(
12
+ t.intersection([
13
+ t.type({
14
+ type: HyperlinkSpanType,
15
+ }),
16
+ SpanLocation,
17
+ withCustomError(
18
+ t.type({
19
+ data: Link,
20
+ }),
21
+ () => "Hyperlink span must contain a 'data' field with link data",
22
+ ),
23
+ ]),
24
+ )
@@ -0,0 +1,8 @@
1
+ import * as t from "io-ts"
2
+
3
+ import { Number } from "../../../../../../../validators"
4
+
5
+ export const SpanLocation = t.type({
6
+ start: Number,
7
+ end: Number,
8
+ })
@@ -0,0 +1,26 @@
1
+ import * as t from "io-ts"
2
+
3
+ import { SpanLocation } from "./SpanLocation"
4
+
5
+ const TextSpanTypes = {
6
+ Strong: "strong",
7
+ Em: "em",
8
+ Label: "label",
9
+ } as const
10
+
11
+ export const TextSpanType = t.keyof({
12
+ [TextSpanTypes.Strong]: null,
13
+ [TextSpanTypes.Em]: null,
14
+ [TextSpanTypes.Label]: null,
15
+ })
16
+
17
+ export const TextSpan = t.exact(
18
+ t.intersection([
19
+ t.type({
20
+ type: TextSpanType,
21
+ }),
22
+ SpanLocation,
23
+ ]),
24
+ )
25
+
26
+ export type TextSpan = t.TypeOf<typeof TextSpan>
@@ -0,0 +1,2 @@
1
+ export * from "./HyperlinkSpan"
2
+ export * from "./TextSpan"
@@ -0,0 +1,2 @@
1
+ export { ImportBlock } from "./ImportBlock"
2
+ export { ImportRichText } from "./ImportRichText"
@@ -13,33 +13,38 @@ const LinkTypeValidator = t.type({
13
13
  ),
14
14
  })
15
15
 
16
- const WebLink = t.intersection([
17
- t.type({
18
- link_type: t.literal("Web"),
19
- url: String,
20
- }),
21
- t.partial({
22
- target: String,
23
- }),
24
- ])
16
+ const WebLink = t.exact(
17
+ t.intersection([
18
+ t.type({
19
+ link_type: t.literal("Web"),
20
+ url: String,
21
+ }),
22
+ t.partial({
23
+ target: String,
24
+ }),
25
+ ]),
26
+ )
25
27
  export type WebLink = t.TypeOf<typeof WebLink>
26
28
 
27
- const DocumentLink = t.type({
29
+ const DocumentLink = t.strict({
28
30
  link_type: t.literal("Document"),
29
31
  id: DocumentId,
30
32
  })
31
33
  export type DocumentLink = t.TypeOf<typeof DocumentLink>
32
34
 
33
- const MediaLink = t.type({
35
+ const MediaLink = t.strict({
34
36
  link_type: t.literal("Media"),
35
37
  id: String,
36
38
  })
37
39
  export type MediaLink = t.TypeOf<typeof MediaLink>
38
40
 
39
- const Link = LinkTypeValidator.pipe(t.union([WebLink, DocumentLink, MediaLink]))
41
+ export const Link = LinkTypeValidator.pipe(
42
+ t.union([WebLink, DocumentLink, MediaLink]),
43
+ )
44
+ export type Link = TypeOf<typeof Link>
40
45
 
41
46
  // This is the default value for the link
42
- const AnyLink = t.type({
47
+ const AnyLink = t.strict({
43
48
  link_type: t.literal("Any"),
44
49
  })
45
50
 
@@ -5,6 +5,7 @@ import { ImportDate } from "./Date"
5
5
  import { ImportEmbed } from "./Embed"
6
6
  import { ImportGeoPoint } from "./GeoPoint"
7
7
  import { ImportImage } from "./Image"
8
+ import { ImportRichText } from "./ImportRichText"
8
9
  import { ImportLink } from "./Link"
9
10
  import { ImportNumber } from "./Number"
10
11
  import { ImportSelect } from "./Select"
@@ -23,6 +24,7 @@ export type ImportNestable =
23
24
  | ImportLink
24
25
  | ImportGeoPoint
25
26
  | ImportImage
27
+ | ImportRichText
26
28
 
27
29
  export const ImportNestable = {
28
30
  is(u: unknown): u is ImportNestable {
@@ -37,7 +39,8 @@ export const ImportNestable = {
37
39
  ImportEmbed.is(u) ||
38
40
  ImportLink.is(u) ||
39
41
  ImportGeoPoint.is(u) ||
40
- ImportImage().is(u)
42
+ ImportImage().is(u) ||
43
+ ImportRichText().is(u)
41
44
  )
42
45
  },
43
46
  decode: (field: NestableWidget) => {
@@ -66,6 +69,8 @@ export const ImportNestable = {
66
69
  return ImportImage(field)
67
70
  case "GeoPoint":
68
71
  return ImportGeoPoint
72
+ case "StructuredText":
73
+ return ImportRichText(field)
69
74
  default:
70
75
  throw new Error(`Unsupported type of nestable field ${field.type}`)
71
76
  }
@@ -1,10 +1,11 @@
1
1
  export * from "./Boolean"
2
2
  export * from "./Color"
3
3
  export * from "./Date"
4
- export * from "./Embed"
4
+ export { ImportEmbed } from "./Embed"
5
5
  export * from "./GeoPoint"
6
6
  export * from "./Image"
7
7
  export * from "./Image/index"
8
+ export * from "./ImportRichText"
8
9
  export * from "./Link"
9
10
  export * from "./Nestable"
10
11
  export * from "./Number"