@altazion/commerce-sdk-core 26.519.8051 → 26.601.8204

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/index.cjs CHANGED
@@ -416,19 +416,128 @@ class SessionModule {
416
416
  return result;
417
417
  }
418
418
  }
419
+ const CART_SUMMARY_KEY = "cart:summary:current";
420
+ const DEFAULT_SUMMARY_STALE_TTL_MS = 9e4;
421
+ const DEFAULT_STORAGE_TTL_MS = 24 * 60 * 6e4;
422
+ class CartSummaryStore {
423
+ constructor(bridge, options) {
424
+ __publicField(this, "summary", null);
425
+ __publicField(this, "staleTtlMs");
426
+ __publicField(this, "storageTtlMs");
427
+ this.bridge = bridge;
428
+ this.staleTtlMs = (options == null ? void 0 : options.staleTtlMs) ?? DEFAULT_SUMMARY_STALE_TTL_MS;
429
+ this.storageTtlMs = (options == null ? void 0 : options.storageTtlMs) ?? DEFAULT_STORAGE_TTL_MS;
430
+ }
431
+ peek() {
432
+ return this.summary;
433
+ }
434
+ async get() {
435
+ if (this.summary !== null) {
436
+ return this.summary;
437
+ }
438
+ this.summary = await this.bridge.get(CART_SUMMARY_KEY);
439
+ return this.summary;
440
+ }
441
+ isStale(summary) {
442
+ if (summary === null) {
443
+ return true;
444
+ }
445
+ return Date.now() >= Date.parse(summary.staleAt);
446
+ }
447
+ async setFromCart(cart) {
448
+ const now = Date.now();
449
+ const summary = buildCartSummarySnapshot(cart, now, this.staleTtlMs);
450
+ this.summary = summary;
451
+ await this.bridge.set(CART_SUMMARY_KEY, summary, this.storageTtlMs);
452
+ return summary;
453
+ }
454
+ async clear() {
455
+ this.summary = null;
456
+ await this.bridge.invalidate("^cart:summary:current$");
457
+ }
458
+ }
459
+ function buildCartSummarySnapshot(cart, now, staleTtlMs) {
460
+ const content = cart.content ?? [];
461
+ const topLevelLines = content.flatMap((entry) => getMainLines(entry));
462
+ return {
463
+ cartGuid: cart.guid,
464
+ sourceCartLastModifiedDate: cart.lastModifiedDate,
465
+ cachedAt: new Date(now).toISOString(),
466
+ staleAt: new Date(now + staleTtlMs).toISOString(),
467
+ totalAmountWithTax: cart.totalAmountWithTax,
468
+ totalQuantity: cart.totalQuantity,
469
+ mainReferencesCount: countDistinctReferences(topLevelLines),
470
+ mainQuantity: sumQuantities(topLevelLines),
471
+ contents: content.map((entry) => buildContentSummary(entry))
472
+ };
473
+ }
474
+ function buildContentSummary(content) {
475
+ const mainLines = getMainLines(content);
476
+ return {
477
+ contentType: content.contentType,
478
+ totalAmountWithTax: content.totalAmountWithTax,
479
+ mainReferencesCount: countDistinctReferences(mainLines),
480
+ mainLinesCount: mainLines.length,
481
+ mainQuantity: sumQuantities(mainLines)
482
+ };
483
+ }
484
+ function getMainLines(content) {
485
+ return (content.lines ?? []).filter((line) => !line.parentLineId);
486
+ }
487
+ function countDistinctReferences(lines) {
488
+ var _a;
489
+ const keys = /* @__PURE__ */ new Set();
490
+ for (const line of lines) {
491
+ const key = ((_a = line.reference) == null ? void 0 : _a.trim()) || line.productGuid;
492
+ if (key) {
493
+ keys.add(key);
494
+ }
495
+ }
496
+ return keys.size;
497
+ }
498
+ function sumQuantities(lines) {
499
+ return lines.reduce((total, line) => total + line.quantity, 0);
500
+ }
419
501
  class CartModule {
420
- constructor(http, cache, connectivity) {
502
+ constructor(http, cache, connectivity, bridge) {
503
+ __publicField(this, "summaryStore");
421
504
  this.http = http;
422
505
  this.cache = cache;
423
506
  this.connectivity = connectivity;
507
+ this.summaryStore = new CartSummaryStore(bridge);
424
508
  }
425
509
  /** Récupère le panier en cours */
426
- getCart() {
427
- return this.cache.execute(
510
+ async getCart() {
511
+ const cart = await this.cache.execute(
428
512
  "cart:current",
429
513
  () => this.http.get("/commerce/api/process/cart"),
430
514
  "network-first"
431
515
  );
516
+ await this.summaryStore.setFromCart(cart);
517
+ return cart;
518
+ }
519
+ /** Retourne le dernier résumé panier disponible sans forcer un accès réseau */
520
+ peekSummary() {
521
+ return this.summaryStore.peek();
522
+ }
523
+ /** Retourne le résumé panier local et lance une revalidation lazy si nécessaire */
524
+ async getSummary() {
525
+ const summary = await this.summaryStore.get();
526
+ if (summary !== null) {
527
+ if (this.summaryStore.isStale(summary) && !this.connectivity.isOffline) {
528
+ void this.refreshSummary();
529
+ }
530
+ return summary;
531
+ }
532
+ if (this.connectivity.isOffline) {
533
+ return null;
534
+ }
535
+ return this.refreshSummary();
536
+ }
537
+ /** Force le rechargement du panier puis du résumé local */
538
+ async refreshSummary() {
539
+ const cart = await this.getCart();
540
+ return this.summaryStore.setFromCart(cart);
432
541
  }
433
542
  /** Récupère le statut de validation du panier */
434
543
  getValidationStatus() {
@@ -440,6 +549,7 @@ class CartModule {
440
549
  const body = { reference, quantity, ...options };
441
550
  const cart = await this.http.post("/commerce/api/process/cart/items", body);
442
551
  await this.cache.execute("cart:current", () => Promise.resolve(cart), "network-first");
552
+ await this.summaryStore.setFromCart(cart);
443
553
  return cart;
444
554
  }
445
555
  /** Met à jour la quantité d'une ligne */
@@ -448,6 +558,7 @@ class CartModule {
448
558
  const body = { quantity };
449
559
  const cart = await this.http.put(`/commerce/api/process/cart/items/${lineId}`, body);
450
560
  await this.cache.execute("cart:current", () => Promise.resolve(cart), "network-first");
561
+ await this.summaryStore.setFromCart(cart);
451
562
  return cart;
452
563
  }
453
564
  /** Supprime une ligne du panier */
@@ -455,6 +566,7 @@ class CartModule {
455
566
  this.ensureOnline();
456
567
  const cart = await this.http.delete(`/commerce/api/process/cart/items/${lineId}`);
457
568
  await this.cache.execute("cart:current", () => Promise.resolve(cart), "network-first");
569
+ await this.summaryStore.setFromCart(cart);
458
570
  return cart;
459
571
  }
460
572
  /** Applique un coupon */
@@ -462,6 +574,7 @@ class CartModule {
462
574
  this.ensureOnline();
463
575
  const cart = await this.http.post("/commerce/api/process/cart/coupons", { code });
464
576
  await this.cache.execute("cart:current", () => Promise.resolve(cart), "network-first");
577
+ await this.summaryStore.setFromCart(cart);
465
578
  return cart;
466
579
  }
467
580
  /** Retire un coupon */
@@ -469,6 +582,7 @@ class CartModule {
469
582
  this.ensureOnline();
470
583
  const cart = await this.http.delete(`/commerce/api/process/cart/coupons/${encodeURIComponent(code)}`);
471
584
  await this.cache.execute("cart:current", () => Promise.resolve(cart), "network-first");
585
+ await this.summaryStore.setFromCart(cart);
472
586
  return cart;
473
587
  }
474
588
  ensureOnline() {
@@ -627,6 +741,734 @@ class StoresModule {
627
741
  );
628
742
  }
629
743
  }
744
+ class DeviceNotification {
745
+ constructor() {
746
+ __publicField(this, "kind");
747
+ __publicField(this, "associatedDevice");
748
+ __publicField(this, "jsonData");
749
+ __publicField(this, "rawData");
750
+ }
751
+ getData() {
752
+ return decodeNotificationData(this.rawData ?? this.jsonData);
753
+ }
754
+ getRecordData() {
755
+ return asRecord(this.getData());
756
+ }
757
+ getNormalizedPayload() {
758
+ const raw = this.getRecordData();
759
+ if (!raw) {
760
+ return null;
761
+ }
762
+ return normalizeDevicePayload(raw, this.associatedDevice);
763
+ }
764
+ }
765
+ class PeripheralBase {
766
+ constructor() {
767
+ __publicField(this, "name", "");
768
+ __publicField(this, "guid", "");
769
+ __publicField(this, "type", "");
770
+ __publicField(this, "state", null);
771
+ }
772
+ isAvailable() {
773
+ if (this.state == null) {
774
+ return true;
775
+ }
776
+ switch (this.state.toLowerCase()) {
777
+ case "available":
778
+ case "active":
779
+ return true;
780
+ default:
781
+ return false;
782
+ }
783
+ }
784
+ IsAvailable() {
785
+ return this.isAvailable();
786
+ }
787
+ }
788
+ class PeripheralBarCode extends PeripheralBase {
789
+ constructor() {
790
+ super(...arguments);
791
+ __publicField(this, "globalListener");
792
+ __publicField(this, "successListener");
793
+ __publicField(this, "failureListener");
794
+ }
795
+ on(callback) {
796
+ this.globalListener = callback;
797
+ }
798
+ onSuccess(callback) {
799
+ this.successListener = callback;
800
+ }
801
+ onError(callback) {
802
+ this.failureListener = callback;
803
+ }
804
+ dispatchNotification(notification) {
805
+ var _a;
806
+ (_a = this.globalListener) == null ? void 0 : _a.call(this, notification);
807
+ }
808
+ dispatchSuccess(type, orderGuid, notification) {
809
+ var _a;
810
+ (_a = this.successListener) == null ? void 0 : _a.call(this, type, orderGuid, notification);
811
+ }
812
+ dispatchFailure(type, orderGuid, notification) {
813
+ var _a;
814
+ (_a = this.failureListener) == null ? void 0 : _a.call(this, type, orderGuid, notification);
815
+ }
816
+ }
817
+ class PeripheralTpe extends PeripheralBase {
818
+ constructor() {
819
+ super(...arguments);
820
+ __publicField(this, "globalListener");
821
+ __publicField(this, "successListener");
822
+ __publicField(this, "failureListener");
823
+ }
824
+ on(callback) {
825
+ this.globalListener = callback;
826
+ }
827
+ onSuccess(callback) {
828
+ this.successListener = callback;
829
+ }
830
+ onFailure(callback) {
831
+ this.failureListener = callback;
832
+ }
833
+ onError(callback) {
834
+ this.failureListener = callback;
835
+ }
836
+ dispatchNotification(notification) {
837
+ var _a;
838
+ (_a = this.globalListener) == null ? void 0 : _a.call(this, notification);
839
+ }
840
+ dispatchSuccess(type, orderGuid, notification) {
841
+ var _a;
842
+ (_a = this.successListener) == null ? void 0 : _a.call(this, type, orderGuid, notification);
843
+ }
844
+ dispatchFailure(type, orderGuid, notification) {
845
+ var _a;
846
+ (_a = this.failureListener) == null ? void 0 : _a.call(this, type, orderGuid, notification);
847
+ }
848
+ }
849
+ class DeviceManager {
850
+ constructor() {
851
+ __publicField(this, "initialized", false);
852
+ __publicField(this, "globalListener");
853
+ __publicField(this, "peripherals", []);
854
+ __publicField(this, "host");
855
+ __publicField(this, "hostListener", (event) => {
856
+ const notification = this.normalizeNotification(event.data);
857
+ if (notification) {
858
+ this.notify(notification);
859
+ }
860
+ });
861
+ var _a;
862
+ this.host = this.resolveHost();
863
+ (_a = this.host) == null ? void 0 : _a.addEventListener("message", this.hostListener);
864
+ }
865
+ get isHostAvailable() {
866
+ return this.host !== null;
867
+ }
868
+ registerGlobalCallback(callback) {
869
+ if (!this.initialized) {
870
+ this.initialize();
871
+ }
872
+ this.globalListener = callback;
873
+ }
874
+ initialize(mockMode = false) {
875
+ var _a;
876
+ if (!mockMode && !this.isHostAvailable) {
877
+ return;
878
+ }
879
+ this.initialized = true;
880
+ this.peripherals = [];
881
+ if (mockMode) {
882
+ const mockTpe = new DeviceTpeMock((notification) => this.notify(notification));
883
+ mockTpe.guid = "86602b7f-3d17-4715-9b5f-7109f4fe92f4";
884
+ mockTpe.name = "MockTPE";
885
+ mockTpe.type = "TPE";
886
+ this.peripherals.push(mockTpe);
887
+ return;
888
+ }
889
+ (_a = this.host) == null ? void 0 : _a.postMessage({
890
+ kind: "DeviceManager.Init"
891
+ });
892
+ }
893
+ init(mockMode = false) {
894
+ this.initialize(mockMode);
895
+ }
896
+ dispose() {
897
+ var _a;
898
+ (_a = this.host) == null ? void 0 : _a.removeEventListener("message", this.hostListener);
899
+ }
900
+ findPeripheral(guid) {
901
+ if (!this.initialized) {
902
+ this.initialize();
903
+ }
904
+ for (const peripheral of this.peripherals) {
905
+ if (peripheral.guid === guid) {
906
+ return peripheral;
907
+ }
908
+ }
909
+ return null;
910
+ }
911
+ findPeripheralByType(type) {
912
+ if (!this.initialized) {
913
+ this.initialize();
914
+ }
915
+ return this.peripherals.filter((peripheral) => peripheral.type.toLowerCase() === type.toLowerCase());
916
+ }
917
+ findPeripheralsByType(type) {
918
+ return this.findPeripheralByType(type);
919
+ }
920
+ notify(notification) {
921
+ var _a, _b, _c;
922
+ if (notification.kind.trim().length === 0) {
923
+ return;
924
+ }
925
+ const kind = notification.kind.toLowerCase();
926
+ switch (kind) {
927
+ case "status_update": {
928
+ const device = notification.associatedDevice ? this.findPeripheral(notification.associatedDevice) : null;
929
+ const status = this.readStatus(notification);
930
+ if (device && status) {
931
+ device.state = status;
932
+ }
933
+ (_a = this.globalListener) == null ? void 0 : _a.call(this, notification);
934
+ break;
935
+ }
936
+ case "init": {
937
+ this.initialized = true;
938
+ this.peripherals = this.createPeripherals(resolveDeviceDescriptors(notification.getData()));
939
+ (_b = this.globalListener) == null ? void 0 : _b.call(this, notification);
940
+ return;
941
+ }
942
+ default:
943
+ (_c = this.globalListener) == null ? void 0 : _c.call(this, notification);
944
+ break;
945
+ }
946
+ if (kind.startsWith("tpe:") || kind.startsWith("barcode:")) {
947
+ this.dispatchPeripheralNotification(notification, kind);
948
+ }
949
+ }
950
+ changeShellState(newState) {
951
+ var _a;
952
+ (_a = this.host) == null ? void 0 : _a.postMessage({
953
+ kind: "shell.state-change",
954
+ data: {
955
+ desiredState: newState
956
+ }
957
+ });
958
+ }
959
+ sendAppStatusUpdate(currentApp, currentStatus, value = null) {
960
+ var _a;
961
+ (_a = this.host) == null ? void 0 : _a.postMessage({
962
+ kind: "app.status-update",
963
+ data: {
964
+ app: currentApp,
965
+ status: currentStatus,
966
+ value
967
+ }
968
+ });
969
+ }
970
+ resolveHost() {
971
+ var _a;
972
+ if (typeof window === "undefined") {
973
+ return null;
974
+ }
975
+ return ((_a = window.chrome) == null ? void 0 : _a.webview) ?? null;
976
+ }
977
+ normalizeNotification(data) {
978
+ if (data instanceof DeviceNotification) {
979
+ if (data.rawData === void 0 && data.jsonData !== void 0) {
980
+ data.rawData = data.jsonData;
981
+ }
982
+ return data;
983
+ }
984
+ const candidate = resolveNotificationRecord(data);
985
+ if (!candidate) {
986
+ return null;
987
+ }
988
+ const kind = normalizeNotificationKind(readStringValue(candidate, ["kind", "Kind", "eventKind", "notificationKind", "type", "Type"]));
989
+ if (!kind) {
990
+ return null;
991
+ }
992
+ const notification = new DeviceNotification();
993
+ const payload = resolveNotificationPayload(candidate);
994
+ notification.kind = kind;
995
+ notification.associatedDevice = readStringValue(candidate, [
996
+ "associatedDevice",
997
+ "AssociatedDevice",
998
+ "associatedDeviceGuid",
999
+ "AssociatedDeviceGuid",
1000
+ "deviceGuid",
1001
+ "DeviceGuid",
1002
+ "deviceId",
1003
+ "DeviceId",
1004
+ "peripheralGuid",
1005
+ "PeripheralGuid"
1006
+ ]) ?? readAssociatedDeviceValue(payload) ?? void 0;
1007
+ notification.rawData = payload;
1008
+ notification.jsonData = encodeNotificationData(payload);
1009
+ return notification;
1010
+ }
1011
+ createPeripherals(devices) {
1012
+ const peripherals = [];
1013
+ for (const device of devices) {
1014
+ const peripheral = this.createPeripheral(device);
1015
+ if (peripheral) {
1016
+ peripherals.push(peripheral);
1017
+ }
1018
+ }
1019
+ return peripherals;
1020
+ }
1021
+ createPeripheral(device) {
1022
+ var _a;
1023
+ const type = (_a = readStringValue(device, ["type", "kind", "deviceKind"])) == null ? void 0 : _a.toLowerCase();
1024
+ let peripheral;
1025
+ switch (type) {
1026
+ case "tpe":
1027
+ peripheral = new DeviceTpeShell(
1028
+ (notification) => this.notify(notification),
1029
+ (message) => {
1030
+ var _a2;
1031
+ return (_a2 = this.host) == null ? void 0 : _a2.postMessage(message);
1032
+ }
1033
+ );
1034
+ break;
1035
+ case "barcodescanner":
1036
+ case "barcode":
1037
+ peripheral = new DeviceBarCodeShell();
1038
+ break;
1039
+ default:
1040
+ peripheral = new PeripheralBase();
1041
+ break;
1042
+ }
1043
+ peripheral.guid = readStringValue(device, ["guid", "deviceGuid", "id"]) ?? "";
1044
+ peripheral.name = readStringValue(device, ["name", "deviceName", "label"]) ?? "";
1045
+ peripheral.type = readStringValue(device, ["type", "kind", "deviceKind"]) ?? "";
1046
+ peripheral.state = readStringValue(device, ["state", "status"]) ?? null;
1047
+ return peripheral;
1048
+ }
1049
+ readStatus(notification) {
1050
+ var _a;
1051
+ return ((_a = notification.getNormalizedPayload()) == null ? void 0 : _a.status) ?? null;
1052
+ }
1053
+ dispatchPeripheralNotification(notification, kind) {
1054
+ var _a;
1055
+ if (!notification.associatedDevice) {
1056
+ return;
1057
+ }
1058
+ const device = this.findPeripheral(notification.associatedDevice);
1059
+ if (!device) {
1060
+ return;
1061
+ }
1062
+ const orderGuid = ((_a = notification.getNormalizedPayload()) == null ? void 0 : _a.orderGuid) ?? "";
1063
+ if (device instanceof PeripheralTpe) {
1064
+ switch (kind) {
1065
+ case "tpe:payment-success":
1066
+ device.dispatchSuccess("payment", orderGuid, notification);
1067
+ break;
1068
+ case "tpe:payment-failure":
1069
+ device.dispatchFailure("payment", orderGuid, notification);
1070
+ break;
1071
+ case "tpe:refund-success":
1072
+ device.dispatchSuccess("refund", orderGuid, notification);
1073
+ break;
1074
+ case "tpe:refund-failure":
1075
+ device.dispatchFailure("refund", orderGuid, notification);
1076
+ break;
1077
+ }
1078
+ device.dispatchNotification(notification);
1079
+ return;
1080
+ }
1081
+ if (device instanceof PeripheralBarCode) {
1082
+ switch (kind) {
1083
+ case "barcode:scan":
1084
+ device.dispatchSuccess("scan", orderGuid, notification);
1085
+ break;
1086
+ case "barcode:error":
1087
+ device.dispatchFailure("scan", orderGuid, notification);
1088
+ break;
1089
+ }
1090
+ device.dispatchNotification(notification);
1091
+ }
1092
+ }
1093
+ }
1094
+ function decodeNotificationData(value) {
1095
+ const decoded = unwrapSerializedData(value);
1096
+ return decoded == null ? null : decoded;
1097
+ }
1098
+ function unwrapSerializedData(value) {
1099
+ let current = value;
1100
+ for (let index = 0; index < 3; index += 1) {
1101
+ if (current == null) {
1102
+ return null;
1103
+ }
1104
+ if (typeof current !== "string") {
1105
+ return current;
1106
+ }
1107
+ const trimmed = current.trim();
1108
+ if (trimmed.length === 0) {
1109
+ return null;
1110
+ }
1111
+ try {
1112
+ current = JSON.parse(trimmed);
1113
+ continue;
1114
+ } catch {
1115
+ return current;
1116
+ }
1117
+ }
1118
+ return current;
1119
+ }
1120
+ function encodeNotificationData(value) {
1121
+ if (value == null) {
1122
+ return void 0;
1123
+ }
1124
+ if (typeof value === "string") {
1125
+ return value;
1126
+ }
1127
+ try {
1128
+ return JSON.stringify(value);
1129
+ } catch {
1130
+ return void 0;
1131
+ }
1132
+ }
1133
+ function resolveNotificationRecord(data) {
1134
+ let current = asRecord(data);
1135
+ for (let depth = 0; depth < 4 && current; depth += 1) {
1136
+ if (readStringValue(current, ["kind", "Kind", "eventKind", "notificationKind", "type", "Type"])) {
1137
+ return current;
1138
+ }
1139
+ const nested = firstRecord(current, ["message", "notification", "event", "payload", "data", "Data"]);
1140
+ if (!nested) {
1141
+ return null;
1142
+ }
1143
+ current = nested;
1144
+ }
1145
+ return null;
1146
+ }
1147
+ function resolveNotificationPayload(notification) {
1148
+ for (const key of ["jsonData", "JsonData", "payload", "Payload", "json", "Json", "data", "Data"]) {
1149
+ if (!(key in notification)) {
1150
+ continue;
1151
+ }
1152
+ const value = notification[key];
1153
+ if (typeof value === "string" || Array.isArray(value)) {
1154
+ return value;
1155
+ }
1156
+ const nested = asRecord(value);
1157
+ if (nested && !readStringValue(nested, ["kind", "Kind", "eventKind", "notificationKind", "type", "Type"])) {
1158
+ return value;
1159
+ }
1160
+ }
1161
+ return void 0;
1162
+ }
1163
+ function normalizeNotificationKind(value) {
1164
+ if (!value) {
1165
+ return null;
1166
+ }
1167
+ const normalized = value.trim().toLowerCase().replace(/\s+/g, "");
1168
+ const unified = normalized.replace(/[.\/]+/g, ":").replace(/_/g, "-");
1169
+ switch (unified) {
1170
+ case "init":
1171
+ case "devicemanager:init":
1172
+ case "device-manager:init":
1173
+ return "init";
1174
+ case "status-update":
1175
+ case "statusupdate":
1176
+ return "status_update";
1177
+ default:
1178
+ if (unified.startsWith("tpe-")) {
1179
+ return `tpe:${unified.slice("tpe-".length)}`;
1180
+ }
1181
+ if (unified.startsWith("barcode-")) {
1182
+ return `barcode:${unified.slice("barcode-".length)}`;
1183
+ }
1184
+ return unified;
1185
+ }
1186
+ }
1187
+ function firstRecord(source, keys) {
1188
+ for (const key of keys) {
1189
+ const value = source[key];
1190
+ const record = asRecord(value);
1191
+ if (record) {
1192
+ return record;
1193
+ }
1194
+ }
1195
+ return null;
1196
+ }
1197
+ function asRecord(value) {
1198
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
1199
+ return null;
1200
+ }
1201
+ return value;
1202
+ }
1203
+ function readStringValue(source, keys) {
1204
+ const record = source;
1205
+ for (const key of keys) {
1206
+ const value = record[key];
1207
+ if (typeof value === "string") {
1208
+ const trimmed = value.trim();
1209
+ if (trimmed.length > 0) {
1210
+ return trimmed;
1211
+ }
1212
+ }
1213
+ }
1214
+ return null;
1215
+ }
1216
+ function resolveDeviceDescriptors(payload) {
1217
+ if (Array.isArray(payload)) {
1218
+ return payload.filter((entry) => asRecord(entry) !== null);
1219
+ }
1220
+ const record = asRecord(payload);
1221
+ if (!record) {
1222
+ return [];
1223
+ }
1224
+ for (const key of ["devices", "Devices", "peripherals", "Peripherals", "data", "Data"]) {
1225
+ const value = record[key];
1226
+ if (Array.isArray(value)) {
1227
+ return value.filter((entry) => asRecord(entry) !== null);
1228
+ }
1229
+ const nested = asRecord(value);
1230
+ if (nested) {
1231
+ const nestedDevices = resolveDeviceDescriptors(nested);
1232
+ if (nestedDevices.length > 0) {
1233
+ return nestedDevices;
1234
+ }
1235
+ }
1236
+ }
1237
+ return [];
1238
+ }
1239
+ function readAssociatedDeviceValue(payload) {
1240
+ const record = asRecord(payload);
1241
+ if (!record) {
1242
+ return null;
1243
+ }
1244
+ const direct = readStringValue(record, [
1245
+ "associatedDevice",
1246
+ "AssociatedDevice",
1247
+ "associatedDeviceGuid",
1248
+ "AssociatedDeviceGuid",
1249
+ "deviceGuid",
1250
+ "DeviceGuid",
1251
+ "deviceId",
1252
+ "DeviceId",
1253
+ "peripheralGuid",
1254
+ "PeripheralGuid"
1255
+ ]);
1256
+ if (direct) {
1257
+ return direct;
1258
+ }
1259
+ for (const key of ["data", "Data", "payload", "Payload"]) {
1260
+ const nested = asRecord(record[key]);
1261
+ if (!nested) {
1262
+ continue;
1263
+ }
1264
+ const nestedDevice = readAssociatedDeviceValue(nested);
1265
+ if (nestedDevice) {
1266
+ return nestedDevice;
1267
+ }
1268
+ }
1269
+ return null;
1270
+ }
1271
+ function normalizeDevicePayload(record, associatedDevice) {
1272
+ return {
1273
+ associatedDevice: associatedDevice ?? readAssociatedDeviceValue(record) ?? void 0,
1274
+ status: readStringValueDeep(record, ["status", "Status", "state", "State"]) ?? void 0,
1275
+ orderGuid: readStringValueDeep(record, ["orderGuid", "OrderGuid", "orderGUID", "orderId", "OrderId"]) ?? void 0,
1276
+ orderNumber: readStringValueDeep(record, ["orderNumber", "OrderNumber", "reference", "Reference"]) ?? void 0,
1277
+ mrgGuid: readStringValueDeep(record, ["mrgGuid", "MrgGuid", "mrgId", "MrgId"]) ?? void 0,
1278
+ amount: readNumberValueDeep(record, ["amount", "Amount", "totalAmount", "TotalAmount"]) ?? void 0,
1279
+ currency: readStringValueDeep(record, ["currency", "Currency", "currencyCode", "CurrencyCode"]) ?? void 0,
1280
+ reasonCode: readStringValueDeep(record, ["reasonCode", "ReasonCode", "code", "Code"]) ?? void 0,
1281
+ reasonMessage: readStringValueDeep(record, ["reasonMessage", "ReasonMessage", "message", "Message"]) ?? void 0,
1282
+ transactionId: readStringValueDeep(record, ["transactionId", "TransactionId", "transactionNumber", "TransactionNumber"]) ?? void 0,
1283
+ barcode: readStringValueDeep(record, ["barcode", "Barcode", "value", "Value", "scanValue", "ScanValue"]) ?? void 0,
1284
+ symbology: readStringValueDeep(record, ["symbology", "Symbology", "barcodeType", "BarcodeType"]) ?? void 0,
1285
+ raw: record
1286
+ };
1287
+ }
1288
+ function readStringValueDeep(source, keys) {
1289
+ const direct = readStringValue(source, keys);
1290
+ if (direct) {
1291
+ return direct;
1292
+ }
1293
+ for (const key of ["data", "Data", "payload", "Payload", "result", "Result"]) {
1294
+ const nested = asRecord(source[key]);
1295
+ if (!nested) {
1296
+ continue;
1297
+ }
1298
+ const nestedValue = readStringValueDeep(nested, keys);
1299
+ if (nestedValue) {
1300
+ return nestedValue;
1301
+ }
1302
+ }
1303
+ return null;
1304
+ }
1305
+ function readNumberValueDeep(source, keys) {
1306
+ const direct = readNumberValue(source, keys);
1307
+ if (direct !== null) {
1308
+ return direct;
1309
+ }
1310
+ for (const key of ["data", "Data", "payload", "Payload", "result", "Result"]) {
1311
+ const nested = asRecord(source[key]);
1312
+ if (!nested) {
1313
+ continue;
1314
+ }
1315
+ const nestedValue = readNumberValueDeep(nested, keys);
1316
+ if (nestedValue !== null) {
1317
+ return nestedValue;
1318
+ }
1319
+ }
1320
+ return null;
1321
+ }
1322
+ function readNumberValue(source, keys) {
1323
+ for (const key of keys) {
1324
+ const value = source[key];
1325
+ if (typeof value === "number" && Number.isFinite(value)) {
1326
+ return value;
1327
+ }
1328
+ if (typeof value === "string") {
1329
+ const parsed = Number(value.trim());
1330
+ if (Number.isFinite(parsed)) {
1331
+ return parsed;
1332
+ }
1333
+ }
1334
+ }
1335
+ return null;
1336
+ }
1337
+ class DeviceTpeMock extends PeripheralTpe {
1338
+ constructor(emitNotification) {
1339
+ super();
1340
+ __publicField(this, "cancelled", false);
1341
+ this.emitNotification = emitNotification;
1342
+ }
1343
+ makePayment(orderGuid, orderNumber, mrgGuid, amount, currency) {
1344
+ this.cancelled = false;
1345
+ this.schedule(200, () => this.createNotification("TPE:Progress", {
1346
+ orderGuid,
1347
+ orderNumber,
1348
+ mrgGuid,
1349
+ amount,
1350
+ currency,
1351
+ reasonCode: "START",
1352
+ reasonMessage: "Veuillez suivre les instructions sur le terminal de paiement"
1353
+ }));
1354
+ this.schedule(2500, () => this.createNotification("TPE:Progress", {
1355
+ orderGuid,
1356
+ orderNumber,
1357
+ mrgGuid,
1358
+ amount,
1359
+ currency,
1360
+ reasonCode: "PINCODE",
1361
+ reasonMessage: "Saisie du pin-code en attente"
1362
+ }));
1363
+ if (orderNumber.startsWith("F")) {
1364
+ this.schedule(7500, () => this.createNotification("TPE:Payment-Failure", {
1365
+ orderGuid,
1366
+ orderNumber,
1367
+ mrgGuid,
1368
+ amount,
1369
+ currency,
1370
+ reasonCode: "FAKE",
1371
+ reasonMessage: "Votre paiement n'a pas pu être traité"
1372
+ }));
1373
+ return;
1374
+ }
1375
+ this.schedule(7500, () => this.createNotification("TPE:Payment-Success", {
1376
+ orderGuid,
1377
+ orderNumber,
1378
+ mrgGuid,
1379
+ amount,
1380
+ currency,
1381
+ transactionId: "FakeTransactionNumber",
1382
+ reasonCode: "FAKE",
1383
+ reasonMessage: "Paiement terminé"
1384
+ }));
1385
+ }
1386
+ makeRefund(orderGuid, orderNumber, mrgGuid, amount, currency) {
1387
+ this.cancelled = false;
1388
+ this.schedule(2500, () => this.createNotification("TPE:Refund-Failure", {
1389
+ orderGuid,
1390
+ orderNumber,
1391
+ mrgGuid,
1392
+ amount,
1393
+ currency,
1394
+ reasonCode: "FAKE",
1395
+ reasonMessage: "Votre paiement n'a pas pu être remboursé : nous sommes en mode mock"
1396
+ }));
1397
+ }
1398
+ cancelPendingPayment() {
1399
+ this.cancelled = true;
1400
+ this.schedule(2500, () => this.createNotification("TPE:Payment-Failure", {
1401
+ reasonCode: "CANCEL",
1402
+ reasonMessage: "Paiement annulé"
1403
+ }));
1404
+ }
1405
+ schedule(delay2, factory) {
1406
+ setTimeout(() => {
1407
+ if (!this.cancelled) {
1408
+ this.emitNotification(factory());
1409
+ }
1410
+ }, delay2);
1411
+ }
1412
+ createNotification(kind, payload) {
1413
+ const notification = new DeviceNotification();
1414
+ notification.kind = kind;
1415
+ notification.associatedDevice = this.guid;
1416
+ notification.jsonData = JSON.stringify(payload);
1417
+ return notification;
1418
+ }
1419
+ }
1420
+ class DeviceTpeShell extends PeripheralTpe {
1421
+ constructor(emitNotification, postMessage) {
1422
+ super();
1423
+ this.emitNotification = emitNotification;
1424
+ this.postMessage = postMessage;
1425
+ }
1426
+ setState(state) {
1427
+ const notification = new DeviceNotification();
1428
+ notification.kind = "STATUS_UPDATE";
1429
+ notification.associatedDevice = this.guid;
1430
+ notification.jsonData = JSON.stringify({ status: state });
1431
+ this.emitNotification(notification);
1432
+ }
1433
+ makePayment(orderGuid, orderNumber, mrgGuid, amount, currency) {
1434
+ this.postMessage({
1435
+ deviceKind: "TPE",
1436
+ deviceGuid: this.guid,
1437
+ kind: "payment-request",
1438
+ data: {
1439
+ orderGuid,
1440
+ orderNumber,
1441
+ mrgGuid,
1442
+ amount,
1443
+ currency
1444
+ }
1445
+ });
1446
+ }
1447
+ makeRefund(orderGuid, orderNumber, mrgGuid, amount, currency) {
1448
+ this.postMessage({
1449
+ deviceKind: "TPE",
1450
+ deviceGuid: this.guid,
1451
+ kind: "refund-request",
1452
+ data: {
1453
+ orderGuid,
1454
+ orderNumber,
1455
+ mrgGuid,
1456
+ amount,
1457
+ currency
1458
+ }
1459
+ });
1460
+ }
1461
+ cancelPendingPayment() {
1462
+ this.postMessage({
1463
+ deviceKind: "TPE",
1464
+ deviceGuid: this.guid,
1465
+ kind: "payment-request-cancel",
1466
+ data: {}
1467
+ });
1468
+ }
1469
+ }
1470
+ class DeviceBarCodeShell extends PeripheralBarCode {
1471
+ }
630
1472
  class CommerceClient {
631
1473
  constructor(options) {
632
1474
  __publicField(this, "context");
@@ -637,6 +1479,7 @@ class CommerceClient {
637
1479
  __publicField(this, "shipping");
638
1480
  __publicField(this, "marketing");
639
1481
  __publicField(this, "stores");
1482
+ __publicField(this, "devices");
640
1483
  __publicField(this, "http");
641
1484
  __publicField(this, "workerBridge");
642
1485
  __publicField(this, "cacheStrategy");
@@ -647,8 +1490,9 @@ class CommerceClient {
647
1490
  this.workerBridge = new WorkerBridge();
648
1491
  this.cacheStrategy = new CacheStrategy(this.workerBridge, this.http);
649
1492
  this.sessionManager = SessionManagerFactory.create(this.http, this.context);
1493
+ this.devices = new DeviceManager();
650
1494
  this.session = new SessionModule(this.http, this.cacheStrategy);
651
- this.cart = new CartModule(this.http, this.cacheStrategy, this.connectivity);
1495
+ this.cart = new CartModule(this.http, this.cacheStrategy, this.connectivity, this.workerBridge);
652
1496
  this.catalog = new CatalogModule(this.http, this.cacheStrategy);
653
1497
  this.shipping = new ShippingModule(this.http, this.cacheStrategy);
654
1498
  this.marketing = new MarketingModule(this.http, this.cacheStrategy);
@@ -679,6 +1523,7 @@ class CommerceClient {
679
1523
  dispose() {
680
1524
  this.connectivity.dispose();
681
1525
  this.workerBridge.dispose();
1526
+ this.devices.dispose();
682
1527
  }
683
1528
  }
684
1529
  exports.AltazionApiError = AltazionApiError;
@@ -686,5 +1531,10 @@ exports.CacheError = CacheError;
686
1531
  exports.CommerceClient = CommerceClient;
687
1532
  exports.CommerceContext = CommerceContext;
688
1533
  exports.ConnectivityManager = ConnectivityManager;
1534
+ exports.DeviceManager = DeviceManager;
1535
+ exports.DeviceNotification = DeviceNotification;
689
1536
  exports.OfflineError = OfflineError;
1537
+ exports.PeripheralBarCode = PeripheralBarCode;
1538
+ exports.PeripheralBase = PeripheralBase;
1539
+ exports.PeripheralTpe = PeripheralTpe;
690
1540
  //# sourceMappingURL=index.cjs.map