@misiki/gocommerce-connector 0.29.0 → 0.31.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 +1 -0
- package/dist/{index-DOlNI60Y.d.cts → index-CSqvRZQ4.d.cts} +136 -3
- package/dist/{index-DOlNI60Y.d.ts → index-CSqvRZQ4.d.ts} +136 -3
- package/dist/index.cjs +185 -23
- 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 +185 -24
- package/dist/index.js.map +1 -1
- package/dist/services/index.cjs +183 -23
- 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 +183 -23
- package/dist/services/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -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,
|
|
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, w as CheckoutService, z as CollectionService, D as Company, E as CompanyOrder, F as ContactService, G as CountryService, H as CouponService, J as Credit, K as CurrencyService, O as CustomizerEditor, P as CustomizerFile, R as CustomizerSavedDesign, S as CustomizerService, V as DealService, W as DemoRequestService, X as EngineRequest, Y as EnquiryService, a0 as FaqService, a1 as FeedbackService, a2 as FooterSettings, a5 as GalleryService, a7 as GoogleReview, a8 as GoogleReviewService, a9 as GoogleReviews, ab as HeaderSettings, ac as HomeLayout, ad as HomeLayoutSection, ae as HomeService, ag as InitService, ah as Invitation, ai as LayoutCollection, aj as LayoutPage, ak as LayoutService, al as Lead, an as MeilisearchService, ao as Member, ar as MenuService, au as NewsletterService, az as OrderService, aA as PageLayout, aB as PageService, aD as PaymentMethodService, aF as PluginService, aF as PluginsService, aG as PopularSearchService, aH as PopularityService, aM as ProductService, aN as ProfileService, aO as Quote, aP as REDIRECT_GATEWAYS, aQ as ReelsService, aR as RegionService, aS as RejectedLine, aV as ReviewService, aY as SearchService, aZ as SettingService, aZ as SettingsService, a$ as SiteChrome, b0 as SiteFooter, b1 as SiteHeader, b2 as SocialLink, b3 as StateService, b4 as StoreClosed, b5 as StorePass, b8 as StoreService, b9 as StoreUnlock, bb as StorefrontMenu, be as ThemeSettings, bf as ThemeSettingsResult, bg as UploadService, bh as UserService, bk as VariantService, bl as VarniCustomDesignService, bm as VarniCustomProductService, bo as VendorService, bp as WarrantyService, bq as WhatsappConsent, br as WhatsappConsentOffer, bs as WhatsappService, bv as WishlistService, bw as addressService, bx as authService, by as autocompleteService, bz as b2bService, bA as bannerService, bB as blogService, bC as cartService, bD as categoryService, bE as chatService, bF as checkoutService, bG as collectionService, bH as contactService, bI as countryService, bJ as couponService, bL as currencyService, bM as customizerService, bN as dealService, bO as demoRequestService, bQ as emptyPage, bR as enquiryService, bS as faqService, bT as feedbackService, bX as galleryService, bY as googleReviewService, bZ as homeService, b_ as initService, b$ as layoutService, c0 as mediaUrl, c1 as meilisearchService, c2 as menuService, c4 as newsletterService, c5 as orderService, c6 as ownDomain, c7 as pageService, c8 as paymentMethodService, c9 as pluginService, ca as pluginsService, cb as popularSearchService, cc as popularityService, cf as productService, ch as profileService, ci as qs, cj as reelsService, ck as regionService, cl as reviewService, cm as searchService, cn as setRequestHost, co as settingService, cp as settingsService, cq as stateService, cr as staticStore, cs as storeForHost, ct 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 whatsappService, cX as wishlistService } from '../index-CSqvRZQ4.cjs';
|
package/dist/services/index.d.ts
CHANGED
|
@@ -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,
|
|
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, w as CheckoutService, z as CollectionService, D as Company, E as CompanyOrder, F as ContactService, G as CountryService, H as CouponService, J as Credit, K as CurrencyService, O as CustomizerEditor, P as CustomizerFile, R as CustomizerSavedDesign, S as CustomizerService, V as DealService, W as DemoRequestService, X as EngineRequest, Y as EnquiryService, a0 as FaqService, a1 as FeedbackService, a2 as FooterSettings, a5 as GalleryService, a7 as GoogleReview, a8 as GoogleReviewService, a9 as GoogleReviews, ab as HeaderSettings, ac as HomeLayout, ad as HomeLayoutSection, ae as HomeService, ag as InitService, ah as Invitation, ai as LayoutCollection, aj as LayoutPage, ak as LayoutService, al as Lead, an as MeilisearchService, ao as Member, ar as MenuService, au as NewsletterService, az as OrderService, aA as PageLayout, aB as PageService, aD as PaymentMethodService, aF as PluginService, aF as PluginsService, aG as PopularSearchService, aH as PopularityService, aM as ProductService, aN as ProfileService, aO as Quote, aP as REDIRECT_GATEWAYS, aQ as ReelsService, aR as RegionService, aS as RejectedLine, aV as ReviewService, aY as SearchService, aZ as SettingService, aZ as SettingsService, a$ as SiteChrome, b0 as SiteFooter, b1 as SiteHeader, b2 as SocialLink, b3 as StateService, b4 as StoreClosed, b5 as StorePass, b8 as StoreService, b9 as StoreUnlock, bb as StorefrontMenu, be as ThemeSettings, bf as ThemeSettingsResult, bg as UploadService, bh as UserService, bk as VariantService, bl as VarniCustomDesignService, bm as VarniCustomProductService, bo as VendorService, bp as WarrantyService, bq as WhatsappConsent, br as WhatsappConsentOffer, bs as WhatsappService, bv as WishlistService, bw as addressService, bx as authService, by as autocompleteService, bz as b2bService, bA as bannerService, bB as blogService, bC as cartService, bD as categoryService, bE as chatService, bF as checkoutService, bG as collectionService, bH as contactService, bI as countryService, bJ as couponService, bL as currencyService, bM as customizerService, bN as dealService, bO as demoRequestService, bQ as emptyPage, bR as enquiryService, bS as faqService, bT as feedbackService, bX as galleryService, bY as googleReviewService, bZ as homeService, b_ as initService, b$ as layoutService, c0 as mediaUrl, c1 as meilisearchService, c2 as menuService, c4 as newsletterService, c5 as orderService, c6 as ownDomain, c7 as pageService, c8 as paymentMethodService, c9 as pluginService, ca as pluginsService, cb as popularSearchService, cc as popularityService, cf as productService, ch as profileService, ci as qs, cj as reelsService, ck as regionService, cl as reviewService, cm as searchService, cn as setRequestHost, co as settingService, cp as settingsService, cq as stateService, cr as staticStore, cs as storeForHost, ct 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 whatsappService, cX as wishlistService } from '../index-CSqvRZQ4.js';
|
package/dist/services/index.js
CHANGED
|
@@ -518,6 +518,7 @@ function productImages(p) {
|
|
|
518
518
|
if (url && !out.includes(url)) out.push(url);
|
|
519
519
|
};
|
|
520
520
|
push(mediaUrl(p.image_url));
|
|
521
|
+
push(mediaUrl(p.hover_image_url));
|
|
521
522
|
for (const m of arr(p.media)) if (m.kind === "image") push(mediaUrl(m.url));
|
|
522
523
|
for (const v of arr(p.variants)) for (const url of variantImages(v)) push(url);
|
|
523
524
|
return out;
|
|
@@ -1085,7 +1086,22 @@ function toCartOffer(o, currency) {
|
|
|
1085
1086
|
applies: o.applies,
|
|
1086
1087
|
amount: o.amount ? toMajor(o.amount) : null,
|
|
1087
1088
|
remaining: o.remaining ? toMajor(o.remaining) : null,
|
|
1088
|
-
reason: o.reason ?? ""
|
|
1089
|
+
reason: o.reason ?? "",
|
|
1090
|
+
autoApply: !!o.auto_apply
|
|
1091
|
+
};
|
|
1092
|
+
}
|
|
1093
|
+
function toCheckoutQuote(q) {
|
|
1094
|
+
const d = q.discount;
|
|
1095
|
+
return {
|
|
1096
|
+
subtotal: toMajor(q.subtotal),
|
|
1097
|
+
shippingCharges: toMajor(q.shipping),
|
|
1098
|
+
shippingMethod: q.shipping_method ?? null,
|
|
1099
|
+
discount: toMajor(d?.amount),
|
|
1100
|
+
coupon: d ? { code: d.code, title: d.title, autoApplied: d.auto_applied, freeShipping: !!d.free_shipping } : null,
|
|
1101
|
+
tax: toMajor(q.tax),
|
|
1102
|
+
taxIncluded: q.tax_inclusive,
|
|
1103
|
+
codCharges: toMajor(q.payment_fee),
|
|
1104
|
+
total: toMajor(q.total)
|
|
1089
1105
|
};
|
|
1090
1106
|
}
|
|
1091
1107
|
function toFreeShipping(f) {
|
|
@@ -1110,6 +1126,14 @@ function remember(key, load, ttl = TTL_MS) {
|
|
|
1110
1126
|
});
|
|
1111
1127
|
return value;
|
|
1112
1128
|
}
|
|
1129
|
+
var known = /* @__PURE__ */ new Map();
|
|
1130
|
+
function keep(key, value) {
|
|
1131
|
+
known.set(key, value);
|
|
1132
|
+
return value;
|
|
1133
|
+
}
|
|
1134
|
+
function recall(key) {
|
|
1135
|
+
return known.get(key);
|
|
1136
|
+
}
|
|
1113
1137
|
|
|
1114
1138
|
// src/services/facts.ts
|
|
1115
1139
|
var StoreFacts = class extends BaseService {
|
|
@@ -2107,6 +2131,7 @@ var customizerService = new CustomizerService();
|
|
|
2107
2131
|
|
|
2108
2132
|
// src/services/checkout-service.ts
|
|
2109
2133
|
var CheckoutService = class extends BaseService {
|
|
2134
|
+
expected = /* @__PURE__ */ new Map();
|
|
2110
2135
|
/** Delivery options for the address on the cart: `{ data: [{ id, name, base_rate }] }`. */
|
|
2111
2136
|
async getShippingRates({ cartId } = {}) {
|
|
2112
2137
|
const id2 = cartId || storedCartId();
|
|
@@ -2278,6 +2303,64 @@ var CheckoutService = class extends BaseService {
|
|
|
2278
2303
|
);
|
|
2279
2304
|
return { methods: options.methods ?? [], currency: options.currency };
|
|
2280
2305
|
}
|
|
2306
|
+
/**
|
|
2307
|
+
* What checkout would charge for the cart now, by the storefront's method
|
|
2308
|
+
* code (`COD`, `RAZORPAY`, `PAYPAL`) or none yet (D185). Null until the
|
|
2309
|
+
* address step has stored an address, and null from an engine before D185.
|
|
2310
|
+
*
|
|
2311
|
+
* A refusal is checkout's own: the same GoCommerceError, with the same
|
|
2312
|
+
* message, that placing the order would raise now.
|
|
2313
|
+
*/
|
|
2314
|
+
async getQuote({ cartId, method = "" } = {}) {
|
|
2315
|
+
const id2 = cartId || storedCartId();
|
|
2316
|
+
if (!id2 || !cartExtras(id2).shippingAddress) return null;
|
|
2317
|
+
const { extras, email, address } = await this.storedCheckout(id2);
|
|
2318
|
+
const code = method.toLowerCase() === "paypal" ? await this.redirectGateway() : method.toLowerCase();
|
|
2319
|
+
try {
|
|
2320
|
+
const quote2 = await this.data("/api/checkout/quote", {
|
|
2321
|
+
query: {
|
|
2322
|
+
cart: id2,
|
|
2323
|
+
country: address.country,
|
|
2324
|
+
state: address.state,
|
|
2325
|
+
shipping_rate_id: extras.shippingRateId || void 0,
|
|
2326
|
+
method: code || void 0,
|
|
2327
|
+
email: email || void 0
|
|
2328
|
+
}
|
|
2329
|
+
});
|
|
2330
|
+
return toCheckoutQuote(quote2);
|
|
2331
|
+
} catch (err) {
|
|
2332
|
+
if (err instanceof GoCommerceError && (err.status === 405 || err.status === 404 && err.message.startsWith("no route for "))) {
|
|
2333
|
+
return null;
|
|
2334
|
+
}
|
|
2335
|
+
throw err;
|
|
2336
|
+
}
|
|
2337
|
+
}
|
|
2338
|
+
/**
|
|
2339
|
+
* The total on screen as the shopper confirms, from getQuote, or null when nothing was quoted
|
|
2340
|
+
* (D185). Every order placed for the cart then carries it, and checkout refuses one whose own
|
|
2341
|
+
* total differs instead of charging it: `onChange` gets checkout's figures now and the sentence
|
|
2342
|
+
* the placing call fails with.
|
|
2343
|
+
*/
|
|
2344
|
+
expectTotal({
|
|
2345
|
+
cartId,
|
|
2346
|
+
total,
|
|
2347
|
+
onChange
|
|
2348
|
+
}) {
|
|
2349
|
+
const id2 = cartId || storedCartId();
|
|
2350
|
+
if (!id2) return;
|
|
2351
|
+
if (typeof total === "number") this.expected.set(id2, { total, onChange });
|
|
2352
|
+
else this.expected.delete(id2);
|
|
2353
|
+
}
|
|
2354
|
+
async storedCheckout(cartId) {
|
|
2355
|
+
const id2 = cartId || storedCartId();
|
|
2356
|
+
if (!id2) throw new GoCommerceError("Your bag is empty.", 400);
|
|
2357
|
+
const extras = cartExtras(id2);
|
|
2358
|
+
const ship = extras.shippingAddress;
|
|
2359
|
+
if (!ship) throw new GoCommerceError("Add a delivery address first.", 400);
|
|
2360
|
+
const cart = await this.data(`/api/carts/${encodeURIComponent(id2)}`);
|
|
2361
|
+
const email = cart.email || (ship.email ? String(ship.email) : "");
|
|
2362
|
+
return { id: id2, extras, email, address: toEngineAddress(ship), currency: cart.currency };
|
|
2363
|
+
}
|
|
2281
2364
|
async redirectGateway() {
|
|
2282
2365
|
const { methods } = await this.listMethods();
|
|
2283
2366
|
return methods.find((m) => REDIRECT_GATEWAYS.has(m.code))?.code;
|
|
@@ -2293,15 +2376,8 @@ var CheckoutService = class extends BaseService {
|
|
|
2293
2376
|
* the engine refuses a key replayed with a different body.
|
|
2294
2377
|
*/
|
|
2295
2378
|
async place(code, cartId, extra = {}) {
|
|
2296
|
-
const id2 =
|
|
2297
|
-
if (!id2) throw new GoCommerceError("Your bag is empty.", 400);
|
|
2298
|
-
const extras = cartExtras(id2);
|
|
2299
|
-
const ship = extras.shippingAddress;
|
|
2300
|
-
if (!ship) throw new GoCommerceError("Add a delivery address first.", 400);
|
|
2301
|
-
const cart = await this.data(`/api/carts/${encodeURIComponent(id2)}`);
|
|
2302
|
-
const email = cart.email || (ship.email ? String(ship.email) : "");
|
|
2379
|
+
const { id: id2, extras, email, address, currency } = await this.storedCheckout(cartId);
|
|
2303
2380
|
if (!email) throw new GoCommerceError("Add an email address so we can send your receipt.", 400);
|
|
2304
|
-
const address = toEngineAddress(ship);
|
|
2305
2381
|
const body = {
|
|
2306
2382
|
cart_id: id2,
|
|
2307
2383
|
email,
|
|
@@ -2324,10 +2400,23 @@ var CheckoutService = class extends BaseService {
|
|
|
2324
2400
|
...meta ? { meta_capi: meta } : {},
|
|
2325
2401
|
...attribution ? { attribution } : {}
|
|
2326
2402
|
};
|
|
2403
|
+
const expected = this.expected.get(id2);
|
|
2327
2404
|
const result = await this.data(`/api/checkout/${encodeURIComponent(code)}`, {
|
|
2328
2405
|
method: "POST",
|
|
2329
|
-
body:
|
|
2406
|
+
body: {
|
|
2407
|
+
...Object.keys(metadata).length ? { ...body, metadata } : body,
|
|
2408
|
+
...expected ? { quoted_total_minor: toMinor(expected.total, currency) } : {}
|
|
2409
|
+
},
|
|
2330
2410
|
headers: { "Idempotency-Key": key }
|
|
2411
|
+
}).catch((err) => {
|
|
2412
|
+
if (keyAlreadyUsed(err)) {
|
|
2413
|
+
throw new GoCommerceError("This order was already placed in another tab. Check that tab for its confirmation.", 400, err.code);
|
|
2414
|
+
}
|
|
2415
|
+
const now = movedTotal(err);
|
|
2416
|
+
if (!expected || !now) throw err;
|
|
2417
|
+
const message = `Your total changed to ${shopperAmount(now.total, currency)}. Check the new total and confirm again.`;
|
|
2418
|
+
expected.onChange?.(now, message);
|
|
2419
|
+
throw new GoCommerceError(message, 409, "total_changed", now);
|
|
2331
2420
|
});
|
|
2332
2421
|
if (result.order.access_token) {
|
|
2333
2422
|
rememberOrder({
|
|
@@ -2350,6 +2439,21 @@ var CheckoutService = class extends BaseService {
|
|
|
2350
2439
|
};
|
|
2351
2440
|
var REDIRECT_GATEWAYS = /* @__PURE__ */ new Set(["adyen", "paddle", "lemonsqueezy", "creem", "hyperswitch", "revenuecat"]);
|
|
2352
2441
|
var unsupported = (method, why) => new NotSupportedError("CheckoutService", method, why);
|
|
2442
|
+
function keyAlreadyUsed(err) {
|
|
2443
|
+
return err instanceof GoCommerceError && err.status === 400 && err.message.includes("Idempotency-Key was already used");
|
|
2444
|
+
}
|
|
2445
|
+
function movedTotal(err) {
|
|
2446
|
+
if (!(err instanceof GoCommerceError) || err.code !== "total_changed") return null;
|
|
2447
|
+
const now = err.details;
|
|
2448
|
+
return now?.total ? toCheckoutQuote(now) : null;
|
|
2449
|
+
}
|
|
2450
|
+
function shopperAmount(amount, currency) {
|
|
2451
|
+
return new Intl.NumberFormat(currency === "INR" ? "en-IN" : "en", {
|
|
2452
|
+
style: "currency",
|
|
2453
|
+
currency,
|
|
2454
|
+
...Number.isInteger(amount) ? { minimumFractionDigits: 0 } : {}
|
|
2455
|
+
}).format(amount);
|
|
2456
|
+
}
|
|
2353
2457
|
function newKey() {
|
|
2354
2458
|
const c = globalThis.crypto;
|
|
2355
2459
|
if (c?.randomUUID) return c.randomUUID();
|
|
@@ -2411,7 +2515,8 @@ var CouponService = class extends BaseService {
|
|
|
2411
2515
|
minAmount: o.minAmount,
|
|
2412
2516
|
description: o.applies ? o.title : o.remaining !== null ? `${o.title}. Add ${o.remaining} more to use this.` : o.reason || o.title,
|
|
2413
2517
|
applies: o.applies,
|
|
2414
|
-
remaining: o.remaining
|
|
2518
|
+
remaining: o.remaining,
|
|
2519
|
+
autoApply: o.autoApply
|
|
2415
2520
|
}));
|
|
2416
2521
|
return { data, count: data.length, pageSize: data.length, noOfPage: 1, page: 1 };
|
|
2417
2522
|
}
|
|
@@ -3167,15 +3272,18 @@ var StoreService = class extends BaseService {
|
|
|
3167
3272
|
async getStoreByIdOrDomain(_args = {}) {
|
|
3168
3273
|
const base = await readStaticStore();
|
|
3169
3274
|
const store = this.store;
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
if (isStoreMissing(err)) {
|
|
3275
|
+
const [plugins, live] = await Promise.all([
|
|
3276
|
+
this.facts.plugins().catch((err) => {
|
|
3277
|
+
if (store && isStoreMissing(err)) {
|
|
3173
3278
|
throw new GoCommerceError(`store not found: no store "${store}" on this engine`, 404, "store_not_found");
|
|
3174
3279
|
}
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3280
|
+
return void 0;
|
|
3281
|
+
}),
|
|
3282
|
+
this.live().catch(() => ({}))
|
|
3283
|
+
]);
|
|
3284
|
+
const known2 = `${this.creds.apiUrl ?? ""}|${store ?? ""}|closed`;
|
|
3285
|
+
const closed = plugins ? keep(known2, closedOf(plugins)) : recall(known2);
|
|
3286
|
+
return { ...base, ...live, closed, id: base.id || "gocommerce" };
|
|
3179
3287
|
}
|
|
3180
3288
|
async getStore(storeId) {
|
|
3181
3289
|
return this.getStoreByIdOrDomain({ storeId });
|
|
@@ -3210,6 +3318,46 @@ var StoreService = class extends BaseService {
|
|
|
3210
3318
|
}
|
|
3211
3319
|
return super.post(path, data);
|
|
3212
3320
|
}
|
|
3321
|
+
/**
|
|
3322
|
+
* A closed store's password (D170), traded for a pass. Never throws. The
|
|
3323
|
+
* engine allows 20 tries an hour per client, and sees this server as the
|
|
3324
|
+
* client unless `clientAddress`, the shopper's, travels as `X-Forwarded-For`.
|
|
3325
|
+
*/
|
|
3326
|
+
async unlockStore(password, { clientAddress } = {}) {
|
|
3327
|
+
const typed = password.trim();
|
|
3328
|
+
if (!typed) return { outcome: "wrong" };
|
|
3329
|
+
try {
|
|
3330
|
+
return { outcome: "unlocked", pass: await this.storePass({ password: typed }, clientAddress) };
|
|
3331
|
+
} catch (err) {
|
|
3332
|
+
return { outcome: err instanceof GoCommerceError && UNLOCK_REFUSED[err.status] || "unavailable" };
|
|
3333
|
+
}
|
|
3334
|
+
}
|
|
3335
|
+
/**
|
|
3336
|
+
* A pass checked without spending a try: the pass, or null when it is wrong,
|
|
3337
|
+
* expired, ended by a new password, or the store takes none now. Throws when
|
|
3338
|
+
* the engine cannot say.
|
|
3339
|
+
*/
|
|
3340
|
+
async checkStorePass(token) {
|
|
3341
|
+
if (!token) return null;
|
|
3342
|
+
try {
|
|
3343
|
+
return await this.storePass({ token });
|
|
3344
|
+
} catch (err) {
|
|
3345
|
+
if (err instanceof GoCommerceError && (err.status === 422 || err.status === 404)) return null;
|
|
3346
|
+
throw err;
|
|
3347
|
+
}
|
|
3348
|
+
}
|
|
3349
|
+
async storePass(body, clientAddress) {
|
|
3350
|
+
const answer = await this.data("/api/store/password", {
|
|
3351
|
+
method: "POST",
|
|
3352
|
+
body,
|
|
3353
|
+
headers: clientAddress && ONE_IP_ADDRESS.test(clientAddress) ? { "X-Forwarded-For": clientAddress } : void 0
|
|
3354
|
+
});
|
|
3355
|
+
const expiresAt = new Date(answer?.expires_at ?? NaN);
|
|
3356
|
+
if (!answer?.token || Number.isNaN(expiresAt.getTime())) {
|
|
3357
|
+
throw new GoCommerceError("The commerce engine answered a store pass without its token or expiry.", 502);
|
|
3358
|
+
}
|
|
3359
|
+
return { token: answer.token, expiresAt };
|
|
3360
|
+
}
|
|
3213
3361
|
async live() {
|
|
3214
3362
|
const [ready, plugins, menus, base, profile, ships] = await Promise.all([
|
|
3215
3363
|
this.facts.ready(),
|
|
@@ -3327,6 +3475,17 @@ var StoreService = class extends BaseService {
|
|
|
3327
3475
|
}
|
|
3328
3476
|
};
|
|
3329
3477
|
var storeService = new StoreService();
|
|
3478
|
+
var ONE_IP_ADDRESS = /^[\da-f.:]{2,45}$/i;
|
|
3479
|
+
var UNLOCK_REFUSED = {
|
|
3480
|
+
422: "wrong",
|
|
3481
|
+
429: "throttled",
|
|
3482
|
+
404: "open"
|
|
3483
|
+
};
|
|
3484
|
+
function closedOf(plugins) {
|
|
3485
|
+
const plugin = plugins?.get("store-close");
|
|
3486
|
+
if (!plugin) return void 0;
|
|
3487
|
+
return { message: String(plugin.settings?.message ?? ""), password: plugin.settings?.password === true };
|
|
3488
|
+
}
|
|
3330
3489
|
var AD_TAGS = [
|
|
3331
3490
|
["meta-pixel", "pixel_id", "facebookPixel"],
|
|
3332
3491
|
["microsoft-clarity", "project_id", "microsoftClarity"],
|
|
@@ -3355,10 +3514,10 @@ function googleTags(plugins) {
|
|
|
3355
3514
|
}
|
|
3356
3515
|
function deliverable(base, ships) {
|
|
3357
3516
|
if (ships.everywhere || !ships.countries.length) return {};
|
|
3358
|
-
const
|
|
3359
|
-
const countries = ships.countries.map((code) =>
|
|
3360
|
-
const
|
|
3361
|
-
return { countries, ...
|
|
3517
|
+
const known2 = new Map((base.countries ?? []).map((c) => [String(c.code).toUpperCase(), c]));
|
|
3518
|
+
const countries = ships.countries.map((code) => known2.get(code) ?? { code, name: regionName(code) });
|
|
3519
|
+
const keep2 = base.country && ships.countries.includes(String(base.country.code).toUpperCase());
|
|
3520
|
+
return { countries, ...keep2 ? {} : { country: countries[0] } };
|
|
3362
3521
|
}
|
|
3363
3522
|
function regionName(code) {
|
|
3364
3523
|
try {
|
|
@@ -3513,7 +3672,8 @@ function toSection(s) {
|
|
|
3513
3672
|
title: c.title,
|
|
3514
3673
|
slug: c.slug,
|
|
3515
3674
|
link: `/collections/${c.slug}`,
|
|
3516
|
-
image: mediaUrl(c.image) ?? null
|
|
3675
|
+
image: mediaUrl(c.image) ?? null,
|
|
3676
|
+
description: c.description || null
|
|
3517
3677
|
}));
|
|
3518
3678
|
}
|
|
3519
3679
|
return out;
|