cloudcommerce 0.33.2 → 0.33.4

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.
Files changed (78) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/ecomplus-stores/barra-doce/functions/many/package.json +3 -3
  3. package/ecomplus-stores/barra-doce/functions/ssr/package.json +6 -6
  4. package/ecomplus-stores/barra-doce/functions/with-apps/package.json +3 -3
  5. package/ecomplus-stores/barra-doce/package.json +2 -2
  6. package/ecomplus-stores/monocard/functions/many/package.json +3 -3
  7. package/ecomplus-stores/monocard/functions/ssr/package.json +6 -6
  8. package/ecomplus-stores/monocard/functions/with-apps/package.json +3 -3
  9. package/ecomplus-stores/monocard/package.json +2 -2
  10. package/package.json +2 -2
  11. package/packages/api/package.json +1 -1
  12. package/packages/apps/affilate-program/package.json +1 -1
  13. package/packages/apps/correios/package.json +1 -1
  14. package/packages/apps/custom-payment/package.json +1 -1
  15. package/packages/apps/custom-shipping/package.json +1 -1
  16. package/packages/apps/datafrete/package.json +1 -1
  17. package/packages/apps/discounts/package.json +1 -1
  18. package/packages/apps/emails/package.json +1 -1
  19. package/packages/apps/fb-conversions/package.json +1 -1
  20. package/packages/apps/flash-courier/package.json +1 -1
  21. package/packages/apps/frenet/package.json +1 -1
  22. package/packages/apps/galaxpay/package.json +1 -1
  23. package/packages/apps/google-analytics/package.json +1 -1
  24. package/packages/apps/jadlog/package.json +1 -1
  25. package/packages/apps/loyalty-points/package.json +1 -1
  26. package/packages/apps/mandae/package.json +1 -1
  27. package/packages/apps/melhor-envio/package.json +1 -1
  28. package/packages/apps/mercadopago/package.json +1 -1
  29. package/packages/apps/pagarme/package.json +1 -1
  30. package/packages/apps/pagarme-v5/package.json +1 -1
  31. package/packages/apps/paghiper/package.json +1 -1
  32. package/packages/apps/pix/package.json +1 -1
  33. package/packages/apps/tiny-erp/package.json +1 -1
  34. package/packages/apps/webhooks/package.json +1 -1
  35. package/packages/cli/package.json +1 -1
  36. package/packages/config/package.json +1 -1
  37. package/packages/emails/package.json +1 -1
  38. package/packages/eslint/package.json +1 -1
  39. package/packages/events/package.json +1 -1
  40. package/packages/feeds/package.json +1 -1
  41. package/packages/firebase/package.json +1 -1
  42. package/packages/i18n/lib/en_us/i19safeBuy.txt +1 -0
  43. package/packages/i18n/lib/en_us.d.ts +1 -0
  44. package/packages/i18n/lib/en_us.js +1 -0
  45. package/packages/i18n/lib/en_us.js.map +1 -1
  46. package/packages/i18n/lib/pt_br/i19safeBuy.txt +1 -0
  47. package/packages/i18n/lib/pt_br.d.ts +1 -0
  48. package/packages/i18n/lib/pt_br.js +1 -0
  49. package/packages/i18n/lib/pt_br.js.map +1 -1
  50. package/packages/i18n/package.json +1 -1
  51. package/packages/i18n/src/en_us.ts +1 -0
  52. package/packages/i18n/src/pt_br.ts +1 -0
  53. package/packages/modules/lib/firebase/checkout.js +1 -1
  54. package/packages/modules/lib/firebase/checkout.js.map +1 -1
  55. package/packages/modules/package.json +1 -1
  56. package/packages/modules/src/firebase/checkout.ts +2 -2
  57. package/packages/passport/package.json +1 -1
  58. package/packages/ssr/lib/analytics-events.js +33 -5
  59. package/packages/ssr/lib/analytics-events.js.map +1 -1
  60. package/packages/ssr/lib/analytics-providers/google-analytics.js +48 -0
  61. package/packages/ssr/lib/analytics-providers/google-analytics.js.map +1 -0
  62. package/packages/ssr/lib/analytics-providers/meta-conversions-api.js +44 -0
  63. package/packages/ssr/lib/analytics-providers/meta-conversions-api.js.map +1 -0
  64. package/packages/ssr/lib/firebase/serve-storefront.js +16 -12
  65. package/packages/ssr/lib/firebase/serve-storefront.js.map +1 -1
  66. package/packages/ssr/package.json +3 -1
  67. package/packages/ssr/src/analytics-events.ts +45 -5
  68. package/packages/ssr/src/analytics-providers/google-analytics.ts +67 -0
  69. package/packages/ssr/src/analytics-providers/meta-conversions-api.ts +57 -0
  70. package/packages/ssr/src/firebase/serve-storefront.ts +17 -12
  71. package/packages/storefront/package.json +1 -1
  72. package/packages/storefront/src/analytics/event-to-fbq.ts +3 -0
  73. package/packages/storefront/src/analytics/event-to-ttq.ts +89 -10
  74. package/packages/storefront/src/lib/scripts/push-analytics-events.ts +15 -0
  75. package/packages/storefront/src/lib/scripts/vbeta-app.ts +172 -0
  76. package/packages/storefront/src/lib/state/shopping-cart.ts +7 -5
  77. package/packages/test-base/package.json +1 -1
  78. package/packages/types/package.json +1 -1
