@contentful/experiences-core 3.3.0 → 3.3.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/exports.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export { ASSEMBLY_BLOCK_NODE_TYPE, ASSEMBLY_DEFAULT_CATEGORY, ASSEMBLY_NODE_TYPE, ASSEMBLY_NODE_TYPES, CF_STYLE_ATTRIBUTES, CONTENTFUL_COMPONENTS, CONTENTFUL_COMPONENT_CATEGORY, CONTENTFUL_DEFAULT_CATEGORY, EMPTY_CONTAINER_SIZE, HYPERLINK_DEFAULT_PATTERN, INCOMING_EVENTS, INTERNAL_EVENTS, LATEST_SCHEMA_VERSION, OUTGOING_EVENTS, PATTERN_PROPERTY_DIVIDER, PostMessageMethods, SCROLL_STATES, SIDELOADED_PREFIX, SUPPORTED_IMAGE_FORMATS, StudioCanvasMode, VISUAL_EDITOR_CONTAINER_ID, VISUAL_EDITOR_EVENTS } from './constants.js';
2
- export { AssembliesAddedPayload, AssembliesRegisteredPayload, BackgroundImageAlignmentOption, BackgroundImageOptions, BackgroundImageScalingOption, Binding, BindingMap, BindingMapByBlockId, BoundComponentPropertyTypes, CSSProperties, CanvasErrorPayload, CanvasGeometryUpdateSourceEvent, CanvasReloadPayload, CanvasResizedPayload, CanvasScrollPayload, ComponentBinding, ComponentDefinition, ComponentDefinitionVariable, ComponentDefinitionVariableBase, ComponentDefinitionVariableTypeMap, ComponentDefinitionVariableValidation, ComponentDragCanceledPayload, ComponentDragEndedPayload, ComponentDragStartedPayload, ComponentDraggingChangedPayload, ComponentDroppedPayload, ComponentMoveEndedPayload, ComponentMoveStartedPayload, ComponentMovedPayload, ComponentRegistration, ComponentRegistrationOptions, ComponentSelectedPayload, ConnectedPayload, ContainerStyleVariableName, Coordinates, DataSourceEntryValueType, DesignTokensDefinition, DesignTokensPayload, DesignVariableMap, DesignVariableTypes, Experience, ExperienceEntry, ExperienceFields, ExperienceTree, ExperienceTreeNode, ExperienceUpdatedPayload, HoverComponentPayload, HoveredElement, ImageLoadingOption, ImageObjectFitOption, ImageObjectPositionOption, ImageOptions, IncomingComponentDragCanceledPayload, IncomingComponentMoveEndedPayload, IncomingEvent, IncomingMessage, IncomingMouseMovePayload, InternalEvent, Link, ManagementEntity, MouseMovePayload, NewHoveredElementPayload, OptimizedBackgroundImageAsset, OptimizedImageAsset, OutgoingEvent, OutgoingMessage, OutsideCanvasClickPayload, RawCoordinates, RecursiveDesignTokenDefinition, RegisteredBreakpointsPayload, RegisteredComponentsPayload, RequestComponentTreeUpdatePayload, RequestEditorModePayload, RequestEntitiesMessage, RequestEntitiesPayload, RequestReadOnlyModePayload, RequestedEntitiesMessage, RequestedEntitiesPayload, ResolveDesignValueType, SDKFeaturesPayload, ScrollState, SelectComponentPayload, SendMessageParams, StructureComponentProps, StyleProps, UpdateSelectedComponentCoordinatesPayload, UpdatedEntityPayload, ValidationOption, VariableFormats } from './types.js';
2
+ export { AssembliesAddedPayload, AssembliesRegisteredPayload, BackgroundImageAlignmentOption, BackgroundImageOptions, BackgroundImageScalingOption, Binding, BindingMap, BindingMapByBlockId, BoundComponentPropertyTypes, CSSProperties, CanvasErrorPayload, CanvasGeometryUpdateSourceEvent, CanvasReloadPayload, CanvasResizedPayload, CanvasScrollPayload, ComponentBinding, ComponentDefinition, ComponentDefinitionVariable, ComponentDefinitionVariableBase, ComponentDefinitionVariableTypeMap, ComponentDefinitionVariableValidation, ComponentDragCanceledPayload, ComponentDragEndedPayload, ComponentDragStartedPayload, ComponentDraggingChangedPayload, ComponentDroppedPayload, ComponentMoveEndedPayload, ComponentMoveStartedPayload, ComponentMovedPayload, ComponentRegistration, ComponentRegistrationOptions, ComponentSelectedPayload, ConnectedPayload, ContainerStyleVariableName, Coordinates, DataSourceEntryValueType, DesignTokensDefinition, DesignTokensPayload, DesignVariableMap, DesignVariableTypes, Experience, ExperienceEntry, ExperienceFields, ExperienceTree, ExperienceTreeNode, ExperienceUpdatedPayload, HoverComponentPayload, HoveredElement, ImageLoadingOption, ImageObjectFitOption, ImageObjectPositionOption, ImageOptions, IncomingComponentDragCanceledPayload, IncomingComponentMoveEndedPayload, IncomingEvent, IncomingMessage, IncomingMouseMovePayload, InternalEvent, Link, ManagementEntity, MouseMovePayload, NewHoveredElementPayload, OptimizedBackgroundImageAsset, OptimizedImageAsset, OutgoingEvent, OutgoingMessage, OutsideCanvasClickPayload, RawCoordinates, RecursiveDesignTokenDefinition, RegisteredBreakpointsPayload, RegisteredComponentsPayload, RequestComponentTreeUpdatePayload, RequestEditorModePayload, RequestEntitiesMessage, RequestEntitiesPayload, RequestReadOnlyModePayload, RequestedEntitiesMessage, RequestedEntitiesPayload, ResolveDesignValueType, SDKFeaturesPayload, ScrollState, SdkOptions, SelectComponentPayload, SendMessageParams, StructureComponentProps, StyleProps, UpdateSelectedComponentCoordinatesPayload, UpdatedEntityPayload, ValidationOption, VariableFormats } from './types.js';
3
3
  export { BoundValue, Breakpoint, ComponentDefinitionPropertyType as ComponentDefinitionVariableType, ComponentPropertyValue, ComponentTreeNode, ComponentValue, DesignValue, ExperienceComponentSettings, ExperienceDataSource, ExperienceUnboundValues, NoValue, Parameter, ParameterDefinition, PrimitiveValue, SchemaVersions, UnboundValue, ValuesByBreakpoint, VariableMapping } from '@contentful/experiences-validators';
