@contentful/experiences-core 3.7.0-dev-20250919T1400-8d76591.0 → 3.7.0-prerelease-20250917T1034-42f0486.0
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/dist/constants.d.ts +0 -2
- package/dist/constants.js +0 -2
- package/dist/constants.js.map +1 -1
- package/dist/deep-binding/DeepReference.d.ts +1 -18
- package/dist/entity/EntityStore.d.ts +1 -1
- package/dist/exports.js +2 -0
- package/dist/exports.js.map +1 -0
- package/dist/index.d.ts +3 -4
- package/dist/index.js +40 -445
- package/dist/index.js.map +1 -1
- package/dist/registries/breakpointsRegistry.d.ts +13 -36
- package/dist/types.d.ts +5 -1
- package/dist/utils/sanitizeNodeProps.d.ts +2 -3
- package/dist/utils/utils.d.ts +1 -6
- package/package.json +8 -21
- package/dist/constants.cjs +0 -198
- package/dist/constants.cjs.map +0 -1
- package/dist/index.cjs +0 -5412
- package/dist/index.cjs.map +0 -1
- package/dist/utils/extractPrebindingData.d.ts +0 -46
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z, ZodIssueCode } from 'zod';
|
|
2
|
-
import cloneDeep from 'lodash
|
|
2
|
+
import { cloneDeep, omit, isArray, uniqBy } from 'lodash-es';
|
|
3
3
|
import md5 from 'md5';
|
|
4
4
|
import { BLOCKS } from '@contentful/rich-text-types';
|
|
5
5
|
import { create } from 'zustand';
|
|
@@ -26,9 +26,7 @@ const INCOMING_EVENTS = {
|
|
|
26
26
|
/** @deprecated will be removed when dropping backward compatibility for old DND */
|
|
27
27
|
HoverComponent: 'hoverComponent',
|
|
28
28
|
UpdatedEntity: 'updatedEntity',
|
|
29
|
-
/** @deprecated not needed after `patternResolution` was introduced. Will be removed in the next major version. */
|
|
30
29
|
AssembliesAdded: 'assembliesAdded',
|
|
31
|
-
/** @deprecated not needed after `patternResolution` was introduced. Will be removed in the next major version. */
|
|
32
30
|
AssembliesRegistered: 'assembliesRegistered',
|
|
33
31
|
/** @deprecated will be removed when dropping backward compatibility for old DND */
|
|
34
32
|
MouseMove: 'mouseMove',
|
|
@@ -1000,7 +998,7 @@ const BreakpointSchema = z
|
|
|
1000
998
|
id: propertyKeySchema,
|
|
1001
999
|
// Can be replace with z.templateLiteral when upgrading to zod v4
|
|
1002
1000
|
query: z.string().refine((s) => BREAKPOINT_QUERY_REGEX.test(s)),
|
|
1003
|
-
previewSize: z.string()
|
|
1001
|
+
previewSize: z.string(),
|
|
1004
1002
|
displayName: z.string(),
|
|
1005
1003
|
displayIcon: z.enum(['desktop', 'tablet', 'mobile']).optional(),
|
|
1006
1004
|
})
|
|
@@ -1037,6 +1035,19 @@ const ComponentVariableSchema = z.object({
|
|
|
1037
1035
|
});
|
|
1038
1036
|
const ComponentTreeNodeSchema = BaseComponentTreeNodeSchema.extend({
|
|
1039
1037
|
children: z.lazy(() => ComponentTreeNodeSchema.array()),
|
|
1038
|
+
}).superRefine(({ id, prebindingId, parameters }, ctx) => {
|
|
1039
|
+
if (prebindingId && !parameters) {
|
|
1040
|
+
ctx.addIssue({
|
|
1041
|
+
code: z.ZodIssueCode.custom,
|
|
1042
|
+
message: `Found "prebindingId" but no "parameters" for node with id: "${id}"`,
|
|
1043
|
+
});
|
|
1044
|
+
}
|
|
1045
|
+
if (parameters && !prebindingId) {
|
|
1046
|
+
ctx.addIssue({
|
|
1047
|
+
code: z.ZodIssueCode.custom,
|
|
1048
|
+
message: `Found "parameters" but no "prebindingId" for node with id: "${id}"`,
|
|
1049
|
+
});
|
|
1050
|
+
}
|
|
1040
1051
|
});
|
|
1041
1052
|
const ComponentTreeSchema = z
|
|
1042
1053
|
.object({
|
|
@@ -1054,25 +1065,6 @@ z.object({
|
|
|
1054
1065
|
usedComponents: localeWrapper(UsedComponentsSchema).optional(),
|
|
1055
1066
|
});
|
|
1056
1067
|
|
|
1057
|
-
function treeVisit$1(initialNode, onNode) {
|
|
1058
|
-
const _treeVisit = (currentNode) => {
|
|
1059
|
-
const children = [...currentNode.children];
|
|
1060
|
-
onNode(currentNode);
|
|
1061
|
-
for (const child of children) {
|
|
1062
|
-
_treeVisit(child);
|
|
1063
|
-
}
|
|
1064
|
-
};
|
|
1065
|
-
if (Array.isArray(initialNode)) {
|
|
1066
|
-
for (const node of initialNode) {
|
|
1067
|
-
_treeVisit(node);
|
|
1068
|
-
}
|
|
1069
|
-
}
|
|
1070
|
-
else {
|
|
1071
|
-
_treeVisit(initialNode);
|
|
1072
|
-
}
|
|
1073
|
-
}
|
|
1074
|
-
|
|
1075
|
-
const MAX_ALLOWED_PATHS = 200;
|
|
1076
1068
|
const THUMBNAIL_IDS = [
|
|
1077
1069
|
'columns',
|
|
1078
1070
|
'columnsPlusRight',
|
|
@@ -1103,17 +1095,7 @@ const THUMBNAIL_IDS = [
|
|
|
1103
1095
|
const VariableMappingSchema = z.object({
|
|
1104
1096
|
parameterId: propertyKeySchema,
|
|
1105
1097
|
type: z.literal('ContentTypeMapping'),
|
|
1106
|
-
pathsByContentType: z
|
|
1107
|
-
.record(z.string(), z.object({ path: z.string() }))
|
|
1108
|
-
.superRefine((paths, ctx) => {
|
|
1109
|
-
const variableId = ctx.path[ctx.path.length - 2];
|
|
1110
|
-
if (Object.keys(paths).length > MAX_ALLOWED_PATHS) {
|
|
1111
|
-
ctx.addIssue({
|
|
1112
|
-
code: z.ZodIssueCode.custom,
|
|
1113
|
-
message: `Too many paths defined for variable mapping with id "${variableId}", maximum allowed is ${MAX_ALLOWED_PATHS}`,
|
|
1114
|
-
});
|
|
1115
|
-
}
|
|
1116
|
-
}),
|
|
1098
|
+
pathsByContentType: z.record(z.string(), z.object({ path: z.string() })),
|
|
1117
1099
|
});
|
|
1118
1100
|
const PassToNodeSchema = z
|
|
1119
1101
|
.object({
|
|
@@ -1137,10 +1119,7 @@ const ParameterDefinitionSchema = z.object({
|
|
|
1137
1119
|
})
|
|
1138
1120
|
.optional(),
|
|
1139
1121
|
contentTypes: z.array(z.string()).min(1),
|
|
1140
|
-
passToNodes: z
|
|
1141
|
-
.array(PassToNodeSchema)
|
|
1142
|
-
.max(1, 'At most one "passToNodes" element is allowed per parameter definition.')
|
|
1143
|
-
.optional(), // we might change this to be empty array for native parameter definitions, that's why we don't use .length(1)
|
|
1122
|
+
passToNodes: z.array(PassToNodeSchema).optional(),
|
|
1144
1123
|
});
|
|
1145
1124
|
const ParameterDefinitionsSchema = z.record(propertyKeySchema, ParameterDefinitionSchema);
|
|
1146
1125
|
const VariableMappingsSchema = z.record(propertyKeySchema, VariableMappingSchema);
|
|
@@ -1161,108 +1140,14 @@ const ComponentSettingsSchema = z
|
|
|
1161
1140
|
category: z.string().max(50, 'Category must contain at most 50 characters').optional(),
|
|
1162
1141
|
prebindingDefinitions: z.array(PrebindingDefinitionSchema).length(1).optional(),
|
|
1163
1142
|
})
|
|
1164
|
-
.strict()
|
|
1165
|
-
|
|
1166
|
-
const { variableDefinitions, prebindingDefinitions } = componentSettings;
|
|
1167
|
-
if (!prebindingDefinitions || prebindingDefinitions.length === 0) {
|
|
1168
|
-
return;
|
|
1169
|
-
}
|
|
1170
|
-
const { parameterDefinitions, variableMappings, allowedVariableOverrides } = prebindingDefinitions[0];
|
|
1171
|
-
validateAtMostOneNativeParameterDefinition(parameterDefinitions, ctx);
|
|
1172
|
-
validateNoOverlapBetweenMappingAndOverrides(variableMappings, allowedVariableOverrides, ctx);
|
|
1173
|
-
validateMappingsAgainstVariableDefinitions(variableMappings, allowedVariableOverrides, variableDefinitions, ctx);
|
|
1174
|
-
validateMappingsAgainstParameterDefinitions(variableMappings, parameterDefinitions, ctx);
|
|
1175
|
-
});
|
|
1176
|
-
z
|
|
1177
|
-
.object({
|
|
1143
|
+
.strict();
|
|
1144
|
+
z.object({
|
|
1178
1145
|
componentTree: localeWrapper(ComponentTreeSchema),
|
|
1179
1146
|
dataSource: localeWrapper(DataSourceSchema),
|
|
1180
1147
|
unboundValues: localeWrapper(UnboundValuesSchema),
|
|
1181
1148
|
usedComponents: localeWrapper(UsedComponentsSchema).optional(),
|
|
1182
1149
|
componentSettings: localeWrapper(ComponentSettingsSchema),
|
|
1183
|
-
})
|
|
1184
|
-
.superRefine((patternFields, ctx) => {
|
|
1185
|
-
const { componentTree, componentSettings } = patternFields;
|
|
1186
|
-
// values at this point are wrapped under locale code
|
|
1187
|
-
const nonLocalisedComponentTree = Object.values(componentTree)[0];
|
|
1188
|
-
const nonLocalisedComponentSettings = Object.values(componentSettings)[0];
|
|
1189
|
-
if (!nonLocalisedComponentSettings || !nonLocalisedComponentTree) {
|
|
1190
|
-
return;
|
|
1191
|
-
}
|
|
1192
|
-
validatePassToNodes(nonLocalisedComponentTree.children || [], nonLocalisedComponentSettings || {}, ctx);
|
|
1193
1150
|
});
|
|
1194
|
-
const validateAtMostOneNativeParameterDefinition = (parameterDefinitions, ctx) => {
|
|
1195
|
-
const nativeParamDefinitions = Object.values(parameterDefinitions).filter((paramDefinition) => !(paramDefinition.passToNodes && paramDefinition.passToNodes.length > 0));
|
|
1196
|
-
if (nativeParamDefinitions.length > 1) {
|
|
1197
|
-
ctx.addIssue({
|
|
1198
|
-
code: z.ZodIssueCode.custom,
|
|
1199
|
-
message: `Only one native parameter definition (parameter definition without passToNodes) is allowed per prebinding definition.`,
|
|
1200
|
-
});
|
|
1201
|
-
}
|
|
1202
|
-
};
|
|
1203
|
-
const validateNoOverlapBetweenMappingAndOverrides = (variableMappings, allowedVariableOverrides, ctx) => {
|
|
1204
|
-
const variableMappingKeys = Object.keys(variableMappings || {});
|
|
1205
|
-
const overridesSet = new Set(allowedVariableOverrides || []);
|
|
1206
|
-
const overlap = variableMappingKeys.filter((key) => overridesSet.has(key));
|
|
1207
|
-
if (overlap.length > 0) {
|
|
1208
|
-
ctx.addIssue({
|
|
1209
|
-
code: z.ZodIssueCode.custom,
|
|
1210
|
-
message: `Found both variable mapping and allowed override for the following keys: ${overlap.map((key) => `"${key}"`).join(', ')}.`,
|
|
1211
|
-
});
|
|
1212
|
-
}
|
|
1213
|
-
};
|
|
1214
|
-
const validateMappingsAgainstVariableDefinitions = (variableMappings, allowedVariableOverrides, variableDefinitions, ctx) => {
|
|
1215
|
-
const nonDesignVariableDefinitionKeys = Object.entries(variableDefinitions)
|
|
1216
|
-
.filter(([_, def]) => def.group !== 'style')
|
|
1217
|
-
.map(([key]) => key);
|
|
1218
|
-
const variableMappingKeys = Object.keys(variableMappings || {});
|
|
1219
|
-
const allKeys = [...variableMappingKeys, ...(allowedVariableOverrides || [])];
|
|
1220
|
-
const invalidMappings = allKeys.filter((key) => !nonDesignVariableDefinitionKeys.includes(key));
|
|
1221
|
-
if (invalidMappings.length > 0) {
|
|
1222
|
-
ctx.addIssue({
|
|
1223
|
-
code: z.ZodIssueCode.custom,
|
|
1224
|
-
message: `The following variable mappings or overrides are missing from the variable definitions: ${invalidMappings.map((key) => `"${key}"`).join(', ')}.`,
|
|
1225
|
-
});
|
|
1226
|
-
}
|
|
1227
|
-
};
|
|
1228
|
-
const validateMappingsAgainstParameterDefinitions = (variableMappings, parameterDefinitions, ctx) => {
|
|
1229
|
-
const parameterDefinitionKeys = Object.keys(parameterDefinitions || {});
|
|
1230
|
-
for (const [mappingKey, mappingValue] of Object.entries(variableMappings || {})) {
|
|
1231
|
-
if (!parameterDefinitionKeys.includes(mappingValue.parameterId)) {
|
|
1232
|
-
ctx.addIssue({
|
|
1233
|
-
code: z.ZodIssueCode.custom,
|
|
1234
|
-
message: `The variable mapping with id "${mappingKey}" references a non-existing parameterId "${mappingValue.parameterId}".`,
|
|
1235
|
-
});
|
|
1236
|
-
}
|
|
1237
|
-
}
|
|
1238
|
-
};
|
|
1239
|
-
const validatePassToNodes = (rootChildren, componentSettings, ctx) => {
|
|
1240
|
-
if (!componentSettings.prebindingDefinitions ||
|
|
1241
|
-
componentSettings.prebindingDefinitions.length === 0) {
|
|
1242
|
-
return;
|
|
1243
|
-
}
|
|
1244
|
-
const { parameterDefinitions } = componentSettings.prebindingDefinitions[0];
|
|
1245
|
-
let nodeIds = new Set();
|
|
1246
|
-
for (const paramDef of Object.values(parameterDefinitions || {})) {
|
|
1247
|
-
paramDef.passToNodes?.forEach((n) => nodeIds.add(n.nodeId));
|
|
1248
|
-
}
|
|
1249
|
-
treeVisit$1(rootChildren, (node) => {
|
|
1250
|
-
if (!node.id)
|
|
1251
|
-
return;
|
|
1252
|
-
if (nodeIds.has(node.id)) {
|
|
1253
|
-
nodeIds.delete(node.id);
|
|
1254
|
-
}
|
|
1255
|
-
});
|
|
1256
|
-
if (nodeIds.size > 0) {
|
|
1257
|
-
const stringifiedNodeIds = Array.from(nodeIds)
|
|
1258
|
-
.map((id) => `"${id}"`)
|
|
1259
|
-
.join(', ');
|
|
1260
|
-
ctx.addIssue({
|
|
1261
|
-
code: z.ZodIssueCode.custom,
|
|
1262
|
-
message: `The following node IDs referenced in passToNodes are not present in the component tree: ${stringifiedNodeIds}.`,
|
|
1263
|
-
});
|
|
1264
|
-
}
|
|
1265
|
-
};
|
|
1266
1151
|
|
|
1267
1152
|
z
|
|
1268
1153
|
.object({
|
|
@@ -1521,42 +1406,11 @@ const validateBreakpointsDefinition = (breakpoints) => {
|
|
|
1521
1406
|
return { success: true };
|
|
1522
1407
|
};
|
|
1523
1408
|
|
|
1524
|
-
|
|
1409
|
+
let breakpointsRegistry = [];
|
|
1525
1410
|
/**
|
|
1526
|
-
*
|
|
1527
|
-
*
|
|
1528
|
-
*
|
|
1529
|
-
* - query: a media query string that defines when this breakpoint is active
|
|
1530
|
-
* - previewSize: an optional fixed preview size to be used in the Studio editor when selecting this breakpoint
|
|
1531
|
-
* - displayName: the name to be displayed in the Studio editor for this breakpoint
|
|
1532
|
-
* - displayIcon: an optional icon to be displayed in the Studio editor for this breakpoint
|
|
1533
|
-
*
|
|
1534
|
-
* The first breakpoint must use a wildcard query (`*`) to match all sizes.
|
|
1535
|
-
*
|
|
1536
|
-
* Every subsequent breakpoint inherits the designs of the previous ones by default.
|
|
1537
|
-
*
|
|
1538
|
-
* The order of breakpoints must be either:
|
|
1539
|
-
* - desktop first: from largest to smallest, using `<` operators
|
|
1540
|
-
* - mobile first: from smallest to largest, using `>` operators
|
|
1541
|
-
*
|
|
1542
|
-
* @note changing breakpoints after you have created experiences may break those experiences
|
|
1543
|
-
* @example
|
|
1544
|
-
* defineBreakpoints([{
|
|
1545
|
-
* id: 'desktop',
|
|
1546
|
-
* query: '*',
|
|
1547
|
-
* displayName: 'Desktop',
|
|
1548
|
-
* displayIcon: 'desktop',
|
|
1549
|
-
* }, {
|
|
1550
|
-
* id: 'tablet',
|
|
1551
|
-
* query: '<992px',
|
|
1552
|
-
* displayName: 'Tablet',
|
|
1553
|
-
* displayIcon: 'tablet',
|
|
1554
|
-
* }, {
|
|
1555
|
-
* id: 'mobile',
|
|
1556
|
-
* query: '<576px',
|
|
1557
|
-
* displayName: 'Mobile',
|
|
1558
|
-
* displayIcon: 'mobile',
|
|
1559
|
-
* }]);
|
|
1411
|
+
* Register custom breakpoints
|
|
1412
|
+
* @param breakpoints - [{[key:string]: string}]
|
|
1413
|
+
* @returns void
|
|
1560
1414
|
*/
|
|
1561
1415
|
const defineBreakpoints = (breakpoints) => {
|
|
1562
1416
|
Object.assign(breakpointsRegistry, breakpoints);
|
|
@@ -1569,6 +1423,12 @@ const runBreakpointsValidation = () => {
|
|
|
1569
1423
|
throw new Error(`Invalid breakpoints definition. Failed with errors: \n${JSON.stringify(validation.errors, null, 2)}`);
|
|
1570
1424
|
}
|
|
1571
1425
|
};
|
|
1426
|
+
// Used in the tests to get a breakpoint registration
|
|
1427
|
+
const getBreakpointRegistration = (id) => breakpointsRegistry.find((breakpoint) => breakpoint.id === id);
|
|
1428
|
+
// Used in the tests to reset the registry
|
|
1429
|
+
const resetBreakpointsRegistry = () => {
|
|
1430
|
+
breakpointsRegistry = [];
|
|
1431
|
+
};
|
|
1572
1432
|
|
|
1573
1433
|
const sdkOptionsRegistry = {};
|
|
1574
1434
|
/**
|
|
@@ -2175,9 +2035,7 @@ const stylesToRemove = CF_STYLE_ATTRIBUTES.filter((style) => !stylesToKeep.inclu
|
|
|
2175
2035
|
// cfWrapColumns & cfWrapColumnsCount are no real style attributes as they are handled on the editor side
|
|
2176
2036
|
const propsToRemove = ['cfSsrClassName', 'cfWrapColumns', 'cfWrapColumnsCount'];
|
|
2177
2037
|
const sanitizeNodeProps = (nodeProps) => {
|
|
2178
|
-
|
|
2179
|
-
const sanitizedProps = Object.fromEntries(Object.entries(nodeProps).filter(([key]) => !keysToRemove.includes(key)));
|
|
2180
|
-
return sanitizedProps;
|
|
2038
|
+
return omit(nodeProps, stylesToRemove, propsToRemove);
|
|
2181
2039
|
};
|
|
2182
2040
|
|
|
2183
2041
|
/** Turn the visibility value into a style object that can be used for inline styles in React */
|
|
@@ -3308,7 +3166,7 @@ function getArrayValue(entryOrAsset, path, entityStore) {
|
|
|
3308
3166
|
}
|
|
3309
3167
|
const fieldName = path.split('/').slice(2, -1);
|
|
3310
3168
|
const arrayValue = get(entryOrAsset, fieldName);
|
|
3311
|
-
if (!
|
|
3169
|
+
if (!isArray(arrayValue)) {
|
|
3312
3170
|
debug.warn(`[experiences-core::getArrayValue] A field '${fieldName}' of an entity was bound to an Array variable. Expected value of that field to be an array, but got: ${JSON.stringify(arrayValue)}`, { entity: entryOrAsset });
|
|
3313
3171
|
return;
|
|
3314
3172
|
}
|
|
@@ -3465,19 +3323,6 @@ function getTargetValueInPixels(targetWidthObject) {
|
|
|
3465
3323
|
return targetWidthObject.value;
|
|
3466
3324
|
}
|
|
3467
3325
|
}
|
|
3468
|
-
/**
|
|
3469
|
-
* Creates a component definition for an assembly. As all assemblies use the same definition in the SDK,
|
|
3470
|
-
* all should be registered via this function.
|
|
3471
|
-
*/
|
|
3472
|
-
const createAssemblyDefinition = (definitionId) => {
|
|
3473
|
-
return {
|
|
3474
|
-
id: definitionId,
|
|
3475
|
-
name: 'Component',
|
|
3476
|
-
variables: {},
|
|
3477
|
-
children: true,
|
|
3478
|
-
category: ASSEMBLY_DEFAULT_CATEGORY,
|
|
3479
|
-
};
|
|
3480
|
-
};
|
|
3481
3326
|
|
|
3482
3327
|
class ParseError extends Error {
|
|
3483
3328
|
constructor(message) {
|
|
@@ -3683,118 +3528,6 @@ const splitDirectAndSlotChildren = (allChildNodes, componentDefinition) => {
|
|
|
3683
3528
|
return { slotNodesMap, directChildNodes };
|
|
3684
3529
|
};
|
|
3685
3530
|
|
|
3686
|
-
const flattenNestedPatterns = (fetchedPatterns) => {
|
|
3687
|
-
const patternsById = {};
|
|
3688
|
-
const queue = [...fetchedPatterns];
|
|
3689
|
-
while (queue.length) {
|
|
3690
|
-
const pattern = queue.shift();
|
|
3691
|
-
if (!pattern) {
|
|
3692
|
-
continue;
|
|
3693
|
-
}
|
|
3694
|
-
if (patternsById[pattern.sys.id]) {
|
|
3695
|
-
continue;
|
|
3696
|
-
}
|
|
3697
|
-
patternsById[pattern.sys.id] = pattern;
|
|
3698
|
-
if (!Array.isArray(pattern.fields.usedComponents) || !pattern.fields.usedComponents.length) {
|
|
3699
|
-
continue;
|
|
3700
|
-
}
|
|
3701
|
-
for (const nestedPattern of pattern.fields.usedComponents) {
|
|
3702
|
-
if (!isLink(nestedPattern)) {
|
|
3703
|
-
queue.push(nestedPattern);
|
|
3704
|
-
}
|
|
3705
|
-
}
|
|
3706
|
-
}
|
|
3707
|
-
return Object.values(patternsById);
|
|
3708
|
-
};
|
|
3709
|
-
/**
|
|
3710
|
-
* Given a list of patterns, extract the prebinding data into a more digestable format indexed by the pattern entry id
|
|
3711
|
-
* @param patterns a list of pattern entries
|
|
3712
|
-
* @returns a map of pattern entry ids to their prebinding data
|
|
3713
|
-
*/
|
|
3714
|
-
const extractPrebindingDataByPatternId = (patterns) => {
|
|
3715
|
-
const prebindingDataByPatternId = {};
|
|
3716
|
-
for (const pattern of patterns) {
|
|
3717
|
-
const patternId = pattern.sys.id;
|
|
3718
|
-
const [prebindingDefinition] = pattern.fields.componentSettings?.prebindingDefinitions ?? [];
|
|
3719
|
-
if (!prebindingDefinition)
|
|
3720
|
-
continue;
|
|
3721
|
-
const [nativeParameterId] = Object.entries(prebindingDefinition.parameterDefinitions ?? {}).find(([, value]) => value.passToNodes === undefined) ?? [];
|
|
3722
|
-
const prebindingData = {
|
|
3723
|
-
prebindingDefinitionId: prebindingDefinition.id,
|
|
3724
|
-
parameterIds: Object.keys(prebindingDefinition.parameterDefinitions),
|
|
3725
|
-
nativeParameterId,
|
|
3726
|
-
parameterDefinitions: prebindingDefinition.parameterDefinitions,
|
|
3727
|
-
variableMappings: prebindingDefinition.variableMappings,
|
|
3728
|
-
};
|
|
3729
|
-
prebindingDataByPatternId[patternId] = prebindingData;
|
|
3730
|
-
}
|
|
3731
|
-
return prebindingDataByPatternId;
|
|
3732
|
-
};
|
|
3733
|
-
const generateDefaultDataSourceForPrebindingDefinition = (prebindingDefinitions = []) => {
|
|
3734
|
-
if (!prebindingDefinitions ||
|
|
3735
|
-
!Array.isArray(prebindingDefinitions) ||
|
|
3736
|
-
!prebindingDefinitions.length) {
|
|
3737
|
-
return { dataSource: {}, parameters: {} };
|
|
3738
|
-
}
|
|
3739
|
-
const prebindingDefinition = prebindingDefinitions[0];
|
|
3740
|
-
const dataSource = {};
|
|
3741
|
-
const parameters = {};
|
|
3742
|
-
for (const [parameterId, parameterDefinition] of Object.entries(prebindingDefinition.parameterDefinitions ?? {})) {
|
|
3743
|
-
if (parameterDefinition.defaultSource && isLink(parameterDefinition.defaultSource.link)) {
|
|
3744
|
-
const dataSourceKey = generateRandomId(7);
|
|
3745
|
-
dataSource[dataSourceKey] = parameterDefinition.defaultSource.link;
|
|
3746
|
-
parameters[parameterId] = {
|
|
3747
|
-
type: 'BoundValue',
|
|
3748
|
-
path: `/${dataSourceKey}`,
|
|
3749
|
-
};
|
|
3750
|
-
}
|
|
3751
|
-
}
|
|
3752
|
-
return {
|
|
3753
|
-
dataSource,
|
|
3754
|
-
parameters,
|
|
3755
|
-
};
|
|
3756
|
-
};
|
|
3757
|
-
function getTargetPatternMappingsForParameter({ fetchedPatterns, prebindingDataByPatternId, patternNodeDefinitionId, parameterId, }) {
|
|
3758
|
-
const patternPrebindingData = prebindingDataByPatternId[patternNodeDefinitionId];
|
|
3759
|
-
if (!patternPrebindingData)
|
|
3760
|
-
return undefined;
|
|
3761
|
-
if (patternPrebindingData.parameterIds.includes(parameterId)) {
|
|
3762
|
-
if (patternPrebindingData.nativeParameterId === parameterId) {
|
|
3763
|
-
if (!patternPrebindingData.variableMappings)
|
|
3764
|
-
return undefined;
|
|
3765
|
-
return Object.fromEntries(Object.entries(patternPrebindingData.variableMappings).filter(([, mapping]) => mapping.parameterId === parameterId));
|
|
3766
|
-
}
|
|
3767
|
-
else {
|
|
3768
|
-
const parameterDefinition = patternPrebindingData.parameterDefinitions[parameterId];
|
|
3769
|
-
if (!parameterDefinition || !parameterDefinition.passToNodes)
|
|
3770
|
-
return undefined;
|
|
3771
|
-
const patternEntry = fetchedPatterns.find((entry) => entry.sys.id === patternNodeDefinitionId);
|
|
3772
|
-
if (!patternEntry)
|
|
3773
|
-
return undefined;
|
|
3774
|
-
let nestedPatternNode;
|
|
3775
|
-
treeVisit({
|
|
3776
|
-
definitionId: 'root',
|
|
3777
|
-
parameters: {},
|
|
3778
|
-
children: patternEntry.fields.componentTree.children,
|
|
3779
|
-
}, (node) => {
|
|
3780
|
-
if (node.id === parameterDefinition.passToNodes?.[0].nodeId) {
|
|
3781
|
-
nestedPatternNode = node;
|
|
3782
|
-
}
|
|
3783
|
-
return undefined;
|
|
3784
|
-
});
|
|
3785
|
-
if (!nestedPatternNode) {
|
|
3786
|
-
return undefined;
|
|
3787
|
-
}
|
|
3788
|
-
return getTargetPatternMappingsForParameter({
|
|
3789
|
-
fetchedPatterns,
|
|
3790
|
-
prebindingDataByPatternId,
|
|
3791
|
-
patternNodeDefinitionId: nestedPatternNode.definitionId,
|
|
3792
|
-
parameterId: parameterDefinition.passToNodes?.[0].parameterId,
|
|
3793
|
-
});
|
|
3794
|
-
}
|
|
3795
|
-
}
|
|
3796
|
-
}
|
|
3797
|
-
|
|
3798
3531
|
const sendMessage = (eventType, data) => {
|
|
3799
3532
|
if (typeof window === 'undefined') {
|
|
3800
3533
|
return;
|
|
@@ -4621,7 +4354,7 @@ function gatherDeepReferencesFromExperienceEntry(experienceEntry) {
|
|
|
4621
4354
|
}, (node) => {
|
|
4622
4355
|
if (!node.variables)
|
|
4623
4356
|
return;
|
|
4624
|
-
for (const variableMapping of Object.
|
|
4357
|
+
for (const [, variableMapping] of Object.entries(node.variables)) {
|
|
4625
4358
|
if (variableMapping.type !== 'BoundValue')
|
|
4626
4359
|
continue;
|
|
4627
4360
|
if (!isDeepPath(variableMapping.path))
|
|
@@ -4634,99 +4367,6 @@ function gatherDeepReferencesFromExperienceEntry(experienceEntry) {
|
|
|
4634
4367
|
});
|
|
4635
4368
|
return deepReferences;
|
|
4636
4369
|
}
|
|
4637
|
-
function gatherDeepPrebindingReferencesFromExperienceEntry({ experienceEntry, fetchedPatterns, prebindingDataByPatternId, fetchedLevel1Entries, }) {
|
|
4638
|
-
const deepPrebindingReferences = [];
|
|
4639
|
-
const dataSource = experienceEntry.fields.dataSource;
|
|
4640
|
-
const { children } = experienceEntry.fields.componentTree;
|
|
4641
|
-
treeVisit({
|
|
4642
|
-
definitionId: 'root',
|
|
4643
|
-
parameters: {},
|
|
4644
|
-
children,
|
|
4645
|
-
}, (node) => {
|
|
4646
|
-
if (!node.parameters)
|
|
4647
|
-
return;
|
|
4648
|
-
for (const [parameterId, parameterValue] of Object.entries(node.parameters)) {
|
|
4649
|
-
const dataSourceKey = parameterValue.path.split('/')[1];
|
|
4650
|
-
const headEntryLink = dataSource[dataSourceKey];
|
|
4651
|
-
if (!headEntryLink)
|
|
4652
|
-
continue;
|
|
4653
|
-
if (headEntryLink.sys.linkType !== 'Entry')
|
|
4654
|
-
continue;
|
|
4655
|
-
const headEntry = fetchedLevel1Entries.find((entry) => entry.sys.id === headEntryLink.sys.id);
|
|
4656
|
-
if (!headEntry)
|
|
4657
|
-
continue;
|
|
4658
|
-
const headEntryContentTypeId = headEntry.sys.contentType.sys.id;
|
|
4659
|
-
// if experience, we don't have any hoisted data on the given experienceEntry
|
|
4660
|
-
// and we have to lookup the pattern instead
|
|
4661
|
-
const variableMappings = getTargetPatternMappingsForParameter({
|
|
4662
|
-
fetchedPatterns,
|
|
4663
|
-
prebindingDataByPatternId,
|
|
4664
|
-
patternNodeDefinitionId: node.definitionId,
|
|
4665
|
-
parameterId,
|
|
4666
|
-
});
|
|
4667
|
-
if (!variableMappings)
|
|
4668
|
-
continue;
|
|
4669
|
-
for (const mappingData of Object.values(variableMappings)) {
|
|
4670
|
-
const targetMapping = mappingData.pathsByContentType[headEntryContentTypeId];
|
|
4671
|
-
if (!targetMapping)
|
|
4672
|
-
continue;
|
|
4673
|
-
// mapping doesn't start with /uuid, but instead starts with /fields
|
|
4674
|
-
// so we add /uuid to make it match the binding path format
|
|
4675
|
-
const path = `/${dataSourceKey}${targetMapping.path}`;
|
|
4676
|
-
if (!isDeepPath(path))
|
|
4677
|
-
continue;
|
|
4678
|
-
deepPrebindingReferences.push(DeepReference.from({
|
|
4679
|
-
path,
|
|
4680
|
-
dataSource,
|
|
4681
|
-
}));
|
|
4682
|
-
}
|
|
4683
|
-
}
|
|
4684
|
-
});
|
|
4685
|
-
return deepPrebindingReferences;
|
|
4686
|
-
}
|
|
4687
|
-
function gatherDeepPrebindingReferencesFromPatternEntry({ patternEntry, fetchedPatterns, prebindingDataByPatternId, fetchedLevel1Entries, }) {
|
|
4688
|
-
const deepPrebindingReferences = [];
|
|
4689
|
-
// patterns can't have parameters in their CDA/CMA JSON, so we can generate random ids here
|
|
4690
|
-
const { dataSource, parameters } = generateDefaultDataSourceForPrebindingDefinition(patternEntry.fields.componentSettings?.prebindingDefinitions);
|
|
4691
|
-
for (const [parameterId, parameterValue] of Object.entries(parameters)) {
|
|
4692
|
-
const dataSourceKey = parameterValue.path.split('/')[1];
|
|
4693
|
-
const headEntryLink = dataSource[dataSourceKey];
|
|
4694
|
-
if (!headEntryLink)
|
|
4695
|
-
continue;
|
|
4696
|
-
if (headEntryLink.sys.linkType !== 'Entry')
|
|
4697
|
-
continue;
|
|
4698
|
-
const headEntry = fetchedLevel1Entries.find((entry) => entry.sys.id === headEntryLink.sys.id);
|
|
4699
|
-
if (!headEntry)
|
|
4700
|
-
continue;
|
|
4701
|
-
const headEntryContentTypeId = headEntry.sys.contentType.sys.id;
|
|
4702
|
-
const variableMappings = getTargetPatternMappingsForParameter({
|
|
4703
|
-
fetchedPatterns,
|
|
4704
|
-
prebindingDataByPatternId,
|
|
4705
|
-
patternNodeDefinitionId: patternEntry.sys.id,
|
|
4706
|
-
parameterId,
|
|
4707
|
-
});
|
|
4708
|
-
if (!variableMappings)
|
|
4709
|
-
continue;
|
|
4710
|
-
for (const mappingData of Object.values(variableMappings)) {
|
|
4711
|
-
const targetMapping = mappingData.pathsByContentType[headEntryContentTypeId];
|
|
4712
|
-
if (!targetMapping)
|
|
4713
|
-
continue;
|
|
4714
|
-
// mapping doesn't start with /uuid, but instead starts with /fields
|
|
4715
|
-
// so we add /uuid to make it match the binding path format
|
|
4716
|
-
const path = `/${dataSourceKey}${targetMapping.path}`;
|
|
4717
|
-
if (!isDeepPath(path))
|
|
4718
|
-
continue;
|
|
4719
|
-
deepPrebindingReferences.push(DeepReference.from({
|
|
4720
|
-
path,
|
|
4721
|
-
dataSource,
|
|
4722
|
-
}));
|
|
4723
|
-
}
|
|
4724
|
-
}
|
|
4725
|
-
return deepPrebindingReferences;
|
|
4726
|
-
}
|
|
4727
|
-
/**
|
|
4728
|
-
* used in editor mode. for delivery mode see `gatherDeepReferencesFromExperienceEntry`
|
|
4729
|
-
*/
|
|
4730
4370
|
function gatherDeepReferencesFromTree(startingNode, dataSource, getEntityFromLink) {
|
|
4731
4371
|
const deepReferences = [];
|
|
4732
4372
|
treeVisit(startingNode, (node) => {
|
|
@@ -4848,8 +4488,8 @@ const fetchAllEntries = async ({ client, ids, locale, skip = 0, limit = 100, res
|
|
|
4848
4488
|
responseIncludes,
|
|
4849
4489
|
});
|
|
4850
4490
|
}
|
|
4851
|
-
const dedupedEntries =
|
|
4852
|
-
const dedupedAssets =
|
|
4491
|
+
const dedupedEntries = uniqBy(responseIncludes?.Entry, (entry) => entry.sys.id);
|
|
4492
|
+
const dedupedAssets = uniqBy(responseIncludes?.Asset, (asset) => asset.sys.id);
|
|
4853
4493
|
return {
|
|
4854
4494
|
items: responseItems,
|
|
4855
4495
|
includes: {
|
|
@@ -4933,6 +4573,7 @@ const fetchReferencedEntities = async ({ client, experienceEntry, locale, }) =>
|
|
|
4933
4573
|
if (!isExperienceEntry(experienceEntry)) {
|
|
4934
4574
|
throw new Error('Failed to fetch experience entities. Provided "experienceEntry" does not match experience entry schema');
|
|
4935
4575
|
}
|
|
4576
|
+
const deepReferences = gatherDeepReferencesFromExperienceEntry(experienceEntry);
|
|
4936
4577
|
const entryIds = new Set();
|
|
4937
4578
|
const assetIds = new Set();
|
|
4938
4579
|
for (const dataBinding of Object.values(experienceEntry.fields.dataSource)) {
|
|
@@ -4950,52 +4591,12 @@ const fetchReferencedEntities = async ({ client, experienceEntry, locale, }) =>
|
|
|
4950
4591
|
fetchAllEntries({ client, ids: [...entryIds], locale }),
|
|
4951
4592
|
fetchAllAssets({ client, ids: [...assetIds], locale }),
|
|
4952
4593
|
]);
|
|
4953
|
-
const
|
|
4954
|
-
const isRenderingExperience = Boolean(!experienceEntry.fields.componentSettings);
|
|
4955
|
-
const deepReferences = gatherDeepReferencesFromExperienceEntry(experienceEntry);
|
|
4956
|
-
// If we are previewing a pattern, we want to include the entry itself as well
|
|
4957
|
-
const fetchedPatterns = (isRenderingExperience ? usedPatterns : [...usedPatterns, experienceEntry]);
|
|
4958
|
-
const allFetchedPatterns = flattenNestedPatterns(fetchedPatterns);
|
|
4959
|
-
const prebindingDataByPatternId = extractPrebindingDataByPatternId(allFetchedPatterns);
|
|
4960
|
-
// Patterns do not have dataSource stored in their dataSource field, so head entities won't be there and we need to fetch them
|
|
4961
|
-
if (!isRenderingExperience) {
|
|
4962
|
-
const { dataSource } = generateDefaultDataSourceForPrebindingDefinition(experienceEntry.fields.componentSettings?.prebindingDefinitions);
|
|
4963
|
-
if (Object.keys(dataSource).length) {
|
|
4964
|
-
const prebindingEntriesResponse = await fetchAllEntries({
|
|
4965
|
-
client,
|
|
4966
|
-
ids: Object.values(dataSource).map((link) => link.sys.id),
|
|
4967
|
-
locale,
|
|
4968
|
-
});
|
|
4969
|
-
entriesResponse.items.push(...prebindingEntriesResponse.items);
|
|
4970
|
-
entriesResponse.includes.Asset.push(...(prebindingEntriesResponse.includes?.Asset ?? []));
|
|
4971
|
-
entriesResponse.includes.Entry.push(...(prebindingEntriesResponse.includes?.Entry ?? []));
|
|
4972
|
-
}
|
|
4973
|
-
}
|
|
4974
|
-
// normally, for experience entry, there should be no need to call this method, as `includes=2` will have them resolved
|
|
4975
|
-
// because the entries used for pre-binding are stored in both - the layout of the experience, as well as the dataSource field
|
|
4976
|
-
const deepPrebindingReferences = isRenderingExperience
|
|
4977
|
-
? gatherDeepPrebindingReferencesFromExperienceEntry({
|
|
4978
|
-
experienceEntry: experienceEntry,
|
|
4979
|
-
fetchedPatterns: allFetchedPatterns,
|
|
4980
|
-
prebindingDataByPatternId,
|
|
4981
|
-
fetchedLevel1Entries: entriesResponse.items,
|
|
4982
|
-
})
|
|
4983
|
-
: // however, for patterns, we have to do it by hand, because a pattern entry doesn't save the pre-binding data neither in the
|
|
4984
|
-
// layout nor in the dataSource field.
|
|
4985
|
-
// for consistency, as well as to be future safe from the change to "includes=2", I added methods for both
|
|
4986
|
-
gatherDeepPrebindingReferencesFromPatternEntry({
|
|
4987
|
-
patternEntry: experienceEntry,
|
|
4988
|
-
fetchedPatterns: allFetchedPatterns,
|
|
4989
|
-
prebindingDataByPatternId,
|
|
4990
|
-
fetchedLevel1Entries: entriesResponse.items,
|
|
4991
|
-
});
|
|
4992
|
-
const allDeepReferences = [...deepReferences, ...deepPrebindingReferences];
|
|
4993
|
-
const { autoFetchedReferentAssets, autoFetchedReferentEntries } = gatherAutoFetchedReferentsFromIncludes(allDeepReferences, entriesResponse);
|
|
4594
|
+
const { autoFetchedReferentAssets, autoFetchedReferentEntries } = gatherAutoFetchedReferentsFromIncludes(deepReferences, entriesResponse);
|
|
4994
4595
|
// Using client getEntries resolves all linked entry references, so we do not need to resolve entries in usedComponents
|
|
4995
4596
|
const allResolvedEntries = [
|
|
4996
4597
|
...(entriesResponse?.items ?? []),
|
|
4997
4598
|
...(entriesResponse.includes?.Entry ?? []),
|
|
4998
|
-
...(
|
|
4599
|
+
...(experienceEntry.fields.usedComponents || []),
|
|
4999
4600
|
...autoFetchedReferentEntries,
|
|
5000
4601
|
];
|
|
5001
4602
|
const allResolvedAssets = [
|
|
@@ -5004,14 +4605,8 @@ const fetchReferencedEntities = async ({ client, experienceEntry, locale, }) =>
|
|
|
5004
4605
|
...autoFetchedReferentAssets,
|
|
5005
4606
|
];
|
|
5006
4607
|
return {
|
|
5007
|
-
|
|
5008
|
-
|
|
5009
|
-
entries: [
|
|
5010
|
-
...new Map(allResolvedEntries.map((entry) => [entry.sys.id, entry])).values(),
|
|
5011
|
-
],
|
|
5012
|
-
assets: [
|
|
5013
|
-
...new Map(allResolvedAssets.map((asset) => [asset.sys.id, asset])).values(),
|
|
5014
|
-
],
|
|
4608
|
+
entries: allResolvedEntries,
|
|
4609
|
+
assets: allResolvedAssets,
|
|
5015
4610
|
};
|
|
5016
4611
|
};
|
|
5017
4612
|
|
|
@@ -5290,5 +4885,5 @@ async function fetchById({ client, experienceTypeId, id, localeCode, isEditorMod
|
|
|
5290
4885
|
}
|
|
5291
4886
|
}
|
|
5292
4887
|
|
|
5293
|
-
export { BREAKPOINTS_STRATEGY_DESKTOP_FIRST, BREAKPOINTS_STRATEGY_MOBILE_FIRST, DebugLogger, DeepReference, EditorModeEntityStore, EntityStore, EntityStoreBase, MEDIA_QUERY_REGEXP, VisualEditorMode, addLocale, addMinHeightForEmptyStructures, breakpointsRegistry, buildCfStyles, buildStyleTag, buildTemplate, builtInStyles, calculateNodeDefaultHeight, checkIsAssemblyDefinition, checkIsAssemblyEntry, checkIsAssemblyNode, columnsBuiltInStyles, containerBuiltInStyles,
|
|
4888
|
+
export { BREAKPOINTS_STRATEGY_DESKTOP_FIRST, BREAKPOINTS_STRATEGY_MOBILE_FIRST, DebugLogger, DeepReference, EditorModeEntityStore, EntityStore, EntityStoreBase, MEDIA_QUERY_REGEXP, VisualEditorMode, addLocale, addMinHeightForEmptyStructures, breakpointsRegistry, buildCfStyles, buildStyleTag, buildTemplate, builtInStyles, calculateNodeDefaultHeight, checkIsAssemblyDefinition, checkIsAssemblyEntry, checkIsAssemblyNode, columnsBuiltInStyles, containerBuiltInStyles, createExperience, debug, defineBreakpoints, defineDesignTokens, defineSdkOptions, designTokensRegistry, detachExperienceStyles, detectBreakpointsStrategy, disableDebug, dividerBuiltInStyles, doesMismatchMessageSchema, enableDebug, extractLeafLinksReferencedFromExperience, extractReferencesFromEntries, extractReferencesFromEntriesAsIds, fetchAllAssets, fetchAllEntries, fetchById, fetchBySlug, fetchExperienceEntry, fetchReferencedEntities, findOutermostCoordinates, flattenDesignTokenRegistry, gatherDeepReferencesFromExperienceEntry, gatherDeepReferencesFromTree, generateRandomId, getActiveBreakpointIndex, getBreakpointRegistration, getDataFromTree, getDesignTokenRegistration, getElementCoordinates, getFallbackBreakpointIndex, getPrebindingPathBySourceEntry, getSdkOptions, getTargetValueInPixels, getTemplateValue, getValueForBreakpoint, inMemoryEntities, inMemoryEntitiesStore, indexByBreakpoint, isArrayOfLinks, isAsset, isCfStyleAttribute, isComponentAllowedOnRoot, isContentfulComponent, isContentfulStructureComponent, isDeepPath, isDeepPrebinding, isElementHidden, isEntry, isExperienceEntry, isLink, isLinkToAsset, isLinkToEntry, isPatternComponent, isPatternEntry, isPreboundProp, isStructureWithRelativeHeight, isValidBreakpointValue, lastPathNamedSegmentEq, localizeEntity, maybePopulateDesignTokenValue, mediaQueryMatcher, mergeDesignValuesByBreakpoint, optionalBuiltInStyles, parseCSSValue, parseDataSourcePathIntoFieldset, parseDataSourcePathWithL1DeepBindings, referencesOf, resetBreakpointsRegistry, resetDesignTokenRegistry, resolveBackgroundImageBinding, resolveHyperlinkPattern, runBreakpointsValidation, sanitizeNodeProps, sdkOptionsRegistry, sectionBuiltInStyles, sendMessage, setDebugLevel, singleColumnBuiltInStyles, splitDirectAndSlotChildren, stringifyCssProperties, toCSSAttribute, toMediaQuery, transformBoundContentValue, transformVisibility, treeMap, treeVisit, tryParseMessage, uniqueById, useInMemoryEntities, validateExperienceBuilderConfig };
|
|
5294
4889
|
//# sourceMappingURL=index.js.map
|