@contentful/experiences-core 3.7.0-dev-20250917T1203-0e23897.0 → 3.7.0-dev-20250917T1515-4c340b9.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/index.js CHANGED
@@ -1052,6 +1052,25 @@ z.object({
1052
1052
  usedComponents: localeWrapper(UsedComponentsSchema).optional(),
1053
1053
  });
1054
1054
 
1055
+ function treeVisit$1(initialNode, onNode) {
1056
+ const _treeVisit = (currentNode) => {
1057
+ const children = [...currentNode.children];
1058
+ onNode(currentNode);
1059
+ for (const child of children) {
1060
+ _treeVisit(child);
1061
+ }
1062
+ };
1063
+ if (Array.isArray(initialNode)) {
1064
+ for (const node of initialNode) {
1065
+ _treeVisit(node);
1066
+ }
1067
+ }
1068
+ else {
1069
+ _treeVisit(initialNode);
1070
+ }
1071
+ }
1072
+
1073
+ const MAX_ALLOWED_PATHS = 200;
1055
1074
  const THUMBNAIL_IDS = [
1056
1075
  'columns',
1057
1076
  'columnsPlusRight',
@@ -1082,7 +1101,17 @@ const THUMBNAIL_IDS = [
1082
1101
  const VariableMappingSchema = z.object({
1083
1102
  parameterId: propertyKeySchema,
1084
1103
  type: z.literal('ContentTypeMapping'),
1085
- pathsByContentType: z.record(z.string(), z.object({ path: z.string() })),
1104
+ pathsByContentType: z
1105
+ .record(z.string(), z.object({ path: z.string() }))
1106
+ .superRefine((paths, ctx) => {
1107
+ const variableId = ctx.path[ctx.path.length - 2];
1108
+ if (Object.keys(paths).length > MAX_ALLOWED_PATHS) {
1109
+ ctx.addIssue({
1110
+ code: z.ZodIssueCode.custom,
1111
+ message: `Too many paths defined for variable mapping with id "${variableId}", maximum allowed is ${MAX_ALLOWED_PATHS}`,
1112
+ });
1113
+ }
1114
+ }),
1086
1115
  });
1087
1116
  const PassToNodeSchema = z
1088
1117
  .object({
@@ -1106,7 +1135,10 @@ const ParameterDefinitionSchema = z.object({
1106
1135
  })
1107
1136
  .optional(),
1108
1137
  contentTypes: z.array(z.string()).min(1),
1109
- passToNodes: z.array(PassToNodeSchema).optional(),
1138
+ passToNodes: z
1139
+ .array(PassToNodeSchema)
1140
+ .max(1, 'At most one "passToNodes" element is allowed per parameter definition.')
1141
+ .optional(), // we might change this to be empty array for native parameter definitions, that's why we don't use .length(1)
1110
1142
  });
1111
1143
  const ParameterDefinitionsSchema = z.record(propertyKeySchema, ParameterDefinitionSchema);
1112
1144
  const VariableMappingsSchema = z.record(propertyKeySchema, VariableMappingSchema);
@@ -1127,14 +1159,108 @@ const ComponentSettingsSchema = z
1127
1159
  category: z.string().max(50, 'Category must contain at most 50 characters').optional(),
1128
1160
  prebindingDefinitions: z.array(PrebindingDefinitionSchema).length(1).optional(),
1129
1161
  })
