@contentful/optimization-core 0.1.0-alpha
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/LICENSE +21 -0
- package/README.md +408 -0
- package/dist/Consent.d.ts +44 -0
- package/dist/Consent.d.ts.map +1 -0
- package/dist/Consent.js +2 -0
- package/dist/Consent.js.map +1 -0
- package/dist/CoreBase.d.ts +161 -0
- package/dist/CoreBase.d.ts.map +1 -0
- package/dist/CoreBase.js +151 -0
- package/dist/CoreBase.js.map +1 -0
- package/dist/CoreStateful.d.ts +142 -0
- package/dist/CoreStateful.d.ts.map +1 -0
- package/dist/CoreStateful.js +137 -0
- package/dist/CoreStateful.js.map +1 -0
- package/dist/CoreStateless.d.ts +53 -0
- package/dist/CoreStateless.d.ts.map +1 -0
- package/dist/CoreStateless.js +43 -0
- package/dist/CoreStateless.js.map +1 -0
- package/dist/ProductBase.d.ts +83 -0
- package/dist/ProductBase.d.ts.map +1 -0
- package/dist/ProductBase.js +50 -0
- package/dist/ProductBase.js.map +1 -0
- package/dist/analytics/AnalyticsBase.d.ts +35 -0
- package/dist/analytics/AnalyticsBase.d.ts.map +1 -0
- package/dist/analytics/AnalyticsBase.js +13 -0
- package/dist/analytics/AnalyticsBase.js.map +1 -0
- package/dist/analytics/AnalyticsStateful.d.ts +138 -0
- package/dist/analytics/AnalyticsStateful.d.ts.map +1 -0
- package/dist/analytics/AnalyticsStateful.js +179 -0
- package/dist/analytics/AnalyticsStateful.js.map +1 -0
- package/dist/analytics/AnalyticsStateless.d.ts +48 -0
- package/dist/analytics/AnalyticsStateless.d.ts.map +1 -0
- package/dist/analytics/AnalyticsStateless.js +61 -0
- package/dist/analytics/AnalyticsStateless.js.map +1 -0
- package/dist/analytics/index.d.ts +5 -0
- package/dist/analytics/index.d.ts.map +1 -0
- package/dist/analytics/index.js +5 -0
- package/dist/analytics/index.js.map +1 -0
- package/dist/global-constants.d.ts +18 -0
- package/dist/global-constants.d.ts.map +1 -0
- package/dist/global-constants.js +18 -0
- package/dist/global-constants.js.map +1 -0
- package/dist/index.cjs +1808 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1535 -0
- package/dist/index.mjs.map +1 -0
- package/dist/lib/decorators/guardedBy.d.ts +113 -0
- package/dist/lib/decorators/guardedBy.d.ts.map +1 -0
- package/dist/lib/decorators/guardedBy.js +143 -0
- package/dist/lib/decorators/guardedBy.js.map +1 -0
- package/dist/lib/decorators/index.d.ts +2 -0
- package/dist/lib/decorators/index.d.ts.map +1 -0
- package/dist/lib/decorators/index.js +2 -0
- package/dist/lib/decorators/index.js.map +1 -0
- package/dist/lib/interceptor/InterceptorManager.d.ts +127 -0
- package/dist/lib/interceptor/InterceptorManager.d.ts.map +1 -0
- package/dist/lib/interceptor/InterceptorManager.js +125 -0
- package/dist/lib/interceptor/InterceptorManager.js.map +1 -0
- package/dist/lib/interceptor/index.d.ts +2 -0
- package/dist/lib/interceptor/index.d.ts.map +1 -0
- package/dist/lib/interceptor/index.js +2 -0
- package/dist/lib/interceptor/index.js.map +1 -0
- package/dist/lib/value-presence/ValuePresence.d.ts +123 -0
- package/dist/lib/value-presence/ValuePresence.d.ts.map +1 -0
- package/dist/lib/value-presence/ValuePresence.js +141 -0
- package/dist/lib/value-presence/ValuePresence.js.map +1 -0
- package/dist/lib/value-presence/index.d.ts +2 -0
- package/dist/lib/value-presence/index.d.ts.map +1 -0
- package/dist/lib/value-presence/index.js +2 -0
- package/dist/lib/value-presence/index.js.map +1 -0
- package/dist/personalization/PersonalizationBase.d.ts +184 -0
- package/dist/personalization/PersonalizationBase.d.ts.map +1 -0
- package/dist/personalization/PersonalizationBase.js +76 -0
- package/dist/personalization/PersonalizationBase.js.map +1 -0
- package/dist/personalization/PersonalizationStateful.d.ts +226 -0
- package/dist/personalization/PersonalizationStateful.d.ts.map +1 -0
- package/dist/personalization/PersonalizationStateful.js +297 -0
- package/dist/personalization/PersonalizationStateful.js.map +1 -0
- package/dist/personalization/PersonalizationStateless.d.ts +74 -0
- package/dist/personalization/PersonalizationStateless.d.ts.map +1 -0
- package/dist/personalization/PersonalizationStateless.js +98 -0
- package/dist/personalization/PersonalizationStateless.js.map +1 -0
- package/dist/personalization/index.d.ts +6 -0
- package/dist/personalization/index.d.ts.map +1 -0
- package/dist/personalization/index.js +6 -0
- package/dist/personalization/index.js.map +1 -0
- package/dist/personalization/resolvers/FlagsResolver.d.ts +35 -0
- package/dist/personalization/resolvers/FlagsResolver.d.ts.map +1 -0
- package/dist/personalization/resolvers/FlagsResolver.js +47 -0
- package/dist/personalization/resolvers/FlagsResolver.js.map +1 -0
- package/dist/personalization/resolvers/MergeTagValueResolver.d.ts +74 -0
- package/dist/personalization/resolvers/MergeTagValueResolver.d.ts.map +1 -0
- package/dist/personalization/resolvers/MergeTagValueResolver.js +109 -0
- package/dist/personalization/resolvers/MergeTagValueResolver.js.map +1 -0
- package/dist/personalization/resolvers/PersonalizedEntryResolver.d.ts +142 -0
- package/dist/personalization/resolvers/PersonalizedEntryResolver.d.ts.map +1 -0
- package/dist/personalization/resolvers/PersonalizedEntryResolver.js +196 -0
- package/dist/personalization/resolvers/PersonalizedEntryResolver.js.map +1 -0
- package/dist/personalization/resolvers/index.d.ts +7 -0
- package/dist/personalization/resolvers/index.d.ts.map +1 -0
- package/dist/personalization/resolvers/index.js +7 -0
- package/dist/personalization/resolvers/index.js.map +1 -0
- package/dist/signals.d.ts +35 -0
- package/dist/signals.d.ts.map +1 -0
- package/dist/signals.js +30 -0
- package/dist/signals.js.map +1 -0
- package/package.json +29 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { MergeTagEntry, Profile } from '@contentful/optimization-api-client';
|
|
2
|
+
/**
|
|
3
|
+
* Resolves merge tag values from a {@link Profile}.
|
|
4
|
+
*
|
|
5
|
+
* @public
|
|
6
|
+
* @remarks
|
|
7
|
+
* *Merge tags* are references to user profile data that may be embedded in content
|
|
8
|
+
* and expanded at runtime. This resolver normalizes the merge-tag identifier into
|
|
9
|
+
* a set of candidate selectors and searches the profile for a matching value.
|
|
10
|
+
* Result values are returned as strings; numeric/boolean primitives are stringified.
|
|
11
|
+
*/
|
|
12
|
+
declare const MergeTagValueResolver: {
|
|
13
|
+
/**
|
|
14
|
+
* Type guard to ensure the input is a {@link MergeTagEntry}.
|
|
15
|
+
*
|
|
16
|
+
* @param embeddedEntryNodeTarget - Unknown value to validate.
|
|
17
|
+
* @returns `true` if the input is a valid merge-tag entry.
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* if (MergeTagValueResolver.isMergeTagEntry(node)) {
|
|
21
|
+
* // safe to read fields
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
isMergeTagEntry(embeddedEntryNodeTarget: unknown): embeddedEntryNodeTarget is MergeTagEntry;
|
|
26
|
+
/**
|
|
27
|
+
* Generate a list of candidate selectors for a merge-tag ID.
|
|
28
|
+
*
|
|
29
|
+
* @param id - Merge-tag identifier (segments separated by `_`).
|
|
30
|
+
* @returns Array of dot-path selectors to try against a profile.
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* // "profile_name_first" -> [
|
|
34
|
+
* // 'profile',
|
|
35
|
+
* // 'profile.name',
|
|
36
|
+
* // 'profile.name.first'
|
|
37
|
+
* // ]
|
|
38
|
+
* const selectors = MergeTagValueResolver.normalizeSelectors('profile_name_first')
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
normalizeSelectors(id: string): string[];
|
|
42
|
+
/**
|
|
43
|
+
* Look up a merge-tag value from a profile using normalized selectors.
|
|
44
|
+
*
|
|
45
|
+
* @param id - Merge-tag identifier.
|
|
46
|
+
* @param profile - Profile from which to resolve the value.
|
|
47
|
+
* @returns A stringified primitive if found; otherwise `undefined`.
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* const value = MergeTagValueResolver.getValueFromProfile('user_email', profile)
|
|
51
|
+
* if (value) sendEmailTo(value)
|
|
52
|
+
* ```
|
|
53
|
+
* @remarks
|
|
54
|
+
* Only string/number/boolean primitives are returned; objects/arrays are ignored.
|
|
55
|
+
*/
|
|
56
|
+
getValueFromProfile(id: string, profile?: Profile): string | undefined;
|
|
57
|
+
/**
|
|
58
|
+
* Resolve the display value for a merge-tag entry using the provided profile,
|
|
59
|
+
* falling back to the entry's configured `nt_fallback` when necessary.
|
|
60
|
+
*
|
|
61
|
+
* @param mergeTagEntry - The merge-tag entry to resolve.
|
|
62
|
+
* @param profile - Optional profile used for lookup.
|
|
63
|
+
* @returns The resolved string, or `undefined` if the entry is invalid and no
|
|
64
|
+
* fallback is available.
|
|
65
|
+
* @example
|
|
66
|
+
* ```ts
|
|
67
|
+
* const text = MergeTagValueResolver.resolve(entry, profile)
|
|
68
|
+
* render(text ?? 'Guest')
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
resolve(mergeTagEntry: MergeTagEntry | undefined, profile?: Profile): string | undefined;
|
|
72
|
+
};
|
|
73
|
+
export default MergeTagValueResolver;
|
|
74
|
+
//# sourceMappingURL=MergeTagValueResolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MergeTagValueResolver.d.ts","sourceRoot":"","sources":["../../../src/personalization/resolvers/MergeTagValueResolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,qCAAqC,CAAA;AAS5E;;;;;;;;;GASG;AACH,QAAA,MAAM,qBAAqB;IACzB;;;;;;;;;;;OAWG;6CACsC,OAAO,GAAG,uBAAuB,IAAI,aAAa;IAI3F;;;;;;;;;;;;;;OAcG;2BACoB,MAAM,GAAG,MAAM,EAAE;IASxC;;;;;;;;;;;;;OAaG;4BACqB,MAAM,YAAY,OAAO,GAAG,MAAM,GAAG,SAAS;IAiBtE;;;;;;;;;;;;;OAaG;2BACoB,aAAa,GAAG,SAAS,YAAY,OAAO,GAAG,MAAM,GAAG,SAAS;CAoBzF,CAAA;AAED,eAAe,qBAAqB,CAAA"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { MergeTagEntry, Profile } from '@contentful/optimization-api-client';
|
|
2
|
+
import { get } from 'es-toolkit/compat';
|
|
3
|
+
import { createScopedLogger } from 'logger';
|
|
4
|
+
const logger = createScopedLogger('Personalization');
|
|
5
|
+
/** Base string for log messages when merge-tag resolution fails. */
|
|
6
|
+
const RESOLUTION_WARNING_BASE = 'Could not resolve Merge Tag value:';
|
|
7
|
+
/**
|
|
8
|
+
* Resolves merge tag values from a {@link Profile}.
|
|
9
|
+
*
|
|
10
|
+
* @public
|
|
11
|
+
* @remarks
|
|
12
|
+
* *Merge tags* are references to user profile data that may be embedded in content
|
|
13
|
+
* and expanded at runtime. This resolver normalizes the merge-tag identifier into
|
|
14
|
+
* a set of candidate selectors and searches the profile for a matching value.
|
|
15
|
+
* Result values are returned as strings; numeric/boolean primitives are stringified.
|
|
16
|
+
*/
|
|
17
|
+
const MergeTagValueResolver = {
|
|
18
|
+
/**
|
|
19
|
+
* Type guard to ensure the input is a {@link MergeTagEntry}.
|
|
20
|
+
*
|
|
21
|
+
* @param embeddedEntryNodeTarget - Unknown value to validate.
|
|
22
|
+
* @returns `true` if the input is a valid merge-tag entry.
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* if (MergeTagValueResolver.isMergeTagEntry(node)) {
|
|
26
|
+
* // safe to read fields
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
isMergeTagEntry(embeddedEntryNodeTarget) {
|
|
31
|
+
return MergeTagEntry.safeParse(embeddedEntryNodeTarget).success;
|
|
32
|
+
},
|
|
33
|
+
/**
|
|
34
|
+
* Generate a list of candidate selectors for a merge-tag ID.
|
|
35
|
+
*
|
|
36
|
+
* @param id - Merge-tag identifier (segments separated by `_`).
|
|
37
|
+
* @returns Array of dot-path selectors to try against a profile.
|
|
38
|
+
* @example
|
|
39
|
+
* ```ts
|
|
40
|
+
* // "profile_name_first" -> [
|
|
41
|
+
* // 'profile',
|
|
42
|
+
* // 'profile.name',
|
|
43
|
+
* // 'profile.name.first'
|
|
44
|
+
* // ]
|
|
45
|
+
* const selectors = MergeTagValueResolver.normalizeSelectors('profile_name_first')
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
normalizeSelectors(id) {
|
|
49
|
+
return id.split('_').map((_path, index, paths) => {
|
|
50
|
+
const dotPath = paths.slice(0, index).join('.');
|
|
51
|
+
const underScorePath = paths.slice(index).join('_');
|
|
52
|
+
return [dotPath, underScorePath].filter((path) => path !== '').join('.');
|
|
53
|
+
});
|
|
54
|
+
},
|
|
55
|
+
/**
|
|
56
|
+
* Look up a merge-tag value from a profile using normalized selectors.
|
|
57
|
+
*
|
|
58
|
+
* @param id - Merge-tag identifier.
|
|
59
|
+
* @param profile - Profile from which to resolve the value.
|
|
60
|
+
* @returns A stringified primitive if found; otherwise `undefined`.
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* const value = MergeTagValueResolver.getValueFromProfile('user_email', profile)
|
|
64
|
+
* if (value) sendEmailTo(value)
|
|
65
|
+
* ```
|
|
66
|
+
* @remarks
|
|
67
|
+
* Only string/number/boolean primitives are returned; objects/arrays are ignored.
|
|
68
|
+
*/
|
|
69
|
+
getValueFromProfile(id, profile) {
|
|
70
|
+
const selectors = MergeTagValueResolver.normalizeSelectors(id);
|
|
71
|
+
const matchingSelector = selectors.find((selector) => get(profile, selector));
|
|
72
|
+
if (!matchingSelector)
|
|
73
|
+
return undefined;
|
|
74
|
+
const value = get(profile, matchingSelector);
|
|
75
|
+
if (!value ||
|
|
76
|
+
(typeof value !== 'string' && typeof value !== 'number' && typeof value !== 'boolean'))
|
|
77
|
+
return undefined;
|
|
78
|
+
return `${value}`;
|
|
79
|
+
},
|
|
80
|
+
/**
|
|
81
|
+
* Resolve the display value for a merge-tag entry using the provided profile,
|
|
82
|
+
* falling back to the entry's configured `nt_fallback` when necessary.
|
|
83
|
+
*
|
|
84
|
+
* @param mergeTagEntry - The merge-tag entry to resolve.
|
|
85
|
+
* @param profile - Optional profile used for lookup.
|
|
86
|
+
* @returns The resolved string, or `undefined` if the entry is invalid and no
|
|
87
|
+
* fallback is available.
|
|
88
|
+
* @example
|
|
89
|
+
* ```ts
|
|
90
|
+
* const text = MergeTagValueResolver.resolve(entry, profile)
|
|
91
|
+
* render(text ?? 'Guest')
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
resolve(mergeTagEntry, profile) {
|
|
95
|
+
if (!MergeTagValueResolver.isMergeTagEntry(mergeTagEntry)) {
|
|
96
|
+
logger.warn(`${RESOLUTION_WARNING_BASE} supplied entry is not a Merge Tag entry`);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const { fields: { nt_fallback: fallback }, } = mergeTagEntry;
|
|
100
|
+
if (!Profile.safeParse(profile).success) {
|
|
101
|
+
logger.warn(`${RESOLUTION_WARNING_BASE} no valid profile`);
|
|
102
|
+
return fallback;
|
|
103
|
+
}
|
|
104
|
+
return (MergeTagValueResolver.getValueFromProfile(mergeTagEntry.fields.nt_mergetag_id, profile) ??
|
|
105
|
+
fallback);
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
export default MergeTagValueResolver;
|
|
109
|
+
//# sourceMappingURL=MergeTagValueResolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MergeTagValueResolver.js","sourceRoot":"","sources":["../../../src/personalization/resolvers/MergeTagValueResolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,qCAAqC,CAAA;AAC5E,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAA;AACvC,OAAO,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAA;AAE3C,MAAM,MAAM,GAAG,kBAAkB,CAAC,iBAAiB,CAAC,CAAA;AAEpD,oEAAoE;AACpE,MAAM,uBAAuB,GAAG,oCAAoC,CAAA;AAEpE;;;;;;;;;GASG;AACH,MAAM,qBAAqB,GAAG;IAC5B;;;;;;;;;;;OAWG;IACH,eAAe,CAAC,uBAAgC;QAC9C,OAAO,aAAa,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC,OAAO,CAAA;IACjE,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACH,kBAAkB,CAAC,EAAU;QAC3B,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;YAC/C,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YAC/C,MAAM,cAAc,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YAEnD,OAAO,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAC1E,CAAC,CAAC,CAAA;IACJ,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,mBAAmB,CAAC,EAAU,EAAE,OAAiB;QAC/C,MAAM,SAAS,GAAG,qBAAqB,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAA;QAC9D,MAAM,gBAAgB,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAA;QAE7E,IAAI,CAAC,gBAAgB;YAAE,OAAO,SAAS,CAAA;QAEvC,MAAM,KAAK,GAAY,GAAG,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAA;QAErD,IACE,CAAC,KAAK;YACN,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS,CAAC;YAEtF,OAAO,SAAS,CAAA;QAElB,OAAO,GAAG,KAAK,EAAE,CAAA;IACnB,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,aAAwC,EAAE,OAAiB;QACjE,IAAI,CAAC,qBAAqB,CAAC,eAAe,CAAC,aAAa,CAAC,EAAE,CAAC;YAC1D,MAAM,CAAC,IAAI,CAAC,GAAG,uBAAuB,0CAA0C,CAAC,CAAA;YACjF,OAAM;QACR,CAAC;QAED,MAAM,EACJ,MAAM,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,GAClC,GAAG,aAAa,CAAA;QAEjB,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC;YACxC,MAAM,CAAC,IAAI,CAAC,GAAG,uBAAuB,mBAAmB,CAAC,CAAA;YAC1D,OAAO,QAAQ,CAAA;QACjB,CAAC;QAED,OAAO,CACL,qBAAqB,CAAC,mBAAmB,CAAC,aAAa,CAAC,MAAM,CAAC,cAAc,EAAE,OAAO,CAAC;YACvF,QAAQ,CACT,CAAA;IACH,CAAC;CACF,CAAA;AAED,eAAe,qBAAqB,CAAA"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { type EntryReplacementVariant, type PersonalizationEntry, type PersonalizedEntry, type SelectedPersonalization, type SelectedPersonalizationArray } from '@contentful/optimization-api-client';
|
|
2
|
+
import type { ChainModifiers, Entry, EntrySkeletonType, LocaleCode } from 'contentful';
|
|
3
|
+
/**
|
|
4
|
+
* Result returned by {@link PersonalizedEntryResolver.resolve}.
|
|
5
|
+
*
|
|
6
|
+
* @typeParam S - Entry skeleton type.
|
|
7
|
+
* @typeParam M - Chain modifiers.
|
|
8
|
+
* @typeParam L - Locale code.
|
|
9
|
+
* @public
|
|
10
|
+
*/
|
|
11
|
+
export interface ResolvedData<S extends EntrySkeletonType, M extends ChainModifiers = ChainModifiers, L extends LocaleCode = LocaleCode> {
|
|
12
|
+
/** The baseline or resolved variant entry. */
|
|
13
|
+
entry: Entry<S, M, L>;
|
|
14
|
+
/** The selected personalization metadata, if a non‑baseline variant was chosen. */
|
|
15
|
+
personalization?: SelectedPersonalization;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Resolve a personalized Contentful entry to the correct variant for the current
|
|
19
|
+
* selections.
|
|
20
|
+
*
|
|
21
|
+
* @public
|
|
22
|
+
* @remarks
|
|
23
|
+
* Given a baseline {@link PersonalizedEntry} and a set of selected personalizations
|
|
24
|
+
* (variants per experience), this resolver finds the matching replacement variant
|
|
25
|
+
* for the component configured against the baseline entry.
|
|
26
|
+
*
|
|
27
|
+
* **Variant indexing**: `variantIndex` in {@link SelectedPersonalization} is treated as
|
|
28
|
+
* 1‑based (index 1 = first variant). A value of `0` indicates baseline.
|
|
29
|
+
*/
|
|
30
|
+
declare const PersonalizedEntryResolver: {
|
|
31
|
+
/**
|
|
32
|
+
* Find the personalization entry corresponding to one of the selected experiences.
|
|
33
|
+
*
|
|
34
|
+
* @param params - Object containing the baseline personalized entry and the selections.
|
|
35
|
+
* @param skipValidation - When `true`, skip type/shape validation for perf.
|
|
36
|
+
* @returns The matching {@link PersonalizationEntry}, or `undefined` if not found/invalid.
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* const personalizationEntry = PersonalizedEntryResolver.getPersonalizationEntry({
|
|
40
|
+
* personalizedEntry: entry,
|
|
41
|
+
* selectedPersonalizations
|
|
42
|
+
* })
|
|
43
|
+
* ```
|
|
44
|
+
* @remarks
|
|
45
|
+
* A personalization entry is a personalization configuration object supplied in a
|
|
46
|
+
* `PersonalizedEntry.nt_experiences` array. A personalized entry may relate to
|
|
47
|
+
* multiple personalizations.
|
|
48
|
+
*/
|
|
49
|
+
getPersonalizationEntry({ personalizedEntry, selectedPersonalizations, }: {
|
|
50
|
+
personalizedEntry: PersonalizedEntry;
|
|
51
|
+
selectedPersonalizations: SelectedPersonalizationArray;
|
|
52
|
+
}, skipValidation?: boolean): PersonalizationEntry | undefined;
|
|
53
|
+
/**
|
|
54
|
+
* Look up the selection metadata for a specific personalization entry.
|
|
55
|
+
*
|
|
56
|
+
* @param params - Object with the target personalization entry and selections.
|
|
57
|
+
* @param skipValidation - When `true`, skip type checks.
|
|
58
|
+
* @returns The matching {@link SelectedPersonalization}, if present.
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* const selectedPersonalization = PersonalizedEntryResolver.getSelectedPersonalization({
|
|
62
|
+
* personalizationEntry,
|
|
63
|
+
* selectedPersonalizations
|
|
64
|
+
* })
|
|
65
|
+
* ```
|
|
66
|
+
* @remarks
|
|
67
|
+
* Selected personalizations are supplied by the Experience API in the
|
|
68
|
+
* `experiences` response data property.
|
|
69
|
+
*/
|
|
70
|
+
getSelectedPersonalization({ personalizationEntry, selectedPersonalizations, }: {
|
|
71
|
+
personalizationEntry: PersonalizationEntry;
|
|
72
|
+
selectedPersonalizations: SelectedPersonalizationArray;
|
|
73
|
+
}, skipValidation?: boolean): SelectedPersonalization | undefined;
|
|
74
|
+
/**
|
|
75
|
+
* Get the replacement variant config for the given selection index.
|
|
76
|
+
*
|
|
77
|
+
* @param params - Baseline entry, personalization entry, and 1‑based variant index.
|
|
78
|
+
* @param skipValidation - When `true`, skip type checks.
|
|
79
|
+
* @returns The {@link EntryReplacementVariant} for the component, if any.
|
|
80
|
+
* @example
|
|
81
|
+
* ```ts
|
|
82
|
+
* const selectedVariant = PersonalizedEntryResolver.getSelectedVariant({
|
|
83
|
+
* personalizedEntry: entry,
|
|
84
|
+
* personalizationEntry,
|
|
85
|
+
* selectedVariantIndex: 2 // second variant (1‑based)
|
|
86
|
+
* })
|
|
87
|
+
* ```
|
|
88
|
+
* @remarks
|
|
89
|
+
* Entry replacement variants are variant configurations specified in a
|
|
90
|
+
* personalization configuration component's `variants` array supplied by the
|
|
91
|
+
* personalized entry via its `nt_config` field.
|
|
92
|
+
*/
|
|
93
|
+
getSelectedVariant({ personalizedEntry, personalizationEntry, selectedVariantIndex, }: {
|
|
94
|
+
personalizedEntry: PersonalizedEntry;
|
|
95
|
+
personalizationEntry: PersonalizationEntry;
|
|
96
|
+
selectedVariantIndex: number;
|
|
97
|
+
}, skipValidation?: boolean): EntryReplacementVariant | undefined;
|
|
98
|
+
/**
|
|
99
|
+
* Resolve the concrete Contentful entry that corresponds to a selected variant.
|
|
100
|
+
*
|
|
101
|
+
* @typeParam S - Entry skeleton type.
|
|
102
|
+
* @typeParam M - Chain modifiers.
|
|
103
|
+
* @typeParam L - Locale code.
|
|
104
|
+
* @param params - Personalization entry and selected variant.
|
|
105
|
+
* @param skipValidation - When `true`, skip type checks.
|
|
106
|
+
* @returns The resolved entry typed as {@link Entry} or `undefined`.
|
|
107
|
+
* @example
|
|
108
|
+
* ```ts
|
|
109
|
+
* const selectedVariantEntry = PersonalizedEntryResolver.getSelectedVariantEntry<{ fields: unknown }>({
|
|
110
|
+
* personalizationEntry,
|
|
111
|
+
* selectedVariant
|
|
112
|
+
* })
|
|
113
|
+
* ```
|
|
114
|
+
* @remarks
|
|
115
|
+
* A personalized entry will resolve either to the baseline (the entry
|
|
116
|
+
* supplied as `personalizedEntry`) or the selected variant.
|
|
117
|
+
*/
|
|
118
|
+
getSelectedVariantEntry<S extends EntrySkeletonType, M extends ChainModifiers = ChainModifiers, L extends LocaleCode = string>({ personalizationEntry, selectedVariant, }: {
|
|
119
|
+
personalizationEntry: PersonalizationEntry;
|
|
120
|
+
selectedVariant: EntryReplacementVariant;
|
|
121
|
+
}, skipValidation?: boolean): Entry<S, M, L> | undefined;
|
|
122
|
+
/**
|
|
123
|
+
* Resolve the selected entry (baseline or variant) for a personalized entry
|
|
124
|
+
* and optional selected personalizations, returning both the entry and the
|
|
125
|
+
* personalization metadata.
|
|
126
|
+
*
|
|
127
|
+
* @typeParam S - Entry skeleton type.
|
|
128
|
+
* @typeParam M - Chain modifiers.
|
|
129
|
+
* @typeParam L - Locale code.
|
|
130
|
+
* @param entry - The baseline personalized entry.
|
|
131
|
+
* @param selectedPersonalizations - Optional selections for the current profile.
|
|
132
|
+
* @returns An object containing the resolved entry and (if chosen) the selection.
|
|
133
|
+
* @example
|
|
134
|
+
* ```ts
|
|
135
|
+
* const { entry: personalizedEntry, personalization } = PersonalizedEntryResolver.resolve(entry, selections)
|
|
136
|
+
* if (personalization) console.log('Variant index', personalization.variantIndex)
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
139
|
+
resolve<S extends EntrySkeletonType, M extends ChainModifiers = ChainModifiers, L extends LocaleCode = string>(entry: Entry<S, M, L>, selectedPersonalizations?: SelectedPersonalizationArray): ResolvedData<S, M, L>;
|
|
140
|
+
};
|
|
141
|
+
export default PersonalizedEntryResolver;
|
|
142
|
+
//# sourceMappingURL=PersonalizedEntryResolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PersonalizedEntryResolver.d.ts","sourceRoot":"","sources":["../../../src/personalization/resolvers/PersonalizedEntryResolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,uBAAuB,EAM5B,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,4BAA4B,EAClC,MAAM,qCAAqC,CAAA;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAKtF;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY,CAC3B,CAAC,SAAS,iBAAiB,EAC3B,CAAC,SAAS,cAAc,GAAG,cAAc,EACzC,CAAC,SAAS,UAAU,GAAG,UAAU;IAEjC,8CAA8C;IAC9C,KAAK,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IACrB,mFAAmF;IACnF,eAAe,CAAC,EAAE,uBAAuB,CAAA;CAC1C;AAKD;;;;;;;;;;;;GAYG;AACH,QAAA,MAAM,yBAAyB;IAC7B;;;;;;;;;;;;;;;;;OAiBG;8EAKE;QACD,iBAAiB,EAAE,iBAAiB,CAAA;QACpC,wBAAwB,EAAE,4BAA4B,CAAA;KACvD,6BAEA,oBAAoB,GAAG,SAAS;IAkBnC;;;;;;;;;;;;;;;;OAgBG;oFAKE;QACD,oBAAoB,EAAE,oBAAoB,CAAA;QAC1C,wBAAwB,EAAE,4BAA4B,CAAA;KACvD,6BAEA,uBAAuB,GAAG,SAAS;IActC;;;;;;;;;;;;;;;;;;OAkBG;2FAME;QACD,iBAAiB,EAAE,iBAAiB,CAAA;QACpC,oBAAoB,EAAE,oBAAoB,CAAA;QAC1C,oBAAoB,EAAE,MAAM,CAAA;KAC7B,6BAEA,uBAAuB,GAAG,SAAS;IAmBtC;;;;;;;;;;;;;;;;;;;OAmBG;4BAED,CAAC,SAAS,iBAAiB,EAC3B,CAAC,SAAS,cAAc,mBACxB,CAAC,SAAS,UAAU,uDAKjB;QACD,oBAAoB,EAAE,oBAAoB,CAAA;QAC1C,eAAe,EAAE,uBAAuB,CAAA;KACzC,6BAEA,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS;IAc7B;;;;;;;;;;;;;;;;OAgBG;YAED,CAAC,SAAS,iBAAiB,EAC3B,CAAC,SAAS,cAAc,mBACxB,CAAC,SAAS,UAAU,kBAEb,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,6BACM,4BAA4B,GACtD,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;CAmFzB,CAAA;AAED,eAAe,yBAAyB,CAAA"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { isEntry, isEntryReplacementComponent, isEntryReplacementVariant, isPersonalizationEntry, isPersonalizedEntry, } from '@contentful/optimization-api-client';
|
|
2
|
+
import { createScopedLogger } from 'logger';
|
|
3
|
+
const logger = createScopedLogger('Personalization');
|
|
4
|
+
/** Base string for resolver warning messages. */
|
|
5
|
+
const RESOLUTION_WARNING_BASE = 'Could not resolve personalized entry variant:';
|
|
6
|
+
/**
|
|
7
|
+
* Resolve a personalized Contentful entry to the correct variant for the current
|
|
8
|
+
* selections.
|
|
9
|
+
*
|
|
10
|
+
* @public
|
|
11
|
+
* @remarks
|
|
12
|
+
* Given a baseline {@link PersonalizedEntry} and a set of selected personalizations
|
|
13
|
+
* (variants per experience), this resolver finds the matching replacement variant
|
|
14
|
+
* for the component configured against the baseline entry.
|
|
15
|
+
*
|
|
16
|
+
* **Variant indexing**: `variantIndex` in {@link SelectedPersonalization} is treated as
|
|
17
|
+
* 1‑based (index 1 = first variant). A value of `0` indicates baseline.
|
|
18
|
+
*/
|
|
19
|
+
const PersonalizedEntryResolver = {
|
|
20
|
+
/**
|
|
21
|
+
* Find the personalization entry corresponding to one of the selected experiences.
|
|
22
|
+
*
|
|
23
|
+
* @param params - Object containing the baseline personalized entry and the selections.
|
|
24
|
+
* @param skipValidation - When `true`, skip type/shape validation for perf.
|
|
25
|
+
* @returns The matching {@link PersonalizationEntry}, or `undefined` if not found/invalid.
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* const personalizationEntry = PersonalizedEntryResolver.getPersonalizationEntry({
|
|
29
|
+
* personalizedEntry: entry,
|
|
30
|
+
* selectedPersonalizations
|
|
31
|
+
* })
|
|
32
|
+
* ```
|
|
33
|
+
* @remarks
|
|
34
|
+
* A personalization entry is a personalization configuration object supplied in a
|
|
35
|
+
* `PersonalizedEntry.nt_experiences` array. A personalized entry may relate to
|
|
36
|
+
* multiple personalizations.
|
|
37
|
+
*/
|
|
38
|
+
getPersonalizationEntry({ personalizedEntry, selectedPersonalizations, }, skipValidation = false) {
|
|
39
|
+
if (!skipValidation &&
|
|
40
|
+
(!selectedPersonalizations.length || !isPersonalizedEntry(personalizedEntry)))
|
|
41
|
+
return;
|
|
42
|
+
const personalizationEntry = personalizedEntry.fields.nt_experiences
|
|
43
|
+
.filter((maybePersonalization) => isPersonalizationEntry(maybePersonalization))
|
|
44
|
+
.find((personalizationEntry) => selectedPersonalizations.some(({ experienceId }) => experienceId === personalizationEntry.fields.nt_experience_id));
|
|
45
|
+
return personalizationEntry;
|
|
46
|
+
},
|
|
47
|
+
/**
|
|
48
|
+
* Look up the selection metadata for a specific personalization entry.
|
|
49
|
+
*
|
|
50
|
+
* @param params - Object with the target personalization entry and selections.
|
|
51
|
+
* @param skipValidation - When `true`, skip type checks.
|
|
52
|
+
* @returns The matching {@link SelectedPersonalization}, if present.
|
|
53
|
+
* @example
|
|
54
|
+
* ```ts
|
|
55
|
+
* const selectedPersonalization = PersonalizedEntryResolver.getSelectedPersonalization({
|
|
56
|
+
* personalizationEntry,
|
|
57
|
+
* selectedPersonalizations
|
|
58
|
+
* })
|
|
59
|
+
* ```
|
|
60
|
+
* @remarks
|
|
61
|
+
* Selected personalizations are supplied by the Experience API in the
|
|
62
|
+
* `experiences` response data property.
|
|
63
|
+
*/
|
|
64
|
+
getSelectedPersonalization({ personalizationEntry, selectedPersonalizations, }, skipValidation = false) {
|
|
65
|
+
if (!skipValidation &&
|
|
66
|
+
(!selectedPersonalizations.length || !isPersonalizationEntry(personalizationEntry)))
|
|
67
|
+
return;
|
|
68
|
+
const selectedPersonalization = selectedPersonalizations.find(({ experienceId }) => experienceId === personalizationEntry.fields.nt_experience_id);
|
|
69
|
+
return selectedPersonalization;
|
|
70
|
+
},
|
|
71
|
+
/**
|
|
72
|
+
* Get the replacement variant config for the given selection index.
|
|
73
|
+
*
|
|
74
|
+
* @param params - Baseline entry, personalization entry, and 1‑based variant index.
|
|
75
|
+
* @param skipValidation - When `true`, skip type checks.
|
|
76
|
+
* @returns The {@link EntryReplacementVariant} for the component, if any.
|
|
77
|
+
* @example
|
|
78
|
+
* ```ts
|
|
79
|
+
* const selectedVariant = PersonalizedEntryResolver.getSelectedVariant({
|
|
80
|
+
* personalizedEntry: entry,
|
|
81
|
+
* personalizationEntry,
|
|
82
|
+
* selectedVariantIndex: 2 // second variant (1‑based)
|
|
83
|
+
* })
|
|
84
|
+
* ```
|
|
85
|
+
* @remarks
|
|
86
|
+
* Entry replacement variants are variant configurations specified in a
|
|
87
|
+
* personalization configuration component's `variants` array supplied by the
|
|
88
|
+
* personalized entry via its `nt_config` field.
|
|
89
|
+
*/
|
|
90
|
+
getSelectedVariant({ personalizedEntry, personalizationEntry, selectedVariantIndex, }, skipValidation = false) {
|
|
91
|
+
if (!skipValidation &&
|
|
92
|
+
(!isPersonalizedEntry(personalizedEntry) || !isPersonalizationEntry(personalizationEntry)))
|
|
93
|
+
return;
|
|
94
|
+
const relevantVariants = personalizationEntry.fields.nt_config?.components
|
|
95
|
+
?.filter((component) => isEntryReplacementComponent(component) && !component.baseline.hidden)
|
|
96
|
+
.find((component) => component.baseline.id === personalizedEntry.sys.id)?.variants;
|
|
97
|
+
if (!relevantVariants?.length)
|
|
98
|
+
return;
|
|
99
|
+
return relevantVariants.at(selectedVariantIndex - 1);
|
|
100
|
+
},
|
|
101
|
+
/**
|
|
102
|
+
* Resolve the concrete Contentful entry that corresponds to a selected variant.
|
|
103
|
+
*
|
|
104
|
+
* @typeParam S - Entry skeleton type.
|
|
105
|
+
* @typeParam M - Chain modifiers.
|
|
106
|
+
* @typeParam L - Locale code.
|
|
107
|
+
* @param params - Personalization entry and selected variant.
|
|
108
|
+
* @param skipValidation - When `true`, skip type checks.
|
|
109
|
+
* @returns The resolved entry typed as {@link Entry} or `undefined`.
|
|
110
|
+
* @example
|
|
111
|
+
* ```ts
|
|
112
|
+
* const selectedVariantEntry = PersonalizedEntryResolver.getSelectedVariantEntry<{ fields: unknown }>({
|
|
113
|
+
* personalizationEntry,
|
|
114
|
+
* selectedVariant
|
|
115
|
+
* })
|
|
116
|
+
* ```
|
|
117
|
+
* @remarks
|
|
118
|
+
* A personalized entry will resolve either to the baseline (the entry
|
|
119
|
+
* supplied as `personalizedEntry`) or the selected variant.
|
|
120
|
+
*/
|
|
121
|
+
getSelectedVariantEntry({ personalizationEntry, selectedVariant, }, skipValidation = false) {
|
|
122
|
+
if (!skipValidation &&
|
|
123
|
+
(!isPersonalizationEntry(personalizationEntry) || !isEntryReplacementVariant(selectedVariant)))
|
|
124
|
+
return;
|
|
125
|
+
const selectedVariantEntry = personalizationEntry.fields.nt_variants?.find((variant) => variant.sys.id === selectedVariant.id);
|
|
126
|
+
return isEntry(selectedVariantEntry) ? selectedVariantEntry : undefined;
|
|
127
|
+
},
|
|
128
|
+
/**
|
|
129
|
+
* Resolve the selected entry (baseline or variant) for a personalized entry
|
|
130
|
+
* and optional selected personalizations, returning both the entry and the
|
|
131
|
+
* personalization metadata.
|
|
132
|
+
*
|
|
133
|
+
* @typeParam S - Entry skeleton type.
|
|
134
|
+
* @typeParam M - Chain modifiers.
|
|
135
|
+
* @typeParam L - Locale code.
|
|
136
|
+
* @param entry - The baseline personalized entry.
|
|
137
|
+
* @param selectedPersonalizations - Optional selections for the current profile.
|
|
138
|
+
* @returns An object containing the resolved entry and (if chosen) the selection.
|
|
139
|
+
* @example
|
|
140
|
+
* ```ts
|
|
141
|
+
* const { entry: personalizedEntry, personalization } = PersonalizedEntryResolver.resolve(entry, selections)
|
|
142
|
+
* if (personalization) console.log('Variant index', personalization.variantIndex)
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
resolve(entry, selectedPersonalizations) {
|
|
146
|
+
logger.debug(`Resolving personalized entry for baseline entry ${entry.sys.id}`);
|
|
147
|
+
if (!selectedPersonalizations?.length) {
|
|
148
|
+
logger.warn(`${RESOLUTION_WARNING_BASE} no selectedPersonalizations exist for the current profile`);
|
|
149
|
+
return { entry };
|
|
150
|
+
}
|
|
151
|
+
if (!isPersonalizedEntry(entry)) {
|
|
152
|
+
logger.warn(`${RESOLUTION_WARNING_BASE} entry ${entry.sys.id} is not personalized`);
|
|
153
|
+
return { entry };
|
|
154
|
+
}
|
|
155
|
+
const personalizationEntry = PersonalizedEntryResolver.getPersonalizationEntry({
|
|
156
|
+
personalizedEntry: entry,
|
|
157
|
+
selectedPersonalizations,
|
|
158
|
+
}, true);
|
|
159
|
+
if (!personalizationEntry) {
|
|
160
|
+
logger.warn(`${RESOLUTION_WARNING_BASE} could not find a personalization entry for ${entry.sys.id}`);
|
|
161
|
+
return { entry };
|
|
162
|
+
}
|
|
163
|
+
const selectedPersonalization = PersonalizedEntryResolver.getSelectedPersonalization({
|
|
164
|
+
personalizationEntry,
|
|
165
|
+
selectedPersonalizations,
|
|
166
|
+
}, true);
|
|
167
|
+
const selectedVariantIndex = selectedPersonalization?.variantIndex ?? 0;
|
|
168
|
+
if (selectedVariantIndex === 0) {
|
|
169
|
+
logger.debug(`Resolved personalization entry for entry ${entry.sys.id} is baseline`);
|
|
170
|
+
return { entry };
|
|
171
|
+
}
|
|
172
|
+
const selectedVariant = PersonalizedEntryResolver.getSelectedVariant({
|
|
173
|
+
personalizedEntry: entry,
|
|
174
|
+
personalizationEntry,
|
|
175
|
+
selectedVariantIndex,
|
|
176
|
+
}, true);
|
|
177
|
+
if (!selectedVariant) {
|
|
178
|
+
logger.warn(`${RESOLUTION_WARNING_BASE} could not find a valid replacement variant entry for ${entry.sys.id}`);
|
|
179
|
+
return { entry };
|
|
180
|
+
}
|
|
181
|
+
const selectedVariantEntry = PersonalizedEntryResolver.getSelectedVariantEntry({
|
|
182
|
+
personalizationEntry,
|
|
183
|
+
selectedVariant,
|
|
184
|
+
}, true);
|
|
185
|
+
if (!selectedVariantEntry) {
|
|
186
|
+
logger.warn(`${RESOLUTION_WARNING_BASE} could not find a valid replacement variant entry for ${entry.sys.id}`);
|
|
187
|
+
return { entry };
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
logger.debug(`Entry ${entry.sys.id} has been resolved to variant entry ${selectedVariantEntry.sys.id}`);
|
|
191
|
+
}
|
|
192
|
+
return { entry: selectedVariantEntry, personalization: selectedPersonalization };
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
export default PersonalizedEntryResolver;
|
|
196
|
+
//# sourceMappingURL=PersonalizedEntryResolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PersonalizedEntryResolver.js","sourceRoot":"","sources":["../../../src/personalization/resolvers/PersonalizedEntryResolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from './FlagsResolver';
|
|
2
|
+
export { default as FlagsResolver } from './FlagsResolver';
|
|
3
|
+
export * from './MergeTagValueResolver';
|
|
4
|
+
export { default as MergeTagValueResolver } from './MergeTagValueResolver';
|
|
5
|
+
export * from './PersonalizedEntryResolver';
|
|
6
|
+
export { default as PersonalizedEntryResolver } from './PersonalizedEntryResolver';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/personalization/resolvers/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAA;AAC/B,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAE1D,cAAc,yBAAyB,CAAA;AACvC,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,yBAAyB,CAAA;AAE1E,cAAc,6BAA6B,CAAA;AAC3C,OAAO,EAAE,OAAO,IAAI,yBAAyB,EAAE,MAAM,6BAA6B,CAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from './FlagsResolver';
|
|
2
|
+
export { default as FlagsResolver } from './FlagsResolver';
|
|
3
|
+
export * from './MergeTagValueResolver';
|
|
4
|
+
export { default as MergeTagValueResolver } from './MergeTagValueResolver';
|
|
5
|
+
export * from './PersonalizedEntryResolver';
|
|
6
|
+
export { default as PersonalizedEntryResolver } from './PersonalizedEntryResolver';
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/personalization/resolvers/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAA;AAC/B,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAE1D,cAAc,yBAAyB,CAAA;AACvC,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,yBAAyB,CAAA;AAE1E,cAAc,6BAA6B,CAAA;AAC3C,OAAO,EAAE,OAAO,IAAI,yBAAyB,EAAE,MAAM,6BAA6B,CAAA"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { InsightsEvent as AnalyticsEvent, ChangeArray, Flags, ExperienceEvent as PersonalizationEvent, Profile } from '@contentful/optimization-api-client';
|
|
2
|
+
import { batch, effect, type Signal } from '@preact/signals-core';
|
|
3
|
+
export declare const changes: Signal<ChangeArray | undefined>;
|
|
4
|
+
export declare const consent: Signal<boolean | undefined>;
|
|
5
|
+
export declare const event: Signal<AnalyticsEvent | PersonalizationEvent | undefined>;
|
|
6
|
+
export declare const flags: import("@preact/signals-core").ReadonlySignal<Flags | undefined>;
|
|
7
|
+
export declare const online: Signal<boolean | undefined>;
|
|
8
|
+
export declare const personalizations: Signal<{
|
|
9
|
+
experienceId: string;
|
|
10
|
+
variantIndex: number;
|
|
11
|
+
variants: Record<string, string>;
|
|
12
|
+
sticky?: boolean | undefined;
|
|
13
|
+
}[] | undefined>;
|
|
14
|
+
export declare const profile: Signal<Profile | undefined>;
|
|
15
|
+
export interface Signals {
|
|
16
|
+
changes: typeof changes;
|
|
17
|
+
consent: typeof consent;
|
|
18
|
+
event: typeof event;
|
|
19
|
+
flags: typeof flags;
|
|
20
|
+
online: typeof online;
|
|
21
|
+
personalizations: typeof personalizations;
|
|
22
|
+
profile: typeof profile;
|
|
23
|
+
}
|
|
24
|
+
export interface Subscription {
|
|
25
|
+
unsubscribe: () => void;
|
|
26
|
+
}
|
|
27
|
+
export interface Observable<T> {
|
|
28
|
+
subscribe: (next: (v: T) => void) => Subscription;
|
|
29
|
+
}
|
|
30
|
+
export declare function toObservable<T>(s: {
|
|
31
|
+
value: T;
|
|
32
|
+
}): Observable<T>;
|
|
33
|
+
export declare const signals: Signals;
|
|
34
|
+
export { batch, effect, type Signal };
|
|
35
|
+
//# sourceMappingURL=signals.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signals.d.ts","sourceRoot":"","sources":["../src/signals.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,IAAI,cAAc,EAC/B,WAAW,EACX,KAAK,EACL,eAAe,IAAI,oBAAoB,EACvC,OAAO,EAER,MAAM,qCAAqC,CAAA;AAC5C,OAAO,EAAE,KAAK,EAAY,MAAM,EAAU,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAGnF,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,WAAW,GAAG,SAAS,CAAqC,CAAA;AAEzF,eAAO,MAAM,OAAO,6BAAgC,CAAA;AAEpD,eAAO,MAAM,KAAK,EAAE,MAAM,CAAC,cAAc,GAAG,oBAAoB,GAAG,SAAS,CAEzE,CAAA;AAEH,eAAO,MAAM,KAAK,kEAAgF,CAAA;AAElG,eAAO,MAAM,MAAM,6BAAoC,CAAA;AAEvD,eAAO,MAAM,gBAAgB;;;;;gBAAqD,CAAA;AAElF,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,OAAO,GAAG,SAAS,CAAiC,CAAA;AAEjF,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,OAAO,OAAO,CAAA;IACvB,OAAO,EAAE,OAAO,OAAO,CAAA;IACvB,KAAK,EAAE,OAAO,KAAK,CAAA;IACnB,KAAK,EAAE,OAAO,KAAK,CAAA;IACnB,MAAM,EAAE,OAAO,MAAM,CAAA;IACrB,gBAAgB,EAAE,OAAO,gBAAgB,CAAA;IACzC,OAAO,EAAE,OAAO,OAAO,CAAA;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,IAAI,CAAA;CACxB;AAED,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,KAAK,YAAY,CAAA;CAClD;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE;IAAE,KAAK,EAAE,CAAC,CAAA;CAAE,GAAG,UAAU,CAAC,CAAC,CAAC,CAU9D;AAED,eAAO,MAAM,OAAO,EAAE,OAQrB,CAAA;AAED,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,MAAM,EAAE,CAAA"}
|
package/dist/signals.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { batch, computed, effect, signal } from '@preact/signals-core';
|
|
2
|
+
import { FlagsResolver } from './personalization/resolvers';
|
|
3
|
+
export const changes = signal();
|
|
4
|
+
export const consent = signal();
|
|
5
|
+
export const event = signal();
|
|
6
|
+
export const flags = computed(() => FlagsResolver.resolve(changes.value ?? []));
|
|
7
|
+
export const online = signal(true);
|
|
8
|
+
export const personalizations = signal();
|
|
9
|
+
export const profile = signal();
|
|
10
|
+
export function toObservable(s) {
|
|
11
|
+
return {
|
|
12
|
+
subscribe(next) {
|
|
13
|
+
const dispose = effect(() => {
|
|
14
|
+
next(s.value);
|
|
15
|
+
});
|
|
16
|
+
return { unsubscribe: dispose };
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export const signals = {
|
|
21
|
+
changes,
|
|
22
|
+
consent,
|
|
23
|
+
event,
|
|
24
|
+
flags,
|
|
25
|
+
online,
|
|
26
|
+
personalizations,
|
|
27
|
+
profile,
|
|
28
|
+
};
|
|
29
|
+
export { batch, effect };
|
|
30
|
+
//# sourceMappingURL=signals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signals.js","sourceRoot":"","sources":["../src/signals.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAe,MAAM,sBAAsB,CAAA;AACnF,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAE3D,MAAM,CAAC,MAAM,OAAO,GAAoC,MAAM,EAA2B,CAAA;AAEzF,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,EAAuB,CAAA;AAEpD,MAAM,CAAC,MAAM,KAAK,GAA8D,MAAM,EAEnF,CAAA;AAEH,MAAM,CAAC,MAAM,KAAK,GAAG,QAAQ,CAAoB,GAAG,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAA;AAElG,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAsB,IAAI,CAAC,CAAA;AAEvD,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,EAA4C,CAAA;AAElF,MAAM,CAAC,MAAM,OAAO,GAAgC,MAAM,EAAuB,CAAA;AAoBjF,MAAM,UAAU,YAAY,CAAI,CAAe;IAC7C,OAAO;QACL,SAAS,CAAC,IAAI;YACZ,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,EAAE;gBAC1B,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;YACf,CAAC,CAAC,CAAA;YAEF,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,CAAA;QACjC,CAAC;KACF,CAAA;AACH,CAAC;AAED,MAAM,CAAC,MAAM,OAAO,GAAY;IAC9B,OAAO;IACP,OAAO;IACP,KAAK;IACL,KAAK;IACL,MAAM;IACN,gBAAgB;IAChB,OAAO;CACR,CAAA;AAED,OAAO,EAAE,KAAK,EAAE,MAAM,EAAe,CAAA"}
|