@monetize.software/sdk-extension 3.0.0-alpha.3 → 3.0.0-alpha.4
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/LICENSE +21 -0
- package/README.md +3 -0
- package/dist/chunks/{chrome-port-DPFUj1MP.js → chrome-port-BAMwPMV0.js} +127 -113
- package/dist/chunks/chrome-port-BAMwPMV0.js.map +1 -0
- package/dist/chunks/chrome-port-CdxuZ1ND.js +2 -0
- package/dist/chunks/chrome-port-CdxuZ1ND.js.map +1 -0
- package/dist/content/RemoteAuthClient.d.ts +2 -2
- package/dist/content/RemoteAuthClient.d.ts.map +1 -1
- package/dist/content.cjs +3 -3
- package/dist/content.cjs.map +1 -1
- package/dist/content.js +118 -117
- package/dist/content.js.map +1 -1
- package/dist/offscreen/server.d.ts.map +1 -1
- package/dist/offscreen.cjs +1 -1
- package/dist/offscreen.cjs.map +1 -1
- package/dist/offscreen.js +6 -6
- package/dist/offscreen.js.map +1 -1
- package/dist/shared/messages.d.ts +5 -2
- package/dist/shared/messages.d.ts.map +1 -1
- package/package.json +35 -18
- package/dist/chunks/chrome-port-DPFUj1MP.js.map +0 -1
- package/dist/chunks/chrome-port-MoMohiHB.js +0 -2
- package/dist/chunks/chrome-port-MoMohiHB.js.map +0 -1
|
@@ -3,7 +3,7 @@ class o extends Error {
|
|
|
3
3
|
super(e), this.name = "PaywallError", this.code = t, this.status = s.status, this.cause = s.cause;
|
|
4
4
|
}
|
|
5
5
|
}
|
|
6
|
-
class
|
|
6
|
+
class q extends o {
|
|
7
7
|
constructor(t) {
|
|
8
8
|
super("not_enough_queries", t.message ?? "Not enough queries", {
|
|
9
9
|
status: 402
|
|
@@ -11,7 +11,7 @@ class N extends o {
|
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
const m = "3.0.0-alpha.0";
|
|
14
|
-
class
|
|
14
|
+
class L {
|
|
15
15
|
constructor(t) {
|
|
16
16
|
this.opts = t;
|
|
17
17
|
}
|
|
@@ -34,13 +34,13 @@ class P {
|
|
|
34
34
|
}
|
|
35
35
|
const f = (u.headers.get("content-type") ?? "").includes("application/json") ? await u.json().catch(() => null) : null;
|
|
36
36
|
if (!u.ok) {
|
|
37
|
-
const h = f && typeof f == "object" && "code" in f && String(f.code) || `http_${u.status}`,
|
|
38
|
-
throw new o(h,
|
|
37
|
+
const h = f && typeof f == "object" && "code" in f && String(f.code) || `http_${u.status}`, w = f && typeof f == "object" && "message" in f && String(f.message) || u.statusText || "Request failed";
|
|
38
|
+
throw new o(h, w, { status: u.status, cause: f });
|
|
39
39
|
}
|
|
40
40
|
return f;
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
|
-
function
|
|
43
|
+
function $() {
|
|
44
44
|
return typeof chrome < "u" && !!chrome?.storage?.local && !!chrome?.runtime?.id;
|
|
45
45
|
}
|
|
46
46
|
const x = {
|
|
@@ -73,7 +73,7 @@ const x = {
|
|
|
73
73
|
};
|
|
74
74
|
return e.addListener(s), () => e.removeListener(s);
|
|
75
75
|
}
|
|
76
|
-
},
|
|
76
|
+
}, H = {
|
|
77
77
|
async getItem(i) {
|
|
78
78
|
try {
|
|
79
79
|
return window.localStorage.getItem(i);
|
|
@@ -101,19 +101,19 @@ const x = {
|
|
|
101
101
|
};
|
|
102
102
|
return window.addEventListener("storage", e), () => window.removeEventListener("storage", e);
|
|
103
103
|
}
|
|
104
|
-
},
|
|
104
|
+
}, I = /* @__PURE__ */ new Map(), J = {
|
|
105
105
|
async getItem(i) {
|
|
106
|
-
return
|
|
106
|
+
return I.get(i) ?? null;
|
|
107
107
|
},
|
|
108
108
|
async setItem(i, t) {
|
|
109
|
-
|
|
109
|
+
I.set(i, t);
|
|
110
110
|
},
|
|
111
111
|
async removeItem(i) {
|
|
112
|
-
|
|
112
|
+
I.delete(i);
|
|
113
113
|
}
|
|
114
114
|
};
|
|
115
115
|
function R(i) {
|
|
116
|
-
return i || (
|
|
116
|
+
return i || ($() ? x : typeof window < "u" && "localStorage" in window ? H : J);
|
|
117
117
|
}
|
|
118
118
|
const y = {
|
|
119
119
|
visitorId: "pw-visitor-id",
|
|
@@ -145,7 +145,7 @@ const y = {
|
|
|
145
145
|
// (оптимистично через `decrementBalanceLocal`).
|
|
146
146
|
balances: (i, t) => `pw-${i}-${t}-balances-v1`
|
|
147
147
|
};
|
|
148
|
-
function
|
|
148
|
+
function P() {
|
|
149
149
|
const i = typeof globalThis < "u" ? globalThis.crypto : void 0;
|
|
150
150
|
if (i && typeof i.randomUUID == "function") return i.randomUUID();
|
|
151
151
|
const t = new Uint8Array(16);
|
|
@@ -157,20 +157,20 @@ function M() {
|
|
|
157
157
|
const e = Array.from(t, (s) => s.toString(16).padStart(2, "0")).join("");
|
|
158
158
|
return `${e.slice(0, 8)}-${e.slice(8, 12)}-${e.slice(12, 16)}-${e.slice(16, 20)}-${e.slice(20)}`;
|
|
159
159
|
}
|
|
160
|
-
async function
|
|
160
|
+
async function _(i) {
|
|
161
161
|
try {
|
|
162
162
|
const e = await i.getItem(y.visitorId);
|
|
163
163
|
if (e && typeof e == "string" && e.length >= 16) return e;
|
|
164
164
|
} catch {
|
|
165
165
|
}
|
|
166
|
-
const t =
|
|
166
|
+
const t = P();
|
|
167
167
|
try {
|
|
168
168
|
await i.setItem(y.visitorId, t);
|
|
169
169
|
} catch {
|
|
170
170
|
}
|
|
171
171
|
return t;
|
|
172
172
|
}
|
|
173
|
-
function
|
|
173
|
+
function D(i) {
|
|
174
174
|
const t = new Uint8Array(i), e = typeof globalThis < "u" ? globalThis.crypto : void 0;
|
|
175
175
|
if (e && typeof e.getRandomValues == "function")
|
|
176
176
|
e.getRandomValues(t);
|
|
@@ -178,30 +178,30 @@ function q(i) {
|
|
|
178
178
|
for (let s = 0; s < i; s++) t[s] = Math.floor(Math.random() * 256);
|
|
179
179
|
return t;
|
|
180
180
|
}
|
|
181
|
-
function
|
|
181
|
+
function b(i) {
|
|
182
182
|
let t = "";
|
|
183
183
|
for (let e = 0; e < i.length; e++) t += String.fromCharCode(i[e]);
|
|
184
184
|
return btoa(t).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
185
185
|
}
|
|
186
186
|
function V() {
|
|
187
|
-
return
|
|
187
|
+
return b(D(64));
|
|
188
188
|
}
|
|
189
189
|
async function j(i) {
|
|
190
190
|
const t = new TextEncoder().encode(i), e = globalThis.crypto;
|
|
191
191
|
if (!e?.subtle?.digest)
|
|
192
192
|
throw new Error("crypto.subtle is required for PKCE");
|
|
193
193
|
const s = await e.subtle.digest("SHA-256", t);
|
|
194
|
-
return
|
|
194
|
+
return b(new Uint8Array(s));
|
|
195
195
|
}
|
|
196
|
-
function
|
|
197
|
-
return
|
|
196
|
+
function G() {
|
|
197
|
+
return b(D(16));
|
|
198
198
|
}
|
|
199
|
-
const
|
|
199
|
+
const X = "https://appbox.space", z = 6e4, Q = 600 * 1e3;
|
|
200
200
|
class mt {
|
|
201
201
|
constructor(t) {
|
|
202
202
|
if (this.session = null, this.inflightRefresh = null, this.inflightAnonSignin = null, this.listeners = /* @__PURE__ */ new Set(), this.storageUnwatch = null, this.destroyed = !1, this.oauthFlows = /* @__PURE__ */ new Map(), !t.paywallId)
|
|
203
203
|
throw new o("invalid_config", "paywallId is required");
|
|
204
|
-
this.paywallId = t.paywallId, this.apiOrigin = t.apiOrigin ??
|
|
204
|
+
this.paywallId = t.paywallId, this.apiOrigin = t.apiOrigin ?? X, this.storage = R(t.storage), this.api = new L({
|
|
205
205
|
apiOrigin: this.apiOrigin,
|
|
206
206
|
paywallId: t.paywallId,
|
|
207
207
|
fetch: t.fetch
|
|
@@ -227,14 +227,15 @@ class mt {
|
|
|
227
227
|
async applyExternalSession(t) {
|
|
228
228
|
if (!this.destroyed && (await this.hydrated, !this.destroyed)) {
|
|
229
229
|
if (t == null) {
|
|
230
|
-
this.session && this.setSession(null, { skipPersist: !0 });
|
|
230
|
+
this.session && this.setSession(null, { skipPersist: !0, event: "SIGNED_OUT" });
|
|
231
231
|
return;
|
|
232
232
|
}
|
|
233
233
|
try {
|
|
234
234
|
const e = JSON.parse(t);
|
|
235
235
|
if (!e || typeof e.access_token != "string" || typeof e.refresh_token != "string" || typeof e.expires_at != "number" || !e.user)
|
|
236
236
|
return;
|
|
237
|
-
this.
|
|
237
|
+
const s = !this.session || this.session.user.id !== e.user.id ? "SIGNED_IN" : "TOKEN_REFRESHED";
|
|
238
|
+
this.setSession(e, { skipPersist: !0, event: s });
|
|
238
239
|
} catch {
|
|
239
240
|
}
|
|
240
241
|
}
|
|
@@ -291,7 +292,7 @@ class mt {
|
|
|
291
292
|
})
|
|
292
293
|
}
|
|
293
294
|
), n = this.toSession(a, a.user);
|
|
294
|
-
return this.setSession(n), n;
|
|
295
|
+
return this.setSession(n, { event: "SIGNED_IN" }), n;
|
|
295
296
|
}
|
|
296
297
|
/**
|
|
297
298
|
* Signup. Если в Supabase включён email confirm — сервер возвращает
|
|
@@ -319,7 +320,7 @@ class mt {
|
|
|
319
320
|
if (a.status === "confirmation_required")
|
|
320
321
|
return { kind: "confirmation_required", user: a.user };
|
|
321
322
|
const n = this.toSession(a, a.user);
|
|
322
|
-
return this.setSession(n), { kind: "signed_in", session: n };
|
|
323
|
+
return this.setSession(n, { event: "SIGNED_IN" }), { kind: "signed_in", session: n };
|
|
323
324
|
}
|
|
324
325
|
/**
|
|
325
326
|
* Повторная отправка confirmation-email после signUp с включённым
|
|
@@ -382,8 +383,8 @@ class mt {
|
|
|
382
383
|
user_meta: t.userMeta
|
|
383
384
|
})
|
|
384
385
|
}
|
|
385
|
-
), a = this.toSession(s, s.user);
|
|
386
|
-
return this.setSession(a), a;
|
|
386
|
+
), a = this.toSession(s, s.user), n = t.type === "recovery" ? "PASSWORD_RECOVERY" : "SIGNED_IN";
|
|
387
|
+
return this.setSession(a, { event: n }), a;
|
|
387
388
|
}
|
|
388
389
|
/**
|
|
389
390
|
* Запрос recovery email. Бэк всегда ok, чтобы не палить enumeration.
|
|
@@ -475,7 +476,7 @@ class mt {
|
|
|
475
476
|
email: s.user.email ?? null,
|
|
476
477
|
is_anonymous: !0
|
|
477
478
|
}, n = this.toSession(s, a);
|
|
478
|
-
return this.setSession(n), await this.writeAnonRefreshToken(n.refresh_token), n;
|
|
479
|
+
return this.setSession(n, { event: "SIGNED_IN" }), await this.writeAnonRefreshToken(n.refresh_token), n;
|
|
479
480
|
})();
|
|
480
481
|
try {
|
|
481
482
|
return await this.inflightAnonSignin;
|
|
@@ -497,7 +498,7 @@ class mt {
|
|
|
497
498
|
`/api/v1/paywall/${this.paywallId}/auth/refresh`,
|
|
498
499
|
{ method: "POST", body: JSON.stringify({ refresh_token: t }) }
|
|
499
500
|
), s = this.session?.user.is_anonymous === !0 ? this.session.user : { id: "", email: null, is_anonymous: !0 }, a = this.toSession(e, s);
|
|
500
|
-
return this.setSession(a), await this.writeAnonRefreshToken(a.refresh_token), a;
|
|
501
|
+
return this.setSession(a, { event: "SIGNED_IN" }), await this.writeAnonRefreshToken(a.refresh_token), a;
|
|
501
502
|
} catch (e) {
|
|
502
503
|
if (e instanceof o && e.status === 401)
|
|
503
504
|
return await this.clearAnonRefreshToken(), null;
|
|
@@ -560,7 +561,7 @@ class mt {
|
|
|
560
561
|
email: a.user.email,
|
|
561
562
|
is_anonymous: a.user.is_anonymous ?? !1
|
|
562
563
|
}, l = { ...n, user: r };
|
|
563
|
-
return this.setSession(l), await this.clearAnonRefreshToken(), { kind: "updated", session: l };
|
|
564
|
+
return this.setSession(l, { event: "USER_UPDATED" }), await this.clearAnonRefreshToken(), { kind: "updated", session: l };
|
|
564
565
|
}
|
|
565
566
|
/**
|
|
566
567
|
* OAuth signin через popup с PKCE. Жизненный цикл:
|
|
@@ -617,7 +618,7 @@ class mt {
|
|
|
617
618
|
*/
|
|
618
619
|
async startOAuthFlow(t) {
|
|
619
620
|
await this.hydrated, this.gcOAuthFlows();
|
|
620
|
-
const e = V(), s = await j(e), a =
|
|
621
|
+
const e = V(), s = await j(e), a = G(), n = {}, r = await this.getAccessToken().catch(() => null);
|
|
621
622
|
r && (n.Authorization = `Bearer ${r}`);
|
|
622
623
|
const { authorize_url: l } = await this.api.request(
|
|
623
624
|
`/api/v1/paywall/${this.paywallId}/auth/oauth/init`,
|
|
@@ -671,7 +672,7 @@ class mt {
|
|
|
671
672
|
if (this.destroyed)
|
|
672
673
|
throw new o("aborted", "AuthClient destroyed mid-flow");
|
|
673
674
|
const n = this.toSession(a, a.user);
|
|
674
|
-
return this.setSession(n), n;
|
|
675
|
+
return this.setSession(n, { event: "SIGNED_IN" }), n;
|
|
675
676
|
}
|
|
676
677
|
gcOAuthFlows() {
|
|
677
678
|
const t = Date.now() - Q;
|
|
@@ -700,10 +701,10 @@ class mt {
|
|
|
700
701
|
body: JSON.stringify({ refresh_token: t })
|
|
701
702
|
}
|
|
702
703
|
), a = this.toSession(s, e);
|
|
703
|
-
return this.setSession(a), e.is_anonymous === !0 && await this.writeAnonRefreshToken(a.refresh_token), a;
|
|
704
|
+
return this.setSession(a, { event: "TOKEN_REFRESHED" }), e.is_anonymous === !0 && await this.writeAnonRefreshToken(a.refresh_token), a;
|
|
704
705
|
} catch (s) {
|
|
705
706
|
if (s instanceof o && s.status === 401)
|
|
706
|
-
return e.is_anonymous === !0 && await this.clearAnonRefreshToken(), this.setSession(null), null;
|
|
707
|
+
return e.is_anonymous === !0 && await this.clearAnonRefreshToken(), this.setSession(null, { event: "SIGNED_OUT" }), null;
|
|
707
708
|
throw s;
|
|
708
709
|
} finally {
|
|
709
710
|
this.inflightRefresh = null;
|
|
@@ -736,7 +737,7 @@ class mt {
|
|
|
736
737
|
method: "POST",
|
|
737
738
|
headers: { Authorization: `Bearer ${t}` }
|
|
738
739
|
}
|
|
739
|
-
), this.setSession(null);
|
|
740
|
+
), this.setSession(null, { event: "SIGNED_OUT" });
|
|
740
741
|
}
|
|
741
742
|
/**
|
|
742
743
|
* Signout: чистит локальную session СРАЗУ (UX — мгновенный logout без
|
|
@@ -756,7 +757,7 @@ class mt {
|
|
|
756
757
|
async signOut(t = {}) {
|
|
757
758
|
await this.hydrated;
|
|
758
759
|
const e = this.session?.access_token, s = this.session?.user.is_anonymous === !0;
|
|
759
|
-
if (this.setSession(null), t.forgetAnonymous && await this.clearAnonRefreshToken(), !!e && !(s && !t.forgetAnonymous))
|
|
760
|
+
if (this.setSession(null, { event: "SIGNED_OUT" }), t.forgetAnonymous && await this.clearAnonRefreshToken(), !!e && !(s && !t.forgetAnonymous))
|
|
760
761
|
try {
|
|
761
762
|
await this.api.request(
|
|
762
763
|
`/api/v1/paywall/${this.paywallId}/auth/signout`,
|
|
@@ -770,22 +771,35 @@ class mt {
|
|
|
770
771
|
}
|
|
771
772
|
/**
|
|
772
773
|
* Подписка на изменения session: signin/signup/refresh/signOut/expired-401.
|
|
773
|
-
*
|
|
774
|
-
*
|
|
774
|
+
*
|
|
775
|
+
* Гарантированный контракт: ПЕРВЫЙ callback каждому subscriber'у — всегда
|
|
776
|
+
* `event = 'INITIAL_SESSION'`, дёргается асинхронно после resolve hydrate'а
|
|
777
|
+
* (даже если session=null — listener получает explicit «нет сессии», а не
|
|
778
|
+
* молчание). Все последующие callback'и — реальные переходы с конкретным
|
|
779
|
+
* event'ом (SIGNED_IN / SIGNED_OUT / TOKEN_REFRESHED / USER_UPDATED /
|
|
780
|
+
* PASSWORD_RECOVERY).
|
|
781
|
+
*
|
|
782
|
+
* Это позволяет listener'у безопасно делать «only on real signin» побочные
|
|
783
|
+
* эффекты (force refetch balances и т.п.) через `event === 'SIGNED_IN'`,
|
|
784
|
+
* не путая их с восстановлением из storage.
|
|
785
|
+
*
|
|
786
|
+
* Возвращает unsubscribe.
|
|
775
787
|
*/
|
|
776
788
|
onAuthChange(t) {
|
|
777
|
-
|
|
789
|
+
return this.listeners.add(t), this.hydrated.then(() => {
|
|
790
|
+
if (this.destroyed || !this.listeners.has(t)) return;
|
|
778
791
|
const e = this.session;
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
})
|
|
782
|
-
|
|
783
|
-
|
|
792
|
+
try {
|
|
793
|
+
t("INITIAL_SESSION", e);
|
|
794
|
+
} catch (s) {
|
|
795
|
+
console.warn("[paywall] onAuthChange INITIAL_SESSION threw", s);
|
|
796
|
+
}
|
|
797
|
+
}), () => {
|
|
784
798
|
this.listeners.delete(t);
|
|
785
799
|
};
|
|
786
800
|
}
|
|
787
801
|
isFresh(t) {
|
|
788
|
-
return t.expires_at - Date.now() >
|
|
802
|
+
return t.expires_at - Date.now() > z;
|
|
789
803
|
}
|
|
790
804
|
toSession(t, e) {
|
|
791
805
|
const s = t.expires_at != null ? t.expires_at * 1e3 : Date.now() + t.expires_in * 1e3;
|
|
@@ -796,17 +810,17 @@ class mt {
|
|
|
796
810
|
user: e
|
|
797
811
|
};
|
|
798
812
|
}
|
|
799
|
-
setSession(t, e
|
|
813
|
+
setSession(t, e) {
|
|
800
814
|
if (this.destroyed) return;
|
|
801
815
|
const s = this.session;
|
|
802
|
-
this.session = t, e.skipPersist || this.persist(), tt(s, t) || this.emit();
|
|
816
|
+
this.session = t, e.skipPersist || this.persist(), tt(s, t) || this.emit(e.event);
|
|
803
817
|
}
|
|
804
|
-
emit() {
|
|
805
|
-
for (const
|
|
818
|
+
emit(t) {
|
|
819
|
+
for (const e of this.listeners)
|
|
806
820
|
try {
|
|
807
|
-
t
|
|
808
|
-
} catch (
|
|
809
|
-
console.warn("[paywall] onAuthChange listener threw",
|
|
821
|
+
e(t, this.session);
|
|
822
|
+
} catch (s) {
|
|
823
|
+
console.warn("[paywall] onAuthChange listener threw", s);
|
|
810
824
|
}
|
|
811
825
|
}
|
|
812
826
|
storageKey() {
|
|
@@ -819,7 +833,7 @@ class mt {
|
|
|
819
833
|
const e = JSON.parse(t);
|
|
820
834
|
if (!e || typeof e.access_token != "string" || typeof e.refresh_token != "string" || typeof e.expires_at != "number" || !e.user)
|
|
821
835
|
return;
|
|
822
|
-
this.session = e
|
|
836
|
+
this.session = e;
|
|
823
837
|
} catch {
|
|
824
838
|
}
|
|
825
839
|
}
|
|
@@ -833,7 +847,7 @@ class mt {
|
|
|
833
847
|
const e = JSON.parse(t);
|
|
834
848
|
if (!e || typeof e.access_token != "string" || typeof e.refresh_token != "string" || typeof e.expires_at != "number" || !e.user)
|
|
835
849
|
return;
|
|
836
|
-
this.setSession(e, { skipPersist: !0 });
|
|
850
|
+
this.setSession(e, { skipPersist: !0, event: "SIGNED_IN" });
|
|
837
851
|
} catch {
|
|
838
852
|
}
|
|
839
853
|
}
|
|
@@ -1007,8 +1021,8 @@ class st {
|
|
|
1007
1021
|
{ status: h.status }
|
|
1008
1022
|
);
|
|
1009
1023
|
}
|
|
1010
|
-
const
|
|
1011
|
-
return this.onChargeSuccess?.(
|
|
1024
|
+
const w = h.headers.get("X-Query-Type") ?? void 0;
|
|
1025
|
+
return this.onChargeSuccess?.(w), h;
|
|
1012
1026
|
}
|
|
1013
1027
|
}
|
|
1014
1028
|
async function it(i) {
|
|
@@ -1023,7 +1037,7 @@ async function it(i) {
|
|
|
1023
1037
|
const a = e[0];
|
|
1024
1038
|
Array.isArray(a) ? s = a : a && Array.isArray(a.balances) && (s = a.balances);
|
|
1025
1039
|
}
|
|
1026
|
-
return new
|
|
1040
|
+
return new q({
|
|
1027
1041
|
balances: s,
|
|
1028
1042
|
queryType: t.details?.queryType ?? "",
|
|
1029
1043
|
currentBalance: t.details?.currentBalance ?? null
|
|
@@ -1038,12 +1052,12 @@ async function at(i) {
|
|
|
1038
1052
|
return null;
|
|
1039
1053
|
}
|
|
1040
1054
|
}
|
|
1041
|
-
const nt = 5e3, rt = 30 * 6e4,
|
|
1055
|
+
const nt = 5e3, rt = 30 * 6e4, B = 60 * 6e4, ot = 5 * 6e4, A = {
|
|
1042
1056
|
has_active_subscription: !1,
|
|
1043
1057
|
purchases: [],
|
|
1044
1058
|
trial: null
|
|
1045
1059
|
};
|
|
1046
|
-
function
|
|
1060
|
+
function k(i) {
|
|
1047
1061
|
return i && (i.email || i.userId || i.anonymousId) || "guest";
|
|
1048
1062
|
}
|
|
1049
1063
|
function ct(i, t) {
|
|
@@ -1058,7 +1072,7 @@ function ut(i, t) {
|
|
|
1058
1072
|
return !0;
|
|
1059
1073
|
}
|
|
1060
1074
|
const dt = "https://appbox.space";
|
|
1061
|
-
class
|
|
1075
|
+
class It {
|
|
1062
1076
|
constructor(t) {
|
|
1063
1077
|
if (this.cachedBootstrap = null, this.cachedBootstrapAt = 0, this.inflightBootstrap = null, this.bootstrapListeners = /* @__PURE__ */ new Set(), this.bootstrapStorageUnwatch = null, this.authUnsubscribe = null, this.cachedUser = null, this.cachedUserAt = 0, this.inflightUser = null, this.userListeners = /* @__PURE__ */ new Set(), this.visitorIdPromise = null, this.visitorId = null, this.inflightCheckouts = /* @__PURE__ */ new Map(), this.cachedBalances = null, this.cachedBalancesAt = 0, this.balancesStorageUnwatch = null, this.inflightBalances = null, this.balanceListeners = /* @__PURE__ */ new Set(), this.previewVersionCounter = 0, !t.paywallId)
|
|
1064
1078
|
throw new o("invalid_config", "paywallId is required");
|
|
@@ -1066,7 +1080,7 @@ class bt {
|
|
|
1066
1080
|
const e = t.auth?.getCachedUser();
|
|
1067
1081
|
this.identity = t.identity ?? (e ? U(e) : void 0), this.apiKey = t.apiKey, this.fetchImpl = t.fetch, t.apiKey && typeof window < "u" && typeof window.document < "u" && console.error(
|
|
1068
1082
|
"[paywall] SECURITY: BillingClient.apiKey detected in browser context. This is a server-SDK key and exposes your account. Remove apiKey or move BillingClient to a trusted backend."
|
|
1069
|
-
), this.storage = R(t.storage), this.api = new
|
|
1083
|
+
), this.storage = R(t.storage), this.api = new L({
|
|
1070
1084
|
apiOrigin: this.apiOrigin,
|
|
1071
1085
|
paywallId: t.paywallId,
|
|
1072
1086
|
capabilities: t.capabilities,
|
|
@@ -1075,10 +1089,10 @@ class bt {
|
|
|
1075
1089
|
// делает lazy refresh, дедупит, на 401 возвращает null — тогда
|
|
1076
1090
|
// Authorization-хедер просто не выставится.
|
|
1077
1091
|
getAuthToken: t.auth ? () => t.auth.getAccessToken() : void 0
|
|
1078
|
-
}), t.auth && (this.authUnsubscribe = t.auth.onAuthChange((s) => {
|
|
1079
|
-
const
|
|
1080
|
-
ft(this.identity,
|
|
1081
|
-
})), this.hydrateUserFromStorage(), this.hydrateBootstrapFromStorage(), this.subscribeBootstrapStorage(), this.hydrateBalancesFromStorage(), this.subscribeBalancesStorage(), this.visitorIdPromise =
|
|
1092
|
+
}), t.auth && (this.authUnsubscribe = t.auth.onAuthChange((s, a) => {
|
|
1093
|
+
const n = a ? U(a.user) : void 0;
|
|
1094
|
+
ft(this.identity, n) || this.setIdentity(n);
|
|
1095
|
+
})), this.hydrateUserFromStorage(), this.hydrateBootstrapFromStorage(), this.subscribeBootstrapStorage(), this.hydrateBalancesFromStorage(), this.subscribeBalancesStorage(), this.visitorIdPromise = _(this.storage).then((s) => (this.visitorId = s, s));
|
|
1082
1096
|
}
|
|
1083
1097
|
/**
|
|
1084
1098
|
* Stable visitor_id (UUID v4). Первый вызов awaitит первичный резолв из
|
|
@@ -1086,7 +1100,7 @@ class bt {
|
|
|
1086
1100
|
* EventTracker'ом для атрибуции аналитики.
|
|
1087
1101
|
*/
|
|
1088
1102
|
async getVisitorId() {
|
|
1089
|
-
return this.visitorId ? this.visitorId : (this.visitorIdPromise || (this.visitorIdPromise =
|
|
1103
|
+
return this.visitorId ? this.visitorId : (this.visitorIdPromise || (this.visitorIdPromise = _(this.storage).then((t) => (this.visitorId = t, t))), this.visitorIdPromise);
|
|
1090
1104
|
}
|
|
1091
1105
|
/** Sync-доступ к visitor_id. null если ещё не зарезолвили (первые ms жизни). */
|
|
1092
1106
|
getCachedVisitorId() {
|
|
@@ -1122,9 +1136,9 @@ class bt {
|
|
|
1122
1136
|
"BillingClient in preview mode but cachedBootstrap is not seeded. Call setBootstrap(bootstrap) before open()."
|
|
1123
1137
|
);
|
|
1124
1138
|
}
|
|
1125
|
-
const s = Date.now(), a = this.cachedBootstrap && this.cachedBootstrapAt > 0 && s - this.cachedBootstrapAt <
|
|
1139
|
+
const s = Date.now(), a = this.cachedBootstrap && this.cachedBootstrapAt > 0 && s - this.cachedBootstrapAt < B;
|
|
1126
1140
|
return !e.force && a ? (s - this.cachedBootstrapAt > ot && this.revalidateBootstrap(e.signal).catch(() => {
|
|
1127
|
-
}), this.cachedBootstrap) : this.inflightBootstrap ? this.inflightBootstrap : (this.inflightBootstrap = this.fetchBootstrap({
|
|
1141
|
+
}), { ...this.cachedBootstrap, user: this.cachedUser ?? void 0 }) : this.inflightBootstrap ? this.inflightBootstrap : (this.inflightBootstrap = this.fetchBootstrap({
|
|
1128
1142
|
ifVersion: e.force ? void 0 : this.cachedBootstrap?.version,
|
|
1129
1143
|
signal: e.signal
|
|
1130
1144
|
}).finally(() => {
|
|
@@ -1172,7 +1186,7 @@ class bt {
|
|
|
1172
1186
|
offers: t.offers !== void 0 ? t.offers : e.offers,
|
|
1173
1187
|
version: `preview:${++this.previewVersionCounter}`
|
|
1174
1188
|
};
|
|
1175
|
-
s.layout || (s.layout = O(s.settings, s.prices)),
|
|
1189
|
+
s.layout || (s.layout = O(s.settings, s.prices)), g(s), this.cachedBootstrap = s, this.cachedBootstrapAt = Date.now();
|
|
1176
1190
|
for (const a of this.bootstrapListeners)
|
|
1177
1191
|
try {
|
|
1178
1192
|
a(s);
|
|
@@ -1194,7 +1208,7 @@ class bt {
|
|
|
1194
1208
|
if ("unchanged" in a && a.unchanged)
|
|
1195
1209
|
return this.cachedBootstrap ? (this.cachedBootstrapAt = Date.now(), a.user && this.applyUser(a.user), this.cachedBootstrap) : this.fetchBootstrap({ signal: t.signal });
|
|
1196
1210
|
const n = a;
|
|
1197
|
-
return n.layout || (n.layout = O(n.settings, n.prices)),
|
|
1211
|
+
return n.layout || (n.layout = O(n.settings, n.prices)), g(n), this.applyBootstrap(n, { persist: !0 }), n.user && this.applyUser(n.user), n;
|
|
1198
1212
|
}
|
|
1199
1213
|
// Фоновый revalidate из stale-while-revalidate ветки. Дедуплицируется через
|
|
1200
1214
|
// `inflightBootstrap`, чтобы параллельные revalidate'ы не пересекались.
|
|
@@ -1227,8 +1241,8 @@ class bt {
|
|
|
1227
1241
|
const t = await this.storage.getItem(y.bootstrap(this.paywallId));
|
|
1228
1242
|
if (!t) return;
|
|
1229
1243
|
const e = JSON.parse(t);
|
|
1230
|
-
if (!e?.bootstrap || Date.now() - e.at >
|
|
1231
|
-
|
|
1244
|
+
if (!e?.bootstrap || Date.now() - e.at > B || this.cachedBootstrap) return;
|
|
1245
|
+
g(e.bootstrap), this.cachedBootstrap = e.bootstrap, this.cachedBootstrapAt = e.at;
|
|
1232
1246
|
for (const s of this.bootstrapListeners)
|
|
1233
1247
|
try {
|
|
1234
1248
|
s(e.bootstrap);
|
|
@@ -1264,7 +1278,7 @@ class bt {
|
|
|
1264
1278
|
this.cachedBootstrapAt = e.at;
|
|
1265
1279
|
return;
|
|
1266
1280
|
}
|
|
1267
|
-
|
|
1281
|
+
g(e.bootstrap), this.applyBootstrap(e.bootstrap, { persist: !1 });
|
|
1268
1282
|
} catch {
|
|
1269
1283
|
}
|
|
1270
1284
|
}
|
|
@@ -1311,7 +1325,7 @@ class bt {
|
|
|
1311
1325
|
* есть `navigator.language`.
|
|
1312
1326
|
*/
|
|
1313
1327
|
getUserLanguage() {
|
|
1314
|
-
const t = typeof navigator < "u" && navigator.language ? navigator.language : null, e = this.cachedBootstrap?.settings.locale_default ?? null, s = this.cachedBootstrap ?
|
|
1328
|
+
const t = typeof navigator < "u" && navigator.language ? navigator.language : null, e = this.cachedBootstrap?.settings.locale_default ?? null, s = this.cachedBootstrap ? M(this.cachedBootstrap) : null;
|
|
1315
1329
|
return { tag: s ?? t ?? e, applied: s, browserLanguage: t, countryLanguage: e };
|
|
1316
1330
|
}
|
|
1317
1331
|
/**
|
|
@@ -1326,7 +1340,7 @@ class bt {
|
|
|
1326
1340
|
return !t && this.cachedUser && Date.now() - this.cachedUserAt < nt ? this.cachedUser : this.inflightUser ? this.inflightUser : (this.inflightUser = (async () => {
|
|
1327
1341
|
try {
|
|
1328
1342
|
if (!this.identity?.email)
|
|
1329
|
-
return this.applyUser(
|
|
1343
|
+
return this.applyUser(A), A;
|
|
1330
1344
|
const s = await this.api.request(
|
|
1331
1345
|
`/api/v1/paywall/${this.paywallId}/user-state`,
|
|
1332
1346
|
{ headers: { "X-User-Email": this.identity.email }, signal: e }
|
|
@@ -1391,7 +1405,7 @@ class bt {
|
|
|
1391
1405
|
}
|
|
1392
1406
|
}
|
|
1393
1407
|
storageKey() {
|
|
1394
|
-
return y.userState(this.paywallId,
|
|
1408
|
+
return y.userState(this.paywallId, k(this.identity));
|
|
1395
1409
|
}
|
|
1396
1410
|
async hydrateUserFromStorage() {
|
|
1397
1411
|
if (!this.cachedUser)
|
|
@@ -1546,7 +1560,7 @@ class bt {
|
|
|
1546
1560
|
}
|
|
1547
1561
|
}
|
|
1548
1562
|
balancesStorageKey() {
|
|
1549
|
-
return y.balances(this.paywallId,
|
|
1563
|
+
return y.balances(this.paywallId, k(this.identity));
|
|
1550
1564
|
}
|
|
1551
1565
|
async hydrateBalancesFromStorage() {
|
|
1552
1566
|
if (!this.cachedBalances)
|
|
@@ -1600,7 +1614,7 @@ class bt {
|
|
|
1600
1614
|
const e = t.idempotencyKey ?? `auto:${t.priceId}`, s = this.inflightCheckouts.get(e);
|
|
1601
1615
|
if (s) return s;
|
|
1602
1616
|
const n = {
|
|
1603
|
-
"Idempotency-Key": t.idempotencyKey ??
|
|
1617
|
+
"Idempotency-Key": t.idempotencyKey ?? P()
|
|
1604
1618
|
};
|
|
1605
1619
|
this.apiKey && (n["X-Api-Key"] = this.apiKey);
|
|
1606
1620
|
const r = this.cachedBootstrap?.settings, l = t.successUrl ?? r?.success_redirect_url ?? void 0, u = t.shopUrl ?? r?.checkout_shop_url ?? void 0, d = this.api.request(`/api/v1/paywall/${this.paywallId}/start-checkout`, {
|
|
@@ -1760,7 +1774,7 @@ function O(i, t) {
|
|
|
1760
1774
|
]
|
|
1761
1775
|
};
|
|
1762
1776
|
}
|
|
1763
|
-
function
|
|
1777
|
+
function M(i) {
|
|
1764
1778
|
const t = i.locales;
|
|
1765
1779
|
if (!t) return null;
|
|
1766
1780
|
const e = [];
|
|
@@ -1775,8 +1789,8 @@ function $(i) {
|
|
|
1775
1789
|
if (a && Object.prototype.hasOwnProperty.call(t, a)) return a;
|
|
1776
1790
|
return null;
|
|
1777
1791
|
}
|
|
1778
|
-
function
|
|
1779
|
-
const t =
|
|
1792
|
+
function g(i) {
|
|
1793
|
+
const t = M(i);
|
|
1780
1794
|
if (!t) return;
|
|
1781
1795
|
const e = i.locales?.[t];
|
|
1782
1796
|
e && (e.layout && (i.layout = e.layout), e.prices && (i.prices = i.prices.map((s) => {
|
|
@@ -1786,8 +1800,8 @@ function w(i) {
|
|
|
1786
1800
|
return "label" in a && (n.label = a.label ?? null), "description" in a && (n.description = a.description ?? null), n;
|
|
1787
1801
|
})));
|
|
1788
1802
|
}
|
|
1789
|
-
const yt = 1500, pt = 20,
|
|
1790
|
-
class
|
|
1803
|
+
const yt = 1500, pt = 20, E = 200;
|
|
1804
|
+
class St {
|
|
1791
1805
|
constructor(t) {
|
|
1792
1806
|
this.buffer = [], this.flushTimer = null, this.destroyed = !1, this.unloadHandler = null, this.visibilityHandler = null, this.opts = t, this.isEnabled() && this.attachUnloadHandlers();
|
|
1793
1807
|
}
|
|
@@ -1802,7 +1816,7 @@ class vt {
|
|
|
1802
1816
|
this.flush();
|
|
1803
1817
|
return;
|
|
1804
1818
|
}
|
|
1805
|
-
this.buffer.length >
|
|
1819
|
+
this.buffer.length > E && (this.buffer = this.buffer.slice(-E)), this.scheduleFlush();
|
|
1806
1820
|
}
|
|
1807
1821
|
scheduleFlush() {
|
|
1808
1822
|
if (this.flushTimer || this.destroyed) return;
|
|
@@ -1885,11 +1899,11 @@ class vt {
|
|
|
1885
1899
|
this.destroyed || (this.destroyed = !0, this.flushTimer && (clearTimeout(this.flushTimer), this.flushTimer = null), this.flush(), this.detachUnloadHandlers());
|
|
1886
1900
|
}
|
|
1887
1901
|
}
|
|
1888
|
-
const
|
|
1889
|
-
function
|
|
1902
|
+
const C = 3600 * 1e3;
|
|
1903
|
+
function S(i) {
|
|
1890
1904
|
return `paywall-${i}-trial-time-first-open`;
|
|
1891
1905
|
}
|
|
1892
|
-
function
|
|
1906
|
+
function v(i) {
|
|
1893
1907
|
return `paywall-${i}-skip-times`;
|
|
1894
1908
|
}
|
|
1895
1909
|
class F {
|
|
@@ -1903,10 +1917,10 @@ class F {
|
|
|
1903
1917
|
return this.config.mode === "time" ? this.recordTime() : this.recordOpens();
|
|
1904
1918
|
}
|
|
1905
1919
|
async reset() {
|
|
1906
|
-
await this.storage.removeItem(this.config.mode === "time" ?
|
|
1920
|
+
await this.storage.removeItem(this.config.mode === "time" ? S(this.paywallId) : v(this.paywallId));
|
|
1907
1921
|
}
|
|
1908
1922
|
async checkTime() {
|
|
1909
|
-
const t = this.config.payload *
|
|
1923
|
+
const t = this.config.payload * C, e = await this.storage.getItem(S(this.paywallId)), s = e ? Number(e) : null;
|
|
1910
1924
|
if (!s || !Number.isFinite(s))
|
|
1911
1925
|
return {
|
|
1912
1926
|
mode: "time",
|
|
@@ -1927,7 +1941,7 @@ class F {
|
|
|
1927
1941
|
};
|
|
1928
1942
|
}
|
|
1929
1943
|
async checkOpens() {
|
|
1930
|
-
const t = this.config.payload, e = await this.storage.getItem(
|
|
1944
|
+
const t = this.config.payload, e = await this.storage.getItem(v(this.paywallId)), s = e ? Number(e) : 0, a = Number.isFinite(s) ? s : 0, n = a < t, r = Math.max(0, t - a);
|
|
1931
1945
|
return {
|
|
1932
1946
|
mode: "opens",
|
|
1933
1947
|
blocked: n,
|
|
@@ -1936,7 +1950,7 @@ class F {
|
|
|
1936
1950
|
};
|
|
1937
1951
|
}
|
|
1938
1952
|
async recordTime() {
|
|
1939
|
-
const t = this.config.payload *
|
|
1953
|
+
const t = this.config.payload * C, e = S(this.paywallId), s = await this.storage.getItem(e);
|
|
1940
1954
|
let a = s ? Number(s) : null;
|
|
1941
1955
|
(!a || !Number.isFinite(a)) && (a = Date.now(), await this.storage.setItem(e, String(a)));
|
|
1942
1956
|
const n = a + t, r = Math.max(0, n - Date.now());
|
|
@@ -1950,7 +1964,7 @@ class F {
|
|
|
1950
1964
|
};
|
|
1951
1965
|
}
|
|
1952
1966
|
async recordOpens() {
|
|
1953
|
-
const t = this.config.payload, e =
|
|
1967
|
+
const t = this.config.payload, e = v(this.paywallId), s = await this.storage.getItem(e), a = s ? Number(s) : 0, n = Number.isFinite(a) ? a : 0, r = Math.min(t, n + 1);
|
|
1954
1968
|
await this.storage.setItem(e, String(r));
|
|
1955
1969
|
const l = Math.max(0, t - r);
|
|
1956
1970
|
return {
|
|
@@ -1961,10 +1975,10 @@ class F {
|
|
|
1961
1975
|
};
|
|
1962
1976
|
}
|
|
1963
1977
|
}
|
|
1964
|
-
let
|
|
1965
|
-
class
|
|
1978
|
+
let N = !1;
|
|
1979
|
+
class wt {
|
|
1966
1980
|
constructor(t, e, s) {
|
|
1967
|
-
|
|
1981
|
+
N || (N = !0, console.warn(
|
|
1968
1982
|
'[paywall] trial.storage="server" is not implemented yet — falling back to client storage. State lives in localStorage; users can reset trial by clearing site data.'
|
|
1969
1983
|
)), this.fallback = new F(t, e, s);
|
|
1970
1984
|
}
|
|
@@ -1978,11 +1992,11 @@ class gt {
|
|
|
1978
1992
|
return this.fallback.reset();
|
|
1979
1993
|
}
|
|
1980
1994
|
}
|
|
1981
|
-
function
|
|
1982
|
-
return e.storage === "server" ? new
|
|
1995
|
+
function vt(i, t, e) {
|
|
1996
|
+
return e.storage === "server" ? new wt(i, t, e) : new F(i, t, e);
|
|
1983
1997
|
}
|
|
1984
|
-
const
|
|
1985
|
-
function
|
|
1998
|
+
const bt = 1;
|
|
1999
|
+
function _t(i) {
|
|
1986
2000
|
return i instanceof o ? {
|
|
1987
2001
|
name: "PaywallError",
|
|
1988
2002
|
code: i.code,
|
|
@@ -2000,7 +2014,7 @@ function Bt(i) {
|
|
|
2000
2014
|
message: typeof i == "string" ? i : "Unknown error"
|
|
2001
2015
|
};
|
|
2002
2016
|
}
|
|
2003
|
-
function
|
|
2017
|
+
function Bt(i) {
|
|
2004
2018
|
if (i.name === "PaywallError") {
|
|
2005
2019
|
const e = new o(i.code, i.message, { status: i.status });
|
|
2006
2020
|
return i.stack && (e.stack = i.stack), e;
|
|
@@ -2008,7 +2022,7 @@ function _t(i) {
|
|
|
2008
2022
|
const t = new Error(i.message);
|
|
2009
2023
|
return t.name = i.name, i.stack && (t.stack = i.stack), t;
|
|
2010
2024
|
}
|
|
2011
|
-
function
|
|
2025
|
+
function gt(i) {
|
|
2012
2026
|
let t = !1;
|
|
2013
2027
|
const e = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Set(), a = (r) => {
|
|
2014
2028
|
for (const l of e) l(r);
|
|
@@ -2040,21 +2054,21 @@ function wt(i) {
|
|
|
2040
2054
|
}
|
|
2041
2055
|
};
|
|
2042
2056
|
}
|
|
2043
|
-
function
|
|
2057
|
+
function At(i) {
|
|
2044
2058
|
const t = chrome.runtime.connect({ name: i });
|
|
2045
|
-
return
|
|
2059
|
+
return gt(t);
|
|
2046
2060
|
}
|
|
2047
2061
|
export {
|
|
2048
2062
|
mt as A,
|
|
2049
|
-
|
|
2050
|
-
|
|
2063
|
+
It as B,
|
|
2064
|
+
St as E,
|
|
2051
2065
|
o as P,
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2066
|
+
bt as a,
|
|
2067
|
+
At as b,
|
|
2068
|
+
vt as c,
|
|
2069
|
+
gt as p,
|
|
2070
|
+
Bt as r,
|
|
2071
|
+
_t as s,
|
|
2058
2072
|
Z as w
|
|
2059
2073
|
};
|
|
2060
|
-
//# sourceMappingURL=chrome-port-
|
|
2074
|
+
//# sourceMappingURL=chrome-port-BAMwPMV0.js.map
|