@@ -9,6 +9,7 @@ import {
9
9
  } from '@@sf/state/use-analytics';
10
10
  import afetch from '../../helpers/afetch';
11
11
  import parseGtagToFbq from '../../analytics/event-to-fbq';
12
+ import parseGtagToTtq from '../../analytics/event-to-ttq';
12
13
 
13
14
  type AnalyticsEvent = {
14
15
  type: 'gtag' | 'fbq' | 'ttq',
@@ -40,10 +41,12 @@ if (!import.meta.env.SSR) {
40
41
  gtag,
41
42
  dataLayer,
42
43
  fbq,
44
+ ttq,
43
45
  } = window as {
44
46
  gtag?: Gtag.Gtag,
45
47
  dataLayer?: Array<any>,
46
48
  fbq?: (action: string, value: string, payload?: any) => any,
49
+ ttq?: { page: () => any, track: (value: string, payload?: any) => any },
47
50
  };
48
51
  if (typeof gtag === 'function') {
49
52
  gtag('event', name, params);
@@ -60,6 +63,18 @@ if (!import.meta.env.SSR) {
60
63
  fbq('track', fbqEvent.name, fbqEvent.params);
61
64
  }
62
65
  });
66
+ const ttqEvents = await parseGtagToTtq(evMessage);
67
+ ttqEvents.forEach((ttqEvent) => {
68
+ if (!ttqEvent.name) return;
69
+ sendServerEvent({ type: 'ttk', ...ttqEvent });
70
+ if (typeof ttq?.page === 'function') {
71
+ if (ttqEvent.name === 'PageView') {
72
+ ttq.page();
73
+ } else {
74
+ ttq.track(ttqEvent.name, ttqEvent.params);
75
+ }
76
+ }
77
+ });
63
78
  });
64
79
 
65
80
  let lastPageLocation = '';
@@ -1,11 +1,182 @@
1
+ import type { Orders, Customers } from '@cloudcommerce/api/types';
1
2
  import { watch } from 'vue';
3
+ import { phone as getPhone } from '@ecomplus/utils';
2
4
  import {
3
5
  session,
4
6
  isAuthenticated,
5
7
  customer,
8
+ customerName,
6
9
  } from '@@sf/state/customer-session';
10
+ import { shoppingCart } from '@@sf/state/shopping-cart';
11
+ import { emitGtagEvent, getGtagItem } from '@@sf/state/use-analytics';
7
12
  import utm from '@@sf/scripts/session-utm';
8
13
 
