@prismicio/types-internal 2.2.0-traverse.alpha-0 → 2.2.0-traverse.alpha-2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/lib/_internal/utils.d.ts +21 -4
  2. package/lib/_internal/utils.js +11 -0
  3. package/lib/content/Document.d.ts +2185 -13
  4. package/lib/content/Document.js +130 -35
  5. package/lib/content/fields/GroupContent.d.ts +11 -4
  6. package/lib/content/fields/GroupContent.js +31 -15
  7. package/lib/content/fields/slices/Slice/CompositeSliceContent.d.ts +8 -6
  8. package/lib/content/fields/slices/Slice/CompositeSliceContent.js +33 -36
  9. package/lib/content/fields/slices/Slice/SharedSliceContent.d.ts +8 -6
  10. package/lib/content/fields/slices/Slice/SharedSliceContent.js +28 -38
  11. package/lib/content/fields/slices/Slice/SimpleSliceContent.d.ts +10 -0
  12. package/lib/content/fields/slices/Slice/SimpleSliceContent.js +60 -1
  13. package/lib/content/fields/slices/SliceItem.d.ts +15 -0
  14. package/lib/content/fields/slices/SliceItem.js +15 -1
  15. package/lib/content/fields/slices/SlicesContent.d.ts +4 -3
  16. package/lib/content/fields/slices/SlicesContent.js +125 -62
  17. package/lib/customtypes/CustomType.d.ts +4 -0
  18. package/lib/customtypes/CustomType.js +18 -1
  19. package/lib/customtypes/Section.d.ts +3 -0
  20. package/lib/customtypes/diff/SharedSlice.d.ts +6 -0
  21. package/lib/customtypes/widgets/Widget.d.ts +3 -0
  22. package/lib/customtypes/widgets/slices/CompositeSlice.d.ts +5 -0
  23. package/lib/customtypes/widgets/slices/SharedSlice.d.ts +8 -0
  24. package/lib/customtypes/widgets/slices/SharedSlice.js +3 -0
  25. package/lib/customtypes/widgets/slices/Slices.d.ts +6 -0
  26. package/lib/import/validators/fields/ImportSlices/SharedSlice/utils.d.ts +3 -0
  27. package/package.json +1 -1
  28. package/src/_internal/utils.ts +63 -7
  29. package/src/content/Document.ts +177 -42
  30. package/src/content/fields/GroupContent.ts +50 -16
  31. package/src/content/fields/slices/Slice/CompositeSliceContent.ts +55 -44
  32. package/src/content/fields/slices/Slice/SharedSliceContent.ts +43 -49
  33. package/src/content/fields/slices/Slice/SimpleSliceContent.ts +99 -1
  34. package/src/content/fields/slices/SliceItem.ts +39 -3
  35. package/src/content/fields/slices/SlicesContent.ts +172 -69
  36. package/src/customtypes/CustomType.ts +21 -0
  37. package/src/customtypes/widgets/slices/CompositeSlice.ts +6 -0
  38. package/src/customtypes/widgets/slices/SharedSlice.ts +12 -0
  39. package/lib/validators/NullOrT.d.ts +0 -2
  40. package/lib/validators/NullOrT.js +0 -12
@@ -1,12 +1,31 @@
1
1
  import * as t from "io-ts"
2
2
 
3
+ import type {
4
+ ContentPath,
5
+ TraverseSliceContentFn,
6
+ TraverseWidgetContentFn,
7
+ } from "../../../../_internal/utils"
8
+ import type {
9
+ Group,
10
+ NestableWidget,
11
+ VariationFields,
12
+ } from "../../../../customtypes"
3
13
  import type { LegacyContentCtx } from "../../../LegacyContentCtx"
4
- import { GroupContent, GroupLegacy, isGroupContent } from "../../GroupContent"
14
+ import {
15
+ GroupContent,
16
+ GroupLegacy,
17
+ isGroupContent,
18
+ traverseGroupContent,
19
+ } from "../../GroupContent"
5
20
  import {
6
21
  isNestableContent,
7
22
  NestableContent,
8
23
  NestableLegacy,
9
24
  } from "../../nestable"
