@misiki/gocommerce-connector 0.11.0 → 0.13.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/README.md +6 -1
- package/dist/{index-90wdO5MM.d.cts → index-DHKyh3CU.d.cts} +481 -8
- package/dist/{index-90wdO5MM.d.ts → index-DHKyh3CU.d.ts} +481 -8
- package/dist/index.cjs +226 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +223 -6
- package/dist/index.js.map +1 -1
- package/dist/services/index.cjs +222 -5
- package/dist/services/index.cjs.map +1 -1
- package/dist/services/index.d.cts +1 -1
- package/dist/services/index.d.ts +1 -1
- package/dist/services/index.js +222 -5
- package/dist/services/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
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-DHKyh3CU.cjs';
|
package/dist/services/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
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-DHKyh3CU.js';
|
package/dist/services/index.js
CHANGED
|
@@ -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
|
-
|
|
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
|
}
|
|
@@ -731,7 +758,12 @@ function toCartLine(l, extra = {}) {
|
|
|
731
758
|
variantTitle: l.variant_label ?? "",
|
|
732
759
|
qty: l.quantity,
|
|
733
760
|
price: toMajor(l.unit_price),
|
|
734
|
-
|
|
761
|
+
// The variant's compare-at price, where the shop set one above what the
|
|
762
|
+
// line costs: what the basket's "you save" is measured from.
|
|
763
|
+
mrp: l.compare_at_price && l.compare_at_price.amount_minor > l.unit_price.amount_minor ? toMajor(l.compare_at_price) : toMajor(l.unit_price),
|
|
764
|
+
/** The add-on this line was bought as (D133), or null on an ordinary line. */
|
|
765
|
+
addOnId: l.add_on_id ? str(l.add_on_id) : null,
|
|
766
|
+
addOnFor: l.add_on_for ? str(l.add_on_for) : null,
|
|
735
767
|
subtotal: toMajor(l.total),
|
|
736
768
|
total: toMajor(l.total),
|
|
737
769
|
inStock: l.in_stock,
|
|
@@ -964,6 +996,45 @@ function toUser(c) {
|
|
|
964
996
|
updatedAt: c.updated_at
|
|
965
997
|
};
|
|
966
998
|
}
|
|
999
|
+
function toAddOn(a) {
|
|
1000
|
+
return {
|
|
1001
|
+
id: str(a.id),
|
|
1002
|
+
productId: str(a.item.product_id),
|
|
1003
|
+
variantId: str(a.variant_id),
|
|
1004
|
+
slug: a.item.slug,
|
|
1005
|
+
title: a.item.title,
|
|
1006
|
+
variantTitle: a.item.variant_label ?? "",
|
|
1007
|
+
thumbnail: mediaUrl(a.item.image_url ?? null),
|
|
1008
|
+
price: toMajor(a.offer_price ?? a.price),
|
|
1009
|
+
regularPrice: toMajor(a.price),
|
|
1010
|
+
hasOffer: !!a.offer_price && a.offer_price.amount_minor < a.price.amount_minor,
|
|
1011
|
+
inStock: a.item.in_stock
|
|
1012
|
+
};
|
|
1013
|
+
}
|
|
1014
|
+
function toCartOffer(o, currency) {
|
|
1015
|
+
const isPercent = o.kind === "percentage";
|
|
1016
|
+
return {
|
|
1017
|
+
code: o.code,
|
|
1018
|
+
title: o.title,
|
|
1019
|
+
isPercent,
|
|
1020
|
+
freeShipping: o.kind === "free_shipping",
|
|
1021
|
+
/** The percentage for a percentage code, the amount for a fixed one. */
|
|
1022
|
+
value: isPercent ? (o.value_bp ?? 0) / 100 : minorToMajor(o.value_minor ?? 0, currency),
|
|
1023
|
+
minAmount: o.min_subtotal_minor ? minorToMajor(o.min_subtotal_minor, currency) : null,
|
|
1024
|
+
applies: o.applies,
|
|
1025
|
+
amount: o.amount ? toMajor(o.amount) : null,
|
|
1026
|
+
remaining: o.remaining ? toMajor(o.remaining) : null,
|
|
1027
|
+
reason: o.reason ?? ""
|
|
1028
|
+
};
|
|
1029
|
+
}
|
|
1030
|
+
function toFreeShipping(f) {
|
|
1031
|
+
return {
|
|
1032
|
+
qualifies: f.qualifies,
|
|
1033
|
+
threshold: f.threshold ? toMajor(f.threshold) : null,
|
|
1034
|
+
remaining: f.remaining ? toMajor(f.remaining) : null,
|
|
1035
|
+
subtotal: toMajor(f.subtotal)
|
|
1036
|
+
};
|
|
1037
|
+
}
|
|
967
1038
|
|
|
968
1039
|
// src/cache.ts
|
|
969
1040
|
var TTL_MS = 6e4;
|
|
@@ -1288,6 +1359,36 @@ var ProductService = class extends CatalogService {
|
|
|
1288
1359
|
if (!category) return this.list({ page, limit });
|
|
1289
1360
|
return this.list({ page, limit, categories: category.slug });
|
|
1290
1361
|
}
|
|
1362
|
+
/**
|
|
1363
|
+
* What the shop offers with a product, ticked in its buy box (D133): each
|
|
1364
|
+
* add-on at the price ticking it adds. Only add-ons that can be bought
|
|
1365
|
+
* arrive; an engine without the route offers none.
|
|
1366
|
+
*/
|
|
1367
|
+
async listAddOns({ product }) {
|
|
1368
|
+
const p = await this.findProduct(String(product));
|
|
1369
|
+
try {
|
|
1370
|
+
return (await this.data("/api/add-ons", { query: { product_id: p.id } }) ?? []).map(toAddOn);
|
|
1371
|
+
} catch (err) {
|
|
1372
|
+
if (err instanceof GoCommerceError && err.status === 404) return [];
|
|
1373
|
+
throw err;
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1376
|
+
/**
|
|
1377
|
+
* "You may also like": the products the shop chose for this one, at their
|
|
1378
|
+
* own prices (D133). Curated only, and empty when none were chosen: the
|
|
1379
|
+
* related products already fill in from the category, and the page should
|
|
1380
|
+
* not draw the same fill twice.
|
|
1381
|
+
*/
|
|
1382
|
+
async listCrossSells({ product, limit }) {
|
|
1383
|
+
const p = await this.findProduct(String(product));
|
|
1384
|
+
try {
|
|
1385
|
+
const rows = await this.data("/api/cross-sells", { query: { product_id: p.id, limit } }) ?? [];
|
|
1386
|
+
return rows.map((r) => toProduct(r));
|
|
1387
|
+
} catch (err) {
|
|
1388
|
+
if (err instanceof GoCommerceError && err.status === 404) return [];
|
|
1389
|
+
throw err;
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1291
1392
|
async relatedTo(slug, limit) {
|
|
1292
1393
|
const size = Math.min(100, Math.max(1, Number(limit) || PAGE_SIZE));
|
|
1293
1394
|
const p = await this.findProduct(slug);
|
|
@@ -1627,6 +1728,88 @@ var CartService = class extends BaseService {
|
|
|
1627
1728
|
throw err;
|
|
1628
1729
|
}
|
|
1629
1730
|
}
|
|
1731
|
+
/**
|
|
1732
|
+
* Adds an add-on from a product's "Complete the set" (D133) at its offer
|
|
1733
|
+
* price. The product it is offered with has to be in the bag already, so
|
|
1734
|
+
* this is called after adding it; the engine refuses one too many with the
|
|
1735
|
+
* sentence the shopper is shown.
|
|
1736
|
+
*/
|
|
1737
|
+
async addAddOn({ cartId, addOnId, qty = 1 }) {
|
|
1738
|
+
const id2 = clean(cartId) ?? storedCartId();
|
|
1739
|
+
if (!id2) throw new GoCommerceError("Add the product to your bag first.", 409);
|
|
1740
|
+
return this.present(
|
|
1741
|
+
await this.data(`/api/carts/${encodeURIComponent(id2)}/line-items`, {
|
|
1742
|
+
method: "POST",
|
|
1743
|
+
body: { add_on_id: Number(addOnId), quantity: Number(qty) }
|
|
1744
|
+
})
|
|
1745
|
+
);
|
|
1746
|
+
}
|
|
1747
|
+
/**
|
|
1748
|
+
* The codes the shop chose to show (D133), each with what it takes off this
|
|
1749
|
+
* bag or how much more the bag needs. None without a bag.
|
|
1750
|
+
*/
|
|
1751
|
+
async getOffers({ cartId } = {}) {
|
|
1752
|
+
const id2 = clean(cartId) ?? storedCartId();
|
|
1753
|
+
if (!id2) return [];
|
|
1754
|
+
try {
|
|
1755
|
+
const rows = await this.data(`/api/carts/${encodeURIComponent(id2)}/offers`) ?? [];
|
|
1756
|
+
const currency = await this.currency();
|
|
1757
|
+
return rows.map((o) => toCartOffer(o, o.amount?.currency ?? o.remaining?.currency ?? currency));
|
|
1758
|
+
} catch (err) {
|
|
1759
|
+
if (err instanceof GoCommerceError && err.status === 404) return [];
|
|
1760
|
+
throw err;
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1763
|
+
/**
|
|
1764
|
+
* How far the bag is from free delivery (D133), read from the store's own
|
|
1765
|
+
* rates for the country (the store's own when none is given). Null when
|
|
1766
|
+
* the engine cannot say: a bar with a made-up figure is worse than none.
|
|
1767
|
+
*/
|
|
1768
|
+
async getFreeShipping({ cartId, country, state } = {}) {
|
|
1769
|
+
const id2 = clean(cartId) ?? storedCartId();
|
|
1770
|
+
if (!id2) return null;
|
|
1771
|
+
const where = country ?? cartExtras(id2).shippingAddress?.country ?? void 0;
|
|
1772
|
+
try {
|
|
1773
|
+
return toFreeShipping(
|
|
1774
|
+
await this.data(`/api/carts/${encodeURIComponent(id2)}/free-shipping`, {
|
|
1775
|
+
query: { country: where || void 0, state: state || void 0 }
|
|
1776
|
+
})
|
|
1777
|
+
);
|
|
1778
|
+
} catch (err) {
|
|
1779
|
+
if (err instanceof GoCommerceError && err.status === 404) return null;
|
|
1780
|
+
throw err;
|
|
1781
|
+
}
|
|
1782
|
+
}
|
|
1783
|
+
/**
|
|
1784
|
+
* "You may be interested in" (D133): what the bag's products suggest, less
|
|
1785
|
+
* what it holds; with nothing curated, the first product's related
|
|
1786
|
+
* products, still less what it holds.
|
|
1787
|
+
*/
|
|
1788
|
+
async listCrossSells({ cartId, limit = 12 } = {}) {
|
|
1789
|
+
const id2 = clean(cartId) ?? storedCartId();
|
|
1790
|
+
if (!id2) return [];
|
|
1791
|
+
let curated = [];
|
|
1792
|
+
try {
|
|
1793
|
+
curated = await this.data(`/api/carts/${encodeURIComponent(id2)}/cross-sells`, { query: { limit } }) ?? [];
|
|
1794
|
+
} catch (err) {
|
|
1795
|
+
if (!(err instanceof GoCommerceError) || err.status !== 404) throw err;
|
|
1796
|
+
}
|
|
1797
|
+
if (curated.length) return curated.map((p) => toProduct(p));
|
|
1798
|
+
let cart;
|
|
1799
|
+
try {
|
|
1800
|
+
cart = await this.data(`/api/carts/${encodeURIComponent(id2)}`);
|
|
1801
|
+
} catch {
|
|
1802
|
+
return [];
|
|
1803
|
+
}
|
|
1804
|
+
const held = new Set((cart.line_items ?? []).map((l) => String(l.product_id)));
|
|
1805
|
+
const first = cart.line_items?.[0];
|
|
1806
|
+
if (!first) return [];
|
|
1807
|
+
const related = await new ProductService(this._fetch).listRelatedProducts({
|
|
1808
|
+
product: String(first.product_id),
|
|
1809
|
+
limit: limit + held.size
|
|
1810
|
+
});
|
|
1811
|
+
return related.data.filter((p) => !held.has(String(p.id))).slice(0, limit);
|
|
1812
|
+
}
|
|
1630
1813
|
/** `qty` is the new total; 0 takes the line out. */
|
|
1631
1814
|
async updateCart({
|
|
1632
1815
|
cartId,
|
|
@@ -2060,7 +2243,20 @@ var paymentMethodService = new PaymentMethodService();
|
|
|
2060
2243
|
// src/services/coupon-service.ts
|
|
2061
2244
|
var CouponService = class extends BaseService {
|
|
2062
2245
|
async listCoupons(_args = {}) {
|
|
2063
|
-
|
|
2246
|
+
const offers = await new CartService(this._fetch).getOffers().catch(() => []);
|
|
2247
|
+
if (!offers.length) return emptyPage();
|
|
2248
|
+
const data = offers.map((o) => ({
|
|
2249
|
+
id: o.code,
|
|
2250
|
+
code: o.code,
|
|
2251
|
+
title: o.title,
|
|
2252
|
+
isPercent: o.isPercent,
|
|
2253
|
+
amount: o.value,
|
|
2254
|
+
minAmount: o.minAmount,
|
|
2255
|
+
description: o.applies ? o.title : o.remaining !== null ? `${o.title}. Add ${o.remaining} more to use this.` : o.reason || o.title,
|
|
2256
|
+
applies: o.applies,
|
|
2257
|
+
remaining: o.remaining
|
|
2258
|
+
}));
|
|
2259
|
+
return { data, count: data.length, pageSize: data.length, noOfPage: 1, page: 1 };
|
|
2064
2260
|
}
|
|
2065
2261
|
};
|
|
2066
2262
|
var couponService = new CouponService();
|
|
@@ -2498,6 +2694,24 @@ var AddressService = class extends BaseService {
|
|
|
2498
2694
|
});
|
|
2499
2695
|
return fromIdentityAddress(a, currentMe()?.email);
|
|
2500
2696
|
}
|
|
2697
|
+
/**
|
|
2698
|
+
* The city and state for a postcode (D134), for the address form to fill
|
|
2699
|
+
* in. India's six-digit PIN codes only, from the directory the engine was
|
|
2700
|
+
* given; null for anything it cannot answer, so the form simply leaves the
|
|
2701
|
+
* fields to the shopper.
|
|
2702
|
+
*/
|
|
2703
|
+
async lookupPostcode({ country = "IN", postcode }) {
|
|
2704
|
+
const code = String(postcode ?? "").trim();
|
|
2705
|
+
const cc = String(country ?? "").trim().toUpperCase();
|
|
2706
|
+
if (cc !== "IN" || !/^[1-9][0-9]{5}$/.test(code)) return null;
|
|
2707
|
+
try {
|
|
2708
|
+
const p = await this.data(`/api/postcodes/${cc}/${code}`);
|
|
2709
|
+
return { country: p.country, postcode: p.postcode, city: p.city, state: p.state, stateCode: p.state_code };
|
|
2710
|
+
} catch (err) {
|
|
2711
|
+
if (err instanceof GoCommerceError && (err.status === 404 || err.status === 400)) return null;
|
|
2712
|
+
throw err;
|
|
2713
|
+
}
|
|
2714
|
+
}
|
|
2501
2715
|
async deleteAddress(id2) {
|
|
2502
2716
|
await this.engine(`/x/identity/me/addresses/${enc(id2)}`, { method: "DELETE", auth: true });
|
|
2503
2717
|
return { id: String(id2), deleted: true };
|
|
@@ -2810,7 +3024,10 @@ var StoreService = class extends BaseService {
|
|
|
2810
3024
|
},
|
|
2811
3025
|
// The footer's sign-up box posts to ext/newsletter, and the theme editor's footer
|
|
2812
3026
|
// switch (D131) can only show it while that is on.
|
|
2813
|
-
newsletter: { ...basePlugins.newsletter, ...flag(plugins.has("newsletter")) }
|
|
3027
|
+
newsletter: { ...basePlugins.newsletter, ...flag(plugins.has("newsletter")) },
|
|
3028
|
+
// Discount codes are core: every GoCommerce store takes them, so
|
|
3029
|
+
// the code box is shown whatever the static record says.
|
|
3030
|
+
isDiscountCoupons: { ...basePlugins.isDiscountCoupons, active: true }
|
|
2814
3031
|
},
|
|
2815
3032
|
...menus?.length ? { menu: menus } : {},
|
|
2816
3033
|
...deliverable(base, ships),
|