@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 +8 -0
- package/dist/catalog.cjs.map +1 -1
- package/dist/catalog.js +8 -0
- package/dist/catalog.js.map +1 -1
- package/dist/index.cjs +121 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +121 -6
- package/dist/index.js.map +1 -1
- package/dist/mock-catalog.d.ts.map +1 -1
- package/dist/mock-provider.d.ts +8 -1
- package/dist/mock-provider.d.ts.map +1 -1
- package/dist/mock.cjs +62 -5
- package/dist/mock.cjs.map +1 -1
- package/dist/mock.js +62 -5
- package/dist/mock.js.map +1 -1
- package/dist/provider.d.ts +5 -1
- package/dist/provider.d.ts.map +1 -1
- package/dist/runtime.cjs +62 -5
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.js +62 -5
- package/dist/runtime.js.map +1 -1
- package/dist/supabase-provider.d.ts +5 -1
- package/dist/supabase-provider.d.ts.map +1 -1
- package/dist/tables.d.ts +1 -0
- package/dist/tables.d.ts.map +1 -1
- package/dist/types.d.ts +48 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/index.ts +1 -0
- package/src/mock-catalog.ts +8 -0
- package/src/mock-provider.ts +63 -5
- package/src/provider.ts +8 -0
- package/src/supabase-provider.ts +64 -1
- package/src/tables.ts +1 -0
- package/src/types.ts +67 -0
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",
|
package/dist/catalog.cjs.map
CHANGED
|
@@ -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",
|
package/dist/catalog.js.map
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
|
-
|
|
456
|
-
|
|
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();
|