@magicfeedback/popup-sdk 1.0.9 → 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/dist/index.js CHANGED
@@ -1787,7 +1787,7 @@ function ensureResponsiveStyles(popup) {
1787
1787
  `;
1788
1788
  popup.appendChild(style);
1789
1789
  }
1790
- async function renderPopup(container, surveyId, productId, actions, emit, onClose) {
1790
+ async function renderPopup(container, surveyId, productId, actions, emit, onClose, env = "production") {
1791
1791
  let surveyCompletedEmitted = false;
1792
1792
  let stylesInjected = false;
1793
1793
  const popup = document.createElement("div");
@@ -1812,7 +1812,7 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
1812
1812
  closeBtn.type = "button";
1813
1813
  closeBtn.setAttribute("aria-label", "Close popup");
1814
1814
  closeBtn.innerHTML = `
1815
- <svg width="28" height="28" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
1815
+ <svg width="28" height="28" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
1816
1816
  <path d="M6 6L18 18M6 18L18 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
1817
1817
  </svg>
1818
1818
  `;
@@ -1863,6 +1863,20 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
1863
1863
  main.style.cssText = "display:flex; flex-direction:column; width:100%; max-height:80vh; overflow-y:auto;";
1864
1864
  const formWrapper = document.createElement("div");
1865
1865
  formWrapper.style.cssText = "width:100%; flex: 1 1 auto;";
1866
+ const errorHint = document.createElement("div");
1867
+ errorHint.className = "deepdots-error-hint";
1868
+ errorHint.style.cssText = `
1869
+ display: none;
1870
+ margin: 12px 0 0 0;
1871
+ padding: 10px 12px;
1872
+ border-radius: 6px;
1873
+ background: #FEF3C7; /* amber-100 */
1874
+ color: #92400E; /* amber-700 */
1875
+ border: 1px solid #FCD34D; /* amber-300 */
1876
+ font-size: 13px;
1877
+ `;
1878
+ errorHint.setAttribute("role", "alert");
1879
+ errorHint.setAttribute("aria-live", "polite");
1866
1880
  const spinnerEl = document.createElement("div");
1867
1881
  spinnerEl.className = "mf-spinner";
1868
1882
  spinnerEl.setAttribute("role", "status");
@@ -1876,6 +1890,7 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
1876
1890
  formWrapper.appendChild(spinnerEl);
1877
1891
  formWrapper.appendChild(formHost);
1878
1892
  main.appendChild(formWrapper);
1893
+ main.appendChild(errorHint);
1879
1894
  const footer = document.createElement("div");
1880
1895
  footer.className = "deepdots-popup-footer";
1881
1896
  footer.setAttribute("data-actions-wrapper", "true");
@@ -2020,7 +2035,6 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
2020
2035
  setLoading(false);
2021
2036
  break;
2022
2037
  case "error":
2023
- closeButton.style.display = "inline-flex";
2024
2038
  setLoading(false);
2025
2039
  break;
2026
2040
  }
@@ -2057,13 +2071,13 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
2057
2071
  setLoading(false);
2058
2072
  return;
2059
2073
  }
2060
- import_native.default.init({ debug: true, env: "prod" });
2074
+ import_native.default.init({ debug: true, env: env === "production" ? "prod" : "dev" });
2061
2075
  formInstance = import_native.default.form(surveyId, productId);
2062
2076
  const generateOptions = {
2063
2077
  addButton: false,
2064
2078
  getMetaData: true
2065
2079
  };
2066
- generateOptions.onLoadedEvent = ({ formData, progress }) => {
2080
+ generateOptions.onLoadedEvent = ({ formData }) => {
2067
2081
  try {
2068
2082
  } catch (e) {
2069
2083
  }
@@ -2149,11 +2163,23 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
2149
2163
  emit("popup_clicked", surveyId, { action: "before_submit" });
2150
2164
  };
2151
2165
  generateOptions.afterSubmitEvent = ({ error, completed, total, progress }) => {
2152
- if (error) {
2153
- emit("popup_clicked", surveyId, { action: "submit_error", error });
2154
- updateButtons("error");
2166
+ const errText = error ? typeof error === "string" ? error : error.message ?? String(error) : "";
2167
+ if (errText) {
2168
+ setLoading(false);
2169
+ if (errText.toLowerCase().includes("no response")) {
2170
+ errorHint.textContent = "Please answer the required question to continue.";
2171
+ errorHint.style.display = "block";
2172
+ emit("popup_clicked", surveyId, { action: "validation_error_required" });
2173
+ updateButtons("in_progress_next");
2174
+ return;
2175
+ }
2176
+ errorHint.textContent = "An error occurred while submitting. Please try again or close the popup.";
2177
+ errorHint.style.display = "block";
2178
+ emit("popup_clicked", surveyId, { action: "submit_error", error: errText });
2155
2179
  return;
2156
2180
  }
2181
+ errorHint.style.display = "none";
2182
+ setLoading(false);
2157
2183
  if (completed) {
2158
2184
  emit("survey_completed", surveyId, { action: "completed" });
2159
2185
  surveyCompletedEmitted = true;
@@ -2196,6 +2222,9 @@ function setupTrigger(popups, trigger) {
2196
2222
  case "exit":
2197
2223
  setupExitTrigger(popups, trigger);
2198
2224
  break;
2225
+ case "click":
2226
+ setupClickTrigger(popups, trigger);
2227
+ break;
2199
2228
  }
2200
2229
  }
2201
2230
  function setupTimeTrigger(popups, trigger) {
@@ -2218,23 +2247,120 @@ function setupScrollTrigger(popups, trigger) {
2218
2247
  popups.debug(`Scroll trigger set for ${threshold}%`);
2219
2248
  }
2220
2249
  function setupExitTrigger(popups, trigger) {
2221
- const handler = (e) => {
2222
- if (e.clientY <= 0) {
2223
- popups.triggerSurvey(trigger.surveyId);
2224
- document.removeEventListener("mouseout", handler);
2250
+ let fired = false;
2251
+ let lastUrl = typeof window !== "undefined" ? window.location.href : "";
2252
+ const historyRef = typeof window !== "undefined" ? window.history : null;
2253
+ const originalPushState = historyRef ? historyRef.pushState.bind(historyRef) : null;
2254
+ const originalReplaceState = historyRef ? historyRef.replaceState.bind(historyRef) : null;
2255
+ const cleanup = () => {
2256
+ document.removeEventListener("click", handleNavClick, true);
2257
+ window.removeEventListener("popstate", handlePopState);
2258
+ if (historyRef && originalPushState) historyRef.pushState = originalPushState;
2259
+ if (historyRef && originalReplaceState) historyRef.replaceState = originalReplaceState;
2260
+ };
2261
+ const fireOnce = () => {
2262
+ if (fired) return;
2263
+ fired = true;
2264
+ popups.triggerSurvey(trigger.surveyId);
2265
+ cleanup();
2266
+ };
2267
+ const handleNavClick = (e) => {
2268
+ if (fired) return;
2269
+ if (e.defaultPrevented) return;
2270
+ if (e.button !== 0) return;
2271
+ if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
2272
+ const target = e.target?.closest?.("a");
2273
+ if (!target) return;
2274
+ const href = target.getAttribute("href");
2275
+ if (!href || href.startsWith("#")) return;
2276
+ const targetAttr = target.getAttribute("target");
2277
+ if (targetAttr && targetAttr !== "_self") return;
2278
+ let url;
2279
+ try {
2280
+ url = new URL(href, window.location.href);
2281
+ } catch {
2282
+ return;
2283
+ }
2284
+ if (url.origin !== window.location.origin) return;
2285
+ e.preventDefault();
2286
+ fireOnce();
2287
+ };
2288
+ const shouldBlockUrl = (rawUrl) => {
2289
+ if (!rawUrl) return false;
2290
+ let url;
2291
+ try {
2292
+ url = rawUrl instanceof URL ? rawUrl : new URL(rawUrl, window.location.href);
2293
+ } catch {
2294
+ return false;
2295
+ }
2296
+ if (url.origin !== window.location.origin) return false;
2297
+ if (url.href === window.location.href) return false;
2298
+ return true;
2299
+ };
2300
+ const handlePopState = () => {
2301
+ if (fired) return;
2302
+ fireOnce();
2303
+ if (historyRef && originalPushState && lastUrl) {
2304
+ originalPushState(null, document.title, lastUrl);
2225
2305
  }
2226
2306
  };
2227
- document.addEventListener("mouseout", handler);
2228
- popups.debug("Exit intent trigger set");
2307
+ if (historyRef && originalPushState && originalReplaceState) {
2308
+ historyRef.pushState = function(data, unused, url) {
2309
+ if (!fired && shouldBlockUrl(url)) {
2310
+ fireOnce();
2311
+ return;
2312
+ }
2313
+ const result = originalPushState(data, unused, url);
2314
+ lastUrl = window.location.href;
2315
+ return result;
2316
+ };
2317
+ historyRef.replaceState = function(data, unused, url) {
2318
+ if (!fired && shouldBlockUrl(url)) {
2319
+ fireOnce();
2320
+ return;
2321
+ }
2322
+ const result = originalReplaceState(data, unused, url);
2323
+ lastUrl = window.location.href;
2324
+ return result;
2325
+ };
2326
+ }
2327
+ document.addEventListener("click", handleNavClick, true);
2328
+ window.addEventListener("popstate", handlePopState);
2329
+ popups.debug("Exit intent trigger set (navigation/spa)");
2330
+ }
2331
+ function setupClickTrigger(popups, trigger) {
2332
+ const targetId = typeof trigger.value === "string" ? trigger.value : "";
2333
+ if (!targetId) {
2334
+ popups.debug("Click trigger missing element id", trigger);
2335
+ return;
2336
+ }
2337
+ const attach = () => {
2338
+ const el = document.getElementById(targetId);
2339
+ if (!el) {
2340
+ popups.debug("Click trigger target not found", targetId);
2341
+ return false;
2342
+ }
2343
+ const handler = (e) => {
2344
+ if (e.defaultPrevented) return;
2345
+ popups.triggerSurvey(trigger.surveyId);
2346
+ el.removeEventListener("click", handler);
2347
+ };
2348
+ el.addEventListener("click", handler);
2349
+ popups.debug(`Click trigger set for #${targetId}`);
2350
+ return true;
2351
+ };
2352
+ if (typeof document === "undefined") return;
2353
+ if (attach()) return;
2354
+ window.addEventListener("DOMContentLoaded", () => attach(), { once: true });
2229
2355
  }
