@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.js
CHANGED
|
@@ -204,6 +204,91 @@ var HostedFrameModal = class {
|
|
|
204
204
|
}
|
|
205
205
|
};
|
|
206
206
|
|
|
207
|
+
// src/environment.ts
|
|
208
|
+
function normalizeText(value) {
|
|
209
|
+
return value || "";
|
|
210
|
+
}
|
|
211
|
+
function getRuntimeInput() {
|
|
212
|
+
if (typeof navigator === "undefined") {
|
|
213
|
+
return {};
|
|
214
|
+
}
|
|
215
|
+
const nav = navigator;
|
|
216
|
+
const coarsePointer = typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia("(pointer: coarse)").matches : void 0;
|
|
217
|
+
return {
|
|
218
|
+
coarsePointer,
|
|
219
|
+
maxTouchPoints: nav.maxTouchPoints || 0,
|
|
220
|
+
platform: nav.platform || "",
|
|
221
|
+
standalone: nav.standalone,
|
|
222
|
+
userAgent: nav.userAgent || "",
|
|
223
|
+
userAgentDataMobile: nav.userAgentData?.mobile
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
function includesAny(value, patterns) {
|
|
227
|
+
return patterns.some((pattern) => pattern.test(value));
|
|
228
|
+
}
|
|
229
|
+
function detectLoginEnvironment(input = getRuntimeInput()) {
|
|
230
|
+
const userAgent = normalizeText(input.userAgent);
|
|
231
|
+
const platform = normalizeText(input.platform);
|
|
232
|
+
const rawMaxTouchPoints = input.maxTouchPoints ?? 0;
|
|
233
|
+
const maxTouchPoints = Number.isFinite(rawMaxTouchPoints) ? Math.max(0, rawMaxTouchPoints) : 0;
|
|
234
|
+
const isCoarsePointer = input.coarsePointer === true;
|
|
235
|
+
const isTouch = maxTouchPoints > 0 || isCoarsePointer;
|
|
236
|
+
const isWeChat = /micromessenger/i.test(userAgent);
|
|
237
|
+
const isAndroid = /\bandroid\b/i.test(userAgent);
|
|
238
|
+
const hasExplicitIOSDevice = /\b(iPad|iPhone|iPod)\b/i.test(userAgent);
|
|
239
|
+
const hasMacintoshUserAgent = /\bMacintosh\b/i.test(userAgent);
|
|
240
|
+
const hasMacPlatform = /^Mac/i.test(platform);
|
|
241
|
+
const isIPadOS = !hasExplicitIOSDevice && hasMacintoshUserAgent && hasMacPlatform && typeof input.standalone !== "undefined" && maxTouchPoints > 2;
|
|
242
|
+
const isIOS = hasExplicitIOSDevice || isIPadOS;
|
|
243
|
+
const isTabletByUa = includesAny(userAgent, [
|
|
244
|
+
/\biPad\b/i,
|
|
245
|
+
/\btablet\b/i,
|
|
246
|
+
/\bplaybook\b/i,
|
|
247
|
+
/\bsilk\b(?!.*\bmobile\b)/i,
|
|
248
|
+
/\bkindle\b/i,
|
|
249
|
+
/\bnexus 7\b/i,
|
|
250
|
+
/\bnexus 9\b/i,
|
|
251
|
+
/\bxoom\b/i,
|
|
252
|
+
/\bsm-t\d+/i,
|
|
253
|
+
/\bgt-p\d+/i,
|
|
254
|
+
/\bmi pad\b/i
|
|
255
|
+
]);
|
|
256
|
+
const isMobileByUa = includesAny(userAgent, [
|
|
257
|
+
/\bMobile\b/i,
|
|
258
|
+
/\biPhone\b/i,
|
|
259
|
+
/\biPod\b/i,
|
|
260
|
+
/\bWindows Phone\b/i,
|
|
261
|
+
/\bIEMobile\b/i,
|
|
262
|
+
/\bBlackBerry\b/i,
|
|
263
|
+
/\bBB10\b/i,
|
|
264
|
+
/\bOpera Mini\b/i,
|
|
265
|
+
/\bOpera Mobi\b/i,
|
|
266
|
+
/\bwebOS\b/i
|
|
267
|
+
]);
|
|
268
|
+
const isAndroidTablet = isAndroid && !/\bMobile\b/i.test(userAgent);
|
|
269
|
+
const isTablet = isIPadOS || isTabletByUa || isAndroidTablet;
|
|
270
|
+
const isMobile = input.userAgentDataMobile === true || isMobileByUa || isAndroid && !isTablet || isIOS && !isTablet;
|
|
271
|
+
const deviceType = isTablet ? "tablet" : isMobile ? "mobile" : userAgent || platform || isTouch ? "desktop" : "unknown";
|
|
272
|
+
const shouldUseRedirectLogin = deviceType === "mobile" || deviceType === "tablet" || isWeChat;
|
|
273
|
+
return {
|
|
274
|
+
deviceType,
|
|
275
|
+
isAndroid,
|
|
276
|
+
isCoarsePointer,
|
|
277
|
+
isDesktop: deviceType === "desktop",
|
|
278
|
+
isIOS,
|
|
279
|
+
isIPadOS,
|
|
280
|
+
isMobile,
|
|
281
|
+
isStandalone: input.standalone === true,
|
|
282
|
+
isTablet,
|
|
283
|
+
isTouch,
|
|
284
|
+
isWeChat,
|
|
285
|
+
maxTouchPoints,
|
|
286
|
+
platform,
|
|
287
|
+
shouldUseRedirectLogin,
|
|
288
|
+
userAgent
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
|
|
207
292
|
// src/login.ts
|
|
208
293
|
function getOrigin(value) {
|
|
209
294
|
if (!value) return null;
|
|
@@ -213,6 +298,15 @@ function getOrigin(value) {
|
|
|
213
298
|
return null;
|
|
214
299
|
}
|
|
215
300
|
}
|
|
301
|
+
function isValidLoginRedirectUrl(value) {
|
|
302
|
+
if (!value) return false;
|
|
303
|
+
try {
|
|
304
|
+
const url = new URL(value);
|
|
305
|
+
return url.protocol === "https:" || url.protocol === "http:";
|
|
306
|
+
} catch {
|
|
307
|
+
return false;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
216
310
|
function createLoginCallbackState() {
|
|
217
311
|
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
218
312
|
return crypto.randomUUID().replace(/-/g, "");
|
|
@@ -559,6 +653,24 @@ function applyLoginPanelStyle(panel) {
|
|
|
559
653
|
backdropFilter: "blur(16px)"
|
|
560
654
|
});
|
|
561
655
|
}
|
|
656
|
+
function applyLoginLoadingPanelStyle(panel) {
|
|
657
|
+
Object.assign(panel.style, {
|
|
658
|
+
position: "absolute",
|
|
659
|
+
inset: "0",
|
|
660
|
+
display: "flex",
|
|
661
|
+
alignItems: "center",
|
|
662
|
+
justifyContent: "center",
|
|
663
|
+
border: "0",
|
|
664
|
+
borderRadius: "28px",
|
|
665
|
+
background: "rgba(255,255,255,0.94)",
|
|
666
|
+
color: "#0f172a",
|
|
667
|
+
padding: "24px",
|
|
668
|
+
textAlign: "center",
|
|
669
|
+
zIndex: "1",
|
|
670
|
+
boxShadow: "none",
|
|
671
|
+
backdropFilter: "blur(16px)"
|
|
672
|
+
});
|
|
673
|
+
}
|
|
562
674
|
function createLoginPanelContent() {
|
|
563
675
|
const content = document.createElement("div");
|
|
564
676
|
Object.assign(content.style, {
|
|
@@ -583,6 +695,71 @@ function createLoginPanelContent() {
|
|
|
583
695
|
content.appendChild(badge);
|
|
584
696
|
return content;
|
|
585
697
|
}
|
|
698
|
+
function createBrandLoadingMark() {
|
|
699
|
+
const logo = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
700
|
+
logo.setAttribute("viewBox", "0 0 1024 1024");
|
|
701
|
+
logo.setAttribute("fill", "none");
|
|
702
|
+
logo.setAttribute("aria-hidden", "true");
|
|
703
|
+
Object.assign(logo.style, {
|
|
704
|
+
width: "112px",
|
|
705
|
+
height: "112px",
|
|
706
|
+
color: "#22c55e",
|
|
707
|
+
display: "block",
|
|
708
|
+
overflow: "visible"
|
|
709
|
+
});
|
|
710
|
+
const group = document.createElementNS("http://www.w3.org/2000/svg", "g");
|
|
711
|
+
group.setAttribute("fill", "currentColor");
|
|
712
|
+
const ring = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
|
713
|
+
ring.setAttribute(
|
|
714
|
+
"d",
|
|
715
|
+
"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"
|
|
716
|
+
);
|
|
717
|
+
ring.setAttribute("class", "youidian-sdk-brand-loading__ring");
|
|
718
|
+
const dot = document.createElementNS("http://www.w3.org/2000/svg", "circle");
|
|
719
|
+
dot.setAttribute("class", "youidian-sdk-brand-loading__dot");
|
|
720
|
+
dot.setAttribute("cx", "714.5");
|
|
721
|
+
dot.setAttribute("cy", "490.5");
|
|
722
|
+
dot.setAttribute("r", "68");
|
|
723
|
+
group.appendChild(ring);
|
|
724
|
+
group.appendChild(dot);
|
|
725
|
+
logo.appendChild(group);
|
|
726
|
+
return logo;
|
|
727
|
+
}
|
|
728
|
+
function createBrandLoadingCopy() {
|
|
729
|
+
const brand = document.createElement("div");
|
|
730
|
+
brand.className = "youidian-sdk-brand-loading__copy";
|
|
731
|
+
Object.assign(brand.style, {
|
|
732
|
+
display: "flex",
|
|
733
|
+
flexDirection: "column",
|
|
734
|
+
alignItems: "flex-start",
|
|
735
|
+
justifyContent: "center",
|
|
736
|
+
lineHeight: "1"
|
|
737
|
+
});
|
|
738
|
+
const name = document.createElement("div");
|
|
739
|
+
name.className = "youidian-sdk-brand-loading__name";
|
|
740
|
+
name.textContent = "\u4F18\u6613\u70B9";
|
|
741
|
+
Object.assign(name.style, {
|
|
742
|
+
color: "#0f172a",
|
|
743
|
+
fontSize: "34px",
|
|
744
|
+
fontWeight: "900",
|
|
745
|
+
letterSpacing: "0",
|
|
746
|
+
lineHeight: "1"
|
|
747
|
+
});
|
|
748
|
+
const tagline = document.createElement("div");
|
|
749
|
+
tagline.className = "youidian-sdk-brand-loading__tagline";
|
|
750
|
+
tagline.textContent = "\u5F00\u53D1\u8005\u670D\u52A1\u4E2D\u53F0";
|
|
751
|
+
Object.assign(tagline.style, {
|
|
752
|
+
color: "#64748b",
|
|
753
|
+
fontSize: "16px",
|
|
754
|
+
fontWeight: "700",
|
|
755
|
+
letterSpacing: "0.24em",
|
|
756
|
+
lineHeight: "1",
|
|
757
|
+
marginTop: "6px"
|
|
758
|
+
});
|
|
759
|
+
brand.appendChild(name);
|
|
760
|
+
brand.appendChild(tagline);
|
|
761
|
+
return brand;
|
|
762
|
+
}
|
|
586
763
|
function createLoginPanelTitle(value) {
|
|
587
764
|
const title = document.createElement("div");
|
|
588
765
|
title.textContent = value;
|
|
@@ -612,32 +789,111 @@ function ensureLoginLoadingStyles() {
|
|
|
612
789
|
}
|
|
613
790
|
const style = document.createElement("style");
|
|
614
791
|
style.id = "youidian-login-loading-style";
|
|
615
|
-
style.textContent =
|
|
792
|
+
style.textContent = `
|
|
793
|
+
.youidian-sdk-brand-loading__ring,
|
|
794
|
+
.youidian-sdk-brand-loading__dot {
|
|
795
|
+
transform-box: fill-box;
|
|
796
|
+
transform-origin: center;
|
|
797
|
+
will-change: opacity, transform;
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
.youidian-sdk-brand-loading__ring {
|
|
801
|
+
animation: youidian-sdk-brand-loading-ring 1400ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
.youidian-sdk-brand-loading__dot {
|
|
805
|
+
animation: youidian-sdk-brand-loading-dot 1400ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
.youidian-sdk-brand-loading__copy {
|
|
809
|
+
will-change: opacity, transform;
|
|
810
|
+
animation: youidian-sdk-brand-loading-copy 1600ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
.youidian-sdk-brand-loading__tagline {
|
|
814
|
+
will-change: opacity;
|
|
815
|
+
animation: youidian-sdk-brand-loading-tagline 1600ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
@keyframes youidian-sdk-brand-loading-ring {
|
|
819
|
+
0%,
|
|
820
|
+
100% {
|
|
821
|
+
opacity: 0.72;
|
|
822
|
+
transform: rotate(0deg) scale(0.98);
|
|
823
|
+
}
|
|
824
|
+
50% {
|
|
825
|
+
opacity: 1;
|
|
826
|
+
transform: rotate(8deg) scale(1.02);
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
@keyframes youidian-sdk-brand-loading-dot {
|
|
831
|
+
0%,
|
|
832
|
+
100% {
|
|
833
|
+
opacity: 0.55;
|
|
834
|
+
transform: scale(0.9);
|
|
835
|
+
}
|
|
836
|
+
50% {
|
|
837
|
+
opacity: 1;
|
|
838
|
+
transform: scale(1.08);
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
@keyframes youidian-sdk-brand-loading-copy {
|
|
843
|
+
0%,
|
|
844
|
+
100% {
|
|
845
|
+
opacity: 0.86;
|
|
846
|
+
transform: translateY(0);
|
|
847
|
+
}
|
|
848
|
+
50% {
|
|
849
|
+
opacity: 1;
|
|
850
|
+
transform: translateY(-1px);
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
@keyframes youidian-sdk-brand-loading-tagline {
|
|
855
|
+
0%,
|
|
856
|
+
100% {
|
|
857
|
+
opacity: 0.64;
|
|
858
|
+
}
|
|
859
|
+
50% {
|
|
860
|
+
opacity: 0.92;
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
@media (prefers-reduced-motion: reduce) {
|
|
865
|
+
.youidian-sdk-brand-loading__ring,
|
|
866
|
+
.youidian-sdk-brand-loading__dot,
|
|
867
|
+
.youidian-sdk-brand-loading__copy,
|
|
868
|
+
.youidian-sdk-brand-loading__tagline {
|
|
869
|
+
animation: none;
|
|
870
|
+
opacity: 1;
|
|
871
|
+
transform: none;
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
`;
|
|
616
875
|
document.head.appendChild(style);
|
|
617
876
|
}
|
|
618
|
-
function createLoginLoadingPanel(
|
|
877
|
+
function createLoginLoadingPanel() {
|
|
619
878
|
ensureLoginLoadingStyles();
|
|
620
879
|
const panel = document.createElement("div");
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
margin: "0 auto 18px",
|
|
631
|
-
animation: "youidian-login-spin 780ms linear infinite"
|
|
880
|
+
applyLoginLoadingPanelStyle(panel);
|
|
881
|
+
panel.setAttribute("role", "status");
|
|
882
|
+
panel.setAttribute("aria-label", "\u4F18\u6613\u70B9\u5F00\u53D1\u8005\u670D\u52A1\u4E2D\u53F0");
|
|
883
|
+
const content = document.createElement("div");
|
|
884
|
+
Object.assign(content.style, {
|
|
885
|
+
display: "flex",
|
|
886
|
+
alignItems: "center",
|
|
887
|
+
justifyContent: "center",
|
|
888
|
+
gap: "12px"
|
|
632
889
|
});
|
|
633
|
-
content.appendChild(
|
|
634
|
-
content.appendChild(
|
|
635
|
-
content.appendChild(createLoginPanelDescription(options.description));
|
|
890
|
+
content.appendChild(createBrandLoadingMark());
|
|
891
|
+
content.appendChild(createBrandLoadingCopy());
|
|
636
892
|
panel.appendChild(content);
|
|
637
893
|
return panel;
|
|
638
894
|
}
|
|
639
|
-
function createLoginRedirectingPanel(
|
|
640
|
-
return createLoginLoadingPanel(
|
|
895
|
+
function createLoginRedirectingPanel(_options) {
|
|
896
|
+
return createLoginLoadingPanel();
|
|
641
897
|
}
|
|
642
898
|
function createLoginFallbackPanel(options) {
|
|
643
899
|
const panel = document.createElement("div");
|
|
@@ -737,14 +993,11 @@ var LoginUI = class extends HostedFrameModal {
|
|
|
737
993
|
this.iframeFallbackPanel = null;
|
|
738
994
|
this.iframeLoadingPanel = null;
|
|
739
995
|
}
|
|
740
|
-
showIframeLoading(container
|
|
996
|
+
showIframeLoading(container) {
|
|
741
997
|
if (this.iframeLoadingPanel || this.iframeReady) {
|
|
742
998
|
return;
|
|
743
999
|
}
|
|
744
|
-
const panel = createLoginLoadingPanel(
|
|
745
|
-
description: options?.loadingDescription || "Please wait while the secure login page opens.",
|
|
746
|
-
title: options?.loadingTitle || "Opening login page"
|
|
747
|
-
});
|
|
1000
|
+
const panel = createLoginLoadingPanel();
|
|
748
1001
|
this.iframeLoadingPanel = panel;
|
|
749
1002
|
container.appendChild(panel);
|
|
750
1003
|
}
|
|
@@ -832,6 +1085,20 @@ var LoginUI = class extends HostedFrameModal {
|
|
|
832
1085
|
break;
|
|
833
1086
|
case "LOGIN_RESIZE":
|
|
834
1087
|
break;
|
|
1088
|
+
case "LOGIN_REDIRECT_REQUIRED":
|
|
1089
|
+
if (!isValidLoginRedirectUrl(data.authUrl)) {
|
|
1090
|
+
logLoginWarn("Login redirect requested with invalid authUrl");
|
|
1091
|
+
options?.onError?.("Login redirect URL is invalid", data);
|
|
1092
|
+
break;
|
|
1093
|
+
}
|
|
1094
|
+
logLoginInfo("Login redirect requested by hosted page", {
|
|
1095
|
+
attemptId: data.attemptId || null,
|
|
1096
|
+
channel: data.channel || null,
|
|
1097
|
+
authUrl: data.authUrl
|
|
1098
|
+
});
|
|
1099
|
+
this.close();
|
|
1100
|
+
window.location.assign(data.authUrl);
|
|
1101
|
+
break;
|
|
835
1102
|
case "LOGIN_ERROR":
|
|
836
1103
|
if (this.completed) {
|
|
837
1104
|
break;
|
|
@@ -855,6 +1122,25 @@ var LoginUI = class extends HostedFrameModal {
|
|
|
855
1122
|
break;
|
|
856
1123
|
}
|
|
857
1124
|
}
|
|
1125
|
+
openLoginRedirect(params, options) {
|
|
1126
|
+
if (typeof window === "undefined") return;
|
|
1127
|
+
const { callbackState, finalUrl, launchPayload } = this.buildOpenContext(
|
|
1128
|
+
params,
|
|
1129
|
+
options
|
|
1130
|
+
);
|
|
1131
|
+
logLoginInfo("Redirecting to hosted login page", {
|
|
1132
|
+
appId: params.appId,
|
|
1133
|
+
callbackState,
|
|
1134
|
+
callbackUrl: launchPayload.callbackUrl || null,
|
|
1135
|
+
hasCallbackUrl: Boolean(launchPayload.callbackUrl),
|
|
1136
|
+
loginUrl: finalUrl,
|
|
1137
|
+
autoClose: options?.autoClose ?? true,
|
|
1138
|
+
displayMode: "redirect",
|
|
1139
|
+
pageUrl: window.location.href,
|
|
1140
|
+
parentOrigin: launchPayload.origin || null
|
|
1141
|
+
});
|
|
1142
|
+
window.location.assign(finalUrl);
|
|
1143
|
+
}
|
|
858
1144
|
listenForLoginCallback(callbackState, options) {
|
|
859
1145
|
try {
|
|
860
1146
|
this.callbackChannel = new BroadcastChannel(
|
|
@@ -931,21 +1217,17 @@ var LoginUI = class extends HostedFrameModal {
|
|
|
931
1217
|
options?.onCancel?.();
|
|
932
1218
|
options?.onClose?.();
|
|
933
1219
|
},
|
|
934
|
-
onMessage: (data,
|
|
1220
|
+
onMessage: (data, _container, event) => {
|
|
935
1221
|
const isIframeEvent = event.source === this.iframe?.contentWindow;
|
|
936
1222
|
if (isIframeEvent && (data.type === "LOGIN_READY" || data.type === "LOGIN_RESIZE") || data.type === "LOGIN_SUCCESS" || data.type === "LOGIN_ERROR") {
|
|
937
1223
|
this.markIframeReady();
|
|
938
1224
|
}
|
|
939
|
-
if (data.type === "LOGIN_RESIZE" && data.height) {
|
|
940
|
-
const maxHeight = window.innerHeight * 0.94;
|
|
941
|
-
container.style.height = `${Math.min(data.height, maxHeight)}px`;
|
|
942
|
-
}
|
|
943
1225
|
this.handleLoginEvent(data, options);
|
|
944
1226
|
},
|
|
945
1227
|
width: "min(520px, 100%)"
|
|
946
1228
|
});
|
|
947
1229
|
if (hostedFrame) {
|
|
948
|
-
this.showIframeLoading(hostedFrame.container
|
|
1230
|
+
this.showIframeLoading(hostedFrame.container);
|
|
949
1231
|
this.startIframeWatchdog({
|
|
950
1232
|
container: hostedFrame.container,
|
|
951
1233
|
finalUrl,
|
|
@@ -1049,11 +1331,19 @@ var LoginUI = class extends HostedFrameModal {
|
|
|
1049
1331
|
}
|
|
1050
1332
|
openLogin(params, options) {
|
|
1051
1333
|
if (typeof window === "undefined") return;
|
|
1052
|
-
const displayMode = options?.displayMode ?? "
|
|
1334
|
+
const displayMode = options?.displayMode ?? "auto";
|
|
1335
|
+
if (displayMode === "redirect") {
|
|
1336
|
+
this.openLoginRedirect(params, options);
|
|
1337
|
+
return;
|
|
1338
|
+
}
|
|
1053
1339
|
if (displayMode === "popup") {
|
|
1054
1340
|
this.openLoginPopup(params, options);
|
|
1055
1341
|
return;
|
|
1056
1342
|
}
|
|
1343
|
+
if (displayMode === "auto" && detectLoginEnvironment().shouldUseRedirectLogin) {
|
|
1344
|
+
this.openLoginRedirect(params, options);
|
|
1345
|
+
return;
|
|
1346
|
+
}
|
|
1057
1347
|
this.openLoginModal(params, options);
|
|
1058
1348
|
}
|
|
1059
1349
|
};
|
|
@@ -1064,6 +1354,43 @@ handleLoginCallbackIfPresent({ autoClose: false });
|
|
|
1064
1354
|
|
|
1065
1355
|
// src/client.ts
|
|
1066
1356
|
var PaymentUI = class extends HostedFrameModal {
|
|
1357
|
+
constructor() {
|
|
1358
|
+
super(...arguments);
|
|
1359
|
+
__publicField(this, "activeCheckoutAppId", null);
|
|
1360
|
+
__publicField(this, "activeCheckoutBaseUrl", null);
|
|
1361
|
+
__publicField(this, "activeOrderId", null);
|
|
1362
|
+
__publicField(this, "paymentCompleted", false);
|
|
1363
|
+
__publicField(this, "cancelRequestedOrderId", null);
|
|
1364
|
+
}
|
|
1365
|
+
cancelHostedOrder(reason = "user_cancel", orderId) {
|
|
1366
|
+
const targetOrderId = orderId || this.activeOrderId;
|
|
1367
|
+
if (!targetOrderId || !this.activeCheckoutAppId || !this.activeCheckoutBaseUrl || this.paymentCompleted || this.cancelRequestedOrderId === targetOrderId) {
|
|
1368
|
+
return;
|
|
1369
|
+
}
|
|
1370
|
+
this.cancelRequestedOrderId = targetOrderId;
|
|
1371
|
+
const url = `${this.activeCheckoutBaseUrl}/api/internal/checkout/cancel-order`;
|
|
1372
|
+
const payload = JSON.stringify({
|
|
1373
|
+
appId: this.activeCheckoutAppId,
|
|
1374
|
+
orderId: targetOrderId,
|
|
1375
|
+
reason
|
|
1376
|
+
});
|
|
1377
|
+
if (typeof navigator !== "undefined" && navigator.sendBeacon) {
|
|
1378
|
+
const sent = navigator.sendBeacon(
|
|
1379
|
+
url,
|
|
1380
|
+
new Blob([payload], { type: "application/json" })
|
|
1381
|
+
);
|
|
1382
|
+
if (sent) return;
|
|
1383
|
+
}
|
|
1384
|
+
void fetch(url, {
|
|
1385
|
+
method: "POST",
|
|
1386
|
+
body: payload,
|
|
1387
|
+
headers: { "Content-Type": "text/plain;charset=UTF-8" },
|
|
1388
|
+
keepalive: true,
|
|
1389
|
+
mode: "no-cors"
|
|
1390
|
+
}).catch(() => {
|
|
1391
|
+
this.cancelRequestedOrderId = null;
|
|
1392
|
+
});
|
|
1393
|
+
}
|
|
1067
1394
|
/**
|
|
1068
1395
|
* Opens the payment checkout page in an iframe modal.
|
|
1069
1396
|
* @param urlOrParams - The checkout page URL or payment parameters
|
|
@@ -1073,11 +1400,25 @@ var PaymentUI = class extends HostedFrameModal {
|
|
|
1073
1400
|
if (typeof document === "undefined") return;
|
|
1074
1401
|
if (this.modal) return;
|
|
1075
1402
|
let checkoutUrl;
|
|
1403
|
+
this.activeOrderId = null;
|
|
1404
|
+
this.paymentCompleted = false;
|
|
1405
|
+
this.cancelRequestedOrderId = null;
|
|
1076
1406
|
if (typeof urlOrParams === "string") {
|
|
1077
1407
|
checkoutUrl = urlOrParams;
|
|
1408
|
+
try {
|
|
1409
|
+
const parsedUrl = new URL(checkoutUrl);
|
|
1410
|
+
this.activeCheckoutBaseUrl = parsedUrl.origin;
|
|
1411
|
+
const parts = parsedUrl.pathname.split("/").filter(Boolean);
|
|
1412
|
+
const checkoutIndex = parts.indexOf("checkout");
|
|
1413
|
+
this.activeCheckoutAppId = checkoutIndex >= 0 ? parts[checkoutIndex + 1] || null : null;
|
|
1414
|
+
} catch {
|
|
1415
|
+
this.activeCheckoutAppId = null;
|
|
1416
|
+
this.activeCheckoutBaseUrl = null;
|
|
1417
|
+
}
|
|
1078
1418
|
} else {
|
|
1079
1419
|
const {
|
|
1080
1420
|
appId,
|
|
1421
|
+
orderId,
|
|
1081
1422
|
productId,
|
|
1082
1423
|
priceId,
|
|
1083
1424
|
productCode,
|
|
@@ -1087,9 +1428,10 @@ var PaymentUI = class extends HostedFrameModal {
|
|
|
1087
1428
|
baseUrl = "https://pay.imgto.link"
|
|
1088
1429
|
} = urlOrParams;
|
|
1089
1430
|
const base = (checkoutUrlParam || baseUrl).replace(/\/$/, "");
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1431
|
+
this.activeCheckoutAppId = appId;
|
|
1432
|
+
this.activeCheckoutBaseUrl = base;
|
|
1433
|
+
const query = new URLSearchParams();
|
|
1434
|
+
if (userId) query.set("userId", userId);
|
|
1093
1435
|
if (customAmount) {
|
|
1094
1436
|
const amount = Number(customAmount.amount);
|
|
1095
1437
|
const currency = customAmount.currency.trim().toUpperCase();
|
|
@@ -1106,13 +1448,22 @@ var PaymentUI = class extends HostedFrameModal {
|
|
|
1106
1448
|
query.set("customAmount", String(amount));
|
|
1107
1449
|
query.set("customCurrency", currency);
|
|
1108
1450
|
}
|
|
1109
|
-
if (
|
|
1451
|
+
if (orderId) {
|
|
1452
|
+
const cleanOrderId = orderId.trim();
|
|
1453
|
+
if (!cleanOrderId) {
|
|
1454
|
+
throw new Error("orderId is required");
|
|
1455
|
+
}
|
|
1456
|
+
this.activeOrderId = cleanOrderId;
|
|
1457
|
+
checkoutUrl = `${base}/checkout/${appId}/orders/${cleanOrderId}`;
|
|
1458
|
+
const queryString = query.toString();
|
|
1459
|
+
if (queryString) checkoutUrl += `?${queryString}`;
|
|
1460
|
+
} else if (productCode) {
|
|
1110
1461
|
checkoutUrl = `${base}/checkout/${appId}/code/${productCode}?${query.toString()}`;
|
|
1111
1462
|
} else if (productId && priceId) {
|
|
1112
1463
|
checkoutUrl = `${base}/checkout/${appId}/${productId}/${priceId}?${query.toString()}`;
|
|
1113
1464
|
} else {
|
|
1114
1465
|
throw new Error(
|
|
1115
|
-
"Either productCode or both productId and priceId are required"
|
|
1466
|
+
"Either orderId, productCode, or both productId and priceId are required"
|
|
1116
1467
|
);
|
|
1117
1468
|
}
|
|
1118
1469
|
}
|
|
@@ -1122,13 +1473,23 @@ var PaymentUI = class extends HostedFrameModal {
|
|
|
1122
1473
|
);
|
|
1123
1474
|
this.openHostedFrame(finalUrl, {
|
|
1124
1475
|
allowedOrigin: options?.allowedOrigin,
|
|
1125
|
-
onCloseButton: () =>
|
|
1476
|
+
onCloseButton: () => {
|
|
1477
|
+
this.cancelHostedOrder("modal_close");
|
|
1478
|
+
options?.onCancel?.(this.activeOrderId || void 0);
|
|
1479
|
+
},
|
|
1126
1480
|
onMessage: (data, container) => {
|
|
1127
1481
|
switch (data.type) {
|
|
1482
|
+
case "PAYMENT_STARTED":
|
|
1483
|
+
if (data.orderId) {
|
|
1484
|
+
this.activeOrderId = data.orderId;
|
|
1485
|
+
}
|
|
1486
|
+
break;
|
|
1128
1487
|
case "PAYMENT_SUCCESS":
|
|
1488
|
+
this.paymentCompleted = true;
|
|
1129
1489
|
options?.onSuccess?.(data.orderId);
|
|
1130
1490
|
break;
|
|
1131
1491
|
case "PAYMENT_CANCELLED":
|
|
1492
|
+
this.cancelHostedOrder("payment_cancelled", data.orderId);
|
|
1132
1493
|
options?.onCancel?.(data.orderId);
|
|
1133
1494
|
break;
|
|
1134
1495
|
case "PAYMENT_RESIZE":
|
|
@@ -1139,6 +1500,7 @@ var PaymentUI = class extends HostedFrameModal {
|
|
|
1139
1500
|
}
|
|
1140
1501
|
break;
|
|
1141
1502
|
case "PAYMENT_CLOSE":
|
|
1503
|
+
this.cancelHostedOrder("payment_close", data.orderId);
|
|
1142
1504
|
this.close();
|
|
1143
1505
|
options?.onClose?.();
|
|
1144
1506
|
break;
|
|
@@ -1198,6 +1560,7 @@ export {
|
|
|
1198
1560
|
PaymentUI,
|
|
1199
1561
|
createLoginUI,
|
|
1200
1562
|
createPaymentUI,
|
|
1563
|
+
detectLoginEnvironment,
|
|
1201
1564
|
handleLoginCallbackIfPresent
|
|
1202
1565
|
};
|
|
1203
1566
|
//# sourceMappingURL=client.js.map
|