@misiki/gocommerce-connector 0.12.0 → 0.14.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.
@@ -1 +1 @@
1
- export { b as AddressService, d as Approval, f as AuthService, g as AutocompleteService, B as B2bPlaced, h as B2bRole, i as B2bService, j as BannerService, k as BaseService, l as BlogService, o as CartService, p as CatalogService, r as CategoryService, s as ChatService, v as CheckoutService, y as CollectionService, z as Company, D as CompanyOrder, E as ContactService, F as CountryService, G as CouponService, I as Credit, J as CurrencyService, L as DealService, M as DemoRequestService, N as EngineRequest, O as EnquiryService, S as FaqService, T as FeedbackService, U as FooterSettings, X as GalleryService, Y as HeaderSettings, Z as HomeLayout, _ as HomeLayoutSection, $ as HomeService, a1 as InitService, a2 as Invitation, a3 as LayoutCollection, a4 as LayoutPage, a5 as LayoutService, a6 as Lead, a8 as MeilisearchService, a9 as Member, ac as MenuService, af as NewsletterService, aj as OrderService, ak as PageLayout, al as PageService, an as PaymentMethodService, ap as PluginService, ap as PluginsService, aq as PopularSearchService, ar as PopularityService, av as ProductService, aw as ProfileService, ax as Quote, ay as REDIRECT_GATEWAYS, az as ReelsService, aA as RegionService, aB as RejectedLine, aE as ReviewService, aH as SearchService, aI as SettingService, aI as SettingsService, aK as SiteChrome, aL as SiteFooter, aM as SiteHeader, aN as SocialLink, aO as StateService, aQ as StoreService, aS as StorefrontMenu, aV as ThemeSettings, aW as ThemeSettingsResult, aX as UploadService, aY as UserService, a$ as VariantService, b0 as VarniCustomDesignService, b1 as VarniCustomProductService, b3 as VendorService, b4 as WarrantyService, b7 as WishlistService, b8 as addressService, b9 as authService, ba as autocompleteService, bb as b2bService, bc as bannerService, bd as blogService, be as cartService, bf as categoryService, bg as chatService, bh as checkoutService, bi as collectionService, bj as contactService, bk as countryService, bl as couponService, bn as currencyService, bo as dealService, bp as demoRequestService, br as emptyPage, bs as enquiryService, bt as faqService, bu as feedbackService, by as galleryService, bz as homeService, bA as initService, bB as layoutService, bC as mediaUrl, bD as meilisearchService, bE as menuService, bG as newsletterService, bH as orderService, bI as ownDomain, bJ as pageService, bK as paymentMethodService, bL as pluginService, bM as pluginsService, bN as popularSearchService, bO as popularityService, bR as productService, bS as profileService, bT as qs, bU as reelsService, bV as regionService, bW as reviewService, bX as searchService, bY as setRequestHost, bZ as settingService, b_ as settingsService, b$ as stateService, c0 as staticStore, c1 as storeForHost, c2 as storeService, cg as toPage, cj as toStorefrontFacets, cn as uploadService, co as userService, cp as variantService, cq as varniCustomDesignService, cr as varniCustomProductService, cs as vendorService, ct as warrantyService, cu as wishlistService } from '../index-Bu4bVBBm.cjs';
1
+ export { b as AddressService, d as Approval, f as AuthService, g as AutocompleteService, B as B2bPlaced, h as B2bRole, i as B2bService, j as BannerService, k as BaseService, l as BlogService, o as CartService, p as CatalogService, r as CategoryService, s as ChatService, v as CheckoutService, y as CollectionService, z as Company, D as CompanyOrder, E as ContactService, F as CountryService, G as CouponService, I as Credit, J as CurrencyService, L as DealService, M as DemoRequestService, N as EngineRequest, O as EnquiryService, S as FaqService, T as FeedbackService, U as FooterSettings, X as GalleryService, Y as HeaderSettings, Z as HomeLayout, _ as HomeLayoutSection, $ as HomeService, a1 as InitService, a2 as Invitation, a3 as LayoutCollection, a4 as LayoutPage, a5 as LayoutService, a6 as Lead, a8 as MeilisearchService, a9 as Member, ac as MenuService, af as NewsletterService, aj as OrderService, ak as PageLayout, al as PageService, an as PaymentMethodService, ap as PluginService, ap as PluginsService, aq as PopularSearchService, ar as PopularityService, aw as ProductService, ax as ProfileService, ay as Quote, az as REDIRECT_GATEWAYS, aA as ReelsService, aB as RegionService, aC as RejectedLine, aF as ReviewService, aI as SearchService, aJ as SettingService, aJ as SettingsService, aL as SiteChrome, aM as SiteFooter, aN as SiteHeader, aO as SocialLink, aP as StateService, aR as StoreService, aT as StorefrontMenu, aW as ThemeSettings, aX as ThemeSettingsResult, aY as UploadService, aZ as UserService, b0 as VariantService, b1 as VarniCustomDesignService, b2 as VarniCustomProductService, b4 as VendorService, b5 as WarrantyService, b8 as WishlistService, b9 as addressService, ba as authService, bb as autocompleteService, bc as b2bService, bd as bannerService, be as blogService, bf as cartService, bg as categoryService, bh as chatService, bi as checkoutService, bj as collectionService, bk as contactService, bl as countryService, bm as couponService, bo as currencyService, bp as dealService, bq as demoRequestService, bs as emptyPage, bt as enquiryService, bu as faqService, bv as feedbackService, bz as galleryService, bA as homeService, bB as initService, bC as layoutService, bD as mediaUrl, bE as meilisearchService, bF as menuService, bH as newsletterService, bI as orderService, bJ as ownDomain, bK as pageService, bL as paymentMethodService, bM as pluginService, bN as pluginsService, bO as popularSearchService, bP as popularityService, bS as productService, bU as profileService, bV as qs, bW as reelsService, bX as regionService, bY as reviewService, bZ as searchService, b_ as setRequestHost, b$ as settingService, c0 as settingsService, c1 as stateService, c2 as staticStore, c3 as storeForHost, c4 as storeService, ci as toPage, cl as toStorefrontFacets, cp as uploadService, cq as userService, cr as variantService, cs as varniCustomDesignService, ct as varniCustomProductService, cu as vendorService, cv as warrantyService, cw as wishlistService } from '../index-C0CR05Q4.cjs';
@@ -1 +1 @@
1
- export { b as AddressService, d as Approval, f as AuthService, g as AutocompleteService, B as B2bPlaced, h as B2bRole, i as B2bService, j as BannerService, k as BaseService, l as BlogService, o as CartService, p as CatalogService, r as CategoryService, s as ChatService, v as CheckoutService, y as CollectionService, z as Company, D as CompanyOrder, E as ContactService, F as CountryService, G as CouponService, I as Credit, J as CurrencyService, L as DealService, M as DemoRequestService, N as EngineRequest, O as EnquiryService, S as FaqService, T as FeedbackService, U as FooterSettings, X as GalleryService, Y as HeaderSettings, Z as HomeLayout, _ as HomeLayoutSection, $ as HomeService, a1 as InitService, a2 as Invitation, a3 as LayoutCollection, a4 as LayoutPage, a5 as LayoutService, a6 as Lead, a8 as MeilisearchService, a9 as Member, ac as MenuService, af as NewsletterService, aj as OrderService, ak as PageLayout, al as PageService, an as PaymentMethodService, ap as PluginService, ap as PluginsService, aq as PopularSearchService, ar as PopularityService, av as ProductService, aw as ProfileService, ax as Quote, ay as REDIRECT_GATEWAYS, az as ReelsService, aA as RegionService, aB as RejectedLine, aE as ReviewService, aH as SearchService, aI as SettingService, aI as SettingsService, aK as SiteChrome, aL as SiteFooter, aM as SiteHeader, aN as SocialLink, aO as StateService, aQ as StoreService, aS as StorefrontMenu, aV as ThemeSettings, aW as ThemeSettingsResult, aX as UploadService, aY as UserService, a$ as VariantService, b0 as VarniCustomDesignService, b1 as VarniCustomProductService, b3 as VendorService, b4 as WarrantyService, b7 as WishlistService, b8 as addressService, b9 as authService, ba as autocompleteService, bb as b2bService, bc as bannerService, bd as blogService, be as cartService, bf as categoryService, bg as chatService, bh as checkoutService, bi as collectionService, bj as contactService, bk as countryService, bl as couponService, bn as currencyService, bo as dealService, bp as demoRequestService, br as emptyPage, bs as enquiryService, bt as faqService, bu as feedbackService, by as galleryService, bz as homeService, bA as initService, bB as layoutService, bC as mediaUrl, bD as meilisearchService, bE as menuService, bG as newsletterService, bH as orderService, bI as ownDomain, bJ as pageService, bK as paymentMethodService, bL as pluginService, bM as pluginsService, bN as popularSearchService, bO as popularityService, bR as productService, bS as profileService, bT as qs, bU as reelsService, bV as regionService, bW as reviewService, bX as searchService, bY as setRequestHost, bZ as settingService, b_ as settingsService, b$ as stateService, c0 as staticStore, c1 as storeForHost, c2 as storeService, cg as toPage, cj as toStorefrontFacets, cn as uploadService, co as userService, cp as variantService, cq as varniCustomDesignService, cr as varniCustomProductService, cs as vendorService, ct as warrantyService, cu as wishlistService } from '../index-Bu4bVBBm.js';
1
+ export { b as AddressService, d as Approval, f as AuthService, g as AutocompleteService, B as B2bPlaced, h as B2bRole, i as B2bService, j as BannerService, k as BaseService, l as BlogService, o as CartService, p as CatalogService, r as CategoryService, s as ChatService, v as CheckoutService, y as CollectionService, z as Company, D as CompanyOrder, E as ContactService, F as CountryService, G as CouponService, I as Credit, J as CurrencyService, L as DealService, M as DemoRequestService, N as EngineRequest, O as EnquiryService, S as FaqService, T as FeedbackService, U as FooterSettings, X as GalleryService, Y as HeaderSettings, Z as HomeLayout, _ as HomeLayoutSection, $ as HomeService, a1 as InitService, a2 as Invitation, a3 as LayoutCollection, a4 as LayoutPage, a5 as LayoutService, a6 as Lead, a8 as MeilisearchService, a9 as Member, ac as MenuService, af as NewsletterService, aj as OrderService, ak as PageLayout, al as PageService, an as PaymentMethodService, ap as PluginService, ap as PluginsService, aq as PopularSearchService, ar as PopularityService, aw as ProductService, ax as ProfileService, ay as Quote, az as REDIRECT_GATEWAYS, aA as ReelsService, aB as RegionService, aC as RejectedLine, aF as ReviewService, aI as SearchService, aJ as SettingService, aJ as SettingsService, aL as SiteChrome, aM as SiteFooter, aN as SiteHeader, aO as SocialLink, aP as StateService, aR as StoreService, aT as StorefrontMenu, aW as ThemeSettings, aX as ThemeSettingsResult, aY as UploadService, aZ as UserService, b0 as VariantService, b1 as VarniCustomDesignService, b2 as VarniCustomProductService, b4 as VendorService, b5 as WarrantyService, b8 as WishlistService, b9 as addressService, ba as authService, bb as autocompleteService, bc as b2bService, bd as bannerService, be as blogService, bf as cartService, bg as categoryService, bh as chatService, bi as checkoutService, bj as collectionService, bk as contactService, bl as countryService, bm as couponService, bo as currencyService, bp as dealService, bq as demoRequestService, bs as emptyPage, bt as enquiryService, bu as faqService, bv as feedbackService, bz as galleryService, bA as homeService, bB as initService, bC as layoutService, bD as mediaUrl, bE as meilisearchService, bF as menuService, bH as newsletterService, bI as orderService, bJ as ownDomain, bK as pageService, bL as paymentMethodService, bM as pluginService, bN as pluginsService, bO as popularSearchService, bP as popularityService, bS as productService, bU as profileService, bV as qs, bW as reelsService, bX as regionService, bY as reviewService, bZ as searchService, b_ as setRequestHost, b$ as settingService, c0 as settingsService, c1 as stateService, c2 as staticStore, c3 as storeForHost, c4 as storeService, ci as toPage, cl as toStorefrontFacets, cp as uploadService, cq as userService, cr as variantService, cs as varniCustomDesignService, ct as varniCustomProductService, cu as vendorService, cv as warrantyService, cw as wishlistService } from '../index-C0CR05Q4.js';
@@ -464,9 +464,27 @@ function productImages(p) {
464
464
  if (url && !out.includes(url)) out.push(url);
465
465
  };
