@cobrastyle/adapter-magento2 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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 +164 -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 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,32 @@ export const GET_PRODUCT_BY_ID = `
|
|
|
177
210
|
message
|
|
178
211
|
}
|
|
179
212
|
}
|
|
213
|
+
... on BundleProduct {
|
|
214
|
+
dynamic_price
|
|
215
|
+
price_view
|
|
216
|
+
bundleItems: items {
|
|
217
|
+
uid
|
|
218
|
+
option_id
|
|
219
|
+
title
|
|
220
|
+
type
|
|
221
|
+
required
|
|
222
|
+
position
|
|
223
|
+
options {
|
|
224
|
+
uid
|
|
225
|
+
id
|
|
226
|
+
label
|
|
227
|
+
quantity
|
|
228
|
+
can_change_quantity
|
|
229
|
+
is_default
|
|
230
|
+
price
|
|
231
|
+
price_type
|
|
232
|
+
product {
|
|
233
|
+
sku
|
|
234
|
+
price_range { minimum_price { final_price { value currency } } }
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
180
239
|
}
|
|
181
240
|
}
|
|
182
241
|
}
|
|
@@ -477,12 +536,20 @@ export const GET_CART = `
|
|
|
477
536
|
name
|
|
478
537
|
url_key
|
|
479
538
|
thumbnail { url label }
|
|
539
|
+
price_range {
|
|
540
|
+
minimum_price {
|
|
541
|
+
regular_price { value currency }
|
|
542
|
+
final_price { value currency }
|
|
543
|
+
}
|
|
544
|
+
}
|
|
480
545
|
}
|
|
481
546
|
quantity
|
|
482
547
|
prices {
|
|
483
548
|
price { value currency }
|
|
484
549
|
row_total { value currency }
|
|
485
550
|
row_total_including_tax { value currency }
|
|
551
|
+
total_item_discount { value }
|
|
552
|
+
discounts { amount { value currency } label }
|
|
486
553
|
}
|
|
487
554
|
... on ConfigurableCartItem {
|
|
488
555
|
configurable_options {
|
|
@@ -490,6 +557,12 @@ export const GET_CART = `
|
|
|
490
557
|
value_label
|
|
491
558
|
}
|
|
492
559
|
}
|
|
560
|
+
... on BundleCartItem {
|
|
561
|
+
bundle_options {
|
|
562
|
+
label
|
|
563
|
+
values { label quantity }
|
|
564
|
+
}
|
|
565
|
+
}
|
|
493
566
|
}
|
|
494
567
|
prices {
|
|
495
568
|
subtotal_excluding_tax { value currency }
|
|
@@ -562,12 +635,14 @@ export const ADD_TO_CART = `
|
|
|
562
635
|
id
|
|
563
636
|
items {
|
|
564
637
|
uid
|
|
565
|
-
product { id sku name url_key thumbnail { url label } }
|
|
638
|
+
product { id sku name url_key thumbnail { url label } price_range { minimum_price { regular_price { value currency } final_price { value currency } } } }
|
|
566
639
|
quantity
|
|
567
640
|
prices {
|
|
568
641
|
price { value currency }
|
|
569
642
|
row_total { value currency }
|
|
570
643
|
row_total_including_tax { value currency }
|
|
644
|
+
total_item_discount { value }
|
|
645
|
+
discounts { amount { value currency } label }
|
|
571
646
|
}
|
|
572
647
|
... on ConfigurableCartItem {
|
|
573
648
|
configurable_options {
|
|
@@ -575,11 +650,19 @@ export const ADD_TO_CART = `
|
|
|
575
650
|
value_label
|
|
576
651
|
}
|
|
577
652
|
}
|
|
653
|
+
... on BundleCartItem {
|
|
654
|
+
bundle_options {
|
|
655
|
+
label
|
|
656
|
+
values { label quantity }
|
|
657
|
+
}
|
|
658
|
+
}
|
|
578
659
|
}
|
|
579
660
|
prices {
|
|
580
661
|
subtotal_excluding_tax { value currency }
|
|
581
662
|
subtotal_including_tax { value currency }
|
|
582
663
|
grand_total { value currency }
|
|
664
|
+
discounts { amount { value currency } label }
|
|
665
|
+
applied_taxes { amount { value currency } label }
|
|
583
666
|
}
|
|
584
667
|
}
|
|
585
668
|
user_errors {
|
|
@@ -601,18 +684,22 @@ export const UPDATE_CART_ITEM = `
|
|
|
601
684
|
id
|
|
602
685
|
items {
|
|
603
686
|
uid
|
|
604
|
-
product { id sku name url_key thumbnail { url label } }
|
|
687
|
+
product { id sku name url_key thumbnail { url label } price_range { minimum_price { regular_price { value currency } final_price { value currency } } } }
|
|
605
688
|
quantity
|
|
606
689
|
prices {
|
|
607
690
|
price { value currency }
|
|
608
691
|
row_total { value currency }
|
|
609
692
|
row_total_including_tax { value currency }
|
|
693
|
+
total_item_discount { value }
|
|
694
|
+
discounts { amount { value currency } label }
|
|
610
695
|
}
|
|
611
696
|
}
|
|
612
697
|
prices {
|
|
613
698
|
subtotal_excluding_tax { value currency }
|
|
614
699
|
subtotal_including_tax { value currency }
|
|
615
700
|
grand_total { value currency }
|
|
701
|
+
discounts { amount { value currency } label }
|
|
702
|
+
applied_taxes { amount { value currency } label }
|
|
616
703
|
}
|
|
617
704
|
}
|
|
618
705
|
}
|
|
@@ -625,18 +712,22 @@ export const REMOVE_CART_ITEM = `
|
|
|
625
712
|
id
|
|
626
713
|
items {
|
|
627
714
|
uid
|
|
628
|
-
product { id sku name url_key thumbnail { url label } }
|
|
715
|
+
product { id sku name url_key thumbnail { url label } price_range { minimum_price { regular_price { value currency } final_price { value currency } } } }
|
|
629
716
|
quantity
|
|
630
717
|
prices {
|
|
631
718
|
price { value currency }
|
|
632
719
|
row_total { value currency }
|
|
633
720
|
row_total_including_tax { value currency }
|
|
721
|
+
total_item_discount { value }
|
|
722
|
+
discounts { amount { value currency } label }
|
|
634
723
|
}
|
|
635
724
|
}
|
|
636
725
|
prices {
|
|
637
726
|
subtotal_excluding_tax { value currency }
|
|
638
727
|
subtotal_including_tax { value currency }
|
|
639
728
|
grand_total { value currency }
|
|
729
|
+
discounts { amount { value currency } label }
|
|
730
|
+
applied_taxes { amount { value currency } label }
|
|
640
731
|
}
|
|
641
732
|
}
|
|
642
733
|
}
|
|
@@ -692,8 +783,20 @@ export const GET_CMS_BLOCKS = `
|
|
|
692
783
|
`;
|
|
693
784
|
// Search Query
|
|
694
785
|
export const SEARCH_PRODUCTS = `
|
|
695
|
-
query SearchProducts(
|
|
696
|
-
|
|
786
|
+
query SearchProducts(
|
|
787
|
+
$search: String!
|
|
788
|
+
$pageSize: Int!
|
|
789
|
+
$currentPage: Int!
|
|
790
|
+
$filter: ProductAttributeFilterInput
|
|
791
|
+
$sort: ProductAttributeSortInput
|
|
792
|
+
) {
|
|
793
|
+
products(
|
|
794
|
+
search: $search
|
|
795
|
+
filter: $filter
|
|
796
|
+
pageSize: $pageSize
|
|
797
|
+
currentPage: $currentPage
|
|
798
|
+
sort: $sort
|
|
799
|
+
) {
|
|
697
800
|
total_count
|
|
698
801
|
page_info {
|
|
699
802
|
current_page
|
|
@@ -723,6 +826,22 @@ export const SEARCH_PRODUCTS = `
|
|
|
723
826
|
label
|
|
724
827
|
}
|
|
725
828
|
}
|
|
829
|
+
aggregations {
|
|
830
|
+
attribute_code
|
|
831
|
+
label
|
|
832
|
+
options {
|
|
833
|
+
value
|
|
834
|
+
label
|
|
835
|
+
count
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
sort_fields {
|
|
839
|
+
default
|
|
840
|
+
options {
|
|
841
|
+
value
|
|
842
|
+
label
|
|
843
|
+
}
|
|
844
|
+
}
|
|
726
845
|
}
|
|
727
846
|
}
|
|
728
847
|
`;
|
|
@@ -988,6 +1107,26 @@ export const GET_RELATED_PRODUCTS = `
|
|
|
988
1107
|
label
|
|
989
1108
|
}
|
|
990
1109
|
}
|
|
1110
|
+
crosssell_products {
|
|
1111
|
+
__typename
|
|
1112
|
+
id
|
|
1113
|
+
uid
|
|
1114
|
+
sku
|
|
1115
|
+
name
|
|
1116
|
+
url_key
|
|
1117
|
+
stock_status
|
|
1118
|
+
price_range {
|
|
1119
|
+
minimum_price {
|
|
1120
|
+
regular_price { value currency }
|
|
1121
|
+
final_price { value currency }
|
|
1122
|
+
discount { amount_off percent_off }
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
thumbnail {
|
|
1126
|
+
url
|
|
1127
|
+
label
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
991
1130
|
}
|
|
992
1131
|
}
|
|
993
1132
|
}
|
|
@@ -1037,6 +1176,26 @@ export const GET_RELATED_PRODUCTS_BY_SKU = `
|
|
|
1037
1176
|
label
|
|
1038
1177
|
}
|
|
1039
1178
|
}
|
|
1179
|
+
crosssell_products {
|
|
1180
|
+
__typename
|
|
1181
|
+
id
|
|
1182
|
+
uid
|
|
1183
|
+
sku
|
|
1184
|
+
name
|
|
1185
|
+
url_key
|
|
1186
|
+
stock_status
|
|
1187
|
+
price_range {
|
|
1188
|
+
minimum_price {
|
|
1189
|
+
regular_price { value currency }
|
|
1190
|
+
final_price { value currency }
|
|
1191
|
+
discount { amount_off percent_off }
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
thumbnail {
|
|
1195
|
+
url
|
|
1196
|
+
label
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1040
1199
|
}
|
|
1041
1200
|
}
|
|
1042
1201
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cobrastyle/adapter-magento2",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
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": {
|