@scayle/storefront-core 8.35.0 → 8.37.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 +24 -0
- package/dist/rpc/methods/campaign.d.ts +11 -5
- package/dist/rpc/methods/campaign.mjs +15 -6
- package/dist/rpc/methods/checkout/checkout.mjs +1 -1
- package/dist/rpc/methods/index.d.ts +1 -1
- package/dist/rpc/methods/index.mjs +1 -1
- package/dist/rpc/methods/products.mjs +17 -33
- package/dist/types/sapi/product.d.ts +5 -20
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @scayle/storefront-core
|
|
2
2
|
|
|
3
|
+
## 8.37.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- The `where` parameter for the `getProductsByCategory` and `getProductsCount` RPCs was extended to include the previously missing options `sellableAt`, `hasCampaignReduction`, and `containsSearch`.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Added missing export of the RPC `getCampaign`
|
|
12
|
+
|
|
13
|
+
## 8.36.0
|
|
14
|
+
|
|
15
|
+
### Minor Changes
|
|
16
|
+
|
|
17
|
+
- Created a new RPC method `getCampaign` to retrieve the first active campaign.
|
|
18
|
+
|
|
19
|
+
More details can be found in the official SCAYLE Resource Center under [API Guides / Storefront API / Campaigns / List Campaigns](https://scayle.dev/en/api-guides/storefront-api/resources/campaigns/list-campaigns).
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
**Dependencies**
|
|
24
|
+
|
|
25
|
+
- Updated dependency to @scayle/storefront-api@18.11.0
|
|
26
|
+
|
|
3
27
|
## 8.35.0
|
|
4
28
|
|
|
5
29
|
### Minor Changes
|
|
@@ -1,4 +1,15 @@
|
|
|
1
|
+
import type { Campaign } from '@scayle/storefront-api';
|
|
1
2
|
import type { RpcHandler } from '../../types';
|
|
3
|
+
/**
|
|
4
|
+
* Retrieves the active campaign.
|
|
5
|
+
*
|
|
6
|
+
* This RPC method retrieves the active campaign.
|
|
7
|
+
* It then returns the first active campaign.
|
|
8
|
+
*
|
|
9
|
+
* @param context The RPC Context
|
|
10
|
+
* @returns The current active campaign.
|
|
11
|
+
*/
|
|
12
|
+
export declare const getCampaign: RpcHandler<Campaign | undefined>;
|
|
2
13
|
/**
|
|
3
14
|
* Retrieves the active campaign key.
|
|
4
15
|
*
|
|
@@ -6,11 +17,6 @@ import type { RpcHandler } from '../../types';
|
|
|
6
17
|
* for an existing `campaignKey`. If not present, it fetches active campaigns from the SAPI
|
|
7
18
|
* `list-campaigns` endpoint using the `sapiClient`, caching the result for 5 minutes.
|
|
8
19
|
*
|
|
9
|
-
* @see https://scayle.dev/en/api-guides/storefront-api/resources/campaigns/list-campaigns
|
|
10
|
-
*
|
|
11
|
-
* This function uses the Storefront cache (`cached()`) with a `get-campaignKey` key prefix to improve performance.
|
|
12
|
-
* Cached entries are returned if found; otherwise, data is fetched and cached.
|
|
13
|
-
*
|
|
14
20
|
* @param context The RPC Context
|
|
15
21
|
* @returns The current active campaign key.
|
|
16
22
|
*/
|
|
@@ -4,10 +4,7 @@ import {
|
|
|
4
4
|
isCampaignActive
|
|
5
5
|
} from "../../utils/campaign.mjs";
|
|
6
6
|
import { defineRpcHandler } from "../../utils/index.mjs";
|
|
7
|
-
|
|
8
|
-
if (context.campaignKey) {
|
|
9
|
-
return context.campaignKey;
|
|
10
|
-
}
|
|
7
|
+
const getCampaigns = async (context) => {
|
|
11
8
|
const { cached, sapiClient } = context;
|
|
12
9
|
const { campaigns } = await cached(async () => {
|
|
13
10
|
const { entities } = await sapiClient.campaigns.get();
|
|
@@ -17,8 +14,20 @@ export const getCampaignKey = defineRpcHandler(async (context) => {
|
|
|
17
14
|
}).sort(sortCampaignsByDateAscending)
|
|
18
15
|
};
|
|
19
16
|
}, {
|
|
20
|
-
cacheKeyPrefix: "get-
|
|
17
|
+
cacheKeyPrefix: "get-campaigns",
|
|
21
18
|
ttl: 5 * 60
|
|
22
19
|
})();
|
|
23
|
-
return campaigns
|
|
20
|
+
return campaigns;
|
|
21
|
+
};
|
|
22
|
+
export const getCampaign = defineRpcHandler(async (context) => {
|
|
23
|
+
const campaigns = await getCampaigns(context);
|
|
24
|
+
return campaigns.find(isCampaignActive);
|
|
25
|
+
});
|
|
26
|
+
export const getCampaignKey = defineRpcHandler(async (context) => {
|
|
27
|
+
if (context.campaignKey) {
|
|
28
|
+
return context.campaignKey;
|
|
29
|
+
}
|
|
30
|
+
const campaigns = await getCampaigns(context);
|
|
31
|
+
const campaign = campaigns.find(isCampaignActive);
|
|
32
|
+
return campaign?.key;
|
|
24
33
|
});
|
|
@@ -37,7 +37,7 @@ export const getCheckoutToken = defineRpcHandler(async (jwtPayload = {}, context
|
|
|
37
37
|
carrier,
|
|
38
38
|
basketId: context.basketKey,
|
|
39
39
|
campaignKey
|
|
40
|
-
}).setIssuedAt(now).setNotBefore(now).setExpirationTime("1h").setIssuer(`${"@scayle/storefront-core"}@${"8.
|
|
40
|
+
}).setIssuedAt(now).setNotBefore(now).setExpirationTime("1h").setIssuer(`${"@scayle/storefront-core"}@${"8.37.0"}`).setProtectedHeader({ alg: "HS256", typ: "JWT" }).sign(secret);
|
|
41
41
|
return {
|
|
42
42
|
accessToken: refreshedAccessToken,
|
|
43
43
|
checkoutJwt
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export * from './basket/basket';
|
|
2
2
|
export * from './brands';
|
|
3
3
|
export * from './categories';
|
|
4
|
-
export
|
|
4
|
+
export * from './campaign';
|
|
5
5
|
export * from './cbd';
|
|
6
6
|
export { getProductById, getProductsByIds, getProductsByReferenceKeys, getProductsCount, fetchAllFiltersForCategory, getFilters, getProductsByCategory, } from './products';
|
|
7
7
|
export * from './search';
|
|
@@ -89,10 +89,11 @@ export const getProductsCount = async function getProductsCount2(params, context
|
|
|
89
89
|
const { cached, sapiClient } = context;
|
|
90
90
|
const campaignKey = await context.callRpc?.("getCampaignKey");
|
|
91
91
|
const { categoryId } = await resolveCategoryIdFromParams(context, params);
|
|
92
|
+
const { attributes, whitelistAttributes, ...filter } = where || {};
|
|
92
93
|
const response = await getSanitizedAttributes(
|
|
93
94
|
context,
|
|
94
95
|
categoryId,
|
|
95
|
-
|
|
96
|
+
attributes || [],
|
|
96
97
|
includedFilters
|
|
97
98
|
);
|
|
98
99
|
if (response instanceof ErrorResponse) {
|
|
@@ -104,17 +105,12 @@ export const getProductsCount = async function getProductsCount2(params, context
|
|
|
104
105
|
cacheKeyPrefix: "products-query"
|
|
105
106
|
})({
|
|
106
107
|
where: {
|
|
108
|
+
...filter,
|
|
107
109
|
categoryId,
|
|
108
|
-
minPrice: where?.minPrice,
|
|
109
|
-
maxPrice: where?.maxPrice,
|
|
110
|
-
minReduction: where?.minReduction,
|
|
111
|
-
maxReduction: where?.maxReduction,
|
|
112
|
-
term: where?.term,
|
|
113
110
|
attributes: [
|
|
114
111
|
...sanitizedAttributes,
|
|
115
|
-
...
|
|
116
|
-
]
|
|
117
|
-
disableFuzziness: where?.disableFuzziness
|
|
112
|
+
...whitelistAttributes || []
|
|
113
|
+
]
|
|
118
114
|
},
|
|
119
115
|
pagination: {
|
|
120
116
|
perPage: 1
|
|
@@ -177,10 +173,11 @@ export const getFilters = async function getFilters2(params, context) {
|
|
|
177
173
|
context,
|
|
178
174
|
params
|
|
179
175
|
);
|
|
176
|
+
const { attributes, whitelistAttributes, ...filter } = where || {};
|
|
180
177
|
const response = await getSanitizedAttributes(
|
|
181
178
|
context,
|
|
182
179
|
categoryId,
|
|
183
|
-
|
|
180
|
+
attributes || [],
|
|
184
181
|
includedFilters
|
|
185
182
|
);
|
|
186
183
|
if (response instanceof ErrorResponse) {
|
|
@@ -192,15 +189,11 @@ export const getFilters = async function getFilters2(params, context) {
|
|
|
192
189
|
cacheKeyPrefix: `get-filters-${categoryId}`
|
|
193
190
|
})({
|
|
194
191
|
where: {
|
|
192
|
+
...filter,
|
|
195
193
|
categoryId,
|
|
196
|
-
minPrice: where?.minPrice,
|
|
197
|
-
maxPrice: where?.maxPrice,
|
|
198
|
-
minReduction: where?.minReduction,
|
|
199
|
-
maxReduction: where?.maxReduction,
|
|
200
|
-
term: where?.term,
|
|
201
194
|
attributes: [
|
|
202
195
|
...sanitizedAttributes,
|
|
203
|
-
...
|
|
196
|
+
...whitelistAttributes || []
|
|
204
197
|
]
|
|
205
198
|
},
|
|
206
199
|
includeSoldOut,
|
|
@@ -214,17 +207,12 @@ export const getFilters = async function getFilters2(params, context) {
|
|
|
214
207
|
cacheKeyPrefix: `products-query-category-${category === "/" ? "root" : categoryId}`
|
|
215
208
|
})({
|
|
216
209
|
where: {
|
|
210
|
+
...filter,
|
|
217
211
|
categoryId,
|
|
218
|
-
minPrice: where?.minPrice,
|
|
219
|
-
maxPrice: where?.maxPrice,
|
|
220
|
-
minReduction: where?.minReduction,
|
|
221
|
-
maxReduction: where?.maxReduction,
|
|
222
|
-
term: where?.term,
|
|
223
212
|
attributes: [
|
|
224
213
|
...sanitizedAttributes,
|
|
225
|
-
...
|
|
226
|
-
]
|
|
227
|
-
disableFuzziness: where?.disableFuzziness
|
|
214
|
+
...whitelistAttributes || []
|
|
215
|
+
]
|
|
228
216
|
},
|
|
229
217
|
pagination: {
|
|
230
218
|
perPage: 1
|
|
@@ -261,10 +249,11 @@ export const getProductsByCategory = async function getProductsByCategory2(param
|
|
|
261
249
|
context,
|
|
262
250
|
params
|
|
263
251
|
);
|
|
252
|
+
const { attributes, whitelistAttributes, ...filter } = where || {};
|
|
264
253
|
const response = await getSanitizedAttributes(
|
|
265
254
|
context,
|
|
266
255
|
categoryId,
|
|
267
|
-
|
|
256
|
+
attributes || [],
|
|
268
257
|
includedFilters
|
|
269
258
|
);
|
|
270
259
|
if (response instanceof ErrorResponse) {
|
|
@@ -280,17 +269,12 @@ export const getProductsByCategory = async function getProductsByCategory2(param
|
|
|
280
269
|
}
|
|
281
270
|
)({
|
|
282
271
|
where: {
|
|
272
|
+
...filter,
|
|
283
273
|
categoryId,
|
|
284
|
-
minPrice: where?.minPrice,
|
|
285
|
-
maxPrice: where?.maxPrice,
|
|
286
|
-
minReduction: where?.minReduction,
|
|
287
|
-
maxReduction: where?.maxReduction,
|
|
288
|
-
term: where?.term,
|
|
289
274
|
attributes: [
|
|
290
275
|
...sanitizedAttributes,
|
|
291
|
-
...
|
|
292
|
-
]
|
|
293
|
-
disableFuzziness: where?.disableFuzziness
|
|
276
|
+
...whitelistAttributes || []
|
|
277
|
+
]
|
|
294
278
|
},
|
|
295
279
|
pagination: {
|
|
296
280
|
perPage: Math.min(perPage, MAX_PER_PAGE),
|
|
@@ -90,6 +90,9 @@ export interface FetchProductsByReferenceKeysParams {
|
|
|
90
90
|
with?: ProductWith;
|
|
91
91
|
pricePromotionKey?: string;
|
|
92
92
|
}
|
|
93
|
+
export type ProductWhere = Partial<Omit<ProductSearchQuery, 'categoryId'> & {
|
|
94
|
+
whitelistAttributes?: ProductSearchQuery['attributes'];
|
|
95
|
+
}>;
|
|
93
96
|
/**
|
|
94
97
|
* Parameters for fetching products by category.
|
|
95
98
|
*/
|
|
@@ -101,16 +104,7 @@ export type FetchProductsByCategoryParams = {
|
|
|
101
104
|
perPage?: number;
|
|
102
105
|
page?: number;
|
|
103
106
|
/** Search query parameters. */
|
|
104
|
-
where?:
|
|
105
|
-
term?: ProductSearchQuery['term'];
|
|
106
|
-
minPrice?: ProductSearchQuery['minPrice'];
|
|
107
|
-
maxPrice?: ProductSearchQuery['maxPrice'];
|
|
108
|
-
minReduction?: ProductSearchQuery['minReduction'];
|
|
109
|
-
maxReduction?: ProductSearchQuery['maxReduction'];
|
|
110
|
-
attributes?: ProductSearchQuery['attributes'];
|
|
111
|
-
disableFuzziness?: ProductSearchQuery['disableFuzziness'];
|
|
112
|
-
whitelistAttributes?: ProductSearchQuery['attributes'];
|
|
113
|
-
};
|
|
107
|
+
where?: ProductWhere;
|
|
114
108
|
/** Sort parameters. */
|
|
115
109
|
sort?: FilterParams['sort'];
|
|
116
110
|
pricePromotionKey?: string;
|
|
@@ -145,16 +139,7 @@ export interface FetchProductsByCategoryResponse {
|
|
|
145
139
|
*/
|
|
146
140
|
export type FetchProductsCountParams = {
|
|
147
141
|
/** Search query parameters. */
|
|
148
|
-
where?:
|
|
149
|
-
term?: ProductSearchQuery['term'];
|
|
150
|
-
minPrice?: ProductSearchQuery['minPrice'];
|
|
151
|
-
maxPrice?: ProductSearchQuery['maxPrice'];
|
|
152
|
-
minReduction?: ProductSearchQuery['minReduction'];
|
|
153
|
-
maxReduction?: ProductSearchQuery['maxReduction'];
|
|
154
|
-
attributes?: ProductSearchQuery['attributes'];
|
|
155
|
-
disableFuzziness?: ProductSearchQuery['disableFuzziness'];
|
|
156
|
-
whitelistAttributes?: ProductSearchQuery['attributes'];
|
|
157
|
-
};
|
|
142
|
+
where?: ProductWhere;
|
|
158
143
|
includedFilters?: Array<string>;
|
|
159
144
|
includeSoldOut?: boolean;
|
|
160
145
|
includeSellableForFree?: boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scayle/storefront-core",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.37.0",
|
|
4
4
|
"description": "Collection of essential utilities to work with the Storefront API",
|
|
5
5
|
"author": "SCAYLE Commerce Engine",
|
|
6
6
|
"license": "MIT",
|
|
@@ -56,12 +56,12 @@
|
|
|
56
56
|
"ufo": "^1.5.3",
|
|
57
57
|
"uncrypto": "^0.1.3",
|
|
58
58
|
"utility-types": "^3.11.0",
|
|
59
|
-
"@scayle/storefront-api": "18.
|
|
59
|
+
"@scayle/storefront-api": "18.11.0",
|
|
60
60
|
"@scayle/unstorage-scayle-kv-driver": "1.0.2"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@types/crypto-js": "4.2.2",
|
|
64
|
-
"@types/node": "22.16.
|
|
64
|
+
"@types/node": "22.16.5",
|
|
65
65
|
"@types/webpack-env": "1.18.8",
|
|
66
66
|
"@vitest/coverage-v8": "3.2.4",
|
|
67
67
|
"dprint": "0.50.1",
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
"@scayle/eslint-config-storefront": "4.6.1"
|
|
78
78
|
},
|
|
79
79
|
"volta": {
|
|
80
|
-
"node": "22.17.
|
|
80
|
+
"node": "22.17.1"
|
|
81
81
|
},
|
|
82
82
|
"scripts": {
|
|
83
83
|
"clean": "rimraf ./dist",
|