466
466
  push(mediaUrl(p.image_url));
467
+ for (const m of arr(p.media)) if (m.kind === "image") push(mediaUrl(m.url));
467
468
  for (const v of arr(p.variants)) for (const url of variantImages(v)) push(url);
468
469
  return out;
469
470
  }
471
+ function productVideos(p) {
472
+ const out = [];
473
+ for (const m of arr(p.media)) {
474
+ const url = m.kind === "video" ? mediaUrl(m.url) : null;
475
+ if (url && !out.includes(url)) out.push(url);
476
+ }
477
+ return out;
478
+ }
479
+ function highlightsOf(p) {
480
+ const raw = p.metadata?.highlights;
481
+ if (!Array.isArray(raw)) return [];
482
+ return raw.filter((s) => typeof s === "string").map((s) => s.trim()).filter(Boolean);
483
+ }
484
+ function freeGiftOf(p) {
485
+ const raw = p.metadata?.free_gift;
486
+ return typeof raw === "string" && raw.trim() ? raw.trim() : null;
487
+ }
470
488
  function toVariant(v, p, optionless) {
471
489
  const images = variantImages(v);
472
490
  const options = arr(p.options);
@@ -514,6 +532,7 @@ function toProduct(p, extra = {}) {
514
532
  const lead = live[0] ?? arr(p.variants)[0];
515
533
  const optionless = arr(p.options).length === 0;
516
534
  const images = productImages(p);
535
+ const videos = productVideos(p);
517
536
  const prices = live.map((v) => toMajor(v.price));
518
537
  const tracked = live.filter((v) => v.track_inventory);
519
538
  const category = p.category;
@@ -540,8 +559,14 @@ function toProduct(p, extra = {}) {
540
559
  originCountry: lead?.origin_country ?? null,
541
560
  thumbnail: images[0] ?? null,
542
561
  image_url: images[0] ?? null,
543
- images: images.join(","),
562
+ images: [...images, ...videos].join(","),
544
563
  imageList: images,
564
+ videos,
565
+ // What the buy box says beside the price (D134): plain text, drawn as text.
566
+ highlights: highlightsOf(p),
567
+ freeGift: freeGiftOf(p),
568
+ // Counted by the engine, rounded down, and absent rather than zero.
569
+ soldAtLeast: typeof p.sold_at_least === "number" && p.sold_at_least > 0 ? p.sold_at_least : null,
545
570
  // Product-level stock is what a card shows before a variant is picked:
546
571
  // buyable when any live variant is, counted only where counting means
547
572
  // something.
@@ -714,7 +739,9 @@ function toIdentityAddress(a) {
714
739
  state: e.state ?? "",
715
740
  postal_code: e.postal_code,
716
741
  country: e.country,
717
- ...a.label ? { label: String(a.label) } : {},
742
+ // Sent whenever the form has it, empty included: the engine keeps a label it is not sent, so
743
+ // leaving out an emptied one would keep the old Home or Work (D134).
744
+ ...typeof a.label === "string" ? { label: a.label } : {},
718
745
  ...a.isPrimary ? { is_default: true } : {}
719
746
  };
720
747
  }
@@ -1168,14 +1195,17 @@ var CatalogService = class extends BaseService {
1168
1195
  const attr = Object.entries(q.attributes ?? {}).flatMap(
1169
1196
  ([handle, values]) => values.filter(Boolean).map((v) => `${handle}:${v}`)
1170
1197
  );
1171
- if (q.facets && !legacyListing.has(this.engineBase())) {
1198
+ const refined = attr.length > 0 || !!(q.tags?.length || q.vendors?.length || q.productTypes?.length);
1199
+ const triedIndex = !!search && !refined;
1200
+ const counted = q.facets && !legacyListing.has(this.engineBase());
1201
+ const facetListing = async (page2, limit2) => {
1172
1202
  const { currency } = await this.facts.ready();
1173
1203
  const minor = (n) => Number.isFinite(n) ? Math.max(0, toMinor(n, currency)) : void 0;
1174
- const env2 = await this.engine("/api/products", {
1204
+ return this.engine("/api/products", {
1175
1205
  query: {
1176
1206
  q: search,
1177
- page,
1178
- limit,
1207
+ page: page2,
1208
+ limit: limit2,
1179
1209
  channel: this.creds.channel,
1180
1210
  category: q.category,
1181
1211
  tag: q.tags,
@@ -1188,6 +1218,16 @@ var CatalogService = class extends BaseService {
1188
1218
  facets: 1
1189
1219
  }
1190
1220
  });
1221
+ };
1222
+ if (triedIndex && await this.facts.pluginOn("meilisearch")) {
1223
+ const [found, rail] = await Promise.all([
1224
+ this.fromIndex(q, { page, limit, search, sortKey, wantsRange, hierarchy }),
1225
+ counted ? facetListing(1, 1).catch(() => null) : null
1226
+ ]);
1227
+ if (found) return rail?.meta?.facets ? { ...found, facets: rail.meta.facets } : found;
1228
+ }
1229
+ if (counted) {
1230
+ const env2 = await facetListing(page, limit);
1191
1231
  if (env2.meta?.facets) {
1192
1232
  return {
1193
1233
  ...toPage(env2, (p) => toProduct(p)),
@@ -1198,39 +1238,9 @@ var CatalogService = class extends BaseService {
1198
1238
  }
1199
1239
  legacyListing.add(this.engineBase());
1200
1240
  }
1201
- if ((sortKey || wantsRange) && await this.facts.pluginOn("meilisearch")) {
1202
- const filters = [];
1203
- if (q.category) {
1204
- const names = (await this.facts.subtree(q.category).catch(() => [])).map(
1205
- (c) => quote(c.full_name)
1206
- );
1207
- if (!names.length) return { ...emptyCatalog(limit), categoryHierarchy: hierarchy, sorted: true };
1208
- filters.push(`category IN [${names.join(", ")}]`);
1209
- }
1210
- if (wantsRange) {
1211
- const { currency } = await this.facts.ready();
1212
- if (Number.isFinite(q.priceFrom)) filters.push(`price_minor >= ${toMinor(q.priceFrom, currency)}`);
1213
- if (Number.isFinite(q.priceTo)) filters.push(`price_minor <= ${toMinor(q.priceTo, currency)}`);
1214
- }
1215
- const res = await this.data("/x/meilisearch/search", {
1216
- query: {
1217
- q: search ?? "",
1218
- limit,
1219
- offset: (page - 1) * limit,
1220
- filter: filters.join(" AND ") || void 0,
1221
- sort: sortKey
1222
- }
1223
- });
1224
- const total = res.total ?? 0;
1225
- return {
1226
- data: (res.hits ?? []).map(fromSearchDoc),
1227
- count: total,
1228
- pageSize: limit,
1229
- noOfPage: Math.max(1, Math.ceil(total / limit)),
1230
- page,
1231
- categoryHierarchy: hierarchy,
1232
- sorted: true
1233
- };
1241
+ if (!triedIndex && (sortKey || wantsRange)) {
1242
+ const found = await this.fromIndex(q, { page, limit, search, sortKey, wantsRange, hierarchy });
1243
+ if (found) return found;
1234
1244
  }
1235
1245
  const sorted = !sortKey && !wantsRange;
1236
1246
  if (q.category && !search) {
@@ -1250,6 +1260,45 @@ var CatalogService = class extends BaseService {
1250
1260
  });
1251
1261
  return { ...toPage(env, (p) => toProduct(p)), categoryHierarchy: hierarchy, sorted };
1252
1262
  }
1263
+ /**
1264
+ * The shelf from the Meilisearch module, or null when the store has it off,
1265
+ * sells through a channel, finds nothing for the words, or it cannot answer (Meilisearch down: the engine says `unavailable`), so
1266
+ * the caller asks the database instead of showing the shopper an error.
1267
+ */
1268
+ async fromIndex(q, o) {
1269
+ if (this.creds.channel || !await this.facts.pluginOn("meilisearch")) return null;
1270
+ const filters = [];
1271
+ if (q.category) {
1272
+ const names = (await this.facts.subtree(q.category).catch(() => [])).map((c) => quote(c.full_name));
1273
+ if (!names.length) return { ...emptyCatalog(o.limit), categoryHierarchy: o.hierarchy, sorted: true };
1274
+ filters.push(`category IN [${names.join(", ")}]`);
1275
+ }
1276
+ if (o.wantsRange) {
1277
+ const { currency } = await this.facts.ready();
1278
+ if (Number.isFinite(q.priceFrom)) filters.push(`price_minor >= ${toMinor(q.priceFrom, currency)}`);
1279
+ if (Number.isFinite(q.priceTo)) filters.push(`price_minor <= ${toMinor(q.priceTo, currency)}`);
1280
+ }
1281
+ const res = await this.data("/x/meilisearch/search", {
1282
+ query: {
1283
+ q: o.search ?? "",
1284
+ limit: o.limit,
1285
+ offset: (o.page - 1) * o.limit,
1286
+ filter: filters.join(" AND ") || void 0,
1287
+ sort: o.sortKey
1288
+ }
1289
+ }).catch(() => null);
1290
+ if (!res || res.unavailable || o.search && !res.hits?.length) return null;
1291
+ const total = res.total ?? 0;
1292
+ return {
1293
+ data: (res.hits ?? []).map(fromSearchDoc),
1294
+ count: total,
1295
+ pageSize: o.limit,
1296
+ noOfPage: Math.max(1, Math.ceil(total / o.limit)),
1297
+ page: o.page,
1298
+ categoryHierarchy: o.hierarchy,
1299
+ sorted: true
1300
+ };
1301
+ }
1253
1302
  };
1254
1303
  function emptyCatalog(limit = PAGE_SIZE) {
1255
1304
  return { data: [], count: 0, pageSize: limit, noOfPage: 0, page: 1 };
@@ -1547,10 +1596,8 @@ var MeilisearchService = class extends CatalogService {
1547
1596
  async searchAutoComplete({ query, search, limit = 8 } = {}) {
1548
1597
  const q = (query ?? search ?? "").trim();
1549
1598
  if (!q) return { data: [] };
1550
- if (await this.facts.pluginOn("meilisearch")) {
1551
- const res = await this.data("/x/meilisearch/search", { query: { q, limit } });
1552
- return { data: (res.hits ?? []).map(fromSearchDoc) };
1553
- }
1599
+ const found = await this.fromIndex({}, { page: 1, limit, search: q, wantsRange: false, hierarchy: [] });
1600
+ if (found) return { data: found.data };
1554
1601
  const rows = await this.data("/api/products", { query: { q, limit, channel: this.creds.channel } }) ?? [];
1555
1602
  return { data: rows.map((p) => toProduct(p)) };
1556
1603
  }
@@ -2667,6 +2714,24 @@ var AddressService = class extends BaseService {
2667
2714
  });
2668
2715
  return fromIdentityAddress(a, currentMe()?.email);
2669
2716
  }
2717
+ /**
2718
+ * The city and state for a postcode (D134), for the address form to fill
2719
+ * in. India's six-digit PIN codes only, from the directory the engine was
2720
+ * given; null for anything it cannot answer, so the form simply leaves the
2721
+ * fields to the shopper.
2722
+ */
2723
+ async lookupPostcode({ country = "IN", postcode }) {
2724
+ const code = String(postcode ?? "").trim();
2725
+ const cc = String(country ?? "").trim().toUpperCase();
2726
+ if (cc !== "IN" || !/^[1-9][0-9]{5}$/.test(code)) return null;
2727
+ try {
2728
+ const p = await this.data(`/api/postcodes/${cc}/${code}`);
2729
+ return { country: p.country, postcode: p.postcode, city: p.city, state: p.state, stateCode: p.state_code };
2730
+ } catch (err) {
2731
+ if (err instanceof GoCommerceError && (err.status === 404 || err.status === 400)) return null;
2732
+ throw err;
2733
+ }
2734
+ }
2670
2735
  async deleteAddress(id2) {
2671
2736
  await this.engine(`/x/identity/me/addresses/${enc(id2)}`, { method: "DELETE", auth: true });
2672
2737
  return { id: String(id2), deleted: true };