2230
2356
 
2231
2357
  // src/config/env.ts
2232
2358
  var ENVIRONMENT_MAP = {
2233
2359
  development: {
2234
- apiBaseUrl: "https://api-dev.magicfeedback.com"
2360
+ apiBaseUrl: "https://api-dev.deepdots.com"
2235
2361
  },
2236
2362
  production: {
2237
- apiBaseUrl: "https://api.magicfeedback.com"
2363
+ apiBaseUrl: "https://api.deepdots.com"
2238
2364
  }
2239
2365
  };
2240
2366
  function resolveEnvironment(nodeEnv) {
@@ -2316,10 +2442,10 @@ var BrowserPopupRenderer = class {
2316
2442
  document.body.appendChild(this.container);
2317
2443
  }
2318
2444
  }
2319
- show(surveyId, productId, actions, emit, onClose) {
2445
+ show(surveyId, productId, actions, emit, onClose, env = "production") {
2320
2446
  if (!this.container) this.init();
2321
2447
  if (!this.container) return;
2322
- renderPopup(this.container, surveyId, productId, actions, emit, onClose);
2448
+ renderPopup(this.container, surveyId, productId, actions, emit, onClose, env);
2323
2449
  }
2324
2450
  hide() {
2325
2451
  if (this.container) {
@@ -2352,8 +2478,12 @@ var DeepdotsPopups = class {
2352
2478
  this.pendingAutoLaunch = false;
2353
2479
  this.answeredSurveys = /* @__PURE__ */ new Set();
2354
2480
  this.lastShown = /* @__PURE__ */ new Map();
2481
+ // popupId -> timestamp mostrado
2482
+ this.surveyToPopupId = /* @__PURE__ */ new Map();
2483
+ // surveyId -> popupId
2484
+ this.baseUrl = "";
2485
+ this.env = "production";
2355
2486
  }
2356
- // popupId -> timestamp mostrado
2357
2487
  /** Initialize the SDK with configuration */
2358
2488
  init(config) {
2359
2489
  if (this.initialized) {
@@ -2361,12 +2491,14 @@ var DeepdotsPopups = class {
2361
2491
  return;
2362
2492
  }
2363
2493
  const env = resolveEnvironment(config.nodeEnv);
2494
+ this.baseUrl = env.apiBaseUrl;
2495
+ this.env = config.nodeEnv || "production";
2364
2496
  this.config = {
2365
2497
  apiKey: config.apiKey || void 0,
2366
- baseUrl: env.apiBaseUrl,
2367
2498
  mode: config.mode || "client",
2368
2499
  debug: config.debug || false,
2369
- popups: config.popups || []
2500
+ popups: config.popups || [],
2501
+ userId: config.userId || void 0
2370
2502
  };
2371
2503
  this.initialized = true;
2372
2504
  this.log("SDK initialized", this.config);
@@ -2415,8 +2547,9 @@ var DeepdotsPopups = class {
2415
2547
  if (isDefinition) {
2416
2548
  const def = options;
2417
2549
  this.log("Showing popup (definition)", def);
2550
+ this.surveyToPopupId.set(def.surveyId, def.id);
2418
2551
  this.renderPopup(def.surveyId, def.productId, def.actions);
2419
- this.emitEvent("popup_shown", def.surveyId);
2552
+ this.emitEvent("popup_shown", def.surveyId, { popupId: def.id });
2420
2553
  } else {
2421
2554
  const opt = options;
2422
2555
  this.log("Showing popup (legacy options)", opt);
@@ -2445,9 +2578,10 @@ var DeepdotsPopups = class {
2445
2578
  configureTriggersFromDefinitions() {
2446
2579
  const derived = [];
2447
2580
  const validDefs = this.validatePopupDefinitions(this.popupDefinitions);
2581
+ console.log("validDefs", validDefs);
2448
2582
  validDefs.forEach((def) => {
2449
- if (!def.trigger) return;
2450
- const t = def.trigger;
2583
+ if (!def.triggers) return;
2584
+ const t = def.triggers;
2451
2585
  let type;
2452
2586
  switch (t.type) {
2453
2587
  case "time_on_page":
@@ -2459,11 +2593,14 @@ var DeepdotsPopups = class {
2459
2593
  case "exit":
2460
2594
  type = "exit";
2461
2595
  break;
2596
+ case "click":
2597
+ type = "click";
2598
+ break;
2462
2599
  default:
2463
2600
  this.debug("Unsupported trigger type", t.type);
2464
2601
  return;
2465
2602
  }
2466
- const value = type === "time" ? t.value * 1e3 : t.value;
2603
+ const value = type === "time" && typeof t.value === "number" ? t.value * 1e3 : t.value;
2467
2604
  derived.push({ type, value, surveyId: def.surveyId });
2468
2605
  });
2469
2606
  if (derived.length) {
@@ -2485,10 +2622,52 @@ var DeepdotsPopups = class {
2485
2622
  this.lastShown.set(def.id, Date.now());
2486
2623
  }
2487
2624
  shouldShow(def) {
2488
- const conditions = def.trigger.condition || [];
2625
+ if (!this.matchesSegmentsPath(def)) {
2626
+ return false;
2627
+ }
2628
+ const conditions = def.triggers.condition || [];
2489
2629
  if (!conditions.length) return true;
2490
2630
  return conditions.every((c) => this.evaluateCondition(def, c));
2491
2631
  }
2632
+ matchesSegmentsPath(def) {
2633
+ const paths = def.segments?.path;
2634
+ if (!paths || paths.length === 0) return true;
2635
+ if (typeof window === "undefined" || !window.location) {
2636
+ this.debug("No window.location available for path comparison", { popupId: def.id, paths });
2637
+ return true;
2638
+ }
2639
+ const currentPath = window.location.pathname || "";
2640
+ const currentHref = window.location.href || "";
2641
+ const normalize = (value) => {
2642
+ if (value.length > 1 && value.endsWith("/")) return value.slice(0, -1);
2643
+ return value;
2644
+ };
2645
+ const normalizedPath = normalize(currentPath);
2646
+ const normalizedHref = normalize(currentHref);
2647
+ const matches = paths.some((rawCandidate) => {
2648
+ const candidate = normalize(rawCandidate);
2649
+ let match = false;
2650
+ if (candidate.startsWith("http://") || candidate.startsWith("https://")) {
2651
+ match = normalizedHref === candidate;
2652
+ } else if (candidate.startsWith("/")) {
2653
+ match = normalizedHref.includes(candidate);
2654
+ } else {
2655
+ match = normalizedPath === candidate;
2656
+ }
2657
+ this.debug("Path comparison", {
2658
+ popupId: def.id,
2659
+ candidate,
2660
+ currentPath: normalizedPath,
2661
+ currentHref: normalizedHref,
2662
+ match
2663
+ });
2664
+ return match;
2665
+ });
2666
+ if (!matches) {
2667
+ this.debug("No path match for popup", { popupId: def.id, paths, currentPath: normalizedPath });
2668
+ }
2669
+ return matches;
2670
+ }
2492
2671
  evaluateCondition(def, condition) {
2493
2672
  if (!condition.answered && this.answeredSurveys.has(def.surveyId)) {
2494
2673
  return false;
@@ -2507,29 +2686,59 @@ var DeepdotsPopups = class {
2507
2686
  markSurveyAnswered(surveyId) {
2508
2687
  this.answeredSurveys.add(surveyId);
2509
2688
  }
2510
- /** Simula fetch al servidor para obtener popups */
2689
+ /** Fetch al servidor para obtener popups */
2511
2690
  async fetchPopupsFromServer() {
2512
- await new Promise((res) => setTimeout(res, 50));
2513
- return this.generateFakePopups();
2691
+ const apiKey = this.config?.apiKey;
2692
+ const baseUrl = this.baseUrl;
2693
+ if (!apiKey || !baseUrl) {
2694
+ this.log("Missing apiKey or baseUrl. Skipping popups fetch.");
2695
+ return [];
2696
+ }
2697
+ const endpoint = `${baseUrl}/sdk/${encodeURIComponent(apiKey)}/popups`;
2698
+ try {
2699
+ const response = await fetch(endpoint);
2700
+ if (!response.ok) {
2701
+ this.log("Failed to fetch popups", response.status, response.statusText);
2702
+ return [];
2703
+ }
2704
+ const raw = await response.text();
2705
+ const parsed = JSON.parse(raw);
2706
+ if (!Array.isArray(parsed)) {
2707
+ this.log("Unexpected popups payload", parsed);
2708
+ return [];
2709
+ }
2710
+ console.log("res: ", parsed, this.validatePopupDefinitions(parsed));
2711
+ return parsed;
2712
+ } catch (error) {
2713
+ this.log("Error fetching popups", error);
2714
+ return [];
2715
+ }
2514
2716
  }
2515
- /** Genera datos fake para pruebas en modo server */
2516
- generateFakePopups() {
2517
- return [
2518
- {
2519
- id: "popup-123",
2520
- title: "Would you like to help us improve?",
2521
- message: "<p>Take a quick survey and share your thoughts.</p>",
2522
- trigger: { type: "time_on_page", value: 1, condition: [{ answered: false, cooldownDays: 7 }] },
2523
- actions: {
2524
- accept: { label: "Take Survey", surveyId: "survey-abc" },
2525
- decline: { label: "Not Now", cooldownDays: 7 }
2526
- },
2527
- surveyId: "survey-abc",
2528
- productId: "product-xyz",
2529
- style: { theme: "light", position: "bottom-right", imageUrl: null },
2530
- segments: { lang: ["en"], path: ["/checkout"] }
2717
+ /** Notifica eventos de popup a la API */
2718
+ async postPopupEvent(status, popupId, userId) {
2719
+ const apiKey = this.config?.apiKey;
2720
+ const baseUrl = this.baseUrl;
2721
+ if (!apiKey || !baseUrl) {
2722
+ return;
2723
+ }
2724
+ const endpoint = `${baseUrl}/sdk/popups`;
2725
+ try {
2726
+ const response = await fetch(endpoint, {
2727
+ method: "POST",
2728
+ headers: { "Content-Type": "application/json" },
2729
+ body: JSON.stringify({
2730
+ publicKey: apiKey,
2731
+ status,
2732
+ popupId,
2733
+ userId: userId || void 0
2734
+ })
2735
+ });
2736
+ if (!response.ok) {
2737
+ this.log("Failed to post popup event", response.status, response.statusText);
2531
2738
  }
2532
- ];
2739
+ } catch (error) {
2740
+ this.log("Error posting popup event", error);
2741
+ }
2533
2742
  }
2534
2743
  /** Add an event listener */
2535
2744
  on(eventType, listener) {
@@ -2569,11 +2778,26 @@ var DeepdotsPopups = class {
2569
2778
  /** Render the popup UI */
2570
2779
  renderPopup(surveyId, productId, actions) {
2571
2780
  if (this.renderer) {
2572
- this.renderer.show(surveyId, productId, actions, (type, id, payload) => this.emitEvent(type, id, payload), () => this.hidePopup());
2781
+ this.renderer.show(
2782
+ surveyId,
2783
+ productId,
2784
+ actions,
2785
+ (type, id, payload) => this.emitEvent(type, id, payload),
2786
+ () => this.hidePopup(),
2787
+ this.env
2788
+ );
2573
2789
  return;
2574
2790
  }
2575
2791
  if (!this.popupContainer) return;
2576
- renderPopup(this.popupContainer, surveyId, productId, actions, (type, id, payload) => this.emitEvent(type, id, payload), () => this.hidePopup());
2792
+ renderPopup(
2793
+ this.popupContainer,
2794
+ surveyId,
2795
+ productId,
2796
+ actions,
2797
+ (type, id, payload) => this.emitEvent(type, id, payload),
2798
+ () => this.hidePopup(),
2799
+ this.env
2800
+ );
2577
2801
  }
2578
2802
  /** Hide the popup */
2579
2803
  hidePopup() {
@@ -2593,6 +2817,16 @@ var DeepdotsPopups = class {
2593
2817
  if (type === "survey_completed") {
2594
2818
  this.markSurveyAnswered(surveyId);
2595
2819
  }
2820
+ if (type === "popup_shown" || type === "survey_completed") {
2821
+ const popupIdFromData = data?.popupId;
2822
+ const popupId = popupIdFromData || this.surveyToPopupId.get(surveyId);
2823
+ if (popupId) {
2824
+ const userIdFromData = data?.userId;
2825
+ void this.postPopupEvent(type === "popup_shown" ? "opened" : "completed", popupId, userIdFromData || this.config?.userId);
2826
+ } else {
2827
+ this.debug("No popupId available to post event", { type, surveyId });
2828
+ }
2829
+ }
2596
2830
  const listeners = this.listeners.get(type);
2597
2831
  if (listeners) {
2598
2832
  listeners.forEach((listener) => {
@@ -2625,10 +2859,26 @@ var DeepdotsPopups = class {
2625
2859
  isPopupDefinition(value) {
2626
2860
  if (typeof value !== "object" || value === null) return false;
2627
2861
  const v = value;
2628
- return typeof v.id === "string" && typeof v.title === "string" && typeof v.message === "string" && typeof v.surveyId === "string" && typeof v.productId === "string" && !!v.trigger;
2862
+ const trigger = v.triggers || v.triggers;
2863
+ if (!trigger) return false;
2864
+ return typeof v.id === "string" && typeof v.title === "string" && typeof v.message === "string" && typeof v.surveyId === "string" && typeof v.productId === "string";
2865
+ }
2866
+ normalizePopupDefinition(def) {
2867
+ if (typeof def !== "object" || def === null) return null;
2868
+ const raw = def;
2869
+ const trigger = raw.triggers || raw.triggers;
2870
+ if (!trigger) return null;
2871
+ const condition = trigger.condition ?? raw.conditions ?? [];
2872
+ return {
2873
+ ...raw,
2874
+ triggers: {
2875
+ ...trigger,
2876
+ condition
2877
+ }
2878
+ };
2629
2879
  }
2630
2880
  validatePopupDefinitions(defs) {
2631
- return defs.filter((d) => this.isPopupDefinition(d));
2881
+ return defs.map((def) => this.normalizePopupDefinition(def)).filter((def) => !!def && this.isPopupDefinition(def));
2632
2882
  }
2633
2883
  };
2634
2884
  //# sourceMappingURL=index.js.map