@contentful/experiences-core 3.8.0-dev-20250926T1559-e1ab24d.0 → 3.8.0-prerelease-20250926T1312-a8b5fb7.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
@@ -135,6 +135,7 @@ var PostMessageMethods;
135
135
  PostMessageMethods["REQUESTED_ENTITIES"] = "REQUESTED_ENTITIES";
136
136
  })(PostMessageMethods || (PostMessageMethods = {}));
137
137
  const SUPPORTED_IMAGE_FORMATS = ['jpg', 'png', 'webp', 'gif', 'avif'];
138
+ const SIDELOADED_PREFIX = 'sideloaded_';
138
139
 
139
140
  const structureComponentIds = new Set([
140
141
  CONTENTFUL_COMPONENTS.section.id,
@@ -1997,9 +1998,6 @@ const getPrebindingPathBySourceEntry = (preboundValueProperty, getHeadEntityByDa
1997
1998
  return undefined;
1998
1999
  }
1999
2000
  const contentTypeId = headEntity.sys.contentType.sys.id;
2000
- if (!preboundValueProperty.pathsByContentType?.[contentTypeId]) {
2001
- return undefined;
2002
- }
2003
2001
  return preboundValueProperty.pathsByContentType?.[contentTypeId]?.path;
2004
2002
  };
2005
2003
  const parseDeepPath = (deepPathCandidate) => {
@@ -2423,7 +2421,6 @@ const detachExperienceStyles = (experience) => {
2423
2421
  if (!experienceTreeRoot) {
2424
2422
  return;
2425
2423
  }
2426
- const isRenderingAPatternEntry = experience.entityStore?.isExperienceAPatternEntry;
2427
2424
  const mapOfDesignVariableKeys = flattenDesignTokenRegistry(designTokensRegistry);
2428
2425
  // getting breakpoints from the entry componentTree field
2429
2426
  const { breakpoints } = experienceTreeRoot;
@@ -2438,7 +2435,7 @@ const detachExperienceStyles = (experience) => {
2438
2435
  }), {});
2439
2436
  // getting the breakpoint ids
2440
2437
  const breakpointIds = Object.keys(mediaQueryDataByBreakpoint);
2441
- const iterateOverTreeAndExtractStyles = ({ componentTree, dataSource, unboundValues, componentSettings, componentVariablesOverwrites, patternWrapper, wrappingPatternIds, wrappingPatternNodeIds = isRenderingAPatternEntry ? ['root'] : [], }) => {
2438
+ const iterateOverTreeAndExtractStyles = ({ componentTree, dataSource, unboundValues, componentSettings, componentVariablesOverwrites, patternWrapper, wrappingPatternIds, wrappingPatternNodeIds = [], }) => {
2442
2439
  // traversing the tree
2443
2440
  const queue = [];
2444
2441
  queue.push(...componentTree.children);
@@ -2529,7 +2526,7 @@ const detachExperienceStyles = (experience) => {
2529
2526
  // Chain IDs to avoid overwriting styles across multiple instances of the same pattern
2530
2527
  // e.g. `{outerPatternNodeId}{innerPatternNodeId}-{currentNodeId}`
2531
2528
  // (!) Notice that the chain of patterns (before the dash) follows the format of prebinding/ parameters
2532
- const currentNodeIdsChain = [...wrappingPatternNodeIds, currentNode.id].join('-');
2529
+ const currentNodeIdsChain = `${wrappingPatternNodeIds.join('')}-${currentNode.id}`;
2533
2530
  // For each breakpoint, resolve design tokens, create the CSS and generate a unique className.
2534
2531
  for (const breakpointId of breakpointIds) {
2535
2532
  const propsByBreakpointWithResolvedDesignTokens = Object.entries(propsByBreakpoint[breakpointId]).reduce((acc, [variableName, variableValue]) => {
@@ -3704,7 +3701,7 @@ const generateDefaultDataSourceForPrebindingDefinition = (prebindingDefinitions
3704
3701
  const parameters = {};
3705
3702
  for (const [parameterId, parameterDefinition] of Object.entries(prebindingDefinition.parameterDefinitions ?? {})) {
3706
3703
  if (parameterDefinition.defaultSource && isLink(parameterDefinition.defaultSource.link)) {
3707
- const dataSourceKey = parameterDefinition.defaultSource.link.sys.id;
3704
+ const dataSourceKey = generateRandomId(7);
3708
3705
  dataSource[dataSourceKey] = parameterDefinition.defaultSource.link;
3709
3706
  parameters[parameterId] = {
3710
3707
  type: 'BoundValue',
@@ -4245,9 +4242,6 @@ class EntityStore extends EntityStoreBase {
4245
4242
  this._experienceEntryId = experienceEntry.sys.id;
4246
4243
  this._unboundValues = experienceEntry.fields.unboundValues;
4247
4244
  }
4248
- this._isExperienceAPatternEntry = checkIsAssemblyEntry({
4249
- fields: this._experienceEntryFields,
4250
- });
4251
4245
  // DERIVE ENTITY STORE INSTANCE VARIBLES
4252
4246
  // Register prebindings
4253
4247
  {
@@ -4331,9 +4325,6 @@ class EntityStore extends EntityStoreBase {
4331
4325
  getCurrentLocale() {
4332
4326
  return this.locale;
4333
4327
  }
4334
- get isExperienceAPatternEntry() {
4335
- return this._isExperienceAPatternEntry;
4336
- }
4337
4328
  get hoistedVariableMappings() {
4338
4329
  return this._hoistedVariableMappings;
4339
4330
  }
@@ -5046,6 +5037,92 @@ const removeSelfReferencingDataSource = (experienceEntry) => {
5046
5037
  experienceEntry.fields.dataSource = newDataSource;
5047
5038
  };
5048
5039
 
5040
+ /**
5041
+ * Attaches the default prebinding value (if any) to the experience entry's dataSource.
5042
+ *
5043
+ * This ensures that any default values defined in pattern property definitions are included
5044
+ * in the dataSource, so that linked entities can be fetched and resolved correctly.
5045
+ * Without this, defaults may be omitted, resulting in unresolved references during binding.
5046
+ *
5047
+ * @returns The number of sideloaded default values, or false if the entry is not a pattern.
5048
+ */
5049
+ const sideloadPrebindingDefaultValues = (patternEntry) => {
5050
+ let sideloadedCount = 0;
5051
+ const addDefaultValueToDataSource = (_definitionId, definition) => {
5052
+ if (!definition.defaultSource) {
5053
+ // prebinding preset doesn't have default value, which is perfectly fine
5054
+ return;
5055
+ }
5056
+ const { contentTypeId, link, type, // At the time of writing, it means that defaultSource is a link to a Contentful Entry, but in the future it could be a link to third party resource or smth.
5057
+ // this .type enumeration will not have the same meaning as `Link#sys#linkType`.
5058
+ } = definition.defaultSource;
5059
+ if (!isLink(link)) {
5060
+ // default value is not a link, maybe due to a bug
5061
+ return;
5062
+ }
5063
+ if (!type || !contentTypeId) {
5064
+ // broken data structure, unlikely to happen, only due to a bug
5065
+ return;
5066
+ }
5067
+ // Throw in the link to the default-entry into the dataSource, this way
5068
+ // we rely on the mechanism of fetchReferencedEntities() to "sideload" them.
5069
+ // Keep in mind that dataSource will be available as EntityStore.dataSource
5070
+ // and now will contain also key for `sideloaded_uuid` entry.
5071
+ // When "sideloading" entries into the entityStore, we must ensure that
5072
+ // there's corresponding entry in the dataSource, because all bound variables
5073
+ // are resolved, via path that is indirectly referencing the dataSource,
5074
+ // eg. { type: 'BoundValue', path: '/sideloaded_uuid/fields/title' }
5075
+ patternEntry.fields.dataSource = {
5076
+ ...patternEntry.fields.dataSource,
5077
+ [`${SIDELOADED_PREFIX}${link.sys.id}`]: {
5078
+ // to highlight that this is a sideloaded entry, we prefix it
5079
+ sys: {
5080
+ type: 'Link',
5081
+ linkType: link.sys.linkType,
5082
+ id: link.sys.id,
5083
+ },
5084
+ },
5085
+ };
5086
+ sideloadedCount++;
5087
+ };
5088
+ if (!checkIsAssemblyEntry(patternEntry)) {
5089
+ // Only supported for pattern entries since experience entries don't define pattern properties.
5090
+ return false;
5091
+ }
5092
+ // --------------------
5093
+ // Sideload prebinding values for the L1 parent pattern aka `pA`
5094
+ // --------------------
5095
+ const definitions = patternEntry.fields.componentSettings?.prebindingDefinitions?.[0].parameterDefinitions ?? {};
5096
+ Object.entries(definitions).forEach(([id, definition]) => {
5097
+ addDefaultValueToDataSource(id, definition);
5098
+ });
5099
+ // --------------------
5100
+ // Sideload all default values for the L2 nested patterns, patterns aka`pB`
5101
+ // --------------------
5102
+ const nestedPatternEntriesLevel2 = (patternEntry.fields.usedComponents || []).filter((component) => component !== undefined && checkIsAssemblyEntry(component));
5103
+ nestedPatternEntriesLevel2.forEach((patternEntry) => {
5104
+ const parameterDefinitions = patternEntry.fields.componentSettings?.prebindingDefinitions?.[0].parameterDefinitions ?? {};
5105
+ Object.entries(parameterDefinitions).forEach(([id, definition]) => {
5106
+ addDefaultValueToDataSource(id, definition);
5107
+ });
5108
+ });
5109
+ // --------------------
5110
+ // Sideload all default values for the L3 nested patterns, patterns aka `pC`
5111
+ // --------------------
5112
+ const nestedPatternEntriesLevel3 = nestedPatternEntriesLevel2.flatMap((patternEntryLevel2) => {
5113
+ const usedComponents = patternEntryLevel2.fields.usedComponents || [];
5114
+ const filteredUsedComponents = usedComponents.filter((component) => component !== undefined && checkIsAssemblyEntry(component));
5115
+ return filteredUsedComponents;
5116
+ });
5117
+ nestedPatternEntriesLevel3.forEach((patternEntry) => {
5118
+ const parameterDefinitions = patternEntry.fields.componentSettings?.prebindingDefinitions?.[0].parameterDefinitions ?? {};
5119
+ Object.entries(parameterDefinitions).forEach(([id, definition]) => {
5120
+ addDefaultValueToDataSource(id, definition);
5121
+ });
5122
+ });
5123
+ return sideloadedCount;
5124
+ };
5125
+
5049
5126
  /**
5050
5127
  * Run additional checks on the references used in the experience entry and
5051
5128
  * process data required for prebinding. This must be used after fetching an
@@ -5056,6 +5133,7 @@ const removeSelfReferencingDataSource = (experienceEntry) => {
5056
5133
  const prepareExperienceEntry = (experienceEntry) => {
5057
5134
  removeCircularPatternReferences(experienceEntry);
5058
5135
  removeSelfReferencingDataSource(experienceEntry);
5136
+ sideloadPrebindingDefaultValues(experienceEntry);
5059
5137
  };
5060
5138
 
5061
5139
  const errorMessagesWhileFetching$1 = {