@fayz-ai/shop 0.6.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -176,6 +176,7 @@ function now() {
176
176
  }
177
177
  var ORDERS_KEY = "fayz.shop.mock.orders.v1";
178
178
  var CUSTOMERS_KEY = "fayz.shop.mock.customers.v1";
179
+ var ENQUIRIES_KEY = "fayz.shop.mock.enquiries.v1";
179
180
  function loadStored(key) {
180
181
  try {
181
182
  if (typeof localStorage === "undefined") return [];
@@ -196,6 +197,7 @@ var MockShopProvider = class {
196
197
  constructor(seed) {
197
198
  this.orders = loadStored(ORDERS_KEY);
198
199
  this.customers = loadStored(CUSTOMERS_KEY);
200
+ this.enquiries = loadStored(ENQUIRIES_KEY);
199
201
  this.products = (seed?.products ?? MOCK_PRODUCTS).map((p) => ({ ...p }));
200
202
  this.categories = (seed?.categories ?? MOCK_CATEGORIES).map((c) => ({ ...c }));
201
203
  this.discounts = (seed?.discounts ?? MOCK_DISCOUNTS).map((d) => ({ ...d }));
@@ -208,12 +210,18 @@ var MockShopProvider = class {
208
210
  syncCustomers() {
209
211
  this.customers = loadStored(CUSTOMERS_KEY);
210
212
  }
213
+ syncEnquiries() {
214
+ this.enquiries = loadStored(ENQUIRIES_KEY);
215
+ }
211
216
  persistOrders() {
212
217
  store(ORDERS_KEY, this.orders);
213
218
  }
214
219
  persistCustomers() {
215
220
  store(CUSTOMERS_KEY, this.customers);
216
221
  }
222
+ persistEnquiries() {
223
+ store(ENQUIRIES_KEY, this.enquiries);
224
+ }
217
225
  // ---------------------------------------------------------------------------
218
226
  // Products
219
227
  // ---------------------------------------------------------------------------
@@ -268,6 +276,44 @@ var MockShopProvider = class {
268
276
  }
269
277
  async deleteProductImage(_imageId) {
270
278
  }
279
+ async createProductEnquiry(input) {
280
+ this.syncEnquiries();
281
+ const ts = now();
282
+ const enquiry = {
283
+ id: uid(),
284
+ tenantId: "mock",
285
+ productId: input.productId ?? null,
286
+ productName: input.productName,
287
+ productSlug: input.productSlug ?? null,
288
+ customerName: input.customerName,
289
+ customerEmail: input.customerEmail,
290
+ customerPhone: input.customerPhone ?? null,
291
+ subject: input.subject ?? null,
292
+ message: input.message,
293
+ sourceUrl: input.sourceUrl ?? null,
294
+ status: "new",
295
+ metadata: input.metadata ?? {},
296
+ createdAt: ts,
297
+ updatedAt: ts
298
+ };
299
+ this.enquiries.unshift(enquiry);
300
+ this.persistEnquiries();
301
+ return enquiry;
302
+ }
303
+ async listProductEnquiries(opts) {
304
+ this.syncEnquiries();
305
+ let list = [...this.enquiries];
306
+ if (opts?.productId) list = list.filter((e) => e.productId === opts.productId);
307
+ if (opts?.customerEmail) {
308
+ const email = opts.customerEmail.toLowerCase();
309
+ list = list.filter((e) => e.customerEmail.toLowerCase() === email);
310
+ }
311
+ if (opts?.status) list = list.filter((e) => e.status === opts.status);
312
+ list.sort((a, b) => b.createdAt.localeCompare(a.createdAt));
313
+ const offset = opts?.offset ?? 0;
314
+ if (offset || opts?.limit) list = list.slice(offset, opts?.limit ? offset + opts.limit : void 0);
315
+ return list;
316
+ }
271
317
  // ---------------------------------------------------------------------------
272
318
  // Categories
273
319
  // ---------------------------------------------------------------------------
@@ -603,6 +649,17 @@ function getShopTenantId() {
603
649
  }
604
650
  }
605
651
 
652
+ // src/tables.ts
653
+ var T = {
654
+ products: "plg_shop_products",
655
+ productImages: "plg_shop_product_images",
656
+ categories: "plg_shop_categories",
657
+ orders: "plg_shop_orders",
658
+ orderItems: "plg_shop_order_items",
659
+ customers: "plg_shop_customers",
660
+ discounts: "plg_shop_discounts"
661
+ };
662
+
606
663
  // src/supabase-provider.ts
607
664
  function getDb() {
608
665
  const supabase = getSupabaseClientOptional();
@@ -730,7 +787,7 @@ var SupabaseShopProvider = class {
730
787
  async listProducts(options) {
731
788
  const db = getDb();
732
789
  const tenantId = getTenantId();
733
- let q = db.from("shop_products").select("*, images:shop_product_images(*)");
790
+ let q = db.from(T.products).select(`*, images:${T.productImages}(*)`);
734
791
  if (tenantId) q = q.eq("tenant_id", tenantId);
735
792
  if (options?.status) q = q.eq("status", options.status);
736
793
  if (options?.categoryId) q = q.eq("category_id", options.categoryId);
@@ -745,14 +802,14 @@ var SupabaseShopProvider = class {
745
802
  }
746
803
  async getProduct(id) {
747
804
  const db = getDb();
748
- const { data, error } = await db.from("shop_products").select("*, images:shop_product_images(*)").eq("id", id).maybeSingle();
805
+ const { data, error } = await db.from(T.products).select(`*, images:${T.productImages}(*)`).eq("id", id).maybeSingle();
749
806
  if (error) throw error;
750
807
  return data ? rowToProduct(data) : null;
751
808
  }
752
809
  async createProduct(input) {
753
810
  const db = getDb();
754
811
  const tenantId = getTenantId();
755
- const { data, error } = await db.from("shop_products").insert({
812
+ const { data, error } = await db.from(T.products).insert({
756
813
  tenant_id: tenantId,
757
814
  name: input.name,
758
815
  slug: input.slug ?? slugify(input.name),
@@ -769,7 +826,7 @@ var SupabaseShopProvider = class {
769
826
  is_physical: input.isPhysical ?? true,
770
827
  weight: input.weight ?? null,
771
828
  weight_unit: input.weightUnit ?? "kg"
772
- }).select("*, images:shop_product_images(*)").single();
829
+ }).select(`*, images:${T.productImages}(*)`).single();
773
830
  if (error) throw error;
774
831
  return rowToProduct(data);
775
832
  }
@@ -791,12 +848,12 @@ var SupabaseShopProvider = class {
791
848
  if (input.categoryId !== void 0) updates.category_id = input.categoryId;
792
849
  if (input.isPhysical !== void 0) updates.is_physical = input.isPhysical;
793
850
  if (input.weight !== void 0) updates.weight = input.weight;
794
- const { data, error } = await db.from("shop_products").update(updates).eq("id", id).select("*, images:shop_product_images(*)").single();
851
+ const { data, error } = await db.from(T.products).update(updates).eq("id", id).select(`*, images:${T.productImages}(*)`).single();
795
852
  if (error) throw error;
796
853
  return rowToProduct(data);
797
854
  }
798
855
  async deleteProduct(id) {
799
- const { error } = await getDb().from("shop_products").delete().eq("id", id);
856
+ const { error } = await getDb().from(T.products).delete().eq("id", id);
800
857
  if (error) throw error;
801
858
  }
802
859
  async uploadProductImage(productId, file) {
@@ -806,12 +863,12 @@ var SupabaseShopProvider = class {
806
863
  const { error: uploadErr } = await db.storage.from("shop-images").upload(path, file);
807
864
  if (uploadErr) throw uploadErr;
808
865
  const { data: { publicUrl } } = db.storage.from("shop-images").getPublicUrl(path);
809
- const { data, error } = await db.from("shop_product_images").insert({ product_id: productId, tenant_id: tenantId, url: publicUrl, sort_order: 0, is_primary: false }).select().single();
866
+ const { data, error } = await db.from(T.productImages).insert({ product_id: productId, tenant_id: tenantId, url: publicUrl, sort_order: 0, is_primary: false }).select().single();
810
867
  if (error) throw error;
811
868
  return rowToImage(data);
812
869
  }
813
870
  async deleteProductImage(imageId) {
814
- const { error } = await getDb().from("shop_product_images").delete().eq("id", imageId);
871
+ const { error } = await getDb().from(T.productImages).delete().eq("id", imageId);
815
872
  if (error) throw error;
816
873
  }
817
874
  // ---------------------------------------------------------------------------
@@ -820,7 +877,7 @@ var SupabaseShopProvider = class {
820
877
  async listCategories() {
821
878
  const db = getDb();
822
879
  const tenantId = getTenantId();
823
- let q = db.from("shop_categories").select("*").order("sort_order", { ascending: true });
880
+ let q = db.from(T.categories).select("*").order("sort_order", { ascending: true });
824
881
  if (tenantId) q = q.eq("tenant_id", tenantId);
825
882
  const { data, error } = await q;
826
883
  if (error) throw error;
@@ -828,7 +885,7 @@ var SupabaseShopProvider = class {
828
885
  }
829
886
  async createCategory(input) {
830
887
  const db = getDb();
831
- const { data, error } = await db.from("shop_categories").insert({ tenant_id: getTenantId(), name: input.name, slug: input.slug ?? slugify(input.name), description: input.description ?? null, parent_id: input.parentId ?? null, sort_order: input.sortOrder ?? 0 }).select().single();
888
+ const { data, error } = await db.from(T.categories).insert({ tenant_id: getTenantId(), name: input.name, slug: input.slug ?? slugify(input.name), description: input.description ?? null, parent_id: input.parentId ?? null, sort_order: input.sortOrder ?? 0 }).select().single();
832
889
  if (error) throw error;
833
890
  return rowToCategory(data);
834
891
  }
@@ -840,12 +897,12 @@ var SupabaseShopProvider = class {
840
897
  if (input.description !== void 0) updates.description = input.description;
841
898
  if (input.parentId !== void 0) updates.parent_id = input.parentId;
842
899
  if (input.sortOrder !== void 0) updates.sort_order = input.sortOrder;
843
- const { data, error } = await db.from("shop_categories").update(updates).eq("id", id).select().single();
900
+ const { data, error } = await db.from(T.categories).update(updates).eq("id", id).select().single();
844
901
  if (error) throw error;
845
902
  return rowToCategory(data);
846
903
  }
847
904
  async deleteCategory(id) {
848
- const { error } = await getDb().from("shop_categories").delete().eq("id", id);
905
+ const { error } = await getDb().from(T.categories).delete().eq("id", id);
849
906
  if (error) throw error;
850
907
  }
851
908
  // ---------------------------------------------------------------------------
@@ -854,7 +911,7 @@ var SupabaseShopProvider = class {
854
911
  async listOrders(options) {
855
912
  const db = getDb();
856
913
  const tenantId = getTenantId();
857
- let q = db.from("shop_orders").select("*, items:shop_order_items(*)");
914
+ let q = db.from(T.orders).select(`*, items:${T.orderItems}(*)`);
858
915
  if (tenantId) q = q.eq("tenant_id", tenantId);
859
916
  if (options?.status) q = q.eq("status", options.status);
860
917
  if (options?.financialStatus) q = q.eq("financial_status", options.financialStatus);
@@ -869,7 +926,7 @@ var SupabaseShopProvider = class {
869
926
  return (data ?? []).map(rowToOrder);
870
927
  }
871
928
  async getOrder(id) {
872
- const { data, error } = await getDb().from("shop_orders").select("*, items:shop_order_items(*)").eq("id", id).maybeSingle();
929
+ const { data, error } = await getDb().from(T.orders).select(`*, items:${T.orderItems}(*)`).eq("id", id).maybeSingle();
873
930
  if (error) throw error;
874
931
  return data ? rowToOrder(data) : null;
875
932
  }
@@ -880,10 +937,10 @@ var SupabaseShopProvider = class {
880
937
  const discountTotal = input.discountTotal ?? 0;
881
938
  const shippingTotal = input.shippingTotal ?? 0;
882
939
  const total = Math.round((subtotal - discountTotal + shippingTotal) * 100) / 100;
883
- const { data: order, error: orderErr } = await db.from("shop_orders").insert({ tenant_id: tenantId, customer_id: input.customerId ?? null, customer_name: input.customerName ?? null, customer_email: input.customerEmail ?? null, currency: input.currency ?? "BRL", notes: input.notes ?? null, subtotal, discount_total: discountTotal, shipping_total: shippingTotal, discount_code: input.discountCode ?? null, total, status: "open", financial_status: "pending", fulfillment_status: "unfulfilled" }).select().single();
940
+ const { data: order, error: orderErr } = await db.from(T.orders).insert({ tenant_id: tenantId, customer_id: input.customerId ?? null, customer_name: input.customerName ?? null, customer_email: input.customerEmail ?? null, currency: input.currency ?? "BRL", notes: input.notes ?? null, subtotal, discount_total: discountTotal, shipping_total: shippingTotal, discount_code: input.discountCode ?? null, total, status: "open", financial_status: "pending", fulfillment_status: "unfulfilled" }).select().single();
884
941
  if (orderErr) throw orderErr;
885
942
  const items = input.items.map((i) => ({ order_id: order.id, product_id: asUuid(i.productId), name: i.name, sku: i.sku ?? null, quantity: i.quantity, unit_price: i.unitPrice, total: i.quantity * i.unitPrice, image_url: i.imageUrl ?? null }));
886
- await db.from("shop_order_items").insert(items);
943
+ await db.from(T.orderItems).insert(items);
887
944
  return this.getOrder(order.id);
888
945
  }
889
946
  async updateOrder(id, input) {
@@ -892,7 +949,7 @@ var SupabaseShopProvider = class {
892
949
  if (input.financialStatus !== void 0) updates.financial_status = input.financialStatus;
893
950
  if (input.fulfillmentStatus !== void 0) updates.fulfillment_status = input.fulfillmentStatus;
894
951
  if (input.notes !== void 0) updates.notes = input.notes;
895
- const { error } = await getDb().from("shop_orders").update(updates).eq("id", id);
952
+ const { error } = await getDb().from(T.orders).update(updates).eq("id", id);
896
953
  if (error) throw error;
897
954
  return this.getOrder(id);
898
955
  }
@@ -925,7 +982,7 @@ var SupabaseShopProvider = class {
925
982
  async listCustomers(options) {
926
983
  const db = getDb();
927
984
  const tenantId = getTenantId();
928
- let q = db.from("shop_customers").select("*").order("first_name", { ascending: true });
985
+ let q = db.from(T.customers).select("*").order("first_name", { ascending: true });
929
986
  if (tenantId) q = q.eq("tenant_id", tenantId);
930
987
  if (options?.search) q = q.or(`first_name.ilike.%${options.search}%,last_name.ilike.%${options.search}%,email.ilike.%${options.search}%`);
931
988
  if (options?.limit) q = q.limit(options.limit);
@@ -934,12 +991,12 @@ var SupabaseShopProvider = class {
934
991
  return (data ?? []).map(rowToCustomer);
935
992
  }
936
993
  async getCustomer(id) {
937
- const { data, error } = await getDb().from("shop_customers").select("*").eq("id", id).maybeSingle();
994
+ const { data, error } = await getDb().from(T.customers).select("*").eq("id", id).maybeSingle();
938
995
  if (error) throw error;
939
996
  return data ? rowToCustomer(data) : null;
940
997
  }
941
998
  async createCustomer(input) {
942
- const { data, error } = await getDb().from("shop_customers").insert({ tenant_id: getTenantId(), first_name: input.firstName, last_name: input.lastName ?? "", email: input.email ?? null, phone: input.phone ?? null, notes: input.notes ?? null }).select().single();
999
+ const { data, error } = await getDb().from(T.customers).insert({ tenant_id: getTenantId(), first_name: input.firstName, last_name: input.lastName ?? "", email: input.email ?? null, phone: input.phone ?? null, notes: input.notes ?? null }).select().single();
943
1000
  if (error) throw error;
944
1001
  return rowToCustomer(data);
945
1002
  }
@@ -950,12 +1007,12 @@ var SupabaseShopProvider = class {
950
1007
  if (input.email !== void 0) updates.email = input.email;
951
1008
  if (input.phone !== void 0) updates.phone = input.phone;
952
1009
  if (input.notes !== void 0) updates.notes = input.notes;
953
- const { data, error } = await getDb().from("shop_customers").update(updates).eq("id", id).select().single();
1010
+ const { data, error } = await getDb().from(T.customers).update(updates).eq("id", id).select().single();
954
1011
  if (error) throw error;
955
1012
  return rowToCustomer(data);
956
1013
  }
957
1014
  async deleteCustomer(id) {
958
- const { error } = await getDb().from("shop_customers").delete().eq("id", id);
1015
+ const { error } = await getDb().from(T.customers).delete().eq("id", id);
959
1016
  if (error) throw error;
960
1017
  }
961
1018
  // Find-or-create + link to auth.uid server-side (SECURITY DEFINER RPC), so the
@@ -980,7 +1037,7 @@ var SupabaseShopProvider = class {
980
1037
  async listDiscounts(options) {
981
1038
  const db = getDb();
982
1039
  const tenantId = getTenantId();
983
- let q = db.from("shop_discounts").select("*").order("created_at", { ascending: false });
1040
+ let q = db.from(T.discounts).select("*").order("created_at", { ascending: false });
984
1041
  if (tenantId) q = q.eq("tenant_id", tenantId);
985
1042
  if (options?.status) q = q.eq("status", options.status);
986
1043
  if (options?.type) q = q.eq("type", options.type);
@@ -991,12 +1048,12 @@ var SupabaseShopProvider = class {
991
1048
  return (data ?? []).map(rowToDiscount);
992
1049
  }
993
1050
  async getDiscount(id) {
994
- const { data, error } = await getDb().from("shop_discounts").select("*").eq("id", id).maybeSingle();
1051
+ const { data, error } = await getDb().from(T.discounts).select("*").eq("id", id).maybeSingle();
995
1052
  if (error) throw error;
996
1053
  return data ? rowToDiscount(data) : null;
997
1054
  }
998
1055
  async createDiscount(input) {
999
- const { data, error } = await getDb().from("shop_discounts").insert({ tenant_id: getTenantId(), title: input.title, code: input.code ?? null, type: input.type, method: input.method ?? "code", value: input.value, usage_limit: input.usageLimit ?? null, once_per_customer: input.oncePerCustomer ?? false, starts_at: input.startsAt ?? (/* @__PURE__ */ new Date()).toISOString(), ends_at: input.endsAt ?? null, status: input.status ?? "active", times_used: 0 }).select().single();
1056
+ const { data, error } = await getDb().from(T.discounts).insert({ tenant_id: getTenantId(), title: input.title, code: input.code ?? null, type: input.type, method: input.method ?? "code", value: input.value, usage_limit: input.usageLimit ?? null, once_per_customer: input.oncePerCustomer ?? false, starts_at: input.startsAt ?? (/* @__PURE__ */ new Date()).toISOString(), ends_at: input.endsAt ?? null, status: input.status ?? "active", times_used: 0 }).select().single();
1000
1057
  if (error) throw error;
1001
1058
  return rowToDiscount(data);
1002
1059
  }
@@ -1009,12 +1066,12 @@ var SupabaseShopProvider = class {
1009
1066
  if (input.usageLimit !== void 0) updates.usage_limit = input.usageLimit;
1010
1067
  if (input.status !== void 0) updates.status = input.status;
1011
1068
  if (input.endsAt !== void 0) updates.ends_at = input.endsAt;
1012
- const { data, error } = await getDb().from("shop_discounts").update(updates).eq("id", id).select().single();
1069
+ const { data, error } = await getDb().from(T.discounts).update(updates).eq("id", id).select().single();
1013
1070
  if (error) throw error;
1014
1071
  return rowToDiscount(data);
1015
1072
  }
1016
1073
  async deleteDiscount(id) {
1017
- const { error } = await getDb().from("shop_discounts").delete().eq("id", id);
1074
+ const { error } = await getDb().from(T.discounts).delete().eq("id", id);
1018
1075
  if (error) throw error;
1019
1076
  }
1020
1077
  };