@growupsell/commerce 1.0.0-alpha.3 → 1.0.0-alpha.5

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.
@@ -1,4 +1,42 @@
1
+ type FormFieldType = 'text' | 'boolean' | 'date' | 'number' | 'email' | 'phone' | 'select' | 'radio' | 'image' | 'file';
2
+ interface FormFieldOption {
3
+ label: string;
4
+ value: string;
5
+ }
6
+ interface FormField {
7
+ /** The key to submit the value under. */
8
+ name: string;
9
+ type: FormFieldType;
10
+ required: boolean;
11
+ /** The merchant's label, or the name with `_` turned into spaces. */
12
+ label: string;
13
+ /** Only for `select` and `radio`; otherwise empty. */
14
+ options: FormFieldOption[];
15
+ }
16
+ /** A merchant-built form, as a shopper fills it in. */
17
+ interface PublicForm {
18
+ id: number;
19
+ slug: string;
20
+ name: string;
21
+ description: string | null;
22
+ /** What to show after a successful submit; null means the app's default. */
23
+ successMessage: string | null;
24
+ fields: FormField[];
25
+ }
26
+ /** A form for the merchant to pick (e.g. for a banner button). */
27
+ interface FormSummary {
28
+ id: number;
29
+ name: string;
30
+ slug: string;
31
+ }
32
+ /**
33
+ * A submitted value. `image` / `file` fields take a URL string: upload the file first. Guests
34
+ * cannot fill them today, because the only upload endpoint needs a customer login (ADR-023).
35
+ */
36
+ type FormValue = string | number | boolean | null;
37
+
1
38
  /** Cart domain types. The backend calculates every total; the library only converts them. */
39
+
2
40
  /** `delivery` (paid online) or `cod` (cash on delivery). */
3
41
  type OrderType = 'delivery' | 'cod';
4
42
  /** How the business charges delivery: fixed thresholds, or a delivery partner's quote. */
@@ -26,7 +64,13 @@ interface CartLine {
26
64
  maxQuantity: number | null;
27
65
  isDigital: boolean;
28
66
  fulfillmentMode: FulfillmentMode;
67
+ /** The shopper's values for the product's custom fields, keyed by field `name`. */
29
68
  customData: Record<string, unknown> | null;
69
+ /**
70
+ * The product's custom fields as the merchant configured them: the label of each
71
+ * `customData` key. Empty for products without custom fields and lines without a SKU.
72
+ */
73
+ customFields: FormField[];
30
74
  variantIds: number[];
31
75
  }
