@azzas/azzas-tracker-web 2.0.2-preview.4 → 2.0.2-preview.5

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/mod.cjs CHANGED
@@ -156,6 +156,7 @@ var EVENTS = {
156
156
  "region",
157
157
  "currency",
158
158
  "promotion_name",
159
+ "promotion_url",
159
160
  "creative_slot",
160
161
  "creative_name"
161
162
  // "items",
@@ -959,6 +960,23 @@ var isDebugMode = () => {
959
960
  return window.location.search.indexOf("__trk_inspect__") !== -1;
960
961
  }
961
962
  };
963
+ function setCookie(name, value, days = 7, domain) {
964
+ if (typeof document === "undefined") return;
965
+ const encodedValue = encodeURIComponent(value);
966
+ let expires = "";
967
+ if (days) {
968
+ const date = /* @__PURE__ */ new Date();
969
+ date.setTime(date.getTime() + days * 24 * 60 * 60 * 1e3);
970
+ expires = "; expires=" + date.toUTCString();
971
+ }
972
+ const domainAttr = domain ? `; domain=.${domain.replace(/^\./, "")}` : "";
973
+ document.cookie = `${name}=${encodedValue}${expires}${domainAttr}; path=/;`;
974
+ }
975
+ function getCookie(name) {
976
+ if (typeof document === "undefined") return null;
977
+ const match = document.cookie.split("; ").find((row) => row.startsWith(`${name}=`));
978
+ return match ? decodeURIComponent(match.slice(name.length + 1)) : null;
979
+ }
962
980
  var paymentTypeMap = [
963
981
  ["vale", "vale cr\xE9dito"],
964
982
  ["pagaleve", "pix"],
@@ -1019,6 +1037,23 @@ var resizeVtexImage2 = (url, width = 500, height = 500) => {
1019
1037
  `$1-${width}-${height}/`
1020
1038
  );
1021
1039
  };
1040
+ function cleanPath(path) {
1041
+ try {
1042
+ return decodeURIComponent(path).toLowerCase().replace(/\/+$/, "");
1043
+ } catch (e) {
1044
+ return path.toLowerCase().replace(/\/+$/, "");
1045
+ }
1046
+ }
1047
+ function matchesPromotion(listName, promotion) {
1048
+ if (!listName || !promotion.promotion_url) return false;
1049
+ let promotionPath;
1050
+ try {
1051
+ promotionPath = new URL(promotion.promotion_url).pathname;
1052
+ } catch (e) {
1053
+ promotionPath = promotion.promotion_url;
1054
+ }
1055
+ return cleanPath(promotionPath) === cleanPath(listName);
1056
+ }
1022
1057
 
1023
1058
  // src/params/legacy/resolvers/paymentType/fromOrderForm.ts
