@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,77 @@
1
+ import type { Asset } from "../../../../common"
2
+ import { getAssetOrThrow } from "../../../../common"
3
+ import type { LinkContent } from "../../../../content"
4
+ import type {
5
+ DocumentLink,
6
+ ImportLink,
7
+ MediaLink,
8
+ WebLink,
9
+ } from "../../../validators"
10
+
11
+ const webLinkConverter = (field: WebLink): LinkContent => ({
12
+ value: {
13
+ url: field.url,
14
+ target: field.target,
15
+ __TYPE__: "ExternalLink",
16
+ },
17
+ __TYPE__: "LinkContent",
18
+ })
19
+
20
+ const documentLinkConverter = (field: DocumentLink): LinkContent => ({
21
+ value: {
22
+ id: field.id,
23
+ __TYPE__: "DocumentLink",
24
+ },
25
+ __TYPE__: "LinkContent",
26
+ })
27
+
28
+ const fileLinkConverter = (field: MediaLink, asset: Asset): LinkContent => ({
29
+ value: {
30
+ id: field.id,
31
+ url: asset.url,
32
+ name: asset.filename ?? "unknown.jpg",
33
+ kind: asset.kind,
34
+ size: asset.size ?? "0",
35
+ __TYPE__: "FileLink",
36
+ },
37
+ __TYPE__: "LinkContent",
38
+ })
39
+
40
+ const imageLinkConverter = (field: MediaLink, asset: Asset): LinkContent => ({
41
+ value: {
42
+ id: field.id,
43
+ url: asset.url,
44
+ height: String(asset.height ?? 1),
45
+ width: String(asset.width ?? 1),
46
+ name: asset.filename ?? "unknown.jpg",
47
+ kind: asset.kind,
48
+ size: asset.size ?? "0",
49
+ __TYPE__: "ImageLink",
50
+ },
51
+ __TYPE__: "LinkContent",
52
+ })
53
+
54
+ export const linkConverter = (
55
+ field: ImportLink["value"],
56
+ assets: Record<string, Asset | undefined>,
57
+ ): LinkContent | undefined => {
58
+ if (field === null) {
59
+ return
60
+ }
61
+
62
+ switch (field.link_type) {
63
+ case "Web":
64
+ return webLinkConverter(field)
65
+ case "Document":
66
+ return documentLinkConverter(field)
67
+ case "Media": {
68
+ const asset = getAssetOrThrow(assets)(field.id)
69
+ switch (asset.kind) {
70
+ case "all":
71
+ return fileLinkConverter(field, asset)
72
+ case "image":
73
+ return imageLinkConverter(field, asset)
74
+ }
75
+ }
76
+ }
77
+ }
@@ -1,8 +1,15 @@
1
+ import type { Asset } from "../../../../common"
2
+ import type { Embed } from "../../../../common/Embed"
1
3
  import type { WidgetContent } from "../../../../content"
2
4
  import type { ImportNestable } from "../../../validators"
