@prismicio/types-internal 2.2.0-alpha.1 → 2.2.0-alpha.10

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 (167) hide show
  1. package/lib/common/Asset.d.ts +16 -0
  2. package/lib/common/Asset.js +11 -0
  3. package/lib/common/Embed.d.ts +15 -0
  4. package/lib/common/Embed.js +10 -0
  5. package/lib/common/index.d.ts +2 -0
  6. package/lib/common/index.js +2 -0
  7. package/lib/content/Document.d.ts +40 -40
  8. package/lib/content/fields/GroupContent.d.ts +12 -12
  9. package/lib/content/fields/GroupContent.js +11 -4
  10. package/lib/content/fields/WidgetContent.d.ts +56 -56
  11. package/lib/content/fields/nestable/NestableContent.d.ts +7 -7
  12. package/lib/content/fields/nestable/RichTextContent/Blocks.d.ts +12 -12
  13. package/lib/content/fields/nestable/RichTextContent/index.d.ts +9 -9
  14. package/lib/content/fields/slices/Slice/CompositeSliceContent.d.ts +14 -14
  15. package/lib/content/fields/slices/Slice/RepeatableContent.d.ts +5 -5
  16. package/lib/content/fields/slices/Slice/SharedSliceContent.d.ts +14 -14
  17. package/lib/content/fields/slices/Slice/SimpleSliceContent.d.ts +14 -14
  18. package/lib/content/fields/slices/Slice/index.d.ts +30 -30
  19. package/lib/content/fields/slices/SliceItem.d.ts +30 -30
  20. package/lib/content/fields/slices/SlicesContent.d.ts +42 -42
  21. package/lib/customtypes/CustomType.d.ts +2 -0
  22. package/lib/customtypes/CustomType.js +8 -1
  23. package/lib/customtypes/widgets/nestable/NestableWidget.d.ts +0 -157
  24. package/lib/customtypes/widgets/nestable/NestableWidget.js +1 -17
  25. package/lib/import/converters/Document.d.ts +4 -2
  26. package/lib/import/converters/Document.js +9 -7
  27. package/lib/import/converters/fields/UID.d.ts +3 -0
  28. package/lib/import/converters/fields/UID.js +12 -0
  29. package/lib/import/converters/fields/index.d.ts +1 -0
  30. package/lib/import/converters/fields/index.js +1 -0
  31. package/lib/import/converters/fields/nestable/Boolean.d.ts +3 -0
  32. package/lib/import/converters/fields/nestable/Boolean.js +12 -0
  33. package/lib/import/converters/fields/nestable/Color.js +9 -6
  34. package/lib/import/converters/fields/nestable/Date.d.ts +1 -1
  35. package/lib/import/converters/fields/nestable/Date.js +5 -5
  36. package/lib/import/converters/fields/nestable/Embed.d.ts +4 -0
  37. package/lib/import/converters/fields/nestable/Embed.js +32 -0
  38. package/lib/import/converters/fields/nestable/GeooPoint.d.ts +3 -0
  39. package/lib/import/converters/fields/nestable/GeooPoint.js +15 -0
  40. package/lib/import/converters/fields/nestable/Image.d.ts +4 -0
  41. package/lib/import/converters/fields/nestable/Image.js +55 -0
  42. package/lib/import/converters/fields/nestable/Link.d.ts +4 -0
  43. package/lib/import/converters/fields/nestable/Link.js +70 -0
  44. package/lib/import/converters/fields/nestable/Nestable.d.ts +3 -1
  45. package/lib/import/converters/fields/nestable/Nestable.js +11 -1
  46. package/lib/import/converters/fields/nestable/Number.js +9 -6
  47. package/lib/import/converters/fields/nestable/Select.js +9 -6
  48. package/lib/import/converters/fields/nestable/Text.js +9 -6
  49. package/lib/import/converters/fields/nestable/Timestamp.d.ts +1 -1
  50. package/lib/import/converters/fields/nestable/Timestamp.js +9 -6
  51. package/lib/import/converters/fields/nestable/index.d.ts +5 -0
  52. package/lib/import/converters/fields/nestable/index.js +5 -0
  53. package/lib/import/validators/Document.d.ts +4 -4
  54. package/lib/import/validators/Document.js +38 -46
  55. package/lib/import/validators/fields/ImportContent.d.ts +5 -0
  56. package/lib/import/validators/fields/ImportContent.js +21 -0
  57. package/lib/import/validators/fields/ImportField.d.ts +125 -0
  58. package/lib/import/validators/fields/ImportField.js +24 -0
  59. package/lib/import/validators/fields/UID.d.ts +6 -0
  60. package/lib/import/validators/fields/UID.js +15 -0
  61. package/lib/import/validators/fields/index.d.ts +1 -5
  62. package/lib/import/validators/fields/index.js +1 -0
  63. package/lib/import/validators/fields/nestable/Boolean.d.ts +6 -0
  64. package/lib/import/validators/fields/nestable/Boolean.js +6 -0
  65. package/lib/import/validators/fields/nestable/Color.d.ts +5 -4
  66. package/lib/import/validators/fields/nestable/Color.js +4 -4
  67. package/lib/import/validators/fields/nestable/Date.d.ts +5 -3
  68. package/lib/import/validators/fields/nestable/Date.js +4 -2
  69. package/lib/import/validators/fields/nestable/Embed.d.ts +10 -0
  70. package/lib/import/validators/fields/nestable/Embed.js +36 -0
  71. package/lib/import/validators/fields/nestable/GeoPoint.d.ts +13 -0
  72. package/lib/import/validators/fields/nestable/GeoPoint.js +13 -0
  73. package/lib/import/validators/fields/nestable/Image/Decoder.d.ts +26 -0
  74. package/lib/import/validators/fields/nestable/Image/Decoder.js +40 -0
  75. package/lib/import/validators/fields/nestable/Image/Validator.d.ts +37 -0
  76. package/lib/import/validators/fields/nestable/Image/Validator.js +26 -0
  77. package/lib/import/validators/fields/nestable/Image/index.d.ts +26 -0
  78. package/lib/import/validators/fields/nestable/Image/index.js +28 -0
  79. package/lib/import/validators/fields/nestable/Image/model.d.ts +18 -0
  80. package/lib/import/validators/fields/nestable/Image/model.js +2 -0
  81. package/lib/import/validators/fields/nestable/Image.d.ts +62 -0
  82. package/lib/import/validators/fields/nestable/Image.js +76 -0
  83. package/lib/import/validators/fields/nestable/Link.d.ts +38 -0
  84. package/lib/import/validators/fields/nestable/Link.js +35 -0
  85. package/lib/import/validators/fields/nestable/Nestable.d.ts +120 -4
  86. package/lib/import/validators/fields/nestable/Nestable.js +59 -28
  87. package/lib/import/validators/fields/nestable/Number.d.ts +16 -9
  88. package/lib/import/validators/fields/nestable/Number.js +5 -4
  89. package/lib/import/validators/fields/nestable/Select.d.ts +15 -8
  90. package/lib/import/validators/fields/nestable/Select.js +4 -2
  91. package/lib/import/validators/fields/nestable/Text.d.ts +6 -3
  92. package/lib/import/validators/fields/nestable/Text.js +2 -1
  93. package/lib/import/validators/fields/nestable/Timestamp.d.ts +5 -3
  94. package/lib/import/validators/fields/nestable/Timestamp.js +4 -2
  95. package/lib/import/validators/fields/nestable/index.d.ts +6 -0
  96. package/lib/import/validators/fields/nestable/index.js +6 -0
  97. package/lib/utils/DocumentId.d.ts +1 -0
  98. package/lib/utils/DocumentId.js +7 -0
  99. package/lib/utils/Objects.d.ts +1 -0
  100. package/lib/utils/Objects.js +5 -1
  101. package/lib/validators/BasicTypes.d.ts +8 -0
  102. package/lib/validators/BasicTypes.js +19 -1
  103. package/lib/validators/DefaultOrElse.d.ts +5 -0
  104. package/lib/validators/DefaultOrElse.js +21 -0
  105. package/lib/validators/NumberRange.d.ts +32 -0
  106. package/lib/validators/NumberRange.js +40 -0
  107. package/lib/validators/function.d.ts +20 -0
  108. package/lib/validators/function.js +41 -1
  109. package/lib/validators/index.d.ts +2 -1
  110. package/lib/validators/index.js +4 -2
  111. package/package.json +3 -2
  112. package/src/common/Asset.ts +25 -0
  113. package/src/common/Embed.ts +22 -0
  114. package/src/common/index.ts +2 -0
  115. package/src/content/fields/GroupContent.ts +9 -5
  116. package/src/customtypes/CustomType.ts +13 -0
  117. package/src/customtypes/widgets/nestable/NestableWidget.ts +0 -17
  118. package/src/import/converters/Document.ts +22 -11
  119. package/src/import/converters/fields/UID.ts +13 -0
  120. package/src/import/converters/fields/index.ts +1 -0
  121. package/src/import/converters/fields/nestable/Boolean.ts +13 -0
  122. package/src/import/converters/fields/nestable/Color.ts +7 -5
  123. package/src/import/converters/fields/nestable/Date.ts +12 -13
  124. package/src/import/converters/fields/nestable/Embed.ts +37 -0
  125. package/src/import/converters/fields/nestable/GeooPoint.ts +16 -0
  126. package/src/import/converters/fields/nestable/Image.ts +73 -0
  127. package/src/import/converters/fields/nestable/Link.ts +77 -0
  128. package/src/import/converters/fields/nestable/Nestable.ts +19 -0
  129. package/src/import/converters/fields/nestable/Number.ts +7 -5
  130. package/src/import/converters/fields/nestable/Select.ts +7 -5
  131. package/src/import/converters/fields/nestable/Text.ts +7 -5
  132. package/src/import/converters/fields/nestable/Timestamp.ts +8 -6
  133. package/src/import/converters/fields/nestable/index.ts +5 -0
  134. package/src/import/validators/Document.ts +86 -79
  135. package/src/import/validators/fields/ImportContent.ts +30 -0
  136. package/src/import/validators/fields/ImportField.ts +25 -0
  137. package/src/import/validators/fields/UID.ts +27 -0
  138. package/src/import/validators/fields/index.ts +1 -7
  139. package/src/import/validators/fields/nestable/Boolean.ts +7 -0
  140. package/src/import/validators/fields/nestable/Color.ts +23 -23
  141. package/src/import/validators/fields/nestable/Date.ts +26 -27
  142. package/src/import/validators/fields/nestable/Embed.ts +54 -0
  143. package/src/import/validators/fields/nestable/GeoPoint.ts +21 -0
  144. package/src/import/validators/fields/nestable/Image/Decoder.ts +61 -0
  145. package/src/import/validators/fields/nestable/Image/Validator.ts +35 -0
  146. package/src/import/validators/fields/nestable/Image/index.ts +45 -0
  147. package/src/import/validators/fields/nestable/Image/model.ts +18 -0
  148. package/src/import/validators/fields/nestable/Link.ts +54 -0
  149. package/src/import/validators/fields/nestable/Nestable.ts +65 -26
  150. package/src/import/validators/fields/nestable/Number.ts +32 -30
  151. package/src/import/validators/fields/nestable/Select.ts +32 -30
  152. package/src/import/validators/fields/nestable/Text.ts +6 -6
  153. package/src/import/validators/fields/nestable/Timestamp.ts +29 -26
  154. package/src/import/validators/fields/nestable/index.ts +6 -0
  155. package/src/utils/DocumentId.ts +9 -0
  156. package/src/utils/Objects.ts +10 -0
  157. package/src/validators/BasicTypes.ts +48 -0
  158. package/src/validators/DefaultOrElse.ts +24 -0
  159. package/src/validators/NumberRange.ts +51 -0
  160. package/src/validators/function.ts +44 -0
  161. package/src/validators/index.ts +2 -1
  162. package/lib/import/converters/fields/utils.d.ts +0 -1
  163. package/lib/import/converters/fields/utils.js +0 -10
  164. package/lib/validators/NullOrT.d.ts +0 -2
  165. package/lib/validators/NullOrT.js +0 -13
  166. package/src/import/converters/fields/utils.ts +0 -7
  167. package/src/validators/NullOrT.ts +0 -18
