@shware/purchase 1.8.8 → 1.9.0
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/_virtual/_rolldown/runtime.cjs +23 -0
- package/dist/app-store/config.cjs +98 -128
- package/dist/app-store/config.cjs.map +1 -1
- package/dist/app-store/config.d.cts +31 -31
- package/dist/app-store/config.d.cts.map +1 -0
- package/dist/app-store/config.d.mts +39 -0
- package/dist/app-store/config.d.mts.map +1 -0
- package/dist/app-store/config.mjs +93 -91
- package/dist/app-store/config.mjs.map +1 -1
- package/dist/app-store/index.cjs +3 -31
- package/dist/app-store/index.d.cts +2 -3
- package/dist/app-store/index.d.mts +2 -0
- package/dist/app-store/index.mjs +1 -5
- package/dist/google-play/config.cjs +100 -123
- package/dist/google-play/config.cjs.map +1 -1
- package/dist/google-play/config.d.cts +31 -31
- package/dist/google-play/config.d.cts.map +1 -0
- package/dist/google-play/config.d.mts +39 -0
- package/dist/google-play/config.d.mts.map +1 -0
- package/dist/google-play/config.mjs +95 -86
- package/dist/google-play/config.mjs.map +1 -1
- package/dist/google-play/index.cjs +9 -42
- package/dist/google-play/index.d.cts +3 -4
- package/dist/google-play/index.d.mts +3 -0
- package/dist/google-play/index.mjs +2 -17
- package/dist/google-play/real-time-developer-notification.cjs +122 -81
- package/dist/google-play/real-time-developer-notification.cjs.map +1 -1
- package/dist/google-play/real-time-developer-notification.d.cts +119 -117
- package/dist/google-play/real-time-developer-notification.d.cts.map +1 -0
- package/dist/google-play/real-time-developer-notification.d.mts +150 -0
- package/dist/google-play/real-time-developer-notification.d.mts.map +1 -0
- package/dist/google-play/real-time-developer-notification.mjs +118 -53
- package/dist/google-play/real-time-developer-notification.mjs.map +1 -1
- package/dist/index.cjs +13 -48
- package/dist/index.d.cts +5 -6
- package/dist/index.d.mts +5 -0
- package/dist/index.mjs +2 -19
- package/dist/stripe/config.cjs +104 -133
- package/dist/stripe/config.cjs.map +1 -1
- package/dist/stripe/config.d.cts +35 -35
- package/dist/stripe/config.d.cts.map +1 -0
- package/dist/stripe/config.d.mts +43 -0
- package/dist/stripe/config.d.mts.map +1 -0
- package/dist/stripe/config.mjs +99 -96
- package/dist/stripe/config.mjs.map +1 -1
- package/dist/stripe/handler.cjs +25 -53
- package/dist/stripe/handler.cjs.map +1 -1
- package/dist/stripe/handler.d.cts +10 -9
- package/dist/stripe/handler.d.cts.map +1 -0
- package/dist/stripe/handler.d.mts +16 -0
- package/dist/stripe/handler.d.mts.map +1 -0
- package/dist/stripe/handler.mjs +25 -29
- package/dist/stripe/handler.mjs.map +1 -1
- package/dist/stripe/index.cjs +27 -74
- package/dist/stripe/index.d.cts +8 -12
- package/dist/stripe/index.d.mts +8 -0
- package/dist/stripe/index.mjs +5 -44
- package/dist/stripe/mapper.cjs +168 -218
- package/dist/stripe/mapper.cjs.map +1 -1
- package/dist/stripe/mapper.d.cts +115 -114
- package/dist/stripe/mapper.d.cts.map +1 -0
- package/dist/stripe/mapper.d.mts +158 -0
- package/dist/stripe/mapper.d.mts.map +1 -0
- package/dist/stripe/mapper.mjs +155 -181
- package/dist/stripe/mapper.mjs.map +1 -1
- package/dist/stripe/metadata.cjs +11 -35
- package/dist/stripe/metadata.cjs.map +1 -1
- package/dist/stripe/metadata.d.cts +9 -7
- package/dist/stripe/metadata.d.cts.map +1 -0
- package/dist/stripe/metadata.d.mts +12 -0
- package/dist/stripe/metadata.d.mts.map +1 -0
- package/dist/stripe/metadata.mjs +11 -11
- package/dist/stripe/metadata.mjs.map +1 -1
- package/dist/stripe/pending-checkout.cjs +55 -61
- package/dist/stripe/pending-checkout.cjs.map +1 -1
- package/dist/stripe/pending-checkout.d.cts +3 -1
- package/dist/stripe/pending-checkout.d.cts.map +1 -0
- package/dist/stripe/{pending-checkout.d.ts → pending-checkout.d.mts} +3 -1
- package/dist/stripe/pending-checkout.d.mts.map +1 -0
- package/dist/stripe/pending-checkout.mjs +52 -34
- package/dist/stripe/pending-checkout.mjs.map +1 -1
- package/dist/stripe/schema.cjs +30 -55
- package/dist/stripe/schema.cjs.map +1 -1
- package/dist/stripe/schema.d.cts +36 -37
- package/dist/stripe/schema.d.cts.map +1 -0
- package/dist/stripe/schema.d.mts +40 -0
- package/dist/stripe/schema.d.mts.map +1 -0
- package/dist/stripe/schema.mjs +28 -40
- package/dist/stripe/schema.mjs.map +1 -1
- package/dist/subscription/index.cjs +178 -80
- package/dist/subscription/index.cjs.map +1 -1
- package/dist/subscription/index.d.cts +136 -134
- package/dist/subscription/index.d.cts.map +1 -0
- package/dist/subscription/index.d.mts +150 -0
- package/dist/subscription/index.d.mts.map +1 -0
- package/dist/subscription/index.mjs +173 -51
- package/dist/subscription/index.mjs.map +1 -1
- package/dist/types.cjs +0 -19
- package/dist/types.d.cts +7 -6
- package/dist/types.d.cts.map +1 -0
- package/dist/types.d.mts +10 -0
- package/dist/types.d.mts.map +1 -0
- package/dist/types.mjs +1 -1
- package/package.json +41 -26
- package/dist/app-store/config.d.ts +0 -39
- package/dist/app-store/index.cjs.map +0 -1
- package/dist/app-store/index.d.ts +0 -3
- package/dist/app-store/index.mjs.map +0 -1
- package/dist/google-play/config.d.ts +0 -39
- package/dist/google-play/index.cjs.map +0 -1
- package/dist/google-play/index.d.ts +0 -4
- package/dist/google-play/index.mjs.map +0 -1
- package/dist/google-play/real-time-developer-notification.d.ts +0 -148
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.ts +0 -6
- package/dist/index.mjs.map +0 -1
- package/dist/stripe/config.d.ts +0 -43
- package/dist/stripe/handler.d.ts +0 -15
- package/dist/stripe/index.cjs.map +0 -1
- package/dist/stripe/index.d.ts +0 -12
- package/dist/stripe/index.mjs.map +0 -1
- package/dist/stripe/mapper.d.ts +0 -157
- package/dist/stripe/metadata.d.ts +0 -10
- package/dist/stripe/schema.d.ts +0 -41
- package/dist/subscription/index.d.ts +0 -148
- package/dist/types.cjs.map +0 -1
- package/dist/types.d.ts +0 -9
- package/dist/types.mjs.map +0 -1
|
@@ -1,74 +1,68 @@
|
|
|
1
|
-
"
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
addPendingCheckout: () => addPendingCheckout,
|
|
24
|
-
getPendingCheckouts: () => getPendingCheckouts,
|
|
25
|
-
removePendingCheckout: () => removePendingCheckout
|
|
26
|
-
});
|
|
27
|
-
module.exports = __toCommonJS(pending_checkout_exports);
|
|
28
|
-
var KEY = "pending-checkout";
|
|
29
|
-
var TTL = 60 * 60 * 1e3;
|
|
30
|
-
var MAX = 5;
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/stripe/pending-checkout.ts
|
|
3
|
+
/**
|
|
4
|
+
* Tracks checkouts that have been started but may not have been confirmed
|
|
5
|
+
* yet — e.g. the user paid on Stripe and closed the tab before being
|
|
6
|
+
* redirected back to the success page (where `confirmCheckoutSession` runs).
|
|
7
|
+
*
|
|
8
|
+
* IMPORTANT: this stores only the *session ids to retry confirmation on*, a
|
|
9
|
+
* best-effort retry hint — NOT the user's paid/balance state. The server
|
|
10
|
+
* remains the single source of truth for entitlements; on the next app boot
|
|
11
|
+
* we simply re-run the (idempotent, ownership-checked) confirm for each
|
|
12
|
+
* session so the credit balance reflects the purchase without waiting on the
|
|
13
|
+
* async Stripe webhook. Scoped to a single browser; cross-device is covered by
|
|
14
|
+
* the webhook backstop.
|
|
15
|
+
*
|
|
16
|
+
* A *list* (not a single value) is kept on purpose: localStorage is shared
|
|
17
|
+
* across tabs, so two concurrent checkouts — or a second checkout started
|
|
18
|
+
* before the first was reconciled — must not clobber each other.
|
|
19
|
+
*/
|
|
20
|
+
const KEY = "pending-checkout";
|
|
21
|
+
/** Drop a hint after this long — an abandoned/unpaid checkout shouldn't retry forever. */
|
|
22
|
+
const TTL = 3600 * 1e3;
|
|
31
23
|
function isFresh(entry) {
|
|
32
|
-
|
|
24
|
+
return Date.now() - entry.ts <= TTL;
|
|
33
25
|
}
|
|
34
26
|
function read() {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return [];
|
|
45
|
-
}
|
|
27
|
+
try {
|
|
28
|
+
const raw = localStorage.getItem(KEY);
|
|
29
|
+
if (!raw) return [];
|
|
30
|
+
const parsed = JSON.parse(raw);
|
|
31
|
+
if (!Array.isArray(parsed)) return [];
|
|
32
|
+
return parsed.filter((e) => !!e && typeof e.sessionId === "string" && typeof e.ts === "number");
|
|
33
|
+
} catch {
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
46
36
|
}
|
|
47
37
|
function write(entries) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
38
|
+
try {
|
|
39
|
+
if (entries.length === 0) localStorage.removeItem(KEY);
|
|
40
|
+
else localStorage.setItem(KEY, JSON.stringify(entries.slice(-5)));
|
|
41
|
+
} catch {}
|
|
53
42
|
}
|
|
43
|
+
/** Record a started checkout to retry confirmation on later. Dedupes by session id. */
|
|
54
44
|
function addPendingCheckout(sessionId) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
45
|
+
const entries = read().filter((e) => isFresh(e) && e.sessionId !== sessionId);
|
|
46
|
+
entries.push({
|
|
47
|
+
sessionId,
|
|
48
|
+
ts: Date.now()
|
|
49
|
+
});
|
|
50
|
+
write(entries);
|
|
58
51
|
}
|
|
52
|
+
/** Fresh session ids awaiting confirmation. Persists the pruned list as a side effect. */
|
|
59
53
|
function getPendingCheckouts() {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
54
|
+
const all = read();
|
|
55
|
+
const fresh = all.filter(isFresh);
|
|
56
|
+
if (fresh.length !== all.length) write(fresh);
|
|
57
|
+
return fresh.map((e) => e.sessionId);
|
|
64
58
|
}
|
|
59
|
+
/** Drop one session once it's confirmed (or known not to belong to this user). */
|
|
65
60
|
function removePendingCheckout(sessionId) {
|
|
66
|
-
|
|
61
|
+
write(read().filter((e) => isFresh(e) && e.sessionId !== sessionId));
|
|
67
62
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
});
|
|
63
|
+
//#endregion
|
|
64
|
+
exports.addPendingCheckout = addPendingCheckout;
|
|
65
|
+
exports.getPendingCheckouts = getPendingCheckouts;
|
|
66
|
+
exports.removePendingCheckout = removePendingCheckout;
|
|
67
|
+
|
|
74
68
|
//# sourceMappingURL=pending-checkout.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/stripe/pending-checkout.ts"],"sourcesContent":["/**\n * Tracks checkouts that have been started but may not have been confirmed\n * yet — e.g. the user paid on Stripe and closed the tab before being\n * redirected back to the success page (where `confirmCheckoutSession` runs).\n *\n * IMPORTANT: this stores only the *session ids to retry confirmation on*, a\n * best-effort retry hint — NOT the user's paid/balance state. The server\n * remains the single source of truth for entitlements; on the next app boot\n * we simply re-run the (idempotent, ownership-checked) confirm for each\n * session so the credit balance reflects the purchase without waiting on the\n * async Stripe webhook. Scoped to a single browser; cross-device is covered by\n * the webhook backstop.\n *\n * A *list* (not a single value) is kept on purpose: localStorage is shared\n * across tabs, so two concurrent checkouts — or a second checkout started\n * before the first was reconciled — must not clobber each other.\n */\n\nconst KEY = 'pending-checkout';\n\n/** Drop a hint after this long — an abandoned/unpaid checkout shouldn't retry forever. */\nconst TTL = 60 * 60 * 1000; // 1 hour\n\n/** Cap the list so a string of abandoned checkouts can't grow it unbounded. */\nconst MAX = 5;\n\ntype Entry = { sessionId: string; ts: number };\n\nfunction isFresh(entry: Entry): boolean {\n return Date.now() - entry.ts <= TTL;\n}\n\nfunction read(): Entry[] {\n try {\n const raw = localStorage.getItem(KEY);\n if (!raw) return [];\n const parsed = JSON.parse(raw);\n if (!Array.isArray(parsed)) return [];\n return parsed.filter(\n (e): e is Entry => !!e && typeof e.sessionId === 'string' && typeof e.ts === 'number'\n );\n } catch {\n return [];\n }\n}\n\nfunction write(entries: Entry[]) {\n try {\n if (entries.length === 0) localStorage.removeItem(KEY);\n else localStorage.setItem(KEY, JSON.stringify(entries.slice(-MAX)));\n } catch {\n // ignore — storage unavailable / quota; the webhook still reconciles.\n }\n}\n\n/** Record a started checkout to retry confirmation on later. Dedupes by session id. */\nexport function addPendingCheckout(sessionId: string) {\n const entries = read().filter((e) => isFresh(e) && e.sessionId !== sessionId);\n entries.push({ sessionId, ts: Date.now() });\n write(entries);\n}\n\n/** Fresh session ids awaiting confirmation. Persists the pruned list as a side effect. */\nexport function getPendingCheckouts(): string[] {\n const all = read();\n const fresh = all.filter(isFresh);\n if (fresh.length !== all.length) write(fresh);\n return fresh.map((e) => e.sessionId);\n}\n\n/** Drop one session once it's confirmed (or known not to belong to this user). */\nexport function removePendingCheckout(sessionId: string) {\n write(read().filter((e) => isFresh(e) && e.sessionId !== sessionId));\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"pending-checkout.cjs","names":[],"sources":["../../src/stripe/pending-checkout.ts"],"sourcesContent":["/**\n * Tracks checkouts that have been started but may not have been confirmed\n * yet — e.g. the user paid on Stripe and closed the tab before being\n * redirected back to the success page (where `confirmCheckoutSession` runs).\n *\n * IMPORTANT: this stores only the *session ids to retry confirmation on*, a\n * best-effort retry hint — NOT the user's paid/balance state. The server\n * remains the single source of truth for entitlements; on the next app boot\n * we simply re-run the (idempotent, ownership-checked) confirm for each\n * session so the credit balance reflects the purchase without waiting on the\n * async Stripe webhook. Scoped to a single browser; cross-device is covered by\n * the webhook backstop.\n *\n * A *list* (not a single value) is kept on purpose: localStorage is shared\n * across tabs, so two concurrent checkouts — or a second checkout started\n * before the first was reconciled — must not clobber each other.\n */\n\nconst KEY = 'pending-checkout';\n\n/** Drop a hint after this long — an abandoned/unpaid checkout shouldn't retry forever. */\nconst TTL = 60 * 60 * 1000; // 1 hour\n\n/** Cap the list so a string of abandoned checkouts can't grow it unbounded. */\nconst MAX = 5;\n\ntype Entry = { sessionId: string; ts: number };\n\nfunction isFresh(entry: Entry): boolean {\n return Date.now() - entry.ts <= TTL;\n}\n\nfunction read(): Entry[] {\n try {\n const raw = localStorage.getItem(KEY);\n if (!raw) return [];\n const parsed = JSON.parse(raw);\n if (!Array.isArray(parsed)) return [];\n return parsed.filter(\n (e): e is Entry => !!e && typeof e.sessionId === 'string' && typeof e.ts === 'number'\n );\n } catch {\n return [];\n }\n}\n\nfunction write(entries: Entry[]) {\n try {\n if (entries.length === 0) localStorage.removeItem(KEY);\n else localStorage.setItem(KEY, JSON.stringify(entries.slice(-MAX)));\n } catch {\n // ignore — storage unavailable / quota; the webhook still reconciles.\n }\n}\n\n/** Record a started checkout to retry confirmation on later. Dedupes by session id. */\nexport function addPendingCheckout(sessionId: string) {\n const entries = read().filter((e) => isFresh(e) && e.sessionId !== sessionId);\n entries.push({ sessionId, ts: Date.now() });\n write(entries);\n}\n\n/** Fresh session ids awaiting confirmation. Persists the pruned list as a side effect. */\nexport function getPendingCheckouts(): string[] {\n const all = read();\n const fresh = all.filter(isFresh);\n if (fresh.length !== all.length) write(fresh);\n return fresh.map((e) => e.sessionId);\n}\n\n/** Drop one session once it's confirmed (or known not to belong to this user). */\nexport function removePendingCheckout(sessionId: string) {\n write(read().filter((e) => isFresh(e) && e.sessionId !== sessionId));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAkBA,MAAM,MAAM;;AAGZ,MAAM,MAAM,OAAU;AAOtB,SAAS,QAAQ,OAAuB;CACtC,OAAO,KAAK,IAAI,IAAI,MAAM,MAAM;AAClC;AAEA,SAAS,OAAgB;CACvB,IAAI;EACF,MAAM,MAAM,aAAa,QAAQ,GAAG;EACpC,IAAI,CAAC,KAAK,OAAO,CAAC;EAClB,MAAM,SAAS,KAAK,MAAM,GAAG;EAC7B,IAAI,CAAC,MAAM,QAAQ,MAAM,GAAG,OAAO,CAAC;EACpC,OAAO,OAAO,QACX,MAAkB,CAAC,CAAC,KAAK,OAAO,EAAE,cAAc,YAAY,OAAO,EAAE,OAAO,QAC/E;CACF,QAAQ;EACN,OAAO,CAAC;CACV;AACF;AAEA,SAAS,MAAM,SAAkB;CAC/B,IAAI;EACF,IAAI,QAAQ,WAAW,GAAG,aAAa,WAAW,GAAG;OAChD,aAAa,QAAQ,KAAK,KAAK,UAAU,QAAQ,MAAM,EAAI,CAAC,CAAC;CACpE,QAAQ,CAER;AACF;;AAGA,SAAgB,mBAAmB,WAAmB;CACpD,MAAM,UAAU,KAAK,CAAC,CAAC,QAAQ,MAAM,QAAQ,CAAC,KAAK,EAAE,cAAc,SAAS;CAC5E,QAAQ,KAAK;EAAE;EAAW,IAAI,KAAK,IAAI;CAAE,CAAC;CAC1C,MAAM,OAAO;AACf;;AAGA,SAAgB,sBAAgC;CAC9C,MAAM,MAAM,KAAK;CACjB,MAAM,QAAQ,IAAI,OAAO,OAAO;CAChC,IAAI,MAAM,WAAW,IAAI,QAAQ,MAAM,KAAK;CAC5C,OAAO,MAAM,KAAK,MAAM,EAAE,SAAS;AACrC;;AAGA,SAAgB,sBAAsB,WAAmB;CACvD,MAAM,KAAK,CAAC,CAAC,QAAQ,MAAM,QAAQ,CAAC,KAAK,EAAE,cAAc,SAAS,CAAC;AACrE"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//#region src/stripe/pending-checkout.d.ts
|
|
1
2
|
/**
|
|
2
3
|
* Tracks checkouts that have been started but may not have been confirmed
|
|
3
4
|
* yet — e.g. the user paid on Stripe and closed the tab before being
|
|
@@ -21,5 +22,6 @@ declare function addPendingCheckout(sessionId: string): void;
|
|
|
21
22
|
declare function getPendingCheckouts(): string[];
|
|
22
23
|
/** Drop one session once it's confirmed (or known not to belong to this user). */
|
|
23
24
|
declare function removePendingCheckout(sessionId: string): void;
|
|
24
|
-
|
|
25
|
+
//#endregion
|
|
25
26
|
export { addPendingCheckout, getPendingCheckouts, removePendingCheckout };
|
|
27
|
+
//# sourceMappingURL=pending-checkout.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pending-checkout.d.cts","names":[],"sources":["../../src/stripe/pending-checkout.ts"],"mappings":";;;;;;;;;;;;;;;;;;;iBAwDgB,mBAAmB;;iBAOnB;;iBAQA,sBAAsB"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//#region src/stripe/pending-checkout.d.ts
|
|
1
2
|
/**
|
|
2
3
|
* Tracks checkouts that have been started but may not have been confirmed
|
|
3
4
|
* yet — e.g. the user paid on Stripe and closed the tab before being
|
|
@@ -21,5 +22,6 @@ declare function addPendingCheckout(sessionId: string): void;
|
|
|
21
22
|
declare function getPendingCheckouts(): string[];
|
|
22
23
|
/** Drop one session once it's confirmed (or known not to belong to this user). */
|
|
23
24
|
declare function removePendingCheckout(sessionId: string): void;
|
|
24
|
-
|
|
25
|
+
//#endregion
|
|
25
26
|
export { addPendingCheckout, getPendingCheckouts, removePendingCheckout };
|
|
27
|
+
//# sourceMappingURL=pending-checkout.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pending-checkout.d.mts","names":[],"sources":["../../src/stripe/pending-checkout.ts"],"mappings":";;;;;;;;;;;;;;;;;;;iBAwDgB,mBAAmB;;iBAOnB;;iBAQA,sBAAsB"}
|
|
@@ -1,47 +1,65 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
//#region src/stripe/pending-checkout.ts
|
|
2
|
+
/**
|
|
3
|
+
* Tracks checkouts that have been started but may not have been confirmed
|
|
4
|
+
* yet — e.g. the user paid on Stripe and closed the tab before being
|
|
5
|
+
* redirected back to the success page (where `confirmCheckoutSession` runs).
|
|
6
|
+
*
|
|
7
|
+
* IMPORTANT: this stores only the *session ids to retry confirmation on*, a
|
|
8
|
+
* best-effort retry hint — NOT the user's paid/balance state. The server
|
|
9
|
+
* remains the single source of truth for entitlements; on the next app boot
|
|
10
|
+
* we simply re-run the (idempotent, ownership-checked) confirm for each
|
|
11
|
+
* session so the credit balance reflects the purchase without waiting on the
|
|
12
|
+
* async Stripe webhook. Scoped to a single browser; cross-device is covered by
|
|
13
|
+
* the webhook backstop.
|
|
14
|
+
*
|
|
15
|
+
* A *list* (not a single value) is kept on purpose: localStorage is shared
|
|
16
|
+
* across tabs, so two concurrent checkouts — or a second checkout started
|
|
17
|
+
* before the first was reconciled — must not clobber each other.
|
|
18
|
+
*/
|
|
19
|
+
const KEY = "pending-checkout";
|
|
20
|
+
/** Drop a hint after this long — an abandoned/unpaid checkout shouldn't retry forever. */
|
|
21
|
+
const TTL = 3600 * 1e3;
|
|
5
22
|
function isFresh(entry) {
|
|
6
|
-
|
|
23
|
+
return Date.now() - entry.ts <= TTL;
|
|
7
24
|
}
|
|
8
25
|
function read() {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
return [];
|
|
19
|
-
}
|
|
26
|
+
try {
|
|
27
|
+
const raw = localStorage.getItem(KEY);
|
|
28
|
+
if (!raw) return [];
|
|
29
|
+
const parsed = JSON.parse(raw);
|
|
30
|
+
if (!Array.isArray(parsed)) return [];
|
|
31
|
+
return parsed.filter((e) => !!e && typeof e.sessionId === "string" && typeof e.ts === "number");
|
|
32
|
+
} catch {
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
20
35
|
}
|
|
21
36
|
function write(entries) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
37
|
+
try {
|
|
38
|
+
if (entries.length === 0) localStorage.removeItem(KEY);
|
|
39
|
+
else localStorage.setItem(KEY, JSON.stringify(entries.slice(-5)));
|
|
40
|
+
} catch {}
|
|
27
41
|
}
|
|
42
|
+
/** Record a started checkout to retry confirmation on later. Dedupes by session id. */
|
|
28
43
|
function addPendingCheckout(sessionId) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
44
|
+
const entries = read().filter((e) => isFresh(e) && e.sessionId !== sessionId);
|
|
45
|
+
entries.push({
|
|
46
|
+
sessionId,
|
|
47
|
+
ts: Date.now()
|
|
48
|
+
});
|
|
49
|
+
write(entries);
|
|
32
50
|
}
|
|
51
|
+
/** Fresh session ids awaiting confirmation. Persists the pruned list as a side effect. */
|
|
33
52
|
function getPendingCheckouts() {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
53
|
+
const all = read();
|
|
54
|
+
const fresh = all.filter(isFresh);
|
|
55
|
+
if (fresh.length !== all.length) write(fresh);
|
|
56
|
+
return fresh.map((e) => e.sessionId);
|
|
38
57
|
}
|
|
58
|
+
/** Drop one session once it's confirmed (or known not to belong to this user). */
|
|
39
59
|
function removePendingCheckout(sessionId) {
|
|
40
|
-
|
|
60
|
+
write(read().filter((e) => isFresh(e) && e.sessionId !== sessionId));
|
|
41
61
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
removePendingCheckout
|
|
46
|
-
};
|
|
62
|
+
//#endregion
|
|
63
|
+
export { addPendingCheckout, getPendingCheckouts, removePendingCheckout };
|
|
64
|
+
|
|
47
65
|
//# sourceMappingURL=pending-checkout.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/stripe/pending-checkout.ts"],"sourcesContent":["/**\n * Tracks checkouts that have been started but may not have been confirmed\n * yet — e.g. the user paid on Stripe and closed the tab before being\n * redirected back to the success page (where `confirmCheckoutSession` runs).\n *\n * IMPORTANT: this stores only the *session ids to retry confirmation on*, a\n * best-effort retry hint — NOT the user's paid/balance state. The server\n * remains the single source of truth for entitlements; on the next app boot\n * we simply re-run the (idempotent, ownership-checked) confirm for each\n * session so the credit balance reflects the purchase without waiting on the\n * async Stripe webhook. Scoped to a single browser; cross-device is covered by\n * the webhook backstop.\n *\n * A *list* (not a single value) is kept on purpose: localStorage is shared\n * across tabs, so two concurrent checkouts — or a second checkout started\n * before the first was reconciled — must not clobber each other.\n */\n\nconst KEY = 'pending-checkout';\n\n/** Drop a hint after this long — an abandoned/unpaid checkout shouldn't retry forever. */\nconst TTL = 60 * 60 * 1000; // 1 hour\n\n/** Cap the list so a string of abandoned checkouts can't grow it unbounded. */\nconst MAX = 5;\n\ntype Entry = { sessionId: string; ts: number };\n\nfunction isFresh(entry: Entry): boolean {\n return Date.now() - entry.ts <= TTL;\n}\n\nfunction read(): Entry[] {\n try {\n const raw = localStorage.getItem(KEY);\n if (!raw) return [];\n const parsed = JSON.parse(raw);\n if (!Array.isArray(parsed)) return [];\n return parsed.filter(\n (e): e is Entry => !!e && typeof e.sessionId === 'string' && typeof e.ts === 'number'\n );\n } catch {\n return [];\n }\n}\n\nfunction write(entries: Entry[]) {\n try {\n if (entries.length === 0) localStorage.removeItem(KEY);\n else localStorage.setItem(KEY, JSON.stringify(entries.slice(-MAX)));\n } catch {\n // ignore — storage unavailable / quota; the webhook still reconciles.\n }\n}\n\n/** Record a started checkout to retry confirmation on later. Dedupes by session id. */\nexport function addPendingCheckout(sessionId: string) {\n const entries = read().filter((e) => isFresh(e) && e.sessionId !== sessionId);\n entries.push({ sessionId, ts: Date.now() });\n write(entries);\n}\n\n/** Fresh session ids awaiting confirmation. Persists the pruned list as a side effect. */\nexport function getPendingCheckouts(): string[] {\n const all = read();\n const fresh = all.filter(isFresh);\n if (fresh.length !== all.length) write(fresh);\n return fresh.map((e) => e.sessionId);\n}\n\n/** Drop one session once it's confirmed (or known not to belong to this user). */\nexport function removePendingCheckout(sessionId: string) {\n write(read().filter((e) => isFresh(e) && e.sessionId !== sessionId));\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"pending-checkout.mjs","names":[],"sources":["../../src/stripe/pending-checkout.ts"],"sourcesContent":["/**\n * Tracks checkouts that have been started but may not have been confirmed\n * yet — e.g. the user paid on Stripe and closed the tab before being\n * redirected back to the success page (where `confirmCheckoutSession` runs).\n *\n * IMPORTANT: this stores only the *session ids to retry confirmation on*, a\n * best-effort retry hint — NOT the user's paid/balance state. The server\n * remains the single source of truth for entitlements; on the next app boot\n * we simply re-run the (idempotent, ownership-checked) confirm for each\n * session so the credit balance reflects the purchase without waiting on the\n * async Stripe webhook. Scoped to a single browser; cross-device is covered by\n * the webhook backstop.\n *\n * A *list* (not a single value) is kept on purpose: localStorage is shared\n * across tabs, so two concurrent checkouts — or a second checkout started\n * before the first was reconciled — must not clobber each other.\n */\n\nconst KEY = 'pending-checkout';\n\n/** Drop a hint after this long — an abandoned/unpaid checkout shouldn't retry forever. */\nconst TTL = 60 * 60 * 1000; // 1 hour\n\n/** Cap the list so a string of abandoned checkouts can't grow it unbounded. */\nconst MAX = 5;\n\ntype Entry = { sessionId: string; ts: number };\n\nfunction isFresh(entry: Entry): boolean {\n return Date.now() - entry.ts <= TTL;\n}\n\nfunction read(): Entry[] {\n try {\n const raw = localStorage.getItem(KEY);\n if (!raw) return [];\n const parsed = JSON.parse(raw);\n if (!Array.isArray(parsed)) return [];\n return parsed.filter(\n (e): e is Entry => !!e && typeof e.sessionId === 'string' && typeof e.ts === 'number'\n );\n } catch {\n return [];\n }\n}\n\nfunction write(entries: Entry[]) {\n try {\n if (entries.length === 0) localStorage.removeItem(KEY);\n else localStorage.setItem(KEY, JSON.stringify(entries.slice(-MAX)));\n } catch {\n // ignore — storage unavailable / quota; the webhook still reconciles.\n }\n}\n\n/** Record a started checkout to retry confirmation on later. Dedupes by session id. */\nexport function addPendingCheckout(sessionId: string) {\n const entries = read().filter((e) => isFresh(e) && e.sessionId !== sessionId);\n entries.push({ sessionId, ts: Date.now() });\n write(entries);\n}\n\n/** Fresh session ids awaiting confirmation. Persists the pruned list as a side effect. */\nexport function getPendingCheckouts(): string[] {\n const all = read();\n const fresh = all.filter(isFresh);\n if (fresh.length !== all.length) write(fresh);\n return fresh.map((e) => e.sessionId);\n}\n\n/** Drop one session once it's confirmed (or known not to belong to this user). */\nexport function removePendingCheckout(sessionId: string) {\n write(read().filter((e) => isFresh(e) && e.sessionId !== sessionId));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAkBA,MAAM,MAAM;;AAGZ,MAAM,MAAM,OAAU;AAOtB,SAAS,QAAQ,OAAuB;CACtC,OAAO,KAAK,IAAI,IAAI,MAAM,MAAM;AAClC;AAEA,SAAS,OAAgB;CACvB,IAAI;EACF,MAAM,MAAM,aAAa,QAAQ,GAAG;EACpC,IAAI,CAAC,KAAK,OAAO,CAAC;EAClB,MAAM,SAAS,KAAK,MAAM,GAAG;EAC7B,IAAI,CAAC,MAAM,QAAQ,MAAM,GAAG,OAAO,CAAC;EACpC,OAAO,OAAO,QACX,MAAkB,CAAC,CAAC,KAAK,OAAO,EAAE,cAAc,YAAY,OAAO,EAAE,OAAO,QAC/E;CACF,QAAQ;EACN,OAAO,CAAC;CACV;AACF;AAEA,SAAS,MAAM,SAAkB;CAC/B,IAAI;EACF,IAAI,QAAQ,WAAW,GAAG,aAAa,WAAW,GAAG;OAChD,aAAa,QAAQ,KAAK,KAAK,UAAU,QAAQ,MAAM,EAAI,CAAC,CAAC;CACpE,QAAQ,CAER;AACF;;AAGA,SAAgB,mBAAmB,WAAmB;CACpD,MAAM,UAAU,KAAK,CAAC,CAAC,QAAQ,MAAM,QAAQ,CAAC,KAAK,EAAE,cAAc,SAAS;CAC5E,QAAQ,KAAK;EAAE;EAAW,IAAI,KAAK,IAAI;CAAE,CAAC;CAC1C,MAAM,OAAO;AACf;;AAGA,SAAgB,sBAAgC;CAC9C,MAAM,MAAM,KAAK;CACjB,MAAM,QAAQ,IAAI,OAAO,OAAO;CAChC,IAAI,MAAM,WAAW,IAAI,QAAQ,MAAM,KAAK;CAC5C,OAAO,MAAM,KAAK,MAAM,EAAE,SAAS;AACrC;;AAGA,SAAgB,sBAAsB,WAAmB;CACvD,MAAM,KAAK,CAAC,CAAC,QAAQ,MAAM,QAAQ,CAAC,KAAK,EAAE,cAAc,SAAS,CAAC;AACrE"}
|
package/dist/stripe/schema.cjs
CHANGED
|
@@ -1,59 +1,34 @@
|
|
|
1
|
-
"
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
var schema_exports = {};
|
|
22
|
-
__export(schema_exports, {
|
|
23
|
-
cancellationDetailsSchema: () => cancellationDetailsSchema,
|
|
24
|
-
createCheckoutSessionSchema: () => createCheckoutSessionSchema
|
|
25
|
-
});
|
|
26
|
-
module.exports = __toCommonJS(schema_exports);
|
|
27
|
-
var import_mini = require("zod/mini");
|
|
28
|
-
var cancellationDetailsSchema = (0, import_mini.object)({
|
|
29
|
-
comment: (0, import_mini.optional)((0, import_mini.nullable)((0, import_mini.string)().check((0, import_mini.maxLength)(1024)))),
|
|
30
|
-
feedback: (0, import_mini.optional)(
|
|
31
|
-
(0, import_mini.nullable)(
|
|
32
|
-
(0, import_mini.enum)([
|
|
33
|
-
"customer_service",
|
|
34
|
-
"low_quality",
|
|
35
|
-
"missing_features",
|
|
36
|
-
"switched_service",
|
|
37
|
-
"too_complex",
|
|
38
|
-
"too_expensive",
|
|
39
|
-
"unused",
|
|
40
|
-
"other"
|
|
41
|
-
])
|
|
42
|
-
)
|
|
43
|
-
),
|
|
44
|
-
resubscribeIntent: (0, import_mini.optional)((0, import_mini.nullable)((0, import_mini.enum)(["maybe", "no", "yes"])))
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
let zod_mini = require("zod/mini");
|
|
3
|
+
//#region src/stripe/schema.ts
|
|
4
|
+
const cancellationDetailsSchema = (0, zod_mini.object)({
|
|
5
|
+
comment: (0, zod_mini.optional)((0, zod_mini.nullable)((0, zod_mini.string)().check((0, zod_mini.maxLength)(1024)))),
|
|
6
|
+
feedback: (0, zod_mini.optional)((0, zod_mini.nullable)((0, zod_mini.enum)([
|
|
7
|
+
"customer_service",
|
|
8
|
+
"low_quality",
|
|
9
|
+
"missing_features",
|
|
10
|
+
"switched_service",
|
|
11
|
+
"too_complex",
|
|
12
|
+
"too_expensive",
|
|
13
|
+
"unused",
|
|
14
|
+
"other"
|
|
15
|
+
]))),
|
|
16
|
+
resubscribeIntent: (0, zod_mini.optional)((0, zod_mini.nullable)((0, zod_mini.enum)([
|
|
17
|
+
"maybe",
|
|
18
|
+
"no",
|
|
19
|
+
"yes"
|
|
20
|
+
])))
|
|
45
21
|
});
|
|
46
22
|
function createCheckoutSessionSchema(productIds) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
23
|
+
return (0, zod_mini.object)({
|
|
24
|
+
quantity: (0, zod_mini._default)((0, zod_mini.int)().check((0, zod_mini.gte)(1)), 1),
|
|
25
|
+
productId: (0, zod_mini.enum)(productIds),
|
|
26
|
+
cancelUrl: (0, zod_mini.optional)((0, zod_mini.url)()),
|
|
27
|
+
successUrl: (0, zod_mini.optional)((0, zod_mini.url)())
|
|
28
|
+
});
|
|
53
29
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
});
|
|
30
|
+
//#endregion
|
|
31
|
+
exports.cancellationDetailsSchema = cancellationDetailsSchema;
|
|
32
|
+
exports.createCheckoutSessionSchema = createCheckoutSessionSchema;
|
|
33
|
+
|
|
59
34
|
//# sourceMappingURL=schema.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/stripe/schema.ts"],"sourcesContent":["import type { Stripe } from 'stripe';\nimport {\n _default,\n enum as _enum,\n gte,\n int,\n maxLength,\n nullable,\n object,\n optional,\n type output,\n string,\n url,\n} from 'zod/mini';\n\nexport const cancellationDetailsSchema = object({\n comment: optional(nullable(string().check(maxLength(1024)))),\n feedback: optional(\n nullable(\n _enum([\n 'customer_service',\n 'low_quality',\n 'missing_features',\n 'switched_service',\n 'too_complex',\n 'too_expensive',\n 'unused',\n 'other',\n ])\n )\n ),\n resubscribeIntent: optional(nullable(_enum(['maybe', 'no', 'yes']))),\n});\n\nexport function createCheckoutSessionSchema(productIds: string[]) {\n return object({\n quantity: _default(int().check(gte(1)), 1),\n productId: _enum(productIds),\n cancelUrl: optional(url()),\n successUrl: optional(url()),\n });\n}\n\nexport interface CancellationDetails extends output<typeof cancellationDetailsSchema> {\n reason?: Stripe.Subscription.CancellationDetails.Reason | null;\n}\n\nexport interface CreateCheckoutSessionDTO {\n productId: string;\n cancelUrl?: string;\n successUrl?: `${string}session_id={CHECKOUT_SESSION_ID}${string}`;\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"schema.cjs","names":[],"sources":["../../src/stripe/schema.ts"],"sourcesContent":["import type { Stripe } from 'stripe';\nimport {\n _default,\n enum as _enum,\n gte,\n int,\n maxLength,\n nullable,\n object,\n optional,\n type output,\n string,\n url,\n} from 'zod/mini';\n\nexport const cancellationDetailsSchema = object({\n comment: optional(nullable(string().check(maxLength(1024)))),\n feedback: optional(\n nullable(\n _enum([\n 'customer_service',\n 'low_quality',\n 'missing_features',\n 'switched_service',\n 'too_complex',\n 'too_expensive',\n 'unused',\n 'other',\n ])\n )\n ),\n resubscribeIntent: optional(nullable(_enum(['maybe', 'no', 'yes']))),\n});\n\nexport function createCheckoutSessionSchema(productIds: string[]) {\n return object({\n quantity: _default(int().check(gte(1)), 1),\n productId: _enum(productIds),\n cancelUrl: optional(url()),\n successUrl: optional(url()),\n });\n}\n\nexport interface CancellationDetails extends output<typeof cancellationDetailsSchema> {\n reason?: Stripe.Subscription.CancellationDetails.Reason | null;\n}\n\nexport interface CreateCheckoutSessionDTO {\n productId: string;\n cancelUrl?: string;\n successUrl?: `${string}session_id={CHECKOUT_SESSION_ID}${string}`;\n}\n"],"mappings":";;;AAeA,MAAa,6BAAA,GAAA,SAAA,OAAA,CAAmC;CAC9C,UAAA,GAAA,SAAA,SAAA,EAAA,GAAA,SAAA,SAAA,EAAA,GAAA,SAAA,OAAA,CAAkC,CAAC,CAAC,OAAA,GAAA,SAAA,UAAA,CAAgB,IAAI,CAAC,CAAC,CAAC;CAC3D,WAAA,GAAA,SAAA,SAAA,EAAA,GAAA,SAAA,SAAA,EAAA,GAAA,SAAA,KAAA,CAEU;EACJ;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,CACH,CACF;CACA,oBAAA,GAAA,SAAA,SAAA,EAAA,GAAA,SAAA,SAAA,EAAA,GAAA,SAAA,KAAA,CAA2C;EAAC;EAAS;EAAM;CAAK,CAAC,CAAC,CAAC;AACrE,CAAC;AAED,SAAgB,4BAA4B,YAAsB;CAChE,QAAA,GAAA,SAAA,OAAA,CAAc;EACZ,WAAA,GAAA,SAAA,SAAA,EAAA,GAAA,SAAA,IAAA,CAAuB,CAAC,CAAC,OAAA,GAAA,SAAA,IAAA,CAAU,CAAC,CAAC,GAAG,CAAC;EACzC,YAAA,GAAA,SAAA,KAAA,CAAiB,UAAU;EAC3B,YAAA,GAAA,SAAA,SAAA,EAAA,GAAA,SAAA,IAAA,CAAwB,CAAC;EACzB,aAAA,GAAA,SAAA,SAAA,EAAA,GAAA,SAAA,IAAA,CAAyB,CAAC;CAC5B,CAAC;AACH"}
|
package/dist/stripe/schema.d.cts
CHANGED
|
@@ -1,41 +1,40 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
successUrl: zod_mini.ZodMiniOptional<zod_mini.ZodMiniURL>;
|
|
31
|
-
}, zod_v4_core.$strip>;
|
|
1
|
+
import { Stripe } from "stripe";
|
|
2
|
+
import { output } from "zod/mini";
|
|
3
|
+
//#region src/stripe/schema.d.ts
|
|
4
|
+
declare const cancellationDetailsSchema: import("zod/mini").ZodMiniObject<{
|
|
5
|
+
comment: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniNullable<import("zod/mini").ZodMiniString<string>>>;
|
|
6
|
+
feedback: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniNullable<import("zod/mini").ZodMiniEnum<{
|
|
7
|
+
customer_service: "customer_service";
|
|
8
|
+
low_quality: "low_quality";
|
|
9
|
+
missing_features: "missing_features";
|
|
10
|
+
other: "other";
|
|
11
|
+
switched_service: "switched_service";
|
|
12
|
+
too_complex: "too_complex";
|
|
13
|
+
too_expensive: "too_expensive";
|
|
14
|
+
unused: "unused";
|
|
15
|
+
}>>>;
|
|
16
|
+
resubscribeIntent: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniNullable<import("zod/mini").ZodMiniEnum<{
|
|
17
|
+
maybe: "maybe";
|
|
18
|
+
no: "no";
|
|
19
|
+
yes: "yes";
|
|
20
|
+
}>>>;
|
|
21
|
+
}, import("zod/v4/core").$strip>;
|
|
22
|
+
declare function createCheckoutSessionSchema(productIds: string[]): import("zod/mini").ZodMiniObject<{
|
|
23
|
+
quantity: import("zod/mini").ZodMiniDefault<import("zod/mini").ZodMiniNumberFormat>;
|
|
24
|
+
productId: import("zod/mini").ZodMiniEnum<{
|
|
25
|
+
[x: string]: string;
|
|
26
|
+
}>;
|
|
27
|
+
cancelUrl: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniURL>;
|
|
28
|
+
successUrl: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniURL>;
|
|
29
|
+
}, import("zod/v4/core").$strip>;
|
|
32
30
|
interface CancellationDetails extends output<typeof cancellationDetailsSchema> {
|
|
33
|
-
|
|
31
|
+
reason?: Stripe.Subscription.CancellationDetails.Reason | null;
|
|
34
32
|
}
|
|
35
33
|
interface CreateCheckoutSessionDTO {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
productId: string;
|
|
35
|
+
cancelUrl?: string;
|
|
36
|
+
successUrl?: `${string}session_id={CHECKOUT_SESSION_ID}${string}`;
|
|
39
37
|
}
|
|
40
|
-
|
|
41
|
-
export {
|
|
38
|
+
//#endregion
|
|
39
|
+
export { CancellationDetails, CreateCheckoutSessionDTO, cancellationDetailsSchema, createCheckoutSessionSchema };
|
|
40
|
+
//# sourceMappingURL=schema.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.cts","names":[],"sources":["../../src/stripe/schema.ts"],"mappings":";;;cAea,8CAAyB;;;;;;;;;;;;;;;;;;iBAmBtB,4BAA4B,0CAAoB;;;;;;;;UAS/C,4BAA4B,cAAc;EACzD,SAAS,OAAO,aAAa,oBAAoB;;UAGlC;EACf;EACA;EACA"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { output } from "zod/mini";
|
|
2
|
+
import { Stripe } from "stripe";
|
|
3
|
+
//#region src/stripe/schema.d.ts
|
|
4
|
+
declare const cancellationDetailsSchema: import("zod/mini").ZodMiniObject<{
|
|
5
|
+
comment: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniNullable<import("zod/mini").ZodMiniString<string>>>;
|
|
6
|
+
feedback: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniNullable<import("zod/mini").ZodMiniEnum<{
|
|
7
|
+
customer_service: "customer_service";
|
|
8
|
+
low_quality: "low_quality";
|
|
9
|
+
missing_features: "missing_features";
|
|
10
|
+
other: "other";
|
|
11
|
+
switched_service: "switched_service";
|
|
12
|
+
too_complex: "too_complex";
|
|
13
|
+
too_expensive: "too_expensive";
|
|
14
|
+
unused: "unused";
|
|
15
|
+
}>>>;
|
|
16
|
+
resubscribeIntent: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniNullable<import("zod/mini").ZodMiniEnum<{
|
|
17
|
+
maybe: "maybe";
|
|
18
|
+
no: "no";
|
|
19
|
+
yes: "yes";
|
|
20
|
+
}>>>;
|
|
21
|
+
}, import("zod/v4/core").$strip>;
|
|
22
|
+
declare function createCheckoutSessionSchema(productIds: string[]): import("zod/mini").ZodMiniObject<{
|
|
23
|
+
quantity: import("zod/mini").ZodMiniDefault<import("zod/mini").ZodMiniNumberFormat>;
|
|
24
|
+
productId: import("zod/mini").ZodMiniEnum<{
|
|
25
|
+
[x: string]: string;
|
|
26
|
+
}>;
|
|
27
|
+
cancelUrl: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniURL>;
|
|
28
|
+
successUrl: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniURL>;
|
|
29
|
+
}, import("zod/v4/core").$strip>;
|
|
30
|
+
interface CancellationDetails extends output<typeof cancellationDetailsSchema> {
|
|
31
|
+
reason?: Stripe.Subscription.CancellationDetails.Reason | null;
|
|
32
|
+
}
|
|
33
|
+
interface CreateCheckoutSessionDTO {
|
|
34
|
+
productId: string;
|
|
35
|
+
cancelUrl?: string;
|
|
36
|
+
successUrl?: `${string}session_id={CHECKOUT_SESSION_ID}${string}`;
|
|
37
|
+
}
|
|
38
|
+
//#endregion
|
|
39
|
+
export { CancellationDetails, CreateCheckoutSessionDTO, cancellationDetailsSchema, createCheckoutSessionSchema };
|
|
40
|
+
//# sourceMappingURL=schema.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.mts","names":[],"sources":["../../src/stripe/schema.ts"],"mappings":";;;cAea,8CAAyB;;;;;;;;;;;;;;;;;;iBAmBtB,4BAA4B,0CAAoB;;;;;;;;UAS/C,4BAA4B,cAAc;EACzD,SAAS,OAAO,aAAa,oBAAoB;;UAGlC;EACf;EACA;EACA"}
|
package/dist/stripe/schema.mjs
CHANGED
|
@@ -1,44 +1,32 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
"low_quality",
|
|
21
|
-
"missing_features",
|
|
22
|
-
"switched_service",
|
|
23
|
-
"too_complex",
|
|
24
|
-
"too_expensive",
|
|
25
|
-
"unused",
|
|
26
|
-
"other"
|
|
27
|
-
])
|
|
28
|
-
)
|
|
29
|
-
),
|
|
30
|
-
resubscribeIntent: optional(nullable(_enum(["maybe", "no", "yes"])))
|
|
1
|
+
import { _default, enum as enum$1, gte, int, maxLength, nullable, object, optional, string, url } from "zod/mini";
|
|
2
|
+
//#region src/stripe/schema.ts
|
|
3
|
+
const cancellationDetailsSchema = object({
|
|
4
|
+
comment: optional(nullable(string().check(maxLength(1024)))),
|
|
5
|
+
feedback: optional(nullable(enum$1([
|
|
6
|
+
"customer_service",
|
|
7
|
+
"low_quality",
|
|
8
|
+
"missing_features",
|
|
9
|
+
"switched_service",
|
|
10
|
+
"too_complex",
|
|
11
|
+
"too_expensive",
|
|
12
|
+
"unused",
|
|
13
|
+
"other"
|
|
14
|
+
]))),
|
|
15
|
+
resubscribeIntent: optional(nullable(enum$1([
|
|
16
|
+
"maybe",
|
|
17
|
+
"no",
|
|
18
|
+
"yes"
|
|
19
|
+
])))
|
|
31
20
|
});
|
|
32
21
|
function createCheckoutSessionSchema(productIds) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
22
|
+
return object({
|
|
23
|
+
quantity: _default(int().check(gte(1)), 1),
|
|
24
|
+
productId: enum$1(productIds),
|
|
25
|
+
cancelUrl: optional(url()),
|
|
26
|
+
successUrl: optional(url())
|
|
27
|
+
});
|
|
39
28
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
};
|
|
29
|
+
//#endregion
|
|
30
|
+
export { cancellationDetailsSchema, createCheckoutSessionSchema };
|
|
31
|
+
|
|
44
32
|
//# sourceMappingURL=schema.mjs.map
|