@youidian/sdk 3.1.1 → 3.2.1
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/client.cjs +552 -2
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +2 -1
- package/dist/client.d.ts +2 -1
- package/dist/client.js +548 -1
- package/dist/client.js.map +1 -1
- package/dist/index.cjs +345 -153
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -2
- package/dist/index.d.ts +1 -2
- package/dist/index.js +347 -156
- package/dist/index.js.map +1 -1
- package/dist/login-D_VaJqQX.d.cts +86 -0
- package/dist/login-D_VaJqQX.d.ts +86 -0
- package/dist/login.cjs +236 -44
- package/dist/login.cjs.map +1 -1
- package/dist/login.d.cts +1 -62
- package/dist/login.d.ts +1 -62
- package/dist/login.js +234 -43
- package/dist/login.js.map +1 -1
- package/package.json +1 -10
- package/dist/hosted-modal-BZmYmXTU.d.cts +0 -20
- package/dist/hosted-modal-BZmYmXTU.d.ts +0 -20
package/dist/login.cjs
CHANGED
|
@@ -23,7 +23,8 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
23
23
|
var login_exports = {};
|
|
24
24
|
__export(login_exports, {
|
|
25
25
|
LoginUI: () => LoginUI,
|
|
26
|
-
createLoginUI: () => createLoginUI
|
|
26
|
+
createLoginUI: () => createLoginUI,
|
|
27
|
+
handleLoginCallbackIfPresent: () => handleLoginCallbackIfPresent
|
|
27
28
|
});
|
|
28
29
|
module.exports = __toCommonJS(login_exports);
|
|
29
30
|
|
|
@@ -132,10 +133,33 @@ function getOrigin(value) {
|
|
|
132
133
|
return null;
|
|
133
134
|
}
|
|
134
135
|
}
|
|
135
|
-
function
|
|
136
|
+
function createLoginCallbackState() {
|
|
137
|
+
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
138
|
+
return crypto.randomUUID().replace(/-/g, "");
|
|
139
|
+
}
|
|
140
|
+
return `${Date.now().toString(36)}${Math.random().toString(36).slice(2)}`;
|
|
141
|
+
}
|
|
142
|
+
function buildLoginCallbackUrl(callbackState, callbackUrl) {
|
|
143
|
+
const baseUrl = callbackUrl || window.location.href;
|
|
144
|
+
const url = new URL(baseUrl, window.location.href);
|
|
145
|
+
const returnHash = url.hash.replace(/^#/, "");
|
|
146
|
+
url.hash = "";
|
|
147
|
+
url.searchParams.set(LOGIN_CALLBACK_MARKER, "1");
|
|
148
|
+
url.searchParams.set(LOGIN_CALLBACK_STATE_PARAM, callbackState);
|
|
149
|
+
if (returnHash) {
|
|
150
|
+
url.searchParams.set(LOGIN_CALLBACK_RETURN_HASH_PARAM, returnHash);
|
|
151
|
+
} else {
|
|
152
|
+
url.searchParams.delete(LOGIN_CALLBACK_RETURN_HASH_PARAM);
|
|
153
|
+
}
|
|
154
|
+
return url.toString();
|
|
155
|
+
}
|
|
156
|
+
function buildLoginLaunchPayload(params, options, callbackState) {
|
|
136
157
|
const parentOrigin = typeof window !== "undefined" ? window.location.origin : void 0;
|
|
158
|
+
const callbackUrl = typeof window !== "undefined" && callbackState ? buildLoginCallbackUrl(callbackState, options?.callbackUrl) : void 0;
|
|
137
159
|
return {
|
|
138
160
|
autoClose: options?.autoClose ?? true,
|
|
161
|
+
callbackUrl,
|
|
162
|
+
callbackState,
|
|
139
163
|
origin: parentOrigin,
|
|
140
164
|
preferredChannel: params.preferredChannel
|
|
141
165
|
};
|
|
@@ -148,6 +172,9 @@ function appendLoginLaunchHash(urlValue, payload) {
|
|
|
148
172
|
if (payload.origin) {
|
|
149
173
|
hashParams.set("ydOrigin", payload.origin);
|
|
150
174
|
}
|
|
175
|
+
if (payload.callbackUrl) {
|
|
176
|
+
hashParams.set("ydCallbackUrl", payload.callbackUrl);
|
|
177
|
+
}
|
|
151
178
|
if (payload.preferredChannel) {
|
|
152
179
|
hashParams.set("ydPreferredChannel", payload.preferredChannel);
|
|
153
180
|
}
|
|
@@ -166,10 +193,9 @@ function appendLoginLaunchHash(urlValue, payload) {
|
|
|
166
193
|
function buildLoginPopupName(payload) {
|
|
167
194
|
return `youidian-login:${JSON.stringify(payload)}`;
|
|
168
195
|
}
|
|
169
|
-
function buildLoginUrl(params, options) {
|
|
196
|
+
function buildLoginUrl(params, options, launchPayload) {
|
|
170
197
|
const { appId, baseUrl = "https://pay.imgto.link", loginUrl } = params;
|
|
171
198
|
const rawBase = (loginUrl || baseUrl).replace(/\/$/, "");
|
|
172
|
-
const launchPayload = buildLoginLaunchPayload(params, options);
|
|
173
199
|
const parentOrigin = launchPayload.origin;
|
|
174
200
|
let finalUrl;
|
|
175
201
|
try {
|
|
@@ -200,6 +226,9 @@ function buildLoginUrl(params, options) {
|
|
|
200
226
|
if (parentOrigin) {
|
|
201
227
|
url.searchParams.set("origin", parentOrigin);
|
|
202
228
|
}
|
|
229
|
+
if (launchPayload.callbackUrl) {
|
|
230
|
+
url.searchParams.set("callbackUrl", launchPayload.callbackUrl);
|
|
231
|
+
}
|
|
203
232
|
return appendLoginLaunchHash(url.toString(), launchPayload);
|
|
204
233
|
} catch (_error) {
|
|
205
234
|
const searchParams = new URLSearchParams();
|
|
@@ -212,6 +241,9 @@ function buildLoginUrl(params, options) {
|
|
|
212
241
|
if (parentOrigin) {
|
|
213
242
|
searchParams.set("origin", parentOrigin);
|
|
214
243
|
}
|
|
244
|
+
if (launchPayload.callbackUrl) {
|
|
245
|
+
searchParams.set("callbackUrl", launchPayload.callbackUrl);
|
|
246
|
+
}
|
|
215
247
|
const query = searchParams.toString();
|
|
216
248
|
if (!query) {
|
|
217
249
|
return appendLoginLaunchHash(finalUrl, launchPayload);
|
|
@@ -238,6 +270,102 @@ function extractLoginResult(data) {
|
|
|
238
270
|
};
|
|
239
271
|
}
|
|
240
272
|
var LOGIN_UI_LOG_PREFIX = "[Youidian LoginUI]";
|
|
273
|
+
var LOGIN_CALLBACK_MARKER = "yd_login_callback";
|
|
274
|
+
var LOGIN_CALLBACK_RESULT_PARAM = "yd_login_result";
|
|
275
|
+
var LOGIN_CALLBACK_RETURN_HASH_PARAM = "yd_login_return_hash";
|
|
276
|
+
var LOGIN_CALLBACK_STATE_PARAM = "yd_login_state";
|
|
277
|
+
var LOGIN_CALLBACK_STORAGE_PREFIX = "yd-login-callback:";
|
|
278
|
+
function decodeCallbackPayload(value) {
|
|
279
|
+
try {
|
|
280
|
+
const padded = value.padEnd(
|
|
281
|
+
value.length + (4 - value.length % 4) % 4,
|
|
282
|
+
"="
|
|
283
|
+
);
|
|
284
|
+
const base64 = padded.replaceAll("-", "+").replaceAll("_", "/");
|
|
285
|
+
const binary = atob(base64);
|
|
286
|
+
const json = decodeURIComponent(
|
|
287
|
+
Array.from(
|
|
288
|
+
binary,
|
|
289
|
+
(char) => `%${char.charCodeAt(0).toString(16).padStart(2, "0")}`
|
|
290
|
+
).join("")
|
|
291
|
+
);
|
|
292
|
+
const parsed = JSON.parse(json);
|
|
293
|
+
return parsed && typeof parsed === "object" && parsed.type ? parsed : null;
|
|
294
|
+
} catch {
|
|
295
|
+
return null;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
function getLoginCallbackChannelName(state) {
|
|
299
|
+
return `youidian-login:${state}`;
|
|
300
|
+
}
|
|
301
|
+
function getLoginCallbackStorageKey(state) {
|
|
302
|
+
return `${LOGIN_CALLBACK_STORAGE_PREFIX}${state}`;
|
|
303
|
+
}
|
|
304
|
+
function publishLoginCallback(state, data) {
|
|
305
|
+
try {
|
|
306
|
+
const channel = new BroadcastChannel(getLoginCallbackChannelName(state));
|
|
307
|
+
channel.postMessage(data);
|
|
308
|
+
channel.close();
|
|
309
|
+
} catch {
|
|
310
|
+
}
|
|
311
|
+
try {
|
|
312
|
+
const storageKey = getLoginCallbackStorageKey(state);
|
|
313
|
+
window.localStorage.setItem(storageKey, JSON.stringify(data));
|
|
314
|
+
window.setTimeout(() => {
|
|
315
|
+
try {
|
|
316
|
+
window.localStorage.removeItem(storageKey);
|
|
317
|
+
} catch {
|
|
318
|
+
}
|
|
319
|
+
}, 800);
|
|
320
|
+
} catch {
|
|
321
|
+
}
|
|
322
|
+
try {
|
|
323
|
+
window.opener?.postMessage(data, window.location.origin);
|
|
324
|
+
} catch {
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
function cleanLoginCallbackUrl(url) {
|
|
328
|
+
url.searchParams.delete(LOGIN_CALLBACK_MARKER);
|
|
329
|
+
url.searchParams.delete(LOGIN_CALLBACK_STATE_PARAM);
|
|
330
|
+
const returnHash = url.searchParams.get(LOGIN_CALLBACK_RETURN_HASH_PARAM);
|
|
331
|
+
url.searchParams.delete(LOGIN_CALLBACK_RETURN_HASH_PARAM);
|
|
332
|
+
url.hash = returnHash ? `#${returnHash}` : "";
|
|
333
|
+
return url.toString();
|
|
334
|
+
}
|
|
335
|
+
function handleLoginCallbackIfPresent() {
|
|
336
|
+
if (typeof window === "undefined") {
|
|
337
|
+
return false;
|
|
338
|
+
}
|
|
339
|
+
const url = new URL(window.location.href);
|
|
340
|
+
if (url.searchParams.get(LOGIN_CALLBACK_MARKER) !== "1") {
|
|
341
|
+
return false;
|
|
342
|
+
}
|
|
343
|
+
const state = url.searchParams.get(LOGIN_CALLBACK_STATE_PARAM) || "";
|
|
344
|
+
const hashParams = new URLSearchParams(url.hash.replace(/^#/, ""));
|
|
345
|
+
const rawResult = hashParams.get(LOGIN_CALLBACK_RESULT_PARAM);
|
|
346
|
+
const data = rawResult && state ? decodeCallbackPayload(rawResult) : {
|
|
347
|
+
type: "LOGIN_ERROR",
|
|
348
|
+
message: "Missing login callback result"
|
|
349
|
+
};
|
|
350
|
+
try {
|
|
351
|
+
document.documentElement.style.visibility = "hidden";
|
|
352
|
+
} catch {
|
|
353
|
+
}
|
|
354
|
+
if (state && data) {
|
|
355
|
+
publishLoginCallback(state, data);
|
|
356
|
+
}
|
|
357
|
+
try {
|
|
358
|
+
window.history.replaceState(null, "", cleanLoginCallbackUrl(url));
|
|
359
|
+
} catch {
|
|
360
|
+
}
|
|
361
|
+
window.setTimeout(() => {
|
|
362
|
+
try {
|
|
363
|
+
window.close();
|
|
364
|
+
} catch {
|
|
365
|
+
}
|
|
366
|
+
}, 30);
|
|
367
|
+
return true;
|
|
368
|
+
}
|
|
241
369
|
function logLoginDebug(message, details) {
|
|
242
370
|
if (typeof console === "undefined") return;
|
|
243
371
|
console.debug(LOGIN_UI_LOG_PREFIX, message, details || {});
|
|
@@ -253,14 +381,24 @@ function logLoginWarn(message, details) {
|
|
|
253
381
|
var LoginUI = class {
|
|
254
382
|
constructor() {
|
|
255
383
|
__publicField(this, "popup", null);
|
|
384
|
+
__publicField(this, "callbackChannel", null);
|
|
385
|
+
__publicField(this, "callbackStorageHandler", null);
|
|
256
386
|
__publicField(this, "messageHandler", null);
|
|
257
387
|
__publicField(this, "closeMonitor", null);
|
|
258
388
|
__publicField(this, "completed", false);
|
|
259
389
|
}
|
|
260
390
|
cleanup() {
|
|
391
|
+
if (this.callbackChannel) {
|
|
392
|
+
this.callbackChannel.close();
|
|
393
|
+
}
|
|
394
|
+
if (typeof window !== "undefined" && this.callbackStorageHandler) {
|
|
395
|
+
window.removeEventListener("storage", this.callbackStorageHandler);
|
|
396
|
+
}
|
|
261
397
|
if (typeof window !== "undefined" && this.messageHandler) {
|
|
262
398
|
window.removeEventListener("message", this.messageHandler);
|
|
263
399
|
}
|
|
400
|
+
this.callbackChannel = null;
|
|
401
|
+
this.callbackStorageHandler = null;
|
|
264
402
|
if (typeof window !== "undefined" && this.closeMonitor) {
|
|
265
403
|
window.clearInterval(this.closeMonitor);
|
|
266
404
|
}
|
|
@@ -269,6 +407,81 @@ var LoginUI = class {
|
|
|
269
407
|
this.popup = null;
|
|
270
408
|
this.completed = false;
|
|
271
409
|
}
|
|
410
|
+
handleLoginEvent(data, options) {
|
|
411
|
+
if (!data || typeof data !== "object" || !data.type) {
|
|
412
|
+
logLoginDebug("Ignored non-login event payload");
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
logLoginInfo("Received login event", {
|
|
416
|
+
type: data.type
|
|
417
|
+
});
|
|
418
|
+
switch (data.type) {
|
|
419
|
+
case "LOGIN_SUCCESS":
|
|
420
|
+
if (this.completed) {
|
|
421
|
+
break;
|
|
422
|
+
}
|
|
423
|
+
this.completed = true;
|
|
424
|
+
logLoginInfo("Login succeeded", {
|
|
425
|
+
channel: data.channel || null,
|
|
426
|
+
userId: data.userId || null
|
|
427
|
+
});
|
|
428
|
+
options?.onSuccess?.(extractLoginResult(data));
|
|
429
|
+
break;
|
|
430
|
+
case "LOGIN_CANCELLED":
|
|
431
|
+
logLoginInfo("Login cancelled");
|
|
432
|
+
options?.onCancel?.();
|
|
433
|
+
break;
|
|
434
|
+
case "LOGIN_RESIZE":
|
|
435
|
+
break;
|
|
436
|
+
case "LOGIN_ERROR":
|
|
437
|
+
if (this.completed) {
|
|
438
|
+
break;
|
|
439
|
+
}
|
|
440
|
+
logLoginWarn("Login flow reported an error", {
|
|
441
|
+
message: data.message || data.error || null
|
|
442
|
+
});
|
|
443
|
+
options?.onError?.(data.message || data.error, data);
|
|
444
|
+
break;
|
|
445
|
+
case "LOGIN_CLOSE":
|
|
446
|
+
if (options?.autoClose === false) {
|
|
447
|
+
logLoginInfo(
|
|
448
|
+
"Login popup requested close; autoClose disabled, keeping popup open"
|
|
449
|
+
);
|
|
450
|
+
options?.onClose?.();
|
|
451
|
+
break;
|
|
452
|
+
}
|
|
453
|
+
logLoginInfo("Login popup requested close; autoClose enabled");
|
|
454
|
+
this.close();
|
|
455
|
+
options?.onClose?.();
|
|
456
|
+
break;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
listenForLoginCallback(callbackState, options) {
|
|
460
|
+
try {
|
|
461
|
+
this.callbackChannel = new BroadcastChannel(
|
|
462
|
+
getLoginCallbackChannelName(callbackState)
|
|
463
|
+
);
|
|
464
|
+
this.callbackChannel.onmessage = (event) => {
|
|
465
|
+
this.handleLoginEvent(event.data, options);
|
|
466
|
+
this.handleLoginEvent({ type: "LOGIN_CLOSE" }, options);
|
|
467
|
+
};
|
|
468
|
+
} catch {
|
|
469
|
+
logLoginDebug("BroadcastChannel is unavailable for login callback");
|
|
470
|
+
}
|
|
471
|
+
this.callbackStorageHandler = (event) => {
|
|
472
|
+
if (event.key !== getLoginCallbackStorageKey(callbackState) || !event.newValue) {
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
try {
|
|
476
|
+
const data = JSON.parse(event.newValue);
|
|
477
|
+
this.handleLoginEvent(data, options);
|
|
478
|
+
this.handleLoginEvent({ type: "LOGIN_CLOSE" }, options);
|
|
479
|
+
} catch {
|
|
480
|
+
logLoginWarn("Failed to parse login callback storage payload");
|
|
481
|
+
}
|
|
482
|
+
};
|
|
483
|
+
window.addEventListener("storage", this.callbackStorageHandler);
|
|
484
|
+
}
|
|
272
485
|
close() {
|
|
273
486
|
logLoginInfo("close() called", {
|
|
274
487
|
hasPopup: Boolean(this.popup),
|
|
@@ -282,12 +495,23 @@ var LoginUI = class {
|
|
|
282
495
|
openLogin(params, options) {
|
|
283
496
|
if (typeof window === "undefined") return;
|
|
284
497
|
if (this.popup && !this.popup.closed) return;
|
|
285
|
-
const
|
|
498
|
+
const callbackState = createLoginCallbackState();
|
|
499
|
+
const launchPayload = buildLoginLaunchPayload(
|
|
500
|
+
params,
|
|
501
|
+
options,
|
|
502
|
+
callbackState
|
|
503
|
+
);
|
|
504
|
+
const finalUrl = buildLoginUrl(params, options, launchPayload);
|
|
286
505
|
logLoginInfo("Opening hosted login popup", {
|
|
287
506
|
appId: params.appId,
|
|
507
|
+
callbackState,
|
|
508
|
+
callbackUrl: launchPayload.callbackUrl || null,
|
|
509
|
+
hasCallbackUrl: Boolean(launchPayload.callbackUrl),
|
|
288
510
|
loginUrl: finalUrl,
|
|
289
511
|
allowedOrigin: options?.allowedOrigin || null,
|
|
290
|
-
autoClose: options?.autoClose ?? true
|
|
512
|
+
autoClose: options?.autoClose ?? true,
|
|
513
|
+
pageUrl: typeof window !== "undefined" ? window.location.href : null,
|
|
514
|
+
parentOrigin: launchPayload.origin || null
|
|
291
515
|
});
|
|
292
516
|
const popupWidth = 520;
|
|
293
517
|
const popupHeight = 720;
|
|
@@ -308,9 +532,7 @@ var LoginUI = class {
|
|
|
308
532
|
"resizable=yes",
|
|
309
533
|
"scrollbars=yes"
|
|
310
534
|
].join(",");
|
|
311
|
-
const popupName = buildLoginPopupName(
|
|
312
|
-
buildLoginLaunchPayload(params, options)
|
|
313
|
-
);
|
|
535
|
+
const popupName = buildLoginPopupName(launchPayload);
|
|
314
536
|
const popup = window.open(finalUrl, popupName, features);
|
|
315
537
|
if (!popup) {
|
|
316
538
|
logLoginWarn("Popup blocked by the browser");
|
|
@@ -319,6 +541,7 @@ var LoginUI = class {
|
|
|
319
541
|
}
|
|
320
542
|
this.popup = popup;
|
|
321
543
|
this.completed = false;
|
|
544
|
+
this.listenForLoginCallback(callbackState, options);
|
|
322
545
|
const allowedOrigin = options?.allowedOrigin;
|
|
323
546
|
const popupOrigin = getOrigin(finalUrl);
|
|
324
547
|
this.messageHandler = (event) => {
|
|
@@ -345,40 +568,7 @@ var LoginUI = class {
|
|
|
345
568
|
type: data.type,
|
|
346
569
|
eventOrigin: event.origin
|
|
347
570
|
});
|
|
348
|
-
|
|
349
|
-
case "LOGIN_SUCCESS":
|
|
350
|
-
this.completed = true;
|
|
351
|
-
logLoginInfo("Login succeeded", {
|
|
352
|
-
channel: data.channel || null,
|
|
353
|
-
userId: data.userId || null
|
|
354
|
-
});
|
|
355
|
-
options?.onSuccess?.(extractLoginResult(data));
|
|
356
|
-
break;
|
|
357
|
-
case "LOGIN_CANCELLED":
|
|
358
|
-
logLoginInfo("Login cancelled");
|
|
359
|
-
options?.onCancel?.();
|
|
360
|
-
break;
|
|
361
|
-
case "LOGIN_RESIZE":
|
|
362
|
-
break;
|
|
363
|
-
case "LOGIN_ERROR":
|
|
364
|
-
logLoginWarn("Login flow reported an error", {
|
|
365
|
-
message: data.message || data.error || null
|
|
366
|
-
});
|
|
367
|
-
options?.onError?.(data.message || data.error, data);
|
|
368
|
-
break;
|
|
369
|
-
case "LOGIN_CLOSE":
|
|
370
|
-
if (options?.autoClose === false) {
|
|
371
|
-
logLoginInfo(
|
|
372
|
-
"Login popup requested close; autoClose disabled, keeping popup open"
|
|
373
|
-
);
|
|
374
|
-
options?.onClose?.();
|
|
375
|
-
break;
|
|
376
|
-
}
|
|
377
|
-
logLoginInfo("Login popup requested close; autoClose enabled");
|
|
378
|
-
this.close();
|
|
379
|
-
options?.onClose?.();
|
|
380
|
-
break;
|
|
381
|
-
}
|
|
571
|
+
this.handleLoginEvent(data, options);
|
|
382
572
|
};
|
|
383
573
|
window.addEventListener("message", this.messageHandler);
|
|
384
574
|
this.closeMonitor = window.setInterval(() => {
|
|
@@ -399,9 +589,11 @@ var LoginUI = class {
|
|
|
399
589
|
function createLoginUI() {
|
|
400
590
|
return new LoginUI();
|
|
401
591
|
}
|
|
592
|
+
handleLoginCallbackIfPresent();
|
|
402
593
|
// Annotate the CommonJS export names for ESM import in node:
|
|
403
594
|
0 && (module.exports = {
|
|
404
595
|
LoginUI,
|
|
405
|
-
createLoginUI
|
|
596
|
+
createLoginUI,
|
|
597
|
+
handleLoginCallbackIfPresent
|
|
406
598
|
});
|
|
407
599
|
//# sourceMappingURL=login.cjs.map
|
package/dist/login.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/login.ts","../src/hosted-modal.ts"],"sourcesContent":["import {\n\tapplyLocaleToUrl,\n\tgetAutoResolvedLocale,\n\ttype HostedFrameMessage,\n} from \"./hosted-modal\"\n\nexport type LoginEventType =\n\t| \"LOGIN_SUCCESS\"\n\t| \"LOGIN_CANCELLED\"\n\t| \"LOGIN_CLOSE\"\n\t| \"LOGIN_RESIZE\"\n\t| \"LOGIN_ERROR\"\n\nexport interface LoginResult {\n\tavatar?: string | null\n\tchannel?: string\n\temail?: string | null\n\texpiresAt?: string\n\tlegacyCasdoorId?: string\n\tloginToken?: string\n\tname?: string | null\n\tuserId?: string\n\twechatOpenId?: string | null\n\twechatUnionId?: string | null\n}\n\nexport interface LoginEventData extends HostedFrameMessage, LoginResult {\n\ttype: LoginEventType\n\terror?: string\n\tmessage?: string\n}\n\nexport interface LoginUIOptions {\n\t/** Origin to validate postMessage (defaults to '*', set for security) */\n\tallowedOrigin?: string\n\t/** Whether the SDK should close the popup after receiving LOGIN_CLOSE. Defaults to true. */\n\tautoClose?: boolean\n\tonCancel?: () => void\n\tonClose?: () => void\n\tonError?: (message?: string, data?: LoginEventData) => void\n\tonSuccess?: (result: LoginResult) => void\n}\n\nexport interface LoginParams {\n\tappId: string\n\n\t/**\n\t * @deprecated Use loginUrl instead\n\t * Defaults to https://pay.imgto.link\n\t */\n\tbaseUrl?: string\n\n\t/**\n\t * Hosted login page base URL (e.g. https://pay.youidian.com)\n\t * Defaults to https://pay.imgto.link\n\t */\n\tloginUrl?: string\n\n\t/**\n\t * Optional locale prefix to prepend to the hosted login path.\n\t * If omitted, the SDK automatically resolves the locale from the browser language.\n\t */\n\tlocale?: string\n\n\t/** Preferred provider/channel code */\n\tpreferredChannel?: string\n}\n\nfunction getOrigin(value?: string): string | null {\n\tif (!value) return null\n\ttry {\n\t\treturn new URL(value).origin\n\t} catch {\n\t\treturn null\n\t}\n}\n\nfunction buildLoginLaunchPayload(\n\tparams: LoginParams,\n\toptions?: LoginUIOptions,\n) {\n\tconst parentOrigin =\n\t\ttypeof window !== \"undefined\" ? window.location.origin : undefined\n\n\treturn {\n\t\tautoClose: options?.autoClose ?? true,\n\t\torigin: parentOrigin,\n\t\tpreferredChannel: params.preferredChannel,\n\t}\n}\n\nfunction appendLoginLaunchHash(\n\turlValue: string,\n\tpayload: ReturnType<typeof buildLoginLaunchPayload>,\n) {\n\tconst hashParams = new URLSearchParams()\n\tif (payload.autoClose === false) {\n\t\thashParams.set(\"ydAutoClose\", \"false\")\n\t}\n\tif (payload.origin) {\n\t\thashParams.set(\"ydOrigin\", payload.origin)\n\t}\n\tif (payload.preferredChannel) {\n\t\thashParams.set(\"ydPreferredChannel\", payload.preferredChannel)\n\t}\n\tconst hash = hashParams.toString()\n\tif (!hash) {\n\t\treturn urlValue\n\t}\n\n\ttry {\n\t\tconst url = new URL(urlValue)\n\t\turl.hash = hash\n\t\treturn url.toString()\n\t} catch (_error) {\n\t\treturn `${urlValue}#${hash}`\n\t}\n}\n\nfunction buildLoginPopupName(\n\tpayload: ReturnType<typeof buildLoginLaunchPayload>,\n) {\n\treturn `youidian-login:${JSON.stringify(payload)}`\n}\n\nfunction buildLoginUrl(params: LoginParams, options?: LoginUIOptions): string {\n\tconst { appId, baseUrl = \"https://pay.imgto.link\", loginUrl } = params\n\tconst rawBase = (loginUrl || baseUrl).replace(/\\/$/, \"\")\n\tconst launchPayload = buildLoginLaunchPayload(params, options)\n\tconst parentOrigin = launchPayload.origin\n\n\tlet finalUrl: string\n\ttry {\n\t\tconst url = new URL(rawBase)\n\t\tif (!/\\/auth\\/connect\\/[^/]+$/.test(url.pathname)) {\n\t\t\turl.pathname =\n\t\t\t\t`${url.pathname.replace(/\\/$/, \"\")}/auth/connect/${appId}`.replace(\n\t\t\t\t\t/\\/{2,}/g,\n\t\t\t\t\t\"/\",\n\t\t\t\t)\n\t\t}\n\t\tfinalUrl = url.toString()\n\t} catch (_error) {\n\t\tif (/\\/auth\\/connect\\/[^/]+$/.test(rawBase)) {\n\t\t\tfinalUrl = rawBase\n\t\t} else {\n\t\t\tfinalUrl = `${rawBase}/auth/connect/${appId}`.replace(/\\/{2,}/g, \"/\")\n\t\t}\n\t}\n\n\tfinalUrl = applyLocaleToUrl(finalUrl, getAutoResolvedLocale(params.locale))\n\n\ttry {\n\t\tconst url = new URL(finalUrl)\n\t\tif (params.preferredChannel) {\n\t\t\turl.searchParams.set(\"preferredChannel\", params.preferredChannel)\n\t\t}\n\t\tif (options?.autoClose === false) {\n\t\t\turl.searchParams.set(\"autoClose\", \"false\")\n\t\t}\n\t\tif (parentOrigin) {\n\t\t\turl.searchParams.set(\"origin\", parentOrigin)\n\t\t}\n\t\treturn appendLoginLaunchHash(url.toString(), launchPayload)\n\t} catch (_error) {\n\t\tconst searchParams = new URLSearchParams()\n\t\tif (params.preferredChannel) {\n\t\t\tsearchParams.set(\"preferredChannel\", params.preferredChannel)\n\t\t}\n\t\tif (options?.autoClose === false) {\n\t\t\tsearchParams.set(\"autoClose\", \"false\")\n\t\t}\n\t\tif (parentOrigin) {\n\t\t\tsearchParams.set(\"origin\", parentOrigin)\n\t\t}\n\t\tconst query = searchParams.toString()\n\t\tif (!query) {\n\t\t\treturn appendLoginLaunchHash(finalUrl, launchPayload)\n\t\t}\n\t\tconst separator = finalUrl.includes(\"?\") ? \"&\" : \"?\"\n\t\treturn appendLoginLaunchHash(\n\t\t\t`${finalUrl}${separator}${query}`,\n\t\t\tlaunchPayload,\n\t\t)\n\t}\n}\n\nfunction extractLoginResult(data: LoginEventData): LoginResult {\n\treturn {\n\t\tavatar: data.avatar,\n\t\tchannel: data.channel,\n\t\temail: data.email,\n\t\texpiresAt: data.expiresAt,\n\t\tlegacyCasdoorId: data.legacyCasdoorId,\n\t\tloginToken: data.loginToken,\n\t\tname: data.name,\n\t\tuserId: data.userId,\n\t\twechatOpenId: data.wechatOpenId,\n\t\twechatUnionId: data.wechatUnionId,\n\t}\n}\n\nconst LOGIN_UI_LOG_PREFIX = \"[Youidian LoginUI]\"\n\nfunction logLoginDebug(message: string, details?: Record<string, unknown>) {\n\tif (typeof console === \"undefined\") return\n\tconsole.debug(LOGIN_UI_LOG_PREFIX, message, details || {})\n}\n\nfunction logLoginInfo(message: string, details?: Record<string, unknown>) {\n\tif (typeof console === \"undefined\") return\n\tconsole.info(LOGIN_UI_LOG_PREFIX, message, details || {})\n}\n\nfunction logLoginWarn(message: string, details?: Record<string, unknown>) {\n\tif (typeof console === \"undefined\") return\n\tconsole.warn(LOGIN_UI_LOG_PREFIX, message, details || {})\n}\n\nexport class LoginUI {\n\tprivate popup: Window | null = null\n\tprivate messageHandler: ((event: MessageEvent) => void) | null = null\n\tprivate closeMonitor: number | null = null\n\tprivate completed = false\n\n\tprivate cleanup() {\n\t\tif (typeof window !== \"undefined\" && this.messageHandler) {\n\t\t\twindow.removeEventListener(\"message\", this.messageHandler)\n\t\t}\n\t\tif (typeof window !== \"undefined\" && this.closeMonitor) {\n\t\t\twindow.clearInterval(this.closeMonitor)\n\t\t}\n\t\tthis.messageHandler = null\n\t\tthis.closeMonitor = null\n\t\tthis.popup = null\n\t\tthis.completed = false\n\t}\n\n\tclose() {\n\t\tlogLoginInfo(\"close() called\", {\n\t\t\thasPopup: Boolean(this.popup),\n\t\t\tpopupClosed: this.popup?.closed ?? true,\n\t\t})\n\t\tif (this.popup && !this.popup.closed) {\n\t\t\tthis.popup.close()\n\t\t}\n\t\tthis.cleanup()\n\t}\n\n\topenLogin(params: LoginParams, options?: LoginUIOptions) {\n\t\tif (typeof window === \"undefined\") return\n\t\tif (this.popup && !this.popup.closed) return\n\n\t\tconst finalUrl = buildLoginUrl(params, options)\n\t\tlogLoginInfo(\"Opening hosted login popup\", {\n\t\t\tappId: params.appId,\n\t\t\tloginUrl: finalUrl,\n\t\t\tallowedOrigin: options?.allowedOrigin || null,\n\t\t\tautoClose: options?.autoClose ?? true,\n\t\t})\n\t\tconst popupWidth = 520\n\t\tconst popupHeight = 720\n\t\tconst left = Math.max(\n\t\t\t0,\n\t\t\tMath.round(window.screenX + (window.outerWidth - popupWidth) / 2),\n\t\t)\n\t\tconst top = Math.max(\n\t\t\t0,\n\t\t\tMath.round(window.screenY + (window.outerHeight - popupHeight) / 2),\n\t\t)\n\t\tconst features = [\n\t\t\t\"popup=yes\",\n\t\t\t`width=${popupWidth}`,\n\t\t\t`height=${popupHeight}`,\n\t\t\t`left=${left}`,\n\t\t\t`top=${top}`,\n\t\t\t\"resizable=yes\",\n\t\t\t\"scrollbars=yes\",\n\t\t].join(\",\")\n\n\t\tconst popupName = buildLoginPopupName(\n\t\t\tbuildLoginLaunchPayload(params, options),\n\t\t)\n\t\tconst popup = window.open(finalUrl, popupName, features)\n\t\tif (!popup) {\n\t\t\tlogLoginWarn(\"Popup blocked by the browser\")\n\t\t\toptions?.onError?.(\"Login popup was blocked\")\n\t\t\treturn\n\t\t}\n\n\t\tthis.popup = popup\n\t\tthis.completed = false\n\n\t\tconst allowedOrigin = options?.allowedOrigin\n\t\tconst popupOrigin = getOrigin(finalUrl)\n\n\t\tthis.messageHandler = (event: MessageEvent) => {\n\t\t\tif (\n\t\t\t\tallowedOrigin &&\n\t\t\t\tallowedOrigin !== \"*\" &&\n\t\t\t\tevent.origin !== allowedOrigin\n\t\t\t) {\n\t\t\t\tlogLoginWarn(\"Ignored message due to allowedOrigin mismatch\", {\n\t\t\t\t\tallowedOrigin,\n\t\t\t\t\teventOrigin: event.origin,\n\t\t\t\t})\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (!allowedOrigin && popupOrigin && event.origin !== popupOrigin) {\n\t\t\t\tlogLoginWarn(\"Ignored message due to popup origin mismatch\", {\n\t\t\t\t\texpectedOrigin: popupOrigin,\n\t\t\t\t\teventOrigin: event.origin,\n\t\t\t\t})\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst data = event.data as LoginEventData\n\t\t\tif (!data || typeof data !== \"object\" || !data.type) {\n\t\t\t\tlogLoginDebug(\"Ignored non-login postMessage payload\")\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tlogLoginInfo(\"Received login event\", {\n\t\t\t\ttype: data.type,\n\t\t\t\teventOrigin: event.origin,\n\t\t\t})\n\n\t\t\tswitch (data.type) {\n\t\t\t\tcase \"LOGIN_SUCCESS\":\n\t\t\t\t\tthis.completed = true\n\t\t\t\t\tlogLoginInfo(\"Login succeeded\", {\n\t\t\t\t\t\tchannel: data.channel || null,\n\t\t\t\t\t\tuserId: data.userId || null,\n\t\t\t\t\t})\n\t\t\t\t\toptions?.onSuccess?.(extractLoginResult(data))\n\t\t\t\t\tbreak\n\t\t\t\tcase \"LOGIN_CANCELLED\":\n\t\t\t\t\tlogLoginInfo(\"Login cancelled\")\n\t\t\t\t\toptions?.onCancel?.()\n\t\t\t\t\tbreak\n\t\t\t\tcase \"LOGIN_RESIZE\":\n\t\t\t\t\tbreak\n\t\t\t\tcase \"LOGIN_ERROR\":\n\t\t\t\t\tlogLoginWarn(\"Login flow reported an error\", {\n\t\t\t\t\t\tmessage: data.message || data.error || null,\n\t\t\t\t\t})\n\t\t\t\t\toptions?.onError?.(data.message || data.error, data)\n\t\t\t\t\tbreak\n\t\t\t\tcase \"LOGIN_CLOSE\":\n\t\t\t\t\tif (options?.autoClose === false) {\n\t\t\t\t\t\tlogLoginInfo(\n\t\t\t\t\t\t\t\"Login popup requested close; autoClose disabled, keeping popup open\",\n\t\t\t\t\t\t)\n\t\t\t\t\t\toptions?.onClose?.()\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tlogLoginInfo(\"Login popup requested close; autoClose enabled\")\n\t\t\t\t\tthis.close()\n\t\t\t\t\toptions?.onClose?.()\n\t\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\twindow.addEventListener(\"message\", this.messageHandler)\n\n\t\tthis.closeMonitor = window.setInterval(() => {\n\t\t\tif (!this.popup || this.popup.closed) {\n\t\t\t\tconst shouldTreatAsCancel = !this.completed\n\t\t\t\tlogLoginInfo(\"Detected popup closed\", {\n\t\t\t\t\tshouldTreatAsCancel,\n\t\t\t\t})\n\t\t\t\tthis.cleanup()\n\t\t\t\tif (shouldTreatAsCancel) {\n\t\t\t\t\toptions?.onCancel?.()\n\t\t\t\t}\n\t\t\t\toptions?.onClose?.()\n\t\t\t}\n\t\t}, 500)\n\t}\n}\n\nexport function createLoginUI(): LoginUI {\n\treturn new LoginUI()\n}\n","export interface HostedFrameMessage {\n\ttype: string\n\theight?: number\n}\n\ntype HostedFrameOptions<TData extends HostedFrameMessage> = {\n\tallowedOrigin?: string\n\theight?: string\n\tonCloseButton?: () => void\n\tonMessage: (data: TData, container: HTMLDivElement) => void\n\twidth?: string\n}\n\nconst SDK_SUPPORTED_LOCALES = [\n\t\"en\",\n\t\"zh-CN\",\n\t\"zh-Hant\",\n\t\"fr\",\n\t\"de\",\n\t\"ja\",\n\t\"es\",\n\t\"ko\",\n\t\"nl\",\n\t\"it\",\n\t\"pt\",\n] as const\n\nconst SDK_DEFAULT_LOCALE = \"zh-CN\"\n\nconst SDK_LOCALE_ALIASES: Record<string, string> = {\n\ten: \"en\",\n\t\"en-us\": \"en\",\n\t\"en-gb\": \"en\",\n\tzh: \"zh-CN\",\n\t\"zh-cn\": \"zh-CN\",\n\t\"zh-tw\": \"zh-Hant\",\n\t\"zh-hk\": \"zh-Hant\",\n\t\"zh-hant\": \"zh-Hant\",\n\t\"zh-hans\": \"zh-CN\",\n\tfr: \"fr\",\n\tde: \"de\",\n\tja: \"ja\",\n\tes: \"es\",\n\tko: \"ko\",\n\tnl: \"nl\",\n\tit: \"it\",\n\tpt: \"pt\",\n}\n\nfunction matchSupportedBaseLocale(locale: string): string | undefined {\n\tconst base = locale.toLowerCase().split(\"-\")[0]\n\treturn SDK_SUPPORTED_LOCALES.find((item) => item.toLowerCase() === base)\n}\n\nexport function normalizeSdkLocale(locale?: string): string | undefined {\n\tif (!locale) return\n\n\tconst sanitized = locale.trim().replace(/_/g, \"-\")\n\tif (!sanitized) return\n\n\tconst lower = sanitized.toLowerCase()\n\tif (SDK_LOCALE_ALIASES[lower]) {\n\t\treturn SDK_LOCALE_ALIASES[lower]\n\t}\n\n\tlet canonical: string | undefined\n\ttry {\n\t\tcanonical = Intl.getCanonicalLocales(sanitized)[0]\n\t} catch {\n\t\tcanonical = undefined\n\t}\n\n\tconst candidates = [canonical, sanitized].filter(Boolean) as string[]\n\n\tfor (const candidate of candidates) {\n\t\tconst candidateLower = candidate.toLowerCase()\n\n\t\tif (SDK_LOCALE_ALIASES[candidateLower]) {\n\t\t\treturn SDK_LOCALE_ALIASES[candidateLower]\n\t\t}\n\t\tif ((SDK_SUPPORTED_LOCALES as readonly string[]).includes(candidate)) {\n\t\t\treturn candidate\n\t\t}\n\n\t\tconst baseMatch = matchSupportedBaseLocale(candidate)\n\t\tif (baseMatch) {\n\t\t\treturn baseMatch\n\t\t}\n\t}\n}\n\nexport function getBrowserLocale(): string | undefined {\n\tif (typeof navigator === \"undefined\") return\n\n\tfor (const candidate of navigator.languages || []) {\n\t\tconst normalized = normalizeSdkLocale(candidate)\n\t\tif (normalized) return normalized\n\t}\n\n\treturn normalizeSdkLocale(navigator.language)\n}\n\nexport function getAutoResolvedLocale(locale?: string): string {\n\treturn normalizeSdkLocale(locale) || getBrowserLocale() || SDK_DEFAULT_LOCALE\n}\n\nexport function applyLocaleToUrl(urlValue: string, locale?: string): string {\n\tif (!locale) return urlValue\n\n\ttry {\n\t\tconst url = new URL(urlValue)\n\t\tconst localePrefix = `/${locale}`\n\t\tif (\n\t\t\t!url.pathname.startsWith(`${localePrefix}/`) &&\n\t\t\turl.pathname !== localePrefix\n\t\t) {\n\t\t\turl.pathname = `${localePrefix}${url.pathname}`\n\t\t}\n\t\treturn url.toString()\n\t} catch (_error) {\n\t\tconst localePrefix = `/${locale}`\n\t\tif (!urlValue.startsWith(`${localePrefix}/`) && urlValue !== localePrefix) {\n\t\t\treturn `${localePrefix}${urlValue.startsWith(\"/\") ? \"\" : \"/\"}${urlValue}`\n\t\t}\n\t\treturn urlValue\n\t}\n}\n\nexport class HostedFrameModal<TData extends HostedFrameMessage> {\n\tprotected iframe: HTMLIFrameElement | null = null\n\tprotected modal: HTMLDivElement | null = null\n\tprotected messageHandler: ((event: MessageEvent) => void) | null = null\n\n\tprotected openHostedFrame(\n\t\turl: string,\n\t\toptions: HostedFrameOptions<TData>,\n\t): void {\n\t\tif (typeof document === \"undefined\") return\n\t\tif (this.modal) return\n\n\t\tthis.modal = document.createElement(\"div\")\n\t\tObject.assign(this.modal.style, {\n\t\t\tposition: \"fixed\",\n\t\t\ttop: \"0\",\n\t\t\tleft: \"0\",\n\t\t\twidth: \"100%\",\n\t\t\theight: \"100%\",\n\t\t\tbackgroundColor: \"rgba(15,23,42,0.52)\",\n\t\t\tdisplay: \"flex\",\n\t\t\talignItems: \"center\",\n\t\t\tjustifyContent: \"center\",\n\t\t\tzIndex: \"9999\",\n\t\t\ttransition: \"opacity 0.3s ease\",\n\t\t\tbackdropFilter: \"blur(14px)\",\n\t\t\tpadding: \"16px\",\n\t\t})\n\n\t\tconst container = document.createElement(\"div\")\n\t\tObject.assign(container.style, {\n\t\t\twidth: options.width || \"450px\",\n\t\t\theight: options.height || \"min(600px, 90vh)\",\n\t\t\tbackgroundColor: \"transparent\",\n\t\t\tborderRadius: \"28px\",\n\t\t\toverflow: \"visible\",\n\t\t\tposition: \"relative\",\n\t\t\tboxShadow: \"none\",\n\t\t\tmaxWidth: \"calc(100vw - 32px)\",\n\t\t\tmaxHeight: \"calc(100vh - 32px)\",\n\t\t\ttransition: \"height 180ms ease\",\n\t\t\twillChange: \"height\",\n\t\t})\n\n\t\tconst closeBtn = document.createElement(\"button\")\n\t\tcloseBtn.innerHTML = \"×\"\n\t\tObject.assign(closeBtn.style, {\n\t\t\tposition: \"absolute\",\n\t\t\tright: \"-14px\",\n\t\t\ttop: \"-14px\",\n\t\t\tfontSize: \"20px\",\n\t\t\twidth: \"36px\",\n\t\t\theight: \"36px\",\n\t\t\tborderRadius: \"9999px\",\n\t\t\tborder: \"1px solid rgba(255,255,255,0.5)\",\n\t\t\tbackground: \"rgba(255,255,255,0.9)\",\n\t\t\tcursor: \"pointer\",\n\t\t\tcolor: \"#475569\",\n\t\t\tzIndex: \"2\",\n\t\t\tboxShadow: \"0 10px 30px rgba(15,23,42,0.16)\",\n\t\t})\n\t\tcloseBtn.onclick = () => {\n\t\t\tthis.close()\n\t\t\toptions.onCloseButton?.()\n\t\t}\n\n\t\tthis.iframe = document.createElement(\"iframe\")\n\t\tthis.iframe.src = url\n\t\tObject.assign(this.iframe.style, {\n\t\t\twidth: \"100%\",\n\t\t\theight: \"100%\",\n\t\t\tborder: \"none\",\n\t\t\tborderRadius: \"28px\",\n\t\t\tbackground: \"transparent\",\n\t\t\tdisplay: \"block\",\n\t\t})\n\n\t\tcontainer.appendChild(closeBtn)\n\t\tcontainer.appendChild(this.iframe)\n\t\tthis.modal.appendChild(container)\n\t\tdocument.body.appendChild(this.modal)\n\n\t\tthis.messageHandler = (event: MessageEvent) => {\n\t\t\tif (options.allowedOrigin && options.allowedOrigin !== \"*\") {\n\t\t\t\tif (event.origin !== options.allowedOrigin) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst data = event.data as TData\n\t\t\tif (!data || typeof data !== \"object\" || !data.type) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\toptions.onMessage(data, container)\n\t\t}\n\n\t\twindow.addEventListener(\"message\", this.messageHandler)\n\t}\n\n\tclose() {\n\t\tif (typeof window === \"undefined\") return\n\n\t\tif (this.messageHandler) {\n\t\t\twindow.removeEventListener(\"message\", this.messageHandler)\n\t\t\tthis.messageHandler = null\n\t\t}\n\n\t\tif (this.modal?.parentNode) {\n\t\t\tthis.modal.parentNode.removeChild(this.modal)\n\t\t}\n\n\t\tthis.modal = null\n\t\tthis.iframe = null\n\t}\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/login.ts","../src/hosted-modal.ts"],"sourcesContent":["import {\n\tapplyLocaleToUrl,\n\tgetAutoResolvedLocale,\n\ttype HostedFrameMessage,\n} from \"./hosted-modal\"\n\nexport type LoginEventType =\n\t| \"LOGIN_SUCCESS\"\n\t| \"LOGIN_CANCELLED\"\n\t| \"LOGIN_CLOSE\"\n\t| \"LOGIN_RESIZE\"\n\t| \"LOGIN_ERROR\"\n\nexport interface LoginResult {\n\tavatar?: string | null\n\tchannel?: string\n\temail?: string | null\n\texpiresAt?: string\n\tlegacyCasdoorId?: string\n\tloginToken?: string\n\tname?: string | null\n\tuserId?: string\n\twechatOpenId?: string | null\n\twechatUnionId?: string | null\n}\n\nexport interface LoginEventData extends HostedFrameMessage, LoginResult {\n\ttype: LoginEventType\n\terror?: string\n\tmessage?: string\n}\n\nexport interface LoginUIOptions {\n\t/** Origin to validate postMessage (defaults to '*', set for security) */\n\tallowedOrigin?: string\n\t/** Whether the SDK should close the popup after receiving LOGIN_CLOSE. Defaults to true. */\n\tautoClose?: boolean\n\t/** Optional same-origin URL used as the no-API popup callback landing page. */\n\tcallbackUrl?: string\n\tonCancel?: () => void\n\tonClose?: () => void\n\tonError?: (message?: string, data?: LoginEventData) => void\n\tonSuccess?: (result: LoginResult) => void\n}\n\nexport interface LoginParams {\n\tappId: string\n\n\t/**\n\t * @deprecated Use loginUrl instead\n\t * Defaults to https://pay.imgto.link\n\t */\n\tbaseUrl?: string\n\n\t/**\n\t * Hosted login page base URL (e.g. https://pay.youidian.com)\n\t * Defaults to https://pay.imgto.link\n\t */\n\tloginUrl?: string\n\n\t/**\n\t * Optional locale prefix to prepend to the hosted login path.\n\t * If omitted, the SDK automatically resolves the locale from the browser language.\n\t */\n\tlocale?: string\n\n\t/** Preferred provider/channel code */\n\tpreferredChannel?: string\n}\n\nfunction getOrigin(value?: string): string | null {\n\tif (!value) return null\n\ttry {\n\t\treturn new URL(value).origin\n\t} catch {\n\t\treturn null\n\t}\n}\n\nfunction createLoginCallbackState() {\n\tif (typeof crypto !== \"undefined\" && crypto.randomUUID) {\n\t\treturn crypto.randomUUID().replace(/-/g, \"\")\n\t}\n\treturn `${Date.now().toString(36)}${Math.random().toString(36).slice(2)}`\n}\n\nfunction buildLoginCallbackUrl(callbackState: string, callbackUrl?: string) {\n\tconst baseUrl = callbackUrl || window.location.href\n\tconst url = new URL(baseUrl, window.location.href)\n\tconst returnHash = url.hash.replace(/^#/, \"\")\n\n\turl.hash = \"\"\n\turl.searchParams.set(LOGIN_CALLBACK_MARKER, \"1\")\n\turl.searchParams.set(LOGIN_CALLBACK_STATE_PARAM, callbackState)\n\tif (returnHash) {\n\t\turl.searchParams.set(LOGIN_CALLBACK_RETURN_HASH_PARAM, returnHash)\n\t} else {\n\t\turl.searchParams.delete(LOGIN_CALLBACK_RETURN_HASH_PARAM)\n\t}\n\n\treturn url.toString()\n}\n\nfunction buildLoginLaunchPayload(\n\tparams: LoginParams,\n\toptions?: LoginUIOptions,\n\tcallbackState?: string,\n) {\n\tconst parentOrigin =\n\t\ttypeof window !== \"undefined\" ? window.location.origin : undefined\n\tconst callbackUrl =\n\t\ttypeof window !== \"undefined\" && callbackState\n\t\t\t? buildLoginCallbackUrl(callbackState, options?.callbackUrl)\n\t\t\t: undefined\n\n\treturn {\n\t\tautoClose: options?.autoClose ?? true,\n\t\tcallbackUrl,\n\t\tcallbackState,\n\t\torigin: parentOrigin,\n\t\tpreferredChannel: params.preferredChannel,\n\t}\n}\n\nfunction appendLoginLaunchHash(\n\turlValue: string,\n\tpayload: ReturnType<typeof buildLoginLaunchPayload>,\n) {\n\tconst hashParams = new URLSearchParams()\n\tif (payload.autoClose === false) {\n\t\thashParams.set(\"ydAutoClose\", \"false\")\n\t}\n\tif (payload.origin) {\n\t\thashParams.set(\"ydOrigin\", payload.origin)\n\t}\n\tif (payload.callbackUrl) {\n\t\thashParams.set(\"ydCallbackUrl\", payload.callbackUrl)\n\t}\n\tif (payload.preferredChannel) {\n\t\thashParams.set(\"ydPreferredChannel\", payload.preferredChannel)\n\t}\n\tconst hash = hashParams.toString()\n\tif (!hash) {\n\t\treturn urlValue\n\t}\n\n\ttry {\n\t\tconst url = new URL(urlValue)\n\t\turl.hash = hash\n\t\treturn url.toString()\n\t} catch (_error) {\n\t\treturn `${urlValue}#${hash}`\n\t}\n}\n\nfunction buildLoginPopupName(payload: LoginLaunchPayload) {\n\treturn `youidian-login:${JSON.stringify(payload)}`\n}\n\nfunction buildLoginUrl(\n\tparams: LoginParams,\n\toptions: LoginUIOptions | undefined,\n\tlaunchPayload: LoginLaunchPayload,\n): string {\n\tconst { appId, baseUrl = \"https://pay.imgto.link\", loginUrl } = params\n\tconst rawBase = (loginUrl || baseUrl).replace(/\\/$/, \"\")\n\tconst parentOrigin = launchPayload.origin\n\n\tlet finalUrl: string\n\ttry {\n\t\tconst url = new URL(rawBase)\n\t\tif (!/\\/auth\\/connect\\/[^/]+$/.test(url.pathname)) {\n\t\t\turl.pathname =\n\t\t\t\t`${url.pathname.replace(/\\/$/, \"\")}/auth/connect/${appId}`.replace(\n\t\t\t\t\t/\\/{2,}/g,\n\t\t\t\t\t\"/\",\n\t\t\t\t)\n\t\t}\n\t\tfinalUrl = url.toString()\n\t} catch (_error) {\n\t\tif (/\\/auth\\/connect\\/[^/]+$/.test(rawBase)) {\n\t\t\tfinalUrl = rawBase\n\t\t} else {\n\t\t\tfinalUrl = `${rawBase}/auth/connect/${appId}`.replace(/\\/{2,}/g, \"/\")\n\t\t}\n\t}\n\n\tfinalUrl = applyLocaleToUrl(finalUrl, getAutoResolvedLocale(params.locale))\n\n\ttry {\n\t\tconst url = new URL(finalUrl)\n\t\tif (params.preferredChannel) {\n\t\t\turl.searchParams.set(\"preferredChannel\", params.preferredChannel)\n\t\t}\n\t\tif (options?.autoClose === false) {\n\t\t\turl.searchParams.set(\"autoClose\", \"false\")\n\t\t}\n\t\tif (parentOrigin) {\n\t\t\turl.searchParams.set(\"origin\", parentOrigin)\n\t\t}\n\t\tif (launchPayload.callbackUrl) {\n\t\t\turl.searchParams.set(\"callbackUrl\", launchPayload.callbackUrl)\n\t\t}\n\t\treturn appendLoginLaunchHash(url.toString(), launchPayload)\n\t} catch (_error) {\n\t\tconst searchParams = new URLSearchParams()\n\t\tif (params.preferredChannel) {\n\t\t\tsearchParams.set(\"preferredChannel\", params.preferredChannel)\n\t\t}\n\t\tif (options?.autoClose === false) {\n\t\t\tsearchParams.set(\"autoClose\", \"false\")\n\t\t}\n\t\tif (parentOrigin) {\n\t\t\tsearchParams.set(\"origin\", parentOrigin)\n\t\t}\n\t\tif (launchPayload.callbackUrl) {\n\t\t\tsearchParams.set(\"callbackUrl\", launchPayload.callbackUrl)\n\t\t}\n\t\tconst query = searchParams.toString()\n\t\tif (!query) {\n\t\t\treturn appendLoginLaunchHash(finalUrl, launchPayload)\n\t\t}\n\t\tconst separator = finalUrl.includes(\"?\") ? \"&\" : \"?\"\n\t\treturn appendLoginLaunchHash(\n\t\t\t`${finalUrl}${separator}${query}`,\n\t\t\tlaunchPayload,\n\t\t)\n\t}\n}\n\nfunction extractLoginResult(data: LoginEventData): LoginResult {\n\treturn {\n\t\tavatar: data.avatar,\n\t\tchannel: data.channel,\n\t\temail: data.email,\n\t\texpiresAt: data.expiresAt,\n\t\tlegacyCasdoorId: data.legacyCasdoorId,\n\t\tloginToken: data.loginToken,\n\t\tname: data.name,\n\t\tuserId: data.userId,\n\t\twechatOpenId: data.wechatOpenId,\n\t\twechatUnionId: data.wechatUnionId,\n\t}\n}\n\nconst LOGIN_UI_LOG_PREFIX = \"[Youidian LoginUI]\"\nconst LOGIN_CALLBACK_MARKER = \"yd_login_callback\"\nconst LOGIN_CALLBACK_RESULT_PARAM = \"yd_login_result\"\nconst LOGIN_CALLBACK_RETURN_HASH_PARAM = \"yd_login_return_hash\"\nconst LOGIN_CALLBACK_STATE_PARAM = \"yd_login_state\"\nconst LOGIN_CALLBACK_STORAGE_PREFIX = \"yd-login-callback:\"\n\ntype LoginLaunchPayload = ReturnType<typeof buildLoginLaunchPayload>\n\nfunction decodeCallbackPayload(value: string): LoginEventData | null {\n\ttry {\n\t\tconst padded = value.padEnd(\n\t\t\tvalue.length + ((4 - (value.length % 4)) % 4),\n\t\t\t\"=\",\n\t\t)\n\t\tconst base64 = padded.replaceAll(\"-\", \"+\").replaceAll(\"_\", \"/\")\n\t\tconst binary = atob(base64)\n\t\tconst json = decodeURIComponent(\n\t\t\tArray.from(\n\t\t\t\tbinary,\n\t\t\t\t(char) => `%${char.charCodeAt(0).toString(16).padStart(2, \"0\")}`,\n\t\t\t).join(\"\"),\n\t\t)\n\t\tconst parsed = JSON.parse(json) as LoginEventData\n\t\treturn parsed && typeof parsed === \"object\" && parsed.type ? parsed : null\n\t} catch {\n\t\treturn null\n\t}\n}\n\nfunction getLoginCallbackChannelName(state: string) {\n\treturn `youidian-login:${state}`\n}\n\nfunction getLoginCallbackStorageKey(state: string) {\n\treturn `${LOGIN_CALLBACK_STORAGE_PREFIX}${state}`\n}\n\nfunction publishLoginCallback(state: string, data: LoginEventData) {\n\ttry {\n\t\tconst channel = new BroadcastChannel(getLoginCallbackChannelName(state))\n\t\tchannel.postMessage(data)\n\t\tchannel.close()\n\t} catch {\n\t\t// BroadcastChannel is not available in every embedded browser.\n\t}\n\n\ttry {\n\t\tconst storageKey = getLoginCallbackStorageKey(state)\n\t\twindow.localStorage.setItem(storageKey, JSON.stringify(data))\n\t\twindow.setTimeout(() => {\n\t\t\ttry {\n\t\t\t\twindow.localStorage.removeItem(storageKey)\n\t\t\t} catch {\n\t\t\t\t// Ignore cleanup failures.\n\t\t\t}\n\t\t}, 800)\n\t} catch {\n\t\t// localStorage may be disabled; postMessage remains available below.\n\t}\n\n\ttry {\n\t\twindow.opener?.postMessage(data, window.location.origin)\n\t} catch {\n\t\t// opener is only an opportunistic fast path.\n\t}\n}\n\nfunction cleanLoginCallbackUrl(url: URL) {\n\turl.searchParams.delete(LOGIN_CALLBACK_MARKER)\n\turl.searchParams.delete(LOGIN_CALLBACK_STATE_PARAM)\n\tconst returnHash = url.searchParams.get(LOGIN_CALLBACK_RETURN_HASH_PARAM)\n\turl.searchParams.delete(LOGIN_CALLBACK_RETURN_HASH_PARAM)\n\turl.hash = returnHash ? `#${returnHash}` : \"\"\n\treturn url.toString()\n}\n\nexport function handleLoginCallbackIfPresent() {\n\tif (typeof window === \"undefined\") {\n\t\treturn false\n\t}\n\n\tconst url = new URL(window.location.href)\n\tif (url.searchParams.get(LOGIN_CALLBACK_MARKER) !== \"1\") {\n\t\treturn false\n\t}\n\n\tconst state = url.searchParams.get(LOGIN_CALLBACK_STATE_PARAM) || \"\"\n\tconst hashParams = new URLSearchParams(url.hash.replace(/^#/, \"\"))\n\tconst rawResult = hashParams.get(LOGIN_CALLBACK_RESULT_PARAM)\n\tconst data: LoginEventData | null =\n\t\trawResult && state\n\t\t\t? decodeCallbackPayload(rawResult)\n\t\t\t: {\n\t\t\t\t\ttype: \"LOGIN_ERROR\",\n\t\t\t\t\tmessage: \"Missing login callback result\",\n\t\t\t\t}\n\n\ttry {\n\t\tdocument.documentElement.style.visibility = \"hidden\"\n\t} catch {\n\t\t// This is best-effort to avoid a visible callback-page flash.\n\t}\n\n\tif (state && data) {\n\t\tpublishLoginCallback(state, data)\n\t}\n\n\ttry {\n\t\twindow.history.replaceState(null, \"\", cleanLoginCallbackUrl(url))\n\t} catch {\n\t\t// Ignore history cleanup failures.\n\t}\n\n\twindow.setTimeout(() => {\n\t\ttry {\n\t\t\twindow.close()\n\t\t} catch {\n\t\t\t// Some browsers disallow script-closing the current window.\n\t\t}\n\t}, 30)\n\n\treturn true\n}\n\nfunction logLoginDebug(message: string, details?: Record<string, unknown>) {\n\tif (typeof console === \"undefined\") return\n\tconsole.debug(LOGIN_UI_LOG_PREFIX, message, details || {})\n}\n\nfunction logLoginInfo(message: string, details?: Record<string, unknown>) {\n\tif (typeof console === \"undefined\") return\n\tconsole.info(LOGIN_UI_LOG_PREFIX, message, details || {})\n}\n\nfunction logLoginWarn(message: string, details?: Record<string, unknown>) {\n\tif (typeof console === \"undefined\") return\n\tconsole.warn(LOGIN_UI_LOG_PREFIX, message, details || {})\n}\n\nexport class LoginUI {\n\tprivate popup: Window | null = null\n\tprivate callbackChannel: BroadcastChannel | null = null\n\tprivate callbackStorageHandler: ((event: StorageEvent) => void) | null = null\n\tprivate messageHandler: ((event: MessageEvent) => void) | null = null\n\tprivate closeMonitor: number | null = null\n\tprivate completed = false\n\n\tprivate cleanup() {\n\t\tif (this.callbackChannel) {\n\t\t\tthis.callbackChannel.close()\n\t\t}\n\t\tif (typeof window !== \"undefined\" && this.callbackStorageHandler) {\n\t\t\twindow.removeEventListener(\"storage\", this.callbackStorageHandler)\n\t\t}\n\t\tif (typeof window !== \"undefined\" && this.messageHandler) {\n\t\t\twindow.removeEventListener(\"message\", this.messageHandler)\n\t\t}\n\t\tthis.callbackChannel = null\n\t\tthis.callbackStorageHandler = null\n\t\tif (typeof window !== \"undefined\" && this.closeMonitor) {\n\t\t\twindow.clearInterval(this.closeMonitor)\n\t\t}\n\t\tthis.messageHandler = null\n\t\tthis.closeMonitor = null\n\t\tthis.popup = null\n\t\tthis.completed = false\n\t}\n\n\tprivate handleLoginEvent(data: LoginEventData, options?: LoginUIOptions) {\n\t\tif (!data || typeof data !== \"object\" || !data.type) {\n\t\t\tlogLoginDebug(\"Ignored non-login event payload\")\n\t\t\treturn\n\t\t}\n\n\t\tlogLoginInfo(\"Received login event\", {\n\t\t\ttype: data.type,\n\t\t})\n\n\t\tswitch (data.type) {\n\t\t\tcase \"LOGIN_SUCCESS\":\n\t\t\t\tif (this.completed) {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tthis.completed = true\n\t\t\t\tlogLoginInfo(\"Login succeeded\", {\n\t\t\t\t\tchannel: data.channel || null,\n\t\t\t\t\tuserId: data.userId || null,\n\t\t\t\t})\n\t\t\t\toptions?.onSuccess?.(extractLoginResult(data))\n\t\t\t\tbreak\n\t\t\tcase \"LOGIN_CANCELLED\":\n\t\t\t\tlogLoginInfo(\"Login cancelled\")\n\t\t\t\toptions?.onCancel?.()\n\t\t\t\tbreak\n\t\t\tcase \"LOGIN_RESIZE\":\n\t\t\t\tbreak\n\t\t\tcase \"LOGIN_ERROR\":\n\t\t\t\tif (this.completed) {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tlogLoginWarn(\"Login flow reported an error\", {\n\t\t\t\t\tmessage: data.message || data.error || null,\n\t\t\t\t})\n\t\t\t\toptions?.onError?.(data.message || data.error, data)\n\t\t\t\tbreak\n\t\t\tcase \"LOGIN_CLOSE\":\n\t\t\t\tif (options?.autoClose === false) {\n\t\t\t\t\tlogLoginInfo(\n\t\t\t\t\t\t\"Login popup requested close; autoClose disabled, keeping popup open\",\n\t\t\t\t\t)\n\t\t\t\t\toptions?.onClose?.()\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tlogLoginInfo(\"Login popup requested close; autoClose enabled\")\n\t\t\t\tthis.close()\n\t\t\t\toptions?.onClose?.()\n\t\t\t\tbreak\n\t\t}\n\t}\n\n\tprivate listenForLoginCallback(\n\t\tcallbackState: string,\n\t\toptions?: LoginUIOptions,\n\t) {\n\t\ttry {\n\t\t\tthis.callbackChannel = new BroadcastChannel(\n\t\t\t\tgetLoginCallbackChannelName(callbackState),\n\t\t\t)\n\t\t\tthis.callbackChannel.onmessage = (event) => {\n\t\t\t\tthis.handleLoginEvent(event.data as LoginEventData, options)\n\t\t\t\tthis.handleLoginEvent({ type: \"LOGIN_CLOSE\" }, options)\n\t\t\t}\n\t\t} catch {\n\t\t\tlogLoginDebug(\"BroadcastChannel is unavailable for login callback\")\n\t\t}\n\n\t\tthis.callbackStorageHandler = (event: StorageEvent) => {\n\t\t\tif (\n\t\t\t\tevent.key !== getLoginCallbackStorageKey(callbackState) ||\n\t\t\t\t!event.newValue\n\t\t\t) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst data = JSON.parse(event.newValue) as LoginEventData\n\t\t\t\tthis.handleLoginEvent(data, options)\n\t\t\t\tthis.handleLoginEvent({ type: \"LOGIN_CLOSE\" }, options)\n\t\t\t} catch {\n\t\t\t\tlogLoginWarn(\"Failed to parse login callback storage payload\")\n\t\t\t}\n\t\t}\n\t\twindow.addEventListener(\"storage\", this.callbackStorageHandler)\n\t}\n\n\tclose() {\n\t\tlogLoginInfo(\"close() called\", {\n\t\t\thasPopup: Boolean(this.popup),\n\t\t\tpopupClosed: this.popup?.closed ?? true,\n\t\t})\n\t\tif (this.popup && !this.popup.closed) {\n\t\t\tthis.popup.close()\n\t\t}\n\t\tthis.cleanup()\n\t}\n\n\topenLogin(params: LoginParams, options?: LoginUIOptions) {\n\t\tif (typeof window === \"undefined\") return\n\t\tif (this.popup && !this.popup.closed) return\n\n\t\tconst callbackState = createLoginCallbackState()\n\t\tconst launchPayload = buildLoginLaunchPayload(\n\t\t\tparams,\n\t\t\toptions,\n\t\t\tcallbackState,\n\t\t)\n\t\tconst finalUrl = buildLoginUrl(params, options, launchPayload)\n\t\tlogLoginInfo(\"Opening hosted login popup\", {\n\t\t\tappId: params.appId,\n\t\t\tcallbackState,\n\t\t\tcallbackUrl: launchPayload.callbackUrl || null,\n\t\t\thasCallbackUrl: Boolean(launchPayload.callbackUrl),\n\t\t\tloginUrl: finalUrl,\n\t\t\tallowedOrigin: options?.allowedOrigin || null,\n\t\t\tautoClose: options?.autoClose ?? true,\n\t\t\tpageUrl: typeof window !== \"undefined\" ? window.location.href : null,\n\t\t\tparentOrigin: launchPayload.origin || null,\n\t\t})\n\t\tconst popupWidth = 520\n\t\tconst popupHeight = 720\n\t\tconst left = Math.max(\n\t\t\t0,\n\t\t\tMath.round(window.screenX + (window.outerWidth - popupWidth) / 2),\n\t\t)\n\t\tconst top = Math.max(\n\t\t\t0,\n\t\t\tMath.round(window.screenY + (window.outerHeight - popupHeight) / 2),\n\t\t)\n\t\tconst features = [\n\t\t\t\"popup=yes\",\n\t\t\t`width=${popupWidth}`,\n\t\t\t`height=${popupHeight}`,\n\t\t\t`left=${left}`,\n\t\t\t`top=${top}`,\n\t\t\t\"resizable=yes\",\n\t\t\t\"scrollbars=yes\",\n\t\t].join(\",\")\n\n\t\tconst popupName = buildLoginPopupName(launchPayload)\n\t\tconst popup = window.open(finalUrl, popupName, features)\n\t\tif (!popup) {\n\t\t\tlogLoginWarn(\"Popup blocked by the browser\")\n\t\t\toptions?.onError?.(\"Login popup was blocked\")\n\t\t\treturn\n\t\t}\n\n\t\tthis.popup = popup\n\t\tthis.completed = false\n\t\tthis.listenForLoginCallback(callbackState, options)\n\n\t\tconst allowedOrigin = options?.allowedOrigin\n\t\tconst popupOrigin = getOrigin(finalUrl)\n\n\t\tthis.messageHandler = (event: MessageEvent) => {\n\t\t\tif (\n\t\t\t\tallowedOrigin &&\n\t\t\t\tallowedOrigin !== \"*\" &&\n\t\t\t\tevent.origin !== allowedOrigin\n\t\t\t) {\n\t\t\t\tlogLoginWarn(\"Ignored message due to allowedOrigin mismatch\", {\n\t\t\t\t\tallowedOrigin,\n\t\t\t\t\teventOrigin: event.origin,\n\t\t\t\t})\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (!allowedOrigin && popupOrigin && event.origin !== popupOrigin) {\n\t\t\t\tlogLoginWarn(\"Ignored message due to popup origin mismatch\", {\n\t\t\t\t\texpectedOrigin: popupOrigin,\n\t\t\t\t\teventOrigin: event.origin,\n\t\t\t\t})\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst data = event.data as LoginEventData\n\t\t\tif (!data || typeof data !== \"object\" || !data.type) {\n\t\t\t\tlogLoginDebug(\"Ignored non-login postMessage payload\")\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tlogLoginInfo(\"Received login event\", {\n\t\t\t\ttype: data.type,\n\t\t\t\teventOrigin: event.origin,\n\t\t\t})\n\n\t\t\tthis.handleLoginEvent(data, options)\n\t\t}\n\n\t\twindow.addEventListener(\"message\", this.messageHandler)\n\n\t\tthis.closeMonitor = window.setInterval(() => {\n\t\t\tif (!this.popup || this.popup.closed) {\n\t\t\t\tconst shouldTreatAsCancel = !this.completed\n\t\t\t\tlogLoginInfo(\"Detected popup closed\", {\n\t\t\t\t\tshouldTreatAsCancel,\n\t\t\t\t})\n\t\t\t\tthis.cleanup()\n\t\t\t\tif (shouldTreatAsCancel) {\n\t\t\t\t\toptions?.onCancel?.()\n\t\t\t\t}\n\t\t\t\toptions?.onClose?.()\n\t\t\t}\n\t\t}, 500)\n\t}\n}\n\nexport function createLoginUI(): LoginUI {\n\treturn new LoginUI()\n}\n\nhandleLoginCallbackIfPresent()\n","export interface HostedFrameMessage {\n\ttype: string\n\theight?: number\n}\n\ntype HostedFrameOptions<TData extends HostedFrameMessage> = {\n\tallowedOrigin?: string\n\theight?: string\n\tonCloseButton?: () => void\n\tonMessage: (data: TData, container: HTMLDivElement) => void\n\twidth?: string\n}\n\nconst SDK_SUPPORTED_LOCALES = [\n\t\"en\",\n\t\"zh-CN\",\n\t\"zh-Hant\",\n\t\"fr\",\n\t\"de\",\n\t\"ja\",\n\t\"es\",\n\t\"ko\",\n\t\"nl\",\n\t\"it\",\n\t\"pt\",\n] as const\n\nconst SDK_DEFAULT_LOCALE = \"zh-CN\"\n\nconst SDK_LOCALE_ALIASES: Record<string, string> = {\n\ten: \"en\",\n\t\"en-us\": \"en\",\n\t\"en-gb\": \"en\",\n\tzh: \"zh-CN\",\n\t\"zh-cn\": \"zh-CN\",\n\t\"zh-tw\": \"zh-Hant\",\n\t\"zh-hk\": \"zh-Hant\",\n\t\"zh-hant\": \"zh-Hant\",\n\t\"zh-hans\": \"zh-CN\",\n\tfr: \"fr\",\n\tde: \"de\",\n\tja: \"ja\",\n\tes: \"es\",\n\tko: \"ko\",\n\tnl: \"nl\",\n\tit: \"it\",\n\tpt: \"pt\",\n}\n\nfunction matchSupportedBaseLocale(locale: string): string | undefined {\n\tconst base = locale.toLowerCase().split(\"-\")[0]\n\treturn SDK_SUPPORTED_LOCALES.find((item) => item.toLowerCase() === base)\n}\n\nexport function normalizeSdkLocale(locale?: string): string | undefined {\n\tif (!locale) return\n\n\tconst sanitized = locale.trim().replace(/_/g, \"-\")\n\tif (!sanitized) return\n\n\tconst lower = sanitized.toLowerCase()\n\tif (SDK_LOCALE_ALIASES[lower]) {\n\t\treturn SDK_LOCALE_ALIASES[lower]\n\t}\n\n\tlet canonical: string | undefined\n\ttry {\n\t\tcanonical = Intl.getCanonicalLocales(sanitized)[0]\n\t} catch {\n\t\tcanonical = undefined\n\t}\n\n\tconst candidates = [canonical, sanitized].filter(Boolean) as string[]\n\n\tfor (const candidate of candidates) {\n\t\tconst candidateLower = candidate.toLowerCase()\n\n\t\tif (SDK_LOCALE_ALIASES[candidateLower]) {\n\t\t\treturn SDK_LOCALE_ALIASES[candidateLower]\n\t\t}\n\t\tif ((SDK_SUPPORTED_LOCALES as readonly string[]).includes(candidate)) {\n\t\t\treturn candidate\n\t\t}\n\n\t\tconst baseMatch = matchSupportedBaseLocale(candidate)\n\t\tif (baseMatch) {\n\t\t\treturn baseMatch\n\t\t}\n\t}\n}\n\nexport function getBrowserLocale(): string | undefined {\n\tif (typeof navigator === \"undefined\") return\n\n\tfor (const candidate of navigator.languages || []) {\n\t\tconst normalized = normalizeSdkLocale(candidate)\n\t\tif (normalized) return normalized\n\t}\n\n\treturn normalizeSdkLocale(navigator.language)\n}\n\nexport function getAutoResolvedLocale(locale?: string): string {\n\treturn normalizeSdkLocale(locale) || getBrowserLocale() || SDK_DEFAULT_LOCALE\n}\n\nexport function applyLocaleToUrl(urlValue: string, locale?: string): string {\n\tif (!locale) return urlValue\n\n\ttry {\n\t\tconst url = new URL(urlValue)\n\t\tconst localePrefix = `/${locale}`\n\t\tif (\n\t\t\t!url.pathname.startsWith(`${localePrefix}/`) &&\n\t\t\turl.pathname !== localePrefix\n\t\t) {\n\t\t\turl.pathname = `${localePrefix}${url.pathname}`\n\t\t}\n\t\treturn url.toString()\n\t} catch (_error) {\n\t\tconst localePrefix = `/${locale}`\n\t\tif (!urlValue.startsWith(`${localePrefix}/`) && urlValue !== localePrefix) {\n\t\t\treturn `${localePrefix}${urlValue.startsWith(\"/\") ? \"\" : \"/\"}${urlValue}`\n\t\t}\n\t\treturn urlValue\n\t}\n}\n\nexport class HostedFrameModal<TData extends HostedFrameMessage> {\n\tprotected iframe: HTMLIFrameElement | null = null\n\tprotected modal: HTMLDivElement | null = null\n\tprotected messageHandler: ((event: MessageEvent) => void) | null = null\n\n\tprotected openHostedFrame(\n\t\turl: string,\n\t\toptions: HostedFrameOptions<TData>,\n\t): void {\n\t\tif (typeof document === \"undefined\") return\n\t\tif (this.modal) return\n\n\t\tthis.modal = document.createElement(\"div\")\n\t\tObject.assign(this.modal.style, {\n\t\t\tposition: \"fixed\",\n\t\t\ttop: \"0\",\n\t\t\tleft: \"0\",\n\t\t\twidth: \"100%\",\n\t\t\theight: \"100%\",\n\t\t\tbackgroundColor: \"rgba(15,23,42,0.52)\",\n\t\t\tdisplay: \"flex\",\n\t\t\talignItems: \"center\",\n\t\t\tjustifyContent: \"center\",\n\t\t\tzIndex: \"9999\",\n\t\t\ttransition: \"opacity 0.3s ease\",\n\t\t\tbackdropFilter: \"blur(14px)\",\n\t\t\tpadding: \"16px\",\n\t\t})\n\n\t\tconst container = document.createElement(\"div\")\n\t\tObject.assign(container.style, {\n\t\t\twidth: options.width || \"450px\",\n\t\t\theight: options.height || \"min(600px, 90vh)\",\n\t\t\tbackgroundColor: \"transparent\",\n\t\t\tborderRadius: \"28px\",\n\t\t\toverflow: \"visible\",\n\t\t\tposition: \"relative\",\n\t\t\tboxShadow: \"none\",\n\t\t\tmaxWidth: \"calc(100vw - 32px)\",\n\t\t\tmaxHeight: \"calc(100vh - 32px)\",\n\t\t\ttransition: \"height 180ms ease\",\n\t\t\twillChange: \"height\",\n\t\t})\n\n\t\tconst closeBtn = document.createElement(\"button\")\n\t\tcloseBtn.innerHTML = \"×\"\n\t\tObject.assign(closeBtn.style, {\n\t\t\tposition: \"absolute\",\n\t\t\tright: \"-14px\",\n\t\t\ttop: \"-14px\",\n\t\t\tfontSize: \"20px\",\n\t\t\twidth: \"36px\",\n\t\t\theight: \"36px\",\n\t\t\tborderRadius: \"9999px\",\n\t\t\tborder: \"1px solid rgba(255,255,255,0.5)\",\n\t\t\tbackground: \"rgba(255,255,255,0.9)\",\n\t\t\tcursor: \"pointer\",\n\t\t\tcolor: \"#475569\",\n\t\t\tzIndex: \"2\",\n\t\t\tboxShadow: \"0 10px 30px rgba(15,23,42,0.16)\",\n\t\t})\n\t\tcloseBtn.onclick = () => {\n\t\t\tthis.close()\n\t\t\toptions.onCloseButton?.()\n\t\t}\n\n\t\tthis.iframe = document.createElement(\"iframe\")\n\t\tthis.iframe.src = url\n\t\tObject.assign(this.iframe.style, {\n\t\t\twidth: \"100%\",\n\t\t\theight: \"100%\",\n\t\t\tborder: \"none\",\n\t\t\tborderRadius: \"28px\",\n\t\t\tbackground: \"transparent\",\n\t\t\tdisplay: \"block\",\n\t\t})\n\n\t\tcontainer.appendChild(closeBtn)\n\t\tcontainer.appendChild(this.iframe)\n\t\tthis.modal.appendChild(container)\n\t\tdocument.body.appendChild(this.modal)\n\n\t\tthis.messageHandler = (event: MessageEvent) => {\n\t\t\tif (options.allowedOrigin && options.allowedOrigin !== \"*\") {\n\t\t\t\tif (event.origin !== options.allowedOrigin) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst data = event.data as TData\n\t\t\tif (!data || typeof data !== \"object\" || !data.type) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\toptions.onMessage(data, container)\n\t\t}\n\n\t\twindow.addEventListener(\"message\", this.messageHandler)\n\t}\n\n\tclose() {\n\t\tif (typeof window === \"undefined\") return\n\n\t\tif (this.messageHandler) {\n\t\t\twindow.removeEventListener(\"message\", this.messageHandler)\n\t\t\tthis.messageHandler = null\n\t\t}\n\n\t\tif (this.modal?.parentNode) {\n\t\t\tthis.modal.parentNode.removeChild(this.modal)\n\t\t}\n\n\t\tthis.modal = null\n\t\tthis.iframe = null\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACaA,IAAM,wBAAwB;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD;AAEA,IAAM,qBAAqB;AAE3B,IAAM,qBAA6C;AAAA,EAClD,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,SAAS;AAAA,EACT,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,WAAW;AAAA,EACX,WAAW;AAAA,EACX,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACL;AAEA,SAAS,yBAAyB,QAAoC;AACrE,QAAM,OAAO,OAAO,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC;AAC9C,SAAO,sBAAsB,KAAK,CAAC,SAAS,KAAK,YAAY,MAAM,IAAI;AACxE;AAEO,SAAS,mBAAmB,QAAqC;AACvE,MAAI,CAAC,OAAQ;AAEb,QAAM,YAAY,OAAO,KAAK,EAAE,QAAQ,MAAM,GAAG;AACjD,MAAI,CAAC,UAAW;AAEhB,QAAM,QAAQ,UAAU,YAAY;AACpC,MAAI,mBAAmB,KAAK,GAAG;AAC9B,WAAO,mBAAmB,KAAK;AAAA,EAChC;AAEA,MAAI;AACJ,MAAI;AACH,gBAAY,KAAK,oBAAoB,SAAS,EAAE,CAAC;AAAA,EAClD,QAAQ;AACP,gBAAY;AAAA,EACb;AAEA,QAAM,aAAa,CAAC,WAAW,SAAS,EAAE,OAAO,OAAO;AAExD,aAAW,aAAa,YAAY;AACnC,UAAM,iBAAiB,UAAU,YAAY;AAE7C,QAAI,mBAAmB,cAAc,GAAG;AACvC,aAAO,mBAAmB,cAAc;AAAA,IACzC;AACA,QAAK,sBAA4C,SAAS,SAAS,GAAG;AACrE,aAAO;AAAA,IACR;AAEA,UAAM,YAAY,yBAAyB,SAAS;AACpD,QAAI,WAAW;AACd,aAAO;AAAA,IACR;AAAA,EACD;AACD;AAEO,SAAS,mBAAuC;AACtD,MAAI,OAAO,cAAc,YAAa;AAEtC,aAAW,aAAa,UAAU,aAAa,CAAC,GAAG;AAClD,UAAM,aAAa,mBAAmB,SAAS;AAC/C,QAAI,WAAY,QAAO;AAAA,EACxB;AAEA,SAAO,mBAAmB,UAAU,QAAQ;AAC7C;AAEO,SAAS,sBAAsB,QAAyB;AAC9D,SAAO,mBAAmB,MAAM,KAAK,iBAAiB,KAAK;AAC5D;AAEO,SAAS,iBAAiB,UAAkB,QAAyB;AAC3E,MAAI,CAAC,OAAQ,QAAO;AAEpB,MAAI;AACH,UAAM,MAAM,IAAI,IAAI,QAAQ;AAC5B,UAAM,eAAe,IAAI,MAAM;AAC/B,QACC,CAAC,IAAI,SAAS,WAAW,GAAG,YAAY,GAAG,KAC3C,IAAI,aAAa,cAChB;AACD,UAAI,WAAW,GAAG,YAAY,GAAG,IAAI,QAAQ;AAAA,IAC9C;AACA,WAAO,IAAI,SAAS;AAAA,EACrB,SAAS,QAAQ;AAChB,UAAM,eAAe,IAAI,MAAM;AAC/B,QAAI,CAAC,SAAS,WAAW,GAAG,YAAY,GAAG,KAAK,aAAa,cAAc;AAC1E,aAAO,GAAG,YAAY,GAAG,SAAS,WAAW,GAAG,IAAI,KAAK,GAAG,GAAG,QAAQ;AAAA,IACxE;AACA,WAAO;AAAA,EACR;AACD;;;ADxDA,SAAS,UAAU,OAA+B;AACjD,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI;AACH,WAAO,IAAI,IAAI,KAAK,EAAE;AAAA,EACvB,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAEA,SAAS,2BAA2B;AACnC,MAAI,OAAO,WAAW,eAAe,OAAO,YAAY;AACvD,WAAO,OAAO,WAAW,EAAE,QAAQ,MAAM,EAAE;AAAA,EAC5C;AACA,SAAO,GAAG,KAAK,IAAI,EAAE,SAAS,EAAE,CAAC,GAAG,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC;AACxE;AAEA,SAAS,sBAAsB,eAAuB,aAAsB;AAC3E,QAAM,UAAU,eAAe,OAAO,SAAS;AAC/C,QAAM,MAAM,IAAI,IAAI,SAAS,OAAO,SAAS,IAAI;AACjD,QAAM,aAAa,IAAI,KAAK,QAAQ,MAAM,EAAE;AAE5C,MAAI,OAAO;AACX,MAAI,aAAa,IAAI,uBAAuB,GAAG;AAC/C,MAAI,aAAa,IAAI,4BAA4B,aAAa;AAC9D,MAAI,YAAY;AACf,QAAI,aAAa,IAAI,kCAAkC,UAAU;AAAA,EAClE,OAAO;AACN,QAAI,aAAa,OAAO,gCAAgC;AAAA,EACzD;AAEA,SAAO,IAAI,SAAS;AACrB;AAEA,SAAS,wBACR,QACA,SACA,eACC;AACD,QAAM,eACL,OAAO,WAAW,cAAc,OAAO,SAAS,SAAS;AAC1D,QAAM,cACL,OAAO,WAAW,eAAe,gBAC9B,sBAAsB,eAAe,SAAS,WAAW,IACzD;AAEJ,SAAO;AAAA,IACN,WAAW,SAAS,aAAa;AAAA,IACjC;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,kBAAkB,OAAO;AAAA,EAC1B;AACD;AAEA,SAAS,sBACR,UACA,SACC;AACD,QAAM,aAAa,IAAI,gBAAgB;AACvC,MAAI,QAAQ,cAAc,OAAO;AAChC,eAAW,IAAI,eAAe,OAAO;AAAA,EACtC;AACA,MAAI,QAAQ,QAAQ;AACnB,eAAW,IAAI,YAAY,QAAQ,MAAM;AAAA,EAC1C;AACA,MAAI,QAAQ,aAAa;AACxB,eAAW,IAAI,iBAAiB,QAAQ,WAAW;AAAA,EACpD;AACA,MAAI,QAAQ,kBAAkB;AAC7B,eAAW,IAAI,sBAAsB,QAAQ,gBAAgB;AAAA,EAC9D;AACA,QAAM,OAAO,WAAW,SAAS;AACjC,MAAI,CAAC,MAAM;AACV,WAAO;AAAA,EACR;AAEA,MAAI;AACH,UAAM,MAAM,IAAI,IAAI,QAAQ;AAC5B,QAAI,OAAO;AACX,WAAO,IAAI,SAAS;AAAA,EACrB,SAAS,QAAQ;AAChB,WAAO,GAAG,QAAQ,IAAI,IAAI;AAAA,EAC3B;AACD;AAEA,SAAS,oBAAoB,SAA6B;AACzD,SAAO,kBAAkB,KAAK,UAAU,OAAO,CAAC;AACjD;AAEA,SAAS,cACR,QACA,SACA,eACS;AACT,QAAM,EAAE,OAAO,UAAU,0BAA0B,SAAS,IAAI;AAChE,QAAM,WAAW,YAAY,SAAS,QAAQ,OAAO,EAAE;AACvD,QAAM,eAAe,cAAc;AAEnC,MAAI;AACJ,MAAI;AACH,UAAM,MAAM,IAAI,IAAI,OAAO;AAC3B,QAAI,CAAC,0BAA0B,KAAK,IAAI,QAAQ,GAAG;AAClD,UAAI,WACH,GAAG,IAAI,SAAS,QAAQ,OAAO,EAAE,CAAC,iBAAiB,KAAK,GAAG;AAAA,QAC1D;AAAA,QACA;AAAA,MACD;AAAA,IACF;AACA,eAAW,IAAI,SAAS;AAAA,EACzB,SAAS,QAAQ;AAChB,QAAI,0BAA0B,KAAK,OAAO,GAAG;AAC5C,iBAAW;AAAA,IACZ,OAAO;AACN,iBAAW,GAAG,OAAO,iBAAiB,KAAK,GAAG,QAAQ,WAAW,GAAG;AAAA,IACrE;AAAA,EACD;AAEA,aAAW,iBAAiB,UAAU,sBAAsB,OAAO,MAAM,CAAC;AAE1E,MAAI;AACH,UAAM,MAAM,IAAI,IAAI,QAAQ;AAC5B,QAAI,OAAO,kBAAkB;AAC5B,UAAI,aAAa,IAAI,oBAAoB,OAAO,gBAAgB;AAAA,IACjE;AACA,QAAI,SAAS,cAAc,OAAO;AACjC,UAAI,aAAa,IAAI,aAAa,OAAO;AAAA,IAC1C;AACA,QAAI,cAAc;AACjB,UAAI,aAAa,IAAI,UAAU,YAAY;AAAA,IAC5C;AACA,QAAI,cAAc,aAAa;AAC9B,UAAI,aAAa,IAAI,eAAe,cAAc,WAAW;AAAA,IAC9D;AACA,WAAO,sBAAsB,IAAI,SAAS,GAAG,aAAa;AAAA,EAC3D,SAAS,QAAQ;AAChB,UAAM,eAAe,IAAI,gBAAgB;AACzC,QAAI,OAAO,kBAAkB;AAC5B,mBAAa,IAAI,oBAAoB,OAAO,gBAAgB;AAAA,IAC7D;AACA,QAAI,SAAS,cAAc,OAAO;AACjC,mBAAa,IAAI,aAAa,OAAO;AAAA,IACtC;AACA,QAAI,cAAc;AACjB,mBAAa,IAAI,UAAU,YAAY;AAAA,IACxC;AACA,QAAI,cAAc,aAAa;AAC9B,mBAAa,IAAI,eAAe,cAAc,WAAW;AAAA,IAC1D;AACA,UAAM,QAAQ,aAAa,SAAS;AACpC,QAAI,CAAC,OAAO;AACX,aAAO,sBAAsB,UAAU,aAAa;AAAA,IACrD;AACA,UAAM,YAAY,SAAS,SAAS,GAAG,IAAI,MAAM;AACjD,WAAO;AAAA,MACN,GAAG,QAAQ,GAAG,SAAS,GAAG,KAAK;AAAA,MAC/B;AAAA,IACD;AAAA,EACD;AACD;AAEA,SAAS,mBAAmB,MAAmC;AAC9D,SAAO;AAAA,IACN,QAAQ,KAAK;AAAA,IACb,SAAS,KAAK;AAAA,IACd,OAAO,KAAK;AAAA,IACZ,WAAW,KAAK;AAAA,IAChB,iBAAiB,KAAK;AAAA,IACtB,YAAY,KAAK;AAAA,IACjB,MAAM,KAAK;AAAA,IACX,QAAQ,KAAK;AAAA,IACb,cAAc,KAAK;AAAA,IACnB,eAAe,KAAK;AAAA,EACrB;AACD;AAEA,IAAM,sBAAsB;AAC5B,IAAM,wBAAwB;AAC9B,IAAM,8BAA8B;AACpC,IAAM,mCAAmC;AACzC,IAAM,6BAA6B;AACnC,IAAM,gCAAgC;AAItC,SAAS,sBAAsB,OAAsC;AACpE,MAAI;AACH,UAAM,SAAS,MAAM;AAAA,MACpB,MAAM,UAAW,IAAK,MAAM,SAAS,KAAM;AAAA,MAC3C;AAAA,IACD;AACA,UAAM,SAAS,OAAO,WAAW,KAAK,GAAG,EAAE,WAAW,KAAK,GAAG;AAC9D,UAAM,SAAS,KAAK,MAAM;AAC1B,UAAM,OAAO;AAAA,MACZ,MAAM;AAAA,QACL;AAAA,QACA,CAAC,SAAS,IAAI,KAAK,WAAW,CAAC,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC;AAAA,MAC/D,EAAE,KAAK,EAAE;AAAA,IACV;AACA,UAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,WAAO,UAAU,OAAO,WAAW,YAAY,OAAO,OAAO,SAAS;AAAA,EACvE,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAEA,SAAS,4BAA4B,OAAe;AACnD,SAAO,kBAAkB,KAAK;AAC/B;AAEA,SAAS,2BAA2B,OAAe;AAClD,SAAO,GAAG,6BAA6B,GAAG,KAAK;AAChD;AAEA,SAAS,qBAAqB,OAAe,MAAsB;AAClE,MAAI;AACH,UAAM,UAAU,IAAI,iBAAiB,4BAA4B,KAAK,CAAC;AACvE,YAAQ,YAAY,IAAI;AACxB,YAAQ,MAAM;AAAA,EACf,QAAQ;AAAA,EAER;AAEA,MAAI;AACH,UAAM,aAAa,2BAA2B,KAAK;AACnD,WAAO,aAAa,QAAQ,YAAY,KAAK,UAAU,IAAI,CAAC;AAC5D,WAAO,WAAW,MAAM;AACvB,UAAI;AACH,eAAO,aAAa,WAAW,UAAU;AAAA,MAC1C,QAAQ;AAAA,MAER;AAAA,IACD,GAAG,GAAG;AAAA,EACP,QAAQ;AAAA,EAER;AAEA,MAAI;AACH,WAAO,QAAQ,YAAY,MAAM,OAAO,SAAS,MAAM;AAAA,EACxD,QAAQ;AAAA,EAER;AACD;AAEA,SAAS,sBAAsB,KAAU;AACxC,MAAI,aAAa,OAAO,qBAAqB;AAC7C,MAAI,aAAa,OAAO,0BAA0B;AAClD,QAAM,aAAa,IAAI,aAAa,IAAI,gCAAgC;AACxE,MAAI,aAAa,OAAO,gCAAgC;AACxD,MAAI,OAAO,aAAa,IAAI,UAAU,KAAK;AAC3C,SAAO,IAAI,SAAS;AACrB;AAEO,SAAS,+BAA+B;AAC9C,MAAI,OAAO,WAAW,aAAa;AAClC,WAAO;AAAA,EACR;AAEA,QAAM,MAAM,IAAI,IAAI,OAAO,SAAS,IAAI;AACxC,MAAI,IAAI,aAAa,IAAI,qBAAqB,MAAM,KAAK;AACxD,WAAO;AAAA,EACR;AAEA,QAAM,QAAQ,IAAI,aAAa,IAAI,0BAA0B,KAAK;AAClE,QAAM,aAAa,IAAI,gBAAgB,IAAI,KAAK,QAAQ,MAAM,EAAE,CAAC;AACjE,QAAM,YAAY,WAAW,IAAI,2BAA2B;AAC5D,QAAM,OACL,aAAa,QACV,sBAAsB,SAAS,IAC/B;AAAA,IACA,MAAM;AAAA,IACN,SAAS;AAAA,EACV;AAEH,MAAI;AACH,aAAS,gBAAgB,MAAM,aAAa;AAAA,EAC7C,QAAQ;AAAA,EAER;AAEA,MAAI,SAAS,MAAM;AAClB,yBAAqB,OAAO,IAAI;AAAA,EACjC;AAEA,MAAI;AACH,WAAO,QAAQ,aAAa,MAAM,IAAI,sBAAsB,GAAG,CAAC;AAAA,EACjE,QAAQ;AAAA,EAER;AAEA,SAAO,WAAW,MAAM;AACvB,QAAI;AACH,aAAO,MAAM;AAAA,IACd,QAAQ;AAAA,IAER;AAAA,EACD,GAAG,EAAE;AAEL,SAAO;AACR;AAEA,SAAS,cAAc,SAAiB,SAAmC;AAC1E,MAAI,OAAO,YAAY,YAAa;AACpC,UAAQ,MAAM,qBAAqB,SAAS,WAAW,CAAC,CAAC;AAC1D;AAEA,SAAS,aAAa,SAAiB,SAAmC;AACzE,MAAI,OAAO,YAAY,YAAa;AACpC,UAAQ,KAAK,qBAAqB,SAAS,WAAW,CAAC,CAAC;AACzD;AAEA,SAAS,aAAa,SAAiB,SAAmC;AACzE,MAAI,OAAO,YAAY,YAAa;AACpC,UAAQ,KAAK,qBAAqB,SAAS,WAAW,CAAC,CAAC;AACzD;AAEO,IAAM,UAAN,MAAc;AAAA,EAAd;AACN,wBAAQ,SAAuB;AAC/B,wBAAQ,mBAA2C;AACnD,wBAAQ,0BAAiE;AACzE,wBAAQ,kBAAyD;AACjE,wBAAQ,gBAA8B;AACtC,wBAAQ,aAAY;AAAA;AAAA,EAEZ,UAAU;AACjB,QAAI,KAAK,iBAAiB;AACzB,WAAK,gBAAgB,MAAM;AAAA,IAC5B;AACA,QAAI,OAAO,WAAW,eAAe,KAAK,wBAAwB;AACjE,aAAO,oBAAoB,WAAW,KAAK,sBAAsB;AAAA,IAClE;AACA,QAAI,OAAO,WAAW,eAAe,KAAK,gBAAgB;AACzD,aAAO,oBAAoB,WAAW,KAAK,cAAc;AAAA,IAC1D;AACA,SAAK,kBAAkB;AACvB,SAAK,yBAAyB;AAC9B,QAAI,OAAO,WAAW,eAAe,KAAK,cAAc;AACvD,aAAO,cAAc,KAAK,YAAY;AAAA,IACvC;AACA,SAAK,iBAAiB;AACtB,SAAK,eAAe;AACpB,SAAK,QAAQ;AACb,SAAK,YAAY;AAAA,EAClB;AAAA,EAEQ,iBAAiB,MAAsB,SAA0B;AACxE,QAAI,CAAC,QAAQ,OAAO,SAAS,YAAY,CAAC,KAAK,MAAM;AACpD,oBAAc,iCAAiC;AAC/C;AAAA,IACD;AAEA,iBAAa,wBAAwB;AAAA,MACpC,MAAM,KAAK;AAAA,IACZ,CAAC;AAED,YAAQ,KAAK,MAAM;AAAA,MAClB,KAAK;AACJ,YAAI,KAAK,WAAW;AACnB;AAAA,QACD;AACA,aAAK,YAAY;AACjB,qBAAa,mBAAmB;AAAA,UAC/B,SAAS,KAAK,WAAW;AAAA,UACzB,QAAQ,KAAK,UAAU;AAAA,QACxB,CAAC;AACD,iBAAS,YAAY,mBAAmB,IAAI,CAAC;AAC7C;AAAA,MACD,KAAK;AACJ,qBAAa,iBAAiB;AAC9B,iBAAS,WAAW;AACpB;AAAA,MACD,KAAK;AACJ;AAAA,MACD,KAAK;AACJ,YAAI,KAAK,WAAW;AACnB;AAAA,QACD;AACA,qBAAa,gCAAgC;AAAA,UAC5C,SAAS,KAAK,WAAW,KAAK,SAAS;AAAA,QACxC,CAAC;AACD,iBAAS,UAAU,KAAK,WAAW,KAAK,OAAO,IAAI;AACnD;AAAA,MACD,KAAK;AACJ,YAAI,SAAS,cAAc,OAAO;AACjC;AAAA,YACC;AAAA,UACD;AACA,mBAAS,UAAU;AACnB;AAAA,QACD;AACA,qBAAa,gDAAgD;AAC7D,aAAK,MAAM;AACX,iBAAS,UAAU;AACnB;AAAA,IACF;AAAA,EACD;AAAA,EAEQ,uBACP,eACA,SACC;AACD,QAAI;AACH,WAAK,kBAAkB,IAAI;AAAA,QAC1B,4BAA4B,aAAa;AAAA,MAC1C;AACA,WAAK,gBAAgB,YAAY,CAAC,UAAU;AAC3C,aAAK,iBAAiB,MAAM,MAAwB,OAAO;AAC3D,aAAK,iBAAiB,EAAE,MAAM,cAAc,GAAG,OAAO;AAAA,MACvD;AAAA,IACD,QAAQ;AACP,oBAAc,oDAAoD;AAAA,IACnE;AAEA,SAAK,yBAAyB,CAAC,UAAwB;AACtD,UACC,MAAM,QAAQ,2BAA2B,aAAa,KACtD,CAAC,MAAM,UACN;AACD;AAAA,MACD;AACA,UAAI;AACH,cAAM,OAAO,KAAK,MAAM,MAAM,QAAQ;AACtC,aAAK,iBAAiB,MAAM,OAAO;AACnC,aAAK,iBAAiB,EAAE,MAAM,cAAc,GAAG,OAAO;AAAA,MACvD,QAAQ;AACP,qBAAa,gDAAgD;AAAA,MAC9D;AAAA,IACD;AACA,WAAO,iBAAiB,WAAW,KAAK,sBAAsB;AAAA,EAC/D;AAAA,EAEA,QAAQ;AACP,iBAAa,kBAAkB;AAAA,MAC9B,UAAU,QAAQ,KAAK,KAAK;AAAA,MAC5B,aAAa,KAAK,OAAO,UAAU;AAAA,IACpC,CAAC;AACD,QAAI,KAAK,SAAS,CAAC,KAAK,MAAM,QAAQ;AACrC,WAAK,MAAM,MAAM;AAAA,IAClB;AACA,SAAK,QAAQ;AAAA,EACd;AAAA,EAEA,UAAU,QAAqB,SAA0B;AACxD,QAAI,OAAO,WAAW,YAAa;AACnC,QAAI,KAAK,SAAS,CAAC,KAAK,MAAM,OAAQ;AAEtC,UAAM,gBAAgB,yBAAyB;AAC/C,UAAM,gBAAgB;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,IACD;AACA,UAAM,WAAW,cAAc,QAAQ,SAAS,aAAa;AAC7D,iBAAa,8BAA8B;AAAA,MAC1C,OAAO,OAAO;AAAA,MACd;AAAA,MACA,aAAa,cAAc,eAAe;AAAA,MAC1C,gBAAgB,QAAQ,cAAc,WAAW;AAAA,MACjD,UAAU;AAAA,MACV,eAAe,SAAS,iBAAiB;AAAA,MACzC,WAAW,SAAS,aAAa;AAAA,MACjC,SAAS,OAAO,WAAW,cAAc,OAAO,SAAS,OAAO;AAAA,MAChE,cAAc,cAAc,UAAU;AAAA,IACvC,CAAC;AACD,UAAM,aAAa;AACnB,UAAM,cAAc;AACpB,UAAM,OAAO,KAAK;AAAA,MACjB;AAAA,MACA,KAAK,MAAM,OAAO,WAAW,OAAO,aAAa,cAAc,CAAC;AAAA,IACjE;AACA,UAAM,MAAM,KAAK;AAAA,MAChB;AAAA,MACA,KAAK,MAAM,OAAO,WAAW,OAAO,cAAc,eAAe,CAAC;AAAA,IACnE;AACA,UAAM,WAAW;AAAA,MAChB;AAAA,MACA,SAAS,UAAU;AAAA,MACnB,UAAU,WAAW;AAAA,MACrB,QAAQ,IAAI;AAAA,MACZ,OAAO,GAAG;AAAA,MACV;AAAA,MACA;AAAA,IACD,EAAE,KAAK,GAAG;AAEV,UAAM,YAAY,oBAAoB,aAAa;AACnD,UAAM,QAAQ,OAAO,KAAK,UAAU,WAAW,QAAQ;AACvD,QAAI,CAAC,OAAO;AACX,mBAAa,8BAA8B;AAC3C,eAAS,UAAU,yBAAyB;AAC5C;AAAA,IACD;AAEA,SAAK,QAAQ;AACb,SAAK,YAAY;AACjB,SAAK,uBAAuB,eAAe,OAAO;AAElD,UAAM,gBAAgB,SAAS;AAC/B,UAAM,cAAc,UAAU,QAAQ;AAEtC,SAAK,iBAAiB,CAAC,UAAwB;AAC9C,UACC,iBACA,kBAAkB,OAClB,MAAM,WAAW,eAChB;AACD,qBAAa,iDAAiD;AAAA,UAC7D;AAAA,UACA,aAAa,MAAM;AAAA,QACpB,CAAC;AACD;AAAA,MACD;AACA,UAAI,CAAC,iBAAiB,eAAe,MAAM,WAAW,aAAa;AAClE,qBAAa,gDAAgD;AAAA,UAC5D,gBAAgB;AAAA,UAChB,aAAa,MAAM;AAAA,QACpB,CAAC;AACD;AAAA,MACD;AAEA,YAAM,OAAO,MAAM;AACnB,UAAI,CAAC,QAAQ,OAAO,SAAS,YAAY,CAAC,KAAK,MAAM;AACpD,sBAAc,uCAAuC;AACrD;AAAA,MACD;AAEA,mBAAa,wBAAwB;AAAA,QACpC,MAAM,KAAK;AAAA,QACX,aAAa,MAAM;AAAA,MACpB,CAAC;AAED,WAAK,iBAAiB,MAAM,OAAO;AAAA,IACpC;AAEA,WAAO,iBAAiB,WAAW,KAAK,cAAc;AAEtD,SAAK,eAAe,OAAO,YAAY,MAAM;AAC5C,UAAI,CAAC,KAAK,SAAS,KAAK,MAAM,QAAQ;AACrC,cAAM,sBAAsB,CAAC,KAAK;AAClC,qBAAa,yBAAyB;AAAA,UACrC;AAAA,QACD,CAAC;AACD,aAAK,QAAQ;AACb,YAAI,qBAAqB;AACxB,mBAAS,WAAW;AAAA,QACrB;AACA,iBAAS,UAAU;AAAA,MACpB;AAAA,IACD,GAAG,GAAG;AAAA,EACP;AACD;AAEO,SAAS,gBAAyB;AACxC,SAAO,IAAI,QAAQ;AACpB;AAEA,6BAA6B;","names":[]}
|
package/dist/login.d.cts
CHANGED
|
@@ -1,62 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
type LoginEventType = "LOGIN_SUCCESS" | "LOGIN_CANCELLED" | "LOGIN_CLOSE" | "LOGIN_RESIZE" | "LOGIN_ERROR";
|
|
4
|
-
interface LoginResult {
|
|
5
|
-
avatar?: string | null;
|
|
6
|
-
channel?: string;
|
|
7
|
-
email?: string | null;
|
|
8
|
-
expiresAt?: string;
|
|
9
|
-
legacyCasdoorId?: string;
|
|
10
|
-
loginToken?: string;
|
|
11
|
-
name?: string | null;
|
|
12
|
-
userId?: string;
|
|
13
|
-
wechatOpenId?: string | null;
|
|
14
|
-
wechatUnionId?: string | null;
|
|
15
|
-
}
|
|
16
|
-
interface LoginEventData extends HostedFrameMessage, LoginResult {
|
|
17
|
-
type: LoginEventType;
|
|
18
|
-
error?: string;
|
|
19
|
-
message?: string;
|
|
20
|
-
}
|
|
21
|
-
interface LoginUIOptions {
|
|
22
|
-
/** Origin to validate postMessage (defaults to '*', set for security) */
|
|
23
|
-
allowedOrigin?: string;
|
|
24
|
-
/** Whether the SDK should close the popup after receiving LOGIN_CLOSE. Defaults to true. */
|
|
25
|
-
autoClose?: boolean;
|
|
26
|
-
onCancel?: () => void;
|
|
27
|
-
onClose?: () => void;
|
|
28
|
-
onError?: (message?: string, data?: LoginEventData) => void;
|
|
29
|
-
onSuccess?: (result: LoginResult) => void;
|
|
30
|
-
}
|
|
31
|
-
interface LoginParams {
|
|
32
|
-
appId: string;
|
|
33
|
-
/**
|
|
34
|
-
* @deprecated Use loginUrl instead
|
|
35
|
-
* Defaults to https://pay.imgto.link
|
|
36
|
-
*/
|
|
37
|
-
baseUrl?: string;
|
|
38
|
-
/**
|
|
39
|
-
* Hosted login page base URL (e.g. https://pay.youidian.com)
|
|
40
|
-
* Defaults to https://pay.imgto.link
|
|
41
|
-
*/
|
|
42
|
-
loginUrl?: string;
|
|
43
|
-
/**
|
|
44
|
-
* Optional locale prefix to prepend to the hosted login path.
|
|
45
|
-
* If omitted, the SDK automatically resolves the locale from the browser language.
|
|
46
|
-
*/
|
|
47
|
-
locale?: string;
|
|
48
|
-
/** Preferred provider/channel code */
|
|
49
|
-
preferredChannel?: string;
|
|
50
|
-
}
|
|
51
|
-
declare class LoginUI {
|
|
52
|
-
private popup;
|
|
53
|
-
private messageHandler;
|
|
54
|
-
private closeMonitor;
|
|
55
|
-
private completed;
|
|
56
|
-
private cleanup;
|
|
57
|
-
close(): void;
|
|
58
|
-
openLogin(params: LoginParams, options?: LoginUIOptions): void;
|
|
59
|
-
}
|
|
60
|
-
declare function createLoginUI(): LoginUI;
|
|
61
|
-
|
|
62
|
-
export { type LoginEventData, type LoginEventType, type LoginParams, type LoginResult, LoginUI, type LoginUIOptions, createLoginUI };
|
|
1
|
+
export { L as LoginEventData, a as LoginEventType, b as LoginParams, c as LoginResult, d as LoginUI, e as LoginUIOptions, f as createLoginUI, h as handleLoginCallbackIfPresent } from './login-D_VaJqQX.cjs';
|
package/dist/login.d.ts
CHANGED
|
@@ -1,62 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
type LoginEventType = "LOGIN_SUCCESS" | "LOGIN_CANCELLED" | "LOGIN_CLOSE" | "LOGIN_RESIZE" | "LOGIN_ERROR";
|
|
4
|
-
interface LoginResult {
|
|
5
|
-
avatar?: string | null;
|
|
6
|
-
channel?: string;
|
|
7
|
-
email?: string | null;
|
|
8
|
-
expiresAt?: string;
|
|
9
|
-
legacyCasdoorId?: string;
|
|
10
|
-
loginToken?: string;
|
|
11
|
-
name?: string | null;
|
|
12
|
-
userId?: string;
|
|
13
|
-
wechatOpenId?: string | null;
|
|
14
|
-
wechatUnionId?: string | null;
|
|
15
|
-
}
|
|
16
|
-
interface LoginEventData extends HostedFrameMessage, LoginResult {
|
|
17
|
-
type: LoginEventType;
|
|
18
|
-
error?: string;
|
|
19
|
-
message?: string;
|
|
20
|
-
}
|
|
21
|
-
interface LoginUIOptions {
|
|
22
|
-
/** Origin to validate postMessage (defaults to '*', set for security) */
|
|
23
|
-
allowedOrigin?: string;
|
|
24
|
-
/** Whether the SDK should close the popup after receiving LOGIN_CLOSE. Defaults to true. */
|
|
25
|
-
autoClose?: boolean;
|
|
26
|
-
onCancel?: () => void;
|
|
27
|
-
onClose?: () => void;
|
|
28
|
-
onError?: (message?: string, data?: LoginEventData) => void;
|
|
29
|
-
onSuccess?: (result: LoginResult) => void;
|
|
30
|
-
}
|
|
31
|
-
interface LoginParams {
|
|
32
|
-
appId: string;
|
|
33
|
-
/**
|
|
34
|
-
* @deprecated Use loginUrl instead
|
|
35
|
-
* Defaults to https://pay.imgto.link
|
|
36
|
-
*/
|
|
37
|
-
baseUrl?: string;
|
|
38
|
-
/**
|
|
39
|
-
* Hosted login page base URL (e.g. https://pay.youidian.com)
|
|
40
|
-
* Defaults to https://pay.imgto.link
|
|
41
|
-
*/
|
|
42
|
-
loginUrl?: string;
|
|
43
|
-
/**
|
|
44
|
-
* Optional locale prefix to prepend to the hosted login path.
|
|
45
|
-
* If omitted, the SDK automatically resolves the locale from the browser language.
|
|
46
|
-
*/
|
|
47
|
-
locale?: string;
|
|
48
|
-
/** Preferred provider/channel code */
|
|
49
|
-
preferredChannel?: string;
|
|
50
|
-
}
|
|
51
|
-
declare class LoginUI {
|
|
52
|
-
private popup;
|
|
53
|
-
private messageHandler;
|
|
54
|
-
private closeMonitor;
|
|
55
|
-
private completed;
|
|
56
|
-
private cleanup;
|
|
57
|
-
close(): void;
|
|
58
|
-
openLogin(params: LoginParams, options?: LoginUIOptions): void;
|
|
59
|
-
}
|
|
60
|
-
declare function createLoginUI(): LoginUI;
|
|
61
|
-
|
|
62
|
-
export { type LoginEventData, type LoginEventType, type LoginParams, type LoginResult, LoginUI, type LoginUIOptions, createLoginUI };
|
|
1
|
+
export { L as LoginEventData, a as LoginEventType, b as LoginParams, c as LoginResult, d as LoginUI, e as LoginUIOptions, f as createLoginUI, h as handleLoginCallbackIfPresent } from './login-D_VaJqQX.js';
|