@fayz-ai/shop 0.7.0 → 0.8.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/README.md CHANGED
@@ -5,6 +5,8 @@
5
5
  [![npm](https://img.shields.io/npm/v/@fayz-ai/shop.svg)](https://www.npmjs.com/package/@fayz-ai/shop)
6
6
  [![license](https://img.shields.io/npm/l/@fayz-ai/shop.svg)](https://github.com/FayaLabs/fayz-sdk/blob/main/LICENSE)
7
7
 
8
+ **Status:** beta — published to npm and used across Fayz dogfood apps. Pre-1.0: minor APIs may change before 1.0.
9
+
8
10
  `@fayz-ai/shop` is the headless ecommerce engine: a `ShopProvider` contract plus the domain types for products, carts, orders, customers, discounts, and shipping. It owns *what commerce means* so the storefront (`@fayz-ai/storefront`) and admin surfaces only have to render it.
9
11
 
10
12
  It's provider-first by design. Ship a demo on `createMockShopProvider`, then drop in `createSupabaseShopProvider` (or your own `ShopProvider`) for real data — the UI doesn't change. Tenancy is resolved through a pluggable resolver, so the same engine serves one store or a marketplace of thousands.
package/dist/index.cjs CHANGED
@@ -390,6 +390,11 @@ var MockShopProvider = class {
390
390
  customerEmail: input.customerEmail ?? null,
391
391
  discountCode: input.discountCode ?? null,
392
392
  notes: input.notes ?? null,
393
+ shippingAddress: null,
394
+ // CreateOrderInput has no payment method — that is a PlaceOrderInput
395
+ // concern; the mock records none rather than inventing one.
396
+ paymentMethodKind: null,
397
+ paidAt: null,
393
398
  items: input.items.map((i) => ({ id: uid(), orderId, productId: i.productId ?? null, name: i.name, sku: i.sku ?? null, quantity: i.quantity, unitPrice: i.unitPrice, total: Math.round(i.quantity * i.unitPrice * 100) / 100, imageUrl: i.imageUrl ?? null })),
394
399
  createdAt: now(),
395
400
  updatedAt: now()
@@ -651,6 +656,21 @@ function getShopTenantId() {
651
656
  }
652
657
  }
653
658
 
659
+ // src/tables.ts
660
+ var T = {
661
+ products: "plg_shop_products",
662
+ productImages: "plg_shop_product_images",
663
+ categories: "plg_shop_categories",
664
+ orders: "plg_shop_orders",
665
+ orderItems: "plg_shop_order_items",
666
+ customers: "plg_shop_customers",
667
+ discounts: "plg_shop_discounts",
668
+ // Core, not plg_shop_*: a delivery zone is a fact about the business, and
669
+ // fulfilment and financial read it too. Same reasoning as addresses and
670
+ // orders — see migration 0021.
671
+ shippingZones: "shipping_zones"
672
+ };
673
+
654
674
  // src/supabase-provider.ts
655
675
  function getDb() {
656
676
  const supabase = core.getSupabaseClientOptional();
@@ -665,6 +685,40 @@ function asUuid(value) {
665
685
  if (!value) return null;
666
686
  return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value) ? value : null;
667
687
  }
688
+ function toPostalDigits(value) {
689
+ const digits = String(value ?? "").replace(/\D/g, "");
690
+ return digits ? digits.padStart(8, "0").slice(0, 8) : void 0;
691
+ }
692
+ function rowToShippingZone(row) {
693
+ return {
694
+ id: row.id,
695
+ tenantId: row.tenant_id,
696
+ name: row.name,
697
+ carrier: row.carrier ?? null,
698
+ postalFrom: String(row.postal_from ?? "").trim(),
699
+ postalTo: String(row.postal_to ?? "").trim(),
700
+ rate: Number(row.rate ?? 0),
701
+ freeAbove: row.free_above == null ? null : Number(row.free_above),
702
+ etaMinDays: row.eta_min_days ?? null,
703
+ etaMaxDays: row.eta_max_days ?? null,
704
+ active: row.active ?? true,
705
+ sortOrder: row.sort_order ?? 0
706
+ };
707
+ }
708
+ function shippingZonePayload(input) {
709
+ const payload = {};
710
+ if (input.name !== void 0) payload.name = input.name;
711
+ if (input.carrier !== void 0) payload.carrier = input.carrier || null;
712
+ if (input.postalFrom !== void 0) payload.postal_from = toPostalDigits(input.postalFrom);
713
+ if (input.postalTo !== void 0) payload.postal_to = toPostalDigits(input.postalTo);
714
+ if (input.rate !== void 0) payload.rate = input.rate;
715
+ if (input.freeAbove !== void 0) payload.free_above = input.freeAbove ?? null;
716
+ if (input.etaMinDays !== void 0) payload.eta_min_days = input.etaMinDays ?? null;
717
+ if (input.etaMaxDays !== void 0) payload.eta_max_days = input.etaMaxDays ?? null;
718
+ if (input.active !== void 0) payload.active = input.active;
719
+ if (input.sortOrder !== void 0) payload.sort_order = input.sortOrder;
720
+ return payload;
721
+ }
668
722
  function rowToProduct(row) {
669
723
  return {
670
724
  id: row.id,
@@ -713,6 +767,19 @@ function rowToCategory(row) {
713
767
  createdAt: row.created_at
714
768
  };
715
769
  }
770
+ function rowToOrderItem(row) {
771
+ return {
772
+ id: row.id,
773
+ orderId: row.order_id,
774
+ productId: row.product_id ?? null,
775
+ name: row.name,
776
+ sku: row.sku ?? null,
777
+ quantity: row.quantity ?? 0,
778
+ unitPrice: row.unit_price ?? 0,
779
+ total: row.total ?? 0,
780
+ imageUrl: row.image_url ?? null
781
+ };
782
+ }
716
783
  function rowToOrder(row) {
717
784
  return {
718
785
  id: row.id,
@@ -732,7 +799,10 @@ function rowToOrder(row) {
732
799
  customerEmail: row.customer_email,
733
800
  discountCode: row.discount_code,
734
801
  notes: row.notes,
735
- items: Array.isArray(row.items) ? row.items : [],
802
+ shippingAddress: row.shipping_address ?? null,
803
+ paymentMethodKind: row.payment_method_kind ?? null,
804
+ paidAt: row.paid_at ?? null,
805
+ items: Array.isArray(row.items) ? row.items.map(rowToOrderItem) : [],
736
806
  createdAt: row.created_at,
737
807
  updatedAt: row.updated_at
738
808
  };
@@ -778,7 +848,7 @@ var SupabaseShopProvider = class {
778
848
  async listProducts(options) {
779
849
  const db = getDb();
780
850
  const tenantId = getTenantId();
781
- let q = db.from("shop_products").select("*, images:shop_product_images(*)");
851
+ let q = db.from(T.products).select(`*, images:${T.productImages}(*)`);
782
852
  if (tenantId) q = q.eq("tenant_id", tenantId);
783
853
  if (options?.status) q = q.eq("status", options.status);
784
854
  if (options?.categoryId) q = q.eq("category_id", options.categoryId);
@@ -793,14 +863,14 @@ var SupabaseShopProvider = class {
793
863
  }
794
864
  async getProduct(id) {
795
865
  const db = getDb();
796
- const { data, error } = await db.from("shop_products").select("*, images:shop_product_images(*)").eq("id", id).maybeSingle();
866
+ const { data, error } = await db.from(T.products).select(`*, images:${T.productImages}(*)`).eq("id", id).maybeSingle();
797
867
  if (error) throw error;
798
868
  return data ? rowToProduct(data) : null;
799
869
  }
800
870
  async createProduct(input) {
801
871
  const db = getDb();
802
872
  const tenantId = getTenantId();
803
- const { data, error } = await db.from("shop_products").insert({
873
+ const { data, error } = await db.from(T.products).insert({
804
874
  tenant_id: tenantId,
805
875
  name: input.name,
806
876
  slug: input.slug ?? slugify(input.name),
@@ -817,7 +887,7 @@ var SupabaseShopProvider = class {
817
887
  is_physical: input.isPhysical ?? true,
818
888
  weight: input.weight ?? null,
819
889
  weight_unit: input.weightUnit ?? "kg"
820
- }).select("*, images:shop_product_images(*)").single();
890
+ }).select(`*, images:${T.productImages}(*)`).single();
821
891
  if (error) throw error;
822
892
  return rowToProduct(data);
823
893
  }
@@ -839,12 +909,12 @@ var SupabaseShopProvider = class {
839
909
  if (input.categoryId !== void 0) updates.category_id = input.categoryId;
840
910
  if (input.isPhysical !== void 0) updates.is_physical = input.isPhysical;
841
911
  if (input.weight !== void 0) updates.weight = input.weight;
842
- const { data, error } = await db.from("shop_products").update(updates).eq("id", id).select("*, images:shop_product_images(*)").single();
912
+ const { data, error } = await db.from(T.products).update(updates).eq("id", id).select(`*, images:${T.productImages}(*)`).single();
843
913
  if (error) throw error;
844
914
  return rowToProduct(data);
845
915
  }
846
916
  async deleteProduct(id) {
847
- const { error } = await getDb().from("shop_products").delete().eq("id", id);
917
+ const { error } = await getDb().from(T.products).delete().eq("id", id);
848
918
  if (error) throw error;
849
919
  }
850
920
  async uploadProductImage(productId, file) {
@@ -854,12 +924,37 @@ var SupabaseShopProvider = class {
854
924
  const { error: uploadErr } = await db.storage.from("shop-images").upload(path, file);
855
925
  if (uploadErr) throw uploadErr;
856
926
  const { data: { publicUrl } } = db.storage.from("shop-images").getPublicUrl(path);
857
- 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();
927
+ const { data: existing } = await db.from(T.productImages).select("id,sort_order").eq("product_id", productId).order("sort_order", { ascending: false }).limit(1);
928
+ const first = !existing || existing.length === 0;
929
+ const nextOrder = first ? 0 : (existing[0].sort_order ?? 0) + 1;
930
+ const { data, error } = await db.from(T.productImages).insert({
931
+ product_id: productId,
932
+ tenant_id: tenantId,
933
+ url: publicUrl,
934
+ sort_order: nextOrder,
935
+ is_primary: first
936
+ }).select().single();
937
+ if (error) throw error;
938
+ return rowToImage(data);
939
+ }
940
+ async updateProductImage(imageId, input) {
941
+ const db = getDb();
942
+ const updates = {};
943
+ if (input.sortOrder !== void 0) updates.sort_order = input.sortOrder;
944
+ if (input.altText !== void 0) updates.alt_text = input.altText;
945
+ if (input.isPrimary !== void 0) updates.is_primary = input.isPrimary;
946
+ if (input.isPrimary) {
947
+ const { data: target } = await db.from(T.productImages).select("product_id").eq("id", imageId).single();
948
+ if (target?.product_id) {
949
+ await db.from(T.productImages).update({ is_primary: false }).eq("product_id", target.product_id).neq("id", imageId);
950
+ }
951
+ }
952
+ const { data, error } = await db.from(T.productImages).update(updates).eq("id", imageId).select().single();
858
953
  if (error) throw error;
859
954
  return rowToImage(data);
860
955
  }
861
956
  async deleteProductImage(imageId) {
862
- const { error } = await getDb().from("shop_product_images").delete().eq("id", imageId);
957
+ const { error } = await getDb().from(T.productImages).delete().eq("id", imageId);
863
958
  if (error) throw error;
864
959
  }
865
960
  // ---------------------------------------------------------------------------
@@ -868,7 +963,7 @@ var SupabaseShopProvider = class {
868
963
  async listCategories() {
869
964
  const db = getDb();
870
965
  const tenantId = getTenantId();
871
- let q = db.from("shop_categories").select("*").order("sort_order", { ascending: true });
966
+ let q = db.from(T.categories).select("*").order("sort_order", { ascending: true });
872
967
  if (tenantId) q = q.eq("tenant_id", tenantId);
873
968
  const { data, error } = await q;
874
969
  if (error) throw error;
@@ -876,7 +971,7 @@ var SupabaseShopProvider = class {
876
971
  }
877
972
  async createCategory(input) {
878
973
  const db = getDb();
879
- 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();
974
+ 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();
880
975
  if (error) throw error;
881
976
  return rowToCategory(data);
882
977
  }
@@ -888,12 +983,12 @@ var SupabaseShopProvider = class {
888
983
  if (input.description !== void 0) updates.description = input.description;
889
984
  if (input.parentId !== void 0) updates.parent_id = input.parentId;
890
985
  if (input.sortOrder !== void 0) updates.sort_order = input.sortOrder;
891
- const { data, error } = await db.from("shop_categories").update(updates).eq("id", id).select().single();
986
+ const { data, error } = await db.from(T.categories).update(updates).eq("id", id).select().single();
892
987
  if (error) throw error;
893
988
  return rowToCategory(data);
894
989
  }
895
990
  async deleteCategory(id) {
896
- const { error } = await getDb().from("shop_categories").delete().eq("id", id);
991
+ const { error } = await getDb().from(T.categories).delete().eq("id", id);
897
992
  if (error) throw error;
898
993
  }
899
994
  // ---------------------------------------------------------------------------
@@ -902,7 +997,7 @@ var SupabaseShopProvider = class {
902
997
  async listOrders(options) {
903
998
  const db = getDb();
904
999
  const tenantId = getTenantId();
905
- let q = db.from("shop_orders").select("*, items:shop_order_items(*)");
1000
+ let q = db.from(T.orders).select(`*, items:${T.orderItems}(*)`);
906
1001
  if (tenantId) q = q.eq("tenant_id", tenantId);
907
1002
  if (options?.status) q = q.eq("status", options.status);
908
1003
  if (options?.financialStatus) q = q.eq("financial_status", options.financialStatus);
@@ -917,7 +1012,7 @@ var SupabaseShopProvider = class {
917
1012
  return (data ?? []).map(rowToOrder);
918
1013
  }
919
1014
  async getOrder(id) {
920
- const { data, error } = await getDb().from("shop_orders").select("*, items:shop_order_items(*)").eq("id", id).maybeSingle();
1015
+ const { data, error } = await getDb().from(T.orders).select(`*, items:${T.orderItems}(*)`).eq("id", id).maybeSingle();
921
1016
  if (error) throw error;
922
1017
  return data ? rowToOrder(data) : null;
923
1018
  }
@@ -928,10 +1023,10 @@ var SupabaseShopProvider = class {
928
1023
  const discountTotal = input.discountTotal ?? 0;
929
1024
  const shippingTotal = input.shippingTotal ?? 0;
930
1025
  const total = Math.round((subtotal - discountTotal + shippingTotal) * 100) / 100;
931
- 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();
1026
+ 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();
932
1027
  if (orderErr) throw orderErr;
933
1028
  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 }));
934
- await db.from("shop_order_items").insert(items);
1029
+ await db.from(T.orderItems).insert(items);
935
1030
  return this.getOrder(order.id);
936
1031
  }
937
1032
  async updateOrder(id, input) {
@@ -940,7 +1035,53 @@ var SupabaseShopProvider = class {
940
1035
  if (input.financialStatus !== void 0) updates.financial_status = input.financialStatus;
941
1036
  if (input.fulfillmentStatus !== void 0) updates.fulfillment_status = input.fulfillmentStatus;
942
1037
  if (input.notes !== void 0) updates.notes = input.notes;
943
- const { error } = await getDb().from("shop_orders").update(updates).eq("id", id);
1038
+ const { error } = await getDb().from(T.orders).update(updates).eq("id", id);
1039
+ if (error) throw error;
1040
+ return this.getOrder(id);
1041
+ }
1042
+ // -------------------------------------------------------------------------
1043
+ // Delivery zones
1044
+ //
1045
+ // Postal codes are stored as 8 bare digits so the range test in
1046
+ // shop_quote_shipping is a plain BETWEEN. Accepting '22.041-001' from the
1047
+ // form and normalising here means the merchant never has to think about it.
1048
+ // -------------------------------------------------------------------------
1049
+ async listShippingZones() {
1050
+ const tenantId = getTenantId();
1051
+ const { data, error } = await getDb().from(T.shippingZones).select("*").eq("tenant_id", tenantId).order("sort_order", { ascending: true }).order("postal_from", { ascending: true });
1052
+ if (error) throw error;
1053
+ return (data ?? []).map(rowToShippingZone);
1054
+ }
1055
+ async createShippingZone(input) {
1056
+ const tenantId = getTenantId();
1057
+ if (!tenantId) throw new Error("@fayz-ai/shop: createShippingZone requires a tenant id.");
1058
+ const { data, error } = await getDb().from(T.shippingZones).insert({ tenant_id: tenantId, ...shippingZonePayload(input) }).select().single();
1059
+ if (error) throw error;
1060
+ return rowToShippingZone(data);
1061
+ }
1062
+ async updateShippingZone(id, input) {
1063
+ const { data, error } = await getDb().from(T.shippingZones).update(shippingZonePayload(input)).eq("id", id).select().single();
1064
+ if (error) throw error;
1065
+ return rowToShippingZone(data);
1066
+ }
1067
+ async deleteShippingZone(id) {
1068
+ const { error } = await getDb().from(T.shippingZones).delete().eq("id", id);
1069
+ if (error) throw error;
1070
+ }
1071
+ /**
1072
+ * Settle a pending order: the merchant confirming that the money arrived.
1073
+ *
1074
+ * Goes through the RPC rather than an UPDATE so the payment ledger row in
1075
+ * public.transactions closes in the same transaction as the order — set
1076
+ * financial_status by hand and the order says paid while the ledger still
1077
+ * says pending. Since 0019 the RPC also enforces who may call it: a member of
1078
+ * the owning tenant, or a PSP webhook with the service role.
1079
+ */
1080
+ async confirmPayment(id, reference) {
1081
+ const { error } = await getDb().rpc("shop_confirm_payment", {
1082
+ p_order_id: id,
1083
+ p_reference: reference ?? null
1084
+ });
944
1085
  if (error) throw error;
945
1086
  return this.getOrder(id);
946
1087
  }
@@ -959,6 +1100,22 @@ var SupabaseShopProvider = class {
959
1100
  p_currency: input.currency ?? "BRL",
960
1101
  p_discount_code: input.discountCode ?? null,
961
1102
  p_shipping_total: input.shippingTotal ?? 0,
1103
+ // snake_case keys on purpose: the RPC freezes this jsonb onto the
1104
+ // order and public.addresses uses these exact column names.
1105
+ p_shipping_address: input.shippingAddress ? {
1106
+ postal_code: input.shippingAddress.postalCode,
1107
+ street: input.shippingAddress.street,
1108
+ number: input.shippingAddress.number ?? null,
1109
+ complement: input.shippingAddress.complement ?? null,
1110
+ district: input.shippingAddress.district ?? null,
1111
+ city: input.shippingAddress.city,
1112
+ state: input.shippingAddress.state,
1113
+ country: input.shippingAddress.country ?? "BR",
1114
+ recipient: input.shippingAddress.recipient ?? null,
1115
+ phone: input.shippingAddress.phone ?? null,
1116
+ label: input.shippingAddress.label ?? null
1117
+ } : null,
1118
+ p_payment_method: input.paymentMethod ?? null,
962
1119
  p_notes: input.notes ?? null
963
1120
  });
964
1121
  if (error) throw error;
@@ -973,7 +1130,7 @@ var SupabaseShopProvider = class {
973
1130
  async listCustomers(options) {
974
1131
  const db = getDb();
975
1132
  const tenantId = getTenantId();
976
- let q = db.from("shop_customers").select("*").order("first_name", { ascending: true });
1133
+ let q = db.from(T.customers).select("*").order("first_name", { ascending: true });
977
1134
  if (tenantId) q = q.eq("tenant_id", tenantId);
978
1135
  if (options?.search) q = q.or(`first_name.ilike.%${options.search}%,last_name.ilike.%${options.search}%,email.ilike.%${options.search}%`);
979
1136
  if (options?.limit) q = q.limit(options.limit);
@@ -982,12 +1139,12 @@ var SupabaseShopProvider = class {
982
1139
  return (data ?? []).map(rowToCustomer);
983
1140
  }
984
1141
  async getCustomer(id) {
985
- const { data, error } = await getDb().from("shop_customers").select("*").eq("id", id).maybeSingle();
1142
+ const { data, error } = await getDb().from(T.customers).select("*").eq("id", id).maybeSingle();
986
1143
  if (error) throw error;
987
1144
  return data ? rowToCustomer(data) : null;
988
1145
  }
989
1146
  async createCustomer(input) {
990
- 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();
1147
+ 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();
991
1148
  if (error) throw error;
992
1149
  return rowToCustomer(data);
993
1150
  }
@@ -998,12 +1155,12 @@ var SupabaseShopProvider = class {
998
1155
  if (input.email !== void 0) updates.email = input.email;
999
1156
  if (input.phone !== void 0) updates.phone = input.phone;
1000
1157
  if (input.notes !== void 0) updates.notes = input.notes;
1001
- const { data, error } = await getDb().from("shop_customers").update(updates).eq("id", id).select().single();
1158
+ const { data, error } = await getDb().from(T.customers).update(updates).eq("id", id).select().single();
1002
1159
  if (error) throw error;
1003
1160
  return rowToCustomer(data);
1004
1161
  }
1005
1162
  async deleteCustomer(id) {
1006
- const { error } = await getDb().from("shop_customers").delete().eq("id", id);
1163
+ const { error } = await getDb().from(T.customers).delete().eq("id", id);
1007
1164
  if (error) throw error;
1008
1165
  }
1009
1166
  // Find-or-create + link to auth.uid server-side (SECURITY DEFINER RPC), so the
@@ -1028,7 +1185,7 @@ var SupabaseShopProvider = class {
1028
1185
  async listDiscounts(options) {
1029
1186
  const db = getDb();
1030
1187
  const tenantId = getTenantId();
1031
- let q = db.from("shop_discounts").select("*").order("created_at", { ascending: false });
1188
+ let q = db.from(T.discounts).select("*").order("created_at", { ascending: false });
1032
1189
  if (tenantId) q = q.eq("tenant_id", tenantId);
1033
1190
  if (options?.status) q = q.eq("status", options.status);
1034
1191
  if (options?.type) q = q.eq("type", options.type);
@@ -1039,12 +1196,12 @@ var SupabaseShopProvider = class {
1039
1196
  return (data ?? []).map(rowToDiscount);
1040
1197
  }
1041
1198
  async getDiscount(id) {
1042
- const { data, error } = await getDb().from("shop_discounts").select("*").eq("id", id).maybeSingle();
1199
+ const { data, error } = await getDb().from(T.discounts).select("*").eq("id", id).maybeSingle();
1043
1200
  if (error) throw error;
1044
1201
  return data ? rowToDiscount(data) : null;
1045
1202
  }
1046
1203
  async createDiscount(input) {
1047
- 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();
1204
+ 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();
1048
1205
  if (error) throw error;
1049
1206
  return rowToDiscount(data);
1050
1207
  }
@@ -1057,12 +1214,12 @@ var SupabaseShopProvider = class {
1057
1214
  if (input.usageLimit !== void 0) updates.usage_limit = input.usageLimit;
1058
1215
  if (input.status !== void 0) updates.status = input.status;
1059
1216
  if (input.endsAt !== void 0) updates.ends_at = input.endsAt;
1060
- const { data, error } = await getDb().from("shop_discounts").update(updates).eq("id", id).select().single();
1217
+ const { data, error } = await getDb().from(T.discounts).update(updates).eq("id", id).select().single();
1061
1218
  if (error) throw error;
1062
1219
  return rowToDiscount(data);
1063
1220
  }
1064
1221
  async deleteDiscount(id) {
1065
- const { error } = await getDb().from("shop_discounts").delete().eq("id", id);
1222
+ const { error } = await getDb().from(T.discounts).delete().eq("id", id);
1066
1223
  if (error) throw error;
1067
1224
  }
1068
1225
  };