@misiki/gocommerce-connector 0.8.0 → 0.9.1

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.
@@ -1222,17 +1222,46 @@ var ProductService = class extends CatalogService {
1222
1222
  async listTrendingProducts({ page = 1, limit } = {}) {
1223
1223
  return this.shelf("trending", { page, limit });
1224
1224
  }
1225
- /** More from this product's category. */
1225
+ /**
1226
+ * More like this product. Given `product` (a slug or id), it is the
1227
+ * product's category first, then its collections, then the newest — never
1228
+ * the product itself. Many shops never fill in categories, and an empty
1229
+ * rail under every product page reads as a broken shop.
1230
+ *
1231
+ * Without `product`, it is the old answer: more from `categoryId`.
1232
+ */
1226
1233
  async listRelatedProducts({
1227
1234
  page = 1,
1228
1235
  categoryId,
1236
+ product,
1229
1237
  limit
1230
1238
  } = {}) {
1239
+ if (product) return this.relatedTo(String(product), limit);
1231
1240
  if (!categoryId) return this.list({ page, limit });
1232
1241
  const category = (await this.facts.categories()).find((c) => String(c.id) === String(categoryId));
1233
1242
  if (!category) return this.list({ page, limit });
1234
1243
  return this.list({ page, limit, categories: category.slug });
1235
1244
  }
1245
+ async relatedTo(slug, limit) {
1246
+ const size = Math.min(100, Math.max(1, Number(limit) || PAGE_SIZE));
1247
+ const p = await this.findProduct(slug);
1248
+ const self = String(p.id);
1249
+ const picked = /* @__PURE__ */ new Map();
1250
+ const add = (rows) => {
1251
+ for (const r of rows) {
1252
+ if (picked.size >= size) return;
1253
+ if (r.id !== self && !picked.has(r.id)) picked.set(r.id, r);
1254
+ }
1255
+ };
1256
+ if (p.category) add((await this.list({ limit: size + 1, categories: p.category.slug })).data);
1257
+ for (const c of p.collections ?? []) {
1258
+ if (picked.size >= size) break;
1259
+ add((await this.shelf(c.slug, { page: 1, limit: size + 1 })).data);
1260
+ }
1261
+ if (picked.size < size) add((await this.list({ limit: size + 1 })).data);
1262
+ const data = [...picked.values()];
1263
+ return { data, count: data.length, pageSize: size, noOfPage: 1, page: 1 };
1264
+ }
1236
1265
  async shelf(slug, { page, sort, limit }) {
1237
1266
  const size = Math.min(100, Math.max(1, Number(limit) || PAGE_SIZE));
1238
1267
  try {
@@ -2745,9 +2774,25 @@ var faqService = new FaqService();
2745
2774
  var MEDIA_KEYS = /* @__PURE__ */ new Set(["image", "mobile_image", "poster", "video_file"]);
2746
2775
  var LayoutService = class extends BaseService {
2747
2776
  async getHomeLayout({ preview } = {}) {
2777
+ return this.getPageLayout("home", { preview });
2778
+ }
2779
+ /**
2780
+ * The template every product page is drawn in: the sections around the
2781
+ * product's core (`main-product`). Null when none is published, so the
2782
+ * product page draws exactly as it did before templates existed.
2783
+ */
2784
+ async getProductLayout({ preview } = {}) {
2785
+ return this.getPageLayout("product", { preview });
2786
+ }
2787
+ /** The template every collection page is drawn in, around its grid (`main-collection`). */
2788
+ async getCollectionLayout({ preview } = {}) {
2789
+ return this.getPageLayout("collection", { preview });
2790
+ }
2791
+ /** Any arranged page by its key; null for none, as the three above. */
2792
+ async getPageLayout(page, { preview } = {}) {
2748
2793
  let layout;
2749
2794
  try {
2750
- layout = await this.data("/x/layouts/home", {
2795
+ layout = await this.data(`/x/layouts/${encodeURIComponent(page)}`, {
2751
2796
  query: { preview: preview?.trim() || void 0 }
2752
2797
  });
2753
2798
  } catch (err) {