@prismicio/types-internal 2.1.0-alpha.2 → 2.1.0-alpha.4
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/content/Document.d.ts +1 -1
- package/lib/content/Document.js +1 -6
- package/lib/customtypes/CustomType.d.ts +1046 -1180
- package/lib/customtypes/CustomType.js +13 -74
- package/lib/customtypes/Section.d.ts +1047 -1171
- package/lib/customtypes/Section.js +23 -1
- package/lib/customtypes/_internal/utils.d.ts +3 -0
- package/lib/customtypes/_internal/utils.js +20 -0
- package/lib/customtypes/diff/SharedSlice.d.ts +184 -220
- package/lib/customtypes/diff/Variation.d.ts +183 -219
- package/lib/customtypes/widgets/Group.d.ts +6 -40
- package/lib/customtypes/widgets/Group.js +20 -1
- package/lib/customtypes/widgets/Widget.d.ts +778 -976
- package/lib/customtypes/widgets/nestable/Link/ContentRelationshipResolver.d.ts +4 -22
- package/lib/customtypes/widgets/nestable/Link/ContentRelationshipResolver.js +5 -34
- package/lib/customtypes/widgets/nestable/Link/index.d.ts +4 -40
- package/lib/customtypes/widgets/nestable/Link/index.js +1 -1
- package/lib/customtypes/widgets/nestable/NestableWidget.d.ts +2 -20
- package/lib/customtypes/widgets/slices/CompositeSlice.d.ts +6 -40
- package/lib/customtypes/widgets/slices/CompositeSlice.js +26 -1
- package/lib/customtypes/widgets/slices/LegacySlice.d.ts +4 -40
- package/lib/customtypes/widgets/slices/SharedSlice.d.ts +10 -80
- package/lib/customtypes/widgets/slices/SharedSlice.js +35 -1
- package/lib/customtypes/widgets/slices/Slices.d.ts +924 -1246
- package/lib/customtypes/widgets/slices/Slices.js +34 -1
- package/lib/validators/StringOrT.d.ts +3 -0
- package/lib/validators/StringOrT.js +15 -0
- package/package.json +1 -1
- package/src/content/Document.ts +2 -6
- package/src/customtypes/CustomType.ts +24 -97
- package/src/customtypes/Section.ts +28 -1
- package/src/customtypes/_internal/utils.ts +25 -0
- package/src/customtypes/widgets/Group.ts +24 -0
- package/src/customtypes/widgets/nestable/Link/ContentRelationshipResolver.ts +5 -54
- package/src/customtypes/widgets/nestable/Link/index.ts +2 -2
- package/src/customtypes/widgets/slices/CompositeSlice.ts +33 -0
- package/src/customtypes/widgets/slices/SharedSlice.ts +47 -0
- package/src/customtypes/widgets/slices/Slices.ts +44 -1
- package/src/validators/StringOrT.ts +21 -0
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Slices = exports.DynamicSlices = exports.StaticSlices = exports.slicesReader = exports.DynamicSlicesConfig = exports.StaticSlicesConfig = exports.slicesConfigReader = exports.SlicesLabels = exports.SlicesFieldType = exports.LegacySlicesFieldType = void 0;
|
|
3
|
+
exports.traverseSlices = exports.Slices = exports.DynamicSlices = exports.StaticSlices = exports.slicesReader = exports.DynamicSlicesConfig = exports.StaticSlicesConfig = exports.slicesConfigReader = exports.SlicesLabels = exports.SlicesFieldType = exports.LegacySlicesFieldType = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const t = (0, tslib_1.__importStar)(require("io-ts"));
|
|
6
6
|
const common_1 = require("../../../common");
|
|
7
7
|
const validators_1 = require("../../../validators");
|
|
8
|
+
const utils_1 = require("../../_internal/utils");
|
|
9
|
+
const Group_1 = require("../Group");
|
|
8
10
|
const CompositeSlice_1 = require("./CompositeSlice");
|
|
9
11
|
const LegacySlice_1 = require("./LegacySlice");
|
|
10
12
|
const SharedSlice_1 = require("./SharedSlice");
|
|
@@ -78,3 +80,34 @@ exports.Slices = {
|
|
|
78
80
|
}
|
|
79
81
|
},
|
|
80
82
|
};
|
|
83
|
+
function traverseSlices(path, slices, f) {
|
|
84
|
+
var _a, _b, _c, _d;
|
|
85
|
+
const entries = ((_a = slices.config) === null || _a === void 0 ? void 0 : _a.choices) &&
|
|
86
|
+
Object.entries(slices.config.choices).map(([sliceKey, sliceValue]) => {
|
|
87
|
+
const slicePath = path.concat(sliceKey);
|
|
88
|
+
switch (sliceValue.type) {
|
|
89
|
+
case "SharedSlice":
|
|
90
|
+
return [sliceKey, f(sliceValue, sliceKey, slicePath)];
|
|
91
|
+
case "Slice":
|
|
92
|
+
return [
|
|
93
|
+
sliceKey,
|
|
94
|
+
f((0, CompositeSlice_1.traverseCompositeSlice)(slicePath, sliceValue, f), sliceKey, slicePath),
|
|
95
|
+
];
|
|
96
|
+
case "Group":
|
|
97
|
+
return [sliceKey, (0, Group_1.traverseGroup)(slicePath, sliceValue, f)];
|
|
98
|
+
default:
|
|
99
|
+
return [sliceKey, f(sliceValue, sliceKey, slicePath)];
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
return {
|
|
103
|
+
...slices,
|
|
104
|
+
config: {
|
|
105
|
+
...(((_b = slices.config) === null || _b === void 0 ? void 0 : _b.label) ? { label: slices.config.label } : {}),
|
|
106
|
+
...(((_c = slices.config) === null || _c === void 0 ? void 0 : _c.labels) ? { labels: slices.config.labels } : {}),
|
|
107
|
+
...(((_d = slices.config) === null || _d === void 0 ? void 0 : _d.choices) && entries
|
|
108
|
+
? { choices: (0, utils_1.fromEntriesWithValue)(entries) }
|
|
109
|
+
: {}),
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
exports.traverseSlices = traverseSlices;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const fp_ts_1 = require("fp-ts");
|
|
5
|
+
const function_1 = require("fp-ts/function");
|
|
6
|
+
const t = (0, tslib_1.__importStar)(require("io-ts"));
|
|
7
|
+
exports.default = (codec) => {
|
|
8
|
+
return (asObject) => new t.Type("StringOrT", (u) => u instanceof Object, (u) => {
|
|
9
|
+
return (0, function_1.pipe)(t.union([t.string, codec]).decode(u), fp_ts_1.either.map((decoded) => {
|
|
10
|
+
if (typeof decoded === "string")
|
|
11
|
+
return asObject(decoded);
|
|
12
|
+
return decoded;
|
|
13
|
+
}));
|
|
14
|
+
}, (f) => f);
|
|
15
|
+
};
|
package/package.json
CHANGED
package/src/content/Document.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { pipe } from "fp-ts/lib/function"
|
|
|
4
4
|
import * as t from "io-ts"
|
|
5
5
|
|
|
6
6
|
import { WidgetKey } from "../common"
|
|
7
|
-
import {
|
|
7
|
+
import { WidgetContent, WidgetLegacy } from "./fields"
|
|
8
8
|
import {
|
|
9
9
|
defaultCtx,
|
|
10
10
|
FieldOrSliceType,
|
|
@@ -97,11 +97,7 @@ function extractMetadata(data: { [p: string]: unknown }): {
|
|
|
97
97
|
)
|
|
98
98
|
|
|
99
99
|
const slugs = (data["slugs_INTERNAL"] as string[]) || []
|
|
100
|
-
const uid =
|
|
101
|
-
const rawUID = data["uid"]
|
|
102
|
-
if (isUIDContent(rawUID)) return rawUID.value
|
|
103
|
-
return
|
|
104
|
-
})()
|
|
100
|
+
const uid = data["uid"] as string | undefined
|
|
105
101
|
|
|
106
102
|
return {
|
|
107
103
|
widgets,
|
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
import { Either, left, right } from "fp-ts/lib/Either"
|
|
2
1
|
import * as t from "io-ts"
|
|
3
2
|
import { withFallback } from "io-ts-types/lib/withFallback"
|
|
4
3
|
|
|
5
4
|
import { StringOrNull } from "../validators"
|
|
6
|
-
import {
|
|
5
|
+
import { fromEntriesWithValue, TraverseFn } from "./_internal/utils"
|
|
6
|
+
import {
|
|
7
|
+
DynamicSection,
|
|
8
|
+
Sections,
|
|
9
|
+
StaticSection,
|
|
10
|
+
traverseSection,
|
|
11
|
+
} from "./Section"
|
|
7
12
|
import type { SharedSlice } from "./widgets/slices/SharedSlice"
|
|
8
13
|
import type { DynamicSlice } from "./widgets/slices/Slice"
|
|
9
|
-
import type { DynamicSlices } from "./widgets/slices/Slices"
|
|
10
14
|
import type { DynamicWidget } from "./widgets/Widget"
|
|
11
15
|
|
|
12
16
|
export const CustomTypeFormat = {
|
|
@@ -14,24 +18,6 @@ export const CustomTypeFormat = {
|
|
|
14
18
|
custom: "custom",
|
|
15
19
|
}
|
|
16
20
|
|
|
17
|
-
class CustomTypeSlicesError extends Error {
|
|
18
|
-
slices: Array<string>
|
|
19
|
-
override message: string
|
|
20
|
-
|
|
21
|
-
constructor(slices: Array<string>) {
|
|
22
|
-
super()
|
|
23
|
-
this.slices = slices
|
|
24
|
-
this.message = this._formatError(slices)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
_formatError(slicesRefs: Array<string>) {
|
|
28
|
-
const slicesMsg = slicesRefs.map((ref) => `\t - ${ref}`)
|
|
29
|
-
return `The following slices doesn't exists in your Prismic repository:
|
|
30
|
-
${slicesMsg.join("\n")}
|
|
31
|
-
`
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
21
|
function customTypeReader<T extends StaticSection | DynamicSection>(
|
|
36
22
|
codec: t.Type<T, unknown>,
|
|
37
23
|
) {
|
|
@@ -73,39 +59,6 @@ export function flattenWidgets(
|
|
|
73
59
|
[],
|
|
74
60
|
)
|
|
75
61
|
}
|
|
76
|
-
function _retrieveSharedSlicesRef(customType: CustomType): Array<string> {
|
|
77
|
-
const slicezones = flattenWidgets(customType).filter(
|
|
78
|
-
([, widget]: [string, DynamicWidget]) => widget.type === "Slices",
|
|
79
|
-
) as Array<[string, DynamicSlices]>
|
|
80
|
-
|
|
81
|
-
const allSharedRefs = slicezones.reduce(
|
|
82
|
-
(acc: Array<string>, [, slicezone]) => {
|
|
83
|
-
const sharedRefs = Object.entries(
|
|
84
|
-
slicezone.config && slicezone.config.choices
|
|
85
|
-
? slicezone.config.choices
|
|
86
|
-
: {},
|
|
87
|
-
)
|
|
88
|
-
.filter(
|
|
89
|
-
([, slice]: [string, DynamicSlice]) => slice.type === "SharedSlice",
|
|
90
|
-
)
|
|
91
|
-
.map(([key]) => key)
|
|
92
|
-
return acc.concat(sharedRefs)
|
|
93
|
-
},
|
|
94
|
-
[],
|
|
95
|
-
)
|
|
96
|
-
|
|
97
|
-
return allSharedRefs
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function _mapSharedSlicesRefs<A>(
|
|
101
|
-
customType: CustomType,
|
|
102
|
-
): (mapFn: (ref: string) => A) => Array<A> {
|
|
103
|
-
const refs = _retrieveSharedSlicesRef(customType)
|
|
104
|
-
|
|
105
|
-
return function (mapFn: (ref: string) => A): Array<A> {
|
|
106
|
-
return refs.map(mapFn)
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
62
|
|
|
110
63
|
export function toStatic(
|
|
111
64
|
customType: CustomType,
|
|
@@ -127,53 +80,11 @@ export function toStatic(
|
|
|
127
80
|
return { ...customType, json } as StaticCustomType
|
|
128
81
|
}
|
|
129
82
|
|
|
130
|
-
export function validateSlices(
|
|
131
|
-
customType: CustomType,
|
|
132
|
-
sharedSlices: Map<string, SharedSlice>,
|
|
133
|
-
): Either<CustomTypeSlicesError, CustomType> {
|
|
134
|
-
const missingSlices = _mapSharedSlicesRefs<string | undefined>(customType)(
|
|
135
|
-
(ref: string) => {
|
|
136
|
-
const slice: SharedSlice | undefined = sharedSlices.get(ref)
|
|
137
|
-
const isMissing = !slice
|
|
138
|
-
if (isMissing) return ref
|
|
139
|
-
return
|
|
140
|
-
},
|
|
141
|
-
).filter(Boolean) as Array<string>
|
|
142
|
-
|
|
143
|
-
if (missingSlices.length > 0)
|
|
144
|
-
return left(new CustomTypeSlicesError(missingSlices))
|
|
145
|
-
else return right(customType)
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
export function collectWidgets(
|
|
149
|
-
customType: CustomType,
|
|
150
|
-
f: (ref: string, widget: DynamicWidget) => DynamicWidget | undefined,
|
|
151
|
-
): CustomType {
|
|
152
|
-
const json = Object.entries(customType.json).reduce(
|
|
153
|
-
(acc, [sectionId, section]: [string, DynamicSection]) => {
|
|
154
|
-
const updatedSection = Object.entries(section).reduce(
|
|
155
|
-
(acc, [ref, widget]) => {
|
|
156
|
-
const updatedWidget = f(ref, widget)
|
|
157
|
-
if (updatedWidget) {
|
|
158
|
-
return { ...acc, [ref]: updatedWidget }
|
|
159
|
-
}
|
|
160
|
-
return acc
|
|
161
|
-
},
|
|
162
|
-
{},
|
|
163
|
-
)
|
|
164
|
-
return { ...acc, [sectionId]: updatedSection }
|
|
165
|
-
},
|
|
166
|
-
{},
|
|
167
|
-
)
|
|
168
|
-
|
|
169
|
-
return { ...customType, json }
|
|
170
|
-
}
|
|
171
|
-
|
|
172
83
|
export function filterMissingSharedSlices(
|
|
173
84
|
customType: CustomType,
|
|
174
85
|
sharedSlices: Map<string, SharedSlice>,
|
|
175
86
|
): CustomType {
|
|
176
|
-
return
|
|
87
|
+
return traverseCustomType(customType, (widget) => {
|
|
177
88
|
if (widget.type === "Slices") {
|
|
178
89
|
if (!widget.config || !widget.config.choices) return widget
|
|
179
90
|
|
|
@@ -194,3 +105,19 @@ export function filterMissingSharedSlices(
|
|
|
194
105
|
return widget
|
|
195
106
|
})
|
|
196
107
|
}
|
|
108
|
+
|
|
109
|
+
export function traverseCustomType(
|
|
110
|
+
customType: CustomType,
|
|
111
|
+
f: TraverseFn,
|
|
112
|
+
): CustomType {
|
|
113
|
+
const ctEntries = Object.entries(customType.json).map(
|
|
114
|
+
([sectionId, section]: [string, DynamicSection]) => {
|
|
115
|
+
return [sectionId, traverseSection([sectionId], section, f)]
|
|
116
|
+
},
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
...customType,
|
|
121
|
+
json: fromEntriesWithValue(ctEntries),
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import * as t from "io-ts"
|
|
2
2
|
|
|
3
3
|
import { WidgetKey } from "../common"
|
|
4
|
-
import
|
|
4
|
+
import { fromEntriesWithValue, TraverseFn } from "./_internal/utils"
|
|
5
|
+
import { traverseGroup } from "./widgets"
|
|
6
|
+
import { SharedSlice, traverseSlices } from "./widgets/slices"
|
|
5
7
|
import { DynamicWidget, StaticWidget, Widgets } from "./widgets/Widget"
|
|
6
8
|
|
|
7
9
|
export function sectionReader<T extends StaticWidget | DynamicWidget>(
|
|
@@ -33,3 +35,28 @@ export const Sections = {
|
|
|
33
35
|
return section as StaticSection
|
|
34
36
|
},
|
|
35
37
|
}
|
|
38
|
+
|
|
39
|
+
export function traverseSection(
|
|
40
|
+
path: ReadonlyArray<string>,
|
|
41
|
+
section: DynamicSection,
|
|
42
|
+
f: TraverseFn,
|
|
43
|
+
): DynamicSection {
|
|
44
|
+
const updatedSection = Object.entries(section).map(([key, widget]) => {
|
|
45
|
+
const widgetPath = path.concat(key)
|
|
46
|
+
|
|
47
|
+
const widgetOutput = (() => {
|
|
48
|
+
switch (widget.type) {
|
|
49
|
+
case "Choice":
|
|
50
|
+
case "Slices":
|
|
51
|
+
return traverseSlices(widgetPath, widget, f)
|
|
52
|
+
case "Group":
|
|
53
|
+
return traverseGroup(widgetPath, widget, f)
|
|
54
|
+
default:
|
|
55
|
+
return f(widget, key, widgetPath)
|
|
56
|
+
}
|
|
57
|
+
})()
|
|
58
|
+
return [key, widgetOutput && f(widgetOutput, key, widgetPath)]
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
return fromEntriesWithValue(updatedSection)
|
|
62
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { DynamicSlice, DynamicWidget } from "../widgets"
|
|
2
|
+
|
|
3
|
+
export type TraverseFn = <T extends DynamicWidget | DynamicSlice>(
|
|
4
|
+
widget: T,
|
|
5
|
+
key: string,
|
|
6
|
+
path: ReadonlyArray<string>,
|
|
7
|
+
) => DynamicWidget | DynamicSlice | undefined
|
|
8
|
+
|
|
9
|
+
export function fromEntriesWithValue<T>(entries: (string | T)[][]) {
|
|
10
|
+
return Array.from(entries).reduce((acc, entry) => {
|
|
11
|
+
/**
|
|
12
|
+
* Replace the untyped default `fromEntries`
|
|
13
|
+
* Role: filter pair with undefined value
|
|
14
|
+
* Error: Throw an error if malformed: key[string]/value[T]
|
|
15
|
+
*/
|
|
16
|
+
if (entry.length !== 2 || typeof entry[0] !== "string")
|
|
17
|
+
throw new Error("Malformed entry, should be a key[string]/value[T] pair.")
|
|
18
|
+
|
|
19
|
+
const [key, value] = entry
|
|
20
|
+
if (value !== undefined) {
|
|
21
|
+
return { ...acc, [key]: entry[1] }
|
|
22
|
+
}
|
|
23
|
+
return acc
|
|
24
|
+
}, {})
|
|
25
|
+
}
|
|
@@ -2,6 +2,7 @@ import * as t from "io-ts"
|
|
|
2
2
|
|
|
3
3
|
import { WidgetKey } from "../../common"
|
|
4
4
|
import { StringOrNull } from "../../validators"
|
|
5
|
+
import { fromEntriesWithValue, TraverseFn } from "../_internal/utils"
|
|
5
6
|
import { NestableWidget } from "./nestable/NestableWidget"
|
|
6
7
|
|
|
7
8
|
export const GroupFieldType = "Group"
|
|
@@ -28,3 +29,26 @@ export const Group = t.exact(
|
|
|
28
29
|
]),
|
|
29
30
|
)
|
|
30
31
|
export type Group = t.TypeOf<typeof Group>
|
|
32
|
+
|
|
33
|
+
export function traverseGroup(
|
|
34
|
+
path: ReadonlyArray<string>,
|
|
35
|
+
group: Group,
|
|
36
|
+
f: TraverseFn,
|
|
37
|
+
): Group | undefined {
|
|
38
|
+
const entries =
|
|
39
|
+
group.config?.fields &&
|
|
40
|
+
Object.entries(group.config.fields).map(([widgetKey, widgetValue]) => {
|
|
41
|
+
return [widgetKey, f(widgetValue, widgetKey, path.concat(widgetKey))]
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
const config = group.config && {
|
|
45
|
+
...group.config,
|
|
46
|
+
...(group.config.fields && entries
|
|
47
|
+
? { fields: fromEntriesWithValue(entries) }
|
|
48
|
+
: {}),
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
...group,
|
|
52
|
+
...(config ? { config } : {}),
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -1,55 +1,6 @@
|
|
|
1
|
-
import { either } from "fp-ts"
|
|
2
|
-
import { pipe } from "fp-ts/function"
|
|
3
1
|
import * as t from "io-ts"
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
const StringOrT = <T>(codec: t.Type<T>) => {
|
|
7
|
-
return (asObject: (strValue: string) => T) =>
|
|
8
|
-
new t.Type<T>(
|
|
9
|
-
"StringOrT",
|
|
10
|
-
(u: unknown): u is T => u instanceof Object,
|
|
11
|
-
(u: unknown) => {
|
|
12
|
-
return pipe(
|
|
13
|
-
t.union([t.string, codec]).decode(u),
|
|
14
|
-
either.map((decoded) => {
|
|
15
|
-
if (typeof decoded === "string") return asObject(decoded)
|
|
16
|
-
return decoded
|
|
17
|
-
}),
|
|
18
|
-
)
|
|
19
|
-
},
|
|
20
|
-
(f) => f,
|
|
21
|
-
)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/*
|
|
25
|
-
* The models have slight differences if they are nested or not to avoid recursion and so an infinite level of nesting which would be incompatible with the Content API mechanism to resolve nested content.
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
const SimpleFieldResolver = StringOrT(
|
|
29
|
-
t.type({
|
|
30
|
-
fieldId: t.string,
|
|
31
|
-
}),
|
|
32
|
-
)((id) => ({ fieldId: id }))
|
|
33
|
-
|
|
34
|
-
type SimpleFieldResolver = t.TypeOf<typeof SimpleFieldResolver>
|
|
35
|
-
|
|
36
|
-
const NestedCustomTypeResolver = t.type({
|
|
37
|
-
customTypeId: t.string,
|
|
38
|
-
fields: t.readonlyArray(SimpleFieldResolver),
|
|
39
|
-
})
|
|
40
|
-
type NestedCustomTypeResolver = t.TypeOf<typeof NestedCustomTypeResolver>
|
|
41
|
-
|
|
42
|
-
const FieldResolver = StringOrT(
|
|
43
|
-
t.intersection([
|
|
44
|
-
t.type({
|
|
45
|
-
fieldId: t.string,
|
|
46
|
-
}),
|
|
47
|
-
t.partial({
|
|
48
|
-
customTypes: t.readonlyArray(NestedCustomTypeResolver),
|
|
49
|
-
}),
|
|
50
|
-
]),
|
|
51
|
-
)((id) => ({ fieldId: id }))
|
|
52
|
-
type FieldResolver = t.TypeOf<typeof FieldResolver>
|
|
3
|
+
import StringOrT from "../../../../validators/StringOrT"
|
|
53
4
|
|
|
54
5
|
const CustomTypeResolver = StringOrT(
|
|
55
6
|
t.intersection([
|
|
@@ -57,13 +8,13 @@ const CustomTypeResolver = StringOrT(
|
|
|
57
8
|
customTypeId: t.string,
|
|
58
9
|
}),
|
|
59
10
|
t.partial({
|
|
60
|
-
|
|
11
|
+
fetchFields: t.boolean,
|
|
61
12
|
}),
|
|
62
13
|
]),
|
|
63
14
|
)((id) => ({ customTypeId: id }))
|
|
64
15
|
type CustomTypeResolver = t.TypeOf<typeof CustomTypeResolver>
|
|
65
16
|
|
|
66
|
-
export const
|
|
67
|
-
export type
|
|
68
|
-
typeof
|
|
17
|
+
export const ContentRelationshipResolver = t.readonlyArray(CustomTypeResolver)
|
|
18
|
+
export type ContentRelationshipResolver = t.TypeOf<
|
|
19
|
+
typeof ContentRelationshipResolver
|
|
69
20
|
>
|
|
@@ -3,7 +3,7 @@ import * as t from "io-ts"
|
|
|
3
3
|
import { withFallback } from "io-ts-types/lib/withFallback"
|
|
4
4
|
|
|
5
5
|
import { StringOrNull } from "../../../../validators"
|
|
6
|
-
import {
|
|
6
|
+
import { ContentRelationshipResolver } from "./ContentRelationshipResolver"
|
|
7
7
|
|
|
8
8
|
const arrayString = (
|
|
9
9
|
entries:
|
|
@@ -75,7 +75,7 @@ export const LinkConfig = t.exact(
|
|
|
75
75
|
]),
|
|
76
76
|
null,
|
|
77
77
|
),
|
|
78
|
-
customtypes:
|
|
78
|
+
customtypes: ContentRelationshipResolver,
|
|
79
79
|
masks: MasksArrayString,
|
|
80
80
|
tags: MasksArrayString,
|
|
81
81
|
allowTargetBlank: t.boolean,
|
|
@@ -2,6 +2,7 @@ import * as t from "io-ts"
|
|
|
2
2
|
|
|
3
3
|
import { WidgetKey } from "../../../common"
|
|
4
4
|
import { StringOrNull } from "../../../validators"
|
|
5
|
+
import { fromEntriesWithValue, TraverseFn } from "../../_internal/utils"
|
|
5
6
|
import { NestableWidget } from "../nestable/NestableWidget"
|
|
6
7
|
|
|
7
8
|
export const CompositeSliceType = "Slice"
|
|
@@ -30,3 +31,35 @@ export const CompositeSlice = t.exact(
|
|
|
30
31
|
]),
|
|
31
32
|
)
|
|
32
33
|
export type CompositeSlice = t.TypeOf<typeof CompositeSlice>
|
|
34
|
+
|
|
35
|
+
export function traverseCompositeSlice(
|
|
36
|
+
path: ReadonlyArray<string>,
|
|
37
|
+
slice: CompositeSlice,
|
|
38
|
+
f: TraverseFn,
|
|
39
|
+
): CompositeSlice {
|
|
40
|
+
const primaryEntries =
|
|
41
|
+
slice["non-repeat"] &&
|
|
42
|
+
Object.entries(slice["non-repeat"]).map(([widgetKey, widgetValue]) => {
|
|
43
|
+
return [
|
|
44
|
+
widgetKey,
|
|
45
|
+
f(widgetValue, widgetKey, path.concat(["non-repeat", widgetKey])),
|
|
46
|
+
]
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
const itemsEntries =
|
|
50
|
+
slice.repeat &&
|
|
51
|
+
Object.entries(slice.repeat).map(([widgetKey, widgetValue]) => {
|
|
52
|
+
return [
|
|
53
|
+
widgetKey,
|
|
54
|
+
f(widgetValue, widgetKey, path.concat(["repeat", widgetKey])),
|
|
55
|
+
]
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
...slice,
|
|
60
|
+
...(primaryEntries
|
|
61
|
+
? { "non-repeat": fromEntriesWithValue(primaryEntries) }
|
|
62
|
+
: {}),
|
|
63
|
+
...(itemsEntries ? { repeat: fromEntriesWithValue(itemsEntries) } : {}),
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -2,6 +2,7 @@ import * as t from "io-ts"
|
|
|
2
2
|
import { withFallback } from "io-ts-types/lib/withFallback"
|
|
3
3
|
|
|
4
4
|
import { WidgetKey } from "../../../common"
|
|
5
|
+
import { fromEntriesWithValue, TraverseFn } from "../../_internal/utils"
|
|
5
6
|
import { NestableWidget } from "../nestable/NestableWidget"
|
|
6
7
|
|
|
7
8
|
const IMAGE_PLACEHOLDER_URL =
|
|
@@ -44,3 +45,49 @@ export const SharedSlice = t.exact(
|
|
|
44
45
|
)
|
|
45
46
|
|
|
46
47
|
export type SharedSlice = t.TypeOf<typeof SharedSlice>
|
|
48
|
+
|
|
49
|
+
function traverseVariation(
|
|
50
|
+
path: ReadonlyArray<string>,
|
|
51
|
+
variation: Variation,
|
|
52
|
+
f: TraverseFn,
|
|
53
|
+
): Variation {
|
|
54
|
+
const primaryEntries =
|
|
55
|
+
variation.primary &&
|
|
56
|
+
Object.entries(variation.primary).map(([widgetKey, widgetValue]) => {
|
|
57
|
+
return [
|
|
58
|
+
widgetKey,
|
|
59
|
+
f(widgetValue, widgetKey, path.concat(["primary", widgetKey])),
|
|
60
|
+
]
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
const itemsEntries =
|
|
64
|
+
variation.items &&
|
|
65
|
+
Object.entries(variation.items).map(([widgetKey, widgetValue]) => {
|
|
66
|
+
return [
|
|
67
|
+
widgetKey,
|
|
68
|
+
f(widgetValue, widgetKey, path.concat(["items", widgetKey])),
|
|
69
|
+
]
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
...variation,
|
|
74
|
+
...(primaryEntries
|
|
75
|
+
? { primary: fromEntriesWithValue(primaryEntries) }
|
|
76
|
+
: {}),
|
|
77
|
+
...(itemsEntries ? { items: fromEntriesWithValue(itemsEntries) } : {}),
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function traverseSharedSlice(
|
|
82
|
+
slice: SharedSlice,
|
|
83
|
+
f: TraverseFn,
|
|
84
|
+
): SharedSlice {
|
|
85
|
+
const variations = slice.variations.reduce<Array<Variation>>((acc, v) => {
|
|
86
|
+
return acc.concat(traverseVariation([v.id], v, f))
|
|
87
|
+
}, [])
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
...slice,
|
|
91
|
+
variations,
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -2,7 +2,9 @@ import * as t from "io-ts"
|
|
|
2
2
|
|
|
3
3
|
import { WidgetKey } from "../../../common"
|
|
4
4
|
import { StringOrNull } from "../../../validators"
|
|
5
|
-
import {
|
|
5
|
+
import { fromEntriesWithValue, TraverseFn } from "../../_internal/utils"
|
|
6
|
+
import { traverseGroup } from "../Group"
|
|
7
|
+
import { CompositeSlice, traverseCompositeSlice } from "./CompositeSlice"
|
|
6
8
|
import { LegacySlice } from "./LegacySlice"
|
|
7
9
|
import { SharedSlice } from "./SharedSlice"
|
|
8
10
|
import { SharedSliceRef } from "./SharedSliceRef"
|
|
@@ -110,3 +112,44 @@ export const Slices = {
|
|
|
110
112
|
}
|
|
111
113
|
},
|
|
112
114
|
}
|
|
115
|
+
|
|
116
|
+
export function traverseSlices(
|
|
117
|
+
path: ReadonlyArray<string>,
|
|
118
|
+
slices: DynamicSlices,
|
|
119
|
+
f: TraverseFn,
|
|
120
|
+
): DynamicSlices {
|
|
121
|
+
const entries =
|
|
122
|
+
slices.config?.choices &&
|
|
123
|
+
Object.entries(slices.config.choices).map(([sliceKey, sliceValue]) => {
|
|
124
|
+
const slicePath = path.concat(sliceKey)
|
|
125
|
+
|
|
126
|
+
switch (sliceValue.type) {
|
|
127
|
+
case "SharedSlice":
|
|
128
|
+
return [sliceKey, f(sliceValue, sliceKey, slicePath)]
|
|
129
|
+
case "Slice":
|
|
130
|
+
return [
|
|
131
|
+
sliceKey,
|
|
132
|
+
f(
|
|
133
|
+
traverseCompositeSlice(slicePath, sliceValue, f),
|
|
134
|
+
sliceKey,
|
|
135
|
+
slicePath,
|
|
136
|
+
),
|
|
137
|
+
]
|
|
138
|
+
case "Group":
|
|
139
|
+
return [sliceKey, traverseGroup(slicePath, sliceValue, f)]
|
|
140
|
+
default:
|
|
141
|
+
return [sliceKey, f(sliceValue, sliceKey, slicePath)]
|
|
142
|
+
}
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
return {
|
|
146
|
+
...slices,
|
|
147
|
+
config: {
|
|
148
|
+
...(slices.config?.label ? { label: slices.config.label } : {}),
|
|
149
|
+
...(slices.config?.labels ? { labels: slices.config.labels } : {}),
|
|
150
|
+
...(slices.config?.choices && entries
|
|
151
|
+
? { choices: fromEntriesWithValue(entries) }
|
|
152
|
+
: {}),
|
|
153
|
+
},
|
|
154
|
+
}
|
|
155
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { either } from "fp-ts"
|
|
2
|
+
import { pipe } from "fp-ts/function"
|
|
3
|
+
import * as t from "io-ts"
|
|
4
|
+
|
|
5
|
+
export default <T>(codec: t.Type<T>) => {
|
|
6
|
+
return (asObject: (strValue: string) => T) =>
|
|
7
|
+
new t.Type<T>(
|
|
8
|
+
"StringOrT",
|
|
9
|
+
(u: unknown): u is T => u instanceof Object,
|
|
10
|
+
(u: unknown) => {
|
|
11
|
+
return pipe(
|
|
12
|
+
t.union([t.string, codec]).decode(u),
|
|
13
|
+
either.map((decoded) => {
|
|
14
|
+
if (typeof decoded === "string") return asObject(decoded)
|
|
15
|
+
return decoded
|
|
16
|
+
}),
|
|
17
|
+
)
|
|
18
|
+
},
|
|
19
|
+
(f) => f,
|
|
20
|
+
)
|
|
21
|
+
}
|