@nextblock-cms/ecom 0.22.2 → 0.22.3
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/index.cjs +1 -1
- package/index.es.js +31 -31
- package/lib/components/Checkout.cjs +1 -1
- package/lib/components/Checkout.es.js +1 -0
- package/lib/components/SubscriptionSelector.cjs +1 -1
- package/lib/components/SubscriptionSelector.es.js +91 -92
- package/lib/coupon-server.cjs +1 -1
- package/lib/coupon-server.es.js +78 -61
- package/lib/coupons.cjs +1 -1
- package/lib/coupons.d.ts +9 -0
- package/lib/coupons.es.js +11 -2
- package/lib/currency-sync.cjs +1 -1
- package/lib/currency-sync.es.js +1 -1
- package/lib/freemius-coupons.cjs +1 -1
- package/lib/freemius-coupons.es.js +88 -92
- package/lib/freemius-license-claim.cjs +1 -1
- package/lib/freemius-license-claim.d.ts +13 -0
- package/lib/freemius-license-claim.es.js +44 -29
- package/lib/freemius-license.cjs +1 -1
- package/lib/freemius-license.es.js +19 -17
- package/lib/freemius-order-sync.cjs +1 -1
- package/lib/freemius-order-sync.d.ts +44 -0
- package/lib/freemius-order-sync.es.js +164 -77
- package/lib/freemius-pricing-server.cjs +1 -0
- package/lib/freemius-pricing-server.d.ts +65 -0
- package/lib/freemius-pricing-server.es.js +82 -0
- package/lib/freemius-pricing.cjs +1 -0
- package/lib/freemius-pricing.d.ts +53 -0
- package/lib/freemius-pricing.es.js +51 -0
- package/lib/invoice-server.cjs +1 -1
- package/lib/invoice-server.es.js +1 -0
- package/lib/pages/cms/coupons/CouponsPage.cjs +1 -1
- package/lib/pages/cms/coupons/CouponsPage.es.js +1 -0
- package/lib/pages/cms/coupons/EditCouponPage.cjs +1 -1
- package/lib/pages/cms/coupons/EditCouponPage.es.js +1 -0
- package/lib/pages/cms/coupons/actions.cjs +1 -1
- package/lib/pages/cms/coupons/actions.es.js +1 -0
- package/lib/pages/cms/orders/actions.cjs +1 -1
- package/lib/pages/cms/orders/actions.es.js +1 -0
- package/lib/pages/cms/orders/export-actions.cjs +1 -1
- package/lib/pages/cms/orders/export-actions.es.js +1 -0
- package/lib/pages/cms/orders/server-actions.cjs +1 -1
- package/lib/pages/cms/orders/server-actions.es.js +1 -0
- package/lib/pages/cms/products/ProductsPage.cjs +1 -1
- package/lib/pages/cms/products/ProductsPage.es.js +1 -0
- package/lib/pages/cms/products/[id]/edit/EditProductPage.cjs +1 -1
- package/lib/pages/cms/products/[id]/edit/EditProductPage.es.js +1 -0
- package/lib/pages/cms/products/actions.cjs +3 -3
- package/lib/pages/cms/products/actions.d.ts +11 -5
- package/lib/pages/cms/products/actions.es.js +45 -12
- package/lib/pages/cms/products/inventory/actions.cjs +1 -1
- package/lib/pages/cms/products/inventory/actions.es.js +1 -0
- package/lib/pages/cms/products/new/NewProductPage.cjs +1 -1
- package/lib/pages/cms/products/new/NewProductPage.es.js +1 -0
- package/lib/pages/cms/products/server-actions.cjs +1 -1
- package/lib/pages/cms/products/server-actions.es.js +1 -0
- package/lib/pages/cms/shipping/ShippingPage.cjs +1 -1
- package/lib/pages/cms/shipping/ShippingPage.es.js +1 -0
- package/lib/pages/cms/shipping/server-actions.cjs +1 -1
- package/lib/pages/cms/shipping/server-actions.es.js +1 -0
- package/lib/pages/cms/taxes/TaxesPage.cjs +1 -1
- package/lib/pages/cms/taxes/TaxesPage.es.js +1 -0
- package/lib/payment-config.cjs +1 -1
- package/lib/payment-config.es.js +1 -0
- package/lib/providers/freemius.cjs +1 -1
- package/lib/providers/freemius.es.js +200 -187
- package/lib/providers/stripe.cjs +1 -1
- package/lib/providers/stripe.es.js +151 -150
- package/lib/server-actions/coupon-actions.cjs +1 -1
- package/lib/server-actions/coupon-actions.es.js +1 -0
- package/lib/server-actions/customer-actions.d.ts +6 -1
- package/lib/server-actions/require-ecom-role.cjs +1 -1
- package/lib/server-actions/require-ecom-role.es.js +22 -10
- package/lib/server-actions/tax-actions.cjs +1 -1
- package/lib/server-actions/tax-actions.es.js +1 -0
- package/lib/shared-inventory.cjs +1 -1
- package/lib/shared-inventory.es.js +1 -1
- package/lib/stripe/checkout.cjs +1 -1
- package/lib/stripe/checkout.es.js +1 -0
- package/lib/stripe/order-sync.cjs +1 -1
- package/lib/stripe/order-sync.es.js +1 -0
- package/lib/stripe/webhooks.cjs +1 -1
- package/lib/stripe/webhooks.d.ts +10 -0
- package/lib/stripe/webhooks.es.js +23 -10
- package/package.json +4 -4
- package/server.cjs +1 -1
- package/server.es.js +31 -31
|
@@ -1,34 +1,36 @@
|
|
|
1
1
|
import { parseFreemiusCheckoutCredentialsMap as e, readFreemiusEnvValue as t, resolveFreemiusCheckoutCredentials as n } from "./providers/freemius.es.js";
|
|
2
2
|
import { applyOrderInventoryDeduction as r } from "./order-inventory.es.js";
|
|
3
3
|
import { assignInvoiceMetadata as i } from "./invoice-server.es.js";
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
4
|
+
import { evaluateFreemiusLicenseClaim as a, parseFreemiusTimestamp as o, retrieveFreemiusLicenseRecords as s } from "./freemius-license-claim.es.js";
|
|
5
|
+
import "server-only";
|
|
6
|
+
import { createClient as c } from "@supabase/supabase-js";
|
|
7
|
+
import l from "crypto";
|
|
8
|
+
import { Freemius as u } from "@freemius/sdk";
|
|
7
9
|
//#region src/lib/freemius-order-sync.ts
|
|
8
|
-
function
|
|
10
|
+
function d(e) {
|
|
9
11
|
return e == null || e === "" ? null : String(e);
|
|
10
12
|
}
|
|
11
|
-
function
|
|
12
|
-
let t =
|
|
13
|
+
function f(e) {
|
|
14
|
+
let t = d(e);
|
|
13
15
|
if (!t) return null;
|
|
14
16
|
let n = t.includes("T") ? t : t.replace(" ", "T") + "Z", r = new Date(n);
|
|
15
17
|
return Number.isNaN(r.getTime()) ? t : r.toISOString();
|
|
16
18
|
}
|
|
17
|
-
function
|
|
19
|
+
function p(e) {
|
|
18
20
|
if (e == null || e === "") return null;
|
|
19
21
|
let t = Number(e);
|
|
20
22
|
return Number.isFinite(t) ? t : null;
|
|
21
23
|
}
|
|
22
|
-
function
|
|
24
|
+
function m(...e) {
|
|
23
25
|
return e.some((e) => {
|
|
24
|
-
let t =
|
|
26
|
+
let t = p(e);
|
|
25
27
|
return t !== null && t > 0;
|
|
26
28
|
});
|
|
27
29
|
}
|
|
28
|
-
function
|
|
30
|
+
function h(e) {
|
|
29
31
|
return e === "pending" || e === "trial";
|
|
30
32
|
}
|
|
31
|
-
function
|
|
33
|
+
function g(e) {
|
|
32
34
|
return [
|
|
33
35
|
"license.cancelled",
|
|
34
36
|
"license.deleted",
|
|
@@ -39,38 +41,38 @@ function p(e) {
|
|
|
39
41
|
"trial.expired"
|
|
40
42
|
].includes(e || "");
|
|
41
43
|
}
|
|
42
|
-
function
|
|
44
|
+
function _(e, t) {
|
|
43
45
|
return e === "license.extended" && (t?.is_renewal === !0 || t?.is_renewal === 1 || t?.is_renewal === "1" || t?.is_renewal === "true");
|
|
44
46
|
}
|
|
45
|
-
function
|
|
47
|
+
function v(e) {
|
|
46
48
|
let t = e.objects?.payment ?? e.data?.payment ?? e.data;
|
|
47
|
-
return e.type === "payment.created" &&
|
|
49
|
+
return e.type === "payment.created" && m(t?.gross, t?.total_gross, t?.amount, t?.initial_amount);
|
|
48
50
|
}
|
|
49
|
-
function
|
|
51
|
+
function y(e) {
|
|
50
52
|
let t = e?.purchase ?? null, n = e?.trial ?? null;
|
|
51
53
|
return {
|
|
52
|
-
freemius_product_id:
|
|
53
|
-
freemius_plan_id:
|
|
54
|
-
freemius_license_id:
|
|
55
|
-
freemius_subscription_id:
|
|
56
|
-
freemius_trial_id:
|
|
57
|
-
freemius_user_id:
|
|
58
|
-
freemius_trial_ends_at:
|
|
54
|
+
freemius_product_id: d(t?.plugin_id) ?? d(t?.product_id) ?? d(t?.productId) ?? d(n?.plugin_id) ?? d(n?.product_id) ?? d(n?.productId),
|
|
55
|
+
freemius_plan_id: d(t?.plan_id) ?? d(t?.planId),
|
|
56
|
+
freemius_license_id: d(t?.license_id) ?? d(t?.licenseId) ?? d(n?.license_id) ?? d(n?.licenseId),
|
|
57
|
+
freemius_subscription_id: d(t?.subscription_id) ?? d(t?.subscriptionId) ?? d(n?.subscription_id) ?? d(n?.subscriptionId),
|
|
58
|
+
freemius_trial_id: d(n?.id),
|
|
59
|
+
freemius_user_id: d(t?.user_id) ?? d(t?.userId) ?? d(n?.user_id) ?? d(n?.userId) ?? d(e?.user?.id),
|
|
60
|
+
freemius_trial_ends_at: f(n?.trial_ends_at) ?? f(n?.trialEndsAt) ?? f(t?.trial_ends) ?? f(t?.trialEnds)
|
|
59
61
|
};
|
|
60
62
|
}
|
|
61
|
-
function
|
|
63
|
+
function b(e, t = "pending") {
|
|
62
64
|
let n = e?.purchase ?? null, r = e?.trial ?? null;
|
|
63
|
-
return t === "paid" ? "paid" : r && (r.canceled_at || r.canceledAt) &&
|
|
65
|
+
return t === "paid" ? "paid" : r && (r.canceled_at || r.canceledAt) && h(t) ? "cancelled" : r ? "trial" : n ? (n.canceled_at || n.canceledAt) && h(t) ? "cancelled" : m(n.initial_amount, n.initialAmount, n.gross, n.total_gross, n.totalGross) ? "paid" : n.trial_ends || n.trialEnds || n.subscription_id || n.subscriptionId ? "trial" : t : t;
|
|
64
66
|
}
|
|
65
|
-
function
|
|
67
|
+
function x(e) {
|
|
66
68
|
let { event: t, currentStatus: n, purchaseData: r } = e;
|
|
67
|
-
return n === "paid" &&
|
|
69
|
+
return n === "paid" && g(t.type) ? "paid" : g(t.type) ? h(n) ? "cancelled" : n : v(t) || _(t.type, t.data) || r && m(r.initialAmount, r.initial_amount, r.gross, r.totalGross, r.total_gross) ? "paid" : r?.canceled === !0 && h(n) ? "cancelled" : n === "pending" && (r?.trialEndsAt || r?.trial_ends_at || r?.trialEnds || r?.trial_ends) || (r?.subscriptionId || r?.subscription_id || t.type === "subscription.created" || t.type === "license.created") && n === "pending" ? "trial" : n;
|
|
68
70
|
}
|
|
69
|
-
function
|
|
71
|
+
function S(e, ...t) {
|
|
70
72
|
let n = t.filter((e) => !!e);
|
|
71
73
|
return e === "paid" || n.includes("paid") ? "paid" : n.includes("cancelled") ? "cancelled" : n.includes("trial") ? "trial" : n.includes("shipped") ? "shipped" : n.includes("refunded") ? "refunded" : e;
|
|
72
74
|
}
|
|
73
|
-
function
|
|
75
|
+
function C(e, t) {
|
|
74
76
|
let n = {
|
|
75
77
|
freemius_last_event_type: t,
|
|
76
78
|
freemius_last_synced_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -78,26 +80,26 @@ function b(e, t) {
|
|
|
78
80
|
for (let [t, r] of Object.entries(e)) r != null && r !== "" && (n[t] = r);
|
|
79
81
|
return n;
|
|
80
82
|
}
|
|
81
|
-
function
|
|
83
|
+
function w() {
|
|
82
84
|
let e = process.env.NEXT_PUBLIC_SUPABASE_URL || process.env.SUPABASE_URL, t = process.env.SUPABASE_SERVICE_ROLE_KEY || process.env.SUPABASE_SECRET_KEY;
|
|
83
85
|
if (!e || !t) throw Error("Missing Supabase Service Role environment variables");
|
|
84
|
-
return
|
|
86
|
+
return c(e, t, { auth: {
|
|
85
87
|
autoRefreshToken: !1,
|
|
86
88
|
persistSession: !1
|
|
87
89
|
} });
|
|
88
90
|
}
|
|
89
|
-
async function
|
|
90
|
-
let { data: n, error: r } = await e.from("orders").select("id, status, provider, freemius_product_id, freemius_plan_id, freemius_license_id, freemius_subscription_id, freemius_trial_id, freemius_user_id, freemius_trial_ends_at").eq("id", t).single();
|
|
91
|
+
async function T(e, t) {
|
|
92
|
+
let { data: n, error: r } = await e.from("orders").select("id, status, provider, created_at, freemius_product_id, freemius_plan_id, freemius_license_id, freemius_subscription_id, freemius_trial_id, freemius_user_id, freemius_trial_ends_at").eq("id", t).single();
|
|
91
93
|
if (r || !n) throw Error(r?.message || "Order not found");
|
|
92
94
|
return n;
|
|
93
95
|
}
|
|
94
|
-
async function
|
|
95
|
-
let { data: n, error: r } = await e.from("orders").select("id, status, provider, freemius_product_id, freemius_plan_id, freemius_license_id, freemius_subscription_id, freemius_trial_id, freemius_user_id, freemius_trial_ends_at").eq("freemius_license_id", t).order("created_at", { ascending: !1 }).limit(1).maybeSingle();
|
|
96
|
+
async function E(e, t) {
|
|
97
|
+
let { data: n, error: r } = await e.from("orders").select("id, status, provider, created_at, freemius_product_id, freemius_plan_id, freemius_license_id, freemius_subscription_id, freemius_trial_id, freemius_user_id, freemius_trial_ends_at").eq("freemius_license_id", t).order("created_at", { ascending: !1 }).limit(1).maybeSingle();
|
|
96
98
|
if (r) throw Error(r.message);
|
|
97
99
|
return n ?? null;
|
|
98
100
|
}
|
|
99
|
-
async function
|
|
100
|
-
let t =
|
|
101
|
+
async function D(e) {
|
|
102
|
+
let t = C(e.metadata, e.eventType), n = e.order.status, a = n === "paid" && e.nextStatus !== "paid" ? "paid" : e.nextStatus;
|
|
101
103
|
a !== n && (t.status = a);
|
|
102
104
|
let { error: o } = await e.client.from("orders").update(t).eq("id", e.order.id);
|
|
103
105
|
if (o) throw Error(o.message);
|
|
@@ -106,77 +108,162 @@ async function w(e) {
|
|
|
106
108
|
client: e.client
|
|
107
109
|
}), await r(e.client, e.order.id)), a;
|
|
108
110
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
+
var O = 3e5, k = "This checkout could not be verified with Freemius. Your license key is in your purchase email.";
|
|
112
|
+
function A(e) {
|
|
113
|
+
let t = d(e.licenseId), n = d(e.order.freemius_product_id);
|
|
114
|
+
if (!t) return {
|
|
115
|
+
ok: !1,
|
|
116
|
+
reason: "no_license_in_callback"
|
|
117
|
+
};
|
|
118
|
+
if (!n) return {
|
|
119
|
+
ok: !1,
|
|
120
|
+
reason: "missing_order_product"
|
|
121
|
+
};
|
|
122
|
+
let r = d(e.order.freemius_license_id);
|
|
123
|
+
if (r && r !== t) return {
|
|
124
|
+
ok: !1,
|
|
125
|
+
reason: "order_has_other_license"
|
|
126
|
+
};
|
|
127
|
+
if (e.linkedToOtherOrder) return {
|
|
128
|
+
ok: !1,
|
|
129
|
+
reason: "license_linked_to_other_order"
|
|
130
|
+
};
|
|
131
|
+
let i = a({
|
|
132
|
+
license: e.license,
|
|
133
|
+
now: e.now,
|
|
134
|
+
request: {
|
|
135
|
+
email: e.callbackEmail ?? "",
|
|
136
|
+
kind: "purchase",
|
|
137
|
+
licenseId: t,
|
|
138
|
+
productId: n,
|
|
139
|
+
userId: d(e.callbackUserId) ?? ""
|
|
140
|
+
},
|
|
141
|
+
user: e.user
|
|
142
|
+
});
|
|
143
|
+
if (!i.ok) return i;
|
|
144
|
+
let s = e.order.created_at ? Date.parse(e.order.created_at) : NaN, c = o(e.license?.created);
|
|
145
|
+
return !Number.isFinite(s) || c === null || c < s - O ? {
|
|
146
|
+
ok: !1,
|
|
147
|
+
reason: "license_predates_order"
|
|
148
|
+
} : { ok: !0 };
|
|
149
|
+
}
|
|
150
|
+
async function j(e, t, n) {
|
|
151
|
+
let { data: r, error: i } = await e.from("orders").select("id").eq("freemius_license_id", t).neq("id", n).limit(1);
|
|
152
|
+
if (i) throw Error(i.message);
|
|
153
|
+
return Array.isArray(r) && r.length > 0;
|
|
154
|
+
}
|
|
155
|
+
async function M(e) {
|
|
156
|
+
let t = e.client ?? w(), n = await T(t, e.orderId);
|
|
111
157
|
if (n.provider !== "freemius") return {
|
|
112
158
|
success: !1,
|
|
113
159
|
error: "Only Freemius orders can be synced from Freemius checkout"
|
|
114
160
|
};
|
|
115
|
-
let r =
|
|
116
|
-
if (
|
|
117
|
-
|
|
161
|
+
let r = y(e.checkoutResponse), i = r.freemius_license_id ?? null, a = d(n.freemius_product_id), o = !!i && d(n.freemius_license_id) === i, c = null;
|
|
162
|
+
if (!o) {
|
|
163
|
+
let o;
|
|
164
|
+
if (!i || !a) o = A({
|
|
165
|
+
callbackEmail: null,
|
|
166
|
+
callbackUserId: null,
|
|
167
|
+
license: null,
|
|
168
|
+
licenseId: i,
|
|
169
|
+
linkedToOtherOrder: !1,
|
|
170
|
+
order: n,
|
|
171
|
+
user: null
|
|
172
|
+
});
|
|
173
|
+
else {
|
|
174
|
+
let l = await (e.retrieveLicense ?? s)(a, i);
|
|
175
|
+
if (!l.ok) return console.error(`[Freemius Checkout Sync] Could not verify license ${i} for order ${n.id}: ${l.reason}`), {
|
|
176
|
+
success: !1,
|
|
177
|
+
error: k
|
|
178
|
+
};
|
|
179
|
+
o = A({
|
|
180
|
+
callbackEmail: e.checkoutResponse?.user?.email ?? null,
|
|
181
|
+
callbackUserId: r.freemius_user_id ?? null,
|
|
182
|
+
license: l.license,
|
|
183
|
+
licenseId: i,
|
|
184
|
+
linkedToOtherOrder: await j(t, i, n.id),
|
|
185
|
+
now: e.now,
|
|
186
|
+
order: n,
|
|
187
|
+
user: l.user
|
|
188
|
+
}), c = l.license;
|
|
189
|
+
}
|
|
190
|
+
if (!o.ok) return console.warn(`[Freemius Checkout Sync] Refused license ${i ?? "(none)"} for order ${n.id}: ${o.reason}`), {
|
|
191
|
+
success: !1,
|
|
192
|
+
error: k
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
let l = {
|
|
196
|
+
...r,
|
|
197
|
+
freemius_product_id: a,
|
|
198
|
+
freemius_plan_id: d(c?.plan_id) ?? d(n.freemius_plan_id) ?? null,
|
|
199
|
+
freemius_license_id: i,
|
|
200
|
+
freemius_user_id: d(c?.user_id) ?? d(n.freemius_user_id) ?? null
|
|
201
|
+
}, u = null;
|
|
202
|
+
if (i) try {
|
|
203
|
+
u = await F(a, i);
|
|
118
204
|
} catch (e) {
|
|
119
205
|
console.error("[Freemius Checkout Sync] Failed to retrieve purchase data:", e);
|
|
120
206
|
}
|
|
121
|
-
let
|
|
207
|
+
let f = {
|
|
122
208
|
type: "checkout.purchaseCompleted",
|
|
123
209
|
data: { license_id: r.freemius_license_id },
|
|
124
210
|
objects: {}
|
|
125
|
-
},
|
|
126
|
-
...
|
|
127
|
-
...
|
|
128
|
-
|
|
129
|
-
|
|
211
|
+
}, p = {
|
|
212
|
+
...l,
|
|
213
|
+
...P(f, u),
|
|
214
|
+
freemius_product_id: a
|
|
215
|
+
}, m = b(e.checkoutResponse, n.status), h = u ? x({
|
|
216
|
+
event: f,
|
|
130
217
|
currentStatus: n.status,
|
|
131
|
-
purchaseData:
|
|
132
|
-
}) : null,
|
|
218
|
+
purchaseData: u
|
|
219
|
+
}) : null, g = m === "paid" ? n.status : m, _ = await D({
|
|
133
220
|
client: t,
|
|
134
221
|
order: n,
|
|
135
|
-
nextStatus:
|
|
136
|
-
metadata:
|
|
222
|
+
nextStatus: S(n.status, g, h),
|
|
223
|
+
metadata: p,
|
|
137
224
|
eventType: "checkout.purchaseCompleted"
|
|
138
225
|
});
|
|
139
226
|
return {
|
|
140
227
|
success: !0,
|
|
141
228
|
orderId: n.id,
|
|
142
|
-
status:
|
|
143
|
-
metadata:
|
|
229
|
+
status: _,
|
|
230
|
+
metadata: p
|
|
144
231
|
};
|
|
145
232
|
}
|
|
146
|
-
function
|
|
147
|
-
return
|
|
233
|
+
function N(e) {
|
|
234
|
+
return d(e.data?.license_id) ?? d(e.objects?.license?.id) ?? d(e.objects?.subscription?.license_id) ?? d(e.objects?.payment?.license_id) ?? d(e.data?.payment?.license_id);
|
|
148
235
|
}
|
|
149
|
-
function
|
|
236
|
+
function P(e, t) {
|
|
150
237
|
let n = e.objects?.license, r = e.objects?.subscription, i = e.objects?.trial, a = e.objects?.payment ?? e.data?.payment;
|
|
151
238
|
return {
|
|
152
|
-
freemius_product_id:
|
|
153
|
-
freemius_plan_id:
|
|
154
|
-
freemius_license_id:
|
|
155
|
-
freemius_subscription_id:
|
|
156
|
-
freemius_trial_id:
|
|
157
|
-
freemius_user_id:
|
|
158
|
-
freemius_trial_ends_at:
|
|
239
|
+
freemius_product_id: d(t?.productId) ?? d(t?.product_id) ?? d(n?.plugin_id) ?? d(r?.plugin_id) ?? d(a?.plugin_id),
|
|
240
|
+
freemius_plan_id: d(t?.planId) ?? d(t?.plan_id) ?? d(n?.plan_id),
|
|
241
|
+
freemius_license_id: d(t?.licenseId) ?? d(t?.license_id) ?? N(e),
|
|
242
|
+
freemius_subscription_id: d(t?.subscriptionId) ?? d(t?.subscription_id) ?? d(r?.id) ?? d(e.data?.subscription_id),
|
|
243
|
+
freemius_trial_id: d(i?.id) ?? d(e.data?.trial_id),
|
|
244
|
+
freemius_user_id: d(t?.userId) ?? d(t?.user_id) ?? d(e.objects?.user?.id),
|
|
245
|
+
freemius_trial_ends_at: f(i?.trial_ends_at) ?? f(i?.trial_ends) ?? f(n?.trial_ends) ?? f(t?.trialEndsAt) ?? f(t?.trial_ends_at)
|
|
159
246
|
};
|
|
160
247
|
}
|
|
161
|
-
async function
|
|
248
|
+
async function F(e, t) {
|
|
162
249
|
if (!e) return null;
|
|
163
250
|
let r = n(e);
|
|
164
|
-
return !r.apiKey || !r.secretKey || !r.publicKey ? null : new
|
|
251
|
+
return !r.apiKey || !r.secretKey || !r.publicKey ? null : new u({
|
|
165
252
|
productId: Number(e),
|
|
166
253
|
apiKey: r.apiKey,
|
|
167
254
|
secretKey: r.secretKey,
|
|
168
255
|
publicKey: r.publicKey
|
|
169
256
|
}).purchase.retrievePurchaseData(t);
|
|
170
257
|
}
|
|
171
|
-
async function
|
|
172
|
-
let t = e.client ??
|
|
258
|
+
async function I(e) {
|
|
259
|
+
let t = e.client ?? w(), n = N(e.event);
|
|
173
260
|
if (!n) return {
|
|
174
261
|
success: !0,
|
|
175
262
|
ignored: !0,
|
|
176
263
|
reason: "missing_license_id",
|
|
177
264
|
type: e.event.type
|
|
178
265
|
};
|
|
179
|
-
let r = await
|
|
266
|
+
let r = await E(t, n);
|
|
180
267
|
if (!r) return {
|
|
181
268
|
success: !0,
|
|
182
269
|
ignored: !0,
|
|
@@ -186,14 +273,14 @@ async function k(e) {
|
|
|
186
273
|
};
|
|
187
274
|
let i = null;
|
|
188
275
|
try {
|
|
189
|
-
i = await
|
|
276
|
+
i = await F(r.freemius_product_id ?? e.event.objects?.license?.plugin_id, n);
|
|
190
277
|
} catch (e) {
|
|
191
278
|
console.error("[Freemius Sync] Failed to retrieve purchase data:", e);
|
|
192
279
|
}
|
|
193
|
-
let a =
|
|
280
|
+
let a = P(e.event, i), o = await D({
|
|
194
281
|
client: t,
|
|
195
282
|
order: r,
|
|
196
|
-
nextStatus:
|
|
283
|
+
nextStatus: x({
|
|
197
284
|
event: e.event,
|
|
198
285
|
currentStatus: r.status,
|
|
199
286
|
purchaseData: i
|
|
@@ -208,7 +295,7 @@ async function k(e) {
|
|
|
208
295
|
type: e.event.type
|
|
209
296
|
};
|
|
210
297
|
}
|
|
211
|
-
function
|
|
298
|
+
function L() {
|
|
212
299
|
let n = [
|
|
213
300
|
t("FREEMIUS_SECRET_KEY"),
|
|
214
301
|
t("FREEMIUS_ECOMMERCE_SANDBOX_SECRET_KEY"),
|
|
@@ -216,15 +303,15 @@ function A() {
|
|
|
216
303
|
];
|
|
217
304
|
return Array.from(new Set(n.filter((e) => !!e)));
|
|
218
305
|
}
|
|
219
|
-
function
|
|
220
|
-
return t ?
|
|
221
|
-
let r =
|
|
306
|
+
function R(e, t) {
|
|
307
|
+
return t ? L().some((n) => {
|
|
308
|
+
let r = l.createHmac("sha256", n).update(e).digest("hex");
|
|
222
309
|
try {
|
|
223
|
-
return
|
|
310
|
+
return l.timingSafeEqual(Buffer.from(r, "hex"), Buffer.from(t, "hex"));
|
|
224
311
|
} catch {
|
|
225
312
|
return !1;
|
|
226
313
|
}
|
|
227
314
|
}) : !1;
|
|
228
315
|
}
|
|
229
316
|
//#endregion
|
|
230
|
-
export {
|
|
317
|
+
export { k as FREEMIUS_CHECKOUT_SYNC_REFUSED_MESSAGE, A as evaluateFreemiusCheckoutLicense, y as extractFreemiusCheckoutMetadata, L as getFreemiusWebhookSecretCandidates, b as resolveFreemiusStatusFromCheckoutResponse, x as resolveFreemiusStatusFromWebhookEvent, M as syncFreemiusCheckoutOrder, I as syncFreemiusOrderFromWebhookEvent, R as verifyFreemiusWebhookSignature };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=require("./currency.cjs"),t=require("./freemius-pricing.cjs");let n=require("@nextblock-cms/utils");require("server-only");var r=`id, translation_group_id, price, prices, sale_price, sale_prices, sale_start_at, sale_end_at, scheduled_price, scheduled_prices, scheduled_price_at`;async function i(e,t){let n=[t.id];if(t.translation_group_id){let{data:r,error:i}=await e.from(`products`).select(`id`).eq(`translation_group_id`,t.translation_group_id);if(i)throw Error(i.message);n=[...new Set([t.id,...(r||[]).map(e=>e.id)])]}let{data:r,error:i}=await e.from(`freemius_plans`).select(`id`).in(`product_id`,n);if(i)throw Error(i.message);if(!r||r.length===0)return null;let{data:a,error:o}=await e.from(`freemius_pricing`).select(`id, license_quota, api_monthly_price, api_annual_price, api_lifetime_price`).in(`plan_id`,r.map(e=>e.id)).eq(`is_active`,!0).order(`license_quota`,{ascending:!0,nullsFirst:!1}).order(`id`,{ascending:!0}).limit(1);if(o)throw Error(o.message);return a?.[0]??null}async function a(r){let{product:a,currencies:o}=r,s=r.now??new Date,c=r.billingCycle,l=c!=null&&c!==``;if(l&&!t.isFreemiusBillingCycle(c))return{ok:!1,reason:`invalid_billing_cycle`};let u=r.tierCache?.get(a.id);u||(u=i(r.client,a),r.tierCache?.set(a.id,u));let d=await u;if(!d){let t=e.resolveEffectivePriceForCurrency({prices:e.normalizePriceMap(a.prices),salePrices:e.normalizeSalePriceMap(a.sale_prices),fallbackPrice:a.price,fallbackSalePrice:a.sale_price,saleStartAt:a.sale_start_at,saleEndAt:a.sale_end_at,scheduledPrice:a.scheduled_price,scheduledPrices:e.normalizePriceMap(a.scheduled_prices),scheduledPriceAt:a.scheduled_price_at,currencyCode:r.currencyCode,currencies:o,now:s});return{ok:!0,source:`product`,billingCycle:l?c:null,price:t.price,unitAmount:t.sale_price??t.price}}let f={monthly:t.toFreemiusCyclePrice(d.api_monthly_price),annual:t.toFreemiusCyclePrice(d.api_annual_price),lifetime:t.toFreemiusCyclePrice(d.api_lifetime_price)},p=t.resolveFreemiusBillingCycle(c,f);if(!p.ok)return p;let m=e.getDefaultCurrency(o),h=e.convertMinorUnitAmount({amount:(0,n.majorUnitAmountToMinor)(f[p.cycle]??0,m.code),fromCurrencyCode:m.code,toCurrencyCode:r.currencyCode,currencies:o,applyRounding:!0}),g=e.isSaleWindowActive({saleStartAt:a.sale_start_at,saleEndAt:a.sale_end_at,now:s})?t.computeFreemiusSaleDiscountPercent(a.price,a.sale_price):null;return{ok:!0,source:`pricing`,billingCycle:p.cycle,price:h,unitAmount:g===null?h:h-Math.round(h*g/100)}}exports.FREEMIUS_PRICED_PRODUCT_COLUMNS=r,exports.resolveFreemiusUnitAmount=a;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { SupabaseClient } from '@supabase/supabase-js';
|
|
2
|
+
import { CurrencyRecord } from './currency';
|
|
3
|
+
import { BillingCycle } from './types';
|
|
4
|
+
type SupabaseLikeClient = SupabaseClient<any>;
|
|
5
|
+
/** The `products` columns the resolver reads; select all of them. */
|
|
6
|
+
export declare const FREEMIUS_PRICED_PRODUCT_COLUMNS = "id, translation_group_id, price, prices, sale_price, sale_prices, sale_start_at, sale_end_at, scheduled_price, scheduled_prices, scheduled_price_at";
|
|
7
|
+
export type FreemiusPricedProduct = {
|
|
8
|
+
id: string;
|
|
9
|
+
translation_group_id?: string | null;
|
|
10
|
+
price: number | null;
|
|
11
|
+
prices?: Record<string, unknown> | null;
|
|
12
|
+
sale_price?: number | null;
|
|
13
|
+
sale_prices?: Record<string, unknown> | null;
|
|
14
|
+
sale_start_at?: string | null;
|
|
15
|
+
sale_end_at?: string | null;
|
|
16
|
+
scheduled_price?: number | null;
|
|
17
|
+
scheduled_prices?: Record<string, unknown> | null;
|
|
18
|
+
scheduled_price_at?: string | null;
|
|
19
|
+
};
|
|
20
|
+
type FreemiusPricingRow = {
|
|
21
|
+
id: string;
|
|
22
|
+
license_quota: number | null;
|
|
23
|
+
api_monthly_price: number | string | null;
|
|
24
|
+
api_annual_price: number | string | null;
|
|
25
|
+
api_lifetime_price: number | string | null;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Tier lookups keyed by product id, shared across one quote. The public coupon action prices a
|
|
29
|
+
* client-supplied line list, so without it repeating one product N times costs 3N queries.
|
|
30
|
+
*/
|
|
31
|
+
export type FreemiusPricingTierCache = Map<string, Promise<FreemiusPricingRow | null>>;
|
|
32
|
+
export type FreemiusUnitAmountResolution = {
|
|
33
|
+
ok: true;
|
|
34
|
+
/** `pricing`: the plan's Freemius price for the cycle. `product`: no pricing rows, so `products.price`. */
|
|
35
|
+
source: 'pricing' | 'product';
|
|
36
|
+
/** The cycle to send to Freemius. Null only on the `product` fallback when none was asked for. */
|
|
37
|
+
billingCycle: BillingCycle | null;
|
|
38
|
+
/** Regular unit price, in the selected currency's minor units. */
|
|
39
|
+
price: number;
|
|
40
|
+
/** What the order records per unit: `price` less an active sale. */
|
|
41
|
+
unitAmount: number;
|
|
42
|
+
} | {
|
|
43
|
+
ok: false;
|
|
44
|
+
reason: 'invalid_billing_cycle' | 'billing_cycle_not_offered';
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* The unit amount a Freemius purchase is recorded and discounted at.
|
|
48
|
+
*
|
|
49
|
+
* Freemius charges its own plan price for the cycle the checkout opens on, so that is what the
|
|
50
|
+
* order records: the `api_*` price (what Freemius charges, never a display override) for the
|
|
51
|
+
* validated cycle, converted from the store's default currency into the selected one the way
|
|
52
|
+
* the product page converts it. An active sale comes off as the percent the Freemius sale coupon
|
|
53
|
+
* carries. `products.price` is used only when the product has no pricing rows at all; it is the
|
|
54
|
+
* sync's cycle-blind annual-first price, so pricing it for a monthly purchase over-records it.
|
|
55
|
+
*/
|
|
56
|
+
export declare function resolveFreemiusUnitAmount(input: {
|
|
57
|
+
client: SupabaseLikeClient;
|
|
58
|
+
product: FreemiusPricedProduct;
|
|
59
|
+
billingCycle?: unknown;
|
|
60
|
+
currencyCode: string;
|
|
61
|
+
currencies: CurrencyRecord[];
|
|
62
|
+
tierCache?: FreemiusPricingTierCache;
|
|
63
|
+
now?: Date;
|
|
64
|
+
}): Promise<FreemiusUnitAmountResolution>;
|
|
65
|
+
export {};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { convertMinorUnitAmount as e, getDefaultCurrency as t, isSaleWindowActive as n, normalizePriceMap as r, normalizeSalePriceMap as i, resolveEffectivePriceForCurrency as a } from "./currency.es.js";
|
|
2
|
+
import { computeFreemiusSaleDiscountPercent as o, isFreemiusBillingCycle as s, resolveFreemiusBillingCycle as c, toFreemiusCyclePrice as l } from "./freemius-pricing.es.js";
|
|
3
|
+
import { majorUnitAmountToMinor as u } from "@nextblock-cms/utils";
|
|
4
|
+
import "server-only";
|
|
5
|
+
//#region src/lib/freemius-pricing-server.ts
|
|
6
|
+
var d = "id, translation_group_id, price, prices, sale_price, sale_prices, sale_start_at, sale_end_at, scheduled_price, scheduled_prices, scheduled_price_at";
|
|
7
|
+
async function f(e, t) {
|
|
8
|
+
let n = [t.id];
|
|
9
|
+
if (t.translation_group_id) {
|
|
10
|
+
let { data: r, error: i } = await e.from("products").select("id").eq("translation_group_id", t.translation_group_id);
|
|
11
|
+
if (i) throw Error(i.message);
|
|
12
|
+
n = [.../* @__PURE__ */ new Set([t.id, ...(r || []).map((e) => e.id)])];
|
|
13
|
+
}
|
|
14
|
+
let { data: r, error: i } = await e.from("freemius_plans").select("id").in("product_id", n);
|
|
15
|
+
if (i) throw Error(i.message);
|
|
16
|
+
if (!r || r.length === 0) return null;
|
|
17
|
+
let { data: a, error: o } = await e.from("freemius_pricing").select("id, license_quota, api_monthly_price, api_annual_price, api_lifetime_price").in("plan_id", r.map((e) => e.id)).eq("is_active", !0).order("license_quota", {
|
|
18
|
+
ascending: !0,
|
|
19
|
+
nullsFirst: !1
|
|
20
|
+
}).order("id", { ascending: !0 }).limit(1);
|
|
21
|
+
if (o) throw Error(o.message);
|
|
22
|
+
return a?.[0] ?? null;
|
|
23
|
+
}
|
|
24
|
+
async function p(d) {
|
|
25
|
+
let { product: p, currencies: m } = d, h = d.now ?? /* @__PURE__ */ new Date(), g = d.billingCycle, _ = g != null && g !== "";
|
|
26
|
+
if (_ && !s(g)) return {
|
|
27
|
+
ok: !1,
|
|
28
|
+
reason: "invalid_billing_cycle"
|
|
29
|
+
};
|
|
30
|
+
let v = d.tierCache?.get(p.id);
|
|
31
|
+
v || (v = f(d.client, p), d.tierCache?.set(p.id, v));
|
|
32
|
+
let y = await v;
|
|
33
|
+
if (!y) {
|
|
34
|
+
let e = a({
|
|
35
|
+
prices: r(p.prices),
|
|
36
|
+
salePrices: i(p.sale_prices),
|
|
37
|
+
fallbackPrice: p.price,
|
|
38
|
+
fallbackSalePrice: p.sale_price,
|
|
39
|
+
saleStartAt: p.sale_start_at,
|
|
40
|
+
saleEndAt: p.sale_end_at,
|
|
41
|
+
scheduledPrice: p.scheduled_price,
|
|
42
|
+
scheduledPrices: r(p.scheduled_prices),
|
|
43
|
+
scheduledPriceAt: p.scheduled_price_at,
|
|
44
|
+
currencyCode: d.currencyCode,
|
|
45
|
+
currencies: m,
|
|
46
|
+
now: h
|
|
47
|
+
});
|
|
48
|
+
return {
|
|
49
|
+
ok: !0,
|
|
50
|
+
source: "product",
|
|
51
|
+
billingCycle: _ ? g : null,
|
|
52
|
+
price: e.price,
|
|
53
|
+
unitAmount: e.sale_price ?? e.price
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
let b = {
|
|
57
|
+
monthly: l(y.api_monthly_price),
|
|
58
|
+
annual: l(y.api_annual_price),
|
|
59
|
+
lifetime: l(y.api_lifetime_price)
|
|
60
|
+
}, x = c(g, b);
|
|
61
|
+
if (!x.ok) return x;
|
|
62
|
+
let S = t(m), C = e({
|
|
63
|
+
amount: u(b[x.cycle] ?? 0, S.code),
|
|
64
|
+
fromCurrencyCode: S.code,
|
|
65
|
+
toCurrencyCode: d.currencyCode,
|
|
66
|
+
currencies: m,
|
|
67
|
+
applyRounding: !0
|
|
68
|
+
}), w = n({
|
|
69
|
+
saleStartAt: p.sale_start_at,
|
|
70
|
+
saleEndAt: p.sale_end_at,
|
|
71
|
+
now: h
|
|
72
|
+
}) ? o(p.price, p.sale_price) : null;
|
|
73
|
+
return {
|
|
74
|
+
ok: !0,
|
|
75
|
+
source: "pricing",
|
|
76
|
+
billingCycle: x.cycle,
|
|
77
|
+
price: C,
|
|
78
|
+
unitAmount: w === null ? C : C - Math.round(C * w / 100)
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
//#endregion
|
|
82
|
+
export { d as FREEMIUS_PRICED_PRODUCT_COLUMNS, p as resolveFreemiusUnitAmount };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e=[`annual`,`monthly`,`lifetime`];function t(t){return typeof t==`string`&&e.includes(t)}function n(e){if(e==null||e===``)return null;let t=Number(e);return Number.isFinite(t)&&t>=0?t:null}function r(e,t){let n=typeof e.license_quota==`number`?e.license_quota:null,r=typeof t.license_quota==`number`?t.license_quota:null;return n===r?e.id<t.id?-1:+(e.id>t.id):n===null?1:r===null?-1:n-r}function i(e){let t=e.filter(e=>e.is_active!==!1);return t.sort(r),t[0]??null}function a(n,r){if(n==null||n===``){let t=e.find(e=>r[e]!==null);return t?{ok:!0,cycle:t}:{ok:!1,reason:`billing_cycle_not_offered`}}return t(n)?r[n]===null?{ok:!1,reason:`billing_cycle_not_offered`}:{ok:!0,cycle:n}:{ok:!1,reason:`invalid_billing_cycle`}}function o(e,t){if(typeof e!=`number`||e<=0||typeof t!=`number`||t<0||t>=e)return null;let n=Math.round((1-t/e)*100);return n<=0||n>100?null:n}exports.FREEMIUS_BILLING_CYCLES=e,exports.compareFreemiusPricingTiers=r,exports.computeFreemiusSaleDiscountPercent=o,exports.isFreemiusBillingCycle=t,exports.pickFreemiusPricingTier=i,exports.resolveFreemiusBillingCycle=a,exports.toFreemiusCyclePrice=n;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { BillingCycle } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Pure Freemius pricing rules shared by the product page (client) and the checkout and coupon
|
|
4
|
+
* quote (server, see freemius-pricing-server.ts). Both sides must pick the same tier and the
|
|
5
|
+
* same cycle, or the price the shopper sees, the coupon base and the recorded order drift apart.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* The cycles a Freemius checkout accepts, in the order a missing cycle defaults through:
|
|
9
|
+
* Freemius opens on the annual cycle when the plan sells one, and the product page pre-selects
|
|
10
|
+
* the same way.
|
|
11
|
+
*/
|
|
12
|
+
export declare const FREEMIUS_BILLING_CYCLES: readonly BillingCycle[];
|
|
13
|
+
export declare function isFreemiusBillingCycle(value: unknown): value is BillingCycle;
|
|
14
|
+
/** Major-unit price per cycle for one pricing tier; null means the plan does not sell that cycle. */
|
|
15
|
+
export type FreemiusCyclePrices = Record<BillingCycle, number | null>;
|
|
16
|
+
export declare function toFreemiusCyclePrice(value: unknown): number | null;
|
|
17
|
+
type FreemiusPricingTierLike = {
|
|
18
|
+
id: string;
|
|
19
|
+
license_quota: number | null;
|
|
20
|
+
is_active?: boolean | null;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* `ORDER BY license_quota ASC NULLS LAST, id ASC`, the order the server query uses. Ids are
|
|
24
|
+
* compared as plain strings (not localeCompare) so lowercase uuids sort as Postgres sorts them.
|
|
25
|
+
*/
|
|
26
|
+
export declare function compareFreemiusPricingTiers(a: FreemiusPricingTierLike, b: FreemiusPricingTierLike): number;
|
|
27
|
+
/**
|
|
28
|
+
* The tier a Freemius product is sold at: the active tier with the lowest license quota. The
|
|
29
|
+
* checkout does not pick a license count, so Freemius charges its entry tier, and this is the
|
|
30
|
+
* tier the product page shows and the order records.
|
|
31
|
+
*/
|
|
32
|
+
export declare function pickFreemiusPricingTier<T extends FreemiusPricingTierLike>(tiers: readonly T[]): T | null;
|
|
33
|
+
export type FreemiusBillingCycleResolution = {
|
|
34
|
+
ok: true;
|
|
35
|
+
cycle: BillingCycle;
|
|
36
|
+
} | {
|
|
37
|
+
ok: false;
|
|
38
|
+
reason: 'invalid_billing_cycle' | 'billing_cycle_not_offered';
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Validates the cycle a cart line asks for against the cycles the tier sells. No cycle (a grid
|
|
42
|
+
* "add to cart" sends none) resolves to the first one sold, in FREEMIUS_BILLING_CYCLES order.
|
|
43
|
+
* Anything that is not a cycle name, or a cycle without a price, is refused: the value is
|
|
44
|
+
* appended to the Freemius checkout as sent, so it is never passed through unchecked.
|
|
45
|
+
*/
|
|
46
|
+
export declare function resolveFreemiusBillingCycle(requested: unknown, prices: FreemiusCyclePrices): FreemiusBillingCycleResolution;
|
|
47
|
+
/**
|
|
48
|
+
* The whole-percent discount a product sale becomes on Freemius. The sale coupon pushed to
|
|
49
|
+
* Freemius (syncProductSaleCouponToFreemius) carries this percent, and Freemius applies it to
|
|
50
|
+
* whichever cycle is bought, so the checkout records the sale with the same percent.
|
|
51
|
+
*/
|
|
52
|
+
export declare function computeFreemiusSaleDiscountPercent(price?: number | null, salePrice?: number | null): number | null;
|
|
53
|
+
export {};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
//#region src/lib/freemius-pricing.ts
|
|
2
|
+
var e = [
|
|
3
|
+
"annual",
|
|
4
|
+
"monthly",
|
|
5
|
+
"lifetime"
|
|
6
|
+
];
|
|
7
|
+
function t(t) {
|
|
8
|
+
return typeof t == "string" && e.includes(t);
|
|
9
|
+
}
|
|
10
|
+
function n(e) {
|
|
11
|
+
if (e == null || e === "") return null;
|
|
12
|
+
let t = Number(e);
|
|
13
|
+
return Number.isFinite(t) && t >= 0 ? t : null;
|
|
14
|
+
}
|
|
15
|
+
function r(e, t) {
|
|
16
|
+
let n = typeof e.license_quota == "number" ? e.license_quota : null, r = typeof t.license_quota == "number" ? t.license_quota : null;
|
|
17
|
+
return n === r ? e.id < t.id ? -1 : +(e.id > t.id) : n === null ? 1 : r === null ? -1 : n - r;
|
|
18
|
+
}
|
|
19
|
+
function i(e) {
|
|
20
|
+
let t = e.filter((e) => e.is_active !== !1);
|
|
21
|
+
return t.sort(r), t[0] ?? null;
|
|
22
|
+
}
|
|
23
|
+
function a(n, r) {
|
|
24
|
+
if (n == null || n === "") {
|
|
25
|
+
let t = e.find((e) => r[e] !== null);
|
|
26
|
+
return t ? {
|
|
27
|
+
ok: !0,
|
|
28
|
+
cycle: t
|
|
29
|
+
} : {
|
|
30
|
+
ok: !1,
|
|
31
|
+
reason: "billing_cycle_not_offered"
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
return t(n) ? r[n] === null ? {
|
|
35
|
+
ok: !1,
|
|
36
|
+
reason: "billing_cycle_not_offered"
|
|
37
|
+
} : {
|
|
38
|
+
ok: !0,
|
|
39
|
+
cycle: n
|
|
40
|
+
} : {
|
|
41
|
+
ok: !1,
|
|
42
|
+
reason: "invalid_billing_cycle"
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function o(e, t) {
|
|
46
|
+
if (typeof e != "number" || e <= 0 || typeof t != "number" || t < 0 || t >= e) return null;
|
|
47
|
+
let n = Math.round((1 - t / e) * 100);
|
|
48
|
+
return n <= 0 || n > 100 ? null : n;
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
export { e as FREEMIUS_BILLING_CYCLES, r as compareFreemiusPricingTiers, o as computeFreemiusSaleDiscountPercent, t as isFreemiusBillingCycle, i as pickFreemiusPricingTier, a as resolveFreemiusBillingCycle, n as toFreemiusCyclePrice };
|
package/lib/invoice-server.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const e=require("./customer.cjs"),t=require("./invoice.cjs"),n=require("./order-tax-details.cjs");let r=require("@nextblock-cms/db/server");function i(e){return e?e.startsWith(`http`)||e.startsWith(`/`)?e:process.env.NEXT_PUBLIC_R2_BASE_URL?`${process.env.NEXT_PUBLIC_R2_BASE_URL}/${e}`:process.env.NEXT_PUBLIC_SUPABASE_URL?`${process.env.NEXT_PUBLIC_SUPABASE_URL}/storage/v1/object/public/media/${e}`:e:null}function a(e){return e??(0,r.getServiceRoleSupabaseClient)()}function o(e){if(!e)return null;let t=e.media?.object_key??e.media?.file_path??null;return{id:e.id,name:e.name??null,url:i(t),width:e.media?.width??null,height:e.media?.height??null}}var s=`active_logo_id`,c=`
|
|
1
|
+
const e=require("./customer.cjs"),t=require("./invoice.cjs"),n=require("./order-tax-details.cjs");require("server-only");let r=require("@nextblock-cms/db/server");function i(e){return e?e.startsWith(`http`)||e.startsWith(`/`)?e:process.env.NEXT_PUBLIC_R2_BASE_URL?`${process.env.NEXT_PUBLIC_R2_BASE_URL}/${e}`:process.env.NEXT_PUBLIC_SUPABASE_URL?`${process.env.NEXT_PUBLIC_SUPABASE_URL}/storage/v1/object/public/media/${e}`:e:null}function a(e){return e??(0,r.getServiceRoleSupabaseClient)()}function o(e){if(!e)return null;let t=e.media?.object_key??e.media?.file_path??null;return{id:e.id,name:e.name??null,url:i(t),width:e.media?.width??null,height:e.media?.height??null}}var s=`active_logo_id`,c=`
|
|
2
2
|
id,
|
|
3
3
|
name,
|
|
4
4
|
media:media_id (
|