@prismicio/types-internal 2.2.0-alpha.16 → 2.2.0-alpha.17
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.
- package/lib/import/converters/fields/nestable/Image.d.ts +3 -1
- package/lib/import/converters/fields/nestable/Image.js +18 -2
- package/lib/import/converters/fields/nestable/Nestable.js +2 -0
- package/lib/import/converters/fields/nestable/RichText.d.ts +4 -0
- package/lib/import/converters/fields/nestable/RichText.js +55 -0
- package/lib/import/converters/fields/nestable/index.d.ts +1 -0
- package/lib/import/converters/fields/nestable/index.js +1 -0
- package/lib/import/validators/fields/ImportField.d.ts +6 -0
- package/lib/import/validators/fields/ImportSlices/SharedSlice/SharedSlice.js +1 -1
- package/lib/import/validators/fields/ImportSlices/SharedSlice/fields/SharedSliceType.js +1 -1
- package/lib/import/validators/fields/ImportSlices/SharedSlice/fields/SharedSliceVariation.js +1 -1
- package/lib/import/validators/fields/nestable/Embed.d.ts +3 -0
- package/lib/import/validators/fields/nestable/Embed.js +3 -8
- package/lib/import/validators/fields/nestable/GeoPoint.js +2 -2
- package/lib/import/validators/fields/nestable/Image/default.d.ts +22 -0
- package/lib/import/validators/fields/nestable/Image/default.js +19 -0
- package/lib/import/validators/fields/nestable/Image/index.d.ts +19 -0
- package/lib/import/validators/fields/nestable/Image/index.js +22 -22
- package/lib/import/validators/fields/nestable/Image/merge.d.ts +23 -0
- package/lib/import/validators/fields/nestable/Image/merge.js +44 -0
- package/lib/import/validators/fields/nestable/Image/validators.d.ts +35 -0
- package/lib/import/validators/fields/nestable/Image/validators.js +31 -0
- package/lib/import/validators/fields/nestable/ImportRichText/ImportBlock.d.ts +6 -0
- package/lib/import/validators/fields/nestable/ImportRichText/ImportBlock.js +25 -0
- package/lib/import/validators/fields/nestable/ImportRichText/ImportRichText.d.ts +24 -0
- package/lib/import/validators/fields/nestable/ImportRichText/ImportRichText.js +26 -0
- package/lib/import/validators/fields/nestable/ImportRichText/blocks/ImportBlockType.d.ts +6 -0
- package/lib/import/validators/fields/nestable/ImportRichText/blocks/ImportBlockType.js +18 -0
- package/lib/import/validators/fields/nestable/ImportRichText/blocks/ImportEmbedBlock.d.ts +10 -0
- package/lib/import/validators/fields/nestable/ImportRichText/blocks/ImportEmbedBlock.js +11 -0
- package/lib/import/validators/fields/nestable/ImportRichText/blocks/ImportImageBlock.d.ts +8 -0
- package/lib/import/validators/fields/nestable/ImportRichText/blocks/ImportImageBlock.js +11 -0
- package/lib/import/validators/fields/nestable/ImportRichText/blocks/ImportTextBlock.d.ts +70 -0
- package/lib/import/validators/fields/nestable/ImportRichText/blocks/ImportTextBlock.js +43 -0
- package/lib/import/validators/fields/nestable/ImportRichText/blocks/Span.d.ts +65 -0
- package/lib/import/validators/fields/nestable/ImportRichText/blocks/Span.js +20 -0
- package/lib/import/validators/fields/nestable/ImportRichText/blocks/index.d.ts +4 -0
- package/lib/import/validators/fields/nestable/ImportRichText/blocks/index.js +7 -0
- package/lib/import/validators/fields/nestable/ImportRichText/blocks/spans/HyperlinkSpan.d.ts +24 -0
- package/lib/import/validators/fields/nestable/ImportRichText/blocks/spans/HyperlinkSpan.js +18 -0
- package/lib/import/validators/fields/nestable/ImportRichText/blocks/spans/SpanLocation.d.ts +5 -0
- package/lib/import/validators/fields/nestable/ImportRichText/blocks/spans/SpanLocation.js +10 -0
- package/lib/import/validators/fields/nestable/ImportRichText/blocks/spans/TextSpan.d.ts +17 -0
- package/lib/import/validators/fields/nestable/ImportRichText/blocks/spans/TextSpan.js +22 -0
- package/lib/import/validators/fields/nestable/ImportRichText/blocks/spans/index.d.ts +2 -0
- package/lib/import/validators/fields/nestable/ImportRichText/blocks/spans/index.js +5 -0
- package/lib/import/validators/fields/nestable/ImportRichText/index.d.ts +2 -0
- package/lib/import/validators/fields/nestable/ImportRichText/index.js +7 -0
- package/lib/import/validators/fields/nestable/Link.d.ts +21 -6
- package/lib/import/validators/fields/nestable/Link.js +8 -8
- package/lib/import/validators/fields/nestable/Nestable.d.ts +8 -1
- package/lib/import/validators/fields/nestable/Nestable.js +5 -1
- package/lib/import/validators/fields/nestable/index.d.ts +2 -1
- package/lib/import/validators/fields/nestable/index.js +4 -1
- package/package.json +1 -1
- package/src/import/converters/fields/nestable/Image.ts +34 -4
- package/src/import/converters/fields/nestable/Nestable.ts +3 -0
- package/src/import/converters/fields/nestable/RichText.ts +62 -0
- package/src/import/converters/fields/nestable/index.ts +1 -0
- package/src/import/validators/fields/ImportSlices/SharedSlice/SharedSlice.ts +1 -1
- package/src/import/validators/fields/ImportSlices/SharedSlice/fields/SharedSliceType.ts +1 -1
- package/src/import/validators/fields/ImportSlices/SharedSlice/fields/SharedSliceVariation.ts +1 -1
- package/src/import/validators/fields/nestable/Embed.ts +4 -17
- package/src/import/validators/fields/nestable/GeoPoint.ts +2 -2
- package/src/import/validators/fields/nestable/Image/default.ts +25 -0
- package/src/import/validators/fields/nestable/Image/index.ts +34 -36
- package/src/import/validators/fields/nestable/Image/{Decoder.ts → merge.ts} +23 -20
- package/src/import/validators/fields/nestable/Image/{Validator.ts → validators.ts} +9 -2
- package/src/import/validators/fields/nestable/ImportRichText/ImportBlock.ts +39 -0
- package/src/import/validators/fields/nestable/ImportRichText/ImportRichText.ts +41 -0
- package/src/import/validators/fields/nestable/ImportRichText/blocks/ImportBlockType.ts +44 -0
- package/src/import/validators/fields/nestable/ImportRichText/blocks/ImportEmbedBlock.ts +13 -0
- package/src/import/validators/fields/nestable/ImportRichText/blocks/ImportImageBlock.ts +13 -0
- package/src/import/validators/fields/nestable/ImportRichText/blocks/ImportTextBlock.ts +56 -0
- package/src/import/validators/fields/nestable/ImportRichText/blocks/Span.ts +44 -0
- package/src/import/validators/fields/nestable/ImportRichText/blocks/index.ts +4 -0
- package/src/import/validators/fields/nestable/ImportRichText/blocks/spans/HyperlinkSpan.ts +24 -0
- package/src/import/validators/fields/nestable/ImportRichText/blocks/spans/SpanLocation.ts +8 -0
- package/src/import/validators/fields/nestable/ImportRichText/blocks/spans/TextSpan.ts +26 -0
- package/src/import/validators/fields/nestable/ImportRichText/blocks/spans/index.ts +2 -0
- package/src/import/validators/fields/nestable/ImportRichText/index.ts +2 -0
- package/src/import/validators/fields/nestable/Link.ts +18 -13
- package/src/import/validators/fields/nestable/Nestable.ts +6 -1
- package/src/import/validators/fields/nestable/index.ts +2 -1
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { Asset, Embed } from "../../../../common"
|
|
2
|
+
import type { Block, RichTextContent } from "../../../../content"
|
|
3
|
+
import { RichTextContentType } from "../../../../content"
|
|
4
|
+
import type { ImportBlock, ImportRichText } from "../../../validators"
|
|
5
|
+
import { embedConverter } from "./Embed"
|
|
6
|
+
import { imageBlockConverter } from "./Image"
|
|
7
|
+
import { linkConverter } from "./Link"
|
|
8
|
+
|
|
9
|
+
const richTextBlockConverter = (
|
|
10
|
+
importBlock: ImportBlock,
|
|
11
|
+
assets: Record<Asset["id"], Asset | undefined>,
|
|
12
|
+
embeds: Record<string, Embed | undefined>,
|
|
13
|
+
): Block => {
|
|
14
|
+
if (importBlock.type === "image") {
|
|
15
|
+
return {
|
|
16
|
+
type: importBlock.type,
|
|
17
|
+
data: imageBlockConverter(importBlock, assets),
|
|
18
|
+
}
|
|
19
|
+
} else if (importBlock.type === "embed") {
|
|
20
|
+
const embedData = embedConverter(importBlock.oembed, embeds)
|
|
21
|
+
if (!embedData) throw new Error("Failed to convert embed data")
|
|
22
|
+
return {
|
|
23
|
+
type: importBlock.type,
|
|
24
|
+
data: embedData,
|
|
25
|
+
}
|
|
26
|
+
} else {
|
|
27
|
+
// Text block
|
|
28
|
+
return {
|
|
29
|
+
type: importBlock.type,
|
|
30
|
+
direction: importBlock.direction ?? "ltr",
|
|
31
|
+
content: {
|
|
32
|
+
text: importBlock.text,
|
|
33
|
+
spans:
|
|
34
|
+
importBlock.spans?.map((span) => {
|
|
35
|
+
const linkData =
|
|
36
|
+
span.type === "hyperlink"
|
|
37
|
+
? linkConverter(span.data, assets)
|
|
38
|
+
: undefined
|
|
39
|
+
return {
|
|
40
|
+
type: span.type,
|
|
41
|
+
start: span.start,
|
|
42
|
+
end: span.end,
|
|
43
|
+
data: linkData,
|
|
44
|
+
}
|
|
45
|
+
}) ?? [],
|
|
46
|
+
},
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export const richTextConverter = (
|
|
51
|
+
richTextField: ImportRichText["value"],
|
|
52
|
+
assets: Record<Asset["id"], Asset | undefined>,
|
|
53
|
+
embeds: Record<string, Embed | undefined>,
|
|
54
|
+
): RichTextContent | undefined => {
|
|
55
|
+
if (richTextField === null) return
|
|
56
|
+
return {
|
|
57
|
+
__TYPE__: RichTextContentType,
|
|
58
|
+
value: richTextField.map((block) =>
|
|
59
|
+
richTextBlockConverter(block, assets, embeds),
|
|
60
|
+
),
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -15,7 +15,7 @@ export type SharedSliceType = {
|
|
|
15
15
|
* slice_type - the validated slice_type
|
|
16
16
|
* slice - SharedSlice custom type data matching the slice_type. We return it alongside the validated slice_type, because it is needed to decode the 'variation' field in the SharedSlice (see SharedSliceVariation.ts)
|
|
17
17
|
*/
|
|
18
|
-
const SharedSliceTypeShape = t.
|
|
18
|
+
const SharedSliceTypeShape = t.strict({
|
|
19
19
|
slice_type: NonEmptyString,
|
|
20
20
|
slice: SharedSliceCustomType,
|
|
21
21
|
})
|
package/src/import/validators/fields/ImportSlices/SharedSlice/fields/SharedSliceVariation.ts
CHANGED
|
@@ -15,7 +15,7 @@ export type SharedSliceVariation = {
|
|
|
15
15
|
* variation - the validated variation of the slice
|
|
16
16
|
* data - Variation data matching the variation. We return it alongside the validated variation, because it is needed to decode the 'primary' and 'items' fields in the SharedSlice.
|
|
17
17
|
*/
|
|
18
|
-
const SharedSliceVariationShape = t.
|
|
18
|
+
const SharedSliceVariationShape = t.strict({
|
|
19
19
|
variation: NonEmptyString,
|
|
20
20
|
data: Variation,
|
|
21
21
|
})
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import * as Either from "fp-ts/Either"
|
|
2
|
-
import { pipe } from "fp-ts/lib/function"
|
|
3
1
|
import * as t from "io-ts"
|
|
4
2
|
|
|
5
3
|
import { EmptyObjectOrElse } from "../../../../validators"
|
|
@@ -32,23 +30,12 @@ const EmbedUrl = new t.Type<URL, URL, unknown>(
|
|
|
32
30
|
t.identity,
|
|
33
31
|
)
|
|
34
32
|
|
|
35
|
-
const
|
|
33
|
+
export const ImportEmbedValue = t.strict({
|
|
36
34
|
embed_url: EmbedUrl,
|
|
37
35
|
})
|
|
38
|
-
type EmbedProto = t.TypeOf<typeof EmbedProto>
|
|
39
36
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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,
|
|
37
|
+
export const ImportEmbed = ImportContent(
|
|
38
|
+
"Embed",
|
|
39
|
+
EmptyObjectOrElse(ImportEmbedValue),
|
|
51
40
|
)
|
|
52
|
-
|
|
53
|
-
export const ImportEmbed = ImportContent("Embed", EmptyObjectOrElse(Embed))
|
|
54
41
|
export type ImportEmbed = t.TypeOf<typeof ImportEmbed>
|
|
@@ -5,7 +5,7 @@ import { EmptyObjectOrElse, NumberRange } from "../../../../validators"
|
|
|
5
5
|
import { withCustomError } from "../../../../validators/function"
|
|
6
6
|
import { ImportContent } from "../ImportContent"
|
|
7
7
|
|
|
8
|
-
const
|
|
8
|
+
const GeoPoint = withCustomError(
|
|
9
9
|
t.strict({
|
|
10
10
|
latitude: NumberRange(-90, 90, "latitude"),
|
|
11
11
|
longitude: NumberRange(-180, 180, "longitude"),
|
|
@@ -16,6 +16,6 @@ const GeooPoint = withCustomError(
|
|
|
16
16
|
|
|
17
17
|
export const ImportGeoPoint = ImportContent(
|
|
18
18
|
"GeoPoint",
|
|
19
|
-
EmptyObjectOrElse(
|
|
19
|
+
EmptyObjectOrElse(GeoPoint),
|
|
20
20
|
)
|
|
21
21
|
export type ImportGeoPoint = TypeOf<typeof ImportGeoPoint>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as t from "io-ts"
|
|
2
|
+
|
|
3
|
+
import type { Image as ImageDefinition } from "../../../../../customtypes"
|
|
4
|
+
import { EmptyObject } from "../../../../../validators"
|
|
5
|
+
import { withCustomError } from "../../../../../validators/function"
|
|
6
|
+
|
|
7
|
+
export const defaultImportImage = (field?: ImageDefinition) => {
|
|
8
|
+
// If there is not thumbnails we expect an empty object
|
|
9
|
+
if (!field?.config?.thumbnails || !field.config.thumbnails.length)
|
|
10
|
+
return EmptyObject
|
|
11
|
+
|
|
12
|
+
// If there are thumbnails, we expect an object with thumbnails as empty objects
|
|
13
|
+
return withCustomError(
|
|
14
|
+
t.strict(
|
|
15
|
+
field.config.thumbnails.reduce(
|
|
16
|
+
(acc, thumbnail) => ({
|
|
17
|
+
...acc,
|
|
18
|
+
[thumbnail.name]: EmptyObject,
|
|
19
|
+
}),
|
|
20
|
+
{},
|
|
21
|
+
),
|
|
22
|
+
),
|
|
23
|
+
() => "The value must be an object",
|
|
24
|
+
)
|
|
25
|
+
}
|
|
@@ -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
|
|
7
|
+
import { DefaultOrElse } from "../../../../../validators"
|
|
8
8
|
import { withCustomError } from "../../../../../validators/function"
|
|
9
9
|
import { ImportContent } from "../../ImportContent"
|
|
10
|
-
import {
|
|
10
|
+
import { defaultImportImage } from "./default"
|
|
11
|
+
import {
|
|
12
|
+
mergeImageViewWithCtConstraints,
|
|
13
|
+
mergeThumbnailsWithCtConstraints,
|
|
14
|
+
} from "./merge"
|
|
11
15
|
import type { ImageFieldWithThumbnails } from "./model"
|
|
12
|
-
import {
|
|
16
|
+
import { ImportImageView, ImportThumbnails } from "./validators"
|
|
13
17
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
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
|
-
|
|
28
|
+
ImportImageView.is(u) &&
|
|
39
29
|
"thumbnails" in u &&
|
|
40
|
-
|
|
30
|
+
ImportThumbnails.is(u["thumbnails"]),
|
|
41
31
|
(u: unknown, ctx): Validation<ImageFieldWithThumbnails> => {
|
|
42
32
|
return pipe(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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
|
-
|
|
40
|
+
// Validating the thumbnails
|
|
41
|
+
ImportThumbnails.validate(thumbnails, ctx),
|
|
49
42
|
map((thumbnails) => ({
|
|
50
|
-
...
|
|
51
|
-
|
|
52
|
-
|
|
43
|
+
...mergeImageViewWithCtConstraints(
|
|
44
|
+
imageApiV2,
|
|
45
|
+
imageApiV2,
|
|
53
46
|
field?.config?.constraint,
|
|
54
47
|
),
|
|
55
|
-
thumbnails:
|
|
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
|
-
|
|
68
|
-
)(
|
|
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 {
|
|
4
|
+
import type { ImportImageView, ImportThumbnails } from "./validators"
|
|
7
5
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
export const
|
|
12
|
-
image:
|
|
13
|
-
|
|
14
|
-
constraints
|
|
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
|
-
|
|
18
|
+
defaultImage?.dimensions?.width
|
|
21
19
|
const height =
|
|
22
20
|
constraints?.height ??
|
|
23
21
|
image?.dimensions?.height ??
|
|
24
|
-
|
|
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 ??
|
|
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
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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]:
|
|
57
|
+
[thumbnail.name]: mergeImageViewWithCtConstraints(
|
|
55
58
|
thumbnails[thumbnail.name],
|
|
56
|
-
|
|
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
|
|
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
|
|
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
|
+
)
|