@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.
package/dist/index.cjs CHANGED
@@ -377,7 +377,8 @@ var BaseService = class _BaseService {
377
377
  const lang = (req.method ?? "GET") === "GET" ? this.creds.language : void 0;
378
378
  const url = this.engineURL(path, lang ? { lang, ...req.query } : req.query);
379
379
  const headers = { Accept: "application/json", ...req.headers };
380
- if (req.body !== void 0) headers["Content-Type"] = "application/json";
380
+ const form = req.body instanceof FormData ? req.body : void 0;
381
+ if (req.body !== void 0 && !form) headers["Content-Type"] = "application/json";
381
382
  const store = this.store;
382
383
  if (store) headers["X-Store"] = store;
383
384
  if (req.auth) {
@@ -388,7 +389,7 @@ var BaseService = class _BaseService {
388
389
  const init = {
389
390
  method: req.method ?? "GET",
390
391
  headers,
391
- body: req.body === void 0 ? void 0 : JSON.stringify(req.body)
392
+ body: form ?? (req.body === void 0 ? void 0 : JSON.stringify(req.body))
392
393
  };
393
394
  let res;
394
395
  try {
@@ -844,6 +845,9 @@ function toCartLine(l, extra = {}) {
844
845
  /** The add-on this line was bought as (D133), or null on an ordinary line. */
845
846
  addOnId: l.add_on_id ? str(l.add_on_id) : null,
846
847
  addOnFor: l.add_on_for ? str(l.add_on_for) : null,
848
+ /** The shopper's own design this line is made to (D162) and its picture, or null on a line sold as it is. */
849
+ designId: l.design_id ?? null,
850
+ designPreview: mediaUrl(l.design_preview_url),
847
851
  subtotal: toMajor(l.total),
848
852
  total: toMajor(l.total),
849
853
  inStock: l.in_stock,
@@ -958,6 +962,8 @@ function toOrderLine(l, currency) {
958
962
  total: toMajor(l.total),
959
963
  currencyCode: currency,
960
964
  status: l.shipped_quantity >= l.quantity ? "Shipped" : "Pending",
965
+ designId: l.metadata?.design?.id ?? null,
966
+ designPreview: mediaUrl(l.metadata?.design?.preview_url),
961
967
  files: [],
962
968
  usedOptions: []
963
969
  };
@@ -1775,13 +1781,16 @@ var CartService = class extends BaseService {
1775
1781
  }
1776
1782
  /**
1777
1783
  * `qty` is a change, not a total: +1 from a product page, −1 from a card's
1778
- * minus button. With no cart yet, one is opened and remembered.
1784
+ * minus button. With no cart yet, one is opened and remembered. A
1785
+ * `designId` from `customizerService.saveDesign` makes the variant to the
1786
+ * shopper's design, on a line of its own.
1779
1787
  */
1780
1788
  async addToCart({
1781
1789
  cartId,
1782
1790
  lineId,
1783
1791
  qty = 1,
1784
- variantId
1792
+ variantId,
1793
+ designId
1785
1794
  }) {
1786
1795
  let id2 = clean(cartId) ?? storedCartId();
1787
1796
  if (lineId && id2) {
@@ -1795,21 +1804,16 @@ var CartService = class extends BaseService {
1795
1804
  if (qty === REMOVE || Number(qty) <= 0) return this.getCartByCartId(id2);
1796
1805
  if (!variantId) throw new GoCommerceError("Please choose an option before adding this to your bag.", 400);
1797
1806
  if (!id2) id2 = await this.open();
1807
+ const body = { variant_id: Number(variantId), quantity: Number(qty), ...designId ? { design_id: designId } : {} };
1798
1808
  try {
1799
1809
  return await this.present(
1800
- await this.data(`/api/carts/${encodeURIComponent(id2)}/line-items`, {
1801
- method: "POST",
1802
- body: { variant_id: Number(variantId), quantity: Number(qty) }
1803
- })
1810
+ await this.data(`/api/carts/${encodeURIComponent(id2)}/line-items`, { method: "POST", body })
1804
1811
  );
1805
1812
  } catch (err) {
1806
- if (err instanceof GoCommerceError && (err.status === 404 || /checked out/.test(err.message))) {
1813
+ if (err instanceof GoCommerceError && /cart not found|checked out/.test(err.message)) {
1807
1814
  const fresh = await this.open();
1808
1815
  return this.present(
1809
- await this.data(`/api/carts/${encodeURIComponent(fresh)}/line-items`, {
1810
- method: "POST",
1811
- body: { variant_id: Number(variantId), quantity: Number(qty) }
1812
- })
1816
+ await this.data(`/api/carts/${encodeURIComponent(fresh)}/line-items`, { method: "POST", body })
1813
1817
  );
1814
1818
  }
1815
1819
  throw err;
@@ -2046,6 +2050,54 @@ var CartService = class extends BaseService {
2046
2050
  var clean = (id2) => id2 && id2 !== "undefined" && id2 !== "null" ? id2 : null;
2047
2051
  var cartService = new CartService();
2048
2052
 
2053
+ // src/services/customizer-service.ts
2054
+ var CustomizerService = class extends BaseService {
2055
+ facts = new StoreFacts(this._fetch);
2056
+ /** Null when the product cannot be designed, or on any failure: the page draws without the editor. */
2057
+ async setup(productId) {
2058
+ const plugins = await this.facts.plugins().catch(() => null);
2059
+ if (plugins && !plugins.has("customizer")) return null;
2060
+ const path = `/x/customizer/products/${encodeURIComponent(String(productId))}`;
2061
+ const s = await this.data(path).catch(() => null);
2062
+ if (!s) return null;
2063
+ return {
2064
+ productId: String(s.product_id),
2065
+ mockup: { ...s.mockup, url: media(s.mockup.url) },
2066
+ overlayUrl: mediaUrl(s.overlay_url),
2067
+ printArea: s.print_area,
2068
+ printSize: { widthMm: s.print_size.width_mm, heightMm: s.print_size.height_mm, dpi: s.print_size.dpi },
2069
+ tools: s.tools,
2070
+ fonts: s.fonts,
2071
+ stickers: s.stickers.map((k) => ({ ...k, url: media(k.url) })),
2072
+ minPhotoPx: s.min_photo_px,
2073
+ consent: s.consent
2074
+ };
2075
+ }
2076
+ /** A photo, or the finished preview or print file. The engine's refusal is thrown with its message. */
2077
+ async upload(file, filename) {
2078
+ const body = new FormData();
2079
+ body.append("file", file, filename);
2080
+ const u = await this.data("/x/customizer/uploads", { method: "POST", body });
2081
+ return { uploadId: u.upload_id, url: media(u.url), width: u.width, height: u.height };
2082
+ }
2083
+ /** The document goes as it is: the order keeps it, and whatever renders the print reads it there. */
2084
+ async saveDesign(design) {
2085
+ const d = await this.data("/x/customizer/designs", {
2086
+ method: "POST",
2087
+ body: {
2088
+ product_id: Number(design.productId),
2089
+ variant_id: Number(design.variantId),
2090
+ preview_upload_id: design.previewUploadId,
2091
+ print_upload_id: design.printUploadId,
2092
+ document: design.document
2093
+ }
2094
+ });
2095
+ return { designId: d.design_id, previewUrl: media(d.preview_url) };
2096
+ }
2097
+ };
2098
+ var media = (url) => mediaUrl(url) ?? url;
2099
+ var customizerService = new CustomizerService();
2100
+
2049
2101
  // src/services/checkout-service.ts
2050
2102
  var CheckoutService = class extends BaseService {
2051
2103
  /** Delivery options for the address on the cart: `{ data: [{ id, name, base_rate }] }`. */
@@ -3716,6 +3768,50 @@ function withAmounts(v) {
3716
3768
  }
3717
3769
  var variantService = new VariantService();
3718
3770
 
3771
+ // src/services/whatsapp-service.ts
3772
+ var WhatsappService = class extends BaseService {
3773
+ /**
3774
+ * Whether to show the boxes. Never throws: an engine without the module, or
3775
+ * one that fails, answers both off, because checkout must not depend on it.
3776
+ */
3777
+ async consentOffer() {
3778
+ try {
3779
+ const d = await this.data("/x/notify-whatsapp/consent");
3780
+ const enabled = d?.enabled === true;
3781
+ return { enabled, marketing: enabled && d?.marketing === true };
3782
+ } catch {
3783
+ return { enabled: false, marketing: false };
3784
+ }
3785
+ }
3786
+ /**
3787
+ * Records both answers for the phone as typed, against the bag (with
3788
+ * `marketing`, the engine keeps the phone on it for basket reminders). Throws
3789
+ * the engine's 400 (`validation_failed`) when the phone is not a WhatsApp
3790
+ * number for the store's country.
3791
+ */
3792
+ async setConsent({
3793
+ cartId,
3794
+ phone,
3795
+ orderUpdates,
3796
+ marketing
3797
+ }) {
3798
+ const d = await this.data(
3799
+ "/x/notify-whatsapp/consent",
3800
+ {
3801
+ method: "PUT",
3802
+ body: {
3803
+ cart_id: cartId || storedCartId() || "",
3804
+ phone: String(phone ?? "").trim(),
3805
+ order_updates: orderUpdates === true,
3806
+ marketing: marketing === true
3807
+ }
3808
+ }
3809
+ );
3810
+ return { phone: d.phone, orderUpdates: d.order_updates, marketing: d.marketing };
3811
+ }
3812
+ };
3813
+ var whatsappService = new WhatsappService();
3814
+
3719
3815
  // src/services/b2b-service.ts
3720
3816
  var B2bService = class extends BaseService {
3721
3817
  // ------------------------------------------------------------ company
@@ -3998,6 +4094,7 @@ exports.ContactService = ContactService;
3998
4094
  exports.CountryService = CountryService;
3999
4095
  exports.CouponService = CouponService;
4000
4096
  exports.CurrencyService = CurrencyService;
4097
+ exports.CustomizerService = CustomizerService;
4001
4098
  exports.DealService = DealService;
4002
4099
  exports.DemoRequestService = DemoRequestService;
4003
4100
  exports.EnquiryService = EnquiryService;
@@ -4038,6 +4135,7 @@ exports.VarniCustomDesignService = VarniCustomDesignService;
4038
4135
  exports.VarniCustomProductService = VarniCustomProductService;
4039
4136
  exports.VendorService = VendorService;
4040
4137
  exports.WarrantyService = WarrantyService;
4138
+ exports.WhatsappService = WhatsappService;
4041
4139
  exports.WishlistService = WishlistService;
4042
4140
  exports.addressService = addressService;
4043
4141
  exports.authService = authService;
@@ -4057,6 +4155,7 @@ exports.countryService = countryService;
4057
4155
  exports.couponService = couponService;
4058
4156
  exports.currencyExponent = currencyExponent;
4059
4157
  exports.currencyService = currencyService;
4158
+ exports.customizerService = customizerService;
4060
4159
  exports.dealService = dealService;
4061
4160
  exports.demoRequestService = demoRequestService;
4062
4161
  exports.emptyCart = emptyCart;
@@ -4133,6 +4232,7 @@ exports.varniCustomDesignService = varniCustomDesignService;
4133
4232
  exports.varniCustomProductService = varniCustomProductService;
4134
4233
  exports.vendorService = vendorService;
4135
4234
  exports.warrantyService = warrantyService;
4235
+ exports.whatsappService = whatsappService;
4136
4236
  exports.wishlistService = wishlistService;
4137
4237
  //# sourceMappingURL=index.cjs.map
4138
4238
  //# sourceMappingURL=index.cjs.map