@cnv-vn/track 0.3.0-beta.2 → 0.3.0-beta.20
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/README.md +3 -3
- package/dist/cnv-track.esm.js +2 -2
- package/dist/cnv-track.min.js +2 -2
- package/dist/cnv-track.umd.cjs +2 -2
- package/dist/types/index.d.ts +151 -66
- package/package.json +3 -3
package/dist/types/index.d.ts
CHANGED
|
@@ -563,6 +563,7 @@ interface LauncherRemoteConfig {
|
|
|
563
563
|
buttonShape?: 'SQUARE' | 'SHAVED' | 'ROUNDED' | 'CIRCULAR';
|
|
564
564
|
placementDesktop?: LauncherPlacement;
|
|
565
565
|
placementMobile?: LauncherPlacement;
|
|
566
|
+
/** Hex hoặc `linear-gradient(…)` (xem `isValidGradient`). */
|
|
566
567
|
backgroundColor?: string;
|
|
567
568
|
textColor?: string;
|
|
568
569
|
contentLayoutDesktop?: 'ICON_WITH_TEXT' | 'TEXT_ONLY' | 'ICON_ONLY';
|
|
@@ -608,7 +609,7 @@ interface PanelRemoteConfig {
|
|
|
608
609
|
colors?: PanelColors;
|
|
609
610
|
shapes?: PanelShapes;
|
|
610
611
|
wallpaper?: 'NONE' | 'WAVES' | 'CUBES' | 'FUN' | 'GEOMETRIC' | 'CROSS_HATCHING';
|
|
611
|
-
/** `true` ⇒ bỏ chân panel "Cung cấp bởi CNV
|
|
612
|
+
/** `true` ⇒ bỏ chân panel "Cung cấp bởi CNV CDP". Thiếu/`false` = vẫn hiện (mặc định). */
|
|
612
613
|
hideBranding?: boolean;
|
|
613
614
|
}
|
|
614
615
|
interface PanelHeaderCopy {
|
|
@@ -645,10 +646,12 @@ interface PanelContentBlock {
|
|
|
645
646
|
description?: string;
|
|
646
647
|
}
|
|
647
648
|
interface PanelColors {
|
|
649
|
+
/** Hex hoặc `linear-gradient(…)` (xem `isValidGradient`), như `buttonBg`. */
|
|
648
650
|
bannerBg?: string;
|
|
649
651
|
bannerFont?: string;
|
|
650
652
|
/** Mirror model admin — `core/panel.ts` hiện CHƯA render field này (Panel không có header bar riêng). */
|
|
651
653
|
headerBarFont?: string;
|
|
654
|
+
/** Hex hoặc `linear-gradient(…)` (xem `isValidGradient`). */
|
|
652
655
|
buttonBg?: string;
|
|
653
656
|
buttonFont?: string;
|
|
654
657
|
linkColor?: string;
|
|
@@ -665,11 +668,14 @@ interface PanelShapes {
|
|
|
665
668
|
* Lý do `loginWithZalo()` thất bại (`ZaloQrLoginError.reason`). LƯU Ý phạm vi
|
|
666
669
|
* reject khác nhau:
|
|
667
670
|
* - `'not-initialized' | 'disabled' | 'consent-required' | 'invalid-project-key'
|
|
668
|
-
* | 'project-suspended' | '
|
|
671
|
+
* | 'project-suspended' | 'origin-required' | 'zalo-login-not-configured'
|
|
672
|
+
* | 'zalo-login-unavailable' | 'network'`: reject ngay lời gọi `loginWithZalo(...)`
|
|
669
673
|
* (trước khi có {@link ZaloQrLoginSession}) — lỗi thiết lập phiên, không có
|
|
670
674
|
* `session`/`session.result` nào để bắt.
|
|
671
|
-
* - `'expired' | 'denied' | '
|
|
672
|
-
*
|
|
675
|
+
* - `'expired' | 'denied' | 'consent-declined' | 'zalo-permission-denied'
|
|
676
|
+
* | 'underage-self-declared' | 'cancelled' | 'agent-registration-required'
|
|
677
|
+
* | 'requester-not-ready' | 'login-blocked'`: reject {@link ZaloQrLoginSession.result} —
|
|
678
|
+
* xảy ra SAU khi đã có `session` (QR đã hiển thị), khi chờ kết quả quét.
|
|
673
679
|
*
|
|
674
680
|
* Bọc `try/catch` quanh CẢ hai điểm `await` (xem ví dụ ở `loginWithZalo` JSDoc)
|
|
675
681
|
* để không bỏ sót nhóm đầu.
|
|
@@ -678,8 +684,36 @@ interface PanelShapes {
|
|
|
678
684
|
* theo HTTP status server trả về (401/403) — đây là lỗi CẤU HÌNH (project key
|
|
679
685
|
* gõ sai/thiếu, hoặc project bị khoá), KHÔNG PHẢI lỗi mạng/CORS thật. Trước đây
|
|
680
686
|
* cả 2 nhóm bị gộp chung `'network'`, khiến integrator debug sai hướng.
|
|
687
|
+
*
|
|
688
|
+
* `'agent-registration-required'`: khách đã quét QR và xác thực Zalo XONG, nhưng shop bật
|
|
689
|
+
* plugin đăng ký đại lý (`apps.agent-registration`) và khách chưa đăng ký / chưa được shop
|
|
690
|
+
* duyệt làm đại lý. Khác `'denied'` (khách tự bấm "Từ chối" trong Mini App) ở chỗ khách không
|
|
691
|
+
* làm gì sai và bấm "Thử lại" cũng vô nghĩa: việc cần làm là mở Mini App của shop để đăng ký
|
|
692
|
+
* đại lý trước. `'login-blocked'` là ca shop chặn vì lý do khác (backend gửi mã lạ) — dùng câu
|
|
693
|
+
* thông báo chung, vẫn cho thử lại.
|
|
694
|
+
*
|
|
695
|
+
* Lỗi tạo phiên theo HTTP status của `POST /zalo-qr/session`: `'zalo-login-not-configured'` (422 —
|
|
696
|
+
* project chưa cấu hình Mini App nhận QR, và cũng không được dùng Mini App CNV dùng chung),
|
|
697
|
+
* `'zalo-login-unavailable'` (503 — Mini App chưa ACTIVE/chưa xác minh được, tạm thời),
|
|
698
|
+
* `'origin-required'` (403 `origin_required` — request không có header `Origin`, tức không gọi
|
|
699
|
+
* từ trình duyệt; KHÁC `'project-suspended'`, cũng là 403).
|
|
700
|
+
*
|
|
701
|
+
* Khách TỰ từ chối ở Mini App — `denied` kèm lý do từ server: `'consent-declined'` (bấm Huỷ ở
|
|
702
|
+
* màn xin quyền của Mini App CNV dùng chung; KHÁC `'consent-required'`, vốn là đồng ý tracking
|
|
703
|
+
* trên website), `'zalo-permission-denied'` (từ chối popup quyền số điện thoại của Zalo),
|
|
704
|
+
* `'underage-self-declared'` (tự khai chưa đủ 16 tuổi). Không có lý do (Mini App riêng của shop,
|
|
705
|
+
* backend cũ) vẫn là `'denied'`.
|
|
706
|
+
*
|
|
707
|
+
* `'requester-not-ready'`: shop CHƯA sẵn sàng nhận xác thực qua Mini App CNV dùng chung (hồ sơ
|
|
708
|
+
* chưa được duyệt, website chưa khai báo…) — việc của shop, khách thử lại ngay cũng vậy.
|
|
681
709
|
*/
|
|
682
|
-
type ZaloQrLoginErrorReason = 'not-initialized' | 'disabled' | 'consent-required' | 'invalid-project-key' | 'project-suspended' | 'network' | 'expired' | 'denied' | 'cancelled';
|
|
710
|
+
type ZaloQrLoginErrorReason = 'not-initialized' | 'disabled' | 'consent-required' | 'invalid-project-key' | 'project-suspended' | 'origin-required' | 'zalo-login-not-configured' | 'zalo-login-unavailable' | 'network' | 'expired' | 'denied' | 'consent-declined' | 'zalo-permission-denied' | 'underage-self-declared' | 'cancelled' | 'agent-registration-required' | 'requester-not-ready' | 'login-blocked';
|
|
711
|
+
/**
|
|
712
|
+
* Mã QR mở Mini App NÀO: `'SHOP'` = Mini App riêng của shop; `'CNV_SHARED'` = Mini App CNV dùng chung
|
|
713
|
+
* (shop không có Mini App riêng), nơi khách thấy màn xin quyền rồi mới chia sẻ thông tin. Server chọn,
|
|
714
|
+
* SDK chỉ đọc — dùng để nói đúng câu với khách (vd "liên hệ shop" thay vì "mở Mini App của shop").
|
|
715
|
+
*/
|
|
716
|
+
type ZaloQrMiniAppKind = 'SHOP' | 'CNV_SHARED';
|
|
683
717
|
/** Tuỳ chọn cho `loginWithZalo()`. */
|
|
684
718
|
interface ZaloQrLoginOptions {
|
|
685
719
|
/** Ưu tiên SSE (mặc định `true`); `false` ⇒ chỉ dùng poll ngay từ đầu. */
|
|
@@ -687,25 +721,36 @@ interface ZaloQrLoginOptions {
|
|
|
687
721
|
/** Khoảng poll fallback (ms). Mặc định 2000. */
|
|
688
722
|
pollIntervalMs?: number;
|
|
689
723
|
/**
|
|
690
|
-
*
|
|
691
|
-
*
|
|
692
|
-
*
|
|
693
|
-
* - Đã có `userId` từ trước (site tự `identify()` sau login thường của họ) → **không ghi đè** —
|
|
694
|
-
* `alias(String(contactId), userId cũ)` để backend biết 2 ID là cùng một người, `userId`
|
|
695
|
-
* hiện tại giữ nguyên, lịch sử tracking không bị "nhảy" giữa chừng.
|
|
724
|
+
* Báo tiến trình của phiên TRƯỚC khi có kết cục — để host đổi màn QR khi khách đã quét mã, thay
|
|
725
|
+
* vì để họ nhìn một mã QR đứng im trong lúc bước tiếp theo nằm trên điện thoại (màn xin quyền
|
|
726
|
+
* của Mini App).
|
|
696
727
|
*
|
|
697
|
-
*
|
|
698
|
-
*
|
|
728
|
+
* Gọi tối đa MỘT lần mỗi phiên (server báo lại "đã quét" ở mỗi nhịp poll và mỗi lần SSE nối lại
|
|
729
|
+
* — SDK lọc hộ). Không phải kết cục: `result` vẫn chờ tiếp như thường. Lỗi ném ra từ callback bị
|
|
730
|
+
* nuốt, không làm hỏng phiên. Server cũ không báo "đã quét" ⇒ không bao giờ được gọi.
|
|
699
731
|
*/
|
|
700
|
-
|
|
732
|
+
onProgress?: (progress: ZaloQrLoginProgress) => void;
|
|
733
|
+
}
|
|
734
|
+
/** Tiến trình của một phiên QR chưa kết thúc — xem {@link ZaloQrLoginOptions.onProgress}. */
|
|
735
|
+
interface ZaloQrLoginProgress {
|
|
736
|
+
/** `'scanned'`: khách đã quét mã, Mini App đang chờ khách xác nhận trên điện thoại. */
|
|
737
|
+
stage: 'scanned';
|
|
738
|
+
/**
|
|
739
|
+
* Số giây phiên còn sống theo server lúc báo. Server gia hạn phiên khi khách quét (đọc màn xin
|
|
740
|
+
* quyền cần thời gian); SDK đã tự nới hạn chờ của `result` theo đó (chỉ nới, không rút) — host
|
|
741
|
+
* chỉ cần đếm ngược lại từ số này. Thiếu (server không đọc được hạn, hoặc số không hợp lệ) ⇒ hạn
|
|
742
|
+
* cũ vẫn đúng, cứ đếm tiếp.
|
|
743
|
+
*/
|
|
744
|
+
expiresInSeconds?: number;
|
|
701
745
|
}
|
|
702
746
|
/**
|
|
703
747
|
* Kết quả khi người dùng quét QR và xác thực Zalo thành công.
|
|
704
748
|
*
|
|
705
749
|
* KHÔNG có `phone` — số điện thoại thật KHÔNG được trả về client (cùng lý do đã bỏ
|
|
706
750
|
* `apiToken`/`loginToken`: PII/credential lộ ra bất kỳ script nào chạy chung trang hoặc
|
|
707
|
-
* ai mở DevTools). `contactId` là định danh
|
|
708
|
-
*
|
|
751
|
+
* ai mở DevTools). `contactId` là định danh khách trong CDP, server đã nối với anonymousId
|
|
752
|
+
* của phiên; host KHÔNG cần gọi identify(). Nếu cần số điện thoại cho nghiệp vụ, tự tra cứu
|
|
753
|
+
* ở backend của bạn bằng `contactId` (đã xác thực thật).
|
|
709
754
|
*/
|
|
710
755
|
interface ZaloQrLoginResult {
|
|
711
756
|
contactId?: number;
|
|
@@ -716,18 +761,28 @@ interface ZaloQrLoginResult {
|
|
|
716
761
|
/** Điểm kinh nghiệm/tích luỹ hiện tại (nếu có). */
|
|
717
762
|
xp?: number;
|
|
718
763
|
/**
|
|
719
|
-
* JWT HẸP QUYỀN, sống
|
|
720
|
-
*
|
|
721
|
-
*
|
|
722
|
-
*
|
|
723
|
-
*
|
|
724
|
-
*
|
|
725
|
-
*
|
|
726
|
-
*
|
|
764
|
+
* JWT HẸP QUYỀN, sống 30 PHÚT — dùng để gọi nhóm `{endpoint}/panel/*` (khôi phục Member sau F5,
|
|
765
|
+
* điểm/ưu đãi/đổi điểm), KHÁC HẲN apiToken/loginToken thật (đã bị chặn không trả về client — xem
|
|
766
|
+
* javadoc trên). An toàn hơn hẳn token thật vì: hẹp quyền, sống rất ngắn, và khoá ký riêng theo
|
|
767
|
+
* từng project — lộ token này chỉ lộ đúng tên/hạng/điểm của 1 khách, không dùng được ở bất kỳ API
|
|
768
|
+
* nào khác trong hệ sinh thái CNV.
|
|
769
|
+
*
|
|
770
|
+
* 30 phút KHÔNG có nghĩa khách phải quét lại QR mỗi 30 phút: `panel.ts` tự gia hạn trước hạn qua
|
|
771
|
+
* `POST {endpoint}/panel/session/refresh`, và cả chuỗi gia hạn có trần 24h kể từ lúc quét QR.
|
|
772
|
+
* Integrator dùng `loginWithZalo()` trực tiếp (không qua Panel) muốn hành vi "nhớ đăng nhập"
|
|
773
|
+
* giống vậy thì phải TỰ gia hạn — token này để yên là chết sau 30 phút.
|
|
727
774
|
*/
|
|
728
775
|
panelSessionToken?: string;
|
|
729
776
|
/** Epoch-ms hết hạn của {@link panelSessionToken} — so `Date.now() > panelSessionExp` không cần decode JWT. */
|
|
730
777
|
panelSessionExp?: number;
|
|
778
|
+
/**
|
|
779
|
+
* Thời lượng còn sống của {@link panelSessionToken}, tính bằng ms kể từ lúc server phát.
|
|
780
|
+
*
|
|
781
|
+
* Dùng field này thay cho {@link panelSessionExp} bất cứ khi nào có: mốc tuyệt đối chỉ đúng nếu
|
|
782
|
+
* đồng hồ máy khách đúng, còn thời lượng thì cùng hệ quy chiếu với `Date.now()` của chính máy đó —
|
|
783
|
+
* quan trọng vì TTL chỉ 30 phút, máy lệch giờ nửa tiếng là tự đăng xuất ngay khi vừa đăng nhập.
|
|
784
|
+
*/
|
|
785
|
+
panelSessionExpiresInMs?: number;
|
|
731
786
|
}
|
|
732
787
|
/**
|
|
733
788
|
* Phiên QR-login đang chờ người dùng quét. SDK KHÔNG tự vẽ QR — host page tự
|
|
@@ -736,12 +791,18 @@ interface ZaloQrLoginResult {
|
|
|
736
791
|
*/
|
|
737
792
|
interface ZaloQrLoginSession {
|
|
738
793
|
sessionToken: string;
|
|
739
|
-
/**
|
|
794
|
+
/**
|
|
795
|
+
* Deep-link Mini App Zalo — host tự vẽ thành mã QR. Trên ĐIỆN THOẠI khách không quét được màn hình
|
|
796
|
+
* của chính mình: dùng chuỗi này làm `href` của một nút "Mở Zalo" (link `https://zalo.me/...` mở
|
|
797
|
+
* thẳng app Zalo), QR chỉ còn là phương án quét bằng máy khác.
|
|
798
|
+
*/
|
|
740
799
|
qrPayload: string;
|
|
741
800
|
expiresInSeconds: number;
|
|
801
|
+
/** Mini App mà mã QR mở — xem {@link ZaloQrMiniAppKind}. Server cũ không gửi ⇒ `'SHOP'`. */
|
|
802
|
+
miniAppKind: ZaloQrMiniAppKind;
|
|
742
803
|
/**
|
|
743
804
|
* Resolve khi quét xong & backend xác nhận; reject với {@link ZaloQrLoginError}
|
|
744
|
-
* có `reason` là `'expired' | 'denied' | 'cancelled'
|
|
805
|
+
* có `reason` là `'expired' | 'denied' | 'cancelled'`… (xem {@link ZaloQrLoginErrorReason}
|
|
745
806
|
* để phân biệt với lỗi thiết lập phiên, vốn reject lời gọi `loginWithZalo()` chứ
|
|
746
807
|
* không phải field này).
|
|
747
808
|
*/
|
|
@@ -766,6 +827,64 @@ interface ZaloQrLoginSession {
|
|
|
766
827
|
*/
|
|
767
828
|
type QueuedCommand = readonly ['init', string, SDKOptions?] | readonly ['pageview', string?, Record<string, JSONValue>?] | readonly ['page', string?, Record<string, JSONValue>?] | readonly ['screen', string?, Record<string, JSONValue>?] | readonly ['track', string, Record<string, JSONValue>?] | readonly ['identify', string, UserTraits?] | readonly ['alias', string, string?] | readonly ['group', string, Record<string, JSONValue>?] | readonly ['reset'] | readonly ['flush'] | readonly ['consent', Partial<ContextConsent>] | readonly ['set', Partial<SDKOptions>];
|
|
768
829
|
|
|
830
|
+
/**
|
|
831
|
+
* ============================================================================
|
|
832
|
+
* zaloQrLogin — đăng nhập bằng Zalo qua QR cho website nhúng SDK
|
|
833
|
+
* ============================================================================
|
|
834
|
+
*
|
|
835
|
+
* `loginWithZalo()` là API ĐẦU TIÊN của SDK không theo hợp đồng "never throw,
|
|
836
|
+
* fire-and-forget" của các method khác (track/identify/...) — nó trả Promise
|
|
837
|
+
* thật, và có THỂ REJECT Ở 2 ĐIỂM khác nhau (xem `ZaloQrLoginErrorReason` ở
|
|
838
|
+
* types.ts để biết chi tiết từng reason):
|
|
839
|
+
* 1. Lời gọi `loginWithZalo()` chính nó — lỗi thiết lập phiên (chưa init,
|
|
840
|
+
* dashboard tắt, thiếu consent, lỗi mạng khi tạo phiên).
|
|
841
|
+
* 2. `session.result` — lỗi xảy ra SAU khi đã có phiên/đã hiển thị QR
|
|
842
|
+
* (hết hạn, bị từ chối, bị huỷ).
|
|
843
|
+
* Consumer cần bọc try/catch quanh CẢ HAI điểm await. Vì cần tương tác 2
|
|
844
|
+
* chiều thực sự (đăng ký phiên → chờ QR được quét), hàm này KHÔNG đi qua
|
|
845
|
+
* queue protocol `window.cnvQ` — chỉ dùng được qua ES-module import.
|
|
846
|
+
*
|
|
847
|
+
* SDK không tự vẽ QR: trả `qrPayload` (deep-link Mini App) để host page tự
|
|
848
|
+
* render `<img>`/canvas, đúng vai trò "tracker" chứ không phải "auth widget"
|
|
849
|
+
* (xem cách `demo/index.html` tự vẽ modal login cho `identify()`).
|
|
850
|
+
*
|
|
851
|
+
* Kênh nhận kết quả: SSE (`GET {endpoint}/zalo-qr/stream`) làm chính, tự
|
|
852
|
+
* fallback sang poll (`GET {endpoint}/zalo-qr/status`) nếu `EventSource`
|
|
853
|
+
* không tồn tại hoặc báo lỗi kéo dài — cùng triết lý "luôn có phương án dự
|
|
854
|
+
* phòng" mà `transport.ts` áp dụng (sendBeacon → fetch).
|
|
855
|
+
*
|
|
856
|
+
* Làm mới QR hết hạn: `session.retry()` — tự huỷ phiên hiện tại (an toàn dù đã
|
|
857
|
+
* hết hạn/bị từ chối/thành công từ trước) rồi tạo phiên MỚI với cùng host/options
|
|
858
|
+
* ban đầu, trả về `ZaloQrLoginSession` mới để host render lại QR + await `result`
|
|
859
|
+
* mới. Không cần tự lưu lại `host`/`opts` hay gọi lại `loginWithZalo()` thủ công.
|
|
860
|
+
* ============================================================================
|
|
861
|
+
*/
|
|
862
|
+
|
|
863
|
+
/** Phần SDK `loginWithZalo()` cần từ runtime — tách nhỏ để test không phải mock cả module runtime. */
|
|
864
|
+
interface ZaloQrLoginHost {
|
|
865
|
+
readonly projectId: string | null;
|
|
866
|
+
readonly endpoint: string | null;
|
|
867
|
+
readonly zaloQrLoginEnabled: boolean;
|
|
868
|
+
readonly consentGranted: boolean;
|
|
869
|
+
/**
|
|
870
|
+
* Nguồn đưa khách tới lần đầu, ĐÃ ở dạng wire (`utm_*`) — xem `core/attribution.ts`. `null` khi
|
|
871
|
+
* chưa ghi được tín hiệu nào.
|
|
872
|
+
*
|
|
873
|
+
* Host trả về bản đã ánh xạ, KHÔNG phải `FirstTouch` thô, là cố ý: việc ánh xạ còn phải gác
|
|
874
|
+
* `allowAdTracking` (không gửi click-id khi shop tắt) và chỉ `runtime` biết cấu hình đó. Để
|
|
875
|
+
* zaloQrLogin tự gọi `toAttributionWire` là mở ra một chỗ thứ hai có thể quên mất cái gác.
|
|
876
|
+
*/
|
|
877
|
+
getAttribution?(): ContextFirstTouch | null;
|
|
878
|
+
/** anonymousId (`_cnv_cid`) — để server nối phiên QR này với hành vi ẩn danh trước đó. */
|
|
879
|
+
getAnonymousId?(): string;
|
|
880
|
+
getSessionId?(): string;
|
|
881
|
+
}
|
|
882
|
+
/** Lỗi nghiệp vụ của `loginWithZalo()` — xem {@link ZaloQrLoginErrorReason} cho phạm vi reject của từng reason. */
|
|
883
|
+
declare class ZaloQrLoginError extends Error {
|
|
884
|
+
readonly reason: ZaloQrLoginErrorReason;
|
|
885
|
+
constructor(reason: ZaloQrLoginErrorReason);
|
|
886
|
+
}
|
|
887
|
+
|
|
769
888
|
/**
|
|
770
889
|
* ============================================================================
|
|
771
890
|
* queue — Queue Processor (Sub-task 3.5)
|
|
@@ -865,49 +984,15 @@ interface Runtime extends Dispatcher {
|
|
|
865
984
|
isZaloQrLoginEnabled(): boolean;
|
|
866
985
|
/** `true` khi cả `analytics` và `marketing` đều được đồng ý — ngưỡng `loginWithZalo()` yêu cầu vì thu thập SĐT. */
|
|
867
986
|
readonly consentGranted: boolean;
|
|
987
|
+
/**
|
|
988
|
+
* Host cho `loginWithZalo()` (nội bộ) — MỘT chỗ dựng cho cả Panel lẫn wrapper public ở `index.ts`, kèm
|
|
989
|
+
* đủ 3 getter nguồn khách + định danh ẩn danh.
|
|
990
|
+
*/
|
|
991
|
+
zaloQrLoginHost(): ZaloQrLoginHost;
|
|
868
992
|
/** Tear down timers + listeners. Test-only in production. */
|
|
869
993
|
destroy(): void;
|
|
870
994
|
}
|
|
871
995
|
|
|
872
|
-
/**
|
|
873
|
-
* ============================================================================
|
|
874
|
-
* zaloQrLogin — đăng nhập bằng Zalo qua QR cho website nhúng SDK
|
|
875
|
-
* ============================================================================
|
|
876
|
-
*
|
|
877
|
-
* `loginWithZalo()` là API ĐẦU TIÊN của SDK không theo hợp đồng "never throw,
|
|
878
|
-
* fire-and-forget" của các method khác (track/identify/...) — nó trả Promise
|
|
879
|
-
* thật, và có THỂ REJECT Ở 2 ĐIỂM khác nhau (xem `ZaloQrLoginErrorReason` ở
|
|
880
|
-
* types.ts để biết chi tiết từng reason):
|
|
881
|
-
* 1. Lời gọi `loginWithZalo()` chính nó — lỗi thiết lập phiên (chưa init,
|
|
882
|
-
* dashboard tắt, thiếu consent, lỗi mạng khi tạo phiên).
|
|
883
|
-
* 2. `session.result` — lỗi xảy ra SAU khi đã có phiên/đã hiển thị QR
|
|
884
|
-
* (hết hạn, bị từ chối, bị huỷ).
|
|
885
|
-
* Consumer cần bọc try/catch quanh CẢ HAI điểm await. Vì cần tương tác 2
|
|
886
|
-
* chiều thực sự (đăng ký phiên → chờ QR được quét), hàm này KHÔNG đi qua
|
|
887
|
-
* queue protocol `window.cnvQ` — chỉ dùng được qua ES-module import.
|
|
888
|
-
*
|
|
889
|
-
* SDK không tự vẽ QR: trả `qrPayload` (deep-link Mini App) để host page tự
|
|
890
|
-
* render `<img>`/canvas, đúng vai trò "tracker" chứ không phải "auth widget"
|
|
891
|
-
* (xem cách `demo/index.html` tự vẽ modal login cho `identify()`).
|
|
892
|
-
*
|
|
893
|
-
* Kênh nhận kết quả: SSE (`GET {endpoint}/zalo-qr/stream`) làm chính, tự
|
|
894
|
-
* fallback sang poll (`GET {endpoint}/zalo-qr/status`) nếu `EventSource`
|
|
895
|
-
* không tồn tại hoặc báo lỗi kéo dài — cùng triết lý "luôn có phương án dự
|
|
896
|
-
* phòng" mà `transport.ts` áp dụng (sendBeacon → fetch).
|
|
897
|
-
*
|
|
898
|
-
* Làm mới QR hết hạn: `session.retry()` — tự huỷ phiên hiện tại (an toàn dù đã
|
|
899
|
-
* hết hạn/bị từ chối/thành công từ trước) rồi tạo phiên MỚI với cùng host/options
|
|
900
|
-
* ban đầu, trả về `ZaloQrLoginSession` mới để host render lại QR + await `result`
|
|
901
|
-
* mới. Không cần tự lưu lại `host`/`opts` hay gọi lại `loginWithZalo()` thủ công.
|
|
902
|
-
* ============================================================================
|
|
903
|
-
*/
|
|
904
|
-
|
|
905
|
-
/** Lỗi nghiệp vụ của `loginWithZalo()` — xem {@link ZaloQrLoginErrorReason} cho phạm vi reject của từng reason. */
|
|
906
|
-
declare class ZaloQrLoginError extends Error {
|
|
907
|
-
readonly reason: ZaloQrLoginErrorReason;
|
|
908
|
-
constructor(reason: ZaloQrLoginErrorReason);
|
|
909
|
-
}
|
|
910
|
-
|
|
911
996
|
/**
|
|
912
997
|
* ============================================================================
|
|
913
998
|
* cnv-track.js — public entry point
|
|
@@ -979,4 +1064,4 @@ declare const cnvTrack: Runtime & {
|
|
|
979
1064
|
};
|
|
980
1065
|
|
|
981
1066
|
export { NAME, SCHEMA_VERSION, VERSION, ZaloQrLoginError, cnvTrack as default, loginWithZalo };
|
|
982
|
-
export type { AutotrackOptions, ButtonTrackingOptions, CaptureSpec, ClickEventSpec, ClickMatch, ClickRule, ContextCampaign, ContextConsent, ContextLibrary, ContextPage, ContextScreen, DataAttrMatch, DestinationMatch, JSONValue, MessageType, PayloadContext, QueuedCommand, RemoteConfigEnvelope, RemoteConfigOptions, SDKOptions, SegmentBatchRequest, SegmentMessage, TextMatch, ThrottleSpec, UrlMatch, UserTraits, ZaloQrLoginErrorReason, ZaloQrLoginOptions, ZaloQrLoginResult, ZaloQrLoginSession };
|
|
1067
|
+
export type { AutotrackOptions, ButtonTrackingOptions, CaptureSpec, ClickEventSpec, ClickMatch, ClickRule, ContextCampaign, ContextConsent, ContextLibrary, ContextPage, ContextScreen, DataAttrMatch, DestinationMatch, JSONValue, MessageType, PayloadContext, QueuedCommand, RemoteConfigEnvelope, RemoteConfigOptions, SDKOptions, SegmentBatchRequest, SegmentMessage, TextMatch, ThrottleSpec, UrlMatch, UserTraits, ZaloQrLoginErrorReason, ZaloQrLoginOptions, ZaloQrLoginProgress, ZaloQrLoginResult, ZaloQrLoginSession, ZaloQrMiniAppKind };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cnv-vn/track",
|
|
3
|
-
"version": "0.3.0-beta.
|
|
3
|
+
"version": "0.3.0-beta.20",
|
|
4
4
|
"description": "CNV Tracking SDK — lightweight, async-first web analytics tracker (<30KB gzipped).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"analytics",
|
|
@@ -97,13 +97,13 @@
|
|
|
97
97
|
{
|
|
98
98
|
"name": "IIFE (minified + gzipped)",
|
|
99
99
|
"path": "dist/cnv-track.min.js",
|
|
100
|
-
"limit": "
|
|
100
|
+
"limit": "60 KB",
|
|
101
101
|
"gzip": true
|
|
102
102
|
},
|
|
103
103
|
{
|
|
104
104
|
"name": "ESM tree-shaken (gzipped)",
|
|
105
105
|
"path": "dist/cnv-track.esm.js",
|
|
106
|
-
"limit": "
|
|
106
|
+
"limit": "60 KB",
|
|
107
107
|
"gzip": true
|
|
108
108
|
}
|
|
109
109
|
],
|