@contentful/experiences-core 1.42.4-prerelease-20250702T1207-37b3bfc.0 → 2.0.0-beta.1
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.js +0 -8
- package/dist/constants.js.map +1 -1
- package/dist/deep-binding/DeepReference.d.ts +2 -2
- package/dist/entity/EditorModeEntityStore.d.ts +0 -1
- package/dist/entity/EntityStoreBase.d.ts +8 -3
- package/dist/entity/InMemoryEntitiesPublicApi.d.ts +32 -0
- package/dist/entity/InMemoryEntitiesStore.d.ts +17 -0
- package/dist/index.d.ts +9 -5
- package/dist/index.js +374 -129
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +4 -10
- package/dist/utils/breakpoints.d.ts +5 -2
- package/dist/utils/isLinkToAsset.d.ts +1 -1
- package/dist/utils/isLinkToEntry.d.ts +5 -0
- package/dist/utils/schema/experienceSchema.d.ts +23 -0
- package/dist/utils/schema/references.d.ts +18 -0
- package/dist/utils/typeguards.d.ts +11 -2
- package/dist/utils/utils.d.ts +1 -6
- package/package.json +3 -3
- package/dist/utils/entityTypeChecks.d.ts +0 -6
package/dist/index.js
CHANGED
|
@@ -2,6 +2,7 @@ import { z, ZodIssueCode } from 'zod';
|
|
|
2
2
|
import { omit, isArray, uniqBy } from 'lodash-es';
|
|
3
3
|
import md5 from 'md5';
|
|
4
4
|
import { BLOCKS } from '@contentful/rich-text-types';
|
|
5
|
+
import { create } from 'zustand';
|
|
5
6
|
|
|
6
7
|
const INCOMING_EVENTS = {
|
|
7
8
|
RequestEditorMode: 'requestEditorMode',
|
|
@@ -114,14 +115,6 @@ const CF_STYLE_ATTRIBUTES = [
|
|
|
114
115
|
'cfTextBold',
|
|
115
116
|
'cfTextItalic',
|
|
116
117
|
'cfTextUnderline',
|
|
117
|
-
// For backwards compatibility
|
|
118
|
-
// we need to keep those in this constant array
|
|
119
|
-
// so that omit() in <VisualEditorBlock> and <CompositionBlock>
|
|
120
|
-
// can filter them out and not pass as props
|
|
121
|
-
'cfBackgroundImageScaling',
|
|
122
|
-
'cfBackgroundImageAlignment',
|
|
123
|
-
'cfBackgroundImageAlignmentVertical',
|
|
124
|
-
'cfBackgroundImageAlignmentHorizontal',
|
|
125
118
|
];
|
|
126
119
|
const EMPTY_CONTAINER_HEIGHT = '80px';
|
|
127
120
|
const DEFAULT_IMAGE_WIDTH = '500px';
|
|
@@ -1457,6 +1450,24 @@ propertyName, resolveDesignTokens = true) => {
|
|
|
1457
1450
|
return valuesByBreakpoint;
|
|
1458
1451
|
}
|
|
1459
1452
|
};
|
|
1453
|
+
/** Overwrites the default value breakpoint by breakpoint. If a breakpoint
|
|
1454
|
+
* is not overwritten, it will fall back to the default. */
|
|
1455
|
+
function mergeDesignValuesByBreakpoint(defaultValue, overwriteValue) {
|
|
1456
|
+
if (!defaultValue || !overwriteValue) {
|
|
1457
|
+
return defaultValue ?? overwriteValue;
|
|
1458
|
+
}
|
|
1459
|
+
const mergedValuesByBreakpoint = { ...defaultValue.valuesByBreakpoint };
|
|
1460
|
+
for (const [breakpointId, value] of Object.entries(overwriteValue.valuesByBreakpoint)) {
|
|
1461
|
+
if (!isValidBreakpointValue(value)) {
|
|
1462
|
+
continue;
|
|
1463
|
+
}
|
|
1464
|
+
mergedValuesByBreakpoint[breakpointId] = value;
|
|
1465
|
+
}
|
|
1466
|
+
return {
|
|
1467
|
+
type: 'DesignValue',
|
|
1468
|
+
valuesByBreakpoint: mergedValuesByBreakpoint,
|
|
1469
|
+
};
|
|
1470
|
+
}
|
|
1460
1471
|
|
|
1461
1472
|
const CF_DEBUG_KEY = 'cf_debug';
|
|
1462
1473
|
/**
|
|
@@ -1586,11 +1597,19 @@ const getElementCoordinates = (element) => {
|
|
|
1586
1597
|
});
|
|
1587
1598
|
};
|
|
1588
1599
|
|
|
1589
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1590
1600
|
const isLinkToAsset = (variable) => {
|
|
1591
|
-
if (
|
|
1601
|
+
if (variable === null || typeof variable !== 'object')
|
|
1602
|
+
return false;
|
|
1603
|
+
// The `'prop' in` pattern is informing TypeScript of the object shape, no need to cast `as`.
|
|
1604
|
+
if (!('sys' in variable))
|
|
1605
|
+
return false;
|
|
1606
|
+
if (variable.sys === null || typeof variable.sys !== 'object')
|
|
1607
|
+
return false;
|
|
1608
|
+
if (!('linkType' in variable.sys))
|
|
1609
|
+
return false;
|
|
1610
|
+
if (!('id' in variable.sys))
|
|
1592
1611
|
return false;
|
|
1593
|
-
if (
|
|
1612
|
+
if (!('type' in variable.sys))
|
|
1594
1613
|
return false;
|
|
1595
1614
|
return (variable.sys?.linkType === 'Asset' &&
|
|
1596
1615
|
typeof variable.sys?.id === 'string' &&
|
|
@@ -1598,13 +1617,33 @@ const isLinkToAsset = (variable) => {
|
|
|
1598
1617
|
variable.sys?.type === 'Link');
|
|
1599
1618
|
};
|
|
1600
1619
|
|
|
1620
|
+
const isLinkToEntry = (variable) => {
|
|
1621
|
+
if (variable === null || typeof variable !== 'object')
|
|
1622
|
+
return false;
|
|
1623
|
+
// The `'prop' in` pattern is informing TypeScript of the object shape, no need to cast `as`.
|
|
1624
|
+
if (!('sys' in variable))
|
|
1625
|
+
return false;
|
|
1626
|
+
if (variable.sys === null || typeof variable.sys !== 'object')
|
|
1627
|
+
return false;
|
|
1628
|
+
if (!('linkType' in variable.sys))
|
|
1629
|
+
return false;
|
|
1630
|
+
if (!('id' in variable.sys))
|
|
1631
|
+
return false;
|
|
1632
|
+
if (!('type' in variable.sys))
|
|
1633
|
+
return false;
|
|
1634
|
+
return (variable.sys?.linkType === 'Entry' &&
|
|
1635
|
+
typeof variable.sys?.id === 'string' &&
|
|
1636
|
+
!!variable.sys?.id &&
|
|
1637
|
+
variable.sys?.type === 'Link');
|
|
1638
|
+
};
|
|
1639
|
+
|
|
1601
1640
|
const isLink = (maybeLink) => {
|
|
1602
1641
|
if (maybeLink === null)
|
|
1603
1642
|
return false;
|
|
1604
1643
|
if (typeof maybeLink !== 'object')
|
|
1605
1644
|
return false;
|
|
1606
1645
|
const link = maybeLink;
|
|
1607
|
-
return Boolean(link.sys?.id) && link.sys?.type === 'Link';
|
|
1646
|
+
return Boolean(link.sys?.id) && link.sys?.type === 'Link' && Boolean(link.sys?.linkType);
|
|
1608
1647
|
};
|
|
1609
1648
|
|
|
1610
1649
|
/**
|
|
@@ -1831,11 +1870,6 @@ const transformVisibility = (value) => {
|
|
|
1831
1870
|
// Don't explicitly set anything when visible to not overwrite values like `grid` or `flex`.
|
|
1832
1871
|
return {};
|
|
1833
1872
|
};
|
|
1834
|
-
// TODO: Remove in next major version v2 since the change is 17 months old
|
|
1835
|
-
// Keep this for backwards compatibility - deleting this would be a breaking change
|
|
1836
|
-
// because existing components on a users experience will have the width value as fill
|
|
1837
|
-
// rather than 100%
|
|
1838
|
-
const transformFill = (value) => (value === 'fill' ? '100%' : value);
|
|
1839
1873
|
const transformGridColumn = (span) => {
|
|
1840
1874
|
if (!span) {
|
|
1841
1875
|
return {};
|
|
@@ -1880,34 +1914,6 @@ const transformBackgroundImage = (cfBackgroundImageUrl, cfBackgroundImageOptions
|
|
|
1880
1914
|
return;
|
|
1881
1915
|
}
|
|
1882
1916
|
let [horizontalAlignment, verticalAlignment] = alignment.trim().split(/\s+/, 2);
|
|
1883
|
-
// Special case for handling single values
|
|
1884
|
-
// for backwards compatibility with single values 'right','left', 'center', 'top','bottom'
|
|
1885
|
-
if (horizontalAlignment && !verticalAlignment) {
|
|
1886
|
-
const singleValue = horizontalAlignment;
|
|
1887
|
-
switch (singleValue) {
|
|
1888
|
-
case 'left':
|
|
1889
|
-
horizontalAlignment = 'left';
|
|
1890
|
-
verticalAlignment = 'center';
|
|
1891
|
-
break;
|
|
1892
|
-
case 'right':
|
|
1893
|
-
horizontalAlignment = 'right';
|
|
1894
|
-
verticalAlignment = 'center';
|
|
1895
|
-
break;
|
|
1896
|
-
case 'center':
|
|
1897
|
-
horizontalAlignment = 'center';
|
|
1898
|
-
verticalAlignment = 'center';
|
|
1899
|
-
break;
|
|
1900
|
-
case 'top':
|
|
1901
|
-
horizontalAlignment = 'center';
|
|
1902
|
-
verticalAlignment = 'top';
|
|
1903
|
-
break;
|
|
1904
|
-
case 'bottom':
|
|
1905
|
-
horizontalAlignment = 'center';
|
|
1906
|
-
verticalAlignment = 'bottom';
|
|
1907
|
-
break;
|
|
1908
|
-
// just fall down to the normal validation logic for horiz and vert
|
|
1909
|
-
}
|
|
1910
|
-
}
|
|
1911
1917
|
const isHorizontalValid = ['left', 'right', 'center'].includes(horizontalAlignment);
|
|
1912
1918
|
const isVerticalValid = ['top', 'bottom', 'center'].includes(verticalAlignment);
|
|
1913
1919
|
horizontalAlignment = isHorizontalValid ? horizontalAlignment : 'left';
|
|
@@ -1992,8 +1998,8 @@ const buildCfStyles = (values) => {
|
|
|
1992
1998
|
margin: values.cfMargin,
|
|
1993
1999
|
padding: values.cfPadding,
|
|
1994
2000
|
backgroundColor: values.cfBackgroundColor,
|
|
1995
|
-
width:
|
|
1996
|
-
height:
|
|
2001
|
+
width: values.cfWidth || values.cfImageOptions?.width,
|
|
2002
|
+
height: values.cfHeight || values.cfImageOptions?.height,
|
|
1997
2003
|
maxWidth: values.cfMaxWidth,
|
|
1998
2004
|
...transformGridColumn(values.cfColumnSpan),
|
|
1999
2005
|
...transformBorderStyle(values.cfBorder),
|
|
@@ -2216,7 +2222,7 @@ const detachExperienceStyles = (experience) => {
|
|
|
2216
2222
|
* {
|
|
2217
2223
|
* desktop: {
|
|
2218
2224
|
* cfMargin: '1px',
|
|
2219
|
-
* cfWidth: '
|
|
2225
|
+
* cfWidth: '100%',
|
|
2220
2226
|
* cfBackgroundImageUrl: 'https://example.com/image.jpg'
|
|
2221
2227
|
* //...
|
|
2222
2228
|
* }
|
|
@@ -2385,9 +2391,10 @@ const resolveComponentVariablesOverwrites = ({ patternNode, wrapperComponentVari
|
|
|
2385
2391
|
const overwritingValue = wrapperComponentVariablesOverwrites?.[propertyValue.key];
|
|
2386
2392
|
// Property definition from the parent pattern
|
|
2387
2393
|
const propertyDefinition = wrapperComponentSettings?.variableDefinitions?.[propertyValue.key];
|
|
2394
|
+
const defaultValue = propertyDefinition?.defaultValue;
|
|
2388
2395
|
// The overwriting value is either a custom value from the experience or default value from a
|
|
2389
2396
|
// wrapping pattern node that got trickled down to this nesting level.
|
|
2390
|
-
resolvedValues[propertyName] = overwritingValue
|
|
2397
|
+
resolvedValues[propertyName] = mergeDefaultAndOverwriteValues(defaultValue, overwritingValue);
|
|
2391
2398
|
}
|
|
2392
2399
|
else {
|
|
2393
2400
|
// Keep raw values
|
|
@@ -2470,15 +2477,15 @@ const resolveBackgroundImageBinding = ({ variableData, getBoundEntityById, dataS
|
|
|
2470
2477
|
// @ts-expect-error TODO: Types coming from validations erroneously assume that `defaultValue` can be a primitive value (e.g. string or number)
|
|
2471
2478
|
const defaultValueKey = variableDefinition.defaultValue?.key;
|
|
2472
2479
|
const defaultValue = unboundValues[defaultValueKey].value;
|
|
2473
|
-
const
|
|
2474
|
-
//
|
|
2475
|
-
if (!
|
|
2480
|
+
const overwriteValue = componentVariablesOverwrites?.[variableDefinitionKey];
|
|
2481
|
+
// overwriteValue is a ComponentValue we can safely return the default value
|
|
2482
|
+
if (!overwriteValue || overwriteValue.type === 'ComponentValue') {
|
|
2476
2483
|
return defaultValue;
|
|
2477
2484
|
}
|
|
2478
|
-
// at this point
|
|
2485
|
+
// at this point overwriteValue will either be type of 'DesignValue' or 'BoundValue'
|
|
2479
2486
|
// so we recursively run resolution again to resolve it
|
|
2480
2487
|
const resolvedValue = resolveBackgroundImageBinding({
|
|
2481
|
-
variableData:
|
|
2488
|
+
variableData: overwriteValue,
|
|
2482
2489
|
getBoundEntityById,
|
|
2483
2490
|
dataSource,
|
|
2484
2491
|
unboundValues,
|
|
@@ -2631,10 +2638,10 @@ const indexByBreakpoint = ({ variables, breakpointIds, getBoundEntityById, unbou
|
|
|
2631
2638
|
let resolvedVariableData = variableData;
|
|
2632
2639
|
if (variableData.type === 'ComponentValue') {
|
|
2633
2640
|
const variableDefinition = componentSettings?.variableDefinitions[variableData.key];
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2641
|
+
const defaultValue = variableDefinition.defaultValue;
|
|
2642
|
+
if (variableDefinition.group === 'style' && defaultValue !== undefined) {
|
|
2643
|
+
const overwriteVariableData = componentVariablesOverwrites?.[variableData.key];
|
|
2644
|
+
resolvedVariableData = mergeDefaultAndOverwriteValues(defaultValue, overwriteVariableData);
|
|
2638
2645
|
}
|
|
2639
2646
|
}
|
|
2640
2647
|
if (resolvedVariableData.type !== 'DesignValue') {
|
|
@@ -2672,6 +2679,12 @@ const flattenDesignTokenRegistry = (designTokenRegistry) => {
|
|
|
2672
2679
|
};
|
|
2673
2680
|
}, {});
|
|
2674
2681
|
};
|
|
2682
|
+
function mergeDefaultAndOverwriteValues(defaultValue, overwriteValue) {
|
|
2683
|
+
if (defaultValue?.type === 'DesignValue' && overwriteValue?.type === 'DesignValue') {
|
|
2684
|
+
return mergeDesignValuesByBreakpoint(defaultValue, overwriteValue);
|
|
2685
|
+
}
|
|
2686
|
+
return overwriteValue ?? defaultValue;
|
|
2687
|
+
}
|
|
2675
2688
|
|
|
2676
2689
|
/**
|
|
2677
2690
|
* Turns a condition like `<768px` or `>1024px` into a media query rule.
|
|
@@ -2767,7 +2780,9 @@ const transformRichText = (entryOrAsset, entityStore, path) => {
|
|
|
2767
2780
|
}
|
|
2768
2781
|
if (typeof value === 'object' && value.nodeType === BLOCKS.DOCUMENT) {
|
|
2769
2782
|
// resolve any links to assets/entries/hyperlinks
|
|
2770
|
-
|
|
2783
|
+
// we need to clone, as we want to keep the original Entity in the EntityStore intact,
|
|
2784
|
+
// and resolveLinks() is mutating the node object.
|
|
2785
|
+
const richTextDocument = structuredClone(value);
|
|
2771
2786
|
resolveLinks(richTextDocument, entityStore);
|
|
2772
2787
|
return richTextDocument;
|
|
2773
2788
|
}
|
|
@@ -2881,17 +2896,37 @@ const transformMedia = (asset, variables, resolveDesignValue, variableName, path
|
|
|
2881
2896
|
return asset.fields.file?.url;
|
|
2882
2897
|
};
|
|
2883
2898
|
|
|
2884
|
-
const
|
|
2899
|
+
const isExperienceEntry = (entry) => {
|
|
2900
|
+
return (entry?.sys?.type === 'Entry' &&
|
|
2901
|
+
!!entry.fields?.title &&
|
|
2902
|
+
!!entry.fields?.slug &&
|
|
2903
|
+
!!entry.fields?.componentTree &&
|
|
2904
|
+
Array.isArray(entry.fields.componentTree.breakpoints) &&
|
|
2905
|
+
Array.isArray(entry.fields.componentTree.children) &&
|
|
2906
|
+
typeof entry.fields.componentTree.schemaVersion === 'string');
|
|
2907
|
+
};
|
|
2908
|
+
const isPatternEntry = (entry) => {
|
|
2909
|
+
return isExperienceEntry(entry) && !!entry.fields?.componentSettings; // signals that this is pattern (not experience) entry
|
|
2910
|
+
};
|
|
2911
|
+
const isEntry = (value) => {
|
|
2885
2912
|
return (null !== value &&
|
|
2886
2913
|
typeof value === 'object' &&
|
|
2887
2914
|
'sys' in value &&
|
|
2888
|
-
value.sys?.type === '
|
|
2915
|
+
value.sys?.type === 'Entry');
|
|
2889
2916
|
};
|
|
2890
|
-
const
|
|
2917
|
+
const isAsset = (value) => {
|
|
2891
2918
|
return (null !== value &&
|
|
2892
2919
|
typeof value === 'object' &&
|
|
2893
2920
|
'sys' in value &&
|
|
2894
|
-
value.sys?.type === '
|
|
2921
|
+
value.sys?.type === 'Asset');
|
|
2922
|
+
};
|
|
2923
|
+
/**
|
|
2924
|
+
* Checks if the values is an array of links.
|
|
2925
|
+
* Note: we use convention where empty arrays are considered valid "arrays of links"
|
|
2926
|
+
* as they don't contradict the type definition.
|
|
2927
|
+
*/
|
|
2928
|
+
const isArrayOfLinks = (value) => {
|
|
2929
|
+
return Array.isArray(value) && value.every((item) => isLink(item));
|
|
2895
2930
|
};
|
|
2896
2931
|
|
|
2897
2932
|
function getResolvedEntryFromLink(entryOrAsset, path, entityStore) {
|
|
@@ -2901,7 +2936,8 @@ function getResolvedEntryFromLink(entryOrAsset, path, entityStore) {
|
|
|
2901
2936
|
else if (!isEntry(entryOrAsset)) {
|
|
2902
2937
|
throw new Error(`Expected an Entry or Asset, but got: ${JSON.stringify(entryOrAsset)}`);
|
|
2903
2938
|
}
|
|
2904
|
-
const
|
|
2939
|
+
const fieldName = path.split('/').slice(2, -1);
|
|
2940
|
+
const value = get(entryOrAsset, fieldName);
|
|
2905
2941
|
let resolvedEntity;
|
|
2906
2942
|
if (isAsset(value) || isEntry(value)) {
|
|
2907
2943
|
// In some cases, reference fields are already resolved
|
|
@@ -2910,74 +2946,67 @@ function getResolvedEntryFromLink(entryOrAsset, path, entityStore) {
|
|
|
2910
2946
|
else if (value?.sys.type === 'Link') {
|
|
2911
2947
|
// Look up the reference in the entity store
|
|
2912
2948
|
resolvedEntity = entityStore.getEntityFromLink(value);
|
|
2913
|
-
if (!resolvedEntity) {
|
|
2914
|
-
return;
|
|
2915
|
-
}
|
|
2916
2949
|
}
|
|
2917
2950
|
else {
|
|
2918
|
-
console.warn(`
|
|
2951
|
+
console.warn(`When attempting to follow link in field '${fieldName}' of entity, the value is expected to be a link, but got: ${JSON.stringify(value)}`, { entity: entryOrAsset });
|
|
2952
|
+
return;
|
|
2953
|
+
}
|
|
2954
|
+
// no need to make structuredClone(entityStore.getEntityFromLink(value)) because
|
|
2955
|
+
// we provide component with the original Object.frozen object of the entity.
|
|
2956
|
+
// As we don't resolve L3 and don't mutate the entity before returning anymore,
|
|
2957
|
+
// we don't need to make a copy of the entity. And even provide better referential integrity
|
|
2958
|
+
// for the component for the same entity.
|
|
2959
|
+
if (!resolvedEntity) {
|
|
2919
2960
|
return;
|
|
2920
2961
|
}
|
|
2921
|
-
//resolve any embedded links - we currently only support 2 levels deep
|
|
2922
|
-
const fields = resolvedEntity.fields || {};
|
|
2923
|
-
Object.entries(fields).forEach(([fieldKey, field]) => {
|
|
2924
|
-
if (field && field.sys?.type === 'Link') {
|
|
2925
|
-
const entity = entityStore.getEntityFromLink(field);
|
|
2926
|
-
if (entity) {
|
|
2927
|
-
resolvedEntity.fields[fieldKey] = entity;
|
|
2928
|
-
}
|
|
2929
|
-
}
|
|
2930
|
-
else if (field && Array.isArray(field)) {
|
|
2931
|
-
resolvedEntity.fields[fieldKey] = field.map((innerField) => {
|
|
2932
|
-
if (innerField && innerField.sys?.type === 'Link') {
|
|
2933
|
-
const entity = entityStore.getEntityFromLink(innerField);
|
|
2934
|
-
if (entity) {
|
|
2935
|
-
return entity;
|
|
2936
|
-
}
|
|
2937
|
-
}
|
|
2938
|
-
return innerField;
|
|
2939
|
-
});
|
|
2940
|
-
}
|
|
2941
|
-
});
|
|
2942
2962
|
return resolvedEntity;
|
|
2943
2963
|
}
|
|
2944
2964
|
|
|
2965
|
+
const excludeUndefined = (value) => {
|
|
2966
|
+
return value !== undefined;
|
|
2967
|
+
};
|
|
2945
2968
|
function getArrayValue(entryOrAsset, path, entityStore) {
|
|
2969
|
+
// NOTE: Not sure if we need this if-statement,
|
|
2970
|
+
// as it is NOT possible to bind to Array variable an Asset
|
|
2971
|
+
// (as Assets don't have multi-reference fields) unless it's a degenerate case.
|
|
2946
2972
|
if (entryOrAsset.sys.type === 'Asset') {
|
|
2947
2973
|
return entryOrAsset;
|
|
2948
2974
|
}
|
|
2949
|
-
const
|
|
2975
|
+
const fieldName = path.split('/').slice(2, -1);
|
|
2976
|
+
const arrayValue = get(entryOrAsset, fieldName);
|
|
2950
2977
|
if (!isArray(arrayValue)) {
|
|
2951
|
-
console.warn(`Expected
|
|
2978
|
+
console.warn(`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 });
|
|
2952
2979
|
return;
|
|
2953
2980
|
}
|
|
2954
|
-
const result = arrayValue
|
|
2981
|
+
const result = arrayValue
|
|
2982
|
+
.map((value) => {
|
|
2955
2983
|
if (typeof value === 'string') {
|
|
2956
|
-
return value;
|
|
2984
|
+
return value; // handles case where Text array is bound (in [Content Model] tab of the platform, select Text and make it a list)
|
|
2957
2985
|
}
|
|
2958
2986
|
else if (value?.sys?.type === 'Link') {
|
|
2959
2987
|
const resolvedEntity = entityStore.getEntityFromLink(value);
|
|
2960
2988
|
if (!resolvedEntity) {
|
|
2989
|
+
// We return undefined, which means that entity wasn't availble in the Entity Store due to:
|
|
2990
|
+
// - because it's archived entity (and they normally wouldn't be sent to the Entity Store)
|
|
2991
|
+
// - bug where some entity wasn't added to the Entity Store
|
|
2992
|
+
// BTW, deleted entities shouldn't even be possible here as they require CT deletion first and that shouldn't allow us to load them at all)
|
|
2961
2993
|
return;
|
|
2962
2994
|
}
|
|
2963
|
-
//resolve any embedded links - we currently only support 2 levels deep
|
|
2964
|
-
const fields = resolvedEntity.fields || {};
|
|
2965
|
-
Object.entries(fields).forEach(([fieldKey, field]) => {
|
|
2966
|
-
if (field && field.sys?.type === 'Link') {
|
|
2967
|
-
const entity = entityStore.getEntityFromLink(field);
|
|
2968
|
-
if (entity) {
|
|
2969
|
-
resolvedEntity.fields[fieldKey] = entity;
|
|
2970
|
-
}
|
|
2971
|
-
}
|
|
2972
|
-
});
|
|
2973
2995
|
return resolvedEntity;
|
|
2974
2996
|
}
|
|
2975
2997
|
else {
|
|
2976
2998
|
console.warn(`Expected value to be a string or Link, but got: ${JSON.stringify(value)}`);
|
|
2977
2999
|
return undefined;
|
|
2978
3000
|
}
|
|
2979
|
-
})
|
|
2980
|
-
|
|
3001
|
+
})
|
|
3002
|
+
.filter(excludeUndefined);
|
|
3003
|
+
// eg. imagine you have multi-referene field with 3 links to archived entries,
|
|
3004
|
+
// all of them will be undefined on previous step and will be filtered out
|
|
3005
|
+
// of resultWithoutUndefined. Instead of passing to component an empty array,
|
|
3006
|
+
// we pass undefined. This means that develloper making custom component
|
|
3007
|
+
// does not have to handle empty array case. But only undefiened, which signals:
|
|
3008
|
+
// user didn't bind anything; user bound to reference field which is unset; all references are archived
|
|
3009
|
+
return result.length > 0 ? result : undefined;
|
|
2981
3010
|
}
|
|
2982
3011
|
|
|
2983
3012
|
const transformBoundContentValue = (variables, entityStore, binding, resolveDesignValue, variableName, variableType, path) => {
|
|
@@ -3038,16 +3067,6 @@ function treeMap(node, onNode) {
|
|
|
3038
3067
|
return newNode;
|
|
3039
3068
|
}
|
|
3040
3069
|
|
|
3041
|
-
const isExperienceEntry = (entry) => {
|
|
3042
|
-
return (entry?.sys?.type === 'Entry' &&
|
|
3043
|
-
!!entry.fields?.title &&
|
|
3044
|
-
!!entry.fields?.slug &&
|
|
3045
|
-
!!entry.fields?.componentTree &&
|
|
3046
|
-
Array.isArray(entry.fields.componentTree.breakpoints) &&
|
|
3047
|
-
Array.isArray(entry.fields.componentTree.children) &&
|
|
3048
|
-
typeof entry.fields.componentTree.schemaVersion === 'string');
|
|
3049
|
-
};
|
|
3050
|
-
|
|
3051
3070
|
const getDataFromTree = (tree) => {
|
|
3052
3071
|
let dataSource = {};
|
|
3053
3072
|
let unboundValues = {};
|
|
@@ -3122,8 +3141,6 @@ const checkIsAssemblyNode = ({ componentId, usedComponents, }) => {
|
|
|
3122
3141
|
return false;
|
|
3123
3142
|
return usedComponents.some((usedComponent) => usedComponent.sys.id === componentId);
|
|
3124
3143
|
};
|
|
3125
|
-
/** @deprecated use `checkIsAssemblyNode` instead. Will be removed with SDK v5. */
|
|
3126
|
-
const checkIsAssembly = checkIsAssemblyNode;
|
|
3127
3144
|
/**
|
|
3128
3145
|
* This check assumes that the entry is already ensured to be an experience, i.e. the
|
|
3129
3146
|
* content type of the entry is an experience type with the necessary annotations.
|
|
@@ -3221,6 +3238,124 @@ const validateExperienceBuilderConfig = ({ locale, mode, }) => {
|
|
|
3221
3238
|
}
|
|
3222
3239
|
};
|
|
3223
3240
|
|
|
3241
|
+
const uniqueById = (arr) => {
|
|
3242
|
+
const map = new Map();
|
|
3243
|
+
arr.forEach((item) => map.set(item.sys.id, item));
|
|
3244
|
+
return [...map.values()];
|
|
3245
|
+
};
|
|
3246
|
+
const isObject = (value) => {
|
|
3247
|
+
return typeof value === 'object' && value !== null;
|
|
3248
|
+
};
|
|
3249
|
+
/**
|
|
3250
|
+
* Extracts all references from an entry.
|
|
3251
|
+
* Handles both: reference and multi-reference fields.
|
|
3252
|
+
* Returns unique array of references (even if they repeat within the entry).
|
|
3253
|
+
*/
|
|
3254
|
+
const referencesOf = (entry, fnShouldFollowReferencesOfEntryField) => {
|
|
3255
|
+
const references = [];
|
|
3256
|
+
const handleArray = (fieldValue, _fieldName) => {
|
|
3257
|
+
for (const item of fieldValue) {
|
|
3258
|
+
if (isObject(item) && item.sys?.type === 'Link') {
|
|
3259
|
+
references.push(item);
|
|
3260
|
+
}
|
|
3261
|
+
}
|
|
3262
|
+
};
|
|
3263
|
+
const handleLink = (fieldValue, _fieldName) => {
|
|
3264
|
+
references.push(fieldValue);
|
|
3265
|
+
};
|
|
3266
|
+
for (const [fieldName, fieldValue] of Object.entries(entry.fields)) {
|
|
3267
|
+
if (fnShouldFollowReferencesOfEntryField &&
|
|
3268
|
+
!fnShouldFollowReferencesOfEntryField(fieldName, entry)) {
|
|
3269
|
+
continue;
|
|
3270
|
+
}
|
|
3271
|
+
if (fieldValue === undefined) {
|
|
3272
|
+
continue; // edge case when field is present on object, but is set to undefined explicitly e.g. during test mocking { myField: undefined }
|
|
3273
|
+
}
|
|
3274
|
+
if (Array.isArray(fieldValue)) {
|
|
3275
|
+
handleArray(fieldValue);
|
|
3276
|
+
}
|
|
3277
|
+
else if (fieldValue !== null &&
|
|
3278
|
+
isObject(fieldValue) &&
|
|
3279
|
+
fieldValue.sys?.type === 'Link') {
|
|
3280
|
+
handleLink(fieldValue);
|
|
3281
|
+
}
|
|
3282
|
+
}
|
|
3283
|
+
return uniqueById(references);
|
|
3284
|
+
};
|
|
3285
|
+
// -- REFERENCE EXTRACTION UTILITIES --
|
|
3286
|
+
function extractReferencesFromEntriesAsIds(entries) {
|
|
3287
|
+
const [uniqueEntries, uniqueAssets, uniqueReferences] = extractReferencesFromEntries(entries);
|
|
3288
|
+
const entryIds = uniqueEntries.map((link) => link.sys.id);
|
|
3289
|
+
const assetIds = uniqueAssets.map((link) => link.sys.id);
|
|
3290
|
+
const referenceIds = uniqueReferences.map((link) => link.sys.id);
|
|
3291
|
+
return [entryIds, assetIds, referenceIds];
|
|
3292
|
+
}
|
|
3293
|
+
function extractReferencesFromEntries(entries) {
|
|
3294
|
+
const allReferences = entries.flatMap((entry) => referencesOf(entry));
|
|
3295
|
+
const uniqueReferences = uniqueById(allReferences);
|
|
3296
|
+
const uniqueAssets = uniqueReferences.filter((link) => link.sys.linkType === 'Asset');
|
|
3297
|
+
const uniqueEntries = uniqueReferences.filter((link) => link.sys.linkType === 'Entry');
|
|
3298
|
+
return [uniqueEntries, uniqueAssets, uniqueReferences];
|
|
3299
|
+
}
|
|
3300
|
+
|
|
3301
|
+
const excludeAssets = (entity) => !isAsset(entity);
|
|
3302
|
+
const excludePatternEntries = (entry) => !isPatternEntry(entry);
|
|
3303
|
+
/**
|
|
3304
|
+
* Parses experience and extracts all leaf links that are referenced from the experience.
|
|
3305
|
+
* PRECONDITION: Relies on the fact that entityStore is preloaded with all dataSource
|
|
3306
|
+
* entries using include=2 (meaning that up to L3 entries are already preloaded into EntitStore).
|
|
3307
|
+
*
|
|
3308
|
+
* The function iterates over all entries in the entityStore (assuming they can be L1, L2, L3) and
|
|
3309
|
+
* over all of their references. Any references that are NOT available in the entityStore are considered
|
|
3310
|
+
* "leaf references" aka "leaf links" and are returned.
|
|
3311
|
+
*
|
|
3312
|
+
* The EntityStore happens to contain also entities representing patterns, which we do NOT consider
|
|
3313
|
+
* as entries that point to leaf links. So we don't iterate over patterns only over entries which
|
|
3314
|
+
* can be used for binding.
|
|
3315
|
+
*/
|
|
3316
|
+
const extractLeafLinksReferencedFromExperience = (experience) => {
|
|
3317
|
+
const assetLinks = [];
|
|
3318
|
+
const entryLinks = [];
|
|
3319
|
+
if (!experience.entityStore) {
|
|
3320
|
+
throw new Error('Parameter `experience` should have valid `experience.entityStore` object. Without it, we cannot extract leaf links. Most likely you passed `experience` instance that was not fully fetched. Check your experience fetching logic.');
|
|
3321
|
+
}
|
|
3322
|
+
// We want only leaf links which can be used for binding. We use two filters:
|
|
3323
|
+
// excludeAssets: because assets do not have references, so we don't need to traverse them
|
|
3324
|
+
// excludePatternEntries: because EntityStore happens to also store pattern-entries.
|
|
3325
|
+
// Those point to other patterns, and we don't want to consider them as
|
|
3326
|
+
// parents of leaf links pointing to actual data carrying entries used for binding.
|
|
3327
|
+
const entries = experience.entityStore.entities
|
|
3328
|
+
.filter(excludeAssets)
|
|
3329
|
+
.filter(excludePatternEntries);
|
|
3330
|
+
// We assume that ALL of the entries in the experience
|
|
3331
|
+
for (const entry of entries) {
|
|
3332
|
+
const references = referencesOf(entry);
|
|
3333
|
+
for (const ref of references) {
|
|
3334
|
+
if (isLinkToAsset(ref)) {
|
|
3335
|
+
if (!experience.entityStore.getEntityFromLink(ref)) {
|
|
3336
|
+
assetLinks.push(ref);
|
|
3337
|
+
}
|
|
3338
|
+
}
|
|
3339
|
+
else if (isLinkToEntry(ref)) {
|
|
3340
|
+
if (!experience.entityStore.getEntityFromLink(ref)) {
|
|
3341
|
+
entryLinks.push(ref);
|
|
3342
|
+
}
|
|
3343
|
+
}
|
|
3344
|
+
else {
|
|
3345
|
+
console.warn(`Unexpected reference type found in entry "${entry.sys.id}": ${JSON.stringify(ref)}`);
|
|
3346
|
+
}
|
|
3347
|
+
}
|
|
3348
|
+
}
|
|
3349
|
+
const dedupedAssetLinks = uniqueById(assetLinks);
|
|
3350
|
+
const dedupedEntryLinks = uniqueById(entryLinks);
|
|
3351
|
+
return {
|
|
3352
|
+
assetLinks: dedupedAssetLinks,
|
|
3353
|
+
entryLinks: dedupedEntryLinks,
|
|
3354
|
+
assetIds: dedupedAssetLinks.map((link) => link.sys.id),
|
|
3355
|
+
entryIds: dedupedEntryLinks.map((link) => link.sys.id),
|
|
3356
|
+
};
|
|
3357
|
+
};
|
|
3358
|
+
|
|
3224
3359
|
const sendMessage = (eventType, data) => {
|
|
3225
3360
|
if (typeof window === 'undefined') {
|
|
3226
3361
|
return;
|
|
@@ -3237,6 +3372,17 @@ const sendMessage = (eventType, data) => {
|
|
|
3237
3372
|
}, '*');
|
|
3238
3373
|
};
|
|
3239
3374
|
|
|
3375
|
+
function deepFreeze(obj) {
|
|
3376
|
+
const propNames = Object.getOwnPropertyNames(obj);
|
|
3377
|
+
for (const name of propNames) {
|
|
3378
|
+
const value = obj[name];
|
|
3379
|
+
if (value && typeof value === 'object') {
|
|
3380
|
+
deepFreeze(value);
|
|
3381
|
+
}
|
|
3382
|
+
}
|
|
3383
|
+
return Object.freeze(obj);
|
|
3384
|
+
}
|
|
3385
|
+
|
|
3240
3386
|
/**
|
|
3241
3387
|
* Base Store for entities
|
|
3242
3388
|
* Can be extended for the different loading behaviours (editor, production, ..)
|
|
@@ -3305,6 +3451,22 @@ class EntityStoreBase {
|
|
|
3305
3451
|
}
|
|
3306
3452
|
return resolvedEntity;
|
|
3307
3453
|
}
|
|
3454
|
+
getAssetById(assetId) {
|
|
3455
|
+
const asset = this.assetMap.get(assetId);
|
|
3456
|
+
if (!asset) {
|
|
3457
|
+
console.warn(`Asset with ID "${assetId}" is not found in the store`);
|
|
3458
|
+
return;
|
|
3459
|
+
}
|
|
3460
|
+
return asset;
|
|
3461
|
+
}
|
|
3462
|
+
getEntryById(entryId) {
|
|
3463
|
+
const entry = this.entryMap.get(entryId);
|
|
3464
|
+
if (!entry) {
|
|
3465
|
+
console.warn(`Entry with ID "${entryId}" is not found in the store`);
|
|
3466
|
+
return;
|
|
3467
|
+
}
|
|
3468
|
+
return entry;
|
|
3469
|
+
}
|
|
3308
3470
|
getEntitiesFromMap(type, ids) {
|
|
3309
3471
|
const resolved = [];
|
|
3310
3472
|
const missing = [];
|
|
@@ -3324,10 +3486,12 @@ class EntityStoreBase {
|
|
|
3324
3486
|
}
|
|
3325
3487
|
addEntity(entity) {
|
|
3326
3488
|
if (isAsset(entity)) {
|
|
3327
|
-
|
|
3489
|
+
// cloned and frozen
|
|
3490
|
+
this.assetMap.set(entity.sys.id, deepFreeze(structuredClone(entity)));
|
|
3328
3491
|
}
|
|
3329
3492
|
else if (isEntry(entity)) {
|
|
3330
|
-
|
|
3493
|
+
// cloned and frozen
|
|
3494
|
+
this.entryMap.set(entity.sys.id, deepFreeze(structuredClone(entity)));
|
|
3331
3495
|
}
|
|
3332
3496
|
else {
|
|
3333
3497
|
throw new Error(`Attempted to add an entity to the store that is neither Asset nor Entry: '${JSON.stringify(entity)}'`);
|
|
@@ -3592,7 +3756,6 @@ class EditorModeEntityStore extends EditorEntityStore {
|
|
|
3592
3756
|
};
|
|
3593
3757
|
};
|
|
3594
3758
|
super({ entities, sendMessage, subscribe, locale, timeoutDuration: REQUEST_TIMEOUT });
|
|
3595
|
-
this.locale = locale;
|
|
3596
3759
|
}
|
|
3597
3760
|
/**
|
|
3598
3761
|
* This function collects and returns the list of requested entries and assets. Additionally, it checks
|
|
@@ -3820,6 +3983,89 @@ class EntityStore extends EntityStoreBase {
|
|
|
3820
3983
|
}
|
|
3821
3984
|
}
|
|
3822
3985
|
|
|
3986
|
+
class UninitializedEntityStore extends EntityStoreBase {
|
|
3987
|
+
constructor() {
|
|
3988
|
+
super({ entities: [], locale: 'uninitialized-locale-in-uninitialized-entity-store' });
|
|
3989
|
+
}
|
|
3990
|
+
}
|
|
3991
|
+
|
|
3992
|
+
const inMemoryEntitiesStore = create((set, get) => ({
|
|
3993
|
+
// The UninitializedEntityStore is a placeholder instance and is here to highlight the
|
|
3994
|
+
// // fact that it's not used by anything until during loading lifecycle it'sreplaced by real entity store:
|
|
3995
|
+
// - in Preview+Delivery mode: right after we fetch Expereince and it entities
|
|
3996
|
+
// - in EDITOR (VisualEditor) mode: right after the VisualEditor is async imported and initialize event happens
|
|
3997
|
+
entityStore: new UninitializedEntityStore(),
|
|
3998
|
+
areEntitiesFetched: false,
|
|
3999
|
+
setEntitiesFetched(fetched) {
|
|
4000
|
+
set({ areEntitiesFetched: fetched });
|
|
4001
|
+
},
|
|
4002
|
+
resolveAssetById(assetId) {
|
|
4003
|
+
if (!assetId)
|
|
4004
|
+
return undefined;
|
|
4005
|
+
const { entityStore } = get();
|
|
4006
|
+
return entityStore.getAssetById(assetId);
|
|
4007
|
+
},
|
|
4008
|
+
resolveEntryById(entryId) {
|
|
4009
|
+
if (!entryId)
|
|
4010
|
+
return undefined;
|
|
4011
|
+
const { entityStore } = get();
|
|
4012
|
+
return entityStore.getEntryById(entryId);
|
|
4013
|
+
},
|
|
4014
|
+
resolveEntity(link) {
|
|
4015
|
+
if (!link)
|
|
4016
|
+
return undefined;
|
|
4017
|
+
const { entityStore } = get();
|
|
4018
|
+
return entityStore.getEntityFromLink(link);
|
|
4019
|
+
},
|
|
4020
|
+
resetEntityStore(entityStore) {
|
|
4021
|
+
set({
|
|
4022
|
+
entityStore,
|
|
4023
|
+
areEntitiesFetched: false,
|
|
4024
|
+
});
|
|
4025
|
+
},
|
|
4026
|
+
}));
|
|
4027
|
+
|
|
4028
|
+
function maybeResolveLink(maybeLink) {
|
|
4029
|
+
if (!isLink(maybeLink)) {
|
|
4030
|
+
console.warn('maybeResolveLink function must receive Link shape. Provided argument does not match the Link shape: ', maybeLink);
|
|
4031
|
+
return undefined;
|
|
4032
|
+
}
|
|
4033
|
+
return inMemoryEntitiesStore.getState().resolveEntity(maybeLink);
|
|
4034
|
+
}
|
|
4035
|
+
function maybeResolveByAssetId(assetId) {
|
|
4036
|
+
return inMemoryEntitiesStore.getState().resolveAssetById(assetId);
|
|
4037
|
+
}
|
|
4038
|
+
function maybeResolveByEntryId(entryId) {
|
|
4039
|
+
return inMemoryEntitiesStore.getState().resolveEntryById(entryId);
|
|
4040
|
+
}
|
|
4041
|
+
function hasEntry(entryId) {
|
|
4042
|
+
return Boolean(maybeResolveByEntryId(entryId));
|
|
4043
|
+
}
|
|
4044
|
+
function hasAsset(assetId) {
|
|
4045
|
+
return Boolean(maybeResolveByAssetId(assetId));
|
|
4046
|
+
}
|
|
4047
|
+
function addEntities(entities) {
|
|
4048
|
+
if (!Array.isArray(entities) || entities.length === 0) {
|
|
4049
|
+
return;
|
|
4050
|
+
}
|
|
4051
|
+
const { entityStore } = inMemoryEntitiesStore.getState();
|
|
4052
|
+
const definedEntities = entities.filter(Boolean);
|
|
4053
|
+
for (const entity of definedEntities) {
|
|
4054
|
+
entityStore.updateEntity(entity);
|
|
4055
|
+
}
|
|
4056
|
+
}
|
|
4057
|
+
const inMemoryEntities = {
|
|
4058
|
+
maybeResolveLink,
|
|
4059
|
+
maybeResolveByAssetId,
|
|
4060
|
+
maybeResolveByEntryId,
|
|
4061
|
+
hasEntry,
|
|
4062
|
+
hasAsset,
|
|
4063
|
+
addEntities,
|
|
4064
|
+
};
|
|
4065
|
+
const useInMemoryEntities = () => {
|
|
4066
|
+
return inMemoryEntities;
|
|
4067
|
+
};
|
|
4068
|
+
|
|
3823
4069
|
var VisualEditorMode;
|
|
3824
4070
|
(function (VisualEditorMode) {
|
|
3825
4071
|
VisualEditorMode["LazyLoad"] = "lazyLoad";
|
|
@@ -3827,11 +4073,9 @@ var VisualEditorMode;
|
|
|
3827
4073
|
})(VisualEditorMode || (VisualEditorMode = {}));
|
|
3828
4074
|
|
|
3829
4075
|
function createExperience(options) {
|
|
4076
|
+
let entityStore;
|
|
3830
4077
|
if (typeof options === 'string') {
|
|
3831
|
-
|
|
3832
|
-
return {
|
|
3833
|
-
entityStore,
|
|
3834
|
-
};
|
|
4078
|
+
entityStore = new EntityStore(options);
|
|
3835
4079
|
}
|
|
3836
4080
|
else {
|
|
3837
4081
|
const { experienceEntry, referencedAssets, referencedEntries, locale } = options;
|
|
@@ -3841,15 +4085,16 @@ function createExperience(options) {
|
|
|
3841
4085
|
if (!isExperienceEntry(experienceEntry)) {
|
|
3842
4086
|
throw new Error('Provided entry is not an experience entry');
|
|
3843
4087
|
}
|
|
3844
|
-
|
|
4088
|
+
entityStore = new EntityStore({
|
|
3845
4089
|
experienceEntry,
|
|
3846
4090
|
entities: [...referencedEntries, ...referencedAssets],
|
|
3847
4091
|
locale,
|
|
3848
4092
|
});
|
|
3849
|
-
return {
|
|
3850
|
-
entityStore,
|
|
3851
|
-
};
|
|
3852
4093
|
}
|
|
4094
|
+
inMemoryEntitiesStore.getState().resetEntityStore(entityStore);
|
|
4095
|
+
return {
|
|
4096
|
+
entityStore,
|
|
4097
|
+
};
|
|
3853
4098
|
}
|
|
3854
4099
|
// Following the API shape, we check the `sys.locale` property as we can't rely on the shape of
|
|
3855
4100
|
// fields to determine whether it's localized or not.
|
|
@@ -4443,5 +4688,5 @@ async function fetchById({ client, experienceTypeId, id, localeCode, isEditorMod
|
|
|
4443
4688
|
}
|
|
4444
4689
|
}
|
|
4445
4690
|
|
|
4446
|
-
export { DebugLogger, DeepReference, EditorModeEntityStore, EntityStore, EntityStoreBase, MEDIA_QUERY_REGEXP, VisualEditorMode, addLocale, addMinHeightForEmptyStructures, breakpointsRegistry, buildCfStyles, buildStyleTag, buildTemplate, builtInStyles, calculateNodeDefaultHeight,
|
|
4691
|
+
export { 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, designTokensRegistry, detachExperienceStyles, disableDebug, dividerBuiltInStyles, doesMismatchMessageSchema, enableDebug, extractLeafLinksReferencedFromExperience, extractReferencesFromEntries, extractReferencesFromEntriesAsIds, fetchAllAssets, fetchAllEntries, fetchById, fetchBySlug, fetchExperienceEntry, fetchReferencedEntities, findOutermostCoordinates, flattenDesignTokenRegistry, gatherDeepReferencesFromExperienceEntry, gatherDeepReferencesFromTree, generateRandomId, getActiveBreakpointIndex, getBreakpointRegistration, getDataFromTree, getDesignTokenRegistration, getElementCoordinates, getFallbackBreakpointIndex, getInsertionData, getTargetValueInPixels, getTemplateValue, getValueForBreakpoint, inMemoryEntities, inMemoryEntitiesStore, indexByBreakpoint, isArrayOfLinks, isAsset, isCfStyleAttribute, isComponentAllowedOnRoot, isContentfulComponent, isContentfulStructureComponent, isDeepPath, isEntry, isExperienceEntry, isLink, isLinkToAsset, isLinkToEntry, isPatternComponent, isPatternEntry, isStructureWithRelativeHeight, isValidBreakpointValue, lastPathNamedSegmentEq, localizeEntity, maybePopulateDesignTokenValue, mediaQueryMatcher, mergeDesignValuesByBreakpoint, optionalBuiltInStyles, parseCSSValue, parseDataSourcePathIntoFieldset, parseDataSourcePathWithL1DeepBindings, referencesOf, resetBreakpointsRegistry, resetDesignTokenRegistry, resolveBackgroundImageBinding, resolveHyperlinkPattern, runBreakpointsValidation, sanitizeNodeProps, sectionBuiltInStyles, sendMessage, singleColumnBuiltInStyles, stringifyCssProperties, toCSSAttribute, toMediaQuery, transformBoundContentValue, transformVisibility, treeMap, treeVisit, tryParseMessage, uniqueById, useInMemoryEntities, validateExperienceBuilderConfig };
|
|
4447
4692
|
//# sourceMappingURL=index.js.map
|