25
+ import type {
26
+ SharedSliceItemContent,
27
+ SimpleSliceItemContent,
28
+ } from "../SliceItem"
10
29
 
11
30
  export const SimpleSliceContent = t.union([NestableContent, GroupContent])
12
31
  export type SimpleSliceContent = t.TypeOf<typeof SimpleSliceContent>
@@ -31,3 +50,82 @@ export const SimpleSliceLegacy = (ctx: LegacyContentCtx) => {
31
50
  },
32
51
  }
33
52
  }
53
+
54
+ export function traverseSimpleSliceContent({
55
+ path,
56
+ sliceKey,
57
+ sliceName,
58
+ model,
59
+ content,
60
+ }: {
61
+ path: ContentPath
62
+ sliceKey: string
63
+ sliceName: string
64
+ content: SimpleSliceItemContent
65
+ model?: VariationFields | Group | NestableWidget | undefined
66
+ }) {
67
+ return (
68
+ transformWidget: TraverseWidgetContentFn,
69
+ transformSlice: TraverseSliceContentFn,
70
+ ): SharedSliceItemContent | SimpleSliceItemContent | undefined => {
71
+ if (isGroupContent(content.widget)) {
72
+ const convertedGroupWidget: GroupContent | undefined =
73
+ traverseGroupContent({
74
+ path,
75
+ key: content.key,
76
+ apiId: content.name,
77
+ model: (() => {
78
+ if (model?.type === "Group") return model
79
+ if (model?.type === "SharedSlice")
80
+ return {
81
+ type: "Group",
82
+ config: { fields: model.fields.items || {} },
83
+ }
84
+ return
85
+ })(),
86
+ content: content.widget,
87
+ })(transformWidget)
88
+
89
+ return (
90
+ convertedGroupWidget &&
91
+ transformSlice({
92
+ key: content.key,
93
+ apiId: content.name,
94
+ path,
95
+ model,
96
+ content: {
97
+ ...content,
98
+ widget: convertedGroupWidget,
99
+ },
100
+ })
101
+ )
102
+ }
103
+
104
+ const convertedNestable: NestableContent | undefined = transformWidget({
105
+ key: content.key,
106
+ apiId: content.name,
107
+ path,
108
+ model: (() => {
109
+ if (model?.type === "SharedSlice")
110
+ return model.fields.primary?.[content.name]
111
+ if (model?.type !== "Group") return model
112
+ return
113
+ })(),
114
+ content: content.widget,
115
+ })
116
+
117
+ return (
118
+ convertedNestable &&
119
+ transformSlice({
120
+ key: sliceKey,
121
+ apiId: sliceName,
122
+ path,
123
+ model,
124
+ content: {
125
+ ...content,
126
+ widget: convertedNestable,
127
+ },
128
+ })
129
+ )
130
+ }
131
+ }
@@ -9,10 +9,21 @@ import {
9
9
  LegacyContentCtx,
10
10
  WithTypes,
11
11
  } from "../../LegacyContentCtx"
12
+ import { isGroupContent } from "../GroupContent"
13
+ import { isNestableContent } from "../nestable"
12
14
  import { SliceContent, SliceLegacy } from "./Slice"
13
- import { isCompositeSliceContent } from "./Slice/CompositeSliceContent"
14
- import { isSharedSliceContent } from "./Slice/SharedSliceContent"
15
- import { isSimpleSliceContent } from "./Slice/SimpleSliceContent"
15
+ import {
16
+ CompositeSliceContent,
17
+ isCompositeSliceContent,
18
+ } from "./Slice/CompositeSliceContent"
19
+ import {
20
+ isSharedSliceContent,
21
+ SharedSliceContent,
22
+ } from "./Slice/SharedSliceContent"
23
+ import {
24
+ isSimpleSliceContent,
25
+ SimpleSliceContent,
26
+ } from "./Slice/SimpleSliceContent"
16
27
 
