@misiki/gocommerce-connector 0.22.0 → 0.24.0

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.
@@ -304,7 +304,8 @@ var BaseService = class _BaseService {
304
304
  const lang = (req.method ?? "GET") === "GET" ? this.creds.language : void 0;
305
305
  const url = this.engineURL(path, lang ? { lang, ...req.query } : req.query);
306
306
  const headers = { Accept: "application/json", ...req.headers };
307
- if (req.body !== void 0) headers["Content-Type"] = "application/json";
307
+ const form = req.body instanceof FormData ? req.body : void 0;
308
+ if (req.body !== void 0 && !form) headers["Content-Type"] = "application/json";
308
309
  const store = this.store;
309
310
  if (store) headers["X-Store"] = store;
310
311
  if (req.auth) {
@@ -315,7 +316,7 @@ var BaseService = class _BaseService {
315
316
  const init = {
316
317
  method: req.method ?? "GET",
317
318
  headers,
318
- body: req.body === void 0 ? void 0 : JSON.stringify(req.body)
319
+ body: form ?? (req.body === void 0 ? void 0 : JSON.stringify(req.body))
319
320
  };
320
321
  let res;
321
322
  try {
@@ -812,6 +813,9 @@ function toCartLine(l, extra = {}) {
812
813
  /** The add-on this line was bought as (D133), or null on an ordinary line. */
813
814
  addOnId: l.add_on_id ? str(l.add_on_id) : null,
814
815
  addOnFor: l.add_on_for ? str(l.add_on_for) : null,
816
+ /** The shopper's own design this line is made to (D162) and its picture, or null on a line sold as it is. */
817
+ designId: l.design_id ?? null,
818
+ designPreview: mediaUrl(l.design_preview_url),
815
819
  subtotal: toMajor(l.total),
816
820
  total: toMajor(l.total),
817
821
  inStock: l.in_stock,
@@ -926,6 +930,8 @@ function toOrderLine(l, currency) {
926
930
  total: toMajor(l.total),
927
931
  currencyCode: currency,
928
932
  status: l.shipped_quantity >= l.quantity ? "Shipped" : "Pending",
933
+ designId: l.metadata?.design?.id ?? null,
934
+ designPreview: mediaUrl(l.metadata?.design?.preview_url),
929
935
  files: [],
930
936
  usedOptions: []
931
937
  };
@@ -1756,13 +1762,16 @@ var CartService = class extends BaseService {
1756
1762
  }
1757
1763
  /**
1758
1764
  * `qty` is a change, not a total: +1 from a product page, −1 from a card's
1759
- * minus button. With no cart yet, one is opened and remembered.
1765
+ * minus button. With no cart yet, one is opened and remembered. A
1766
+ * `designId` from `customizerService.saveDesign` makes the variant to the
1767
+ * shopper's design, on a line of its own.
1760
1768
  */
1761
1769
  async addToCart({
1762
1770
  cartId,
1763
1771
  lineId,
1764
1772
  qty = 1,
1765
- variantId
1773
+ variantId,
1774
+ designId
1766
1775
  }) {
1767
1776
  let id2 = clean(cartId) ?? storedCartId();
1768
1777
  if (lineId && id2) {
@@ -1776,21 +1785,16 @@ var CartService = class extends BaseService {
1776
1785
  if (qty === REMOVE || Number(qty) <= 0) return this.getCartByCartId(id2);
1777
1786
  if (!variantId) throw new GoCommerceError("Please choose an option before adding this to your bag.", 400);
1778
1787
  if (!id2) id2 = await this.open();
1788
+ const body = { variant_id: Number(variantId), quantity: Number(qty), ...designId ? { design_id: designId } : {} };
1779
1789
  try {
1780
1790
  return await this.present(
1781
- await this.data(`/api/carts/${encodeURIComponent(id2)}/line-items`, {
1782
- method: "POST",
1783
- body: { variant_id: Number(variantId), quantity: Number(qty) }
1784
- })
1791
+ await this.data(`/api/carts/${encodeURIComponent(id2)}/line-items`, { method: "POST", body })
1785
1792
  );
1786
1793
  } catch (err) {
1787
- if (err instanceof GoCommerceError && (err.status === 404 || /checked out/.test(err.message))) {
1794
+ if (err instanceof GoCommerceError && /cart not found|checked out/.test(err.message)) {
1788
1795
  const fresh = await this.open();
1789
1796
  return this.present(
1790
- await this.data(`/api/carts/${encodeURIComponent(fresh)}/line-items`, {
1791
- method: "POST",
1792
- body: { variant_id: Number(variantId), quantity: Number(qty) }
1793
- })
1797
+ await this.data(`/api/carts/${encodeURIComponent(fresh)}/line-items`, { method: "POST", body })
1794
1798
  );
1795
1799
  }
1796
1800
  throw err;
@@ -2027,6 +2031,54 @@ var CartService = class extends BaseService {
2027
2031
  var clean = (id2) => id2 && id2 !== "undefined" && id2 !== "null" ? id2 : null;
2028
2032
  var cartService = new CartService();
2029
2033
 
2034
+ // src/services/customizer-service.ts
2035
+ var CustomizerService = class extends BaseService {
2036
+ facts = new StoreFacts(this._fetch);
2037
+ /** Null when the product cannot be designed, or on any failure: the page draws without the editor. */
2038
+ async setup(productId) {
2039
+ const plugins = await this.facts.plugins().catch(() => null);
2040
+ if (plugins && !plugins.has("customizer")) return null;
2041
+ const path = `/x/customizer/products/${encodeURIComponent(String(productId))}`;
2042
+ const s = await this.data(path).catch(() => null);
2043
+ if (!s) return null;
2044
+ return {
2045
+ productId: String(s.product_id),
2046
+ mockup: { ...s.mockup, url: media(s.mockup.url) },
2047
+ overlayUrl: mediaUrl(s.overlay_url),
2048
+ printArea: s.print_area,
2049
+ printSize: { widthMm: s.print_size.width_mm, heightMm: s.print_size.height_mm, dpi: s.print_size.dpi },
2050
+ tools: s.tools,
2051
+ fonts: s.fonts,
2052
+ stickers: s.stickers.map((k) => ({ ...k, url: media(k.url) })),
2053
+ minPhotoPx: s.min_photo_px,
2054
+ consent: s.consent
2055
+ };
2056
+ }
2057
+ /** A photo, or the finished preview or print file. The engine's refusal is thrown with its message. */
2058
+ async upload(file, filename) {
2059
+ const body = new FormData();
2060
+ body.append("file", file, filename);
2061
+ const u = await this.data("/x/customizer/uploads", { method: "POST", body });
2062
+ return { uploadId: u.upload_id, url: media(u.url), width: u.width, height: u.height };
2063
+ }
2064
+ /** The document goes as it is: the order keeps it, and whatever renders the print reads it there. */
2065
+ async saveDesign(design) {
2066
+ const d = await this.data("/x/customizer/designs", {
2067
+ method: "POST",
2068
+ body: {
2069
+ product_id: Number(design.productId),
2070
+ variant_id: Number(design.variantId),
2071
+ preview_upload_id: design.previewUploadId,
2072
+ print_upload_id: design.printUploadId,
2073
+ document: design.document
2074
+ }
2075
+ });
2076
+ return { designId: d.design_id, previewUrl: media(d.preview_url) };
2077
+ }
2078
+ };
2079
+ var media = (url) => mediaUrl(url) ?? url;
2080
+ var customizerService = new CustomizerService();
2081
+
2030
2082
  // src/services/checkout-service.ts
2031
2083
  var CheckoutService = class extends BaseService {
2032
2084
  /** Delivery options for the address on the cart: `{ data: [{ id, name, base_rate }] }`. */
@@ -3700,6 +3752,50 @@ function withAmounts(v) {
3700
3752
  }
3701
3753
  var variantService = new VariantService();
3702
3754
 
3755
+ // src/services/whatsapp-service.ts
3756
+ var WhatsappService = class extends BaseService {
3757
+ /**
3758
+ * Whether to show the boxes. Never throws: an engine without the module, or
3759
+ * one that fails, answers both off, because checkout must not depend on it.
3760
+ */
3761
+ async consentOffer() {
3762
+ try {
3763
+ const d = await this.data("/x/notify-whatsapp/consent");
3764
+ const enabled = d?.enabled === true;
3765
+ return { enabled, marketing: enabled && d?.marketing === true };
3766
+ } catch {
3767
+ return { enabled: false, marketing: false };
3768
+ }
3769
+ }
3770
+ /**
3771
+ * Records both answers for the phone as typed, against the bag (with
3772
+ * `marketing`, the engine keeps the phone on it for basket reminders). Throws
3773
+ * the engine's 400 (`validation_failed`) when the phone is not a WhatsApp
3774
+ * number for the store's country.
3775
+ */
3776
+ async setConsent({
3777
+ cartId,
3778
+ phone,
3779
+ orderUpdates,
3780
+ marketing
3781
+ }) {
3782
+ const d = await this.data(
3783
+ "/x/notify-whatsapp/consent",
3784
+ {
3785
+ method: "PUT",
3786
+ body: {
3787
+ cart_id: cartId || storedCartId() || "",
3788
+ phone: String(phone ?? "").trim(),
3789
+ order_updates: orderUpdates === true,
3790
+ marketing: marketing === true
3791
+ }
3792
+ }
3793
+ );
3794
+ return { phone: d.phone, orderUpdates: d.order_updates, marketing: d.marketing };
3795
+ }
3796
+ };
3797
+ var whatsappService = new WhatsappService();
3798
+
3703
3799
  // src/services/b2b-service.ts
3704
3800
  var B2bService = class extends BaseService {
3705
3801
  // ------------------------------------------------------------ company
@@ -3982,6 +4078,7 @@ exports.ContactService = ContactService;
3982
4078
  exports.CountryService = CountryService;
3983
4079
  exports.CouponService = CouponService;
3984
4080
  exports.CurrencyService = CurrencyService;
4081
+ exports.CustomizerService = CustomizerService;
3985
4082
  exports.DealService = DealService;
3986
4083
  exports.DemoRequestService = DemoRequestService;
3987
4084
  exports.EnquiryService = EnquiryService;
@@ -4020,6 +4117,7 @@ exports.VarniCustomDesignService = VarniCustomDesignService;
4020
4117
  exports.VarniCustomProductService = VarniCustomProductService;
4021
4118
  exports.VendorService = VendorService;
4022
4119
  exports.WarrantyService = WarrantyService;
4120
+ exports.WhatsappService = WhatsappService;
4023
4121
  exports.WishlistService = WishlistService;
4024
4122
  exports.addressService = addressService;
4025
4123
  exports.authService = authService;
@@ -4036,6 +4134,7 @@ exports.contactService = contactService;
4036
4134
  exports.countryService = countryService;
4037
4135
  exports.couponService = couponService;
4038
4136
  exports.currencyService = currencyService;
4137
+ exports.customizerService = customizerService;
4039
4138
  exports.dealService = dealService;
4040
4139
  exports.demoRequestService = demoRequestService;
4041
4140
  exports.emptyPage = emptyPage;
@@ -4082,6 +4181,7 @@ exports.varniCustomDesignService = varniCustomDesignService;
4082
4181
  exports.varniCustomProductService = varniCustomProductService;
4083
4182
  exports.vendorService = vendorService;
4084
4183
  exports.warrantyService = warrantyService;
4184
+ exports.whatsappService = whatsappService;
4085
4185
  exports.wishlistService = wishlistService;
4086
4186
  //# sourceMappingURL=index.cjs.map
4087
4187
  //# sourceMappingURL=index.cjs.map