@lifeaz/lors-helper 1.1.0 → 1.1.2

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/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # 🛒 LORS Helper
2
- **1.1.0** Lifeaz Online Retail Solution Helper
2
+ **1.1.2** Lifeaz Online Retail Solution Helper
3
3
 
4
4
  ---
5
5
 
package/dist/main.d.ts CHANGED
@@ -516,6 +516,7 @@ export declare const CartSchema: z.ZodObject<{
516
516
  locale: z.ZodUnion<readonly [z.ZodLiteral<"fr">, z.ZodLiteral<"en">, z.ZodLiteral<"nl">, z.ZodLiteral<"de">, z.ZodLiteral<"it">, z.ZodLiteral<"es">, z.ZodLiteral<"pt">, z.ZodLiteral<"pl">]>;
517
517
  vatNumber: z.ZodNullable<z.ZodString>;
518
518
  multiAddressesCallback: z.ZodBoolean;
519
+ simulated: z.ZodDefault<z.ZodBoolean>;
519
520
  partnerId: z.ZodNullable<z.ZodCustom<UUID, UUID>>;
520
521
  createdAt: z.ZodCustom<Dayjs, Dayjs>;
521
522
  updatedAt: z.ZodCustom<Dayjs, Dayjs>;
@@ -818,8 +819,8 @@ export type MvtDevice = '_Mobile_' | '_Tablet_' | '_Desktop_';
818
819
  export declare const MvtDeviceSchema: z.ZodUnion<readonly [z.ZodLiteral<"_Mobile_">, z.ZodLiteral<"_Tablet_">, z.ZodLiteral<"_Desktop_">]>;
819
820
  export type MvtNodeKind = '_And_' | '_Or_' | '_Not_' | '_Leaf_';
820
821
  export declare const MvtNodeKindSchema: z.ZodUnion<readonly [z.ZodLiteral<"_And_">, z.ZodLiteral<"_Or_">, z.ZodLiteral<"_Not_">, z.ZodLiteral<"_Leaf_">]>;
821
- export type MvtOperator = '_Device_In_' | '_Lang_In_' | '_Country_In_' | '_Profile_In_' | '_Partner_In_' | '_Partner_Absent_' | '_Campaign_Seen_' | '_Campaign_Not_Seen_' | '_Visitor_Is_New_' | '_Visitor_Is_Returning_' | '_Utm_Source_In_' | '_Utm_Medium_In_' | '_Utm_Campaign_In_' | '_Referrer_Matches_' | '_Path_Matches_' | '_Has_Cart_' | '_Hour_Of_Day_Between_' | '_Day_Of_Week_In_';
822
- export declare const MvtOperatorSchema: z.ZodUnion<readonly [z.ZodLiteral<"_Device_In_">, z.ZodLiteral<"_Lang_In_">, z.ZodLiteral<"_Country_In_">, z.ZodLiteral<"_Profile_In_">, z.ZodLiteral<"_Partner_In_">, z.ZodLiteral<"_Partner_Absent_">, z.ZodLiteral<"_Campaign_Seen_">, z.ZodLiteral<"_Campaign_Not_Seen_">, z.ZodLiteral<"_Visitor_Is_New_">, z.ZodLiteral<"_Visitor_Is_Returning_">, z.ZodLiteral<"_Utm_Source_In_">, z.ZodLiteral<"_Utm_Medium_In_">, z.ZodLiteral<"_Utm_Campaign_In_">, z.ZodLiteral<"_Referrer_Matches_">, z.ZodLiteral<"_Path_Matches_">, z.ZodLiteral<"_Has_Cart_">, z.ZodLiteral<"_Hour_Of_Day_Between_">, z.ZodLiteral<"_Day_Of_Week_In_">]>;
822
+ export type MvtOperator = '_Device_In_' | '_Lang_In_' | '_Country_In_' | '_Profile_In_' | '_Partner_In_' | '_Partner_Absent_' | '_Campaign_Seen_' | '_Campaign_Not_Seen_' | '_Visitor_Is_New_' | '_Visitor_Is_Returning_' | '_Utm_Source_In_' | '_Utm_Medium_In_' | '_Utm_Campaign_In_' | '_Referrer_Matches_' | '_Path_Matches_' | '_Has_Cart_' | '_Hour_Of_Day_Between_' | '_Day_Of_Week_In_' | '_Query_Param_Matches_' | '_Screen_Width_Between_' | '_Visits_At_Least_' | '_Logged_In_' | '_Logged_Out_' | '_Is_Weekend_' | '_Date_Between_';
823
+ export declare const MvtOperatorSchema: z.ZodUnion<readonly [z.ZodLiteral<"_Device_In_">, z.ZodLiteral<"_Lang_In_">, z.ZodLiteral<"_Country_In_">, z.ZodLiteral<"_Profile_In_">, z.ZodLiteral<"_Partner_In_">, z.ZodLiteral<"_Partner_Absent_">, z.ZodLiteral<"_Campaign_Seen_">, z.ZodLiteral<"_Campaign_Not_Seen_">, z.ZodLiteral<"_Visitor_Is_New_">, z.ZodLiteral<"_Visitor_Is_Returning_">, z.ZodLiteral<"_Utm_Source_In_">, z.ZodLiteral<"_Utm_Medium_In_">, z.ZodLiteral<"_Utm_Campaign_In_">, z.ZodLiteral<"_Referrer_Matches_">, z.ZodLiteral<"_Path_Matches_">, z.ZodLiteral<"_Has_Cart_">, z.ZodLiteral<"_Hour_Of_Day_Between_">, z.ZodLiteral<"_Day_Of_Week_In_">, z.ZodLiteral<"_Query_Param_Matches_">, z.ZodLiteral<"_Screen_Width_Between_">, z.ZodLiteral<"_Visits_At_Least_">, z.ZodLiteral<"_Logged_In_">, z.ZodLiteral<"_Logged_Out_">, z.ZodLiteral<"_Is_Weekend_">, z.ZodLiteral<"_Date_Between_">]>;
823
824
  export declare const MVT_NULLARY_OPERATORS: readonly MvtOperator[];
824
825
  export type MvtOverrideOp = 'set' | 'merge' | 'remove' | 'reorder' | 'insert' | 'patch';
825
826
  export declare const MvtOverrideOpSchema: z.ZodUnion<readonly [z.ZodLiteral<"set">, z.ZodLiteral<"merge">, z.ZodLiteral<"remove">, z.ZodLiteral<"reorder">, z.ZodLiteral<"insert">, z.ZodLiteral<"patch">]>;
@@ -857,8 +858,19 @@ export declare const MvtVariantSchema: z.ZodObject<{
857
858
  equals: z.ZodString;
858
859
  }, z.core.$strip>>;
859
860
  }, z.core.$strip>>;
861
+ audience: z.ZodDefault<z.ZodNullable<z.ZodType<MvtAudienceNode, unknown, z.core.$ZodTypeInternals<MvtAudienceNode, unknown>>>>;
862
+ order: z.ZodDefault<z.ZodNumber>;
863
+ color: z.ZodDefault<z.ZodNullable<z.ZodString>>;
864
+ description: z.ZodDefault<z.ZodNullable<z.ZodString>>;
860
865
  }, z.core.$strip>;
861
866
  export type MvtVariant = z.infer<typeof MvtVariantSchema>;
867
+ export type MvtAllocationMode = '_Targeted_' | '_Weighted_' | '_Unreachable_';
868
+ export interface MvtAllocationRow {
869
+ key: string;
870
+ mode: MvtAllocationMode;
871
+ weight: number;
872
+ sharePct: number;
873
+ }
862
874
  export declare const MvtExperimentSchema: z.ZodObject<{
863
875
  id: z.ZodCustom<UUID, UUID>;
864
876
  key: z.ZodString;
@@ -891,6 +903,10 @@ export declare const MvtExperimentSchema: z.ZodObject<{
891
903
  equals: z.ZodString;
892
904
  }, z.core.$strip>>;
893
905
  }, z.core.$strip>>;
