@bacano/sdk 1.2.4 → 1.2.6
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 +10 -7
- package/STOREFRONT_PERFORMANCE.md +12 -5
- package/graphql.cjs +59 -0
- package/graphql.js +59 -0
- package/index.cjs +102 -11
- package/index.js +102 -11
- package/package.json +1 -1
- package/react.cjs +102 -11
- package/react.js +102 -11
- package/skills/bacano-web/references/storefront.md +11 -0
- package/transport/documents.d.ts +10 -10
- package/types.d.ts +5 -2
package/README.md
CHANGED
|
@@ -288,10 +288,12 @@ await client.init();
|
|
|
288
288
|
|
|
289
289
|
### 3. Browse Products (No Auth Required)
|
|
290
290
|
|
|
291
|
-
`catalog.getProducts()`
|
|
292
|
-
website branch
|
|
293
|
-
|
|
294
|
-
|
|
291
|
+
`catalog.getProducts()` returns products that are active, published for the
|
|
292
|
+
website, enabled for its branch and have a valid `CLIENT` price. By default it
|
|
293
|
+
excludes sold-out products, but a website may show them globally or override
|
|
294
|
+
that choice per published product. The SDK applies this rule; a visible
|
|
295
|
+
sold-out product remains unavailable for purchase. Websites without custom
|
|
296
|
+
inventory sources continue using the branch's default warehouse.
|
|
295
297
|
|
|
296
298
|
```typescript
|
|
297
299
|
// List products
|
|
@@ -317,7 +319,7 @@ const affordable = await client.catalog.getProducts({
|
|
|
317
319
|
maxPrice: 50,
|
|
318
320
|
});
|
|
319
321
|
|
|
320
|
-
//
|
|
322
|
+
// Strictly in-stock, even if this website displays sold-out products.
|
|
321
323
|
const available = await client.catalog.getProducts({ inStock: true });
|
|
322
324
|
|
|
323
325
|
// Filter by color
|
|
@@ -353,7 +355,7 @@ const filtered = await client.catalog.getProducts({
|
|
|
353
355
|
// Single product
|
|
354
356
|
const product = await client.catalog.getProduct("product-uuid");
|
|
355
357
|
|
|
356
|
-
// Static builds: fetch the complete
|
|
358
|
+
// Static builds: fetch the complete visible catalog and its first renderable
|
|
357
359
|
// catalog page. This is the canonical source for initial HTML, routes,
|
|
358
360
|
// metadata, sitemap and product page data.
|
|
359
361
|
const bootstrap = await client.catalog.getStaticCatalogBootstrap({
|
|
@@ -369,7 +371,8 @@ const productByRoute = new Map(
|
|
|
369
371
|
bootstrap.products.map((item) => [item.slug || item.id, item]),
|
|
370
372
|
);
|
|
371
373
|
|
|
372
|
-
// Cards and filters use product.variants.
|
|
374
|
+
// Cards and filters use product.variants. These can include sold-out variants
|
|
375
|
+
// if the website permits their display. Detail selectors use the official
|
|
373
376
|
// helper so sold-out sizes remain visible and older snapshots stay compatible.
|
|
374
377
|
const detailVariants = getProductDetailVariants(product!);
|
|
375
378
|
|
|
@@ -49,9 +49,11 @@ if this contract fails; they must not silently publish an empty catalog.
|
|
|
49
49
|
|
|
50
50
|
The static bootstrap deliberately exposes two projections on each product:
|
|
51
51
|
|
|
52
|
-
- `product.variants` contains
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
- `product.variants` contains variants eligible for this website's listings.
|
|
53
|
+
It can include sold-out variants when the website setting or this product's
|
|
54
|
+
per-website exception allows them to remain visible. Cards, price ranges,
|
|
55
|
+
filters and listing visibility must use this projection; visibility is not
|
|
56
|
+
permission to purchase.
|
|
55
57
|
- `product.detailVariants` also contains enabled, published variants with a
|
|
56
58
|
public price that are currently sold out. Product detail selectors must use
|
|
57
59
|
this projection so a customer can see unavailable sizes instead of assuming
|
|
@@ -71,8 +73,13 @@ const liveState = await client.catalog.getProductLiveState(
|
|
|
71
73
|
`getProduct()` and `getProductBySlug()` expose the complete detail projection
|
|
72
74
|
through `variants` as well. A sold-out variant returns `inStock: false` and
|
|
73
75
|
`maxPurchasableQuantity: 0` from live state. Never use `detailVariants` to
|
|
74
|
-
calculate a card's minimum price or
|
|
75
|
-
|
|
76
|
+
calculate a card's minimum price or independently decide whether a completely
|
|
77
|
+
sold-out product belongs in listings. The SDK applies the website rule and the
|
|
78
|
+
product's per-website exception to listings, static routes, search suggestions
|
|
79
|
+
and recommendations. `getProducts({ inStock: true })` remains strictly
|
|
80
|
+
in-stock. The public SDK reads these rules; their administration belongs in
|
|
81
|
+
Bacano. Changing them requires rebuilding static routes and catalog HTML;
|
|
82
|
+
live-state refresh cannot add a route missing from the build.
|
|
76
83
|
|
|
77
84
|
## Live price and availability
|
|
78
85
|
|
package/graphql.cjs
CHANGED
|
@@ -122,6 +122,12 @@ var GET_PRODUCTS = (
|
|
|
122
122
|
id
|
|
123
123
|
name
|
|
124
124
|
description
|
|
125
|
+
product_website_publications(
|
|
126
|
+
where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }
|
|
127
|
+
limit: 1
|
|
128
|
+
) {
|
|
129
|
+
show_when_out_of_stock
|
|
130
|
+
}
|
|
125
131
|
long_description
|
|
126
132
|
slug
|
|
127
133
|
seo_title
|
|
@@ -357,6 +363,12 @@ var GET_PRODUCT_BY_PK = (
|
|
|
357
363
|
limit: 1
|
|
358
364
|
) {
|
|
359
365
|
id
|
|
366
|
+
product_website_publications(
|
|
367
|
+
where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }
|
|
368
|
+
limit: 1
|
|
369
|
+
) {
|
|
370
|
+
show_when_out_of_stock
|
|
371
|
+
}
|
|
360
372
|
product_option_group_members(limit: 1) {
|
|
361
373
|
group {
|
|
362
374
|
id
|
|
@@ -606,6 +618,12 @@ var GET_PRODUCT_SEO_ENTRIES = (
|
|
|
606
618
|
id
|
|
607
619
|
name
|
|
608
620
|
slug
|
|
621
|
+
product_website_publications(
|
|
622
|
+
where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }
|
|
623
|
+
limit: 1
|
|
624
|
+
) {
|
|
625
|
+
show_when_out_of_stock
|
|
626
|
+
}
|
|
609
627
|
seo_title
|
|
610
628
|
seo_description
|
|
611
629
|
seo_image_file_id
|
|
@@ -2108,6 +2126,7 @@ var GET_PRODUCT_FILTERS = (
|
|
|
2108
2126
|
query GetProductFilters(
|
|
2109
2127
|
$companyId: uuid!
|
|
2110
2128
|
$chainId: uuid!
|
|
2129
|
+
$websiteId: uuid!
|
|
2111
2130
|
$where: products_bool_exp = {}
|
|
2112
2131
|
$attributeListKey: String!
|
|
2113
2132
|
) {
|
|
@@ -2115,6 +2134,12 @@ var GET_PRODUCT_FILTERS = (
|
|
|
2115
2134
|
where: {
|
|
2116
2135
|
_and: [
|
|
2117
2136
|
{ company_id: { _eq: $companyId } }
|
|
2137
|
+
{
|
|
2138
|
+
product_website_publications: {
|
|
2139
|
+
website_id: { _eq: $websiteId }
|
|
2140
|
+
is_visible: { _eq: true }
|
|
2141
|
+
}
|
|
2142
|
+
}
|
|
2118
2143
|
{
|
|
2119
2144
|
chain_products: {
|
|
2120
2145
|
chain_id: { _eq: $chainId }
|
|
@@ -2127,6 +2152,12 @@ var GET_PRODUCT_FILTERS = (
|
|
|
2127
2152
|
}
|
|
2128
2153
|
) {
|
|
2129
2154
|
id
|
|
2155
|
+
product_website_publications(
|
|
2156
|
+
where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }
|
|
2157
|
+
limit: 1
|
|
2158
|
+
) {
|
|
2159
|
+
show_when_out_of_stock
|
|
2160
|
+
}
|
|
2130
2161
|
category
|
|
2131
2162
|
subcategory
|
|
2132
2163
|
color
|
|
@@ -2234,6 +2265,7 @@ var GET_SEARCH_SUGGESTIONS = (
|
|
|
2234
2265
|
query GetSearchSuggestions(
|
|
2235
2266
|
$companyId: uuid!
|
|
2236
2267
|
$chainId: uuid!
|
|
2268
|
+
$websiteId: uuid!
|
|
2237
2269
|
$term: String!
|
|
2238
2270
|
$productLimit: Int = 5
|
|
2239
2271
|
$brandLimit: Int = 3
|
|
@@ -2241,6 +2273,10 @@ var GET_SEARCH_SUGGESTIONS = (
|
|
|
2241
2273
|
products(
|
|
2242
2274
|
where: {
|
|
2243
2275
|
company_id: { _eq: $companyId }
|
|
2276
|
+
product_website_publications: {
|
|
2277
|
+
website_id: { _eq: $websiteId }
|
|
2278
|
+
is_visible: { _eq: true }
|
|
2279
|
+
}
|
|
2244
2280
|
chain_products: {
|
|
2245
2281
|
chain_id: { _eq: $chainId }
|
|
2246
2282
|
is_enabled: { _eq: true }
|
|
@@ -2253,6 +2289,29 @@ var GET_SEARCH_SUGGESTIONS = (
|
|
|
2253
2289
|
) {
|
|
2254
2290
|
id
|
|
2255
2291
|
name
|
|
2292
|
+
product_website_publications(
|
|
2293
|
+
where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }
|
|
2294
|
+
limit: 1
|
|
2295
|
+
) {
|
|
2296
|
+
show_when_out_of_stock
|
|
2297
|
+
}
|
|
2298
|
+
product_variants(where: { is_disabled: { _eq: false } }) {
|
|
2299
|
+
id
|
|
2300
|
+
product_variant_prices(
|
|
2301
|
+
where: {
|
|
2302
|
+
price_type: { _eq: CLIENT }
|
|
2303
|
+
_or: [
|
|
2304
|
+
{ chain_id: { _eq: $chainId } }
|
|
2305
|
+
{ chain_id: { _is_null: true } }
|
|
2306
|
+
]
|
|
2307
|
+
}
|
|
2308
|
+
) {
|
|
2309
|
+
id
|
|
2310
|
+
price
|
|
2311
|
+
price_type
|
|
2312
|
+
chain_id
|
|
2313
|
+
}
|
|
2314
|
+
}
|
|
2256
2315
|
}
|
|
2257
2316
|
brands(
|
|
2258
2317
|
where: {
|
package/graphql.js
CHANGED
|
@@ -62,6 +62,12 @@ var GET_PRODUCTS = (
|
|
|
62
62
|
id
|
|
63
63
|
name
|
|
64
64
|
description
|
|
65
|
+
product_website_publications(
|
|
66
|
+
where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }
|
|
67
|
+
limit: 1
|
|
68
|
+
) {
|
|
69
|
+
show_when_out_of_stock
|
|
70
|
+
}
|
|
65
71
|
long_description
|
|
66
72
|
slug
|
|
67
73
|
seo_title
|
|
@@ -297,6 +303,12 @@ var GET_PRODUCT_BY_PK = (
|
|
|
297
303
|
limit: 1
|
|
298
304
|
) {
|
|
299
305
|
id
|
|
306
|
+
product_website_publications(
|
|
307
|
+
where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }
|
|
308
|
+
limit: 1
|
|
309
|
+
) {
|
|
310
|
+
show_when_out_of_stock
|
|
311
|
+
}
|
|
300
312
|
product_option_group_members(limit: 1) {
|
|
301
313
|
group {
|
|
302
314
|
id
|
|
@@ -546,6 +558,12 @@ var GET_PRODUCT_SEO_ENTRIES = (
|
|
|
546
558
|
id
|
|
547
559
|
name
|
|
548
560
|
slug
|
|
561
|
+
product_website_publications(
|
|
562
|
+
where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }
|
|
563
|
+
limit: 1
|
|
564
|
+
) {
|
|
565
|
+
show_when_out_of_stock
|
|
566
|
+
}
|
|
549
567
|
seo_title
|
|
550
568
|
seo_description
|
|
551
569
|
seo_image_file_id
|
|
@@ -2048,6 +2066,7 @@ var GET_PRODUCT_FILTERS = (
|
|
|
2048
2066
|
query GetProductFilters(
|
|
2049
2067
|
$companyId: uuid!
|
|
2050
2068
|
$chainId: uuid!
|
|
2069
|
+
$websiteId: uuid!
|
|
2051
2070
|
$where: products_bool_exp = {}
|
|
2052
2071
|
$attributeListKey: String!
|
|
2053
2072
|
) {
|
|
@@ -2055,6 +2074,12 @@ var GET_PRODUCT_FILTERS = (
|
|
|
2055
2074
|
where: {
|
|
2056
2075
|
_and: [
|
|
2057
2076
|
{ company_id: { _eq: $companyId } }
|
|
2077
|
+
{
|
|
2078
|
+
product_website_publications: {
|
|
2079
|
+
website_id: { _eq: $websiteId }
|
|
2080
|
+
is_visible: { _eq: true }
|
|
2081
|
+
}
|
|
2082
|
+
}
|
|
2058
2083
|
{
|
|
2059
2084
|
chain_products: {
|
|
2060
2085
|
chain_id: { _eq: $chainId }
|
|
@@ -2067,6 +2092,12 @@ var GET_PRODUCT_FILTERS = (
|
|
|
2067
2092
|
}
|
|
2068
2093
|
) {
|
|
2069
2094
|
id
|
|
2095
|
+
product_website_publications(
|
|
2096
|
+
where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }
|
|
2097
|
+
limit: 1
|
|
2098
|
+
) {
|
|
2099
|
+
show_when_out_of_stock
|
|
2100
|
+
}
|
|
2070
2101
|
category
|
|
2071
2102
|
subcategory
|
|
2072
2103
|
color
|
|
@@ -2174,6 +2205,7 @@ var GET_SEARCH_SUGGESTIONS = (
|
|
|
2174
2205
|
query GetSearchSuggestions(
|
|
2175
2206
|
$companyId: uuid!
|
|
2176
2207
|
$chainId: uuid!
|
|
2208
|
+
$websiteId: uuid!
|
|
2177
2209
|
$term: String!
|
|
2178
2210
|
$productLimit: Int = 5
|
|
2179
2211
|
$brandLimit: Int = 3
|
|
@@ -2181,6 +2213,10 @@ var GET_SEARCH_SUGGESTIONS = (
|
|
|
2181
2213
|
products(
|
|
2182
2214
|
where: {
|
|
2183
2215
|
company_id: { _eq: $companyId }
|
|
2216
|
+
product_website_publications: {
|
|
2217
|
+
website_id: { _eq: $websiteId }
|
|
2218
|
+
is_visible: { _eq: true }
|
|
2219
|
+
}
|
|
2184
2220
|
chain_products: {
|
|
2185
2221
|
chain_id: { _eq: $chainId }
|
|
2186
2222
|
is_enabled: { _eq: true }
|
|
@@ -2193,6 +2229,29 @@ var GET_SEARCH_SUGGESTIONS = (
|
|
|
2193
2229
|
) {
|
|
2194
2230
|
id
|
|
2195
2231
|
name
|
|
2232
|
+
product_website_publications(
|
|
2233
|
+
where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }
|
|
2234
|
+
limit: 1
|
|
2235
|
+
) {
|
|
2236
|
+
show_when_out_of_stock
|
|
2237
|
+
}
|
|
2238
|
+
product_variants(where: { is_disabled: { _eq: false } }) {
|
|
2239
|
+
id
|
|
2240
|
+
product_variant_prices(
|
|
2241
|
+
where: {
|
|
2242
|
+
price_type: { _eq: CLIENT }
|
|
2243
|
+
_or: [
|
|
2244
|
+
{ chain_id: { _eq: $chainId } }
|
|
2245
|
+
{ chain_id: { _is_null: true } }
|
|
2246
|
+
]
|
|
2247
|
+
}
|
|
2248
|
+
) {
|
|
2249
|
+
id
|
|
2250
|
+
price
|
|
2251
|
+
price_type
|
|
2252
|
+
chain_id
|
|
2253
|
+
}
|
|
2254
|
+
}
|
|
2196
2255
|
}
|
|
2197
2256
|
brands(
|
|
2198
2257
|
where: {
|
package/index.cjs
CHANGED
|
@@ -551,6 +551,12 @@ var GET_PRODUCTS = (
|
|
|
551
551
|
id
|
|
552
552
|
name
|
|
553
553
|
description
|
|
554
|
+
product_website_publications(
|
|
555
|
+
where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }
|
|
556
|
+
limit: 1
|
|
557
|
+
) {
|
|
558
|
+
show_when_out_of_stock
|
|
559
|
+
}
|
|
554
560
|
long_description
|
|
555
561
|
slug
|
|
556
562
|
seo_title
|
|
@@ -786,6 +792,12 @@ var GET_PRODUCT_BY_PK = (
|
|
|
786
792
|
limit: 1
|
|
787
793
|
) {
|
|
788
794
|
id
|
|
795
|
+
product_website_publications(
|
|
796
|
+
where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }
|
|
797
|
+
limit: 1
|
|
798
|
+
) {
|
|
799
|
+
show_when_out_of_stock
|
|
800
|
+
}
|
|
789
801
|
product_option_group_members(limit: 1) {
|
|
790
802
|
group {
|
|
791
803
|
id
|
|
@@ -1035,6 +1047,12 @@ var GET_PRODUCT_SEO_ENTRIES = (
|
|
|
1035
1047
|
id
|
|
1036
1048
|
name
|
|
1037
1049
|
slug
|
|
1050
|
+
product_website_publications(
|
|
1051
|
+
where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }
|
|
1052
|
+
limit: 1
|
|
1053
|
+
) {
|
|
1054
|
+
show_when_out_of_stock
|
|
1055
|
+
}
|
|
1038
1056
|
seo_title
|
|
1039
1057
|
seo_description
|
|
1040
1058
|
seo_image_file_id
|
|
@@ -2668,6 +2686,7 @@ var GET_PRODUCT_FILTERS = (
|
|
|
2668
2686
|
query GetProductFilters(
|
|
2669
2687
|
$companyId: uuid!
|
|
2670
2688
|
$chainId: uuid!
|
|
2689
|
+
$websiteId: uuid!
|
|
2671
2690
|
$where: products_bool_exp = {}
|
|
2672
2691
|
$attributeListKey: String!
|
|
2673
2692
|
) {
|
|
@@ -2675,6 +2694,12 @@ var GET_PRODUCT_FILTERS = (
|
|
|
2675
2694
|
where: {
|
|
2676
2695
|
_and: [
|
|
2677
2696
|
{ company_id: { _eq: $companyId } }
|
|
2697
|
+
{
|
|
2698
|
+
product_website_publications: {
|
|
2699
|
+
website_id: { _eq: $websiteId }
|
|
2700
|
+
is_visible: { _eq: true }
|
|
2701
|
+
}
|
|
2702
|
+
}
|
|
2678
2703
|
{
|
|
2679
2704
|
chain_products: {
|
|
2680
2705
|
chain_id: { _eq: $chainId }
|
|
@@ -2687,6 +2712,12 @@ var GET_PRODUCT_FILTERS = (
|
|
|
2687
2712
|
}
|
|
2688
2713
|
) {
|
|
2689
2714
|
id
|
|
2715
|
+
product_website_publications(
|
|
2716
|
+
where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }
|
|
2717
|
+
limit: 1
|
|
2718
|
+
) {
|
|
2719
|
+
show_when_out_of_stock
|
|
2720
|
+
}
|
|
2690
2721
|
category
|
|
2691
2722
|
subcategory
|
|
2692
2723
|
color
|
|
@@ -2794,6 +2825,7 @@ var GET_SEARCH_SUGGESTIONS = (
|
|
|
2794
2825
|
query GetSearchSuggestions(
|
|
2795
2826
|
$companyId: uuid!
|
|
2796
2827
|
$chainId: uuid!
|
|
2828
|
+
$websiteId: uuid!
|
|
2797
2829
|
$term: String!
|
|
2798
2830
|
$productLimit: Int = 5
|
|
2799
2831
|
$brandLimit: Int = 3
|
|
@@ -2801,6 +2833,10 @@ var GET_SEARCH_SUGGESTIONS = (
|
|
|
2801
2833
|
products(
|
|
2802
2834
|
where: {
|
|
2803
2835
|
company_id: { _eq: $companyId }
|
|
2836
|
+
product_website_publications: {
|
|
2837
|
+
website_id: { _eq: $websiteId }
|
|
2838
|
+
is_visible: { _eq: true }
|
|
2839
|
+
}
|
|
2804
2840
|
chain_products: {
|
|
2805
2841
|
chain_id: { _eq: $chainId }
|
|
2806
2842
|
is_enabled: { _eq: true }
|
|
@@ -2813,6 +2849,29 @@ var GET_SEARCH_SUGGESTIONS = (
|
|
|
2813
2849
|
) {
|
|
2814
2850
|
id
|
|
2815
2851
|
name
|
|
2852
|
+
product_website_publications(
|
|
2853
|
+
where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }
|
|
2854
|
+
limit: 1
|
|
2855
|
+
) {
|
|
2856
|
+
show_when_out_of_stock
|
|
2857
|
+
}
|
|
2858
|
+
product_variants(where: { is_disabled: { _eq: false } }) {
|
|
2859
|
+
id
|
|
2860
|
+
product_variant_prices(
|
|
2861
|
+
where: {
|
|
2862
|
+
price_type: { _eq: CLIENT }
|
|
2863
|
+
_or: [
|
|
2864
|
+
{ chain_id: { _eq: $chainId } }
|
|
2865
|
+
{ chain_id: { _is_null: true } }
|
|
2866
|
+
]
|
|
2867
|
+
}
|
|
2868
|
+
) {
|
|
2869
|
+
id
|
|
2870
|
+
price
|
|
2871
|
+
price_type
|
|
2872
|
+
chain_id
|
|
2873
|
+
}
|
|
2874
|
+
}
|
|
2816
2875
|
}
|
|
2817
2876
|
brands(
|
|
2818
2877
|
where: {
|
|
@@ -3972,6 +4031,7 @@ function mapProduct(raw, storageUrl, labels, chainId) {
|
|
|
3972
4031
|
createdAt: raw.created_at,
|
|
3973
4032
|
updatedAt: raw.updated_at ?? raw.created_at,
|
|
3974
4033
|
variants,
|
|
4034
|
+
outOfStockVisibilityOverride: raw.product_website_publications?.[0]?.show_when_out_of_stock ?? null,
|
|
3975
4035
|
detailVariants,
|
|
3976
4036
|
media: raw.product_media.map((m) => mapMedia(m, storageUrl)),
|
|
3977
4037
|
attributes: raw.product_attributes.map(
|
|
@@ -4333,7 +4393,7 @@ async function getWebsiteAvailabilityByVariantId(graphqlUrl, getHeaders, variant
|
|
|
4333
4393
|
}
|
|
4334
4394
|
return availabilityByVariantId;
|
|
4335
4395
|
}
|
|
4336
|
-
async function filterProductsForWebsiteStock(graphqlUrl, getHeaders, products, chainId, websiteId) {
|
|
4396
|
+
async function filterProductsForWebsiteStock(graphqlUrl, getHeaders, products, chainId, websiteId, showOutOfStockByDefault = false, onlyInStock = false) {
|
|
4337
4397
|
const variantIds = products.flatMap(
|
|
4338
4398
|
(product) => product.variants.map((variant) => variant.id)
|
|
4339
4399
|
);
|
|
@@ -4359,11 +4419,11 @@ async function filterProductsForWebsiteStock(graphqlUrl, getHeaders, products, c
|
|
|
4359
4419
|
pricing: resolveProductPricing(prices)
|
|
4360
4420
|
};
|
|
4361
4421
|
}).filter(
|
|
4362
|
-
(variant) => inStockVariantIds.has(variant.id) && variant.pricing.currentPrice != null
|
|
4422
|
+
(variant) => (inStockVariantIds.has(variant.id) || !onlyInStock && (product.outOfStockVisibilityOverride ?? showOutOfStockByDefault)) && variant.pricing.currentPrice != null
|
|
4363
4423
|
)
|
|
4364
4424
|
})).filter((product) => product.variants.length > 0);
|
|
4365
4425
|
}
|
|
4366
|
-
async function filterSeoProductsForWebsiteStock(graphqlUrl, getHeaders, products, chainId, websiteId) {
|
|
4426
|
+
async function filterSeoProductsForWebsiteStock(graphqlUrl, getHeaders, products, chainId, websiteId, showOutOfStockByDefault = false) {
|
|
4367
4427
|
const variantIds = products.flatMap(
|
|
4368
4428
|
(product) => product.product_variants.map((variant) => variant.id)
|
|
4369
4429
|
);
|
|
@@ -4385,7 +4445,7 @@ async function filterSeoProductsForWebsiteStock(graphqlUrl, getHeaders, products
|
|
|
4385
4445
|
const pricing = resolveProductPricing(
|
|
4386
4446
|
selectPublicPrices(prices, chainId)
|
|
4387
4447
|
);
|
|
4388
|
-
return inStockVariantIds.has(variant.id) && pricing.currentPrice != null;
|
|
4448
|
+
return (inStockVariantIds.has(variant.id) || (product.product_website_publications?.[0]?.show_when_out_of_stock ?? showOutOfStockByDefault)) && pricing.currentPrice != null;
|
|
4389
4449
|
})
|
|
4390
4450
|
);
|
|
4391
4451
|
}
|
|
@@ -4456,7 +4516,8 @@ function createCatalogModule(graphqlUrl, getHeaders, getContext, storageUrl) {
|
|
|
4456
4516
|
getHeaders,
|
|
4457
4517
|
[mappedProduct],
|
|
4458
4518
|
ctx.chainId,
|
|
4459
|
-
ctx.websiteId
|
|
4519
|
+
ctx.websiteId,
|
|
4520
|
+
ctx.config?.show_out_of_stock_products === true
|
|
4460
4521
|
);
|
|
4461
4522
|
if (!filteredProducts[0]) return null;
|
|
4462
4523
|
const specifications = await loadProductSpecifications([product.id]);
|
|
@@ -4689,7 +4750,8 @@ function createCatalogModule(graphqlUrl, getHeaders, getContext, storageUrl) {
|
|
|
4689
4750
|
getHeaders,
|
|
4690
4751
|
data.products ?? [],
|
|
4691
4752
|
ctx.chainId,
|
|
4692
|
-
ctx.websiteId
|
|
4753
|
+
ctx.websiteId,
|
|
4754
|
+
ctx.config?.show_out_of_stock_products === true
|
|
4693
4755
|
);
|
|
4694
4756
|
const entries = availableProducts.slice(0, limit).map((product) => mapProductSeoEntry(product, storageUrl)).filter((entry) => Boolean(entry));
|
|
4695
4757
|
return {
|
|
@@ -4766,7 +4828,9 @@ function createCatalogModule(graphqlUrl, getHeaders, getContext, storageUrl) {
|
|
|
4766
4828
|
(p) => mapProduct(p, storageUrl, publicAttributeLabels, chainId)
|
|
4767
4829
|
),
|
|
4768
4830
|
chainId,
|
|
4769
|
-
ctx.websiteId
|
|
4831
|
+
ctx.websiteId,
|
|
4832
|
+
ctx.config?.show_out_of_stock_products === true,
|
|
4833
|
+
opts?.inStock === true
|
|
4770
4834
|
);
|
|
4771
4835
|
const specifications = await loadProductSpecifications(
|
|
4772
4836
|
products.map((product) => product.id)
|
|
@@ -4873,6 +4937,7 @@ function createCatalogModule(graphqlUrl, getHeaders, getContext, storageUrl) {
|
|
|
4873
4937
|
{
|
|
4874
4938
|
companyId: ctx.companyId,
|
|
4875
4939
|
chainId,
|
|
4940
|
+
websiteId: ctx.websiteId,
|
|
4876
4941
|
attributeListKey: DEFAULT_FILTER_ATTRIBUTE_LIST_KEY,
|
|
4877
4942
|
where: buildProductWhere(opts.filters ?? {}, chainId)
|
|
4878
4943
|
},
|
|
@@ -4896,7 +4961,7 @@ function createCatalogModule(graphqlUrl, getHeaders, getContext, storageUrl) {
|
|
|
4896
4961
|
variant.product_variant_prices.map(mapPrice),
|
|
4897
4962
|
chainId
|
|
4898
4963
|
);
|
|
4899
|
-
return prices.length > 0 && (availabilityByVariantId.get(variant.id)?.inStock ?? false);
|
|
4964
|
+
return prices.length > 0 && ((availabilityByVariantId.get(variant.id)?.inStock ?? false) || (product.product_website_publications?.[0]?.show_when_out_of_stock ?? ctx.config?.show_out_of_stock_products === true));
|
|
4900
4965
|
});
|
|
4901
4966
|
if (!hasVisibleVariant) continue;
|
|
4902
4967
|
applicableCategories.add(product.category);
|
|
@@ -4984,6 +5049,7 @@ function createCatalogModule(graphqlUrl, getHeaders, getContext, storageUrl) {
|
|
|
4984
5049
|
{
|
|
4985
5050
|
companyId: ctx.companyId,
|
|
4986
5051
|
chainId,
|
|
5052
|
+
websiteId: ctx.websiteId,
|
|
4987
5053
|
attributeListKey: opts?.attributeListKey ?? DEFAULT_FILTER_ATTRIBUTE_LIST_KEY,
|
|
4988
5054
|
where: {
|
|
4989
5055
|
...opts?.categoryName ? { category: { _eq: opts.categoryName } } : {},
|
|
@@ -5038,7 +5104,9 @@ function createCatalogModule(graphqlUrl, getHeaders, getContext, storageUrl) {
|
|
|
5038
5104
|
chainId
|
|
5039
5105
|
),
|
|
5040
5106
|
inStock: availabilityByVariantId.get(variant.id)?.inStock ?? false
|
|
5041
|
-
})).filter(
|
|
5107
|
+
})).filter(
|
|
5108
|
+
(variant) => (variant.inStock || (product.product_website_publications?.[0]?.show_when_out_of_stock ?? ctx.config?.show_out_of_stock_products === true)) && variant.prices.length > 0
|
|
5109
|
+
);
|
|
5042
5110
|
if (visibleVariants.length === 0) continue;
|
|
5043
5111
|
categoryCounts.set(
|
|
5044
5112
|
product.category,
|
|
@@ -5123,6 +5191,7 @@ function createCatalogModule(graphqlUrl, getHeaders, getContext, storageUrl) {
|
|
|
5123
5191
|
"NO_CHAIN"
|
|
5124
5192
|
);
|
|
5125
5193
|
}
|
|
5194
|
+
const chainId = ctx.chainId;
|
|
5126
5195
|
const term = `%${opts.query}%`;
|
|
5127
5196
|
const limit = opts.limit ?? 8;
|
|
5128
5197
|
const data = await executeGraphQL(
|
|
@@ -5130,7 +5199,8 @@ function createCatalogModule(graphqlUrl, getHeaders, getContext, storageUrl) {
|
|
|
5130
5199
|
GET_SEARCH_SUGGESTIONS,
|
|
5131
5200
|
{
|
|
5132
5201
|
companyId: ctx.companyId,
|
|
5133
|
-
chainId
|
|
5202
|
+
chainId,
|
|
5203
|
+
websiteId: ctx.websiteId,
|
|
5134
5204
|
term,
|
|
5135
5205
|
productLimit: Math.min(limit, 5),
|
|
5136
5206
|
brandLimit: Math.max(limit - 5, 3)
|
|
@@ -5138,8 +5208,29 @@ function createCatalogModule(graphqlUrl, getHeaders, getContext, storageUrl) {
|
|
|
5138
5208
|
getHeaders
|
|
5139
5209
|
);
|
|
5140
5210
|
const suggestions = [];
|
|
5211
|
+
const availability = await getWebsiteAvailabilityByVariantId(
|
|
5212
|
+
graphqlUrl,
|
|
5213
|
+
getHeaders,
|
|
5214
|
+
(data.products ?? []).flatMap(
|
|
5215
|
+
(product) => product.product_variants.map((variant) => variant.id)
|
|
5216
|
+
),
|
|
5217
|
+
chainId,
|
|
5218
|
+
ctx.websiteId
|
|
5219
|
+
);
|
|
5141
5220
|
for (const p of data.products ?? []) {
|
|
5142
|
-
|
|
5221
|
+
const showWithoutStock = p.product_website_publications?.[0]?.show_when_out_of_stock ?? ctx.config?.show_out_of_stock_products === true;
|
|
5222
|
+
const isVisible = p.product_variants.some((variant) => {
|
|
5223
|
+
const hasPrice = resolveProductPricing(
|
|
5224
|
+
selectPublicPrices(
|
|
5225
|
+
variant.product_variant_prices.map(mapPrice),
|
|
5226
|
+
chainId
|
|
5227
|
+
)
|
|
5228
|
+
).currentPrice != null;
|
|
5229
|
+
return hasPrice && (showWithoutStock || availability.get(variant.id)?.inStock === true);
|
|
5230
|
+
});
|
|
5231
|
+
if (isVisible) {
|
|
5232
|
+
suggestions.push({ type: "product", text: p.name, id: p.id });
|
|
5233
|
+
}
|
|
5143
5234
|
}
|
|
5144
5235
|
for (const b of data.brands ?? []) {
|
|
5145
5236
|
suggestions.push({ type: "brand", text: b.name, id: b.id });
|