@salesforce/storefront-next-runtime 0.2.0-alpha.2 → 0.3.0-alpha.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/DesignFrame.js +6 -2
- package/dist/DesignFrame.js.map +1 -1
- package/dist/DesignRegion.js +2 -1
- package/dist/DesignRegion.js.map +1 -1
- package/dist/component.types.d.ts +6 -0
- package/dist/component.types.d.ts.map +1 -1
- package/dist/config-load.d.ts +27 -0
- package/dist/config-load.d.ts.map +1 -0
- package/dist/config-load.js +3 -0
- package/dist/config.d.ts +248 -1
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +429 -0
- package/dist/config.js.map +1 -0
- package/dist/design-data.d.ts +40 -27
- package/dist/design-data.d.ts.map +1 -1
- package/dist/design-data.js +50 -26
- package/dist/design-data.js.map +1 -1
- package/dist/design-react-core.d.ts +2 -2
- package/dist/design-react-core.js +3 -1
- package/dist/design-react-core.js.map +1 -1
- package/dist/events.d.ts +9 -4
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +6 -6
- package/dist/events.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/load-config.js +41 -0
- package/dist/load-config.js.map +1 -0
- package/dist/multi-site.d.ts +68 -43
- package/dist/multi-site.d.ts.map +1 -1
- package/dist/multi-site.js +36 -10
- package/dist/multi-site.js.map +1 -1
- package/dist/routing.d.ts.map +1 -1
- package/dist/routing.js +4 -37
- package/dist/routing.js.map +1 -1
- package/dist/scapi.d.ts +8 -0
- package/dist/scapi.d.ts.map +1 -1
- package/dist/scapi.js +1 -1
- package/dist/scapi.js.map +1 -1
- package/dist/schema.d.ts +78 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +7 -1
package/dist/design-data.d.ts
CHANGED
|
@@ -11,8 +11,6 @@ import { r as ShopperExperience } from "./types2.js";
|
|
|
11
11
|
interface PageManifest {
|
|
12
12
|
/** The unique identifier of the page this manifest represents. */
|
|
13
13
|
pageId: string;
|
|
14
|
-
/** The locale this manifest applies to (e.g. `"en-US"`). */
|
|
15
|
-
locale: string;
|
|
16
14
|
/** Campaigns and customer groups referenced across all variations in this manifest. */
|
|
17
15
|
context: PageManifestContext;
|
|
18
16
|
/** Ordered list of variation IDs defining the evaluation sequence. */
|
|
@@ -30,10 +28,14 @@ interface PageManifest {
|
|
|
30
28
|
[componentId: string]: {
|
|
31
29
|
/** The visibility rules for this component. */
|
|
32
30
|
visibilityRules: VisibilityRuleDef[];
|
|
33
|
-
/**
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Locale-specific content attributes for this component. Keyed by locale
|
|
33
|
+
* (e.g. `"en_US"`), each entry contains attribute values that are merged
|
|
34
|
+
* into the component's `data` during page processing.
|
|
35
|
+
*/
|
|
36
|
+
content?: {
|
|
37
|
+
[locale: string]: Record<string, unknown>;
|
|
38
|
+
};
|
|
37
39
|
};
|
|
38
40
|
};
|
|
39
41
|
}
|
|
@@ -153,8 +155,8 @@ interface VisibilityRuleDef {
|
|
|
153
155
|
/** End time as an ISO 8601 UTC string. Rule fails after this time. */
|
|
154
156
|
end?: string;
|
|
155
157
|
};
|
|
156
|
-
/**
|
|
157
|
-
|
|
158
|
+
/** The locales for which this rule is active (e.g. `["en_US", "fr_FR"]`). The rule fails for locales not in this list. When `null`, the rule is valid for every locale. */
|
|
159
|
+
activeLocales: string[] | null;
|
|
158
160
|
}
|
|
159
161
|
/**
|
|
160
162
|
* Runtime context representing the current shopper's active qualifiers.
|
|
@@ -216,19 +218,23 @@ interface ManifestStorage {
|
|
|
216
218
|
/** Fetch the site-wide manifest for a given locale. */
|
|
217
219
|
getSiteManifest(locale: string): Promise<SiteManifest>;
|
|
218
220
|
}
|
|
221
|
+
type ContextResolver = (context: PageManifest['context']) => Promise<QualifierContext>;
|
|
219
222
|
type VisitorContextType = 'page' | 'region' | 'component' | 'root';
|
|
220
223
|
type InferNodeFromType<TType extends VisitorContextType> = TType extends 'page' ? ShopperExperience.schemas['Page'] : TType extends 'region' ? ShopperExperience.schemas['Region'] : ShopperExperience.schemas['Component'];
|
|
221
224
|
//#endregion
|
|
222
225
|
//#region src/design/data/page/process-page.d.ts
|
|
223
226
|
/**
|
|
224
227
|
* Context required for page processing. Contains the shopper's runtime
|
|
225
|
-
* qualifiers
|
|
228
|
+
* qualifiers, the component-level visibility rules, and the locale used
|
|
229
|
+
* to resolve locale-specific component content from the page manifest.
|
|
226
230
|
*/
|
|
227
231
|
interface PageProcessorContext {
|
|
228
232
|
/** The shopper's active qualifiers (campaigns, customer groups), or `null` if not resolved. */
|
|
229
233
|
qualifiers: QualifierContext | null;
|
|
230
234
|
/** Component visibility rule definitions extracted from the page layout. */
|
|
231
235
|
componentInfo: PageManifest['componentInfo'];
|
|
236
|
+
/** The locale to use when resolving locale-specific component content (e.g. `"en_US"`). */
|
|
237
|
+
locale: string;
|
|
232
238
|
}
|
|
233
239
|
/**
|
|
234
240
|
* Filters a page's components based on their visibility rules and resolves
|
|
@@ -266,10 +272,9 @@ interface PageProcessorContext {
|
|
|
266
272
|
*
|
|
267
273
|
* // The "loyalty-offer" component requires the shopper to be in "loyalty-members"
|
|
268
274
|
* const componentInfo = {
|
|
269
|
-
* 'public-banner': { visibilityRules: []
|
|
275
|
+
* 'public-banner': { visibilityRules: [] },
|
|
270
276
|
* 'loyalty-offer': {
|
|
271
277
|
* visibilityRules: [{ customerGroups: ['loyalty-members'] }],
|
|
272
|
-
* hasVisibilityRules: true,
|
|
273
278
|
* },
|
|
274
279
|
* };
|
|
275
280
|
*
|
|
@@ -735,7 +740,7 @@ declare function resolvePage({
|
|
|
735
740
|
aspectType?: string;
|
|
736
741
|
locale: string;
|
|
737
742
|
manifestStorage: ManifestStorage;
|
|
738
|
-
contextResolver?:
|
|
743
|
+
contextResolver?: ContextResolver;
|
|
739
744
|
}): Promise<ShopperExperience.schemas['Page'] | null>;
|
|
740
745
|
//#endregion
|
|
741
746
|
//#region src/design/data/manifest/resolve-dynamic-page-id.d.ts
|
|
@@ -813,6 +818,7 @@ declare function resolveDynamicPageId<TIdentifier extends IdentifierType = Ident
|
|
|
813
818
|
* @param manifest - The page manifest containing all variations.
|
|
814
819
|
* @param options - Resolution options.
|
|
815
820
|
* @param options.contextResolver - Optional async function that returns the shopper's qualifier context. Only called if a variation's rule needs it.
|
|
821
|
+
* @param options.locale - The current locale (e.g. `"en_US"`). Used to evaluate locale-based visibility rules.
|
|
816
822
|
* @returns The selected variation entry and resolved context, or `null` if no variation (including default) exists.
|
|
817
823
|
*
|
|
818
824
|
* @example
|
|
@@ -821,23 +827,23 @@ declare function resolveDynamicPageId<TIdentifier extends IdentifierType = Ident
|
|
|
821
827
|
*
|
|
822
828
|
* const manifest = {
|
|
823
829
|
* pageId: 'homepage',
|
|
824
|
-
* locale: 'en-US',
|
|
825
830
|
* context: { campaignQualifiers: [], customerGroups: ['vip-customers'], dataBindings: [] },
|
|
826
831
|
* variationOrder: ['vip-homepage', 'holiday-homepage'],
|
|
827
832
|
* variations: {
|
|
828
833
|
* 'vip-homepage': {
|
|
829
834
|
* ruleRequiresContext: true,
|
|
830
835
|
* pageRequiresContext: false,
|
|
831
|
-
* visibilityRule: { customerGroups: ['vip-customers'] },
|
|
836
|
+
* visibilityRule: { activeLocales: ['en-US'], customerGroups: ['vip-customers'] },
|
|
832
837
|
* page: { id: 'homepage', typeId: 'storePage', regions: [] },
|
|
833
838
|
* },
|
|
834
839
|
* 'holiday-homepage': {
|
|
835
840
|
* ruleRequiresContext: false,
|
|
836
841
|
* pageRequiresContext: false,
|
|
837
842
|
* visibilityRule: {
|
|
843
|
+
* activeLocales: ['en-US'],
|
|
838
844
|
* schedule: {
|
|
839
|
-
* start: new Date('2026-12-01').
|
|
840
|
-
* end: new Date('2026-12-31').
|
|
845
|
+
* start: new Date('2026-12-01').toISOString(),
|
|
846
|
+
* end: new Date('2026-12-31').toISOString(),
|
|
841
847
|
* },
|
|
842
848
|
* },
|
|
843
849
|
* page: { id: 'homepage', typeId: 'storePage', regions: [] },
|
|
@@ -849,11 +855,12 @@ declare function resolveDynamicPageId<TIdentifier extends IdentifierType = Ident
|
|
|
849
855
|
* },
|
|
850
856
|
* },
|
|
851
857
|
* defaultVariation: 'default-homepage',
|
|
852
|
-
*
|
|
858
|
+
* componentInfo: {},
|
|
853
859
|
* };
|
|
854
860
|
*
|
|
855
861
|
* // VIP shopper — matches first variation
|
|
856
862
|
* const result = await getPageFromManifest(manifest, {
|
|
863
|
+
* locale: 'en-US',
|
|
857
864
|
* contextResolver: async () => ({
|
|
858
865
|
* customerGroups: { 'vip-customers': true },
|
|
859
866
|
* campaignQualifiers: {},
|
|
@@ -863,6 +870,7 @@ declare function resolveDynamicPageId<TIdentifier extends IdentifierType = Ident
|
|
|
863
870
|
*
|
|
864
871
|
* // Non-VIP shopper outside holiday window — falls back to default
|
|
865
872
|
* const fallback = await getPageFromManifest(manifest, {
|
|
873
|
+
* locale: 'en-US',
|
|
866
874
|
* contextResolver: async () => ({
|
|
867
875
|
* customerGroups: {},
|
|
868
876
|
* campaignQualifiers: {},
|
|
@@ -872,9 +880,11 @@ declare function resolveDynamicPageId<TIdentifier extends IdentifierType = Ident
|
|
|
872
880
|
* ```
|
|
873
881
|
*/
|
|
874
882
|
declare function getPageFromManifest(manifest: PageManifest, {
|
|
875
|
-
contextResolver
|
|
883
|
+
contextResolver,
|
|
884
|
+
locale
|
|
876
885
|
}: {
|
|
877
|
-
contextResolver?:
|
|
886
|
+
contextResolver?: ContextResolver;
|
|
887
|
+
locale: string;
|
|
878
888
|
}): Promise<{
|
|
879
889
|
entry: VariationEntry;
|
|
880
890
|
context: QualifierContext | null;
|
|
@@ -944,17 +954,18 @@ declare const ContentAssignmentResolvers: Map<string, ContentAssignmentResolver>
|
|
|
944
954
|
* matching the server's `VisibilityDefinition.isVisible()` logic:
|
|
945
955
|
*
|
|
946
956
|
* - **Campaign-based rule** (has `campaignQualifiers`): only the campaign
|
|
947
|
-
* qualifiers are checked. Schedule and customer-group fields are
|
|
948
|
-
* because the campaign qualification already incorporates those
|
|
949
|
-
* server-side.
|
|
950
|
-
* - **Non-campaign rule**: schedule AND customer groups are checked.
|
|
951
|
-
* specified conditions must pass.
|
|
957
|
+
* qualifiers are checked. Schedule, locale, and customer-group fields are
|
|
958
|
+
* ignored because the campaign qualification already incorporates those
|
|
959
|
+
* checks server-side.
|
|
960
|
+
* - **Non-campaign rule**: locale, schedule, AND customer groups are checked.
|
|
961
|
+
* All specified conditions must pass.
|
|
952
962
|
*
|
|
953
963
|
* When no context is provided and the rule requires campaign or customer group
|
|
954
964
|
* checks, those checks will fail (returning `false`). Schedule checks do not
|
|
955
965
|
* require context and are evaluated against `Date.now()`.
|
|
956
966
|
*
|
|
957
967
|
* @param rule - The visibility rule to evaluate.
|
|
968
|
+
* @param locale - The current locale (e.g. `"en_US"`). Used to check whether the rule applies to this locale.
|
|
958
969
|
* @param context - The shopper's active qualifiers, or `null`/`undefined` if not yet resolved.
|
|
959
970
|
* @returns `true` if the rule's conditions pass, `false` otherwise.
|
|
960
971
|
*
|
|
@@ -964,11 +975,13 @@ declare const ContentAssignmentResolvers: Map<string, ContentAssignmentResolver>
|
|
|
964
975
|
*
|
|
965
976
|
* // Campaign-based rule — only campaign qualifiers are evaluated
|
|
966
977
|
* const campaignRule = {
|
|
978
|
+
* activeLocales: ['en_US'],
|
|
967
979
|
* campaignQualifiers: [{ campaignId: 'holiday-sale-2026', promotionId: 'free-shipping' }],
|
|
968
980
|
* };
|
|
969
981
|
*
|
|
970
|
-
* // Non-campaign rule — schedule AND customer groups are evaluated
|
|
982
|
+
* // Non-campaign rule — locale, schedule AND customer groups are evaluated
|
|
971
983
|
* const segmentRule = {
|
|
984
|
+
* activeLocales: ['en_US', 'fr_FR'],
|
|
972
985
|
* customerGroups: ['vip-customers'],
|
|
973
986
|
* schedule: {
|
|
974
987
|
* start: new Date('2026-12-01').toISOString(),
|
|
@@ -977,7 +990,7 @@ declare const ContentAssignmentResolvers: Map<string, ContentAssignmentResolver>
|
|
|
977
990
|
* };
|
|
978
991
|
* ```
|
|
979
992
|
*/
|
|
980
|
-
declare function validateRule(rule: VisibilityRuleDef, context?: QualifierContext | null): boolean;
|
|
993
|
+
declare function validateRule(rule: VisibilityRuleDef, locale: string, context?: QualifierContext | null): boolean;
|
|
981
994
|
//#endregion
|
|
982
|
-
export { CampaignQualifier, type ComponentDataBinding, ContentAssignmentResolvers, type DataBindingContext, DataBindingRequirement, IdentifierType, InferNodeFromType, ManifestStorage, PageManifest, PageManifestContext, type PageProcessorContext, type PageVisitor, QualifierContext, RequiredError, ResolvedDataBinding, SiteManifest, VariationEntry, VisibilityRuleDef, type VisitorContext, VisitorContextType, getPageFromManifest, parseExpression, processPage, resolveComponentDataBindings, resolveDynamicPageId, resolveExpression, resolvePage, transformComponent, transformPage, transformRegion, validateRule };
|
|
995
|
+
export { CampaignQualifier, type ComponentDataBinding, ContentAssignmentResolvers, ContextResolver, type DataBindingContext, DataBindingRequirement, IdentifierType, InferNodeFromType, ManifestStorage, PageManifest, PageManifestContext, type PageProcessorContext, type PageVisitor, QualifierContext, RequiredError, ResolvedDataBinding, SiteManifest, VariationEntry, VisibilityRuleDef, type VisitorContext, VisitorContextType, getPageFromManifest, parseExpression, processPage, resolveComponentDataBindings, resolveDynamicPageId, resolveExpression, resolvePage, transformComponent, transformPage, transformRegion, validateRule };
|
|
983
996
|
//# sourceMappingURL=design-data.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"design-data.d.ts","names":[],"sources":["../src/design/data/types.ts","../src/design/data/page/process-page.ts","../src/design/data/page/transform.ts","../src/design/data/errors/required.ts","../src/design/data/page/resolve-data-bindings.ts","../src/design/data/page/resolve-page.ts","../src/design/data/manifest/resolve-dynamic-page-id.ts","../src/design/data/manifest/get-page.ts","../src/design/data/manifest/content-assignment-resolvers.ts","../src/design/data/validate-rule.ts"],"sourcesContent":[],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"design-data.d.ts","names":[],"sources":["../src/design/data/types.ts","../src/design/data/page/process-page.ts","../src/design/data/page/transform.ts","../src/design/data/errors/required.ts","../src/design/data/page/resolve-data-bindings.ts","../src/design/data/page/resolve-page.ts","../src/design/data/manifest/resolve-dynamic-page-id.ts","../src/design/data/manifest/get-page.ts","../src/design/data/manifest/content-assignment-resolvers.ts","../src/design/data/validate-rule.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/design-data.js
CHANGED
|
@@ -460,17 +460,18 @@ function resolveComponentDataBindings(component, dataBindings) {
|
|
|
460
460
|
* matching the server's `VisibilityDefinition.isVisible()` logic:
|
|
461
461
|
*
|
|
462
462
|
* - **Campaign-based rule** (has `campaignQualifiers`): only the campaign
|
|
463
|
-
* qualifiers are checked. Schedule and customer-group fields are
|
|
464
|
-
* because the campaign qualification already incorporates those
|
|
465
|
-
* server-side.
|
|
466
|
-
* - **Non-campaign rule**: schedule AND customer groups are checked.
|
|
467
|
-
* specified conditions must pass.
|
|
463
|
+
* qualifiers are checked. Schedule, locale, and customer-group fields are
|
|
464
|
+
* ignored because the campaign qualification already incorporates those
|
|
465
|
+
* checks server-side.
|
|
466
|
+
* - **Non-campaign rule**: locale, schedule, AND customer groups are checked.
|
|
467
|
+
* All specified conditions must pass.
|
|
468
468
|
*
|
|
469
469
|
* When no context is provided and the rule requires campaign or customer group
|
|
470
470
|
* checks, those checks will fail (returning `false`). Schedule checks do not
|
|
471
471
|
* require context and are evaluated against `Date.now()`.
|
|
472
472
|
*
|
|
473
473
|
* @param rule - The visibility rule to evaluate.
|
|
474
|
+
* @param locale - The current locale (e.g. `"en_US"`). Used to check whether the rule applies to this locale.
|
|
474
475
|
* @param context - The shopper's active qualifiers, or `null`/`undefined` if not yet resolved.
|
|
475
476
|
* @returns `true` if the rule's conditions pass, `false` otherwise.
|
|
476
477
|
*
|
|
@@ -480,11 +481,13 @@ function resolveComponentDataBindings(component, dataBindings) {
|
|
|
480
481
|
*
|
|
481
482
|
* // Campaign-based rule — only campaign qualifiers are evaluated
|
|
482
483
|
* const campaignRule = {
|
|
484
|
+
* activeLocales: ['en_US'],
|
|
483
485
|
* campaignQualifiers: [{ campaignId: 'holiday-sale-2026', promotionId: 'free-shipping' }],
|
|
484
486
|
* };
|
|
485
487
|
*
|
|
486
|
-
* // Non-campaign rule — schedule AND customer groups are evaluated
|
|
488
|
+
* // Non-campaign rule — locale, schedule AND customer groups are evaluated
|
|
487
489
|
* const segmentRule = {
|
|
490
|
+
* activeLocales: ['en_US', 'fr_FR'],
|
|
488
491
|
* customerGroups: ['vip-customers'],
|
|
489
492
|
* schedule: {
|
|
490
493
|
* start: new Date('2026-12-01').toISOString(),
|
|
@@ -493,11 +496,11 @@ function resolveComponentDataBindings(component, dataBindings) {
|
|
|
493
496
|
* };
|
|
494
497
|
* ```
|
|
495
498
|
*/
|
|
496
|
-
function validateRule(rule, context) {
|
|
499
|
+
function validateRule(rule, locale, context) {
|
|
497
500
|
if (rule.campaignQualifiers) {
|
|
498
501
|
for (const campaignQualifier of rule.campaignQualifiers) if (!context?.campaignQualifiers[campaignQualifier.campaignId]?.[campaignQualifier.promotionId]) return false;
|
|
499
502
|
} else {
|
|
500
|
-
if (!rule.
|
|
503
|
+
if (rule.activeLocales && !rule.activeLocales.includes(locale)) return false;
|
|
501
504
|
if (rule.schedule) {
|
|
502
505
|
const now = Date.now();
|
|
503
506
|
if (rule.schedule.start) {
|
|
@@ -554,10 +557,9 @@ function validateRule(rule, context) {
|
|
|
554
557
|
*
|
|
555
558
|
* // The "loyalty-offer" component requires the shopper to be in "loyalty-members"
|
|
556
559
|
* const componentInfo = {
|
|
557
|
-
* 'public-banner': { visibilityRules: []
|
|
560
|
+
* 'public-banner': { visibilityRules: [] },
|
|
558
561
|
* 'loyalty-offer': {
|
|
559
562
|
* visibilityRules: [{ customerGroups: ['loyalty-members'] }],
|
|
560
|
-
* hasVisibilityRules: true,
|
|
561
563
|
* },
|
|
562
564
|
* };
|
|
563
565
|
*
|
|
@@ -575,14 +577,29 @@ function processPage(page, processorContext) {
|
|
|
575
577
|
const componentInfo = processorContext.componentInfo[ctx.node.id];
|
|
576
578
|
const visibilityRules = componentInfo?.visibilityRules ?? [];
|
|
577
579
|
if (visibilityRules.length > 0) {
|
|
578
|
-
if (!visibilityRules.some((rule) => validateRule(rule, processorContext.qualifiers))) return null;
|
|
580
|
+
if (!visibilityRules.some((rule) => validateRule(rule, processorContext.locale, processorContext.qualifiers))) return null;
|
|
579
581
|
}
|
|
580
|
-
const
|
|
581
|
-
|
|
582
|
-
|
|
582
|
+
const defaultContent = componentInfo?.content?.default ?? {};
|
|
583
|
+
const localeContent = componentInfo?.content?.[processorContext.locale] ?? {};
|
|
584
|
+
const content = {
|
|
585
|
+
...defaultContent,
|
|
586
|
+
...localeContent
|
|
587
|
+
};
|
|
588
|
+
const isLocalized = Boolean(componentInfo?.content?.[processorContext.locale]);
|
|
589
|
+
let node = {
|
|
590
|
+
...ctx.node,
|
|
591
|
+
localized: isLocalized,
|
|
592
|
+
visible: true,
|
|
593
|
+
data: {
|
|
594
|
+
...ctx.node.data,
|
|
595
|
+
...content
|
|
596
|
+
}
|
|
597
|
+
};
|
|
598
|
+
node = resolveComponentDataBindings(node, processorContext.qualifiers?.dataBindings);
|
|
599
|
+
return {
|
|
600
|
+
...node,
|
|
583
601
|
regions: ctx.visitRegions(ctx.node.regions)
|
|
584
602
|
};
|
|
585
|
-
return resolved;
|
|
586
603
|
} });
|
|
587
604
|
}
|
|
588
605
|
|
|
@@ -743,6 +760,7 @@ function resolveDynamicPageId({ id, identifierType, siteManifest, aspectType })
|
|
|
743
760
|
* @param manifest - The page manifest containing all variations.
|
|
744
761
|
* @param options - Resolution options.
|
|
745
762
|
* @param options.contextResolver - Optional async function that returns the shopper's qualifier context. Only called if a variation's rule needs it.
|
|
763
|
+
* @param options.locale - The current locale (e.g. `"en_US"`). Used to evaluate locale-based visibility rules.
|
|
746
764
|
* @returns The selected variation entry and resolved context, or `null` if no variation (including default) exists.
|
|
747
765
|
*
|
|
748
766
|
* @example
|
|
@@ -751,23 +769,23 @@ function resolveDynamicPageId({ id, identifierType, siteManifest, aspectType })
|
|
|
751
769
|
*
|
|
752
770
|
* const manifest = {
|
|
753
771
|
* pageId: 'homepage',
|
|
754
|
-
* locale: 'en-US',
|
|
755
772
|
* context: { campaignQualifiers: [], customerGroups: ['vip-customers'], dataBindings: [] },
|
|
756
773
|
* variationOrder: ['vip-homepage', 'holiday-homepage'],
|
|
757
774
|
* variations: {
|
|
758
775
|
* 'vip-homepage': {
|
|
759
776
|
* ruleRequiresContext: true,
|
|
760
777
|
* pageRequiresContext: false,
|
|
761
|
-
* visibilityRule: { customerGroups: ['vip-customers'] },
|
|
778
|
+
* visibilityRule: { activeLocales: ['en-US'], customerGroups: ['vip-customers'] },
|
|
762
779
|
* page: { id: 'homepage', typeId: 'storePage', regions: [] },
|
|
763
780
|
* },
|
|
764
781
|
* 'holiday-homepage': {
|
|
765
782
|
* ruleRequiresContext: false,
|
|
766
783
|
* pageRequiresContext: false,
|
|
767
784
|
* visibilityRule: {
|
|
785
|
+
* activeLocales: ['en-US'],
|
|
768
786
|
* schedule: {
|
|
769
|
-
* start: new Date('2026-12-01').
|
|
770
|
-
* end: new Date('2026-12-31').
|
|
787
|
+
* start: new Date('2026-12-01').toISOString(),
|
|
788
|
+
* end: new Date('2026-12-31').toISOString(),
|
|
771
789
|
* },
|
|
772
790
|
* },
|
|
773
791
|
* page: { id: 'homepage', typeId: 'storePage', regions: [] },
|
|
@@ -779,11 +797,12 @@ function resolveDynamicPageId({ id, identifierType, siteManifest, aspectType })
|
|
|
779
797
|
* },
|
|
780
798
|
* },
|
|
781
799
|
* defaultVariation: 'default-homepage',
|
|
782
|
-
*
|
|
800
|
+
* componentInfo: {},
|
|
783
801
|
* };
|
|
784
802
|
*
|
|
785
803
|
* // VIP shopper — matches first variation
|
|
786
804
|
* const result = await getPageFromManifest(manifest, {
|
|
805
|
+
* locale: 'en-US',
|
|
787
806
|
* contextResolver: async () => ({
|
|
788
807
|
* customerGroups: { 'vip-customers': true },
|
|
789
808
|
* campaignQualifiers: {},
|
|
@@ -793,6 +812,7 @@ function resolveDynamicPageId({ id, identifierType, siteManifest, aspectType })
|
|
|
793
812
|
*
|
|
794
813
|
* // Non-VIP shopper outside holiday window — falls back to default
|
|
795
814
|
* const fallback = await getPageFromManifest(manifest, {
|
|
815
|
+
* locale: 'en-US',
|
|
796
816
|
* contextResolver: async () => ({
|
|
797
817
|
* customerGroups: {},
|
|
798
818
|
* campaignQualifiers: {},
|
|
@@ -801,13 +821,13 @@ function resolveDynamicPageId({ id, identifierType, siteManifest, aspectType })
|
|
|
801
821
|
* // fallback.entry === manifest.variations['default-homepage']
|
|
802
822
|
* ```
|
|
803
823
|
*/
|
|
804
|
-
async function getPageFromManifest(manifest, { contextResolver }) {
|
|
824
|
+
async function getPageFromManifest(manifest, { contextResolver, locale }) {
|
|
805
825
|
let context = null;
|
|
806
826
|
let resolvedVariation = null;
|
|
807
827
|
for (const variationId of manifest.variationOrder) {
|
|
808
828
|
const variation = manifest.variations[variationId];
|
|
809
|
-
if (variation?.ruleRequiresContext && !context) context = await contextResolver?.() ?? null;
|
|
810
|
-
if (!variation?.visibilityRule || validateRule(variation.visibilityRule, context)) {
|
|
829
|
+
if (variation?.ruleRequiresContext && !context) context = await contextResolver?.(manifest.context) ?? null;
|
|
830
|
+
if (!variation?.visibilityRule || validateRule(variation.visibilityRule, locale, context)) {
|
|
811
831
|
resolvedVariation = variation;
|
|
812
832
|
break;
|
|
813
833
|
}
|
|
@@ -893,13 +913,17 @@ async function resolvePage({ id, identifierType, aspectType, locale, manifestSto
|
|
|
893
913
|
if (!resolvedId) return null;
|
|
894
914
|
const pageManifest = await manifestStorage.getPageManifest(resolvedId, locale);
|
|
895
915
|
if (!pageManifest) return null;
|
|
896
|
-
const pageResults = await getPageFromManifest(pageManifest, {
|
|
916
|
+
const pageResults = await getPageFromManifest(pageManifest, {
|
|
917
|
+
contextResolver,
|
|
918
|
+
locale
|
|
919
|
+
});
|
|
897
920
|
if (!pageResults) return null;
|
|
898
921
|
let context = null;
|
|
899
|
-
if (pageResults.entry.pageRequiresContext) context = pageResults.context ?? await contextResolver?.() ?? null;
|
|
922
|
+
if (pageResults.entry.pageRequiresContext) context = pageResults.context ?? await contextResolver?.(pageManifest.context) ?? null;
|
|
900
923
|
return processPage(pageResults.entry.page, {
|
|
901
924
|
qualifiers: context,
|
|
902
|
-
componentInfo: pageManifest.componentInfo
|
|
925
|
+
componentInfo: pageManifest.componentInfo,
|
|
926
|
+
locale
|
|
903
927
|
});
|
|
904
928
|
}
|
|
905
929
|
|