@youidian/sdk 3.3.7 → 3.4.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 +400 -36
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +41 -5
- package/dist/client.d.ts +41 -5
- package/dist/client.js +399 -36
- package/dist/client.js.map +1 -1
- package/dist/feedback.cjs +682 -0
- package/dist/feedback.cjs.map +1 -0
- package/dist/feedback.d.cts +38 -0
- package/dist/feedback.d.ts +38 -0
- package/dist/feedback.js +656 -0
- package/dist/feedback.js.map +1 -0
- package/dist/index.cjs +1164 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +1161 -36
- package/dist/index.js.map +1 -1
- package/dist/{login-DerOcXcH.d.cts → login-Dqemys65.d.cts} +8 -4
- package/dist/{login-DerOcXcH.d.ts → login-Dqemys65.d.ts} +8 -4
- package/dist/login.cjs +320 -30
- package/dist/login.cjs.map +1 -1
- package/dist/login.d.cts +1 -1
- package/dist/login.d.ts +1 -1
- package/dist/login.js +320 -30
- package/dist/login.js.map +1 -1
- package/dist/server.cjs +108 -0
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +137 -1
- package/dist/server.d.ts +137 -1
- package/dist/server.js +108 -0
- package/dist/server.js.map +1 -1
- package/package.json +6 -1
package/dist/client.cjs
CHANGED
|
@@ -26,6 +26,7 @@ __export(client_exports, {
|
|
|
26
26
|
PaymentUI: () => PaymentUI,
|
|
27
27
|
createLoginUI: () => createLoginUI,
|
|
28
28
|
createPaymentUI: () => createPaymentUI,
|
|
29
|
+
detectLoginEnvironment: () => detectLoginEnvironment,
|
|
29
30
|
handleLoginCallbackIfPresent: () => handleLoginCallbackIfPresent
|
|
30
31
|
});
|
|
31
32
|
module.exports = __toCommonJS(client_exports);
|
|
@@ -232,6 +233,91 @@ var HostedFrameModal = class {
|
|
|
232
233
|
}
|
|
233
234
|
};
|
|
234
235
|
|
|
236
|
+
// src/environment.ts
|
|
237
|
+
function normalizeText(value) {
|
|
238
|
+
return value || "";
|
|
239
|
+
}
|
|
240
|
+
function getRuntimeInput() {
|
|
241
|
+
if (typeof navigator === "undefined") {
|
|
242
|
+
return {};
|
|
243
|
+
}
|
|
244
|
+
const nav = navigator;
|
|
245
|
+
const coarsePointer = typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia("(pointer: coarse)").matches : void 0;
|
|
246
|
+
return {
|
|
247
|
+
coarsePointer,
|
|
248
|
+
maxTouchPoints: nav.maxTouchPoints || 0,
|
|
249
|
+
platform: nav.platform || "",
|
|
250
|
+
standalone: nav.standalone,
|
|
251
|
+
userAgent: nav.userAgent || "",
|
|
252
|
+
userAgentDataMobile: nav.userAgentData?.mobile
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
function includesAny(value, patterns) {
|
|
256
|
+
return patterns.some((pattern) => pattern.test(value));
|
|
257
|
+
}
|
|
258
|
+
function detectLoginEnvironment(input = getRuntimeInput()) {
|
|
259
|
+
const userAgent = normalizeText(input.userAgent);
|
|
260
|
+
const platform = normalizeText(input.platform);
|
|
261
|
+
const rawMaxTouchPoints = input.maxTouchPoints ?? 0;
|
|
262
|
+
const maxTouchPoints = Number.isFinite(rawMaxTouchPoints) ? Math.max(0, rawMaxTouchPoints) : 0;
|
|
263
|
+
const isCoarsePointer = input.coarsePointer === true;
|
|
264
|
+
const isTouch = maxTouchPoints > 0 || isCoarsePointer;
|
|
265
|
+
const isWeChat = /micromessenger/i.test(userAgent);
|
|
266
|
+
const isAndroid = /\bandroid\b/i.test(userAgent);
|
|
267
|
+
const hasExplicitIOSDevice = /\b(iPad|iPhone|iPod)\b/i.test(userAgent);
|
|
268
|
+
const hasMacintoshUserAgent = /\bMacintosh\b/i.test(userAgent);
|
|
269
|
+
const hasMacPlatform = /^Mac/i.test(platform);
|
|
270
|
+
const isIPadOS = !hasExplicitIOSDevice && hasMacintoshUserAgent && hasMacPlatform && typeof input.standalone !== "undefined" && maxTouchPoints > 2;
|
|
271
|
+
const isIOS = hasExplicitIOSDevice || isIPadOS;
|
|
272
|
+
const isTabletByUa = includesAny(userAgent, [
|
|
273
|
+
/\biPad\b/i,
|
|
274
|
+
/\btablet\b/i,
|
|
275
|
+
/\bplaybook\b/i,
|
|
276
|
+
/\bsilk\b(?!.*\bmobile\b)/i,
|
|
277
|
+
/\bkindle\b/i,
|
|
278
|
+
/\bnexus 7\b/i,
|
|
279
|
+
/\bnexus 9\b/i,
|
|
280
|
+
/\bxoom\b/i,
|
|
281
|
+
/\bsm-t\d+/i,
|
|
282
|
+
/\bgt-p\d+/i,
|
|
283
|
+
/\bmi pad\b/i
|
|
284
|
+
]);
|
|
285
|
+
const isMobileByUa = includesAny(userAgent, [
|
|
286
|
+
/\bMobile\b/i,
|
|
287
|
+
/\biPhone\b/i,
|
|
288
|
+
/\biPod\b/i,
|
|
289
|
+
/\bWindows Phone\b/i,
|
|
290
|
+
/\bIEMobile\b/i,
|
|
291
|
+
/\bBlackBerry\b/i,
|
|
292
|
+
/\bBB10\b/i,
|
|
293
|
+
/\bOpera Mini\b/i,
|
|
294
|
+
/\bOpera Mobi\b/i,
|
|
295
|
+
/\bwebOS\b/i
|
|
296
|
+
]);
|
|
297
|
+
const isAndroidTablet = isAndroid && !/\bMobile\b/i.test(userAgent);
|
|
298
|
+
const isTablet = isIPadOS || isTabletByUa || isAndroidTablet;
|
|
299
|
+
const isMobile = input.userAgentDataMobile === true || isMobileByUa || isAndroid && !isTablet || isIOS && !isTablet;
|
|
300
|
+
const deviceType = isTablet ? "tablet" : isMobile ? "mobile" : userAgent || platform || isTouch ? "desktop" : "unknown";
|
|
301
|
+
const shouldUseRedirectLogin = deviceType === "mobile" || deviceType === "tablet" || isWeChat;
|
|
302
|
+
return {
|
|
303
|
+
deviceType,
|
|
304
|
+
isAndroid,
|
|
305
|
+
isCoarsePointer,
|
|
306
|
+
isDesktop: deviceType === "desktop",
|
|
307
|
+
isIOS,
|
|
308
|
+
isIPadOS,
|
|
309
|
+
isMobile,
|
|
310
|
+
isStandalone: input.standalone === true,
|
|
311
|
+
isTablet,
|
|
312
|
+
isTouch,
|
|
313
|
+
isWeChat,
|
|
314
|
+
maxTouchPoints,
|
|
315
|
+
platform,
|
|
316
|
+
shouldUseRedirectLogin,
|
|
317
|
+
userAgent
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
|
|
235
321
|
// src/login.ts
|
|
236
322
|
function getOrigin(value) {
|
|
237
323
|
if (!value) return null;
|
|
@@ -241,6 +327,15 @@ function getOrigin(value) {
|
|
|
241
327
|
return null;
|
|
242
328
|
}
|
|
243
329
|
}
|
|
330
|
+
function isValidLoginRedirectUrl(value) {
|
|
331
|
+
if (!value) return false;
|
|
332
|
+
try {
|
|
333
|
+
const url = new URL(value);
|
|
334
|
+
return url.protocol === "https:" || url.protocol === "http:";
|
|
335
|
+
} catch {
|
|
336
|
+
return false;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
244
339
|
function createLoginCallbackState() {
|
|
245
340
|
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
246
341
|
return crypto.randomUUID().replace(/-/g, "");
|
|
@@ -587,6 +682,24 @@ function applyLoginPanelStyle(panel) {
|
|
|
587
682
|
backdropFilter: "blur(16px)"
|
|
588
683
|
});
|
|
589
684
|
}
|
|
685
|
+
function applyLoginLoadingPanelStyle(panel) {
|
|
686
|
+
Object.assign(panel.style, {
|
|
687
|
+
position: "absolute",
|
|
688
|
+
inset: "0",
|
|
689
|
+
display: "flex",
|
|
690
|
+
alignItems: "center",
|
|
691
|
+
justifyContent: "center",
|
|
692
|
+
border: "0",
|
|
693
|
+
borderRadius: "28px",
|
|
694
|
+
background: "rgba(255,255,255,0.94)",
|
|
695
|
+
color: "#0f172a",
|
|
696
|
+
padding: "24px",
|
|
697
|
+
textAlign: "center",
|
|
698
|
+
zIndex: "1",
|
|
699
|
+
boxShadow: "none",
|
|
700
|
+
backdropFilter: "blur(16px)"
|
|
701
|
+
});
|
|
702
|
+
}
|
|
590
703
|
function createLoginPanelContent() {
|
|
591
704
|
const content = document.createElement("div");
|
|
592
705
|
Object.assign(content.style, {
|
|
@@ -611,6 +724,71 @@ function createLoginPanelContent() {
|
|
|
611
724
|
content.appendChild(badge);
|
|
612
725
|
return content;
|
|
613
726
|
}
|
|
727
|
+
function createBrandLoadingMark() {
|
|
728
|
+
const logo = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
729
|
+
logo.setAttribute("viewBox", "0 0 1024 1024");
|
|
730
|
+
logo.setAttribute("fill", "none");
|
|
731
|
+
logo.setAttribute("aria-hidden", "true");
|
|
732
|
+
Object.assign(logo.style, {
|
|
733
|
+
width: "112px",
|
|
734
|
+
height: "112px",
|
|
735
|
+
color: "#22c55e",
|
|
736
|
+
display: "block",
|
|
737
|
+
overflow: "visible"
|
|
738
|
+
});
|
|
739
|
+
const group = document.createElementNS("http://www.w3.org/2000/svg", "g");
|
|
740
|
+
group.setAttribute("fill", "currentColor");
|
|
741
|
+
const ring = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
|
742
|
+
ring.setAttribute(
|
|
743
|
+
"d",
|
|
744
|
+
"M704.298 679.54A264 264 0 1 1 704.298 309.46A49 49 0 0 1 634.4 378.149A166 166 0 1 0 634.4 610.851A49 49 0 0 1 704.298 679.54Z"
|
|
745
|
+
);
|
|
746
|
+
ring.setAttribute("class", "youidian-sdk-brand-loading__ring");
|
|
747
|
+
const dot = document.createElementNS("http://www.w3.org/2000/svg", "circle");
|
|
748
|
+
dot.setAttribute("class", "youidian-sdk-brand-loading__dot");
|
|
749
|
+
dot.setAttribute("cx", "714.5");
|
|
750
|
+
dot.setAttribute("cy", "490.5");
|
|
751
|
+
dot.setAttribute("r", "68");
|
|
752
|
+
group.appendChild(ring);
|
|
753
|
+
group.appendChild(dot);
|
|
754
|
+
logo.appendChild(group);
|
|
755
|
+
return logo;
|
|
756
|
+
}
|
|
757
|
+
function createBrandLoadingCopy() {
|
|
758
|
+
const brand = document.createElement("div");
|
|
759
|
+
brand.className = "youidian-sdk-brand-loading__copy";
|
|
760
|
+
Object.assign(brand.style, {
|
|
761
|
+
display: "flex",
|
|
762
|
+
flexDirection: "column",
|
|
763
|
+
alignItems: "flex-start",
|
|
764
|
+
justifyContent: "center",
|
|
765
|
+
lineHeight: "1"
|
|
766
|
+
});
|
|
767
|
+
const name = document.createElement("div");
|
|
768
|
+
name.className = "youidian-sdk-brand-loading__name";
|
|
769
|
+
name.textContent = "\u4F18\u6613\u70B9";
|
|
770
|
+
Object.assign(name.style, {
|
|
771
|
+
color: "#0f172a",
|
|
772
|
+
fontSize: "34px",
|
|
773
|
+
fontWeight: "900",
|
|
774
|
+
letterSpacing: "0",
|
|
775
|
+
lineHeight: "1"
|
|
776
|
+
});
|
|
777
|
+
const tagline = document.createElement("div");
|
|
778
|
+
tagline.className = "youidian-sdk-brand-loading__tagline";
|
|
779
|
+
tagline.textContent = "\u5F00\u53D1\u8005\u670D\u52A1\u4E2D\u53F0";
|
|
780
|
+
Object.assign(tagline.style, {
|
|
781
|
+
color: "#64748b",
|
|
782
|
+
fontSize: "16px",
|
|
783
|
+
fontWeight: "700",
|
|
784
|
+
letterSpacing: "0.24em",
|
|
785
|
+
lineHeight: "1",
|
|
786
|
+
marginTop: "6px"
|
|
787
|
+
});
|
|
788
|
+
brand.appendChild(name);
|
|
789
|
+
brand.appendChild(tagline);
|
|
790
|
+
return brand;
|
|
791
|
+
}
|
|
614
792
|
function createLoginPanelTitle(value) {
|
|
615
793
|
const title = document.createElement("div");
|
|
616
794
|
title.textContent = value;
|
|
@@ -640,32 +818,111 @@ function ensureLoginLoadingStyles() {
|
|
|
640
818
|
}
|
|
641
819
|
const style = document.createElement("style");
|
|
642
820
|
style.id = "youidian-login-loading-style";
|
|
643
|
-
style.textContent =
|
|
821
|
+
style.textContent = `
|
|
822
|
+
.youidian-sdk-brand-loading__ring,
|
|
823
|
+
.youidian-sdk-brand-loading__dot {
|
|
824
|
+
transform-box: fill-box;
|
|
825
|
+
transform-origin: center;
|
|
826
|
+
will-change: opacity, transform;
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
.youidian-sdk-brand-loading__ring {
|
|
830
|
+
animation: youidian-sdk-brand-loading-ring 1400ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
.youidian-sdk-brand-loading__dot {
|
|
834
|
+
animation: youidian-sdk-brand-loading-dot 1400ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
.youidian-sdk-brand-loading__copy {
|
|
838
|
+
will-change: opacity, transform;
|
|
839
|
+
animation: youidian-sdk-brand-loading-copy 1600ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
.youidian-sdk-brand-loading__tagline {
|
|
843
|
+
will-change: opacity;
|
|
844
|
+
animation: youidian-sdk-brand-loading-tagline 1600ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
@keyframes youidian-sdk-brand-loading-ring {
|
|
848
|
+
0%,
|
|
849
|
+
100% {
|
|
850
|
+
opacity: 0.72;
|
|
851
|
+
transform: rotate(0deg) scale(0.98);
|
|
852
|
+
}
|
|
853
|
+
50% {
|
|
854
|
+
opacity: 1;
|
|
855
|
+
transform: rotate(8deg) scale(1.02);
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
@keyframes youidian-sdk-brand-loading-dot {
|
|
860
|
+
0%,
|
|
861
|
+
100% {
|
|
862
|
+
opacity: 0.55;
|
|
863
|
+
transform: scale(0.9);
|
|
864
|
+
}
|
|
865
|
+
50% {
|
|
866
|
+
opacity: 1;
|
|
867
|
+
transform: scale(1.08);
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
@keyframes youidian-sdk-brand-loading-copy {
|
|
872
|
+
0%,
|
|
873
|
+
100% {
|
|
874
|
+
opacity: 0.86;
|
|
875
|
+
transform: translateY(0);
|
|
876
|
+
}
|
|
877
|
+
50% {
|
|
878
|
+
opacity: 1;
|
|
879
|
+
transform: translateY(-1px);
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
@keyframes youidian-sdk-brand-loading-tagline {
|
|
884
|
+
0%,
|
|
885
|
+
100% {
|
|
886
|
+
opacity: 0.64;
|
|
887
|
+
}
|
|
888
|
+
50% {
|
|
889
|
+
opacity: 0.92;
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
@media (prefers-reduced-motion: reduce) {
|
|
894
|
+
.youidian-sdk-brand-loading__ring,
|
|
895
|
+
.youidian-sdk-brand-loading__dot,
|
|
896
|
+
.youidian-sdk-brand-loading__copy,
|
|
897
|
+
.youidian-sdk-brand-loading__tagline {
|
|
898
|
+
animation: none;
|
|
899
|
+
opacity: 1;
|
|
900
|
+
transform: none;
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
`;
|
|
644
904
|
document.head.appendChild(style);
|
|
645
905
|
}
|
|
646
|
-
function createLoginLoadingPanel(
|
|
906
|
+
function createLoginLoadingPanel() {
|
|
647
907
|
ensureLoginLoadingStyles();
|
|
648
908
|
const panel = document.createElement("div");
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
margin: "0 auto 18px",
|
|
659
|
-
animation: "youidian-login-spin 780ms linear infinite"
|
|
909
|
+
applyLoginLoadingPanelStyle(panel);
|
|
910
|
+
panel.setAttribute("role", "status");
|
|
911
|
+
panel.setAttribute("aria-label", "\u4F18\u6613\u70B9\u5F00\u53D1\u8005\u670D\u52A1\u4E2D\u53F0");
|
|
912
|
+
const content = document.createElement("div");
|
|
913
|
+
Object.assign(content.style, {
|
|
914
|
+
display: "flex",
|
|
915
|
+
alignItems: "center",
|
|
916
|
+
justifyContent: "center",
|
|
917
|
+
gap: "12px"
|
|
660
918
|
});
|
|
661
|
-
content.appendChild(
|
|
662
|
-
content.appendChild(
|
|
663
|
-
content.appendChild(createLoginPanelDescription(options.description));
|
|
919
|
+
content.appendChild(createBrandLoadingMark());
|
|
920
|
+
content.appendChild(createBrandLoadingCopy());
|
|
664
921
|
panel.appendChild(content);
|
|
665
922
|
return panel;
|
|
666
923
|
}
|
|
667
|
-
function createLoginRedirectingPanel(
|
|
668
|
-
return createLoginLoadingPanel(
|
|
924
|
+
function createLoginRedirectingPanel(_options) {
|
|
925
|
+
return createLoginLoadingPanel();
|
|
669
926
|
}
|
|
670
927
|
function createLoginFallbackPanel(options) {
|
|
671
928
|
const panel = document.createElement("div");
|
|
@@ -765,14 +1022,11 @@ var LoginUI = class extends HostedFrameModal {
|
|
|
765
1022
|
this.iframeFallbackPanel = null;
|
|
766
1023
|
this.iframeLoadingPanel = null;
|
|
767
1024
|
}
|
|
768
|
-
showIframeLoading(container
|
|
1025
|
+
showIframeLoading(container) {
|
|
769
1026
|
if (this.iframeLoadingPanel || this.iframeReady) {
|
|
770
1027
|
return;
|
|
771
1028
|
}
|
|
772
|
-
const panel = createLoginLoadingPanel(
|
|
773
|
-
description: options?.loadingDescription || "Please wait while the secure login page opens.",
|
|
774
|
-
title: options?.loadingTitle || "Opening login page"
|
|
775
|
-
});
|
|
1029
|
+
const panel = createLoginLoadingPanel();
|
|
776
1030
|
this.iframeLoadingPanel = panel;
|
|
777
1031
|
container.appendChild(panel);
|
|
778
1032
|
}
|
|
@@ -860,6 +1114,20 @@ var LoginUI = class extends HostedFrameModal {
|
|
|
860
1114
|
break;
|
|
861
1115
|
case "LOGIN_RESIZE":
|
|
862
1116
|
break;
|
|
1117
|
+
case "LOGIN_REDIRECT_REQUIRED":
|
|
1118
|
+
if (!isValidLoginRedirectUrl(data.authUrl)) {
|
|
1119
|
+
logLoginWarn("Login redirect requested with invalid authUrl");
|
|
1120
|
+
options?.onError?.("Login redirect URL is invalid", data);
|
|
1121
|
+
break;
|
|
1122
|
+
}
|
|
1123
|
+
logLoginInfo("Login redirect requested by hosted page", {
|
|
1124
|
+
attemptId: data.attemptId || null,
|
|
1125
|
+
channel: data.channel || null,
|
|
1126
|
+
authUrl: data.authUrl
|
|
1127
|
+
});
|
|
1128
|
+
this.close();
|
|
1129
|
+
window.location.assign(data.authUrl);
|
|
1130
|
+
break;
|
|
863
1131
|
case "LOGIN_ERROR":
|
|
864
1132
|
if (this.completed) {
|
|
865
1133
|
break;
|
|
@@ -883,6 +1151,25 @@ var LoginUI = class extends HostedFrameModal {
|
|
|
883
1151
|
break;
|
|
884
1152
|
}
|
|
885
1153
|
}
|
|
1154
|
+
openLoginRedirect(params, options) {
|
|
1155
|
+
if (typeof window === "undefined") return;
|
|
1156
|
+
const { callbackState, finalUrl, launchPayload } = this.buildOpenContext(
|
|
1157
|
+
params,
|
|
1158
|
+
options
|
|
1159
|
+
);
|
|
1160
|
+
logLoginInfo("Redirecting to hosted login page", {
|
|
1161
|
+
appId: params.appId,
|
|
1162
|
+
callbackState,
|
|
1163
|
+
callbackUrl: launchPayload.callbackUrl || null,
|
|
1164
|
+
hasCallbackUrl: Boolean(launchPayload.callbackUrl),
|
|
1165
|
+
loginUrl: finalUrl,
|
|
1166
|
+
autoClose: options?.autoClose ?? true,
|
|
1167
|
+
displayMode: "redirect",
|
|
1168
|
+
pageUrl: window.location.href,
|
|
1169
|
+
parentOrigin: launchPayload.origin || null
|
|
1170
|
+
});
|
|
1171
|
+
window.location.assign(finalUrl);
|
|
1172
|
+
}
|
|
886
1173
|
listenForLoginCallback(callbackState, options) {
|
|
887
1174
|
try {
|
|
888
1175
|
this.callbackChannel = new BroadcastChannel(
|
|
@@ -959,21 +1246,17 @@ var LoginUI = class extends HostedFrameModal {
|
|
|
959
1246
|
options?.onCancel?.();
|
|
960
1247
|
options?.onClose?.();
|
|
961
1248
|
},
|
|
962
|
-
onMessage: (data,
|
|
1249
|
+
onMessage: (data, _container, event) => {
|
|
963
1250
|
const isIframeEvent = event.source === this.iframe?.contentWindow;
|
|
964
1251
|
if (isIframeEvent && (data.type === "LOGIN_READY" || data.type === "LOGIN_RESIZE") || data.type === "LOGIN_SUCCESS" || data.type === "LOGIN_ERROR") {
|
|
965
1252
|
this.markIframeReady();
|
|
966
1253
|
}
|
|
967
|
-
if (data.type === "LOGIN_RESIZE" && data.height) {
|
|
968
|
-
const maxHeight = window.innerHeight * 0.94;
|
|
969
|
-
container.style.height = `${Math.min(data.height, maxHeight)}px`;
|
|
970
|
-
}
|
|
971
1254
|
this.handleLoginEvent(data, options);
|
|
972
1255
|
},
|
|
973
1256
|
width: "min(520px, 100%)"
|
|
974
1257
|
});
|
|
975
1258
|
if (hostedFrame) {
|
|
976
|
-
this.showIframeLoading(hostedFrame.container
|
|
1259
|
+
this.showIframeLoading(hostedFrame.container);
|
|
977
1260
|
this.startIframeWatchdog({
|
|
978
1261
|
container: hostedFrame.container,
|
|
979
1262
|
finalUrl,
|
|
@@ -1077,11 +1360,19 @@ var LoginUI = class extends HostedFrameModal {
|
|
|
1077
1360
|
}
|
|
1078
1361
|
openLogin(params, options) {
|
|
1079
1362
|
if (typeof window === "undefined") return;
|
|
1080
|
-
const displayMode = options?.displayMode ?? "
|
|
1363
|
+
const displayMode = options?.displayMode ?? "auto";
|
|
1364
|
+
if (displayMode === "redirect") {
|
|
1365
|
+
this.openLoginRedirect(params, options);
|
|
1366
|
+
return;
|
|
1367
|
+
}
|
|
1081
1368
|
if (displayMode === "popup") {
|
|
1082
1369
|
this.openLoginPopup(params, options);
|
|
1083
1370
|
return;
|
|
1084
1371
|
}
|
|
1372
|
+
if (displayMode === "auto" && detectLoginEnvironment().shouldUseRedirectLogin) {
|
|
1373
|
+
this.openLoginRedirect(params, options);
|
|
1374
|
+
return;
|
|
1375
|
+
}
|
|
1085
1376
|
this.openLoginModal(params, options);
|
|
1086
1377
|
}
|
|
1087
1378
|
};
|
|
@@ -1092,6 +1383,43 @@ handleLoginCallbackIfPresent({ autoClose: false });
|
|
|
1092
1383
|
|
|
1093
1384
|
// src/client.ts
|
|
1094
1385
|
var PaymentUI = class extends HostedFrameModal {
|
|
1386
|
+
constructor() {
|
|
1387
|
+
super(...arguments);
|
|
1388
|
+
__publicField(this, "activeCheckoutAppId", null);
|
|
1389
|
+
__publicField(this, "activeCheckoutBaseUrl", null);
|
|
1390
|
+
__publicField(this, "activeOrderId", null);
|
|
1391
|
+
__publicField(this, "paymentCompleted", false);
|
|
1392
|
+
__publicField(this, "cancelRequestedOrderId", null);
|
|
1393
|
+
}
|
|
1394
|
+
cancelHostedOrder(reason = "user_cancel", orderId) {
|
|
1395
|
+
const targetOrderId = orderId || this.activeOrderId;
|
|
1396
|
+
if (!targetOrderId || !this.activeCheckoutAppId || !this.activeCheckoutBaseUrl || this.paymentCompleted || this.cancelRequestedOrderId === targetOrderId) {
|
|
1397
|
+
return;
|
|
1398
|
+
}
|
|
1399
|
+
this.cancelRequestedOrderId = targetOrderId;
|
|
1400
|
+
const url = `${this.activeCheckoutBaseUrl}/api/internal/checkout/cancel-order`;
|
|
1401
|
+
const payload = JSON.stringify({
|
|
1402
|
+
appId: this.activeCheckoutAppId,
|
|
1403
|
+
orderId: targetOrderId,
|
|
1404
|
+
reason
|
|
1405
|
+
});
|
|
1406
|
+
if (typeof navigator !== "undefined" && navigator.sendBeacon) {
|
|
1407
|
+
const sent = navigator.sendBeacon(
|
|
1408
|
+
url,
|
|
1409
|
+
new Blob([payload], { type: "application/json" })
|
|
1410
|
+
);
|
|
1411
|
+
if (sent) return;
|
|
1412
|
+
}
|
|
1413
|
+
void fetch(url, {
|
|
1414
|
+
method: "POST",
|
|
1415
|
+
body: payload,
|
|
1416
|
+
headers: { "Content-Type": "text/plain;charset=UTF-8" },
|
|
1417
|
+
keepalive: true,
|
|
1418
|
+
mode: "no-cors"
|
|
1419
|
+
}).catch(() => {
|
|
1420
|
+
this.cancelRequestedOrderId = null;
|
|
1421
|
+
});
|
|
1422
|
+
}
|
|
1095
1423
|
/**
|
|
1096
1424
|
* Opens the payment checkout page in an iframe modal.
|
|
1097
1425
|
* @param urlOrParams - The checkout page URL or payment parameters
|
|
@@ -1101,11 +1429,25 @@ var PaymentUI = class extends HostedFrameModal {
|
|
|
1101
1429
|
if (typeof document === "undefined") return;
|
|
1102
1430
|
if (this.modal) return;
|
|
1103
1431
|
let checkoutUrl;
|
|
1432
|
+
this.activeOrderId = null;
|
|
1433
|
+
this.paymentCompleted = false;
|
|
1434
|
+
this.cancelRequestedOrderId = null;
|
|
1104
1435
|
if (typeof urlOrParams === "string") {
|
|
1105
1436
|
checkoutUrl = urlOrParams;
|
|
1437
|
+
try {
|
|
1438
|
+
const parsedUrl = new URL(checkoutUrl);
|
|
1439
|
+
this.activeCheckoutBaseUrl = parsedUrl.origin;
|
|
1440
|
+
const parts = parsedUrl.pathname.split("/").filter(Boolean);
|
|
1441
|
+
const checkoutIndex = parts.indexOf("checkout");
|
|
1442
|
+
this.activeCheckoutAppId = checkoutIndex >= 0 ? parts[checkoutIndex + 1] || null : null;
|
|
1443
|
+
} catch {
|
|
1444
|
+
this.activeCheckoutAppId = null;
|
|
1445
|
+
this.activeCheckoutBaseUrl = null;
|
|
1446
|
+
}
|
|
1106
1447
|
} else {
|
|
1107
1448
|
const {
|
|
1108
1449
|
appId,
|
|
1450
|
+
orderId,
|
|
1109
1451
|
productId,
|
|
1110
1452
|
priceId,
|
|
1111
1453
|
productCode,
|
|
@@ -1115,9 +1457,10 @@ var PaymentUI = class extends HostedFrameModal {
|
|
|
1115
1457
|
baseUrl = "https://pay.imgto.link"
|
|
1116
1458
|
} = urlOrParams;
|
|
1117
1459
|
const base = (checkoutUrlParam || baseUrl).replace(/\/$/, "");
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1460
|
+
this.activeCheckoutAppId = appId;
|
|
1461
|
+
this.activeCheckoutBaseUrl = base;
|
|
1462
|
+
const query = new URLSearchParams();
|
|
1463
|
+
if (userId) query.set("userId", userId);
|
|
1121
1464
|
if (customAmount) {
|
|
1122
1465
|
const amount = Number(customAmount.amount);
|
|
1123
1466
|
const currency = customAmount.currency.trim().toUpperCase();
|
|
@@ -1134,13 +1477,22 @@ var PaymentUI = class extends HostedFrameModal {
|
|
|
1134
1477
|
query.set("customAmount", String(amount));
|
|
1135
1478
|
query.set("customCurrency", currency);
|
|
1136
1479
|
}
|
|
1137
|
-
if (
|
|
1480
|
+
if (orderId) {
|
|
1481
|
+
const cleanOrderId = orderId.trim();
|
|
1482
|
+
if (!cleanOrderId) {
|
|
1483
|
+
throw new Error("orderId is required");
|
|
1484
|
+
}
|
|
1485
|
+
this.activeOrderId = cleanOrderId;
|
|
1486
|
+
checkoutUrl = `${base}/checkout/${appId}/orders/${cleanOrderId}`;
|
|
1487
|
+
const queryString = query.toString();
|
|
1488
|
+
if (queryString) checkoutUrl += `?${queryString}`;
|
|
1489
|
+
} else if (productCode) {
|
|
1138
1490
|
checkoutUrl = `${base}/checkout/${appId}/code/${productCode}?${query.toString()}`;
|
|
1139
1491
|
} else if (productId && priceId) {
|
|
1140
1492
|
checkoutUrl = `${base}/checkout/${appId}/${productId}/${priceId}?${query.toString()}`;
|
|
1141
1493
|
} else {
|
|
1142
1494
|
throw new Error(
|
|
1143
|
-
"Either productCode or both productId and priceId are required"
|
|
1495
|
+
"Either orderId, productCode, or both productId and priceId are required"
|
|
1144
1496
|
);
|
|
1145
1497
|
}
|
|
1146
1498
|
}
|
|
@@ -1150,13 +1502,23 @@ var PaymentUI = class extends HostedFrameModal {
|
|
|
1150
1502
|
);
|
|
1151
1503
|
this.openHostedFrame(finalUrl, {
|
|
1152
1504
|
allowedOrigin: options?.allowedOrigin,
|
|
1153
|
-
onCloseButton: () =>
|
|
1505
|
+
onCloseButton: () => {
|
|
1506
|
+
this.cancelHostedOrder("modal_close");
|
|
1507
|
+
options?.onCancel?.(this.activeOrderId || void 0);
|
|
1508
|
+
},
|
|
1154
1509
|
onMessage: (data, container) => {
|
|
1155
1510
|
switch (data.type) {
|
|
1511
|
+
case "PAYMENT_STARTED":
|
|
1512
|
+
if (data.orderId) {
|
|
1513
|
+
this.activeOrderId = data.orderId;
|
|
1514
|
+
}
|
|
1515
|
+
break;
|
|
1156
1516
|
case "PAYMENT_SUCCESS":
|
|
1517
|
+
this.paymentCompleted = true;
|
|
1157
1518
|
options?.onSuccess?.(data.orderId);
|
|
1158
1519
|
break;
|
|
1159
1520
|
case "PAYMENT_CANCELLED":
|
|
1521
|
+
this.cancelHostedOrder("payment_cancelled", data.orderId);
|
|
1160
1522
|
options?.onCancel?.(data.orderId);
|
|
1161
1523
|
break;
|
|
1162
1524
|
case "PAYMENT_RESIZE":
|
|
@@ -1167,6 +1529,7 @@ var PaymentUI = class extends HostedFrameModal {
|
|
|
1167
1529
|
}
|
|
1168
1530
|
break;
|
|
1169
1531
|
case "PAYMENT_CLOSE":
|
|
1532
|
+
this.cancelHostedOrder("payment_close", data.orderId);
|
|
1170
1533
|
this.close();
|
|
1171
1534
|
options?.onClose?.();
|
|
1172
1535
|
break;
|
|
@@ -1227,6 +1590,7 @@ function createPaymentUI() {
|
|
|
1227
1590
|
PaymentUI,
|
|
1228
1591
|
createLoginUI,
|
|
1229
1592
|
createPaymentUI,
|
|
1593
|
+
detectLoginEnvironment,
|
|
1230
1594
|
handleLoginCallbackIfPresent
|
|
1231
1595
|
});
|
|
1232
1596
|
//# sourceMappingURL=client.cjs.map
|