32
76
  interface AppliedOffer {
@@ -305,6 +349,12 @@ interface ProductDetail {
305
349
  hasDigitalDelivery: boolean;
306
350
  fulfillmentMode: FulfillmentMode;
307
351
  advanceAmount: number | null;
352
+ /**
353
+ * The custom fields the shopper fills in for a made-to-order or custom fixed-price product
354
+ * (`cart.addItem` `customData`, `checkout.createAdvanceOrder`), as the merchant configured
355
+ * them. Empty for other products.
356
+ */
357
+ customFields: FormField[];
308
358
  }
309
359
  /** A product as listed by `products.list()` (home sliders, product pickers). */
310
360
  interface ProductOverview {
@@ -581,4 +631,4 @@ interface AdvanceOrder {
581
631
  payment: PendingPayment;
582
632
  }
583
633
 
584
- export type { AdvanceOrder as A, Brand as B, Cart as C, DeliveryChargeType as D, ProductSectionItem as E, FulfillmentMode as F, GiftCard as G, ProductSectionItemTarget as H, ProductSku as I, ProductSort as J, ProductSpecificationGroup as K, PromoCode as L, ReviewEligibility as M, ReviewListItem as N, Offer as O, Page as P, ReviewReply as Q, Review as R, ReviewSummary as S, RewardPointSettings as T, SearchSuggestion as U, SpecificationScope as V, TaxDetails as W, VariantGroup as X, VariantOption as Y, AppliedOffer as a, AppliedPromoCode as b, CartLine as c, CartTotals as d, CatalogSettings as e, Category as f, CategoryTree as g, CheckoutSettings as h, CustomerProfile as i, DeliveryEstimate as j, OfferScope as k, OrderType as l, PaymentMethodType as m, PendingPayment as n, PlaceOrderResult as o, ProductBlock as p, ProductDetail as q, ProductFilterConfig as r, ProductImage as s, ProductListItem as t, ProductListOptions as u, ProductListSort as v, ProductOverview as w, ProductPolicies as x, ProductSearchOptions as y, ProductSection as z };
634
+ export type { SpecificationScope as $, AdvanceOrder as A, Brand as B, Cart as C, DeliveryChargeType as D, ProductListSort as E, FormField as F, GiftCard as G, ProductOverview as H, ProductPolicies as I, ProductSearchOptions as J, ProductSection as K, ProductSectionItem as L, ProductSectionItemTarget as M, ProductSku as N, Offer as O, Page as P, ProductSort as Q, ProductSpecificationGroup as R, PromoCode as S, PublicForm as T, Review as U, ReviewEligibility as V, ReviewListItem as W, ReviewReply as X, ReviewSummary as Y, RewardPointSettings as Z, SearchSuggestion as _, AppliedOffer as a, TaxDetails as a0, VariantGroup as a1, VariantOption as a2, AppliedPromoCode as b, CartLine as c, CartTotals as d, CatalogSettings as e, Category as f, CategoryTree as g, CheckoutSettings as h, CustomerProfile as i, DeliveryEstimate as j, FormFieldOption as k, FormFieldType as l, FormSummary as m, FormValue as n, FulfillmentMode as o, OfferScope as p, OrderType as q, PaymentMethodType as r, PendingPayment as s, PlaceOrderResult as t, ProductBlock as u, ProductDetail as v, ProductFilterConfig as w, ProductImage as x, ProductListItem as y, ProductListOptions as z };
@@ -256,6 +256,61 @@ function toBankTransferOption(wire) {
256
256
  };
257
257
  }
258
258
 
259
+ // src/http/forms.ts
260
+ var PUBLIC3 = { anonymous: true, business: "required" };
261
+ var SUBMIT = { business: "required" };
262
+ var MERCHANT3 = { merchant: true, anonymous: true, business: "required" };
263
+ function createFormsApi(request) {
264
+ return {
265
+ async get(slug) {
266
+ return toPublicForm(
267
+ await request("GET", `/forms/public/${path2(slug)}`, PUBLIC3)
268
+ );
269
+ },
270
+ async submit(slug, values) {
271
+ const json = { data: values };
272
+ await request("POST", `/forms/submit/${path2(slug)}`, { ...SUBMIT, json });
273
+ },
274
+ async listForMerchant() {
275
+ const rows = await request("GET", "/forms/list", {
276
+ ...MERCHANT3,
277
+ query: { is_active: true }
278
+ });
279
+ return rows.map(toFormSummary);
280
+ }
281
+ };
282
+ }
283
+ function path2(slug) {
284
+ if (!slug.trim()) throw new Error("forms: slug is required.");
285
+ return encodeURIComponent(slug.trim());
286
+ }
287
+ function toPublicForm(wire) {
288
+ return {
289
+ id: wire.id,
290
+ slug: wire.slug,
291
+ name: wire.name,
292
+ description: text(wire.description),
293
+ successMessage: text(wire.success_message),
294
+ fields: toFormFields(wire.field_configuration)
295
+ };
296
+ }
297
+ function toFormFields(wire) {
298
+ return Array.isArray(wire) ? wire.map(toFormField) : [];
299
+ }
300
+ function toFormSummary(wire) {
301
+ return { id: wire.id, name: wire.name, slug: wire.slug };
302
+ }
303
+ function toFormField(wire) {
304
+ return {
305
+ name: wire.name,
306
+ // The backend only saves the ten known types (`validation.py:4-7`).
307
+ type: wire.type,
308
+ required: wire.required,
309
+ label: text(wire.label) ?? wire.name.replace(/_/g, " "),
310
+ options: wire.options?.map((o) => ({ label: o.label, value: o.value })) ?? []
311
+ };
312
+ }
313
+
259
314
  // src/http/cart.ts
260
315
  var SHOPPER = { business: "required", customerOrSession: "required" };
261
316
  function createCartApi(request) {
@@ -392,6 +447,7 @@ function toCartLine(wire) {
392
447
  isDigital: wire.is_digital_product,
393
448
  fulfillmentMode: text(wire.fulfillment_mode) ?? "none",
394
449
  customData: wire.custom_data ?? null,
450
+ customFields: toFormFields(wire.custom_field_configuration),
395
451
  // The cart serialises the SKU at depth 2, so `selected_variants` are variant rows, not ids
396
452
  // (local backend, 2026-11-01): take each row's id.
397
453
  variantIds: (sku?.selected_variants ?? []).map((variant) => variant.id)
@@ -414,13 +470,13 @@ function sum(values) {
414
470
  }
415
471
 
416
472
  // src/http/catalog.ts
417
- var PUBLIC3 = { business: "required", anonymous: true };
473
+ var PUBLIC4 = { business: "required", anonymous: true };
418
474
  function createCatalogApi(request) {
419
475
  return {
420
476
  async categories(options = {}) {
421
477
  const search = options.search?.trim();
422
478
  const wire = await request("GET", "/product/category/list", {
423
- ...PUBLIC3,
479
+ ...PUBLIC4,
424
480
  query: { search }
425
481
  });
426
482
  return wire.map(toCategoryTree);
@@ -435,21 +491,21 @@ function createCatalogApi(request) {
435
491
  async categoriesByIds(ids) {
436
492
  if (ids.length === 0) return [];
437
493
  const wire = await request("GET", "/product/category/list/filter", {
438
- ...PUBLIC3,
494
+ ...PUBLIC4,
439
495
  query: { ids }
440
496
  });
441
497
  return wire.map(toCategory2);
442
498
  },
443
499
  async brands(options = {}) {
444
500
  const wire = await request("GET", "/product/brand/list", {
445
- ...PUBLIC3,
501
+ ...PUBLIC4,
446
502
  query: { category_ids: options.categoryIds }
447
503
  });
448
504
  return wire.map(toBrand);
449
505
  },
450
506
  async settings() {
451
507
  return toCatalogSettings(
452
- await request("GET", "/product/business/setting/get", PUBLIC3)
508
+ await request("GET", "/product/business/setting/get", PUBLIC4)
453
509
  );
454
510
  }
455
511
  };
@@ -491,31 +547,31 @@ function toCatalogSettings(wire) {
491
547
  }
492
548
 
493
549
  // src/http/faq.ts
494
- var PUBLIC4 = { business: "required", anonymous: true };
495
- var MERCHANT3 = { business: "required", merchant: true, anonymous: true };
550
+ var PUBLIC5 = { business: "required", anonymous: true };
551
+ var MERCHANT4 = { business: "required", merchant: true, anonymous: true };
496
552
  function createFaqApi(request) {
497
553
  return {
498
554
  async list() {
499
- return (await request("GET", "/content/faq/list", PUBLIC4)).map(toFaq);
555
+ return (await request("GET", "/content/faq/list", PUBLIC5)).map(toFaq);
500
556
  },
501
557
  async create(input) {
502
558
  const json = { question: input.question, answer: input.answer };
503
- return toFaq(await request("POST", "/content/faq/create", { ...MERCHANT3, json }));
559
+ return toFaq(await request("POST", "/content/faq/create", { ...MERCHANT4, json }));
504
560
  },
505
561
  async update(id, changes) {
506
562
  const json = {};
507
563
  if (changes.question !== void 0) json.question = changes.question;
508
564
  if (changes.answer !== void 0) json.answer = changes.answer;
509
565
  return toFaq(
510
- await request("PATCH", `/content/faq/update/${id}`, { ...MERCHANT3, json })
566
+ await request("PATCH", `/content/faq/update/${id}`, { ...MERCHANT4, json })
511
567
  );
512
568
  },
513
569
  async move(id, direction) {
514
570
  const json = { direction };
515
- await request("PATCH", `/content/faq/update/${id}`, { ...MERCHANT3, json });
571
+ await request("PATCH", `/content/faq/update/${id}`, { ...MERCHANT4, json });
516
572
  },
517
573
  async remove(id) {
518
- await request("DELETE", `/content/faq/delete/${id}`, MERCHANT3);
574
+ await request("DELETE", `/content/faq/delete/${id}`, MERCHANT4);
519
575
  }
520
576
  };
521
577
  }
@@ -528,59 +584,6 @@ function toFaq(wire) {
528
584
  };
529
585
  }
530
586
 
531
- // src/http/forms.ts
532
- var PUBLIC5 = { anonymous: true, business: "required" };
533
- var SUBMIT = { business: "required" };
534
- var MERCHANT4 = { merchant: true, anonymous: true, business: "required" };
535
- function createFormsApi(request) {
536
- return {
537
- async get(slug) {
538
- return toPublicForm(
539
- await request("GET", `/forms/public/${path2(slug)}`, PUBLIC5)
540
- );
541
- },
542
- async submit(slug, values) {
543
- const json = { data: values };
544
- await request("POST", `/forms/submit/${path2(slug)}`, { ...SUBMIT, json });
545
- },
546
- async listForMerchant() {
547
- const rows = await request("GET", "/forms/list", {
548
- ...MERCHANT4,
549
- query: { is_active: true }
550
- });
551
- return rows.map(toFormSummary);
552
- }
553
- };
554
- }
555
- function path2(slug) {
556
- if (!slug.trim()) throw new Error("forms: slug is required.");
557
- return encodeURIComponent(slug.trim());
558
- }
559
- function toPublicForm(wire) {
560
- const fields = Array.isArray(wire.field_configuration) ? wire.field_configuration : [];
561
- return {
562
- id: wire.id,
563
- slug: wire.slug,
564
- name: wire.name,
565
- description: text(wire.description),
566
- successMessage: text(wire.success_message),
567
- fields: fields.map(toFormField)
568
- };
569
- }
570
- function toFormSummary(wire) {
571
- return { id: wire.id, name: wire.name, slug: wire.slug };
572
- }
573
- function toFormField(wire) {
574
- return {
575
- name: wire.name,
576
- // The backend only saves the ten known types (`validation.py:4-7`).
577
- type: wire.type,
578
- required: wire.required,
579
- label: text(wire.label) ?? wire.name.replace(/_/g, " "),
580
- options: wire.options?.map((o) => ({ label: o.label, value: o.value })) ?? []
581
- };
582
- }
583
-
584
587
  // src/http/helpdesk.ts
585
588
  var CREATE = { business: "required" };
586
589
  function createHelpdeskApi(request) {
@@ -1111,7 +1114,8 @@ function toProductDetail(wire) {
1111
1114
  availableForSubscription: wire.available_for_subscription ?? false,
1112
1115
  hasDigitalDelivery: wire.has_digital_delivery ?? false,
1113
1116
  fulfillmentMode: wire.fulfillment_mode ?? "none",
1114
- advanceAmount: amount(wire.advance_amount)
1117
+ advanceAmount: amount(wire.advance_amount),
1118
+ customFields: toFormFields(wire.custom_field_configuration)
1115
1119
  };
1116
1120
  }
1117
1121
  function toProductOverview(wire) {
@@ -2394,6 +2398,9 @@ function toOrderLine(wire) {
2394
2398
  taxPercent: amount(wire.tax),
2395
2399
  isDigital: wire.is_digital_product,
2396
2400
  customData: wire.custom_data,
2401
+ customFields: toFormFields(wire.custom_field_configuration),
2402
+ // At depth 2 the variants are rows, as in the cart: take each row's id.
2403
+ variantIds: (wire.sku?.selected_variants ?? []).map((variant) => variant.id),
2397
2404
  canReplace: wire.can_replace,
2398
2405
  canExchange: wire.can_exchange,
2399
2406
  maxReplaceOrExchangeQuantity: wire.max_qty_for_replace_or_exchange
@@ -2409,7 +2416,8 @@ function toOrderAddress(wire) {
2409
2416
  state: text(wire.state_name),
2410
2417
  postalCode: text(wire.postal_code),
2411
2418
  country: text(wire.country),
2412
- type: text(wire.type)
2419
+ type: text(wire.type),
2420
+ contactNo: text(wire.contact_no)
2413
2421
  };
2414
2422
  }
2415
2423
  function toOrderPaymentEntry(wire) {
@@ -2419,7 +2427,10 @@ function toOrderPaymentEntry(wire) {
2419
2427
  amount: amount(wire.amount) ?? 0,
2420
2428
  status: wire.status,
2421
2429
  method: wire.payment_method?.type ?? null,
2422
- label: wire.payment_method_label
2430
+ label: wire.payment_method_label,
2431
+ // Only an unpaid online entry can be resumed: COD is collected on delivery, cash and
2432
+ // transfers by the merchant, gift cards and reward points are spent when the order is placed.
2433
+ pendingPayment: wire.type === "pg" && wire.status === "unpaid" ? toPendingPayment(wire) : null
2423
2434
  };
2424
2435
  }
2425
2436
  function toOrderDetail(wire) {
@@ -2443,6 +2454,8 @@ function toOrderDetail(wire) {
2443
2454
  shippingAddress: wire.shipping_address ? toOrderAddress(wire.shipping_address) : null,
2444
2455
  billingAddress: wire.billing_address ? toOrderAddress(wire.billing_address) : null,
2445
2456
  payments: (wire.payment_history ?? []).map(toOrderPaymentEntry),
2457
+ paymentStatus: wire.payment?.status ?? null,
2458
+ promoCode: text(wire.promo?.code),
2446
2459
  hasExchangeOrReplacement: wire.has_exchange_or_replacement
2447
2460
  };
2448
2461
  }
@@ -2479,6 +2492,10 @@ function toShipment(wire) {
2479
2492
  trackingNumber: text(info.tracking_number),
2480
2493
  status: info.status,
2481
2494
  createdAt: info.created_at,
2495
+ trackingUrl: text(info.tracking_url),
2496
+ method: text(info.method),
2497
+ charge: amount(info.charge) ?? 0,
2498
+ courierPartner: text(info.courier_partner),
2482
2499
  items: wire.products.map((item) => ({
2483
2500
  orderLineId: item.order_product,
2484
2501
  name: item.product_name ?? "",
@@ -2537,7 +2554,22 @@ function toReturnableItem(wire) {
2537
2554
  photo: text(wire.product_photo),
2538
2555
  unitPrice: amount(wire.price) ?? 0,
2539
2556
  maxQuantity: wire.max_returnable_qty,
2540
- unitTrackingIds: wire.unit_tracking_infos.map((unit) => unit.id)
2557
+ unitTrackingIds: wire.unit_tracking_infos.map((unit) => unit.id),
2558
+ trackedUnits: wire.unit_tracking_infos.map(toTrackedUnit)
2559
+ };
2560
+ }
2561
+ function toTrackedUnit(wire) {
2562
+ const { data } = wire;
2563
+ const isRecord = typeof data === "object" && data !== null && !Array.isArray(data);
2564
+ return { id: wire.id, data: isRecord ? data : null };
2565
+ }
2566
+ function toRefund(wire) {
2567
+ return {
2568
+ id: wire.id,
2569
+ amount: amount(wire.amount) ?? 0,
2570
+ type: text(wire.type),
2571
+ status: wire.status,
2572
+ createdAt: wire.created_at
2541
2573
  };
2542
2574
  }
2543
2575
  function toReturnRequest(wire) {
@@ -2546,11 +2578,21 @@ function toReturnRequest(wire) {
2546
2578
  status: wire.status,
2547
2579
  createdAt: wire.created_at,
2548
2580
  amount: amount(wire.final_amount) ?? 0,
2581
+ amountInWords: text(wire.total_in_words),
2582
+ reason: text(wire.requested_message),
2583
+ declineMessage: text(wire.declined_message),
2584
+ creditNoteNumber: text(wire.cn_number),
2585
+ refunds: (wire.payment_refund_histories ?? []).map(toRefund),
2549
2586
  items: (wire.products ?? []).map((item) => ({
2550
2587
  id: item.id,
2551
2588
  name: item.product_name ?? "",
2589
+ photo: text(item.product_photo),
2590
+ unitPrice: amount(item.price) ?? 0,
2552
2591
  quantity: item.qty,
2553
- status: item.status
2592
+ status: item.status,
2593
+ reason: text(item.requested_message),
2594
+ declineMessage: text(item.declined_message),
2595
+ mediaUrl: text(item.request_media)
2554
2596
  }))
2555
2597
  };
2556
2598
  }
@@ -2648,19 +2690,30 @@ function toExchangeListItem(wire) {
2648
2690
  status: wire.status,
2649
2691
  createdAt: wire.created_at,
2650
2692
  paymentId: wire.payment_id,
2651
- itemCount: wire.products_count
2693
+ itemCount: wire.products_count,
2694
+ reason: text(wire.requested_message),
2695
+ declineMessage: text(wire.declined_message)
2652
2696
  };
2653
2697
  }
2654
2698
  function toExchangeDetail(wire) {
2655
2699
  return {
2656
2700
  ...toExchangeListItem({ ...wire, products_count: wire.products.length }),
2701
+ payments: (wire.payment_history ?? []).map(toOrderPaymentEntry),
2702
+ refunds: (wire.payment_refund_histories ?? []).map(toRefund),
2657
2703
  items: wire.products.map((row) => ({
2658
2704
  orderLineId: row.order_product,
2659
2705
  name: text(row.original_sku?.product_name),
2660
2706
  targetSkuId: row.target_sku,
2707
+ targetSkuName: text(row.target_sku_data?.product_name),
2708
+ targetSkuCode: text(row.target_sku_data?.sku),
2661
2709
  quantity: row.qty,
2710
+ unitPrice: amount(row.price) ?? 0,
2711
+ originalUnitPrice: amount(row.original_price) ?? 0,
2662
2712
  priceDifference: amount(row.price_difference) ?? 0,
2663
- status: row.status
2713
+ status: row.status,
2714
+ reason: text(row.requested_message),
2715
+ declineMessage: text(row.declined_message),
2716
+ mediaUrl: text(row.request_media)
2664
2717
  }))
2665
2718
  };
2666
2719
  }
@@ -2887,4 +2940,4 @@ export {
2887
2940
  GrowupsellApiError,
2888
2941
  createClient
2889
2942
  };
2890
- //# sourceMappingURL=chunk-BORVKACK.js.map
2943
+ //# sourceMappingURL=chunk-VB5IJELC.js.map