@cobrastyle/adapter-magento2 1.0.1 → 1.1.1
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/LICENSE +1 -2
- package/dist/adapter.js +25 -71
- package/dist/magento-types.d.ts +44 -0
- package/dist/mappers.d.ts +13 -2
- package/dist/mappers.js +124 -0
- package/dist/queries.d.ts +9 -9
- package/dist/queries.js +223 -5
- package/package.json +3 -3
package/LICENSE
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 Cobrastyle
|
|
2
|
+
Copyright (c) 2026 Ecomero Management AB - Cobra Style Express
|
|
4
3
|
|
|
5
4
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
5
|
of this software and associated documentation files (the "Software"), to deal
|
package/dist/adapter.js
CHANGED
|
@@ -69,6 +69,13 @@ export const magento2Adapter = {
|
|
|
69
69
|
const upsellProducts = data.products.items[0]?.upsell_products ?? [];
|
|
70
70
|
return upsellProducts.map((p) => mappers.mapProductListItem(p, productUrlSuffix));
|
|
71
71
|
},
|
|
72
|
+
getCrossSells: async (productId) => {
|
|
73
|
+
const { productUrlSuffix } = await getStoreConfig();
|
|
74
|
+
// productId is typically the SKU - fetch directly with crosssell_products
|
|
75
|
+
const data = await graphqlFetch(queries.GET_RELATED_PRODUCTS_BY_SKU, { sku: productId });
|
|
76
|
+
const crossSellProducts = data.products.items[0]?.crosssell_products ?? [];
|
|
77
|
+
return crossSellProducts.map((p) => mappers.mapProductListItem(p, productUrlSuffix));
|
|
78
|
+
},
|
|
72
79
|
getBySkus: async (skus) => {
|
|
73
80
|
const unique = [...new Set(skus)].filter(Boolean);
|
|
74
81
|
if (unique.length === 0)
|
|
@@ -115,62 +122,15 @@ export const magento2Adapter = {
|
|
|
115
122
|
},
|
|
116
123
|
getProducts: async (input) => {
|
|
117
124
|
const { productUrlSuffix } = await getStoreConfig();
|
|
118
|
-
// Build the filter
|
|
119
|
-
//
|
|
120
|
-
//
|
|
125
|
+
// Build the Magento filter. Use category_uid for Magento 2.4+; a numeric
|
|
126
|
+
// id is base64-encoded to a uid. Attribute/range filters from `input`
|
|
127
|
+
// are folded in by the shared helper (also used by search.search).
|
|
121
128
|
const categoryUid = /^\d+$/.test(input.categoryId)
|
|
122
129
|
? Buffer.from(input.categoryId).toString("base64")
|
|
123
130
|
: input.categoryId;
|
|
124
|
-
const filter = {
|
|
131
|
+
const filter = mappers.buildProductFilter(input.filters, {
|
|
125
132
|
category_uid: { eq: categoryUid },
|
|
126
|
-
};
|
|
127
|
-
// Helper to detect and parse range filter values (format: "from_to" like "10_100" or "*_100" or "100_*")
|
|
128
|
-
const parseRangeValue = (value) => {
|
|
129
|
-
// Range values typically have underscore separator: "min_max"
|
|
130
|
-
const rangeMatch = value.match(/^(\*|\d+(?:\.\d+)?)_(\*|\d+(?:\.\d+)?)$/);
|
|
131
|
-
if (rangeMatch) {
|
|
132
|
-
const [, fromVal, toVal] = rangeMatch;
|
|
133
|
-
const result = {};
|
|
134
|
-
if (fromVal !== "*")
|
|
135
|
-
result.from = fromVal;
|
|
136
|
-
if (toVal !== "*")
|
|
137
|
-
result.to = toVal;
|
|
138
|
-
return result;
|
|
139
|
-
}
|
|
140
|
-
return null;
|
|
141
|
-
};
|
|
142
|
-
// Known range filter attributes in Magento (price is always range, others can be custom)
|
|
143
|
-
const knownRangeFilters = new Set(["price"]);
|
|
144
|
-
// Add attribute filters from input
|
|
145
|
-
if (input.filters) {
|
|
146
|
-
for (const [code, values] of Object.entries(input.filters)) {
|
|
147
|
-
const valueArray = Array.isArray(values) ? values : [values];
|
|
148
|
-
if (valueArray.length === 0)
|
|
149
|
-
continue;
|
|
150
|
-
// Check if this looks like a range filter
|
|
151
|
-
const firstValue = valueArray[0];
|
|
152
|
-
const rangeValue = parseRangeValue(firstValue);
|
|
153
|
-
if (rangeValue || knownRangeFilters.has(code)) {
|
|
154
|
-
// This is a range filter - use from/to syntax
|
|
155
|
-
// For range filters, we use the first value only (ranges can't be combined with "in")
|
|
156
|
-
const parsed = rangeValue || parseRangeValue(firstValue);
|
|
157
|
-
if (parsed) {
|
|
158
|
-
filter[code] = parsed;
|
|
159
|
-
}
|
|
160
|
-
else {
|
|
161
|
-
// Fallback: treat as a single equality value if it doesn't match range pattern
|
|
162
|
-
filter[code] = { eq: firstValue };
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
// Standard filter - use eq/in syntax
|
|
167
|
-
filter[code] =
|
|
168
|
-
valueArray.length === 1
|
|
169
|
-
? { eq: valueArray[0] }
|
|
170
|
-
: { in: valueArray };
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
}
|
|
133
|
+
});
|
|
174
134
|
const data = await graphqlFetch(queries.GET_CATEGORY_PRODUCTS, {
|
|
175
135
|
filter,
|
|
176
136
|
pageSize: input.pageSize ?? 12,
|
|
@@ -187,25 +147,8 @@ export const magento2Adapter = {
|
|
|
187
147
|
pageSize: data.products.page_info.page_size,
|
|
188
148
|
totalPages: data.products.page_info.total_pages,
|
|
189
149
|
},
|
|
190
|
-
filters: (data.products.aggregations
|
|
191
|
-
|
|
192
|
-
const isRangeFilter = agg.attribute_code === "price" ||
|
|
193
|
-
agg.options?.some((opt) => /^\*?\d*_\d*\*?$/.test(opt.value));
|
|
194
|
-
return {
|
|
195
|
-
code: agg.attribute_code,
|
|
196
|
-
label: agg.label,
|
|
197
|
-
type: isRangeFilter ? "range" : "multiselect",
|
|
198
|
-
values: (agg.options ?? []).map((opt) => ({
|
|
199
|
-
value: opt.value,
|
|
200
|
-
label: opt.label,
|
|
201
|
-
count: opt.count,
|
|
202
|
-
})),
|
|
203
|
-
};
|
|
204
|
-
}),
|
|
205
|
-
sortOptions: (data.products.sort_fields?.options ?? []).map((opt) => ({
|
|
206
|
-
value: opt.value,
|
|
207
|
-
label: opt.label,
|
|
208
|
-
})),
|
|
150
|
+
filters: mappers.mapAggregations(data.products.aggregations),
|
|
151
|
+
sortOptions: mappers.mapSortFields(data.products.sort_fields),
|
|
209
152
|
};
|
|
210
153
|
},
|
|
211
154
|
searchByName: async (query, limit = 5) => {
|
|
@@ -566,10 +509,19 @@ export const magento2Adapter = {
|
|
|
566
509
|
search: {
|
|
567
510
|
search: async (query, options) => {
|
|
568
511
|
const { productUrlSuffix } = await getStoreConfig();
|
|
512
|
+
// Fold attribute/range filters into a Magento filter (same helper the PLP
|
|
513
|
+
// uses); pass undefined when empty so `products(search:)` isn't given an
|
|
514
|
+
// empty filter object.
|
|
515
|
+
const builtFilter = mappers.buildProductFilter(options?.filters);
|
|
516
|
+
const filter = Object.keys(builtFilter).length > 0 ? builtFilter : undefined;
|
|
569
517
|
const data = await graphqlFetch(queries.SEARCH_PRODUCTS, {
|
|
570
518
|
search: query,
|
|
571
519
|
pageSize: options?.pageSize ?? 12,
|
|
572
520
|
currentPage: options?.page ?? 1,
|
|
521
|
+
filter,
|
|
522
|
+
sort: options?.sort
|
|
523
|
+
? { [options.sort.field]: options.sort.direction }
|
|
524
|
+
: undefined,
|
|
573
525
|
}, { tags: [CONTENT_TAGS.search] });
|
|
574
526
|
return {
|
|
575
527
|
items: data.products.items.map((p) => mappers.mapProductListItem(p, productUrlSuffix)),
|
|
@@ -579,6 +531,8 @@ export const magento2Adapter = {
|
|
|
579
531
|
pageSize: data.products.page_info.page_size,
|
|
580
532
|
totalPages: data.products.page_info.total_pages,
|
|
581
533
|
},
|
|
534
|
+
filters: mappers.mapAggregations(data.products.aggregations),
|
|
535
|
+
sortOptions: mappers.mapSortFields(data.products.sort_fields),
|
|
582
536
|
};
|
|
583
537
|
},
|
|
584
538
|
},
|
package/dist/magento-types.d.ts
CHANGED
|
@@ -67,6 +67,7 @@ export interface MagentoProduct {
|
|
|
67
67
|
stock_status: string;
|
|
68
68
|
price_range: {
|
|
69
69
|
minimum_price: MagentoProductPrice;
|
|
70
|
+
maximum_price?: MagentoProductPrice;
|
|
70
71
|
};
|
|
71
72
|
price_tiers?: MagentoTierPrice[] | null;
|
|
72
73
|
media_gallery?: Array<{
|
|
@@ -118,6 +119,32 @@ export interface MagentoProduct {
|
|
|
118
119
|
position: number;
|
|
119
120
|
product: MagentoProduct | null;
|
|
120
121
|
}>;
|
|
122
|
+
dynamic_price?: boolean;
|
|
123
|
+
price_view?: string;
|
|
124
|
+
bundleItems?: Array<{
|
|
125
|
+
uid: string;
|
|
126
|
+
option_id: number;
|
|
127
|
+
title: string;
|
|
128
|
+
type: string;
|
|
129
|
+
required: boolean;
|
|
130
|
+
position: number;
|
|
131
|
+
options: Array<{
|
|
132
|
+
uid: string;
|
|
133
|
+
id: number;
|
|
134
|
+
label: string;
|
|
135
|
+
quantity: number;
|
|
136
|
+
can_change_quantity: boolean;
|
|
137
|
+
is_default: boolean;
|
|
138
|
+
price: number;
|
|
139
|
+
price_type: string;
|
|
140
|
+
product: {
|
|
141
|
+
sku: string;
|
|
142
|
+
price_range: {
|
|
143
|
+
minimum_price: MagentoProductPrice;
|
|
144
|
+
};
|
|
145
|
+
};
|
|
146
|
+
}>;
|
|
147
|
+
}>;
|
|
121
148
|
}
|
|
122
149
|
export interface MagentoPageInfo {
|
|
123
150
|
current_page: number;
|
|
@@ -151,6 +178,9 @@ export interface MagentoCartItem {
|
|
|
151
178
|
url: string;
|
|
152
179
|
label?: string;
|
|
153
180
|
} | null;
|
|
181
|
+
price_range?: {
|
|
182
|
+
minimum_price: MagentoProductPrice;
|
|
183
|
+
} | null;
|
|
154
184
|
};
|
|
155
185
|
prices: {
|
|
156
186
|
price: MagentoMoney;
|
|
@@ -160,11 +190,25 @@ export interface MagentoCartItem {
|
|
|
160
190
|
row_total_including_tax?: {
|
|
161
191
|
value: number;
|
|
162
192
|
} | null;
|
|
193
|
+
total_item_discount?: {
|
|
194
|
+
value: number;
|
|
195
|
+
} | null;
|
|
196
|
+
discounts?: Array<{
|
|
197
|
+
amount: MagentoMoney;
|
|
198
|
+
label: string;
|
|
199
|
+
} | null> | null;
|
|
163
200
|
};
|
|
164
201
|
configurable_options?: Array<{
|
|
165
202
|
option_label: string;
|
|
166
203
|
value_label: string;
|
|
167
204
|
}> | null;
|
|
205
|
+
bundle_options?: Array<{
|
|
206
|
+
label: string;
|
|
207
|
+
values: Array<{
|
|
208
|
+
label: string;
|
|
209
|
+
quantity: number;
|
|
210
|
+
}>;
|
|
211
|
+
}> | null;
|
|
168
212
|
}
|
|
169
213
|
export interface MagentoCartPrices {
|
|
170
214
|
subtotal_excluding_tax?: MagentoMoney | null;
|
package/dist/mappers.d.ts
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
|
-
import type { AnyProduct, GroupedProductItem, ProductListItem, Price, ProductImage, StockStatus, ConfigurableOption, ProductVariant, CategoryReference, Cart, CartItem, CartTotals, ShippingAddress, ShippingMethod, PaymentMethod, Category, Country, NavigationItem, UrlResolverResult, CmsPage, CmsBlock, Customer, CustomerAddress } from '@cobrastyle/shared-types';
|
|
2
|
-
import type { MagentoProductPrice, MagentoTierPrice, MagentoCustomAttributesV2, MagentoProduct, MagentoCart, MagentoCartItem, MagentoCartPrices, MagentoShippingAddress, MagentoShippingMethod, MagentoPaymentMethod, MagentoCountry, MagentoCategory, MagentoCmsPage, MagentoCmsBlock, MagentoRoute, MagentoCustomer, MagentoCustomerAddress, MagentoCustomerOrder, MagentoCustomerOrderItem, MagentoWishlist, MagentoWishlistItem } from './magento-types';
|
|
1
|
+
import type { AnyProduct, GroupedProductItem, BundleOption, ProductListItem, Price, ProductImage, StockStatus, ConfigurableOption, ProductVariant, CategoryReference, Cart, CartItem, CartTotals, ShippingAddress, ShippingMethod, PaymentMethod, Category, Country, NavigationItem, UrlResolverResult, CmsPage, CmsBlock, Customer, CustomerAddress, FilterOption, SortOption } from '@cobrastyle/shared-types';
|
|
2
|
+
import type { MagentoProductPrice, MagentoTierPrice, MagentoCustomAttributesV2, MagentoProduct, MagentoCart, MagentoCartItem, MagentoCartPrices, MagentoShippingAddress, MagentoShippingMethod, MagentoPaymentMethod, MagentoCountry, MagentoCategory, MagentoCmsPage, MagentoCmsBlock, MagentoRoute, MagentoCustomer, MagentoCustomerAddress, MagentoCustomerOrder, MagentoCustomerOrderItem, MagentoWishlist, MagentoWishlistItem, MagentoAggregation, MagentoSortFields } from './magento-types';
|
|
3
|
+
/**
|
|
4
|
+
* Build a Magento `ProductAttributeFilterInput` from URL-style filter params.
|
|
5
|
+
* `base` seeds fixed constraints (e.g. `{ category_uid: { eq } }` for a PLP);
|
|
6
|
+
* search passes no base.
|
|
7
|
+
*/
|
|
8
|
+
export declare const buildProductFilter: (filters?: Record<string, string | string[]>, base?: Record<string, unknown>) => Record<string, unknown>;
|
|
9
|
+
/** Map Magento aggregations into domain FilterOption[] (range vs multiselect). */
|
|
10
|
+
export declare const mapAggregations: (aggregations?: MagentoAggregation[]) => FilterOption[];
|
|
11
|
+
/** Map Magento sort_fields into domain SortOption[]. */
|
|
12
|
+
export declare const mapSortFields: (sortFields?: MagentoSortFields) => SortOption[];
|
|
3
13
|
export declare const mapPrice: (priceData: MagentoProductPrice, tiers?: MagentoTierPrice[] | null) => Price;
|
|
4
14
|
export declare const mapImages: (mediaGallery: Array<{
|
|
5
15
|
url: string;
|
|
@@ -24,6 +34,7 @@ export declare const mapCustomAttributes: (custom: MagentoCustomAttributesV2 | u
|
|
|
24
34
|
value: string;
|
|
25
35
|
}>;
|
|
26
36
|
export declare const mapGroupedItems: (items: NonNullable<MagentoProduct["items"]>, productSuffix?: string) => GroupedProductItem[];
|
|
37
|
+
export declare const mapBundleOptions: (items: NonNullable<MagentoProduct["bundleItems"]>) => BundleOption[];
|
|
27
38
|
export declare const mapProduct: (product: MagentoProduct, productSuffix?: string, categorySuffix?: string, attributeLabels?: ReadonlyMap<string, string>) => AnyProduct;
|
|
28
39
|
export declare const mapProductListItem: (product: MagentoProduct, productSuffix?: string) => ProductListItem;
|
|
29
40
|
export declare const mapCart: (magentoCart: MagentoCart, productSuffix?: string) => Cart;
|
package/dist/mappers.js
CHANGED
|
@@ -1,4 +1,69 @@
|
|
|
1
1
|
import { applySuffix, buildCategoryUrl, joinSegments } from './urls';
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// Product listing filters/sort — shared by category.getProducts and
|
|
4
|
+
// search.search so the Magento filter-building and aggregation/sort-field
|
|
5
|
+
// mapping live in exactly one place.
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
/** Parse a range filter value like "10_100", "*_100" or "100_*". */
|
|
8
|
+
const parseRangeValue = (value) => {
|
|
9
|
+
const rangeMatch = value.match(/^(\*|\d+(?:\.\d+)?)_(\*|\d+(?:\.\d+)?)$/);
|
|
10
|
+
if (!rangeMatch)
|
|
11
|
+
return null;
|
|
12
|
+
const [, fromVal, toVal] = rangeMatch;
|
|
13
|
+
const result = {};
|
|
14
|
+
if (fromVal !== '*')
|
|
15
|
+
result.from = fromVal;
|
|
16
|
+
if (toVal !== '*')
|
|
17
|
+
result.to = toVal;
|
|
18
|
+
return result;
|
|
19
|
+
};
|
|
20
|
+
/** Attributes Magento always treats as ranges even without a "from_to" value. */
|
|
21
|
+
const KNOWN_RANGE_FILTERS = new Set(['price']);
|
|
22
|
+
/**
|
|
23
|
+
* Build a Magento `ProductAttributeFilterInput` from URL-style filter params.
|
|
24
|
+
* `base` seeds fixed constraints (e.g. `{ category_uid: { eq } }` for a PLP);
|
|
25
|
+
* search passes no base.
|
|
26
|
+
*/
|
|
27
|
+
export const buildProductFilter = (filters, base = {}) => {
|
|
28
|
+
const filter = { ...base };
|
|
29
|
+
if (!filters)
|
|
30
|
+
return filter;
|
|
31
|
+
for (const [code, values] of Object.entries(filters)) {
|
|
32
|
+
const valueArray = Array.isArray(values) ? values : [values];
|
|
33
|
+
if (valueArray.length === 0)
|
|
34
|
+
continue;
|
|
35
|
+
const firstValue = valueArray[0];
|
|
36
|
+
const rangeValue = parseRangeValue(firstValue);
|
|
37
|
+
if (rangeValue || KNOWN_RANGE_FILTERS.has(code)) {
|
|
38
|
+
filter[code] = rangeValue ?? { eq: firstValue };
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
filter[code] =
|
|
42
|
+
valueArray.length === 1 ? { eq: valueArray[0] } : { in: valueArray };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return filter;
|
|
46
|
+
};
|
|
47
|
+
/** Map Magento aggregations into domain FilterOption[] (range vs multiselect). */
|
|
48
|
+
export const mapAggregations = (aggregations) => (aggregations ?? []).map((agg) => {
|
|
49
|
+
const isRangeFilter = agg.attribute_code === 'price' ||
|
|
50
|
+
agg.options?.some((opt) => /^\*?\d*_\d*\*?$/.test(opt.value));
|
|
51
|
+
return {
|
|
52
|
+
code: agg.attribute_code,
|
|
53
|
+
label: agg.label,
|
|
54
|
+
type: isRangeFilter ? 'range' : 'multiselect',
|
|
55
|
+
values: (agg.options ?? []).map((opt) => ({
|
|
56
|
+
value: opt.value,
|
|
57
|
+
label: opt.label,
|
|
58
|
+
count: opt.count,
|
|
59
|
+
})),
|
|
60
|
+
};
|
|
61
|
+
});
|
|
62
|
+
/** Map Magento sort_fields into domain SortOption[]. */
|
|
63
|
+
export const mapSortFields = (sortFields) => (sortFields?.options ?? []).map((opt) => ({
|
|
64
|
+
value: opt.value,
|
|
65
|
+
label: opt.label,
|
|
66
|
+
}));
|
|
2
67
|
// Product Mappers
|
|
3
68
|
export const mapPrice = (priceData, tiers) => {
|
|
4
69
|
const mappedTiers = (tiers ?? [])
|
|
@@ -133,6 +198,35 @@ export const mapGroupedItems = (items, productSuffix = '') => items
|
|
|
133
198
|
type: 'simple',
|
|
134
199
|
},
|
|
135
200
|
}));
|
|
201
|
+
const BUNDLE_OPTION_TYPES = ['select', 'radio', 'checkbox', 'multi'];
|
|
202
|
+
const toBundleOptionType = (raw) => BUNDLE_OPTION_TYPES.includes(raw) ? raw : 'select';
|
|
203
|
+
const toPriceType = (raw) => raw === 'PERCENT' ? 'PERCENT' : raw === 'DYNAMIC' ? 'DYNAMIC' : 'FIXED';
|
|
204
|
+
export const mapBundleOptions = (items) => items
|
|
205
|
+
.slice()
|
|
206
|
+
.sort((a, b) => a.position - b.position)
|
|
207
|
+
.map((item) => ({
|
|
208
|
+
uid: item.uid,
|
|
209
|
+
optionId: item.option_id,
|
|
210
|
+
title: item.title,
|
|
211
|
+
type: toBundleOptionType(item.type),
|
|
212
|
+
required: item.required,
|
|
213
|
+
position: item.position,
|
|
214
|
+
// Selections keep Magento's provided order (the store's configured
|
|
215
|
+
// display order for this option's values) — no re-sort by id here.
|
|
216
|
+
selections: item.options
|
|
217
|
+
.map((opt) => ({
|
|
218
|
+
uid: opt.uid,
|
|
219
|
+
id: opt.id,
|
|
220
|
+
label: opt.label,
|
|
221
|
+
quantity: opt.quantity,
|
|
222
|
+
canChangeQuantity: opt.can_change_quantity,
|
|
223
|
+
isDefault: opt.is_default,
|
|
224
|
+
price: opt.price,
|
|
225
|
+
priceType: toPriceType(opt.price_type),
|
|
226
|
+
productSku: opt.product.sku,
|
|
227
|
+
productPrice: opt.product.price_range.minimum_price.final_price.value,
|
|
228
|
+
})),
|
|
229
|
+
}));
|
|
136
230
|
// `productSuffix`/`categorySuffix` are storeConfig.product_url_suffix /
|
|
137
231
|
// category_url_suffix (e.g. ".html"). productSuffix is appended to the
|
|
138
232
|
// product's url_key; categorySuffix is used for the product's category
|
|
@@ -155,6 +249,17 @@ export const mapProduct = (product, productSuffix = '', categorySuffix = '', att
|
|
|
155
249
|
metaTitle: product.meta_title,
|
|
156
250
|
metaDescription: product.meta_description,
|
|
157
251
|
};
|
|
252
|
+
if (product.__typename === 'BundleProduct' && product.bundleItems) {
|
|
253
|
+
return {
|
|
254
|
+
...baseProduct,
|
|
255
|
+
type: 'bundle',
|
|
256
|
+
dynamicPrice: product.dynamic_price ?? false,
|
|
257
|
+
priceView: product.price_view === 'AS_LOW_AS' ? 'AS_LOW_AS' : 'PRICE_RANGE',
|
|
258
|
+
maxPrice: product.price_range.maximum_price?.final_price.value ??
|
|
259
|
+
product.price_range.minimum_price.final_price.value,
|
|
260
|
+
bundleOptions: mapBundleOptions(product.bundleItems),
|
|
261
|
+
};
|
|
262
|
+
}
|
|
158
263
|
// Check for grouped product (using __typename from GraphQL)
|
|
159
264
|
if (product.__typename === 'GroupedProduct' && product.items) {
|
|
160
265
|
return {
|
|
@@ -177,6 +282,8 @@ export const mapProduct = (product, productSuffix = '', categorySuffix = '', att
|
|
|
177
282
|
};
|
|
178
283
|
};
|
|
179
284
|
const getProductType = (product) => {
|
|
285
|
+
if (product.__typename === 'BundleProduct')
|
|
286
|
+
return 'bundle';
|
|
180
287
|
if (product.__typename === 'GroupedProduct')
|
|
181
288
|
return 'grouped';
|
|
182
289
|
if (product.configurable_options)
|
|
@@ -242,12 +349,29 @@ export const mapCartItems = (items, productSuffix = '') => items.filter((item) =
|
|
|
242
349
|
price: item.prices.price.value,
|
|
243
350
|
rowTotal: item.prices.row_total.value,
|
|
244
351
|
rowTotalIncludingTax: item.prices.row_total_including_tax?.value ?? item.prices.row_total.value,
|
|
352
|
+
rowTotalWithDiscount: item.prices.row_total.value - (item.prices.total_item_discount?.value ?? 0),
|
|
353
|
+
// Regular (list) price × qty, so catalog special prices show a struck-through
|
|
354
|
+
// original in the cart. Magento's cart `prices` only carries the special price,
|
|
355
|
+
// so the list price comes from the product's price_range.regular_price.
|
|
356
|
+
rowTotalRegular: item.product.price_range?.minimum_price?.regular_price?.value != null
|
|
357
|
+
? item.product.price_range.minimum_price.regular_price.value * item.quantity
|
|
358
|
+
: item.prices.row_total.value,
|
|
245
359
|
currency: item.prices.price.currency,
|
|
360
|
+
discounts: (item.prices.discounts ?? [])
|
|
361
|
+
.filter((d) => d != null)
|
|
362
|
+
.map((d) => ({
|
|
363
|
+
amount: d.amount.value,
|
|
364
|
+
label: d.label,
|
|
365
|
+
})),
|
|
246
366
|
},
|
|
247
367
|
configurableOptions: item.configurable_options?.map((opt) => ({
|
|
248
368
|
optionLabel: opt.option_label,
|
|
249
369
|
valueLabel: opt.value_label,
|
|
250
370
|
})),
|
|
371
|
+
bundleOptions: item.bundle_options?.map((opt) => ({
|
|
372
|
+
label: opt.label,
|
|
373
|
+
values: opt.values.map((v) => ({ label: v.label, quantity: v.quantity })),
|
|
374
|
+
})),
|
|
251
375
|
}));
|
|
252
376
|
export const mapCartTotals = (prices) => ({
|
|
253
377
|
subtotal: prices.subtotal_excluding_tax?.value ?? 0,
|
package/dist/queries.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export declare const GET_PRODUCT_BY_URL_KEY = "\n query GetProductByUrlKey($urlKey: String!) {\n products(filter: { url_key: { eq: $urlKey } }) {\n items {\n __typename\n id\n sku\n name\n url_key\n description { html }\n short_description { html }\n meta_title\n meta_description\n stock_status\n price_range {\n minimum_price {\n regular_price { value currency }\n final_price { value currency }\n discount { amount_off percent_off }\n }\n }\n price_tiers {\n quantity\n final_price { value currency }\n discount { amount_off percent_off }\n }\n media_gallery {\n url\n label\n position\n }\n categories {\n id\n name\n url_key\n breadcrumbs {\n category_url_key\n category_level\n }\n }\n custom_attributesV2(filters: { is_visible_on_front: true }) {\n items {\n code\n __typename\n ... on AttributeValue {\n value\n }\n ... on AttributeSelectedOptions {\n selected_options {\n label\n value\n }\n }\n }\n errors {\n message\n }\n }\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_code\n label\n values {\n uid\n label\n swatch_data {\n __typename\n value\n }\n }\n }\n variants {\n product {\n id\n sku\n name\n stock_status\n price_range {\n minimum_price {\n regular_price { value currency }\n final_price { value currency }\n }\n }\n }\n attributes {\n code\n label\n value_index\n }\n }\n }\n ... on GroupedProduct {\n items {\n qty\n position\n product {\n ... on ProductInterface {\n __typename\n id\n uid\n sku\n name\n url_key\n stock_status\n price_range {\n minimum_price {\n regular_price { value currency }\n final_price { value currency }\n discount { amount_off percent_off }\n }\n }\n thumbnail { url label }\n }\n }\n }\n }\n }\n }\n }\n";
|
|
2
|
-
export declare const GET_PRODUCT_BY_ID = "\n query GetProductBySku($sku: String!) {\n products(filter: { sku: { eq: $sku } }) {\n items {\n id\n sku\n name\n url_key\n description { html }\n short_description { html }\n meta_title\n meta_description\n stock_status\n price_range {\n minimum_price {\n regular_price { value currency }\n final_price { value currency }\n discount { amount_off percent_off }\n }\n }\n price_tiers {\n quantity\n final_price { value currency }\n discount { amount_off percent_off }\n }\n media_gallery {\n url\n label\n position\n }\n categories {\n id\n name\n url_key\n breadcrumbs {\n category_url_key\n category_level\n }\n }\n custom_attributesV2(filters: { is_visible_on_front: true }) {\n items {\n code\n __typename\n ... on AttributeValue {\n value\n }\n ... on AttributeSelectedOptions {\n selected_options {\n label\n value\n }\n }\n }\n errors {\n message\n }\n }\n }\n }\n }\n";
|
|
1
|
+
export declare const GET_PRODUCT_BY_URL_KEY = "\n query GetProductByUrlKey($urlKey: String!) {\n products(filter: { url_key: { eq: $urlKey } }) {\n items {\n __typename\n id\n sku\n name\n url_key\n description { html }\n short_description { html }\n meta_title\n meta_description\n stock_status\n price_range {\n minimum_price {\n regular_price { value currency }\n final_price { value currency }\n discount { amount_off percent_off }\n }\n maximum_price {\n final_price { value currency }\n }\n }\n price_tiers {\n quantity\n final_price { value currency }\n discount { amount_off percent_off }\n }\n media_gallery {\n url\n label\n position\n }\n categories {\n id\n name\n url_key\n breadcrumbs {\n category_url_key\n category_level\n }\n }\n custom_attributesV2(filters: { is_visible_on_front: true }) {\n items {\n code\n __typename\n ... on AttributeValue {\n value\n }\n ... on AttributeSelectedOptions {\n selected_options {\n label\n value\n }\n }\n }\n errors {\n message\n }\n }\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_code\n label\n values {\n uid\n label\n swatch_data {\n __typename\n value\n }\n }\n }\n variants {\n product {\n id\n sku\n name\n stock_status\n price_range {\n minimum_price {\n regular_price { value currency }\n final_price { value currency }\n }\n }\n }\n attributes {\n code\n label\n value_index\n }\n }\n }\n ... on GroupedProduct {\n items {\n qty\n position\n product {\n ... on ProductInterface {\n __typename\n id\n uid\n sku\n name\n url_key\n stock_status\n price_range {\n minimum_price {\n regular_price { value currency }\n final_price { value currency }\n discount { amount_off percent_off }\n }\n }\n thumbnail { url label }\n }\n }\n }\n }\n ... on BundleProduct {\n dynamic_price\n price_view\n bundleItems: items {\n uid\n option_id\n title\n type\n required\n position\n options {\n uid\n id\n label\n quantity\n can_change_quantity\n is_default\n price\n price_type\n product {\n sku\n price_range { minimum_price { final_price { value currency } } }\n }\n }\n }\n }\n }\n }\n }\n";
|
|
2
|
+
export declare const GET_PRODUCT_BY_ID = "\n query GetProductBySku($sku: String!) {\n products(filter: { sku: { eq: $sku } }) {\n items {\n __typename\n id\n sku\n name\n url_key\n description { html }\n short_description { html }\n meta_title\n meta_description\n stock_status\n price_range {\n minimum_price {\n regular_price { value currency }\n final_price { value currency }\n discount { amount_off percent_off }\n }\n maximum_price {\n final_price { value currency }\n }\n }\n price_tiers {\n quantity\n final_price { value currency }\n discount { amount_off percent_off }\n }\n media_gallery {\n url\n label\n position\n }\n categories {\n id\n name\n url_key\n breadcrumbs {\n category_url_key\n category_level\n }\n }\n custom_attributesV2(filters: { is_visible_on_front: true }) {\n items {\n code\n __typename\n ... on AttributeValue {\n value\n }\n ... on AttributeSelectedOptions {\n selected_options {\n label\n value\n }\n }\n }\n errors {\n message\n }\n }\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_code\n label\n values {\n uid\n label\n swatch_data {\n __typename\n value\n }\n }\n }\n variants {\n product {\n id\n sku\n name\n stock_status\n price_range {\n minimum_price {\n regular_price { value currency }\n final_price { value currency }\n }\n }\n }\n attributes {\n code\n label\n value_index\n }\n }\n }\n ... on GroupedProduct {\n items {\n qty\n position\n product {\n ... on ProductInterface {\n __typename\n id\n uid\n sku\n name\n url_key\n stock_status\n price_range {\n minimum_price {\n regular_price { value currency }\n final_price { value currency }\n discount { amount_off percent_off }\n }\n }\n thumbnail { url label }\n }\n }\n }\n }\n ... on BundleProduct {\n dynamic_price\n price_view\n bundleItems: items {\n uid\n option_id\n title\n type\n required\n position\n options {\n uid\n id\n label\n quantity\n can_change_quantity\n is_default\n price\n price_type\n product {\n sku\n price_range { minimum_price { final_price { value currency } } }\n }\n }\n }\n }\n }\n }\n }\n";
|
|
3
3
|
export declare const GET_PRODUCT_ATTRIBUTE_LABELS = "\n query GetProductAttributeLabels {\n attributesList(entityType: CATALOG_PRODUCT, filters: { is_visible_on_front: true }) {\n items {\n code\n label\n }\n errors {\n message\n }\n }\n }\n";
|
|
4
4
|
export declare const GET_CATEGORY_BY_URL_KEY = "\n query GetCategoryByUrlKey($urlKey: String!) {\n categoryList(filters: { url_path: { eq: $urlKey } }) {\n id\n uid\n name\n url_key\n url_path\n description\n image\n meta_title\n meta_description\n product_count\n breadcrumbs {\n category_id\n category_uid\n category_name\n category_url_key\n category_url_path\n category_level\n }\n children {\n id\n uid\n name\n url_key\n url_path\n product_count\n }\n }\n }\n";
|
|
5
5
|
export declare const GET_CATEGORY_BY_URL_KEY_SINGLE = "\n query GetCategoryByUrlKeySingle($urlKey: String!) {\n categoryList(filters: { url_key: { eq: $urlKey } }) {\n id\n uid\n name\n url_key\n url_path\n description\n image\n meta_title\n meta_description\n product_count\n breadcrumbs {\n category_id\n category_uid\n category_name\n category_url_key\n category_url_path\n category_level\n }\n children {\n id\n uid\n name\n url_key\n url_path\n product_count\n }\n }\n }\n";
|
|
@@ -11,14 +11,14 @@ export declare const GET_AVAILABLE_STORES = "\n query GetAvailableStores {\n
|
|
|
11
11
|
export declare const GET_COUNTRIES = "\n query GetCountries {\n countries {\n two_letter_abbreviation\n full_name_locale\n available_regions {\n id\n code\n name\n }\n }\n }\n";
|
|
12
12
|
export declare const GET_NAVIGATION = "\n query GetNavigation($id: Int!) {\n category(id: $id) {\n id\n children {\n id\n name\n url_key\n url_path\n position\n level\n include_in_menu\n children {\n id\n name\n url_key\n url_path\n position\n level\n include_in_menu\n children {\n id\n name\n url_key\n url_path\n position\n level\n include_in_menu\n }\n }\n }\n }\n }\n";
|
|
13
13
|
export declare const CREATE_EMPTY_CART = "\n mutation CreateEmptyCart {\n createEmptyCart\n }\n";
|
|
14
|
-
export declare const GET_CART = "\n query GetCart($cartId: String!) {\n cart(cart_id: $cartId) {\n id\n email\n items {\n uid\n product {\n id\n sku\n name\n url_key\n thumbnail { url label }\n }\n quantity\n prices {\n price { value currency }\n row_total { value currency }\n row_total_including_tax { value currency }\n }\n ... on ConfigurableCartItem {\n configurable_options {\n option_label\n value_label\n }\n }\n }\n prices {\n subtotal_excluding_tax { value currency }\n subtotal_including_tax { value currency }\n grand_total { value currency }\n discounts {\n amount { value currency }\n label\n }\n applied_taxes {\n amount { value currency }\n label\n }\n }\n applied_coupons {\n code\n }\n shipping_addresses {\n firstname\n lastname\n street\n city\n region { code label }\n postcode\n country { code label }\n telephone\n available_shipping_methods {\n carrier_code\n carrier_title\n method_code\n method_title\n amount { value currency }\n }\n selected_shipping_method {\n carrier_code\n carrier_title\n method_code\n method_title\n amount { value currency }\n }\n }\n billing_address {\n firstname\n lastname\n street\n city\n region { code label }\n postcode\n country { code label }\n telephone\n }\n available_payment_methods {\n code\n title\n }\n selected_payment_method {\n code\n title\n }\n }\n }\n";
|
|
15
|
-
export declare const ADD_TO_CART = "\n mutation AddToCart($cartId: String!, $cartItems: [CartItemInput!]!) {\n addProductsToCart(\n cartId: $cartId\n cartItems: $cartItems\n ) {\n cart {\n id\n items {\n uid\n product { id sku name url_key thumbnail { url label } }\n quantity\n prices {\n price { value currency }\n row_total { value currency }\n row_total_including_tax { value currency }\n }\n ... on ConfigurableCartItem {\n configurable_options {\n option_label\n value_label\n }\n }\n }\n prices {\n subtotal_excluding_tax { value currency }\n subtotal_including_tax { value currency }\n grand_total { value currency }\n }\n }\n user_errors {\n code\n message\n }\n }\n }\n";
|
|
16
|
-
export declare const UPDATE_CART_ITEM = "\n mutation UpdateCartItem($cartId: String!, $itemUid: ID!, $quantity: Float!) {\n updateCartItems(\n input: {\n cart_id: $cartId\n cart_items: [{ cart_item_uid: $itemUid, quantity: $quantity }]\n }\n ) {\n cart {\n id\n items {\n uid\n product { id sku name url_key thumbnail { url label } }\n quantity\n prices {\n price { value currency }\n row_total { value currency }\n row_total_including_tax { value currency }\n }\n }\n prices {\n subtotal_excluding_tax { value currency }\n subtotal_including_tax { value currency }\n grand_total { value currency }\n }\n }\n }\n }\n";
|
|
17
|
-
export declare const REMOVE_CART_ITEM = "\n mutation RemoveCartItem($cartId: String!, $itemUid: ID!) {\n removeItemFromCart(input: { cart_id: $cartId, cart_item_uid: $itemUid }) {\n cart {\n id\n items {\n uid\n product { id sku name url_key thumbnail { url label } }\n quantity\n prices {\n price { value currency }\n row_total { value currency }\n row_total_including_tax { value currency }\n }\n }\n prices {\n subtotal_excluding_tax { value currency }\n subtotal_including_tax { value currency }\n grand_total { value currency }\n }\n }\n }\n }\n";
|
|
14
|
+
export declare const GET_CART = "\n query GetCart($cartId: String!) {\n cart(cart_id: $cartId) {\n id\n email\n items {\n uid\n product {\n id\n sku\n name\n url_key\n thumbnail { url label }\n price_range {\n minimum_price {\n regular_price { value currency }\n final_price { value currency }\n }\n }\n }\n quantity\n prices {\n price { value currency }\n row_total { value currency }\n row_total_including_tax { value currency }\n total_item_discount { value }\n discounts { amount { value currency } label }\n }\n ... on ConfigurableCartItem {\n configurable_options {\n option_label\n value_label\n }\n }\n ... on BundleCartItem {\n bundle_options {\n label\n values { label quantity }\n }\n }\n }\n prices {\n subtotal_excluding_tax { value currency }\n subtotal_including_tax { value currency }\n grand_total { value currency }\n discounts {\n amount { value currency }\n label\n }\n applied_taxes {\n amount { value currency }\n label\n }\n }\n applied_coupons {\n code\n }\n shipping_addresses {\n firstname\n lastname\n street\n city\n region { code label }\n postcode\n country { code label }\n telephone\n available_shipping_methods {\n carrier_code\n carrier_title\n method_code\n method_title\n amount { value currency }\n }\n selected_shipping_method {\n carrier_code\n carrier_title\n method_code\n method_title\n amount { value currency }\n }\n }\n billing_address {\n firstname\n lastname\n street\n city\n region { code label }\n postcode\n country { code label }\n telephone\n }\n available_payment_methods {\n code\n title\n }\n selected_payment_method {\n code\n title\n }\n }\n }\n";
|
|
15
|
+
export declare const ADD_TO_CART = "\n mutation AddToCart($cartId: String!, $cartItems: [CartItemInput!]!) {\n addProductsToCart(\n cartId: $cartId\n cartItems: $cartItems\n ) {\n cart {\n id\n items {\n uid\n product { id sku name url_key thumbnail { url label } price_range { minimum_price { regular_price { value currency } final_price { value currency } } } }\n quantity\n prices {\n price { value currency }\n row_total { value currency }\n row_total_including_tax { value currency }\n total_item_discount { value }\n discounts { amount { value currency } label }\n }\n ... on ConfigurableCartItem {\n configurable_options {\n option_label\n value_label\n }\n }\n ... on BundleCartItem {\n bundle_options {\n label\n values { label quantity }\n }\n }\n }\n prices {\n subtotal_excluding_tax { value currency }\n subtotal_including_tax { value currency }\n grand_total { value currency }\n discounts { amount { value currency } label }\n applied_taxes { amount { value currency } label }\n }\n }\n user_errors {\n code\n message\n }\n }\n }\n";
|
|
16
|
+
export declare const UPDATE_CART_ITEM = "\n mutation UpdateCartItem($cartId: String!, $itemUid: ID!, $quantity: Float!) {\n updateCartItems(\n input: {\n cart_id: $cartId\n cart_items: [{ cart_item_uid: $itemUid, quantity: $quantity }]\n }\n ) {\n cart {\n id\n items {\n uid\n product { id sku name url_key thumbnail { url label } price_range { minimum_price { regular_price { value currency } final_price { value currency } } } }\n quantity\n prices {\n price { value currency }\n row_total { value currency }\n row_total_including_tax { value currency }\n total_item_discount { value }\n discounts { amount { value currency } label }\n }\n }\n prices {\n subtotal_excluding_tax { value currency }\n subtotal_including_tax { value currency }\n grand_total { value currency }\n discounts { amount { value currency } label }\n applied_taxes { amount { value currency } label }\n }\n }\n }\n }\n";
|
|
17
|
+
export declare const REMOVE_CART_ITEM = "\n mutation RemoveCartItem($cartId: String!, $itemUid: ID!) {\n removeItemFromCart(input: { cart_id: $cartId, cart_item_uid: $itemUid }) {\n cart {\n id\n items {\n uid\n product { id sku name url_key thumbnail { url label } price_range { minimum_price { regular_price { value currency } final_price { value currency } } } }\n quantity\n prices {\n price { value currency }\n row_total { value currency }\n row_total_including_tax { value currency }\n total_item_discount { value }\n discounts { amount { value currency } label }\n }\n }\n prices {\n subtotal_excluding_tax { value currency }\n subtotal_including_tax { value currency }\n grand_total { value currency }\n discounts { amount { value currency } label }\n applied_taxes { amount { value currency } label }\n }\n }\n }\n }\n";
|
|
18
18
|
export declare const URL_RESOLVER = "\n query UrlResolver($url: String!) {\n route(url: $url) {\n __typename\n ... on ProductInterface {\n id\n uid\n sku\n url_key\n }\n ... on CategoryTree {\n id\n uid\n url_key\n }\n ... on CmsPage {\n identifier\n url_key\n }\n }\n }\n";
|
|
19
19
|
export declare const GET_CMS_PAGE = "\n query GetCmsPage($identifier: String!) {\n cmsPage(identifier: $identifier) {\n identifier\n url_key\n title\n content\n content_heading\n meta_title\n meta_description\n }\n }\n";
|
|
20
20
|
export declare const GET_CMS_BLOCKS = "\n query GetCmsBlocks($identifiers: [String!]!) {\n cmsBlocks(identifiers: $identifiers) {\n items {\n identifier\n title\n content\n }\n }\n }\n";
|
|
21
|
-
export declare const SEARCH_PRODUCTS = "\n query SearchProducts($search: String
|
|
21
|
+
export declare const SEARCH_PRODUCTS = "\n query SearchProducts(\n $search: String!\n $pageSize: Int!\n $currentPage: Int!\n $filter: ProductAttributeFilterInput\n $sort: ProductAttributeSortInput\n ) {\n products(\n search: $search\n filter: $filter\n pageSize: $pageSize\n currentPage: $currentPage\n sort: $sort\n ) {\n total_count\n page_info {\n current_page\n page_size\n total_pages\n }\n items {\n id\n sku\n name\n url_key\n stock_status\n price_range {\n minimum_price {\n regular_price { value currency }\n final_price { value currency }\n discount { amount_off percent_off }\n }\n }\n price_tiers {\n quantity\n final_price { value currency }\n discount { amount_off percent_off }\n }\n thumbnail {\n url\n label\n }\n }\n aggregations {\n attribute_code\n label\n options {\n value\n label\n count\n }\n }\n sort_fields {\n default\n options {\n value\n label\n }\n }\n }\n }\n";
|
|
22
22
|
export declare const GENERATE_CUSTOMER_TOKEN = "\n mutation GenerateCustomerToken($email: String!, $password: String!) {\n generateCustomerToken(email: $email, password: $password) {\n token\n }\n }\n";
|
|
23
23
|
export declare const CREATE_CUSTOMER = "\n mutation CreateCustomer($input: CustomerCreateInput!) {\n createCustomerV2(input: $input) {\n customer {\n id\n email\n firstname\n lastname\n date_of_birth\n gender\n created_at\n }\n }\n }\n";
|
|
24
24
|
export declare const GET_CUSTOMER = "\n query GetCustomer {\n customer {\n id\n email\n firstname\n lastname\n date_of_birth\n gender\n created_at\n addresses {\n id\n firstname\n lastname\n street\n city\n region { region_code region region_id }\n postcode\n country_code\n telephone\n company\n default_shipping\n default_billing\n }\n }\n }\n";
|
|
@@ -30,8 +30,8 @@ export declare const SET_SHIPPING_ADDRESS = "\n mutation SetShippingAddress($ca
|
|
|
30
30
|
export declare const SET_SHIPPING_METHOD = "\n mutation SetShippingMethod(\n $cartId: String!\n $carrierCode: String!\n $methodCode: String!\n ) {\n setShippingMethodsOnCart(\n input: {\n cart_id: $cartId\n shipping_methods: [\n { carrier_code: $carrierCode, method_code: $methodCode }\n ]\n }\n ) {\n cart {\n id\n shipping_addresses {\n selected_shipping_method {\n carrier_code\n carrier_title\n method_code\n method_title\n amount { value currency }\n }\n }\n prices {\n grand_total { value currency }\n }\n }\n }\n }\n";
|
|
31
31
|
export declare const SET_PAYMENT_METHOD = "\n mutation SetPaymentMethod($cartId: String!, $code: String!) {\n setPaymentMethodOnCart(\n input: { cart_id: $cartId, payment_method: { code: $code } }\n ) {\n cart {\n id\n selected_payment_method {\n code\n title\n }\n }\n }\n }\n";
|
|
32
32
|
export declare const PLACE_ORDER = "\n mutation PlaceOrder($cartId: String!) {\n placeOrder(input: { cart_id: $cartId }) {\n order {\n order_number\n }\n }\n }\n";
|
|
33
|
-
export declare const GET_RELATED_PRODUCTS = "\n query GetRelatedProducts($urlKey: String!) {\n products(filter: { url_key: { eq: $urlKey } }) {\n items {\n related_products {\n __typename\n id\n uid\n sku\n name\n url_key\n stock_status\n price_range {\n minimum_price {\n regular_price { value currency }\n final_price { value currency }\n discount { amount_off percent_off }\n }\n }\n thumbnail {\n url\n label\n }\n }\n upsell_products {\n __typename\n id\n uid\n sku\n name\n url_key\n stock_status\n price_range {\n minimum_price {\n regular_price { value currency }\n final_price { value currency }\n discount { amount_off percent_off }\n }\n }\n thumbnail {\n url\n label\n }\n }\n }\n }\n }\n";
|
|
34
|
-
export declare const GET_RELATED_PRODUCTS_BY_SKU = "\n query GetRelatedProductsBySku($sku: String!) {\n products(filter: { sku: { eq: $sku } }) {\n items {\n related_products {\n __typename\n id\n uid\n sku\n name\n url_key\n stock_status\n price_range {\n minimum_price {\n regular_price { value currency }\n final_price { value currency }\n discount { amount_off percent_off }\n }\n }\n thumbnail {\n url\n label\n }\n }\n upsell_products {\n __typename\n id\n uid\n sku\n name\n url_key\n stock_status\n price_range {\n minimum_price {\n regular_price { value currency }\n final_price { value currency }\n discount { amount_off percent_off }\n }\n }\n thumbnail {\n url\n label\n }\n }\n }\n }\n }\n";
|
|
33
|
+
export declare const GET_RELATED_PRODUCTS = "\n query GetRelatedProducts($urlKey: String!) {\n products(filter: { url_key: { eq: $urlKey } }) {\n items {\n related_products {\n __typename\n id\n uid\n sku\n name\n url_key\n stock_status\n price_range {\n minimum_price {\n regular_price { value currency }\n final_price { value currency }\n discount { amount_off percent_off }\n }\n }\n thumbnail {\n url\n label\n }\n }\n upsell_products {\n __typename\n id\n uid\n sku\n name\n url_key\n stock_status\n price_range {\n minimum_price {\n regular_price { value currency }\n final_price { value currency }\n discount { amount_off percent_off }\n }\n }\n thumbnail {\n url\n label\n }\n }\n crosssell_products {\n __typename\n id\n uid\n sku\n name\n url_key\n stock_status\n price_range {\n minimum_price {\n regular_price { value currency }\n final_price { value currency }\n discount { amount_off percent_off }\n }\n }\n thumbnail {\n url\n label\n }\n }\n }\n }\n }\n";
|
|
34
|
+
export declare const GET_RELATED_PRODUCTS_BY_SKU = "\n query GetRelatedProductsBySku($sku: String!) {\n products(filter: { sku: { eq: $sku } }) {\n items {\n related_products {\n __typename\n id\n uid\n sku\n name\n url_key\n stock_status\n price_range {\n minimum_price {\n regular_price { value currency }\n final_price { value currency }\n discount { amount_off percent_off }\n }\n }\n thumbnail {\n url\n label\n }\n }\n upsell_products {\n __typename\n id\n uid\n sku\n name\n url_key\n stock_status\n price_range {\n minimum_price {\n regular_price { value currency }\n final_price { value currency }\n discount { amount_off percent_off }\n }\n }\n thumbnail {\n url\n label\n }\n }\n crosssell_products {\n __typename\n id\n uid\n sku\n name\n url_key\n stock_status\n price_range {\n minimum_price {\n regular_price { value currency }\n final_price { value currency }\n discount { amount_off percent_off }\n }\n }\n thumbnail {\n url\n label\n }\n }\n }\n }\n }\n";
|
|
35
35
|
export declare const GET_PRODUCTS_BY_SKUS = "\n query GetProductsBySkus($skus: [String!]!, $pageSize: Int!) {\n products(filter: { sku: { in: $skus } }, pageSize: $pageSize) {\n items {\n id\n sku\n name\n url_key\n stock_status\n price_range {\n minimum_price {\n regular_price { value currency }\n final_price { value currency }\n discount { amount_off percent_off }\n }\n }\n price_tiers {\n quantity\n final_price { value currency }\n discount { amount_off percent_off }\n }\n thumbnail { url label }\n }\n }\n }\n";
|
|
36
36
|
export declare const GET_CUSTOMER_CART = "\n query GetCustomerCart {\n customerCart {\n id\n }\n }\n";
|
|
37
37
|
export declare const MERGE_CARTS = "\n mutation MergeCarts($guestCartId: String!, $customerCartId: String!) {\n mergeCarts(source_cart_id: $guestCartId, destination_cart_id: $customerCartId) {\n id\n }\n }\n";
|
package/dist/queries.js
CHANGED
|
@@ -19,6 +19,9 @@ export const GET_PRODUCT_BY_URL_KEY = `
|
|
|
19
19
|
final_price { value currency }
|
|
20
20
|
discount { amount_off percent_off }
|
|
21
21
|
}
|
|
22
|
+
maximum_price {
|
|
23
|
+
final_price { value currency }
|
|
24
|
+
}
|
|
22
25
|
}
|
|
23
26
|
price_tiers {
|
|
24
27
|
quantity
|
|
@@ -116,6 +119,32 @@ export const GET_PRODUCT_BY_URL_KEY = `
|
|
|
116
119
|
}
|
|
117
120
|
}
|
|
118
121
|
}
|
|
122
|
+
... on BundleProduct {
|
|
123
|
+
dynamic_price
|
|
124
|
+
price_view
|
|
125
|
+
bundleItems: items {
|
|
126
|
+
uid
|
|
127
|
+
option_id
|
|
128
|
+
title
|
|
129
|
+
type
|
|
130
|
+
required
|
|
131
|
+
position
|
|
132
|
+
options {
|
|
133
|
+
uid
|
|
134
|
+
id
|
|
135
|
+
label
|
|
136
|
+
quantity
|
|
137
|
+
can_change_quantity
|
|
138
|
+
is_default
|
|
139
|
+
price
|
|
140
|
+
price_type
|
|
141
|
+
product {
|
|
142
|
+
sku
|
|
143
|
+
price_range { minimum_price { final_price { value currency } } }
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
119
148
|
}
|
|
120
149
|
}
|
|
121
150
|
}
|
|
@@ -124,6 +153,7 @@ export const GET_PRODUCT_BY_ID = `
|
|
|
124
153
|
query GetProductBySku($sku: String!) {
|
|
125
154
|
products(filter: { sku: { eq: $sku } }) {
|
|
126
155
|
items {
|
|
156
|
+
__typename
|
|
127
157
|
id
|
|
128
158
|
sku
|
|
129
159
|
name
|
|
@@ -139,6 +169,9 @@ export const GET_PRODUCT_BY_ID = `
|
|
|
139
169
|
final_price { value currency }
|
|
140
170
|
discount { amount_off percent_off }
|
|
141
171
|
}
|
|
172
|
+
maximum_price {
|
|
173
|
+
final_price { value currency }
|
|
174
|
+
}
|
|
142
175
|
}
|
|
143
176
|
price_tiers {
|
|
144
177
|
quantity
|
|
@@ -177,6 +210,91 @@ export const GET_PRODUCT_BY_ID = `
|
|
|
177
210
|
message
|
|
178
211
|
}
|
|
179
212
|
}
|
|
213
|
+
... on ConfigurableProduct {
|
|
214
|
+
configurable_options {
|
|
215
|
+
id
|
|
216
|
+
attribute_code
|
|
217
|
+
label
|
|
218
|
+
values {
|
|
219
|
+
uid
|
|
220
|
+
label
|
|
221
|
+
swatch_data {
|
|
222
|
+
__typename
|
|
223
|
+
value
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
variants {
|
|
228
|
+
product {
|
|
229
|
+
id
|
|
230
|
+
sku
|
|
231
|
+
name
|
|
232
|
+
stock_status
|
|
233
|
+
price_range {
|
|
234
|
+
minimum_price {
|
|
235
|
+
regular_price { value currency }
|
|
236
|
+
final_price { value currency }
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
attributes {
|
|
241
|
+
code
|
|
242
|
+
label
|
|
243
|
+
value_index
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
... on GroupedProduct {
|
|
248
|
+
items {
|
|
249
|
+
qty
|
|
250
|
+
position
|
|
251
|
+
product {
|
|
252
|
+
... on ProductInterface {
|
|
253
|
+
__typename
|
|
254
|
+
id
|
|
255
|
+
uid
|
|
256
|
+
sku
|
|
257
|
+
name
|
|
258
|
+
url_key
|
|
259
|
+
stock_status
|
|
260
|
+
price_range {
|
|
261
|
+
minimum_price {
|
|
262
|
+
regular_price { value currency }
|
|
263
|
+
final_price { value currency }
|
|
264
|
+
discount { amount_off percent_off }
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
thumbnail { url label }
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
... on BundleProduct {
|
|
273
|
+
dynamic_price
|
|
274
|
+
price_view
|
|
275
|
+
bundleItems: items {
|
|
276
|
+
uid
|
|
277
|
+
option_id
|
|
278
|
+
title
|
|
279
|
+
type
|
|
280
|
+
required
|
|
281
|
+
position
|
|
282
|
+
options {
|
|
283
|
+
uid
|
|
284
|
+
id
|
|
285
|
+
label
|
|
286
|
+
quantity
|
|
287
|
+
can_change_quantity
|
|
288
|
+
is_default
|
|
289
|
+
price
|
|
290
|
+
price_type
|
|
291
|
+
product {
|
|
292
|
+
sku
|
|
293
|
+
price_range { minimum_price { final_price { value currency } } }
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
180
298
|
}
|
|
181
299
|
}
|
|
182
300
|
}
|
|
@@ -477,12 +595,20 @@ export const GET_CART = `
|
|
|
477
595
|
name
|
|
478
596
|
url_key
|
|
479
597
|
thumbnail { url label }
|
|
598
|
+
price_range {
|
|
599
|
+
minimum_price {
|
|
600
|
+
regular_price { value currency }
|
|
601
|
+
final_price { value currency }
|
|
602
|
+
}
|
|
603
|
+
}
|
|
480
604
|
}
|
|
481
605
|
quantity
|
|
482
606
|
prices {
|
|
483
607
|
price { value currency }
|
|
484
608
|
row_total { value currency }
|
|
485
609
|
row_total_including_tax { value currency }
|
|
610
|
+
total_item_discount { value }
|
|
611
|
+
discounts { amount { value currency } label }
|
|
486
612
|
}
|
|
487
613
|
... on ConfigurableCartItem {
|
|
488
614
|
configurable_options {
|
|
@@ -490,6 +616,12 @@ export const GET_CART = `
|
|
|
490
616
|
value_label
|
|
491
617
|
}
|
|
492
618
|
}
|
|
619
|
+
... on BundleCartItem {
|
|
620
|
+
bundle_options {
|
|
621
|
+
label
|
|
622
|
+
values { label quantity }
|
|
623
|
+
}
|
|
624
|
+
}
|
|
493
625
|
}
|
|
494
626
|
prices {
|
|
495
627
|
subtotal_excluding_tax { value currency }
|
|
@@ -562,12 +694,14 @@ export const ADD_TO_CART = `
|
|
|
562
694
|
id
|
|
563
695
|
items {
|
|
564
696
|
uid
|
|
565
|
-
product { id sku name url_key thumbnail { url label } }
|
|
697
|
+
product { id sku name url_key thumbnail { url label } price_range { minimum_price { regular_price { value currency } final_price { value currency } } } }
|
|
566
698
|
quantity
|
|
567
699
|
prices {
|
|
568
700
|
price { value currency }
|
|
569
701
|
row_total { value currency }
|
|
570
702
|
row_total_including_tax { value currency }
|
|
703
|
+
total_item_discount { value }
|
|
704
|
+
discounts { amount { value currency } label }
|
|
571
705
|
}
|
|
572
706
|
... on ConfigurableCartItem {
|
|
573
707
|
configurable_options {
|
|
@@ -575,11 +709,19 @@ export const ADD_TO_CART = `
|
|
|
575
709
|
value_label
|
|
576
710
|
}
|
|
577
711
|
}
|
|
712
|
+
... on BundleCartItem {
|
|
713
|
+
bundle_options {
|
|
714
|
+
label
|
|
715
|
+
values { label quantity }
|
|
716
|
+
}
|
|
717
|
+
}
|
|
578
718
|
}
|
|
579
719
|
prices {
|
|
580
720
|
subtotal_excluding_tax { value currency }
|
|
581
721
|
subtotal_including_tax { value currency }
|
|
582
722
|
grand_total { value currency }
|
|
723
|
+
discounts { amount { value currency } label }
|
|
724
|
+
applied_taxes { amount { value currency } label }
|
|
583
725
|
}
|
|
584
726
|
}
|
|
585
727
|
user_errors {
|
|
@@ -601,18 +743,22 @@ export const UPDATE_CART_ITEM = `
|
|
|
601
743
|
id
|
|
602
744
|
items {
|
|
603
745
|
uid
|
|
604
|
-
product { id sku name url_key thumbnail { url label } }
|
|
746
|
+
product { id sku name url_key thumbnail { url label } price_range { minimum_price { regular_price { value currency } final_price { value currency } } } }
|
|
605
747
|
quantity
|
|
606
748
|
prices {
|
|
607
749
|
price { value currency }
|
|
608
750
|
row_total { value currency }
|
|
609
751
|
row_total_including_tax { value currency }
|
|
752
|
+
total_item_discount { value }
|
|
753
|
+
discounts { amount { value currency } label }
|
|
610
754
|
}
|
|
611
755
|
}
|
|
612
756
|
prices {
|
|
613
757
|
subtotal_excluding_tax { value currency }
|
|
614
758
|
subtotal_including_tax { value currency }
|
|
615
759
|
grand_total { value currency }
|
|
760
|
+
discounts { amount { value currency } label }
|
|
761
|
+
applied_taxes { amount { value currency } label }
|
|
616
762
|
}
|
|
617
763
|
}
|
|
618
764
|
}
|
|
@@ -625,18 +771,22 @@ export const REMOVE_CART_ITEM = `
|
|
|
625
771
|
id
|
|
626
772
|
items {
|
|
627
773
|
uid
|
|
628
|
-
product { id sku name url_key thumbnail { url label } }
|
|
774
|
+
product { id sku name url_key thumbnail { url label } price_range { minimum_price { regular_price { value currency } final_price { value currency } } } }
|
|
629
775
|
quantity
|
|
630
776
|
prices {
|
|
631
777
|
price { value currency }
|
|
632
778
|
row_total { value currency }
|
|
633
779
|
row_total_including_tax { value currency }
|
|
780
|
+
total_item_discount { value }
|
|
781
|
+
discounts { amount { value currency } label }
|
|
634
782
|
}
|
|
635
783
|
}
|
|
636
784
|
prices {
|
|
637
785
|
subtotal_excluding_tax { value currency }
|
|
638
786
|
subtotal_including_tax { value currency }
|
|
639
787
|
grand_total { value currency }
|
|
788
|
+
discounts { amount { value currency } label }
|
|
789
|
+
applied_taxes { amount { value currency } label }
|
|
640
790
|
}
|
|
641
791
|
}
|
|
642
792
|
}
|
|
@@ -692,8 +842,20 @@ export const GET_CMS_BLOCKS = `
|
|
|
692
842
|
`;
|
|
693
843
|
// Search Query
|
|
694
844
|
export const SEARCH_PRODUCTS = `
|
|
695
|
-
query SearchProducts(
|
|
696
|
-
|
|
845
|
+
query SearchProducts(
|
|
846
|
+
$search: String!
|
|
847
|
+
$pageSize: Int!
|
|
848
|
+
$currentPage: Int!
|
|
849
|
+
$filter: ProductAttributeFilterInput
|
|
850
|
+
$sort: ProductAttributeSortInput
|
|
851
|
+
) {
|
|
852
|
+
products(
|
|
853
|
+
search: $search
|
|
854
|
+
filter: $filter
|
|
855
|
+
pageSize: $pageSize
|
|
856
|
+
currentPage: $currentPage
|
|
857
|
+
sort: $sort
|
|
858
|
+
) {
|
|
697
859
|
total_count
|
|
698
860
|
page_info {
|
|
699
861
|
current_page
|
|
@@ -723,6 +885,22 @@ export const SEARCH_PRODUCTS = `
|
|
|
723
885
|
label
|
|
724
886
|
}
|
|
725
887
|
}
|
|
888
|
+
aggregations {
|
|
889
|
+
attribute_code
|
|
890
|
+
label
|
|
891
|
+
options {
|
|
892
|
+
value
|
|
893
|
+
label
|
|
894
|
+
count
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
sort_fields {
|
|
898
|
+
default
|
|
899
|
+
options {
|
|
900
|
+
value
|
|
901
|
+
label
|
|
902
|
+
}
|
|
903
|
+
}
|
|
726
904
|
}
|
|
727
905
|
}
|
|
728
906
|
`;
|
|
@@ -988,6 +1166,26 @@ export const GET_RELATED_PRODUCTS = `
|
|
|
988
1166
|
label
|
|
989
1167
|
}
|
|
990
1168
|
}
|
|
1169
|
+
crosssell_products {
|
|
1170
|
+
__typename
|
|
1171
|
+
id
|
|
1172
|
+
uid
|
|
1173
|
+
sku
|
|
1174
|
+
name
|
|
1175
|
+
url_key
|
|
1176
|
+
stock_status
|
|
1177
|
+
price_range {
|
|
1178
|
+
minimum_price {
|
|
1179
|
+
regular_price { value currency }
|
|
1180
|
+
final_price { value currency }
|
|
1181
|
+
discount { amount_off percent_off }
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
thumbnail {
|
|
1185
|
+
url
|
|
1186
|
+
label
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
991
1189
|
}
|
|
992
1190
|
}
|
|
993
1191
|
}
|
|
@@ -1037,6 +1235,26 @@ export const GET_RELATED_PRODUCTS_BY_SKU = `
|
|
|
1037
1235
|
label
|
|
1038
1236
|
}
|
|
1039
1237
|
}
|
|
1238
|
+
crosssell_products {
|
|
1239
|
+
__typename
|
|
1240
|
+
id
|
|
1241
|
+
uid
|
|
1242
|
+
sku
|
|
1243
|
+
name
|
|
1244
|
+
url_key
|
|
1245
|
+
stock_status
|
|
1246
|
+
price_range {
|
|
1247
|
+
minimum_price {
|
|
1248
|
+
regular_price { value currency }
|
|
1249
|
+
final_price { value currency }
|
|
1250
|
+
discount { amount_off percent_off }
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
thumbnail {
|
|
1254
|
+
url
|
|
1255
|
+
label
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1040
1258
|
}
|
|
1041
1259
|
}
|
|
1042
1260
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cobrastyle/adapter-magento2",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"exports": {
|
|
@@ -13,12 +13,12 @@
|
|
|
13
13
|
"dist"
|
|
14
14
|
],
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@cobrastyle/shared-types": "1.0
|
|
16
|
+
"@cobrastyle/shared-types": "1.1.0"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
19
|
"@types/node": "^20.0.0",
|
|
20
20
|
"typescript": "^5.3.0",
|
|
21
|
-
"@cobrastyle/adapter-conformance": "1.0.
|
|
21
|
+
"@cobrastyle/adapter-conformance": "1.0.2"
|
|
22
22
|
},
|
|
23
23
|
"license": "MIT",
|
|
24
24
|
"repository": {
|