@misiki/gocommerce-connector 0.23.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 }] }`. */
@@ -4026,6 +4078,7 @@ exports.ContactService = ContactService;
4026
4078
  exports.CountryService = CountryService;
4027
4079
  exports.CouponService = CouponService;
4028
4080
  exports.CurrencyService = CurrencyService;
4081
+ exports.CustomizerService = CustomizerService;
4029
4082
  exports.DealService = DealService;
4030
4083
  exports.DemoRequestService = DemoRequestService;
4031
4084
  exports.EnquiryService = EnquiryService;
@@ -4081,6 +4134,7 @@ exports.contactService = contactService;
4081
4134
  exports.countryService = countryService;
4082
4135
  exports.couponService = couponService;
4083
4136
  exports.currencyService = currencyService;
4137
+ exports.customizerService = customizerService;
4084
4138
  exports.dealService = dealService;
4085
4139
  exports.demoRequestService = demoRequestService;
4086
4140
  exports.emptyPage = emptyPage;