@nextblock-cms/ecom 0.22.0 → 0.22.2
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 +2 -1
- package/lib/coupon-server.cjs +1 -1
- package/lib/coupon-server.d.ts +65 -1
- package/lib/coupon-server.es.js +151 -91
- package/lib/coupons.cjs +1 -1
- package/lib/coupons.d.ts +13 -0
- package/lib/coupons.es.js +5 -4
- package/lib/order-access-token.cjs +1 -0
- package/lib/order-access-token.d.ts +2 -0
- package/lib/order-access-token.es.js +18 -0
- package/lib/pages/cms/orders/actions.cjs +3 -3
- package/lib/pages/cms/orders/actions.es.js +48 -26
- package/lib/pages/cms/orders/export-actions.cjs +1 -1
- package/lib/pages/cms/orders/export-actions.d.ts +42 -1
- package/lib/pages/cms/orders/export-actions.es.js +18 -16
- package/lib/pages/cms/orders/server-actions.cjs +1 -1
- package/lib/pages/cms/orders/server-actions.es.js +25 -15
- package/lib/pages/cms/products/actions.cjs +4 -4
- package/lib/pages/cms/products/actions.es.js +44 -41
- package/lib/pages/cms/products/inventory/actions.cjs +2 -2
- package/lib/pages/cms/products/inventory/actions.es.js +23 -23
- package/lib/pages/cms/products/server-actions.cjs +1 -1
- package/lib/pages/cms/products/server-actions.es.js +109 -108
- package/lib/pages/cms/shipping/server-actions.cjs +1 -1
- package/lib/pages/cms/shipping/server-actions.es.js +27 -26
- package/lib/payment-config.cjs +1 -1
- package/lib/payment-config.d.ts +4 -2
- package/lib/payment-config.es.js +73 -72
- package/lib/product-actions.cjs +1 -1
- package/lib/product-actions.es.js +6 -6
- package/lib/providers/checkout-items.cjs +1 -0
- package/lib/providers/checkout-items.d.ts +30 -0
- package/lib/providers/checkout-items.es.js +43 -0
- package/lib/providers/freemius.cjs +1 -1
- package/lib/providers/freemius.d.ts +1 -1
- package/lib/providers/freemius.es.js +166 -144
- package/lib/providers/stripe.cjs +1 -1
- package/lib/providers/stripe.d.ts +1 -1
- package/lib/providers/stripe.es.js +191 -146
- package/lib/server-actions/coupon-actions.cjs +1 -1
- package/lib/server-actions/coupon-actions.d.ts +11 -12
- package/lib/server-actions/coupon-actions.es.js +19 -11
- package/lib/server-actions/require-ecom-role.cjs +1 -0
- package/lib/server-actions/require-ecom-role.d.ts +5825 -0
- package/lib/server-actions/require-ecom-role.es.js +24 -0
- package/lib/server-actions/shipping-actions.cjs +1 -1
- package/lib/server-actions/shipping-actions.es.js +4 -4
- package/lib/server-actions/tax-actions.cjs +1 -1
- package/lib/server-actions/tax-actions.es.js +22 -18
- package/lib/shipping/checkout-shipping-method.cjs +7 -0
- package/lib/shipping/checkout-shipping-method.d.ts +115 -0
- package/lib/shipping/checkout-shipping-method.es.js +167 -0
- package/lib/shipping/resolver.cjs +1 -7
- package/lib/shipping/resolver.d.ts +7 -12
- package/lib/shipping/resolver.es.js +13 -38
- package/package.json +4 -4
- package/server.cjs +1 -1
- package/server.d.ts +1 -0
- package/server.es.js +49 -48
|
@@ -1,28 +1,29 @@
|
|
|
1
1
|
"use server";
|
|
2
2
|
import { normalizeCurrencyRecord as e } from "../../../currency.es.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
3
|
+
import { requireEcomStaff as t } from "../../../server-actions/require-ecom-role.es.js";
|
|
4
|
+
import { createProduct as n, deleteProduct as r, syncCategoriesForTranslationGroup as i } from "../../../product-actions.es.js";
|
|
5
|
+
import { sanitizeProductFormValuesForStoreManagedCurrencies as a } from "./product-price-sync.es.js";
|
|
6
|
+
import { syncProductSaleCouponToFreemius as o } from "../../../freemius-coupons.es.js";
|
|
7
|
+
import { createClient as s, getServiceRoleSupabaseClient as c } from "@nextblock-cms/db/server";
|
|
8
|
+
import { redirect as l } from "next/navigation";
|
|
9
|
+
import { revalidatePath as u } from "next/cache";
|
|
9
10
|
//#region src/lib/pages/cms/products/server-actions.ts
|
|
10
|
-
function
|
|
11
|
+
function d(e) {
|
|
11
12
|
return e.toLowerCase().trim().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
12
13
|
}
|
|
13
|
-
async function
|
|
14
|
-
let r =
|
|
14
|
+
async function f(t) {
|
|
15
|
+
let r = s(), { data: i } = await r.from("currencies").select("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").eq("is_active", !0).order("code", { ascending: !0 }), d = a(t, (i || []).map((t) => e(t))), f = await n(r, d);
|
|
15
16
|
if (d.payment_provider === "freemius" && f?.id) try {
|
|
16
|
-
await
|
|
17
|
+
await o({
|
|
17
18
|
productId: f.id,
|
|
18
|
-
client:
|
|
19
|
+
client: c()
|
|
19
20
|
});
|
|
20
21
|
} catch (e) {
|
|
21
22
|
console.error("Failed to sync Freemius sale coupon on create:", e);
|
|
22
23
|
}
|
|
23
|
-
|
|
24
|
+
u("/cms/products"), l("/cms/products");
|
|
24
25
|
}
|
|
25
|
-
async function
|
|
26
|
+
async function p(e, t, n, r) {
|
|
26
27
|
let i = {
|
|
27
28
|
author_id: n,
|
|
28
29
|
meta: r,
|
|
@@ -51,107 +52,107 @@ async function f(e, t, n, r) {
|
|
|
51
52
|
throw Error(`Failed to save product draft: ${u.message}`);
|
|
52
53
|
}
|
|
53
54
|
}
|
|
54
|
-
async function
|
|
55
|
-
let r =
|
|
56
|
-
if (!
|
|
57
|
-
let { data:
|
|
58
|
-
return await
|
|
55
|
+
async function m(t, n) {
|
|
56
|
+
let r = s(), { data: { user: i } } = await r.auth.getUser();
|
|
57
|
+
if (!i) throw Error("User not authenticated.");
|
|
58
|
+
let { data: o } = await r.from("currencies").select("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").eq("is_active", !0).order("code", { ascending: !0 }), c = a(n, (o || []).map((t) => e(t)));
|
|
59
|
+
return await p(r, t, i.id, c), { success: !0 };
|
|
59
60
|
}
|
|
60
|
-
async function
|
|
61
|
-
let t =
|
|
62
|
-
await
|
|
61
|
+
async function h(e) {
|
|
62
|
+
let t = s();
|
|
63
|
+
await r(t, e), u("/cms/products");
|
|
63
64
|
}
|
|
64
|
-
function
|
|
65
|
+
function g(e) {
|
|
65
66
|
return Array.from(new Set(e.map((e) => e.trim()).filter(Boolean)));
|
|
66
67
|
}
|
|
67
|
-
async function
|
|
68
|
-
let t =
|
|
68
|
+
async function _(e) {
|
|
69
|
+
let t = g(e);
|
|
69
70
|
if (t.length === 0) return {
|
|
70
71
|
success: !1,
|
|
71
72
|
error: "Select at least one product."
|
|
72
73
|
};
|
|
73
|
-
let { error: n } = await
|
|
74
|
+
let { error: n } = await s().from("products").delete().in("id", t);
|
|
74
75
|
return n ? {
|
|
75
76
|
success: !1,
|
|
76
77
|
error: n.message
|
|
77
|
-
} : (
|
|
78
|
+
} : (u("/cms/products"), {
|
|
78
79
|
success: !0,
|
|
79
80
|
count: t.length
|
|
80
81
|
});
|
|
81
82
|
}
|
|
82
|
-
async function
|
|
83
|
-
let t =
|
|
83
|
+
async function v(e) {
|
|
84
|
+
let t = g(e);
|
|
84
85
|
if (t.length === 0) return {
|
|
85
86
|
success: !1,
|
|
86
87
|
error: "Select at least one product."
|
|
87
88
|
};
|
|
88
|
-
let { error: n } = await
|
|
89
|
+
let { error: n } = await s().from("products").update({
|
|
89
90
|
status: "draft",
|
|
90
91
|
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
91
92
|
}).in("id", t);
|
|
92
93
|
return n ? {
|
|
93
94
|
success: !1,
|
|
94
95
|
error: n.message
|
|
95
|
-
} : (
|
|
96
|
+
} : (u("/cms/products"), {
|
|
96
97
|
success: !0,
|
|
97
98
|
count: t.length
|
|
98
99
|
});
|
|
99
100
|
}
|
|
100
|
-
async function
|
|
101
|
+
async function y(e) {
|
|
101
102
|
let t = String(e || "").trim();
|
|
102
103
|
if (!t) return { error: "Missing product id." };
|
|
103
|
-
let n =
|
|
104
|
+
let n = s(), { data: { user: r } } = await n.auth.getUser();
|
|
104
105
|
if (!r) return { error: "You must be signed in to publish a product." };
|
|
105
106
|
let { data: i, error: a } = await n.from("products").update({
|
|
106
107
|
status: "active",
|
|
107
108
|
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
108
109
|
}).eq("id", t).select("slug").single();
|
|
109
|
-
return a || !i ? { error: a?.message || "Could not publish the product." } : (
|
|
110
|
+
return a || !i ? { error: a?.message || "Could not publish the product." } : (u("/cms/products"), u(`/cms/products/${t}/edit`), i.slug && u(`/product/${i.slug}`), {});
|
|
110
111
|
}
|
|
111
|
-
async function
|
|
112
|
-
let
|
|
113
|
-
if (!
|
|
112
|
+
async function b(e) {
|
|
113
|
+
let n = await t(), r = e.name.trim(), i = d(e.slug?.trim() || e.name);
|
|
114
|
+
if (!r || !i) return {
|
|
114
115
|
success: !1,
|
|
115
116
|
error: "Attribute name is required."
|
|
116
117
|
};
|
|
117
|
-
let { error:
|
|
118
|
-
name:
|
|
119
|
-
slug:
|
|
118
|
+
let { error: a } = await n.from("product_attributes").insert({
|
|
119
|
+
name: r,
|
|
120
|
+
slug: i
|
|
120
121
|
});
|
|
121
|
-
return
|
|
122
|
+
return a ? {
|
|
122
123
|
success: !1,
|
|
123
|
-
error:
|
|
124
|
-
} : (
|
|
124
|
+
error: a.message
|
|
125
|
+
} : (u("/cms/products/attributes"), u("/cms/products/new"), u("/cms/products"), { success: !0 });
|
|
125
126
|
}
|
|
126
|
-
async function
|
|
127
|
-
let { error:
|
|
128
|
-
return
|
|
127
|
+
async function x(e) {
|
|
128
|
+
let { error: n } = await (await t()).from("product_attributes").delete().eq("id", e);
|
|
129
|
+
return n ? {
|
|
129
130
|
success: !1,
|
|
130
|
-
error:
|
|
131
|
-
} : (
|
|
131
|
+
error: n.message
|
|
132
|
+
} : (u("/cms/products/attributes"), u("/cms/products/new"), u("/cms/products"), { success: !0 });
|
|
132
133
|
}
|
|
133
|
-
async function
|
|
134
|
-
let
|
|
135
|
-
if (!
|
|
134
|
+
async function S(e) {
|
|
135
|
+
let n = await t(), r = e.value.trim(), i = d(e.slug?.trim() || e.value);
|
|
136
|
+
if (!r || !i) return {
|
|
136
137
|
success: !1,
|
|
137
138
|
error: "Term value is required."
|
|
138
139
|
};
|
|
139
|
-
let { data:
|
|
140
|
+
let { data: a } = await n.from("product_attribute_terms").select("sort_order").eq("attribute_id", e.attributeId).order("sort_order", { ascending: !1 }).limit(1), o = typeof a?.[0]?.sort_order == "number" ? a[0].sort_order + 1 : 0, { error: s } = await n.from("product_attribute_terms").insert({
|
|
140
141
|
attribute_id: e.attributeId,
|
|
141
|
-
value:
|
|
142
|
-
slug:
|
|
143
|
-
sort_order:
|
|
142
|
+
value: r,
|
|
143
|
+
slug: i,
|
|
144
|
+
sort_order: o
|
|
144
145
|
});
|
|
145
|
-
return
|
|
146
|
+
return s ? {
|
|
146
147
|
success: !1,
|
|
147
|
-
error:
|
|
148
|
-
} : (
|
|
148
|
+
error: s.message
|
|
149
|
+
} : (u("/cms/products/attributes"), u("/cms/products/new"), u("/cms/products"), { success: !0 });
|
|
149
150
|
}
|
|
150
|
-
async function
|
|
151
|
-
let
|
|
152
|
-
for (let [
|
|
153
|
-
let { error: i } = await
|
|
154
|
-
sort_order:
|
|
151
|
+
async function C(e) {
|
|
152
|
+
let n = await t();
|
|
153
|
+
for (let [t, r] of e.orderedTermIds.entries()) {
|
|
154
|
+
let { error: i } = await n.from("product_attribute_terms").update({
|
|
155
|
+
sort_order: t,
|
|
155
156
|
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
156
157
|
}).eq("id", r).eq("attribute_id", e.attributeId);
|
|
157
158
|
if (i) return {
|
|
@@ -159,86 +160,86 @@ async function S(e) {
|
|
|
159
160
|
error: i.message
|
|
160
161
|
};
|
|
161
162
|
}
|
|
162
|
-
return
|
|
163
|
+
return u("/cms/products/attributes"), u("/cms/products/new"), u("/cms/products"), { success: !0 };
|
|
163
164
|
}
|
|
164
|
-
async function
|
|
165
|
-
let
|
|
165
|
+
async function w(e) {
|
|
166
|
+
let n = await t(), { error: r } = await n.from("product_attributes").update({
|
|
166
167
|
name_translations: e.nameTranslations,
|
|
167
168
|
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
168
169
|
}).eq("id", e.attributeId);
|
|
169
|
-
if (
|
|
170
|
+
if (r) return {
|
|
170
171
|
success: !1,
|
|
171
|
-
error:
|
|
172
|
+
error: r.message
|
|
172
173
|
};
|
|
173
|
-
for (let
|
|
174
|
-
let { error: r } = await
|
|
175
|
-
value_translations:
|
|
174
|
+
for (let t of e.termTranslations) {
|
|
175
|
+
let { error: r } = await n.from("product_attribute_terms").update({
|
|
176
|
+
value_translations: t.valueTranslations,
|
|
176
177
|
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
177
|
-
}).eq("id",
|
|
178
|
+
}).eq("id", t.termId).eq("attribute_id", e.attributeId);
|
|
178
179
|
if (r) return {
|
|
179
180
|
success: !1,
|
|
180
181
|
error: r.message
|
|
181
182
|
};
|
|
182
183
|
}
|
|
183
|
-
return
|
|
184
|
+
return u("/cms/products/attributes"), u("/cms/products/new"), u("/cms/products"), { success: !0 };
|
|
184
185
|
}
|
|
185
|
-
async function
|
|
186
|
-
let { error:
|
|
187
|
-
return
|
|
186
|
+
async function T(e) {
|
|
187
|
+
let { error: n } = await (await t()).from("product_attribute_terms").delete().eq("id", e);
|
|
188
|
+
return n ? {
|
|
188
189
|
success: !1,
|
|
189
|
-
error:
|
|
190
|
-
} : (
|
|
190
|
+
error: n.message
|
|
191
|
+
} : (u("/cms/products/attributes"), u("/cms/products/new"), u("/cms/products"), { success: !0 });
|
|
191
192
|
}
|
|
192
|
-
async function
|
|
193
|
-
let
|
|
194
|
-
if (!
|
|
193
|
+
async function E(e) {
|
|
194
|
+
let n = await t(), r = e.name.trim(), i = d(e.slug?.trim() || e.name);
|
|
195
|
+
if (!r || !i) return {
|
|
195
196
|
success: !1,
|
|
196
197
|
error: "Category name is required."
|
|
197
198
|
};
|
|
198
|
-
let { data:
|
|
199
|
-
name:
|
|
200
|
-
slug:
|
|
199
|
+
let { data: a, error: o } = await n.from("categories").insert({
|
|
200
|
+
name: r,
|
|
201
|
+
slug: i,
|
|
201
202
|
description: e.description?.trim() || null,
|
|
202
203
|
name_translations: e.nameTranslations || {},
|
|
203
204
|
description_translations: e.descriptionTranslations || {}
|
|
204
205
|
}).select().single();
|
|
205
|
-
return
|
|
206
|
+
return o ? {
|
|
206
207
|
success: !1,
|
|
207
|
-
error:
|
|
208
|
-
} : (
|
|
208
|
+
error: o.message
|
|
209
|
+
} : (u("/cms/products/categories"), u("/cms/products/new"), u("/cms/products"), {
|
|
209
210
|
success: !0,
|
|
210
|
-
category:
|
|
211
|
+
category: a
|
|
211
212
|
});
|
|
212
213
|
}
|
|
213
|
-
async function
|
|
214
|
-
let
|
|
215
|
-
if (!
|
|
214
|
+
async function D(e, n) {
|
|
215
|
+
let r = await t(), i = n.name.trim(), a = d(n.slug?.trim() || n.name);
|
|
216
|
+
if (!i || !a) return {
|
|
216
217
|
success: !1,
|
|
217
218
|
error: "Category name is required."
|
|
218
219
|
};
|
|
219
|
-
let { error:
|
|
220
|
-
name:
|
|
221
|
-
slug:
|
|
222
|
-
description:
|
|
223
|
-
name_translations:
|
|
224
|
-
description_translations:
|
|
220
|
+
let { error: o } = await r.from("categories").update({
|
|
221
|
+
name: i,
|
|
222
|
+
slug: a,
|
|
223
|
+
description: n.description?.trim() || null,
|
|
224
|
+
name_translations: n.nameTranslations || {},
|
|
225
|
+
description_translations: n.descriptionTranslations || {}
|
|
225
226
|
}).eq("id", e);
|
|
226
|
-
return
|
|
227
|
+
return o ? {
|
|
227
228
|
success: !1,
|
|
228
|
-
error:
|
|
229
|
-
} : (
|
|
229
|
+
error: o.message
|
|
230
|
+
} : (u("/cms/products/categories"), u("/cms/products/new"), u("/cms/products"), { success: !0 });
|
|
230
231
|
}
|
|
231
|
-
async function
|
|
232
|
-
let { error:
|
|
233
|
-
return
|
|
232
|
+
async function O(e) {
|
|
233
|
+
let { error: n } = await (await t()).from("categories").delete().eq("id", e);
|
|
234
|
+
return n ? {
|
|
234
235
|
success: !1,
|
|
235
|
-
error:
|
|
236
|
-
} : (
|
|
236
|
+
error: n.message
|
|
237
|
+
} : (u("/cms/products/categories"), u("/cms/products/new"), u("/cms/products"), { success: !0 });
|
|
237
238
|
}
|
|
238
|
-
async function
|
|
239
|
-
let
|
|
239
|
+
async function k(e, n) {
|
|
240
|
+
let r = await t();
|
|
240
241
|
try {
|
|
241
|
-
return await r
|
|
242
|
+
return await i(r, e, n), u("/cms/products"), u(`/cms/products/${e}/edit`), { success: !0 };
|
|
242
243
|
} catch (e) {
|
|
243
244
|
return {
|
|
244
245
|
success: !1,
|
|
@@ -247,4 +248,4 @@ async function O(e, t) {
|
|
|
247
248
|
}
|
|
248
249
|
}
|
|
249
250
|
//#endregion
|
|
250
|
-
export {
|
|
251
|
+
export { _ as bulkDeleteProductsAction, v as bulkDraftProductsAction, E as createCategoryAction, f as createProductAction, b as createProductAttributeAction, S as createProductAttributeTermAction, O as deleteCategoryAction, h as deleteProductAction, x as deleteProductAttributeAction, T as deleteProductAttributeTermAction, y as publishProductAction, C as reorderProductAttributeTermsAction, k as syncProductCategoriesAction, D as updateCategoryAction, m as updateProductAction, w as updateProductAttributeTranslationsAction };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use server";const e=require("../../../currency.cjs"),t=require("../../../countries.cjs"),n=require("../../../shipping-rate-currency.cjs"),r=require("../../../states.cjs"),i=require("../../../inventory-settings.cjs");let
|
|
1
|
+
"use server";const e=require("../../../currency.cjs"),t=require("../../../countries.cjs"),n=require("../../../shipping-rate-currency.cjs"),r=require("../../../states.cjs"),i=require("../../../inventory-settings.cjs"),a=require("../../../server-actions/require-ecom-role.cjs");let o=require("@nextblock-cms/db/server"),s=require("next/navigation"),c=require("next/cache");function l(e){return Object.entries(e||{}).reduce((e,[t,n])=>{let r=t.trim().toLowerCase(),i=n.trim();return r&&i&&(e[r]=i),e},{})}async function u(e){let t=(0,o.createClient)(),{data:{user:n}}=await t.auth.getUser();if(!n)throw Error(`Unauthorized`);let{data:r}=await t.from(`profiles`).select(`role`).eq(`id`,n.id).single();if(!r||r.role!==`ADMIN`)throw Error(`Forbidden`);let a=e.getAll(`trackQuantities`).includes(`true`),l=await i.getEcommerceInventorySettings(t),{error:u}=await i.upsertEcommerceInventorySettings(t,{trackQuantities:a,enableTaxes:l.enableTaxes,taxCalculationMode:l.taxCalculationMode});if(u)throw Error(u.message);(0,c.revalidatePath)(`/cms/shipping`),(0,s.redirect)(`/cms/shipping?success=Inventory settings updated`)}function d(e){let n=new Map;for(let i of e){let e=t.normalizeCountryCode(i.country_code);if(!e)continue;let a=r.normalizeSubdivisionCode(e,i.state_code)||null,o=`${e}:${a??`*`}`;n.set(o,{country_code:e,state_code:a})}return[...n.values()]}async function f(e){let{data:t,error:n}=await e.from(`currencies`).select(`code, is_default`).eq(`is_active`,!0).order(`is_default`,{ascending:!1}).order(`code`,{ascending:!0});return n?{error:n.message}:{currencies:t||[]}}async function p(e,t,n){let r=await a.requireEcomAdmin(),i=d(n),{data:o,error:s}=await r.from(`shipping_zones`).insert({name:e,priority_order:t}).select().single();if(s||!o)return{error:s?.message||`Failed to create zone`};if(i.length>0){let e=i.map(e=>({zone_id:o.id,country_code:e.country_code,state_code:e.state_code??null})),{error:t}=await r.from(`shipping_zone_locations`).insert(e);if(t)return{error:t.message}}return(0,c.revalidatePath)(`/cms/shipping`),{success:!0}}async function m(e,t,n,r){let i=await a.requireEcomAdmin(),o=d(r),{error:s}=await i.from(`shipping_zones`).update({name:t,priority_order:n,updated_at:new Date().toISOString()}).eq(`id`,e);if(s)return{error:s.message||`Failed to update zone`};let{error:l}=await i.from(`shipping_zone_locations`).delete().eq(`zone_id`,e);if(l)return{error:`Failed to refresh locations`};if(o.length>0){let t=o.map(t=>({zone_id:e,country_code:t.country_code,state_code:t.state_code??null})),{error:n}=await i.from(`shipping_zone_locations`).insert(t);if(n)return{error:n.message}}return(0,c.revalidatePath)(`/cms/shipping`),{success:!0}}async function h(e){let{error:t}=await(await a.requireEcomAdmin()).from(`shipping_zones`).delete().eq(`id`,e);return t?{error:t.message}:((0,c.revalidatePath)(`/cms/shipping`),{success:!0})}async function g(t,r){let i=await a.requireEcomAdmin(),o=await f(i);if(`error`in o)return{error:o.error};let s=n.sanitizeShippingRateAmountMaps({currencies:o.currencies.map(t=>e.normalizeCurrencyRecord(t)),mode:r.currencyPricingMode,sourceCurrencyCode:r.sourceCurrencyCode,costAmounts:r.costAmounts,minOrderAmounts:r.minOrderAmounts,fallbackCostAmount:r.cost,fallbackMinOrderAmount:r.minOrderAmount}),{error:u}=await i.from(`shipping_zone_methods`).insert({zone_id:t,name:r.name.trim(),name_translations:l(r.nameTranslations),method_type:r.type,currency_pricing_mode:s.mode,cost_amount:s.costAmounts[s.sourceCurrencyCode],cost_amounts:s.costAmounts,cost_currency:s.sourceCurrencyCode,min_order_amount:s.minOrderAmounts[s.sourceCurrencyCode],min_order_amounts:s.minOrderAmounts});return u?{error:u.message}:((0,c.revalidatePath)(`/cms/shipping`),{success:!0})}async function _(t,r){let i=await a.requireEcomAdmin(),o=await f(i);if(`error`in o)return{error:o.error};let s=n.sanitizeShippingRateAmountMaps({currencies:o.currencies.map(t=>e.normalizeCurrencyRecord(t)),mode:r.currencyPricingMode,sourceCurrencyCode:r.sourceCurrencyCode,costAmounts:r.costAmounts,minOrderAmounts:r.minOrderAmounts,fallbackCostAmount:r.cost,fallbackMinOrderAmount:r.minOrderAmount}),{error:u}=await i.from(`shipping_zone_methods`).update({name:r.name.trim(),name_translations:l(r.nameTranslations),method_type:r.type,currency_pricing_mode:s.mode,cost_amount:s.costAmounts[s.sourceCurrencyCode],cost_amounts:s.costAmounts,cost_currency:s.sourceCurrencyCode,min_order_amount:s.minOrderAmounts[s.sourceCurrencyCode],min_order_amounts:s.minOrderAmounts,updated_at:new Date().toISOString()}).eq(`id`,t);return u?{error:u.message}:((0,c.revalidatePath)(`/cms/shipping`),{success:!0})}async function v(e){let{error:t}=await(await a.requireEcomAdmin()).from(`shipping_zone_methods`).delete().eq(`id`,e);return t?{error:t.message}:((0,c.revalidatePath)(`/cms/shipping`),{success:!0})}exports.createShippingRate=g,exports.createShippingZone=p,exports.deleteShippingRate=v,exports.deleteShippingZone=h,exports.updateInventoryTrackingAction=u,exports.updateShippingRate=_,exports.updateShippingZone=m;
|
|
@@ -4,7 +4,8 @@ import { normalizeCountryCode as t } from "../../../countries.es.js";
|
|
|
4
4
|
import { sanitizeShippingRateAmountMaps as n } from "../../../shipping-rate-currency.es.js";
|
|
5
5
|
import { normalizeSubdivisionCode as r } from "../../../states.es.js";
|
|
6
6
|
import { getEcommerceInventorySettings as i, upsertEcommerceInventorySettings as a } from "../../../inventory-settings.es.js";
|
|
7
|
-
import {
|
|
7
|
+
import { requireEcomAdmin as o } from "../../../server-actions/require-ecom-role.es.js";
|
|
8
|
+
import { createClient as s } from "@nextblock-cms/db/server";
|
|
8
9
|
import { redirect as c } from "next/navigation";
|
|
9
10
|
import { revalidatePath as l } from "next/cache";
|
|
10
11
|
//#region src/lib/pages/cms/shipping/server-actions.ts
|
|
@@ -15,12 +16,12 @@ function u(e) {
|
|
|
15
16
|
}, {});
|
|
16
17
|
}
|
|
17
18
|
async function d(e) {
|
|
18
|
-
let t =
|
|
19
|
+
let t = s(), { data: { user: n } } = await t.auth.getUser();
|
|
19
20
|
if (!n) throw Error("Unauthorized");
|
|
20
21
|
let { data: r } = await t.from("profiles").select("role").eq("id", n.id).single();
|
|
21
22
|
if (!r || r.role !== "ADMIN") throw Error("Forbidden");
|
|
22
|
-
let
|
|
23
|
-
trackQuantities:
|
|
23
|
+
let o = e.getAll("trackQuantities").includes("true"), u = await i(t), { error: d } = await a(t, {
|
|
24
|
+
trackQuantities: o,
|
|
24
25
|
enableTaxes: u.enableTaxes,
|
|
25
26
|
taxCalculationMode: u.taxCalculationMode
|
|
26
27
|
});
|
|
@@ -45,11 +46,11 @@ async function p(e) {
|
|
|
45
46
|
return n ? { error: n.message } : { currencies: t || [] };
|
|
46
47
|
}
|
|
47
48
|
async function m(e, t, n) {
|
|
48
|
-
let r =
|
|
49
|
+
let r = await o(), i = f(n), { data: a, error: s } = await r.from("shipping_zones").insert({
|
|
49
50
|
name: e,
|
|
50
51
|
priority_order: t
|
|
51
52
|
}).select().single();
|
|
52
|
-
if (
|
|
53
|
+
if (s || !a) return { error: s?.message || "Failed to create zone" };
|
|
53
54
|
if (i.length > 0) {
|
|
54
55
|
let e = i.map((e) => ({
|
|
55
56
|
zone_id: a.id,
|
|
@@ -61,12 +62,12 @@ async function m(e, t, n) {
|
|
|
61
62
|
return l("/cms/shipping"), { success: !0 };
|
|
62
63
|
}
|
|
63
64
|
async function h(e, t, n, r) {
|
|
64
|
-
let i =
|
|
65
|
+
let i = await o(), a = f(r), { error: s } = await i.from("shipping_zones").update({
|
|
65
66
|
name: t,
|
|
66
67
|
priority_order: n,
|
|
67
68
|
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
68
69
|
}).eq("id", e);
|
|
69
|
-
if (
|
|
70
|
+
if (s) return { error: s.message || "Failed to update zone" };
|
|
70
71
|
let { error: c } = await i.from("shipping_zone_locations").delete().eq("zone_id", e);
|
|
71
72
|
if (c) return { error: "Failed to refresh locations" };
|
|
72
73
|
if (a.length > 0) {
|
|
@@ -80,13 +81,13 @@ async function h(e, t, n, r) {
|
|
|
80
81
|
return l("/cms/shipping"), { success: !0 };
|
|
81
82
|
}
|
|
82
83
|
async function g(e) {
|
|
83
|
-
let { error: t } = await
|
|
84
|
+
let { error: t } = await (await o()).from("shipping_zones").delete().eq("id", e);
|
|
84
85
|
return t ? { error: t.message } : (l("/cms/shipping"), { success: !0 });
|
|
85
86
|
}
|
|
86
87
|
async function _(t, r) {
|
|
87
|
-
let i =
|
|
88
|
+
let i = await o(), a = await p(i);
|
|
88
89
|
if ("error" in a) return { error: a.error };
|
|
89
|
-
let
|
|
90
|
+
let s = n({
|
|
90
91
|
currencies: a.currencies.map((t) => e(t)),
|
|
91
92
|
mode: r.currencyPricingMode,
|
|
92
93
|
sourceCurrencyCode: r.sourceCurrencyCode,
|
|
@@ -99,19 +100,19 @@ async function _(t, r) {
|
|
|
99
100
|
name: r.name.trim(),
|
|
100
101
|
name_translations: u(r.nameTranslations),
|
|
101
102
|
method_type: r.type,
|
|
102
|
-
currency_pricing_mode:
|
|
103
|
-
cost_amount:
|
|
104
|
-
cost_amounts:
|
|
105
|
-
cost_currency:
|
|
106
|
-
min_order_amount:
|
|
107
|
-
min_order_amounts:
|
|
103
|
+
currency_pricing_mode: s.mode,
|
|
104
|
+
cost_amount: s.costAmounts[s.sourceCurrencyCode],
|
|
105
|
+
cost_amounts: s.costAmounts,
|
|
106
|
+
cost_currency: s.sourceCurrencyCode,
|
|
107
|
+
min_order_amount: s.minOrderAmounts[s.sourceCurrencyCode],
|
|
108
|
+
min_order_amounts: s.minOrderAmounts
|
|
108
109
|
});
|
|
109
110
|
return c ? { error: c.message } : (l("/cms/shipping"), { success: !0 });
|
|
110
111
|
}
|
|
111
112
|
async function v(t, r) {
|
|
112
|
-
let i =
|
|
113
|
+
let i = await o(), a = await p(i);
|
|
113
114
|
if ("error" in a) return { error: a.error };
|
|
114
|
-
let
|
|
115
|
+
let s = n({
|
|
115
116
|
currencies: a.currencies.map((t) => e(t)),
|
|
116
117
|
mode: r.currencyPricingMode,
|
|
117
118
|
sourceCurrencyCode: r.sourceCurrencyCode,
|
|
@@ -123,18 +124,18 @@ async function v(t, r) {
|
|
|
123
124
|
name: r.name.trim(),
|
|
124
125
|
name_translations: u(r.nameTranslations),
|
|
125
126
|
method_type: r.type,
|
|
126
|
-
currency_pricing_mode:
|
|
127
|
-
cost_amount:
|
|
128
|
-
cost_amounts:
|
|
129
|
-
cost_currency:
|
|
130
|
-
min_order_amount:
|
|
131
|
-
min_order_amounts:
|
|
127
|
+
currency_pricing_mode: s.mode,
|
|
128
|
+
cost_amount: s.costAmounts[s.sourceCurrencyCode],
|
|
129
|
+
cost_amounts: s.costAmounts,
|
|
130
|
+
cost_currency: s.sourceCurrencyCode,
|
|
131
|
+
min_order_amount: s.minOrderAmounts[s.sourceCurrencyCode],
|
|
132
|
+
min_order_amounts: s.minOrderAmounts,
|
|
132
133
|
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
133
134
|
}).eq("id", t);
|
|
134
135
|
return c ? { error: c.message } : (l("/cms/shipping"), { success: !0 });
|
|
135
136
|
}
|
|
136
137
|
async function y(e) {
|
|
137
|
-
let { error: t } = await
|
|
138
|
+
let { error: t } = await (await o()).from("shipping_zone_methods").delete().eq("id", e);
|
|
138
139
|
return t ? { error: t.message } : (l("/cms/shipping"), { success: !0 });
|
|
139
140
|
}
|
|
140
141
|
//#endregion
|
package/lib/payment-config.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
const e=require("./server-actions/require-ecom-role.cjs");let t=require("@nextblock-cms/db/server");var n=`payment_secret`,r=`payment_public`,i=6e4,a=null;function o(e){return e&&typeof e==`object`&&!Array.isArray(e)?e:{}}async function s(e=!1){let s=Date.now();if(!e&&a&&s-a.at<i)return{secret:a.secret,public:a.public};let c={},l={};try{let e=(0,t.getServiceRoleSupabaseClient)(),[{data:i},{data:a}]=await Promise.all([e.from(`site_settings`).select(`value`).eq(`key`,n).maybeSingle(),e.from(`site_settings`).select(`value`).eq(`key`,r).maybeSingle()]);c=o(i?.value),l=o(a?.value)}catch{}return a={at:s,secret:c,public:l},{secret:c,public:l}}function c(){a=null}function l(e,n){return(0,t.tryDecryptWithEnvKey)(e[n])}async function u(){let{secret:e}=await s();return(0,t.resolveConfigValue)(l(e,`stripeSecretKey`),`STRIPE_SECRET_KEY`)}async function d(){let{secret:e}=await s();return(0,t.resolveConfigValue)(l(e,`stripeWebhookSecret`),`STRIPE_WEBHOOK_SECRET`)}async function f(){let{public:e}=await s(),n=o(e.stripe).publishableKey;return(0,t.resolveConfigValue)(typeof n==`string`?n:null,`NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY`)}async function p(){try{let{secret:e,public:t}=await s(),n=o(t.freemius),r=(e,t)=>{t&&t.trim()&&(process.env[e]=t.trim())};r(`FREEMIUS_SECRET_KEY`,l(e,`freemiusSecretKey`)),r(`FREEMIUS_API_KEY`,l(e,`freemiusApiKey`)),r(`FREEMIUS_ECOMMERCE_SANDBOX_SECRET_KEY`,l(e,`freemiusSandboxSecretKey`)),r(`FREEMIUS_PUBLIC_KEY`,typeof n.publicKey==`string`?n.publicKey:null),r(`FREEMIUS_PRODUCT_ID`,typeof n.productId==`string`?n.productId:null),r(`FREEMIUS_DEVELOPER_ID`,typeof n.developerId==`string`?n.developerId:null)}catch(e){console.warn(`[payment-config] Could not hydrate Freemius credentials from the database:`,e)}}async function m(){let{secret:e,public:n}=await s(),r=o(n.freemius),i=o(n.stripe),a=[];(0,t.resolveConfigValue)(l(e,`stripeSecretKey`),`STRIPE_SECRET_KEY`)||a.push(`Secret key`),(0,t.resolveConfigValue)(typeof i.publishableKey==`string`?i.publishableKey:null,`NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY`)||a.push(`Publishable key`),(0,t.resolveConfigValue)(l(e,`stripeWebhookSecret`),`STRIPE_WEBHOOK_SECRET`)||a.push(`Webhook secret`);let c=[];return(0,t.resolveConfigValue)(typeof r.publicKey==`string`?r.publicKey:null,`FREEMIUS_PUBLIC_KEY`)||c.push(`Public key`),(0,t.resolveConfigValue)(l(e,`freemiusSecretKey`),`FREEMIUS_SECRET_KEY`)||c.push(`Secret key`),{stripe:{hasKeys:a.length===0,missing:a},freemius:{hasKeys:c.length===0,missing:c}}}async function h(){let i=await e.getEcomActorRole()===`ADMIN`?(0,t.getServiceRoleSupabaseClient)():(0,t.createClient)(),[{data:a},{data:s}]=await Promise.all([i.from(`site_settings`).select(`value`).eq(`key`,n).maybeSingle(),i.from(`site_settings`).select(`value`).eq(`key`,r).maybeSingle()]),c=o(a?.value),l=o(s?.value),u=o(l.stripe),d=o(l.freemius),f=e=>typeof e==`string`?e:``;return{stripe:{publishableKey:f(u.publishableKey),hasSecretKey:(0,t.getSecretEnvelopeStatus)(c.stripeSecretKey).hasStoredValue,hasWebhookSecret:(0,t.getSecretEnvelopeStatus)(c.stripeWebhookSecret).hasStoredValue},freemius:{developerId:f(d.developerId),publicKey:f(d.publicKey),productId:f(d.productId),hasSecretKey:(0,t.getSecretEnvelopeStatus)(c.freemiusSecretKey).hasStoredValue,hasApiKey:(0,t.getSecretEnvelopeStatus)(c.freemiusApiKey).hasStoredValue},envFallbackActive:!(c.stripeSecretKey||!process.env.STRIPE_SECRET_KEY)}}async function g(i){let a=await e.requireEcomAdmin(),s={stripe:{publishableKey:i.stripe.publishableKey.trim()},freemius:{developerId:i.freemius.developerId.trim(),publicKey:i.freemius.publicKey.trim(),productId:i.freemius.productId.trim(),sandboxEnabled:!1}},{error:l}=await a.from(`site_settings`).upsert({key:r,value:s});if(l)throw console.error(`Error saving payment_public settings:`,l.message),Error(`Failed to save payment settings.`);let u=[[`stripeSecretKey`,i.stripe.secretKey],[`stripeWebhookSecret`,i.stripe.webhookSecret],[`freemiusSecretKey`,i.freemius.secretKey],[`freemiusApiKey`,i.freemius.apiKey]];if(u.some(([,e])=>e&&e.trim())){if((0,t.isSandboxEnvironment)())throw Error(`The sandbox cannot store live payment credentials.`);let{data:e}=await a.from(`site_settings`).select(`value`).eq(`key`,n).maybeSingle(),r={...o(e?.value)};for(let[e,n]of u)n&&n.trim()&&(r[e]=(0,t.encryptWithEnvKey)(n.trim()));let{error:i}=await a.from(`site_settings`).upsert({key:n,value:r});if(i)throw console.error(`Error saving payment_secret settings:`,i.message),Error(`Failed to save payment credentials.`)}c()}exports.clearPaymentConfigCache=c,exports.getPaymentConfigStatus=m,exports.getPaymentCredentialsView=h,exports.hydrateFreemiusEnvFromDb=p,exports.resolveStripePublishableKey=f,exports.resolveStripeSecretKey=u,exports.resolveStripeWebhookSecret=d,exports.savePaymentCredentials=g;
|
package/lib/payment-config.d.ts
CHANGED
|
@@ -51,7 +51,9 @@ export interface SavePaymentCredentialsInput {
|
|
|
51
51
|
/**
|
|
52
52
|
* Persist payment credentials. Public fields always overwrite; secret fields are
|
|
53
53
|
* encrypted and only written when a new value is supplied (blank keeps the stored
|
|
54
|
-
* secret). Refuses to store real secrets in the sandbox.
|
|
55
|
-
*
|
|
54
|
+
* secret). Refuses to store real secrets in the sandbox. Enforces ADMIN itself (throws
|
|
55
|
+
* otherwise) and writes with the service role: `payment_secret` is in the ADMIN-only write
|
|
56
|
+
* tier that migration 02023 gates behind `is_admin_mfa()`, which a "remember this device"
|
|
57
|
+
* (aal1) admin cannot satisfy through the cookie client.
|
|
56
58
|
*/
|
|
57
59
|
export declare function savePaymentCredentials(input: SavePaymentCredentialsInput): Promise<void>;
|