@cimplify/sdk 0.44.7 → 0.44.10

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
@@ -4149,6 +4149,26 @@ function defaultPriceInfo(price, currency) {
4149
4149
  }
4150
4150
 
4151
4151
  // src/mock/domain/catalogue/product-shape.ts
4152
+ function withDisplayAttributes(v, registry) {
4153
+ const axes = registry.variantAxes.list((a) => a.product_id === v.product_id);
4154
+ const display_attributes = v.axis_value_ids.flatMap((valueId) => {
4155
+ for (const axis of axes) {
4156
+ const value = axis.values.find((vv) => vv.id === valueId);
4157
+ if (value) {
4158
+ return [
4159
+ {
4160
+ axis_id: axis.id,
4161
+ axis_name: axis.name,
4162
+ value_id: value.id,
4163
+ value_name: value.name
4164
+ }
4165
+ ];
4166
+ }
4167
+ }
4168
+ return [];
4169
+ });
4170
+ return { ...v, display_attributes };
4171
+ }
4152
4172
  function toCanonicalProductSummary(p) {
4153
4173
  return {
4154
4174
  id: p.id,
@@ -4242,7 +4262,7 @@ function toApiProduct(p, ctx) {
4242
4262
  // ─── Embedded relations (ProductWithDetails) ───
4243
4263
  category: registry.categories.get(p.category_ids[0]),
4244
4264
  add_ons: p.add_on_ids.map((aid) => registry.addOns.get(aid)).filter(Boolean),
4245
- variants: registry.variants.list((v) => v.product_id === p.id),
4265
+ variants: registry.variants.list((v) => v.product_id === p.id).map((v) => withDisplayAttributes(v, registry)),
4246
4266
  variant_axes: registry.variantAxes.list((a) => a.product_id === p.id),
4247
4267
  // ─── Composite-specific (CompositeProductLayout reads product.groups) ───
4248
4268
  groups,
@@ -4359,7 +4379,20 @@ function buildBundleComponent(bundleId, productId, p) {
4359
4379
  function createCatalogueService(opts) {
4360
4380
  const { registry, clock, ids } = opts;
4361
4381
  const productsForBusiness = (businessId) => registry.products.list((p) => p.business_id === businessId);
4362
- const variantsForProduct = (productId) => registry.variants.list((v) => v.product_id === productId);
4382
+ const variantsForProduct = (productId) => registry.variants.list((v) => v.product_id === productId).map(enrichVariant);
4383
+ const enrichVariant = (v) => {
4384
+ const axes = registry.variantAxes.list((a) => a.product_id === v.product_id);
4385
+ const display_attributes = v.axis_value_ids.flatMap((valueId) => {
4386
+ for (const axis of axes) {
4387
+ const value = axis.values.find((vv) => vv.id === valueId);
4388
+ if (value) {
4389
+ return [{ axis_id: axis.id, axis_name: axis.name, value_id: value.id, value_name: value.name }];
4390
+ }
4391
+ }
4392
+ return [];
4393
+ });
4394
+ return { ...v, display_attributes };
4395
+ };
4363
4396
  const axesForProduct = (productId) => registry.variantAxes.list((a) => a.product_id === productId);
4364
4397
  const addOnLinksForProduct = (productId) => registry.productAddOns.list((l) => l.product_id === productId);
4365
4398
  const apiProduct = (p) => {
@@ -4435,7 +4468,7 @@ function createCatalogueService(opts) {
4435
4468
  if (!v || v.product_id !== productId) {
4436
4469
  throw notFound(`Variant ${variantId} not found on product ${productId}`);
4437
4470
  }
4438
- return v;
4471
+ return enrichVariant(v);
4439
4472
  },
4440
4473
  findProductVariant(productId, properties) {
4441
4474
  const variants = variantsForProduct(productId);
@@ -4827,7 +4860,7 @@ function defaultChosenPrice(price) {
4827
4860
  markup_discount_amount: ZERO
4828
4861
  };
4829
4862
  }
4830
- function variantDisplaySuffix(registry, variant) {
4863
+ function variantDisplayName(registry, variant) {
4831
4864
  const valueNames = [];
4832
4865
  for (const valueId of variant.axis_value_ids) {
4833
4866
  for (const axis of registry.variantAxes.list((a) => a.product_id === variant.product_id)) {
@@ -4835,7 +4868,7 @@ function variantDisplaySuffix(registry, variant) {
4835
4868
  if (v) valueNames.push(v.name);
4836
4869
  }
4837
4870
  }
4838
- return valueNames.length ? ` (${valueNames.join(" \u2022 ")})` : "";
4871
+ return valueNames.join(" \u2022 ");
4839
4872
  }
4840
4873
  function toUICart(registry, cart) {
4841
4874
  return {
@@ -4845,17 +4878,50 @@ function toUICart(registry, cart) {
4845
4878
  const product = registry.products.get(i.item_id);
4846
4879
  const variant = i.variant_id ? registry.variants.get(i.variant_id) : void 0;
4847
4880
  const cfg = i.configuration;
4848
- const variantName = variant ? variantDisplaySuffix(registry, variant) : "";
4881
+ const variantName = variant ? variantDisplayName(registry, variant) : "";
4882
+ const variantDisplayAttributes = variant ? variant.axis_value_ids.flatMap((valueId) => {
4883
+ for (const axis of registry.variantAxes.list((a) => a.product_id === variant.product_id)) {
4884
+ const v = axis.values.find((vv) => vv.id === valueId);
4885
+ if (v) return [{ axis_id: axis.id, axis_name: axis.name, value_id: v.id, value_name: v.name }];
4886
+ }
4887
+ return [];
4888
+ }) : void 0;
4849
4889
  const baseName = product?.name ?? "Unknown product";
4890
+ const isBundle = cfg.type === "bundle";
4891
+ const isComposite = cfg.type === "composite";
4850
4892
  return {
4851
4893
  id: i.id,
4852
4894
  cart_id: i.cart_id,
4853
4895
  item_id: i.item_id,
4854
4896
  variant_id: i.variant_id,
4897
+ variant_name: variantName || void 0,
4898
+ variant_info: variant ? {
4899
+ id: variant.id,
4900
+ name: variantName,
4901
+ sku: variant.sku,
4902
+ price_adjustment: variant.price_adjustment,
4903
+ display_attributes: variantDisplayAttributes,
4904
+ images: variant.images
4905
+ } : void 0,
4906
+ variant_details: variant ? {
4907
+ variant_id: variant.id,
4908
+ sku: variant.sku,
4909
+ properties: variant.axis_value_ids.reduce((acc, valueId) => {
4910
+ for (const axis of registry.variantAxes.list((a) => a.product_id === variant.product_id)) {
4911
+ const v = axis.values.find((vv) => vv.id === valueId);
4912
+ if (v) acc[axis.name] = v.name;
4913
+ }
4914
+ return acc;
4915
+ }, {})
4916
+ } : void 0,
4855
4917
  quantity: i.quantity,
4856
4918
  line_key: i.line_key,
4857
4919
  line_type: cfg.type,
4858
- name: baseName + variantName,
4920
+ name: baseName,
4921
+ description: product?.description,
4922
+ image_url: product?.image,
4923
+ category_id: product?.category_ids?.[0],
4924
+ category_name: product?.category_ids?.[0] ? registry.categories.get(product.category_ids[0])?.name : void 0,
4859
4925
  is_available: product?.is_available ?? true,
4860
4926
  base_price: i.price,
4861
4927
  add_ons_price: i.add_ons_price,
@@ -4867,7 +4933,26 @@ function toUICart(registry, cart) {
4867
4933
  add_on_details: cfg.add_ons ?? { selected_options: [], total_add_on_price: ZERO, add_ons: [] },
4868
4934
  add_on_options: cfg.add_ons?.selected_options ?? [],
4869
4935
  add_ons: cfg.add_ons?.add_ons ?? [],
4936
+ // Service / scheduling
4937
+ scheduled_start: i.scheduled_start,
4938
+ scheduled_end: i.scheduled_end,
4939
+ staff_id: i.staff_id,
4940
+ resource_id: i.resource_id,
4941
+ service_status: i.service_status,
4942
+ confirmation_code: i.confirmation_code,
4943
+ // Customization
4944
+ special_instructions: i.special_instructions,
4945
+ customer_inputs: i.customer_inputs,
4946
+ // Bundle / composite resolved breakdowns
4947
+ bundle_selections: isBundle ? cfg.input : void 0,
4948
+ bundle_resolved: isBundle ? cfg.resolved : void 0,
4949
+ composite_selections: isComposite ? cfg.input : void 0,
4950
+ composite_resolved: isComposite ? cfg.resolved : void 0,
4951
+ // Billing / discounts / metadata
4952
+ billing_plan_id: i.billing_plan_id,
4870
4953
  applied_discount_ids: i.applied_discount_ids,
4954
+ discount_details: void 0,
4955
+ metadata: i.metadata,
4871
4956
  created_at: i.created_at,
4872
4957
  updated_at: i.updated_at
4873
4958
  };
@@ -4878,7 +4963,9 @@ function toUICart(registry, cart) {
4878
4963
  tax_amount: cart.tax_amount,
4879
4964
  service_charge: cart.service_charge,
4880
4965
  total_price: cart.total_price,
4881
- currency: cart.currency
4966
+ currency: cart.currency,
4967
+ tax_rate: cart.tax_rate,
4968
+ service_charge_rate: cart.service_charge_rate
4882
4969
  },
4883
4970
  customer_info: {
4884
4971
  name: cart.customer_name,
@@ -5064,6 +5151,7 @@ function createCartService(opts) {
5064
5151
  existing.quantity += body.quantity;
5065
5152
  existing.updated_at = clock.iso();
5066
5153
  } else {
5154
+ const isService = product.product_type === "service";
5067
5155
  const item = {
5068
5156
  id: ids.cartItem(),
5069
5157
  cart_id: cart.id,
@@ -5076,6 +5164,15 @@ function createCartService(opts) {
5076
5164
  configuration,
5077
5165
  applied_discount_ids: [],
5078
5166
  item_discount_amount: ZERO2,
5167
+ scheduled_start: body.scheduled_start,
5168
+ scheduled_end: body.scheduled_end,
5169
+ staff_id: body.staff_id,
5170
+ resource_id: body.resource_id,
5171
+ service_status: isService && body.scheduled_start ? "pending" : void 0,
5172
+ special_instructions: body.special_instructions,
5173
+ customer_inputs: body.customer_inputs,
5174
+ billing_plan_id: body.billing_plan_id,
5175
+ metadata: body.metadata,
5079
5176
  created_at: clock.iso(),
5080
5177
  updated_at: clock.iso()
5081
5178
  };
@@ -1,5 +1,5 @@
1
- import { M as MockBus, a as MockEvent } from '../server-DD-Cd1Ob.mjs';
2
- export { A as AppHandle, m as Clock, C as CreateAppOptions, D as Deps, I as IdGen, h as MockBusiness, j as MockCart, l as MockEventType, d as MockOptions, k as MockOrder, i as MockProduct, S as SeedName, f as Session, g as StateRegistry, e as applySeed, b as createDeps, c as createMockApp } from '../server-DD-Cd1Ob.mjs';
1
+ import { M as MockBus, a as MockEvent } from '../server-CUbuQxOV.mjs';
2
+ export { A as AppHandle, m as Clock, C as CreateAppOptions, D as Deps, I as IdGen, h as MockBusiness, j as MockCart, l as MockEventType, d as MockOptions, k as MockOrder, i as MockProduct, S as SeedName, f as Session, g as StateRegistry, e as applySeed, b as createDeps, c as createMockApp } from '../server-CUbuQxOV.mjs';
3
3
  import 'hono';
4
4
 
5
5
  interface WebhookOptions {
@@ -1,5 +1,5 @@
1
- import { M as MockBus, a as MockEvent } from '../server-DD-Cd1Ob.js';
2
- export { A as AppHandle, m as Clock, C as CreateAppOptions, D as Deps, I as IdGen, h as MockBusiness, j as MockCart, l as MockEventType, d as MockOptions, k as MockOrder, i as MockProduct, S as SeedName, f as Session, g as StateRegistry, e as applySeed, b as createDeps, c as createMockApp } from '../server-DD-Cd1Ob.js';
1
+ import { M as MockBus, a as MockEvent } from '../server-CUbuQxOV.js';
2
+ export { A as AppHandle, m as Clock, C as CreateAppOptions, D as Deps, I as IdGen, h as MockBusiness, j as MockCart, l as MockEventType, d as MockOptions, k as MockOrder, i as MockProduct, S as SeedName, f as Session, g as StateRegistry, e as applySeed, b as createDeps, c as createMockApp } from '../server-CUbuQxOV.js';
3
3
  import 'hono';
4
4
 
5
5
  interface WebhookOptions {
@@ -3517,6 +3517,26 @@ function defaultPriceInfo(price, currency) {
3517
3517
  }
3518
3518
 
3519
3519
  // src/mock/domain/catalogue/product-shape.ts
3520
+ function withDisplayAttributes(v, registry) {
3521
+ const axes = registry.variantAxes.list((a) => a.product_id === v.product_id);
3522
+ const display_attributes = v.axis_value_ids.flatMap((valueId) => {
3523
+ for (const axis of axes) {
3524
+ const value = axis.values.find((vv) => vv.id === valueId);
3525
+ if (value) {
3526
+ return [
3527
+ {
3528
+ axis_id: axis.id,
3529
+ axis_name: axis.name,
3530
+ value_id: value.id,
3531
+ value_name: value.name
3532
+ }
3533
+ ];
3534
+ }
3535
+ }
3536
+ return [];
3537
+ });
3538
+ return { ...v, display_attributes };
3539
+ }
3520
3540
  function toCanonicalProductSummary(p) {
3521
3541
  return {
3522
3542
  id: p.id,
@@ -3610,7 +3630,7 @@ function toApiProduct(p, ctx) {
3610
3630
  // ─── Embedded relations (ProductWithDetails) ───
3611
3631
  category: registry.categories.get(p.category_ids[0]),
3612
3632
  add_ons: p.add_on_ids.map((aid) => registry.addOns.get(aid)).filter(Boolean),
3613
- variants: registry.variants.list((v) => v.product_id === p.id),
3633
+ variants: registry.variants.list((v) => v.product_id === p.id).map((v) => withDisplayAttributes(v, registry)),
3614
3634
  variant_axes: registry.variantAxes.list((a) => a.product_id === p.id),
3615
3635
  // ─── Composite-specific (CompositeProductLayout reads product.groups) ───
3616
3636
  groups,
@@ -3727,7 +3747,20 @@ function buildBundleComponent(bundleId, productId, p) {
3727
3747
  function createCatalogueService(opts) {
3728
3748
  const { registry, clock, ids } = opts;
3729
3749
  const productsForBusiness = (businessId) => registry.products.list((p) => p.business_id === businessId);
3730
- const variantsForProduct = (productId) => registry.variants.list((v) => v.product_id === productId);
3750
+ const variantsForProduct = (productId) => registry.variants.list((v) => v.product_id === productId).map(enrichVariant);
3751
+ const enrichVariant = (v) => {
3752
+ const axes = registry.variantAxes.list((a) => a.product_id === v.product_id);
3753
+ const display_attributes = v.axis_value_ids.flatMap((valueId) => {
3754
+ for (const axis of axes) {
3755
+ const value = axis.values.find((vv) => vv.id === valueId);
3756
+ if (value) {
3757
+ return [{ axis_id: axis.id, axis_name: axis.name, value_id: value.id, value_name: value.name }];
3758
+ }
3759
+ }
3760
+ return [];
3761
+ });
3762
+ return { ...v, display_attributes };
3763
+ };
3731
3764
  const axesForProduct = (productId) => registry.variantAxes.list((a) => a.product_id === productId);
3732
3765
  const addOnLinksForProduct = (productId) => registry.productAddOns.list((l) => l.product_id === productId);
3733
3766
  const apiProduct = (p) => {
@@ -3803,7 +3836,7 @@ function createCatalogueService(opts) {
3803
3836
  if (!v || v.product_id !== productId) {
3804
3837
  throw notFound(`Variant ${variantId} not found on product ${productId}`);
3805
3838
  }
3806
- return v;
3839
+ return enrichVariant(v);
3807
3840
  },
3808
3841
  findProductVariant(productId, properties) {
3809
3842
  const variants = variantsForProduct(productId);
@@ -4195,7 +4228,7 @@ function defaultChosenPrice(price) {
4195
4228
  markup_discount_amount: ZERO
4196
4229
  };
4197
4230
  }
4198
- function variantDisplaySuffix(registry, variant) {
4231
+ function variantDisplayName(registry, variant) {
4199
4232
  const valueNames = [];
4200
4233
  for (const valueId of variant.axis_value_ids) {
4201
4234
  for (const axis of registry.variantAxes.list((a) => a.product_id === variant.product_id)) {
@@ -4203,7 +4236,7 @@ function variantDisplaySuffix(registry, variant) {
4203
4236
  if (v) valueNames.push(v.name);
4204
4237
  }
4205
4238
  }
4206
- return valueNames.length ? ` (${valueNames.join(" \u2022 ")})` : "";
4239
+ return valueNames.join(" \u2022 ");
4207
4240
  }
4208
4241
  function toUICart(registry, cart) {
4209
4242
  return {
@@ -4213,17 +4246,50 @@ function toUICart(registry, cart) {
4213
4246
  const product = registry.products.get(i.item_id);
4214
4247
  const variant = i.variant_id ? registry.variants.get(i.variant_id) : void 0;
4215
4248
  const cfg = i.configuration;
4216
- const variantName = variant ? variantDisplaySuffix(registry, variant) : "";
4249
+ const variantName = variant ? variantDisplayName(registry, variant) : "";
4250
+ const variantDisplayAttributes = variant ? variant.axis_value_ids.flatMap((valueId) => {
4251
+ for (const axis of registry.variantAxes.list((a) => a.product_id === variant.product_id)) {
4252
+ const v = axis.values.find((vv) => vv.id === valueId);
4253
+ if (v) return [{ axis_id: axis.id, axis_name: axis.name, value_id: v.id, value_name: v.name }];
4254
+ }
4255
+ return [];
4256
+ }) : void 0;
4217
4257
  const baseName = product?.name ?? "Unknown product";
4258
+ const isBundle = cfg.type === "bundle";
4259
+ const isComposite = cfg.type === "composite";
4218
4260
  return {
4219
4261
  id: i.id,
4220
4262
  cart_id: i.cart_id,
4221
4263
  item_id: i.item_id,
4222
4264
  variant_id: i.variant_id,
4265
+ variant_name: variantName || void 0,
4266
+ variant_info: variant ? {
4267
+ id: variant.id,
4268
+ name: variantName,
4269
+ sku: variant.sku,
4270
+ price_adjustment: variant.price_adjustment,
4271
+ display_attributes: variantDisplayAttributes,
4272
+ images: variant.images
4273
+ } : void 0,
4274
+ variant_details: variant ? {
4275
+ variant_id: variant.id,
4276
+ sku: variant.sku,
4277
+ properties: variant.axis_value_ids.reduce((acc, valueId) => {
4278
+ for (const axis of registry.variantAxes.list((a) => a.product_id === variant.product_id)) {
4279
+ const v = axis.values.find((vv) => vv.id === valueId);
4280
+ if (v) acc[axis.name] = v.name;
4281
+ }
4282
+ return acc;
4283
+ }, {})
4284
+ } : void 0,
4223
4285
  quantity: i.quantity,
4224
4286
  line_key: i.line_key,
4225
4287
  line_type: cfg.type,
4226
- name: baseName + variantName,
4288
+ name: baseName,
4289
+ description: product?.description,
4290
+ image_url: product?.image,
4291
+ category_id: product?.category_ids?.[0],
4292
+ category_name: product?.category_ids?.[0] ? registry.categories.get(product.category_ids[0])?.name : void 0,
4227
4293
  is_available: product?.is_available ?? true,
4228
4294
  base_price: i.price,
4229
4295
  add_ons_price: i.add_ons_price,
@@ -4235,7 +4301,26 @@ function toUICart(registry, cart) {
4235
4301
  add_on_details: cfg.add_ons ?? { selected_options: [], total_add_on_price: ZERO, add_ons: [] },
4236
4302
  add_on_options: cfg.add_ons?.selected_options ?? [],
4237
4303
  add_ons: cfg.add_ons?.add_ons ?? [],
4304
+ // Service / scheduling
4305
+ scheduled_start: i.scheduled_start,
4306
+ scheduled_end: i.scheduled_end,
4307
+ staff_id: i.staff_id,
4308
+ resource_id: i.resource_id,
4309
+ service_status: i.service_status,
4310
+ confirmation_code: i.confirmation_code,
4311
+ // Customization
4312
+ special_instructions: i.special_instructions,
4313
+ customer_inputs: i.customer_inputs,
4314
+ // Bundle / composite resolved breakdowns
4315
+ bundle_selections: isBundle ? cfg.input : void 0,
4316
+ bundle_resolved: isBundle ? cfg.resolved : void 0,
4317
+ composite_selections: isComposite ? cfg.input : void 0,
4318
+ composite_resolved: isComposite ? cfg.resolved : void 0,
4319
+ // Billing / discounts / metadata
4320
+ billing_plan_id: i.billing_plan_id,
4238
4321
  applied_discount_ids: i.applied_discount_ids,
4322
+ discount_details: void 0,
4323
+ metadata: i.metadata,
4239
4324
  created_at: i.created_at,
4240
4325
  updated_at: i.updated_at
4241
4326
  };
@@ -4246,7 +4331,9 @@ function toUICart(registry, cart) {
4246
4331
  tax_amount: cart.tax_amount,
4247
4332
  service_charge: cart.service_charge,
4248
4333
  total_price: cart.total_price,
4249
- currency: cart.currency
4334
+ currency: cart.currency,
4335
+ tax_rate: cart.tax_rate,
4336
+ service_charge_rate: cart.service_charge_rate
4250
4337
  },
4251
4338
  customer_info: {
4252
4339
  name: cart.customer_name,
@@ -4432,6 +4519,7 @@ function createCartService(opts) {
4432
4519
  existing.quantity += body.quantity;
4433
4520
  existing.updated_at = clock.iso();
4434
4521
  } else {
4522
+ const isService = product.product_type === "service";
4435
4523
  const item = {
4436
4524
  id: ids.cartItem(),
4437
4525
  cart_id: cart.id,
@@ -4444,6 +4532,15 @@ function createCartService(opts) {
4444
4532
  configuration,
4445
4533
  applied_discount_ids: [],
4446
4534
  item_discount_amount: ZERO2,
4535
+ scheduled_start: body.scheduled_start,
4536
+ scheduled_end: body.scheduled_end,
4537
+ staff_id: body.staff_id,
4538
+ resource_id: body.resource_id,
4539
+ service_status: isService && body.scheduled_start ? "pending" : void 0,
4540
+ special_instructions: body.special_instructions,
4541
+ customer_inputs: body.customer_inputs,
4542
+ billing_plan_id: body.billing_plan_id,
4543
+ metadata: body.metadata,
4447
4544
  created_at: clock.iso(),
4448
4545
  updated_at: clock.iso()
4449
4546
  };
@@ -3515,6 +3515,26 @@ function defaultPriceInfo(price, currency) {
3515
3515
  }
3516
3516
 
3517
3517
  // src/mock/domain/catalogue/product-shape.ts
3518
+ function withDisplayAttributes(v, registry) {
3519
+ const axes = registry.variantAxes.list((a) => a.product_id === v.product_id);
3520
+ const display_attributes = v.axis_value_ids.flatMap((valueId) => {
3521
+ for (const axis of axes) {
3522
+ const value = axis.values.find((vv) => vv.id === valueId);
3523
+ if (value) {
3524
+ return [
3525
+ {
3526
+ axis_id: axis.id,
3527
+ axis_name: axis.name,
3528
+ value_id: value.id,
3529
+ value_name: value.name
3530
+ }
3531
+ ];
3532
+ }
3533
+ }
3534
+ return [];
3535
+ });
3536
+ return { ...v, display_attributes };
3537
+ }
3518
3538
  function toCanonicalProductSummary(p) {
3519
3539
  return {
3520
3540
  id: p.id,
@@ -3608,7 +3628,7 @@ function toApiProduct(p, ctx) {
3608
3628
  // ─── Embedded relations (ProductWithDetails) ───
3609
3629
  category: registry.categories.get(p.category_ids[0]),
3610
3630
  add_ons: p.add_on_ids.map((aid) => registry.addOns.get(aid)).filter(Boolean),
3611
- variants: registry.variants.list((v) => v.product_id === p.id),
3631
+ variants: registry.variants.list((v) => v.product_id === p.id).map((v) => withDisplayAttributes(v, registry)),
3612
3632
  variant_axes: registry.variantAxes.list((a) => a.product_id === p.id),
3613
3633
  // ─── Composite-specific (CompositeProductLayout reads product.groups) ───
3614
3634
  groups,
@@ -3725,7 +3745,20 @@ function buildBundleComponent(bundleId, productId, p) {
3725
3745
  function createCatalogueService(opts) {
3726
3746
  const { registry, clock, ids } = opts;
3727
3747
  const productsForBusiness = (businessId) => registry.products.list((p) => p.business_id === businessId);
3728
- const variantsForProduct = (productId) => registry.variants.list((v) => v.product_id === productId);
3748
+ const variantsForProduct = (productId) => registry.variants.list((v) => v.product_id === productId).map(enrichVariant);
3749
+ const enrichVariant = (v) => {
3750
+ const axes = registry.variantAxes.list((a) => a.product_id === v.product_id);
3751
+ const display_attributes = v.axis_value_ids.flatMap((valueId) => {
3752
+ for (const axis of axes) {
3753
+ const value = axis.values.find((vv) => vv.id === valueId);
3754
+ if (value) {
3755
+ return [{ axis_id: axis.id, axis_name: axis.name, value_id: value.id, value_name: value.name }];
3756
+ }
3757
+ }
3758
+ return [];
3759
+ });
3760
+ return { ...v, display_attributes };
3761
+ };
3729
3762
  const axesForProduct = (productId) => registry.variantAxes.list((a) => a.product_id === productId);
3730
3763
  const addOnLinksForProduct = (productId) => registry.productAddOns.list((l) => l.product_id === productId);
3731
3764
  const apiProduct = (p) => {
@@ -3801,7 +3834,7 @@ function createCatalogueService(opts) {
3801
3834
  if (!v || v.product_id !== productId) {
3802
3835
  throw notFound(`Variant ${variantId} not found on product ${productId}`);
3803
3836
  }
3804
- return v;
3837
+ return enrichVariant(v);
3805
3838
  },
3806
3839
  findProductVariant(productId, properties) {
3807
3840
  const variants = variantsForProduct(productId);
@@ -4193,7 +4226,7 @@ function defaultChosenPrice(price) {
4193
4226
  markup_discount_amount: ZERO
4194
4227
  };
4195
4228
  }
4196
- function variantDisplaySuffix(registry, variant) {
4229
+ function variantDisplayName(registry, variant) {
4197
4230
  const valueNames = [];
4198
4231
  for (const valueId of variant.axis_value_ids) {
4199
4232
  for (const axis of registry.variantAxes.list((a) => a.product_id === variant.product_id)) {
@@ -4201,7 +4234,7 @@ function variantDisplaySuffix(registry, variant) {
4201
4234
  if (v) valueNames.push(v.name);
4202
4235
  }
4203
4236
  }
4204
- return valueNames.length ? ` (${valueNames.join(" \u2022 ")})` : "";
4237
+ return valueNames.join(" \u2022 ");
4205
4238
  }
4206
4239
  function toUICart(registry, cart) {
4207
4240
  return {
@@ -4211,17 +4244,50 @@ function toUICart(registry, cart) {
4211
4244
  const product = registry.products.get(i.item_id);
4212
4245
  const variant = i.variant_id ? registry.variants.get(i.variant_id) : void 0;
4213
4246
  const cfg = i.configuration;
4214
- const variantName = variant ? variantDisplaySuffix(registry, variant) : "";
4247
+ const variantName = variant ? variantDisplayName(registry, variant) : "";
4248
+ const variantDisplayAttributes = variant ? variant.axis_value_ids.flatMap((valueId) => {
4249
+ for (const axis of registry.variantAxes.list((a) => a.product_id === variant.product_id)) {
4250
+ const v = axis.values.find((vv) => vv.id === valueId);
4251
+ if (v) return [{ axis_id: axis.id, axis_name: axis.name, value_id: v.id, value_name: v.name }];
4252
+ }
4253
+ return [];
4254
+ }) : void 0;
4215
4255
  const baseName = product?.name ?? "Unknown product";
4256
+ const isBundle = cfg.type === "bundle";
4257
+ const isComposite = cfg.type === "composite";
4216
4258
  return {
4217
4259
  id: i.id,
4218
4260
  cart_id: i.cart_id,
4219
4261
  item_id: i.item_id,
4220
4262
  variant_id: i.variant_id,
4263
+ variant_name: variantName || void 0,
4264
+ variant_info: variant ? {
4265
+ id: variant.id,
4266
+ name: variantName,
4267
+ sku: variant.sku,
4268
+ price_adjustment: variant.price_adjustment,
4269
+ display_attributes: variantDisplayAttributes,
4270
+ images: variant.images
4271
+ } : void 0,
4272
+ variant_details: variant ? {
4273
+ variant_id: variant.id,
4274
+ sku: variant.sku,
4275
+ properties: variant.axis_value_ids.reduce((acc, valueId) => {
4276
+ for (const axis of registry.variantAxes.list((a) => a.product_id === variant.product_id)) {
4277
+ const v = axis.values.find((vv) => vv.id === valueId);
4278
+ if (v) acc[axis.name] = v.name;
4279
+ }
4280
+ return acc;
4281
+ }, {})
4282
+ } : void 0,
4221
4283
  quantity: i.quantity,
4222
4284
  line_key: i.line_key,
4223
4285
  line_type: cfg.type,
4224
- name: baseName + variantName,
4286
+ name: baseName,
4287
+ description: product?.description,
4288
+ image_url: product?.image,
4289
+ category_id: product?.category_ids?.[0],
4290
+ category_name: product?.category_ids?.[0] ? registry.categories.get(product.category_ids[0])?.name : void 0,
4225
4291
  is_available: product?.is_available ?? true,
4226
4292
  base_price: i.price,
4227
4293
  add_ons_price: i.add_ons_price,
@@ -4233,7 +4299,26 @@ function toUICart(registry, cart) {
4233
4299
  add_on_details: cfg.add_ons ?? { selected_options: [], total_add_on_price: ZERO, add_ons: [] },
4234
4300
  add_on_options: cfg.add_ons?.selected_options ?? [],
4235
4301
  add_ons: cfg.add_ons?.add_ons ?? [],
4302
+ // Service / scheduling
4303
+ scheduled_start: i.scheduled_start,
4304
+ scheduled_end: i.scheduled_end,
4305
+ staff_id: i.staff_id,
4306
+ resource_id: i.resource_id,
4307
+ service_status: i.service_status,
4308
+ confirmation_code: i.confirmation_code,
4309
+ // Customization
4310
+ special_instructions: i.special_instructions,
4311
+ customer_inputs: i.customer_inputs,
4312
+ // Bundle / composite resolved breakdowns
4313
+ bundle_selections: isBundle ? cfg.input : void 0,
4314
+ bundle_resolved: isBundle ? cfg.resolved : void 0,
4315
+ composite_selections: isComposite ? cfg.input : void 0,
4316
+ composite_resolved: isComposite ? cfg.resolved : void 0,
4317
+ // Billing / discounts / metadata
4318
+ billing_plan_id: i.billing_plan_id,
4236
4319
  applied_discount_ids: i.applied_discount_ids,
4320
+ discount_details: void 0,
4321
+ metadata: i.metadata,
4237
4322
  created_at: i.created_at,
4238
4323
  updated_at: i.updated_at
4239
4324
  };
@@ -4244,7 +4329,9 @@ function toUICart(registry, cart) {
4244
4329
  tax_amount: cart.tax_amount,
4245
4330
  service_charge: cart.service_charge,
4246
4331
  total_price: cart.total_price,
4247
- currency: cart.currency
4332
+ currency: cart.currency,
4333
+ tax_rate: cart.tax_rate,
4334
+ service_charge_rate: cart.service_charge_rate
4248
4335
  },
4249
4336
  customer_info: {
4250
4337
  name: cart.customer_name,
@@ -4430,6 +4517,7 @@ function createCartService(opts) {
4430
4517
  existing.quantity += body.quantity;
4431
4518
  existing.updated_at = clock.iso();
4432
4519
  } else {
4520
+ const isService = product.product_type === "service";
4433
4521
  const item = {
4434
4522
  id: ids.cartItem(),
4435
4523
  cart_id: cart.id,
@@ -4442,6 +4530,15 @@ function createCartService(opts) {
4442
4530
  configuration,
4443
4531
  applied_discount_ids: [],
4444
4532
  item_discount_amount: ZERO2,
4533
+ scheduled_start: body.scheduled_start,
4534
+ scheduled_end: body.scheduled_end,
4535
+ staff_id: body.staff_id,
4536
+ resource_id: body.resource_id,
4537
+ service_status: isService && body.scheduled_start ? "pending" : void 0,
4538
+ special_instructions: body.special_instructions,
4539
+ customer_inputs: body.customer_inputs,
4540
+ billing_plan_id: body.billing_plan_id,
4541
+ metadata: body.metadata,
4445
4542
  created_at: clock.iso(),
4446
4543
  updated_at: clock.iso()
4447
4544
  };
@@ -1,4 +1,4 @@
1
- import { A as AppHandle, C as CreateAppOptions } from '../server-DD-Cd1Ob.mjs';
1
+ import { A as AppHandle, C as CreateAppOptions } from '../server-CUbuQxOV.mjs';
2
2
  import 'hono';
3
3
 
4
4
  interface MswHandlerSetup {
@@ -1,4 +1,4 @@
1
- import { A as AppHandle, C as CreateAppOptions } from '../server-DD-Cd1Ob.js';
1
+ import { A as AppHandle, C as CreateAppOptions } from '../server-CUbuQxOV.js';
2
2
  import 'hono';
3
3
 
4
4
  interface MswHandlerSetup {