@cimplify/sdk 0.38.3 → 0.38.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/mock/msw.mjs CHANGED
@@ -3535,7 +3535,9 @@ function toCanonicalProductSummary(p) {
3535
3535
  };
3536
3536
  }
3537
3537
  function deriveRenderHint(p) {
3538
+ if (p.render_hint) return p.render_hint;
3538
3539
  if (p.product_type === "service") return "general";
3540
+ if (p.product_type === "digital") return "general";
3539
3541
  const foodish = (p.tags ?? []).some(
3540
3542
  (t) => /food|drink|cake|bread|pastry|dessert|coffee|tea|juice|spice/i.test(t)
3541
3543
  );
@@ -3563,6 +3565,12 @@ function toApiProduct(p, ctx) {
3563
3565
  tags: p.tags ?? [],
3564
3566
  calories: p.calories,
3565
3567
  allergies: p.allergies ?? [],
3568
+ display_mode: p.display_mode,
3569
+ digital_product_type: p.digital_product_type,
3570
+ quantity_pricing: p.quantity_pricing,
3571
+ duration_unit: p.duration_unit,
3572
+ duration_minutes: p.duration_minutes,
3573
+ billing_plans: p.billing_plans,
3566
3574
  created_at: p.created_at,
3567
3575
  updated_at: p.updated_at,
3568
3576
  metadata: {
@@ -5053,6 +5061,21 @@ function makeProduct(input, categoryIds) {
5053
5061
  pairings: input.pairings ?? [],
5054
5062
  is_signature: input.isSignature ?? false,
5055
5063
  is_new: input.isNew ?? false,
5064
+ render_hint: input.renderHint,
5065
+ display_mode: input.displayMode,
5066
+ digital_product_type: input.digitalProductType,
5067
+ quantity_pricing: input.quantityPricing,
5068
+ duration_unit: input.durationUnit,
5069
+ duration_minutes: input.durationMinutes,
5070
+ billing_plans: input.billingPlans?.map((b) => ({
5071
+ id: b.id,
5072
+ name: b.name,
5073
+ interval: b.interval,
5074
+ interval_count: b.interval_count,
5075
+ price: b.price,
5076
+ currency: b.currency ?? "GHS",
5077
+ trial_period_days: b.trial_period_days
5078
+ })),
5056
5079
  created_at: ISO,
5057
5080
  updated_at: ISO
5058
5081
  };
@@ -5093,7 +5116,9 @@ function seedDefault(registry) {
5093
5116
  { slug: "pastries", name: "Pastries", description: "Hand-laminated croissants, danishes, brownies." },
5094
5117
  { slug: "cakes", name: "Cakes", description: "Slices and made-to-order showstoppers." },
5095
5118
  { slug: "drinks", name: "Drinks", description: "Locally roasted coffee, brewed teas, fresh juice." },
5096
- { slug: "boxes", name: "Boxes & Bundles", description: "Curated boxes for sharing." }
5119
+ { slug: "boxes", name: "Boxes & Bundles", description: "Curated boxes for sharing." },
5120
+ { slug: "merch", name: "Merch & More", description: "Branded goods, wholesale flour, downloadable recipes, gift cards." },
5121
+ { slug: "classes", name: "Classes & Stays", description: "Hands-on baking classes, kitchen rentals, monthly bread subscriptions." }
5097
5122
  ];
5098
5123
  const catIds = /* @__PURE__ */ new Map();
5099
5124
  for (const c of categoryDefs) {
@@ -5407,6 +5432,154 @@ function seedDefault(registry) {
5407
5432
  imageUrl: img("1486427944299-d1955d23e34d"),
5408
5433
  tags: ["composite", "build-your-own", "gift"],
5409
5434
  productType: "composite"
5435
+ },
5436
+ // ── Merch (Retail card — render_hint=physical) ──
5437
+ {
5438
+ id: "prod_apron",
5439
+ name: "Akua's Bakery Apron",
5440
+ slug: "apron",
5441
+ price: "85.00",
5442
+ description: "Heavy-weight cotton-canvas apron with leather neck strap, embroidered logo, and two front pockets. Made in Accra.",
5443
+ category: "merch",
5444
+ imageUrl: img("1556905055-8f358a7a47b2"),
5445
+ tags: ["merch", "physical"],
5446
+ renderHint: "physical"
5447
+ },
5448
+ {
5449
+ id: "prod_tote",
5450
+ name: "Bakery Tote Bag",
5451
+ slug: "tote-bag",
5452
+ price: "35.00",
5453
+ description: "12oz natural canvas tote, screen-printed with our wheat-stalk crest. Roomy enough for two loaves.",
5454
+ category: "merch",
5455
+ imageUrl: img("1591561954557-26941169b49e"),
5456
+ tags: ["merch", "physical", "gift"],
5457
+ renderHint: "physical",
5458
+ isNew: true
5459
+ },
5460
+ // ── Wholesale (Wholesale card — quantity_pricing tiers) ──
5461
+ {
5462
+ id: "prod_flour-wholesale",
5463
+ name: "Heritage Flour \u2014 25kg Sack",
5464
+ slug: "flour-25kg",
5465
+ price: "320.00",
5466
+ description: "Stone-milled heritage wheat flour, the same we use in our country sourdough. Tiered pricing for caf\xE9s, restaurants, and home-baking co-ops.",
5467
+ category: "merch",
5468
+ imageUrl: img("1568254183919-78a4f43a2877"),
5469
+ tags: ["wholesale", "physical", "trade"],
5470
+ renderHint: "physical",
5471
+ quantityPricing: [
5472
+ { min_quantity: 1, unit_price: "320.00" },
5473
+ { min_quantity: 5, unit_price: "295.00" },
5474
+ { min_quantity: 10, unit_price: "270.00" },
5475
+ { min_quantity: 25, unit_price: "245.00" }
5476
+ ]
5477
+ },
5478
+ // ── Digital products (Digital card — type=digital) ──
5479
+ {
5480
+ id: "prod_recipe-ebook",
5481
+ name: "Sourdough Starter eBook",
5482
+ slug: "sourdough-ebook",
5483
+ price: "45.00",
5484
+ description: "PDF + EPUB walkthrough of our sourdough programme \u2014 starter, levain, autolyse, bulk fermentation, shaping, scoring. Lifetime updates.",
5485
+ category: "merch",
5486
+ imageUrl: img("1543002588-bfa74002ed7e"),
5487
+ tags: ["digital", "download"],
5488
+ productType: "digital",
5489
+ digitalProductType: "download"
5490
+ },
5491
+ {
5492
+ id: "prod_gift-card",
5493
+ name: "Bakery Gift Card",
5494
+ slug: "gift-card",
5495
+ price: "100.00",
5496
+ description: "Send instantly. Redeemable in-store and online toward any product. Choose any amount from GH\u20B550 upward.",
5497
+ category: "merch",
5498
+ imageUrl: img("1556905055-8f358a7a47b2"),
5499
+ tags: ["digital", "gift"],
5500
+ productType: "digital",
5501
+ digitalProductType: "gift_code",
5502
+ isSignature: true
5503
+ },
5504
+ // ── Services (Standard service card — type=service + duration_minutes) ──
5505
+ {
5506
+ id: "prod_baking-class",
5507
+ name: "Sourdough Baking Class",
5508
+ slug: "baking-class",
5509
+ price: "320.00",
5510
+ description: "Two-hour hands-on class: shape your own boule, score it, and take home a baked loaf and a starter jar. Held Saturdays, 10am\u201312pm.",
5511
+ category: "classes",
5512
+ imageUrl: img("1556909114-44e3e9399a2e"),
5513
+ tags: ["class", "service", "hands-on"],
5514
+ productType: "service",
5515
+ durationMinutes: 120
5516
+ },
5517
+ {
5518
+ id: "prod_pastry-workshop",
5519
+ name: "Lamination Workshop",
5520
+ slug: "pastry-workshop",
5521
+ price: "480.00",
5522
+ description: "Three-hour deep-dive on laminated dough. We cover croissants, danishes, kouign-amann. Aprons supplied; pastries to take home.",
5523
+ category: "classes",
5524
+ imageUrl: img("1517433367423-c7e5b0f35086"),
5525
+ tags: ["class", "service", "advanced"],
5526
+ productType: "service",
5527
+ durationMinutes: 180,
5528
+ isNew: true
5529
+ },
5530
+ // ── Rental service (Rental card — duration_unit=hours) ──
5531
+ {
5532
+ id: "prod_kitchen-rental",
5533
+ name: "Pro Kitchen Rental",
5534
+ slug: "kitchen-rental",
5535
+ price: "180.00",
5536
+ description: "Rent our commercial bakery after hours. Deck oven, retarder-proofer, mixers, scales \u2014 bring your team or shoot your content. Hourly.",
5537
+ category: "classes",
5538
+ imageUrl: img("1556909114-44e3e9399a2e"),
5539
+ tags: ["rental", "service", "commercial"],
5540
+ productType: "service",
5541
+ durationUnit: "hours"
5542
+ },
5543
+ // ── Accommodation (Accommodation card — duration_unit=nights) ──
5544
+ {
5545
+ id: "prod_loft-stay",
5546
+ name: "Bakery Loft \u2014 Weekend Stay",
5547
+ slug: "loft-stay",
5548
+ price: "650.00",
5549
+ description: "One-bedroom loft above the bakery. Wakes up to fresh croissants, ends with a private dinner. Ghana Tourism-licensed. Per night.",
5550
+ category: "classes",
5551
+ imageUrl: img("1564013799919-ab600027ffc6"),
5552
+ tags: ["stay", "service", "premium"],
5553
+ productType: "service",
5554
+ durationUnit: "nights"
5555
+ },
5556
+ // ── Subscription (Subscription card — billing_plans, no duration_minutes) ──
5557
+ {
5558
+ id: "prod_loaf-subscription",
5559
+ name: "Weekly Loaf Subscription",
5560
+ slug: "loaf-subscription",
5561
+ price: "0.00",
5562
+ description: "A fresh loaf delivered to your door every week. Pause or skip any time. Choose monthly or quarterly billing for a discount.",
5563
+ category: "classes",
5564
+ imageUrl: img("1509440159596-0249088772ff"),
5565
+ tags: ["subscription", "service", "delivery"],
5566
+ productType: "service",
5567
+ billingPlans: [
5568
+ {
5569
+ id: "plan_loaf_monthly",
5570
+ name: "Monthly",
5571
+ interval: "month",
5572
+ interval_count: 1,
5573
+ price: "90.00"
5574
+ },
5575
+ {
5576
+ id: "plan_loaf_quarterly",
5577
+ name: "Quarterly (save 10%)",
5578
+ interval: "month",
5579
+ interval_count: 3,
5580
+ price: "243.00"
5581
+ }
5582
+ ]
5410
5583
  }
5411
5584
  ];
5412
5585
  for (const input of productInputs) {
package/dist/react.js CHANGED
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var chunkZYACIPKO_js = require('./chunk-ZYACIPKO.js');
5
- var chunkHKVRUGM6_js = require('./chunk-HKVRUGM6.js');
4
+ var chunk5VHKZTFJ_js = require('./chunk-5VHKZTFJ.js');
5
+ var chunkBAWKQRIB_js = require('./chunk-BAWKQRIB.js');
6
6
  var chunkV2O5AO7I_js = require('./chunk-V2O5AO7I.js');
7
7
  var React10 = require('react');
8
8
  var jsxRuntime = require('react/jsx-runtime');
@@ -1151,7 +1151,7 @@ var DEFAULT_COUNTRY = "US";
1151
1151
  function createDefaultClient() {
1152
1152
  const processRef = globalThis.process;
1153
1153
  const envPublicKey = processRef?.env?.NEXT_PUBLIC_CIMPLIFY_PUBLIC_KEY || "";
1154
- return chunkZYACIPKO_js.createCimplifyClient({ publicKey: envPublicKey });
1154
+ return chunk5VHKZTFJ_js.createCimplifyClient({ publicKey: envPublicKey });
1155
1155
  }
1156
1156
  function getStoredLocationId() {
1157
1157
  if (typeof window === "undefined" || !window.localStorage) {
@@ -3657,19 +3657,19 @@ function AuthElement({
3657
3657
  }, [onReady, onAuthenticated, onRequiresOtp, onError]);
3658
3658
  React10.useEffect(() => {
3659
3659
  if (!elements || !containerRef.current) return;
3660
- const element = elements.create(chunkHKVRUGM6_js.ELEMENT_TYPES.AUTH, { prefillEmail });
3660
+ const element = elements.create(chunkBAWKQRIB_js.ELEMENT_TYPES.AUTH, { prefillEmail });
3661
3661
  elementRef.current = element;
3662
- element.on(chunkHKVRUGM6_js.EVENT_TYPES.READY, () => onReadyRef.current?.());
3662
+ element.on(chunkBAWKQRIB_js.EVENT_TYPES.READY, () => onReadyRef.current?.());
3663
3663
  element.on(
3664
- chunkHKVRUGM6_js.EVENT_TYPES.AUTHENTICATED,
3664
+ chunkBAWKQRIB_js.EVENT_TYPES.AUTHENTICATED,
3665
3665
  (data) => onAuthenticatedRef.current?.(data)
3666
3666
  );
3667
3667
  element.on(
3668
- chunkHKVRUGM6_js.EVENT_TYPES.REQUIRES_OTP,
3668
+ chunkBAWKQRIB_js.EVENT_TYPES.REQUIRES_OTP,
3669
3669
  (data) => onRequiresOtpRef.current?.(data)
3670
3670
  );
3671
3671
  element.on(
3672
- chunkHKVRUGM6_js.EVENT_TYPES.ERROR,
3672
+ chunkBAWKQRIB_js.EVENT_TYPES.ERROR,
3673
3673
  (data) => onErrorRef.current?.(data)
3674
3674
  );
3675
3675
  element.mount(containerRef.current);
@@ -3698,15 +3698,15 @@ function AddressElement({
3698
3698
  }, [onReady, onChange, onError]);
3699
3699
  React10.useEffect(() => {
3700
3700
  if (!elements || !containerRef.current) return;
3701
- const element = elements.create(chunkHKVRUGM6_js.ELEMENT_TYPES.ADDRESS, { mode });
3701
+ const element = elements.create(chunkBAWKQRIB_js.ELEMENT_TYPES.ADDRESS, { mode });
3702
3702
  elementRef.current = element;
3703
- element.on(chunkHKVRUGM6_js.EVENT_TYPES.READY, () => onReadyRef.current?.());
3703
+ element.on(chunkBAWKQRIB_js.EVENT_TYPES.READY, () => onReadyRef.current?.());
3704
3704
  element.on(
3705
- chunkHKVRUGM6_js.EVENT_TYPES.CHANGE,
3705
+ chunkBAWKQRIB_js.EVENT_TYPES.CHANGE,
3706
3706
  (data) => onChangeRef.current?.(data)
3707
3707
  );
3708
3708
  element.on(
3709
- chunkHKVRUGM6_js.EVENT_TYPES.ERROR,
3709
+ chunkBAWKQRIB_js.EVENT_TYPES.ERROR,
3710
3710
  (data) => onErrorRef.current?.(data)
3711
3711
  );
3712
3712
  element.mount(containerRef.current);
@@ -3736,15 +3736,15 @@ function PaymentElement({
3736
3736
  }, [onReady, onChange, onError]);
3737
3737
  React10.useEffect(() => {
3738
3738
  if (!elements || !containerRef.current) return;
3739
- const element = elements.create(chunkHKVRUGM6_js.ELEMENT_TYPES.PAYMENT, { amount, currency });
3739
+ const element = elements.create(chunkBAWKQRIB_js.ELEMENT_TYPES.PAYMENT, { amount, currency });
3740
3740
  elementRef.current = element;
3741
- element.on(chunkHKVRUGM6_js.EVENT_TYPES.READY, () => onReadyRef.current?.());
3741
+ element.on(chunkBAWKQRIB_js.EVENT_TYPES.READY, () => onReadyRef.current?.());
3742
3742
  element.on(
3743
- chunkHKVRUGM6_js.EVENT_TYPES.CHANGE,
3743
+ chunkBAWKQRIB_js.EVENT_TYPES.CHANGE,
3744
3744
  (data) => onChangeRef.current?.(data)
3745
3745
  );
3746
3746
  element.on(
3747
- chunkHKVRUGM6_js.EVENT_TYPES.ERROR,
3747
+ chunkBAWKQRIB_js.EVENT_TYPES.ERROR,
3748
3748
  (data) => onErrorRef.current?.(data)
3749
3749
  );
3750
3750
  element.mount(containerRef.current);
@@ -4004,7 +4004,7 @@ function VariantSelector({
4004
4004
  {
4005
4005
  "data-cimplify-variant-name": true,
4006
4006
  className: cn("flex-1 min-w-0 text-sm", classNames?.name),
4007
- children: chunkZYACIPKO_js.getVariantDisplayName(variant, productName)
4007
+ children: chunk5VHKZTFJ_js.getVariantDisplayName(variant, productName)
4008
4008
  }
4009
4009
  ),
4010
4010
  /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-variant-pricing": true, className: cn("text-sm text-muted-foreground", classNames?.pricing), children: [
@@ -5221,12 +5221,12 @@ function FieldInput({
5221
5221
  classNames?.input
5222
5222
  );
5223
5223
  switch (field.field_type) {
5224
- case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Text:
5225
- case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Url:
5224
+ case chunk5VHKZTFJ_js.INPUT_FIELD_TYPE.Text:
5225
+ case chunk5VHKZTFJ_js.INPUT_FIELD_TYPE.Url:
5226
5226
  return /* @__PURE__ */ jsxRuntime.jsx(
5227
5227
  "input",
5228
5228
  {
5229
- type: field.field_type === chunkZYACIPKO_js.INPUT_FIELD_TYPE.Url ? "url" : "text",
5229
+ type: field.field_type === chunk5VHKZTFJ_js.INPUT_FIELD_TYPE.Url ? "url" : "text",
5230
5230
  value: typeof value === "string" ? value : "",
5231
5231
  onChange: (e) => onValueChange(e.target.value),
5232
5232
  placeholder: field.placeholder,
@@ -5235,7 +5235,7 @@ function FieldInput({
5235
5235
  className: inputClass
5236
5236
  }
5237
5237
  );
5238
- case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Textarea:
5238
+ case chunk5VHKZTFJ_js.INPUT_FIELD_TYPE.Textarea:
5239
5239
  return /* @__PURE__ */ jsxRuntime.jsx(
5240
5240
  "textarea",
5241
5241
  {
@@ -5248,7 +5248,7 @@ function FieldInput({
5248
5248
  className: cn(inputClass, "resize-none", classNames?.textarea)
5249
5249
  }
5250
5250
  );
5251
- case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Number:
5251
+ case chunk5VHKZTFJ_js.INPUT_FIELD_TYPE.Number:
5252
5252
  return /* @__PURE__ */ jsxRuntime.jsx(
5253
5253
  "input",
5254
5254
  {
@@ -5262,7 +5262,7 @@ function FieldInput({
5262
5262
  className: inputClass
5263
5263
  }
5264
5264
  );
5265
- case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Select:
5265
+ case chunk5VHKZTFJ_js.INPUT_FIELD_TYPE.Select:
5266
5266
  return /* @__PURE__ */ jsxRuntime.jsxs(
5267
5267
  "select",
5268
5268
  {
@@ -5276,7 +5276,7 @@ function FieldInput({
5276
5276
  ]
5277
5277
  }
5278
5278
  );
5279
- case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Radio:
5279
+ case chunk5VHKZTFJ_js.INPUT_FIELD_TYPE.Radio:
5280
5280
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("space-y-2", classNames?.radioGroup), children: (field.options || []).map((opt) => /* @__PURE__ */ jsxRuntime.jsxs(
5281
5281
  "label",
5282
5282
  {
@@ -5301,7 +5301,7 @@ function FieldInput({
5301
5301
  },
5302
5302
  opt
5303
5303
  )) });
5304
- case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Checkbox:
5304
+ case chunk5VHKZTFJ_js.INPUT_FIELD_TYPE.Checkbox:
5305
5305
  return /* @__PURE__ */ jsxRuntime.jsxs("label", { className: cn("flex items-center gap-2 text-sm cursor-pointer", classNames?.checkboxLabel), children: [
5306
5306
  /* @__PURE__ */ jsxRuntime.jsx(
5307
5307
  "input",
@@ -5314,7 +5314,7 @@ function FieldInput({
5314
5314
  ),
5315
5315
  field.placeholder || field.name
5316
5316
  ] });
5317
- case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Color:
5317
+ case chunk5VHKZTFJ_js.INPUT_FIELD_TYPE.Color:
5318
5318
  return /* @__PURE__ */ jsxRuntime.jsx(
5319
5319
  "input",
5320
5320
  {
@@ -5324,7 +5324,7 @@ function FieldInput({
5324
5324
  className: cn("w-12 h-10 rounded-md border border-input cursor-pointer", classNames?.colorInput)
5325
5325
  }
5326
5326
  );
5327
- case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Date:
5327
+ case chunk5VHKZTFJ_js.INPUT_FIELD_TYPE.Date:
5328
5328
  return /* @__PURE__ */ jsxRuntime.jsx(
5329
5329
  "input",
5330
5330
  {
@@ -5335,8 +5335,8 @@ function FieldInput({
5335
5335
  className: inputClass
5336
5336
  }
5337
5337
  );
5338
- case chunkZYACIPKO_js.INPUT_FIELD_TYPE.File:
5339
- case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Image:
5338
+ case chunk5VHKZTFJ_js.INPUT_FIELD_TYPE.File:
5339
+ case chunk5VHKZTFJ_js.INPUT_FIELD_TYPE.Image:
5340
5340
  return /* @__PURE__ */ jsxRuntime.jsx(
5341
5341
  FileUploadInput,
5342
5342
  {
@@ -5347,7 +5347,7 @@ function FieldInput({
5347
5347
  classNames
5348
5348
  }
5349
5349
  );
5350
- case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Email:
5350
+ case chunk5VHKZTFJ_js.INPUT_FIELD_TYPE.Email:
5351
5351
  return /* @__PURE__ */ jsxRuntime.jsx(
5352
5352
  "input",
5353
5353
  {
@@ -5359,7 +5359,7 @@ function FieldInput({
5359
5359
  className: inputClass
5360
5360
  }
5361
5361
  );
5362
- case chunkZYACIPKO_js.INPUT_FIELD_TYPE.DateTime: {
5362
+ case chunk5VHKZTFJ_js.INPUT_FIELD_TYPE.DateTime: {
5363
5363
  const dtLocalValue = typeof value === "string" && value.includes("T") ? value.slice(0, 16) : typeof value === "string" ? value : "";
5364
5364
  return /* @__PURE__ */ jsxRuntime.jsx(
5365
5365
  "input",
@@ -5379,7 +5379,7 @@ function FieldInput({
5379
5379
  }
5380
5380
  );
5381
5381
  }
5382
- case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Time:
5382
+ case chunk5VHKZTFJ_js.INPUT_FIELD_TYPE.Time:
5383
5383
  return /* @__PURE__ */ jsxRuntime.jsx(
5384
5384
  "input",
5385
5385
  {
@@ -5390,7 +5390,7 @@ function FieldInput({
5390
5390
  className: inputClass
5391
5391
  }
5392
5392
  );
5393
- case chunkZYACIPKO_js.INPUT_FIELD_TYPE.MultiSelect:
5393
+ case chunk5VHKZTFJ_js.INPUT_FIELD_TYPE.MultiSelect:
5394
5394
  return /* @__PURE__ */ jsxRuntime.jsx(
5395
5395
  MultiSelectInput,
5396
5396
  {
@@ -5400,7 +5400,7 @@ function FieldInput({
5400
5400
  classNames
5401
5401
  }
5402
5402
  );
5403
- case chunkZYACIPKO_js.INPUT_FIELD_TYPE.DateRange:
5403
+ case chunk5VHKZTFJ_js.INPUT_FIELD_TYPE.DateRange:
5404
5404
  return /* @__PURE__ */ jsxRuntime.jsx(
5405
5405
  DateRangeInput,
5406
5406
  {
@@ -5411,7 +5411,7 @@ function FieldInput({
5411
5411
  inputClass
5412
5412
  }
5413
5413
  );
5414
- case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Address:
5414
+ case chunk5VHKZTFJ_js.INPUT_FIELD_TYPE.Address:
5415
5415
  return /* @__PURE__ */ jsxRuntime.jsx(
5416
5416
  AddressInput,
5417
5417
  {
@@ -5422,7 +5422,7 @@ function FieldInput({
5422
5422
  inputClass
5423
5423
  }
5424
5424
  );
5425
- case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Location:
5425
+ case chunk5VHKZTFJ_js.INPUT_FIELD_TYPE.Location:
5426
5426
  return /* @__PURE__ */ jsxRuntime.jsx(
5427
5427
  LocationInput,
5428
5428
  {
@@ -5433,7 +5433,7 @@ function FieldInput({
5433
5433
  inputClass
5434
5434
  }
5435
5435
  );
5436
- case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Phone:
5436
+ case chunk5VHKZTFJ_js.INPUT_FIELD_TYPE.Phone:
5437
5437
  return /* @__PURE__ */ jsxRuntime.jsx(
5438
5438
  PhoneInput,
5439
5439
  {
@@ -5444,7 +5444,7 @@ function FieldInput({
5444
5444
  inputClass
5445
5445
  }
5446
5446
  );
5447
- case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Signature:
5447
+ case chunk5VHKZTFJ_js.INPUT_FIELD_TYPE.Signature:
5448
5448
  return /* @__PURE__ */ jsxRuntime.jsx(
5449
5449
  SignatureInput,
5450
5450
  {
@@ -5477,7 +5477,7 @@ function FileUploadInput({
5477
5477
  const [isUploading, setIsUploading] = React10__default.default.useState(false);
5478
5478
  const fileUrl = typeof value === "string" ? value : void 0;
5479
5479
  const acceptedFormats = field.validation?.accepted_formats;
5480
- const accept = acceptedFormats ? acceptedFormats.map((f) => `.${f}`).join(",") : field.field_type === chunkZYACIPKO_js.INPUT_FIELD_TYPE.Image ? "image/*" : void 0;
5480
+ const accept = acceptedFormats ? acceptedFormats.map((f) => `.${f}`).join(",") : field.field_type === chunk5VHKZTFJ_js.INPUT_FIELD_TYPE.Image ? "image/*" : void 0;
5481
5481
  const handleFile = async (file) => {
5482
5482
  if (!onFileUpload) return;
5483
5483
  if (field.validation?.max_size_mb) {
@@ -5495,7 +5495,7 @@ function FileUploadInput({
5495
5495
  }
5496
5496
  };
5497
5497
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("space-y-2", classNames?.fileInput), children: fileUrl ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
5498
- field.field_type === chunkZYACIPKO_js.INPUT_FIELD_TYPE.Image && /* @__PURE__ */ jsxRuntime.jsx("img", { src: fileUrl, alt: "Uploaded", className: "w-16 h-16 object-cover rounded-md border border-border" }),
5498
+ field.field_type === chunk5VHKZTFJ_js.INPUT_FIELD_TYPE.Image && /* @__PURE__ */ jsxRuntime.jsx("img", { src: fileUrl, alt: "Uploaded", className: "w-16 h-16 object-cover rounded-md border border-border" }),
5499
5499
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-foreground truncate", children: fileUrl.split("/").pop() }) }),
5500
5500
  /* @__PURE__ */ jsxRuntime.jsx(
5501
5501
  "button",
@@ -5521,7 +5521,7 @@ function FileUploadInput({
5521
5521
  }
5522
5522
  ),
5523
5523
  isUploading ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Uploading..." }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5524
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: field.placeholder || `Upload ${field.field_type === chunkZYACIPKO_js.INPUT_FIELD_TYPE.Image ? "image" : "file"}` }),
5524
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: field.placeholder || `Upload ${field.field_type === chunk5VHKZTFJ_js.INPUT_FIELD_TYPE.Image ? "image" : "file"}` }),
5525
5525
  acceptedFormats && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground/60 mt-1", children: [
5526
5526
  acceptedFormats.map((f) => f.toUpperCase()).join(", "),
5527
5527
  field.validation?.max_size_mb && ` \xB7 Max ${field.validation.max_size_mb}MB`
@@ -6456,7 +6456,7 @@ function CartLineItemRow({
6456
6456
  children: [
6457
6457
  /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-item-info": true, children: [
6458
6458
  /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-item-name": true, className: classNames?.itemName, children: item.product.name }),
6459
- item.variant && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-item-variant": true, children: chunkZYACIPKO_js.getVariantDisplayName(item.variant, item.product.name) }),
6459
+ item.variant && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-item-variant": true, children: chunk5VHKZTFJ_js.getVariantDisplayName(item.variant, item.product.name) }),
6460
6460
  item.addOnOptions && item.addOnOptions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-cart-item-addons": true, children: [
6461
6461
  "+ ",
6462
6462
  item.addOnOptions.map((opt) => opt.name).join(", ")
@@ -6465,7 +6465,7 @@ function CartLineItemRow({
6465
6465
  item.specialInstructions && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-item-instructions": true, className: "text-xs text-muted-foreground", children: item.specialInstructions }),
6466
6466
  item.customerInputs && item.customerInputs.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-cart-customer-inputs": true, className: classNames?.customerInputs, children: item.customerInputs.map((input) => /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-input": true, children: [
6467
6467
  /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-input-label": true, children: input.field_name }),
6468
- /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-input-value": true, children: input.field_type === chunkZYACIPKO_js.INPUT_FIELD_TYPE.File || input.field_type === chunkZYACIPKO_js.INPUT_FIELD_TYPE.Image ? String(input.value).split("/").pop() || "Uploaded file" : String(input.value) })
6468
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-input-value": true, children: input.field_type === chunk5VHKZTFJ_js.INPUT_FIELD_TYPE.File || input.field_type === chunk5VHKZTFJ_js.INPUT_FIELD_TYPE.Image ? String(input.value).split("/").pop() || "Uploaded file" : String(input.value) })
6469
6469
  ] }, input.field_id)) }),
6470
6470
  (item.lineType === "service" || item.product.type === "service") && item.scheduledStart && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-service-info": true, className: classNames?.serviceInfo, children: [
6471
6471
  /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
@@ -7017,7 +7017,7 @@ function FoodProductCard({
7017
7017
  const tags = product.tags || [];
7018
7018
  const isSignature = product.metadata?.is_signature === true;
7019
7019
  const isNew = product.metadata?.is_new === true;
7020
- const isComposite = product.type === chunkZYACIPKO_js.PRODUCT_TYPE.Composite;
7020
+ const isComposite = product.type === chunk5VHKZTFJ_js.PRODUCT_TYPE.Composite;
7021
7021
  return /* @__PURE__ */ jsxRuntime.jsxs(CardShell, { product, renderLink, className, children: [
7022
7022
  /* @__PURE__ */ jsxRuntime.jsxs(CardImage, { src: image, alt: product.name, aspectRatio: "square", renderImage, children: [
7023
7023
  isSignature && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "absolute top-3 left-3 inline-flex items-center gap-1 text-[11px] font-semibold tracking-wide bg-amber-50 text-amber-700 border border-amber-200/60 px-2 py-0.5 rounded-md", children: [
@@ -7770,26 +7770,26 @@ var BUILT_IN_CARDS = {
7770
7770
  ["composite" /* Composite */]: CompositeProductCard,
7771
7771
  ["subscription" /* Subscription */]: SubscriptionCard
7772
7772
  };
7773
- var RENTAL_UNITS = /* @__PURE__ */ new Set([chunkZYACIPKO_js.DURATION_UNIT.Days, chunkZYACIPKO_js.DURATION_UNIT.Hours]);
7774
- var LEASE_UNITS = /* @__PURE__ */ new Set([chunkZYACIPKO_js.DURATION_UNIT.Weeks, chunkZYACIPKO_js.DURATION_UNIT.Months, chunkZYACIPKO_js.DURATION_UNIT.Years]);
7773
+ var RENTAL_UNITS = /* @__PURE__ */ new Set([chunk5VHKZTFJ_js.DURATION_UNIT.Days, chunk5VHKZTFJ_js.DURATION_UNIT.Hours]);
7774
+ var LEASE_UNITS = /* @__PURE__ */ new Set([chunk5VHKZTFJ_js.DURATION_UNIT.Weeks, chunk5VHKZTFJ_js.DURATION_UNIT.Months, chunk5VHKZTFJ_js.DURATION_UNIT.Years]);
7775
7775
  function resolveCardVariant(product) {
7776
- if (product.type === chunkZYACIPKO_js.PRODUCT_TYPE.Bundle) {
7776
+ if (product.type === chunk5VHKZTFJ_js.PRODUCT_TYPE.Bundle) {
7777
7777
  return "bundle" /* Bundle */;
7778
7778
  }
7779
- if (product.type === chunkZYACIPKO_js.PRODUCT_TYPE.Composite) {
7779
+ if (product.type === chunk5VHKZTFJ_js.PRODUCT_TYPE.Composite) {
7780
7780
  return "composite" /* Composite */;
7781
7781
  }
7782
7782
  if (product.quantity_pricing && product.quantity_pricing.length > 1) {
7783
7783
  return "wholesale" /* Wholesale */;
7784
7784
  }
7785
- if (product.type === chunkZYACIPKO_js.PRODUCT_TYPE.Digital) {
7785
+ if (product.type === chunk5VHKZTFJ_js.PRODUCT_TYPE.Digital) {
7786
7786
  return "digital" /* Digital */;
7787
7787
  }
7788
- if (product.type === chunkZYACIPKO_js.PRODUCT_TYPE.Service) {
7788
+ if (product.type === chunk5VHKZTFJ_js.PRODUCT_TYPE.Service) {
7789
7789
  if (product.duration_unit && RENTAL_UNITS.has(product.duration_unit)) {
7790
7790
  return "rental" /* Rental */;
7791
7791
  }
7792
- if (product.duration_unit === chunkZYACIPKO_js.DURATION_UNIT.Nights) {
7792
+ if (product.duration_unit === chunk5VHKZTFJ_js.DURATION_UNIT.Nights) {
7793
7793
  return "accommodation" /* Accommodation */;
7794
7794
  }
7795
7795
  if (product.duration_unit && LEASE_UNITS.has(product.duration_unit)) {
@@ -7800,10 +7800,10 @@ function resolveCardVariant(product) {
7800
7800
  }
7801
7801
  return "standard" /* Standard */;
7802
7802
  }
7803
- if (product.render_hint === chunkZYACIPKO_js.RENDER_HINT.Food) {
7803
+ if (product.render_hint === chunk5VHKZTFJ_js.RENDER_HINT.Food) {
7804
7804
  return "food" /* Food */;
7805
7805
  }
7806
- if (product.render_hint === chunkZYACIPKO_js.RENDER_HINT.Physical) {
7806
+ if (product.render_hint === chunk5VHKZTFJ_js.RENDER_HINT.Physical) {
7807
7807
  return "retail" /* Retail */;
7808
7808
  }
7809
7809
  return "retail" /* Retail */;
@@ -10564,25 +10564,25 @@ function resolveTemplateKey(product) {
10564
10564
  if (typeof metaTemplate === "string" && metaTemplate.trim()) {
10565
10565
  return metaTemplate.trim();
10566
10566
  }
10567
- if (product.type === chunkZYACIPKO_js.PRODUCT_TYPE.Bundle) {
10567
+ if (product.type === chunk5VHKZTFJ_js.PRODUCT_TYPE.Bundle) {
10568
10568
  return "bundle" /* Bundle */;
10569
10569
  }
10570
- if (product.type === chunkZYACIPKO_js.PRODUCT_TYPE.Composite) {
10570
+ if (product.type === chunk5VHKZTFJ_js.PRODUCT_TYPE.Composite) {
10571
10571
  return "composite" /* Composite */;
10572
10572
  }
10573
10573
  if (product.quantity_pricing && product.quantity_pricing.length > 1) {
10574
10574
  return "wholesale" /* Wholesale */;
10575
10575
  }
10576
- if (product.type === chunkZYACIPKO_js.PRODUCT_TYPE.Service) {
10576
+ if (product.type === chunk5VHKZTFJ_js.PRODUCT_TYPE.Service) {
10577
10577
  return "service" /* Service */;
10578
10578
  }
10579
- if (product.type === chunkZYACIPKO_js.PRODUCT_TYPE.Digital) {
10579
+ if (product.type === chunk5VHKZTFJ_js.PRODUCT_TYPE.Digital) {
10580
10580
  return "digital" /* Digital */;
10581
10581
  }
10582
- if (product.render_hint === chunkZYACIPKO_js.RENDER_HINT.Food) {
10582
+ if (product.render_hint === chunk5VHKZTFJ_js.RENDER_HINT.Food) {
10583
10583
  return "food" /* Food */;
10584
10584
  }
10585
- if (product.render_hint === chunkZYACIPKO_js.RENDER_HINT.Physical) {
10585
+ if (product.render_hint === chunk5VHKZTFJ_js.RENDER_HINT.Physical) {
10586
10586
  return "physical" /* Physical */;
10587
10587
  }
10588
10588
  return "default" /* Default */;
@@ -12646,7 +12646,7 @@ function SparkleIcon({ className }) {
12646
12646
 
12647
12647
  Object.defineProperty(exports, "getVariantDisplayName", {
12648
12648
  enumerable: true,
12649
- get: function () { return chunkZYACIPKO_js.getVariantDisplayName; }
12649
+ get: function () { return chunk5VHKZTFJ_js.getVariantDisplayName; }
12650
12650
  });
12651
12651
  exports.AccommodationCard = AccommodationCard;
12652
12652
  exports.Ad = Ad;
package/dist/react.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
- import { DURATION_UNIT, getVariantDisplayName, INPUT_FIELD_TYPE, PRODUCT_TYPE, createCimplifyClient, RENDER_HINT } from './chunk-2X6P5WJZ.mjs';
3
- export { getVariantDisplayName } from './chunk-2X6P5WJZ.mjs';
4
- import { ELEMENT_TYPES, EVENT_TYPES } from './chunk-TFHKVQLL.mjs';
2
+ import { DURATION_UNIT, getVariantDisplayName, INPUT_FIELD_TYPE, PRODUCT_TYPE, createCimplifyClient, RENDER_HINT } from './chunk-JTU5P6GM.mjs';
3
+ export { getVariantDisplayName } from './chunk-JTU5P6GM.mjs';
4
+ import { ELEMENT_TYPES, EVENT_TYPES } from './chunk-EZK2FXTM.mjs';
5
5
  import { isSupportedCurrency, formatPrice, parsePrice, getUnitPriceAtQuantity, isOnSale, getDiscountPercentage, getBasePrice, getPriceRange, formatPriceRange } from './chunk-6TVQQYQ5.mjs';
6
6
  import React10, { createContext, useRef, useState, useCallback, useEffect, useContext, useMemo, useId, useSyncExternalStore } from 'react';
7
7
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
@@ -117,6 +117,19 @@ interface MockBusiness {
117
117
  timezone?: string;
118
118
  metadata?: Record<string, unknown>;
119
119
  }
120
+ interface MockQuantityPricingTier {
121
+ min_quantity: number;
122
+ unit_price: string;
123
+ }
124
+ interface MockBillingPlan {
125
+ id: string;
126
+ name: string;
127
+ interval: "day" | "week" | "month" | "year";
128
+ interval_count: number;
129
+ price: string;
130
+ currency: string;
131
+ trial_period_days?: number;
132
+ }
120
133
  interface MockProduct {
121
134
  id: string;
122
135
  business_id: string;
@@ -140,6 +153,20 @@ interface MockProduct {
140
153
  pairings?: string[];
141
154
  is_signature?: boolean;
142
155
  is_new?: boolean;
156
+ /** Override for the auto-derived render hint. */
157
+ render_hint?: "food" | "physical" | "general";
158
+ /** Display mode hint (card opens modal, page is a link). Storefronts can override. */
159
+ display_mode?: "card" | "page";
160
+ /** For digital products — how the SDK renders fulfilment UI. */
161
+ digital_product_type?: "download" | "license" | "event_ticket" | "access_pass" | "gift_code";
162
+ /** For wholesale products — quantity-pricing tiers. */
163
+ quantity_pricing?: MockQuantityPricingTier[];
164
+ /** For services — duration unit (drives Rental/Accommodation/Lease cards). */
165
+ duration_unit?: "minutes" | "hours" | "days" | "nights" | "weeks" | "months" | "years";
166
+ /** For schedule services — duration in minutes (presence implies non-subscription service). */
167
+ duration_minutes?: number;
168
+ /** For subscription services — billing plans. */
169
+ billing_plans?: MockBillingPlan[];
143
170
  metadata?: Record<string, unknown>;
144
171
  created_at: string;
145
172
  updated_at: string;