14
+ const watchAppRoutes = () => {
15
+ const router = (window as any).storefrontApp?.router;
16
+ if (router) {
17
+ const getCouponApplied = () => {
18
+ return sessionStorage.getItem('st_discount_coupon') || undefined;
19
+ };
20
+ const fixMoneyValue = (value: number) => {
21
+ return Math.round(value * 100) / 100;
22
+ };
23
+
24
+ const emittedCheckoutSteps: Array<
25
+ 'view_cart' | 'begin_checkout' |
26
+ 'add_payment_info' | 'add_shipping_info'
27
+ > = [];
28
+ const emitCheckout = (
29
+ evName: typeof emittedCheckoutSteps[0],
30
+ params?: Gtag.EventParams,
31
+ ) => {
32
+ if (emittedCheckoutSteps.includes(evName)) return;
33
+ emittedCheckoutSteps.push(evName);
34
+ if (!params) {
35
+ params = {
36
+ value: fixMoneyValue(shoppingCart.value.subtotal),
37
+ items: shoppingCart.value.items.map(getGtagItem),
38
+ };
39
+ }
40
+ if (evName !== 'view_cart') {
41
+ params.coupon = getCouponApplied();
42
+ if (!emittedCheckoutSteps.includes('begin_checkout')) {
43
+ emitCheckout('begin_checkout');
44
+ }
45
+ }
46
+ emitGtagEvent(evName, params);
47
+ };
48
+
49
+ let isPurchaseSent = false;
50
+ const emitPurchase = (orderId: string, orderJson?: string) => {
51
+ if (!isPurchaseSent) {
52
+ if (localStorage.getItem('gtag.orderIdSent') !== orderId) {
53
+ let order: Orders | undefined;
54
+ if (orderJson) {
55
+ try {
56
+ order = JSON.parse(orderJson);
57
+ } catch {
58
+ //
59
+ }
60
+ }
61
+ const { amount } = (order || (window as any).storefrontApp) as {
62
+ amount?: Orders['amount'],
63
+ };
64
+ const params: Gtag.EventParams = {
65
+ transaction_id: orderId,
66
+ value: fixMoneyValue(amount?.total || shoppingCart.value.subtotal),
67
+ items: shoppingCart.value.items.map(getGtagItem),
68
+ coupon: order
69
+ ? order.extra_discount?.discount_coupon
70
+ : getCouponApplied(),
71
+ };
72
+ if (amount) {
73
+ if (amount.freight !== undefined) {
74
+ params.shipping = fixMoneyValue(amount.freight);
75
+ }
76
+ if (amount.tax !== undefined) {
77
+ params.tax = fixMoneyValue(amount.tax);
78
+ }
79
+ }
80
+ let purchaseTimeout = 1;
81
+ const { dataLayer, __sendGTMExtraPurchaseData } = (window as any);
82
+ if (dataLayer && __sendGTMExtraPurchaseData) {
83
+ const extraPurchaseData: Record<string, any> = {};
84
+ let shippingAddr: Exclude<Customers['addresses'], undefined>[0] | undefined;
85
+ if (customer) {
86
+ extraPurchaseData.customerDisplayName = customerName.value;
87
+ let customerFullName = customer.value.name;
88
+ if (!customerFullName?.given_name) {
89
+ try {
90
+ const storedCustomer = sessionStorage.getItem('ecomCustomerAccount');
91
+ if (storedCustomer) {
92
+ const sessionCustomer = JSON.parse(storedCustomer);
93
+ if (typeof sessionCustomer === 'object' && sessionCustomer) {
94
+ customerFullName = sessionCustomer.name;
95
+ }
96
+ }
97
+ } catch {
98
+ //
99
+ }
100
+ }
101
+ if (customerFullName) {
102
+ extraPurchaseData.customerGivenName = customerFullName.given_name;
103
+ extraPurchaseData.customerFamilyName = customerFullName.family_name;
104
+ }
105
+ extraPurchaseData.customerEmail = customer.value.main_email;
106
+ extraPurchaseData.customerPhone = getPhone(customer.value);
107
+ shippingAddr = customer.value.addresses?.[0];
108
+ }
109
+ try {
110
+ const storedAddr = sessionStorage.getItem('ecomCustomerAddress');
111
+ if (storedAddr) {
112
+ const sessionShippingAddr = JSON.parse(storedAddr);
113
+ if (typeof shippingAddr === 'object' && shippingAddr) {
114
+ Object.assign(shippingAddr, sessionShippingAddr);
115
+ } else {
116
+ shippingAddr = sessionShippingAddr;
117
+ }
118
+ }
119
+ } catch {
120
+ //
121
+ }
122
+ if (shippingAddr && shippingAddr.zip) {
123
+ extraPurchaseData.shippingAddrZip = shippingAddr.zip;
124
+ extraPurchaseData.shippingAddrStreet = shippingAddr.street;
125
+ extraPurchaseData.shippingAddrNumber = shippingAddr.number;
126
+ if (shippingAddr.street && shippingAddr.number) {
127
+ extraPurchaseData.shippingAddrStreet += `, ${shippingAddr.number}`;
128
+ }
129
+ extraPurchaseData.shippingAddrCity = shippingAddr.city;
130
+ extraPurchaseData.shippingAddrProvinceCode = shippingAddr.province_code;
131
+ }
132
+ dataLayer.push({
133
+ event: 'purchaseExtraData',
134
+ ...extraPurchaseData,
135
+ });
136
+ purchaseTimeout = 100;
137
+ }
138
+ setTimeout(() => emitGtagEvent('purchase', params), purchaseTimeout);
139
+ localStorage.setItem('gtag.orderIdSent', orderId);
140
+ }
141
+ isPurchaseSent = true;
142
+ }
143
+ };
144
+
145
+ let emitPurchaseTimer: NodeJS.Timeout | undefined;
146
+ const parseRouteToGtag = ({ name, params }) => {
147
+ switch (name) {
148
+ case 'cart':
149
+ emitCheckout('view_cart');
150
+ break;
151
+ case 'checkout':
152
+ if (!params.step) {
153
+ emitCheckout('begin_checkout');
154
+ } else if (Number(params.step) === 1) {
155
+ emitCheckout('add_shipping_info');
156
+ } else if (Number(params.step) === 2) {
157
+ emitCheckout('add_payment_info');
158
+ }
159
+ break;
160
+ case 'confirmation':
161
+ clearTimeout(emitPurchaseTimer);
162
+ if (params.json) {
163
+ emitPurchase(params.id, decodeURIComponent(params.json));
164
+ } else {
165
+ emitPurchaseTimer = setTimeout(() => {
166
+ emitPurchase(params.id);
167
+ }, 1500);
168
+ }
169
+ break;
170
+ default:
171
+ }
172
+ };
173
+ if (router.currentRoute) {
174
+ parseRouteToGtag(router.currentRoute);
175
+ }
176
+ router.afterEach(parseRouteToGtag);
177
+ }
178
+ };
179
+
9
180
  // https://github.com/ecomplus/storefront/tree/master/%40ecomplus/storefront-app compat
