@nextblock-cms/ecom 0.9.95 → 0.9.98
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/lib/currency-rest-client.cjs.js +1 -1
- package/lib/currency-rest-client.es.js +7 -7
- package/lib/freemius-order-sync.cjs.js +1 -1
- package/lib/freemius-order-sync.es.js +29 -29
- package/lib/pages/cms/orders/server-actions.cjs.js +1 -1
- package/lib/pages/cms/orders/server-actions.es.js +16 -16
- package/lib/providers/freemius.cjs.js +2 -2
- package/lib/providers/freemius.es.js +159 -159
- package/lib/providers/stripe.cjs.js +1 -1
- package/lib/providers/stripe.es.js +51 -51
- package/lib/stripe/checkout.cjs.js +1 -1
- package/lib/stripe/checkout.es.js +25 -25
- package/lib/stripe/order-sync.cjs.js +1 -1
- package/lib/stripe/order-sync.es.js +38 -38
- package/package.json +4 -4
|
@@ -3,8 +3,8 @@ import Q from "crypto";
|
|
|
3
3
|
import { Freemius as te } from "@freemius/sdk";
|
|
4
4
|
import { normalizeOrderCustomerDetails as ne } from "../customer.es.js";
|
|
5
5
|
import { getCouponQuote as ie, recordCouponRedemption as se } from "../coupon-server.es.js";
|
|
6
|
-
import { upsertDefaultUserAddresses as oe, fillMissingUserProfileCheckoutDetails as
|
|
7
|
-
import { getDefaultCurrency as
|
|
6
|
+
import { upsertDefaultUserAddresses as oe, fillMissingUserProfileCheckoutDetails as ce } from "../customer-addresses.es.js";
|
|
7
|
+
import { getDefaultCurrency as ae, resolveEffectivePriceForCurrency as le, isSaleWindowActive as z } from "../currency.es.js";
|
|
8
8
|
function o(e) {
|
|
9
9
|
const r = process.env[e];
|
|
10
10
|
if (!r)
|
|
@@ -46,7 +46,7 @@ function X(e, r) {
|
|
|
46
46
|
}
|
|
47
47
|
return Array.isArray(e) ? e : [];
|
|
48
48
|
}
|
|
49
|
-
function
|
|
49
|
+
function D(e) {
|
|
50
50
|
if (e == null || e === "")
|
|
51
51
|
return null;
|
|
52
52
|
const r = Number(e);
|
|
@@ -75,8 +75,8 @@ function fe() {
|
|
|
75
75
|
), null;
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
|
-
function
|
|
79
|
-
const r = fe(), t = String(e), i = r?.[t],
|
|
78
|
+
function Ee(e) {
|
|
79
|
+
const r = fe(), t = String(e), i = r?.[t], c = o("FREEMIUS_PRODUCT_ID"), d = o(
|
|
80
80
|
"FREEMIUS_ECOMMERCE_SANDBOX_PUBLIC_KEY"
|
|
81
81
|
), f = o(
|
|
82
82
|
"FREEMIUS_ECOMMERCE_SANDBOX_SECRET_KEY"
|
|
@@ -86,12 +86,12 @@ function ge(e) {
|
|
|
86
86
|
secretKey: i.secretKey ?? null,
|
|
87
87
|
apiKey: i.apiKey ?? null,
|
|
88
88
|
source: "product-map"
|
|
89
|
-
} : process.env.FREEMIUS_SANDBOX_ENABLED === "true" &&
|
|
89
|
+
} : process.env.FREEMIUS_SANDBOX_ENABLED === "true" && c && c === t && d ? {
|
|
90
90
|
publicKey: d,
|
|
91
91
|
secretKey: f,
|
|
92
92
|
apiKey: o("FREEMIUS_API_KEY"),
|
|
93
93
|
source: "single-product-sandbox-env"
|
|
94
|
-
} :
|
|
94
|
+
} : c && c === t && o("FREEMIUS_PUBLIC_KEY") ? {
|
|
95
95
|
publicKey: o("FREEMIUS_PUBLIC_KEY"),
|
|
96
96
|
secretKey: o("FREEMIUS_SECRET_KEY"),
|
|
97
97
|
apiKey: o("FREEMIUS_API_KEY"),
|
|
@@ -103,7 +103,7 @@ function ge(e) {
|
|
|
103
103
|
source: "legacy-env"
|
|
104
104
|
};
|
|
105
105
|
}
|
|
106
|
-
async function
|
|
106
|
+
async function ge(e) {
|
|
107
107
|
if (!e.apiKey)
|
|
108
108
|
throw new Error("Missing Freemius API key for SDK sandbox generation.");
|
|
109
109
|
return new te({
|
|
@@ -113,7 +113,7 @@ async function Ee(e) {
|
|
|
113
113
|
publicKey: e.publicKey
|
|
114
114
|
}).checkout.getSandboxParams();
|
|
115
115
|
}
|
|
116
|
-
class
|
|
116
|
+
class Ue {
|
|
117
117
|
getProviderName() {
|
|
118
118
|
return "Freemius";
|
|
119
119
|
}
|
|
@@ -121,33 +121,33 @@ class we {
|
|
|
121
121
|
items: r,
|
|
122
122
|
customerEmail: t,
|
|
123
123
|
customerPhone: i,
|
|
124
|
-
userId:
|
|
124
|
+
userId: c,
|
|
125
125
|
billingAddress: d,
|
|
126
126
|
shippingAddress: f,
|
|
127
127
|
currencyCode: m,
|
|
128
|
-
couponCode:
|
|
129
|
-
couponContextItems:
|
|
128
|
+
couponCode: K,
|
|
129
|
+
couponContextItems: E
|
|
130
130
|
}) {
|
|
131
|
-
const
|
|
132
|
-
if (!
|
|
131
|
+
const a = process.env.NEXT_PUBLIC_SUPABASE_URL || process.env.SUPABASE_URL, l = process.env.SUPABASE_SERVICE_ROLE_KEY || process.env.SUPABASE_SECRET_KEY;
|
|
132
|
+
if (!a || !l)
|
|
133
133
|
return { error: "Missing Supabase credentials for checkout (Service Key required).", url: null };
|
|
134
|
-
const p = H(
|
|
134
|
+
const p = H(a, l);
|
|
135
135
|
if (!r || r.length === 0)
|
|
136
136
|
return { error: "Cart is empty", url: null };
|
|
137
137
|
if (r.length !== 1)
|
|
138
138
|
return { error: "Freemius items must be checked out one at a time.", url: null };
|
|
139
|
-
const { data:
|
|
139
|
+
const { data: g, error: U } = await p.from("currencies").select(
|
|
140
140
|
"code, symbol, exchange_rate, is_default, is_active, auto_sync_product_prices, auto_update_exchange_rate, exchange_rate_source, exchange_rate_updated_at, rounding_mode, rounding_increment, rounding_charm_amount"
|
|
141
|
-
).eq("is_active", !0).order("code", { ascending: !0 }),
|
|
142
|
-
if (
|
|
141
|
+
).eq("is_active", !0).order("code", { ascending: !0 }), v = g ?? [];
|
|
142
|
+
if (U || v.length === 0)
|
|
143
143
|
return { error: "Failed to resolve store currencies", url: null };
|
|
144
|
-
const j =
|
|
145
|
-
if (
|
|
144
|
+
const j = ae(v), b = v.find((u) => u.code === (m || "").toUpperCase()) ?? j, S = r[0], { data: s, error: I } = await p.from("products").select("id, title, price, prices, sale_price, sale_prices, sale_start_at, sale_end_at, scheduled_price, scheduled_prices, scheduled_price_at, freemius_plan_id, freemius_product_id, trial_period_days, trial_requires_payment_method").eq("id", S.product_id).single();
|
|
145
|
+
if (I || !s)
|
|
146
146
|
return { error: "Product not found", url: null };
|
|
147
|
-
const
|
|
148
|
-
if (!
|
|
147
|
+
const w = s.freemius_plan_id, P = s.freemius_product_id;
|
|
148
|
+
if (!w || !P)
|
|
149
149
|
return { error: "Product is not configured for Freemius checkout (missing Plan ID or Product ID)", url: null };
|
|
150
|
-
const
|
|
150
|
+
const k = le({
|
|
151
151
|
prices: s.prices || {},
|
|
152
152
|
salePrices: s.sale_prices || {},
|
|
153
153
|
fallbackPrice: s.price,
|
|
@@ -157,19 +157,19 @@ class we {
|
|
|
157
157
|
scheduledPrice: s.scheduled_price,
|
|
158
158
|
scheduledPrices: s.scheduled_prices || {},
|
|
159
159
|
scheduledPriceAt: s.scheduled_price_at,
|
|
160
|
-
currencyCode:
|
|
161
|
-
currencies:
|
|
162
|
-
}), N =
|
|
160
|
+
currencyCode: b.code,
|
|
161
|
+
currencies: v
|
|
162
|
+
}), N = k.sale_price ?? k.price, x = z({
|
|
163
163
|
saleStartAt: s.sale_start_at,
|
|
164
164
|
saleEndAt: s.sale_end_at
|
|
165
|
-
}),
|
|
165
|
+
}), y = N * S.quantity;
|
|
166
166
|
let n = null, _ = 0;
|
|
167
|
-
if (
|
|
167
|
+
if (K) {
|
|
168
168
|
const u = await ie({
|
|
169
169
|
client: p,
|
|
170
|
-
code:
|
|
171
|
-
items:
|
|
172
|
-
currencyCode:
|
|
170
|
+
code: K,
|
|
171
|
+
items: E && E.length > 0 ? E : r,
|
|
172
|
+
currencyCode: b.code
|
|
173
173
|
});
|
|
174
174
|
if (!u.success)
|
|
175
175
|
return {
|
|
@@ -179,18 +179,18 @@ class we {
|
|
|
179
179
|
url: null
|
|
180
180
|
};
|
|
181
181
|
n = u.quote, _ = Math.min(
|
|
182
|
-
|
|
182
|
+
y,
|
|
183
183
|
n.lineDiscounts.filter(($) => $.product_id === s.id).reduce(($, T) => $ + T.discount, 0)
|
|
184
184
|
);
|
|
185
185
|
}
|
|
186
|
-
const
|
|
186
|
+
const F = G(s.trial_period_days), R = F > 0 ? S.trial_preference ? S.trial_preference : s.trial_requires_payment_method ? "paid" : "free" : null, B = "pending", h = ue(
|
|
187
187
|
d?.recipient_name ?? null
|
|
188
188
|
), { data: Y, error: V } = await p.from("orders").insert({
|
|
189
|
-
status:
|
|
190
|
-
total: Math.max(0,
|
|
191
|
-
currency:
|
|
192
|
-
exchange_rate_at_purchase:
|
|
193
|
-
subtotal:
|
|
189
|
+
status: B,
|
|
190
|
+
total: Math.max(0, y - _),
|
|
191
|
+
currency: b.code,
|
|
192
|
+
exchange_rate_at_purchase: b.exchange_rate,
|
|
193
|
+
subtotal: y,
|
|
194
194
|
discount_total: _,
|
|
195
195
|
coupon_id: n?.couponId ?? null,
|
|
196
196
|
coupon_code: n?.code ?? null,
|
|
@@ -204,9 +204,9 @@ class we {
|
|
|
204
204
|
final_amount_owned_by: "freemius"
|
|
205
205
|
} : null,
|
|
206
206
|
provider: "freemius",
|
|
207
|
-
freemius_product_id: String(
|
|
208
|
-
freemius_plan_id: String(
|
|
209
|
-
user_id:
|
|
207
|
+
freemius_product_id: String(P),
|
|
208
|
+
freemius_plan_id: String(w),
|
|
209
|
+
user_id: c || null,
|
|
210
210
|
customer_details: ne({
|
|
211
211
|
email: t,
|
|
212
212
|
phone: i,
|
|
@@ -220,18 +220,18 @@ class we {
|
|
|
220
220
|
const { error: J } = await p.from("order_items").insert([{
|
|
221
221
|
order_id: Y.id,
|
|
222
222
|
product_id: s.id,
|
|
223
|
-
quantity:
|
|
223
|
+
quantity: S.quantity,
|
|
224
224
|
price_at_purchase: N
|
|
225
225
|
}]);
|
|
226
|
-
if (J && console.error("Failed to insert order items:", J),
|
|
226
|
+
if (J && console.error("Failed to insert order items:", J), c)
|
|
227
227
|
try {
|
|
228
228
|
await oe({
|
|
229
|
-
userId:
|
|
229
|
+
userId: c,
|
|
230
230
|
billingAddress: d,
|
|
231
231
|
shippingAddress: f,
|
|
232
232
|
client: p
|
|
233
|
-
}), await
|
|
234
|
-
userId:
|
|
233
|
+
}), await ce({
|
|
234
|
+
userId: c,
|
|
235
235
|
fullName: d?.recipient_name ?? f?.recipient_name ?? null,
|
|
236
236
|
phone: i,
|
|
237
237
|
client: p
|
|
@@ -248,37 +248,37 @@ class we {
|
|
|
248
248
|
orderId: Y.id,
|
|
249
249
|
provider: "freemius",
|
|
250
250
|
discountTotal: _,
|
|
251
|
-
userId:
|
|
251
|
+
userId: c,
|
|
252
252
|
customerEmail: t,
|
|
253
253
|
metadata: {
|
|
254
|
-
currency:
|
|
255
|
-
subtotal:
|
|
254
|
+
currency: b.code,
|
|
255
|
+
subtotal: y,
|
|
256
256
|
final_amount_owned_by: "freemius"
|
|
257
257
|
}
|
|
258
258
|
});
|
|
259
|
-
const
|
|
260
|
-
if (!
|
|
259
|
+
const O = process.env.FREEMIUS_SANDBOX_ENABLED === "true", M = Ee(P), A = M.publicKey, L = M.secretKey, W = M.apiKey;
|
|
260
|
+
if (!A || O && !L)
|
|
261
261
|
return { error: "Missing FREEMIUS credentials (PUBLIC_KEY or SECRET_KEY) in environment variables.", url: null };
|
|
262
|
-
if (
|
|
262
|
+
if (O && M.source === "legacy-env") {
|
|
263
263
|
const u = o("FREEMIUS_PRODUCT_ID"), $ = !!o("FREEMIUS_ECOMMERCE_SANDBOX_PUBLIC_KEY"), T = !!o("FREEMIUS_ECOMMERCE_SANDBOX_SECRET_KEY");
|
|
264
264
|
console.warn(
|
|
265
|
-
`[Freemius Checkout] Sandbox is enabled for product ${
|
|
265
|
+
`[Freemius Checkout] Sandbox is enabled for product ${P}, but no product-scoped checkout credentials were selected. Falling back to legacy FREEMIUS_PUBLIC_KEY/FREEMIUS_SECRET_KEY may open live checkout instead of sandbox.`,
|
|
266
266
|
{
|
|
267
267
|
configuredProductId: u,
|
|
268
|
-
productIdsMatch: u === String(
|
|
268
|
+
productIdsMatch: u === String(P),
|
|
269
269
|
hasSandboxOverridePublicKey: $,
|
|
270
270
|
hasSandboxOverrideSecretKey: T,
|
|
271
271
|
hasCheckoutProductsJson: !!o("FREEMIUS_CHECKOUT_PRODUCTS_JSON")
|
|
272
272
|
}
|
|
273
273
|
);
|
|
274
274
|
}
|
|
275
|
-
let
|
|
276
|
-
if (
|
|
275
|
+
let q = !1;
|
|
276
|
+
if (O && L && A)
|
|
277
277
|
try {
|
|
278
|
-
|
|
279
|
-
productId:
|
|
280
|
-
publicKey:
|
|
281
|
-
secretKey:
|
|
278
|
+
q = await ge({
|
|
279
|
+
productId: P,
|
|
280
|
+
publicKey: A,
|
|
281
|
+
secretKey: L,
|
|
282
282
|
apiKey: W
|
|
283
283
|
});
|
|
284
284
|
} catch (u) {
|
|
@@ -286,18 +286,18 @@ class we {
|
|
|
286
286
|
"Freemius Checkout - SDK sandbox generation failed. Falling back to manual token generation.",
|
|
287
287
|
u,
|
|
288
288
|
{
|
|
289
|
-
credentialSource:
|
|
289
|
+
credentialSource: M.source,
|
|
290
290
|
hasApiKey: !!W
|
|
291
291
|
}
|
|
292
292
|
);
|
|
293
|
-
const $ = Math.floor(Date.now() / 1e3).toString(), T = `${$}${
|
|
294
|
-
|
|
293
|
+
const $ = Math.floor(Date.now() / 1e3).toString(), T = `${$}${P}${L}${A}checkout`, re = Q.createHash("md5").update(T).digest("hex");
|
|
294
|
+
q = {
|
|
295
295
|
ctx: $,
|
|
296
296
|
token: re
|
|
297
297
|
};
|
|
298
298
|
}
|
|
299
|
-
const C = new URL(`https://checkout.freemius.com/app/${
|
|
300
|
-
if (
|
|
299
|
+
const C = new URL(`https://checkout.freemius.com/app/${P}/plan/${w}/`);
|
|
300
|
+
if (O && L && A ? (C.searchParams.append("sandbox", q.token), C.searchParams.append("s_ctx_ts", q.ctx)) : O && C.searchParams.append("sandbox", "true"), t && C.searchParams.append("user_email", t), h.firstName && C.searchParams.append("user_firstname", h.firstName), h.lastName && C.searchParams.append("user_lastname", h.lastName), C.searchParams.append("currency", b.code.toLowerCase()), S.billing_cycle && C.searchParams.append("billing_cycle", S.billing_cycle), R && C.searchParams.append("trial", R), n)
|
|
301
301
|
C.searchParams.append("coupon", n.code);
|
|
302
302
|
else if (x) {
|
|
303
303
|
const { data: u } = await p.from("product_freemius_sale_coupons").select("freemius_coupon_code, is_active, starts_at, ends_at, sync_status").eq("product_id", s.id).maybeSingle();
|
|
@@ -310,19 +310,19 @@ class we {
|
|
|
310
310
|
url: C.toString(),
|
|
311
311
|
customProps: {
|
|
312
312
|
provider: "freemius",
|
|
313
|
-
plugin_id:
|
|
314
|
-
plan_id:
|
|
315
|
-
public_key:
|
|
313
|
+
plugin_id: P,
|
|
314
|
+
plan_id: w,
|
|
315
|
+
public_key: A,
|
|
316
316
|
user_email: t,
|
|
317
317
|
user_firstname: h.firstName,
|
|
318
318
|
user_lastname: h.lastName,
|
|
319
|
-
credential_source:
|
|
320
|
-
sandbox:
|
|
321
|
-
billing_cycle:
|
|
319
|
+
credential_source: M.source,
|
|
320
|
+
sandbox: q,
|
|
321
|
+
billing_cycle: S.billing_cycle,
|
|
322
322
|
trial: R,
|
|
323
|
-
trial_period_days:
|
|
323
|
+
trial_period_days: F,
|
|
324
324
|
trial_requires_payment_method: s.trial_requires_payment_method,
|
|
325
|
-
initial_order_status:
|
|
325
|
+
initial_order_status: B,
|
|
326
326
|
coupon: n?.code ?? null,
|
|
327
327
|
order_id: Y.id
|
|
328
328
|
}
|
|
@@ -334,93 +334,93 @@ async function Z(e, r, t, i) {
|
|
|
334
334
|
|
|
335
335
|
|
|
336
336
|
${d}
|
|
337
|
-
${e}`, m = Q.createHmac("sha256", i).update(f).digest("hex"),
|
|
337
|
+
${e}`, m = Q.createHmac("sha256", i).update(f).digest("hex"), K = Buffer.from(m).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, ""), E = `FS ${r}:${t}:${K}`, a = await fetch(`https://api.freemius.com${e}`, {
|
|
338
338
|
headers: {
|
|
339
|
-
Authorization:
|
|
339
|
+
Authorization: E,
|
|
340
340
|
Date: d,
|
|
341
341
|
Accept: "application/json"
|
|
342
342
|
}
|
|
343
343
|
});
|
|
344
|
-
if (!
|
|
345
|
-
const l = await
|
|
346
|
-
throw console.error(`[Freemius API] [ERROR] ${e} returned ${
|
|
344
|
+
if (!a.ok) {
|
|
345
|
+
const l = await a.text();
|
|
346
|
+
throw console.error(`[Freemius API] [ERROR] ${e} returned ${a.status}: ${l}`), new Error(`Freemius API failed on ${e}: ${a.status} - ${l}`);
|
|
347
347
|
}
|
|
348
|
-
return
|
|
348
|
+
return a.json();
|
|
349
349
|
}
|
|
350
|
-
async function
|
|
351
|
-
const e = o("FREEMIUS_DEVELOPER_ID"), r = o("FREEMIUS_PUBLIC_KEY"), t = o("FREEMIUS_SECRET_KEY"), i = process.env.NEXT_PUBLIC_SUPABASE_URL,
|
|
352
|
-
if (!e || !r || !t || !i || !
|
|
350
|
+
async function be() {
|
|
351
|
+
const e = o("FREEMIUS_DEVELOPER_ID"), r = o("FREEMIUS_PUBLIC_KEY"), t = o("FREEMIUS_SECRET_KEY"), i = process.env.NEXT_PUBLIC_SUPABASE_URL || process.env.SUPABASE_URL, c = process.env.SUPABASE_SERVICE_ROLE_KEY || process.env.SUPABASE_SECRET_KEY;
|
|
352
|
+
if (!e || !r || !t || !i || !c)
|
|
353
353
|
throw new Error("Missing necessary environment variables for Freemius Sync.");
|
|
354
|
-
const d = H(i,
|
|
354
|
+
const d = H(i, c, {
|
|
355
355
|
auth: { autoRefreshToken: !1, persistSession: !1 }
|
|
356
356
|
}), f = (m) => Z(m, e, r, t);
|
|
357
357
|
try {
|
|
358
358
|
console.log(`[Freemius Sync] Fetching all plugins for developer ${e}...`);
|
|
359
|
-
const m = await f(`/v1/developers/${e}/plugins.json`),
|
|
360
|
-
console.log(`[Freemius Sync] Found ${
|
|
361
|
-
let
|
|
362
|
-
const { data:
|
|
359
|
+
const m = await f(`/v1/developers/${e}/plugins.json`), K = X(m, ["plugins", "plugin"]);
|
|
360
|
+
console.log(`[Freemius Sync] Found ${K.length} plugins. Syncing plans...`);
|
|
361
|
+
let E = 0;
|
|
362
|
+
const { data: a } = await d.from("languages").select("id").eq("code", "en").single(), l = a?.id;
|
|
363
363
|
if (!l)
|
|
364
364
|
throw new Error("English language not found in database. Cannot sync products.");
|
|
365
|
-
for (const p of
|
|
366
|
-
const
|
|
367
|
-
if (!
|
|
365
|
+
for (const p of K) {
|
|
366
|
+
const g = p.id?.toString();
|
|
367
|
+
if (!g) {
|
|
368
368
|
console.warn("[Freemius Sync] Skipping plugin without an id:", p);
|
|
369
369
|
continue;
|
|
370
370
|
}
|
|
371
|
-
const
|
|
371
|
+
const U = await ee(
|
|
372
372
|
d,
|
|
373
373
|
e,
|
|
374
|
-
|
|
375
|
-
p.title || p.name || `Freemius Product ${
|
|
374
|
+
g,
|
|
375
|
+
p.title || p.name || `Freemius Product ${g}`,
|
|
376
376
|
f,
|
|
377
377
|
l
|
|
378
378
|
);
|
|
379
|
-
|
|
379
|
+
E += U;
|
|
380
380
|
}
|
|
381
|
-
return { success: !0, count:
|
|
381
|
+
return { success: !0, count: E };
|
|
382
382
|
} catch (m) {
|
|
383
383
|
throw console.error("[Freemius Sync] Global Error:", m), m;
|
|
384
384
|
}
|
|
385
385
|
}
|
|
386
386
|
async function Re(e) {
|
|
387
|
-
const r = o("FREEMIUS_DEVELOPER_ID"), t = o("FREEMIUS_PUBLIC_KEY"), i = o("FREEMIUS_SECRET_KEY"),
|
|
388
|
-
if (!r || !t || !i || !
|
|
387
|
+
const r = o("FREEMIUS_DEVELOPER_ID"), t = o("FREEMIUS_PUBLIC_KEY"), i = o("FREEMIUS_SECRET_KEY"), c = process.env.NEXT_PUBLIC_SUPABASE_URL || process.env.SUPABASE_URL, d = process.env.SUPABASE_SERVICE_ROLE_KEY || process.env.SUPABASE_SECRET_KEY;
|
|
388
|
+
if (!r || !t || !i || !c || !d)
|
|
389
389
|
throw new Error("Missing environment variables for Freemius Sync.");
|
|
390
|
-
const f = H(
|
|
391
|
-
if (!
|
|
390
|
+
const f = H(c, d), m = (g) => Z(g, r, t, i), { data: K } = await f.from("languages").select("id").eq("code", "en").single(), E = K?.id;
|
|
391
|
+
if (!E)
|
|
392
392
|
throw new Error("English language not found in database. Cannot sync products.");
|
|
393
|
-
const
|
|
393
|
+
const a = await m(`/v1/developers/${r}/plugins/${e}.json`), l = a.plugin ?? a;
|
|
394
394
|
return { success: !0, count: await ee(
|
|
395
395
|
f,
|
|
396
396
|
r,
|
|
397
397
|
e,
|
|
398
398
|
l.title || l.name || `Freemius Product ${e}`,
|
|
399
399
|
m,
|
|
400
|
-
|
|
400
|
+
E
|
|
401
401
|
) };
|
|
402
402
|
}
|
|
403
|
-
async function ee(e, r, t, i,
|
|
403
|
+
async function ee(e, r, t, i, c, d) {
|
|
404
404
|
console.log(`[Freemius Sync] Fetching plans for plugin: ${i} (${t})...`);
|
|
405
405
|
let f = 0;
|
|
406
406
|
try {
|
|
407
|
-
const m = `/v1/developers/${r}/plugins/${t}/plans.json`,
|
|
408
|
-
console.log(`[Freemius Sync] Received ${
|
|
409
|
-
for (const
|
|
410
|
-
const l =
|
|
407
|
+
const m = `/v1/developers/${r}/plugins/${t}/plans.json`, K = await c(m), E = X(K, ["plans", "plan"]);
|
|
408
|
+
console.log(`[Freemius Sync] Received ${E.length} plans for plugin ${t}.`);
|
|
409
|
+
for (const a of E) {
|
|
410
|
+
const l = a.id?.toString();
|
|
411
411
|
if (!l) {
|
|
412
|
-
console.warn("[Freemius Sync] Skipping plan without an id:",
|
|
412
|
+
console.warn("[Freemius Sync] Skipping plan without an id:", a);
|
|
413
413
|
continue;
|
|
414
414
|
}
|
|
415
|
-
const p =
|
|
416
|
-
console.log(`[Freemius Sync] Processing plan: ${
|
|
417
|
-
let
|
|
418
|
-
if (
|
|
415
|
+
const p = a.name || a.title || l, g = a.title || p;
|
|
416
|
+
console.log(`[Freemius Sync] Processing plan: ${g} (${l})...`);
|
|
417
|
+
let U = a;
|
|
418
|
+
if (U.trial_period === void 0 || U.is_require_subscription === void 0)
|
|
419
419
|
try {
|
|
420
|
-
const n = `/v1/developers/${r}/plugins/${t}/plans/${l}.json`, _ = await
|
|
421
|
-
|
|
422
|
-
...
|
|
423
|
-
...
|
|
420
|
+
const n = `/v1/developers/${r}/plugins/${t}/plans/${l}.json`, _ = await c(n), F = _.plan ?? _;
|
|
421
|
+
U = {
|
|
422
|
+
...U,
|
|
423
|
+
...F
|
|
424
424
|
};
|
|
425
425
|
} catch (n) {
|
|
426
426
|
console.warn(
|
|
@@ -428,100 +428,100 @@ async function ee(e, r, t, i, a, d) {
|
|
|
428
428
|
n instanceof Error ? n.message : n
|
|
429
429
|
);
|
|
430
430
|
}
|
|
431
|
-
const
|
|
432
|
-
let
|
|
431
|
+
const v = G(U.trial_period), j = v > 0 && de(U.is_require_subscription);
|
|
432
|
+
let b = 0, S = [];
|
|
433
433
|
try {
|
|
434
|
-
const n = `/v1/developers/${r}/plugins/${t}/plans/${l}/pricing.json`, _ = await
|
|
435
|
-
if (
|
|
434
|
+
const n = `/v1/developers/${r}/plugins/${t}/plans/${l}/pricing.json`, _ = await c(n);
|
|
435
|
+
if (S = X(_, [
|
|
436
436
|
"pricing",
|
|
437
437
|
"prices",
|
|
438
438
|
"pricings"
|
|
439
|
-
]),
|
|
440
|
-
const
|
|
441
|
-
|
|
439
|
+
]), S.length > 0) {
|
|
440
|
+
const F = S[0], R = D(F.annual_price) ?? D(F.monthly_price) ?? D(F.lifetime_price);
|
|
441
|
+
b = _e(R);
|
|
442
442
|
}
|
|
443
|
-
console.log(`[Freemius Sync] Plan: ${
|
|
443
|
+
console.log(`[Freemius Sync] Plan: ${g} -> Resolved Price (cents): ${b}`);
|
|
444
444
|
} catch (n) {
|
|
445
445
|
console.warn(`[Freemius Sync] Could not fetch pricing for plan ${l}:`, n instanceof Error ? n.message : n);
|
|
446
446
|
}
|
|
447
|
-
const s = `${i}-${
|
|
448
|
-
title: `${i} - ${
|
|
447
|
+
const s = `${i}-${g}`.toLowerCase().replace(/[^\w\s-]/g, "").replace(/[\s_]+/g, "-").replace(/^-+|-+$/g, ""), I = {
|
|
448
|
+
title: `${i} - ${g}`,
|
|
449
449
|
slug: s,
|
|
450
|
-
short_description:
|
|
451
|
-
price:
|
|
450
|
+
short_description: a.description || "",
|
|
451
|
+
price: b,
|
|
452
452
|
product_type: "digital",
|
|
453
453
|
payment_provider: "freemius",
|
|
454
454
|
freemius_plan_id: l,
|
|
455
455
|
freemius_product_id: t,
|
|
456
|
-
trial_period_days:
|
|
456
|
+
trial_period_days: v,
|
|
457
457
|
trial_requires_payment_method: j,
|
|
458
458
|
status: "active",
|
|
459
459
|
stock: 999,
|
|
460
460
|
sku: `FM-${t}-${l}`,
|
|
461
461
|
language_id: d
|
|
462
|
-
}, { data:
|
|
463
|
-
if (
|
|
464
|
-
console.error(`[Freemius Sync] Error upserting product ${
|
|
462
|
+
}, { data: w, error: P } = await e.from("products").upsert(I, { onConflict: "language_id, sku" }).select();
|
|
463
|
+
if (P || !w || w.length === 0) {
|
|
464
|
+
console.error(`[Freemius Sync] Error upserting product ${I.sku}:`, P);
|
|
465
465
|
continue;
|
|
466
466
|
}
|
|
467
|
-
const
|
|
467
|
+
const k = w[0].id, { data: N, error: x } = await e.from("freemius_plans").select("id").eq("product_id", k).eq("name", p).maybeSingle();
|
|
468
468
|
x && console.warn(
|
|
469
|
-
`[Freemius Sync] Could not check existing local plan for ${
|
|
469
|
+
`[Freemius Sync] Could not check existing local plan for ${I.sku}:`,
|
|
470
470
|
x.message || x
|
|
471
471
|
);
|
|
472
|
-
let
|
|
472
|
+
let y = "";
|
|
473
473
|
if (N) {
|
|
474
|
-
|
|
475
|
-
const { error: n } = await e.from("freemius_plans").update({ title:
|
|
474
|
+
y = N.id;
|
|
475
|
+
const { error: n } = await e.from("freemius_plans").update({ title: g, updated_at: (/* @__PURE__ */ new Date()).toISOString() }).eq("id", y);
|
|
476
476
|
n && console.warn(
|
|
477
|
-
`[Freemius Sync] Could not update local plan ${
|
|
477
|
+
`[Freemius Sync] Could not update local plan ${y}:`,
|
|
478
478
|
n.message || n
|
|
479
479
|
);
|
|
480
480
|
} else {
|
|
481
481
|
const { data: n, error: _ } = await e.from("freemius_plans").insert({
|
|
482
|
-
product_id:
|
|
482
|
+
product_id: k,
|
|
483
483
|
name: p,
|
|
484
|
-
title:
|
|
484
|
+
title: g
|
|
485
485
|
}).select("id").single();
|
|
486
486
|
_ && console.warn(
|
|
487
|
-
`[Freemius Sync] Could not insert local plan for ${
|
|
487
|
+
`[Freemius Sync] Could not insert local plan for ${I.sku}:`,
|
|
488
488
|
_.message || _
|
|
489
|
-
), n && (
|
|
489
|
+
), n && (y = n.id);
|
|
490
490
|
}
|
|
491
|
-
if (
|
|
492
|
-
for (const n of
|
|
491
|
+
if (y && S.length > 0)
|
|
492
|
+
for (const n of S) {
|
|
493
493
|
const _ = me(
|
|
494
494
|
n.licenses ?? n.license_quota ?? n.quota
|
|
495
|
-
), { data:
|
|
495
|
+
), { data: F, error: R } = await e.from("freemius_pricing").select("id").eq("plan_id", y).eq("license_quota", _).maybeSingle();
|
|
496
496
|
R && console.warn(
|
|
497
|
-
`[Freemius Sync] Could not check pricing for plan ${
|
|
497
|
+
`[Freemius Sync] Could not check pricing for plan ${y}, quota ${_}:`,
|
|
498
498
|
R.message || R
|
|
499
499
|
);
|
|
500
|
-
const
|
|
501
|
-
api_monthly_price:
|
|
502
|
-
api_annual_price:
|
|
503
|
-
api_lifetime_price:
|
|
500
|
+
const B = {
|
|
501
|
+
api_monthly_price: D(n.monthly_price),
|
|
502
|
+
api_annual_price: D(n.annual_price),
|
|
503
|
+
api_lifetime_price: D(n.lifetime_price),
|
|
504
504
|
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
505
505
|
};
|
|
506
|
-
if (
|
|
507
|
-
const { error: h } = await e.from("freemius_pricing").update(
|
|
506
|
+
if (F) {
|
|
507
|
+
const { error: h } = await e.from("freemius_pricing").update(B).eq("id", F.id);
|
|
508
508
|
h && console.warn(
|
|
509
|
-
`[Freemius Sync] Could not update pricing ${
|
|
509
|
+
`[Freemius Sync] Could not update pricing ${F.id}:`,
|
|
510
510
|
h.message || h
|
|
511
511
|
);
|
|
512
512
|
} else {
|
|
513
513
|
const { error: h } = await e.from("freemius_pricing").insert({
|
|
514
|
-
plan_id:
|
|
514
|
+
plan_id: y,
|
|
515
515
|
license_quota: _,
|
|
516
|
-
...
|
|
516
|
+
...B
|
|
517
517
|
});
|
|
518
518
|
h && console.warn(
|
|
519
|
-
`[Freemius Sync] Could not insert pricing for plan ${
|
|
519
|
+
`[Freemius Sync] Could not insert pricing for plan ${y}, quota ${_}:`,
|
|
520
520
|
h.message || h
|
|
521
521
|
);
|
|
522
522
|
}
|
|
523
523
|
}
|
|
524
|
-
console.log(`[Freemius Sync] Successfully fully synced product ${
|
|
524
|
+
console.log(`[Freemius Sync] Successfully fully synced product ${I.sku}.`), f++;
|
|
525
525
|
}
|
|
526
526
|
} catch (m) {
|
|
527
527
|
console.error(`[Freemius Sync] Failed sync for plugin ${t}:`, m.message);
|
|
@@ -529,10 +529,10 @@ async function ee(e, r, t, i, a, d) {
|
|
|
529
529
|
return f;
|
|
530
530
|
}
|
|
531
531
|
export {
|
|
532
|
-
|
|
532
|
+
Ue as FreemiusProvider,
|
|
533
533
|
fe as parseFreemiusCheckoutCredentialsMap,
|
|
534
534
|
o as readFreemiusEnvValue,
|
|
535
|
-
|
|
536
|
-
|
|
535
|
+
Ee as resolveFreemiusCheckoutCredentials,
|
|
536
|
+
be as syncFreemiusProductsToSupabase,
|
|
537
537
|
Re as syncSingleFreemiusProduct
|
|
538
538
|
};
|