@magicfeedback/popup-sdk 1.0.10 → 1.0.11
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 +19 -16
- package/dist/index.d.mts +20 -13
- package/dist/index.d.ts +20 -13
- package/dist/index.js +268 -44
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +268 -44
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1774,7 +1774,7 @@ function ensureResponsiveStyles(popup) {
|
|
|
1774
1774
|
`;
|
|
1775
1775
|
popup.appendChild(style);
|
|
1776
1776
|
}
|
|
1777
|
-
async function renderPopup(container, surveyId, productId, actions, emit, onClose) {
|
|
1777
|
+
async function renderPopup(container, surveyId, productId, actions, emit, onClose, env = "production") {
|
|
1778
1778
|
let surveyCompletedEmitted = false;
|
|
1779
1779
|
let stylesInjected = false;
|
|
1780
1780
|
const popup = document.createElement("div");
|
|
@@ -2058,7 +2058,7 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
|
|
|
2058
2058
|
setLoading(false);
|
|
2059
2059
|
return;
|
|
2060
2060
|
}
|
|
2061
|
-
import_native.default.init({ debug: true, env: "prod" });
|
|
2061
|
+
import_native.default.init({ debug: true, env: env === "production" ? "prod" : "dev" });
|
|
2062
2062
|
formInstance = import_native.default.form(surveyId, productId);
|
|
2063
2063
|
const generateOptions = {
|
|
2064
2064
|
addButton: false,
|
|
@@ -2209,6 +2209,9 @@ function setupTrigger(popups, trigger) {
|
|
|
2209
2209
|
case "exit":
|
|
2210
2210
|
setupExitTrigger(popups, trigger);
|
|
2211
2211
|
break;
|
|
2212
|
+
case "click":
|
|
2213
|
+
setupClickTrigger(popups, trigger);
|
|
2214
|
+
break;
|
|
2212
2215
|
}
|
|
2213
2216
|
}
|
|
2214
2217
|
function setupTimeTrigger(popups, trigger) {
|
|
@@ -2231,23 +2234,120 @@ function setupScrollTrigger(popups, trigger) {
|
|
|
2231
2234
|
popups.debug(`Scroll trigger set for ${threshold}%`);
|
|
2232
2235
|
}
|
|
2233
2236
|
function setupExitTrigger(popups, trigger) {
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2237
|
+
let fired = false;
|
|
2238
|
+
let lastUrl = typeof window !== "undefined" ? window.location.href : "";
|
|
2239
|
+
const historyRef = typeof window !== "undefined" ? window.history : null;
|
|
2240
|
+
const originalPushState = historyRef ? historyRef.pushState.bind(historyRef) : null;
|
|
2241
|
+
const originalReplaceState = historyRef ? historyRef.replaceState.bind(historyRef) : null;
|
|
2242
|
+
const cleanup = () => {
|
|
2243
|
+
document.removeEventListener("click", handleNavClick, true);
|
|
2244
|
+
window.removeEventListener("popstate", handlePopState);
|
|
2245
|
+
if (historyRef && originalPushState) historyRef.pushState = originalPushState;
|
|
2246
|
+
if (historyRef && originalReplaceState) historyRef.replaceState = originalReplaceState;
|
|
2247
|
+
};
|
|
2248
|
+
const fireOnce = () => {
|
|
2249
|
+
if (fired) return;
|
|
2250
|
+
fired = true;
|
|
2251
|
+
popups.triggerSurvey(trigger.surveyId);
|
|
2252
|
+
cleanup();
|
|
2253
|
+
};
|
|
2254
|
+
const handleNavClick = (e) => {
|
|
2255
|
+
if (fired) return;
|
|
2256
|
+
if (e.defaultPrevented) return;
|
|
2257
|
+
if (e.button !== 0) return;
|
|
2258
|
+
if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
|
|
2259
|
+
const target = e.target?.closest?.("a");
|
|
2260
|
+
if (!target) return;
|
|
2261
|
+
const href = target.getAttribute("href");
|
|
2262
|
+
if (!href || href.startsWith("#")) return;
|
|
2263
|
+
const targetAttr = target.getAttribute("target");
|
|
2264
|
+
if (targetAttr && targetAttr !== "_self") return;
|
|
2265
|
+
let url;
|
|
2266
|
+
try {
|
|
2267
|
+
url = new URL(href, window.location.href);
|
|
2268
|
+
} catch {
|
|
2269
|
+
return;
|
|
2270
|
+
}
|
|
2271
|
+
if (url.origin !== window.location.origin) return;
|
|
2272
|
+
e.preventDefault();
|
|
2273
|
+
fireOnce();
|
|
2274
|
+
};
|
|
2275
|
+
const shouldBlockUrl = (rawUrl) => {
|
|
2276
|
+
if (!rawUrl) return false;
|
|
2277
|
+
let url;
|
|
2278
|
+
try {
|
|
2279
|
+
url = rawUrl instanceof URL ? rawUrl : new URL(rawUrl, window.location.href);
|
|
2280
|
+
} catch {
|
|
2281
|
+
return false;
|
|
2238
2282
|
}
|
|
2283
|
+
if (url.origin !== window.location.origin) return false;
|
|
2284
|
+
if (url.href === window.location.href) return false;
|
|
2285
|
+
return true;
|
|
2239
2286
|
};
|
|
2240
|
-
|
|
2241
|
-
|
|
2287
|
+
const handlePopState = () => {
|
|
2288
|
+
if (fired) return;
|
|
2289
|
+
fireOnce();
|
|
2290
|
+
if (historyRef && originalPushState && lastUrl) {
|
|
2291
|
+
originalPushState(null, document.title, lastUrl);
|
|
2292
|
+
}
|
|
2293
|
+
};
|
|
2294
|
+
if (historyRef && originalPushState && originalReplaceState) {
|
|
2295
|
+
historyRef.pushState = function(data, unused, url) {
|
|
2296
|
+
if (!fired && shouldBlockUrl(url)) {
|
|
2297
|
+
fireOnce();
|
|
2298
|
+
return;
|
|
2299
|
+
}
|
|
2300
|
+
const result = originalPushState(data, unused, url);
|
|
2301
|
+
lastUrl = window.location.href;
|
|
2302
|
+
return result;
|
|
2303
|
+
};
|
|
2304
|
+
historyRef.replaceState = function(data, unused, url) {
|
|
2305
|
+
if (!fired && shouldBlockUrl(url)) {
|
|
2306
|
+
fireOnce();
|
|
2307
|
+
return;
|
|
2308
|
+
}
|
|
2309
|
+
const result = originalReplaceState(data, unused, url);
|
|
2310
|
+
lastUrl = window.location.href;
|
|
2311
|
+
return result;
|
|
2312
|
+
};
|
|
2313
|
+
}
|
|
2314
|
+
document.addEventListener("click", handleNavClick, true);
|
|
2315
|
+
window.addEventListener("popstate", handlePopState);
|
|
2316
|
+
popups.debug("Exit intent trigger set (navigation/spa)");
|
|
2317
|
+
}
|
|
2318
|
+
function setupClickTrigger(popups, trigger) {
|
|
2319
|
+
const targetId = typeof trigger.value === "string" ? trigger.value : "";
|
|
2320
|
+
if (!targetId) {
|
|
2321
|
+
popups.debug("Click trigger missing element id", trigger);
|
|
2322
|
+
return;
|
|
2323
|
+
}
|
|
2324
|
+
const attach = () => {
|
|
2325
|
+
const el = document.getElementById(targetId);
|
|
2326
|
+
if (!el) {
|
|
2327
|
+
popups.debug("Click trigger target not found", targetId);
|
|
2328
|
+
return false;
|
|
2329
|
+
}
|
|
2330
|
+
const handler = (e) => {
|
|
2331
|
+
if (e.defaultPrevented) return;
|
|
2332
|
+
popups.triggerSurvey(trigger.surveyId);
|
|
2333
|
+
el.removeEventListener("click", handler);
|
|
2334
|
+
};
|
|
2335
|
+
el.addEventListener("click", handler);
|
|
2336
|
+
popups.debug(`Click trigger set for #${targetId}`);
|
|
2337
|
+
return true;
|
|
2338
|
+
};
|
|
2339
|
+
if (typeof document === "undefined") return;
|
|
2340
|
+
if (attach()) return;
|
|
2341
|
+
window.addEventListener("DOMContentLoaded", () => attach(), { once: true });
|
|
2242
2342
|
}
|
|
2243
2343
|
|
|
2244
2344
|
// src/config/env.ts
|
|
2245
2345
|
var ENVIRONMENT_MAP = {
|
|
2246
2346
|
development: {
|
|
2247
|
-
apiBaseUrl: "https://api-dev.
|
|
2347
|
+
apiBaseUrl: "https://api-dev.deepdots.com"
|
|
2248
2348
|
},
|
|
2249
2349
|
production: {
|
|
2250
|
-
apiBaseUrl: "https://api.
|
|
2350
|
+
apiBaseUrl: "https://api.deepdots.com"
|
|
2251
2351
|
}
|
|
2252
2352
|
};
|
|
2253
2353
|
function resolveEnvironment(nodeEnv) {
|
|
@@ -2329,10 +2429,10 @@ var BrowserPopupRenderer = class {
|
|
|
2329
2429
|
document.body.appendChild(this.container);
|
|
2330
2430
|
}
|
|
2331
2431
|
}
|
|
2332
|
-
show(surveyId, productId, actions, emit, onClose) {
|
|
2432
|
+
show(surveyId, productId, actions, emit, onClose, env = "production") {
|
|
2333
2433
|
if (!this.container) this.init();
|
|
2334
2434
|
if (!this.container) return;
|
|
2335
|
-
renderPopup(this.container, surveyId, productId, actions, emit, onClose);
|
|
2435
|
+
renderPopup(this.container, surveyId, productId, actions, emit, onClose, env);
|
|
2336
2436
|
}
|
|
2337
2437
|
hide() {
|
|
2338
2438
|
if (this.container) {
|
|
@@ -2365,8 +2465,12 @@ var DeepdotsPopups = class {
|
|
|
2365
2465
|
this.pendingAutoLaunch = false;
|
|
2366
2466
|
this.answeredSurveys = /* @__PURE__ */ new Set();
|
|
2367
2467
|
this.lastShown = /* @__PURE__ */ new Map();
|
|
2468
|
+
// popupId -> timestamp mostrado
|
|
2469
|
+
this.surveyToPopupId = /* @__PURE__ */ new Map();
|
|
2470
|
+
// surveyId -> popupId
|
|
2471
|
+
this.baseUrl = "";
|
|
2472
|
+
this.env = "production";
|
|
2368
2473
|
}
|
|
2369
|
-
// popupId -> timestamp mostrado
|
|
2370
2474
|
/** Initialize the SDK with configuration */
|
|
2371
2475
|
init(config) {
|
|
2372
2476
|
if (this.initialized) {
|
|
@@ -2374,12 +2478,14 @@ var DeepdotsPopups = class {
|
|
|
2374
2478
|
return;
|
|
2375
2479
|
}
|
|
2376
2480
|
const env = resolveEnvironment(config.nodeEnv);
|
|
2481
|
+
this.baseUrl = env.apiBaseUrl;
|
|
2482
|
+
this.env = config.nodeEnv || "production";
|
|
2377
2483
|
this.config = {
|
|
2378
2484
|
apiKey: config.apiKey || void 0,
|
|
2379
|
-
baseUrl: env.apiBaseUrl,
|
|
2380
2485
|
mode: config.mode || "client",
|
|
2381
2486
|
debug: config.debug || false,
|
|
2382
|
-
popups: config.popups || []
|
|
2487
|
+
popups: config.popups || [],
|
|
2488
|
+
userId: config.userId || void 0
|
|
2383
2489
|
};
|
|
2384
2490
|
this.initialized = true;
|
|
2385
2491
|
this.log("SDK initialized", this.config);
|
|
@@ -2428,8 +2534,9 @@ var DeepdotsPopups = class {
|
|
|
2428
2534
|
if (isDefinition) {
|
|
2429
2535
|
const def = options;
|
|
2430
2536
|
this.log("Showing popup (definition)", def);
|
|
2537
|
+
this.surveyToPopupId.set(def.surveyId, def.id);
|
|
2431
2538
|
this.renderPopup(def.surveyId, def.productId, def.actions);
|
|
2432
|
-
this.emitEvent("popup_shown", def.surveyId);
|
|
2539
|
+
this.emitEvent("popup_shown", def.surveyId, { popupId: def.id });
|
|
2433
2540
|
} else {
|
|
2434
2541
|
const opt = options;
|
|
2435
2542
|
this.log("Showing popup (legacy options)", opt);
|
|
@@ -2458,9 +2565,10 @@ var DeepdotsPopups = class {
|
|
|
2458
2565
|
configureTriggersFromDefinitions() {
|
|
2459
2566
|
const derived = [];
|
|
2460
2567
|
const validDefs = this.validatePopupDefinitions(this.popupDefinitions);
|
|
2568
|
+
console.log("validDefs", validDefs);
|
|
2461
2569
|
validDefs.forEach((def) => {
|
|
2462
|
-
if (!def.
|
|
2463
|
-
const t = def.
|
|
2570
|
+
if (!def.triggers) return;
|
|
2571
|
+
const t = def.triggers;
|
|
2464
2572
|
let type;
|
|
2465
2573
|
switch (t.type) {
|
|
2466
2574
|
case "time_on_page":
|
|
@@ -2472,11 +2580,14 @@ var DeepdotsPopups = class {
|
|
|
2472
2580
|
case "exit":
|
|
2473
2581
|
type = "exit";
|
|
2474
2582
|
break;
|
|
2583
|
+
case "click":
|
|
2584
|
+
type = "click";
|
|
2585
|
+
break;
|
|
2475
2586
|
default:
|
|
2476
2587
|
this.debug("Unsupported trigger type", t.type);
|
|
2477
2588
|
return;
|
|
2478
2589
|
}
|
|
2479
|
-
const value = type === "time" ? t.value * 1e3 : t.value;
|
|
2590
|
+
const value = type === "time" && typeof t.value === "number" ? t.value * 1e3 : t.value;
|
|
2480
2591
|
derived.push({ type, value, surveyId: def.surveyId });
|
|
2481
2592
|
});
|
|
2482
2593
|
if (derived.length) {
|
|
@@ -2498,10 +2609,52 @@ var DeepdotsPopups = class {
|
|
|
2498
2609
|
this.lastShown.set(def.id, Date.now());
|
|
2499
2610
|
}
|
|
2500
2611
|
shouldShow(def) {
|
|
2501
|
-
|
|
2612
|
+
if (!this.matchesSegmentsPath(def)) {
|
|
2613
|
+
return false;
|
|
2614
|
+
}
|
|
2615
|
+
const conditions = def.triggers.condition || [];
|
|
2502
2616
|
if (!conditions.length) return true;
|
|
2503
2617
|
return conditions.every((c) => this.evaluateCondition(def, c));
|
|
2504
2618
|
}
|
|
2619
|
+
matchesSegmentsPath(def) {
|
|
2620
|
+
const paths = def.segments?.path;
|
|
2621
|
+
if (!paths || paths.length === 0) return true;
|
|
2622
|
+
if (typeof window === "undefined" || !window.location) {
|
|
2623
|
+
this.debug("No window.location available for path comparison", { popupId: def.id, paths });
|
|
2624
|
+
return true;
|
|
2625
|
+
}
|
|
2626
|
+
const currentPath = window.location.pathname || "";
|
|
2627
|
+
const currentHref = window.location.href || "";
|
|
2628
|
+
const normalize = (value) => {
|
|
2629
|
+
if (value.length > 1 && value.endsWith("/")) return value.slice(0, -1);
|
|
2630
|
+
return value;
|
|
2631
|
+
};
|
|
2632
|
+
const normalizedPath = normalize(currentPath);
|
|
2633
|
+
const normalizedHref = normalize(currentHref);
|
|
2634
|
+
const matches = paths.some((rawCandidate) => {
|
|
2635
|
+
const candidate = normalize(rawCandidate);
|
|
2636
|
+
let match = false;
|
|
2637
|
+
if (candidate.startsWith("http://") || candidate.startsWith("https://")) {
|
|
2638
|
+
match = normalizedHref === candidate;
|
|
2639
|
+
} else if (candidate.startsWith("/")) {
|
|
2640
|
+
match = normalizedHref.includes(candidate);
|
|
2641
|
+
} else {
|
|
2642
|
+
match = normalizedPath === candidate;
|
|
2643
|
+
}
|
|
2644
|
+
this.debug("Path comparison", {
|
|
2645
|
+
popupId: def.id,
|
|
2646
|
+
candidate,
|
|
2647
|
+
currentPath: normalizedPath,
|
|
2648
|
+
currentHref: normalizedHref,
|
|
2649
|
+
match
|
|
2650
|
+
});
|
|
2651
|
+
return match;
|
|
2652
|
+
});
|
|
2653
|
+
if (!matches) {
|
|
2654
|
+
this.debug("No path match for popup", { popupId: def.id, paths, currentPath: normalizedPath });
|
|
2655
|
+
}
|
|
2656
|
+
return matches;
|
|
2657
|
+
}
|
|
2505
2658
|
evaluateCondition(def, condition) {
|
|
2506
2659
|
if (!condition.answered && this.answeredSurveys.has(def.surveyId)) {
|
|
2507
2660
|
return false;
|
|
@@ -2520,29 +2673,59 @@ var DeepdotsPopups = class {
|
|
|
2520
2673
|
markSurveyAnswered(surveyId) {
|
|
2521
2674
|
this.answeredSurveys.add(surveyId);
|
|
2522
2675
|
}
|
|
2523
|
-
/**
|
|
2676
|
+
/** Fetch al servidor para obtener popups */
|
|
2524
2677
|
async fetchPopupsFromServer() {
|
|
2525
|
-
|
|
2526
|
-
|
|
2678
|
+
const apiKey = this.config?.apiKey;
|
|
2679
|
+
const baseUrl = this.baseUrl;
|
|
2680
|
+
if (!apiKey || !baseUrl) {
|
|
2681
|
+
this.log("Missing apiKey or baseUrl. Skipping popups fetch.");
|
|
2682
|
+
return [];
|
|
2683
|
+
}
|
|
2684
|
+
const endpoint = `${baseUrl}/sdk/${encodeURIComponent(apiKey)}/popups`;
|
|
2685
|
+
try {
|
|
2686
|
+
const response = await fetch(endpoint);
|
|
2687
|
+
if (!response.ok) {
|
|
2688
|
+
this.log("Failed to fetch popups", response.status, response.statusText);
|
|
2689
|
+
return [];
|
|
2690
|
+
}
|
|
2691
|
+
const raw = await response.text();
|
|
2692
|
+
const parsed = JSON.parse(raw);
|
|
2693
|
+
if (!Array.isArray(parsed)) {
|
|
2694
|
+
this.log("Unexpected popups payload", parsed);
|
|
2695
|
+
return [];
|
|
2696
|
+
}
|
|
2697
|
+
console.log("res: ", parsed, this.validatePopupDefinitions(parsed));
|
|
2698
|
+
return parsed;
|
|
2699
|
+
} catch (error) {
|
|
2700
|
+
this.log("Error fetching popups", error);
|
|
2701
|
+
return [];
|
|
2702
|
+
}
|
|
2527
2703
|
}
|
|
2528
|
-
/**
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
},
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2704
|
+
/** Notifica eventos de popup a la API */
|
|
2705
|
+
async postPopupEvent(status, popupId, userId) {
|
|
2706
|
+
const apiKey = this.config?.apiKey;
|
|
2707
|
+
const baseUrl = this.baseUrl;
|
|
2708
|
+
if (!apiKey || !baseUrl) {
|
|
2709
|
+
return;
|
|
2710
|
+
}
|
|
2711
|
+
const endpoint = `${baseUrl}/sdk/popups`;
|
|
2712
|
+
try {
|
|
2713
|
+
const response = await fetch(endpoint, {
|
|
2714
|
+
method: "POST",
|
|
2715
|
+
headers: { "Content-Type": "application/json" },
|
|
2716
|
+
body: JSON.stringify({
|
|
2717
|
+
publicKey: apiKey,
|
|
2718
|
+
status,
|
|
2719
|
+
popupId,
|
|
2720
|
+
userId: userId || void 0
|
|
2721
|
+
})
|
|
2722
|
+
});
|
|
2723
|
+
if (!response.ok) {
|
|
2724
|
+
this.log("Failed to post popup event", response.status, response.statusText);
|
|
2544
2725
|
}
|
|
2545
|
-
|
|
2726
|
+
} catch (error) {
|
|
2727
|
+
this.log("Error posting popup event", error);
|
|
2728
|
+
}
|
|
2546
2729
|
}
|
|
2547
2730
|
/** Add an event listener */
|
|
2548
2731
|
on(eventType, listener) {
|
|
@@ -2582,11 +2765,26 @@ var DeepdotsPopups = class {
|
|
|
2582
2765
|
/** Render the popup UI */
|
|
2583
2766
|
renderPopup(surveyId, productId, actions) {
|
|
2584
2767
|
if (this.renderer) {
|
|
2585
|
-
this.renderer.show(
|
|
2768
|
+
this.renderer.show(
|
|
2769
|
+
surveyId,
|
|
2770
|
+
productId,
|
|
2771
|
+
actions,
|
|
2772
|
+
(type, id, payload) => this.emitEvent(type, id, payload),
|
|
2773
|
+
() => this.hidePopup(),
|
|
2774
|
+
this.env
|
|
2775
|
+
);
|
|
2586
2776
|
return;
|
|
2587
2777
|
}
|
|
2588
2778
|
if (!this.popupContainer) return;
|
|
2589
|
-
renderPopup(
|
|
2779
|
+
renderPopup(
|
|
2780
|
+
this.popupContainer,
|
|
2781
|
+
surveyId,
|
|
2782
|
+
productId,
|
|
2783
|
+
actions,
|
|
2784
|
+
(type, id, payload) => this.emitEvent(type, id, payload),
|
|
2785
|
+
() => this.hidePopup(),
|
|
2786
|
+
this.env
|
|
2787
|
+
);
|
|
2590
2788
|
}
|
|
2591
2789
|
/** Hide the popup */
|
|
2592
2790
|
hidePopup() {
|
|
@@ -2606,6 +2804,16 @@ var DeepdotsPopups = class {
|
|
|
2606
2804
|
if (type === "survey_completed") {
|
|
2607
2805
|
this.markSurveyAnswered(surveyId);
|
|
2608
2806
|
}
|
|
2807
|
+
if (type === "popup_shown" || type === "survey_completed") {
|
|
2808
|
+
const popupIdFromData = data?.popupId;
|
|
2809
|
+
const popupId = popupIdFromData || this.surveyToPopupId.get(surveyId);
|
|
2810
|
+
if (popupId) {
|
|
2811
|
+
const userIdFromData = data?.userId;
|
|
2812
|
+
void this.postPopupEvent(type === "popup_shown" ? "opened" : "completed", popupId, userIdFromData || this.config?.userId);
|
|
2813
|
+
} else {
|
|
2814
|
+
this.debug("No popupId available to post event", { type, surveyId });
|
|
2815
|
+
}
|
|
2816
|
+
}
|
|
2609
2817
|
const listeners = this.listeners.get(type);
|
|
2610
2818
|
if (listeners) {
|
|
2611
2819
|
listeners.forEach((listener) => {
|
|
@@ -2638,10 +2846,26 @@ var DeepdotsPopups = class {
|
|
|
2638
2846
|
isPopupDefinition(value) {
|
|
2639
2847
|
if (typeof value !== "object" || value === null) return false;
|
|
2640
2848
|
const v = value;
|
|
2641
|
-
|
|
2849
|
+
const trigger = v.triggers || v.triggers;
|
|
2850
|
+
if (!trigger) return false;
|
|
2851
|
+
return typeof v.id === "string" && typeof v.title === "string" && typeof v.message === "string" && typeof v.surveyId === "string" && typeof v.productId === "string";
|
|
2852
|
+
}
|
|
2853
|
+
normalizePopupDefinition(def) {
|
|
2854
|
+
if (typeof def !== "object" || def === null) return null;
|
|
2855
|
+
const raw = def;
|
|
2856
|
+
const trigger = raw.triggers || raw.triggers;
|
|
2857
|
+
if (!trigger) return null;
|
|
2858
|
+
const condition = trigger.condition ?? raw.conditions ?? [];
|
|
2859
|
+
return {
|
|
2860
|
+
...raw,
|
|
2861
|
+
triggers: {
|
|
2862
|
+
...trigger,
|
|
2863
|
+
condition
|
|
2864
|
+
}
|
|
2865
|
+
};
|
|
2642
2866
|
}
|
|
2643
2867
|
validatePopupDefinitions(defs) {
|
|
2644
|
-
return defs.filter((
|
|
2868
|
+
return defs.map((def) => this.normalizePopupDefinition(def)).filter((def) => !!def && this.isPopupDefinition(def));
|
|
2645
2869
|
}
|
|
2646
2870
|
};
|
|
2647
2871
|
export {
|