906
+ audience: z.ZodDefault<z.ZodNullable<z.ZodType<MvtAudienceNode, unknown, z.core.$ZodTypeInternals<MvtAudienceNode, unknown>>>>;
907
+ order: z.ZodDefault<z.ZodNumber>;
908
+ color: z.ZodDefault<z.ZodNullable<z.ZodString>>;
909
+ description: z.ZodDefault<z.ZodNullable<z.ZodString>>;
894
910
  }, z.core.$strip>>;
895
911
  }, z.core.$strip>;
896
912
  export type MvtExperiment = z.infer<typeof MvtExperimentSchema>;
@@ -929,6 +945,10 @@ export declare const MvtConfigSchema: z.ZodObject<{
929
945
  equals: z.ZodString;
930
946
  }, z.core.$strip>>;
931
947
  }, z.core.$strip>>;
948
+ audience: z.ZodDefault<z.ZodNullable<z.ZodType<MvtAudienceNode, unknown, z.core.$ZodTypeInternals<MvtAudienceNode, unknown>>>>;
949
+ order: z.ZodDefault<z.ZodNumber>;
950
+ color: z.ZodDefault<z.ZodNullable<z.ZodString>>;
951
+ description: z.ZodDefault<z.ZodNullable<z.ZodString>>;
932
952
  }, z.core.$strip>>;
933
953
  }, z.core.$strip>>;
934
954
  }, z.core.$strip>;
@@ -951,7 +971,14 @@ export interface MvtContext {
951
971
  hasCart: boolean;
952
972
  firstSeenAt: number;
953
973
  now: number;
974
+ query: Record<string, string>;
975
+ screenWidth: number;
976
+ visits: number;
977
+ loggedIn: boolean;
954
978
  }