3
5
  import {
6
+ booleanConverter,
4
7
  colorConverter,
5
8
  dateConverter,
9
+ embedConverter,
10
+ geopointConverter,
11
+ imageConverter,
12
+ linkConverter,
6
13
  numberConverter,
7
14
  selectConverter,
8
15
  textConverter,
@@ -11,8 +18,12 @@ import {
11
18
 
12
19
  export function convertNestableWidget(
13
20
  field: ImportNestable,
21
+ assets: Record<Asset["id"], Asset | undefined>,
22
+ embeds: Record<string, Embed | undefined>,
14
23
  ): WidgetContent | undefined {
15
24
  switch (field.type) {
25
+ case "Boolean":
26
+ return booleanConverter(field.value)
16
27
  case "Color":
17
28
  return colorConverter(field.value)
18
29
  case "Select":
@@ -25,6 +36,14 @@ export function convertNestableWidget(
25
36
  return dateConverter(field.value)
26
37
  case "Timestamp":
27
38
  return timestampConverter(field.value)
39
+ case "Embed":
40
+ return embedConverter(field.value, embeds)
41
+ case "GeoPoint":
42
+ return geopointConverter(field.value)
43
+ case "Link":
44
+ return linkConverter(field.value, assets)
45
+ case "Image":
46
+ return imageConverter(field.value, assets)
28
47
  default:
29
48
  throw new Error(
30
49
  `Unsupported type of nestable converter ${JSON.stringify(field)}`,
@@ -1,12 +1,14 @@
1
1
  import type { NumberContent } from "../../../../content"
2
2
  import type { ImportNumber } from "../../../validators"
3
- import { nullableConverter } from "../utils"
4
3
 
5
4
  export const numberConverter = (
6
5
  field: ImportNumber["value"],
7
- ): NumberContent | undefined =>
8
- nullableConverter(field, (value: NonNullable<ImportNumber["value"]>) => ({
6
+ ): NumberContent | undefined => {
7
+ if (field === null) return
8
+
9
+ return {
9
10
  type: "Number",
10
- value: value.toString(),
11
+ value: field.toString(),
11
12
  __TYPE__: "FieldContent",
12
- }))
13
+ }
14
+ }
@@ -1,12 +1,14 @@
1
1
  import type { SelectContent } from "../../../../content"
2
2
  import type { ImportSelect } from "../../../validators"
3
- import { nullableConverter } from "../utils"
4
3
 
5
4
  export const selectConverter = (
6
5
  field: ImportSelect["value"],
7
- ): SelectContent | undefined =>
8
- nullableConverter(field, (value: NonNullable<ImportSelect["value"]>) => ({
6
+ ): SelectContent | undefined => {
7
+ if (field === null) return
8
+
9
+ return {
9
10
  type: "Select",
10
- value: value,
11
+ value: field,
11
12
  __TYPE__: "FieldContent",
12
- }))
13
+ }
14
+ }
@@ -1,12 +1,14 @@
1
1
  import type { TextContent } from "../../../../content"
2
2
  import type { ImportText } from "../../../validators"
3
- import { nullableConverter } from "../utils"
4
3
 
5
4
  export const textConverter = (
6
5
  field: ImportText["value"],
7
- ): TextContent | undefined =>
8
- nullableConverter(field, (value: NonNullable<ImportText["value"]>) => ({
6
+ ): TextContent | undefined => {
7
+ if (field === null) return
8
+
9
+ return {
9
10
  type: "Text",
10
- value: value,
11
+ value: field,
11
12
  __TYPE__: "FieldContent",
12
- }))
13
+ }
14
+ }
@@ -1,12 +1,14 @@
1
1
  import type { TimestampContent } from "../../../../content"
2
- import type { ImportTimestamp } from "../../.."
3
- import { nullableConverter } from "../utils"
2
+ import type { ImportTimestamp } from "../../../validators"
4
3
 
5
4
  export const timestampConverter = (
6
5
  field: ImportTimestamp["value"],
7
- ): TimestampContent | undefined =>
8
- nullableConverter(field, (value: NonNullable<ImportTimestamp["value"]>) => ({
6
+ ): TimestampContent | undefined => {
7
+ if (field === null) return
8
+
9
+ return {
9
10
  type: "Timestamp",
10
- value: value.toISOString(),
11
+ value: field.toISOString(),
11
12
  __TYPE__: "FieldContent",
12
- }))
13
+ }
14
+ }
@@ -1,5 +1,10 @@
1
+ export * from "./Boolean"
1
2
  export * from "./Color"
2
3
  export * from "./Date"
4
+ export * from "./Embed"
5
+ export * from "./GeooPoint"
6
+ export * from "./Image"
7
+ export * from "./Link"
3
8
  export * from "./Nestable"
4
9
  export * from "./Number"
5
10
  export * from "./Select"
@@ -1,96 +1,103 @@
1
- import * as Either from "fp-ts/Either"
1
+ import { either } from "fp-ts"
2
+ import { Either, isLeft } from "fp-ts/Either"
3
+ import { pipe } from "fp-ts/lib/function"
2
4
  import * as t from "io-ts"
5
+ import { withMessage } from "io-ts-types"
3
6
 
4
7
  import type { WidgetKey } from "../../common"
5
- import {
6
- isNestableWidget,
7
- StaticCustomType,
8
- StaticWidget,
9
- } from "../../customtypes"
8
+ import type { StaticCustomType, StaticWidget } from "../../customtypes"
9
+ import { flattenCustomTypeFields } from "../../customtypes"
10
10
  import { isObject } from "../../utils/Objects"
11
- import { getNestableFieldCodec, ImportNestable } from "./fields"
11
+ import { ImportField } from "./fields/ImportField"
12
12
 
13
- export type ImportDocument = Record<WidgetKey, ImportNestable>
14
- export const ImportDocument = (mask: StaticCustomType) =>
15
- new t.Type<ImportDocument, ImportDocument, unknown>(
16
- "ImportDocument",
17
- (u): u is ImportDocument => isObject(u),
18
- (raw: unknown) => {
19
- if (!isObject(raw)) {
20
- const error: t.ValidationError = {
21
- value: raw,
22
- context: [],
23
- message: "document is not an object",
24
- }
25
- return Either.left([error])
26
- }
13
+ const rawImportDocument = withMessage(
14
+ t.record(t.string, t.unknown),
15
+ () => "document is not an object",
16
+ )
27
17
 
28
- // flattening the fields within the tabs
29
- const maskFields = Object.values(mask.json).reduce((acc, tab) => ({
30
- ...acc,
31
- ...tab,
32
- }))
18
+ function validateField(
19
+ document: Record<string, unknown>,
20
+ customType: StaticCustomType,
21
+ ) {
22
+ return (
23
+ key: string,
24
+ content: unknown,
25
+ model?: StaticWidget,
26
+ ): Either<t.Errors, ImportField> => {
27
+ // the field is not defined in the custom type -> extra field or typo
28
+ if (!model) {
29
+ const error: t.ValidationError = {
30
+ value: content,
31
+ context: [{ key: key, type: t.unknown }],
32
+ message: `The field ${key} is not part of the Custom type`,
33
+ }
34
+ return either.left([error])
35
+ }
33
36
 
34
- // Listing all errors for each fields
35
- const { document, errors } = Object.entries(raw).reduce<{
36
- document: ImportDocument
37
- errors: t.Errors
38
- }>(
39
- (acc, [fieldKey, fieldValue]) => {
40
- const maskFieldValue = maskFields[fieldKey]
37
+ // retrieving the right codec then testing out fieldValue with it.
38
+ const { result, codec } = ImportField.decode(model)(content)
41
39
 
42
- // the field is not defined in the custom type -> extra field or typo
43
- if (!maskFieldValue) {
44
- const error: t.ValidationError = {
45
- value: fieldValue,
46
- context: [{ key: fieldKey, type: t.unknown }],
47
- message: `The field ${fieldKey} is not part of the Custom type`,
48
- }
49
- return { ...acc, errors: [...acc.errors, error] }
50
- }
40
+ // error.context is pointing at root when it should point to a `fieldKey`.
41
+ // We need to override the context to make it right.
42
+ if (isLeft(result)) {
43
+ const errors: t.Errors = result.left.map((error) => {
44
+ const contextHead = error.context[0]
45
+ const context = [
46
+ { key: "", actual: document, type: ImportDocument(customType) },
47
+ contextHead
48
+ ? { ...contextHead, key: key }
49
+ : { key: key, actual: content, type: codec },
50
+ ...error.context.slice(1),
51
+ ]
51
52
 
52
- // retrieving the right codec then testing out fieldValue with it.
53
- const fieldCodec = getFieldCodec(maskFieldValue)
54
- const result = fieldCodec.decode(fieldValue)
53
+ return { ...error, context }
54
+ })
55
+ return either.left(errors)
56
+ }
57
+ return either.right(result.right)
58
+ }
59
+ }
55
60
 
56
- // returning validation errors
57
- if (Either.isLeft(result)) {
58
- // error.context is pointing at root when it should point to a `fieldKey`.
59
- // We need to override the context to make it right.
60
- const errors: t.Errors = result.left.map(error => {
61
- const contextHead = error.context[0];
62
- const context = [
63
- { key: '', actual: raw, type: ImportDocument(mask) },
64
- contextHead
65
- ? { ...contextHead, key: fieldKey }
66
- : {key: fieldKey, actual: fieldValue, type: fieldCodec},
67
- ...error.context.slice(1)
68
- ];
61
+ function validateDocument(
62
+ customType: StaticCustomType,
63
+ rawDoc: Record<string, unknown>,
64
+ ) {
65
+ const fieldModels = flattenCustomTypeFields(customType)
66
+ const { document, errors } = Object.entries(rawDoc).reduce<{
67
+ document: ImportDocument
68
+ errors: t.Errors
69
+ }>(
70
+ (acc, [fieldKey, fieldValue]) => {
71
+ const parsedField = validateField(rawDoc, customType)(
72
+ fieldKey,
73
+ fieldValue,
74
+ fieldModels[fieldKey],
75
+ )
69
76
 
70
- return { ...error, context };
71
- });
77
+ if (isLeft(parsedField))
78
+ return { ...acc, errors: [...acc.errors, ...parsedField.left] }
72
79
 
73
- return { ...acc, errors: [...acc.errors, ...errors] };
74
- }
80
+ return {
81
+ ...acc,
82
+ document: { ...acc.document, [fieldKey]: parsedField.right },
83
+ }
84
+ },
85
+ { document: {}, errors: [] },
86
+ )
87
+ if (errors.length > 0) return either.left(errors)
88
+ return either.right(document)
89
+ }
75
90
 
76
- // registering the field as validated
77
- return {
78
- ...acc,
79
- document: { ...acc.document, [fieldKey]: result.right },
80
- }
81
- },
82
- { document: {}, errors: [] },
91
+ export type ImportDocument = Record<WidgetKey, ImportField>
92
+ export const ImportDocument = (customType: StaticCustomType) =>
93
+ new t.Type<ImportDocument, ImportDocument, unknown>(
94
+ "ImportDocument",
95
+ (u): u is ImportDocument => isObject(u),
96
+ (raw: unknown) => {
97
+ return pipe(
98
+ rawImportDocument.decode(raw),
99
+ either.chain((doc) => validateDocument(customType, doc)),
83
100
  )
84
-
85
- // Returning either the errors of
86
- if (errors.length > 0) return Either.left(errors)
87
- return Either.right(document)
88
101
  },
89
102
  t.identity,
90
103
  )
91
-
92
- function getFieldCodec(maskValue: StaticWidget) {
93
- if (isNestableWidget(maskValue)) return getNestableFieldCodec(maskValue)
94
- throw new Error(`Unsupported type of field ${maskValue.type}`)
95
- }
96
-
@@ -0,0 +1,30 @@
1
+ import { either } from "fp-ts"
2
+ import { pipe } from "fp-ts/lib/function"
3
+ import * as t from "io-ts"
4
+
5
+ import type { FieldType } from "../../../customtypes"
6
+ import { isObject } from "../../../utils/Objects"
7
+
8
+ export const ImportContent = <T extends FieldType, A, O = A>(
9
+ type: T,
10
+ valueCodec: t.Type<A, O>,
11
+ ) =>
12
+ new t.Type<{ type: T; value: A }, O>(
13
+ "ImportField",
14
+ (u: unknown): u is { type: T; value: A } => {
15
+ if (!isObject(u)) return false
16
+ return type === u["type"] && valueCodec.is(u["value"])
17
+ },
18
+ (u: unknown) => {
19
+ return pipe(
20
+ valueCodec.decode(u),
21
+ either.map((decodedValue) => {
22
+ return {
23
+ type,
24
+ value: decodedValue,
25
+ }
26
+ }),
27
+ )
28
+ },
29
+ (field) => field.value as unknown as O,
30
+ )
@@ -0,0 +1,25 @@
1
+ import type { StaticWidget } from "../../../customtypes"
2
+ import { ImportNestable } from "./nestable"
3
+ import { ImportUID } from "./UID"
4
+
5
+ export type ImportField = ImportUID | ImportNestable
6
+
7
+ export const ImportField = {
8
+ is(u: unknown): u is ImportNestable {
9
+ return ImportUID.is(u) || ImportNestable.is(u)
10
+ },
11
+ decode: (field: StaticWidget) => {
12
+ return (content: unknown) => {
13
+ switch (field.type) {
14
+ case "UID":
15
+ return { codec: ImportUID, result: ImportUID.decode(content) }
16
+ case "Choice":
17
+ case "Slices":
18
+ case "Group":
19
+ throw new Error(`Unsupported type of field ${field.type}`)
20
+ default:
21
+ return ImportNestable.decode(field)(content)
22
+ }
23
+ }
24
+ },
25
+ }
@@ -0,0 +1,27 @@
1
+ import * as t from "io-ts"
2
+
3
+ import { NullOrElse, String } from "../../../validators"
4
+ import { ImportContent } from "./ImportContent"
5
+
6
+ const regex = /^[a-z0-9-_.]+$/
7
+
8
+ const uidValue = String.pipe(
9
+ new t.Type<string, string, string>(
10
+ "ImportUIDField",
11
+ (u: unknown): u is string => String.is(u),
12
+ (n: string, c: t.Context) => {
13
+ if (regex.test(n)) {
14
+ return t.success(n)
15
+ }
16
+ return t.failure(
17
+ n,
18
+ c,
19
+ "UID can only contain alphanumeric characters, dashes, underscores, and dots",
20
+ )
21
+ },
22
+ t.identity,
23
+ ),
24
+ )
25
+
26
+ export const ImportUID = ImportContent("UID", NullOrElse(uidValue))
27
+ export type ImportUID = t.TypeOf<typeof ImportUID>
@@ -1,8 +1,2 @@
1
- import type { FieldType } from "../../../customtypes"
2
-
3
1
  export * from "./nestable"
4
-
5
- export interface ImportFieldOutput<t extends FieldType, v, d = null> {
6
- type: t
7
- value: v | d
8
- }
2
+ export * from "./UID"
@@ -0,0 +1,7 @@
1
+ import type { TypeOf } from "io-ts"
2
+
3
+ import { Boolean, NullOrElse } from "../../../../validators"
4
+ import { ImportContent } from "../ImportContent"
5
+
6
+ export const ImportBoolean = ImportContent("Boolean", NullOrElse(Boolean))
7
+ export type ImportBoolean = TypeOf<typeof ImportBoolean>
@@ -1,28 +1,28 @@
1
1
  import * as t from "io-ts"
2
2
 
3
3
  import { HexaColor, HexaColorCode } from "../../../../common/HexaColorCode"
4
- import { NullOrT, String } from "../../../../validators"
5
- import type { ImportFieldOutput } from ".."
4
+ import { NullOrElse, String } from "../../../../validators"
5
+ import { ImportContent } from "../ImportContent"
6
6
 
7
- export type ImportColor = ImportFieldOutput<"Color", HexaColorCode>
8
- export const ImportColor = NullOrT<HexaColorCode, ImportColor>(
9
- // @ts-expect-error HexaColorCode is not inferred as a string.
10
- String.pipe(
11
- new t.Type<HexaColorCode, HexaColorCode, string>(
12
- "ImportColorField",
13
- (u: unknown): u is HexaColorCode => String.is(u) && HexaColor.is(u),
14
- (s: string, c: t.Context) => {
15
- if (!HexaColor.is(s)) {
16
- return t.failure(
17
- s,
18
- c,
19
- "The color value must be an hexadecimal color code",
20
- )
21
- }
7
+ const colorValue = new t.Type<HexaColorCode, HexaColorCode, string>(
8
+ "ImportColorValue",
9
+ (u: unknown): u is HexaColorCode => String.is(u) && HexaColor.is(u),
10
+ (s: string, c: t.Context) => {
11
+ if (!HexaColor.is(s)) {
12
+ return t.failure(
13
+ s,
14
+ c,
15
+ "The color value must be an hexadecimal color code",
16
+ )
17
+ }
22
18
 
23
- return t.success(s)
24
- },
25
- t.identity,
26
- ),
27
- ),
28
- )((s: HexaColorCode | null) => ({ type: "Color", value: s }))
19
+ return t.success(s)
20
+ },
21
+ t.identity,
22
+ )
23
+
24
+ export const ImportColor = ImportContent(
25
+ "Color",
26
+ NullOrElse(String.pipe(colorValue)),
27
+ )
28
+ export type ImportColor = t.TypeOf<typeof ImportColor>
@@ -2,34 +2,33 @@ 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 ".."
7
-
5
+ import { NullOrElse, String } from "../../../../validators"
6
+ import { ImportContent } from "../ImportContent"
8
7
  const DATE_INPUT_REGEX = /^(\d{1,4})-(\d{1,2})-(\d{1,2})$/
9
8
 
10
- export type ImportDate = ImportFieldOutput<"Date", Date>
11
- export const ImportDate = NullOrT<Date, ImportDate>(
12
- new t.Type<Date, Date, unknown>(
13
- "ImportDate",
14
- (u: unknown): u is Date => u instanceof Date,
15
- (u: unknown, c: t.Context) =>
16
- pipe(
17
- String.validate(u, c),
18
- chain((s: string) => {
19
- const date = new Date(s)
20
- const isInvalidDate = isNaN(date.getTime())
9
+ const dateValue = new t.Type<Date, Date, unknown>(
10
+ "ImportNumberValue",
11
+ (u: unknown): u is Date => u instanceof Date,
12
+ (u: unknown, c: t.Context) =>
13
+ pipe(
14
+ String.validate(u, c),
15
+ chain((s: string) => {
16
+ const date = new Date(s)
17
+ const isInvalidDate = isNaN(date.getTime())
18
+
19
+ if (isInvalidDate || !DATE_INPUT_REGEX.test(s)) {
20
+ return t.failure(
21
+ u,
22
+ c,
23
+ "The value must be a Date in the format YYYY-MM-DD",
24
+ )
25
+ }
21
26
 
22
- if (isInvalidDate || !DATE_INPUT_REGEX.test(s)) {
23
- return t.failure(
24
- u,
25
- c,
26
- "The value must be a Date in the format YYYY-MM-DD",
27
- )
28
- }
27
+ return t.success(date)
28
+ }),
29
+ ),
30
+ t.identity,
31
+ )
29
32
 
30
- return t.success(date)
31
- }),
32
- ),
33
- t.identity,
34
- ),
35
- )((s: Date | null) => ({ type: "Date", value: s }))
33
+ export const ImportDate = ImportContent("Date", NullOrElse(dateValue))
34
+ export type ImportDate = t.TypeOf<typeof ImportDate>