package/dist/index.d.ts CHANGED
@@ -20,6 +20,7 @@ export { checkIsAssemblyDefinition, checkIsAssemblyEntry, checkIsAssemblyNode, g
20
20
  export { doesMismatchMessageSchema, tryParseMessage, validateExperienceBuilderConfig } from './utils/validations.js';
21
21
  export { extractLeafLinksReferencedFromExperience } from './utils/schema/experienceSchema.js';
22
22
  export { FnShouldFollowReferencesOfEntryField, extractReferencesFromEntries, extractReferencesFromEntriesAsIds, referencesOf, uniqueById } from './utils/schema/references.js';
23
+ export { splitDirectAndSlotChildren } from './utils/splitDirectAndSlotChildren.js';
23
24
  export { builtInStyles, columnsBuiltInStyles, containerBuiltInStyles, dividerBuiltInStyles, optionalBuiltInStyles, sectionBuiltInStyles, singleColumnBuiltInStyles } from './definitions/styles.js';
24
25
  export { EditorModeEntityStore } from './entity/EditorModeEntityStore.js';
25
26
  export { EntityStore } from './entity/EntityStore.js';
@@ -36,4 +37,5 @@ export { fetchReferencedEntities } from './fetchers/fetchReferencedEntities.js';
36
37
  export { fetchExperienceEntry } from './fetchers/fetchExperienceEntry.js';
37
38
  export { defineDesignTokens, designTokensRegistry, getDesignTokenRegistration, resetDesignTokenRegistry } from './registries/designTokenRegistry.js';
38
39
  export { breakpointsRegistry, defineBreakpoints, getBreakpointRegistration, resetBreakpointsRegistry, runBreakpointsValidation } from './registries/breakpointsRegistry.js';
40
+ export { defineSdkOptions, getSdkOptions, sdkOptionsRegistry } from './registries/sdkOptionsRegistry.js';
39
41
  export { DeepReference, gatherDeepReferencesFromExperienceEntry, gatherDeepReferencesFromTree } from './deep-binding/DeepReference.js';
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { z, ZodIssueCode } from 'zod';
2
- import { omit, isArray, uniqBy } from 'lodash-es';
2
+ import { cloneDeep, omit, isArray, uniqBy } from 'lodash-es';
3
3
  import md5 from 'md5';
4
4
  import { BLOCKS } from '@contentful/rich-text-types';
5
5
  import { create } from 'zustand';
@@ -1383,6 +1383,18 @@ const resetBreakpointsRegistry = () => {
1383
1383
  breakpointsRegistry = [];
1384
1384
  };
1385
1385
 
1386
+ const sdkOptionsRegistry = {};
1387
+ /**
1388
+ * Used inside defineComponents to forward registry arguments to this registry
1389
+ * of SDK options.
1390
+ */
1391
+ const defineSdkOptions = (options) => {
1392
+ Object.assign(sdkOptionsRegistry, options);
1393
+ };
1394
+ const getSdkOptions = () => {
1395
+ return { ...sdkOptionsRegistry };
1396
+ };
1397
+
1386
1398
  const MEDIA_QUERY_REGEXP = /(<|>)(\d{1,})(px|cm|mm|in|pt|pc)$/;
1387
1399
  const toCSSMediaQuery = ({ query }) => {
1388
1400
  if (query === '*')
@@ -1743,7 +1755,7 @@ function localizeEntity(entity, locale) {
1743
1755
  if (entity.sys.locale) {
1744
1756
  return entity;
1745
1757
  }
1746
- const cloned = structuredClone(entity);
1758
+ const cloned = cloneDeep(entity);
1747
1759
  // Set the requested locale as entry locale to follow the API shape:
1748
1760
  // https://www.contentful.com/developers/docs/references/content-delivery-api/#/introduction/common-resource-attributes
1749
1761
  cloned.sys.locale = locale;
@@ -2053,6 +2065,20 @@ const transformBackgroundImage = (cfBackgroundImageUrl, cfBackgroundImageOptions
2053
2065
  backgroundSize: matchBackgroundSize(cfBackgroundImageOptions?.scaling),
2054
2066
  };
2055
2067
  };
2068
+ const transformTextAlign = (value) => {
2069
+ if (!value)
2070
+ return undefined;
2071
+ const sdkOptions = getSdkOptions();
2072
+ // New behavior: translate left/right to start/end
2073
+ // Customer can opt-out by activating this global option toggle
2074
+ if (!sdkOptions.__disableTextAlignmentTransform) {
2075
+ if (value === 'left')
2076
+ return 'start';
2077
+ if (value === 'right')
2078
+ return 'end';
2079
+ }
2080
+ return value;
2081
+ };
2056
2082
 
2057
2083
  const toCSSAttribute = (key) => {
2058
2084
  let val = key.replace(/[A-Z]/g, (m) => '-' + m.toLowerCase());
@@ -2130,7 +2156,7 @@ const buildCfStyles = (values) => {
2130
2156
  lineHeight: values.cfLineHeight,
2131
2157
  letterSpacing: values.cfLetterSpacing,
2132
2158
  color: values.cfTextColor,
2133
- textAlign: values.cfTextAlign,
2159
+ textAlign: transformTextAlign(values.cfTextAlign),
2134
2160
  textTransform: values.cfTextTransform,
2135
2161
  objectFit: values.cfImageOptions?.objectFit,
2136
2162
  objectPosition: values.cfImageOptions?.objectPosition,
@@ -2894,7 +2920,7 @@ const transformRichText = (entryOrAsset, entityStore, path) => {
2894
2920
  // resolve any links to assets/entries/hyperlinks
2895
2921
  // we need to clone, as we want to keep the original Entity in the EntityStore intact,
2896
2922
  // and resolveLinks() is mutating the node object.
2897
- const richTextDocument = structuredClone(value);
2923
+ const richTextDocument = cloneDeep(value);
2898
2924
  resolveLinks(richTextDocument, entityStore);
2899
2925
  return richTextDocument;
2900
2926
  }
@@ -3427,6 +3453,27 @@ const extractLeafLinksReferencedFromExperience = (experience) => {
3427
3453
  };
3428
3454
  };
3429
3455
 
3456
+ const splitDirectAndSlotChildren = (allChildNodes, componentDefinition) => {
3457
+ // Bridge difference between editor and delivery mode
3458
+ const getSlotId = (child) => {
3459
+ if ('data' in child)
3460
+ return child.data.slotId;
3461
+ return child.slotId;
3462
+ };
3463
+ const slotNodesMap = {};
3464
+ for (const slotId in componentDefinition.slots) {
3465
+ // We only allow one component per slot (container). This is just safer to not render components twice or not at all
3466
+ const nodes = allChildNodes.filter((child) => getSlotId(child) === slotId);
3467
+ slotNodesMap[slotId] = nodes.length ? nodes : null;
3468
+ }
3469
+ const directChildNodes = allChildNodes.filter((child) => getSlotId(child) === undefined);
3470
+ if (!componentDefinition.children || !directChildNodes.length) {
3471
+ // If there are no children allowed in the component or no children added, render as undefined
3472
+ return { slotNodesMap, directChildNodes: undefined };
3473
+ }
3474
+ return { slotNodesMap, directChildNodes };
3475
+ };
3476
+
3430
3477
  const sendMessage = (eventType, data) => {
3431
3478
  if (typeof window === 'undefined') {
3432
3479
  return;
@@ -3558,11 +3605,11 @@ class EntityStoreBase {
3558
3605
  addEntity(entity) {
3559
3606
  if (isAsset(entity)) {
3560
3607
  // cloned and frozen
3561
- this.assetMap.set(entity.sys.id, deepFreeze(structuredClone(entity)));
3608
+ this.assetMap.set(entity.sys.id, deepFreeze(cloneDeep(entity)));
3562
3609
  }
3563
3610
  else if (isEntry(entity)) {
3564
3611
  // cloned and frozen
3565
- this.entryMap.set(entity.sys.id, deepFreeze(structuredClone(entity)));
3612
+ this.entryMap.set(entity.sys.id, deepFreeze(cloneDeep(entity)));
3566
3613
  }
3567
3614
  else {
3568
3615
  throw new Error(`Attempted to add an entity to the store that is neither Asset nor Entry: '${JSON.stringify(entity)}'`);
@@ -4656,6 +4703,19 @@ const sideloadPrebindingDefaultValues = (patternEntry) => {
4656
4703
  return sideloadedCount;
4657
4704
  };
4658
4705
 
4706
+ /**
4707
+ * Run additional checks on the references used in the experience entry and
4708
+ * process data required for prebinding. This must be used after fetching an
4709
+ * experience entry.
4710
+ *
4711
+ * The changes made to the passed experience entry are done inplace.
4712
+ **/
4713
+ const prepareExperienceEntry = (experienceEntry) => {
4714
+ removeCircularPatternReferences(experienceEntry);
4715
+ removeSelfReferencingDataSource(experienceEntry);
4716
+ sideloadPrebindingDefaultValues(experienceEntry);
4717
+ };
4718
+
4659
4719
  const errorMessagesWhileFetching$1 = {
4660
4720
  experience: 'Failed to fetch experience',
4661
4721
  experienceReferences: 'Failed to fetch entities, referenced in experience',
@@ -4689,9 +4749,7 @@ async function fetchBySlug({ client, experienceTypeId, slug, localeCode, isEdito
4689
4749
  if (!experienceEntry) {
4690
4750
  throw new Error(`No experience entry with slug: ${slug} exists`);
4691
4751
  }
4692
- removeCircularPatternReferences(experienceEntry);
4693
- removeSelfReferencingDataSource(experienceEntry);
4694
- sideloadPrebindingDefaultValues(experienceEntry);
4752
+ prepareExperienceEntry(experienceEntry);
4695
4753
  try {
4696
4754
  const { entries, assets } = await fetchReferencedEntities({
4697
4755
  client,
@@ -4748,9 +4806,7 @@ async function fetchById({ client, experienceTypeId, id, localeCode, isEditorMod
4748
4806
  if (!experienceEntry) {
4749
4807
  throw new Error(`No experience entry with id: ${id} exists`);
4750
4808
  }
4751
- removeCircularPatternReferences(experienceEntry);
4752
- removeSelfReferencingDataSource(experienceEntry);
4753
- sideloadPrebindingDefaultValues(experienceEntry);
4809
+ prepareExperienceEntry(experienceEntry);
4754
4810
  try {
4755
4811
  const { entries, assets } = await fetchReferencedEntities({
4756
4812
  client,
@@ -4774,5 +4830,5 @@ async function fetchById({ client, experienceTypeId, id, localeCode, isEditorMod
4774
4830
  }
4775
4831
  }
4776
4832
 
4777
- export { BREAKPOINTS_STRATEGY_DESKTOP_FIRST, BREAKPOINTS_STRATEGY_MOBILE_FIRST, 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, detectBreakpointsStrategy, disableDebug, dividerBuiltInStyles, doesMismatchMessageSchema, enableDebug, extractLeafLinksReferencedFromExperience, extractReferencesFromEntries, extractReferencesFromEntriesAsIds, fetchAllAssets, fetchAllEntries, fetchById, fetchBySlug, fetchExperienceEntry, fetchReferencedEntities, findOutermostCoordinates, flattenDesignTokenRegistry, gatherDeepReferencesFromExperienceEntry, gatherDeepReferencesFromTree, generateRandomId, getActiveBreakpointIndex, getBreakpointRegistration, getDataFromTree, getDesignTokenRegistration, getElementCoordinates, getFallbackBreakpointIndex, getPrebindingPathBySourceEntry, getTargetValueInPixels, getTemplateValue, getValueForBreakpoint, inMemoryEntities, inMemoryEntitiesStore, indexByBreakpoint, isArrayOfLinks, isAsset, isCfStyleAttribute, isComponentAllowedOnRoot, isContentfulComponent, isContentfulStructureComponent, isDeepPath, isDeepPrebinding, isElementHidden, isEntry, isExperienceEntry, isLink, isLinkToAsset, isLinkToEntry, isPatternComponent, isPatternEntry, isPreboundProp, 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 };
4833
+ export { BREAKPOINTS_STRATEGY_DESKTOP_FIRST, BREAKPOINTS_STRATEGY_MOBILE_FIRST, 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, defineSdkOptions, designTokensRegistry, detachExperienceStyles, detectBreakpointsStrategy, disableDebug, dividerBuiltInStyles, doesMismatchMessageSchema, enableDebug, extractLeafLinksReferencedFromExperience, extractReferencesFromEntries, extractReferencesFromEntriesAsIds, fetchAllAssets, fetchAllEntries, fetchById, fetchBySlug, fetchExperienceEntry, fetchReferencedEntities, findOutermostCoordinates, flattenDesignTokenRegistry, gatherDeepReferencesFromExperienceEntry, gatherDeepReferencesFromTree, generateRandomId, getActiveBreakpointIndex, getBreakpointRegistration, getDataFromTree, getDesignTokenRegistration, getElementCoordinates, getFallbackBreakpointIndex, getPrebindingPathBySourceEntry, getSdkOptions, getTargetValueInPixels, getTemplateValue, getValueForBreakpoint, inMemoryEntities, inMemoryEntitiesStore, indexByBreakpoint, isArrayOfLinks, isAsset, isCfStyleAttribute, isComponentAllowedOnRoot, isContentfulComponent, isContentfulStructureComponent, isDeepPath, isDeepPrebinding, isElementHidden, isEntry, isExperienceEntry, isLink, isLinkToAsset, isLinkToEntry, isPatternComponent, isPatternEntry, isPreboundProp, isStructureWithRelativeHeight, isValidBreakpointValue, lastPathNamedSegmentEq, localizeEntity, maybePopulateDesignTokenValue, mediaQueryMatcher, mergeDesignValuesByBreakpoint, optionalBuiltInStyles, parseCSSValue, parseDataSourcePathIntoFieldset, parseDataSourcePathWithL1DeepBindings, referencesOf, resetBreakpointsRegistry, resetDesignTokenRegistry, resolveBackgroundImageBinding, resolveHyperlinkPattern, runBreakpointsValidation, sanitizeNodeProps, sdkOptionsRegistry, sectionBuiltInStyles, sendMessage, singleColumnBuiltInStyles, splitDirectAndSlotChildren, stringifyCssProperties, toCSSAttribute, toMediaQuery, transformBoundContentValue, transformVisibility, treeMap, treeVisit, tryParseMessage, uniqueById, useInMemoryEntities, validateExperienceBuilderConfig };
4778
4834
  //# sourceMappingURL=index.js.map