979
+ export declare function mvtNormalizeContext(context: Partial<MvtContext> & {
980
+ unitId: string;
981
+ }): MvtContext;
955
982
  export interface MvtDecision {
956
983
  experimentKey: string;
957
984
  experimentId: UUID;
@@ -963,7 +990,8 @@ export interface MvtDecision {
963
990
  export declare function mvtHash(input: string): number;
964
991
  export declare function mvtBucket(salt: string, unitId: string, namespace?: string): number;
965
992
  export declare function mvtIsEligibleForTraffic(experiment: MvtExperiment, unitId: string): boolean;
966
- export declare function mvtPickVariant(experiment: MvtExperiment, unitId: string): MvtVariant | null;
993
+ export declare function mvtPickVariant(experiment: MvtExperiment, unitId: string, context?: MvtContext): MvtVariant | null;
994
+ export declare function mvtDistribution(variants: readonly MvtVariant[]): MvtAllocationRow[];
967
995
  export declare function mvtEvaluateAudience(node: MvtAudienceNode | null, context: MvtContext): boolean;
968
996
  export declare function mvtIsWithinWindow(experiment: MvtExperiment, now: number): boolean;
969
997
  export declare function mvtIsLive(experiment: MvtExperiment, now: number): boolean;
@@ -989,6 +1017,37 @@ export interface MvtSlotDefinition {
989
1017
  itemKey?: string;
990
1018
  schema: z.ZodType<unknown>;
991
1019
  }
1020
+ export declare const MvtAnchorPatchSchema: z.ZodObject<{
1021
+ hidden: z.ZodOptional<z.ZodBoolean>;
1022
+ order: z.ZodOptional<z.ZodNumber>;
1023
+ text: z.ZodOptional<z.ZodRecord<z.ZodUnion<readonly [z.ZodLiteral<"fr">, z.ZodLiteral<"en">, z.ZodLiteral<"nl">, z.ZodLiteral<"de">, z.ZodLiteral<"it">, z.ZodLiteral<"es">, z.ZodLiteral<"pt">, z.ZodLiteral<"pl">]> & z.core.$partial, z.ZodString>>;
1024
+ href: z.ZodOptional<z.ZodString>;
1025
+ route: z.ZodOptional<z.ZodString>;
1026
+ image: z.ZodOptional<z.ZodString>;
1027
+ style: z.ZodOptional<z.ZodObject<{
1028
+ background: z.ZodOptional<z.ZodString>;
1029
+ color: z.ZodOptional<z.ZodString>;
1030
+ borderColor: z.ZodOptional<z.ZodString>;
1031
+ borderRadius: z.ZodOptional<z.ZodNumber>;
1032
+ fontSize: z.ZodOptional<z.ZodNumber>;
1033
+ fontWeight: z.ZodOptional<z.ZodEnum<{
1034
+ 300: "300";
1035
+ 400: "400";
1036
+ 500: "500";
1037
+ 600: "600";
1038
+ 700: "700";
1039
+ 800: "800";
1040
+ }>>;
1041
+ align: z.ZodOptional<z.ZodEnum<{
1042
+ left: "left";
1043
+ center: "center";
1044
+ right: "right";
1045
+ }>>;
1046
+ paddingY: z.ZodOptional<z.ZodNumber>;
1047
+ paddingX: z.ZodOptional<z.ZodNumber>;
1048
+ }, z.core.$strip>>;
1049
+ }, z.core.$strip>;
1050
+ export type MvtAnchorPatch = z.infer<typeof MvtAnchorPatchSchema>;
992
1051
  export declare const MVT_SLOTS: readonly MvtSlotDefinition[];
993
1052
  export declare function mvtSlot(key: string): MvtSlotDefinition | null;
994
1053
  export declare function mvtSlotsForScope(scope: MvtScope): MvtSlotDefinition[];
@@ -999,4 +1058,101 @@ export interface MvtOverrideIssue {
999
1058
  }
1000
1059
  export declare function mvtValidateOverrides(overrides: MvtOverride[]): MvtOverrideIssue[];
1001
1060
  export declare function mvtApplyOverride<T>(base: T, override: MvtOverride): T;
1061
+ export declare const MVT_ANCHOR_ATTRIBUTE = "data-mvt-anchor";
1062
+ export declare function mvtAnchorsSlot(scope: MvtScope): string;
1063
+ export declare function mvtMergeAnchorPatch(base: MvtAnchorPatch | undefined, next: MvtAnchorPatch | undefined): MvtAnchorPatch;
1064
+ export declare function mvtAnchorStyle(patch: MvtAnchorPatch | null | undefined): Record<string, string>;
1065
+ export declare const MVT_STUDIO_PROTOCOL = 2;
1066
+ export type MvtStudioAnchorRole = 'section' | 'cta' | 'text' | 'image' | 'block';
1067
+ export interface MvtStudioAnchor {
1068
+ id: string;
1069
+ label: string;
1070
+ role: MvtStudioAnchorRole;
1071
+ parentId: string | null;
1072
+ order: number;
1073
+ text: string | null;
1074
+ movable: boolean;
1075
+ hideable: boolean;
1076
+ rect: {
1077
+ top: number;
1078
+ left: number;
1079
+ width: number;
1080
+ height: number;
1081
+ };
1082
+ }
1083
+ export interface MvtStudioLink {
1084
+ path: string;
1085
+ label: string;
1086
+ kind: 'link' | 'step';
1087
+ reachable: boolean;
1088
+ }
1089
+ export interface MvtStudioCart {
1090
+ reference: string;
1091
+ secret: string;
1092
+ step: string;
1093
+ simulated: true;
1094
+ }
1095
+ export type MvtStudioRequest = {
1096
+ protocol: number;
1097
+ type: 'studio:hello';
1098
+ } | {
1099
+ protocol: number;
1100
+ type: 'studio:scan';
1101
+ } | {
1102
+ protocol: number;
1103
+ type: 'studio:select';
1104
+ anchorId: string | null;
1105
+ } | {
1106
+ protocol: number;
1107
+ type: 'studio:apply';
1108
+ anchors: Record<string, MvtAnchorPatch>;
1109
+ lang: string;
1110
+ } | {
1111
+ protocol: number;
1112
+ type: 'studio:mode';
1113
+ picking: boolean;
1114
+ } | {
1115
+ protocol: number;
1116
+ type: 'studio:navigate';
1117
+ path: string;
1118
+ } | {
1119
+ protocol: number;
1120
+ type: 'studio:links';
1121
+ } | {
1122
+ protocol: number;
1123
+ type: 'studio:cart';
1124
+ cart: MvtStudioCart;
1125
+ };
1126
+ export type MvtStudioEvent = {
1127
+ protocol: number;
1128
+ type: 'studio:ready';
1129
+ scope: MvtScope;
1130
+ path: string;
1131
+ langs: string[];
1132
+ } | {
1133
+ protocol: number;
1134
+ type: 'studio:anchors';
1135
+ anchors: MvtStudioAnchor[];
1136
+ path: string;
1137
+ } | {
1138
+ protocol: number;
1139
+ type: 'studio:picked';
1140
+ anchor: MvtStudioAnchor;
1141
+ } | {
1142
+ protocol: number;
1143
+ type: 'studio:navigated';
1144
+ path: string;
1145
+ } | {
1146
+ protocol: number;
1147
+ type: 'studio:links';
1148
+ links: MvtStudioLink[];
1149
+ path: string;
1150
+ } | {
1151
+ protocol: number;
1152
+ type: 'studio:cart';
1153
+ cart: MvtStudioCart | null;
1154
+ };
1155
+ export declare function mvtCollectLinks(root: ParentNode, origin: string): MvtStudioLink[];
1156
+ export declare function mvtIsStudioEvent(data: unknown): data is MvtStudioEvent;
1157
+ export declare function mvtIsStudioRequest(data: unknown): data is MvtStudioRequest;
1002
1158
  //# sourceMappingURL=main.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
package/dist/main.js CHANGED
@@ -272,6 +272,7 @@ export const CartSchema = z.object({
272
272
  locale: LangSchema,
273
273
  vatNumber: z.string().nullable(),
274
274
  multiAddressesCallback: z.boolean(),
275
+ simulated: z.boolean().default(false),
275
276
  partnerId: uuidSchema.nullable(),
276
277
  createdAt: dayjsSchema,
277
278
  updatedAt: dayjsSchema,
@@ -493,12 +494,22 @@ export const MvtOperatorSchema = z.union([
493
494
  z.literal('_Has_Cart_'),
494
495
  z.literal('_Hour_Of_Day_Between_'),
495
496
  z.literal('_Day_Of_Week_In_'),
497
+ z.literal('_Query_Param_Matches_'),
498
+ z.literal('_Screen_Width_Between_'),
499
+ z.literal('_Visits_At_Least_'),
500
+ z.literal('_Logged_In_'),
501
+ z.literal('_Logged_Out_'),
502
+ z.literal('_Is_Weekend_'),
503
+ z.literal('_Date_Between_'),
496
504
  ]);
497
505
  export const MVT_NULLARY_OPERATORS = [
498
506
  '_Partner_Absent_',
499
507
  '_Visitor_Is_New_',
500
508
  '_Visitor_Is_Returning_',
501
509
  '_Has_Cart_',
510
+ '_Logged_In_',
511
+ '_Logged_Out_',
512
+ '_Is_Weekend_',
502
513
  ];
503
514
  export const MvtOverrideOpSchema = z.union([z.literal('set'), z.literal('merge'), z.literal('remove'), z.literal('reorder'), z.literal('insert'), z.literal('patch')]);
504
515
  export const MvtOverrideSchema = z.object({
@@ -521,6 +532,10 @@ export const MvtVariantSchema = z.object({
521
532
  weight: z.number().int().nonnegative(),
522
533
  control: z.boolean(),
523
534
  overrides: z.array(MvtOverrideSchema),
535
+ audience: MvtAudienceNodeSchema.nullable().default(null),
536
+ order: z.number().int().default(0),
537
+ color: z.string().nullable().default(null),
538
+ description: z.string().nullable().default(null),
524
539
  });
525
540
  export const MvtExperimentSchema = z.object({
526
541
  id: uuidSchema,
@@ -545,6 +560,27 @@ export const MvtConfigSchema = z.object({
545
560
  enabled: z.boolean(),
546
561
  experiments: z.array(MvtExperimentSchema),
547
562
  });
563
+ export function mvtNormalizeContext(context) {
564
+ return {
565
+ device: '_Desktop_',
566
+ lang: 'fr',
567
+ country: null,
568
+ profile: null,
569
+ partner: null,
570
+ seen: {},
571
+ utm: { source: null, medium: null, campaign: null },
572
+ referrer: null,
573
+ path: '/',
574
+ hasCart: false,
575
+ firstSeenAt: Date.now(),
576
+ now: Date.now(),
577
+ query: {},
578
+ screenWidth: 0,
579
+ visits: 1,
580
+ loggedIn: false,
581
+ ...context,
582
+ };
583
+ }
548
584
  const MVT_RETURNING_AFTER_MS = 30 * 60 * 1000;
549
585
  export function mvtHash(input) {
550
586
  let hash = 0x811c9dc5;
@@ -564,19 +600,42 @@ export function mvtIsEligibleForTraffic(experiment, unitId) {
564
600
  return false;
565
601
  return mvtBucket(experiment.salt, unitId, 'traffic') < experiment.trafficPct * 100;
566
602
  }
567
- export function mvtPickVariant(experiment, unitId) {
568
- const variants = [...experiment.variants].sort((a, b) => a.key.localeCompare(b.key));
569
- const total = variants.reduce((sum, v) => sum + Math.max(v.weight, 0), 0);
570
- if (!variants.length || total <= 0)
603
+ export function mvtPickVariant(experiment, unitId, context) {
604
+ const targeted = experiment.variants
605
+ .filter(variant => !!variant.audience)
606
+ .sort((a, b) => (a.order ?? 0) - (b.order ?? 0) || a.key.localeCompare(b.key));
607
+ if (context)
608
+ for (const variant of targeted)
609
+ if (mvtEvaluateAudience(variant.audience ?? null, context))
610
+ return variant;
611
+ const pool = experiment.variants.filter(variant => !variant.audience).sort((a, b) => a.key.localeCompare(b.key));
612
+ const total = pool.reduce((sum, v) => sum + Math.max(v.weight, 0), 0);
613
+ if (!pool.length || total <= 0)
571
614
  return null;
572
615
  const target = (mvtBucket(experiment.salt, unitId) / 10000) * total;
573
616
  let cursor = 0;
574
- for (const variant of variants) {
617
+ for (const variant of pool) {
575
618
  cursor += Math.max(variant.weight, 0);
576
619
  if (target < cursor)
577
620
  return variant;
578
621
  }
579
- return variants[variants.length - 1];
622
+ return pool[pool.length - 1];
623
+ }
624
+ export function mvtDistribution(variants) {
625
+ const pool = variants.filter(variant => !variant.audience);
626
+ const total = pool.reduce((sum, v) => sum + Math.max(v.weight, 0), 0);
627
+ return variants.map(variant => {
628
+ if (variant.audience)
629
+ return { key: variant.key, mode: '_Targeted_', weight: variant.weight, sharePct: 0 };
630
+ if (total <= 0 || variant.weight <= 0)
631
+ return { key: variant.key, mode: '_Unreachable_', weight: variant.weight, sharePct: 0 };
632
+ return {
633
+ key: variant.key,
634
+ mode: '_Weighted_',
635
+ weight: variant.weight,
636
+ sharePct: Math.round((Math.max(variant.weight, 0) / total) * 1000) / 10,
637
+ };
638
+ });
580
639
  }
581
640
  function mvtMatchesPattern(value, patterns) {
582
641
  if (value === null)
@@ -621,6 +680,35 @@ function mvtEvaluateLeaf(operator, values, context) {
621
680
  return from <= to ? hour >= from && hour <= to : hour >= from || hour <= to;
622
681
  }
623
682
  case '_Day_Of_Week_In_': return values.map(Number).includes(new Date(context.now).getDay());
683
+ case '_Logged_In_': return context.loggedIn;
684
+ case '_Logged_Out_': return !context.loggedIn;
685
+ case '_Is_Weekend_': return [0, 6].includes(new Date(context.now).getDay());
686
+ case '_Visits_At_Least_': return context.visits >= Number(values[0] ?? 1);
687
+ case '_Query_Param_Matches_': {
688
+ return values.some(raw => {
689
+ const separator = raw.indexOf('=');
690
+ const name = (separator < 0 ? raw : raw.slice(0, separator)).trim().toLowerCase();
691
+ const expected = separator < 0 ? null : raw.slice(separator + 1);
692
+ const actual = context.query[name];
693
+ if (actual === undefined)
694
+ return false;
695
+ if (expected === null)
696
+ return true;
697
+ return mvtMatchesPattern(actual, [expected]);
698
+ });
699
+ }
700
+ case '_Screen_Width_Between_': {
701
+ const from = Number(values[0] ?? 0);
702
+ const to = Number(values[1] ?? Number.MAX_SAFE_INTEGER);
703
+ return context.screenWidth >= from && context.screenWidth <= to;
704
+ }
705
+ case '_Date_Between_': {
706
+ const from = values[0] ? Date.parse(values[0]) : Number.NEGATIVE_INFINITY;
707
+ const to = values[1] ? Date.parse(values[1]) : Number.POSITIVE_INFINITY;
708
+ if (Number.isNaN(from) || Number.isNaN(to))
709
+ return false;
710
+ return context.now >= from && context.now <= to;
711
+ }
624
712
  default: return false;
625
713
  }
626
714
  }
@@ -667,7 +755,7 @@ export function mvtResolve(config, context, forced = {}) {
667
755
  continue;
668
756
  if (!mvtIsEligibleForTraffic(experiment, context.unitId))
669
757
  continue;
670
- const variant = mvtPickVariant(experiment, context.unitId);
758
+ const variant = mvtPickVariant(experiment, context.unitId, context);
671
759
  if (!variant)
672
760
  continue;
673
761
  if (experiment.exclusionGroup)
@@ -686,8 +774,36 @@ function mvtToDecision(experiment, variant) {
686
774
  overrides: variant.overrides,
687
775
  };
688
776
  }
689
- const i18nTextSchema = z.record(LangSchema, z.string());
777
+ const i18nTextSchema = z.partialRecord(LangSchema, z.string());
690
778
  const colorSchema = z.string().regex(/^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i);
779
+ export const MvtAnchorPatchSchema = z.object({
780
+ hidden: z.boolean().optional(),
781
+ order: z.number().int().min(-999).max(999).optional(),
782
+ text: i18nTextSchema.optional(),
783
+ href: z.string().max(2048).optional(),
784
+ route: z.string().max(512).optional(),
785
+ image: z.string().max(2048).optional(),
786
+ style: z.object({
787
+ background: colorSchema.optional(),
788
+ color: colorSchema.optional(),
789
+ borderColor: colorSchema.optional(),
790
+ borderRadius: z.number().int().min(0).max(96).optional(),
791
+ fontSize: z.number().int().min(8).max(96).optional(),
792
+ fontWeight: z.enum(['300', '400', '500', '600', '700', '800']).optional(),
793
+ align: z.enum(['left', 'center', 'right']).optional(),
794
+ paddingY: z.number().int().min(0).max(160).optional(),
795
+ paddingX: z.number().int().min(0).max(160).optional(),
796
+ }).optional(),
797
+ });
798
+ const anchorsSchema = z.record(z.string(), MvtAnchorPatchSchema);
799
+ const ANCHOR_FIELDS = [
800
+ { key: 'hidden', label: 'Hidden', kind: 'boolean' },
801
+ { key: 'order', label: 'Position', kind: 'number' },
802
+ { key: 'text', label: 'Text', kind: 'i18n' },
803
+ { key: 'href', label: 'External link', kind: 'text' },
804
+ { key: 'route', label: 'Internal route', kind: 'text' },
805
+ { key: 'image', label: 'Image', kind: 'image' },
806
+ ];
691
807
  function slot(definition) {
692
808
  return definition;
693
809
  }
@@ -809,6 +925,18 @@ export const MVT_SLOTS = [
809
925
  ],
810
926
  schema: z.object({ mobile: z.boolean().optional(), tablet: z.boolean().optional(), desktop: z.boolean().optional() }),
811
927
  }),
928
+ slot({
929
+ key: 'storefront.anchors', scope: '_Storefront_', area: 'Studio', label: 'Anchored elements',
930
+ hint: 'Everything the visual editor writes: elements hidden, moved, reworded or restyled by clicking on the page itself.',
931
+ kind: 'record', entryKind: 'object', ops: ['merge', 'set'], fields: ANCHOR_FIELDS, itemKey: 'anchor',
932
+ schema: anchorsSchema,
933
+ }),
934
+ slot({
935
+ key: 'checkout.anchors', scope: '_Checkout_', area: 'Studio', label: 'Anchored elements',
936
+ hint: 'Everything the visual editor writes: elements hidden, moved, reworded or restyled by clicking on the page itself.',
937
+ kind: 'record', entryKind: 'object', ops: ['merge', 'set'], fields: ANCHOR_FIELDS, itemKey: 'anchor',
938
+ schema: anchorsSchema,
939
+ }),
812
940
  ];
813
941
  const MVT_SLOTS_BY_KEY = new Map(MVT_SLOTS.map(s => [s.key, s]));
814
942
  export function mvtSlot(key) {
@@ -832,8 +960,12 @@ export function mvtValidateOverrides(overrides) {
832
960
  if (override.op === 'remove' || override.op === 'reorder')
833
961
  return;
834
962
  if (override.op === 'merge' || override.op === 'patch' || override.op === 'insert') {
835
- if (override.value === undefined)
963
+ if (override.value === undefined) {
836
964
  issues.push({ index, slot: override.slot, reason: 'missing_value' });
965
+ return;
966
+ }
967
+ if (definition.kind === 'record' && !definition.schema.safeParse(override.value).success)
968
+ issues.push({ index, slot: override.slot, reason: 'invalid_value' });
837
969
  return;
838
970
  }
839
971
  if (!definition.schema.safeParse(override.value).success)
@@ -898,3 +1030,80 @@ export function mvtApplyOverride(base, override) {
898
1030
  return base;
899
1031
  }
900
1032
  }
1033
+ export const MVT_ANCHOR_ATTRIBUTE = 'data-mvt-anchor';
1034
+ export function mvtAnchorsSlot(scope) {
1035
+ return scope === '_Checkout_' ? 'checkout.anchors' : 'storefront.anchors';
1036
+ }
1037
+ export function mvtMergeAnchorPatch(base, next) {
1038
+ if (!base)
1039
+ return next ?? {};
1040
+ if (!next)
1041
+ return base;
1042
+ return {
1043
+ ...base,
1044
+ ...next,
1045
+ text: next.text || base.text ? { ...(base.text ?? {}), ...(next.text ?? {}) } : undefined,
1046
+ style: next.style || base.style ? { ...(base.style ?? {}), ...(next.style ?? {}) } : undefined,
1047
+ };
1048
+ }
1049
+ export function mvtAnchorStyle(patch) {
1050
+ const style = patch?.style;
1051
+ if (!style)
1052
+ return {};
1053
+ const out = {};
1054
+ if (style.background)
1055
+ out['background-color'] = style.background;
1056
+ if (style.color)
1057
+ out['color'] = style.color;
1058
+ if (style.borderColor)
1059
+ out['border-color'] = style.borderColor;
1060
+ if (style.borderRadius !== undefined)
1061
+ out['border-radius'] = `${style.borderRadius}px`;
1062
+ if (style.fontSize !== undefined)
1063
+ out['font-size'] = `${style.fontSize}px`;
1064
+ if (style.fontWeight)
1065
+ out['font-weight'] = style.fontWeight;
1066
+ if (style.align)
1067
+ out['text-align'] = style.align;
1068
+ if (style.paddingY !== undefined)
1069
+ out['padding-block'] = `${style.paddingY}px`;
1070
+ if (style.paddingX !== undefined)
1071
+ out['padding-inline'] = `${style.paddingX}px`;
1072
+ return out;
1073
+ }
1074
+ export const MVT_STUDIO_PROTOCOL = 2;
1075
+ export function mvtCollectLinks(root, origin) {
1076
+ const seen = new Set();
1077
+ const links = [];
1078
+ for (const element of Array.from(root.querySelectorAll('a[href]'))) {
1079
+ const anchor = element;
1080
+ if (anchor.hasAttribute('download') || anchor.target === '_blank')
1081
+ continue;
1082
+ let url;
1083
+ try {
1084
+ url = new URL(anchor.getAttribute('href') ?? '', origin);
1085
+ }
1086
+ catch {
1087
+ continue;
1088
+ }
1089
+ if (url.origin !== origin)
1090
+ continue;
1091
+ if (!url.pathname.startsWith('/'))
1092
+ continue;
1093
+ if (seen.has(url.pathname))
1094
+ continue;
1095
+ seen.add(url.pathname);
1096
+ const label = (anchor.textContent ?? '').replace(/\s+/g, ' ').trim();
1097
+ links.push({ path: url.pathname, label: label || url.pathname, kind: 'link', reachable: true });
1098
+ }
1099
+ return links.sort((a, b) => a.label.localeCompare(b.label));
1100
+ }
1101
+ export function mvtIsStudioEvent(data) {
1102
+ if (!data || typeof data !== 'object')
1103
+ return false;
1104
+ const message = data;
1105
+ return message.protocol === MVT_STUDIO_PROTOCOL && typeof message.type === 'string' && message.type.startsWith('studio:');
1106
+ }
1107
+ export function mvtIsStudioRequest(data) {
1108
+ return mvtIsStudioEvent(data);
1109
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lifeaz/lors-helper",
3
3
  "description": "Lifeaz Online Retail Storefront Helper",
4
- "version": "1.1.0",
4
+ "version": "1.1.2",
5
5
  "main": "dist/main.js",
6
6
  "files": [
7
7
  "dist",
@@ -51,8 +51,8 @@
51
51
  "lifeaz": {
52
52
  "version": {
53
53
  "short": 1,
54
- "full": "1.1.0-b35",
55
- "code": "101000035"
54
+ "full": "1.1.2-b37",
55
+ "code": "101020037"
56
56
  }
57
57
  }
58
58
  }
package/src/main.ts CHANGED
@@ -407,6 +407,14 @@ export const CartSchema = z.object({
407
407
  locale: LangSchema,
408
408
  vatNumber: z.string().nullable(),
409
409
  multiAddressesCallback: z.boolean(),
410
+ /**
411
+ * True for a basket the MVT studio minted so an operator can edit the funnel from inside it.
412
+ *
413
+ * Defaulted rather than required, so a release that predates the column - or any caller that
414
+ * simply does not set it - produces a real cart. The safe value is the one you get by saying
415
+ * nothing.
416
+ */
417
+ simulated: z.boolean().default(false),
410
418
  partnerId: uuidSchema.nullable(),
411
419
  createdAt: dayjsSchema,
412
420
  updatedAt: dayjsSchema,
@@ -696,7 +704,14 @@ export type MvtOperator =
696
704
  | '_Path_Matches_'
697
705
  | '_Has_Cart_'
698
706
  | '_Hour_Of_Day_Between_'
699
- | '_Day_Of_Week_In_';
707
+ | '_Day_Of_Week_In_'
708
+ | '_Query_Param_Matches_'
709
+ | '_Screen_Width_Between_'
710
+ | '_Visits_At_Least_'
711
+ | '_Logged_In_'
712
+ | '_Logged_Out_'
713
+ | '_Is_Weekend_'
714
+ | '_Date_Between_';
700
715
 
701
716
  export const MvtOperatorSchema = z.union([
702
717
  z.literal('_Device_In_'),
@@ -717,6 +732,13 @@ export const MvtOperatorSchema = z.union([
717
732
  z.literal('_Has_Cart_'),
718
733
  z.literal('_Hour_Of_Day_Between_'),
719
734
  z.literal('_Day_Of_Week_In_'),
735
+ z.literal('_Query_Param_Matches_'),
736
+ z.literal('_Screen_Width_Between_'),
737
+ z.literal('_Visits_At_Least_'),
738
+ z.literal('_Logged_In_'),
739
+ z.literal('_Logged_Out_'),
740
+ z.literal('_Is_Weekend_'),
741
+ z.literal('_Date_Between_'),
720
742
  ]);
721
743
 
722
744
  /**
@@ -729,6 +751,9 @@ export const MVT_NULLARY_OPERATORS: readonly MvtOperator[] = [
729
751
  '_Visitor_Is_New_',
730
752
  '_Visitor_Is_Returning_',
731
753
  '_Has_Cart_',
754
+ '_Logged_In_',
755
+ '_Logged_Out_',
756
+ '_Is_Weekend_',
732
757
  ];
733
758
 
734
759
  export type MvtOverrideOp = 'set' | 'merge' | 'remove' | 'reorder' | 'insert' | 'patch';
@@ -764,9 +789,36 @@ export const MvtVariantSchema = z.object({
764
789
  weight: z.number().int().nonnegative(),
765
790
  control: z.boolean(),
766
791
  overrides: z.array(MvtOverrideSchema),
792
+ /**
793
+ * Optional sub-targeting. A variant carrying one stops being a share of the split and becomes
794
+ * a rule: every unit matching it lands here, whatever the weights say. See mvtPickVariant.
795
+ */
796
+ audience: MvtAudienceNodeSchema.nullable().default(null),
797
+ /** Evaluation order of the targeted variants. The first match wins, so this is the tie-break. */
798
+ order: z.number().int().default(0),
799
+ /** Purely cosmetic, so one arm keeps the same colour across the split bar, the studio and the results. */
800
+ color: z.string().nullable().default(null),
801
+ description: z.string().nullable().default(null),
767
802
  });
768
803
  export type MvtVariant = z.infer<typeof MvtVariantSchema>;
769
804
 
805
+ /**
806
+ * How one variant ends up receiving traffic, resolved from the variant set as a whole.
807
+ *
808
+ * `_Targeted_` variants are claimed by their own conditions and take no part in the weighted
809
+ * draw; `_Weighted_` ones share whatever is left. Computed in one place because the operator is
810
+ * shown this and the evaluator obeys it, and the two disagreeing would be the worst outcome.
811
+ */
812
+ export type MvtAllocationMode = '_Targeted_' | '_Weighted_' | '_Unreachable_';
813
+
814
+ export interface MvtAllocationRow {
815
+ key: string;
816
+ mode: MvtAllocationMode;
817
+ weight: number;
818
+ /** Share of the units that reach the weighted draw. Zero for a targeted variant, whose share depends on the audience rather than on a number. */
819
+ sharePct: number;
820
+ }
821
+
770
822
  export const MvtExperimentSchema = z.object({
771
823
  id: uuidSchema,
772
824
  key: z.string().min(1),
@@ -815,6 +867,42 @@ export interface MvtContext {
815
867
  hasCart: boolean;
816
868
  firstSeenAt: number;
817
869
  now: number;
870
+ /** Query string of the landing URL, lowercased keys. Reads as a targeting dimension of its own so an ad link can pin an arm without an UTM convention. */
871
+ query: Record<string, string>;
872
+ /** Viewport width in CSS pixels. Coarser than the device buckets, for the tests where the breakpoint itself is the subject. */
873
+ screenWidth: number;
874
+ /** Sessions this unit has opened, this one included. */
875
+ visits: number;
876
+ loggedIn: boolean;
877
+ }
878
+
879
+ /**
880
+ * Fill in the dimensions an older caller does not provide.
881
+ *
882
+ * The context grew, and a front built against the previous shape must not start failing every
883
+ * leaf that reads a new field. Defaults are chosen so an absent dimension excludes rather than
884
+ * includes: a condition on something the caller cannot observe should not match everybody.
885
+ */
886
+ export function mvtNormalizeContext(context: Partial<MvtContext> & { unitId: string }): MvtContext {
887
+ return {
888
+ device: '_Desktop_',
889
+ lang: 'fr',
890
+ country: null,
891
+ profile: null,
892
+ partner: null,
893
+ seen: {},
894
+ utm: { source: null, medium: null, campaign: null },
895
+ referrer: null,
896
+ path: '/',
897
+ hasCart: false,
898
+ firstSeenAt: Date.now(),
899
+ now: Date.now(),
900
+ query: {},
901
+ screenWidth: 0,
902
+ visits: 1,
903
+ loggedIn: false,
904
+ ...context,
905
+ };
818
906
  }
819
907
 
820
908
  export interface MvtDecision {
@@ -866,22 +954,61 @@ export function mvtIsEligibleForTraffic(experiment: MvtExperiment, unitId: strin
866
954
  * so that the mapping from bucket range to variant depends only on the weights themselves and not
867
955
  * on the order rows happened to come back from the database.
868
956
  */
869
- export function mvtPickVariant(experiment: MvtExperiment, unitId: string): MvtVariant | null {
870
- const variants = [...experiment.variants].sort((a, b) => a.key.localeCompare(b.key));
871
- const total = variants.reduce((sum, v) => sum + Math.max(v.weight, 0), 0);
872
-
873
- if (!variants.length || total <= 0) return null;
957
+ export function mvtPickVariant(experiment: MvtExperiment, unitId: string, context?: MvtContext): MvtVariant | null {
958
+ const targeted = experiment.variants
959
+ .filter(variant => !!variant.audience)
960
+ .sort((a, b) => (a.order ?? 0) - (b.order ?? 0) || a.key.localeCompare(b.key));
961
+
962
+ // Targeted arms are rules, not shares: the first whose own conditions hold claims the unit
963
+ // outright. Evaluated before the draw so that "everyone on mobile sees B" means exactly that
964
+ // rather than "mobile visitors have a better chance of seeing B", which is what a weight
965
+ // nudged by hand would have produced and what an operator would have had to verify by eye.
966
+ if (context)
967
+ for (const variant of targeted)
968
+ if (mvtEvaluateAudience(variant.audience ?? null, context)) return variant;
969
+
970
+ const pool = experiment.variants.filter(variant => !variant.audience).sort((a, b) => a.key.localeCompare(b.key));
971
+ const total = pool.reduce((sum, v) => sum + Math.max(v.weight, 0), 0);
972
+
973
+ // Every arm targeted and none of them matching leaves nobody to fall back on. The unit is
974
+ // left out of the experiment entirely rather than pushed onto an arm whose conditions it
975
+ // failed, which would silently make the targeting a lie.
976
+ if (!pool.length || total <= 0) return null;
874
977
 
875
978
  const target = (mvtBucket(experiment.salt, unitId) / 10000) * total;
876
979
  let cursor = 0;
877
980
 
878
- for (const variant of variants) {
981
+ for (const variant of pool) {
879
982
  cursor += Math.max(variant.weight, 0);
880
983
 
881
984
  if (target < cursor) return variant;
882
985
  }
883
986
 
884
- return variants[variants.length - 1];
987
+ return pool[pool.length - 1];
988
+ }
989
+
990
+ /**
991
+ * How the split actually resolves, for the operator rather than the evaluator.
992
+ *
993
+ * Weights are relative and targeted arms are outside the draw entirely, so the number an operator
994
+ * typed and the share it buys are rarely the same. Computing that here, from the same rules the
995
+ * bucketing obeys, is what lets the interface show a split bar that cannot drift from the truth.
996
+ */
997
+ export function mvtDistribution(variants: readonly MvtVariant[]): MvtAllocationRow[] {
998
+ const pool = variants.filter(variant => !variant.audience);
999
+ const total = pool.reduce((sum, v) => sum + Math.max(v.weight, 0), 0);
1000
+
1001
+ return variants.map(variant => {
1002
+ if (variant.audience) return { key: variant.key, mode: '_Targeted_' as const, weight: variant.weight, sharePct: 0 };
1003
+ if (total <= 0 || variant.weight <= 0) return { key: variant.key, mode: '_Unreachable_' as const, weight: variant.weight, sharePct: 0 };
1004
+
1005
+ return {
1006
+ key: variant.key,
1007
+ mode: '_Weighted_' as const,
1008
+ weight: variant.weight,
1009
+ sharePct: Math.round((Math.max(variant.weight, 0) / total) * 1000) / 10,
1010
+ };
1011
+ });
885
1012
  }
886
1013
 
887
1014
  function mvtMatchesPattern(value: string | null, patterns: string[]): boolean {
@@ -929,6 +1056,47 @@ function mvtEvaluateLeaf(operator: MvtOperator, values: string[], context: MvtCo
929
1056
  return from <= to ? hour >= from && hour <= to : hour >= from || hour <= to;
930
1057
  }
931
1058
  case '_Day_Of_Week_In_': return values.map(Number).includes(new Date(context.now).getDay());
1059
+ case '_Logged_In_': return context.loggedIn;
1060
+ case '_Logged_Out_': return !context.loggedIn;
1061
+ case '_Is_Weekend_': return [0, 6].includes(new Date(context.now).getDay());
1062
+ case '_Visits_At_Least_': return context.visits >= Number(values[0] ?? 1);
1063
+
1064
+ // Written "name=value", or "name" on its own to test for presence. The value side goes
1065
+ // through the same wildcard matcher as the UTM leaves, so utm-like conventions carried in
1066
+ // a bespoke parameter behave the way an operator already expects them to.
1067
+ case '_Query_Param_Matches_': {
1068
+ return values.some(raw => {
1069
+ const separator = raw.indexOf('=');
1070
+ const name = (separator < 0 ? raw : raw.slice(0, separator)).trim().toLowerCase();
1071
+ const expected = separator < 0 ? null : raw.slice(separator + 1);
1072
+ const actual = context.query[name];
1073
+
1074
+ if (actual === undefined) return false;
1075
+ if (expected === null) return true;
1076
+
1077
+ return mvtMatchesPattern(actual, [expected]);
1078
+ });
1079
+ }
1080
+
1081
+ case '_Screen_Width_Between_': {
1082
+ const from = Number(values[0] ?? 0);
1083
+ const to = Number(values[1] ?? Number.MAX_SAFE_INTEGER);
1084
+
1085
+ return context.screenWidth >= from && context.screenWidth <= to;
1086
+ }
1087
+
1088
+ // Bounds are wall-clock dates, and either may be left out for an open-ended window. This
1089
+ // is not the experiment's own schedule: it is for the tests whose point is a date, such
1090
+ // as a variant that only exists over a sale weekend.
1091
+ case '_Date_Between_': {
1092
+ const from = values[0] ? Date.parse(values[0]) : Number.NEGATIVE_INFINITY;
1093
+ const to = values[1] ? Date.parse(values[1]) : Number.POSITIVE_INFINITY;
1094
+
1095
+ if (Number.isNaN(from) || Number.isNaN(to)) return false;
1096
+
1097
+ return context.now >= from && context.now <= to;
1098
+ }
1099
+
932
1100
  default: return false;
933
1101
  }
934
1102
  }
@@ -995,7 +1163,7 @@ export function mvtResolve(config: MvtConfig, context: MvtContext, forced: Recor
995
1163
  if (!mvtEvaluateAudience(experiment.audience, context)) continue;
996
1164
  if (!mvtIsEligibleForTraffic(experiment, context.unitId)) continue;
997
1165
 
998
- const variant = mvtPickVariant(experiment, context.unitId);
1166
+ const variant = mvtPickVariant(experiment, context.unitId, context);
999
1167
 
1000
1168
  if (!variant) continue;
1001
1169
  if (experiment.exclusionGroup) claimed.add(experiment.exclusionGroup);
@@ -1058,9 +1226,62 @@ export interface MvtSlotDefinition {
1058
1226
  schema: z.ZodType<unknown>;
1059
1227
  }
1060
1228
 
1061
- const i18nTextSchema = z.record(LangSchema, z.string());
1229
+ /**
1230
+ * A piece of copy, written in whichever languages the operator filled in.
1231
+ *
1232
+ * Partial on purpose, and it has to be said in the schema rather than left to convention: zod
1233
+ * treats a record keyed by a closed set as exhaustive, so `z.record` here would refuse a French-
1234
+ * only override at write time - which is the normal case, since a language left empty is
1235
+ * documented everywhere as keeping the untouched original rather than blanking it.
1236
+ */
1237
+ const i18nTextSchema = z.partialRecord(LangSchema, z.string());
1062
1238
  const colorSchema = z.string().regex(/^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i);
1063
1239
 
1240
+ /**
1241
+ * What a test may do to one anchored element.
1242
+ *
1243
+ * This is the whole vocabulary of the visual editor, and it is deliberately short. Hide it, move
1244
+ * it, reword it, repoint it, restyle it within a closed set of properties. Nothing here can
1245
+ * inject markup or a script, so an override authored by clicking around a page carries the same
1246
+ * blast radius as one typed into the registry editor, which is what makes the studio safe to
1247
+ * hand to somebody who is not going to read a diff.
1248
+ *
1249
+ * Every field is optional and absence means untouched, so the patches stay small and two editing
1250
+ * sessions on the same element compose instead of overwriting one another.
1251
+ */
1252
+ export const MvtAnchorPatchSchema = z.object({
1253
+ hidden: z.boolean().optional(),
1254
+ /** Position among its siblings. Lower comes first; anchors without one keep their place. */
1255
+ order: z.number().int().min(-999).max(999).optional(),
1256
+ text: i18nTextSchema.optional(),
1257
+ href: z.string().max(2048).optional(),
1258
+ route: z.string().max(512).optional(),
1259
+ image: z.string().max(2048).optional(),
1260
+ style: z.object({
1261
+ background: colorSchema.optional(),
1262
+ color: colorSchema.optional(),
1263
+ borderColor: colorSchema.optional(),
1264
+ borderRadius: z.number().int().min(0).max(96).optional(),
1265
+ fontSize: z.number().int().min(8).max(96).optional(),
1266
+ fontWeight: z.enum(['300', '400', '500', '600', '700', '800']).optional(),
1267
+ align: z.enum(['left', 'center', 'right']).optional(),
1268
+ paddingY: z.number().int().min(0).max(160).optional(),
1269
+ paddingX: z.number().int().min(0).max(160).optional(),
1270
+ }).optional(),
1271
+ });
1272
+ export type MvtAnchorPatch = z.infer<typeof MvtAnchorPatchSchema>;
1273
+
1274
+ const anchorsSchema = z.record(z.string(), MvtAnchorPatchSchema);
1275
+
1276
+ const ANCHOR_FIELDS: readonly MvtSlotField[] = [
1277
+ { key: 'hidden', label: 'Hidden', kind: 'boolean' },
1278
+ { key: 'order', label: 'Position', kind: 'number' },
1279
+ { key: 'text', label: 'Text', kind: 'i18n' },
1280
+ { key: 'href', label: 'External link', kind: 'text' },
1281
+ { key: 'route', label: 'Internal route', kind: 'text' },
1282
+ { key: 'image', label: 'Image', kind: 'image' },
1283
+ ];
1284
+
1064
1285
  function slot(definition: MvtSlotDefinition): MvtSlotDefinition {
1065
1286
  return definition;
1066
1287
  }
@@ -1200,6 +1421,19 @@ export const MVT_SLOTS: readonly MvtSlotDefinition[] = [
1200
1421
  ],
1201
1422
  schema: z.object({ mobile: z.boolean().optional(), tablet: z.boolean().optional(), desktop: z.boolean().optional() }),
1202
1423
  }),
1424
+
1425
+ slot({
1426
+ key: 'storefront.anchors', scope: '_Storefront_', area: 'Studio', label: 'Anchored elements',
1427
+ hint: 'Everything the visual editor writes: elements hidden, moved, reworded or restyled by clicking on the page itself.',
1428
+ kind: 'record', entryKind: 'object', ops: ['merge', 'set'], fields: ANCHOR_FIELDS, itemKey: 'anchor',
1429
+ schema: anchorsSchema,
1430
+ }),
1431
+ slot({
1432
+ key: 'checkout.anchors', scope: '_Checkout_', area: 'Studio', label: 'Anchored elements',
1433
+ hint: 'Everything the visual editor writes: elements hidden, moved, reworded or restyled by clicking on the page itself.',
1434
+ kind: 'record', entryKind: 'object', ops: ['merge', 'set'], fields: ANCHOR_FIELDS, itemKey: 'anchor',
1435
+ schema: anchorsSchema,
1436
+ }),
1203
1437
  ] as const;
1204
1438
 
1205
1439
  const MVT_SLOTS_BY_KEY: ReadonlyMap<string, MvtSlotDefinition> = new Map(MVT_SLOTS.map(s => [s.key, s]));
@@ -1246,7 +1480,18 @@ export function mvtValidateOverrides(overrides: MvtOverride[]): MvtOverrideIssue
1246
1480
  if (override.op === 'remove' || override.op === 'reorder') return;
1247
1481
 
1248
1482
  if (override.op === 'merge' || override.op === 'patch' || override.op === 'insert') {
1249
- if (override.value === undefined) issues.push({ index, slot: override.slot, reason: 'missing_value' });
1483
+ if (override.value === undefined) {
1484
+ issues.push({ index, slot: override.slot, reason: 'missing_value' });
1485
+
1486
+ return;
1487
+ }
1488
+
1489
+ // A merge onto a record is still a record of the same entries, so the full schema
1490
+ // applies and catches a malformed anchor patch here rather than in a customer's
1491
+ // browser. A merge onto a fixed-shape object is a partial by definition, and running
1492
+ // the whole schema over it would refuse every legitimate single-field edit.
1493
+ if (definition.kind === 'record' && !definition.schema.safeParse(override.value).success)
1494
+ issues.push({ index, slot: override.slot, reason: 'invalid_value' });
1250
1495
 
1251
1496
  return;
1252
1497
  }
@@ -1331,3 +1576,213 @@ export function mvtApplyOverride<T>(base: T, override: MvtOverride): T {
1331
1576
  return base;
1332
1577
  }
1333
1578
  }
1579
+
1580
+ // -----------------------------------------------------------------------------
1581
+ // Anchors
1582
+ // -----------------------------------------------------------------------------
1583
+
1584
+ export const MVT_ANCHOR_ATTRIBUTE = 'data-mvt-anchor';
1585
+
1586
+ /**
1587
+ * The anchors slot for one scope.
1588
+ *
1589
+ * Kept as a lookup rather than a naming convention the call sites repeat, because the studio, the
1590
+ * API validator and the two fronts all have to agree on it, and a typo in any of the four would
1591
+ * produce an override that validates and does nothing.
1592
+ */
1593
+ export function mvtAnchorsSlot(scope: MvtScope): string {
1594
+ return scope === '_Checkout_' ? 'checkout.anchors' : 'storefront.anchors';
1595
+ }
1596
+
1597
+ /**
1598
+ * Fold a stack of anchor patches into one.
1599
+ *
1600
+ * Later patches win field by field rather than wholesale: two overrides touching the same element,
1601
+ * one hiding it and one rewording it, both have to survive, or the operator has to remember which
1602
+ * of their own edits cancelled which.
1603
+ */
1604
+ export function mvtMergeAnchorPatch(base: MvtAnchorPatch | undefined, next: MvtAnchorPatch | undefined): MvtAnchorPatch {
1605
+ if (!base) return next ?? {};
1606
+ if (!next) return base;
1607
+
1608
+ return {
1609
+ ...base,
1610
+ ...next,
1611
+ text: next.text || base.text ? { ...(base.text ?? {}), ...(next.text ?? {}) } : undefined,
1612
+ style: next.style || base.style ? { ...(base.style ?? {}), ...(next.style ?? {}) } : undefined,
1613
+ };
1614
+ }
1615
+
1616
+ /**
1617
+ * The inline style an anchor patch asks for, as a plain property bag.
1618
+ *
1619
+ * Only the closed set the patch schema allows can come out of here, which is the point: a front
1620
+ * applying this is not evaluating anything an operator wrote, it is reading a handful of numbers
1621
+ * and colours that have already been validated twice.
1622
+ */
1623
+ export function mvtAnchorStyle(patch: MvtAnchorPatch | null | undefined): Record<string, string> {
1624
+ const style = patch?.style;
1625
+
1626
+ if (!style) return {};
1627
+
1628
+ const out: Record<string, string> = {};
1629
+
1630
+ if (style.background) out['background-color'] = style.background;
1631
+ if (style.color) out['color'] = style.color;
1632
+ if (style.borderColor) out['border-color'] = style.borderColor;
1633
+ if (style.borderRadius !== undefined) out['border-radius'] = `${style.borderRadius}px`;
1634
+ if (style.fontSize !== undefined) out['font-size'] = `${style.fontSize}px`;
1635
+ if (style.fontWeight) out['font-weight'] = style.fontWeight;
1636
+ if (style.align) out['text-align'] = style.align;
1637
+ if (style.paddingY !== undefined) out['padding-block'] = `${style.paddingY}px`;
1638
+ if (style.paddingX !== undefined) out['padding-inline'] = `${style.paddingX}px`;
1639
+
1640
+ return out;
1641
+ }
1642
+
1643
+ // -----------------------------------------------------------------------------
1644
+ // Studio bridge
1645
+ // -----------------------------------------------------------------------------
1646
+
1647
+ /**
1648
+ * The message vocabulary between the Tools studio and the front rendered inside its frame.
1649
+ *
1650
+ * A separate protocol rather than a preview link with more query parameters, because the studio
1651
+ * has to do two things a link cannot: read back what is actually on the page - the anchors, their
1652
+ * labels, their nesting - and apply an edit without a reload, so that changing a colour is a
1653
+ * colour changing rather than a page blinking.
1654
+ *
1655
+ * Every message carries the protocol version. A front and a Tools release drift apart eventually,
1656
+ * and a version mismatch has to degrade to a plain preview rather than to an editor whose clicks
1657
+ * quietly do nothing.
1658
+ */
1659
+ export const MVT_STUDIO_PROTOCOL = 2;
1660
+
1661
+ export type MvtStudioAnchorRole = 'section' | 'cta' | 'text' | 'image' | 'block';
1662
+
1663
+ export interface MvtStudioAnchor {
1664
+ /** Stable identifier written into the markup by the front, never derived from the DOM position. */
1665
+ id: string;
1666
+ label: string;
1667
+ role: MvtStudioAnchorRole;
1668
+ /** The anchor this one sits inside, for the studio's tree. Null at the top level. */
1669
+ parentId: string | null;
1670
+ order: number;
1671
+ /** What the untouched page shows today, so the editor opens on the real copy rather than an empty field. */
1672
+ text: string | null;
1673
+ movable: boolean;
1674
+ hideable: boolean;
1675
+ rect: { top: number; left: number; width: number; height: number };
1676
+ }
1677
+
1678
+ /**
1679
+ * Somewhere the studio can go next.
1680
+ *
1681
+ * The editor used to reach other pages through a free-text path field, which asked an operator to
1682
+ * already know the route they wanted and silently rendered a 404 inside the frame when they were
1683
+ * one character out. The front knows its own routes, so it says what they are.
1684
+ *
1685
+ * `kind` separates what the page happens to link to from what the front declares it can reach.
1686
+ * A storefront only has links; the checkout has steps that exist whether or not the current page
1687
+ * links to them, and an operator editing the payment step should not have to walk the funnel to
1688
+ * get there.
1689
+ */
1690
+ export interface MvtStudioLink {
1691
+ path: string;
1692
+ label: string;
1693
+ kind: 'link' | 'step';
1694
+ /** Steps the cart has not unlocked yet are offered but marked, rather than hidden. */
1695
+ reachable: boolean;
1696
+ }
1697
+
1698
+ /**
1699
+ * The simulated basket the checkout studio runs on.
1700
+ *
1701
+ * Editing the funnel means being inside it, and being inside it means holding a cart. Minting one
1702
+ * by hand through the real onboarding flow every time is what made the checkout scope effectively
1703
+ * uneditable.
1704
+ */
1705
+ export interface MvtStudioCart {
1706
+ reference: string;
1707
+ secret: string;
1708
+ /** Where the simulated cart currently sits, so the studio can offer the steps behind it. */
1709
+ step: string;
1710
+ simulated: true;
1711
+ }
1712
+
1713
+ /** Tools to front. */
1714
+ export type MvtStudioRequest =
1715
+ | { protocol: number; type: 'studio:hello' }
1716
+ | { protocol: number; type: 'studio:scan' }
1717
+ | { protocol: number; type: 'studio:select'; anchorId: string | null }
1718
+ | { protocol: number; type: 'studio:apply'; anchors: Record<string, MvtAnchorPatch>; lang: string }
1719
+ | { protocol: number; type: 'studio:mode'; picking: boolean }
1720
+ | { protocol: number; type: 'studio:navigate'; path: string }
1721
+ | { protocol: number; type: 'studio:links' }
1722
+ | { protocol: number; type: 'studio:cart'; cart: MvtStudioCart };
1723
+
1724
+ /** Front to Tools. */
1725
+ export type MvtStudioEvent =
1726
+ | { protocol: number; type: 'studio:ready'; scope: MvtScope; path: string; langs: string[] }
1727
+ | { protocol: number; type: 'studio:anchors'; anchors: MvtStudioAnchor[]; path: string }
1728
+ | { protocol: number; type: 'studio:picked'; anchor: MvtStudioAnchor }
1729
+ | { protocol: number; type: 'studio:navigated'; path: string }
1730
+ | { protocol: number; type: 'studio:links'; links: MvtStudioLink[]; path: string }
1731
+ | { protocol: number; type: 'studio:cart'; cart: MvtStudioCart | null };
1732
+
1733
+ /**
1734
+ * Collect the navigable links of the page the front is currently showing.
1735
+ *
1736
+ * Shared rather than written twice, because the filtering is where this gets subtle and getting it
1737
+ * wrong in one front and not the other produces a link list that behaves differently depending on
1738
+ * which scope is being edited.
1739
+ *
1740
+ * Only same-origin, non-anchor, non-download links survive. An external link would navigate the
1741
+ * frame off the front entirely, taking the preview token with it and leaving the studio talking to
1742
+ * a page that has never heard of it; an in-page anchor is not a destination.
1743
+ */
1744
+ export function mvtCollectLinks(root: ParentNode, origin: string): MvtStudioLink[] {
1745
+ const seen = new Set<string>();
1746
+ const links: MvtStudioLink[] = [];
1747
+
1748
+ for (const element of Array.from(root.querySelectorAll('a[href]'))) {
1749
+ const anchor = element as HTMLAnchorElement;
1750
+
1751
+ if (anchor.hasAttribute('download') || anchor.target === '_blank') continue;
1752
+
1753
+ let url: URL;
1754
+
1755
+ try {
1756
+ url = new URL(anchor.getAttribute('href') ?? '', origin);
1757
+ } catch {
1758
+ continue;
1759
+ }
1760
+
1761
+ if (url.origin !== origin) continue;
1762
+ if (!url.pathname.startsWith('/')) continue;
1763
+ if (seen.has(url.pathname)) continue;
1764
+
1765
+ seen.add(url.pathname);
1766
+
1767
+ // The visible text, collapsed. An operator picks a destination by the words they can see
1768
+ // on the page, not by its route, and a label carrying the whitespace of a three-line
1769
+ // menu entry is unreadable in a dropdown.
1770
+ const label = (anchor.textContent ?? '').replace(/\s+/g, ' ').trim();
1771
+
1772
+ links.push({ path: url.pathname, label: label || url.pathname, kind: 'link', reachable: true });
1773
+ }
1774
+
1775
+ return links.sort((a, b) => a.label.localeCompare(b.label));
1776
+ }
1777
+
1778
+ export function mvtIsStudioEvent(data: unknown): data is MvtStudioEvent {
1779
+ if (!data || typeof data !== 'object') return false;
1780
+
1781
+ const message = data as Partial<MvtStudioEvent>;
1782
+
1783
+ return message.protocol === MVT_STUDIO_PROTOCOL && typeof message.type === 'string' && message.type.startsWith('studio:');
1784
+ }
1785
+
1786
+ export function mvtIsStudioRequest(data: unknown): data is MvtStudioRequest {
1787
+ return mvtIsStudioEvent(data);
1788
+ }