1024
1059
  function paymentTypeFromOrderForm(context) {
@@ -1397,6 +1432,9 @@ var metaAdapter = {
1397
1432
  promotion_name: (context) => {
1398
1433
  return context.meta.promotion_name || null;
1399
1434
  },
1435
+ promotion_url: (context) => {
1436
+ return context.meta.promotion_url || null;
1437
+ },
1400
1438
  creative_name: (context) => {
1401
1439
  return context.meta.creative_name || null;
1402
1440
  },
@@ -1584,7 +1622,7 @@ var getItemCategory5 = (item) => {
1584
1622
  };
1585
1623
  var getItemCategory23 = (item) => {
1586
1624
  var _a, _b, _c, _d;
1587
- const AVOID_CATEGORIES = /^(outlet|bazar|sale|coleção)$/i;
1625
+ const AVOID_CATEGORIES = /^(outlet|bazar|sale|coleção|promoção)$/i;
1588
1626
  const categories = (_c = (_b = (_a = item == null ? void 0 : item.similarItems) == null ? void 0 : _a[0]) == null ? void 0 : _b.categories) != null ? _c : [];
1589
1627
  const validHierarchy = categories.filter((c) => c && !AVOID_CATEGORIES.test(c));
1590
1628
  const deepest = (_d = validHierarchy[validHierarchy.length - 1]) != null ? _d : "";
@@ -2139,6 +2177,94 @@ var orderFormAdapter = {
2139
2177
  }
2140
2178
  };
2141
2179
 
2180
+ // src/core/promotion.ts
2181
+ var PROMO_COOKIE = "__azzas_trk_promo";
2182
+ var PROMO_TTL_MS = 10 * 60 * 1e3;
2183
+ var MAX_RELATED_KEYS = 30;
2184
+ var cachedRootDomain;
2185
+ function resolveRootDomain() {
2186
+ if (cachedRootDomain !== void 0) return cachedRootDomain;
2187
+ if (typeof document === "undefined") return null;
2188
+ const hostname = window.location.hostname;
2189
+ const isLocalhost = hostname === "localhost";
2190
+ const isIpAddress = /^[\d.]+$/.test(hostname);
2191
+ if (!hostname || isLocalhost || isIpAddress) {
2192
+ cachedRootDomain = null;
2193
+ return null;
2194
+ }
2195
+ const parts = hostname.split(".");
2196
+ const PROBE = "__azzas_trk_probe";
2197
+ for (let i = parts.length - 2; i >= 0; i--) {
2198
+ const candidate = parts.slice(i).join(".");
2199
+ document.cookie = `${PROBE}=1; domain=.${candidate}; path=/;`;
2200
+ if (document.cookie.includes(`${PROBE}=`)) {
2201
+ document.cookie = `${PROBE}=; domain=.${candidate}; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT`;
2202
+ cachedRootDomain = candidate;
2203
+ return candidate;
2204
+ }
2205
+ }
2206
+ cachedRootDomain = null;
2207
+ return null;
2208
+ }
2209
+ function writePromotion(promotion) {
2210
+ const remainingDays = (promotion.saved_at + PROMO_TTL_MS - Date.now()) / (24 * 60 * 60 * 1e3);
2211
+ if (remainingDays <= 0) return;
2212
+ setCookie(PROMO_COOKIE, JSON.stringify(promotion), remainingDays, resolveRootDomain());
2213
+ }
2214
+ function savePromotion(input) {
2215
+ writePromotion({
2216
+ ...input,
2217
+ related_keys: [],
2218
+ saved_at: Date.now()
2219
+ });
2220
+ }
2221
+ function getPromotion() {
2222
+ const raw = getCookie(PROMO_COOKIE);
2223
+ if (!raw) return null;
2224
+ try {
2225
+ const promotion = JSON.parse(raw);
2226
+ const isExpired = !promotion.saved_at || Date.now() - promotion.saved_at > PROMO_TTL_MS;
2227
+ if (isExpired) {
2228
+ clearPromotion();
2229
+ return null;
2230
+ }
2231
+ return promotion;
2232
+ } catch (e) {
2233
+ return null;
2234
+ }
2235
+ }
2236
+ function clearPromotion() {
2237
+ setCookie(PROMO_COOKIE, "", -1, resolveRootDomain());
2238
+ }
2239
+ function itemsWithPromotion(items) {
2240
+ const promotion = getPromotion();
2241
+ if (!promotion) return items;
2242
+ const relatedKeys = new Set(promotion.related_keys);
2243
+ const newKeys = [];
2244
+ const enrichedItems = items.map((item) => {
2245
+ const itemKeys = [item.item_id].filter((key) => Boolean(key));
2246
+ const alreadyRelated = itemKeys.some((key) => relatedKeys.has(key));
2247
+ const isRelated = alreadyRelated || matchesPromotion(item.item_list_name, promotion);
2248
+ if (!isRelated) return item;
2249
+ if (!alreadyRelated) {
2250
+ newKeys.push(...itemKeys);
2251
+ }
2252
+ return {
2253
+ ...item,
2254
+ promotion_name: promotion.promotion_name,
2255
+ creative_name: promotion.creative_name,
2256
+ creative_slot: promotion.creative_slot
2257
+ };
2258
+ });
2259
+ if (newKeys.length) {
2260
+ writePromotion({
2261
+ ...promotion,
2262
+ related_keys: [...promotion.related_keys, ...newKeys].slice(0, MAX_RELATED_KEYS)
2263
+ });
2264
+ }
2265
+ return enrichedItems;
2266
+ }
2267
+
2142
2268
  // src/formatter.ts
2143
2269
  var adapters = {
2144
2270
  DECO: decoAdapter,
@@ -2164,7 +2290,11 @@ async function getParameters(context, eventName, config2) {
2164
2290
  return [param, await getter(context, config2)];
2165
2291
  })
2166
2292
  );
2167
- return Object.fromEntries(entries);
2293
+ const parameters = Object.fromEntries(entries);
2294
+ if (Array.isArray(parameters.items) && parameters.items.length) {
2295
+ parameters.items = itemsWithPromotion(parameters.items);
2296
+ }
2297
+ return parameters;
2168
2298
  }
2169
2299
 
2170
2300
  // src/index.ts
@@ -2173,18 +2303,30 @@ function initTracker(c) {
2173
2303
  config = c;
2174
2304
  }
2175
2305
  async function trackWebEvent(event, context) {
2306
+ var _a, _b, _c, _d;
2176
2307
  try {
2177
2308
  const parameters = await getParameters(context, event, config);
2178
- if (isDebugMode()) {
2179
- console.log(`[DT v2] ${event}, context e parameters: `, {
2180
- context,
2181
- parameters
2309
+ if (event === "SELECT_PROMOTION" && parameters) {
2310
+ savePromotion({
2311
+ promotion_name: (_a = parameters.promotion_name) != null ? _a : null,
2312
+ creative_name: (_b = parameters.creative_name) != null ? _b : null,
2313
+ creative_slot: (_c = parameters.creative_slot) != null ? _c : null,
2314
+ promotion_url: (_d = parameters.promotion_url) != null ? _d : null
2182
2315
  });
2183
2316
  }
2184
- return await pushToDataLayer(
2185
- event,
2186
- Object.assign({}, parameters, { window: context.window })
2187
- );
2317
+ if (isDebugMode()) {
2318
+ console.log(
2319
+ `%c [DT v2] %c ${event} `,
2320
+ "background: #6366f1; color: #fff; font-weight: bold; padding: 2px 6px; border-radius: 4px 0 0 4px;",
2321
+ "background: #1e1e2e; color: #a5b4fc; font-weight: bold; padding: 2px 6px; border-radius: 0 4px 4px 0;",
2322
+ { context, parameters }
2323
+ );
2324
+ }
2325
+ const result = await pushToDataLayer(event, Object.assign({}, parameters, { window: context.window }));
2326
+ if (event === "PURCHASE" || event === "CUSTOM_PURCHASE") {
2327
+ clearPromotion();
2328
+ }
2329
+ return result;
2188
2330
  } catch (err) {
2189
2331
  return console.error(`[DT] Error tracking event ${event}:`, err);
2190
2332
  }