@contentful/experiences-core 1.36.0-dev-20250417T1301-b6204ec.0 → 1.36.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.
|
@@ -12,7 +12,7 @@ declare abstract class EntityStoreBase {
|
|
|
12
12
|
entities: Array<Entry | Asset>;
|
|
13
13
|
locale: string;
|
|
14
14
|
});
|
|
15
|
-
get entities(): (Asset<ChainModifiers, string>
|
|
15
|
+
get entities(): (Entry | Asset<ChainModifiers, string>)[];
|
|
16
16
|
updateEntity(entity: Entry | Asset): void;
|
|
17
17
|
getEntryOrAsset(linkOrEntryOrAsset: UnresolvedLink<'Entry' | 'Asset'> | Asset | Entry, path: string): Entry | Asset | undefined;
|
|
18
18
|
/**
|
|
@@ -24,7 +24,7 @@ declare abstract class EntityStoreBase {
|
|
|
24
24
|
getValue(entityLink: UnresolvedLink<'Entry' | 'Asset'>, path: string[]): string | undefined;
|
|
25
25
|
getEntityFromLink(link: UnresolvedLink<'Entry' | 'Asset'>): Asset | Entry | undefined;
|
|
26
26
|
protected getEntitiesFromMap(type: 'Entry' | 'Asset', ids: string[]): {
|
|
27
|
-
resolved: (Asset<ChainModifiers, string>
|
|
27
|
+
resolved: (Entry | Asset<ChainModifiers, string>)[];
|
|
28
28
|
missing: string[];
|
|
29
29
|
};
|
|
30
30
|
protected addEntity(entity: Entry | Asset): void;
|
package/dist/index.js
CHANGED
|
@@ -1645,69 +1645,6 @@ const resetBreakpointsRegistry = () => {
|
|
|
1645
1645
|
breakpointsRegistry = [];
|
|
1646
1646
|
};
|
|
1647
1647
|
|
|
1648
|
-
function getOptimizedImageUrl(url, width, quality, format) {
|
|
1649
|
-
if (url.startsWith('//')) {
|
|
1650
|
-
url = 'https:' + url;
|
|
1651
|
-
}
|
|
1652
|
-
const params = new URLSearchParams();
|
|
1653
|
-
if (width) {
|
|
1654
|
-
params.append('w', width.toString());
|
|
1655
|
-
}
|
|
1656
|
-
if (quality && quality > 0 && quality < 100) {
|
|
1657
|
-
params.append('q', quality.toString());
|
|
1658
|
-
}
|
|
1659
|
-
if (format) {
|
|
1660
|
-
params.append('fm', format);
|
|
1661
|
-
}
|
|
1662
|
-
const queryString = params.toString();
|
|
1663
|
-
return `${url}${queryString ? '?' + queryString : ''}`;
|
|
1664
|
-
}
|
|
1665
|
-
|
|
1666
|
-
function validateParams(file, quality, format) {
|
|
1667
|
-
if (!file.details.image) {
|
|
1668
|
-
throw Error('No image in file asset to transform');
|
|
1669
|
-
}
|
|
1670
|
-
if (quality < 0 || quality > 100) {
|
|
1671
|
-
throw Error('Quality must be between 0 and 100');
|
|
1672
|
-
}
|
|
1673
|
-
if (format && !SUPPORTED_IMAGE_FORMATS.includes(format)) {
|
|
1674
|
-
throw Error(`Format must be one of ${SUPPORTED_IMAGE_FORMATS.join(', ')}`);
|
|
1675
|
-
}
|
|
1676
|
-
return true;
|
|
1677
|
-
}
|
|
1678
|
-
|
|
1679
|
-
const MAX_WIDTH_ALLOWED$1 = 2000;
|
|
1680
|
-
const getOptimizedBackgroundImageAsset = (file, widthStyle, quality = '100%', format) => {
|
|
1681
|
-
const qualityNumber = Number(quality.replace('%', ''));
|
|
1682
|
-
if (!validateParams(file, qualityNumber, format)) ;
|
|
1683
|
-
if (!validateParams(file, qualityNumber, format)) ;
|
|
1684
|
-
const url = file.url;
|
|
1685
|
-
const { width1x, width2x } = getWidths(widthStyle, file);
|
|
1686
|
-
const imageUrl1x = getOptimizedImageUrl(url, width1x, qualityNumber, format);
|
|
1687
|
-
const imageUrl2x = getOptimizedImageUrl(url, width2x, qualityNumber, format);
|
|
1688
|
-
const srcSet = [`url(${imageUrl1x}) 1x`, `url(${imageUrl2x}) 2x`];
|
|
1689
|
-
const returnedUrl = getOptimizedImageUrl(url, width2x, qualityNumber, format);
|
|
1690
|
-
const optimizedBackgroundImageAsset = {
|
|
1691
|
-
url: returnedUrl,
|
|
1692
|
-
srcSet,
|
|
1693
|
-
file,
|
|
1694
|
-
};
|
|
1695
|
-
return optimizedBackgroundImageAsset;
|
|
1696
|
-
function getWidths(widthStyle, file) {
|
|
1697
|
-
let width1x = 0;
|
|
1698
|
-
let width2x = 0;
|
|
1699
|
-
const intrinsicImageWidth = file.details.image.width;
|
|
1700
|
-
if (widthStyle.endsWith('px')) {
|
|
1701
|
-
width1x = Math.min(Number(widthStyle.replace('px', '')), intrinsicImageWidth);
|
|
1702
|
-
}
|
|
1703
|
-
else {
|
|
1704
|
-
width1x = Math.min(MAX_WIDTH_ALLOWED$1, intrinsicImageWidth);
|
|
1705
|
-
}
|
|
1706
|
-
width2x = Math.min(width1x * 2, intrinsicImageWidth);
|
|
1707
|
-
return { width1x, width2x };
|
|
1708
|
-
}
|
|
1709
|
-
};
|
|
1710
|
-
|
|
1711
1648
|
const detachExperienceStyles = (experience) => {
|
|
1712
1649
|
const experienceTreeRoot = experience.entityStore?.experienceEntryFields
|
|
1713
1650
|
?.componentTree;
|
|
@@ -1727,25 +1664,17 @@ const detachExperienceStyles = (experience) => {
|
|
|
1727
1664
|
}), {});
|
|
1728
1665
|
// getting the breakpoint ids
|
|
1729
1666
|
const breakpointIds = Object.keys(mediaQueryDataByBreakpoint);
|
|
1730
|
-
const iterateOverTreeAndExtractStyles = ({ componentTree, dataSource, unboundValues, componentSettings, componentVariablesOverwrites, patternWrapper, wrappingPatternIds,
|
|
1667
|
+
const iterateOverTreeAndExtractStyles = ({ componentTree, dataSource, unboundValues, componentSettings, componentVariablesOverwrites, patternWrapper, wrappingPatternIds, patternNodeIdsChain = '', }) => {
|
|
1731
1668
|
// traversing the tree
|
|
1732
1669
|
const queue = [];
|
|
1733
|
-
queue.push(...componentTree.children
|
|
1734
|
-
|
|
1735
|
-
parentChain: [...parentChainArr],
|
|
1736
|
-
})));
|
|
1670
|
+
queue.push(...componentTree.children);
|
|
1671
|
+
let currentNode = undefined;
|
|
1737
1672
|
// for each tree node
|
|
1738
1673
|
while (queue.length) {
|
|
1739
|
-
|
|
1740
|
-
if (!queueItem) {
|
|
1741
|
-
break;
|
|
1742
|
-
}
|
|
1743
|
-
const { node: currentNode, parentChain } = queueItem;
|
|
1674
|
+
currentNode = queue.shift();
|
|
1744
1675
|
if (!currentNode) {
|
|
1745
1676
|
break;
|
|
1746
1677
|
}
|
|
1747
|
-
const currentNodeParentChain = [...parentChain, currentNode.id || ''];
|
|
1748
|
-
const currentPatternNodeIdsChain = currentNodeParentChain.join('');
|
|
1749
1678
|
const usedComponents = experience.entityStore?.usedComponents ?? [];
|
|
1750
1679
|
const isPatternNode = checkIsAssemblyNode({
|
|
1751
1680
|
componentId: currentNode.definitionId,
|
|
@@ -1783,7 +1712,7 @@ const detachExperienceStyles = (experience) => {
|
|
|
1783
1712
|
// pass top-level pattern node to store instance-specific child styles for rendering
|
|
1784
1713
|
patternWrapper: currentNode,
|
|
1785
1714
|
wrappingPatternIds: new Set([...wrappingPatternIds, currentNode.definitionId]),
|
|
1786
|
-
|
|
1715
|
+
patternNodeIdsChain: `${patternNodeIdsChain}${currentNode.id}`,
|
|
1787
1716
|
});
|
|
1788
1717
|
continue;
|
|
1789
1718
|
}
|
|
@@ -1869,12 +1798,13 @@ const detachExperienceStyles = (experience) => {
|
|
|
1869
1798
|
// making sure that we respect the order of breakpoints from
|
|
1870
1799
|
// we can achieve "desktop first" or "mobile first" approach to style over-writes
|
|
1871
1800
|
if (patternWrapper) {
|
|
1801
|
+
currentNode.id = currentNode.id || generateRandomId(5);
|
|
1872
1802
|
// @ts-expect-error -- valueByBreakpoint is not explicitly defined, but it's already defined in the patternWrapper styles
|
|
1873
1803
|
patternWrapper.variables.cfSsrClassName = {
|
|
1874
1804
|
...(patternWrapper.variables.cfSsrClassName ?? {}),
|
|
1875
1805
|
type: 'DesignValue',
|
|
1876
1806
|
// Chain IDs to avoid overwriting styles across multiple instances of the same pattern
|
|
1877
|
-
[
|
|
1807
|
+
[`${patternNodeIdsChain}${currentNode.id}`]: {
|
|
1878
1808
|
valuesByBreakpoint: {
|
|
1879
1809
|
[breakpointIds[0]]: currentNodeClassNames.join(' '),
|
|
1880
1810
|
},
|
|
@@ -1889,10 +1819,7 @@ const detachExperienceStyles = (experience) => {
|
|
|
1889
1819
|
},
|
|
1890
1820
|
};
|
|
1891
1821
|
}
|
|
1892
|
-
queue.push(...currentNode.children
|
|
1893
|
-
node: child,
|
|
1894
|
-
parentChain: currentNodeParentChain,
|
|
1895
|
-
})));
|
|
1822
|
+
queue.push(...currentNode.children);
|
|
1896
1823
|
}
|
|
1897
1824
|
};
|
|
1898
1825
|
iterateOverTreeAndExtractStyles({
|
|
@@ -2014,28 +1941,7 @@ const maybePopulateDesignTokenValue = (variableName, variableValue, mapOfDesignV
|
|
|
2014
1941
|
// Not trimming would end up with a trailing space that breaks the check in `calculateNodeDefaultHeight`
|
|
2015
1942
|
return resolvedValue.trim();
|
|
2016
1943
|
};
|
|
2017
|
-
const
|
|
2018
|
-
try {
|
|
2019
|
-
const asset = boundAsset;
|
|
2020
|
-
// Target width (px/rem/em) will be applied to the css url if it's lower than the original image width (in px)
|
|
2021
|
-
const assetDetails = asset.fields.file?.details;
|
|
2022
|
-
const assetWidth = assetDetails?.image?.width || 0; // This is always in px
|
|
2023
|
-
if (!options) {
|
|
2024
|
-
return asset.fields.file?.url;
|
|
2025
|
-
}
|
|
2026
|
-
const targetWidthObject = parseCSSValue(options.targetSize); // Contains value and unit (px/rem/em) so convert and then compare to assetWidth
|
|
2027
|
-
const targetValue = targetWidthObject ? getTargetValueInPixels(targetWidthObject) : assetWidth;
|
|
2028
|
-
if (targetValue < assetWidth)
|
|
2029
|
-
width = `${targetValue}px`;
|
|
2030
|
-
const value = getOptimizedBackgroundImageAsset(asset.fields.file, width, options.quality, options.format);
|
|
2031
|
-
return value;
|
|
2032
|
-
}
|
|
2033
|
-
catch (error) {
|
|
2034
|
-
console.error('Error transforming image asset', error);
|
|
2035
|
-
}
|
|
2036
|
-
return boundAsset.fields.file?.url;
|
|
2037
|
-
};
|
|
2038
|
-
const resolveBackgroundImageBinding = ({ variableData, getBoundEntityById, dataSource = {}, unboundValues = {}, componentVariablesOverwrites, componentSettings = { variableDefinitions: {} }, options, width, }) => {
|
|
1944
|
+
const resolveBackgroundImageBinding = ({ variableData, getBoundEntityById, dataSource = {}, unboundValues = {}, componentVariablesOverwrites, componentSettings = { variableDefinitions: {} }, }) => {
|
|
2039
1945
|
if (variableData.type === 'UnboundValue') {
|
|
2040
1946
|
const uuid = variableData.key;
|
|
2041
1947
|
return unboundValues[uuid]?.value;
|
|
@@ -2060,8 +1966,6 @@ const resolveBackgroundImageBinding = ({ variableData, getBoundEntityById, dataS
|
|
|
2060
1966
|
unboundValues,
|
|
2061
1967
|
componentVariablesOverwrites,
|
|
2062
1968
|
componentSettings,
|
|
2063
|
-
options,
|
|
2064
|
-
width,
|
|
2065
1969
|
});
|
|
2066
1970
|
return resolvedValue || defaultValue;
|
|
2067
1971
|
}
|
|
@@ -2074,7 +1978,7 @@ const resolveBackgroundImageBinding = ({ variableData, getBoundEntityById, dataS
|
|
|
2074
1978
|
return;
|
|
2075
1979
|
}
|
|
2076
1980
|
if (boundEntity.sys.type === 'Asset') {
|
|
2077
|
-
return
|
|
1981
|
+
return boundEntity.fields.file?.url;
|
|
2078
1982
|
}
|
|
2079
1983
|
else {
|
|
2080
1984
|
// '/lUERH7tX7nJTaPX6f0udB/fields/assetReference/~locale/fields/file/~locale'
|
|
@@ -2098,31 +2002,11 @@ const resolveBackgroundImageBinding = ({ variableData, getBoundEntityById, dataS
|
|
|
2098
2002
|
if (!referencedAsset) {
|
|
2099
2003
|
return;
|
|
2100
2004
|
}
|
|
2101
|
-
return
|
|
2005
|
+
return referencedAsset.fields.file?.url;
|
|
2102
2006
|
}
|
|
2103
2007
|
}
|
|
2104
2008
|
}
|
|
2105
2009
|
};
|
|
2106
|
-
const resolveVariable = ({ variableData, defaultBreakpoint, componentSettings = { variableDefinitions: {} }, componentVariablesOverwrites, }) => {
|
|
2107
|
-
if (variableData?.type === 'DesignValue') {
|
|
2108
|
-
return variableData.valuesByBreakpoint[defaultBreakpoint] || {};
|
|
2109
|
-
}
|
|
2110
|
-
else if (variableData?.type === 'ComponentValue') {
|
|
2111
|
-
const variableDefinitionKey = variableData.key;
|
|
2112
|
-
const variableDefinition = componentSettings.variableDefinitions[variableDefinitionKey];
|
|
2113
|
-
const defaultValue = variableDefinition.defaultValue;
|
|
2114
|
-
const userSetValue = componentVariablesOverwrites?.[variableDefinitionKey];
|
|
2115
|
-
if (!userSetValue || userSetValue.type === 'ComponentValue') {
|
|
2116
|
-
return defaultValue?.valuesByBreakpoint[defaultBreakpoint] || '';
|
|
2117
|
-
}
|
|
2118
|
-
return resolveVariable({
|
|
2119
|
-
variableData: userSetValue,
|
|
2120
|
-
defaultBreakpoint,
|
|
2121
|
-
componentSettings,
|
|
2122
|
-
componentVariablesOverwrites,
|
|
2123
|
-
});
|
|
2124
|
-
}
|
|
2125
|
-
};
|
|
2126
2010
|
/**
|
|
2127
2011
|
* Takes the initial set of properties, filters only design properties that will be mapped to CSS and
|
|
2128
2012
|
* re-organizes them to be indexed by breakpoint ID ("breakpoint > variable > value"). It will
|
|
@@ -2173,22 +2057,6 @@ const indexByBreakpoint = ({ variables, breakpointIds, getBoundEntityById, unbou
|
|
|
2173
2057
|
if (variableName === 'cfBackgroundImageUrl' ||
|
|
2174
2058
|
// TODO: Test this for nested patterns as the name might be just a random hash without the actual name (needs to be validated).
|
|
2175
2059
|
variableName.startsWith('cfBackgroundImageUrl_')) {
|
|
2176
|
-
const width = resolveVariable({
|
|
2177
|
-
variableData: variables['cfWidth'],
|
|
2178
|
-
defaultBreakpoint,
|
|
2179
|
-
componentSettings,
|
|
2180
|
-
componentVariablesOverwrites,
|
|
2181
|
-
});
|
|
2182
|
-
const options = resolveVariable({
|
|
2183
|
-
variableData: variables['cfBackgroundImageOptions'],
|
|
2184
|
-
defaultBreakpoint,
|
|
2185
|
-
componentSettings,
|
|
2186
|
-
componentVariablesOverwrites,
|
|
2187
|
-
});
|
|
2188
|
-
if (!options) {
|
|
2189
|
-
console.error(`Error transforming image asset: Required variable [cfBackgroundImageOptions] missing from component definition`);
|
|
2190
|
-
continue;
|
|
2191
|
-
}
|
|
2192
2060
|
const imageUrl = resolveBackgroundImageBinding({
|
|
2193
2061
|
variableData,
|
|
2194
2062
|
getBoundEntityById,
|
|
@@ -2196,8 +2064,6 @@ const indexByBreakpoint = ({ variables, breakpointIds, getBoundEntityById, unbou
|
|
|
2196
2064
|
dataSource,
|
|
2197
2065
|
componentSettings,
|
|
2198
2066
|
componentVariablesOverwrites,
|
|
2199
|
-
width,
|
|
2200
|
-
options,
|
|
2201
2067
|
});
|
|
2202
2068
|
if (imageUrl) {
|
|
2203
2069
|
variableValuesByBreakpoints[defaultBreakpoint][variableName] = imageUrl;
|
|
@@ -2337,6 +2203,69 @@ const resolveLinks = (node, entityStore) => {
|
|
|
2337
2203
|
}
|
|
2338
2204
|
};
|
|
2339
2205
|
|
|
2206
|
+
function getOptimizedImageUrl(url, width, quality, format) {
|
|
2207
|
+
if (url.startsWith('//')) {
|
|
2208
|
+
url = 'https:' + url;
|
|
2209
|
+
}
|
|
2210
|
+
const params = new URLSearchParams();
|
|
2211
|
+
if (width) {
|
|
2212
|
+
params.append('w', width.toString());
|
|
2213
|
+
}
|
|
2214
|
+
if (quality && quality > 0 && quality < 100) {
|
|
2215
|
+
params.append('q', quality.toString());
|
|
2216
|
+
}
|
|
2217
|
+
if (format) {
|
|
2218
|
+
params.append('fm', format);
|
|
2219
|
+
}
|
|
2220
|
+
const queryString = params.toString();
|
|
2221
|
+
return `${url}${queryString ? '?' + queryString : ''}`;
|
|
2222
|
+
}
|
|
2223
|
+
|
|
2224
|
+
function validateParams(file, quality, format) {
|
|
2225
|
+
if (!file.details.image) {
|
|
2226
|
+
throw Error('No image in file asset to transform');
|
|
2227
|
+
}
|
|
2228
|
+
if (quality < 0 || quality > 100) {
|
|
2229
|
+
throw Error('Quality must be between 0 and 100');
|
|
2230
|
+
}
|
|
2231
|
+
if (format && !SUPPORTED_IMAGE_FORMATS.includes(format)) {
|
|
2232
|
+
throw Error(`Format must be one of ${SUPPORTED_IMAGE_FORMATS.join(', ')}`);
|
|
2233
|
+
}
|
|
2234
|
+
return true;
|
|
2235
|
+
}
|
|
2236
|
+
|
|
2237
|
+
const MAX_WIDTH_ALLOWED$1 = 2000;
|
|
2238
|
+
const getOptimizedBackgroundImageAsset = (file, widthStyle, quality = '100%', format) => {
|
|
2239
|
+
const qualityNumber = Number(quality.replace('%', ''));
|
|
2240
|
+
if (!validateParams(file, qualityNumber, format)) ;
|
|
2241
|
+
if (!validateParams(file, qualityNumber, format)) ;
|
|
2242
|
+
const url = file.url;
|
|
2243
|
+
const { width1x, width2x } = getWidths(widthStyle, file);
|
|
2244
|
+
const imageUrl1x = getOptimizedImageUrl(url, width1x, qualityNumber, format);
|
|
2245
|
+
const imageUrl2x = getOptimizedImageUrl(url, width2x, qualityNumber, format);
|
|
2246
|
+
const srcSet = [`url(${imageUrl1x}) 1x`, `url(${imageUrl2x}) 2x`];
|
|
2247
|
+
const returnedUrl = getOptimizedImageUrl(url, width2x, qualityNumber, format);
|
|
2248
|
+
const optimizedBackgroundImageAsset = {
|
|
2249
|
+
url: returnedUrl,
|
|
2250
|
+
srcSet,
|
|
2251
|
+
file,
|
|
2252
|
+
};
|
|
2253
|
+
return optimizedBackgroundImageAsset;
|
|
2254
|
+
function getWidths(widthStyle, file) {
|
|
2255
|
+
let width1x = 0;
|
|
2256
|
+
let width2x = 0;
|
|
2257
|
+
const intrinsicImageWidth = file.details.image.width;
|
|
2258
|
+
if (widthStyle.endsWith('px')) {
|
|
2259
|
+
width1x = Math.min(Number(widthStyle.replace('px', '')), intrinsicImageWidth);
|
|
2260
|
+
}
|
|
2261
|
+
else {
|
|
2262
|
+
width1x = Math.min(MAX_WIDTH_ALLOWED$1, intrinsicImageWidth);
|
|
2263
|
+
}
|
|
2264
|
+
width2x = Math.min(width1x * 2, intrinsicImageWidth);
|
|
2265
|
+
return { width1x, width2x };
|
|
2266
|
+
}
|
|
2267
|
+
};
|
|
2268
|
+
|
|
2340
2269
|
const MAX_WIDTH_ALLOWED = 4000;
|
|
2341
2270
|
const getOptimizedImageAsset = ({ file, sizes, loading, quality = '100%', format, }) => {
|
|
2342
2271
|
const qualityNumber = Number(quality.replace('%', ''));
|