@prismicio/types-internal 3.11.2 → 3.12.0-alpha.1
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/CHANGELOG.md +764 -0
- package/lib/content/Document.d.ts +32 -7
- package/lib/content/Document.js +22 -8
- package/lib/content/LegacyContentCtx.d.ts +25 -3
- package/lib/content/LegacyContentCtx.js +67 -5
- package/lib/content/fields/GroupContent.d.ts +4 -2
- package/lib/content/fields/GroupContent.js +40 -17
- package/lib/content/fields/UIDContent.js +1 -0
- package/lib/content/fields/WidgetContent.d.ts +6 -0
- package/lib/content/fields/nestable/BooleanContent.js +1 -0
- package/lib/content/fields/nestable/EmbedContent.js +1 -0
- package/lib/content/fields/nestable/FieldContent/ColorContent.js +1 -0
- package/lib/content/fields/nestable/FieldContent/DateContent.js +1 -0
- package/lib/content/fields/nestable/FieldContent/NumberContent.js +1 -0
- package/lib/content/fields/nestable/FieldContent/RangeContent.js +1 -0
- package/lib/content/fields/nestable/FieldContent/SelectContent.js +1 -0
- package/lib/content/fields/nestable/FieldContent/TextContent.js +1 -0
- package/lib/content/fields/nestable/FieldContent/TimestampContent.js +1 -0
- package/lib/content/fields/nestable/GeoPointContent.js +1 -0
- package/lib/content/fields/nestable/ImageContent.js +1 -0
- package/lib/content/fields/nestable/IntegrationFieldContent.js +1 -0
- package/lib/content/fields/nestable/LinkContent.js +2 -0
- package/lib/content/fields/nestable/RepeatableContent.js +1 -0
- package/lib/content/fields/nestable/RichTextContent/index.js +1 -0
- package/lib/content/fields/nestable/SeparatorContent.js +1 -0
- package/lib/content/fields/nestable/TableContent.js +1 -0
- package/lib/content/fields/slices/Slice/CompositeSliceContent.d.ts +3 -0
- package/lib/content/fields/slices/Slice/CompositeSliceContent.js +19 -5
- package/lib/content/fields/slices/Slice/RepeatableContent.d.ts +5 -4
- package/lib/content/fields/slices/Slice/RepeatableContent.js +2 -1
- package/lib/content/fields/slices/Slice/SharedSliceContent.d.ts +3 -0
- package/lib/content/fields/slices/Slice/SharedSliceContent.js +26 -19
- package/lib/content/fields/slices/Slice/SimpleSliceContent.js +1 -0
- package/lib/content/fields/slices/Slice/index.d.ts +4 -0
- package/lib/content/fields/slices/SliceItem.d.ts +12 -0
- package/lib/content/fields/slices/SliceItem.js +11 -2
- package/lib/content/fields/slices/SlicesContent.d.ts +6 -0
- package/lib/content/fields/slices/SlicesContent.js +1 -0
- package/lib/customtypes/CustomType.js +6 -9
- package/lib/customtypes/Section.js +3 -8
- package/lib/customtypes/widgets/Group.js +20 -20
- package/lib/customtypes/widgets/nestable/NestableWidgetZ.d.ts +3 -0
- package/lib/customtypes/widgets/nestable/NestableWidgetZ.js +29 -0
- package/lib/customtypes/widgets/slices/CompositeSlice.js +9 -22
- package/lib/customtypes/widgets/slices/SharedSlice.js +18 -37
- package/lib/customtypes/widgets/slices/SharedSliceZ.d.ts +16 -0
- package/lib/customtypes/widgets/slices/SharedSliceZ.js +39 -0
- package/lib/customtypes/widgets/slices/SlicePrimaryWidgetZ.d.ts +3 -0
- package/lib/customtypes/widgets/slices/SlicePrimaryWidgetZ.js +6 -0
- package/lib/customtypes/widgets/slices/Slices.js +9 -16
- package/package.json +1 -1
- package/src/content/Document.ts +31 -8
- package/src/content/LegacyContentCtx.ts +72 -16
- package/src/content/fields/GroupContent.ts +58 -16
- package/src/content/fields/UIDContent.ts +1 -0
- package/src/content/fields/nestable/BooleanContent.ts +1 -0
- package/src/content/fields/nestable/EmbedContent.ts +1 -0
- package/src/content/fields/nestable/FieldContent/ColorContent.ts +1 -0
- package/src/content/fields/nestable/FieldContent/DateContent.ts +1 -0
- package/src/content/fields/nestable/FieldContent/NumberContent.ts +1 -0
- package/src/content/fields/nestable/FieldContent/RangeContent.ts +1 -0
- package/src/content/fields/nestable/FieldContent/SelectContent.ts +1 -0
- package/src/content/fields/nestable/FieldContent/TextContent.ts +1 -0
- package/src/content/fields/nestable/FieldContent/TimestampContent.ts +1 -0
- package/src/content/fields/nestable/GeoPointContent.ts +1 -0
- package/src/content/fields/nestable/ImageContent.ts +1 -0
- package/src/content/fields/nestable/IntegrationFieldContent.ts +1 -0
- package/src/content/fields/nestable/LinkContent.ts +2 -0
- package/src/content/fields/nestable/RepeatableContent.ts +4 -0
- package/src/content/fields/nestable/RichTextContent/index.ts +1 -0
- package/src/content/fields/nestable/SeparatorContent.ts +1 -0
- package/src/content/fields/nestable/TableContent.ts +1 -0
- package/src/content/fields/slices/Slice/CompositeSliceContent.ts +19 -5
- package/src/content/fields/slices/Slice/RepeatableContent.ts +7 -2
- package/src/content/fields/slices/Slice/SharedSliceContent.ts +26 -19
- package/src/content/fields/slices/Slice/SimpleSliceContent.ts +1 -0
- package/src/content/fields/slices/SliceItem.ts +12 -3
- package/src/content/fields/slices/SlicesContent.ts +4 -1
- package/src/customtypes/CustomType.ts +6 -9
- package/src/customtypes/Section.ts +3 -9
- package/src/customtypes/widgets/Group.ts +20 -21
- package/src/customtypes/widgets/slices/CompositeSlice.ts +9 -22
- package/src/customtypes/widgets/slices/SharedSlice.ts +23 -38
- package/src/customtypes/widgets/slices/Slices.ts +9 -15
- package/lib/content/fields/RepeatableContent.d.ts +0 -162
- package/lib/content/fields/RepeatableContent.js +0 -93
- package/lib/content/fields/nestable/RichTextContent/TextBlock.d.ts +0 -727
- package/lib/content/fields/nestable/RichTextContent/TextBlock.js +0 -80
- package/lib/customtypes/widgets/slices/SliceWidget.d.ts +0 -327
- package/lib/customtypes/widgets/slices/SliceWidget.js +0 -8
|
@@ -31,33 +31,20 @@ exports.isCompositeSlice = isCompositeSlice;
|
|
|
31
31
|
function traverseCompositeSlice(args) {
|
|
32
32
|
var _a, _b;
|
|
33
33
|
const { path: prevPath, slice, onField } = args;
|
|
34
|
-
|
|
34
|
+
const nonRepeat = {};
|
|
35
35
|
for (const [key, field] of Object.entries((_a = slice["non-repeat"]) !== null && _a !== void 0 ? _a : {})) {
|
|
36
36
|
const path = [...prevPath, "non-repeat", key];
|
|
37
|
-
|
|
38
|
-
if (field !== newField) {
|
|
39
|
-
if (!nonRepeat)
|
|
40
|
-
nonRepeat = { ...slice["non-repeat"] };
|
|
41
|
-
nonRepeat[key] = newField;
|
|
42
|
-
}
|
|
37
|
+
nonRepeat[key] = onField({ path, key, field });
|
|
43
38
|
}
|
|
44
|
-
|
|
39
|
+
const repeat = {};
|
|
45
40
|
for (const [key, field] of Object.entries((_b = slice.repeat) !== null && _b !== void 0 ? _b : {})) {
|
|
46
41
|
const path = [...prevPath, "repeat", key];
|
|
47
|
-
|
|
48
|
-
if (field !== newField) {
|
|
49
|
-
if (!repeat)
|
|
50
|
-
repeat = { ...slice.repeat };
|
|
51
|
-
repeat[key] = newField;
|
|
52
|
-
}
|
|
42
|
+
repeat[key] = onField({ path, key, field });
|
|
53
43
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
...(repeat && { repeat }),
|
|
60
|
-
}
|
|
61
|
-
: slice;
|
|
44
|
+
return {
|
|
45
|
+
...slice,
|
|
46
|
+
...(slice["non-repeat"] && { "non-repeat": nonRepeat }),
|
|
47
|
+
...(slice.repeat && { repeat }),
|
|
48
|
+
};
|
|
62
49
|
}
|
|
63
50
|
exports.traverseCompositeSlice = traverseCompositeSlice;
|
|
@@ -50,7 +50,7 @@ exports.isDynamicSharedSlice = isDynamicSharedSlice;
|
|
|
50
50
|
function traverseVariation(args) {
|
|
51
51
|
var _a, _b;
|
|
52
52
|
const { path: prevPath, variation, onField } = args;
|
|
53
|
-
|
|
53
|
+
const primary = {};
|
|
54
54
|
for (const [key, prevField] of Object.entries((_a = variation.primary) !== null && _a !== void 0 ? _a : {})) {
|
|
55
55
|
const path = [...prevPath, "primary", key];
|
|
56
56
|
let field;
|
|
@@ -66,53 +66,34 @@ function traverseVariation(args) {
|
|
|
66
66
|
field = prevField;
|
|
67
67
|
break;
|
|
68
68
|
}
|
|
69
|
-
|
|
70
|
-
if (field !== newField) {
|
|
71
|
-
if (!primary)
|
|
72
|
-
primary = { ...variation.primary };
|
|
73
|
-
primary[key] = newField;
|
|
74
|
-
}
|
|
69
|
+
primary[key] = onField({ path, key, field });
|
|
75
70
|
}
|
|
76
|
-
|
|
77
|
-
for (const [key,
|
|
71
|
+
const items = {};
|
|
72
|
+
for (const [key, field] of Object.entries((_b = variation.items) !== null && _b !== void 0 ? _b : {})) {
|
|
78
73
|
const path = [...prevPath, "items", key];
|
|
79
|
-
|
|
80
|
-
path,
|
|
81
|
-
key,
|
|
82
|
-
field: prevField,
|
|
83
|
-
});
|
|
84
|
-
if (prevField !== newField) {
|
|
85
|
-
if (!items)
|
|
86
|
-
items = { ...variation.items };
|
|
87
|
-
items[key] = newField;
|
|
88
|
-
}
|
|
74
|
+
items[key] = onField({ path, key, field });
|
|
89
75
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
76
|
+
return {
|
|
77
|
+
...variation,
|
|
78
|
+
...(variation.primary && { primary }),
|
|
79
|
+
...(variation.items && { items }),
|
|
80
|
+
};
|
|
94
81
|
}
|
|
95
82
|
exports.traverseVariation = traverseVariation;
|
|
96
83
|
function traverseSharedSlice(args) {
|
|
97
84
|
const { path: prevPath, slice, onField } = args;
|
|
98
|
-
|
|
99
|
-
for (
|
|
100
|
-
const variation = slice.variations[i];
|
|
101
|
-
if (!variation)
|
|
102
|
-
continue;
|
|
85
|
+
const variations = [];
|
|
86
|
+
for (const variation of slice.variations) {
|
|
103
87
|
const path = [...prevPath, variation.id];
|
|
104
|
-
|
|
88
|
+
variations.push(traverseVariation({
|
|
105
89
|
path,
|
|
106
90
|
variation,
|
|
107
91
|
onField,
|
|
108
|
-
});
|
|
109
|
-
if (newVariation !== variation) {
|
|
110
|
-
if (!variations)
|
|
111
|
-
variations = [...slice.variations];
|
|
112
|
-
variations[i] = newVariation;
|
|
113
|
-
}
|
|
92
|
+
}));
|
|
114
93
|
}
|
|
115
|
-
|
|
116
|
-
|
|
94
|
+
return {
|
|
95
|
+
...slice,
|
|
96
|
+
variations,
|
|
97
|
+
};
|
|
117
98
|
}
|
|
118
99
|
exports.traverseSharedSlice = traverseSharedSlice;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { SharedSliceRef } from "./SharedSliceRef";
|
|
3
|
+
import type { DynamicSlice, StaticSlice } from "./Slice";
|
|
4
|
+
export declare const Variation: any;
|
|
5
|
+
export declare type Variation = z.infer<typeof Variation>;
|
|
6
|
+
export declare type VariationFields = {
|
|
7
|
+
type: "SharedSlice";
|
|
8
|
+
sliceName: string;
|
|
9
|
+
variationId: string;
|
|
10
|
+
fields: Pick<Variation, "primary" | "items">;
|
|
11
|
+
};
|
|
12
|
+
export declare const SharedSliceType: "SharedSlice";
|
|
13
|
+
export declare const SharedSlice: any;
|
|
14
|
+
export declare type SharedSlice = z.infer<typeof SharedSlice>;
|
|
15
|
+
export declare function isStaticSharedSlice(slice: StaticSlice): slice is SharedSlice;
|
|
16
|
+
export declare function isDynamicSharedSlice(slice: DynamicSlice): slice is SharedSliceRef;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isDynamicSharedSlice = exports.isStaticSharedSlice = exports.SharedSlice = exports.SharedSliceType = exports.Variation = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const NestableWidgetZ_1 = require("../nestable/NestableWidgetZ");
|
|
6
|
+
const SlicePrimaryWidgetZ_1 = require("./SlicePrimaryWidgetZ");
|
|
7
|
+
const IMAGE_PLACEHOLDER_URL = "https://images.prismic.io/slice-machine/621a5ec4-0387-4bc5-9860-2dd46cbc07cd_default_ss.png?auto=compress,format";
|
|
8
|
+
// Helper for WidgetKey validation
|
|
9
|
+
const WidgetKeySchema = zod_1.z.string().refine((val) => true, {
|
|
10
|
+
message: "Invalid widget key",
|
|
11
|
+
});
|
|
12
|
+
exports.Variation = zod_1.z.object({
|
|
13
|
+
id: zod_1.z.string(),
|
|
14
|
+
name: zod_1.z.string(),
|
|
15
|
+
description: zod_1.z.string(),
|
|
16
|
+
imageUrl: zod_1.z.string().default(IMAGE_PLACEHOLDER_URL),
|
|
17
|
+
docURL: zod_1.z.string(),
|
|
18
|
+
version: zod_1.z.string(),
|
|
19
|
+
display: zod_1.z.string().optional(),
|
|
20
|
+
primary: zod_1.z.record(WidgetKeySchema, SlicePrimaryWidgetZ_1.SlicePrimaryWidget).optional(),
|
|
21
|
+
items: zod_1.z.record(WidgetKeySchema, NestableWidgetZ_1.NestableWidget).optional(),
|
|
22
|
+
}).strict();
|
|
23
|
+
exports.SharedSliceType = "SharedSlice";
|
|
24
|
+
exports.SharedSlice = zod_1.z.object({
|
|
25
|
+
id: zod_1.z.string(),
|
|
26
|
+
type: zod_1.z.literal(exports.SharedSliceType),
|
|
27
|
+
name: zod_1.z.string(),
|
|
28
|
+
variations: zod_1.z.array(exports.Variation).readonly(),
|
|
29
|
+
description: zod_1.z.string().optional(),
|
|
30
|
+
legacyPaths: zod_1.z.record(zod_1.z.string(), zod_1.z.string()).optional(),
|
|
31
|
+
}).strict();
|
|
32
|
+
function isStaticSharedSlice(slice) {
|
|
33
|
+
return slice.type === "SharedSlice";
|
|
34
|
+
}
|
|
35
|
+
exports.isStaticSharedSlice = isStaticSharedSlice;
|
|
36
|
+
function isDynamicSharedSlice(slice) {
|
|
37
|
+
return slice.type === "SharedSlice";
|
|
38
|
+
}
|
|
39
|
+
exports.isDynamicSharedSlice = isDynamicSharedSlice;
|
|
@@ -84,7 +84,7 @@ function traverseSlices(args) {
|
|
|
84
84
|
const { path: prevPath, slices, onField } = args;
|
|
85
85
|
if (!((_a = slices.config) === null || _a === void 0 ? void 0 : _a.choices))
|
|
86
86
|
return slices;
|
|
87
|
-
|
|
87
|
+
const choices = {};
|
|
88
88
|
for (const [key, prevModel] of Object.entries(slices.config.choices)) {
|
|
89
89
|
const path = [...prevPath, key];
|
|
90
90
|
let model;
|
|
@@ -126,21 +126,14 @@ function traverseSlices(args) {
|
|
|
126
126
|
});
|
|
127
127
|
break;
|
|
128
128
|
}
|
|
129
|
-
|
|
130
|
-
if (!choices)
|
|
131
|
-
choices = { ...slices.config.choices };
|
|
132
|
-
choices[key] = model;
|
|
133
|
-
}
|
|
129
|
+
choices[key] = model;
|
|
134
130
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
...slices,
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
},
|
|
143
|
-
}
|
|
144
|
-
: slices;
|
|
131
|
+
return {
|
|
132
|
+
...slices,
|
|
133
|
+
config: {
|
|
134
|
+
...slices.config,
|
|
135
|
+
choices,
|
|
136
|
+
},
|
|
137
|
+
};
|
|
145
138
|
}
|
|
146
139
|
exports.traverseSlices = traverseSlices;
|
package/package.json
CHANGED
package/src/content/Document.ts
CHANGED
|
@@ -47,7 +47,10 @@ type DocumentLegacy = t.TypeOf<typeof legacyDocReader>
|
|
|
47
47
|
* `DocumentLegacyCodec` handles decoding and encoding documents to the legacy
|
|
48
48
|
* format used by Prismic DB, therefore, this function itself is not "legacy".
|
|
49
49
|
*/
|
|
50
|
-
const DocumentLegacyCodec = (
|
|
50
|
+
const DocumentLegacyCodec = (
|
|
51
|
+
allTypes?: LegacyContentCtx["allTypes"],
|
|
52
|
+
allKeys?: LegacyContentCtx["allKeys"],
|
|
53
|
+
) => {
|
|
51
54
|
return new t.Type<Document, WithTypes<DocumentLegacy>, unknown>(
|
|
52
55
|
"Document",
|
|
53
56
|
(u): u is Document => !!u && typeof u === "object",
|
|
@@ -57,7 +60,7 @@ const DocumentLegacyCodec = (allTypes?: LegacyContentCtx["allTypes"]) => {
|
|
|
57
60
|
either.map((parsedDoc) => {
|
|
58
61
|
return Object.entries(parsedDoc).reduce(
|
|
59
62
|
(acc, [widgetKey, widgetValue]) => {
|
|
60
|
-
const widgetCtx = defaultCtx(widgetKey, allTypes)
|
|
63
|
+
const widgetCtx = defaultCtx(widgetKey, allTypes, allKeys)
|
|
61
64
|
const parsedW = WidgetLegacy(widgetCtx).decode(widgetValue)
|
|
62
65
|
if (!parsedW || isLeft(parsedW)) return acc
|
|
63
66
|
|
|
@@ -78,9 +81,10 @@ const DocumentLegacyCodec = (allTypes?: LegacyContentCtx["allTypes"]) => {
|
|
|
78
81
|
return {
|
|
79
82
|
content: { ...acc.content, [key]: result.content },
|
|
80
83
|
types: { ...acc.types, ...result.types },
|
|
84
|
+
keys: { ...acc.keys, ...result.keys },
|
|
81
85
|
}
|
|
82
86
|
},
|
|
83
|
-
{ content: {}, types: {} },
|
|
87
|
+
{ content: {}, types: {}, keys: {} },
|
|
84
88
|
)
|
|
85
89
|
},
|
|
86
90
|
)
|
|
@@ -89,12 +93,13 @@ const DocumentLegacyCodec = (allTypes?: LegacyContentCtx["allTypes"]) => {
|
|
|
89
93
|
function extractMetadata(data: { [p: string]: unknown }): {
|
|
90
94
|
types: Map<string, FieldOrSliceType>
|
|
91
95
|
widgets: Partial<Record<WidgetKey, unknown>>
|
|
96
|
+
keys: Map<string, string>
|
|
92
97
|
slugs: ReadonlyArray<string>
|
|
93
98
|
uid: string | undefined
|
|
94
99
|
} {
|
|
95
100
|
const fields: [string, unknown][] = Object.entries(data)
|
|
96
101
|
|
|
97
|
-
const { types, widgets } = fields.reduce(
|
|
102
|
+
const { types, widgets, keys } = fields.reduce(
|
|
98
103
|
(acc, [k, v]) => {
|
|
99
104
|
if (k.endsWith("_TYPE")) {
|
|
100
105
|
const decodedValue = FieldOrSliceType.decode(v)
|
|
@@ -108,7 +113,23 @@ function extractMetadata(data: { [p: string]: unknown }): {
|
|
|
108
113
|
}
|
|
109
114
|
}
|
|
110
115
|
}
|
|
111
|
-
if (
|
|
116
|
+
if (k.endsWith("_KEY")) {
|
|
117
|
+
const decodedValue = t.string.decode(v)
|
|
118
|
+
if (isRight(decodedValue)) {
|
|
119
|
+
return {
|
|
120
|
+
...acc,
|
|
121
|
+
keys: acc.keys.set(
|
|
122
|
+
k.substring(0, k.length - 4),
|
|
123
|
+
decodedValue.right,
|
|
124
|
+
),
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (
|
|
129
|
+
!k.endsWith("_POSITION") &&
|
|
130
|
+
!k.endsWith("_TYPE") &&
|
|
131
|
+
!k.endsWith("_KEY")
|
|
132
|
+
) {
|
|
112
133
|
return {
|
|
113
134
|
...acc,
|
|
114
135
|
widgets: {
|
|
@@ -122,6 +143,7 @@ function extractMetadata(data: { [p: string]: unknown }): {
|
|
|
122
143
|
{
|
|
123
144
|
types: new Map<string, FieldOrSliceType>(),
|
|
124
145
|
widgets: {},
|
|
146
|
+
keys: new Map<string, string>(),
|
|
125
147
|
},
|
|
126
148
|
)
|
|
127
149
|
|
|
@@ -131,6 +153,7 @@ function extractMetadata(data: { [p: string]: unknown }): {
|
|
|
131
153
|
return {
|
|
132
154
|
widgets,
|
|
133
155
|
types,
|
|
156
|
+
keys,
|
|
134
157
|
uid,
|
|
135
158
|
slugs,
|
|
136
159
|
}
|
|
@@ -150,9 +173,9 @@ function parseLegacyDocument(
|
|
|
150
173
|
t.record(WidgetKey, t.unknown).decode(legacyDoc),
|
|
151
174
|
either.chain((doc) => {
|
|
152
175
|
// extract all metadata, meaning all _TYPES keys from legacy format + the widgets as unknown
|
|
153
|
-
const { types, widgets } = extractMetadata(doc)
|
|
176
|
+
const { types, widgets, keys } = extractMetadata(doc)
|
|
154
177
|
// parse the actual widgets
|
|
155
|
-
return DocumentLegacyCodec(types).decode(widgets)
|
|
178
|
+
return DocumentLegacyCodec(types, keys).decode(widgets)
|
|
156
179
|
}),
|
|
157
180
|
)
|
|
158
181
|
|
|
@@ -161,7 +184,7 @@ function parseLegacyDocument(
|
|
|
161
184
|
|
|
162
185
|
function encodeToLegacyDocument(document: Document): DocumentLegacy {
|
|
163
186
|
const encoded = DocumentLegacyCodec().encode(document)
|
|
164
|
-
return { ...encoded.content, ...encoded.types }
|
|
187
|
+
return { ...encoded.content, ...encoded.types, ...encoded.keys }
|
|
165
188
|
}
|
|
166
189
|
|
|
167
190
|
export const DocumentLegacy = {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as t from "io-ts"
|
|
2
|
+
import { v4 as uuid } from "uuid"
|
|
2
3
|
|
|
3
4
|
import { FieldType, SlicesTypes } from "../customtypes/widgets"
|
|
4
5
|
|
|
@@ -7,54 +8,109 @@ export const FieldOrSliceType = t.union([
|
|
|
7
8
|
t.literal("Repeatable.Link"),
|
|
8
9
|
])
|
|
9
10
|
export type FieldOrSliceType = t.TypeOf<typeof FieldOrSliceType>
|
|
11
|
+
|
|
12
|
+
interface LegacyContentCtxParams {
|
|
13
|
+
fieldKey: string
|
|
14
|
+
contentKey?: string
|
|
15
|
+
fieldPath?: Array<string>
|
|
16
|
+
contentPath?: Array<string>
|
|
17
|
+
allTypes?: Map<string, FieldOrSliceType>
|
|
18
|
+
allKeys?: Map<string, string>
|
|
19
|
+
}
|
|
20
|
+
|
|
10
21
|
export class LegacyContentCtx {
|
|
11
22
|
fieldKey: string
|
|
12
23
|
prefixedKey: string
|
|
13
24
|
keyOfType: string
|
|
25
|
+
keyOfKey: string
|
|
14
26
|
fieldPath: Array<string>
|
|
15
27
|
fieldType?: FieldOrSliceType | undefined
|
|
16
28
|
allTypes: Map<string, FieldOrSliceType>
|
|
29
|
+
allKeys: Map<string, string>
|
|
30
|
+
contentKey: string
|
|
31
|
+
contentPath: Array<string>
|
|
32
|
+
fieldContentKey: string
|
|
17
33
|
|
|
18
|
-
constructor(
|
|
19
|
-
fieldKey
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
34
|
+
constructor({
|
|
35
|
+
fieldKey,
|
|
36
|
+
contentKey,
|
|
37
|
+
contentPath,
|
|
38
|
+
fieldPath,
|
|
39
|
+
allTypes,
|
|
40
|
+
allKeys,
|
|
41
|
+
}: LegacyContentCtxParams) {
|
|
23
42
|
this.fieldKey = fieldKey
|
|
43
|
+
this.contentKey = contentKey || fieldKey
|
|
24
44
|
this.fieldPath = fieldPath || []
|
|
45
|
+
this.contentPath = contentPath || []
|
|
25
46
|
this.allTypes = allTypes || new Map<string, FieldOrSliceType>()
|
|
47
|
+
this.allKeys = allKeys || new Map<string, string>()
|
|
26
48
|
|
|
27
49
|
const prefixedKey = Array.of(this.fieldPath, [this.fieldKey])
|
|
28
50
|
.flat()
|
|
29
51
|
.join(".")
|
|
30
52
|
|
|
53
|
+
const prefixedContentKey = Array.of(this.contentPath, [this.contentKey])
|
|
54
|
+
.flat()
|
|
55
|
+
.join(".")
|
|
56
|
+
|
|
31
57
|
this.prefixedKey = prefixedKey
|
|
32
58
|
this.keyOfType = `${prefixedKey}_TYPE`
|
|
33
|
-
|
|
59
|
+
this.keyOfKey = `${prefixedContentKey}_KEY`
|
|
34
60
|
this.fieldType = this.allTypes.get(this.prefixedKey)
|
|
61
|
+
this.fieldContentKey = this.allKeys.get(prefixedContentKey) ?? uuid()
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
withContentKey(contentKey: string): LegacyContentCtx {
|
|
65
|
+
return new LegacyContentCtx({
|
|
66
|
+
...this,
|
|
67
|
+
contentPath: [...this.contentPath, this.contentKey],
|
|
68
|
+
contentKey,
|
|
69
|
+
})
|
|
35
70
|
}
|
|
36
71
|
}
|
|
37
72
|
|
|
38
|
-
|
|
39
|
-
fieldKey: string
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
73
|
+
interface GetFieldCtxParams {
|
|
74
|
+
fieldKey: string
|
|
75
|
+
contentKey?: string
|
|
76
|
+
ctx: LegacyContentCtx
|
|
77
|
+
prefixes?: Array<string>
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function getFieldCtx({
|
|
81
|
+
fieldKey,
|
|
82
|
+
contentKey: contentKeyParam,
|
|
83
|
+
ctx,
|
|
84
|
+
prefixes,
|
|
85
|
+
}: GetFieldCtxParams): LegacyContentCtx {
|
|
86
|
+
const contentKey = contentKeyParam || fieldKey
|
|
87
|
+
return new LegacyContentCtx({
|
|
44
88
|
fieldKey,
|
|
45
|
-
|
|
46
|
-
ctx.
|
|
47
|
-
|
|
89
|
+
contentKey,
|
|
90
|
+
contentPath: [...ctx.contentPath, ctx.contentKey, ...(prefixes || [])],
|
|
91
|
+
fieldPath: [...ctx.fieldPath, ctx.fieldKey, ...(prefixes || [])],
|
|
92
|
+
allTypes: ctx.allTypes,
|
|
93
|
+
allKeys: ctx.allKeys,
|
|
94
|
+
})
|
|
48
95
|
}
|
|
49
96
|
|
|
50
97
|
export function defaultCtx(
|
|
51
98
|
key: string,
|
|
52
99
|
allTypes: Map<string, FieldOrSliceType> = new Map(),
|
|
100
|
+
allKeys: Map<string, string> = new Map(),
|
|
53
101
|
): LegacyContentCtx {
|
|
54
|
-
return new LegacyContentCtx(
|
|
102
|
+
return new LegacyContentCtx({
|
|
103
|
+
fieldKey: key,
|
|
104
|
+
contentKey: key,
|
|
105
|
+
contentPath: [],
|
|
106
|
+
fieldPath: [],
|
|
107
|
+
allTypes,
|
|
108
|
+
allKeys,
|
|
109
|
+
})
|
|
55
110
|
}
|
|
56
111
|
|
|
57
112
|
export type WithTypes<T> = {
|
|
113
|
+
keys: Record<string, string>
|
|
58
114
|
types: Record<string, FieldOrSliceType>
|
|
59
115
|
content: T
|
|
60
116
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { either } from "fp-ts"
|
|
1
|
+
import { array, either } from "fp-ts"
|
|
2
2
|
import { isLeft } from "fp-ts/lib/Either"
|
|
3
3
|
import { pipe } from "fp-ts/lib/function"
|
|
4
4
|
import * as t from "io-ts"
|
|
@@ -38,6 +38,7 @@ export const GroupItemContent: t.Type<GroupItemContent> = t.recursion(
|
|
|
38
38
|
() =>
|
|
39
39
|
t.strict({
|
|
40
40
|
__TYPE__: t.literal(GroupItemContentType),
|
|
41
|
+
key: t.string,
|
|
41
42
|
value: t.array(
|
|
42
43
|
t.tuple([t.string, t.union([NestableContent, GroupContent])]),
|
|
43
44
|
),
|
|
@@ -45,6 +46,7 @@ export const GroupItemContent: t.Type<GroupItemContent> = t.recursion(
|
|
|
45
46
|
)
|
|
46
47
|
export type GroupItemContent = {
|
|
47
48
|
__TYPE__: typeof GroupItemContentType
|
|
49
|
+
key: string
|
|
48
50
|
value: [string, NestableContent | GroupContent][]
|
|
49
51
|
}
|
|
50
52
|
|
|
@@ -70,9 +72,9 @@ export const GroupContentDefaultValue: GroupContent = {
|
|
|
70
72
|
}
|
|
71
73
|
|
|
72
74
|
const itemLegacyReader = t.record(t.string, t.unknown)
|
|
73
|
-
type GroupItemLegacy = t.TypeOf<typeof itemLegacyReader>
|
|
75
|
+
export type GroupItemLegacy = t.TypeOf<typeof itemLegacyReader>
|
|
74
76
|
|
|
75
|
-
export const GroupItemLegacy = (ctx: LegacyContentCtx) => {
|
|
77
|
+
export const GroupItemLegacy = (ctx: LegacyContentCtx, index: number) => {
|
|
76
78
|
return new t.Type<GroupItemContent, WithTypes<GroupItemLegacy>>(
|
|
77
79
|
"GroupItemLegacy",
|
|
78
80
|
(u): u is GroupItemContent =>
|
|
@@ -81,10 +83,15 @@ export const GroupItemLegacy = (ctx: LegacyContentCtx) => {
|
|
|
81
83
|
const parsed = pipe(
|
|
82
84
|
itemLegacyReader.decode(u),
|
|
83
85
|
either.map((items) => {
|
|
86
|
+
const groupItemCtx = ctx.withContentKey(`${index}`)
|
|
84
87
|
const parsedItems = Object.entries(items).reduce<
|
|
85
88
|
Array<[string, NestableContent | GroupContent]>
|
|
86
89
|
>((acc, [itemKey, itemValue]) => {
|
|
87
|
-
const itemCtx = getFieldCtx(
|
|
90
|
+
const itemCtx = getFieldCtx({
|
|
91
|
+
fieldKey: itemKey,
|
|
92
|
+
contentKey: itemKey,
|
|
93
|
+
ctx: groupItemCtx,
|
|
94
|
+
})
|
|
88
95
|
const result =
|
|
89
96
|
itemCtx.fieldType === GroupFieldType
|
|
90
97
|
? GroupLegacy(itemCtx).decode(itemValue)
|
|
@@ -99,15 +106,17 @@ export const GroupItemLegacy = (ctx: LegacyContentCtx) => {
|
|
|
99
106
|
return {
|
|
100
107
|
value: parsedItems,
|
|
101
108
|
__TYPE__: GroupItemContentType,
|
|
109
|
+
key: groupItemCtx.fieldContentKey,
|
|
102
110
|
}
|
|
103
111
|
}),
|
|
104
112
|
)
|
|
105
113
|
return parsed
|
|
106
114
|
},
|
|
107
115
|
(item) => {
|
|
116
|
+
const groupItemCtx = ctx.withContentKey(`${index}`)
|
|
108
117
|
return item.value.reduce<WithTypes<GroupItemLegacy>>(
|
|
109
118
|
(acc, [key, value]) => {
|
|
110
|
-
const itemCtx = getFieldCtx(key, ctx)
|
|
119
|
+
const itemCtx = getFieldCtx({ fieldKey: key, ctx })
|
|
111
120
|
const encoded = isGroupContent(value)
|
|
112
121
|
? GroupLegacy(itemCtx).encode(value)
|
|
113
122
|
: NestableLegacy(itemCtx).encode(value)
|
|
@@ -117,20 +126,46 @@ export const GroupItemLegacy = (ctx: LegacyContentCtx) => {
|
|
|
117
126
|
return {
|
|
118
127
|
content: { ...acc.content, [key]: encoded.content },
|
|
119
128
|
types: { ...acc.types, ...encoded.types },
|
|
129
|
+
keys: { ...acc.keys, ...encoded.keys },
|
|
120
130
|
}
|
|
121
131
|
},
|
|
122
|
-
{ content: {}, types: {} },
|
|
132
|
+
{ content: {}, types: {}, keys: { [groupItemCtx.keyOfKey]: item.key } },
|
|
123
133
|
)
|
|
124
134
|
},
|
|
125
135
|
)
|
|
126
136
|
}
|
|
127
137
|
|
|
138
|
+
export function arrayWithIndexCodec<T, O>(
|
|
139
|
+
f: (index: number) => t.Type<T, O, unknown>,
|
|
140
|
+
): t.Type<Array<T>, O[], unknown> {
|
|
141
|
+
return new t.Type<Array<T>, O[], unknown>(
|
|
142
|
+
"ArrayWithIndexCodec",
|
|
143
|
+
(u): u is Array<T> => Array.isArray(u),
|
|
144
|
+
(items) =>
|
|
145
|
+
pipe(
|
|
146
|
+
t.array(t.unknown).decode(items),
|
|
147
|
+
either.chain((validItems) => {
|
|
148
|
+
const decodedItems = validItems.map((item, index) => {
|
|
149
|
+
return f(index).decode(item)
|
|
150
|
+
})
|
|
151
|
+
return array.sequence(either.Applicative)(decodedItems)
|
|
152
|
+
}),
|
|
153
|
+
),
|
|
154
|
+
(items) => items.map((item, index) => f(index).encode(item)),
|
|
155
|
+
)
|
|
156
|
+
}
|
|
157
|
+
|
|
128
158
|
type GroupLegacy = Array<GroupItemLegacy>
|
|
129
159
|
export const GroupLegacy = (
|
|
130
160
|
ctx: LegacyContentCtx,
|
|
131
161
|
): t.Type<GroupContent, WithTypes<GroupLegacy>, unknown> => {
|
|
132
|
-
const codecDecode =
|
|
133
|
-
|
|
162
|
+
const codecDecode = arrayWithIndexCodec<
|
|
163
|
+
GroupItemContent | null,
|
|
164
|
+
WithTypes<GroupItemLegacy> | null
|
|
165
|
+
>((index) => t.union([GroupItemLegacy(ctx, index), t.null]))
|
|
166
|
+
|
|
167
|
+
const codecEncode = (items: GroupItemContent[]) =>
|
|
168
|
+
items.map((item, index) => GroupItemLegacy(ctx, index).encode(item))
|
|
134
169
|
|
|
135
170
|
return new t.Type<GroupContent, WithTypes<GroupLegacy>, unknown>(
|
|
136
171
|
"GroupLegacy",
|
|
@@ -139,19 +174,22 @@ export const GroupLegacy = (
|
|
|
139
174
|
return pipe(
|
|
140
175
|
codecDecode.decode(items),
|
|
141
176
|
either.map((parsedItems) => {
|
|
177
|
+
const value = parsedItems.map((i, index) => {
|
|
178
|
+
if (i === null) {
|
|
179
|
+
const key = ctx.withContentKey(`${index}`).fieldContentKey
|
|
180
|
+
return { __TYPE__: GroupItemContentType, key, value: [] }
|
|
181
|
+
}
|
|
182
|
+
return i
|
|
183
|
+
})
|
|
142
184
|
return {
|
|
143
|
-
value
|
|
144
|
-
if (i === null) {
|
|
145
|
-
return { __TYPE__: GroupItemContentType, value: [] }
|
|
146
|
-
} else return i
|
|
147
|
-
}),
|
|
185
|
+
value,
|
|
148
186
|
__TYPE__: GroupContentType,
|
|
149
187
|
}
|
|
150
188
|
}),
|
|
151
189
|
)
|
|
152
190
|
},
|
|
153
191
|
(g: GroupContent) => {
|
|
154
|
-
const res = codecEncode
|
|
192
|
+
const res = codecEncode(g.value)
|
|
155
193
|
return {
|
|
156
194
|
content: res.map((block) => block.content),
|
|
157
195
|
types: res.reduce<Record<string, FieldOrSliceType>>(
|
|
@@ -160,6 +198,9 @@ export const GroupLegacy = (
|
|
|
160
198
|
},
|
|
161
199
|
{ [ctx.keyOfType]: GroupFieldType },
|
|
162
200
|
),
|
|
201
|
+
keys: res.reduce<Record<string, string>>((acc, block) => {
|
|
202
|
+
return { ...acc, ...block.keys }
|
|
203
|
+
}, {}),
|
|
163
204
|
}
|
|
164
205
|
},
|
|
165
206
|
)
|
|
@@ -223,9 +264,9 @@ export function traverseGroupItemsContent({
|
|
|
223
264
|
model?: Record<string, Group | NestableWidget> | undefined
|
|
224
265
|
}) {
|
|
225
266
|
return (transform: TraverseWidgetContentFn): Array<GroupItemContent> => {
|
|
226
|
-
return content.map((groupItem
|
|
267
|
+
return content.map((groupItem) => {
|
|
227
268
|
const groupItemPath = path.concat([
|
|
228
|
-
{ key:
|
|
269
|
+
{ key: groupItem.key, type: "GroupItem" },
|
|
229
270
|
])
|
|
230
271
|
|
|
231
272
|
const groupItemFields = groupItem.value.reduce<GroupItemContent["value"]>(
|
|
@@ -284,6 +325,7 @@ export function traverseGroupItemsContent({
|
|
|
284
325
|
|
|
285
326
|
return {
|
|
286
327
|
__TYPE__: groupItem.__TYPE__,
|
|
328
|
+
key: groupItem.key,
|
|
287
329
|
value: groupItemFields,
|
|
288
330
|
}
|
|
289
331
|
})
|