ng-miam 8.8.16 → 8.8.18

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.
@@ -3882,9 +3882,71 @@
3882
3882
  return RecipeLike;
3883
3883
  }(i2$2.Resource));
3884
3884
 
3885
+ var VERSION = '8.8.18';
3886
+
3887
+ var _eventEmitter = new i0.EventEmitter();
3888
+ /** Maps SDK 8.8 legacy names to canonical mealz-shared-analytics@4.13 event names. */
3889
+ var LEGACY_EVENT_NAME_MAP = {
3890
+ 'entry.add': 'entry.added',
3891
+ 'entry.delete': 'entry.deleted',
3892
+ 'entry.replace': 'entry.replaced',
3893
+ 'pos.selected': 'locator.select',
3894
+ 'search.store': 'locator.search',
3895
+ 'planner.confirmed': 'planner.confirm',
3896
+ 'recipe.print': 'recipe.show'
3897
+ };
3898
+ /** Maps SDK 8.8 legacy prop keys to canonical shared-analytics keys. */
3899
+ var LEGACY_PROP_KEY_MAP = {
3900
+ recipes_count: 'recipe_count',
3901
+ new_ext_item_id: 'new_item_ext_id',
3902
+ old_ext_item_id: 'old_item_ext_id'
3903
+ };
3904
+ /** Legacy marker event; reset is already tracked via subsequent recipe.remove events. */
3905
+ var LEGACY_EVENTS_SKIPPED = new Set(['recipe.reset']);
3906
+ function mapLegacyEventName(name) {
3907
+ var _a;
3908
+ return (_a = LEGACY_EVENT_NAME_MAP[name]) !== null && _a !== void 0 ? _a : name;
3909
+ }
3910
+ function shouldSkipLegacyEvent(name) {
3911
+ return LEGACY_EVENTS_SKIPPED.has(name);
3912
+ }
3913
+ function normalizeLegacyProps(props) {
3914
+ if (!props) {
3915
+ return {};
3916
+ }
3917
+ var normalized = {};
3918
+ Object.keys(props).forEach(function (key) {
3919
+ var _a;
3920
+ var value = props[key];
3921
+ if (value === undefined || value === null) {
3922
+ return;
3923
+ }
3924
+ var normalizedKey = (_a = LEGACY_PROP_KEY_MAP[key]) !== null && _a !== void 0 ? _a : key;
3925
+ normalized[normalizedKey] = String(value);
3926
+ });
3927
+ return normalized;
3928
+ }
3929
+ var getAnalyticsEnvironment = function () { return environment$1.env === 'prod' ? 'prod' : 'uat'; };
3930
+ // Exported for unit tests
3931
+ // eslint-disable-next-line prefer-arrow/prefer-arrow-functions
3932
+ function url(path) {
3933
+ if (path) {
3934
+ return "" + location.origin + path;
3935
+ }
3936
+ return location.href;
3937
+ }
3938
+ // Exported for unit tests
3939
+ // eslint-disable-next-line prefer-arrow/prefer-arrow-functions
3940
+ function _onEmit(event) {
3941
+ _eventEmitter.emit(JSON.stringify({
3942
+ name: event.name,
3943
+ path: event.url,
3944
+ props: event.props
3945
+ }));
3946
+ }
3885
3947
  var AnalyticsService = /** @class */ (function () {
3886
3948
  function AnalyticsService() {
3887
- this.EVENT_PAGEVIEW = 'pageview'; // GA4 is page_view -> use this one on ga to autotrack some fields
3949
+ this.EVENT_PAGEVIEW = 'pageview';
3888
3950
  this.EVENT_SEARCH = 'search';
3889
3951
  this.EVENT_RECIPE_SHOW = 'recipe.show';
3890
3952
  this.EVENT_RECIPE_DISPLAY = 'recipe.display';
@@ -3913,69 +3975,54 @@
3913
3975
  this.EVENT_ONBOARDING_CLOSE = 'onboarding.close';
3914
3976
  this.EVENT_ONBOARDING_ACTION = 'onboarding.action';
3915
3977
  this.ready$ = new rxjs.BehaviorSubject(false);
3916
- this.eventEmitter = new i0.EventEmitter();
3978
+ this.eventEmitter = _eventEmitter;
3979
+ this.alreadyInitialized = false;
3917
3980
  }
3918
3981
  // DEPRECATED: optimizeKey parameter to be removed with next major version
3919
3982
  AnalyticsService.prototype.init = function (domain, _optimizeKey) {
3920
- this._injectPlausible(domain);
3921
- };
3922
- /**
3923
- * Set the identifier of the ABTest experience if one is running
3924
- * It will then be added as props to all events sent
3925
- * @param key A unique identifier for the ABTest experience
3926
- */
3927
- AnalyticsService.prototype.setAbTestKey = function (key) {
3928
- this.abTestkey = key;
3929
- };
3930
- AnalyticsService.prototype.event = function (name, path, props) {
3931
3983
  var _a;
3932
- if (this.abTestkey) {
3933
- props.abTestKey = this.abTestkey;
3984
+ if (this.alreadyInitialized || !domain) {
3985
+ return;
3986
+ }
3987
+ mealzSharedAnalytics.initSharedAnalytics(domain, VERSION, _onEmit, getAnalyticsEnvironment());
3988
+ var storedAbTestKey = localStorage.getItem('_miam/ab');
3989
+ if ((storedAbTestKey === null || storedAbTestKey === void 0 ? void 0 : storedAbTestKey.length) > 0) {
3990
+ mealzSharedAnalytics.setABTestKey(storedAbTestKey);
3991
+ }
3992
+ else if (this.pendingAbTestKey !== undefined) {
3993
+ mealzSharedAnalytics.setABTestKey(this.pendingAbTestKey);
3934
3994
  }
3935
3995
  if (((_a = localStorage.getItem('_miam/affiliate')) === null || _a === void 0 ? void 0 : _a.length) > 0) {
3936
- props.affiliate = localStorage.getItem('_miam/affiliate');
3937
- }
3938
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call
3939
- plausible(name, { u: this.url(path), props: props });
3940
- this.eventEmitter.emit(JSON.stringify({
3941
- name: name,
3942
- path: this.url(path),
3943
- props: props
3944
- }));
3996
+ mealzSharedAnalytics.setAffiliate(localStorage.getItem('_miam/affiliate'));
3997
+ }
3998
+ this.alreadyInitialized = true;
3999
+ this.ready$.next(true);
4000
+ };
4001
+ AnalyticsService.prototype.setAbTestKey = function (key) {
4002
+ this.pendingAbTestKey = key;
4003
+ if (this.alreadyInitialized) {
4004
+ mealzSharedAnalytics.setABTestKey(key);
4005
+ }
3945
4006
  };
3946
4007
  AnalyticsService.prototype.sendEventWhenReady = function (name, path, props) {
3947
4008
  var _this = this;
3948
4009
  if (this.ready$.getValue()) {
3949
- return this.event(name, path, props);
4010
+ this.sendAnalyticsEvent(name, path, props);
4011
+ return;
3950
4012
  }
3951
- this.ready$.pipe(operators.filter(function (ready) { return ready; }), operators.take(1)).subscribe(function () { return _this.event(name, path, props); });
4013
+ this.ready$.pipe(operators.filter(function (ready) { return ready; }), operators.take(1)).subscribe(function () { return _this.sendAnalyticsEvent(name, path, props); });
3952
4014
  };
3953
- AnalyticsService.prototype.url = function (path) {
3954
- if (path) {
3955
- return "" + location.origin + path;
4015
+ AnalyticsService.prototype.sendAnalyticsEvent = function (name, path, props) {
4016
+ if (shouldSkipLegacyEvent(name)) {
4017
+ return;
3956
4018
  }
3957
- return location.href;
3958
- };
3959
- AnalyticsService.prototype._injectPlausible = function (domain) {
3960
- var _this = this;
3961
- var script = document.createElement('script');
3962
- if (domain === 'miam.test') {
3963
- // In development, charge the "local" extension to make sure events can be routed from localhost to miam.test domain
3964
- script.src = 'https://plausible.io/js/plausible.local.manual.js';
4019
+ var eventName = mapLegacyEventName(name);
4020
+ try {
4021
+ mealzSharedAnalytics.sendEvent(eventName, url(path), '', normalizeLegacyProps(props));
3965
4022
  }
3966
- else {
3967
- // Use manual script to limit the number of pageviews
3968
- // Don't trigger pageviews automatically. Also allows you to specify custom locations to redact URLs with identifiers.
3969
- // You can also use it to track custom query parameters
3970
- script.src = 'https://plausible.io/js/plausible.manual.js';
4023
+ catch (error) {
4024
+ console.error('[Miam] Error sending analytics event', error);
3971
4025
  }
3972
- script.defer = true;
3973
- script.setAttribute('data-domain', domain);
3974
- script.onload = function () {
3975
- console.debug("[Miam] Analytics ready for domain: " + JSON.stringify(domain));
3976
- _this.ready$.next(true);
3977
- };
3978
- document.head.appendChild(script);
3979
4026
  };
3980
4027
  /** ************************************************* SEND EVENT FOR BASKET ACTIONS ************************************************* **/
3981
4028
  AnalyticsService.prototype.sendRemoveRecipesEvents = function (actions) {
@@ -4050,7 +4097,7 @@
4050
4097
  item_id: action.params.basketEntry.selectedItem.id,
4051
4098
  ext_item_id: action.params.basketEntry.selectedItem.attributes['ext-id'],
4052
4099
  item_ean: action.params.basketEntry.selectedItem.ean,
4053
- diff: action.params.newQuantity - action.params.basketEntry.quantity
4100
+ product_quantity: action.params.newQuantity
4054
4101
  });
4055
4102
  });
4056
4103
  };
@@ -4058,6 +4105,7 @@
4058
4105
  this.sendEventWhenReady(this.EVENT_ENTRY_REPLACE, action.params.eventTrace.originPath, {
4059
4106
  recipe_id: action.params.recipeId,
4060
4107
  entry_name: action.params.basketEntry.name,
4108
+ product_quantity: action.params.basketEntry.quantity,
4061
4109
  new_item_id: action.params.basketEntry.selectedItem.id,
4062
4110
  new_ext_item_id: action.params.basketEntry.selectedItem.attributes['ext-id'],
4063
4111
  new_item_ean: action.params.basketEntry.selectedItem.ean,
@@ -5154,6 +5202,7 @@
5154
5202
  _this.basketPreviewIsCalculating = false;
5155
5203
  _this.basketInitCalled = false;
5156
5204
  _this.confirming = new rxjs.BehaviorSubject(false);
5205
+ _this.authlessTransferInProgress = false;
5157
5206
  _this.basketActionsQueue = new rxjs.BehaviorSubject([]);
5158
5207
  _this._entries$ = new rxjs.BehaviorSubject([]);
5159
5208
  _this.actionsBeingProcessed = new rxjs.BehaviorSubject([]);
@@ -5332,22 +5381,30 @@
5332
5381
  this.loadPreview().subscribe();
5333
5382
  }
5334
5383
  };
5384
+ /** Marks basket as initialized and loads preview only (no loadBasket) — used before authless→logged-in transfer. */
5385
+ BasketsService.prototype.initBasketPreviewOnly = function () {
5386
+ if (!this.basketInitCalled) {
5387
+ this.basketInitCalled = true;
5388
+ this.loadPreview().subscribe();
5389
+ }
5390
+ };
5335
5391
  BasketsService.prototype.refreshCurrentBasket = function () {
5336
5392
  var _this = this;
5337
- this.currentAndPreviewFetching.next(true);
5338
5393
  return this.usersService.ensureAnonymousUserIdIfMissing().pipe(operators.switchMap(function () { return _this.posService.waitForPos.pipe(operators.take(1), operators.switchMap(function (pos) {
5339
5394
  console.debug('[Miam] refreshing basket');
5340
5395
  var authlessId = localStorage.getItem('_miam/authlessId');
5341
5396
  var userId = localStorage.getItem('_miam/userId');
5397
+ var willTransfer = !!(authlessId && userId);
5398
+ if (_this.authlessTransferInProgress) {
5399
+ return _this._basket$;
5400
+ }
5401
+ _this.currentAndPreviewFetching.next(true);
5342
5402
  if (_this.currentSubscription) {
5343
5403
  _this.currentSubscription.unsubscribe();
5344
5404
  }
5345
- var basketLoad$ = (authlessId && userId)
5405
+ var basketLoad$ = willTransfer
5346
5406
  ? _this.transferAuthlessBasket(pos.id, authlessId)
5347
5407
  : _this.fetchCurrentBasket(pos.id);
5348
- if (authlessId && userId) {
5349
- localStorage.removeItem('_miam/authlessId');
5350
- }
5351
5408
  var basketObservable = basketLoad$.pipe(
5352
5409
  // Affiliated requires a basket to exist server-side; run only after current basket fetch/update completes.
5353
5410
  operators.tap(function () { return _this.checkIfIsAffiliated(); }));
@@ -5385,13 +5442,22 @@
5385
5442
  BasketsService.prototype.transferAuthlessBasket = function (posId, authlessId) {
5386
5443
  var _this = this;
5387
5444
  var transferAuthlessBasketUrl = environment$1.miamAPI + "/api/v1/baskets/transfer_authless?point_of_sale_id=" + posId + "&authless_user_id=" + authlessId;
5388
- return this.http.patch(transferAuthlessBasketUrl, {}).pipe(operators.switchMap(function (response) {
5445
+ this.authlessTransferInProgress = true;
5446
+ return this.http.patch(transferAuthlessBasketUrl, {}).pipe(operators.tap(function () {
5447
+ localStorage.removeItem('_miam/authlessId');
5448
+ }), operators.switchMap(function (response) {
5389
5449
  var confirmedBasket = _this.new();
5390
5450
  confirmedBasket.fill(response);
5391
5451
  return _this.updateLocalBasket(confirmedBasket);
5392
- }), operators.catchError(function () {
5393
- // If authless transfer returned an error, there might be something wrong with the basketId in localStorage, thus we fetchCurrent
5452
+ }), operators.catchError(function (err) {
5453
+ // Keep the id on abort/cancel (status 0) so a raced refresh cannot drop a real pending transfer.
5454
+ // Clear it on a completed API error so a leftover empty authless id cannot block later confirms.
5455
+ if (err.status >= 400) {
5456
+ localStorage.removeItem('_miam/authlessId');
5457
+ }
5394
5458
  return _this.fetchCurrentBasket(posId);
5459
+ }), operators.finalize(function () {
5460
+ _this.authlessTransferInProgress = false;
5395
5461
  }));
5396
5462
  };
5397
5463
  BasketsService.prototype.fetchCurrentBasket = function (posId) {
@@ -5444,13 +5510,16 @@
5444
5510
  }), operators.take(1));
5445
5511
  };
5446
5512
  BasketsService.prototype.eventProps = function (basket, totalPrice) {
5513
+ var _a, _b, _c, _d;
5447
5514
  return {
5448
5515
  // if you have a basket you have a pos...
5449
5516
  pos_id: this.posService.pos$.getValue().id,
5450
5517
  pos_name: this.posService.pos$.getValue().attributes.name,
5451
5518
  basket_id: basket.id,
5452
5519
  miam_amount: basket.totalPrice,
5453
- total_amount: totalPrice
5520
+ total_amount: totalPrice,
5521
+ recipe_count: (_b = (_a = basket.recipeInfos) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0,
5522
+ miam_products: (_d = (_c = basket.completion) === null || _c === void 0 ? void 0 : _c.total) !== null && _d !== void 0 ? _d : 0
5454
5523
  };
5455
5524
  };
5456
5525
  /** ******************************************************* ACTIONS ON ENTRIES ******************************************************* **/
@@ -5547,8 +5616,8 @@
5547
5616
  var _this = this;
5548
5617
  if (include === void 0) { include = []; }
5549
5618
  if (isSchoolList === void 0) { isSchoolList = false; }
5550
- return this.waitForBasket.pipe(operators.switchMap(function (basket) { return _this.posService.waitForPos.pipe(operators.take(1), operators.map(function (pos) { return [basket, pos]; })); }), operators.switchMap(function (_b) {
5551
- var _c = __read(_b, 2), basket = _c[0], pos = _c[1];
5619
+ return this.waitForBasket.pipe(operators.switchMap(function (basket) { return _this.posService.waitForPos.pipe(operators.take(1), operators.map(function (pos) { return [basket, pos]; })); }), operators.switchMap(function (_e) {
5620
+ var _f = __read(_e, 2), basket = _f[0], pos = _f[1];
5552
5621
  var url;
5553
5622
  if (isSchoolList) {
5554
5623
  url = environment$1.miamAPI + "/api/v1/baskets/school-list?fields[baskets]=" + BASKET_SPARSE_FIELDS.baskets.join(',') +
@@ -6952,16 +7021,8 @@
6952
7021
  this.posService.waitForPos.pipe(operators.take(1))
6953
7022
  ]).subscribe(function (res) {
6954
7023
  var basket = res[0];
6955
- var pos = res[1];
6956
7024
  if (basket.totalPrice > 0) {
6957
- var props = {
6958
- pos_id: pos.id,
6959
- pos_name: pos.attributes.name,
6960
- basket_id: basket.id,
6961
- miam_amount: basket.totalPrice,
6962
- total_amount: totalPrice
6963
- };
6964
- _this.analyticsService.sendEventWhenReady(eventType, null, props);
7025
+ _this.analyticsService.sendEventWhenReady(eventType, null, _this.basketsService.eventProps(basket, totalPrice));
6965
7026
  }
6966
7027
  });
6967
7028
  };
@@ -6970,12 +7031,17 @@
6970
7031
  if (tokenOrId) {
6971
7032
  this.userService.toggleIsLogged(true);
6972
7033
  }
7034
+ var pendingAuthlessTransfer = !!localStorage.getItem('_miam/authlessId');
6973
7035
  // if initBasket is set to false, the basket & list will not be initialised until the first time they are needed
6974
- if (initBasket) {
7036
+ if (initBasket && !pendingAuthlessTransfer) {
6975
7037
  this.basketsService.initBasket();
6976
7038
  }
7039
+ else if (initBasket && pendingAuthlessTransfer) {
7040
+ // reloadBasket below runs transfer_authless — skip loadBasket to avoid a concurrent refreshCurrentBasket
7041
+ this.basketsService.initBasketPreviewOnly();
7042
+ }
6977
7043
  return this.userService.generatingAuthlessId$.pipe(operators.skipWhile(function (generating) { return generating; }), operators.take(1), operators.switchMap(function () {
6978
- if (!!localStorage.getItem('_miam/authlessId')) {
7044
+ if (pendingAuthlessTransfer) {
6979
7045
  return _this.basketsService.reloadBasket();
6980
7046
  }
6981
7047
  return rxjs.of(null);
@@ -8757,7 +8823,7 @@
8757
8823
  MiamInterceptor.prototype.setMiamHeaders = function (request) {
8758
8824
  var headersToAdd = {
8759
8825
  'miam-origin': this.context.origin.value,
8760
- 'miam-front-version': '8.8.10',
8826
+ 'miam-front-version': '8.8.18',
8761
8827
  'miam-front-type': 'web',
8762
8828
  'miam-api-version': '4.7.0'
8763
8829
  };
@@ -26752,6 +26818,11 @@
26752
26818
  exports.WEB_COMPONENTS_NAMES = WEB_COMPONENTS_NAMES;
26753
26819
  exports.WarningStoreLocatorComponent = WarningStoreLocatorComponent;
26754
26820
  exports.WebComponentsModule = WebComponentsModule;
26821
+ exports._onEmit = _onEmit;
26822
+ exports.mapLegacyEventName = mapLegacyEventName;
26823
+ exports.normalizeLegacyProps = normalizeLegacyProps;
26824
+ exports.shouldSkipLegacyEvent = shouldSkipLegacyEvent;
26825
+ exports.url = url;
26755
26826
 
26756
26827
  Object.defineProperty(exports, '__esModule', { value: true });
26757
26828