@contentful/experiences-components-react 3.7.0-prerelease-20250917T1034-42f0486.0 → 3.7.1-beta.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 +132 -6
- package/dist/index.js.map +1 -1
- package/package.json +3 -4
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import React, { forwardRef } from 'react';
|
|
|
3
3
|
import { documentToReactComponents } from '@contentful/rich-text-react-renderer';
|
|
4
4
|
import { BLOCKS } from '@contentful/rich-text-types';
|
|
5
5
|
import { z } from 'zod';
|
|
6
|
-
import
|
|
6
|
+
import cloneDeep from 'lodash.clonedeep';
|
|
7
7
|
import 'md5';
|
|
8
8
|
import { create } from 'zustand';
|
|
9
9
|
|
|
@@ -1339,7 +1339,7 @@ const BreakpointSchema = z
|
|
|
1339
1339
|
id: propertyKeySchema,
|
|
1340
1340
|
// Can be replace with z.templateLiteral when upgrading to zod v4
|
|
1341
1341
|
query: z.string().refine((s) => BREAKPOINT_QUERY_REGEX.test(s)),
|
|
1342
|
-
previewSize: z.string(),
|
|
1342
|
+
previewSize: z.string().optional(),
|
|
1343
1343
|
displayName: z.string(),
|
|
1344
1344
|
displayIcon: z.enum(['desktop', 'tablet', 'mobile']).optional(),
|
|
1345
1345
|
})
|
|
@@ -1406,6 +1406,25 @@ z.object({
|
|
|
1406
1406
|
usedComponents: localeWrapper(UsedComponentsSchema).optional(),
|
|
1407
1407
|
});
|
|
1408
1408
|
|
|
1409
|
+
function treeVisit$1(initialNode, onNode) {
|
|
1410
|
+
const _treeVisit = (currentNode) => {
|
|
1411
|
+
const children = [...currentNode.children];
|
|
1412
|
+
onNode(currentNode);
|
|
1413
|
+
for (const child of children) {
|
|
1414
|
+
_treeVisit(child);
|
|
1415
|
+
}
|
|
1416
|
+
};
|
|
1417
|
+
if (Array.isArray(initialNode)) {
|
|
1418
|
+
for (const node of initialNode) {
|
|
1419
|
+
_treeVisit(node);
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
else {
|
|
1423
|
+
_treeVisit(initialNode);
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
|
|
1427
|
+
const MAX_ALLOWED_PATHS = 200;
|
|
1409
1428
|
const THUMBNAIL_IDS = [
|
|
1410
1429
|
'columns',
|
|
1411
1430
|
'columnsPlusRight',
|
|
@@ -1436,7 +1455,17 @@ const THUMBNAIL_IDS = [
|
|
|
1436
1455
|
const VariableMappingSchema = z.object({
|
|
1437
1456
|
parameterId: propertyKeySchema,
|
|
1438
1457
|
type: z.literal('ContentTypeMapping'),
|
|
1439
|
-
pathsByContentType: z
|
|
1458
|
+
pathsByContentType: z
|
|
1459
|
+
.record(z.string(), z.object({ path: z.string() }))
|
|
1460
|
+
.superRefine((paths, ctx) => {
|
|
1461
|
+
const variableId = ctx.path[ctx.path.length - 2];
|
|
1462
|
+
if (Object.keys(paths).length > MAX_ALLOWED_PATHS) {
|
|
1463
|
+
ctx.addIssue({
|
|
1464
|
+
code: z.ZodIssueCode.custom,
|
|
1465
|
+
message: `Too many paths defined for variable mapping with id "${variableId}", maximum allowed is ${MAX_ALLOWED_PATHS}`,
|
|
1466
|
+
});
|
|
1467
|
+
}
|
|
1468
|
+
}),
|
|
1440
1469
|
});
|
|
1441
1470
|
const PassToNodeSchema = z
|
|
1442
1471
|
.object({
|
|
@@ -1460,7 +1489,10 @@ const ParameterDefinitionSchema = z.object({
|
|
|
1460
1489
|
})
|
|
1461
1490
|
.optional(),
|
|
1462
1491
|
contentTypes: z.array(z.string()).min(1),
|
|
1463
|
-
passToNodes: z
|
|
1492
|
+
passToNodes: z
|
|
1493
|
+
.array(PassToNodeSchema)
|
|
1494
|
+
.max(1, 'At most one "passToNodes" element is allowed per parameter definition.')
|
|
1495
|
+
.optional(), // we might change this to be empty array for native parameter definitions, that's why we don't use .length(1)
|
|
1464
1496
|
});
|
|
1465
1497
|
const ParameterDefinitionsSchema = z.record(propertyKeySchema, ParameterDefinitionSchema);
|
|
1466
1498
|
const VariableMappingsSchema = z.record(propertyKeySchema, VariableMappingSchema);
|
|
@@ -1481,14 +1513,108 @@ const ComponentSettingsSchema = z
|
|
|
1481
1513
|
category: z.string().max(50, 'Category must contain at most 50 characters').optional(),
|
|
1482
1514
|
prebindingDefinitions: z.array(PrebindingDefinitionSchema).length(1).optional(),
|
|
1483
1515
|
})
|
|
1484
|
-
.strict()
|
|
1485
|
-
|
|
1516
|
+
.strict()
|
|
1517
|
+
.superRefine((componentSettings, ctx) => {
|
|
1518
|
+
const { variableDefinitions, prebindingDefinitions } = componentSettings;
|
|
1519
|
+
if (!prebindingDefinitions || prebindingDefinitions.length === 0) {
|
|
1520
|
+
return;
|
|
1521
|
+
}
|
|
1522
|
+
const { parameterDefinitions, variableMappings, allowedVariableOverrides } = prebindingDefinitions[0];
|
|
1523
|
+
validateAtMostOneNativeParameterDefinition(parameterDefinitions, ctx);
|
|
1524
|
+
validateNoOverlapBetweenMappingAndOverrides(variableMappings, allowedVariableOverrides, ctx);
|
|
1525
|
+
validateMappingsAgainstVariableDefinitions(variableMappings, allowedVariableOverrides, variableDefinitions, ctx);
|
|
1526
|
+
validateMappingsAgainstParameterDefinitions(variableMappings, parameterDefinitions, ctx);
|
|
1527
|
+
});
|
|
1528
|
+
z
|
|
1529
|
+
.object({
|
|
1486
1530
|
componentTree: localeWrapper(ComponentTreeSchema),
|
|
1487
1531
|
dataSource: localeWrapper(DataSourceSchema),
|
|
1488
1532
|
unboundValues: localeWrapper(UnboundValuesSchema),
|
|
1489
1533
|
usedComponents: localeWrapper(UsedComponentsSchema).optional(),
|
|
1490
1534
|
componentSettings: localeWrapper(ComponentSettingsSchema),
|
|
1535
|
+
})
|
|
1536
|
+
.superRefine((patternFields, ctx) => {
|
|
1537
|
+
const { componentTree, componentSettings } = patternFields;
|
|
1538
|
+
// values at this point are wrapped under locale code
|
|
1539
|
+
const nonLocalisedComponentTree = Object.values(componentTree)[0];
|
|
1540
|
+
const nonLocalisedComponentSettings = Object.values(componentSettings)[0];
|
|
1541
|
+
if (!nonLocalisedComponentSettings || !nonLocalisedComponentTree) {
|
|
1542
|
+
return;
|
|
1543
|
+
}
|
|
1544
|
+
validatePassToNodes(nonLocalisedComponentTree.children || [], nonLocalisedComponentSettings || {}, ctx);
|
|
1491
1545
|
});
|
|
1546
|
+
const validateAtMostOneNativeParameterDefinition = (parameterDefinitions, ctx) => {
|
|
1547
|
+
const nativeParamDefinitions = Object.values(parameterDefinitions).filter((paramDefinition) => !(paramDefinition.passToNodes && paramDefinition.passToNodes.length > 0));
|
|
1548
|
+
if (nativeParamDefinitions.length > 1) {
|
|
1549
|
+
ctx.addIssue({
|
|
1550
|
+
code: z.ZodIssueCode.custom,
|
|
1551
|
+
message: `Only one native parameter definition (parameter definition without passToNodes) is allowed per prebinding definition.`,
|
|
1552
|
+
});
|
|
1553
|
+
}
|
|
1554
|
+
};
|
|
1555
|
+
const validateNoOverlapBetweenMappingAndOverrides = (variableMappings, allowedVariableOverrides, ctx) => {
|
|
1556
|
+
const variableMappingKeys = Object.keys(variableMappings || {});
|
|
1557
|
+
const overridesSet = new Set(allowedVariableOverrides || []);
|
|
1558
|
+
const overlap = variableMappingKeys.filter((key) => overridesSet.has(key));
|
|
1559
|
+
if (overlap.length > 0) {
|
|
1560
|
+
ctx.addIssue({
|
|
1561
|
+
code: z.ZodIssueCode.custom,
|
|
1562
|
+
message: `Found both variable mapping and allowed override for the following keys: ${overlap.map((key) => `"${key}"`).join(', ')}.`,
|
|
1563
|
+
});
|
|
1564
|
+
}
|
|
1565
|
+
};
|
|
1566
|
+
const validateMappingsAgainstVariableDefinitions = (variableMappings, allowedVariableOverrides, variableDefinitions, ctx) => {
|
|
1567
|
+
const nonDesignVariableDefinitionKeys = Object.entries(variableDefinitions)
|
|
1568
|
+
.filter(([_, def]) => def.group !== 'style')
|
|
1569
|
+
.map(([key]) => key);
|
|
1570
|
+
const variableMappingKeys = Object.keys(variableMappings || {});
|
|
1571
|
+
const allKeys = [...variableMappingKeys, ...(allowedVariableOverrides || [])];
|
|
1572
|
+
const invalidMappings = allKeys.filter((key) => !nonDesignVariableDefinitionKeys.includes(key));
|
|
1573
|
+
if (invalidMappings.length > 0) {
|
|
1574
|
+
ctx.addIssue({
|
|
1575
|
+
code: z.ZodIssueCode.custom,
|
|
1576
|
+
message: `The following variable mappings or overrides are missing from the variable definitions: ${invalidMappings.map((key) => `"${key}"`).join(', ')}.`,
|
|
1577
|
+
});
|
|
1578
|
+
}
|
|
1579
|
+
};
|
|
1580
|
+
const validateMappingsAgainstParameterDefinitions = (variableMappings, parameterDefinitions, ctx) => {
|
|
1581
|
+
const parameterDefinitionKeys = Object.keys(parameterDefinitions || {});
|
|
1582
|
+
for (const [mappingKey, mappingValue] of Object.entries(variableMappings || {})) {
|
|
1583
|
+
if (!parameterDefinitionKeys.includes(mappingValue.parameterId)) {
|
|
1584
|
+
ctx.addIssue({
|
|
1585
|
+
code: z.ZodIssueCode.custom,
|
|
1586
|
+
message: `The variable mapping with id "${mappingKey}" references a non-existing parameterId "${mappingValue.parameterId}".`,
|
|
1587
|
+
});
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
};
|
|
1591
|
+
const validatePassToNodes = (rootChildren, componentSettings, ctx) => {
|
|
1592
|
+
if (!componentSettings.prebindingDefinitions ||
|
|
1593
|
+
componentSettings.prebindingDefinitions.length === 0) {
|
|
1594
|
+
return;
|
|
1595
|
+
}
|
|
1596
|
+
const { parameterDefinitions } = componentSettings.prebindingDefinitions[0];
|
|
1597
|
+
let nodeIds = new Set();
|
|
1598
|
+
for (const paramDef of Object.values(parameterDefinitions || {})) {
|
|
1599
|
+
paramDef.passToNodes?.forEach((n) => nodeIds.add(n.nodeId));
|
|
1600
|
+
}
|
|
1601
|
+
treeVisit$1(rootChildren, (node) => {
|
|
1602
|
+
if (!node.id)
|
|
1603
|
+
return;
|
|
1604
|
+
if (nodeIds.has(node.id)) {
|
|
1605
|
+
nodeIds.delete(node.id);
|
|
1606
|
+
}
|
|
1607
|
+
});
|
|
1608
|
+
if (nodeIds.size > 0) {
|
|
1609
|
+
const stringifiedNodeIds = Array.from(nodeIds)
|
|
1610
|
+
.map((id) => `"${id}"`)
|
|
1611
|
+
.join(', ');
|
|
1612
|
+
ctx.addIssue({
|
|
1613
|
+
code: z.ZodIssueCode.custom,
|
|
1614
|
+
message: `The following node IDs referenced in passToNodes are not present in the component tree: ${stringifiedNodeIds}.`,
|
|
1615
|
+
});
|
|
1616
|
+
}
|
|
1617
|
+
};
|
|
1492
1618
|
|
|
1493
1619
|
z
|
|
1494
1620
|
.object({
|