@fayz-ai/shop 0.8.2 → 0.8.4

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/catalog.cjs CHANGED
@@ -84,6 +84,10 @@ var MOCK_DISCOUNTS = [
84
84
  value: 10,
85
85
  usageLimit: null,
86
86
  oncePerCustomer: false,
87
+ minSubtotal: null,
88
+ appliesTo: "all",
89
+ productIds: [],
90
+ categoryIds: [],
87
91
  startsAt: T0,
88
92
  endsAt: null,
89
93
  status: "active",
@@ -157,6 +161,10 @@ function buildMockCatalog(input) {
157
161
  value: d.percent,
158
162
  usageLimit: null,
159
163
  oncePerCustomer: false,
164
+ minSubtotal: null,
165
+ appliesTo: "all",
166
+ productIds: [],
167
+ categoryIds: [],
160
168
  startsAt: T0,
161
169
  endsAt: null,
162
170
  status: "active",
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/mock-catalog.ts"],"names":[],"mappings":"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","file":"catalog.cjs","sourcesContent":["import type { Product, ProductImage, Category, Discount } from './types'\n\n// ---------------------------------------------------------------------------\n// Deterministic, offline product catalog for the mock provider.\n// Product names sourced from the Fayz client repo references\n// (apps/web ShopSection mockups + original shop seeds), expanded to a\n// 16-product / 4-category Shopify-style catalog.\n// ---------------------------------------------------------------------------\n\nconst T0 = '2026-01-01T12:00:00.000Z'\n\n/** 600x600 gradient SVG with product initials — no network, e2e-stable. */\nexport function svgPlaceholder(label: string, hueA: number, hueB: number): string {\n const initials = label\n .split(/\\s+/)\n .map((w) => w[0])\n .slice(0, 2)\n .join('')\n .toUpperCase()\n const svg =\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"600\" height=\"600\">` +\n `<defs><linearGradient id=\"g\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">` +\n `<stop offset=\"0\" stop-color=\"hsl(${hueA},45%,82%)\"/>` +\n `<stop offset=\"1\" stop-color=\"hsl(${hueB},50%,62%)\"/>` +\n `</linearGradient></defs>` +\n `<rect width=\"600\" height=\"600\" fill=\"url(#g)\"/>` +\n `<text x=\"300\" y=\"330\" font-family=\"sans-serif\" font-size=\"120\" font-weight=\"700\" ` +\n `fill=\"rgba(255,255,255,0.85)\" text-anchor=\"middle\">${initials}</text>` +\n `</svg>`\n return `data:image/svg+xml;utf8,${encodeURIComponent(svg)}`\n}\n\nfunction image(productId: string, name: string, hueA: number, hueB: number, idx = 0): ProductImage {\n return {\n id: `img-${productId}-${idx}`,\n productId,\n url: svgPlaceholder(name, hueA, hueB),\n altText: name,\n sortOrder: idx,\n isPrimary: idx === 0,\n createdAt: T0,\n }\n}\n\nexport const MOCK_CATEGORIES: Category[] = [\n { id: 'cat-apparel', tenantId: 'mock', name: 'Apparel', slug: 'apparel', description: 'Clothing and wearables', parentId: null, sortOrder: 0, createdAt: T0 },\n { id: 'cat-bags', tenantId: 'mock', name: 'Bags & Accessories', slug: 'bags-accessories', description: 'Bags, wallets and carry gear', parentId: null, sortOrder: 1, createdAt: T0 },\n { id: 'cat-home', tenantId: 'mock', name: 'Home & Kitchen', slug: 'home-kitchen', description: 'Everyday home goods', parentId: null, sortOrder: 2, createdAt: T0 },\n { id: 'cat-tech', tenantId: 'mock', name: 'Stationery & Tech', slug: 'stationery-tech', description: 'Desk, audio and paper goods', parentId: null, sortOrder: 3, createdAt: T0 },\n]\n\ninterface SeedProduct {\n id: string\n name: string\n slug: string\n description: string\n price: number\n compareAtPrice?: number\n inventoryCount: number\n sku: string\n categoryId: string\n hues: [number, number]\n weight: number\n}\n\nconst SEEDS: SeedProduct[] = [\n // --- Apparel ---\n { id: 'p-01', name: 'Classic T-Shirt', slug: 'classic-t-shirt', description: 'A timeless crew-neck tee in heavyweight combed cotton. Pre-shrunk, breathable, and built to outlast trends.', price: 59.9, compareAtPrice: 79.9, inventoryCount: 50, sku: 'TSH-001', categoryId: 'cat-apparel', hues: [210, 240], weight: 0.2 },\n { id: 'p-02', name: 'Linen Shirt', slug: 'linen-shirt', description: 'A relaxed-fit shirt in 100% European linen. Naturally breathable and softer with every wash.', price: 189.9, inventoryCount: 24, sku: 'LNS-002', categoryId: 'cat-apparel', hues: [35, 20], weight: 0.3 },\n { id: 'p-03', name: 'Denim Jacket', slug: 'denim-jacket', description: 'A structured trucker jacket in 12oz raw denim. Ages beautifully with hidden interior pockets.', price: 299.9, inventoryCount: 12, sku: 'DNJ-003', categoryId: 'cat-apparel', hues: [215, 200], weight: 0.8 },\n { id: 'p-04', name: 'Wool Beanie', slug: 'wool-beanie', description: 'A double-layer merino wool beanie. Warm without itch, with a low-profile cuffed fit.', price: 79.9, inventoryCount: 0, sku: 'WBN-004', categoryId: 'cat-apparel', hues: [0, 350], weight: 0.1 },\n\n // --- Bags & Accessories ---\n { id: 'p-05', name: 'Canvas Tote Bag', slug: 'canvas-tote-bag', description: 'An everyday carryall in 16oz waxed canvas with reinforced straps and an interior zip pocket.', price: 39.9, inventoryCount: 30, sku: 'BAG-001', categoryId: 'cat-bags', hues: [80, 110], weight: 0.3 },\n { id: 'p-06', name: 'Leather Backpack', slug: 'leather-backpack', description: 'Full-grain leather backpack with a padded 15\" laptop sleeve, magnetic closures and brass hardware.', price: 549.9, inventoryCount: 8, sku: 'LBP-006', categoryId: 'cat-bags', hues: [25, 15], weight: 1.4 },\n { id: 'p-07', name: 'Leather Card Wallet', slug: 'leather-card-wallet', description: 'A slim six-card wallet in vegetable-tanned leather. RFID-shielded with a center cash slot.', price: 89.9, compareAtPrice: 119.9, inventoryCount: 45, sku: 'LCW-007', categoryId: 'cat-bags', hues: [30, 45], weight: 0.08 },\n { id: 'p-08', name: 'Travel Duffel', slug: 'travel-duffel', description: 'A 40L weekender in ballistic nylon with a trolley sleeve, shoe compartment and detachable strap.', price: 329.9, inventoryCount: 15, sku: 'TDF-008', categoryId: 'cat-bags', hues: [150, 170], weight: 1.1 },\n\n // --- Home & Kitchen ---\n { id: 'p-09', name: 'Ceramic Coffee Mug', slug: 'ceramic-coffee-mug', description: 'A 350ml stoneware mug with a matte glaze and comfortable wide handle. Dishwasher and microwave safe.', price: 34.9, inventoryCount: 0, sku: 'MUG-001', categoryId: 'cat-home', hues: [190, 210], weight: 0.4 },\n { id: 'p-10', name: 'Scented Soy Candle', slug: 'scented-soy-candle', description: 'Hand-poured soy wax candle with cedar and bergamot notes. 45-hour burn time in a reusable glass jar.', price: 69.9, inventoryCount: 60, sku: 'SSC-010', categoryId: 'cat-home', hues: [45, 30], weight: 0.5 },\n { id: 'p-11', name: 'Bamboo Cutting Board', slug: 'bamboo-cutting-board', description: 'An end-grain bamboo board that is gentle on knives, with a juice groove and inset handles.', price: 119.9, inventoryCount: 22, sku: 'BCB-011', categoryId: 'cat-home', hues: [90, 70], weight: 1.2 },\n { id: 'p-12', name: 'Stoneware Plate Set', slug: 'stoneware-plate-set', description: 'A set of four reactive-glaze dinner plates. Each piece is unique, oven-safe to 220°C.', price: 249.9, inventoryCount: 10, sku: 'SPS-012', categoryId: 'cat-home', hues: [200, 180], weight: 2.4 },\n\n // --- Stationery & Tech ---\n { id: 'p-13', name: 'Wireless Headphones', slug: 'wireless-headphones', description: 'Over-ear headphones with active noise cancelling, 40-hour battery and multipoint Bluetooth 5.3.', price: 899.9, inventoryCount: 18, sku: 'WHP-013', categoryId: 'cat-tech', hues: [260, 280], weight: 0.35 },\n { id: 'p-14', name: 'Notebook Set', slug: 'notebook-set', description: 'Three A5 dot-grid notebooks with 120gsm paper, lay-flat binding and numbered pages.', price: 29.9, inventoryCount: 80, sku: 'NBS-014', categoryId: 'cat-tech', hues: [330, 310], weight: 0.45 },\n { id: 'p-15', name: 'Bluetooth Speaker', slug: 'bluetooth-speaker', description: 'A pocket-size speaker with surprising low end, IPX7 waterproofing and 14-hour playtime.', price: 199.9, compareAtPrice: 259.9, inventoryCount: 26, sku: 'BTS-015', categoryId: 'cat-tech', hues: [170, 190], weight: 0.3 },\n { id: 'p-16', name: 'Felt Desk Mat', slug: 'felt-desk-mat', description: 'A 80x30cm merino felt desk mat with a cork base. Protects the desk and quiets the keyboard.', price: 99.9, inventoryCount: 34, sku: 'FDM-016', categoryId: 'cat-tech', hues: [220, 230], weight: 0.6 },\n]\n\nconst CATEGORY_NAME: Record<string, string> = Object.fromEntries(\n MOCK_CATEGORIES.map((c) => [c.id, c.name]),\n)\n\nexport const MOCK_PRODUCTS: Product[] = SEEDS.map((s, i) => ({\n id: s.id,\n tenantId: 'mock',\n name: s.name,\n slug: s.slug,\n description: s.description,\n price: s.price,\n compareAtPrice: s.compareAtPrice ?? null,\n currency: 'BRL',\n status: 'active',\n inventoryCount: s.inventoryCount,\n sku: s.sku,\n sortOrder: i,\n metadata: {},\n images: [image(s.id, s.name, s.hues[0], s.hues[1])],\n categoryId: s.categoryId,\n categoryName: CATEGORY_NAME[s.categoryId] ?? null,\n isPhysical: true,\n weight: s.weight,\n weightUnit: 'kg',\n // staggered timestamps → deterministic 'newest' sort (p-16 newest)\n createdAt: `2026-01-${String(i + 1).padStart(2, '0')}T12:00:00.000Z`,\n updatedAt: `2026-01-${String(i + 1).padStart(2, '0')}T12:00:00.000Z`,\n}))\n\nexport const MOCK_DISCOUNTS: Discount[] = [\n {\n id: 'disc-welcome',\n tenantId: 'mock',\n title: 'Welcome 10%',\n code: 'BEMVINDO10',\n type: 'percentage',\n method: 'code',\n value: 10,\n usageLimit: null,\n oncePerCustomer: false,\n startsAt: T0,\n endsAt: null,\n status: 'active',\n timesUsed: 0,\n createdAt: T0,\n updatedAt: T0,\n },\n]\n\n// ---------------------------------------------------------------------------\n// buildMockCatalog — terse per-store catalog definition. Generates ids,\n// slugs, SVG imagery and staggered timestamps so every store gets a\n// deterministic, e2e-stable catalog from a few lines of data.\n// ---------------------------------------------------------------------------\n\nexport interface CatalogCategoryInput {\n name: string\n description?: string\n image?: string\n}\n\nexport interface CatalogProductInput {\n name: string\n description: string\n price: number\n compareAtPrice?: number\n inventory: number\n sku: string\n /** Category name — must match one of the categories */\n category: string\n hues?: [number, number]\n weight?: number\n image?: string\n metadata?: Record<string, unknown>\n}\n\nexport interface CatalogInput {\n categories: CatalogCategoryInput[]\n products: CatalogProductInput[]\n /** Percentage discount codes, e.g. [{ code: 'BEMVINDO10', percent: 10 }] */\n discounts?: Array<{ code: string; percent: number; title?: string }>\n currency?: string\n}\n\nfunction slugifyName(name: string): string {\n return name\n .toLowerCase()\n .normalize('NFD')\n .replace(/[̀-ͯ]/g, '')\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '')\n}\n\nexport function buildMockCatalog(input: CatalogInput): { products: Product[]; categories: Category[]; discounts: Discount[] } {\n const categories: Category[] = input.categories.map((c, i) => ({\n id: `cat-${slugifyName(c.name)}`,\n tenantId: 'mock',\n name: c.name,\n slug: slugifyName(c.name),\n description: c.description ?? null,\n parentId: null,\n sortOrder: i,\n imageUrl: c.image ?? null,\n createdAt: T0,\n }))\n const byName = Object.fromEntries(categories.map((c) => [c.name, c]))\n\n const products: Product[] = input.products.map((p, i) => {\n const cat = byName[p.category]\n const id = `p-${String(i + 1).padStart(2, '0')}`\n const hues = p.hues ?? [(i * 47) % 360, (i * 47 + 50) % 360]\n const stamp = `2026-01-${String((i % 27) + 1).padStart(2, '0')}T12:00:00.000Z`\n return {\n id,\n tenantId: 'mock',\n name: p.name,\n slug: slugifyName(p.name),\n description: p.description,\n price: p.price,\n compareAtPrice: p.compareAtPrice ?? null,\n currency: input.currency ?? 'BRL',\n status: 'active',\n inventoryCount: p.inventory,\n sku: p.sku,\n sortOrder: i,\n metadata: p.metadata ?? {},\n images: [\n {\n id: `img-${id}-0`,\n productId: id,\n url: p.image ?? svgPlaceholder(p.name, hues[0], hues[1]),\n altText: p.name,\n sortOrder: 0,\n isPrimary: true,\n createdAt: T0,\n },\n ],\n categoryId: cat?.id ?? null,\n categoryName: cat?.name ?? null,\n isPhysical: true,\n weight: p.weight ?? 0.5,\n weightUnit: 'kg',\n createdAt: stamp,\n updatedAt: stamp,\n }\n })\n\n const discounts: Discount[] = (input.discounts ?? []).map((d, i) => ({\n id: `disc-${slugifyName(d.code)}`,\n tenantId: 'mock',\n title: d.title ?? `${d.percent}% off`,\n code: d.code,\n type: 'percentage',\n method: 'code',\n value: d.percent,\n usageLimit: null,\n oncePerCustomer: false,\n startsAt: T0,\n endsAt: null,\n status: 'active',\n timesUsed: 0,\n createdAt: T0,\n updatedAt: T0,\n }))\n\n return { products, categories, discounts }\n}\n"]}
1
+ {"version":3,"sources":["../src/mock-catalog.ts"],"names":[],"mappings":"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","file":"catalog.cjs","sourcesContent":["import type { Product, ProductImage, Category, Discount } from './types'\n\n// ---------------------------------------------------------------------------\n// Deterministic, offline product catalog for the mock provider.\n// Product names sourced from the Fayz client repo references\n// (apps/web ShopSection mockups + original shop seeds), expanded to a\n// 16-product / 4-category Shopify-style catalog.\n// ---------------------------------------------------------------------------\n\nconst T0 = '2026-01-01T12:00:00.000Z'\n\n/** 600x600 gradient SVG with product initials — no network, e2e-stable. */\nexport function svgPlaceholder(label: string, hueA: number, hueB: number): string {\n const initials = label\n .split(/\\s+/)\n .map((w) => w[0])\n .slice(0, 2)\n .join('')\n .toUpperCase()\n const svg =\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"600\" height=\"600\">` +\n `<defs><linearGradient id=\"g\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">` +\n `<stop offset=\"0\" stop-color=\"hsl(${hueA},45%,82%)\"/>` +\n `<stop offset=\"1\" stop-color=\"hsl(${hueB},50%,62%)\"/>` +\n `</linearGradient></defs>` +\n `<rect width=\"600\" height=\"600\" fill=\"url(#g)\"/>` +\n `<text x=\"300\" y=\"330\" font-family=\"sans-serif\" font-size=\"120\" font-weight=\"700\" ` +\n `fill=\"rgba(255,255,255,0.85)\" text-anchor=\"middle\">${initials}</text>` +\n `</svg>`\n return `data:image/svg+xml;utf8,${encodeURIComponent(svg)}`\n}\n\nfunction image(productId: string, name: string, hueA: number, hueB: number, idx = 0): ProductImage {\n return {\n id: `img-${productId}-${idx}`,\n productId,\n url: svgPlaceholder(name, hueA, hueB),\n altText: name,\n sortOrder: idx,\n isPrimary: idx === 0,\n createdAt: T0,\n }\n}\n\nexport const MOCK_CATEGORIES: Category[] = [\n { id: 'cat-apparel', tenantId: 'mock', name: 'Apparel', slug: 'apparel', description: 'Clothing and wearables', parentId: null, sortOrder: 0, createdAt: T0 },\n { id: 'cat-bags', tenantId: 'mock', name: 'Bags & Accessories', slug: 'bags-accessories', description: 'Bags, wallets and carry gear', parentId: null, sortOrder: 1, createdAt: T0 },\n { id: 'cat-home', tenantId: 'mock', name: 'Home & Kitchen', slug: 'home-kitchen', description: 'Everyday home goods', parentId: null, sortOrder: 2, createdAt: T0 },\n { id: 'cat-tech', tenantId: 'mock', name: 'Stationery & Tech', slug: 'stationery-tech', description: 'Desk, audio and paper goods', parentId: null, sortOrder: 3, createdAt: T0 },\n]\n\ninterface SeedProduct {\n id: string\n name: string\n slug: string\n description: string\n price: number\n compareAtPrice?: number\n inventoryCount: number\n sku: string\n categoryId: string\n hues: [number, number]\n weight: number\n}\n\nconst SEEDS: SeedProduct[] = [\n // --- Apparel ---\n { id: 'p-01', name: 'Classic T-Shirt', slug: 'classic-t-shirt', description: 'A timeless crew-neck tee in heavyweight combed cotton. Pre-shrunk, breathable, and built to outlast trends.', price: 59.9, compareAtPrice: 79.9, inventoryCount: 50, sku: 'TSH-001', categoryId: 'cat-apparel', hues: [210, 240], weight: 0.2 },\n { id: 'p-02', name: 'Linen Shirt', slug: 'linen-shirt', description: 'A relaxed-fit shirt in 100% European linen. Naturally breathable and softer with every wash.', price: 189.9, inventoryCount: 24, sku: 'LNS-002', categoryId: 'cat-apparel', hues: [35, 20], weight: 0.3 },\n { id: 'p-03', name: 'Denim Jacket', slug: 'denim-jacket', description: 'A structured trucker jacket in 12oz raw denim. Ages beautifully with hidden interior pockets.', price: 299.9, inventoryCount: 12, sku: 'DNJ-003', categoryId: 'cat-apparel', hues: [215, 200], weight: 0.8 },\n { id: 'p-04', name: 'Wool Beanie', slug: 'wool-beanie', description: 'A double-layer merino wool beanie. Warm without itch, with a low-profile cuffed fit.', price: 79.9, inventoryCount: 0, sku: 'WBN-004', categoryId: 'cat-apparel', hues: [0, 350], weight: 0.1 },\n\n // --- Bags & Accessories ---\n { id: 'p-05', name: 'Canvas Tote Bag', slug: 'canvas-tote-bag', description: 'An everyday carryall in 16oz waxed canvas with reinforced straps and an interior zip pocket.', price: 39.9, inventoryCount: 30, sku: 'BAG-001', categoryId: 'cat-bags', hues: [80, 110], weight: 0.3 },\n { id: 'p-06', name: 'Leather Backpack', slug: 'leather-backpack', description: 'Full-grain leather backpack with a padded 15\" laptop sleeve, magnetic closures and brass hardware.', price: 549.9, inventoryCount: 8, sku: 'LBP-006', categoryId: 'cat-bags', hues: [25, 15], weight: 1.4 },\n { id: 'p-07', name: 'Leather Card Wallet', slug: 'leather-card-wallet', description: 'A slim six-card wallet in vegetable-tanned leather. RFID-shielded with a center cash slot.', price: 89.9, compareAtPrice: 119.9, inventoryCount: 45, sku: 'LCW-007', categoryId: 'cat-bags', hues: [30, 45], weight: 0.08 },\n { id: 'p-08', name: 'Travel Duffel', slug: 'travel-duffel', description: 'A 40L weekender in ballistic nylon with a trolley sleeve, shoe compartment and detachable strap.', price: 329.9, inventoryCount: 15, sku: 'TDF-008', categoryId: 'cat-bags', hues: [150, 170], weight: 1.1 },\n\n // --- Home & Kitchen ---\n { id: 'p-09', name: 'Ceramic Coffee Mug', slug: 'ceramic-coffee-mug', description: 'A 350ml stoneware mug with a matte glaze and comfortable wide handle. Dishwasher and microwave safe.', price: 34.9, inventoryCount: 0, sku: 'MUG-001', categoryId: 'cat-home', hues: [190, 210], weight: 0.4 },\n { id: 'p-10', name: 'Scented Soy Candle', slug: 'scented-soy-candle', description: 'Hand-poured soy wax candle with cedar and bergamot notes. 45-hour burn time in a reusable glass jar.', price: 69.9, inventoryCount: 60, sku: 'SSC-010', categoryId: 'cat-home', hues: [45, 30], weight: 0.5 },\n { id: 'p-11', name: 'Bamboo Cutting Board', slug: 'bamboo-cutting-board', description: 'An end-grain bamboo board that is gentle on knives, with a juice groove and inset handles.', price: 119.9, inventoryCount: 22, sku: 'BCB-011', categoryId: 'cat-home', hues: [90, 70], weight: 1.2 },\n { id: 'p-12', name: 'Stoneware Plate Set', slug: 'stoneware-plate-set', description: 'A set of four reactive-glaze dinner plates. Each piece is unique, oven-safe to 220°C.', price: 249.9, inventoryCount: 10, sku: 'SPS-012', categoryId: 'cat-home', hues: [200, 180], weight: 2.4 },\n\n // --- Stationery & Tech ---\n { id: 'p-13', name: 'Wireless Headphones', slug: 'wireless-headphones', description: 'Over-ear headphones with active noise cancelling, 40-hour battery and multipoint Bluetooth 5.3.', price: 899.9, inventoryCount: 18, sku: 'WHP-013', categoryId: 'cat-tech', hues: [260, 280], weight: 0.35 },\n { id: 'p-14', name: 'Notebook Set', slug: 'notebook-set', description: 'Three A5 dot-grid notebooks with 120gsm paper, lay-flat binding and numbered pages.', price: 29.9, inventoryCount: 80, sku: 'NBS-014', categoryId: 'cat-tech', hues: [330, 310], weight: 0.45 },\n { id: 'p-15', name: 'Bluetooth Speaker', slug: 'bluetooth-speaker', description: 'A pocket-size speaker with surprising low end, IPX7 waterproofing and 14-hour playtime.', price: 199.9, compareAtPrice: 259.9, inventoryCount: 26, sku: 'BTS-015', categoryId: 'cat-tech', hues: [170, 190], weight: 0.3 },\n { id: 'p-16', name: 'Felt Desk Mat', slug: 'felt-desk-mat', description: 'A 80x30cm merino felt desk mat with a cork base. Protects the desk and quiets the keyboard.', price: 99.9, inventoryCount: 34, sku: 'FDM-016', categoryId: 'cat-tech', hues: [220, 230], weight: 0.6 },\n]\n\nconst CATEGORY_NAME: Record<string, string> = Object.fromEntries(\n MOCK_CATEGORIES.map((c) => [c.id, c.name]),\n)\n\nexport const MOCK_PRODUCTS: Product[] = SEEDS.map((s, i) => ({\n id: s.id,\n tenantId: 'mock',\n name: s.name,\n slug: s.slug,\n description: s.description,\n price: s.price,\n compareAtPrice: s.compareAtPrice ?? null,\n currency: 'BRL',\n status: 'active',\n inventoryCount: s.inventoryCount,\n sku: s.sku,\n sortOrder: i,\n metadata: {},\n images: [image(s.id, s.name, s.hues[0], s.hues[1])],\n categoryId: s.categoryId,\n categoryName: CATEGORY_NAME[s.categoryId] ?? null,\n isPhysical: true,\n weight: s.weight,\n weightUnit: 'kg',\n // staggered timestamps → deterministic 'newest' sort (p-16 newest)\n createdAt: `2026-01-${String(i + 1).padStart(2, '0')}T12:00:00.000Z`,\n updatedAt: `2026-01-${String(i + 1).padStart(2, '0')}T12:00:00.000Z`,\n}))\n\nexport const MOCK_DISCOUNTS: Discount[] = [\n {\n id: 'disc-welcome',\n tenantId: 'mock',\n title: 'Welcome 10%',\n code: 'BEMVINDO10',\n type: 'percentage',\n method: 'code',\n value: 10,\n usageLimit: null,\n oncePerCustomer: false,\n minSubtotal: null,\n appliesTo: 'all',\n productIds: [],\n categoryIds: [],\n startsAt: T0,\n endsAt: null,\n status: 'active',\n timesUsed: 0,\n createdAt: T0,\n updatedAt: T0,\n },\n]\n\n// ---------------------------------------------------------------------------\n// buildMockCatalog — terse per-store catalog definition. Generates ids,\n// slugs, SVG imagery and staggered timestamps so every store gets a\n// deterministic, e2e-stable catalog from a few lines of data.\n// ---------------------------------------------------------------------------\n\nexport interface CatalogCategoryInput {\n name: string\n description?: string\n image?: string\n}\n\nexport interface CatalogProductInput {\n name: string\n description: string\n price: number\n compareAtPrice?: number\n inventory: number\n sku: string\n /** Category name — must match one of the categories */\n category: string\n hues?: [number, number]\n weight?: number\n image?: string\n metadata?: Record<string, unknown>\n}\n\nexport interface CatalogInput {\n categories: CatalogCategoryInput[]\n products: CatalogProductInput[]\n /** Percentage discount codes, e.g. [{ code: 'BEMVINDO10', percent: 10 }] */\n discounts?: Array<{ code: string; percent: number; title?: string }>\n currency?: string\n}\n\nfunction slugifyName(name: string): string {\n return name\n .toLowerCase()\n .normalize('NFD')\n .replace(/[̀-ͯ]/g, '')\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '')\n}\n\nexport function buildMockCatalog(input: CatalogInput): { products: Product[]; categories: Category[]; discounts: Discount[] } {\n const categories: Category[] = input.categories.map((c, i) => ({\n id: `cat-${slugifyName(c.name)}`,\n tenantId: 'mock',\n name: c.name,\n slug: slugifyName(c.name),\n description: c.description ?? null,\n parentId: null,\n sortOrder: i,\n imageUrl: c.image ?? null,\n createdAt: T0,\n }))\n const byName = Object.fromEntries(categories.map((c) => [c.name, c]))\n\n const products: Product[] = input.products.map((p, i) => {\n const cat = byName[p.category]\n const id = `p-${String(i + 1).padStart(2, '0')}`\n const hues = p.hues ?? [(i * 47) % 360, (i * 47 + 50) % 360]\n const stamp = `2026-01-${String((i % 27) + 1).padStart(2, '0')}T12:00:00.000Z`\n return {\n id,\n tenantId: 'mock',\n name: p.name,\n slug: slugifyName(p.name),\n description: p.description,\n price: p.price,\n compareAtPrice: p.compareAtPrice ?? null,\n currency: input.currency ?? 'BRL',\n status: 'active',\n inventoryCount: p.inventory,\n sku: p.sku,\n sortOrder: i,\n metadata: p.metadata ?? {},\n images: [\n {\n id: `img-${id}-0`,\n productId: id,\n url: p.image ?? svgPlaceholder(p.name, hues[0], hues[1]),\n altText: p.name,\n sortOrder: 0,\n isPrimary: true,\n createdAt: T0,\n },\n ],\n categoryId: cat?.id ?? null,\n categoryName: cat?.name ?? null,\n isPhysical: true,\n weight: p.weight ?? 0.5,\n weightUnit: 'kg',\n createdAt: stamp,\n updatedAt: stamp,\n }\n })\n\n const discounts: Discount[] = (input.discounts ?? []).map((d, i) => ({\n id: `disc-${slugifyName(d.code)}`,\n tenantId: 'mock',\n title: d.title ?? `${d.percent}% off`,\n code: d.code,\n type: 'percentage',\n method: 'code',\n value: d.percent,\n usageLimit: null,\n oncePerCustomer: false,\n minSubtotal: null,\n appliesTo: 'all',\n productIds: [],\n categoryIds: [],\n startsAt: T0,\n endsAt: null,\n status: 'active',\n timesUsed: 0,\n createdAt: T0,\n updatedAt: T0,\n }))\n\n return { products, categories, discounts }\n}\n"]}
package/dist/catalog.js CHANGED
@@ -82,6 +82,10 @@ var MOCK_DISCOUNTS = [
82
82
  value: 10,
83
83
  usageLimit: null,
84
84
  oncePerCustomer: false,
85
+ minSubtotal: null,
86
+ appliesTo: "all",
87
+ productIds: [],
88
+ categoryIds: [],
85
89
  startsAt: T0,
86
90
  endsAt: null,
87
91
  status: "active",
@@ -155,6 +159,10 @@ function buildMockCatalog(input) {
155
159
  value: d.percent,
156
160
  usageLimit: null,
157
161
  oncePerCustomer: false,
162
+ minSubtotal: null,
163
+ appliesTo: "all",
164
+ productIds: [],
165
+ categoryIds: [],
158
166
  startsAt: T0,
159
167
  endsAt: null,
160
168
  status: "active",
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/mock-catalog.ts"],"names":[],"mappings":"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","file":"catalog.js","sourcesContent":["import type { Product, ProductImage, Category, Discount } from './types'\n\n// ---------------------------------------------------------------------------\n// Deterministic, offline product catalog for the mock provider.\n// Product names sourced from the Fayz client repo references\n// (apps/web ShopSection mockups + original shop seeds), expanded to a\n// 16-product / 4-category Shopify-style catalog.\n// ---------------------------------------------------------------------------\n\nconst T0 = '2026-01-01T12:00:00.000Z'\n\n/** 600x600 gradient SVG with product initials — no network, e2e-stable. */\nexport function svgPlaceholder(label: string, hueA: number, hueB: number): string {\n const initials = label\n .split(/\\s+/)\n .map((w) => w[0])\n .slice(0, 2)\n .join('')\n .toUpperCase()\n const svg =\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"600\" height=\"600\">` +\n `<defs><linearGradient id=\"g\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">` +\n `<stop offset=\"0\" stop-color=\"hsl(${hueA},45%,82%)\"/>` +\n `<stop offset=\"1\" stop-color=\"hsl(${hueB},50%,62%)\"/>` +\n `</linearGradient></defs>` +\n `<rect width=\"600\" height=\"600\" fill=\"url(#g)\"/>` +\n `<text x=\"300\" y=\"330\" font-family=\"sans-serif\" font-size=\"120\" font-weight=\"700\" ` +\n `fill=\"rgba(255,255,255,0.85)\" text-anchor=\"middle\">${initials}</text>` +\n `</svg>`\n return `data:image/svg+xml;utf8,${encodeURIComponent(svg)}`\n}\n\nfunction image(productId: string, name: string, hueA: number, hueB: number, idx = 0): ProductImage {\n return {\n id: `img-${productId}-${idx}`,\n productId,\n url: svgPlaceholder(name, hueA, hueB),\n altText: name,\n sortOrder: idx,\n isPrimary: idx === 0,\n createdAt: T0,\n }\n}\n\nexport const MOCK_CATEGORIES: Category[] = [\n { id: 'cat-apparel', tenantId: 'mock', name: 'Apparel', slug: 'apparel', description: 'Clothing and wearables', parentId: null, sortOrder: 0, createdAt: T0 },\n { id: 'cat-bags', tenantId: 'mock', name: 'Bags & Accessories', slug: 'bags-accessories', description: 'Bags, wallets and carry gear', parentId: null, sortOrder: 1, createdAt: T0 },\n { id: 'cat-home', tenantId: 'mock', name: 'Home & Kitchen', slug: 'home-kitchen', description: 'Everyday home goods', parentId: null, sortOrder: 2, createdAt: T0 },\n { id: 'cat-tech', tenantId: 'mock', name: 'Stationery & Tech', slug: 'stationery-tech', description: 'Desk, audio and paper goods', parentId: null, sortOrder: 3, createdAt: T0 },\n]\n\ninterface SeedProduct {\n id: string\n name: string\n slug: string\n description: string\n price: number\n compareAtPrice?: number\n inventoryCount: number\n sku: string\n categoryId: string\n hues: [number, number]\n weight: number\n}\n\nconst SEEDS: SeedProduct[] = [\n // --- Apparel ---\n { id: 'p-01', name: 'Classic T-Shirt', slug: 'classic-t-shirt', description: 'A timeless crew-neck tee in heavyweight combed cotton. Pre-shrunk, breathable, and built to outlast trends.', price: 59.9, compareAtPrice: 79.9, inventoryCount: 50, sku: 'TSH-001', categoryId: 'cat-apparel', hues: [210, 240], weight: 0.2 },\n { id: 'p-02', name: 'Linen Shirt', slug: 'linen-shirt', description: 'A relaxed-fit shirt in 100% European linen. Naturally breathable and softer with every wash.', price: 189.9, inventoryCount: 24, sku: 'LNS-002', categoryId: 'cat-apparel', hues: [35, 20], weight: 0.3 },\n { id: 'p-03', name: 'Denim Jacket', slug: 'denim-jacket', description: 'A structured trucker jacket in 12oz raw denim. Ages beautifully with hidden interior pockets.', price: 299.9, inventoryCount: 12, sku: 'DNJ-003', categoryId: 'cat-apparel', hues: [215, 200], weight: 0.8 },\n { id: 'p-04', name: 'Wool Beanie', slug: 'wool-beanie', description: 'A double-layer merino wool beanie. Warm without itch, with a low-profile cuffed fit.', price: 79.9, inventoryCount: 0, sku: 'WBN-004', categoryId: 'cat-apparel', hues: [0, 350], weight: 0.1 },\n\n // --- Bags & Accessories ---\n { id: 'p-05', name: 'Canvas Tote Bag', slug: 'canvas-tote-bag', description: 'An everyday carryall in 16oz waxed canvas with reinforced straps and an interior zip pocket.', price: 39.9, inventoryCount: 30, sku: 'BAG-001', categoryId: 'cat-bags', hues: [80, 110], weight: 0.3 },\n { id: 'p-06', name: 'Leather Backpack', slug: 'leather-backpack', description: 'Full-grain leather backpack with a padded 15\" laptop sleeve, magnetic closures and brass hardware.', price: 549.9, inventoryCount: 8, sku: 'LBP-006', categoryId: 'cat-bags', hues: [25, 15], weight: 1.4 },\n { id: 'p-07', name: 'Leather Card Wallet', slug: 'leather-card-wallet', description: 'A slim six-card wallet in vegetable-tanned leather. RFID-shielded with a center cash slot.', price: 89.9, compareAtPrice: 119.9, inventoryCount: 45, sku: 'LCW-007', categoryId: 'cat-bags', hues: [30, 45], weight: 0.08 },\n { id: 'p-08', name: 'Travel Duffel', slug: 'travel-duffel', description: 'A 40L weekender in ballistic nylon with a trolley sleeve, shoe compartment and detachable strap.', price: 329.9, inventoryCount: 15, sku: 'TDF-008', categoryId: 'cat-bags', hues: [150, 170], weight: 1.1 },\n\n // --- Home & Kitchen ---\n { id: 'p-09', name: 'Ceramic Coffee Mug', slug: 'ceramic-coffee-mug', description: 'A 350ml stoneware mug with a matte glaze and comfortable wide handle. Dishwasher and microwave safe.', price: 34.9, inventoryCount: 0, sku: 'MUG-001', categoryId: 'cat-home', hues: [190, 210], weight: 0.4 },\n { id: 'p-10', name: 'Scented Soy Candle', slug: 'scented-soy-candle', description: 'Hand-poured soy wax candle with cedar and bergamot notes. 45-hour burn time in a reusable glass jar.', price: 69.9, inventoryCount: 60, sku: 'SSC-010', categoryId: 'cat-home', hues: [45, 30], weight: 0.5 },\n { id: 'p-11', name: 'Bamboo Cutting Board', slug: 'bamboo-cutting-board', description: 'An end-grain bamboo board that is gentle on knives, with a juice groove and inset handles.', price: 119.9, inventoryCount: 22, sku: 'BCB-011', categoryId: 'cat-home', hues: [90, 70], weight: 1.2 },\n { id: 'p-12', name: 'Stoneware Plate Set', slug: 'stoneware-plate-set', description: 'A set of four reactive-glaze dinner plates. Each piece is unique, oven-safe to 220°C.', price: 249.9, inventoryCount: 10, sku: 'SPS-012', categoryId: 'cat-home', hues: [200, 180], weight: 2.4 },\n\n // --- Stationery & Tech ---\n { id: 'p-13', name: 'Wireless Headphones', slug: 'wireless-headphones', description: 'Over-ear headphones with active noise cancelling, 40-hour battery and multipoint Bluetooth 5.3.', price: 899.9, inventoryCount: 18, sku: 'WHP-013', categoryId: 'cat-tech', hues: [260, 280], weight: 0.35 },\n { id: 'p-14', name: 'Notebook Set', slug: 'notebook-set', description: 'Three A5 dot-grid notebooks with 120gsm paper, lay-flat binding and numbered pages.', price: 29.9, inventoryCount: 80, sku: 'NBS-014', categoryId: 'cat-tech', hues: [330, 310], weight: 0.45 },\n { id: 'p-15', name: 'Bluetooth Speaker', slug: 'bluetooth-speaker', description: 'A pocket-size speaker with surprising low end, IPX7 waterproofing and 14-hour playtime.', price: 199.9, compareAtPrice: 259.9, inventoryCount: 26, sku: 'BTS-015', categoryId: 'cat-tech', hues: [170, 190], weight: 0.3 },\n { id: 'p-16', name: 'Felt Desk Mat', slug: 'felt-desk-mat', description: 'A 80x30cm merino felt desk mat with a cork base. Protects the desk and quiets the keyboard.', price: 99.9, inventoryCount: 34, sku: 'FDM-016', categoryId: 'cat-tech', hues: [220, 230], weight: 0.6 },\n]\n\nconst CATEGORY_NAME: Record<string, string> = Object.fromEntries(\n MOCK_CATEGORIES.map((c) => [c.id, c.name]),\n)\n\nexport const MOCK_PRODUCTS: Product[] = SEEDS.map((s, i) => ({\n id: s.id,\n tenantId: 'mock',\n name: s.name,\n slug: s.slug,\n description: s.description,\n price: s.price,\n compareAtPrice: s.compareAtPrice ?? null,\n currency: 'BRL',\n status: 'active',\n inventoryCount: s.inventoryCount,\n sku: s.sku,\n sortOrder: i,\n metadata: {},\n images: [image(s.id, s.name, s.hues[0], s.hues[1])],\n categoryId: s.categoryId,\n categoryName: CATEGORY_NAME[s.categoryId] ?? null,\n isPhysical: true,\n weight: s.weight,\n weightUnit: 'kg',\n // staggered timestamps → deterministic 'newest' sort (p-16 newest)\n createdAt: `2026-01-${String(i + 1).padStart(2, '0')}T12:00:00.000Z`,\n updatedAt: `2026-01-${String(i + 1).padStart(2, '0')}T12:00:00.000Z`,\n}))\n\nexport const MOCK_DISCOUNTS: Discount[] = [\n {\n id: 'disc-welcome',\n tenantId: 'mock',\n title: 'Welcome 10%',\n code: 'BEMVINDO10',\n type: 'percentage',\n method: 'code',\n value: 10,\n usageLimit: null,\n oncePerCustomer: false,\n startsAt: T0,\n endsAt: null,\n status: 'active',\n timesUsed: 0,\n createdAt: T0,\n updatedAt: T0,\n },\n]\n\n// ---------------------------------------------------------------------------\n// buildMockCatalog — terse per-store catalog definition. Generates ids,\n// slugs, SVG imagery and staggered timestamps so every store gets a\n// deterministic, e2e-stable catalog from a few lines of data.\n// ---------------------------------------------------------------------------\n\nexport interface CatalogCategoryInput {\n name: string\n description?: string\n image?: string\n}\n\nexport interface CatalogProductInput {\n name: string\n description: string\n price: number\n compareAtPrice?: number\n inventory: number\n sku: string\n /** Category name — must match one of the categories */\n category: string\n hues?: [number, number]\n weight?: number\n image?: string\n metadata?: Record<string, unknown>\n}\n\nexport interface CatalogInput {\n categories: CatalogCategoryInput[]\n products: CatalogProductInput[]\n /** Percentage discount codes, e.g. [{ code: 'BEMVINDO10', percent: 10 }] */\n discounts?: Array<{ code: string; percent: number; title?: string }>\n currency?: string\n}\n\nfunction slugifyName(name: string): string {\n return name\n .toLowerCase()\n .normalize('NFD')\n .replace(/[̀-ͯ]/g, '')\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '')\n}\n\nexport function buildMockCatalog(input: CatalogInput): { products: Product[]; categories: Category[]; discounts: Discount[] } {\n const categories: Category[] = input.categories.map((c, i) => ({\n id: `cat-${slugifyName(c.name)}`,\n tenantId: 'mock',\n name: c.name,\n slug: slugifyName(c.name),\n description: c.description ?? null,\n parentId: null,\n sortOrder: i,\n imageUrl: c.image ?? null,\n createdAt: T0,\n }))\n const byName = Object.fromEntries(categories.map((c) => [c.name, c]))\n\n const products: Product[] = input.products.map((p, i) => {\n const cat = byName[p.category]\n const id = `p-${String(i + 1).padStart(2, '0')}`\n const hues = p.hues ?? [(i * 47) % 360, (i * 47 + 50) % 360]\n const stamp = `2026-01-${String((i % 27) + 1).padStart(2, '0')}T12:00:00.000Z`\n return {\n id,\n tenantId: 'mock',\n name: p.name,\n slug: slugifyName(p.name),\n description: p.description,\n price: p.price,\n compareAtPrice: p.compareAtPrice ?? null,\n currency: input.currency ?? 'BRL',\n status: 'active',\n inventoryCount: p.inventory,\n sku: p.sku,\n sortOrder: i,\n metadata: p.metadata ?? {},\n images: [\n {\n id: `img-${id}-0`,\n productId: id,\n url: p.image ?? svgPlaceholder(p.name, hues[0], hues[1]),\n altText: p.name,\n sortOrder: 0,\n isPrimary: true,\n createdAt: T0,\n },\n ],\n categoryId: cat?.id ?? null,\n categoryName: cat?.name ?? null,\n isPhysical: true,\n weight: p.weight ?? 0.5,\n weightUnit: 'kg',\n createdAt: stamp,\n updatedAt: stamp,\n }\n })\n\n const discounts: Discount[] = (input.discounts ?? []).map((d, i) => ({\n id: `disc-${slugifyName(d.code)}`,\n tenantId: 'mock',\n title: d.title ?? `${d.percent}% off`,\n code: d.code,\n type: 'percentage',\n method: 'code',\n value: d.percent,\n usageLimit: null,\n oncePerCustomer: false,\n startsAt: T0,\n endsAt: null,\n status: 'active',\n timesUsed: 0,\n createdAt: T0,\n updatedAt: T0,\n }))\n\n return { products, categories, discounts }\n}\n"]}
1
+ {"version":3,"sources":["../src/mock-catalog.ts"],"names":[],"mappings":"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","file":"catalog.js","sourcesContent":["import type { Product, ProductImage, Category, Discount } from './types'\n\n// ---------------------------------------------------------------------------\n// Deterministic, offline product catalog for the mock provider.\n// Product names sourced from the Fayz client repo references\n// (apps/web ShopSection mockups + original shop seeds), expanded to a\n// 16-product / 4-category Shopify-style catalog.\n// ---------------------------------------------------------------------------\n\nconst T0 = '2026-01-01T12:00:00.000Z'\n\n/** 600x600 gradient SVG with product initials — no network, e2e-stable. */\nexport function svgPlaceholder(label: string, hueA: number, hueB: number): string {\n const initials = label\n .split(/\\s+/)\n .map((w) => w[0])\n .slice(0, 2)\n .join('')\n .toUpperCase()\n const svg =\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"600\" height=\"600\">` +\n `<defs><linearGradient id=\"g\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">` +\n `<stop offset=\"0\" stop-color=\"hsl(${hueA},45%,82%)\"/>` +\n `<stop offset=\"1\" stop-color=\"hsl(${hueB},50%,62%)\"/>` +\n `</linearGradient></defs>` +\n `<rect width=\"600\" height=\"600\" fill=\"url(#g)\"/>` +\n `<text x=\"300\" y=\"330\" font-family=\"sans-serif\" font-size=\"120\" font-weight=\"700\" ` +\n `fill=\"rgba(255,255,255,0.85)\" text-anchor=\"middle\">${initials}</text>` +\n `</svg>`\n return `data:image/svg+xml;utf8,${encodeURIComponent(svg)}`\n}\n\nfunction image(productId: string, name: string, hueA: number, hueB: number, idx = 0): ProductImage {\n return {\n id: `img-${productId}-${idx}`,\n productId,\n url: svgPlaceholder(name, hueA, hueB),\n altText: name,\n sortOrder: idx,\n isPrimary: idx === 0,\n createdAt: T0,\n }\n}\n\nexport const MOCK_CATEGORIES: Category[] = [\n { id: 'cat-apparel', tenantId: 'mock', name: 'Apparel', slug: 'apparel', description: 'Clothing and wearables', parentId: null, sortOrder: 0, createdAt: T0 },\n { id: 'cat-bags', tenantId: 'mock', name: 'Bags & Accessories', slug: 'bags-accessories', description: 'Bags, wallets and carry gear', parentId: null, sortOrder: 1, createdAt: T0 },\n { id: 'cat-home', tenantId: 'mock', name: 'Home & Kitchen', slug: 'home-kitchen', description: 'Everyday home goods', parentId: null, sortOrder: 2, createdAt: T0 },\n { id: 'cat-tech', tenantId: 'mock', name: 'Stationery & Tech', slug: 'stationery-tech', description: 'Desk, audio and paper goods', parentId: null, sortOrder: 3, createdAt: T0 },\n]\n\ninterface SeedProduct {\n id: string\n name: string\n slug: string\n description: string\n price: number\n compareAtPrice?: number\n inventoryCount: number\n sku: string\n categoryId: string\n hues: [number, number]\n weight: number\n}\n\nconst SEEDS: SeedProduct[] = [\n // --- Apparel ---\n { id: 'p-01', name: 'Classic T-Shirt', slug: 'classic-t-shirt', description: 'A timeless crew-neck tee in heavyweight combed cotton. Pre-shrunk, breathable, and built to outlast trends.', price: 59.9, compareAtPrice: 79.9, inventoryCount: 50, sku: 'TSH-001', categoryId: 'cat-apparel', hues: [210, 240], weight: 0.2 },\n { id: 'p-02', name: 'Linen Shirt', slug: 'linen-shirt', description: 'A relaxed-fit shirt in 100% European linen. Naturally breathable and softer with every wash.', price: 189.9, inventoryCount: 24, sku: 'LNS-002', categoryId: 'cat-apparel', hues: [35, 20], weight: 0.3 },\n { id: 'p-03', name: 'Denim Jacket', slug: 'denim-jacket', description: 'A structured trucker jacket in 12oz raw denim. Ages beautifully with hidden interior pockets.', price: 299.9, inventoryCount: 12, sku: 'DNJ-003', categoryId: 'cat-apparel', hues: [215, 200], weight: 0.8 },\n { id: 'p-04', name: 'Wool Beanie', slug: 'wool-beanie', description: 'A double-layer merino wool beanie. Warm without itch, with a low-profile cuffed fit.', price: 79.9, inventoryCount: 0, sku: 'WBN-004', categoryId: 'cat-apparel', hues: [0, 350], weight: 0.1 },\n\n // --- Bags & Accessories ---\n { id: 'p-05', name: 'Canvas Tote Bag', slug: 'canvas-tote-bag', description: 'An everyday carryall in 16oz waxed canvas with reinforced straps and an interior zip pocket.', price: 39.9, inventoryCount: 30, sku: 'BAG-001', categoryId: 'cat-bags', hues: [80, 110], weight: 0.3 },\n { id: 'p-06', name: 'Leather Backpack', slug: 'leather-backpack', description: 'Full-grain leather backpack with a padded 15\" laptop sleeve, magnetic closures and brass hardware.', price: 549.9, inventoryCount: 8, sku: 'LBP-006', categoryId: 'cat-bags', hues: [25, 15], weight: 1.4 },\n { id: 'p-07', name: 'Leather Card Wallet', slug: 'leather-card-wallet', description: 'A slim six-card wallet in vegetable-tanned leather. RFID-shielded with a center cash slot.', price: 89.9, compareAtPrice: 119.9, inventoryCount: 45, sku: 'LCW-007', categoryId: 'cat-bags', hues: [30, 45], weight: 0.08 },\n { id: 'p-08', name: 'Travel Duffel', slug: 'travel-duffel', description: 'A 40L weekender in ballistic nylon with a trolley sleeve, shoe compartment and detachable strap.', price: 329.9, inventoryCount: 15, sku: 'TDF-008', categoryId: 'cat-bags', hues: [150, 170], weight: 1.1 },\n\n // --- Home & Kitchen ---\n { id: 'p-09', name: 'Ceramic Coffee Mug', slug: 'ceramic-coffee-mug', description: 'A 350ml stoneware mug with a matte glaze and comfortable wide handle. Dishwasher and microwave safe.', price: 34.9, inventoryCount: 0, sku: 'MUG-001', categoryId: 'cat-home', hues: [190, 210], weight: 0.4 },\n { id: 'p-10', name: 'Scented Soy Candle', slug: 'scented-soy-candle', description: 'Hand-poured soy wax candle with cedar and bergamot notes. 45-hour burn time in a reusable glass jar.', price: 69.9, inventoryCount: 60, sku: 'SSC-010', categoryId: 'cat-home', hues: [45, 30], weight: 0.5 },\n { id: 'p-11', name: 'Bamboo Cutting Board', slug: 'bamboo-cutting-board', description: 'An end-grain bamboo board that is gentle on knives, with a juice groove and inset handles.', price: 119.9, inventoryCount: 22, sku: 'BCB-011', categoryId: 'cat-home', hues: [90, 70], weight: 1.2 },\n { id: 'p-12', name: 'Stoneware Plate Set', slug: 'stoneware-plate-set', description: 'A set of four reactive-glaze dinner plates. Each piece is unique, oven-safe to 220°C.', price: 249.9, inventoryCount: 10, sku: 'SPS-012', categoryId: 'cat-home', hues: [200, 180], weight: 2.4 },\n\n // --- Stationery & Tech ---\n { id: 'p-13', name: 'Wireless Headphones', slug: 'wireless-headphones', description: 'Over-ear headphones with active noise cancelling, 40-hour battery and multipoint Bluetooth 5.3.', price: 899.9, inventoryCount: 18, sku: 'WHP-013', categoryId: 'cat-tech', hues: [260, 280], weight: 0.35 },\n { id: 'p-14', name: 'Notebook Set', slug: 'notebook-set', description: 'Three A5 dot-grid notebooks with 120gsm paper, lay-flat binding and numbered pages.', price: 29.9, inventoryCount: 80, sku: 'NBS-014', categoryId: 'cat-tech', hues: [330, 310], weight: 0.45 },\n { id: 'p-15', name: 'Bluetooth Speaker', slug: 'bluetooth-speaker', description: 'A pocket-size speaker with surprising low end, IPX7 waterproofing and 14-hour playtime.', price: 199.9, compareAtPrice: 259.9, inventoryCount: 26, sku: 'BTS-015', categoryId: 'cat-tech', hues: [170, 190], weight: 0.3 },\n { id: 'p-16', name: 'Felt Desk Mat', slug: 'felt-desk-mat', description: 'A 80x30cm merino felt desk mat with a cork base. Protects the desk and quiets the keyboard.', price: 99.9, inventoryCount: 34, sku: 'FDM-016', categoryId: 'cat-tech', hues: [220, 230], weight: 0.6 },\n]\n\nconst CATEGORY_NAME: Record<string, string> = Object.fromEntries(\n MOCK_CATEGORIES.map((c) => [c.id, c.name]),\n)\n\nexport const MOCK_PRODUCTS: Product[] = SEEDS.map((s, i) => ({\n id: s.id,\n tenantId: 'mock',\n name: s.name,\n slug: s.slug,\n description: s.description,\n price: s.price,\n compareAtPrice: s.compareAtPrice ?? null,\n currency: 'BRL',\n status: 'active',\n inventoryCount: s.inventoryCount,\n sku: s.sku,\n sortOrder: i,\n metadata: {},\n images: [image(s.id, s.name, s.hues[0], s.hues[1])],\n categoryId: s.categoryId,\n categoryName: CATEGORY_NAME[s.categoryId] ?? null,\n isPhysical: true,\n weight: s.weight,\n weightUnit: 'kg',\n // staggered timestamps → deterministic 'newest' sort (p-16 newest)\n createdAt: `2026-01-${String(i + 1).padStart(2, '0')}T12:00:00.000Z`,\n updatedAt: `2026-01-${String(i + 1).padStart(2, '0')}T12:00:00.000Z`,\n}))\n\nexport const MOCK_DISCOUNTS: Discount[] = [\n {\n id: 'disc-welcome',\n tenantId: 'mock',\n title: 'Welcome 10%',\n code: 'BEMVINDO10',\n type: 'percentage',\n method: 'code',\n value: 10,\n usageLimit: null,\n oncePerCustomer: false,\n minSubtotal: null,\n appliesTo: 'all',\n productIds: [],\n categoryIds: [],\n startsAt: T0,\n endsAt: null,\n status: 'active',\n timesUsed: 0,\n createdAt: T0,\n updatedAt: T0,\n },\n]\n\n// ---------------------------------------------------------------------------\n// buildMockCatalog — terse per-store catalog definition. Generates ids,\n// slugs, SVG imagery and staggered timestamps so every store gets a\n// deterministic, e2e-stable catalog from a few lines of data.\n// ---------------------------------------------------------------------------\n\nexport interface CatalogCategoryInput {\n name: string\n description?: string\n image?: string\n}\n\nexport interface CatalogProductInput {\n name: string\n description: string\n price: number\n compareAtPrice?: number\n inventory: number\n sku: string\n /** Category name — must match one of the categories */\n category: string\n hues?: [number, number]\n weight?: number\n image?: string\n metadata?: Record<string, unknown>\n}\n\nexport interface CatalogInput {\n categories: CatalogCategoryInput[]\n products: CatalogProductInput[]\n /** Percentage discount codes, e.g. [{ code: 'BEMVINDO10', percent: 10 }] */\n discounts?: Array<{ code: string; percent: number; title?: string }>\n currency?: string\n}\n\nfunction slugifyName(name: string): string {\n return name\n .toLowerCase()\n .normalize('NFD')\n .replace(/[̀-ͯ]/g, '')\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '')\n}\n\nexport function buildMockCatalog(input: CatalogInput): { products: Product[]; categories: Category[]; discounts: Discount[] } {\n const categories: Category[] = input.categories.map((c, i) => ({\n id: `cat-${slugifyName(c.name)}`,\n tenantId: 'mock',\n name: c.name,\n slug: slugifyName(c.name),\n description: c.description ?? null,\n parentId: null,\n sortOrder: i,\n imageUrl: c.image ?? null,\n createdAt: T0,\n }))\n const byName = Object.fromEntries(categories.map((c) => [c.name, c]))\n\n const products: Product[] = input.products.map((p, i) => {\n const cat = byName[p.category]\n const id = `p-${String(i + 1).padStart(2, '0')}`\n const hues = p.hues ?? [(i * 47) % 360, (i * 47 + 50) % 360]\n const stamp = `2026-01-${String((i % 27) + 1).padStart(2, '0')}T12:00:00.000Z`\n return {\n id,\n tenantId: 'mock',\n name: p.name,\n slug: slugifyName(p.name),\n description: p.description,\n price: p.price,\n compareAtPrice: p.compareAtPrice ?? null,\n currency: input.currency ?? 'BRL',\n status: 'active',\n inventoryCount: p.inventory,\n sku: p.sku,\n sortOrder: i,\n metadata: p.metadata ?? {},\n images: [\n {\n id: `img-${id}-0`,\n productId: id,\n url: p.image ?? svgPlaceholder(p.name, hues[0], hues[1]),\n altText: p.name,\n sortOrder: 0,\n isPrimary: true,\n createdAt: T0,\n },\n ],\n categoryId: cat?.id ?? null,\n categoryName: cat?.name ?? null,\n isPhysical: true,\n weight: p.weight ?? 0.5,\n weightUnit: 'kg',\n createdAt: stamp,\n updatedAt: stamp,\n }\n })\n\n const discounts: Discount[] = (input.discounts ?? []).map((d, i) => ({\n id: `disc-${slugifyName(d.code)}`,\n tenantId: 'mock',\n title: d.title ?? `${d.percent}% off`,\n code: d.code,\n type: 'percentage',\n method: 'code',\n value: d.percent,\n usageLimit: null,\n oncePerCustomer: false,\n minSubtotal: null,\n appliesTo: 'all',\n productIds: [],\n categoryIds: [],\n startsAt: T0,\n endsAt: null,\n status: 'active',\n timesUsed: 0,\n createdAt: T0,\n updatedAt: T0,\n }))\n\n return { products, categories, discounts }\n}\n"]}
package/dist/index.cjs CHANGED
@@ -86,6 +86,10 @@ var MOCK_DISCOUNTS = [
86
86
  value: 10,
87
87
  usageLimit: null,
88
88
  oncePerCustomer: false,
89
+ minSubtotal: null,
90
+ appliesTo: "all",
91
+ productIds: [],
92
+ categoryIds: [],
89
93
  startsAt: T0,
90
94
  endsAt: null,
91
95
  status: "active",
@@ -159,6 +163,10 @@ function buildMockCatalog(input) {
159
163
  value: d.percent,
160
164
  usageLimit: null,
161
165
  oncePerCustomer: false,
166
+ minSubtotal: null,
167
+ appliesTo: "all",
168
+ productIds: [],
169
+ categoryIds: [],
162
170
  startsAt: T0,
163
171
  endsAt: null,
164
172
  status: "active",
@@ -179,6 +187,10 @@ function now() {
179
187
  var ORDERS_KEY = "fayz.shop.mock.orders.v1";
180
188
  var CUSTOMERS_KEY = "fayz.shop.mock.customers.v1";
181
189
  var ENQUIRIES_KEY = "fayz.shop.mock.enquiries.v1";
190
+ var CHANNELS_KEY = "fayz.shop.mock.channels.v1";
191
+ var DEFAULT_CHANNELS = [
192
+ { id: "online-store", tenantId: "mock", kind: "online_store", label: "Loja Online", url: null, enabled: true, position: 0, createdAt: now(), updatedAt: now() }
193
+ ];
182
194
  function loadStored(key) {
183
195
  try {
184
196
  if (typeof localStorage === "undefined") return [];
@@ -200,6 +212,10 @@ var MockShopProvider = class {
200
212
  this.orders = loadStored(ORDERS_KEY);
201
213
  this.customers = loadStored(CUSTOMERS_KEY);
202
214
  this.enquiries = loadStored(ENQUIRIES_KEY);
215
+ this.channels = (() => {
216
+ const stored = loadStored(CHANNELS_KEY);
217
+ return stored.length ? stored : DEFAULT_CHANNELS.map((c) => ({ ...c }));
218
+ })();
203
219
  this.products = (seed?.products ?? MOCK_PRODUCTS).map((p) => ({ ...p }));
204
220
  this.categories = (seed?.categories ?? MOCK_CATEGORIES).map((c) => ({ ...c }));
205
221
  this.discounts = (seed?.discounts ?? MOCK_DISCOUNTS).map((d) => ({ ...d }));
@@ -215,6 +231,10 @@ var MockShopProvider = class {
215
231
  syncEnquiries() {
216
232
  this.enquiries = loadStored(ENQUIRIES_KEY);
217
233
  }
234
+ syncChannels() {
235
+ const stored = loadStored(CHANNELS_KEY);
236
+ if (stored.length) this.channels = stored;
237
+ }
218
238
  persistOrders() {
219
239
  store(ORDERS_KEY, this.orders);
220
240
  }
@@ -224,6 +244,9 @@ var MockShopProvider = class {
224
244
  persistEnquiries() {
225
245
  store(ENQUIRIES_KEY, this.enquiries);
226
246
  }
247
+ persistChannels() {
248
+ store(CHANNELS_KEY, this.channels);
249
+ }
227
250
  // ---------------------------------------------------------------------------
228
251
  // Products
229
252
  // ---------------------------------------------------------------------------
@@ -432,13 +455,16 @@ var MockShopProvider = class {
432
455
  }
433
456
  }
434
457
  const items = [];
458
+ const lineDetails = [];
435
459
  let subtotal = 0;
436
460
  for (const line of input.items) {
437
461
  const product = this.products.find((p) => p.id === line.productId);
438
462
  if (!product || product.status !== "active") throw new Error(`Product unavailable: ${line.productId}`);
439
463
  if (product.inventoryCount < line.quantity) throw new Error(`Insufficient stock for ${product.name}`);
440
464
  const name = line.optionsLabel ? `${product.name} (${line.optionsLabel})` : product.name;
441
- subtotal += product.price * line.quantity;
465
+ const lineTotal = product.price * line.quantity;
466
+ subtotal += lineTotal;
467
+ lineDetails.push({ productId: product.id, categoryId: product.categoryId, lineTotal });
442
468
  items.push({ productId: product.id, name, sku: product.sku ?? void 0, quantity: line.quantity, unitPrice: product.price, imageUrl: product.images[0]?.url });
443
469
  }
444
470
  subtotal = Math.round(subtotal * 100) / 100;
@@ -449,11 +475,19 @@ var MockShopProvider = class {
449
475
  const code = input.discountCode.trim().toLowerCase();
450
476
  const d = this.discounts.find((x) => (x.code ?? "").toLowerCase() === code);
451
477
  const ts = now();
452
- const valid = !!d && d.status === "active" && d.startsAt <= ts && (!d.endsAt || d.endsAt >= ts) && (d.usageLimit == null || d.timesUsed < d.usageLimit);
478
+ const meetsMin = !d?.minSubtotal || subtotal >= d.minSubtotal;
479
+ const valid = !!d && d.status === "active" && d.startsAt <= ts && (!d.endsAt || d.endsAt >= ts) && (d.usageLimit == null || d.timesUsed < d.usageLimit) && meetsMin;
453
480
  if (valid && d) {
454
481
  appliedCode = d.code;
455
- if (d.type === "percentage") discountTotal = Math.round(subtotal * d.value) / 100;
456
- else if (d.type === "fixed_amount") discountTotal = Math.min(d.value, subtotal);
482
+ let eligible = subtotal;
483
+ if (d.appliesTo === "products") {
484
+ eligible = lineDetails.filter((l) => d.productIds.includes(l.productId)).reduce((s, l) => s + l.lineTotal, 0);
485
+ } else if (d.appliesTo === "categories") {
486
+ eligible = lineDetails.filter((l) => l.categoryId && d.categoryIds.includes(l.categoryId)).reduce((s, l) => s + l.lineTotal, 0);
487
+ }
488
+ eligible = Math.round(eligible * 100) / 100;
489
+ if (d.type === "percentage") discountTotal = Math.round(eligible * d.value) / 100;
490
+ else if (d.type === "fixed_amount") discountTotal = Math.min(d.value, eligible);
457
491
  else if (d.type === "free_shipping") shippingTotal = 0;
458
492
  d.timesUsed += 1;
459
493
  }
@@ -533,7 +567,7 @@ var MockShopProvider = class {
533
567
  return this.discounts.find((d) => d.id === id) ?? null;
534
568
  }
535
569
  async createDiscount(input) {
536
- const d = { id: uid(), tenantId: "mock", title: input.title, code: input.code ?? null, type: input.type, method: input.method ?? "code", value: input.value, usageLimit: input.usageLimit ?? null, oncePerCustomer: input.oncePerCustomer ?? false, startsAt: input.startsAt ?? now(), endsAt: input.endsAt ?? null, status: input.status ?? "active", timesUsed: 0, createdAt: now(), updatedAt: now() };
570
+ const d = { id: uid(), tenantId: "mock", title: input.title, code: input.code ?? null, type: input.type, method: input.method ?? "code", value: input.value, usageLimit: input.usageLimit ?? null, oncePerCustomer: input.oncePerCustomer ?? false, minSubtotal: input.minSubtotal ?? null, appliesTo: input.appliesTo ?? "all", productIds: input.productIds ?? [], categoryIds: input.categoryIds ?? [], startsAt: input.startsAt ?? now(), endsAt: input.endsAt ?? null, status: input.status ?? "active", timesUsed: 0, createdAt: now(), updatedAt: now() };
537
571
  this.discounts.push(d);
538
572
  return d;
539
573
  }
@@ -546,6 +580,33 @@ var MockShopProvider = class {
546
580
  async deleteDiscount(id) {
547
581
  this.discounts = this.discounts.filter((d) => d.id !== id);
548
582
  }
583
+ // ---------------------------------------------------------------------------
584
+ // Sales channels
585
+ // ---------------------------------------------------------------------------
586
+ async listSalesChannels() {
587
+ this.syncChannels();
588
+ return [...this.channels].sort((a, b) => a.position - b.position);
589
+ }
590
+ async createSalesChannel(input) {
591
+ this.syncChannels();
592
+ const c = { id: uid(), tenantId: "mock", kind: input.kind, label: input.label, url: input.url ?? null, enabled: input.enabled ?? true, position: input.position ?? this.channels.length, createdAt: now(), updatedAt: now() };
593
+ this.channels.push(c);
594
+ this.persistChannels();
595
+ return c;
596
+ }
597
+ async updateSalesChannel(id, input) {
598
+ this.syncChannels();
599
+ const i = this.channels.findIndex((c) => c.id === id);
600
+ if (i < 0) throw new Error("Sales channel not found");
601
+ this.channels[i] = { ...this.channels[i], ...input, updatedAt: now() };
602
+ this.persistChannels();
603
+ return this.channels[i];
604
+ }
605
+ async deleteSalesChannel(id) {
606
+ this.syncChannels();
607
+ this.channels = this.channels.filter((c) => c.id !== id);
608
+ this.persistChannels();
609
+ }
549
610
  };
550
611
  function createMockShopProvider(seed) {
551
612
  return new MockShopProvider(seed);
@@ -665,6 +726,7 @@ var T = {
665
726
  orderItems: "plg_shop_order_items",
666
727
  customers: "plg_shop_customers",
667
728
  discounts: "plg_shop_discounts",
729
+ salesChannels: "plg_shop_channels",
668
730
  // Core, not plg_shop_*: a delivery zone is a fact about the business, and
669
731
  // fulfilment and financial read it too. Same reasoning as addresses and
670
732
  // orders — see migration 0021.
@@ -833,6 +895,10 @@ function rowToDiscount(row) {
833
895
  value: row.value ?? 0,
834
896
  usageLimit: row.usage_limit,
835
897
  oncePerCustomer: row.once_per_customer ?? false,
898
+ minSubtotal: row.min_subtotal ?? null,
899
+ appliesTo: row.applies_to ?? "all",
900
+ productIds: row.product_ids ?? [],
901
+ categoryIds: row.category_ids ?? [],
836
902
  startsAt: row.starts_at,
837
903
  endsAt: row.ends_at,
838
904
  status: row.status ?? "active",
@@ -841,6 +907,19 @@ function rowToDiscount(row) {
841
907
  updatedAt: row.updated_at
842
908
  };
843
909
  }
910
+ function rowToSalesChannel(row) {
911
+ return {
912
+ id: row.id,
913
+ tenantId: row.tenant_id,
914
+ kind: row.kind,
915
+ label: row.label,
916
+ url: row.url,
917
+ enabled: row.enabled ?? true,
918
+ position: row.position ?? 0,
919
+ createdAt: row.created_at,
920
+ updatedAt: row.updated_at
921
+ };
922
+ }
844
923
  var SupabaseShopProvider = class {
845
924
  // ---------------------------------------------------------------------------
846
925
  // Products
@@ -1201,7 +1280,7 @@ var SupabaseShopProvider = class {
1201
1280
  return data ? rowToDiscount(data) : null;
1202
1281
  }
1203
1282
  async createDiscount(input) {
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();
1283
+ 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, min_subtotal: input.minSubtotal ?? null, applies_to: input.appliesTo ?? "all", product_ids: input.productIds ?? [], category_ids: input.categoryIds ?? [], starts_at: input.startsAt ?? (/* @__PURE__ */ new Date()).toISOString(), ends_at: input.endsAt ?? null, status: input.status ?? "active", times_used: 0 }).select().single();
1205
1284
  if (error) throw error;
1206
1285
  return rowToDiscount(data);
1207
1286
  }
@@ -1212,6 +1291,10 @@ var SupabaseShopProvider = class {
1212
1291
  if (input.type !== void 0) updates.type = input.type;
1213
1292
  if (input.value !== void 0) updates.value = input.value;
1214
1293
  if (input.usageLimit !== void 0) updates.usage_limit = input.usageLimit;
1294
+ if (input.minSubtotal !== void 0) updates.min_subtotal = input.minSubtotal;
1295
+ if (input.appliesTo !== void 0) updates.applies_to = input.appliesTo;
1296
+ if (input.productIds !== void 0) updates.product_ids = input.productIds;
1297
+ if (input.categoryIds !== void 0) updates.category_ids = input.categoryIds;
1215
1298
  if (input.status !== void 0) updates.status = input.status;
1216
1299
  if (input.endsAt !== void 0) updates.ends_at = input.endsAt;
1217
1300
  const { data, error } = await getDb().from(T.discounts).update(updates).eq("id", id).select().single();
@@ -1222,6 +1305,38 @@ var SupabaseShopProvider = class {
1222
1305
  const { error } = await getDb().from(T.discounts).delete().eq("id", id);
1223
1306
  if (error) throw error;
1224
1307
  }
1308
+ // ---------------------------------------------------------------------------
1309
+ // Sales channels
1310
+ // ---------------------------------------------------------------------------
1311
+ async listSalesChannels() {
1312
+ const db = getDb();
1313
+ const tenantId = getTenantId();
1314
+ let q = db.from(T.salesChannels).select("*").order("position", { ascending: true });
1315
+ if (tenantId) q = q.eq("tenant_id", tenantId);
1316
+ const { data, error } = await q;
1317
+ if (error) throw error;
1318
+ return (data ?? []).map(rowToSalesChannel);
1319
+ }
1320
+ async createSalesChannel(input) {
1321
+ const { data, error } = await getDb().from(T.salesChannels).insert({ tenant_id: getTenantId(), kind: input.kind, label: input.label, url: input.url ?? null, enabled: input.enabled ?? true, position: input.position ?? 0 }).select().single();
1322
+ if (error) throw error;
1323
+ return rowToSalesChannel(data);
1324
+ }
1325
+ async updateSalesChannel(id, input) {
1326
+ const updates = {};
1327
+ if (input.kind !== void 0) updates.kind = input.kind;
1328
+ if (input.label !== void 0) updates.label = input.label;
1329
+ if (input.url !== void 0) updates.url = input.url;
1330
+ if (input.enabled !== void 0) updates.enabled = input.enabled;
1331
+ if (input.position !== void 0) updates.position = input.position;
1332
+ const { data, error } = await getDb().from(T.salesChannels).update(updates).eq("id", id).select().single();
1333
+ if (error) throw error;
1334
+ return rowToSalesChannel(data);
1335
+ }
1336
+ async deleteSalesChannel(id) {
1337
+ const { error } = await getDb().from(T.salesChannels).delete().eq("id", id);
1338
+ if (error) throw error;
1339
+ }
1225
1340
  };
1226
1341
  function createSupabaseShopProvider() {
1227
1342
  return new SupabaseShopProvider();