@contentful/experiences-core 1.30.0-beta.0 → 1.30.0-dev-20250124T1739-560b81b.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/entity/EntityStore.d.ts +2 -5
- package/dist/index.js +33 -118
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -10,15 +10,13 @@ type EntityStoreArgs = {
|
|
|
10
10
|
locale: string;
|
|
11
11
|
};
|
|
12
12
|
declare class EntityStore extends EntityStoreBase {
|
|
13
|
-
private
|
|
14
|
-
private _experienceEntryId;
|
|
13
|
+
private _experienceEntry;
|
|
15
14
|
private _unboundValues;
|
|
16
15
|
private _usedComponentsWithDeepReferences;
|
|
17
16
|
constructor(json: string);
|
|
18
17
|
constructor({ experienceEntry, entities, locale }: EntityStoreArgs);
|
|
19
18
|
getCurrentLocale(): string;
|
|
20
19
|
get experienceEntryFields(): ExperienceFields | undefined;
|
|
21
|
-
get experienceEntryId(): string | undefined;
|
|
22
20
|
get schemaVersion(): "2023-09-28" | undefined;
|
|
23
21
|
get breakpoints(): {
|
|
24
22
|
id: string;
|
|
@@ -56,8 +54,7 @@ declare class EntityStore extends EntityStoreBase {
|
|
|
56
54
|
[k: string]: Asset<contentful.ChainModifiers, string>;
|
|
57
55
|
};
|
|
58
56
|
locale: string;
|
|
59
|
-
|
|
60
|
-
_experienceEntryId: string | undefined;
|
|
57
|
+
_experienceEntry: ExperienceFields | undefined;
|
|
61
58
|
_unboundValues: Record<string, {
|
|
62
59
|
value?: string | number | boolean | Record<any, any> | undefined;
|
|
63
60
|
}> | undefined;
|
package/dist/index.js
CHANGED
|
@@ -1563,7 +1563,7 @@ const detachExperienceStyles = (experience) => {
|
|
|
1563
1563
|
}, {});
|
|
1564
1564
|
// getting the breakpoint ids
|
|
1565
1565
|
const breakpointIds = Object.keys(mediaQueriesTemplate);
|
|
1566
|
-
const iterateOverTreeAndExtractStyles = ({ componentTree, dataSource, unboundValues, componentSettings, componentVariablesOverwrites, patternWrapper,
|
|
1566
|
+
const iterateOverTreeAndExtractStyles = ({ componentTree, dataSource, unboundValues, componentSettings, componentVariablesOverwrites, patternWrapper, }) => {
|
|
1567
1567
|
// traversing the tree
|
|
1568
1568
|
const queue = [];
|
|
1569
1569
|
queue.push(...componentTree.children);
|
|
@@ -1580,10 +1580,6 @@ const detachExperienceStyles = (experience) => {
|
|
|
1580
1580
|
usedComponents,
|
|
1581
1581
|
});
|
|
1582
1582
|
if (isPatternNode) {
|
|
1583
|
-
// When detecting a circular dependency among patterns, stop to avoid an infinite loop
|
|
1584
|
-
if (wrappingPatternIds.has(currentNode.definitionId)) {
|
|
1585
|
-
continue;
|
|
1586
|
-
}
|
|
1587
1583
|
const patternEntry = usedComponents.find((component) => component.sys.id === currentNode.definitionId);
|
|
1588
1584
|
if (!patternEntry || !('fields' in patternEntry)) {
|
|
1589
1585
|
continue;
|
|
@@ -1624,7 +1620,6 @@ const detachExperienceStyles = (experience) => {
|
|
|
1624
1620
|
componentVariablesOverwrites: currentNode.variables,
|
|
1625
1621
|
// pass top-level pattern node to store instance-specific child styles for rendering
|
|
1626
1622
|
patternWrapper: currentNode,
|
|
1627
|
-
wrappingPatternIds: new Set([...wrappingPatternIds, currentNode.definitionId]),
|
|
1628
1623
|
});
|
|
1629
1624
|
continue;
|
|
1630
1625
|
}
|
|
@@ -1781,7 +1776,6 @@ const detachExperienceStyles = (experience) => {
|
|
|
1781
1776
|
dataSource: experience.entityStore?.dataSource ?? {},
|
|
1782
1777
|
unboundValues: experience.entityStore?.unboundValues ?? {},
|
|
1783
1778
|
componentSettings: experience.entityStore?.experienceEntryFields?.componentSettings,
|
|
1784
|
-
wrappingPatternIds: new Set(experience.entityStore?.experienceEntryId ? [experience.entityStore.experienceEntryId] : []),
|
|
1785
1779
|
});
|
|
1786
1780
|
// once the whole tree was traversed, for each breakpoint, I aggregate the styles
|
|
1787
1781
|
// for each generated className into one css string
|
|
@@ -3144,76 +3138,64 @@ class EditorModeEntityStore extends EditorEntityStore {
|
|
|
3144
3138
|
}
|
|
3145
3139
|
}
|
|
3146
3140
|
|
|
3147
|
-
const
|
|
3148
|
-
const
|
|
3141
|
+
const gatherUsedComponentsWithDeepRefernces = (experienceEntryFields) => {
|
|
3142
|
+
const usedComponentDeepReferences = [];
|
|
3149
3143
|
const usedComponents = experienceEntryFields?.usedComponents;
|
|
3150
3144
|
if (!usedComponents || usedComponents.length === 0) {
|
|
3151
3145
|
return [];
|
|
3152
3146
|
}
|
|
3153
3147
|
for (const component of usedComponents) {
|
|
3154
3148
|
if ('fields' in component) {
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
continue;
|
|
3158
|
-
}
|
|
3159
|
-
totalUsedComponents.push(...resolveDeepUsedComponents({
|
|
3160
|
-
experienceEntryFields: component.fields,
|
|
3161
|
-
parentComponents: new Set([...parentComponents, component.sys.id]),
|
|
3162
|
-
}));
|
|
3149
|
+
usedComponentDeepReferences.push(component);
|
|
3150
|
+
usedComponentDeepReferences.push(...gatherUsedComponentsWithDeepRefernces(component.fields));
|
|
3163
3151
|
}
|
|
3164
3152
|
}
|
|
3165
|
-
return
|
|
3153
|
+
return usedComponentDeepReferences;
|
|
3166
3154
|
};
|
|
3167
3155
|
|
|
3168
3156
|
class EntityStore extends EntityStoreBase {
|
|
3169
3157
|
constructor(options) {
|
|
3170
3158
|
if (typeof options === 'string') {
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
const serializedAttributes = JSON.parse(options).entityStore;
|
|
3159
|
+
const data = JSON.parse(options);
|
|
3160
|
+
const { _experienceEntry, _unboundValues, locale, entryMap, assetMap } = data.entityStore;
|
|
3174
3161
|
super({
|
|
3175
3162
|
entities: [
|
|
3176
|
-
...Object.values(
|
|
3177
|
-
...Object.values(
|
|
3163
|
+
...Object.values(entryMap),
|
|
3164
|
+
...Object.values(assetMap),
|
|
3178
3165
|
],
|
|
3179
|
-
locale
|
|
3166
|
+
locale,
|
|
3180
3167
|
});
|
|
3181
|
-
this.
|
|
3182
|
-
this.
|
|
3183
|
-
this.
|
|
3168
|
+
this._experienceEntry = _experienceEntry;
|
|
3169
|
+
this._unboundValues = _unboundValues;
|
|
3170
|
+
this._usedComponentsWithDeepReferences = gatherUsedComponentsWithDeepRefernces(this._experienceEntry);
|
|
3184
3171
|
}
|
|
3185
3172
|
else {
|
|
3186
3173
|
const { experienceEntry, entities, locale } = options;
|
|
3187
|
-
|
|
3174
|
+
super({ entities, locale });
|
|
3175
|
+
if (isExperienceEntry(experienceEntry)) {
|
|
3176
|
+
this._experienceEntry = experienceEntry.fields;
|
|
3177
|
+
this._unboundValues = experienceEntry.fields.unboundValues;
|
|
3178
|
+
this._usedComponentsWithDeepReferences = gatherUsedComponentsWithDeepRefernces(this._experienceEntry);
|
|
3179
|
+
}
|
|
3180
|
+
else {
|
|
3188
3181
|
throw new Error('Provided entry is not experience entry');
|
|
3189
3182
|
}
|
|
3190
|
-
super({ entities, locale });
|
|
3191
|
-
this._experienceEntryFields = experienceEntry.fields;
|
|
3192
|
-
this._experienceEntryId = experienceEntry.sys.id;
|
|
3193
|
-
this._unboundValues = experienceEntry.fields.unboundValues;
|
|
3194
3183
|
}
|
|
3195
|
-
this._usedComponentsWithDeepReferences = resolveDeepUsedComponents({
|
|
3196
|
-
experienceEntryFields: this._experienceEntryFields,
|
|
3197
|
-
parentComponents: new Set([this._experienceEntryId]),
|
|
3198
|
-
});
|
|
3199
3184
|
}
|
|
3200
3185
|
getCurrentLocale() {
|
|
3201
3186
|
return this.locale;
|
|
3202
3187
|
}
|
|
3203
3188
|
get experienceEntryFields() {
|
|
3204
|
-
return this.
|
|
3205
|
-
}
|
|
3206
|
-
get experienceEntryId() {
|
|
3207
|
-
return this._experienceEntryId;
|
|
3189
|
+
return this._experienceEntry;
|
|
3208
3190
|
}
|
|
3209
3191
|
get schemaVersion() {
|
|
3210
|
-
return this.
|
|
3192
|
+
return this._experienceEntry?.componentTree.schemaVersion;
|
|
3211
3193
|
}
|
|
3212
3194
|
get breakpoints() {
|
|
3213
|
-
return this.
|
|
3195
|
+
return this._experienceEntry?.componentTree.breakpoints ?? [];
|
|
3214
3196
|
}
|
|
3215
3197
|
get dataSource() {
|
|
3216
|
-
return this.
|
|
3198
|
+
return this._experienceEntry?.dataSource ?? {};
|
|
3217
3199
|
}
|
|
3218
3200
|
get unboundValues() {
|
|
3219
3201
|
return this._unboundValues ?? {};
|
|
@@ -3244,8 +3226,7 @@ class EntityStore extends EntityStoreBase {
|
|
|
3244
3226
|
}
|
|
3245
3227
|
toJSON() {
|
|
3246
3228
|
return {
|
|
3247
|
-
|
|
3248
|
-
_experienceEntryId: this._experienceEntryId,
|
|
3229
|
+
_experienceEntry: this._experienceEntry,
|
|
3249
3230
|
_unboundValues: this._unboundValues,
|
|
3250
3231
|
...super.toJSON(),
|
|
3251
3232
|
};
|
|
@@ -3570,22 +3551,22 @@ const fetchReferencedEntities = async ({ client, experienceEntry, locale, }) =>
|
|
|
3570
3551
|
throw new Error('Failed to fetch experience entities. Provided "experienceEntry" does not match experience entry schema');
|
|
3571
3552
|
}
|
|
3572
3553
|
const deepReferences = gatherDeepReferencesFromExperienceEntry(experienceEntry);
|
|
3573
|
-
const entryIds =
|
|
3574
|
-
const assetIds =
|
|
3554
|
+
const entryIds = [];
|
|
3555
|
+
const assetIds = [];
|
|
3575
3556
|
for (const dataBinding of Object.values(experienceEntry.fields.dataSource)) {
|
|
3576
3557
|
if (!('sys' in dataBinding)) {
|
|
3577
3558
|
continue;
|
|
3578
3559
|
}
|
|
3579
3560
|
if (dataBinding.sys.linkType === 'Entry') {
|
|
3580
|
-
entryIds.
|
|
3561
|
+
entryIds.push(dataBinding.sys.id);
|
|
3581
3562
|
}
|
|
3582
3563
|
if (dataBinding.sys.linkType === 'Asset') {
|
|
3583
|
-
assetIds.
|
|
3564
|
+
assetIds.push(dataBinding.sys.id);
|
|
3584
3565
|
}
|
|
3585
3566
|
}
|
|
3586
3567
|
const [entriesResponse, assetsResponse] = await Promise.all([
|
|
3587
|
-
fetchAllEntries({ client, ids:
|
|
3588
|
-
fetchAllAssets({ client, ids:
|
|
3568
|
+
fetchAllEntries({ client, ids: entryIds, locale }),
|
|
3569
|
+
fetchAllAssets({ client, ids: assetIds, locale }),
|
|
3589
3570
|
]);
|
|
3590
3571
|
const { autoFetchedReferentAssets, autoFetchedReferentEntries } = gatherAutoFetchedReferentsFromIncludes(deepReferences, entriesResponse);
|
|
3591
3572
|
// Using client getEntries resolves all linked entry references, so we do not need to resolve entries in usedComponents
|
|
@@ -3606,68 +3587,6 @@ const fetchReferencedEntities = async ({ client, experienceEntry, locale, }) =>
|
|
|
3606
3587
|
};
|
|
3607
3588
|
};
|
|
3608
3589
|
|
|
3609
|
-
/**
|
|
3610
|
-
* The CMA client will automatically replace links with entry references.
|
|
3611
|
-
* As we're including all referenced pattern entries in usedComponents, this can lead
|
|
3612
|
-
* to a circular reference. This function replaces those with plain links inplace (!).
|
|
3613
|
-
*
|
|
3614
|
-
* @see https://github.com/contentful/contentful.js/issues/377
|
|
3615
|
-
*/
|
|
3616
|
-
const removeCircularPatternReferences = (experienceEntry, _parentIds) => {
|
|
3617
|
-
const parentIds = _parentIds ?? new Set([experienceEntry.sys.id]);
|
|
3618
|
-
const usedComponents = experienceEntry.fields.usedComponents;
|
|
3619
|
-
const newUsedComponents = usedComponents?.reduce((acc, linkOrEntry) => {
|
|
3620
|
-
if (!('fields' in linkOrEntry)) {
|
|
3621
|
-
// It is a link, we're good
|
|
3622
|
-
return [...acc, linkOrEntry];
|
|
3623
|
-
}
|
|
3624
|
-
const entry = linkOrEntry;
|
|
3625
|
-
if (parentIds.has(entry.sys.id)) {
|
|
3626
|
-
// It is an entry that already occurred -> turn it into a link to remove the circularity
|
|
3627
|
-
const link = {
|
|
3628
|
-
sys: {
|
|
3629
|
-
id: entry.sys.id,
|
|
3630
|
-
linkType: 'Entry',
|
|
3631
|
-
type: 'Link',
|
|
3632
|
-
},
|
|
3633
|
-
};
|
|
3634
|
-
return [...acc, link];
|
|
3635
|
-
}
|
|
3636
|
-
// Remove circularity for its usedComponents as well (inplace)
|
|
3637
|
-
removeCircularPatternReferences(entry, new Set([...parentIds, entry.sys.id]));
|
|
3638
|
-
return [...acc, entry];
|
|
3639
|
-
}, []);
|
|
3640
|
-
// @ts-expect-error - type of usedComponents doesn't yet allow a mixed list of both links and entries
|
|
3641
|
-
experienceEntry.fields.usedComponents = newUsedComponents;
|
|
3642
|
-
};
|
|
3643
|
-
/**
|
|
3644
|
-
* The CMA client will automatically replace links with entry references if they are available.
|
|
3645
|
-
* While we're not fetching the data sources, a self reference would be replaced as the entry is
|
|
3646
|
-
* fetched. Any circuar reference in the object breaks SSR where we have to stringify the JSON.
|
|
3647
|
-
* This would fail if the object contains circular references.
|
|
3648
|
-
*/
|
|
3649
|
-
const removeSelfReferencingDataSource = (experienceEntry) => {
|
|
3650
|
-
const dataSources = experienceEntry.fields.dataSource;
|
|
3651
|
-
const newDataSource = Object.entries(dataSources).reduce((acc, [key, linkOrEntry]) => {
|
|
3652
|
-
if ('fields' in linkOrEntry && linkOrEntry.sys.id === experienceEntry.sys.id) {
|
|
3653
|
-
const entry = linkOrEntry;
|
|
3654
|
-
acc[key] = {
|
|
3655
|
-
sys: {
|
|
3656
|
-
id: entry.sys.id,
|
|
3657
|
-
linkType: 'Entry',
|
|
3658
|
-
type: 'Link',
|
|
3659
|
-
},
|
|
3660
|
-
};
|
|
3661
|
-
}
|
|
3662
|
-
else {
|
|
3663
|
-
const link = linkOrEntry;
|
|
3664
|
-
acc[key] = link;
|
|
3665
|
-
}
|
|
3666
|
-
return acc;
|
|
3667
|
-
}, {});
|
|
3668
|
-
experienceEntry.fields.dataSource = newDataSource;
|
|
3669
|
-
};
|
|
3670
|
-
|
|
3671
3590
|
const errorMessagesWhileFetching$1 = {
|
|
3672
3591
|
experience: 'Failed to fetch experience',
|
|
3673
3592
|
experienceReferences: 'Failed to fetch entities, referenced in experience',
|
|
@@ -3681,7 +3600,7 @@ const handleError$1 = (generalMessage, error) => {
|
|
|
3681
3600
|
* @param {FetchBySlugParams} options - options to fetch the experience
|
|
3682
3601
|
*/
|
|
3683
3602
|
async function fetchBySlug({ client, experienceTypeId, slug, localeCode, isEditorMode, }) {
|
|
3684
|
-
//
|
|
3603
|
+
//Be a no-op if in editor mode
|
|
3685
3604
|
if (isEditorMode)
|
|
3686
3605
|
return;
|
|
3687
3606
|
let experienceEntry = undefined;
|
|
@@ -3697,8 +3616,6 @@ async function fetchBySlug({ client, experienceTypeId, slug, localeCode, isEdito
|
|
|
3697
3616
|
if (!experienceEntry) {
|
|
3698
3617
|
throw new Error(`No experience entry with slug: ${slug} exists`);
|
|
3699
3618
|
}
|
|
3700
|
-
removeCircularPatternReferences(experienceEntry);
|
|
3701
|
-
removeSelfReferencingDataSource(experienceEntry);
|
|
3702
3619
|
try {
|
|
3703
3620
|
const { entries, assets } = await fetchReferencedEntities({
|
|
3704
3621
|
client,
|
|
@@ -3751,8 +3668,6 @@ async function fetchById({ client, experienceTypeId, id, localeCode, isEditorMod
|
|
|
3751
3668
|
if (!experienceEntry) {
|
|
3752
3669
|
throw new Error(`No experience entry with id: ${id} exists`);
|
|
3753
3670
|
}
|
|
3754
|
-
removeCircularPatternReferences(experienceEntry);
|
|
3755
|
-
removeSelfReferencingDataSource(experienceEntry);
|
|
3756
3671
|
try {
|
|
3757
3672
|
const { entries, assets } = await fetchReferencedEntities({
|
|
3758
3673
|
client,
|