10
181
  if (!import.meta.env.SSR) {
11
182
  if (Object.keys(utm).length) {
@@ -49,6 +220,7 @@ if (!import.meta.env.SSR) {
49
220
  }, {
50
221
  immediate: true,
51
222
  });
223
+ setTimeout(watchAppRoutes, 400);
52
224
  };
53
225
 
54
226
  const appScript = document.createElement('script');
@@ -1,5 +1,6 @@
1
1
  import type { Products, CartSet, SearchItem } from '@cloudcommerce/api/types';
2
- import { computed, watch } from 'vue';
2
+ import { computed } from 'vue';
3
+ import { watchDebounced } from '@vueuse/core';
3
4
  import mitt from 'mitt';
4
5
  import useStorage from '@@sf/state/use-storage';
5
6
  import addItem from '@@sf/state/shopping-cart/add-cart-item';
@@ -107,7 +108,7 @@ type CartEvent = {
107
108
  const cartEmitter = mitt<CartEvent>();
108
109
  const cloneItems = () => shoppingCart.value.items.map((item) => ({ ...item }));
109
110
  let oldItems = cloneItems();
110
- watch(shoppingCart, ({ items }) => {
111
+ watchDebounced(shoppingCart, ({ items }) => {
111
112
  ['addCartItem' as const, 'removeCartItem' as const].forEach((evName) => {
112
113
  const isAdd = evName === 'addCartItem';
113
114
  const baseItems = isAdd ? items : oldItems;
@@ -115,16 +116,17 @@ watch(shoppingCart, ({ items }) => {
115
116
  baseItems.forEach((baseItem) => {
116
117
  if (!baseItem.quantity) return;
117
118
  const compareItem = compareItems.find(({ _id }) => _id === baseItem._id);
118
- if (compareItem && baseItem.quantity > compareItem.quantity) {
119
+ const compareQnt = compareItem?.quantity || 0;
120
+ if (baseItem.quantity > compareQnt) {
119
121
  cartEmitter.emit(evName, {
120
122
  ...baseItem,
121
- quantity: baseItem.quantity - (compareItem?.quantity || 0),
123
+ quantity: baseItem.quantity - compareQnt,
122
124
  });
123
125
  }
124
126
  });
125
127
  });
126
128
  oldItems = cloneItems();
127
- });
129
+ }, { debounce: 200 });
128
130
 
129
131
  export const cartEvents = {
130
132
  on: cartEmitter.on,
@@ -2,7 +2,7 @@
2
2
  "name": "@cloudcommerce/test-base",
3
3
  "private": true,
4
4
  "type": "module",
5
- "version": "0.33.2",
5
+ "version": "0.33.4",
6
6
  "description": "E-Com Plus Cloud Commerce basic setup for testing",
7
7
  "main": "lib/index.js",
8
8
  "repository": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/types",
3
3
  "type": "module",
4
- "version": "0.33.2",
4
+ "version": "0.33.4",
5
5
  "description": "E-Com Plus Cloud Commerce reusable type definitions",
6
6
  "main": "index.ts",
7
7
  "repository": {