@cimplify/sdk 0.38.1 → 0.38.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/mock/cli.mjs CHANGED
@@ -3959,6 +3959,15 @@ function percent(a, pct) {
3959
3959
  function createCatalogueService(opts) {
3960
3960
  const { registry, clock, ids } = opts;
3961
3961
  const productsForBusiness = (businessId) => registry.products.list((p) => p.business_id === businessId);
3962
+ const defaultPriceInfo = (price, currency) => ({
3963
+ base_price: price,
3964
+ final_price: price,
3965
+ markup_percentage: "0.00",
3966
+ markup_amount: "0.00",
3967
+ markup_discount_percentage: "0.00",
3968
+ markup_discount_amount: "0.00",
3969
+ currency
3970
+ });
3962
3971
  const toApiProduct = (p) => ({
3963
3972
  id: p.id,
3964
3973
  business_id: p.business_id,
@@ -3967,10 +3976,15 @@ function createCatalogueService(opts) {
3967
3976
  description: p.description ?? "",
3968
3977
  product_type: p.product_type,
3969
3978
  base_price: p.base_price,
3979
+ default_price: p.base_price,
3980
+ default_price_info: defaultPriceInfo(p.base_price, p.currency),
3981
+ price_info: defaultPriceInfo(p.base_price, p.currency),
3970
3982
  currency: p.currency,
3971
3983
  image: p.image,
3984
+ image_url: p.image,
3972
3985
  images: p.images,
3973
3986
  is_available: p.is_available,
3987
+ category_id: p.category_ids[0],
3974
3988
  category_ids: p.category_ids,
3975
3989
  collection_ids: p.collection_ids,
3976
3990
  add_on_ids: p.add_on_ids,
@@ -3980,6 +3994,7 @@ function createCatalogueService(opts) {
3980
3994
  custom_attributes: [],
3981
3995
  properties: [],
3982
3996
  has_variants: p.variant_ids.length > 0,
3997
+ type: p.product_type,
3983
3998
  render_hint: "general"
3984
3999
  });
3985
4000
  const variantsForProduct = (productId) => registry.variants.list((v) => v.product_id === productId);
@@ -5246,26 +5261,26 @@ function createLiteService(opts) {
5246
5261
  // src/mock/seeds/default.ts
5247
5262
  var ISO = "2026-01-01T00:00:00.000Z";
5248
5263
  var PRODUCTS = [
5249
- { name: "Sourdough Loaf", slug: "sourdough-loaf", price: "25.00", category: "breads", description: "Artisanal 24-hour fermented sourdough.", image: "https://mock.cimplify.io/img/sourdough.jpg" },
5250
- { name: "Whole Wheat Bread", slug: "whole-wheat", price: "20.00", category: "breads", description: "Hearty whole wheat with seeds.", image: "https://mock.cimplify.io/img/wheat.jpg" },
5251
- { name: "Baguette", slug: "baguette", price: "15.00", category: "breads", description: "Crispy crust, soft inside.", image: "https://mock.cimplify.io/img/baguette.jpg" },
5252
- { name: "Focaccia", slug: "focaccia", price: "30.00", category: "breads", description: "Olive oil and rosemary focaccia.", image: "https://mock.cimplify.io/img/focaccia.jpg" },
5253
- { name: "Croissant", slug: "croissant", price: "12.00", category: "pastries", description: "Buttery French croissant.", image: "https://mock.cimplify.io/img/croissant.jpg" },
5254
- { name: "Pain au Chocolat", slug: "pain-au-chocolat", price: "14.00", category: "pastries", description: "Croissant with dark chocolate.", image: "https://mock.cimplify.io/img/pac.jpg" },
5255
- { name: "Almond Danish", slug: "almond-danish", price: "16.00", category: "pastries", description: "Flaky pastry with almond cream.", image: "https://mock.cimplify.io/img/danish.jpg" },
5256
- { name: "Cinnamon Roll", slug: "cinnamon-roll", price: "13.00", category: "pastries", description: "Soft roll with cinnamon glaze.", image: "https://mock.cimplify.io/img/cinnamon.jpg" },
5257
- { name: "Chocolate Cake (Slice)", slug: "chocolate-cake", price: "22.00", category: "cakes", description: "Rich dark chocolate cake.", image: "https://mock.cimplify.io/img/choc-cake.jpg" },
5258
- { name: "Red Velvet (Slice)", slug: "red-velvet", price: "22.00", category: "cakes", description: "Classic red velvet with cream cheese.", image: "https://mock.cimplify.io/img/red-velvet.jpg" },
5259
- { name: "Carrot Cake (Slice)", slug: "carrot-cake", price: "20.00", category: "cakes", description: "Spiced carrot cake with walnut.", image: "https://mock.cimplify.io/img/carrot.jpg" },
5260
- { name: "Cheesecake (Slice)", slug: "cheesecake", price: "24.00", category: "cakes", description: "New York style cheesecake.", image: "https://mock.cimplify.io/img/cheesecake.jpg" },
5261
- { name: "Coffee", slug: "coffee", price: "10.00", category: "drinks", description: "Locally roasted Arabica.", image: "https://mock.cimplify.io/img/coffee.jpg" },
5262
- { name: "Tea", slug: "tea", price: "8.00", category: "drinks", description: "Black, green, or herbal.", image: "https://mock.cimplify.io/img/tea.jpg" },
5263
- { name: "Hibiscus Tea (Sobolo)", slug: "sobolo", price: "12.00", category: "drinks", description: "Iced hibiscus drink.", image: "https://mock.cimplify.io/img/sobolo.jpg" },
5264
- { name: "Fresh Orange Juice", slug: "orange-juice", price: "15.00", category: "drinks", description: "Cold-pressed orange juice.", image: "https://mock.cimplify.io/img/oj.jpg" },
5265
- { name: "Banana Bread", slug: "banana-bread", price: "18.00", category: "breads", description: "Moist banana loaf.", image: "https://mock.cimplify.io/img/banana.jpg" },
5266
- { name: "Brownie", slug: "brownie", price: "12.00", category: "pastries", description: "Fudgy chocolate brownie.", image: "https://mock.cimplify.io/img/brownie.jpg" },
5267
- { name: "Macaron Box (6)", slug: "macaron-box", price: "60.00", category: "pastries", description: "Six assorted macarons.", image: "https://mock.cimplify.io/img/macaron.jpg" },
5268
- { name: "Custom Birthday Cake", slug: "birthday-cake", price: "250.00", category: "cakes", description: "Made-to-order. Min 48h notice.", image: "https://mock.cimplify.io/img/birthday.jpg" }
5264
+ { name: "Sourdough Loaf", slug: "sourdough-loaf", price: "25.00", category: "breads", description: "Artisanal 24-hour fermented sourdough.", image: "/img/sourdough.jpg" },
5265
+ { name: "Whole Wheat Bread", slug: "whole-wheat", price: "20.00", category: "breads", description: "Hearty whole wheat with seeds.", image: "/img/wheat.jpg" },
5266
+ { name: "Baguette", slug: "baguette", price: "15.00", category: "breads", description: "Crispy crust, soft inside.", image: "/img/baguette.jpg" },
5267
+ { name: "Focaccia", slug: "focaccia", price: "30.00", category: "breads", description: "Olive oil and rosemary focaccia.", image: "/img/focaccia.jpg" },
5268
+ { name: "Croissant", slug: "croissant", price: "12.00", category: "pastries", description: "Buttery French croissant.", image: "/img/croissant.jpg" },
5269
+ { name: "Pain au Chocolat", slug: "pain-au-chocolat", price: "14.00", category: "pastries", description: "Croissant with dark chocolate.", image: "/img/pac.jpg" },
5270
+ { name: "Almond Danish", slug: "almond-danish", price: "16.00", category: "pastries", description: "Flaky pastry with almond cream.", image: "/img/danish.jpg" },
5271
+ { name: "Cinnamon Roll", slug: "cinnamon-roll", price: "13.00", category: "pastries", description: "Soft roll with cinnamon glaze.", image: "/img/cinnamon.jpg" },
5272
+ { name: "Chocolate Cake (Slice)", slug: "chocolate-cake", price: "22.00", category: "cakes", description: "Rich dark chocolate cake.", image: "/img/choc-cake.jpg" },
5273
+ { name: "Red Velvet (Slice)", slug: "red-velvet", price: "22.00", category: "cakes", description: "Classic red velvet with cream cheese.", image: "/img/red-velvet.jpg" },
5274
+ { name: "Carrot Cake (Slice)", slug: "carrot-cake", price: "20.00", category: "cakes", description: "Spiced carrot cake with walnut.", image: "/img/carrot.jpg" },
5275
+ { name: "Cheesecake (Slice)", slug: "cheesecake", price: "24.00", category: "cakes", description: "New York style cheesecake.", image: "/img/cheesecake.jpg" },
5276
+ { name: "Coffee", slug: "coffee", price: "10.00", category: "drinks", description: "Locally roasted Arabica.", image: "/img/coffee.jpg" },
5277
+ { name: "Tea", slug: "tea", price: "8.00", category: "drinks", description: "Black, green, or herbal.", image: "/img/tea.jpg" },
5278
+ { name: "Hibiscus Tea (Sobolo)", slug: "sobolo", price: "12.00", category: "drinks", description: "Iced hibiscus drink.", image: "/img/sobolo.jpg" },
5279
+ { name: "Fresh Orange Juice", slug: "orange-juice", price: "15.00", category: "drinks", description: "Cold-pressed orange juice.", image: "/img/oj.jpg" },
5280
+ { name: "Banana Bread", slug: "banana-bread", price: "18.00", category: "breads", description: "Moist banana loaf.", image: "/img/banana.jpg" },
5281
+ { name: "Brownie", slug: "brownie", price: "12.00", category: "pastries", description: "Fudgy chocolate brownie.", image: "/img/brownie.jpg" },
5282
+ { name: "Macaron Box (6)", slug: "macaron-box", price: "60.00", category: "pastries", description: "Six assorted macarons.", image: "/img/macaron.jpg" },
5283
+ { name: "Custom Birthday Cake", slug: "birthday-cake", price: "250.00", category: "cakes", description: "Made-to-order. Min 48h notice.", image: "/img/birthday.jpg" }
5269
5284
  ];
5270
5285
  var CATEGORIES = [
5271
5286
  { slug: "breads", name: "Breads", description: "Sourdough, baguettes, focaccia." },
@@ -5286,7 +5301,7 @@ function seedDefault(registry) {
5286
5301
  default_address: "12 Independence Ave, Accra",
5287
5302
  default_offers_table_service: true,
5288
5303
  default_accepts_online_orders: true,
5289
- image: "https://mock.cimplify.io/img/akua-logo.png",
5304
+ image: "/img/akua-logo.png",
5290
5305
  status: "active",
5291
5306
  created_at: ISO,
5292
5307
  updated_at: ISO,
@@ -5546,8 +5561,8 @@ function seedDefault(registry) {
5546
5561
  product_type: "bundle",
5547
5562
  base_price: "30.00",
5548
5563
  currency: "GHS",
5549
- image: "https://mock.cimplify.io/img/breakfast-box.jpg",
5550
- images: ["https://mock.cimplify.io/img/breakfast-box.jpg"],
5564
+ image: "/img/breakfast-box.jpg",
5565
+ images: ["/img/breakfast-box.jpg"],
5551
5566
  is_available: true,
5552
5567
  category_ids: [categoryIdsBySlug.get("pastries")],
5553
5568
  collection_ids: [],
@@ -5587,8 +5602,8 @@ function seedDefault(registry) {
5587
5602
  product_type: "composite",
5588
5603
  base_price: "60.00",
5589
5604
  currency: "GHS",
5590
- image: "https://mock.cimplify.io/img/pastry-box.jpg",
5591
- images: ["https://mock.cimplify.io/img/pastry-box.jpg"],
5605
+ image: "/img/pastry-box.jpg",
5606
+ images: ["/img/pastry-box.jpg"],
5592
5607
  is_available: true,
5593
5608
  category_ids: [categoryIdsBySlug.get("pastries")],
5594
5609
  collection_ids: [],
@@ -5774,7 +5789,7 @@ function seedReesa(registry) {
5774
5789
  default_address: "5 Allen Avenue, Ikeja, Lagos",
5775
5790
  default_offers_table_service: false,
5776
5791
  default_accepts_online_orders: true,
5777
- image: "https://mock.cimplify.io/img/reesa-logo.png",
5792
+ image: "/img/reesa-logo.png",
5778
5793
  status: "active",
5779
5794
  created_at: ISO3,
5780
5795
  updated_at: ISO3,
@@ -5830,8 +5845,8 @@ function seedReesa(registry) {
5830
5845
  product_type: "product",
5831
5846
  base_price: p.price,
5832
5847
  currency: "NGN",
5833
- image: `https://mock.cimplify.io/img/reesa/${p.slug}.jpg`,
5834
- images: [`https://mock.cimplify.io/img/reesa/${p.slug}.jpg`],
5848
+ image: `/img/reesa/${p.slug}.jpg`,
5849
+ images: [`/img/reesa/${p.slug}.jpg`],
5835
5850
  is_available: true,
5836
5851
  category_ids: [catId],
5837
5852
  collection_ids: [],
@@ -6054,8 +6069,8 @@ function seedReesa(registry) {
6054
6069
  product_type: "bundle",
6055
6070
  base_price: "55000.00",
6056
6071
  currency: "NGN",
6057
- image: "https://mock.cimplify.io/img/reesa/owambe.jpg",
6058
- images: ["https://mock.cimplify.io/img/reesa/owambe.jpg"],
6072
+ image: "/img/reesa/owambe.jpg",
6073
+ images: ["/img/reesa/owambe.jpg"],
6059
6074
  is_available: true,
6060
6075
  category_ids: [catIdsBySlug.get("apparel")],
6061
6076
  collection_ids: [],
@@ -6186,7 +6201,7 @@ function seedRestaurant(registry) {
6186
6201
  default_address: "8 Ring Road, East Legon, Accra",
6187
6202
  default_offers_table_service: true,
6188
6203
  default_accepts_online_orders: true,
6189
- image: "https://mock.cimplify.io/img/mamas-logo.png",
6204
+ image: "/img/mamas-logo.png",
6190
6205
  status: "active",
6191
6206
  created_at: ISO4,
6192
6207
  updated_at: ISO4,
@@ -6257,8 +6272,8 @@ function seedRestaurant(registry) {
6257
6272
  product_type: "product",
6258
6273
  base_price: p.price,
6259
6274
  currency: "GHS",
6260
- image: `https://mock.cimplify.io/img/mamas/${p.slug}.jpg`,
6261
- images: [`https://mock.cimplify.io/img/mamas/${p.slug}.jpg`],
6275
+ image: `/img/mamas/${p.slug}.jpg`,
6276
+ images: [`/img/mamas/${p.slug}.jpg`],
6262
6277
  is_available: true,
6263
6278
  category_ids: [catId],
6264
6279
  collection_ids: [],
@@ -6496,8 +6511,8 @@ function seedRestaurant(registry) {
6496
6511
  product_type: "bundle",
6497
6512
  base_price: "180.00",
6498
6513
  currency: "GHS",
6499
- image: "https://mock.cimplify.io/img/mamas/feast.jpg",
6500
- images: ["https://mock.cimplify.io/img/mamas/feast.jpg"],
6514
+ image: "/img/mamas/feast.jpg",
6515
+ images: ["/img/mamas/feast.jpg"],
6501
6516
  is_available: true,
6502
6517
  category_ids: [catIds.get("mains")],
6503
6518
  collection_ids: [],
@@ -6532,8 +6547,8 @@ function seedRestaurant(registry) {
6532
6547
  product_type: "composite",
6533
6548
  base_price: "0.00",
6534
6549
  currency: "GHS",
6535
- image: "https://mock.cimplify.io/img/mamas/byo.jpg",
6536
- images: ["https://mock.cimplify.io/img/mamas/byo.jpg"],
6550
+ image: "/img/mamas/byo.jpg",
6551
+ images: ["/img/mamas/byo.jpg"],
6537
6552
  is_available: true,
6538
6553
  category_ids: [catIds.get("mains")],
6539
6554
  collection_ids: [],
@@ -6645,7 +6660,7 @@ function seedRetail(registry) {
6645
6660
  default_address: "Atomic Junction, Accra",
6646
6661
  default_offers_table_service: false,
6647
6662
  default_accepts_online_orders: true,
6648
- image: "https://mock.cimplify.io/img/currents-logo.png",
6663
+ image: "/img/currents-logo.png",
6649
6664
  status: "active",
6650
6665
  created_at: ISO5,
6651
6666
  updated_at: ISO5,
@@ -6715,8 +6730,8 @@ function seedRetail(registry) {
6715
6730
  product_type: "product",
6716
6731
  base_price: p.price,
6717
6732
  currency: "GHS",
6718
- image: `https://mock.cimplify.io/img/currents/${p.slug}.jpg`,
6719
- images: [`https://mock.cimplify.io/img/currents/${p.slug}.jpg`],
6733
+ image: `/img/currents/${p.slug}.jpg`,
6734
+ images: [`/img/currents/${p.slug}.jpg`],
6720
6735
  is_available: true,
6721
6736
  category_ids: [catId],
6722
6737
  collection_ids: [],
@@ -6979,8 +6994,8 @@ function seedRetail(registry) {
6979
6994
  product_type: "bundle",
6980
6995
  base_price: "11910.00",
6981
6996
  currency: "GHS",
6982
- image: "https://mock.cimplify.io/img/currents/wfh.jpg",
6983
- images: ["https://mock.cimplify.io/img/currents/wfh.jpg"],
6997
+ image: "/img/currents/wfh.jpg",
6998
+ images: ["/img/currents/wfh.jpg"],
6984
6999
  is_available: true,
6985
7000
  category_ids: [catIds.get("laptops")],
6986
7001
  collection_ids: [],
@@ -7013,8 +7028,8 @@ function seedRetail(registry) {
7013
7028
  product_type: "bundle",
7014
7029
  base_price: "4200.00",
7015
7030
  currency: "GHS",
7016
- image: "https://mock.cimplify.io/img/currents/game-pack.jpg",
7017
- images: ["https://mock.cimplify.io/img/currents/game-pack.jpg"],
7031
+ image: "/img/currents/game-pack.jpg",
7032
+ images: ["/img/currents/game-pack.jpg"],
7018
7033
  is_available: true,
7019
7034
  category_ids: [catIds.get("gaming")],
7020
7035
  collection_ids: [],
@@ -7117,7 +7132,7 @@ function seedServices(registry) {
7117
7132
  default_address: "12 Cantonments Road, Accra",
7118
7133
  default_offers_table_service: false,
7119
7134
  default_accepts_online_orders: true,
7120
- image: "https://mock.cimplify.io/img/serene-logo.png",
7135
+ image: "/img/serene-logo.png",
7121
7136
  status: "active",
7122
7137
  created_at: ISO6,
7123
7138
  updated_at: ISO6,
@@ -7185,8 +7200,8 @@ function seedServices(registry) {
7185
7200
  product_type: "service",
7186
7201
  base_price: s.price,
7187
7202
  currency: "GHS",
7188
- image: `https://mock.cimplify.io/img/serene/${s.slug}.jpg`,
7189
- images: [`https://mock.cimplify.io/img/serene/${s.slug}.jpg`],
7203
+ image: `/img/serene/${s.slug}.jpg`,
7204
+ images: [`/img/serene/${s.slug}.jpg`],
7190
7205
  is_available: true,
7191
7206
  category_ids: [catId],
7192
7207
  collection_ids: [],
@@ -7322,8 +7337,8 @@ function seedServices(registry) {
7322
7337
  product_type: "bundle",
7323
7338
  base_price: "480.00",
7324
7339
  currency: "GHS",
7325
- image: "https://mock.cimplify.io/img/serene/spa-day.jpg",
7326
- images: ["https://mock.cimplify.io/img/serene/spa-day.jpg"],
7340
+ image: "/img/serene/spa-day.jpg",
7341
+ images: ["/img/serene/spa-day.jpg"],
7327
7342
  is_available: true,
7328
7343
  category_ids: [catIds.get("wellness")],
7329
7344
  collection_ids: [],
@@ -7356,8 +7371,8 @@ function seedServices(registry) {
7356
7371
  product_type: "bundle",
7357
7372
  base_price: "850.50",
7358
7373
  currency: "GHS",
7359
- image: "https://mock.cimplify.io/img/serene/couples.jpg",
7360
- images: ["https://mock.cimplify.io/img/serene/couples.jpg"],
7374
+ image: "/img/serene/couples.jpg",
7375
+ images: ["/img/serene/couples.jpg"],
7361
7376
  is_available: true,
7362
7377
  category_ids: [catIds.get("wellness")],
7363
7378
  collection_ids: [],
@@ -7392,8 +7407,8 @@ function seedServices(registry) {
7392
7407
  product_type: "composite",
7393
7408
  base_price: "0.00",
7394
7409
  currency: "GHS",
7395
- image: "https://mock.cimplify.io/img/serene/custom.jpg",
7396
- images: ["https://mock.cimplify.io/img/serene/custom.jpg"],
7410
+ image: "/img/serene/custom.jpg",
7411
+ images: ["/img/serene/custom.jpg"],
7397
7412
  is_available: true,
7398
7413
  category_ids: [catIds.get("wellness")],
7399
7414
  collection_ids: [],
@@ -7496,7 +7511,7 @@ function seedGrocery(registry) {
7496
7511
  default_address: "Spintex Road, Accra",
7497
7512
  default_offers_table_service: false,
7498
7513
  default_accepts_online_orders: true,
7499
- image: "https://mock.cimplify.io/img/freshmart-logo.png",
7514
+ image: "/img/freshmart-logo.png",
7500
7515
  status: "active",
7501
7516
  created_at: ISO7,
7502
7517
  updated_at: ISO7,
@@ -7571,8 +7586,8 @@ function seedGrocery(registry) {
7571
7586
  product_type: "product",
7572
7587
  base_price: p.price,
7573
7588
  currency: "GHS",
7574
- image: `https://mock.cimplify.io/img/freshmart/${p.slug}.jpg`,
7575
- images: [`https://mock.cimplify.io/img/freshmart/${p.slug}.jpg`],
7589
+ image: `/img/freshmart/${p.slug}.jpg`,
7590
+ images: [`/img/freshmart/${p.slug}.jpg`],
7576
7591
  is_available: true,
7577
7592
  category_ids: [catId],
7578
7593
  collection_ids: [],
@@ -7655,8 +7670,8 @@ function seedGrocery(registry) {
7655
7670
  product_type: "bundle",
7656
7671
  base_price: "199.50",
7657
7672
  currency: "GHS",
7658
- image: "https://mock.cimplify.io/img/freshmart/essentials.jpg",
7659
- images: ["https://mock.cimplify.io/img/freshmart/essentials.jpg"],
7673
+ image: "/img/freshmart/essentials.jpg",
7674
+ images: ["/img/freshmart/essentials.jpg"],
7660
7675
  is_available: true,
7661
7676
  category_ids: [catIds.get("pantry")],
7662
7677
  collection_ids: [],
@@ -7868,6 +7883,158 @@ function createMockApp(options = {}) {
7868
7883
  })
7869
7884
  );
7870
7885
  app.get("/healthz", (c) => c.json({ ok: true, time: deps.clock.iso() }));
7886
+ const UNSPLASH_PHOTOS = {
7887
+ // Akua's Bakery (default seed)
7888
+ sourdough: "1509440159596-0249088772ff",
7889
+ wheat: "1486887396153-fa416526c108",
7890
+ baguette: "1568471173242-461f0a730452",
7891
+ focaccia: "1573472635068-fd9b1abdd8e5",
7892
+ croissant: "1555507036-ab1f4038808a",
7893
+ pac: "1530610476181-d83430b64dcd",
7894
+ danish: "1517433367423-c7e5b0f35086",
7895
+ cinnamon: "1583527976767-50068e72b7a3",
7896
+ "choc-cake": "1565958011703-44f9829ba187",
7897
+ "red-velvet": "1586788680434-30d324b2d46f",
7898
+ carrot: "1568827999250-3f6afff96e66",
7899
+ cheesecake: "1567306226416-28f0efdc88ce",
7900
+ coffee: "1495474472287-4d71bcdd2085",
7901
+ tea: "1576092768241-dec231879fc3",
7902
+ sobolo: "1556679343-c7306c1976bc",
7903
+ oj: "1600271886742-f049b969dc7a",
7904
+ banana: "1632931057819-4eefffa8e007",
7905
+ brownie: "1551024506-0bccd828d307",
7906
+ macaron: "1558326567-98ae2405596b",
7907
+ birthday: "1535254973040-607b474cb50d",
7908
+ "breakfast-box": "1533089860892-a7c6f0a88666",
7909
+ "pastry-box": "1486427944299-d1955d23e34d",
7910
+ // Mama's Kitchen (restaurant seed)
7911
+ kelewele: "1585536830049-aedf5c1b98a4",
7912
+ "spring-rolls": "1606755962773-d324e0a13086",
7913
+ "soup-of-the-day": "1547592180-85f173990554",
7914
+ "jollof-rice": "1604329760661-e71dc83f8f26",
7915
+ "banku-tilapia": "1559847844-5315695dadae",
7916
+ "fufu-light-soup": "1547928576-b822bcced36e",
7917
+ waakye: "1604329760661-e71dc83f8f26",
7918
+ "grilled-chicken": "1532550907401-a500c9a57435",
7919
+ burger: "1568901346375-23c9450c58cd",
7920
+ "yam-fries": "1573080496219-bb080dd4f877",
7921
+ "fried-plantain": "1604329760661-e71dc83f8f26",
7922
+ salad: "1512621776951-a57141f2eefd",
7923
+ "ice-cream": "1497034825429-c343d7c6a68f",
7924
+ "cake-slice": "1565958011703-44f9829ba187",
7925
+ "fruit-bowl": "1490474418585-ba9bad8fd0ea",
7926
+ "soft-drink": "1497534446932-c925b458314e",
7927
+ "fresh-juice": "1622597467836-f3285f2131b8",
7928
+ water: "1548839140-29a749e1cf4d",
7929
+ feast: "1546069901-ba9599a7e63c",
7930
+ byo: "1546069901-ba9599a7e63c",
7931
+ // Currents Electronics
7932
+ "android-flagship": "1511707171634-5f897ff02aa9",
7933
+ "android-mid": "1592899677977-9c10ca588bbd",
7934
+ "phone-budget": "1574944985070-8f3ebc6b79d2",
7935
+ "laptop-pro": "1496181133206-80ce9b88a853",
7936
+ "laptop-air": "1517336714731-489689fd1ca8",
7937
+ "laptop-budget": "1541807084-5c52b6b3adef",
7938
+ "headphones-anc": "1583394838336-acd977736f90",
7939
+ "earbuds-pro": "1606220945770-b5b6c2c55bf1",
7940
+ "speaker-bt": "1608043152269-423dbba4e7e1",
7941
+ "phone-case": "1601593346740-925612772716",
7942
+ "screen-protector": "1592890288564-76628a30a657",
7943
+ "fast-charger": "1583394838336-acd977736f90",
7944
+ "laptop-sleeve": "1525547719571-a2d4ac8945e2",
7945
+ "wireless-mouse": "1527864550417-7fd91fc51a46",
7946
+ "mech-keyboard": "1587829741301-dc798b83add3",
7947
+ "gaming-controller": "1592840496694-26d035b52b48",
7948
+ "gaming-headset": "1591105327764-407a4a06e768",
7949
+ "console-handheld": "1606144042614-b2417e99c4e3",
7950
+ wfh: "1593642632559-0c6d3fc62b89",
7951
+ "game-pack": "1606144042614-b2417e99c4e3",
7952
+ // Reesa apparel
7953
+ "ankara-shirt": "1591047139829-d91aecb6caea",
7954
+ "agbada-set": "1605497788044-5a32c7078486",
7955
+ kaftan: "1554412933-514a83d2f3c8",
7956
+ "leather-tote": "1584917865442-de89df76afd3",
7957
+ sandals: "1543163521-1bf539c55dd2",
7958
+ "beaded-bracelet": "1611591437281-460bfbe1220a",
7959
+ owambe: "1605497788044-5a32c7078486",
7960
+ // FreshMart
7961
+ "tomatoes-1kg": "1546470427-227f1c75a9ef",
7962
+ "onions-1kg": "1620574387735-3624d75b2dbc",
7963
+ "ginger-200g": "1606937330526-f5e6a2a83555",
7964
+ "bananas-bunch": "1571771894821-ce9b6c11b08e",
7965
+ pineapple: "1550258987-190a2d41a8ba",
7966
+ "spinach-bunch": "1576045057995-568f588f82fb",
7967
+ "milk-1l": "1550583724-b2692b85b150",
7968
+ "yogurt-500g": "1571212515416-fef01fc43637",
7969
+ "eggs-12": "1582722872445-44dc5f7e3c8f",
7970
+ "cheese-200g": "1486297678162-eb2a19b0a32d",
7971
+ "chicken-1kg": "1604503468506-a8da13d82791",
7972
+ "beef-mince-500g": "1607623814075-e51df1bdc82f",
7973
+ "tilapia-each": "1546069901-ba9599a7e63c",
7974
+ "rice-5kg": "1586201375761-83865001e31c",
7975
+ "garri-2kg": "1604329760661-e71dc83f8f26",
7976
+ "palm-oil-1l": "1474979266404-7eaacbcd87c5",
7977
+ "vegetable-oil-1l": "1474979266404-7eaacbcd87c5",
7978
+ "salt-1kg": "1612531386530-97286d97c2d2",
7979
+ "sugar-1kg": "1581281697996-3aef0c3b9b12",
7980
+ "tomato-paste": "1546470427-227f1c75a9ef",
7981
+ "soap-bar": "1583912267550-d6c2ac3196c0",
7982
+ "detergent-1kg": "1583912267550-d6c2ac3196c0",
7983
+ "tissue-pack": "1610557892470-55d9e80c0bce",
7984
+ "trash-bags": "1583912267550-d6c2ac3196c0",
7985
+ essentials: "1542838132-92c53300491e",
7986
+ // Serene Spa services
7987
+ "swedish-massage-60": "1544161515-4ab6ce6db874",
7988
+ "swedish-massage-90": "1544161515-4ab6ce6db874",
7989
+ "deep-tissue-60": "1600334129128-685c5582fd35",
7990
+ "couples-massage": "1540555700478-4be289fbecef",
7991
+ "hot-stone-90": "1600334129128-685c5582fd35",
7992
+ "facial-classic": "1570172619644-dfd03ed5d881",
7993
+ "facial-anti-aging": "1571019613454-1cb2f99b2d8b",
7994
+ "facial-acne": "1571019613454-1cb2f99b2d8b",
7995
+ manicure: "1604654894610-df63bc536371",
7996
+ pedicure: "1610701596007-11502861dcfa",
7997
+ "gel-manicure": "1604654894610-df63bc536371",
7998
+ haircut: "1562322140-8baeececf3df",
7999
+ "hair-treatment": "1522337360788-8b13dee7a37e",
8000
+ color: "1562322140-8baeececf3df",
8001
+ "yoga-session": "1545205597-3d9d02c29597",
8002
+ meditation: "1545389336-cf090694435e",
8003
+ "spa-day": "1540555700478-4be289fbecef",
8004
+ "couples-retreat": "1540555700478-4be289fbecef",
8005
+ "custom-experience": "1545389336-cf090694435e"
8006
+ };
8007
+ app.get("/img/*", (c) => {
8008
+ const path = c.req.path.replace(/^\/img\//, "").replace(/\.[a-z0-9]+$/i, "");
8009
+ const slug = path.split("/").pop() ?? "";
8010
+ const photoId = UNSPLASH_PHOTOS[slug];
8011
+ if (photoId) {
8012
+ return c.redirect(`https://images.unsplash.com/photo-${photoId}?w=600&h=600&fit=crop&auto=format&q=80`, 302);
8013
+ }
8014
+ const label = slug.replace(/[-_]+/g, " ").trim() || "product";
8015
+ let hash = 0;
8016
+ for (let i = 0; i < slug.length; i++) hash = hash * 31 + slug.charCodeAt(i) >>> 0;
8017
+ const hue = hash % 360;
8018
+ const display = label.length > 20 ? label.slice(0, 20) + "\u2026" : label;
8019
+ const svg = `<?xml version="1.0" encoding="UTF-8"?>
8020
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400" width="400" height="400">
8021
+ <defs>
8022
+ <linearGradient id="g" x1="0" y1="0" x2="1" y2="1">
8023
+ <stop offset="0%" stop-color="hsl(${hue}, 65%, 65%)"/>
8024
+ <stop offset="100%" stop-color="hsl(${(hue + 40) % 360}, 70%, 45%)"/>
8025
+ </linearGradient>
8026
+ </defs>
8027
+ <rect width="400" height="400" fill="url(#g)"/>
8028
+ <text x="200" y="210" font-family="-apple-system, BlinkMacSystemFont, Inter, sans-serif" font-size="22" font-weight="600" fill="white" text-anchor="middle" dominant-baseline="middle" style="text-transform: capitalize">${display.replace(/[<>&]/g, "")}</text>
8029
+ </svg>`;
8030
+ return new Response(svg, {
8031
+ headers: {
8032
+ "Content-Type": "image/svg+xml; charset=utf-8",
8033
+ "Cache-Control": "public, max-age=3600",
8034
+ "Access-Control-Allow-Origin": "*"
8035
+ }
8036
+ });
8037
+ });
7871
8038
  app.route("/api/v1", buildV1(deps));
7872
8039
  app.route("/_mock", buildAdmin(deps));
7873
8040
  app.route("/elements", buildElements(deps));