@prismicio/types-internal 2.2.0-alpha.24 → 2.2.0-alpha.26
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/Document.js +2 -0
- package/lib/import/converters/fields/Group.d.ts +4 -0
- package/lib/import/converters/fields/Group.js +14 -0
- package/lib/import/converters/fields/RepeatableZone.d.ts +309 -0
- package/lib/import/converters/fields/RepeatableZone.js +15 -0
- package/lib/import/converters/fields/RepeatableZoneItem.d.ts +11 -0
- package/lib/import/converters/fields/RepeatableZoneItem.js +19 -0
- package/lib/import/converters/fields/Slices/SharedSliceContent.js +6 -41
- package/lib/import/converters/fields/index.d.ts +1 -0
- package/lib/import/converters/fields/index.js +1 -0
- package/lib/import/validators/fields/ImportContent.js +1 -1
- package/lib/import/validators/fields/ImportField.d.ts +12 -2
- package/lib/import/validators/fields/ImportField.js +6 -1
- package/lib/import/validators/fields/ImportGroup.d.ts +345 -0
- package/lib/import/validators/fields/ImportGroup.js +27 -0
- package/lib/import/validators/fields/ImportSlices/ImportSlices.js +4 -3
- package/lib/import/validators/fields/ImportSlices/SharedSlice/SharedSlice.d.ts +5 -3
- package/lib/import/validators/fields/ImportSlices/SharedSlice/SharedSlice.js +4 -4
- package/lib/import/validators/fields/ImportSlices/SharedSlice/fields/index.d.ts +0 -1
- package/lib/import/validators/fields/ImportSlices/SharedSlice/fields/index.js +0 -1
- package/lib/import/validators/fields/RepeatableZone.d.ts +11 -0
- package/lib/import/validators/fields/RepeatableZone.js +14 -0
- package/lib/import/validators/fields/RepeatableZoneItem.d.ts +11 -0
- package/lib/import/validators/fields/RepeatableZoneItem.js +39 -0
- package/lib/import/validators/fields/index.d.ts +2 -0
- package/lib/import/validators/fields/index.js +2 -0
- package/lib/import/validators/fields/nestable/ImportRichText/ImportRichText.d.ts +1 -1
- package/lib/import/validators/fields/nestable/ImportRichText/ImportRichText.js +20 -14
- package/lib/import/validators/fields/nestable/Nestable.d.ts +61 -1
- package/lib/import/validators/fields/nestable/Nestable.js +32 -30
- package/lib/validators/DefaultOrElse.js +1 -1
- package/package.json +1 -1
- package/src/import/converters/Document.ts +7 -1
- package/src/import/converters/fields/Group.ts +18 -0
- package/src/import/converters/fields/RepeatableZone.ts +19 -0
- package/src/import/converters/fields/RepeatableZoneItem.ts +32 -0
- package/src/import/converters/fields/Slices/SharedSliceContent.ts +9 -76
- package/src/import/converters/fields/index.ts +1 -0
- package/src/import/validators/fields/ImportContent.ts +1 -1
- package/src/import/validators/fields/ImportField.ts +7 -2
- package/src/import/validators/fields/ImportGroup.ts +45 -0
- package/src/import/validators/fields/ImportSlices/ImportSlices.ts +5 -3
- package/src/import/validators/fields/ImportSlices/SharedSlice/SharedSlice.ts +6 -18
- package/src/import/validators/fields/ImportSlices/SharedSlice/fields/index.ts +0 -1
- package/src/import/validators/fields/RepeatableZone.ts +21 -0
- package/src/import/validators/fields/RepeatableZoneItem.ts +64 -0
- package/src/import/validators/fields/index.ts +2 -0
- package/src/import/validators/fields/nestable/ImportRichText/ImportRichText.ts +38 -25
- package/src/import/validators/fields/nestable/Nestable.ts +34 -31
- package/src/validators/DefaultOrElse.ts +1 -1
- package/lib/import/validators/fields/ImportSlices/SharedSlice/fields/SharedSliceContent/SharedSliceContent.d.ts +0 -17
- package/lib/import/validators/fields/ImportSlices/SharedSlice/fields/SharedSliceContent/SharedSliceContent.js +0 -30
- package/lib/import/validators/fields/ImportSlices/SharedSlice/fields/SharedSliceContent/SharedSliceContentEntry.d.ts +0 -43
- package/lib/import/validators/fields/ImportSlices/SharedSlice/fields/SharedSliceContent/SharedSliceContentEntry.js +0 -69
- package/lib/import/validators/fields/ImportSlices/SharedSlice/fields/SharedSliceContent/errors.d.ts +0 -4
- package/lib/import/validators/fields/ImportSlices/SharedSlice/fields/SharedSliceContent/errors.js +0 -6
- package/lib/import/validators/fields/ImportSlices/SharedSlice/fields/SharedSliceContent/index.d.ts +0 -2
- package/lib/import/validators/fields/ImportSlices/SharedSlice/fields/SharedSliceContent/index.js +0 -5
- package/lib/import/validators/fields/ImportSlices/SharedSlice/fields/SharedSliceContent/types.d.ts +0 -1
- package/lib/import/validators/fields/ImportSlices/SharedSlice/fields/SharedSliceContent/types.js +0 -2
- package/lib/utils/io-ts.d.ts +0 -2
- package/lib/utils/io-ts.js +0 -22
- package/src/import/validators/fields/ImportSlices/SharedSlice/fields/SharedSliceContent/SharedSliceContent.ts +0 -64
- package/src/import/validators/fields/ImportSlices/SharedSlice/fields/SharedSliceContent/SharedSliceContentEntry.ts +0 -100
- package/src/import/validators/fields/ImportSlices/SharedSlice/fields/SharedSliceContent/errors.ts +0 -10
- package/src/import/validators/fields/ImportSlices/SharedSlice/fields/SharedSliceContent/index.ts +0 -2
- package/src/import/validators/fields/ImportSlices/SharedSlice/fields/SharedSliceContent/types.ts +0 -1
- package/src/utils/io-ts.ts +0 -29
|
@@ -62,7 +62,7 @@ export declare const ImportNestable: {
|
|
|
62
62
|
} | undefined, unknown> | import("io-ts").Type<{
|
|
63
63
|
type: "StructuredText";
|
|
64
64
|
value: import("./ImportRichText").ImportBlock[] | null;
|
|
65
|
-
},
|
|
65
|
+
}, import("./ImportRichText").ImportBlock[] | undefined, unknown> | import("io-ts").Type<{
|
|
66
66
|
type: "Number";
|
|
67
67
|
value: number | null;
|
|
68
68
|
}, number | undefined, unknown> | import("io-ts").Type<{
|
|
@@ -129,4 +129,64 @@ export declare const ImportNestable: {
|
|
|
129
129
|
value: boolean | null;
|
|
130
130
|
}>;
|
|
131
131
|
};
|
|
132
|
+
getCodec: (field: NestableWidget) => import("io-ts").Type<{
|
|
133
|
+
type: "Boolean";
|
|
134
|
+
value: boolean | null;
|
|
135
|
+
}, boolean | undefined, unknown> | import("io-ts").Type<{
|
|
136
|
+
type: "Color";
|
|
137
|
+
value: `#${string}` | null;
|
|
138
|
+
}, string | undefined, unknown> | import("io-ts").Type<{
|
|
139
|
+
type: "Date";
|
|
140
|
+
value: Date | null;
|
|
141
|
+
}, Date | undefined, unknown> | import("io-ts").Type<{
|
|
142
|
+
type: "Embed";
|
|
143
|
+
value: {
|
|
144
|
+
embed_url: string;
|
|
145
|
+
} | null;
|
|
146
|
+
}, {
|
|
147
|
+
embed_url: string;
|
|
148
|
+
} | undefined, unknown> | import("io-ts").Type<{
|
|
149
|
+
type: "GeoPoint";
|
|
150
|
+
value: {
|
|
151
|
+
latitude: number;
|
|
152
|
+
longitude: number;
|
|
153
|
+
} | null;
|
|
154
|
+
}, {
|
|
155
|
+
latitude: number;
|
|
156
|
+
longitude: number;
|
|
157
|
+
} | undefined, unknown> | import("io-ts").Type<{
|
|
158
|
+
type: "Image";
|
|
159
|
+
value: import("./Image").ImageFieldWithThumbnails | null;
|
|
160
|
+
}, import("./Image").ImageFieldWithThumbnails | undefined, unknown> | import("io-ts").Type<{
|
|
161
|
+
type: "Link";
|
|
162
|
+
value: ({
|
|
163
|
+
link_type: "Web";
|
|
164
|
+
url: string;
|
|
165
|
+
} & {
|
|
166
|
+
target?: string;
|
|
167
|
+
}) | {
|
|
168
|
+
link_type: "Document";
|
|
169
|
+
id: string;
|
|
170
|
+
} | {
|
|
171
|
+
link_type: "Media";
|
|
172
|
+
id: string;
|
|
173
|
+
} | null;
|
|
174
|
+
}, {
|
|
175
|
+
link_type: "Document" | "Web" | "Media";
|
|
176
|
+
} | undefined, unknown> | import("io-ts").Type<{
|
|
177
|
+
type: "StructuredText";
|
|
178
|
+
value: import("./ImportRichText").ImportBlock[] | null;
|
|
179
|
+
}, import("./ImportRichText").ImportBlock[] | undefined, unknown> | import("io-ts").Type<{
|
|
180
|
+
type: "Number";
|
|
181
|
+
value: number | null;
|
|
182
|
+
}, number | undefined, unknown> | import("io-ts").Type<{
|
|
183
|
+
type: "Select";
|
|
184
|
+
value: string | null;
|
|
185
|
+
}, string | undefined, unknown> | import("io-ts").Type<{
|
|
186
|
+
type: "Text";
|
|
187
|
+
value: string | null;
|
|
188
|
+
}, string | undefined, unknown> | import("io-ts").Type<{
|
|
189
|
+
type: "Timestamp";
|
|
190
|
+
value: Date | null;
|
|
191
|
+
}, Date | undefined, unknown>;
|
|
132
192
|
};
|
|
@@ -13,6 +13,36 @@ const Number_1 = require("./Number");
|
|
|
13
13
|
const Select_1 = require("./Select");
|
|
14
14
|
const Text_1 = require("./Text");
|
|
15
15
|
const Timestamp_1 = require("./Timestamp");
|
|
16
|
+
const getCodecOrThrow = (field) => {
|
|
17
|
+
switch (field.type) {
|
|
18
|
+
case "Boolean":
|
|
19
|
+
return Boolean_1.ImportBoolean;
|
|
20
|
+
case "Color":
|
|
21
|
+
return Color_1.ImportColor;
|
|
22
|
+
case "Number":
|
|
23
|
+
return (0, Number_1.ImportNumber)(field);
|
|
24
|
+
case "Select":
|
|
25
|
+
return (0, Select_1.ImportSelect)(field);
|
|
26
|
+
case "Text":
|
|
27
|
+
return Text_1.ImportText;
|
|
28
|
+
case "Date":
|
|
29
|
+
return Date_1.ImportDate;
|
|
30
|
+
case "Timestamp":
|
|
31
|
+
return Timestamp_1.ImportTimestamp;
|
|
32
|
+
case "Embed":
|
|
33
|
+
return Embed_1.ImportEmbed;
|
|
34
|
+
case "Link":
|
|
35
|
+
return Link_1.ImportLink;
|
|
36
|
+
case "Image":
|
|
37
|
+
return (0, Image_1.ImportImage)(field);
|
|
38
|
+
case "GeoPoint":
|
|
39
|
+
return GeoPoint_1.ImportGeoPoint;
|
|
40
|
+
case "StructuredText":
|
|
41
|
+
return (0, ImportRichText_1.ImportRichText)(field);
|
|
42
|
+
default:
|
|
43
|
+
throw new Error(`Unsupported type of nestable field ${field.type}`);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
16
46
|
exports.ImportNestable = {
|
|
17
47
|
is(u) {
|
|
18
48
|
return (Boolean_1.ImportBoolean.is(u) ||
|
|
@@ -30,40 +60,12 @@ exports.ImportNestable = {
|
|
|
30
60
|
},
|
|
31
61
|
decode: (field) => {
|
|
32
62
|
return (content) => {
|
|
33
|
-
const codec = (
|
|
34
|
-
switch (field.type) {
|
|
35
|
-
case "Boolean":
|
|
36
|
-
return Boolean_1.ImportBoolean;
|
|
37
|
-
case "Color":
|
|
38
|
-
return Color_1.ImportColor;
|
|
39
|
-
case "Number":
|
|
40
|
-
return (0, Number_1.ImportNumber)(field);
|
|
41
|
-
case "Select":
|
|
42
|
-
return (0, Select_1.ImportSelect)(field);
|
|
43
|
-
case "Text":
|
|
44
|
-
return Text_1.ImportText;
|
|
45
|
-
case "Date":
|
|
46
|
-
return Date_1.ImportDate;
|
|
47
|
-
case "Timestamp":
|
|
48
|
-
return Timestamp_1.ImportTimestamp;
|
|
49
|
-
case "Embed":
|
|
50
|
-
return Embed_1.ImportEmbed;
|
|
51
|
-
case "Link":
|
|
52
|
-
return Link_1.ImportLink;
|
|
53
|
-
case "Image":
|
|
54
|
-
return (0, Image_1.ImportImage)(field);
|
|
55
|
-
case "GeoPoint":
|
|
56
|
-
return GeoPoint_1.ImportGeoPoint;
|
|
57
|
-
case "StructuredText":
|
|
58
|
-
return (0, ImportRichText_1.ImportRichText)(field);
|
|
59
|
-
default:
|
|
60
|
-
throw new Error(`Unsupported type of nestable field ${field.type}`);
|
|
61
|
-
}
|
|
62
|
-
})();
|
|
63
|
+
const codec = getCodecOrThrow(field);
|
|
63
64
|
return {
|
|
64
65
|
codec,
|
|
65
66
|
result: codec.decode(content),
|
|
66
67
|
};
|
|
67
68
|
};
|
|
68
69
|
},
|
|
70
|
+
getCodec: getCodecOrThrow,
|
|
69
71
|
};
|
|
@@ -6,7 +6,7 @@ const Either_1 = require("fp-ts/lib/Either");
|
|
|
6
6
|
const t = (0, tslib_1.__importStar)(require("io-ts"));
|
|
7
7
|
const BasicTypes_1 = require("./BasicTypes");
|
|
8
8
|
const DefaultOrElse = (inputValidator) => {
|
|
9
|
-
return (codec) => new t.Type(
|
|
9
|
+
return (codec) => new t.Type(`DefaultOrElse<${inputValidator.name}, ${codec.name}>`, (u) => null === u || codec.is(u), (u, c) => {
|
|
10
10
|
if ((0, Either_1.isRight)(inputValidator.validate(u, c)))
|
|
11
11
|
return t.success(null);
|
|
12
12
|
return codec.validate(u, c);
|
package/package.json
CHANGED
|
@@ -2,7 +2,11 @@ import type { Asset, Embed } from "../../common"
|
|
|
2
2
|
import type { Document, WidgetContent } from "../../content"
|
|
3
3
|
import type { ImportDocument } from "../validators"
|
|
4
4
|
import type { ImportField } from "../validators/fields/ImportField"
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
convertNestableWidget,
|
|
7
|
+
importGroupConverter,
|
|
8
|
+
importSlicesConverter,
|
|
9
|
+
} from "./fields"
|
|
6
10
|
|
|
7
11
|
export function convertImportToContent(
|
|
8
12
|
document: ImportDocument,
|
|
@@ -26,6 +30,8 @@ function convertWidget(
|
|
|
26
30
|
switch (field.type) {
|
|
27
31
|
case "Slices":
|
|
28
32
|
return importSlicesConverter(field.value, assets, embeds)
|
|
33
|
+
case "Group":
|
|
34
|
+
return importGroupConverter(field.value, assets, embeds)
|
|
29
35
|
default:
|
|
30
36
|
return convertNestableWidget(field, assets, embeds)
|
|
31
37
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Asset, Embed } from "../../../common"
|
|
2
|
+
import type { GroupContent } from "../../../content"
|
|
3
|
+
import { GroupContentType } from "../../../content"
|
|
4
|
+
import type { ImportGroup } from "../../validators/fields/ImportGroup"
|
|
5
|
+
import { repeatableZoneConverter } from "./RepeatableZone"
|
|
6
|
+
|
|
7
|
+
export const importGroupConverter = (
|
|
8
|
+
field: ImportGroup["value"],
|
|
9
|
+
assets: Record<Asset["id"], Asset | undefined>,
|
|
10
|
+
embeds: Record<string, Embed | undefined>,
|
|
11
|
+
): GroupContent | undefined => {
|
|
12
|
+
if (field === null) return
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
__TYPE__: GroupContentType,
|
|
16
|
+
value: repeatableZoneConverter(field, assets, embeds),
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Asset, Embed } from "../../../common"
|
|
2
|
+
import { GroupItemContentType, NestableContent } from "../../../content"
|
|
3
|
+
import type { RepeatableZone } from "../../validators"
|
|
4
|
+
import { repeatableZoneItemConverter } from "./RepeatableZoneItem"
|
|
5
|
+
|
|
6
|
+
export const repeatableZoneConverter = (
|
|
7
|
+
zone: RepeatableZone,
|
|
8
|
+
assets: Record<Asset["id"], Asset | undefined>,
|
|
9
|
+
embeds: Record<string, Embed | undefined>,
|
|
10
|
+
) => {
|
|
11
|
+
return zone.map((item) => {
|
|
12
|
+
const groupContent: Record<string, NestableContent> =
|
|
13
|
+
repeatableZoneItemConverter(item, assets, embeds)
|
|
14
|
+
return {
|
|
15
|
+
__TYPE__: GroupItemContentType,
|
|
16
|
+
value: Object.entries(groupContent),
|
|
17
|
+
}
|
|
18
|
+
})
|
|
19
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { pipe } from "fp-ts/function"
|
|
2
|
+
import * as O from "fp-ts/Option"
|
|
3
|
+
import * as R from "fp-ts/Record"
|
|
4
|
+
|
|
5
|
+
import type { Asset, Embed } from "../../../common"
|
|
6
|
+
import type { NestableContent } from "../../../content"
|
|
7
|
+
import type { RepeatableZoneItem } from "../../validators"
|
|
8
|
+
import { convertNestableWidget } from "./nestable"
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Converts the RepeatableZoneItem which is a record of widget keys and ImportNestable values to a record of widget keys and NestableContent values.
|
|
12
|
+
*
|
|
13
|
+
* @param content a single RepeatableZoneItem
|
|
14
|
+
* @param assets assets that are required for a conversion of a nestable widget
|
|
15
|
+
* @param embeds embeds that are required for a conversion of a nestable widget
|
|
16
|
+
*/
|
|
17
|
+
export const repeatableZoneItemConverter = (
|
|
18
|
+
content: RepeatableZoneItem,
|
|
19
|
+
assets: Record<Asset["id"], Asset | undefined>,
|
|
20
|
+
embeds: Record<string, Embed | undefined>,
|
|
21
|
+
): Record<string, NestableContent> =>
|
|
22
|
+
pipe(
|
|
23
|
+
content,
|
|
24
|
+
// convertNestableWidget can theoretically return undefined, so we need to filter out those values
|
|
25
|
+
R.filterMap((contentValue) =>
|
|
26
|
+
pipe(
|
|
27
|
+
contentValue,
|
|
28
|
+
(content) => content && convertNestableWidget(content, assets, embeds),
|
|
29
|
+
O.fromNullable,
|
|
30
|
+
),
|
|
31
|
+
),
|
|
32
|
+
)
|
|
@@ -1,78 +1,9 @@
|
|
|
1
|
-
import { pipe } from "fp-ts/function"
|
|
2
|
-
import * as O from "fp-ts/Option"
|
|
3
|
-
import * as R from "fp-ts/Record"
|
|
4
|
-
|
|
5
1
|
import type { Asset, Embed } from "../../../../common"
|
|
6
|
-
import type {
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
} from "
|
|
11
|
-
import type {
|
|
12
|
-
SharedSlice as ImportSharedSlice,
|
|
13
|
-
SharedSliceContent as ImportSharedSliceContent,
|
|
14
|
-
} from "../../../validators/fields/ImportSlices/SharedSlice"
|
|
15
|
-
import { convertNestableWidget } from "../nestable"
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Converts the ImportSharedSliceContent which is a record of widget keys and ImportNestable values to a record of widget keys and NestableContent values.
|
|
19
|
-
*
|
|
20
|
-
* @param content a single ImportSharedSliceContent
|
|
21
|
-
* @param assets assets that are required for a conversion of a nestable widget
|
|
22
|
-
* @param embeds embeds that are required for a conversion of a nestable widget
|
|
23
|
-
*/
|
|
24
|
-
const sharedSliceContentConverter = (
|
|
25
|
-
content: ImportSharedSliceContent,
|
|
26
|
-
assets: Record<Asset["id"], Asset | undefined>,
|
|
27
|
-
embeds: Record<string, Embed | undefined>,
|
|
28
|
-
): Record<string, NestableContent> =>
|
|
29
|
-
pipe(
|
|
30
|
-
content,
|
|
31
|
-
// convertNestableWidget can theoretically return undefined, so we need to filter out those values
|
|
32
|
-
R.filterMap((contentValue) =>
|
|
33
|
-
pipe(
|
|
34
|
-
contentValue,
|
|
35
|
-
(content) => convertNestableWidget(content, assets, embeds),
|
|
36
|
-
O.fromNullable,
|
|
37
|
-
),
|
|
38
|
-
),
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Converts a list of items to a list of repeatable widgets.
|
|
43
|
-
* Each ImportSharedSliceContent element is a record of fields, but in the content model it is represented as a list of tuples (key, value)
|
|
44
|
-
*
|
|
45
|
-
* For example, given the following slice content:
|
|
46
|
-
* {
|
|
47
|
-
* "slice_text": (ImportNestable),
|
|
48
|
-
* "slice_number": (ImportNestable),
|
|
49
|
-
* }
|
|
50
|
-
*
|
|
51
|
-
* has to be converted to:
|
|
52
|
-
*
|
|
53
|
-
* {
|
|
54
|
-
* __TYPE__: "GroupItemContentType",
|
|
55
|
-
* value: [
|
|
56
|
-
* ["slice_text", (NestableContent)],
|
|
57
|
-
* ["slice_number", (NestableContent)],
|
|
58
|
-
* ]
|
|
59
|
-
* }
|
|
60
|
-
*
|
|
61
|
-
* @param items list of items to be converted
|
|
62
|
-
* @param assets assets that are required for a conversion of a nestable widget
|
|
63
|
-
*/
|
|
64
|
-
const itemsConverter = (
|
|
65
|
-
items: ImportSharedSliceContent[],
|
|
66
|
-
assets: Record<Asset["id"], Asset | undefined>,
|
|
67
|
-
embeds: Record<string, Embed | undefined>,
|
|
68
|
-
): SharedSliceContent["items"] =>
|
|
69
|
-
items.map((item) =>
|
|
70
|
-
pipe(
|
|
71
|
-
sharedSliceContentConverter(item, assets, embeds),
|
|
72
|
-
(record) => Object.entries(record),
|
|
73
|
-
(entries) => ({ __TYPE__: GroupItemContentType, value: entries }),
|
|
74
|
-
),
|
|
75
|
-
)
|
|
2
|
+
import type { SharedSliceContent } from "../../../../content"
|
|
3
|
+
import { SharedSliceContentType } from "../../../../content"
|
|
4
|
+
import type { SharedSlice as ImportSharedSlice } from "../../../validators/fields/ImportSlices/SharedSlice"
|
|
5
|
+
import { repeatableZoneConverter } from "../RepeatableZone"
|
|
6
|
+
import { repeatableZoneItemConverter } from "../RepeatableZoneItem"
|
|
76
7
|
|
|
77
8
|
/**
|
|
78
9
|
* Builds SharedSliceContent model from ImportSharedSlice
|
|
@@ -87,8 +18,10 @@ export const importSharedSliceContentConverter = (
|
|
|
87
18
|
): SharedSliceContent => ({
|
|
88
19
|
__TYPE__: SharedSliceContentType,
|
|
89
20
|
primary: field.primary
|
|
90
|
-
?
|
|
21
|
+
? repeatableZoneItemConverter(field.primary, assets, embeds)
|
|
91
22
|
: {},
|
|
92
|
-
items: field.items
|
|
23
|
+
items: field.items
|
|
24
|
+
? repeatableZoneConverter(field.items, assets, embeds)
|
|
25
|
+
: [],
|
|
93
26
|
variation: field.variation,
|
|
94
27
|
})
|
|
@@ -10,7 +10,7 @@ export const ImportContent = <T extends FieldType, A, O = A>(
|
|
|
10
10
|
valueCodec: t.Type<A, O>,
|
|
11
11
|
) =>
|
|
12
12
|
new t.Type<{ type: T; value: A }, O>(
|
|
13
|
-
|
|
13
|
+
`ImportField: ${valueCodec.name}`,
|
|
14
14
|
(u: unknown): u is { type: T; value: A } => {
|
|
15
15
|
if (!isObject(u)) return false
|
|
16
16
|
return type === u["type"] && valueCodec.is(u["value"])
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { StaticWidget } from "../../../customtypes"
|
|
2
|
+
import { ImportGroup } from "./ImportGroup"
|
|
2
3
|
import { ImportSlices } from "./ImportSlices"
|
|
3
4
|
import { ImportNestable } from "./nestable"
|
|
4
5
|
|
|
5
|
-
export type ImportField = ImportSlices | ImportNestable
|
|
6
|
+
export type ImportField = ImportSlices | ImportNestable | ImportGroup
|
|
6
7
|
|
|
7
8
|
export const ImportField = {
|
|
8
9
|
is(u: unknown): u is ImportField {
|
|
@@ -20,8 +21,12 @@ export const ImportField = {
|
|
|
20
21
|
codec: ImportSlices(field),
|
|
21
22
|
result: ImportSlices(field).decode(content),
|
|
22
23
|
}
|
|
23
|
-
case "Choice":
|
|
24
24
|
case "Group":
|
|
25
|
+
return {
|
|
26
|
+
codec: ImportGroup(field),
|
|
27
|
+
result: ImportGroup(field).decode(content),
|
|
28
|
+
}
|
|
29
|
+
case "Choice":
|
|
25
30
|
throw new Error(`Unsupported type of field ${field.type}`)
|
|
26
31
|
default:
|
|
27
32
|
return ImportNestable.decode(field)(content)
|
|
@@ -0,0 +1,45 @@
|
|
|
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 type { Group } from "../../../customtypes"
|
|
6
|
+
import { EmptyArrayOrElse } from "../../../validators"
|
|
7
|
+
import { withCustomError } from "../../../validators/function"
|
|
8
|
+
import { ImportContent } from "./ImportContent"
|
|
9
|
+
import { RepeatableZone } from "./RepeatableZone"
|
|
10
|
+
|
|
11
|
+
export const ImportGroupValue = (groupCustomType?: Group) => {
|
|
12
|
+
const fieldsModel = groupCustomType?.config?.fields ?? {}
|
|
13
|
+
const groupArrayCodec = RepeatableZone(fieldsModel)
|
|
14
|
+
|
|
15
|
+
return withCustomError(
|
|
16
|
+
new t.Type<RepeatableZone>(
|
|
17
|
+
groupArrayCodec.name,
|
|
18
|
+
groupArrayCodec.is,
|
|
19
|
+
(u, c) =>
|
|
20
|
+
pipe(
|
|
21
|
+
groupArrayCodec.validate(u, c),
|
|
22
|
+
E.chain((groups) => {
|
|
23
|
+
if (
|
|
24
|
+
groupCustomType?.config?.repeat === false &&
|
|
25
|
+
groups.length > 1
|
|
26
|
+
) {
|
|
27
|
+
return t.failure(
|
|
28
|
+
groups,
|
|
29
|
+
c,
|
|
30
|
+
"The custom type for this group field does not allow multiple group items",
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
return t.success(groups)
|
|
34
|
+
}),
|
|
35
|
+
),
|
|
36
|
+
t.identity,
|
|
37
|
+
),
|
|
38
|
+
() => "The group field value must be an array",
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export const ImportGroup = (groupCustomType?: Group) =>
|
|
43
|
+
ImportContent("Group", EmptyArrayOrElse(ImportGroupValue(groupCustomType)))
|
|
44
|
+
|
|
45
|
+
export type ImportGroup = t.TypeOf<ReturnType<typeof ImportGroup>>
|
|
@@ -16,13 +16,14 @@ export const ImportSlices = (staticSlices: StaticSlices) => {
|
|
|
16
16
|
|
|
17
17
|
// For now we only support the SharedSlice, however if we want to support more in the future
|
|
18
18
|
// we would have to change the codec here to something like this: t.array(t.union([ImportSharedSlice(sharedSlices), NewSliceCodec(newSliceCustomTypes)])).
|
|
19
|
-
const
|
|
19
|
+
const SharedSliceCodec = SharedSlice(supportedSlices)
|
|
20
|
+
const SlicesArrayCodec = t.array(SharedSliceCodec)
|
|
20
21
|
|
|
21
22
|
return ImportContent(
|
|
22
23
|
"Slices",
|
|
23
24
|
EmptyArrayOrElse(
|
|
24
|
-
new t.
|
|
25
|
-
|
|
25
|
+
new t.ArrayType<typeof SharedSliceCodec, SharedSlice[]>(
|
|
26
|
+
SlicesArrayCodec.name,
|
|
26
27
|
(u): u is SharedSlice[] => SlicesArrayCodec.is(u),
|
|
27
28
|
(u, c) => {
|
|
28
29
|
return pipe(
|
|
@@ -46,6 +47,7 @@ export const ImportSlices = (staticSlices: StaticSlices) => {
|
|
|
46
47
|
)
|
|
47
48
|
},
|
|
48
49
|
t.identity,
|
|
50
|
+
SharedSliceCodec,
|
|
49
51
|
),
|
|
50
52
|
),
|
|
51
53
|
)
|
|
@@ -4,10 +4,10 @@ import * as t from "io-ts"
|
|
|
4
4
|
|
|
5
5
|
import type { SharedSlice as SharedSliceCustomType } from "../../../../../customtypes"
|
|
6
6
|
import { NonEmptyString, String } from "../../../../../validators"
|
|
7
|
-
import {
|
|
7
|
+
import { RepeatableZone } from "../../RepeatableZone"
|
|
8
|
+
import { RepeatableZoneItem } from "../../RepeatableZoneItem"
|
|
8
9
|
import {
|
|
9
10
|
OptionalSharedSliceId,
|
|
10
|
-
SharedSliceContent,
|
|
11
11
|
SharedSliceId,
|
|
12
12
|
SharedSliceType,
|
|
13
13
|
SharedSliceVariation,
|
|
@@ -18,8 +18,8 @@ export type SharedSlice = {
|
|
|
18
18
|
slice_type: string
|
|
19
19
|
name: string
|
|
20
20
|
variation: string
|
|
21
|
-
primary:
|
|
22
|
-
items:
|
|
21
|
+
primary: RepeatableZoneItem | null | undefined
|
|
22
|
+
items: RepeatableZone | null | undefined
|
|
23
23
|
slice_label: string | null | undefined
|
|
24
24
|
version: string | null | undefined
|
|
25
25
|
}
|
|
@@ -70,22 +70,10 @@ export const SharedSlice = (sharedSlices: SharedSliceCustomType[]) =>
|
|
|
70
70
|
// We validate the 'primary' and 'items' content fields, for which we need the Variation custom type retrieved in the previous step
|
|
71
71
|
t
|
|
72
72
|
.partial({
|
|
73
|
-
primary:
|
|
74
|
-
decoded.slice_type.slice_type,
|
|
75
|
-
"primary",
|
|
73
|
+
primary: RepeatableZoneItem(
|
|
76
74
|
decoded.variation.data.primary ?? {},
|
|
77
75
|
),
|
|
78
|
-
|
|
79
|
-
items: withCustomError(
|
|
80
|
-
t.array(
|
|
81
|
-
SharedSliceContent(
|
|
82
|
-
decoded.slice_type.slice_type,
|
|
83
|
-
"items",
|
|
84
|
-
decoded.variation.data.items ?? {},
|
|
85
|
-
),
|
|
86
|
-
),
|
|
87
|
-
() => "The value must be an array",
|
|
88
|
-
),
|
|
76
|
+
items: RepeatableZone(decoded.variation.data.items ?? {}),
|
|
89
77
|
})
|
|
90
78
|
.validate(u, c),
|
|
91
79
|
E.map(({ primary, items }) => ({ ...decoded, primary, items })),
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as t from "io-ts"
|
|
2
|
+
|
|
3
|
+
import type { WidgetKey } from "../../../common"
|
|
4
|
+
import type { NestableWidget } from "../../../customtypes"
|
|
5
|
+
import { withCustomError } from "../../../validators/function"
|
|
6
|
+
import { RepeatableZoneItem } from "./RepeatableZoneItem"
|
|
7
|
+
|
|
8
|
+
export type RepeatableZone = t.TypeOf<ReturnType<typeof RepeatableZone>>
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A custom type for a repeatable zone. This type of structure can be found 'items' field of a slice or in the group field.
|
|
12
|
+
*
|
|
13
|
+
* @param fieldModels a record of all nestable widgets that can be used in the zone
|
|
14
|
+
*/
|
|
15
|
+
export const RepeatableZone = (
|
|
16
|
+
fieldModels: Record<WidgetKey, NestableWidget>,
|
|
17
|
+
) =>
|
|
18
|
+
withCustomError(
|
|
19
|
+
t.array(RepeatableZoneItem(fieldModels)),
|
|
20
|
+
() => "The repeatable zone value must be an array",
|
|
21
|
+
)
|
|
@@ -0,0 +1,64 @@
|
|
|
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 { WidgetKey } from "../../../common"
|
|
6
|
+
import type { NestableWidget } from "../../../customtypes"
|
|
7
|
+
import { withCustomError } from "../../../validators/function"
|
|
8
|
+
import { ImportNestable } from "./nestable"
|
|
9
|
+
|
|
10
|
+
export type RepeatableZoneItem = Record<WidgetKey, ImportNestable>
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A custom type for an item of a repeatable zone. This type of structure can be found in the 'primary' and 'items' fields of a slice or in the group field.
|
|
14
|
+
*
|
|
15
|
+
* @param fieldModels a record of all nestable widgets that can be used in the zone
|
|
16
|
+
*/
|
|
17
|
+
export const RepeatableZoneItem = (
|
|
18
|
+
fieldModels: Record<WidgetKey, NestableWidget>,
|
|
19
|
+
) =>
|
|
20
|
+
new t.Type<RepeatableZoneItem>(
|
|
21
|
+
"RepeatableZoneItem",
|
|
22
|
+
(u): u is RepeatableZoneItem =>
|
|
23
|
+
t.record(WidgetKey, t.unknown).is(u) &&
|
|
24
|
+
Object.values(u).reduce<boolean>(
|
|
25
|
+
(acc, value) => acc && ImportNestable.is(value),
|
|
26
|
+
true,
|
|
27
|
+
),
|
|
28
|
+
(u, c) => {
|
|
29
|
+
const codecEntries = Object.entries(fieldModels).map(
|
|
30
|
+
([key, model]) => [key, ImportNestable.getCodec(model)] as const,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
const groupCodec = withCustomError(
|
|
34
|
+
t.partial({
|
|
35
|
+
...Object.fromEntries(codecEntries),
|
|
36
|
+
}),
|
|
37
|
+
() => "The value must be an object",
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
return pipe(
|
|
41
|
+
groupCodec.validate(u, c),
|
|
42
|
+
E.chain((decodedContent) => {
|
|
43
|
+
// Validate if all fields are present in the model
|
|
44
|
+
const keys = Object.keys(decodedContent)
|
|
45
|
+
const errors: t.Errors = keys.flatMap((key) =>
|
|
46
|
+
fieldModels[key]
|
|
47
|
+
? []
|
|
48
|
+
: [
|
|
49
|
+
{
|
|
50
|
+
value: decodedContent[key],
|
|
51
|
+
context: c,
|
|
52
|
+
message: `The field '${key}' is not defined in the custom type`,
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
return errors.length > 0
|
|
58
|
+
? t.failures(errors)
|
|
59
|
+
: t.success(decodedContent as RepeatableZoneItem) // We can never have a key with decoded value 'undefined' so we can ignore the type derived from t.partial
|
|
60
|
+
}),
|
|
61
|
+
)
|
|
62
|
+
},
|
|
63
|
+
t.identity,
|
|
64
|
+
)
|