@magicfeedback/popup-sdk 1.1.4 → 1.1.6
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/assets/assets/style.css +10 -1
- package/dist/{chunk-IOAZQPZE.mjs → chunk-4UXOEIAB.mjs} +54 -2
- package/dist/chunk-4UXOEIAB.mjs.map +1 -0
- package/dist/{chunk-6WTOQGET.mjs → chunk-XOTM5CHX.mjs} +54 -2
- package/dist/chunk-XOTM5CHX.mjs.map +1 -0
- package/dist/index.d.mts +27 -2
- package/dist/index.d.ts +27 -2
- package/dist/index.js +118 -16
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +27 -15
- package/dist/index.mjs.map +1 -1
- package/dist/react-native.d.mts +25 -1
- package/dist/react-native.d.ts +25 -1
- package/dist/react-native.js +118 -16
- package/dist/react-native.js.map +1 -1
- package/dist/react-native.mjs +27 -15
- package/dist/react-native.mjs.map +1 -1
- package/dist/{renderPopup-YLFRGPQN.mjs → renderPopup-EZKDMLVZ.mjs} +42 -8
- package/dist/renderPopup-EZKDMLVZ.mjs.map +1 -0
- package/dist/{renderPopup-KBDWWSUU.mjs → renderPopup-PS3NJDUR.mjs} +42 -8
- package/dist/renderPopup-PS3NJDUR.mjs.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-6WTOQGET.mjs.map +0 -1
- package/dist/chunk-IOAZQPZE.mjs.map +0 -1
- package/dist/renderPopup-KBDWWSUU.mjs.map +0 -1
- package/dist/renderPopup-YLFRGPQN.mjs.map +0 -1
package/dist/index.js
CHANGED
|
@@ -144,6 +144,64 @@ var init_tracking_manager = __esm({
|
|
|
144
144
|
}
|
|
145
145
|
});
|
|
146
146
|
|
|
147
|
+
// src/ui/font.ts
|
|
148
|
+
function fontFormatFromUrl(url) {
|
|
149
|
+
const clean = url.split("?")[0].split("#")[0];
|
|
150
|
+
const ext = clean.slice(clean.lastIndexOf(".") + 1).toLowerCase();
|
|
151
|
+
return FORMAT_BY_EXT[ext];
|
|
152
|
+
}
|
|
153
|
+
function sanitizeFamily(family) {
|
|
154
|
+
return family.replace(/[^A-Za-z0-9 ._-]/g, "").trim();
|
|
155
|
+
}
|
|
156
|
+
function isSafeFontUrl(url) {
|
|
157
|
+
if (!/^(https?:|data:)/i.test(url)) return false;
|
|
158
|
+
return !/[\x00-\x20"<>\\]/.test(url);
|
|
159
|
+
}
|
|
160
|
+
function buildFontFamilyValue(family) {
|
|
161
|
+
const safe = sanitizeFamily(family);
|
|
162
|
+
return `"${safe}", -apple-system, system-ui, sans-serif`;
|
|
163
|
+
}
|
|
164
|
+
function buildFontFaceCss(family, url) {
|
|
165
|
+
if (!url || !isSafeFontUrl(url)) return "";
|
|
166
|
+
const safe = sanitizeFamily(family);
|
|
167
|
+
const fmt = fontFormatFromUrl(url);
|
|
168
|
+
const src = fmt ? `url("${url}") format("${fmt}")` : `url("${url}")`;
|
|
169
|
+
return `@font-face{font-family:"${safe}";src:${src};font-display:swap;}`;
|
|
170
|
+
}
|
|
171
|
+
var FORMAT_BY_EXT;
|
|
172
|
+
var init_font = __esm({
|
|
173
|
+
"src/ui/font.ts"() {
|
|
174
|
+
"use strict";
|
|
175
|
+
FORMAT_BY_EXT = {
|
|
176
|
+
woff2: "woff2",
|
|
177
|
+
woff: "woff",
|
|
178
|
+
ttf: "truetype",
|
|
179
|
+
otf: "opentype"
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// src/util/logger.ts
|
|
185
|
+
function setLogger(logger) {
|
|
186
|
+
active = logger ?? console;
|
|
187
|
+
}
|
|
188
|
+
function sdkLog(...args) {
|
|
189
|
+
active.log(...args);
|
|
190
|
+
}
|
|
191
|
+
function sdkWarn(...args) {
|
|
192
|
+
(active.warn ?? active.log)(...args);
|
|
193
|
+
}
|
|
194
|
+
function sdkError(...args) {
|
|
195
|
+
(active.error ?? active.log)(...args);
|
|
196
|
+
}
|
|
197
|
+
var active;
|
|
198
|
+
var init_logger = __esm({
|
|
199
|
+
"src/util/logger.ts"() {
|
|
200
|
+
"use strict";
|
|
201
|
+
active = console;
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
|
|
147
205
|
// node_modules/@magicfeedback/native/dist/magicfeedback-sdk.browser.js
|
|
148
206
|
var require_magicfeedback_sdk_browser = __commonJS({
|
|
149
207
|
"node_modules/@magicfeedback/native/dist/magicfeedback-sdk.browser.js"(exports, module2) {
|
|
@@ -2213,13 +2271,22 @@ var init_style = __esm({
|
|
|
2213
2271
|
padding: 0;
|
|
2214
2272
|
font-weight: 900;
|
|
2215
2273
|
color: #222;
|
|
2216
|
-
font-family: 'Montserrat';
|
|
2274
|
+
font-family: var(--deepdots-font, 'Montserrat');
|
|
2217
2275
|
font-size: 18px;
|
|
2218
2276
|
text-transform: uppercase;
|
|
2219
2277
|
text-align: center;
|
|
2220
2278
|
margin-bottom: 40px;
|
|
2221
2279
|
}
|
|
2222
2280
|
|
|
2281
|
+
/* Los controles de formulario no heredan font-family por defecto: cuando hay
|
|
2282
|
+
fuente custom (clase deepdots-has-font), los forzamos a usar la del contenedor. */
|
|
2283
|
+
.deepdots-popup.deepdots-has-font button,
|
|
2284
|
+
.deepdots-popup.deepdots-has-font input,
|
|
2285
|
+
.deepdots-popup.deepdots-has-font textarea,
|
|
2286
|
+
.deepdots-popup.deepdots-has-font select {
|
|
2287
|
+
font-family: var(--deepdots-font, inherit);
|
|
2288
|
+
}
|
|
2289
|
+
|
|
2223
2290
|
.deepdots-popup h6 {
|
|
2224
2291
|
margin-bottom: 1rem;
|
|
2225
2292
|
}
|
|
@@ -2992,6 +3059,18 @@ function ensureResponsiveStyles(_popup) {
|
|
|
2992
3059
|
`;
|
|
2993
3060
|
document.head.appendChild(style);
|
|
2994
3061
|
}
|
|
3062
|
+
function ensureFontFace(family, url) {
|
|
3063
|
+
const css = buildFontFaceCss(family, url);
|
|
3064
|
+
if (!css) return;
|
|
3065
|
+
const STYLE_ID = "deepdots-font-face";
|
|
3066
|
+
let el = document.getElementById(STYLE_ID);
|
|
3067
|
+
if (!el) {
|
|
3068
|
+
el = document.createElement("style");
|
|
3069
|
+
el.id = STYLE_ID;
|
|
3070
|
+
document.head.appendChild(el);
|
|
3071
|
+
}
|
|
3072
|
+
if (el.textContent !== css) el.textContent = css;
|
|
3073
|
+
}
|
|
2995
3074
|
async function renderPopup(container, surveyId, productId, actions, emit, onClose, env = "production", userId, style, sessionId, miniService, analyticsFeedbackSessionId) {
|
|
2996
3075
|
let surveyCompletedEmitted = false;
|
|
2997
3076
|
let stylesInjected = false;
|
|
@@ -3027,6 +3106,14 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
|
|
|
3027
3106
|
width: 90%;
|
|
3028
3107
|
min-height: 200px;
|
|
3029
3108
|
`;
|
|
3109
|
+
const font = style?.font;
|
|
3110
|
+
if (font?.family) {
|
|
3111
|
+
const familyValue = buildFontFamilyValue(font.family);
|
|
3112
|
+
popup.style.fontFamily = familyValue;
|
|
3113
|
+
popup.style.setProperty("--deepdots-font", familyValue);
|
|
3114
|
+
popup.classList.add("deepdots-has-font");
|
|
3115
|
+
if (font.url) ensureFontFace(font.family, font.url);
|
|
3116
|
+
}
|
|
3030
3117
|
const header = document.createElement("div");
|
|
3031
3118
|
header.className = "deepdots-popup-header";
|
|
3032
3119
|
header.style.cssText = "display:flex; justify-content:flex-end; align-items:center; width:100%;";
|
|
@@ -3293,7 +3380,7 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
|
|
|
3293
3380
|
let formInstance = null;
|
|
3294
3381
|
try {
|
|
3295
3382
|
if (!import_native.default || typeof import_native.default.form !== "function") {
|
|
3296
|
-
|
|
3383
|
+
sdkWarn("[MagicFeedback] form() no disponible. Fallback manual.");
|
|
3297
3384
|
setLoading(false);
|
|
3298
3385
|
return;
|
|
3299
3386
|
}
|
|
@@ -3380,7 +3467,7 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
|
|
|
3380
3467
|
}
|
|
3381
3468
|
}
|
|
3382
3469
|
if (s.startMessage && s.startMessage !== "") {
|
|
3383
|
-
|
|
3470
|
+
sdkLog(s.startMessage);
|
|
3384
3471
|
updateButtons("start");
|
|
3385
3472
|
} else {
|
|
3386
3473
|
updateButtons("in_progress_first");
|
|
@@ -3435,11 +3522,11 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
|
|
|
3435
3522
|
}
|
|
3436
3523
|
};
|
|
3437
3524
|
formInstance.generate(formDivId, generateOptions).catch((err) => {
|
|
3438
|
-
|
|
3525
|
+
sdkError("[MagicFeedback] Error generating form:", err);
|
|
3439
3526
|
setLoading(false);
|
|
3440
3527
|
});
|
|
3441
3528
|
} catch (e) {
|
|
3442
|
-
|
|
3529
|
+
sdkError("[MagicFeedback] Exception initializing form:", e);
|
|
3443
3530
|
setLoading(false);
|
|
3444
3531
|
}
|
|
3445
3532
|
}
|
|
@@ -3448,6 +3535,8 @@ var init_renderPopup = __esm({
|
|
|
3448
3535
|
"src/ui/renderPopup.ts"() {
|
|
3449
3536
|
"use strict";
|
|
3450
3537
|
init_tracking_manager();
|
|
3538
|
+
init_font();
|
|
3539
|
+
init_logger();
|
|
3451
3540
|
import_native = __toESM(require_magicfeedback_sdk_browser());
|
|
3452
3541
|
init_style();
|
|
3453
3542
|
}
|
|
@@ -3664,6 +3753,7 @@ function resolveEnvironment(nodeEnv) {
|
|
|
3664
3753
|
init_tracking_manager();
|
|
3665
3754
|
|
|
3666
3755
|
// src/ui/surveyHtml.ts
|
|
3756
|
+
init_font();
|
|
3667
3757
|
function buildSurveyHtml(opts) {
|
|
3668
3758
|
const env = opts.env === "development" ? "dev" : "prod";
|
|
3669
3759
|
const version = opts.version ?? "2.2.4";
|
|
@@ -3672,10 +3762,12 @@ function buildSurveyHtml(opts) {
|
|
|
3672
3762
|
const pid = JSON.stringify(opts.productId);
|
|
3673
3763
|
const profileJson = JSON.stringify(opts.profile ?? []);
|
|
3674
3764
|
const metaJson = JSON.stringify(opts.metadata ?? []);
|
|
3765
|
+
const fontFaceCss = opts.font ? buildFontFaceCss(opts.font.family, opts.font.url) : "";
|
|
3766
|
+
const fontFamilyValue = opts.font ? buildFontFamilyValue(opts.font.family) : "-apple-system,system-ui,sans-serif";
|
|
3675
3767
|
return `<!DOCTYPE html><html><head>
|
|
3676
3768
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
|
3677
3769
|
<meta name="color-scheme" content="light"/>
|
|
3678
|
-
<style
|
|
3770
|
+
<style>${fontFaceCss}html,body{margin:0;padding:0;background:transparent;font-family:${fontFamilyValue}}#mf{width:100%;box-sizing:border-box}#mf *{max-width:100%;box-sizing:border-box}</style>
|
|
3679
3771
|
</head><body>
|
|
3680
3772
|
<div id="mf"></div>
|
|
3681
3773
|
<script>
|
|
@@ -3716,6 +3808,7 @@ function buildSurveyHtml(opts) {
|
|
|
3716
3808
|
}
|
|
3717
3809
|
|
|
3718
3810
|
// src/platform/react-native-renderer.ts
|
|
3811
|
+
init_logger();
|
|
3719
3812
|
var ReactNativePopupRenderer = class {
|
|
3720
3813
|
constructor(options = {}) {
|
|
3721
3814
|
this.options = options;
|
|
@@ -3726,17 +3819,17 @@ var ReactNativePopupRenderer = class {
|
|
|
3726
3819
|
}
|
|
3727
3820
|
init() {
|
|
3728
3821
|
}
|
|
3729
|
-
show(surveyId, productId, _actions, emit, onClose, env = "production", userId,
|
|
3822
|
+
show(surveyId, productId, _actions, emit, onClose, env = "production", userId, style, sessionId, miniService, analyticsFeedbackSessionId) {
|
|
3730
3823
|
this.emitFn = emit;
|
|
3731
3824
|
this.onCloseFn = onClose;
|
|
3732
3825
|
this.currentSurveyId = surveyId;
|
|
3733
3826
|
this.partialEmitted = false;
|
|
3734
3827
|
const { profile, metadata } = buildSurveyIdentity(userId ?? null, sessionId ?? null, miniService ?? null, analyticsFeedbackSessionId ?? null);
|
|
3735
|
-
const html = buildSurveyHtml({ surveyId, productId, env, profile, metadata });
|
|
3828
|
+
const html = buildSurveyHtml({ surveyId, productId, env, profile, metadata, font: style?.font });
|
|
3736
3829
|
if (this.options.onShow) {
|
|
3737
3830
|
this.options.onShow({ surveyId, productId, html });
|
|
3738
3831
|
} else {
|
|
3739
|
-
|
|
3832
|
+
sdkWarn(
|
|
3740
3833
|
"[Deepdots] ReactNativePopupRenderer sin onShow: pasa { onShow } a new ReactNativePopupRenderer({...}) para montar el WebView del survey."
|
|
3741
3834
|
);
|
|
3742
3835
|
}
|
|
@@ -3853,12 +3946,13 @@ function createDefaultRenderer() {
|
|
|
3853
3946
|
init_tracking_manager();
|
|
3854
3947
|
|
|
3855
3948
|
// src/analytics/analytics-manager.ts
|
|
3856
|
-
|
|
3857
|
-
|
|
3949
|
+
function createDryRunSink(log = console.log) {
|
|
3950
|
+
return (payload) => log(
|
|
3858
3951
|
"[DeepdotsAnalytics] (dry-run \xB7 NO enviado \xB7 sin init.analytics) POST /sdk/feedback \u2192",
|
|
3859
3952
|
JSON.stringify(payload, null, 2)
|
|
3860
3953
|
);
|
|
3861
|
-
}
|
|
3954
|
+
}
|
|
3955
|
+
var dryRunSink = createDryRunSink();
|
|
3862
3956
|
var AnalyticsManager = class {
|
|
3863
3957
|
constructor(options = {}) {
|
|
3864
3958
|
this.events = [];
|
|
@@ -4374,7 +4468,7 @@ var CrashReporter = class {
|
|
|
4374
4468
|
}
|
|
4375
4469
|
/** Instala los handlers globales de errores no capturados (no-op sin `window`). */
|
|
4376
4470
|
install() {
|
|
4377
|
-
if (typeof window === "undefined") return;
|
|
4471
|
+
if (typeof window === "undefined" || typeof window.addEventListener !== "function") return;
|
|
4378
4472
|
window.addEventListener("error", (e) => {
|
|
4379
4473
|
if (!this.isEnabled()) return;
|
|
4380
4474
|
this.captureUnhandled(e.error ?? e.message ?? "error");
|
|
@@ -4398,6 +4492,9 @@ var CrashReporter = class {
|
|
|
4398
4492
|
}
|
|
4399
4493
|
};
|
|
4400
4494
|
|
|
4495
|
+
// src/core/deepdots-popups.ts
|
|
4496
|
+
init_logger();
|
|
4497
|
+
|
|
4401
4498
|
// src/analytics/messaging.ts
|
|
4402
4499
|
function buildMessageParams(stage, o) {
|
|
4403
4500
|
const p = {
|
|
@@ -4426,6 +4523,8 @@ var DeepdotsPopups = class {
|
|
|
4426
4523
|
this.triggers = [];
|
|
4427
4524
|
this.initialized = false;
|
|
4428
4525
|
this.renderer = createDefaultRenderer();
|
|
4526
|
+
/** Logger para el output de debug. Default `console`; el host puede inyectar el suyo en init(). */
|
|
4527
|
+
this.logger = console;
|
|
4429
4528
|
this.popupContainer = null;
|
|
4430
4529
|
// deprecated: mantenido para compatibilidad interna
|
|
4431
4530
|
this.popupDefinitions = [];
|
|
@@ -4461,6 +4560,8 @@ var DeepdotsPopups = class {
|
|
|
4461
4560
|
}
|
|
4462
4561
|
/** Initialize the SDK with configuration */
|
|
4463
4562
|
init(config) {
|
|
4563
|
+
this.logger = config.logger ?? console;
|
|
4564
|
+
setLogger(this.logger);
|
|
4464
4565
|
if (this.initialized) {
|
|
4465
4566
|
this.log("SDK already initialized");
|
|
4466
4567
|
return;
|
|
@@ -4500,7 +4601,7 @@ var DeepdotsPopups = class {
|
|
|
4500
4601
|
onSessionId: (id) => {
|
|
4501
4602
|
this.analyticsFeedbackSessionId = id;
|
|
4502
4603
|
}
|
|
4503
|
-
}) :
|
|
4604
|
+
}) : createDryRunSink((...a) => this.logger.log(...a));
|
|
4504
4605
|
const device = config.device ?? collectDeviceInfo(config.appVersion);
|
|
4505
4606
|
this.analytics = new AnalyticsManager({
|
|
4506
4607
|
sink: analyticsSink,
|
|
@@ -5209,7 +5310,8 @@ var DeepdotsPopups = class {
|
|
|
5209
5310
|
try {
|
|
5210
5311
|
listener(event);
|
|
5211
5312
|
} catch (error) {
|
|
5212
|
-
|
|
5313
|
+
if (this.logger.error) this.logger.error("Error in event listener:", error);
|
|
5314
|
+
else this.logger.log("Error in event listener:", error);
|
|
5213
5315
|
}
|
|
5214
5316
|
});
|
|
5215
5317
|
}
|
|
@@ -5217,7 +5319,7 @@ var DeepdotsPopups = class {
|
|
|
5217
5319
|
/** Log debug messages */
|
|
5218
5320
|
log(...args) {
|
|
5219
5321
|
if (this.config?.debug) {
|
|
5220
|
-
|
|
5322
|
+
this.logger.log("[DeepdotsPopups]", ...args);
|
|
5221
5323
|
}
|
|
5222
5324
|
}
|
|
5223
5325
|
/** External debug method for triggers */
|