@shoppexio/storefront 1.0.100 → 1.0.102
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/CHANGELOG.md +8 -0
- package/dist/customer.cjs +0 -4
- package/dist/customer.cjs.map +1 -1
- package/dist/customer.js +0 -4
- package/dist/customer.js.map +1 -1
- package/dist/index.cjs +24 -32
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -77
- package/dist/index.d.ts +8 -77
- package/dist/index.js +24 -32
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -271,13 +271,7 @@ interface Product {
|
|
|
271
271
|
price_display?: string;
|
|
272
272
|
price_discount?: number;
|
|
273
273
|
currency: string;
|
|
274
|
-
/**
|
|
275
|
-
* RAW local stock only. `-1` (or any negative value) means unlimited, `0` means
|
|
276
|
-
* no local units. This is NEVER on its own a purchasable cap: a supplier-backed
|
|
277
|
-
* product reports `stock: 0` by design and is still buyable. Gate buying on
|
|
278
|
-
* {@link Product.orderable}, and use `resolveDisplayStock` / `isProductInStock`
|
|
279
|
-
* rather than reading this field directly.
|
|
280
|
-
*/
|
|
274
|
+
/** Local stock; a negative value means unlimited. */
|
|
281
275
|
stock?: number;
|
|
282
276
|
/**
|
|
283
277
|
* Per-product override for the shop's stock-counter setting; `null` inherits.
|
|
@@ -294,27 +288,8 @@ interface Product {
|
|
|
294
288
|
*/
|
|
295
289
|
hideStockCounter?: boolean | null;
|
|
296
290
|
hide_stock_counter?: boolean | null;
|
|
297
|
-
/**
|
|
298
|
-
* Authoritative buyability predicate, mirrored from the backend's order-time
|
|
299
|
-
* gate: `local stock covers one unit OR an eligible supplier source can fulfil
|
|
300
|
-
* the line`. This — not `stock` — is what a storefront must gate the buy button,
|
|
301
|
-
* the quantity cap and the sold-out badge on.
|
|
302
|
-
*
|
|
303
|
-
* Absent on payloads that predate Dynamic Delivery. When absent, treat
|
|
304
|
-
* availability exactly as `stock` alone dictates; a missing field must never
|
|
305
|
-
* turn a genuinely sold-out product into a buyable one.
|
|
306
|
-
*/
|
|
291
|
+
/** Whether local stock and visibility allow this selection to be bought. */
|
|
307
292
|
orderable?: boolean;
|
|
308
|
-
/**
|
|
309
|
-
* True when an enabled supplier source fulfils this product instead of local
|
|
310
|
-
* stock. `orderable` remains the buy/sold-out gate; this field decides the
|
|
311
|
-
* QUANTITY CAP: the supplier purchase — not the local counter — fulfils the line
|
|
312
|
-
* and the completion excludes it from the local decrement, so residual local
|
|
313
|
-
* units bound nothing and the cap is unlimited even at `stock: 1`. Absent on
|
|
314
|
-
* payloads that predate Dynamic Delivery; when absent, the cap stays exactly
|
|
315
|
-
* what `stock` alone dictates.
|
|
316
|
-
*/
|
|
317
|
-
supplier_backed?: boolean;
|
|
318
293
|
quantity_min?: number;
|
|
319
294
|
quantity_max?: number;
|
|
320
295
|
min_quantity?: number;
|
|
@@ -411,32 +386,10 @@ interface ProductVariant {
|
|
|
411
386
|
price?: number;
|
|
412
387
|
/** The merchant's SKU for this option; null when they set none. */
|
|
413
388
|
sku?: string | null;
|
|
414
|
-
/**
|
|
415
|
-
* RAW local stock for this option only. `-1` (or any negative value) means
|
|
416
|
-
* unlimited, `0` means no local units — which a supplier-backed option reports
|
|
417
|
-
* by design. Never render this as a purchasable cap on its own; gate on
|
|
418
|
-
* {@link ProductVariant.orderable}.
|
|
419
|
-
*/
|
|
389
|
+
/** Local stock; a negative value means unlimited. */
|
|
420
390
|
stock?: number;
|
|
421
|
-
/**
|
|
422
|
-
* Authoritative buyability predicate for this option: `local stock covers one
|
|
423
|
-
* unit OR an eligible supplier source can fulfil the line`. The backend resolves
|
|
424
|
-
* a product-wide supplier mapping onto every variant's own flag, so this alone
|
|
425
|
-
* is authoritative for a selected variant.
|
|
426
|
-
*
|
|
427
|
-
* Absent on payloads that predate Dynamic Delivery; when absent, availability
|
|
428
|
-
* follows `stock` alone, exactly as before.
|
|
429
|
-
*/
|
|
391
|
+
/** Whether local stock and visibility allow this selection to be bought. */
|
|
430
392
|
orderable?: boolean;
|
|
431
|
-
/**
|
|
432
|
-
* True when an enabled supplier source fulfils this option instead of local
|
|
433
|
-
* stock. `orderable` remains the buy/sold-out gate; this field decides the
|
|
434
|
-
* QUANTITY CAP — a supplier-backed row is unbounded even when it still holds a
|
|
435
|
-
* few local units, because the supplier purchase fulfils the line and the
|
|
436
|
-
* completion excludes it from the local decrement. Absent on payloads that
|
|
437
|
-
* predate Dynamic Delivery.
|
|
438
|
-
*/
|
|
439
|
-
supplier_backed?: boolean;
|
|
440
393
|
quantity_min?: number;
|
|
441
394
|
quantity_max?: number;
|
|
442
395
|
quantityMin?: number;
|
|
@@ -479,32 +432,10 @@ interface PriceVariant {
|
|
|
479
432
|
price: number;
|
|
480
433
|
/** The merchant's SKU for this option; null when they set none. */
|
|
481
434
|
sku?: string | null;
|
|
482
|
-
/**
|
|
483
|
-
* RAW local stock for this price variant only. `-1` (or any negative value)
|
|
484
|
-
* means unlimited, `0` means no local units — which a supplier-backed variant
|
|
485
|
-
* reports by design. Never render this as a purchasable cap on its own; gate on
|
|
486
|
-
* {@link PriceVariant.orderable}.
|
|
487
|
-
*/
|
|
435
|
+
/** Local stock; a negative value means unlimited. */
|
|
488
436
|
stock?: number;
|
|
489
|
-
/**
|
|
490
|
-
* Authoritative buyability predicate for this price variant: `local stock covers
|
|
491
|
-
* one unit OR an eligible supplier source can fulfil the line`. The backend
|
|
492
|
-
* resolves a product-wide supplier mapping onto every variant's own flag, so
|
|
493
|
-
* this alone is authoritative for a selected variant.
|
|
494
|
-
*
|
|
495
|
-
* Absent on payloads that predate Dynamic Delivery; when absent, availability
|
|
496
|
-
* follows `stock` alone, exactly as before.
|
|
497
|
-
*/
|
|
437
|
+
/** Whether local stock and visibility allow this selection to be bought. */
|
|
498
438
|
orderable?: boolean;
|
|
499
|
-
/**
|
|
500
|
-
* True when an enabled supplier source fulfils this price variant instead of
|
|
501
|
-
* local stock. `orderable` remains the buy/sold-out gate; this field decides the
|
|
502
|
-
* QUANTITY CAP — a supplier-backed row is unbounded even when it still holds a
|
|
503
|
-
* few local units, because the supplier purchase fulfils the line and the
|
|
504
|
-
* completion excludes it from the local decrement. Absent on payloads that
|
|
505
|
-
* predate Dynamic Delivery.
|
|
506
|
-
*/
|
|
507
|
-
supplier_backed?: boolean;
|
|
508
439
|
quantity_min?: number;
|
|
509
440
|
quantity_max?: number;
|
|
510
441
|
quantityMin?: number;
|
|
@@ -1698,8 +1629,8 @@ declare function isStorefrontCheckboxCustomFieldValueChecked(value: string | und
|
|
|
1698
1629
|
declare function validateStorefrontCustomFieldValue(field: StorefrontCustomField, value: string): string | null;
|
|
1699
1630
|
declare function buildStorefrontCustomFieldPayload(fields: StorefrontCustomField[], values: Record<string, string>): Record<string, string>;
|
|
1700
1631
|
|
|
1701
|
-
type VariantLike = Pick<ProductVariant, 'stock' | 'orderable'
|
|
1702
|
-
type ProductLike = Pick<Product, 'type' | 'stock' | 'orderable' | '
|
|
1632
|
+
type VariantLike = Pick<ProductVariant, 'stock' | 'orderable'> | Pick<PriceVariant, 'stock' | 'orderable'>;
|
|
1633
|
+
type ProductLike = Pick<Product, 'type' | 'stock' | 'orderable' | 'on_hold' | 'price_variants' | 'variants'> & {
|
|
1703
1634
|
onHold?: boolean | number | string | null;
|
|
1704
1635
|
is_on_hold?: boolean | number | string | null;
|
|
1705
1636
|
isOnHold?: boolean | number | string | null;
|
package/dist/index.d.ts
CHANGED
|
@@ -271,13 +271,7 @@ interface Product {
|
|
|
271
271
|
price_display?: string;
|
|
272
272
|
price_discount?: number;
|
|
273
273
|
currency: string;
|
|
274
|
-
/**
|
|
275
|
-
* RAW local stock only. `-1` (or any negative value) means unlimited, `0` means
|
|
276
|
-
* no local units. This is NEVER on its own a purchasable cap: a supplier-backed
|
|
277
|
-
* product reports `stock: 0` by design and is still buyable. Gate buying on
|
|
278
|
-
* {@link Product.orderable}, and use `resolveDisplayStock` / `isProductInStock`
|
|
279
|
-
* rather than reading this field directly.
|
|
280
|
-
*/
|
|
274
|
+
/** Local stock; a negative value means unlimited. */
|
|
281
275
|
stock?: number;
|
|
282
276
|
/**
|
|
283
277
|
* Per-product override for the shop's stock-counter setting; `null` inherits.
|
|
@@ -294,27 +288,8 @@ interface Product {
|
|
|
294
288
|
*/
|
|
295
289
|
hideStockCounter?: boolean | null;
|
|
296
290
|
hide_stock_counter?: boolean | null;
|
|
297
|
-
/**
|
|
298
|
-
* Authoritative buyability predicate, mirrored from the backend's order-time
|
|
299
|
-
* gate: `local stock covers one unit OR an eligible supplier source can fulfil
|
|
300
|
-
* the line`. This — not `stock` — is what a storefront must gate the buy button,
|
|
301
|
-
* the quantity cap and the sold-out badge on.
|
|
302
|
-
*
|
|
303
|
-
* Absent on payloads that predate Dynamic Delivery. When absent, treat
|
|
304
|
-
* availability exactly as `stock` alone dictates; a missing field must never
|
|
305
|
-
* turn a genuinely sold-out product into a buyable one.
|
|
306
|
-
*/
|
|
291
|
+
/** Whether local stock and visibility allow this selection to be bought. */
|
|
307
292
|
orderable?: boolean;
|
|
308
|
-
/**
|
|
309
|
-
* True when an enabled supplier source fulfils this product instead of local
|
|
310
|
-
* stock. `orderable` remains the buy/sold-out gate; this field decides the
|
|
311
|
-
* QUANTITY CAP: the supplier purchase — not the local counter — fulfils the line
|
|
312
|
-
* and the completion excludes it from the local decrement, so residual local
|
|
313
|
-
* units bound nothing and the cap is unlimited even at `stock: 1`. Absent on
|
|
314
|
-
* payloads that predate Dynamic Delivery; when absent, the cap stays exactly
|
|
315
|
-
* what `stock` alone dictates.
|
|
316
|
-
*/
|
|
317
|
-
supplier_backed?: boolean;
|
|
318
293
|
quantity_min?: number;
|
|
319
294
|
quantity_max?: number;
|
|
320
295
|
min_quantity?: number;
|
|
@@ -411,32 +386,10 @@ interface ProductVariant {
|
|
|
411
386
|
price?: number;
|
|
412
387
|
/** The merchant's SKU for this option; null when they set none. */
|
|
413
388
|
sku?: string | null;
|
|
414
|
-
/**
|
|
415
|
-
* RAW local stock for this option only. `-1` (or any negative value) means
|
|
416
|
-
* unlimited, `0` means no local units — which a supplier-backed option reports
|
|
417
|
-
* by design. Never render this as a purchasable cap on its own; gate on
|
|
418
|
-
* {@link ProductVariant.orderable}.
|
|
419
|
-
*/
|
|
389
|
+
/** Local stock; a negative value means unlimited. */
|
|
420
390
|
stock?: number;
|
|
421
|
-
/**
|
|
422
|
-
* Authoritative buyability predicate for this option: `local stock covers one
|
|
423
|
-
* unit OR an eligible supplier source can fulfil the line`. The backend resolves
|
|
424
|
-
* a product-wide supplier mapping onto every variant's own flag, so this alone
|
|
425
|
-
* is authoritative for a selected variant.
|
|
426
|
-
*
|
|
427
|
-
* Absent on payloads that predate Dynamic Delivery; when absent, availability
|
|
428
|
-
* follows `stock` alone, exactly as before.
|
|
429
|
-
*/
|
|
391
|
+
/** Whether local stock and visibility allow this selection to be bought. */
|
|
430
392
|
orderable?: boolean;
|
|
431
|
-
/**
|
|
432
|
-
* True when an enabled supplier source fulfils this option instead of local
|
|
433
|
-
* stock. `orderable` remains the buy/sold-out gate; this field decides the
|
|
434
|
-
* QUANTITY CAP — a supplier-backed row is unbounded even when it still holds a
|
|
435
|
-
* few local units, because the supplier purchase fulfils the line and the
|
|
436
|
-
* completion excludes it from the local decrement. Absent on payloads that
|
|
437
|
-
* predate Dynamic Delivery.
|
|
438
|
-
*/
|
|
439
|
-
supplier_backed?: boolean;
|
|
440
393
|
quantity_min?: number;
|
|
441
394
|
quantity_max?: number;
|
|
442
395
|
quantityMin?: number;
|
|
@@ -479,32 +432,10 @@ interface PriceVariant {
|
|
|
479
432
|
price: number;
|
|
480
433
|
/** The merchant's SKU for this option; null when they set none. */
|
|
481
434
|
sku?: string | null;
|
|
482
|
-
/**
|
|
483
|
-
* RAW local stock for this price variant only. `-1` (or any negative value)
|
|
484
|
-
* means unlimited, `0` means no local units — which a supplier-backed variant
|
|
485
|
-
* reports by design. Never render this as a purchasable cap on its own; gate on
|
|
486
|
-
* {@link PriceVariant.orderable}.
|
|
487
|
-
*/
|
|
435
|
+
/** Local stock; a negative value means unlimited. */
|
|
488
436
|
stock?: number;
|
|
489
|
-
/**
|
|
490
|
-
* Authoritative buyability predicate for this price variant: `local stock covers
|
|
491
|
-
* one unit OR an eligible supplier source can fulfil the line`. The backend
|
|
492
|
-
* resolves a product-wide supplier mapping onto every variant's own flag, so
|
|
493
|
-
* this alone is authoritative for a selected variant.
|
|
494
|
-
*
|
|
495
|
-
* Absent on payloads that predate Dynamic Delivery; when absent, availability
|
|
496
|
-
* follows `stock` alone, exactly as before.
|
|
497
|
-
*/
|
|
437
|
+
/** Whether local stock and visibility allow this selection to be bought. */
|
|
498
438
|
orderable?: boolean;
|
|
499
|
-
/**
|
|
500
|
-
* True when an enabled supplier source fulfils this price variant instead of
|
|
501
|
-
* local stock. `orderable` remains the buy/sold-out gate; this field decides the
|
|
502
|
-
* QUANTITY CAP — a supplier-backed row is unbounded even when it still holds a
|
|
503
|
-
* few local units, because the supplier purchase fulfils the line and the
|
|
504
|
-
* completion excludes it from the local decrement. Absent on payloads that
|
|
505
|
-
* predate Dynamic Delivery.
|
|
506
|
-
*/
|
|
507
|
-
supplier_backed?: boolean;
|
|
508
439
|
quantity_min?: number;
|
|
509
440
|
quantity_max?: number;
|
|
510
441
|
quantityMin?: number;
|
|
@@ -1698,8 +1629,8 @@ declare function isStorefrontCheckboxCustomFieldValueChecked(value: string | und
|
|
|
1698
1629
|
declare function validateStorefrontCustomFieldValue(field: StorefrontCustomField, value: string): string | null;
|
|
1699
1630
|
declare function buildStorefrontCustomFieldPayload(fields: StorefrontCustomField[], values: Record<string, string>): Record<string, string>;
|
|
1700
1631
|
|
|
1701
|
-
type VariantLike = Pick<ProductVariant, 'stock' | 'orderable'
|
|
1702
|
-
type ProductLike = Pick<Product, 'type' | 'stock' | 'orderable' | '
|
|
1632
|
+
type VariantLike = Pick<ProductVariant, 'stock' | 'orderable'> | Pick<PriceVariant, 'stock' | 'orderable'>;
|
|
1633
|
+
type ProductLike = Pick<Product, 'type' | 'stock' | 'orderable' | 'on_hold' | 'price_variants' | 'variants'> & {
|
|
1703
1634
|
onHold?: boolean | number | string | null;
|
|
1704
1635
|
is_on_hold?: boolean | number | string | null;
|
|
1705
1636
|
isOnHold?: boolean | number | string | null;
|
package/dist/index.js
CHANGED
|
@@ -2472,12 +2472,7 @@ function priceVariantToProductVariant(variant) {
|
|
|
2472
2472
|
price: typeof variant.price === "number" ? variant.price : Number(variant.price) || 0,
|
|
2473
2473
|
sku: variant.sku,
|
|
2474
2474
|
stock: typeof variant.stock === "number" ? variant.stock : void 0,
|
|
2475
|
-
// Dynamic Delivery (S8): carry the availability pair through. A supplier-backed
|
|
2476
|
-
// variant reports `stock: 0`, so dropping `orderable` here would make the mapped
|
|
2477
|
-
// variant look sold out. Left `undefined` when the source omits it, which keeps
|
|
2478
|
-
// the historical stock-only behaviour for payloads that predate the field.
|
|
2479
2475
|
orderable: typeof variant.orderable === "boolean" ? variant.orderable : void 0,
|
|
2480
|
-
supplier_backed: typeof variant.supplier_backed === "boolean" ? variant.supplier_backed : void 0,
|
|
2481
2476
|
quantity_min: variant.quantity_min,
|
|
2482
2477
|
quantity_max: variant.quantity_max,
|
|
2483
2478
|
quantityMin: variant.quantityMin,
|
|
@@ -2668,6 +2663,16 @@ function isSafeHttpsRedirectTemplateUrl(url) {
|
|
|
2668
2663
|
}
|
|
2669
2664
|
}
|
|
2670
2665
|
|
|
2666
|
+
// ../contracts/src/storefront-consent-choice.ts
|
|
2667
|
+
var COOKIE_CONSENT_VERSION = 1;
|
|
2668
|
+
var COOKIE_CONSENT_COOKIE = "shoppex_consent";
|
|
2669
|
+
var COOKIE_CONSENT_CHECKOUT_HASH_KEY = "shoppex_consent";
|
|
2670
|
+
var COOKIE_CONSENT_VALUE = new RegExp(`^v${COOKIE_CONSENT_VERSION}\\.f([01])\\.a([01])\\.m([01])$`);
|
|
2671
|
+
function parseCookieConsentValue(value) {
|
|
2672
|
+
const match = value ? COOKIE_CONSENT_VALUE.exec(value) : null;
|
|
2673
|
+
return match ? { functional: match[1] === "1", analytics: match[2] === "1", marketing: match[3] === "1" } : null;
|
|
2674
|
+
}
|
|
2675
|
+
|
|
2671
2676
|
// ../sdk/src/modules/checkout.ts
|
|
2672
2677
|
var CheckoutCreateError = class _CheckoutCreateError extends Error {
|
|
2673
2678
|
constructor(message, options = {}) {
|
|
@@ -2832,10 +2837,16 @@ function buildCheckoutUrlFromInvoiceId(checkoutBaseUrl, invoiceId) {
|
|
|
2832
2837
|
return null;
|
|
2833
2838
|
}
|
|
2834
2839
|
}
|
|
2840
|
+
function readStorefrontConsentValue() {
|
|
2841
|
+
if (typeof document === "undefined" || typeof document.cookie !== "string") return null;
|
|
2842
|
+
const value = document.cookie.split(";").map((part) => part.trim()).find((part) => part.startsWith(`${COOKIE_CONSENT_COOKIE}=`))?.slice(COOKIE_CONSENT_COOKIE.length + 1);
|
|
2843
|
+
return parseCookieConsentValue(value) ? value : null;
|
|
2844
|
+
}
|
|
2835
2845
|
function appendCheckoutUrlOptions(checkoutUrl, options) {
|
|
2836
2846
|
const normalizedEmail = normalizeEmail(options.email);
|
|
2837
2847
|
const normalizedLocale = typeof options.locale === "string" ? options.locale.trim() : "";
|
|
2838
|
-
|
|
2848
|
+
const consent = readStorefrontConsentValue();
|
|
2849
|
+
if (!normalizedEmail && !normalizedLocale && !consent) {
|
|
2839
2850
|
return checkoutUrl;
|
|
2840
2851
|
}
|
|
2841
2852
|
try {
|
|
@@ -2843,9 +2854,10 @@ function appendCheckoutUrlOptions(checkoutUrl, options) {
|
|
|
2843
2854
|
if (normalizedLocale) {
|
|
2844
2855
|
parsedCheckoutUrl.searchParams.set("locale", normalizedLocale);
|
|
2845
2856
|
}
|
|
2846
|
-
if (normalizedEmail) {
|
|
2857
|
+
if (normalizedEmail || consent) {
|
|
2847
2858
|
const hashParams = new URLSearchParams(parsedCheckoutUrl.hash.startsWith("#") ? parsedCheckoutUrl.hash.slice(1) : parsedCheckoutUrl.hash);
|
|
2848
|
-
hashParams.set(CHECKOUT_PREFILL_EMAIL_HASH_KEY, normalizedEmail);
|
|
2859
|
+
if (normalizedEmail) hashParams.set(CHECKOUT_PREFILL_EMAIL_HASH_KEY, normalizedEmail);
|
|
2860
|
+
if (consent) hashParams.set(COOKIE_CONSENT_CHECKOUT_HASH_KEY, consent);
|
|
2849
2861
|
parsedCheckoutUrl.hash = hashParams.toString();
|
|
2850
2862
|
}
|
|
2851
2863
|
return parsedCheckoutUrl.toString();
|
|
@@ -3303,18 +3315,6 @@ async function getShopReviews() {
|
|
|
3303
3315
|
|
|
3304
3316
|
// ../sdk/src/utils/storefront-stock.ts
|
|
3305
3317
|
var UNLIMITED_STOCK = -1;
|
|
3306
|
-
function applyOrderable(stock, orderable, supplierBacked) {
|
|
3307
|
-
if (orderable !== true) {
|
|
3308
|
-
return stock;
|
|
3309
|
-
}
|
|
3310
|
-
if (supplierBacked === true) {
|
|
3311
|
-
return UNLIMITED_STOCK;
|
|
3312
|
-
}
|
|
3313
|
-
if (stock !== 0) {
|
|
3314
|
-
return stock;
|
|
3315
|
-
}
|
|
3316
|
-
return UNLIMITED_STOCK;
|
|
3317
|
-
}
|
|
3318
3318
|
function normalizeStockValue(value) {
|
|
3319
3319
|
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
3320
3320
|
return null;
|
|
@@ -3344,18 +3344,14 @@ function collectVariantStocks(product) {
|
|
|
3344
3344
|
}
|
|
3345
3345
|
function resolveVariantStockValue(variant) {
|
|
3346
3346
|
const normalized = normalizeStockValue(variant?.stock);
|
|
3347
|
-
return
|
|
3347
|
+
return normalized ?? UNLIMITED_STOCK;
|
|
3348
3348
|
}
|
|
3349
3349
|
function resolveDisplayStock(product) {
|
|
3350
3350
|
if (!product) {
|
|
3351
3351
|
return UNLIMITED_STOCK;
|
|
3352
3352
|
}
|
|
3353
3353
|
if (typeof product.type === "string" && product.type.toUpperCase() === "SERIALS") {
|
|
3354
|
-
return
|
|
3355
|
-
normalizeStockValue(product.stock) ?? UNLIMITED_STOCK,
|
|
3356
|
-
product.orderable,
|
|
3357
|
-
product.supplier_backed
|
|
3358
|
-
);
|
|
3354
|
+
return normalizeStockValue(product.stock) ?? UNLIMITED_STOCK;
|
|
3359
3355
|
}
|
|
3360
3356
|
const variantStocks = collectVariantStocks(product);
|
|
3361
3357
|
if (variantStocks.length > 0) {
|
|
@@ -3363,13 +3359,9 @@ function resolveDisplayStock(product) {
|
|
|
3363
3359
|
return UNLIMITED_STOCK;
|
|
3364
3360
|
}
|
|
3365
3361
|
const total = variantStocks.reduce((sum, stock) => sum + Math.max(stock, 0), 0);
|
|
3366
|
-
return
|
|
3362
|
+
return total;
|
|
3367
3363
|
}
|
|
3368
|
-
return
|
|
3369
|
-
normalizeStockValue(product.stock) ?? UNLIMITED_STOCK,
|
|
3370
|
-
product.orderable,
|
|
3371
|
-
product.supplier_backed
|
|
3372
|
-
);
|
|
3364
|
+
return normalizeStockValue(product.stock) ?? UNLIMITED_STOCK;
|
|
3373
3365
|
}
|
|
3374
3366
|
function isProductOutOfStock(product) {
|
|
3375
3367
|
if (isProductOnHold(product)) return true;
|