1130
- .strict();
1131
- z.object({
1162
+ .strict()
1163
+ .superRefine((componentSettings, ctx) => {
1164
+ const { variableDefinitions, prebindingDefinitions } = componentSettings;
1165
+ if (!prebindingDefinitions || prebindingDefinitions.length === 0) {
1166
+ return;
1167
+ }
1168
+ const { parameterDefinitions, variableMappings, allowedVariableOverrides } = prebindingDefinitions[0];
1169
+ validateAtMostOneNativeParameterDefinition(parameterDefinitions, ctx);
1170
+ validateNoOverlapBetweenMappingAndOverrides(variableMappings, allowedVariableOverrides, ctx);
1171
+ validateMappingsAgainstVariableDefinitions(variableMappings, allowedVariableOverrides, variableDefinitions, ctx);
1172
+ validateMappingsAgainstParameterDefinitions(variableMappings, parameterDefinitions, ctx);
1173
+ });
1174
+ z
1175
+ .object({
1132
1176
  componentTree: localeWrapper(ComponentTreeSchema),
1133
1177
  dataSource: localeWrapper(DataSourceSchema),
1134
1178
  unboundValues: localeWrapper(UnboundValuesSchema),
1135
1179
  usedComponents: localeWrapper(UsedComponentsSchema).optional(),
1136
1180
  componentSettings: localeWrapper(ComponentSettingsSchema),
1181
+ })
1182
+ .superRefine((patternFields, ctx) => {
1183
+ const { componentTree, componentSettings } = patternFields;
1184
+ // values at this point are wrapped under locale code
1185
+ const nonLocalisedComponentTree = Object.values(componentTree)[0];
1186
+ const nonLocalisedComponentSettings = Object.values(componentSettings)[0];
1187
+ if (!nonLocalisedComponentSettings || !nonLocalisedComponentTree) {
1188
+ return;
1189
+ }
1190
+ validatePassToNodes(nonLocalisedComponentTree.children || [], nonLocalisedComponentSettings || {}, ctx);
1137
1191
  });
1192
+ const validateAtMostOneNativeParameterDefinition = (parameterDefinitions, ctx) => {
1193
+ const nativeParamDefinitions = Object.values(parameterDefinitions).filter((paramDefinition) => !(paramDefinition.passToNodes && paramDefinition.passToNodes.length > 0));
1194
+ if (nativeParamDefinitions.length > 1) {
1195
+ ctx.addIssue({
1196
+ code: z.ZodIssueCode.custom,
1197
+ message: `Only one native parameter definition (parameter definition without passToNodes) is allowed per prebinding definition.`,
1198
+ });
1199
+ }
1200
+ };
1201
+ const validateNoOverlapBetweenMappingAndOverrides = (variableMappings, allowedVariableOverrides, ctx) => {
1202
+ const variableMappingKeys = Object.keys(variableMappings || {});
1203
+ const overridesSet = new Set(allowedVariableOverrides || []);
1204
+ const overlap = variableMappingKeys.filter((key) => overridesSet.has(key));
1205
+ if (overlap.length > 0) {
1206
+ ctx.addIssue({
1207
+ code: z.ZodIssueCode.custom,
1208
+ message: `Found both variable mapping and allowed override for the following keys: ${overlap.map((key) => `"${key}"`).join(', ')}.`,
1209
+ });
1210
+ }
1211
+ };
1212
+ const validateMappingsAgainstVariableDefinitions = (variableMappings, allowedVariableOverrides, variableDefinitions, ctx) => {
1213
+ const nonDesignVariableDefinitionKeys = Object.entries(variableDefinitions)
1214
+ .filter(([_, def]) => def.group !== 'style')
1215
+ .map(([key]) => key);
1216
+ const variableMappingKeys = Object.keys(variableMappings || {});
1217
+ const allKeys = [...variableMappingKeys, ...(allowedVariableOverrides || [])];
1218
+ const invalidMappings = allKeys.filter((key) => !nonDesignVariableDefinitionKeys.includes(key));
1219
+ if (invalidMappings.length > 0) {
1220
+ ctx.addIssue({
1221
+ code: z.ZodIssueCode.custom,
1222
+ message: `The following variable mappings or overrides are missing from the variable definitions: ${invalidMappings.map((key) => `"${key}"`).join(', ')}.`,
1223
+ });
1224
+ }
1225
+ };
1226
+ const validateMappingsAgainstParameterDefinitions = (variableMappings, parameterDefinitions, ctx) => {
1227
+ const parameterDefinitionKeys = Object.keys(parameterDefinitions || {});
1228
+ for (const [mappingKey, mappingValue] of Object.entries(variableMappings || {})) {
1229
+ if (!parameterDefinitionKeys.includes(mappingValue.parameterId)) {
1230
+ ctx.addIssue({
1231
+ code: z.ZodIssueCode.custom,
1232
+ message: `The variable mapping with id "${mappingKey}" references a non-existing parameterId "${mappingValue.parameterId}".`,
1233
+ });
1234
+ }
1235
+ }
1236
+ };
1237
+ const validatePassToNodes = (rootChildren, componentSettings, ctx) => {
1238
+ if (!componentSettings.prebindingDefinitions ||
1239
+ componentSettings.prebindingDefinitions.length === 0) {
1240
+ return;
1241
+ }
1242
+ const { parameterDefinitions } = componentSettings.prebindingDefinitions[0];
1243
+ let nodeIds = new Set();
1244
+ for (const paramDef of Object.values(parameterDefinitions || {})) {
1245
+ paramDef.passToNodes?.forEach((n) => nodeIds.add(n.nodeId));
1246
+ }
1247
+ treeVisit$1(rootChildren, (node) => {
1248
+ if (!node.id)
1249
+ return;
1250
+ if (nodeIds.has(node.id)) {
1251
+ nodeIds.delete(node.id);
1252
+ }
1253
+ });
1254
+ if (nodeIds.size > 0) {
1255
+ const stringifiedNodeIds = Array.from(nodeIds)
1256
+ .map((id) => `"${id}"`)
1257
+ .join(', ');
1258
+ ctx.addIssue({
1259
+ code: z.ZodIssueCode.custom,
1260
+ message: `The following node IDs referenced in passToNodes are not present in the component tree: ${stringifiedNodeIds}.`,
1261
+ });
1262
+ }
1263
+ };
1138
1264
 
1139
1265
  z
1140
1266
  .object({