@@ -0,0 +1,54 @@
1
+ import * as Either from "fp-ts/Either"
2
+ import { pipe } from "fp-ts/lib/function"
3
+ import * as t from "io-ts"
4
+
5
+ import { EmptyObjectOrElse } from "../../../../validators"
6
+ import { ImportContent } from "../ImportContent"
7
+
8
+ type URL = string
9
+
10
+ function isValidHttpUrl(param: unknown): param is URL {
11
+ try {
12
+ if (typeof param !== "string") {
13
+ return false
14
+ }
15
+ const url = new URL(param)
16
+ return ["http:", "https:"].includes(url.protocol)
17
+ } catch (err) {
18
+ return false
19
+ }
20
+ }
21
+
22
+ const EmbedUrl = new t.Type<URL, URL, unknown>(
23
+ "EmbedUrl",
24
+ (u: unknown): u is URL => isValidHttpUrl(u),
25
+ (u: unknown, c: t.Context) => {
26
+ if (isValidHttpUrl(u)) {
27
+ return t.success(u)
28
+ } else {
29
+ return t.failure(u, c, "The value must be a valid http/https url")
30
+ }
31
+ },
32
+ t.identity,
33
+ )
34
+
35
+ const EmbedProto = t.type({
36
+ embed_url: EmbedUrl,
37
+ })
38
+ type EmbedProto = t.TypeOf<typeof EmbedProto>
39
+
40
+ type Embed = EmbedProto
41
+ const Embed = new t.Type<Embed>(
42
+ "ImportEmbedValue",
43
+ (u: unknown): u is Embed => EmbedProto.is(u),
44
+ (u: unknown) => {
45
+ return pipe(
46
+ EmbedProto.decode(u),
47
+ Either.map((parsed) => ({ embed_url: parsed.embed_url })),
48
+ )
49
+ },
50
+ t.identity,
51
+ )
52
+
53
+ export const ImportEmbed = ImportContent("Embed", EmptyObjectOrElse(Embed))
54
+ export type ImportEmbed = t.TypeOf<typeof ImportEmbed>
@@ -0,0 +1,21 @@
1
+ import type { TypeOf } from "io-ts"
2
+ import * as t from "io-ts"
3
+
4
+ import { EmptyObjectOrElse, NumberRange } from "../../../../validators"
5
+ import { withFallbackMessage } from "../../../../validators/function"
6
+ import { ImportContent } from "../ImportContent"
7
+
8
+ const GeooPoint = withFallbackMessage(
9
+ t.strict({
10
+ latitude: NumberRange(-90, 90, "latitude"),
11
+ longitude: NumberRange(-180, 180, "longitude"),
12
+ }),
13
+ () =>
14
+ "GeoPoint must be an object with the properties `latitude` and `longitude` between the given ranges",
15
+ )
16
+
17
+ export const ImportGeoPoint = ImportContent(
18
+ "GeoPoint",
19
+ EmptyObjectOrElse(GeooPoint),
20
+ )
21
+ export type ImportGeoPoint = TypeOf<typeof ImportGeoPoint>
@@ -0,0 +1,61 @@
1
+ import type { TypeOf } from "io-ts"
2
+
3
+ import type { Image } from "../../../../../customtypes"
4
+ import type ImageConstraint from "../../../../../customtypes/widgets/shared/ImageConstraint"
5
+ import type { ImageField } from "./model"
6
+ import type { ImageFieldValidator, ThumbnailsValidator } from "./Validator"
7
+
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,
15
+ ): ImageField => {
16
+ const background = image?.edit?.background
17
+ const width =
18
+ constraints?.width ??
19
+ image?.dimensions?.width ??
20
+ mainImage.dimensions?.width
21
+ const height =
22
+ constraints?.height ??
23
+ image?.dimensions?.height ??
24
+ mainImage.dimensions?.height
25
+ const alt = image?.alt
26
+ const credit = image?.credit
27
+
28
+ return {
29
+ id: image?.id ?? mainImage?.id,
30
+ edit: {
31
+ x: image?.edit?.x ?? 0,
32
+ y: image?.edit?.y ?? 0,
33
+ zoom: image?.edit?.zoom ?? 1,
34
+ ...(background !== undefined ? { background } : {}),
35
+ },
36
+ dimensions: {
37
+ ...(width !== undefined ? { width } : {}),
38
+ ...(height !== undefined ? { height } : {}),
39
+ },
40
+ ...(alt !== undefined ? { alt } : {}),
41
+ ...(credit !== undefined ? { credit } : {}),
42
+ }
43
+ }
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>,
49
+ field?: Image,
50
+ ) =>
51
+ field?.config?.thumbnails?.reduce(
52
+ (acc, thumbnail) => ({
53
+ ...acc,
54
+ [thumbnail.name]: decodeImageField(
55
+ thumbnails[thumbnail.name],
56
+ mainImage,
57
+ thumbnail,
58
+ ),
59
+ }),
60
+ {},
61
+ ) ?? {}
@@ -0,0 +1,35 @@
1
+ import * as t from "io-ts"
2
+
3
+ import {
4
+ AnyObject,
5
+ Number,
6
+ String,
7
+ StringOrNull,
8
+ } from "../../../../../validators/BasicTypes"
9
+
10
+ export const ImageFieldValidator = AnyObject.pipe(
11
+ t.intersection([
12
+ t.type({
13
+ id: String,
14
+ }),
15
+ t.partial({
16
+ dimensions: AnyObject.pipe(
17
+ t.partial({
18
+ width: Number,
19
+ height: Number,
20
+ }),
21
+ ),
22
+ edit: AnyObject.pipe(
23
+ t.partial({
24
+ x: Number,
25
+ y: Number,
26
+ zoom: Number,
27
+ background: String,
28
+ }),
29
+ ),
30
+ credit: StringOrNull,
31
+ alt: StringOrNull,
32
+ }),
33
+ ]),
34
+ )
35
+ export const ThumbnailsValidator = t.record(t.string, ImageFieldValidator)
@@ -0,0 +1,45 @@
1
+ import { chain, map } from "fp-ts/Either"
2
+ import { pipe } from "fp-ts/function"
3
+ import type { Validation } from "io-ts"
4
+ import * as t from "io-ts"
5
+
6
+ import type { Image as ImageDefinition } from "../../../../../customtypes"
7
+ import { NullOrElse } from "../../../../../validators"
8
+ import { ImportContent } from "../../ImportContent"
9
+ import { decodeImageField, decodeThumbnails } from "./Decoder"
10
+ import type { ImageFieldWithThumbnails } from "./model"
11
+ import { ImageFieldValidator, ThumbnailsValidator } from "./Validator"
12
+
13
+ const ImageField = (field?: ImageDefinition) =>
14
+ new t.Type<ImageFieldWithThumbnails>(
15
+ "ImageField",
16
+ (u: unknown): u is ImageFieldWithThumbnails =>
17
+ ImageFieldValidator.is(u) &&
18
+ "thumbnails" in u &&
19
+ ThumbnailsValidator.is(u["thumbnails"]),
20
+ (u: unknown, ctx): Validation<ImageFieldWithThumbnails> => {
21
+ return pipe(
22
+ ImageFieldValidator.validate(u, ctx),
23
+ chain((mainImage) => {
24
+ const { id, dimensions, edit, credit, alt, ...maybeThumbnails } =
25
+ mainImage
26
+ return pipe(
27
+ ThumbnailsValidator.validate(maybeThumbnails, ctx),
28
+ map((thumbnails) => ({
29
+ ...decodeImageField(
30
+ mainImage,
31
+ mainImage,
32
+ field?.config?.constraint,
33
+ ),
34
+ thumbnails: decodeThumbnails(mainImage, thumbnails, field),
35
+ })),
36
+ )
37
+ }),
38
+ )
39
+ },
40
+ t.identity,
41
+ )
42
+ export const ImportImage = (field?: ImageDefinition) =>
43
+ ImportContent("Image", NullOrElse(ImageField(field)))
44
+ export type ImportImage = t.TypeOf<ReturnType<typeof ImportImage>>
45
+ export * from "./model"
@@ -0,0 +1,18 @@
1
+ export type ImageField = {
2
+ id: string
3
+ edit: {
4
+ x: number
5
+ y: number
6
+ zoom: number
7
+ background?: string
8
+ }
9
+ dimensions: {
10
+ width?: number
11
+ height?: number
12
+ }
13
+ credit?: string | null
14
+ alt?: string | null
15
+ }
16
+ export type ImageFieldWithThumbnails = ImageField & {
17
+ thumbnails: Record<string, ImageField>
18
+ }
@@ -0,0 +1,54 @@
1
+ import type { OutputOf, TypeOf } from "io-ts"
2
+ import * as t from "io-ts"
3
+ import { withMessage } from "io-ts-types"
4
+
5
+ import { DocumentId } from "../../../../utils/DocumentId"
6
+ import { DefaultOrElse, String } from "../../../../validators"
7
+ import { ImportContent } from "../ImportContent"
8
+
9
+ const LinkTypeValidator = t.type({
10
+ link_type: withMessage(
11
+ t.union([t.literal("Web"), t.literal("Document"), t.literal("Media")]),
12
+ () => "The value must be `Web`, `Document` or `Media`",
13
+ ),
14
+ })
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
+ ])
25
+ export type WebLink = t.TypeOf<typeof WebLink>
26
+
27
+ const DocumentLink = t.type({
28
+ link_type: t.literal("Document"),
29
+ id: DocumentId,
30
+ })
31
+ export type DocumentLink = t.TypeOf<typeof DocumentLink>
32
+
33
+ const MediaLink = t.type({
34
+ link_type: t.literal("Media"),
35
+ id: String,
36
+ })
37
+ export type MediaLink = t.TypeOf<typeof MediaLink>
38
+
39
+ const Link = LinkTypeValidator.pipe(t.union([WebLink, DocumentLink, MediaLink]))
40
+
41
+ // This is the default value for the link
42
+ const AnyLink = t.type({
43
+ link_type: t.literal("Any"),
44
+ })
45
+
46
+ export const ImportLink = ImportContent(
47
+ "Link",
48
+ DefaultOrElse<
49
+ TypeOf<typeof AnyLink>,
50
+ TypeOf<typeof Link>,
51
+ OutputOf<typeof Link>
52
+ >(AnyLink)(Link),
53
+ )
54
+ export type ImportLink = TypeOf<typeof ImportLink>
@@ -1,41 +1,80 @@
1
1
  import type { NestableWidget } from "../../../../customtypes"
