@scayle/storefront-core 7.64.3 → 7.65.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/CHANGELOG.md +22 -0
- package/dist/api/customer.cjs +1 -5
- package/dist/api/customer.mjs +1 -3
- package/dist/cache/cached.cjs +1 -1
- package/dist/cache/cached.mjs +1 -1
- package/dist/helpers/filterHelper.cjs +8 -3
- package/dist/helpers/filterHelper.d.ts +1 -1
- package/dist/helpers/filterHelper.mjs +8 -3
- package/dist/helpers/productHelpers.cjs +5 -3
- package/dist/helpers/productHelpers.d.ts +1 -1
- package/dist/helpers/productHelpers.mjs +8 -7
- package/dist/helpers/sanitizationHelpers.cjs +2 -3
- package/dist/helpers/sanitizationHelpers.mjs +4 -3
- package/dist/helpers/sortingHelper.cjs +3 -2
- package/dist/helpers/sortingHelper.d.ts +8 -13
- package/dist/helpers/sortingHelper.mjs +7 -2
- package/dist/rpc/methods/cbd.cjs +23 -25
- package/dist/rpc/methods/cbd.d.ts +2 -1
- package/dist/rpc/methods/cbd.mjs +48 -28
- package/dist/rpc/methods/checkout/checkout.cjs +5 -1
- package/dist/rpc/methods/checkout/checkout.mjs +9 -1
- package/dist/rpc/methods/products.cjs +67 -50
- package/dist/rpc/methods/products.d.ts +3 -4
- package/dist/rpc/methods/products.mjs +74 -48
- package/dist/types/bapi/filter.d.ts +8 -3
- package/dist/types/bapi/product.d.ts +16 -7
- package/dist/utils/hash.cjs +5 -4
- package/dist/utils/hash.d.ts +1 -1
- package/dist/utils/hash.mjs +3 -2
- package/package.json +5 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# @scayle/storefront-core
|
|
2
2
|
|
|
3
|
+
## 7.65.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Improves the handling of `getOrderDataByCbd` RPC to return descriptive errors in case the validation of the token fails.
|
|
8
|
+
|
|
9
|
+
In case the token can't be validated using the Checkout Secret, this is now returned and a warning on the server is logged.
|
|
10
|
+
|
|
11
|
+
If the token has expired, this is now also returned and logged on the server.
|
|
12
|
+
|
|
13
|
+
- Support passing `categoryId` as an alternative to the category path in `getProductsByCategory` and `getFilters`
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- Fixed cached fallback ttl to be used only if passed `option.ttl` is undefined
|
|
18
|
+
|
|
19
|
+
## 7.64.4
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- Replaced `radash` utils with custom native implementations
|
|
24
|
+
|
|
3
25
|
## 7.64.3
|
|
4
26
|
|
|
5
27
|
### Patch Changes
|
package/dist/api/customer.cjs
CHANGED
|
@@ -15,14 +15,10 @@ class CustomerAPIClient {
|
|
|
15
15
|
this.context = context;
|
|
16
16
|
}
|
|
17
17
|
get headers() {
|
|
18
|
-
const accessHeader = this.context.checkout.accessHeader;
|
|
19
18
|
return {
|
|
20
19
|
Authorization: `Bearer ${this.context.accessToken}`,
|
|
21
20
|
Accept: "application/json",
|
|
22
|
-
"Content-Type": "application/json"
|
|
23
|
-
...(accessHeader ? {
|
|
24
|
-
"X-Access-Header": accessHeader
|
|
25
|
-
} : {})
|
|
21
|
+
"Content-Type": "application/json"
|
|
26
22
|
};
|
|
27
23
|
}
|
|
28
24
|
async sendRequest(request, retry = true) {
|
package/dist/api/customer.mjs
CHANGED
|
@@ -9,12 +9,10 @@ export class CustomerAPIClient {
|
|
|
9
9
|
this.context = context;
|
|
10
10
|
}
|
|
11
11
|
get headers() {
|
|
12
|
-
const accessHeader = this.context.checkout.accessHeader;
|
|
13
12
|
return {
|
|
14
13
|
Authorization: `Bearer ${this.context.accessToken}`,
|
|
15
14
|
Accept: "application/json",
|
|
16
|
-
"Content-Type": "application/json"
|
|
17
|
-
...accessHeader ? { "X-Access-Header": accessHeader } : {}
|
|
15
|
+
"Content-Type": "application/json"
|
|
18
16
|
};
|
|
19
17
|
}
|
|
20
18
|
async sendRequest(request, retry = true) {
|
package/dist/cache/cached.cjs
CHANGED
|
@@ -71,7 +71,7 @@ class Cached {
|
|
|
71
71
|
if (!this.isCacheEnabled) {
|
|
72
72
|
return;
|
|
73
73
|
}
|
|
74
|
-
const ttl = options?.ttl
|
|
74
|
+
const ttl = options?.ttl ?? 60 * MINUTE;
|
|
75
75
|
if (ttl) {
|
|
76
76
|
await (0, _utils.timeout)(_constants.CACHE_TIMEOUT, this.cache.set(cacheKey, value, ttl));
|
|
77
77
|
}
|
package/dist/cache/cached.mjs
CHANGED
|
@@ -5,7 +5,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.transformToWhereCondition = exports.transformStateToFilters = exports.transformSortToFilter = exports.transformMinAndMaxPriceToFilter = exports.serializeFilters = exports.mergeFilters = exports.isFilterActive = exports.groupFiltersByKey = exports.groupFilterableValuesByKey = exports.getGroupedFilterableValues = exports.getFilterablePriceValue = exports.getActiveFilters = exports.deserializeFilters = void 0;
|
|
7
7
|
var _storefrontApi = require("@scayle/storefront-api");
|
|
8
|
-
var _radash = require("radash");
|
|
9
8
|
var _sortingHelper = require("./sortingHelper.cjs");
|
|
10
9
|
const transformToWhereCondition = conditions => {
|
|
11
10
|
const where = {
|
|
@@ -108,7 +107,13 @@ const getActiveFilters = (filters, activeFilters) => {
|
|
|
108
107
|
};
|
|
109
108
|
exports.getActiveFilters = getActiveFilters;
|
|
110
109
|
const groupFiltersByKey = filters => {
|
|
111
|
-
|
|
110
|
+
const groupedFilters = filters.reduce((acc, item) => {
|
|
111
|
+
const groupId = item.key;
|
|
112
|
+
if (!acc[groupId]) acc[groupId] = [];
|
|
113
|
+
acc[groupId].push(item);
|
|
114
|
+
return acc;
|
|
115
|
+
}, {});
|
|
116
|
+
return Object.entries(groupedFilters);
|
|
112
117
|
};
|
|
113
118
|
exports.groupFiltersByKey = groupFiltersByKey;
|
|
114
119
|
const transformMinAndMaxPriceToFilter = prices => {
|
|
@@ -145,7 +150,7 @@ const getFilterablePriceValue = (filterableValues, key = "min") => {
|
|
|
145
150
|
};
|
|
146
151
|
exports.getFilterablePriceValue = getFilterablePriceValue;
|
|
147
152
|
const serializeFilters = filter => {
|
|
148
|
-
if (
|
|
153
|
+
if (Object.keys(filter).length === 0) {
|
|
149
154
|
return void 0;
|
|
150
155
|
}
|
|
151
156
|
return Object.assign({}, ...Object.entries(filter).map(([filterName, filterValue]) => {
|
|
@@ -33,7 +33,7 @@ export declare const transformStateToFilters: (state: {
|
|
|
33
33
|
export declare const mergeFilters: (filters: TransformedFilter[]) => Record<string, any>;
|
|
34
34
|
export declare const isFilterActive: (filters: Record<string, any>, filterToCheck: TransformedFilter) => any;
|
|
35
35
|
export declare const getActiveFilters: (filters: Record<string, any>, activeFilters: Record<string, any>) => TransformedFilter[];
|
|
36
|
-
export declare const groupFiltersByKey: (filters: TransformedFilter[]) =>
|
|
36
|
+
export declare const groupFiltersByKey: (filters: TransformedFilter[]) => [string, TransformedFilter[]][];
|
|
37
37
|
export declare const transformMinAndMaxPriceToFilter: (prices: (CentAmount | undefined)[]) => any;
|
|
38
38
|
export declare const transformSortToFilter: (sort: string) => {
|
|
39
39
|
by: import("@scayle/storefront-api").APISortOption;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { FilterTypes } from "@scayle/storefront-api";
|
|
2
|
-
import { group, isEmpty } from "radash";
|
|
3
2
|
import { getSortByValue } from "./sortingHelper.mjs";
|
|
4
3
|
export const transformToWhereCondition = (conditions) => {
|
|
5
4
|
const where = { attributes: [] };
|
|
@@ -96,7 +95,13 @@ export const getActiveFilters = (filters, activeFilters) => {
|
|
|
96
95
|
return [].concat(...Object.values(filters)).filter((item) => isFilterActive(activeFilters, item)) || [];
|
|
97
96
|
};
|
|
98
97
|
export const groupFiltersByKey = (filters) => {
|
|
99
|
-
|
|
98
|
+
const groupedFilters = filters.reduce((acc, item) => {
|
|
99
|
+
const groupId = item.key;
|
|
100
|
+
if (!acc[groupId]) acc[groupId] = [];
|
|
101
|
+
acc[groupId].push(item);
|
|
102
|
+
return acc;
|
|
103
|
+
}, {});
|
|
104
|
+
return Object.entries(groupedFilters);
|
|
100
105
|
};
|
|
101
106
|
export const transformMinAndMaxPriceToFilter = (prices) => {
|
|
102
107
|
const [min = 0, max = 1e5] = prices;
|
|
@@ -127,7 +132,7 @@ export const getFilterablePriceValue = (filterableValues, key = "min") => {
|
|
|
127
132
|
return prices.value[key];
|
|
128
133
|
};
|
|
129
134
|
export const serializeFilters = (filter) => {
|
|
130
|
-
if (
|
|
135
|
+
if (Object.keys(filter).length === 0) {
|
|
131
136
|
return void 0;
|
|
132
137
|
}
|
|
133
138
|
return Object.assign(
|
|
@@ -5,7 +5,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.slugify = exports.isVariantInStock = exports.isInStock = exports.getVariantCrosssellingValues = exports.getVariantBySize = exports.getVariant = exports.getTotalAppliedReductions = exports.getSizeFromVariant = exports.getSizeFromSpecificVariant = exports.getProductSiblings = exports.getProductPath = exports.getProductColors = exports.getProductAndSiblingsColors = exports.getPrice = exports.getOriginalPrice = exports.getLowestPrice = exports.getLatestCategory = exports.getCategoriesByRoute = exports.getBadgeLabel = exports.getAttribute = exports.getAppliedReductionsByCategory = exports.getAllSizesFromVariants = void 0;
|
|
7
7
|
var _storefrontApi = require("@scayle/storefront-api");
|
|
8
|
-
var _radash = require("radash");
|
|
9
8
|
var _slugify = _interopRequireDefault(require("slugify"));
|
|
10
9
|
var _product = require("../constants/product.cjs");
|
|
11
10
|
var _attributeHelpers = require("./attributeHelpers.cjs");
|
|
@@ -97,7 +96,10 @@ const getVariant = (variants, id) => {
|
|
|
97
96
|
return variants?.find(variant => variant.id === id);
|
|
98
97
|
};
|
|
99
98
|
exports.getVariant = getVariant;
|
|
100
|
-
const getAllSizesFromVariants = (variantsAttributes, attributeName = "shopSize") =>
|
|
99
|
+
const getAllSizesFromVariants = (variantsAttributes, attributeName = "shopSize") => {
|
|
100
|
+
const array = variantsAttributes.map(variant => (0, _storefrontApi.getFirstAttributeValue)(variant.attributes, attributeName)).filter(Boolean);
|
|
101
|
+
return [...new Map(array.map(item => [item?.id ?? item, item])).values()];
|
|
102
|
+
};
|
|
101
103
|
exports.getAllSizesFromVariants = getAllSizesFromVariants;
|
|
102
104
|
const getProductSiblings = (product, colorAttributeName = "colorDetail") => {
|
|
103
105
|
if (!product) {
|
|
@@ -180,7 +182,7 @@ const getVariantCrosssellingValues = variants => {
|
|
|
180
182
|
return [];
|
|
181
183
|
}
|
|
182
184
|
const crossellings = variants.map(variant => variant.advancedAttributes?.variantCrosssellings).filter(Boolean);
|
|
183
|
-
const uniqueCrossellings = (
|
|
185
|
+
const uniqueCrossellings = [...new Map(crossellings.map(item => [item?.id ?? item, item])).values()];
|
|
184
186
|
const values = uniqueCrossellings.map(r => r?.values);
|
|
185
187
|
const fieldSets = (0, _arrayHelpers.flattenDeep)(values).map(r => r?.fieldSet);
|
|
186
188
|
return (0, _arrayHelpers.flattenDeep)(fieldSets).map(r => r?.value).filter(it => !!it);
|
|
@@ -30,7 +30,7 @@ export declare const getAppliedReductionsByCategory: (price: VariantPrice | Bask
|
|
|
30
30
|
export declare const getSizeFromVariant: (variant: Variant, attributeName?: string) => Value | undefined;
|
|
31
31
|
export declare const getSizeFromSpecificVariant: (product: Product, variantId?: number) => Value | null | undefined;
|
|
32
32
|
export declare const getVariant: (variants: Variant[], id: number) => Variant | undefined;
|
|
33
|
-
export declare const getAllSizesFromVariants: (variantsAttributes: Variant[], attributeName?: string) =>
|
|
33
|
+
export declare const getAllSizesFromVariants: (variantsAttributes: Variant[], attributeName?: string) => any[];
|
|
34
34
|
export declare const getProductSiblings: (product?: Product | null, colorAttributeName?: string) => ProductSibling[];
|
|
35
35
|
export declare const getProductColors: (product: Product, colorAttributeName?: string) => string[];
|
|
36
36
|
export declare const getVariantBySize: (variants: Variant[], size: Value, sizeAttributeName?: string) => Variant | undefined;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { getFirstAttributeValue } from "@scayle/storefront-api";
|
|
2
|
-
import { unique } from "radash";
|
|
3
2
|
import baseSlugify from "slugify";
|
|
4
3
|
import { ProductImageType } from "../constants/product.mjs";
|
|
5
4
|
import { getAttributeValue, getAttributeValueTuples } from "./attributeHelpers.mjs";
|
|
@@ -73,12 +72,12 @@ export const getSizeFromSpecificVariant = (product, variantId) => {
|
|
|
73
72
|
export const getVariant = (variants, id) => {
|
|
74
73
|
return variants?.find((variant) => variant.id === id);
|
|
75
74
|
};
|
|
76
|
-
export const getAllSizesFromVariants = (variantsAttributes, attributeName = "shopSize") =>
|
|
77
|
-
variantsAttributes.map(
|
|
75
|
+
export const getAllSizesFromVariants = (variantsAttributes, attributeName = "shopSize") => {
|
|
76
|
+
const array = variantsAttributes.map(
|
|
78
77
|
(variant) => getFirstAttributeValue(variant.attributes, attributeName)
|
|
79
|
-
).filter(Boolean)
|
|
80
|
-
(
|
|
81
|
-
|
|
78
|
+
).filter(Boolean);
|
|
79
|
+
return [...new Map(array.map((item) => [item?.id ?? item, item])).values()];
|
|
80
|
+
};
|
|
82
81
|
export const getProductSiblings = (product, colorAttributeName = "colorDetail") => {
|
|
83
82
|
if (!product) {
|
|
84
83
|
return [];
|
|
@@ -163,7 +162,9 @@ export const getVariantCrosssellingValues = (variants) => {
|
|
|
163
162
|
return [];
|
|
164
163
|
}
|
|
165
164
|
const crossellings = variants.map((variant) => variant.advancedAttributes?.variantCrosssellings).filter(Boolean);
|
|
166
|
-
const uniqueCrossellings =
|
|
165
|
+
const uniqueCrossellings = [
|
|
166
|
+
...new Map(crossellings.map((item) => [item?.id ?? item, item])).values()
|
|
167
|
+
];
|
|
167
168
|
const values = uniqueCrossellings.map((r) => r?.values);
|
|
168
169
|
const fieldSets = flattenDeep(values).map((r) => r?.fieldSet);
|
|
169
170
|
return flattenDeep(fieldSets).map((r) => r?.value).filter((it) => !!it);
|
|
@@ -4,7 +4,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.stripShopLocaleFromPath = exports.purifySensitiveValue = exports.purifySensitiveData = exports.createAndPurifyHeaders = void 0;
|
|
7
|
-
var _radash = require("radash");
|
|
8
7
|
const SANITIZATION_MASK = "********";
|
|
9
8
|
const regex = /(?<!^).(?!$)/g;
|
|
10
9
|
const stripShopLocaleFromPath = (locale, path, splitter = "/") => path.split(splitter).filter(segment => segment.toLowerCase() !== locale.toLowerCase()).join("/");
|
|
@@ -15,7 +14,7 @@ const purifySensitiveValue = (value, showFirstAndLastChar = false) => {
|
|
|
15
14
|
exports.purifySensitiveValue = purifySensitiveValue;
|
|
16
15
|
const purifySensitiveData = (data = {}, blacklistedKeys = ["password"], showFirstAndLastChar = false) => {
|
|
17
16
|
return Object.entries(data).reduce((purifiedPayload, [key, value]) => {
|
|
18
|
-
if (
|
|
17
|
+
if (!!value && value.constructor === Object) {
|
|
19
18
|
purifiedPayload[key] = purifySensitiveData(value, blacklistedKeys);
|
|
20
19
|
return purifiedPayload;
|
|
21
20
|
}
|
|
@@ -30,7 +29,7 @@ const purifySensitiveData = (data = {}, blacklistedKeys = ["password"], showFirs
|
|
|
30
29
|
};
|
|
31
30
|
exports.purifySensitiveData = purifySensitiveData;
|
|
32
31
|
const createAndPurifyHeaders = headers => {
|
|
33
|
-
const sanitizedHeaders = (
|
|
32
|
+
const sanitizedHeaders = Object.fromEntries(Object.entries(headers).filter(([_, value]) => value !== void 0));
|
|
34
33
|
return new Headers(sanitizedHeaders);
|
|
35
34
|
};
|
|
36
35
|
exports.createAndPurifyHeaders = createAndPurifyHeaders;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { isObject, shake } from "radash";
|
|
2
1
|
const SANITIZATION_MASK = "********";
|
|
3
2
|
const regex = /(?<!^).(?!$)/g;
|
|
4
3
|
export const stripShopLocaleFromPath = (locale, path, splitter = "/") => path.split(splitter).filter((segment) => segment.toLowerCase() !== locale.toLowerCase()).join("/");
|
|
@@ -8,7 +7,7 @@ export const purifySensitiveValue = (value, showFirstAndLastChar = false) => {
|
|
|
8
7
|
export const purifySensitiveData = (data = {}, blacklistedKeys = ["password"], showFirstAndLastChar = false) => {
|
|
9
8
|
return Object.entries(data).reduce(
|
|
10
9
|
(purifiedPayload, [key, value]) => {
|
|
11
|
-
if (
|
|
10
|
+
if (!!value && value.constructor === Object) {
|
|
12
11
|
purifiedPayload[key] = purifySensitiveData(value, blacklistedKeys);
|
|
13
12
|
return purifiedPayload;
|
|
14
13
|
}
|
|
@@ -26,6 +25,8 @@ export const purifySensitiveData = (data = {}, blacklistedKeys = ["password"], s
|
|
|
26
25
|
);
|
|
27
26
|
};
|
|
28
27
|
export const createAndPurifyHeaders = (headers) => {
|
|
29
|
-
const sanitizedHeaders =
|
|
28
|
+
const sanitizedHeaders = Object.fromEntries(
|
|
29
|
+
Object.entries(headers).filter(([_, value]) => value !== void 0)
|
|
30
|
+
);
|
|
30
31
|
return new Headers(sanitizedHeaders);
|
|
31
32
|
};
|
|
@@ -5,7 +5,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.getSortingValues = exports.getSortByValue = void 0;
|
|
7
7
|
var _storefrontApi = require("@scayle/storefront-api");
|
|
8
|
-
var _radash = require("radash");
|
|
9
8
|
var _sorting = require("../constants/sorting.cjs");
|
|
10
9
|
const SORTING_VALUES = {
|
|
11
10
|
topSeller: {
|
|
@@ -44,7 +43,9 @@ const SORTING_VALUES = {
|
|
|
44
43
|
query: _sorting.SortQuery.REDUCTION_ASC
|
|
45
44
|
}
|
|
46
45
|
};
|
|
47
|
-
const getSortingValues = (options = ["topSeller", "dateNewest", "priceDesc", "priceAsc", "reductionDesc", "reductionAsc"]) =>
|
|
46
|
+
const getSortingValues = (options = ["topSeller", "dateNewest", "priceDesc", "priceAsc", "reductionDesc", "reductionAsc"]) => {
|
|
47
|
+
return Object.fromEntries(options.filter(key => key in SORTING_VALUES).map(key => [key, SORTING_VALUES[key]]));
|
|
48
|
+
};
|
|
48
49
|
exports.getSortingValues = getSortingValues;
|
|
49
50
|
const getSortByValue = (query, defaultSort) => {
|
|
50
51
|
switch (query) {
|
|
@@ -1,42 +1,37 @@
|
|
|
1
1
|
import { APISortOption, APISortOrder } from '@scayle/storefront-api';
|
|
2
2
|
import type { Query, SortingValueKey } from '../index';
|
|
3
|
-
export declare const getSortingValues: (options?: Array<SortingValueKey>) =>
|
|
4
|
-
|
|
3
|
+
export declare const getSortingValues: (options?: Array<SortingValueKey>) => {
|
|
4
|
+
[k: string]: {
|
|
5
5
|
by: APISortOption;
|
|
6
6
|
direction: APISortOrder;
|
|
7
7
|
name: "topseller";
|
|
8
8
|
query: "topseller";
|
|
9
|
-
}
|
|
10
|
-
dateNewest: {
|
|
9
|
+
} | {
|
|
11
10
|
by: APISortOption;
|
|
12
11
|
name: "date_newest";
|
|
13
12
|
query: "date-newest";
|
|
14
|
-
}
|
|
15
|
-
priceDesc: {
|
|
13
|
+
} | {
|
|
16
14
|
by: APISortOption;
|
|
17
15
|
direction: APISortOrder;
|
|
18
16
|
name: "price_desc";
|
|
19
17
|
query: "price-desc";
|
|
20
|
-
}
|
|
21
|
-
priceAsc: {
|
|
18
|
+
} | {
|
|
22
19
|
by: APISortOption;
|
|
23
20
|
direction: APISortOrder;
|
|
24
21
|
name: "price_asc";
|
|
25
22
|
query: "price-asc";
|
|
26
|
-
}
|
|
27
|
-
reductionDesc: {
|
|
23
|
+
} | {
|
|
28
24
|
by: APISortOption;
|
|
29
25
|
direction: APISortOrder;
|
|
30
26
|
name: "reduction_desc";
|
|
31
27
|
query: "reduction-desc";
|
|
32
|
-
}
|
|
33
|
-
reductionAsc: {
|
|
28
|
+
} | {
|
|
34
29
|
by: APISortOption;
|
|
35
30
|
direction: APISortOrder;
|
|
36
31
|
name: "reduction_asc";
|
|
37
32
|
query: "reduction-asc";
|
|
38
33
|
};
|
|
39
|
-
}
|
|
34
|
+
};
|
|
40
35
|
export declare const getSortByValue: (query: Query, defaultSort?: SortingValueKey) => {
|
|
41
36
|
by: APISortOption;
|
|
42
37
|
direction: APISortOrder;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { APISortOption, APISortOrder } from "@scayle/storefront-api";
|
|
2
|
-
import { pick } from "radash";
|
|
3
2
|
import { SortName, SortQuery } from "../constants/sorting.mjs";
|
|
4
3
|
const SORTING_VALUES = {
|
|
5
4
|
topSeller: {
|
|
@@ -45,7 +44,13 @@ export const getSortingValues = (options = [
|
|
|
45
44
|
"priceAsc",
|
|
46
45
|
"reductionDesc",
|
|
47
46
|
"reductionAsc"
|
|
48
|
-
]) =>
|
|
47
|
+
]) => {
|
|
48
|
+
return Object.fromEntries(
|
|
49
|
+
options.filter((key) => key in SORTING_VALUES).map(
|
|
50
|
+
(key) => [key, SORTING_VALUES[key]]
|
|
51
|
+
)
|
|
52
|
+
);
|
|
53
|
+
};
|
|
49
54
|
export const getSortByValue = (query, defaultSort) => {
|
|
50
55
|
switch (query) {
|
|
51
56
|
case SortQuery.PRICE_DESC:
|
package/dist/rpc/methods/cbd.cjs
CHANGED
|
@@ -4,37 +4,35 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.getOrderDataByCbd = void 0;
|
|
7
|
+
var _constants = require("../../constants/index.cjs");
|
|
8
|
+
var _errors = require("../../errors/index.cjs");
|
|
7
9
|
var _hash = require("../../utils/hash.cjs");
|
|
8
10
|
const getOrderDataByCbd = exports.getOrderDataByCbd = async function getOrderDataByCbd2({
|
|
9
11
|
cbdToken
|
|
10
12
|
}, context) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
const payload = await (0, _hash.verifyOrderSuccessToken)(cbdToken, context.checkout.secret);
|
|
14
|
+
if (!payload) {
|
|
15
|
+
context.log.warn("Unable to verify CBD token. Please check that you configured the correct Checkout Secret");
|
|
16
|
+
return new _errors.ErrorResponse(_constants.HttpStatusCode.BAD_REQUEST, _constants.HttpStatusMessage.BAD_REQUEST, "Unable to verify CBD token.");
|
|
13
17
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
context.
|
|
25
|
-
return;
|
|
18
|
+
if (context.checkout.cbdExpiration && Math.floor(Date.now() / 1e3) - payload.issued_at > context.checkout.cbdExpiration) {
|
|
19
|
+
context.log.warn("Attempting to use expired CBD token");
|
|
20
|
+
return new _errors.ErrorResponse(_constants.HttpStatusCode.BAD_REQUEST, _constants.HttpStatusMessage.BAD_REQUEST, "The CBD token has expired.");
|
|
21
|
+
}
|
|
22
|
+
const checkoutUrl = context.checkout.url;
|
|
23
|
+
const basicAuth = (0, _hash.encodeBase64)(`${context.checkout.user}:${context.checkout.token}`);
|
|
24
|
+
const response = await fetch(`${checkoutUrl}/api/v1/orders/${payload.order_id}`, {
|
|
25
|
+
headers: {
|
|
26
|
+
Accept: "application/json",
|
|
27
|
+
Authorization: `Basic ${basicAuth}`,
|
|
28
|
+
"X-Shop-Id": context.shopId.toString()
|
|
26
29
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
headers: {
|
|
30
|
-
Accept: "application/json",
|
|
31
|
-
Authorization: `Basic ${accessToken}`,
|
|
32
|
-
"x-shop-id": shopId.toString(),
|
|
33
|
-
...(accessHeader ? {
|
|
34
|
-
"X-Access-Header": accessHeader
|
|
35
|
-
} : {})
|
|
36
|
-
}
|
|
37
|
-
});
|
|
30
|
+
});
|
|
31
|
+
if (response.ok) {
|
|
38
32
|
return await response.json();
|
|
39
33
|
}
|
|
34
|
+
context.log.error(`Unexpected status code when fetching order from Checkout API: ${response.status}`);
|
|
35
|
+
return new _errors.ErrorResponse(_constants.HttpStatusCode.INTERNAL_SERVER_ERROR, _constants.HttpStatusMessage.INTERNAL_SERVER_ERROR, "Unknown error", {
|
|
36
|
+
detail: `Fetching order failed with status code ${response.status}`
|
|
37
|
+
});
|
|
40
38
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
+
import { ErrorResponse } from '../../errors';
|
|
1
2
|
import type { Order, RpcContext } from '../../types';
|
|
2
3
|
export declare const getOrderDataByCbd: ({ cbdToken }: {
|
|
3
4
|
cbdToken: string;
|
|
4
|
-
}, context: RpcContext) => Promise<Order |
|
|
5
|
+
}, context: RpcContext) => Promise<Order | ErrorResponse>;
|
package/dist/rpc/methods/cbd.mjs
CHANGED
|
@@ -1,35 +1,55 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { HttpStatusCode, HttpStatusMessage } from "../../constants/index.mjs";
|
|
2
|
+
import { ErrorResponse } from "../../errors/index.mjs";
|
|
3
|
+
import { encodeBase64, verifyOrderSuccessToken } from "../../utils/hash.mjs";
|
|
2
4
|
export const getOrderDataByCbd = async function getOrderDataByCbd2({ cbdToken }, context) {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
+
const payload = await verifyOrderSuccessToken(
|
|
6
|
+
cbdToken,
|
|
7
|
+
context.checkout.secret
|
|
8
|
+
);
|
|
9
|
+
if (!payload) {
|
|
10
|
+
context.log.warn(
|
|
11
|
+
"Unable to verify CBD token. Please check that you configured the correct Checkout Secret"
|
|
12
|
+
);
|
|
13
|
+
return new ErrorResponse(
|
|
14
|
+
HttpStatusCode.BAD_REQUEST,
|
|
15
|
+
HttpStatusMessage.BAD_REQUEST,
|
|
16
|
+
"Unable to verify CBD token."
|
|
17
|
+
);
|
|
5
18
|
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const checkoutUsername = context.checkout.user;
|
|
13
|
-
const checkoutToken = context.checkout.token;
|
|
14
|
-
const checkoutUrl = context.checkout.url;
|
|
15
|
-
if (context.checkout.cbdExpiration && Math.floor(Date.now() / 1e3) - payload.issued_at > context.checkout.cbdExpiration) {
|
|
16
|
-
context.log.debug("Attempting to use expired CBD token");
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
const accessToken = encodeBase64(
|
|
20
|
-
`${checkoutUsername}:${unescape(checkoutToken)}`
|
|
19
|
+
if (context.checkout.cbdExpiration && Math.floor(Date.now() / 1e3) - payload.issued_at > context.checkout.cbdExpiration) {
|
|
20
|
+
context.log.warn("Attempting to use expired CBD token");
|
|
21
|
+
return new ErrorResponse(
|
|
22
|
+
HttpStatusCode.BAD_REQUEST,
|
|
23
|
+
HttpStatusMessage.BAD_REQUEST,
|
|
24
|
+
"The CBD token has expired."
|
|
21
25
|
);
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
}
|
|
27
|
+
const checkoutUrl = context.checkout.url;
|
|
28
|
+
const basicAuth = encodeBase64(
|
|
29
|
+
`${context.checkout.user}:${context.checkout.token}`
|
|
30
|
+
);
|
|
31
|
+
const response = await fetch(
|
|
32
|
+
`${checkoutUrl}/api/v1/orders/${payload.order_id}`,
|
|
33
|
+
{
|
|
34
|
+
headers: {
|
|
35
|
+
Accept: "application/json",
|
|
36
|
+
Authorization: `Basic ${basicAuth}`,
|
|
37
|
+
"X-Shop-Id": context.shopId.toString()
|
|
31
38
|
}
|
|
32
|
-
|
|
39
|
+
}
|
|
40
|
+
);
|
|
41
|
+
if (response.ok) {
|
|
33
42
|
return await response.json();
|
|
34
43
|
}
|
|
44
|
+
context.log.error(
|
|
45
|
+
`Unexpected status code when fetching order from Checkout API: ${response.status}`
|
|
46
|
+
);
|
|
47
|
+
return new ErrorResponse(
|
|
48
|
+
HttpStatusCode.INTERNAL_SERVER_ERROR,
|
|
49
|
+
HttpStatusMessage.INTERNAL_SERVER_ERROR,
|
|
50
|
+
"Unknown error",
|
|
51
|
+
{
|
|
52
|
+
detail: `Fetching order failed with status code ${response.status}`
|
|
53
|
+
}
|
|
54
|
+
);
|
|
35
55
|
};
|
|
@@ -5,10 +5,14 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.getCheckoutToken = void 0;
|
|
7
7
|
var _jose = require("jose");
|
|
8
|
+
var _types = require("../../../types/index.cjs");
|
|
8
9
|
var _errors = require("../../../errors/index.cjs");
|
|
9
10
|
var _constants = require("../../../constants/index.cjs");
|
|
10
11
|
var _user = require("../user.cjs");
|
|
11
12
|
const getCheckoutToken = exports.getCheckoutToken = async function getCheckoutToken2(jwtPayload = {}, context) {
|
|
13
|
+
if (!(0, _types.hasSession)(context)) {
|
|
14
|
+
return new _errors.ErrorResponse(_constants.HttpStatusCode.BAD_REQUEST, _constants.HttpStatusMessage.BAD_REQUEST, "No Session found");
|
|
15
|
+
}
|
|
12
16
|
if (!context.accessToken) {
|
|
13
17
|
return new _errors.ErrorResponse(_constants.HttpStatusCode.UNAUTHORIZED, _constants.HttpStatusMessage.UNAUTHORIZED, "No access token present");
|
|
14
18
|
}
|
|
@@ -33,7 +37,7 @@ const getCheckoutToken = exports.getCheckoutToken = async function getCheckoutTo
|
|
|
33
37
|
carrier,
|
|
34
38
|
basketId: context.basketKey,
|
|
35
39
|
campaignKey: context.campaignKey
|
|
36
|
-
}).setIssuedAt(now).setNotBefore(now).setExpirationTime("1h").setIssuer(`${"@scayle/storefront-core"}@${"7.
|
|
40
|
+
}).setIssuedAt(now).setNotBefore(now).setExpirationTime("1h").setIssuer(`${"@scayle/storefront-core"}@${"7.65.0"}`).setProtectedHeader({
|
|
37
41
|
alg: "HS256",
|
|
38
42
|
typ: "JWT"
|
|
39
43
|
}).sign(secret);
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
import { SignJWT } from "jose";
|
|
2
|
+
import { hasSession } from "../../../types/index.mjs";
|
|
2
3
|
import { ErrorResponse } from "../../../errors/index.mjs";
|
|
3
4
|
import { HttpStatusCode, HttpStatusMessage } from "../../../constants/index.mjs";
|
|
4
5
|
import { getAccessToken } from "../user.mjs";
|
|
5
6
|
export const getCheckoutToken = async function getCheckoutToken2(jwtPayload = {}, context) {
|
|
7
|
+
if (!hasSession(context)) {
|
|
8
|
+
return new ErrorResponse(
|
|
9
|
+
HttpStatusCode.BAD_REQUEST,
|
|
10
|
+
HttpStatusMessage.BAD_REQUEST,
|
|
11
|
+
"No Session found"
|
|
12
|
+
);
|
|
13
|
+
}
|
|
6
14
|
if (!context.accessToken) {
|
|
7
15
|
return new ErrorResponse(
|
|
8
16
|
HttpStatusCode.UNAUTHORIZED,
|
|
@@ -27,7 +35,7 @@ export const getCheckoutToken = async function getCheckoutToken2(jwtPayload = {}
|
|
|
27
35
|
carrier,
|
|
28
36
|
basketId: context.basketKey,
|
|
29
37
|
campaignKey: context.campaignKey
|
|
30
|
-
}).setIssuedAt(now).setNotBefore(now).setExpirationTime("1h").setIssuer(`${"@scayle/storefront-core"}@${"7.
|
|
38
|
+
}).setIssuedAt(now).setNotBefore(now).setExpirationTime("1h").setIssuer(`${"@scayle/storefront-core"}@${"7.65.0"}`).setProtectedHeader({ alg: "HS256", typ: "JWT" }).sign(secret);
|
|
31
39
|
return {
|
|
32
40
|
accessToken: refreshedAccessToken,
|
|
33
41
|
checkoutJwt
|
|
@@ -68,31 +68,36 @@ const getProductsByReferenceKeys = exports.getProductsByReferenceKeys = async fu
|
|
|
68
68
|
pricePromotionKey: options.pricePromotionKey
|
|
69
69
|
});
|
|
70
70
|
};
|
|
71
|
-
const getProductsCount = exports.getProductsCount = async function getProductsCount2({
|
|
72
|
-
category = "/",
|
|
73
|
-
categoryId = void 0,
|
|
74
|
-
where = void 0,
|
|
75
|
-
includeSoldOut = false,
|
|
76
|
-
includeSellableForFree = false,
|
|
77
|
-
orFiltersOperator = void 0
|
|
78
|
-
}, {
|
|
71
|
+
const getProductsCount = exports.getProductsCount = async function getProductsCount2(params, {
|
|
79
72
|
cached,
|
|
80
73
|
bapiClient,
|
|
81
74
|
campaignKey
|
|
82
75
|
}) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
76
|
+
const {
|
|
77
|
+
where = void 0,
|
|
78
|
+
includeSoldOut = false,
|
|
79
|
+
includeSellableForFree = false,
|
|
80
|
+
orFiltersOperator = void 0
|
|
81
|
+
} = params;
|
|
82
|
+
let category;
|
|
83
|
+
let categoryId;
|
|
84
|
+
if ("category" in params && !params.category) {
|
|
85
|
+
category = "/";
|
|
86
|
+
}
|
|
87
|
+
if ("categoryId" in params) {
|
|
88
|
+
categoryId = params.categoryId;
|
|
89
|
+
} else if (category && category !== "/") {
|
|
90
|
+
const result = await cached(bapiClient.categories.getByPath, {
|
|
91
|
+
cacheKeyPrefix: `getByPath-categories-${category}`
|
|
92
|
+
})((0, _helpers.splitAndRemoveEmpty)(category));
|
|
93
|
+
categoryId = result.id;
|
|
89
94
|
}
|
|
90
95
|
const productCount = await cached(bapiClient.products.query, {
|
|
91
96
|
ttl: 15 * _cache.MINUTE,
|
|
92
97
|
cacheKeyPrefix: "products-query"
|
|
93
98
|
})({
|
|
94
99
|
where: {
|
|
95
|
-
categoryId
|
|
100
|
+
categoryId,
|
|
96
101
|
minPrice: where?.minPrice,
|
|
97
102
|
maxPrice: where?.maxPrice,
|
|
98
103
|
attributes: where?.attributes,
|
|
@@ -131,32 +136,38 @@ const fetchAllFiltersForCategory = exports.fetchAllFiltersForCategory = async fu
|
|
|
131
136
|
return await cached(fetchAndMapFiltersToSlugs, {
|
|
132
137
|
ttl: 4 * 60 * 60,
|
|
133
138
|
// cached for 4 hours
|
|
134
|
-
cacheKey: `filters-for-category-${category.
|
|
139
|
+
cacheKey: `filters-for-category-${category.id}`
|
|
135
140
|
})();
|
|
136
141
|
};
|
|
137
|
-
const getFilters = exports.getFilters = async function getFilters2({
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
145
|
-
let
|
|
142
|
+
const getFilters = exports.getFilters = async function getFilters2(params, context) {
|
|
143
|
+
const {
|
|
144
|
+
includedFilters,
|
|
145
|
+
where = void 0,
|
|
146
|
+
includeSoldOut = false,
|
|
147
|
+
includeSellableForFree = false,
|
|
148
|
+
orFiltersOperator
|
|
149
|
+
} = params;
|
|
150
|
+
let category;
|
|
151
|
+
let categoryId;
|
|
146
152
|
const {
|
|
147
153
|
cached,
|
|
148
154
|
bapiClient,
|
|
149
155
|
campaignKey
|
|
150
156
|
} = context;
|
|
151
|
-
if (category
|
|
152
|
-
|
|
157
|
+
if ("category" in params && !params.category) {
|
|
158
|
+
category = "/";
|
|
159
|
+
}
|
|
160
|
+
if ("categoryId" in params) {
|
|
161
|
+
categoryId = params.categoryId;
|
|
162
|
+
} else if (category && category !== "/") {
|
|
163
|
+
const result = await cached(bapiClient.categories.getByPath, {
|
|
153
164
|
cacheKeyPrefix: `getByPath-categories-${category}`
|
|
154
165
|
})((0, _helpers.splitAndRemoveEmpty)(category));
|
|
166
|
+
categoryId = result.id;
|
|
155
167
|
}
|
|
156
168
|
const response = await fetchAllFiltersForCategory({
|
|
157
169
|
category: {
|
|
158
|
-
id:
|
|
159
|
-
slug: category
|
|
170
|
+
id: categoryId
|
|
160
171
|
},
|
|
161
172
|
includedFilters
|
|
162
173
|
}, context);
|
|
@@ -173,7 +184,7 @@ const getFilters = exports.getFilters = async function getFilters2({
|
|
|
173
184
|
cacheKeyPrefix: `get-filters-${category}`
|
|
174
185
|
})({
|
|
175
186
|
where: {
|
|
176
|
-
categoryId
|
|
187
|
+
categoryId,
|
|
177
188
|
minPrice: where?.minPrice,
|
|
178
189
|
maxPrice: where?.maxPrice,
|
|
179
190
|
term: where?.term,
|
|
@@ -189,7 +200,7 @@ const getFilters = exports.getFilters = async function getFilters2({
|
|
|
189
200
|
cacheKeyPrefix: `products-query-category-${category === "/" ? "root" : category}`
|
|
190
201
|
})({
|
|
191
202
|
where: {
|
|
192
|
-
categoryId
|
|
203
|
+
categoryId,
|
|
193
204
|
minPrice: where?.minPrice,
|
|
194
205
|
maxPrice: where?.maxPrice,
|
|
195
206
|
term: where?.term,
|
|
@@ -207,34 +218,40 @@ const getFilters = exports.getFilters = async function getFilters2({
|
|
|
207
218
|
unfilteredCount: productCount?.pagination.total
|
|
208
219
|
};
|
|
209
220
|
};
|
|
210
|
-
const getProductsByCategory = exports.getProductsByCategory = async function getProductsByCategory2({
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
}
|
|
223
|
-
let result;
|
|
221
|
+
const getProductsByCategory = exports.getProductsByCategory = async function getProductsByCategory2(params, context) {
|
|
222
|
+
const {
|
|
223
|
+
cache,
|
|
224
|
+
with: _with,
|
|
225
|
+
perPage = 20,
|
|
226
|
+
page = 1,
|
|
227
|
+
where = void 0,
|
|
228
|
+
sort = void 0,
|
|
229
|
+
pricePromotionKey = "",
|
|
230
|
+
includeSellableForFree = void 0,
|
|
231
|
+
includeSoldOut = void 0,
|
|
232
|
+
orFiltersOperator = void 0
|
|
233
|
+
} = params;
|
|
224
234
|
const {
|
|
225
235
|
cached,
|
|
226
236
|
bapiClient,
|
|
227
237
|
campaignKey
|
|
228
238
|
} = context;
|
|
229
|
-
|
|
230
|
-
|
|
239
|
+
let category;
|
|
240
|
+
let categoryId;
|
|
241
|
+
if ("category" in params && !params.category) {
|
|
242
|
+
category = "/";
|
|
243
|
+
}
|
|
244
|
+
if ("categoryId" in params) {
|
|
245
|
+
categoryId = params.categoryId;
|
|
246
|
+
} else if (category && category !== "/") {
|
|
247
|
+
const result = await cached(bapiClient.categories.getByPath, {
|
|
231
248
|
cacheKeyPrefix: `getByPath-categories-${category}`
|
|
232
249
|
})((0, _helpers.splitAndRemoveEmpty)(category));
|
|
250
|
+
categoryId = result.id;
|
|
233
251
|
}
|
|
234
252
|
const response = await fetchAllFiltersForCategory({
|
|
235
253
|
category: {
|
|
236
|
-
id:
|
|
237
|
-
slug: category
|
|
254
|
+
id: categoryId
|
|
238
255
|
}
|
|
239
256
|
}, context);
|
|
240
257
|
if (response instanceof _errors.ErrorResponse) {
|
|
@@ -255,7 +272,7 @@ const getProductsByCategory = exports.getProductsByCategory = async function get
|
|
|
255
272
|
})({
|
|
256
273
|
where: {
|
|
257
274
|
term: where?.term,
|
|
258
|
-
categoryId
|
|
275
|
+
categoryId,
|
|
259
276
|
minPrice: where?.minPrice,
|
|
260
277
|
maxPrice: where?.maxPrice,
|
|
261
278
|
attributes: [...sanitizedAttributes, ...(where?.whitelistAttributes || [])],
|
|
@@ -4,21 +4,20 @@ import { ErrorResponse } from '../../errors';
|
|
|
4
4
|
export declare const getProductById: (options: FetchProductParams, { bapiClient, cached, campaignKey, withParams }: RpcContext) => Promise<Product>;
|
|
5
5
|
export declare const getProductsByIds: (options: FetchProductsByIdsParams, { bapiClient, cached, campaignKey, withParams }: RpcContext) => Promise<Product[]>;
|
|
6
6
|
export declare const getProductsByReferenceKeys: (options: FetchProductsByReferenceKeysParams, { bapiClient, cached, campaignKey, withParams }: RpcContext) => Promise<Product[]>;
|
|
7
|
-
export declare const getProductsCount: (
|
|
7
|
+
export declare const getProductsCount: (params: FetchProductsCountParams, { cached, bapiClient, campaignKey }: RpcContext) => Promise<{
|
|
8
8
|
count: number;
|
|
9
9
|
}>;
|
|
10
10
|
export declare const fetchAllFiltersForCategory: ({ includedFilters, category }: {
|
|
11
11
|
includedFilters?: string[];
|
|
12
12
|
category: {
|
|
13
|
-
slug: string;
|
|
14
13
|
id?: number;
|
|
15
14
|
};
|
|
16
15
|
}, { cached, bapiClient, campaignKey }: RpcContext) => Promise<string[]>;
|
|
17
|
-
export declare const getFilters: (
|
|
16
|
+
export declare const getFilters: (params: FetchFiltersParams, context: RpcContext) => Promise<(string[] & ErrorResponse) | {
|
|
18
17
|
filters: FiltersEndpointResponseData;
|
|
19
18
|
unfilteredCount: number;
|
|
20
19
|
}>;
|
|
21
|
-
export declare const getProductsByCategory: (
|
|
20
|
+
export declare const getProductsByCategory: (params: FetchProductsByCategoryParams, context: RpcContext) => Promise<(string[] & ErrorResponse) | {
|
|
22
21
|
products: Product[];
|
|
23
22
|
pagination: {
|
|
24
23
|
current: number;
|
|
@@ -45,27 +45,32 @@ export const getProductsByReferenceKeys = async function getProductsByReferenceK
|
|
|
45
45
|
pricePromotionKey: options.pricePromotionKey
|
|
46
46
|
});
|
|
47
47
|
};
|
|
48
|
-
export const getProductsCount = async function getProductsCount2({
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
let
|
|
57
|
-
if (category
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
48
|
+
export const getProductsCount = async function getProductsCount2(params, { cached, bapiClient, campaignKey }) {
|
|
49
|
+
const {
|
|
50
|
+
where = void 0,
|
|
51
|
+
includeSoldOut = false,
|
|
52
|
+
includeSellableForFree = false,
|
|
53
|
+
orFiltersOperator = void 0
|
|
54
|
+
} = params;
|
|
55
|
+
let category;
|
|
56
|
+
let categoryId;
|
|
57
|
+
if ("category" in params && !params.category) {
|
|
58
|
+
category = "/";
|
|
59
|
+
}
|
|
60
|
+
if ("categoryId" in params) {
|
|
61
|
+
categoryId = params.categoryId;
|
|
62
|
+
} else if (category && category !== "/") {
|
|
63
|
+
const result = await cached(bapiClient.categories.getByPath, {
|
|
64
|
+
cacheKeyPrefix: `getByPath-categories-${category}`
|
|
65
|
+
})(splitAndRemoveEmpty(category));
|
|
66
|
+
categoryId = result.id;
|
|
62
67
|
}
|
|
63
68
|
const productCount = await cached(bapiClient.products.query, {
|
|
64
69
|
ttl: 15 * MINUTE,
|
|
65
70
|
cacheKeyPrefix: "products-query"
|
|
66
71
|
})({
|
|
67
72
|
where: {
|
|
68
|
-
categoryId
|
|
73
|
+
categoryId,
|
|
69
74
|
minPrice: where?.minPrice,
|
|
70
75
|
maxPrice: where?.maxPrice,
|
|
71
76
|
attributes: where?.attributes,
|
|
@@ -95,26 +100,36 @@ export const fetchAllFiltersForCategory = async function fetchAllFiltersForCateg
|
|
|
95
100
|
return await cached(fetchAndMapFiltersToSlugs, {
|
|
96
101
|
ttl: 4 * 60 * 60,
|
|
97
102
|
// cached for 4 hours
|
|
98
|
-
cacheKey: `filters-for-category-${category.
|
|
103
|
+
cacheKey: `filters-for-category-${category.id}`
|
|
99
104
|
})();
|
|
100
105
|
};
|
|
101
|
-
export const getFilters = async function getFilters2({
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
let
|
|
106
|
+
export const getFilters = async function getFilters2(params, context) {
|
|
107
|
+
const {
|
|
108
|
+
includedFilters,
|
|
109
|
+
where = void 0,
|
|
110
|
+
includeSoldOut = false,
|
|
111
|
+
includeSellableForFree = false,
|
|
112
|
+
orFiltersOperator
|
|
113
|
+
} = params;
|
|
114
|
+
let category;
|
|
115
|
+
let categoryId;
|
|
110
116
|
const { cached, bapiClient, campaignKey } = context;
|
|
111
|
-
if (category
|
|
112
|
-
|
|
117
|
+
if ("category" in params && !params.category) {
|
|
118
|
+
category = "/";
|
|
119
|
+
}
|
|
120
|
+
if ("categoryId" in params) {
|
|
121
|
+
categoryId = params.categoryId;
|
|
122
|
+
} else if (category && category !== "/") {
|
|
123
|
+
const result = await cached(bapiClient.categories.getByPath, {
|
|
113
124
|
cacheKeyPrefix: `getByPath-categories-${category}`
|
|
114
125
|
})(splitAndRemoveEmpty(category));
|
|
126
|
+
categoryId = result.id;
|
|
115
127
|
}
|
|
116
128
|
const response = await fetchAllFiltersForCategory(
|
|
117
|
-
{
|
|
129
|
+
{
|
|
130
|
+
category: { id: categoryId },
|
|
131
|
+
includedFilters
|
|
132
|
+
},
|
|
118
133
|
context
|
|
119
134
|
);
|
|
120
135
|
if (response instanceof ErrorResponse) {
|
|
@@ -131,7 +146,7 @@ export const getFilters = async function getFilters2({
|
|
|
131
146
|
cacheKeyPrefix: `get-filters-${category}`
|
|
132
147
|
})({
|
|
133
148
|
where: {
|
|
134
|
-
categoryId
|
|
149
|
+
categoryId,
|
|
135
150
|
minPrice: where?.minPrice,
|
|
136
151
|
maxPrice: where?.maxPrice,
|
|
137
152
|
term: where?.term,
|
|
@@ -151,7 +166,7 @@ export const getFilters = async function getFilters2({
|
|
|
151
166
|
cacheKeyPrefix: `products-query-category-${category === "/" ? "root" : category}`
|
|
152
167
|
})({
|
|
153
168
|
where: {
|
|
154
|
-
categoryId
|
|
169
|
+
categoryId,
|
|
155
170
|
minPrice: where?.minPrice,
|
|
156
171
|
maxPrice: where?.maxPrice,
|
|
157
172
|
term: where?.term,
|
|
@@ -173,28 +188,39 @@ export const getFilters = async function getFilters2({
|
|
|
173
188
|
unfilteredCount: productCount?.pagination.total
|
|
174
189
|
};
|
|
175
190
|
};
|
|
176
|
-
export const getProductsByCategory = async function getProductsByCategory2({
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
}
|
|
189
|
-
let result;
|
|
191
|
+
export const getProductsByCategory = async function getProductsByCategory2(params, context) {
|
|
192
|
+
const {
|
|
193
|
+
cache,
|
|
194
|
+
with: _with,
|
|
195
|
+
perPage = 20,
|
|
196
|
+
page = 1,
|
|
197
|
+
where = void 0,
|
|
198
|
+
sort = void 0,
|
|
199
|
+
pricePromotionKey = "",
|
|
200
|
+
includeSellableForFree = void 0,
|
|
201
|
+
includeSoldOut = void 0,
|
|
202
|
+
orFiltersOperator = void 0
|
|
203
|
+
} = params;
|
|
190
204
|
const { cached, bapiClient, campaignKey } = context;
|
|
191
|
-
|
|
192
|
-
|
|
205
|
+
let category;
|
|
206
|
+
let categoryId;
|
|
207
|
+
if ("category" in params && !params.category) {
|
|
208
|
+
category = "/";
|
|
209
|
+
}
|
|
210
|
+
if ("categoryId" in params) {
|
|
211
|
+
categoryId = params.categoryId;
|
|
212
|
+
} else if (category && category !== "/") {
|
|
213
|
+
const result = await cached(bapiClient.categories.getByPath, {
|
|
193
214
|
cacheKeyPrefix: `getByPath-categories-${category}`
|
|
194
215
|
})(splitAndRemoveEmpty(category));
|
|
216
|
+
categoryId = result.id;
|
|
195
217
|
}
|
|
196
218
|
const response = await fetchAllFiltersForCategory(
|
|
197
|
-
{
|
|
219
|
+
{
|
|
220
|
+
category: {
|
|
221
|
+
id: categoryId
|
|
222
|
+
}
|
|
223
|
+
},
|
|
198
224
|
context
|
|
199
225
|
);
|
|
200
226
|
if (response instanceof ErrorResponse) {
|
|
@@ -215,7 +241,7 @@ export const getProductsByCategory = async function getProductsByCategory2({
|
|
|
215
241
|
)({
|
|
216
242
|
where: {
|
|
217
243
|
term: where?.term,
|
|
218
|
-
categoryId
|
|
244
|
+
categoryId,
|
|
219
245
|
minPrice: where?.minPrice,
|
|
220
246
|
maxPrice: where?.maxPrice,
|
|
221
247
|
attributes: [
|
|
@@ -15,8 +15,7 @@ export interface FilterParams {
|
|
|
15
15
|
sort?: ProductSortConfig;
|
|
16
16
|
orFiltersOperator?: ProductsSearchEndpointParameters['orFiltersOperator'];
|
|
17
17
|
}
|
|
18
|
-
export
|
|
19
|
-
category: string;
|
|
18
|
+
export type FetchFiltersParams = {
|
|
20
19
|
includedFilters?: Array<string>;
|
|
21
20
|
where?: {
|
|
22
21
|
term?: ProductSearchQuery['term'];
|
|
@@ -28,7 +27,13 @@ export interface FetchFiltersParams {
|
|
|
28
27
|
includeSoldOut?: boolean;
|
|
29
28
|
includeSellableForFree?: boolean;
|
|
30
29
|
orFiltersOperator?: ProductsSearchEndpointParameters['orFiltersOperator'];
|
|
31
|
-
}
|
|
30
|
+
} & ({
|
|
31
|
+
category?: string;
|
|
32
|
+
categoryId?: undefined;
|
|
33
|
+
} | {
|
|
34
|
+
categoryId: number;
|
|
35
|
+
category?: undefined;
|
|
36
|
+
});
|
|
32
37
|
export interface FetchFiltersResponse {
|
|
33
38
|
filters: FiltersEndpointResponseData;
|
|
34
39
|
unfilteredCount: number;
|
|
@@ -43,8 +43,7 @@ export interface FetchProductsByReferenceKeysParams {
|
|
|
43
43
|
with?: ProductWith;
|
|
44
44
|
pricePromotionKey?: string;
|
|
45
45
|
}
|
|
46
|
-
export
|
|
47
|
-
category: string;
|
|
46
|
+
export type FetchProductsByCategoryParams = {
|
|
48
47
|
with?: ProductWith;
|
|
49
48
|
cache?: CacheOptions;
|
|
50
49
|
includedFilters?: Array<string>;
|
|
@@ -63,14 +62,18 @@ export interface FetchProductsByCategoryParams {
|
|
|
63
62
|
includeSellableForFree?: boolean;
|
|
64
63
|
includeSoldOut?: boolean;
|
|
65
64
|
orFiltersOperator?: ProductsSearchEndpointParameters['orFiltersOperator'];
|
|
66
|
-
}
|
|
65
|
+
} & ({
|
|
66
|
+
category?: string;
|
|
67
|
+
categoryId?: undefined;
|
|
68
|
+
} | {
|
|
69
|
+
categoryId: number;
|
|
70
|
+
category?: undefined;
|
|
71
|
+
});
|
|
67
72
|
export interface FetchProductsByCategoryResponse {
|
|
68
73
|
products: Product[];
|
|
69
74
|
pagination: ProductsByIdsEndpointResponseData['pagination'];
|
|
70
75
|
}
|
|
71
|
-
export
|
|
72
|
-
category?: string;
|
|
73
|
-
categoryId?: number;
|
|
76
|
+
export type FetchProductsCountParams = {
|
|
74
77
|
where?: {
|
|
75
78
|
term?: ProductSearchQuery['term'];
|
|
76
79
|
minPrice?: ProductSearchQuery['minPrice'];
|
|
@@ -80,7 +83,13 @@ export interface FetchProductsCountParams {
|
|
|
80
83
|
includeSoldOut?: boolean;
|
|
81
84
|
includeSellableForFree?: boolean;
|
|
82
85
|
orFiltersOperator?: ProductsSearchEndpointParameters['orFiltersOperator'];
|
|
83
|
-
}
|
|
86
|
+
} & ({
|
|
87
|
+
category?: string;
|
|
88
|
+
categoryId?: undefined;
|
|
89
|
+
} | {
|
|
90
|
+
categoryId: number;
|
|
91
|
+
category?: undefined;
|
|
92
|
+
});
|
|
84
93
|
export interface FetchProductsCountResponse {
|
|
85
94
|
count: number;
|
|
86
95
|
}
|
package/dist/utils/hash.cjs
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.verifyOrderSuccessToken = exports.sha256 = exports.md5 = exports.hmac = exports.encodeBase64 = exports.decodeBase64 = exports.buildSignature = exports.buildHashPayload = void 0;
|
|
7
7
|
var _uncrypto = require("uncrypto");
|
|
8
8
|
const md5 = async value => {
|
|
9
9
|
if (!process.env.SFC_OMIT_MD5) {
|
|
@@ -54,14 +54,15 @@ const decodeBase64 = string => {
|
|
|
54
54
|
return new TextDecoder().decode(base64ToBytes(string));
|
|
55
55
|
};
|
|
56
56
|
exports.decodeBase64 = decodeBase64;
|
|
57
|
-
const
|
|
57
|
+
const verifyOrderSuccessToken = async (token, secret) => {
|
|
58
58
|
const [encodedPayload, signature] = token.split(".", 2);
|
|
59
59
|
const expectedSignature = encodeBase64(await hmac(encodedPayload, secret));
|
|
60
60
|
if (expectedSignature === signature) {
|
|
61
|
-
return decodeBase64(encodedPayload);
|
|
61
|
+
return JSON.parse(decodeBase64(encodedPayload));
|
|
62
62
|
}
|
|
63
|
+
return void 0;
|
|
63
64
|
};
|
|
64
|
-
exports.
|
|
65
|
+
exports.verifyOrderSuccessToken = verifyOrderSuccessToken;
|
|
65
66
|
const buildHashPayload = payload => encodeBase64(JSON.stringify(payload));
|
|
66
67
|
exports.buildHashPayload = buildHashPayload;
|
|
67
68
|
const buildSignature = async (payloadHash, secret) => encodeBase64(await hmac(payloadHash, secret));
|
package/dist/utils/hash.d.ts
CHANGED
|
@@ -3,6 +3,6 @@ export declare const sha256: (value: string) => Promise<string>;
|
|
|
3
3
|
export declare const hmac: (value: string, secret: string, algorithm?: string) => Promise<string>;
|
|
4
4
|
export declare const encodeBase64: (string: string) => string;
|
|
5
5
|
export declare const decodeBase64: (string: string) => string;
|
|
6
|
-
export declare const
|
|
6
|
+
export declare const verifyOrderSuccessToken: <T = unknown>(token: string, secret: string) => Promise<T | undefined>;
|
|
7
7
|
export declare const buildHashPayload: (payload: unknown) => string;
|
|
8
8
|
export declare const buildSignature: (payloadHash: string, secret: string) => Promise<string>;
|
package/dist/utils/hash.mjs
CHANGED
|
@@ -50,12 +50,13 @@ export const decodeBase64 = (string) => {
|
|
|
50
50
|
}
|
|
51
51
|
return new TextDecoder().decode(base64ToBytes(string));
|
|
52
52
|
};
|
|
53
|
-
export const
|
|
53
|
+
export const verifyOrderSuccessToken = async (token, secret) => {
|
|
54
54
|
const [encodedPayload, signature] = token.split(".", 2);
|
|
55
55
|
const expectedSignature = encodeBase64(await hmac(encodedPayload, secret));
|
|
56
56
|
if (expectedSignature === signature) {
|
|
57
|
-
return decodeBase64(encodedPayload);
|
|
57
|
+
return JSON.parse(decodeBase64(encodedPayload));
|
|
58
58
|
}
|
|
59
|
+
return void 0;
|
|
59
60
|
};
|
|
60
61
|
export const buildHashPayload = (payload) => encodeBase64(JSON.stringify(payload));
|
|
61
62
|
export const buildSignature = async (payloadHash, secret) => encodeBase64(await hmac(payloadHash, secret));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scayle/storefront-core",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.65.0",
|
|
4
4
|
"description": "Collection of essential utilities to work with the Storefront API",
|
|
5
5
|
"author": "SCAYLE Commerce Engine",
|
|
6
6
|
"license": "MIT",
|
|
@@ -63,7 +63,6 @@
|
|
|
63
63
|
"crypto-js": "^4.2.0",
|
|
64
64
|
"hookable": "^5.5.3",
|
|
65
65
|
"jose": "^5.6.3",
|
|
66
|
-
"radash": "^12.1.0",
|
|
67
66
|
"slugify": "^1.6.6",
|
|
68
67
|
"ufo": "^1.5.3",
|
|
69
68
|
"uncrypto": "^0.1.3",
|
|
@@ -72,18 +71,18 @@
|
|
|
72
71
|
"devDependencies": {
|
|
73
72
|
"@scayle/eslint-config-storefront": "4.3.0",
|
|
74
73
|
"@types/crypto-js": "4.2.2",
|
|
75
|
-
"@types/node": "20.16.
|
|
74
|
+
"@types/node": "20.16.5",
|
|
76
75
|
"@types/webpack-env": "1.18.5",
|
|
77
76
|
"@vitest/coverage-v8": "2.0.5",
|
|
78
77
|
"dprint": "0.47.2",
|
|
79
|
-
"eslint": "9.
|
|
78
|
+
"eslint": "9.10.0",
|
|
80
79
|
"eslint-formatter-gitlab": "5.1.0",
|
|
81
80
|
"publint": "0.2.10",
|
|
82
81
|
"rimraf": "6.0.1",
|
|
83
82
|
"ts-node": "10.9.2",
|
|
84
|
-
"typescript": "5.
|
|
83
|
+
"typescript": "5.6.2",
|
|
85
84
|
"unbuild": "2.0.0",
|
|
86
|
-
"unstorage": "1.
|
|
85
|
+
"unstorage": "1.12.0",
|
|
87
86
|
"vitest": "2.0.5"
|
|
88
87
|
},
|
|
89
88
|
"optionalDependencies": {
|