@contentful/experiences-sdk-react 3.8.0-beta.1 → 3.8.0-beta.3
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/blocks/preview/CompositionBlock.js +43 -36
- package/dist/blocks/preview/CompositionBlock.js.map +1 -1
- package/dist/blocks/preview/PreviewDeliveryRoot.js +18 -1
- package/dist/blocks/preview/PreviewDeliveryRoot.js.map +1 -1
- package/dist/core/preview/PrebindingManager.js +249 -0
- package/dist/core/preview/PrebindingManager.js.map +1 -0
- package/dist/core/preview/assemblyUtils.js +74 -38
- package/dist/core/preview/assemblyUtils.js.map +1 -1
- package/dist/core/sdkFeatures.js +1 -0
- package/dist/core/sdkFeatures.js.map +1 -1
- package/dist/core/styles/createStylesheetsForBuiltInStyles.js +1 -1
- package/dist/core/styles/createStylesheetsForBuiltInStyles.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/sdkVersion.js +1 -1
- package/dist/sdkVersion.js.map +1 -1
- package/dist/src/blocks/preview/CompositionBlock.d.ts +3 -3
- package/dist/src/blocks/preview/PreviewDeliveryRoot.d.ts +1 -1
- package/dist/src/core/preview/PrebindingManager.d.ts +152 -0
- package/dist/src/core/preview/PrebindingManager.test.d.ts +1 -0
- package/dist/src/core/preview/__fixtures__.d.ts +517 -0
- package/dist/src/core/preview/assemblyUtils.d.ts +17 -8
- package/dist/src/core/styles/createStylesheetsForBuiltInStyles.d.ts +1 -1
- package/dist/src/sdkVersion.d.ts +1 -1
- package/dist/src/utils/parseComponentProps.d.ts +9 -3
- package/dist/src/utils/prebindingUtils.d.ts +6 -3
- package/dist/test/__fixtures__/assembly.d.ts +5 -2
- package/dist/utils/parseComponentProps.js +2 -2
- package/dist/utils/parseComponentProps.js.map +1 -1
- package/dist/utils/prebindingUtils.js +26 -12
- package/dist/utils/prebindingUtils.js.map +1 -1
- package/package.json +6 -6
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import React, { useMemo } from 'react';
|
|
3
|
-
import { checkIsAssemblyNode,
|
|
3
|
+
import { checkIsAssemblyNode, transformBoundContentValue, resolveHyperlinkPattern, splitDirectAndSlotChildren, getSdkOptions, sanitizeNodeProps } from '@contentful/experiences-core';
|
|
4
4
|
import { HYPERLINK_DEFAULT_PATTERN, CONTENTFUL_COMPONENTS } from '@contentful/experiences-core/constants';
|
|
5
5
|
import { getComponentRegistration, createAssemblyRegistration } from '../../core/componentRegistry.js';
|
|
6
6
|
import { useInjectStylesheet } from '../../hooks/useInjectStylesheet.js';
|
|
@@ -9,51 +9,53 @@ import { resolvePattern } from '../../core/preview/assemblyUtils.js';
|
|
|
9
9
|
import { resolveMaybePrebindingDefaultValuePath } from '../../utils/prebindingUtils.js';
|
|
10
10
|
import { parseComponentProps } from '../../utils/parseComponentProps.js';
|
|
11
11
|
|
|
12
|
-
const CompositionBlock = ({ node: rawNode, locale, entityStore, hyperlinkPattern, resolveDesignValue, getPatternChildNodeClassName, wrappingPatternIds: parentWrappingPatternIds = new Set(),
|
|
12
|
+
const CompositionBlock = ({ node: rawNode, locale, entityStore, hyperlinkPattern, resolveDesignValue, getPatternChildNodeClassName, wrappingPatternIds: parentWrappingPatternIds = new Set(), patternRootNodeIdsChain: parentPatternRootNodeIdsChain = [], rootPatternParameters, }) => {
|
|
13
13
|
const isPatternNode = useMemo(() => {
|
|
14
14
|
return checkIsAssemblyNode({
|
|
15
15
|
componentId: rawNode.definitionId,
|
|
16
16
|
usedComponents: entityStore.usedComponents,
|
|
17
17
|
});
|
|
18
18
|
}, [entityStore.usedComponents, rawNode.definitionId]);
|
|
19
|
-
const isPatternEntry = useMemo(() => {
|
|
20
|
-
return checkIsAssemblyEntry({ fields: entityStore.experienceEntryFields });
|
|
21
|
-
}, [entityStore]);
|
|
22
19
|
const patternRootNodeIdsChain = useMemo(() => {
|
|
23
20
|
if (isPatternNode) {
|
|
24
21
|
// Pattern nodes are chained without a separator (following the format for prebinding/parameters)
|
|
25
|
-
return
|
|
22
|
+
return [...parentPatternRootNodeIdsChain, rawNode.id];
|
|
26
23
|
}
|
|
27
24
|
return parentPatternRootNodeIdsChain;
|
|
28
25
|
}, [isPatternNode, parentPatternRootNodeIdsChain, rawNode.id]);
|
|
26
|
+
const rootParameters = useMemo(() => {
|
|
27
|
+
// covers the case when previewing a pattern
|
|
28
|
+
// all parameters are defined on the tree root node and will be provided from the start
|
|
29
|
+
if (rootPatternParameters) {
|
|
30
|
+
return rootPatternParameters;
|
|
31
|
+
}
|
|
32
|
+
// covers the case when previewing an experience
|
|
33
|
+
// parameters here are stored in CMA, so we retrieve them from the pattern's node and pass it down
|
|
34
|
+
if (isPatternNode && rawNode.parameters && Object.keys(rawNode.parameters).length) {
|
|
35
|
+
return rawNode.parameters;
|
|
36
|
+
}
|
|
37
|
+
// in case none exist - it is likely a non-pattern component, or just a pattern that has no parameters
|
|
38
|
+
return undefined;
|
|
39
|
+
}, [rawNode, rootPatternParameters, isPatternNode]);
|
|
29
40
|
const node = useMemo(() => {
|
|
30
41
|
if (isPatternNode) {
|
|
31
42
|
return resolvePattern({
|
|
32
43
|
node: rawNode,
|
|
33
44
|
entityStore,
|
|
34
|
-
|
|
35
|
-
|
|
45
|
+
parentPatternRootNodeIdsChain: patternRootNodeIdsChain,
|
|
46
|
+
rootPatternParameters: rootParameters,
|
|
36
47
|
});
|
|
37
48
|
}
|
|
38
49
|
else {
|
|
39
50
|
return rawNode;
|
|
40
51
|
}
|
|
41
|
-
}, [entityStore, isPatternNode, rawNode,
|
|
52
|
+
}, [entityStore, isPatternNode, rawNode, patternRootNodeIdsChain, rootParameters]);
|
|
42
53
|
const wrappingPatternIds = useMemo(() => {
|
|
43
54
|
if (isPatternNode) {
|
|
44
55
|
return new Set([node.definitionId, ...parentWrappingPatternIds]);
|
|
45
56
|
}
|
|
46
57
|
return parentWrappingPatternIds;
|
|
47
58
|
}, [isPatternNode, node, parentWrappingPatternIds]);
|
|
48
|
-
// Merge the pattern properties of the current node with the parent's pattern properties
|
|
49
|
-
// to ensure nested patterns receive relevant pattern properties that were bubbled up
|
|
50
|
-
// during assembly serialization.
|
|
51
|
-
const wrappingParameters = useMemo(() => {
|
|
52
|
-
if (isPatternNode) {
|
|
53
|
-
return { ...parentWrappingParameters, ...(rawNode.parameters || {}) };
|
|
54
|
-
}
|
|
55
|
-
return parentWrappingParameters;
|
|
56
|
-
}, [isPatternNode, rawNode, parentWrappingParameters]);
|
|
57
59
|
const componentRegistration = useMemo(() => {
|
|
58
60
|
const registration = getComponentRegistration(node.definitionId);
|
|
59
61
|
if (isPatternNode && !registration) {
|
|
@@ -93,6 +95,10 @@ const CompositionBlock = ({ node: rawNode, locale, entityStore, hyperlinkPattern
|
|
|
93
95
|
resolveBoundValue: ({ binding, propertyName, dataType }) => {
|
|
94
96
|
const [, uuid] = binding.path.split('/');
|
|
95
97
|
const boundEntityLink = entityStore.dataSource[uuid];
|
|
98
|
+
// TODO: Temporary fix while we look into SPA-3212 it occurs where we have prebound props but data source link is missing
|
|
99
|
+
// this only occurs after live updates of nested patterns.
|
|
100
|
+
if (!boundEntityLink)
|
|
101
|
+
return;
|
|
96
102
|
return transformBoundContentValue(node.variables, entityStore, boundEntityLink, resolveDesignValue, propertyName, dataType, binding.path);
|
|
97
103
|
},
|
|
98
104
|
resolveHyperlinkValue: ({ linkTargetKey }) => {
|
|
@@ -105,22 +111,24 @@ const CompositionBlock = ({ node: rawNode, locale, entityStore, hyperlinkPattern
|
|
|
105
111
|
resolveUnboundValue: ({ mappingKey, defaultValue }) => {
|
|
106
112
|
return entityStore.unboundValues[mappingKey]?.value ?? defaultValue;
|
|
107
113
|
},
|
|
108
|
-
|
|
109
|
-
if (
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
114
|
+
resolveComponentValue: ({ mappingKey, propertyName, dataType, resolveBoundValue }) => {
|
|
115
|
+
if (!entityStore.isExperienceAPatternEntry) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const path = resolveMaybePrebindingDefaultValuePath({
|
|
119
|
+
componentValueKey: mappingKey,
|
|
120
|
+
patternRootNodeIdsChain,
|
|
121
|
+
entityStore,
|
|
122
|
+
});
|
|
123
|
+
if (path) {
|
|
124
|
+
return resolveBoundValue({
|
|
125
|
+
propertyName,
|
|
126
|
+
dataType,
|
|
127
|
+
binding: {
|
|
128
|
+
type: 'BoundValue',
|
|
129
|
+
path,
|
|
130
|
+
},
|
|
113
131
|
});
|
|
114
|
-
if (path) {
|
|
115
|
-
return resolveBoundValue({
|
|
116
|
-
propertyName,
|
|
117
|
-
dataType,
|
|
118
|
-
binding: {
|
|
119
|
-
type: 'BoundValue',
|
|
120
|
-
path,
|
|
121
|
-
},
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
132
|
}
|
|
125
133
|
},
|
|
126
134
|
});
|
|
@@ -138,7 +146,6 @@ const CompositionBlock = ({ node: rawNode, locale, entityStore, hyperlinkPattern
|
|
|
138
146
|
};
|
|
139
147
|
}, [
|
|
140
148
|
node,
|
|
141
|
-
isPatternEntry,
|
|
142
149
|
entityStore,
|
|
143
150
|
componentRegistration,
|
|
144
151
|
isPatternNode,
|
|
@@ -161,7 +168,7 @@ const CompositionBlock = ({ node: rawNode, locale, entityStore, hyperlinkPattern
|
|
|
161
168
|
// Retrieves the CSS class name for a given child node ID.
|
|
162
169
|
const _getPatternChildNodeClassName = (childNodeId) => {
|
|
163
170
|
if (isPatternNode) {
|
|
164
|
-
const nodeIdsChain =
|
|
171
|
+
const nodeIdsChain = [...patternRootNodeIdsChain, childNodeId].join('-');
|
|
165
172
|
// @ts-expect-error -- property cfSsrClassName is a map (id to classNames) that is added during rendering in ssrStyles
|
|
166
173
|
const classesForNode = node.variables.cfSsrClassName?.[nodeIdsChain];
|
|
167
174
|
if (!classesForNode)
|
|
@@ -171,7 +178,7 @@ const CompositionBlock = ({ node: rawNode, locale, entityStore, hyperlinkPattern
|
|
|
171
178
|
return getPatternChildNodeClassName?.(childNodeId);
|
|
172
179
|
};
|
|
173
180
|
const { slotNodesMap, directChildNodes } = splitDirectAndSlotChildren(node.children, componentRegistration.definition);
|
|
174
|
-
const renderChildNode = (childNode, index) => (jsx(CompositionBlock, { getPatternChildNodeClassName: isPatternNode || getPatternChildNodeClassName ? _getPatternChildNodeClassName : undefined, node: childNode, locale: locale, hyperlinkPattern: hyperlinkPattern, entityStore: entityStore, resolveDesignValue: resolveDesignValue, wrappingPatternIds: wrappingPatternIds,
|
|
181
|
+
const renderChildNode = (childNode, index) => (jsx(CompositionBlock, { getPatternChildNodeClassName: isPatternNode || getPatternChildNodeClassName ? _getPatternChildNodeClassName : undefined, node: childNode, locale: locale, hyperlinkPattern: hyperlinkPattern, entityStore: entityStore, resolveDesignValue: resolveDesignValue, wrappingPatternIds: wrappingPatternIds, patternRootNodeIdsChain: patternRootNodeIdsChain, rootPatternParameters: rootParameters }, childNode.id ?? index));
|
|
175
182
|
const renderedSlotNodesMap = Object.entries(slotNodesMap).reduce((acc, [slotId, nodes]) => {
|
|
176
183
|
if (nodes?.length) {
|
|
177
184
|
acc[slotId] = jsx(Fragment, { children: nodes.map(renderChildNode) });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CompositionBlock.js","sources":["../../../../src/blocks/preview/CompositionBlock.tsx"],"sourcesContent":["import React, { useMemo } from 'react';\nimport type { UnresolvedLink } from 'contentful';\nimport { Entry } from 'contentful';\nimport {\n checkIsAssemblyEntry,\n checkIsAssemblyNode,\n EntityStore,\n resolveHyperlinkPattern,\n sanitizeNodeProps,\n transformBoundContentValue,\n splitDirectAndSlotChildren,\n getSdkOptions,\n} from '@contentful/experiences-core';\nimport {\n CONTENTFUL_COMPONENTS,\n HYPERLINK_DEFAULT_PATTERN,\n} from '@contentful/experiences-core/constants';\nimport type {\n ComponentTreeNode,\n DesignValue,\n Parameter,\n PrimitiveValue,\n ResolveDesignValueType,\n StyleProps,\n} from '@contentful/experiences-core/types';\nimport { createAssemblyRegistration, getComponentRegistration } from '../../core/componentRegistry';\nimport { useInjectStylesheet } from '../../hooks/useInjectStylesheet';\nimport { Assembly, ContentfulContainer } from '@contentful/experiences-components-react';\nimport { resolvePattern } from '../../core/preview/assemblyUtils';\nimport { resolveMaybePrebindingDefaultValuePath } from '../../utils/prebindingUtils';\nimport { parseComponentProps } from '../../utils/parseComponentProps';\n\ntype CompositionBlockProps = {\n node: ComponentTreeNode;\n locale: string;\n entityStore: EntityStore;\n hyperlinkPattern?: string | undefined;\n resolveDesignValue: ResolveDesignValueType;\n getPatternChildNodeClassName?: (childNodeId: string) => string | undefined;\n /** Set of definition IDs of wrapping patterns to prevent circular dependencies. */\n wrappingPatternIds?: Set<string>;\n /**\n * Chained IDs to ensure uniqueness across multiple instances of the same pattern\n * when storing & accessing cfSsrClassName.\n */\n patternRootNodeIdsChain?: string;\n wrappingParameters?: Record<string, Parameter>;\n};\n\nexport const CompositionBlock = ({\n node: rawNode,\n locale,\n entityStore,\n hyperlinkPattern,\n resolveDesignValue,\n getPatternChildNodeClassName,\n wrappingPatternIds: parentWrappingPatternIds = new Set(),\n wrappingParameters: parentWrappingParameters = {},\n patternRootNodeIdsChain: parentPatternRootNodeIdsChain = '',\n}: CompositionBlockProps) => {\n const isPatternNode = useMemo(() => {\n return checkIsAssemblyNode({\n componentId: rawNode.definitionId,\n usedComponents: entityStore.usedComponents,\n });\n }, [entityStore.usedComponents, rawNode.definitionId]);\n\n const isPatternEntry = useMemo(() => {\n return checkIsAssemblyEntry({ fields: entityStore.experienceEntryFields } as unknown as Entry);\n }, [entityStore]);\n\n const patternRootNodeIdsChain = useMemo(() => {\n if (isPatternNode) {\n // Pattern nodes are chained without a separator (following the format for prebinding/parameters)\n return `${parentPatternRootNodeIdsChain}${rawNode.id}`;\n }\n return parentPatternRootNodeIdsChain;\n }, [isPatternNode, parentPatternRootNodeIdsChain, rawNode.id]);\n\n const node = useMemo(() => {\n if (isPatternNode) {\n return resolvePattern({\n node: rawNode,\n entityStore,\n parentParameters: parentWrappingParameters,\n patternRootNodeIdsChain,\n });\n } else {\n return rawNode;\n }\n }, [entityStore, isPatternNode, rawNode, parentWrappingParameters, patternRootNodeIdsChain]);\n\n const wrappingPatternIds = useMemo(() => {\n if (isPatternNode) {\n return new Set([node.definitionId, ...parentWrappingPatternIds]);\n }\n return parentWrappingPatternIds;\n }, [isPatternNode, node, parentWrappingPatternIds]);\n\n // Merge the pattern properties of the current node with the parent's pattern properties\n // to ensure nested patterns receive relevant pattern properties that were bubbled up\n // during assembly serialization.\n const wrappingParameters = useMemo(() => {\n if (isPatternNode) {\n return { ...parentWrappingParameters, ...(rawNode.parameters || {}) };\n }\n return parentWrappingParameters;\n }, [isPatternNode, rawNode, parentWrappingParameters]);\n\n const componentRegistration = useMemo(() => {\n const registration = getComponentRegistration(node.definitionId as string);\n\n if (isPatternNode && !registration) {\n return createAssemblyRegistration({\n definitionId: node.definitionId as string,\n component: Assembly,\n });\n }\n return registration;\n }, [isPatternNode, node.definitionId]);\n\n const { ssrProps, contentProps, props, mediaQuery } = useMemo(() => {\n // In SSR, we store the className under breakpoints[0] which is resolved here to the actual string\n const cfSsrClassNameValues = node.variables.cfSsrClassName as DesignValue | undefined;\n const mainBreakpoint = entityStore.breakpoints[0];\n const cfSsrClassName = cfSsrClassNameValues?.valuesByBreakpoint?.[mainBreakpoint.id] as\n | string\n | undefined;\n\n // Don't enrich the assembly wrapper node with props\n if (!componentRegistration || isPatternNode) {\n const ssrProps = { cfSsrClassName };\n const props: Record<string, PrimitiveValue> = { className: cfSsrClassName };\n return {\n ssrProps,\n props,\n };\n }\n\n const ssrProps: Record<string, string | undefined> = {\n cfSsrClassName:\n node.id && getPatternChildNodeClassName\n ? getPatternChildNodeClassName(node.id)\n : cfSsrClassName,\n };\n\n const {\n contentProps = {},\n styleProps = {},\n customDesignProps = {},\n mediaQuery,\n } = parseComponentProps({\n breakpoints: entityStore.breakpoints,\n mainBreakpoint,\n componentDefinition: componentRegistration.definition,\n patternRootNodeIdsChain,\n node,\n resolveDesignValue,\n resolveBoundValue: ({ binding, propertyName, dataType }) => {\n const [, uuid] = binding.path.split('/');\n const boundEntityLink = entityStore.dataSource[uuid] as UnresolvedLink<'Entry' | 'Asset'>;\n return transformBoundContentValue(\n node.variables,\n entityStore,\n boundEntityLink,\n resolveDesignValue,\n propertyName,\n dataType,\n binding.path,\n );\n },\n resolveHyperlinkValue: ({ linkTargetKey }) => {\n const boundEntity = entityStore.dataSource[linkTargetKey];\n const hyperlinkEntry = entityStore.getEntryOrAsset(boundEntity, linkTargetKey);\n\n return resolveHyperlinkPattern(\n componentRegistration.definition.hyperlinkPattern ||\n hyperlinkPattern ||\n HYPERLINK_DEFAULT_PATTERN,\n hyperlinkEntry as Entry,\n locale,\n );\n },\n resolveUnboundValue: ({ mappingKey, defaultValue }) => {\n return entityStore.unboundValues[mappingKey]?.value ?? defaultValue;\n },\n resolvePrebindingValue: ({ mappingKey, propertyName, dataType, resolveBoundValue }) => {\n if (isPatternEntry) {\n const path = resolveMaybePrebindingDefaultValuePath({\n componentValueKey: mappingKey,\n entityStore,\n });\n\n if (path) {\n return resolveBoundValue({\n propertyName,\n dataType,\n binding: {\n type: 'BoundValue',\n path,\n },\n });\n }\n }\n },\n });\n\n const props: Record<string, PrimitiveValue> = {\n className: ssrProps.cfSsrClassName ?? mediaQuery?.className,\n ...styleProps,\n ...contentProps,\n ...customDesignProps,\n };\n\n return {\n ssrProps,\n contentProps,\n mediaQuery,\n props,\n };\n }, [\n node,\n isPatternEntry,\n entityStore,\n componentRegistration,\n isPatternNode,\n getPatternChildNodeClassName,\n resolveDesignValue,\n hyperlinkPattern,\n locale,\n patternRootNodeIdsChain,\n ]);\n\n // do not inject the stylesheet into the dom because it's already been done on the server side\n useInjectStylesheet(ssrProps.cfSsrClassName ? undefined : mediaQuery?.css);\n\n if (!componentRegistration) {\n return null;\n }\n\n // When detecting a circular dependency, we stop silently. The editor mode will render an actionable error.\n if (parentWrappingPatternIds.has(node.definitionId)) {\n return null;\n }\n\n const { component: component } = componentRegistration;\n\n // Retrieves the CSS class name for a given child node ID.\n const _getPatternChildNodeClassName = (childNodeId: string) => {\n if (isPatternNode) {\n const nodeIdsChain = `${patternRootNodeIdsChain}-${childNodeId}`;\n // @ts-expect-error -- property cfSsrClassName is a map (id to classNames) that is added during rendering in ssrStyles\n const classesForNode: DesignValue | undefined = node.variables.cfSsrClassName?.[nodeIdsChain];\n if (!classesForNode) return undefined;\n return resolveDesignValue(classesForNode.valuesByBreakpoint) as string;\n }\n return getPatternChildNodeClassName?.(childNodeId);\n };\n\n const { slotNodesMap, directChildNodes } = splitDirectAndSlotChildren(\n node.children,\n componentRegistration.definition,\n );\n\n const renderChildNode = (childNode: ComponentTreeNode, index: number) => (\n <CompositionBlock\n getPatternChildNodeClassName={\n isPatternNode || getPatternChildNodeClassName ? _getPatternChildNodeClassName : undefined\n }\n node={childNode}\n key={childNode.id ?? index}\n locale={locale}\n hyperlinkPattern={hyperlinkPattern}\n entityStore={entityStore}\n resolveDesignValue={resolveDesignValue}\n wrappingPatternIds={wrappingPatternIds}\n wrappingParameters={wrappingParameters}\n patternRootNodeIdsChain={patternRootNodeIdsChain}\n />\n );\n\n const renderedSlotNodesMap = Object.entries(slotNodesMap).reduce(\n (acc, [slotId, nodes]) => {\n if (nodes?.length) {\n acc[slotId] = <>{nodes.map(renderChildNode)}</>;\n }\n return acc;\n },\n {} as Record<string, React.JSX.Element>,\n );\n\n const renderedChildren = directChildNodes?.map(renderChildNode);\n\n const sdkOptions = getSdkOptions();\n\n // TODO: we might be able to remove this special case as well by not dropping the two props in the sanitizeNodeProps function\n // We allow custom container rendering through a new sdk option (not introducing a breaking change for existing customers).\n if (\n isContainerOrSection(node.definitionId) &&\n !sdkOptions.__unsafe__enableBuiltInStructureOverwrites\n ) {\n return (\n <ContentfulContainer\n cfHyperlink={(contentProps as StyleProps).cfHyperlink}\n cfOpenInNewTab={(contentProps as StyleProps).cfOpenInNewTab}\n className={props.className as string | undefined}>\n {renderedChildren}\n </ContentfulContainer>\n );\n }\n\n return React.createElement(\n component,\n {\n ...sanitizeNodeProps(props),\n ...renderedSlotNodesMap,\n },\n // If there are no children, a custom property called `children` can be passed through to the custom component\n ...(renderedChildren ?? []),\n );\n};\n\nconst isContainerOrSection = (\n nodeDefinitionId: string,\n): nodeDefinitionId is 'contentful-container' | 'contentful-section' =>\n [CONTENTFUL_COMPONENTS.container.id, CONTENTFUL_COMPONENTS.section.id].includes(\n nodeDefinitionId as 'contentful-container' | 'contentful-section',\n );\n"],"names":["_jsx","_Fragment"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CompositionBlock.js","sources":["../../../../src/blocks/preview/CompositionBlock.tsx"],"sourcesContent":["import React, { useMemo } from 'react';\nimport type { UnresolvedLink } from 'contentful';\nimport { Entry } from 'contentful';\nimport {\n checkIsAssemblyNode,\n EntityStore,\n resolveHyperlinkPattern,\n sanitizeNodeProps,\n transformBoundContentValue,\n splitDirectAndSlotChildren,\n getSdkOptions,\n} from '@contentful/experiences-core';\nimport {\n CONTENTFUL_COMPONENTS,\n HYPERLINK_DEFAULT_PATTERN,\n} from '@contentful/experiences-core/constants';\nimport type {\n ComponentTreeNode,\n DesignValue,\n Parameter,\n PrimitiveValue,\n ResolveDesignValueType,\n StyleProps,\n} from '@contentful/experiences-core/types';\nimport { createAssemblyRegistration, getComponentRegistration } from '../../core/componentRegistry';\nimport { useInjectStylesheet } from '../../hooks/useInjectStylesheet';\nimport { Assembly, ContentfulContainer } from '@contentful/experiences-components-react';\nimport { resolvePattern } from '../../core/preview/assemblyUtils';\nimport { resolveMaybePrebindingDefaultValuePath } from '../../utils/prebindingUtils';\nimport { parseComponentProps } from '../../utils/parseComponentProps';\n\ntype CompositionBlockProps = {\n node: ComponentTreeNode;\n locale: string;\n entityStore: EntityStore;\n hyperlinkPattern?: string | undefined;\n resolveDesignValue: ResolveDesignValueType;\n getPatternChildNodeClassName?: (childNodeId: string) => string | undefined;\n /** Set of definition IDs of wrapping patterns to prevent circular dependencies. */\n wrappingPatternIds?: Set<string>;\n rootPatternParameters?: Record<string, Parameter>;\n /**\n * Chained IDs to ensure uniqueness across multiple instances of the same pattern\n * when storing & accessing cfSsrClassName.\n */\n patternRootNodeIdsChain?: Array<string>;\n};\n\nexport const CompositionBlock = ({\n node: rawNode,\n locale,\n entityStore,\n hyperlinkPattern,\n resolveDesignValue,\n getPatternChildNodeClassName,\n wrappingPatternIds: parentWrappingPatternIds = new Set(),\n patternRootNodeIdsChain: parentPatternRootNodeIdsChain = [],\n rootPatternParameters,\n}: CompositionBlockProps) => {\n const isPatternNode = useMemo(() => {\n return checkIsAssemblyNode({\n componentId: rawNode.definitionId,\n usedComponents: entityStore.usedComponents,\n });\n }, [entityStore.usedComponents, rawNode.definitionId]);\n\n const patternRootNodeIdsChain = useMemo(() => {\n if (isPatternNode) {\n // Pattern nodes are chained without a separator (following the format for prebinding/parameters)\n return [...parentPatternRootNodeIdsChain, rawNode.id!];\n }\n return parentPatternRootNodeIdsChain;\n }, [isPatternNode, parentPatternRootNodeIdsChain, rawNode.id]);\n\n const rootParameters = useMemo(() => {\n // covers the case when previewing a pattern\n // all parameters are defined on the tree root node and will be provided from the start\n if (rootPatternParameters) {\n return rootPatternParameters;\n }\n\n // covers the case when previewing an experience\n // parameters here are stored in CMA, so we retrieve them from the pattern's node and pass it down\n if (isPatternNode && rawNode.parameters && Object.keys(rawNode.parameters).length) {\n return rawNode.parameters;\n }\n\n // in case none exist - it is likely a non-pattern component, or just a pattern that has no parameters\n return undefined;\n }, [rawNode, rootPatternParameters, isPatternNode]);\n\n const node = useMemo(() => {\n if (isPatternNode) {\n return resolvePattern({\n node: rawNode,\n entityStore,\n parentPatternRootNodeIdsChain: patternRootNodeIdsChain,\n rootPatternParameters: rootParameters!,\n });\n } else {\n return rawNode;\n }\n }, [entityStore, isPatternNode, rawNode, patternRootNodeIdsChain, rootParameters]);\n\n const wrappingPatternIds = useMemo(() => {\n if (isPatternNode) {\n return new Set([node.definitionId, ...parentWrappingPatternIds]);\n }\n return parentWrappingPatternIds;\n }, [isPatternNode, node, parentWrappingPatternIds]);\n\n const componentRegistration = useMemo(() => {\n const registration = getComponentRegistration(node.definitionId as string);\n\n if (isPatternNode && !registration) {\n return createAssemblyRegistration({\n definitionId: node.definitionId as string,\n component: Assembly,\n });\n }\n return registration;\n }, [isPatternNode, node.definitionId]);\n\n const { ssrProps, contentProps, props, mediaQuery } = useMemo(() => {\n // In SSR, we store the className under breakpoints[0] which is resolved here to the actual string\n const cfSsrClassNameValues = node.variables.cfSsrClassName as DesignValue | undefined;\n const mainBreakpoint = entityStore.breakpoints[0];\n const cfSsrClassName = cfSsrClassNameValues?.valuesByBreakpoint?.[mainBreakpoint.id] as\n | string\n | undefined;\n\n // Don't enrich the assembly wrapper node with props\n if (!componentRegistration || isPatternNode) {\n const ssrProps = { cfSsrClassName };\n const props: Record<string, PrimitiveValue> = { className: cfSsrClassName };\n return {\n ssrProps,\n props,\n };\n }\n\n const ssrProps: Record<string, string | undefined> = {\n cfSsrClassName:\n node.id && getPatternChildNodeClassName\n ? getPatternChildNodeClassName(node.id)\n : cfSsrClassName,\n };\n\n const {\n contentProps = {},\n styleProps = {},\n customDesignProps = {},\n mediaQuery,\n } = parseComponentProps({\n breakpoints: entityStore.breakpoints,\n mainBreakpoint,\n componentDefinition: componentRegistration.definition,\n patternRootNodeIdsChain,\n node,\n resolveDesignValue,\n resolveBoundValue: ({ binding, propertyName, dataType }) => {\n const [, uuid] = binding.path.split('/');\n const boundEntityLink = entityStore.dataSource[uuid] as UnresolvedLink<'Entry' | 'Asset'>;\n // TODO: Temporary fix while we look into SPA-3212 it occurs where we have prebound props but data source link is missing\n // this only occurs after live updates of nested patterns.\n if (!boundEntityLink) return;\n return transformBoundContentValue(\n node.variables,\n entityStore,\n boundEntityLink,\n resolveDesignValue,\n propertyName,\n dataType,\n binding.path,\n );\n },\n resolveHyperlinkValue: ({ linkTargetKey }) => {\n const boundEntity = entityStore.dataSource[linkTargetKey];\n const hyperlinkEntry = entityStore.getEntryOrAsset(boundEntity, linkTargetKey);\n\n return resolveHyperlinkPattern(\n componentRegistration.definition.hyperlinkPattern ||\n hyperlinkPattern ||\n HYPERLINK_DEFAULT_PATTERN,\n hyperlinkEntry as Entry,\n locale,\n );\n },\n resolveUnboundValue: ({ mappingKey, defaultValue }) => {\n return entityStore.unboundValues[mappingKey]?.value ?? defaultValue;\n },\n resolveComponentValue: ({ mappingKey, propertyName, dataType, resolveBoundValue }) => {\n if (!entityStore.isExperienceAPatternEntry) {\n return;\n }\n\n const path = resolveMaybePrebindingDefaultValuePath({\n componentValueKey: mappingKey,\n patternRootNodeIdsChain,\n entityStore,\n });\n\n if (path) {\n return resolveBoundValue({\n propertyName,\n dataType,\n binding: {\n type: 'BoundValue',\n path,\n },\n });\n }\n },\n });\n\n const props: Record<string, PrimitiveValue> = {\n className: ssrProps.cfSsrClassName ?? mediaQuery?.className,\n ...styleProps,\n ...contentProps,\n ...customDesignProps,\n };\n\n return {\n ssrProps,\n contentProps,\n mediaQuery,\n props,\n };\n }, [\n node,\n entityStore,\n componentRegistration,\n isPatternNode,\n getPatternChildNodeClassName,\n resolveDesignValue,\n hyperlinkPattern,\n locale,\n patternRootNodeIdsChain,\n ]);\n\n // do not inject the stylesheet into the dom because it's already been done on the server side\n useInjectStylesheet(ssrProps.cfSsrClassName ? undefined : mediaQuery?.css);\n\n if (!componentRegistration) {\n return null;\n }\n\n // When detecting a circular dependency, we stop silently. The editor mode will render an actionable error.\n if (parentWrappingPatternIds.has(node.definitionId)) {\n return null;\n }\n\n const { component: component } = componentRegistration;\n\n // Retrieves the CSS class name for a given child node ID.\n const _getPatternChildNodeClassName = (childNodeId: string) => {\n if (isPatternNode) {\n const nodeIdsChain = [...patternRootNodeIdsChain, childNodeId].join('-');\n // @ts-expect-error -- property cfSsrClassName is a map (id to classNames) that is added during rendering in ssrStyles\n const classesForNode: DesignValue | undefined = node.variables.cfSsrClassName?.[nodeIdsChain];\n if (!classesForNode) return undefined;\n return resolveDesignValue(classesForNode.valuesByBreakpoint) as string;\n }\n return getPatternChildNodeClassName?.(childNodeId);\n };\n\n const { slotNodesMap, directChildNodes } = splitDirectAndSlotChildren(\n node.children,\n componentRegistration.definition,\n );\n\n const renderChildNode = (childNode: ComponentTreeNode, index: number) => (\n <CompositionBlock\n getPatternChildNodeClassName={\n isPatternNode || getPatternChildNodeClassName ? _getPatternChildNodeClassName : undefined\n }\n node={childNode}\n key={childNode.id ?? index}\n locale={locale}\n hyperlinkPattern={hyperlinkPattern}\n entityStore={entityStore}\n resolveDesignValue={resolveDesignValue}\n wrappingPatternIds={wrappingPatternIds}\n patternRootNodeIdsChain={patternRootNodeIdsChain}\n rootPatternParameters={rootParameters}\n />\n );\n\n const renderedSlotNodesMap = Object.entries(slotNodesMap).reduce(\n (acc, [slotId, nodes]) => {\n if (nodes?.length) {\n acc[slotId] = <>{nodes.map(renderChildNode)}</>;\n }\n return acc;\n },\n {} as Record<string, React.JSX.Element>,\n );\n\n const renderedChildren = directChildNodes?.map(renderChildNode);\n\n const sdkOptions = getSdkOptions();\n\n // TODO: we might be able to remove this special case as well by not dropping the two props in the sanitizeNodeProps function\n // We allow custom container rendering through a new sdk option (not introducing a breaking change for existing customers).\n if (\n isContainerOrSection(node.definitionId) &&\n !sdkOptions.__unsafe__enableBuiltInStructureOverwrites\n ) {\n return (\n <ContentfulContainer\n cfHyperlink={(contentProps as StyleProps).cfHyperlink}\n cfOpenInNewTab={(contentProps as StyleProps).cfOpenInNewTab}\n className={props.className as string | undefined}>\n {renderedChildren}\n </ContentfulContainer>\n );\n }\n\n return React.createElement(\n component,\n {\n ...sanitizeNodeProps(props),\n ...renderedSlotNodesMap,\n },\n // If there are no children, a custom property called `children` can be passed through to the custom component\n ...(renderedChildren ?? []),\n );\n};\n\nconst isContainerOrSection = (\n nodeDefinitionId: string,\n): nodeDefinitionId is 'contentful-container' | 'contentful-section' =>\n [CONTENTFUL_COMPONENTS.container.id, CONTENTFUL_COMPONENTS.section.id].includes(\n nodeDefinitionId as 'contentful-container' | 'contentful-section',\n );\n"],"names":["_jsx","_Fragment"],"mappings":"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"}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { jsx, Fragment } from 'react/jsx-runtime';
|
|
2
|
-
import { debug } from '@contentful/experiences-core';
|
|
2
|
+
import { debug, generateDefaultDataSourceForPrebindingDefinition } from '@contentful/experiences-core';
|
|
3
3
|
import { CompositionBlock } from './CompositionBlock.js';
|
|
4
4
|
import { compatibleVersions } from '../../constants.js';
|
|
5
5
|
import { useBreakpoints } from '../../hooks/useBreakpoints.js';
|
|
6
6
|
import 'react';
|
|
7
7
|
import '@contentful/experiences-core/constants';
|
|
8
|
+
import { PrebindingManager } from '../../core/preview/PrebindingManager.js';
|
|
8
9
|
|
|
10
|
+
const initialPatternRootNodeIdsChain = ['root'];
|
|
9
11
|
const PreviewDeliveryRoot = ({ locale, experience }) => {
|
|
10
12
|
const { entityStore } = experience;
|
|
11
13
|
const { resolveDesignValue } = useBreakpoints(entityStore?.breakpoints ?? []);
|
|
@@ -16,6 +18,21 @@ const PreviewDeliveryRoot = ({ locale, experience }) => {
|
|
|
16
18
|
debug.warn(`[experiences-sdk-react::PreviewDeliveryRoot] Contentful experience schema version: ${entityStore.schemaVersion} does not match the compatible schema versions: ${compatibleVersions}. Aborting.`);
|
|
17
19
|
return null;
|
|
18
20
|
}
|
|
21
|
+
const isPreviewingAPattern = entityStore.isExperienceAPatternEntry;
|
|
22
|
+
if (isPreviewingAPattern) {
|
|
23
|
+
const prebindingDefinitions = entityStore.experienceEntryFields.componentSettings?.prebindingDefinitions ?? [];
|
|
24
|
+
PrebindingManager.storePrebindingDefinitions('root', entityStore.experienceEntryId, prebindingDefinitions);
|
|
25
|
+
const { dataSource, parameters: defaultParametersFromRootPattern } = generateDefaultDataSourceForPrebindingDefinition(prebindingDefinitions);
|
|
26
|
+
if (Object.keys(dataSource).length) {
|
|
27
|
+
entityStore.experienceEntryFields.dataSource = {
|
|
28
|
+
...entityStore.dataSource,
|
|
29
|
+
...dataSource,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return entityStore.experienceEntryFields.componentTree.children.map((childNode, index) => {
|
|
33
|
+
return (jsx(CompositionBlock, { node: childNode, hyperlinkPattern: experience.hyperlinkPattern, locale: locale, entityStore: entityStore, resolveDesignValue: resolveDesignValue, patternRootNodeIdsChain: initialPatternRootNodeIdsChain, rootPatternParameters: defaultParametersFromRootPattern }, index));
|
|
34
|
+
});
|
|
35
|
+
}
|
|
19
36
|
return (jsx(Fragment, { children: entityStore.experienceEntryFields.componentTree.children.map((childNode, index) => (jsx(CompositionBlock, { node: childNode, hyperlinkPattern: experience.hyperlinkPattern, locale: locale, entityStore: entityStore, resolveDesignValue: resolveDesignValue }, index))) }));
|
|
20
37
|
};
|
|
21
38
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PreviewDeliveryRoot.js","sources":["../../../../src/blocks/preview/PreviewDeliveryRoot.tsx"],"sourcesContent":["import React from 'react';\nimport {
|
|
1
|
+
{"version":3,"file":"PreviewDeliveryRoot.js","sources":["../../../../src/blocks/preview/PreviewDeliveryRoot.tsx"],"sourcesContent":["import React from 'react';\nimport {\n debug,\n EntityStore,\n generateDefaultDataSourceForPrebindingDefinition,\n} from '@contentful/experiences-core';\nimport type { Experience } from '@contentful/experiences-core/types';\nimport { CompositionBlock } from './CompositionBlock';\nimport { compatibleVersions } from '../../constants';\nimport { useBreakpoints } from '../../hooks';\nimport { PrebindingManager } from '../../core/preview/PrebindingManager';\n\nconst initialPatternRootNodeIdsChain = ['root'];\n\ntype DeliveryRootProps = {\n experience: Experience<EntityStore>;\n locale: string;\n};\n\nexport const PreviewDeliveryRoot = ({ locale, experience }: DeliveryRootProps) => {\n const { entityStore } = experience;\n\n const { resolveDesignValue } = useBreakpoints(entityStore?.breakpoints ?? []);\n\n if (!entityStore?.experienceEntryFields || !entityStore?.schemaVersion) {\n return null;\n }\n\n if (!compatibleVersions.includes(entityStore.schemaVersion)) {\n debug.warn(\n `[experiences-sdk-react::PreviewDeliveryRoot] Contentful experience schema version: ${entityStore.schemaVersion} does not match the compatible schema versions: ${compatibleVersions}. Aborting.`,\n );\n return null;\n }\n\n const isPreviewingAPattern = entityStore.isExperienceAPatternEntry;\n\n if (isPreviewingAPattern) {\n const prebindingDefinitions =\n entityStore.experienceEntryFields.componentSettings?.prebindingDefinitions ?? [];\n PrebindingManager.storePrebindingDefinitions(\n 'root',\n entityStore.experienceEntryId!,\n prebindingDefinitions,\n );\n const { dataSource, parameters: defaultParametersFromRootPattern } =\n generateDefaultDataSourceForPrebindingDefinition(prebindingDefinitions);\n\n if (Object.keys(dataSource).length) {\n entityStore.experienceEntryFields!.dataSource = {\n ...entityStore.dataSource,\n ...dataSource,\n };\n }\n\n return entityStore.experienceEntryFields.componentTree.children.map((childNode, index) => {\n return (\n <CompositionBlock\n key={index}\n node={childNode}\n hyperlinkPattern={experience.hyperlinkPattern}\n locale={locale}\n entityStore={entityStore}\n resolveDesignValue={resolveDesignValue}\n patternRootNodeIdsChain={initialPatternRootNodeIdsChain}\n rootPatternParameters={defaultParametersFromRootPattern}\n />\n );\n });\n }\n\n return (\n <>\n {entityStore.experienceEntryFields.componentTree.children.map((childNode, index) => (\n <CompositionBlock\n key={index}\n node={childNode}\n hyperlinkPattern={experience.hyperlinkPattern}\n locale={locale}\n entityStore={entityStore}\n resolveDesignValue={resolveDesignValue}\n />\n ))}\n </>\n );\n};\n"],"names":["_jsx"],"mappings":";;;;;;;;;AAYA,MAAM,8BAA8B,GAAG,CAAC,MAAM,CAAC,CAAC;AAOnC,MAAA,mBAAmB,GAAG,CAAC,EAAE,MAAM,EAAE,UAAU,EAAqB,KAAI;AAC/E,IAAA,MAAM,EAAE,WAAW,EAAE,GAAG,UAAU,CAAC;AAEnC,IAAA,MAAM,EAAE,kBAAkB,EAAE,GAAG,cAAc,CAAC,WAAW,EAAE,WAAW,IAAI,EAAE,CAAC,CAAC;IAE9E,IAAI,CAAC,WAAW,EAAE,qBAAqB,IAAI,CAAC,WAAW,EAAE,aAAa,EAAE;AACtE,QAAA,OAAO,IAAI,CAAC;KACb;IAED,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,WAAW,CAAC,aAAa,CAAC,EAAE;QAC3D,KAAK,CAAC,IAAI,CACR,CAAsF,mFAAA,EAAA,WAAW,CAAC,aAAa,CAAmD,gDAAA,EAAA,kBAAkB,CAAa,WAAA,CAAA,CAClM,CAAC;AACF,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,MAAM,oBAAoB,GAAG,WAAW,CAAC,yBAAyB,CAAC;IAEnE,IAAI,oBAAoB,EAAE;QACxB,MAAM,qBAAqB,GACzB,WAAW,CAAC,qBAAqB,CAAC,iBAAiB,EAAE,qBAAqB,IAAI,EAAE,CAAC;QACnF,iBAAiB,CAAC,0BAA0B,CAC1C,MAAM,EACN,WAAW,CAAC,iBAAkB,EAC9B,qBAAqB,CACtB,CAAC;AACF,QAAA,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,gCAAgC,EAAE,GAChE,gDAAgD,CAAC,qBAAqB,CAAC,CAAC;QAE1E,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,EAAE;AAClC,YAAA,WAAW,CAAC,qBAAsB,CAAC,UAAU,GAAG;gBAC9C,GAAG,WAAW,CAAC,UAAU;AACzB,gBAAA,GAAG,UAAU;aACd,CAAC;SACH;AAED,QAAA,OAAO,WAAW,CAAC,qBAAqB,CAAC,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,KAAK,KAAI;AACvF,YAAA,QACEA,GAAC,CAAA,gBAAgB,EAEf,EAAA,IAAI,EAAE,SAAS,EACf,gBAAgB,EAAE,UAAU,CAAC,gBAAgB,EAC7C,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,EACxB,kBAAkB,EAAE,kBAAkB,EACtC,uBAAuB,EAAE,8BAA8B,EACvD,qBAAqB,EAAE,gCAAgC,IAPlD,KAAK,CAQV,EACF;AACJ,SAAC,CAAC,CAAC;KACJ;IAED,QACEA,0BACG,WAAW,CAAC,qBAAqB,CAAC,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,KAAK,MAC7EA,GAAA,CAAC,gBAAgB,EAAA,EAEf,IAAI,EAAE,SAAS,EACf,gBAAgB,EAAE,UAAU,CAAC,gBAAgB,EAC7C,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,EACxB,kBAAkB,EAAE,kBAAkB,EALjC,EAAA,KAAK,CAMV,CACH,CAAC,EACD,CAAA,EACH;AACJ;;;;"}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
const NODE_ID_SEPARATOR = '---'; // separator used to separate pattern levels in deseralizePatternNode
|
|
2
|
+
/**
|
|
3
|
+
* PrebindingManager utility class for resolving parameter bindings across nested patterns.
|
|
4
|
+
*
|
|
5
|
+
* The core approach is to first resolve the top-level parameterId using `getParameterIdByNodeId`,
|
|
6
|
+
* which uses the paramIdToOverwriteIdMap, set when storing pre-binding based on the passToNodes chain to determine which parameter in the parent pattern
|
|
7
|
+
* overrides a given parameterId (with some additionally workaround due to node ID renaming for patterns).
|
|
8
|
+
* Once the owning top-level `parameterId` is found, we can follow the `passToNodes` chain back
|
|
9
|
+
* down to retrieve all nested overrides — including parameter definitions, allowed content types,
|
|
10
|
+
* and default sources — up to three levels deep.
|
|
11
|
+
*
|
|
12
|
+
* ## Lifecycle
|
|
13
|
+
* This utility class currently uses static state, with Zustand stores supplementing the “latest” data
|
|
14
|
+
* for root-level patterns data — for example, when overwriting content types on nested patterns or binding
|
|
15
|
+
* fields on simple patterns. If we need the override mappings to be reactive, we could easily move
|
|
16
|
+
* the full override chain tracking into Zustand but currently we can rely on the pattern definition
|
|
17
|
+
* stores we have currently.
|
|
18
|
+
*
|
|
19
|
+
* The state is populated during deserialization, where we call `storePrebindingDefinitions` for each
|
|
20
|
+
* pattern node. It is ready to be consumed at each level as nodes are deserialized top-down:
|
|
21
|
+
* 1. Pattern C (Template Pattern)
|
|
22
|
+
* 2. Pattern B (Nested Pattern)
|
|
23
|
+
* 3. Pattern A (Simple Pattern)
|
|
24
|
+
*
|
|
25
|
+
* At each level, accessing overrides is possible:
|
|
26
|
+
* - Pattern C has everything it needs once deserialized with its own parameters
|
|
27
|
+
* - Pattern B has everything it needs once deserialized, with its own parameters possibly overridden by C
|
|
28
|
+
* - Pattern A has its own parameters and possiblle overrites by B and/or C
|
|
29
|
+
*
|
|
30
|
+
* After actions that modify patterns without re-deserializing the tree — such as duplication,
|
|
31
|
+
* deletion, or detachment — this state must be kept up to date via storePrebindingDefinitions
|
|
32
|
+
* or storeParameterDefinitions if only parameter definitions are updated.
|
|
33
|
+
*
|
|
34
|
+
* ## Core Data Structures
|
|
35
|
+
*
|
|
36
|
+
* - prebindingDefinitions - A collection of all prebinding definitions aggregated
|
|
37
|
+
* from the parent pattern down to all nested patterns.
|
|
38
|
+
*
|
|
39
|
+
* - prebindingDefinitionIdsByNodeId - Same as above, but indexed by `nodeId`. This allows us
|
|
40
|
+
* to easily find the prebinding definition id for a given node ID.
|
|
41
|
+
*
|
|
42
|
+
* - parameterDefinitionsById - A collection of all parameter definitions aggregated
|
|
43
|
+
* from the parent pattern down to nested patterns.
|
|
44
|
+
*
|
|
45
|
+
* - variableMappingByPatternId - A collection of all variable mappings aggregated from
|
|
46
|
+
* the parent pattern down to nested patterns, indexed by
|
|
47
|
+
* `patternId` for efficient access.
|
|
48
|
+
*
|
|
49
|
+
* - newToOriginalNodeIdMap - When deserializing pattern child nodes, we replace their
|
|
50
|
+
* node IDs with new ones based on their location inside the
|
|
51
|
+
* pattern. This prevents conflicts when multiple instances
|
|
52
|
+
* of the same pattern exist. The issue is that prebinding
|
|
53
|
+
* `passToNodes` resolution requires the original node ID.
|
|
54
|
+
* This map allows us to retrieve it to follow the chain.
|
|
55
|
+
*
|
|
56
|
+
* - paramIdToOverwriteIdMap - Tracks parameter ID overrides through the `passToNodes`
|
|
57
|
+
* chain, allowing us to resolve overrides correctly from
|
|
58
|
+
* the top-level parameter down to the lowest-level.
|
|
59
|
+
*/
|
|
60
|
+
class PrebindingManager {
|
|
61
|
+
static prebindingDefinitions = new Map();
|
|
62
|
+
static prebindingDefinitionIdsByNodeId = new Map();
|
|
63
|
+
static parameterDefinitionsById = new Map();
|
|
64
|
+
static parameterDefinitionsByNodeId = new Map();
|
|
65
|
+
static variableMappingByPatternId = new Map();
|
|
66
|
+
static newToOriginalNodeIdMap = new Map();
|
|
67
|
+
static paramIdToOverwriteIdMap = new Map();
|
|
68
|
+
/**
|
|
69
|
+
* Links new node IDs to original node IDs
|
|
70
|
+
* - This is used to track the original node IDs for pattern instances as we change them when deserializing pattern nodes.
|
|
71
|
+
* @param newNodeId
|
|
72
|
+
* @param originalNodeId
|
|
73
|
+
*/
|
|
74
|
+
static linkOriginalNodeIds(newNodeId, originalNodeId) {
|
|
75
|
+
PrebindingManager.newToOriginalNodeIdMap.set(newNodeId, originalNodeId);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Initializes the pattern editor manager by storing the definitions during deserialization
|
|
79
|
+
* for the root pattern and all nested patterns.
|
|
80
|
+
*
|
|
81
|
+
* @param nodeId - The ID of the pattern node.
|
|
82
|
+
* @param patternEntryId - The ID of the pattern entry from the patterns store.
|
|
83
|
+
* @param prebindingDefinitions - The prebinding definitions from the current pattern's component settings.
|
|
84
|
+
*/
|
|
85
|
+
static storePrebindingDefinitions(nodeId, patternEntryId, prebindingDefinitions) {
|
|
86
|
+
for (const definition of prebindingDefinitions ?? []) {
|
|
87
|
+
PrebindingManager.prebindingDefinitions.set(definition.id, { ...definition });
|
|
88
|
+
PrebindingManager.prebindingDefinitionIdsByNodeId.set(nodeId, [definition.id]); // can only be one right now
|
|
89
|
+
if (definition.variableMappings) {
|
|
90
|
+
PrebindingManager.variableMappingByPatternId.set(patternEntryId, definition.variableMappings);
|
|
91
|
+
}
|
|
92
|
+
// Store the parameter definitions for the node
|
|
93
|
+
PrebindingManager.storeParameterDefinitions(nodeId, definition.parameterDefinitions || {});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Stores parameter definitions for a given nodeId.
|
|
98
|
+
* @param nodeId - The ID of the node to store parameter definitions for.
|
|
99
|
+
* @param parameterDefinitions - The parameter definitions to store.
|
|
100
|
+
*/
|
|
101
|
+
static storeParameterDefinitions(nodeId, parameterDefinitions) {
|
|
102
|
+
// Reset the list of parameter definitions for the nodeId
|
|
103
|
+
PrebindingManager.parameterDefinitionsByNodeId.set(nodeId, []);
|
|
104
|
+
const updatedParameterDefinitionsByNodeId = [];
|
|
105
|
+
for (const [parameterId, parameter] of Object.entries(parameterDefinitions || {})) {
|
|
106
|
+
PrebindingManager.parameterDefinitionsById.set(parameterId, {
|
|
107
|
+
parameterId,
|
|
108
|
+
parameter,
|
|
109
|
+
});
|
|
110
|
+
if (parameter.passToNodes) {
|
|
111
|
+
const { parameterId: paramIdToOverwrite, nodeId: targetNodeId } = parameter.passToNodes[0] ?? {};
|
|
112
|
+
if (paramIdToOverwrite) {
|
|
113
|
+
const existing = PrebindingManager.paramIdToOverwriteIdMap.get(paramIdToOverwrite) ?? [];
|
|
114
|
+
const hasMatchingOverride = existing.some((it) => it.overwrittenByParamId === parameterId &&
|
|
115
|
+
it.originalNodeIdToOverride === targetNodeId &&
|
|
116
|
+
it.indexedParentPatternNodeId === nodeId);
|
|
117
|
+
// Only add the override if it doesn't already exist to save duplicates
|
|
118
|
+
if (!hasMatchingOverride) {
|
|
119
|
+
PrebindingManager.paramIdToOverwriteIdMap.set(paramIdToOverwrite, [
|
|
120
|
+
...existing,
|
|
121
|
+
{
|
|
122
|
+
overwrittenByParamId: parameterId,
|
|
123
|
+
originalNodeIdToOverride: targetNodeId,
|
|
124
|
+
indexedParentPatternNodeId: nodeId,
|
|
125
|
+
},
|
|
126
|
+
]);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
updatedParameterDefinitionsByNodeId.push({ parameterId, parameter });
|
|
131
|
+
}
|
|
132
|
+
PrebindingManager.parameterDefinitionsByNodeId.set(nodeId, updatedParameterDefinitionsByNodeId);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Resolves the top-level parameterId for a given nodeId.
|
|
136
|
+
*
|
|
137
|
+
* @param nodeId - The nodeId to resolve the parameterId for
|
|
138
|
+
* @param useStoreParameters - Whether to use the zustand store parameters or not
|
|
139
|
+
* @returns string | undefined - The resolved parameterId or undefined if not found
|
|
140
|
+
**/
|
|
141
|
+
static getParameterIdByNodeId(nodeId) {
|
|
142
|
+
const nativeParameterDefinitionForNodeId = PrebindingManager.getNativeParameterDefinitionByNodeId(nodeId);
|
|
143
|
+
if (!nativeParameterDefinitionForNodeId) {
|
|
144
|
+
return undefined;
|
|
145
|
+
}
|
|
146
|
+
const hoistedParameterId = PrebindingManager.getHoistedIdForParameterId(nativeParameterDefinitionForNodeId?.parameterId, nodeId);
|
|
147
|
+
return hoistedParameterId;
|
|
148
|
+
}
|
|
149
|
+
/* Returns the parameter definitions from a parameterId
|
|
150
|
+
* @param parameterId - The parameter to resolve all levels for
|
|
151
|
+
* @param useStoreParameters - Whether to use the zustand store parameters or not
|
|
152
|
+
* @returns [l1ParameterDefinitions, l2ParameterDefinitions, l3ParameterDefinitions]: Array of parameter definitions for each level
|
|
153
|
+
*/
|
|
154
|
+
static getParameterDefinitionsByParameterId(parameterId) {
|
|
155
|
+
const l1Definition = PrebindingManager.parameterDefinitionsById.get(parameterId);
|
|
156
|
+
const l1PassToNode = (l1Definition?.parameter?.passToNodes || [])[0];
|
|
157
|
+
// Level 2
|
|
158
|
+
const l2Definition = PrebindingManager.parameterDefinitionsById.get(l1PassToNode?.parameterId);
|
|
159
|
+
const l2PassToNode = (l2Definition?.parameter?.passToNodes || [])[0];
|
|
160
|
+
let l3Definition;
|
|
161
|
+
// Level 3
|
|
162
|
+
if (l2PassToNode) {
|
|
163
|
+
// If the child definition has passToNodes, we can look up the child parameter definition by its composite key
|
|
164
|
+
l3Definition = PrebindingManager.parameterDefinitionsById.get(l2PassToNode?.parameterId);
|
|
165
|
+
}
|
|
166
|
+
// Return the definitions for all three levels unless they are all empty
|
|
167
|
+
const definitions = [l1Definition, l2Definition, l3Definition];
|
|
168
|
+
if (!definitions || !definitions.filter(Boolean).length) {
|
|
169
|
+
return undefined; // No definitions found
|
|
170
|
+
}
|
|
171
|
+
return definitions;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Returns all parameter definitions defined on the pattern of the given nodeId OR the pattern, wrapping the given nodeId
|
|
175
|
+
*/
|
|
176
|
+
static getAllParameterDefinitionsForNodeId(nodeId) {
|
|
177
|
+
return Object.fromEntries((PrebindingManager.parameterDefinitionsByNodeId.get(nodeId) ?? []).map(({ parameterId, parameter }) => [parameterId, parameter]));
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Return all parameter ID's on a pattern by NodeId
|
|
181
|
+
* @param nodeId - The nodeId to return params for
|
|
182
|
+
* @returns string[] An array of parameter IDs or undefined
|
|
183
|
+
*/
|
|
184
|
+
static getAllParameterIdsByNodeId(nodeId) {
|
|
185
|
+
return Object.keys(PrebindingManager.getAllParameterDefinitionsForNodeId(nodeId));
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Get the highest level overriding parameterId for a given parameterId + nodeId combination
|
|
189
|
+
* @param parameterId - The parameter to resolve
|
|
190
|
+
* @param indexedNodeId - The indexed node ID to resolve the parameterId for
|
|
191
|
+
* @returns string - The resolved parameterId - will be from "root" in patterns or the parent pattern node in experiences
|
|
192
|
+
*/
|
|
193
|
+
static getHoistedIdForParameterId(parameterId, indexedNodeId) {
|
|
194
|
+
let currentParamId = parameterId;
|
|
195
|
+
let currentIndexedNodeId = indexedNodeId;
|
|
196
|
+
let currentOriginalNodeId = PrebindingManager.newToOriginalNodeIdMap.get(indexedNodeId) ?? indexedNodeId;
|
|
197
|
+
let override;
|
|
198
|
+
do {
|
|
199
|
+
const overrides = PrebindingManager.paramIdToOverwriteIdMap.get(currentParamId) ?? [];
|
|
200
|
+
const splitByDash = currentIndexedNodeId.split(NODE_ID_SEPARATOR);
|
|
201
|
+
override = overrides.find((it) => it.originalNodeIdToOverride === currentOriginalNodeId &&
|
|
202
|
+
((splitByDash.length > 1 &&
|
|
203
|
+
currentIndexedNodeId.includes(it.indexedParentPatternNodeId)) ||
|
|
204
|
+
(splitByDash.length === 1 && it.indexedParentPatternNodeId === 'root')));
|
|
205
|
+
if (override) {
|
|
206
|
+
const { overwrittenByParamId, indexedParentPatternNodeId } = override;
|
|
207
|
+
currentParamId = overwrittenByParamId;
|
|
208
|
+
currentIndexedNodeId = indexedParentPatternNodeId;
|
|
209
|
+
currentOriginalNodeId =
|
|
210
|
+
PrebindingManager.newToOriginalNodeIdMap.get(indexedParentPatternNodeId) ??
|
|
211
|
+
indexedParentPatternNodeId;
|
|
212
|
+
}
|
|
213
|
+
} while (override);
|
|
214
|
+
return currentParamId;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Retrieves the native parameter definition for a given nodeId. ie one without passToNodes on the node.
|
|
218
|
+
* @param nodeId - The nodeId to retrieve the native parameter definition for
|
|
219
|
+
* @returns The native parameter definition for the given nodeId, or undefined if not found
|
|
220
|
+
*/
|
|
221
|
+
static getNativeParameterDefinitionByNodeId(nodeId) {
|
|
222
|
+
const parameterDefinitionsForNodeId = PrebindingManager.parameterDefinitionsByNodeId.get(nodeId);
|
|
223
|
+
return PrebindingManager.extractNativeParameterDefinition(parameterDefinitionsForNodeId);
|
|
224
|
+
}
|
|
225
|
+
static extractNativeParameterDefinition(parameterDefinitions) {
|
|
226
|
+
const { parameterId, parameter } = parameterDefinitions?.find((it) => !it.parameter.passToNodes?.length) || {};
|
|
227
|
+
if (!parameterId || !parameter)
|
|
228
|
+
return;
|
|
229
|
+
return {
|
|
230
|
+
parameterId,
|
|
231
|
+
parameter,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Resets all properties of the PrebindingManager class
|
|
236
|
+
* triggered when we leave ExperienceBuilder back to experience folder view.
|
|
237
|
+
**/
|
|
238
|
+
static reset() {
|
|
239
|
+
PrebindingManager.prebindingDefinitions = new Map();
|
|
240
|
+
PrebindingManager.parameterDefinitionsById = new Map();
|
|
241
|
+
PrebindingManager.parameterDefinitionsByNodeId = new Map();
|
|
242
|
+
PrebindingManager.variableMappingByPatternId = new Map();
|
|
243
|
+
PrebindingManager.newToOriginalNodeIdMap = new Map();
|
|
244
|
+
PrebindingManager.paramIdToOverwriteIdMap = new Map();
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export { PrebindingManager };
|
|
249
|
+
//# sourceMappingURL=PrebindingManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PrebindingManager.js","sources":["../../../../src/core/preview/PrebindingManager.ts"],"sourcesContent":["import {\n ExperienceComponentSettings,\n ParameterDefinition,\n VariableMapping,\n} from '@contentful/experiences-core/types';\n\nconst NODE_ID_SEPARATOR = '---'; // separator used to separate pattern levels in deseralizePatternNode\n\nexport type ParameterDefinitionWithParameterId = {\n parameterId: string;\n parameter: ParameterDefinition;\n};\ntype ParameterOverride = {\n overwrittenByParamId: string;\n originalNodeIdToOverride: string;\n indexedParentPatternNodeId: string;\n};\n\n/**\n * PrebindingManager utility class for resolving parameter bindings across nested patterns.\n *\n * The core approach is to first resolve the top-level parameterId using `getParameterIdByNodeId`,\n * which uses the paramIdToOverwriteIdMap, set when storing pre-binding based on the passToNodes chain to determine which parameter in the parent pattern\n * overrides a given parameterId (with some additionally workaround due to node ID renaming for patterns).\n * Once the owning top-level `parameterId` is found, we can follow the `passToNodes` chain back\n * down to retrieve all nested overrides — including parameter definitions, allowed content types,\n * and default sources — up to three levels deep.\n *\n * ## Lifecycle\n * This utility class currently uses static state, with Zustand stores supplementing the “latest” data\n * for root-level patterns data — for example, when overwriting content types on nested patterns or binding\n * fields on simple patterns. If we need the override mappings to be reactive, we could easily move\n * the full override chain tracking into Zustand but currently we can rely on the pattern definition\n * stores we have currently.\n *\n * The state is populated during deserialization, where we call `storePrebindingDefinitions` for each\n * pattern node. It is ready to be consumed at each level as nodes are deserialized top-down:\n * 1. Pattern C (Template Pattern)\n * 2. Pattern B (Nested Pattern)\n * 3. Pattern A (Simple Pattern)\n *\n * At each level, accessing overrides is possible:\n * - Pattern C has everything it needs once deserialized with its own parameters\n * - Pattern B has everything it needs once deserialized, with its own parameters possibly overridden by C\n * - Pattern A has its own parameters and possiblle overrites by B and/or C\n *\n * After actions that modify patterns without re-deserializing the tree — such as duplication,\n * deletion, or detachment — this state must be kept up to date via storePrebindingDefinitions\n * or storeParameterDefinitions if only parameter definitions are updated.\n *\n * ## Core Data Structures\n *\n * - prebindingDefinitions - A collection of all prebinding definitions aggregated\n * from the parent pattern down to all nested patterns.\n *\n * - prebindingDefinitionIdsByNodeId - Same as above, but indexed by `nodeId`. This allows us\n * to easily find the prebinding definition id for a given node ID.\n *\n * - parameterDefinitionsById - A collection of all parameter definitions aggregated\n * from the parent pattern down to nested patterns.\n *\n * - variableMappingByPatternId - A collection of all variable mappings aggregated from\n * the parent pattern down to nested patterns, indexed by\n * `patternId` for efficient access.\n *\n * - newToOriginalNodeIdMap - When deserializing pattern child nodes, we replace their\n * node IDs with new ones based on their location inside the\n * pattern. This prevents conflicts when multiple instances\n * of the same pattern exist. The issue is that prebinding\n * `passToNodes` resolution requires the original node ID.\n * This map allows us to retrieve it to follow the chain.\n *\n * - paramIdToOverwriteIdMap - Tracks parameter ID overrides through the `passToNodes`\n * chain, allowing us to resolve overrides correctly from\n * the top-level parameter down to the lowest-level.\n */\nexport class PrebindingManager {\n private static prebindingDefinitions: Map<\n string,\n NonNullable<ExperienceComponentSettings['prebindingDefinitions']>[number]\n > = new Map();\n private static prebindingDefinitionIdsByNodeId: Map<string, string[]> = new Map();\n private static parameterDefinitionsById: Map<string, ParameterDefinitionWithParameterId> =\n new Map();\n private static parameterDefinitionsByNodeId: Map<string, ParameterDefinitionWithParameterId[]> =\n new Map();\n private static variableMappingByPatternId: Map<string, Record<string, VariableMapping>> =\n new Map();\n private static newToOriginalNodeIdMap = new Map<string, string>();\n private static paramIdToOverwriteIdMap = new Map<string, Array<ParameterOverride>>();\n\n /**\n * Links new node IDs to original node IDs\n * - This is used to track the original node IDs for pattern instances as we change them when deserializing pattern nodes.\n * @param newNodeId\n * @param originalNodeId\n */\n public static linkOriginalNodeIds(newNodeId: string, originalNodeId: string) {\n PrebindingManager.newToOriginalNodeIdMap.set(newNodeId, originalNodeId);\n }\n\n /**\n * Initializes the pattern editor manager by storing the definitions during deserialization\n * for the root pattern and all nested patterns.\n *\n * @param nodeId - The ID of the pattern node.\n * @param patternEntryId - The ID of the pattern entry from the patterns store.\n * @param prebindingDefinitions - The prebinding definitions from the current pattern's component settings.\n */\n public static storePrebindingDefinitions(\n nodeId: string,\n patternEntryId: string,\n prebindingDefinitions: NonNullable<ExperienceComponentSettings['prebindingDefinitions']>,\n ) {\n for (const definition of prebindingDefinitions ?? []) {\n PrebindingManager.prebindingDefinitions.set(definition.id, { ...definition });\n PrebindingManager.prebindingDefinitionIdsByNodeId.set(nodeId, [definition.id]); // can only be one right now\n\n if (definition.variableMappings) {\n PrebindingManager.variableMappingByPatternId.set(\n patternEntryId,\n definition.variableMappings,\n );\n }\n // Store the parameter definitions for the node\n PrebindingManager.storeParameterDefinitions(nodeId, definition.parameterDefinitions || {});\n }\n }\n\n /**\n * Stores parameter definitions for a given nodeId.\n * @param nodeId - The ID of the node to store parameter definitions for.\n * @param parameterDefinitions - The parameter definitions to store.\n */\n public static storeParameterDefinitions(\n nodeId: string,\n parameterDefinitions?: Record<string, ParameterDefinition>,\n ) {\n // Reset the list of parameter definitions for the nodeId\n PrebindingManager.parameterDefinitionsByNodeId.set(nodeId, []);\n const updatedParameterDefinitionsByNodeId: ParameterDefinitionWithParameterId[] = [];\n\n for (const [parameterId, parameter] of Object.entries(parameterDefinitions || {})) {\n PrebindingManager.parameterDefinitionsById.set(parameterId, {\n parameterId,\n parameter,\n });\n\n if (parameter.passToNodes) {\n const { parameterId: paramIdToOverwrite, nodeId: targetNodeId } =\n parameter.passToNodes[0] ?? {};\n\n if (paramIdToOverwrite) {\n const existing = PrebindingManager.paramIdToOverwriteIdMap.get(paramIdToOverwrite) ?? [];\n const hasMatchingOverride = existing.some(\n (it) =>\n it.overwrittenByParamId === parameterId &&\n it.originalNodeIdToOverride === targetNodeId &&\n it.indexedParentPatternNodeId === nodeId,\n );\n\n // Only add the override if it doesn't already exist to save duplicates\n if (!hasMatchingOverride) {\n PrebindingManager.paramIdToOverwriteIdMap.set(paramIdToOverwrite, [\n ...existing,\n {\n overwrittenByParamId: parameterId,\n originalNodeIdToOverride: targetNodeId,\n indexedParentPatternNodeId: nodeId,\n },\n ]);\n }\n }\n }\n updatedParameterDefinitionsByNodeId.push({ parameterId, parameter });\n }\n PrebindingManager.parameterDefinitionsByNodeId.set(nodeId, updatedParameterDefinitionsByNodeId);\n }\n\n /**\n * Resolves the top-level parameterId for a given nodeId.\n *\n * @param nodeId - The nodeId to resolve the parameterId for\n * @param useStoreParameters - Whether to use the zustand store parameters or not\n * @returns string | undefined - The resolved parameterId or undefined if not found\n **/\n public static getParameterIdByNodeId(nodeId: string): string | undefined {\n const nativeParameterDefinitionForNodeId =\n PrebindingManager.getNativeParameterDefinitionByNodeId(nodeId);\n\n if (!nativeParameterDefinitionForNodeId) {\n return undefined;\n }\n const hoistedParameterId = PrebindingManager.getHoistedIdForParameterId(\n nativeParameterDefinitionForNodeId?.parameterId,\n nodeId,\n );\n\n return hoistedParameterId;\n }\n\n /* Returns the parameter definitions from a parameterId\n * @param parameterId - The parameter to resolve all levels for\n * @param useStoreParameters - Whether to use the zustand store parameters or not\n * @returns [l1ParameterDefinitions, l2ParameterDefinitions, l3ParameterDefinitions]: Array of parameter definitions for each level\n */\n public static getParameterDefinitionsByParameterId(\n parameterId: string,\n ): (ParameterDefinitionWithParameterId | undefined)[] | undefined {\n const l1Definition = PrebindingManager.parameterDefinitionsById.get(parameterId);\n\n const l1PassToNode = (l1Definition?.parameter?.passToNodes || [])[0];\n // Level 2\n const l2Definition = PrebindingManager.parameterDefinitionsById.get(l1PassToNode?.parameterId);\n const l2PassToNode = (l2Definition?.parameter?.passToNodes || [])[0];\n let l3Definition: ParameterDefinitionWithParameterId | undefined;\n // Level 3\n if (l2PassToNode) {\n // If the child definition has passToNodes, we can look up the child parameter definition by its composite key\n l3Definition = PrebindingManager.parameterDefinitionsById.get(l2PassToNode?.parameterId);\n }\n // Return the definitions for all three levels unless they are all empty\n const definitions = [l1Definition, l2Definition, l3Definition];\n if (!definitions || !definitions.filter(Boolean).length) {\n return undefined; // No definitions found\n }\n return definitions;\n }\n\n /**\n * Returns all parameter definitions defined on the pattern of the given nodeId OR the pattern, wrapping the given nodeId\n */\n public static getAllParameterDefinitionsForNodeId(nodeId: string) {\n return Object.fromEntries(\n (PrebindingManager.parameterDefinitionsByNodeId.get(nodeId) ?? []).map(\n ({ parameterId, parameter }) => [parameterId, parameter],\n ),\n );\n }\n\n /**\n * Return all parameter ID's on a pattern by NodeId\n * @param nodeId - The nodeId to return params for\n * @returns string[] An array of parameter IDs or undefined\n */\n public static getAllParameterIdsByNodeId(nodeId: string): string[] | undefined {\n return Object.keys(PrebindingManager.getAllParameterDefinitionsForNodeId(nodeId));\n }\n\n /**\n * Get the highest level overriding parameterId for a given parameterId + nodeId combination\n * @param parameterId - The parameter to resolve\n * @param indexedNodeId - The indexed node ID to resolve the parameterId for\n * @returns string - The resolved parameterId - will be from \"root\" in patterns or the parent pattern node in experiences\n */\n public static getHoistedIdForParameterId(parameterId: string, indexedNodeId: string): string {\n let currentParamId = parameterId;\n let currentIndexedNodeId = indexedNodeId;\n let currentOriginalNodeId: string | undefined =\n PrebindingManager.newToOriginalNodeIdMap.get(indexedNodeId) ?? indexedNodeId;\n let override: ParameterOverride | undefined;\n\n do {\n const overrides = PrebindingManager.paramIdToOverwriteIdMap.get(currentParamId) ?? [];\n const splitByDash = currentIndexedNodeId.split(NODE_ID_SEPARATOR);\n override = overrides.find(\n (it) =>\n it.originalNodeIdToOverride === currentOriginalNodeId &&\n ((splitByDash.length > 1 &&\n currentIndexedNodeId.includes(it.indexedParentPatternNodeId)) ||\n (splitByDash.length === 1 && it.indexedParentPatternNodeId === 'root')),\n );\n if (override) {\n const { overwrittenByParamId, indexedParentPatternNodeId } = override;\n currentParamId = overwrittenByParamId;\n currentIndexedNodeId = indexedParentPatternNodeId;\n currentOriginalNodeId =\n PrebindingManager.newToOriginalNodeIdMap.get(indexedParentPatternNodeId) ??\n indexedParentPatternNodeId;\n }\n } while (override);\n\n return currentParamId;\n }\n\n /**\n * Retrieves the native parameter definition for a given nodeId. ie one without passToNodes on the node.\n * @param nodeId - The nodeId to retrieve the native parameter definition for\n * @returns The native parameter definition for the given nodeId, or undefined if not found\n */\n public static getNativeParameterDefinitionByNodeId(\n nodeId: string,\n ): ParameterDefinitionWithParameterId | undefined {\n const parameterDefinitionsForNodeId =\n PrebindingManager.parameterDefinitionsByNodeId.get(nodeId);\n return PrebindingManager.extractNativeParameterDefinition(parameterDefinitionsForNodeId);\n }\n\n private static extractNativeParameterDefinition(\n parameterDefinitions: ParameterDefinitionWithParameterId[] | undefined,\n ): ParameterDefinitionWithParameterId | undefined {\n const { parameterId, parameter } =\n parameterDefinitions?.find((it) => !it.parameter.passToNodes?.length) || {};\n if (!parameterId || !parameter) return;\n return {\n parameterId,\n parameter,\n };\n }\n\n /**\n * Resets all properties of the PrebindingManager class\n * triggered when we leave ExperienceBuilder back to experience folder view.\n **/\n public static reset() {\n PrebindingManager.prebindingDefinitions = new Map();\n PrebindingManager.parameterDefinitionsById = new Map();\n PrebindingManager.parameterDefinitionsByNodeId = new Map();\n PrebindingManager.variableMappingByPatternId = new Map();\n PrebindingManager.newToOriginalNodeIdMap = new Map();\n PrebindingManager.paramIdToOverwriteIdMap = new Map();\n }\n}\n"],"names":[],"mappings":"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"}
|