17
28
  export const SliceItemContent = t.type({
18
29
  key: t.string,
@@ -21,6 +32,31 @@ export const SliceItemContent = t.type({
21
32
  widget: SliceContent,
22
33
  })
23
34
  export type SliceItemContent = t.TypeOf<typeof SliceItemContent>
35
+ export type SharedSliceItemContent = Omit<SliceItemContent, "widget"> & {
36
+ widget: SharedSliceContent
37
+ }
38
+ export function isSharedSliceItemContent(
39
+ item: SliceItemContent,
40
+ ): item is SharedSliceItemContent {
41
+ return isSharedSliceContent(item.widget)
42
+ }
43
+
44
+ export type CompositeSliceItemContent = Omit<SliceItemContent, "widget"> & {
45
+ widget: CompositeSliceContent
46
+ }
47
+ export function isCompositeSliceItemContent(
48
+ item: SliceItemContent,
49
+ ): item is CompositeSliceItemContent {
50
+ return isCompositeSliceContent(item.widget)
51
+ }
52
+ export type SimpleSliceItemContent = Omit<SliceItemContent, "widget"> & {
53
+ widget: SimpleSliceContent
54
+ }
55
+ export function isSimpleSliceItemContent(
56
+ item: SliceItemContent,
57
+ ): item is SimpleSliceItemContent {
58
+ return isGroupContent(item.widget) || isNestableContent(item.widget)
59
+ }
24
60
 
25
61
  const itemLegacyReader = t.exact(
26
62
  t.intersection([
@@ -2,13 +2,22 @@ import { either } from "fp-ts"
2
2
  import { pipe } from "fp-ts/lib/function"
3
3
  import * as t from "io-ts"
4
4
 
5
- import type { ContentPath, TraverseContentFn } from "../../../_internal/utils"
6
5
  import {
7
- type StaticSlice,
6
+ ContentPath,
7
+ SliceModel,
8
+ TraverseSliceContentFn,
9
+ TraverseWidgetContentFn,
10
+ } from "../../../_internal/utils"
11
+ import {
8
12
  type StaticSlices,
13
+ CompositeSliceFields,
14
+ Group,
9
15
  isCompositeSlice,
10
16
  isLegacySlice,
11
17
  isStaticSharedSlice,
18
+ NestableWidget,
19
+ SharedSlice,
20
+ VariationFields,
12
21
  } from "../../../customtypes"
13
22
  import type {
14
23
  FieldOrSliceType,
@@ -16,10 +25,16 @@ import type {
16
25
  WithTypes,
17
26
  } from "../../LegacyContentCtx"
18
27
  import { hasContentType } from "../../utils"
19
- import { traverseGroupContent } from "../GroupContent"
20
28
  import { traverseCompositeSliceContent } from "./Slice/CompositeSliceContent"
21
29
  import { traverseSharedSliceContent } from "./Slice/SharedSliceContent"
22
- import { SliceItemContent, SlicesItemLegacy } from "./SliceItem"
30
+ import { traverseSimpleSliceContent } from "./Slice/SimpleSliceContent"
31
+ import {
32
+ isCompositeSliceItemContent,
33
+ isSharedSliceItemContent,
34
+ isSimpleSliceItemContent,
35
+ SliceItemContent,
36
+ SlicesItemLegacy,
37
+ } from "./SliceItem"
23
38
 
24
39
  export const SlicesContentType = "SliceContentType"
25
40
 
@@ -66,87 +81,175 @@ export const SlicesContent = t.type({
66
81
 
67
82
  export type SlicesContent = t.TypeOf<typeof SlicesContent>
68
83
 
84
+ function findSliceModel(
85
+ slicesPath: ContentPath,
86
+ model: StaticSlices,
87
+ content: SliceItemContent,
88
+ ): SliceModel | undefined {
89
+ const defaultModel = model?.config?.choices?.[content.name]
90
+
91
+ // regular case for shared slices
92
+ const sharedSliceModel = (): VariationFields | undefined => {
93
+ if (isSharedSliceItemContent(content)) {
94
+ if (defaultModel && isStaticSharedSlice(defaultModel)) {
95
+ const variationDef = defaultModel.variations.find(
96
+ (v) => v.id === content.widget.variation,
97
+ )
98
+ return variationDef
99
+ ? {
100
+ type: "SharedSlice",
101
+ sliceName: defaultModel.id,
102
+ variationId: variationDef.id,
103
+ fields: {
104
+ primary: variationDef.primary || {},
105
+ items: variationDef.items || {},
106
+ },
107
+ }
108
+ : undefined
109
+ }
110
+ }
111
+ return
112
+ }
113
+
114
+ const migratedSliceModel = (): VariationFields | undefined => {
115
+ const legacyContentPath = ContentPath.append(
116
+ ContentPath.serialize(slicesPath),
117
+ content.name,
118
+ )
119
+
120
+ const migratedSliceModel = Object.values(model?.config?.choices || {}).find(
121
+ (sliceModel): sliceModel is SharedSlice => {
122
+ if (isStaticSharedSlice(sliceModel)) {
123
+ return !!sliceModel.legacyPaths?.[legacyContentPath]
124
+ }
125
+
126
+ return false
127
+ },
128
+ )
129
+ if (!migratedSliceModel) return
130
+
131
+ const migratedVariation = migratedSliceModel?.variations.find(
132
+ (v) => v.id === migratedSliceModel.legacyPaths?.[legacyContentPath],
133
+ )
134
+ if (!migratedVariation) return
135
+
136
+ return {
137
+ type: "SharedSlice",
138
+ sliceName: migratedSliceModel.id,
139
+ variationId: migratedVariation.id,
140
+ fields: {
141
+ primary: migratedVariation.primary || {},
142
+ items: migratedVariation.items || {},
143
+ },
144
+ }
145
+ }
146
+
147
+ const legacySliceModel = ():
148
+ | NestableWidget
149
+ | CompositeSliceFields
150
+ | Group
151
+ | undefined => {
152
+ if (!defaultModel) return
153
+
154
+ if (isCompositeSlice(defaultModel)) {
155
+ return {
156
+ type: "Slice",
157
+ fields: {
158
+ "non-repeat": defaultModel["non-repeat"] || {},
159
+ repeat: defaultModel.repeat || {},
160
+ },
161
+ }
162
+ }
163
+ if (isLegacySlice(defaultModel)) {
164
+ return defaultModel
165
+ }
166
+
167
+ return
168
+ }
169
+ return sharedSliceModel() || migratedSliceModel() || legacySliceModel()
170
+ }
171
+
69
172
  export function traverseSlices({
70
173
  path,
174
+ key,
71
175
  model,
72
176
  content,
73
177
  }: {
74
178
  path: ContentPath
179
+ key: string
75
180
  content: SlicesContent
76
181
  model?: StaticSlices | undefined
77
182
  }) {
78
- return (transform: TraverseContentFn): SlicesContent | undefined => {
183
+ return (
184
+ transformWidget: TraverseWidgetContentFn,
185
+ transformSlice: TraverseSliceContentFn,
186
+ ): SlicesContent | undefined => {
79
187
  const value = content.value.reduce<SlicesContent["value"]>(
80
188
  (acc, sliceContent) => {
81
- const sliceModel: StaticSlice | undefined =
82
- model?.config?.choices?.[sliceContent.name]
83
-
84
- const slicePath = path.concat({
85
- key: sliceContent.key,
86
- type: sliceContent.widget.__TYPE__,
87
- })
88
-
89
- const convertedSliceWidget = (() => {
90
- switch (sliceContent.widget.__TYPE__) {
91
- case "SharedSliceContent":
92
- return traverseSharedSliceContent({
93
- path: slicePath,
94
- sliceName: sliceContent.name,
95
- model:
96
- sliceModel && isStaticSharedSlice(sliceModel)
97
- ? sliceModel
98
- : undefined,
99
- content: sliceContent.widget,
100
- })(transform)
101
- case "CompositeSliceContent":
102
- return traverseCompositeSliceContent({
103
- path: slicePath,
104
- sliceName: sliceContent.name,
105
- model:
106
- sliceModel && isCompositeSlice(sliceModel)
107
- ? sliceModel
108
- : undefined,
109
- content: sliceContent.widget,
110
- })(transform)
111
- case "GroupContentType":
112
- return traverseGroupContent({
113
- path: slicePath,
114
- model:
115
- sliceModel &&
116
- isLegacySlice(sliceModel) &&
117
- sliceModel.type === "Group"
118
- ? sliceModel
119
- : undefined,
120
- content: sliceContent.widget,
121
- })(transform)
122
- default:
123
- return sliceContent.widget
124
- }
189
+ const sliceModel = model && findSliceModel(path, model, sliceContent)
190
+
191
+ const convertedSlice: SliceItemContent | undefined = (() => {
192
+ if (isSharedSliceItemContent(sliceContent))
193
+ return traverseSharedSliceContent({
194
+ path: path.concat({
195
+ key: sliceContent.key,
196
+ type: "SharedSlice",
197
+ }),
198
+ sliceKey: sliceContent.key,
199
+ sliceName: sliceContent.name,
200
+ model:
201
+ sliceModel?.type === "SharedSlice" ? sliceModel : undefined,
202
+ content: sliceContent,
203
+ })(transformWidget, transformSlice)
204
+
205
+ if (isCompositeSliceItemContent(sliceContent))
206
+ return traverseCompositeSliceContent({
207
+ path: path.concat({
208
+ key: sliceContent.key,
209
+ type: "Slice",
210
+ }),
211
+ sliceKey: sliceContent.key,
212
+ sliceName: sliceContent.name,
213
+ model:
214
+ sliceModel?.type === "Slice" ||
215
+ sliceModel?.type === "SharedSlice"
216
+ ? sliceModel
217
+ : undefined,
218
+ content: sliceContent,
219
+ })(transformWidget, transformSlice)
220
+
221
+ if (isSimpleSliceItemContent(sliceContent))
222
+ return traverseSimpleSliceContent({
223
+ path: path.concat({
224
+ key: sliceContent.key,
225
+ type: "LegacySlice",
226
+ }),
227
+ sliceKey: sliceContent.key,
228
+ sliceName: sliceContent.name,
229
+ model:
230
+ sliceModel && sliceModel?.type !== "Slice"
231
+ ? sliceModel
232
+ : undefined,
233
+ content: sliceContent,
234
+ })(transformWidget, transformSlice)
235
+
236
+ return
125
237
  })()
126
238
 
127
- if (!convertedSliceWidget) return acc
128
-
129
- const convertedSlice = transform({
130
- key: sliceContent.key,
131
- apiId: sliceContent.name,
132
- path: slicePath,
133
- model: sliceModel,
134
- content: convertedSliceWidget,
135
- })
136
-
137
- const convertedSliceParent = convertedSlice && {
138
- ...sliceContent,
139
- widget: convertedSlice,
140
- }
141
-
142
- return convertedSliceParent ? acc.concat(convertedSliceParent) : acc
239
+ return convertedSlice ? acc.concat(convertedSlice) : acc
143
240
  },
144
241
  [],
145
242
  )
146
243
 
147
- return {
148
- __TYPE__: content.__TYPE__,
149
- value,
150
- }
244
+ return transformWidget({
245
+ path,
246
+ key,
247
+ apiId: key,
248
+ model,
249
+ content: {
250
+ __TYPE__: content.__TYPE__,
251
+ value,
252
+ },
253
+ })
151
254
  }
152
255
  }
@@ -224,3 +224,24 @@ export function flattenCustomTypeFields(
224
224
  {},
225
225
  )
226
226
  }
227
+
228
+ export function collectSharedSlices(
229
+ customType: StaticCustomType,
230
+ ): Record<string, SharedSlice> {
231
+ return flattenStaticWidgets(customType).reduce((acc, [, w]) => {
232
+ if (w.type === "Slices" || w.type === "Choice") {
233
+ return {
234
+ ...acc,
235
+ ...Object.entries(w.config?.choices || {}).reduce(
236
+ (sliceZoneAcc, [sliceKey, sliceModel]) => {
237
+ return sliceModel.type === "SharedSlice"
238
+ ? { ...sliceZoneAcc, [sliceKey]: sliceModel }
239
+ : sliceZoneAcc
240
+ },
241
+ {},
242
+ ),
243
+ }
244
+ }
245
+ return acc
246
+ }, {})
247
+ }
@@ -1,5 +1,6 @@
1
1
  import * as t from "io-ts"
2
2
 
3
+ import type { PickOnly } from "../../../_internal/utils"
3
4
  import { WidgetKey } from "../../../common"
4
5
  import { StringOrNull } from "../../../validators"
5
6
  import { NestableWidget } from "../nestable/NestableWidget"
@@ -32,6 +33,11 @@ export const CompositeSlice = t.exact(
32
33
  )
33
34
  export type CompositeSlice = t.TypeOf<typeof CompositeSlice>
34
35
 
36
+ export type CompositeSliceFields = {
37
+ type: "Slice"
38
+ fields: PickOnly<CompositeSlice, "non-repeat" | "repeat">
39
+ }
40
+
35
41
  export function isCompositeSlice(
36
42
  slice: DynamicSlice | StaticSlice,
37
43
  ): slice is CompositeSlice {
@@ -1,6 +1,7 @@
1
1
  import * as t from "io-ts"
2
2
  import { withFallback } from "io-ts-types/lib/withFallback"
3
3
 
4
+ import type { PickOnly } from "../../../_internal/utils"
4
5
  import { WidgetKey } from "../../../common"
5
6
  import { NestableWidget } from "../nestable/NestableWidget"
6
7
  import type { SharedSliceRef } from "./SharedSliceRef"
@@ -29,8 +30,18 @@ export const Variation = t.exact(
29
30
 
30
31
  export type Variation = t.TypeOf<typeof Variation>
31
32
 
33
+ export type VariationFields = {
34
+ type: "SharedSlice"
35
+ sliceName: string
36
+ variationId: string
37
+ fields: PickOnly<Variation, "primary" | "items">
38
+ }
39
+
32
40
  export const SharedSliceType = "SharedSlice"
33
41
 
42
+ const LegacyPath = t.string
43
+ const VariationId = t.string
44
+
34
45
  export const SharedSlice = t.exact(
35
46
  t.intersection([
36
47
  t.type({
@@ -41,6 +52,7 @@ export const SharedSlice = t.exact(
41
52
  }),
42
53
  t.partial({
43
54
  description: t.string,
55
+ legacyPaths: t.record(LegacyPath, VariationId),
44
56
  }),
45
57
  ]),
46
58
  )
@@ -1,2 +0,0 @@
1
- import * as t from "io-ts";
2
- export declare const NullOrElse: <A, O = A>(codec: t.Type<A, O, unknown>) => t.Type<A | null, O | undefined, unknown>;
@@ -1,12 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.NullOrElse = void 0;
4
- const tslib_1 = require("tslib");
5
- const Either_1 = require("fp-ts/lib/Either");
6
- const t = (0, tslib_1.__importStar)(require("io-ts"));
7
- const NullOrElse = (codec) => new t.Type("NullOrT", (u) => null === u || codec.is(u), (u) => {
8
- if ((0, Either_1.isRight)(t.null.decode(u)))
9
- return t.success(null);
10
- return codec.decode(u);
11
- }, (chunk) => (chunk ? codec.encode(chunk) : undefined));
12
- exports.NullOrElse = NullOrElse;