2
- import { ImportDate, ImportTimestamp } from "."
2
+ import { ImportBoolean } from "./Boolean"
3
3
  import { ImportColor } from "./Color"
4
+ import { ImportDate } from "./Date"
5
+ import { ImportEmbed } from "./Embed"
6
+ import { ImportGeoPoint } from "./GeoPoint"
7
+ import { ImportImage } from "./Image"
8
+ import { ImportLink } from "./Link"
4
9
  import { ImportNumber } from "./Number"
5
10
  import { ImportSelect } from "./Select"
6
11
  import { ImportText } from "./Text"
12
+ import { ImportTimestamp } from "./Timestamp"
7
13
 
8
14
  export type ImportNestable =
15
+ | ImportBoolean
9
16
  | ImportColor
10
- | ImportSelect
11
17
  | ImportNumber
18
+ | ImportSelect
12
19
  | ImportText
13
20
  | ImportDate
14
21
  | ImportTimestamp
22
+ | ImportEmbed
23
+ | ImportLink
24
+ | ImportGeoPoint
25
+ | ImportImage
15
26
 
16
- export const isNestableFieldValue = (u: unknown): u is ImportNestable =>
17
- ImportColor.is(u) ||
18
- ImportSelect().is(u) ||
19
- ImportNumber().is(u) ||
20
- ImportText.is(u) ||
21
- ImportDate.is(u) ||
22
- ImportTimestamp.is(u)
27
+ export const ImportNestable = {
28
+ is(u: unknown): u is ImportNestable {
29
+ return (
30
+ ImportBoolean.is(u) ||
31
+ ImportColor.is(u) ||
32
+ ImportNumber().is(u) ||
33
+ ImportSelect().is(u) ||
34
+ ImportText.is(u) ||
35
+ ImportDate.is(u) ||
36
+ ImportTimestamp.is(u) ||
37
+ ImportEmbed.is(u) ||
38
+ ImportLink.is(u) ||
39
+ ImportGeoPoint.is(u) ||
40
+ ImportImage().is(u)
41
+ )
42
+ },
43
+ decode: (field: NestableWidget) => {
44
+ return (content: unknown) => {
45
+ const codec = (() => {
46
+ switch (field.type) {
47
+ case "Boolean":
48
+ return ImportBoolean
49
+ case "Color":
50
+ return ImportColor
51
+ case "Number":
52
+ return ImportNumber(field)
53
+ case "Select":
54
+ return ImportSelect(field)
55
+ case "Text":
56
+ return ImportText
57
+ case "Date":
58
+ return ImportDate
59
+ case "Timestamp":
60
+ return ImportTimestamp
61
+ case "Embed":
62
+ return ImportEmbed
63
+ case "Link":
64
+ return ImportLink
65
+ case "Image":
66
+ return ImportImage(field)
67
+ case "GeoPoint":
68
+ return ImportGeoPoint
69
+ default:
70
+ throw new Error(`Unsupported type of nestable field ${field.type}`)
71
+ }
72
+ })()
23
73
 
24
- export function getNestableFieldCodec(field: NestableWidget) {
25
- switch (field.type) {
26
- case "Color":
27
- return ImportColor
28
- case "Select":
29
- return ImportSelect(field.config)
30
- case "Number":
31
- return ImportNumber(field.config)
32
- case "Text":
33
- return ImportText
34
- case "Date":
35
- return ImportDate
36
- case "Timestamp":
37
- return ImportTimestamp
38
- default:
39
- throw new Error(`Unsupported type of nestable field ${field.type}`)
40
- }
74
+ return {
75
+ codec,
76
+ result: codec.decode(content),
77
+ }
78
+ }
79
+ },
41
80
  }
@@ -1,36 +1,38 @@
1
1
  import * as t from "io-ts"
2
2
 
3
- import type { NumberConfig } from "../../../../customtypes"
4
- import { NullOrT, Number } from "../../../../validators"
5
- import type { ImportFieldOutput } from ".."
3
+ import type {
4
+ Number as NumberField,
5
+ NumberConfig,
6
+ } from "../../../../customtypes"
7
+ import { NullOrElse, Number } from "../../../../validators"
8
+ import { ImportContent } from "../ImportContent"
6
9
 
7
- export type ImportNumber = ImportFieldOutput<"Number", number>
8
- export const ImportNumber = (config?: NumberConfig) =>
9
- NullOrT<number, ImportNumber>(
10
- Number.pipe(
11
- new t.Type<number, number, number>(
12
- "ImportColorField",
13
- (u: unknown): u is number => Number.is(u),
14
- (n: number, c: t.Context) => {
15
- const min = config?.min
16
- const max = config?.max
10
+ const numberValue = (config?: NumberConfig) =>
11
+ Number.pipe(
12
+ new t.Type<number, number, number>(
13
+ "ImportNumberValue",
14
+ (u: unknown): u is number => Number.is(u),
15
+ (n: number, c: t.Context) => {
16
+ const min = config?.min
17
+ const max = config?.max
17
18
 
18
- if (
19
- (min !== undefined && n < min) ||
20
- (max !== undefined && n > max)
21
- ) {
22
- return t.failure(
23
- n,
24
- c,
25
- `The value must be between [${min !== undefined ? min : ""}, ${
26
- max !== undefined ? max : ""
27
- }]`,
28
- )
29
- }
19
+ if ((min !== undefined && n < min) || (max !== undefined && n > max)) {
20
+ return t.failure(
21
+ n,
22
+ c,
23
+ `The value must be between [${min !== undefined ? min : ""}, ${
24
+ max !== undefined ? max : ""
25
+ }]`,
26
+ )
27
+ }
30
28
 
31
- return t.success(n)
32
- },
33
- t.identity,
34
- ),
29
+ return t.success(n)
30
+ },
31
+ t.identity,
35
32
  ),
36
- )((n: number | null) => ({ type: "Number", value: n }))
33
+ )
34
+
35
+ export const ImportNumber = (field?: NumberField) =>
36
+ ImportContent("Number", NullOrElse(numberValue(field?.config)))
37
+
38
+ export type ImportNumber = t.TypeOf<ReturnType<typeof ImportNumber>>
@@ -1,36 +1,38 @@
1
1
  import * as t from "io-ts"
2
2
 
3
- import type { SelectConfig } from "../../../../customtypes"
4
- import { NullOrT, String } from "../../../../validators"
5
- import type { ImportFieldOutput } from ".."
3
+ import type { Select, SelectConfig } from "../../../../customtypes"
4
+ import { NullOrElse, String } from "../../../../validators"
5
+ import { ImportContent } from "../ImportContent"
6
6
 
7
- export type ImportSelect = ImportFieldOutput<"Select", string>
8
- export const ImportSelect = (config?: SelectConfig) =>
9
- NullOrT<string, ImportSelect>(
10
- String.pipe(
11
- new t.Type<string, string, string>(
12
- "ImportColorField",
13
- (u: unknown): u is string => String.is(u),
14
- (s: string, c: t.Context) => {
15
- if (!config?.options) {
16
- return t.failure(
17
- s,
18
- c,
19
- "The value must be defined in the custom type's configuration of the field",
20
- )
21
- }
7
+ const selectValue = (config?: SelectConfig) =>
8
+ String.pipe(
9
+ new t.Type<string, string, string>(
10
+ "ImportSelectValue",
11
+ (u: unknown): u is string => String.is(u),
12
+ (s: string, c: t.Context) => {
13
+ if (!config?.options) {
14
+ return t.failure(
15
+ s,
16
+ c,
17
+ "The value must be defined in the custom type's configuration of the field",
18
+ )
19
+ }
22
20
 
23
- if (!config.options.includes(s)) {
24
- return t.failure(
25
- s,
26
- c,
27
- `The value must be one of these: ${config.options?.join(",")}`,
28
- )
29
- }
21
+ if (!config.options.includes(s)) {
22
+ return t.failure(
23
+ s,
24
+ c,
25
+ `The value must be one of these: ${config.options?.join(",")}`,
26
+ )
27
+ }
30
28
 
31
- return t.success(s)
32
- },
33
- t.identity,
34
- ),
29
+ return t.success(s)
30
+ },
31
+ t.identity,
35
32
  ),
36
- )((s: string | null) => ({ type: "Select", value: s }))
33
+ )
34
+
35
+ export const ImportSelect = (field?: Select) =>
36
+ ImportContent("Select", NullOrElse(selectValue(field?.config)))
37
+
38
+ export type ImportSelect = t.TypeOf<ReturnType<typeof ImportSelect>>
@@ -1,7 +1,7 @@
1
- import { NullOrT, String } from "../../../../validators"
2
- import type { ImportFieldOutput } from ".."
1
+ import type { TypeOf } from "io-ts"
3
2
 
4
- export type ImportText = ImportFieldOutput<"Text", string>
5
- export const ImportText = NullOrT<string, ImportText>(String)(
6
- (s: string | null) => ({ type: "Text", value: s }),
7
- )
3
+ import { NullOrElse, String } from "../../../../validators"
4
+ import { ImportContent } from "../ImportContent"
5
+
6
+ export const ImportText = ImportContent("Text", NullOrElse(String))
7
+ export type ImportText = TypeOf<typeof ImportText>
@@ -2,35 +2,38 @@ import { chain } from "fp-ts/Either"
2
2
  import { pipe } from "fp-ts/function"
3
3
  import * as t from "io-ts"
4
4
 
5
- import { NullOrT, String } from "../../../../validators"
6
- import type { ImportFieldOutput } from ".."
5
+ import { NullOrElse, String } from "../../../../validators"
6
+ import { ImportContent } from "../ImportContent"
7
7
 
8
8
  export const TIMESTAMP_INPUT_REGEX =
9
9
  /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:(?:[+-]{1}\d{2}:?\d{2})|Z)$/
10
10
 
11
- export type ImportTimestamp = ImportFieldOutput<"Timestamp", Date>
12
- export const ImportTimestamp = NullOrT<Date, ImportTimestamp>(
13
- new t.Type<Date, Date, unknown>(
14
- "ImportDate",
15
- (u: unknown): u is Date => u instanceof Date,
16
- (u: unknown, c: t.Context) =>
17
- pipe(
18
- String.validate(u, c),
19
- chain((s: string) => {
20
- const date = new Date(s)
21
- const isInvalidDate = isNaN(date.getTime())
11
+ const timestampValue = new t.Type<Date, Date, unknown>(
12
+ "ImportTimestampValue",
13
+ (u: unknown): u is Date => u instanceof Date,
14
+ (u: unknown, c: t.Context) =>
15
+ pipe(
16
+ String.validate(u, c),
17
+ chain((s: string) => {
18
+ const date = new Date(s)
19
+ const isInvalidDate = isNaN(date.getTime())
22
20
 
23
- if (isInvalidDate || !TIMESTAMP_INPUT_REGEX.test(s)) {
24
- return t.failure(
25
- u,
26
- c,
27
- "The value must be a DateTime in the format YYYY-MM-DDTHH:MM:SS+0000",
28
- )
29
- }
21
+ if (isInvalidDate || !TIMESTAMP_INPUT_REGEX.test(s)) {
22
+ return t.failure(
23
+ u,
24
+ c,
25
+ "The value must be a DateTime in the format YYYY-MM-DDTHH:MM:SS+0000",
26
+ )
27
+ }
30
28
 
31
- return t.success(date)
32
- }),
33
- ),
34
- t.identity,
35
- ),
36
- )((s: Date | null) => ({ type: "Timestamp", value: s }))
29
+ return t.success(date)
30
+ }),
31
+ ),
32
+ t.identity,
33
+ )
34
+
35
+ export const ImportTimestamp = ImportContent(
36
+ "Timestamp",
37
+ NullOrElse(timestampValue),
38
+ )
39
+ export type ImportTimestamp = t.TypeOf<typeof ImportTimestamp>
@@ -1,5 +1,11 @@
1
+ export * from "./Boolean"
1
2
  export * from "./Color"
2
3
  export * from "./Date"
4
+ export * from "./Embed"
5
+ export * from "./GeoPoint"
6
+ export * from "./Image"
7
+ export * from "./Image/index"
8
+ export * from "./Link"
3
9
  export * from "./Nestable"
4
10
  export * from "./Number"
5
11
  export * from "./Select"
@@ -0,0 +1,9 @@
1
+ import { withMessage } from "io-ts-types"
2
+
3
+ import { String } from "../validators"
4
+ import { refineType } from "../validators/function"
5
+
6
+ export const DocumentId = withMessage(
7
+ refineType(String, "DocumentId", (s) => s.length === 16),
8
+ () => "DocumentId must be a 16 character string",
9
+ )
@@ -41,3 +41,13 @@ const recordCodec = t.record(t.string, t.unknown)
41
41
  export function isObject(value: unknown): value is Record<string, unknown> {
42
42
  return isRight(recordCodec.decode(value))
43
43
  }
44
+
45
+ export function mapValues<T, O>(
46
+ record: Record<string, T>,
47
+ fn: (value: T, key: string) => O,
48
+ ): Record<string, O> {
49
+ return Object.entries<T>(record).reduce<Record<string, O>>(
50
+ (acc, [key, value]) => ({ ...acc, [key]: fn(value, key) }),
51
+ {},
52
+ )
53
+ }