@scayle/storefront-core 8.61.0 → 8.61.2
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-V7.md +1 -11
- package/CHANGELOG.md +100 -103
- package/dist/api/customer.mjs +1 -3
- package/dist/api/oauth.mjs +9 -6
- package/dist/cache/providers/unstorage.mjs +1 -3
- package/dist/constants/withParameters.mjs +2 -16
- package/dist/helpers/attributeHelpers.mjs +3 -1
- package/dist/helpers/filterHelper.mjs +11 -8
- package/dist/helpers/productHelpers.mjs +1 -3
- package/dist/helpers/sanitizationHelpers.mjs +1 -4
- package/dist/helpers/sortingHelper.mjs +1 -3
- package/dist/rpc/methods/basket/basket.d.ts +2 -2
- package/dist/rpc/methods/basket/basket.mjs +334 -321
- package/dist/rpc/methods/brands.mjs +26 -20
- package/dist/rpc/methods/campaign.mjs +32 -23
- package/dist/rpc/methods/categories.mjs +156 -135
- package/dist/rpc/methods/cbd.mjs +52 -49
- package/dist/rpc/methods/checkout/checkout.mjs +42 -39
- package/dist/rpc/methods/checkout/order.mjs +46 -40
- package/dist/rpc/methods/checkout/shopUser.mjs +112 -106
- package/dist/rpc/methods/navigationTrees.mjs +50 -32
- package/dist/rpc/methods/oauth/idp.mjs +64 -55
- package/dist/rpc/methods/products.mjs +224 -212
- package/dist/rpc/methods/promotion.mjs +46 -31
- package/dist/rpc/methods/search.mjs +26 -20
- package/dist/rpc/methods/session.mjs +289 -260
- package/dist/rpc/methods/shopConfiguration.mjs +12 -9
- package/dist/rpc/methods/user.mjs +87 -78
- package/dist/rpc/methods/variants.mjs +17 -14
- package/dist/rpc/methods/wishlist.mjs +71 -62
- package/dist/utils/hash.mjs +2 -7
- package/dist/utils/sapi.mjs +10 -7
- package/package.json +4 -4
package/CHANGELOG-V7.md
CHANGED
|
@@ -440,7 +440,6 @@ This changelog contains all changes of `@scayle/storefront-core` above v6.0.0 an
|
|
|
440
440
|
- Upgraded to `@scayle/storefront-api@v17.0.0` and replaced `@aboutyou/backbone`
|
|
441
441
|
|
|
442
442
|
Noticeable changes are:
|
|
443
|
-
|
|
444
443
|
- Rename `BapiClient` to `StorefrontAPIClient`
|
|
445
444
|
- Removed basic auth support from `initBapi`
|
|
446
445
|
|
|
@@ -542,9 +541,7 @@ This changelog contains all changes of `@scayle/storefront-core` above v6.0.0 an
|
|
|
542
541
|
For example:
|
|
543
542
|
|
|
544
543
|
```ts
|
|
545
|
-
export const custom: RpcHandler<{ shop: number }> = (
|
|
546
|
-
context: RpcContext,
|
|
547
|
-
) => {
|
|
544
|
+
export const custom: RpcHandler<{ shop: number }> = (context: RpcContext) => {
|
|
548
545
|
return {
|
|
549
546
|
shop: context.shopId,
|
|
550
547
|
}
|
|
@@ -1064,7 +1061,6 @@ This changelog contains all changes of `@scayle/storefront-core` above v6.0.0 an
|
|
|
1064
1061
|
- **Removal**: `sortingValues`
|
|
1065
1062
|
- instead use `getSortingValues()`
|
|
1066
1063
|
- **Changed NPM package names**
|
|
1067
|
-
|
|
1068
1064
|
- **Breaking**: Change package scope and name of `@aboutyou/scayle-sfc-nuxt` to `@scayle/storefront-nuxt2`
|
|
1069
1065
|
- **Breaking**: Change package scope and name of `@aboutyou/sfc-nuxt3` to `@scayle/storefront-nuxt`
|
|
1070
1066
|
- **Breaking**: Change package scope and name of `@aboutyou/scayle-sfc-lib` to `@scayle/storefront-core`
|
|
@@ -1073,7 +1069,6 @@ This changelog contains all changes of `@scayle/storefront-core` above v6.0.0 an
|
|
|
1073
1069
|
|
|
1074
1070
|
_NOTE: Due to the changes of the NPM package scope from `@aboutyou` to `@scayle`,
|
|
1075
1071
|
it is required to change the consuming projects local `.npmrc` file as follows:_
|
|
1076
|
-
|
|
1077
1072
|
- Before:
|
|
1078
1073
|
|
|
1079
1074
|
```text
|
|
@@ -1101,7 +1096,6 @@ This changelog contains all changes of `@scayle/storefront-core` above v6.0.0 an
|
|
|
1101
1096
|
- Support sha256 for basket and wishlist keys
|
|
1102
1097
|
|
|
1103
1098
|
The `appKeys.isHashed` config option has been renamed to `appKeys.hashAlgorithm`. Instead of a boolean, there are now three options.
|
|
1104
|
-
|
|
1105
1099
|
- `'sha256'` Use the `sha256` function for hashing basket and wishlist keys
|
|
1106
1100
|
- `'md5'` Use the `md5` function for hashing basket and wishlist keys (Equivalent to `isHashed: true` in v6)
|
|
1107
1101
|
- `null` Do not hash basket and wishlist keys (Equivalent to `isHashed: false` in v6)
|
|
@@ -1151,7 +1145,6 @@ This changelog contains all changes of `@scayle/storefront-core` above v6.0.0 an
|
|
|
1151
1145
|
- Support sha256 for basket and wishlist keys
|
|
1152
1146
|
|
|
1153
1147
|
The `appKeys.isHashed` config option has been renamed to `appKeys.hashAlgorithm`. Instead of a boolean, there are now three options.
|
|
1154
|
-
|
|
1155
1148
|
- `'sha256'` Use the `sha256` function for hashing basket and wishlist keys
|
|
1156
1149
|
- `'md5'` Use the `md5` function for hashing basket and wishlist keys (Equivalent to `isHashed: true` in v6)
|
|
1157
1150
|
- `null` Do not hash basket and wishlist keys (Equivalent to `isHashed: false` in v6)
|
|
@@ -1210,7 +1203,6 @@ This changelog contains all changes of `@scayle/storefront-core` above v6.0.0 an
|
|
|
1210
1203
|
They can no longer be overridden when calling `wishlist.addItem()`, `wishlist.removeItem()`, `wishlist.toggleItem()` and `wishlist.fetch()`.
|
|
1211
1204
|
|
|
1212
1205
|
- **Removed deprecated functions and values**
|
|
1213
|
-
|
|
1214
1206
|
- `user.fetch()` User is fetched automatically. If you want to refresh the user, use `user.refresh()`
|
|
1215
1207
|
- `user.forceRefreshUser()` Use `user.refresh()` instead.
|
|
1216
1208
|
- `useUser()` Use `useUserWithParams()` instead.
|
|
@@ -1224,7 +1216,6 @@ This changelog contains all changes of `@scayle/storefront-core` above v6.0.0 an
|
|
|
1224
1216
|
- `sortingValues` Use `getSortingValues()` instead.
|
|
1225
1217
|
|
|
1226
1218
|
- **Changed NPM package names**
|
|
1227
|
-
|
|
1228
1219
|
- **Breaking**: Change package scope and name of `@aboutyou/scayle-sfc-nuxt` to `@scayle/storefront-nuxt2`
|
|
1229
1220
|
- **Breaking**: Change package scope and name of `@aboutyou/sfc-nuxt3` to `@scayle/storefront-nuxt`
|
|
1230
1221
|
- **Breaking**: Change package scope and name of `@aboutyou/scayle-sfc-lib` to `@scayle/storefront-core``
|
|
@@ -1233,7 +1224,6 @@ This changelog contains all changes of `@scayle/storefront-core` above v6.0.0 an
|
|
|
1233
1224
|
|
|
1234
1225
|
Due to the changes of the NPM package scope from `@aboutyou` to `@scayle`,
|
|
1235
1226
|
it is required to change the consuming projects local `.npmrc` file as follows:
|
|
1236
|
-
|
|
1237
1227
|
- Before: `@aboutyou:registry=https://gitlab.com/api/v4/packages/npm/`
|
|
1238
1228
|
- After: `@scayle:registry=https://gitlab.com/api/v4/packages/npm/`
|
|
1239
1229
|
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @scayle/storefront-core
|
|
2
2
|
|
|
3
|
+
## 8.61.2
|
|
4
|
+
|
|
5
|
+
No changes in this release.
|
|
6
|
+
|
|
7
|
+
## 8.61.1
|
|
8
|
+
|
|
9
|
+
No changes in this release.
|
|
10
|
+
|
|
3
11
|
## 8.61.0
|
|
4
12
|
|
|
5
13
|
### Minor Changes
|
|
@@ -9,23 +17,23 @@
|
|
|
9
17
|
User- and session-specific RPCs (`getBasket`, `getUser`, `fetchUser`, `getWishlist`, `getAccessToken`, `getCheckoutToken`, `getOrderById`, `getCheckoutDataByCbd`, `getShopUserAddress`) intentionally stay on `POST` so their responses are never eligible for CDN or browser caching.
|
|
10
18
|
|
|
11
19
|
```ts
|
|
12
|
-
import { defineRpcHandler, type RpcContext } from
|
|
20
|
+
import { defineRpcHandler, type RpcContext } from '@scayle/storefront-core'
|
|
13
21
|
|
|
14
22
|
// Safe, public read — eligible for CDN/browser caching
|
|
15
23
|
export const getNavigation = defineRpcHandler(
|
|
16
24
|
async (context: RpcContext) => {
|
|
17
25
|
/* ... */
|
|
18
26
|
},
|
|
19
|
-
{ method:
|
|
20
|
-
)
|
|
27
|
+
{ method: 'GET' },
|
|
28
|
+
)
|
|
21
29
|
|
|
22
30
|
// User-specific / Mutation — uses POST to prevent cache leakage
|
|
23
31
|
export const getBasket = defineRpcHandler(
|
|
24
32
|
async (context: RpcContext) => {
|
|
25
33
|
/* ... */
|
|
26
|
-
}
|
|
34
|
+
},
|
|
27
35
|
// method defaults to 'POST'
|
|
28
|
-
)
|
|
36
|
+
)
|
|
29
37
|
```
|
|
30
38
|
|
|
31
39
|
### Patch Changes
|
|
@@ -91,33 +99,33 @@
|
|
|
91
99
|
**Migration:**
|
|
92
100
|
|
|
93
101
|
```ts
|
|
94
|
-
import baseSlugify from
|
|
102
|
+
import baseSlugify from 'slugify'
|
|
95
103
|
|
|
96
104
|
const slugify = (url: string | undefined): string => {
|
|
97
|
-
return baseSlugify(url ??
|
|
105
|
+
return baseSlugify(url ?? '', {
|
|
98
106
|
lower: true,
|
|
99
107
|
remove: /[*+~.()'"!:@/#?]/g,
|
|
100
|
-
})
|
|
101
|
-
}
|
|
108
|
+
})
|
|
109
|
+
}
|
|
102
110
|
|
|
103
|
-
const localePath = useLocalePath()
|
|
111
|
+
const localePath = useLocalePath()
|
|
104
112
|
|
|
105
113
|
const getProductDetailRoute = (
|
|
106
114
|
id: number,
|
|
107
115
|
name?: string,
|
|
108
|
-
locale?: Locale
|
|
116
|
+
locale?: Locale,
|
|
109
117
|
): string => {
|
|
110
118
|
return localePath(
|
|
111
119
|
{
|
|
112
|
-
name:
|
|
120
|
+
name: 'p-productName-id',
|
|
113
121
|
params: {
|
|
114
122
|
productName: slugify(name),
|
|
115
123
|
id: `${id}`,
|
|
116
124
|
},
|
|
117
125
|
},
|
|
118
|
-
locale
|
|
119
|
-
)
|
|
120
|
-
}
|
|
126
|
+
locale,
|
|
127
|
+
)
|
|
128
|
+
}
|
|
121
129
|
```
|
|
122
130
|
|
|
123
131
|
## 8.59.1
|
|
@@ -174,7 +182,6 @@
|
|
|
174
182
|
- **\[Navigation\]** Exported Navigation V2 API types to provide TypeScript support for the new navigation endpoints.
|
|
175
183
|
|
|
176
184
|
The following types are now available from `@scayle/storefront-core`:
|
|
177
|
-
|
|
178
185
|
- `GetNavigationV2Parameters` - Parameters for fetching navigation trees via the V2 API
|
|
179
186
|
- `NavigationV2AllEndpointResponseData` - Response type for fetching all navigation trees
|
|
180
187
|
- `NavigationV2ByReferenceEndpointResponseData` - Response type for fetching a navigation tree by reference key
|
|
@@ -298,10 +305,10 @@
|
|
|
298
305
|
Example:
|
|
299
306
|
|
|
300
307
|
```ts
|
|
301
|
-
import { sha256 } from
|
|
308
|
+
import { sha256 } from '@scayle/storefront-core'
|
|
302
309
|
|
|
303
|
-
const hash = await sha256(
|
|
304
|
-
console.log(hash)
|
|
310
|
+
const hash = await sha256('hello')
|
|
311
|
+
console.log(hash) // '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824'
|
|
305
312
|
```
|
|
306
313
|
|
|
307
314
|
### Patch Changes
|
|
@@ -318,7 +325,6 @@
|
|
|
318
325
|
- Export `SmartSortingKey` constant containing all predefined smart sorting keys for intelligent product sorting. Smart sorting keys provide advanced sorting algorithms that consider multiple factors like discounts, inventory levels, sales performance, and recency to optimize product listings.
|
|
319
326
|
|
|
320
327
|
Available keys:
|
|
321
|
-
|
|
322
328
|
- `SmartSortingKey.SALES_PUSH` - Promotes items with highest discounts and oldest inventory
|
|
323
329
|
- `SmartSortingKey.NEW_ARRIVALS` - Prioritizes recently added products with good availability
|
|
324
330
|
- `SmartSortingKey.BALANCED_OFFERINGS` - Balances recency, availability, discounts, and sales data
|
|
@@ -361,8 +367,8 @@
|
|
|
361
367
|
customer: {
|
|
362
368
|
groups: context.user?.groups,
|
|
363
369
|
},
|
|
364
|
-
}
|
|
365
|
-
})
|
|
370
|
+
}
|
|
371
|
+
})
|
|
366
372
|
```
|
|
367
373
|
|
|
368
374
|
For further information, please refer to the [Overriding Core RPC Methods](https://scayle.dev/en/core-documentation/storefront-guide/storefront-application/technical-foundation/rpc-methods?sourceText=RPC%2520Methods#overriding-core-rpc-methods).
|
|
@@ -395,37 +401,36 @@
|
|
|
395
401
|
#### Looking up by name (existing, now renamed):
|
|
396
402
|
|
|
397
403
|
```typescript
|
|
398
|
-
import { getAttributeValuesByName } from
|
|
404
|
+
import { getAttributeValuesByName } from '@scayle/storefront-core'
|
|
399
405
|
|
|
400
406
|
// Single-select attribute
|
|
401
|
-
const sizes = getAttributeValuesByName(product.attributes,
|
|
407
|
+
const sizes = getAttributeValuesByName(product.attributes, 'size')
|
|
402
408
|
// Returns: [{ id: 1, label: 'M', value: 'medium' }]
|
|
403
409
|
|
|
404
410
|
// Multi-select attribute
|
|
405
|
-
const colors = getAttributeValuesByName(product.attributes,
|
|
411
|
+
const colors = getAttributeValuesByName(product.attributes, 'color')
|
|
406
412
|
// Returns: [{ id: 1, label: 'Red' }, { id: 2, label: 'Blue' }]
|
|
407
413
|
|
|
408
414
|
// Non-existent attribute
|
|
409
|
-
const missing = getAttributeValuesByName(product.attributes,
|
|
415
|
+
const missing = getAttributeValuesByName(product.attributes, 'doesNotExist')
|
|
410
416
|
// Returns: []
|
|
411
417
|
```
|
|
412
418
|
|
|
413
419
|
#### Looking up by group ID (new):
|
|
414
420
|
|
|
415
421
|
```typescript
|
|
416
|
-
import { getAttributeValuesByGroupId } from
|
|
422
|
+
import { getAttributeValuesByGroupId } from '@scayle/storefront-core'
|
|
417
423
|
|
|
418
424
|
// Look up attribute by its numeric ID from the SCAYLE API
|
|
419
|
-
const promotionValues = getAttributeValuesByGroupId(product.attributes, 42)
|
|
425
|
+
const promotionValues = getAttributeValuesByGroupId(product.attributes, 42)
|
|
420
426
|
// Returns: [{ id: 123, label: 'Summer Sale', value: 'summer-2024' }]
|
|
421
427
|
|
|
422
428
|
// Non-existent attribute group
|
|
423
|
-
const missing = getAttributeValuesByGroupId(product.attributes, 9999)
|
|
429
|
+
const missing = getAttributeValuesByGroupId(product.attributes, 9999)
|
|
424
430
|
// Returns: []
|
|
425
431
|
```
|
|
426
432
|
|
|
427
433
|
### When to Use Each Function
|
|
428
|
-
|
|
429
434
|
- **`getAttributeValuesByName`**: Use when you know the attribute name key (e.g., 'color', 'size'). This is the most common use case in application code.
|
|
430
435
|
- **`getAttributeValuesByGroupId`**: Use when you have the numeric attribute group ID from the SCAYLE API, such as when processing API configurations, handling dynamic attribute mappings, or working with attribute group references.
|
|
431
436
|
|
|
@@ -516,10 +521,10 @@
|
|
|
516
521
|
|
|
517
522
|
```ts
|
|
518
523
|
const isComboDealType = (
|
|
519
|
-
promotion?: Promotion | null
|
|
524
|
+
promotion?: Promotion | null,
|
|
520
525
|
): promotion is Promotion<ComboDealEffect> => {
|
|
521
|
-
return promotion?.effect?.type === PromotionEffectType.COMBO_DEAL
|
|
522
|
-
}
|
|
526
|
+
return promotion?.effect?.type === PromotionEffectType.COMBO_DEAL
|
|
527
|
+
}
|
|
523
528
|
```
|
|
524
529
|
|
|
525
530
|
### Patch Changes
|
|
@@ -791,23 +796,23 @@
|
|
|
791
796
|
- Added `minReduction` and `maxReduction` filter parameters to `FetchProductsByCategoryParams.where` and `FetchFiltersParams.where` types, and updated the `getProductsByCategory` and `getFilters` RPC methods to accept and handle these new reduction-based filtering conditions.
|
|
792
797
|
|
|
793
798
|
```ts
|
|
794
|
-
const { data } = useRpc(
|
|
799
|
+
const { data } = useRpc('getFilters', 'getFiltersKey', () => ({
|
|
795
800
|
where: {
|
|
796
801
|
minReduction: 10,
|
|
797
802
|
maxReduction: 20,
|
|
798
803
|
},
|
|
799
|
-
}))
|
|
804
|
+
}))
|
|
800
805
|
|
|
801
806
|
const { data } = useRpc(
|
|
802
|
-
|
|
803
|
-
|
|
807
|
+
'getProductsByCategory',
|
|
808
|
+
'getProductsByCategoryKey',
|
|
804
809
|
() => ({
|
|
805
810
|
where: {
|
|
806
811
|
minReduction: 10,
|
|
807
812
|
maxReduction: 20,
|
|
808
813
|
},
|
|
809
|
-
})
|
|
810
|
-
)
|
|
814
|
+
}),
|
|
815
|
+
)
|
|
811
816
|
```
|
|
812
817
|
|
|
813
818
|
## 8.30.3
|
|
@@ -838,28 +843,28 @@ No changes in this release.
|
|
|
838
843
|
|
|
839
844
|
```ts
|
|
840
845
|
export const existingHandlerWithoutParams = async (_context: RpcContext) => {
|
|
841
|
-
return
|
|
842
|
-
}
|
|
846
|
+
return 'existing handler'
|
|
847
|
+
}
|
|
843
848
|
|
|
844
849
|
export const existingHandlerWithParams = async (
|
|
845
850
|
{ name }: { name: string },
|
|
846
|
-
_context: RpcContext
|
|
851
|
+
_context: RpcContext,
|
|
847
852
|
) => {
|
|
848
|
-
return name
|
|
849
|
-
}
|
|
853
|
+
return name
|
|
854
|
+
}
|
|
850
855
|
|
|
851
856
|
// will become
|
|
852
857
|
|
|
853
858
|
export const existingHandlerWithoutParams = defineRpcHandler(
|
|
854
859
|
async (_context: RpcContext) => {
|
|
855
|
-
return
|
|
856
|
-
}
|
|
857
|
-
)
|
|
860
|
+
return 'existing handler'
|
|
861
|
+
},
|
|
862
|
+
)
|
|
858
863
|
export const existingHandlerWithParams = defineRpcHandler(
|
|
859
864
|
async ({ name }: { name: string }, _context: RpcContext) => {
|
|
860
|
-
return name
|
|
861
|
-
}
|
|
862
|
-
)
|
|
865
|
+
return name
|
|
866
|
+
},
|
|
867
|
+
)
|
|
863
868
|
```
|
|
864
869
|
|
|
865
870
|
### Patch Changes
|
|
@@ -876,15 +881,15 @@ No changes in this release.
|
|
|
876
881
|
- Added an optional `hideEmptyCategories` parameter to `getCategoryTree`. When enabled, the product count for each category is retrieved, and categories (including their children) without any products are removed. Enabling this option may increase response times, especially for large category trees.
|
|
877
882
|
|
|
878
883
|
```ts
|
|
879
|
-
import { rpcMethods } from
|
|
884
|
+
import { rpcMethods } from '@scayle/storefront-core'
|
|
880
885
|
|
|
881
|
-
rpcMethods.getCategoryTree({ hideEmptyCategories: true }, rpcContext)
|
|
886
|
+
rpcMethods.getCategoryTree({ hideEmptyCategories: true }, rpcContext)
|
|
882
887
|
```
|
|
883
888
|
|
|
884
889
|
or
|
|
885
890
|
|
|
886
891
|
```ts
|
|
887
|
-
import { useCategoryTree } from
|
|
892
|
+
import { useCategoryTree } from '#storefront/composables'
|
|
888
893
|
|
|
889
894
|
const { data: rootCategories, status } = useCategoryTree(
|
|
890
895
|
{
|
|
@@ -892,8 +897,8 @@ No changes in this release.
|
|
|
892
897
|
hideEmptyCategories: true,
|
|
893
898
|
},
|
|
894
899
|
},
|
|
895
|
-
|
|
896
|
-
)
|
|
900
|
+
'category-navigation-tree',
|
|
901
|
+
)
|
|
897
902
|
```
|
|
898
903
|
|
|
899
904
|
### Patch Changes
|
|
@@ -1059,7 +1064,6 @@ No changes in this release.
|
|
|
1059
1064
|
### Minor Changes
|
|
1060
1065
|
|
|
1061
1066
|
- Expose the following filter types from `storefront-api`:
|
|
1062
|
-
|
|
1063
1067
|
- `FilterItemWithValues`
|
|
1064
1068
|
- `BooleanFilterItemWithValues`
|
|
1065
1069
|
- `RangeFilterItemWithValues`
|
|
@@ -1254,7 +1258,6 @@ No changes in this release.
|
|
|
1254
1258
|
- Simplified exported `Order` interface by relying directly on primitive types instead of having multiple intermediate types that resolve to primitives.
|
|
1255
1259
|
|
|
1256
1260
|
The following formerly exported intermediate types have been replaces by primitive types:
|
|
1257
|
-
|
|
1258
1261
|
- resolving to `string` now
|
|
1259
1262
|
- `TimestampOfOrderConfirmation`
|
|
1260
1263
|
- `CharacterCurrencyCode`
|
|
@@ -1325,12 +1328,12 @@ To get the default campaign key, you can call the RPC method:
|
|
|
1325
1328
|
```typescript
|
|
1326
1329
|
// Before
|
|
1327
1330
|
async function rpcMethod(context) {
|
|
1328
|
-
const campaignKey = { context }
|
|
1331
|
+
const campaignKey = { context }
|
|
1329
1332
|
// ...
|
|
1330
1333
|
}
|
|
1331
1334
|
// After
|
|
1332
1335
|
async function rpcMethod(context) {
|
|
1333
|
-
const campaignKey = await context.callRpc?.(
|
|
1336
|
+
const campaignKey = await context.callRpc?.('getCampaignKey')
|
|
1334
1337
|
// ...
|
|
1335
1338
|
}
|
|
1336
1339
|
```
|
|
@@ -1491,7 +1494,6 @@ See [Overriding core RPC Methods](https://scayle.dev/en/core-documentation/store
|
|
|
1491
1494
|
### Minor Changes
|
|
1492
1495
|
|
|
1493
1496
|
- **RPC Methods:** Propagate SAPI response codes through RPC methods. This addresses an issue introduced in Storefront Core v8 where specific status codes were incorrectly reported as generic 500 errors. The following RPC methods are impacted:
|
|
1494
|
-
|
|
1495
1497
|
- `getBrands`
|
|
1496
1498
|
- `getBrandById`
|
|
1497
1499
|
- `getCategoryByPath`
|
|
@@ -1513,53 +1515,51 @@ See [Overriding core RPC Methods](https://scayle.dev/en/core-documentation/store
|
|
|
1513
1515
|
### Major Changes
|
|
1514
1516
|
|
|
1515
1517
|
- **\[💥 BREAKING\]** The `getBadgeLabel` helper function has been removed, giving you more control over badge label display.
|
|
1516
|
-
|
|
1517
1518
|
- **Note:** This change doesn't affect projects using SCAYLE Storefront Boilerplate v1.0 or later.
|
|
1518
1519
|
- For applications based on older versions or using `getBadgeLabel`, you can refer to the previous implementation below:
|
|
1519
1520
|
|
|
1520
1521
|
```ts
|
|
1521
1522
|
const BadgeLabel = {
|
|
1522
|
-
NEW:
|
|
1523
|
-
SOLD_OUT:
|
|
1524
|
-
ONLINE_EXCLUSIVE:
|
|
1525
|
-
SUSTAINABLE:
|
|
1526
|
-
PREMIUM:
|
|
1527
|
-
DEFAULT:
|
|
1528
|
-
} as const
|
|
1523
|
+
NEW: 'new',
|
|
1524
|
+
SOLD_OUT: 'sold_out',
|
|
1525
|
+
ONLINE_EXCLUSIVE: 'online_exclusive',
|
|
1526
|
+
SUSTAINABLE: 'sustainable',
|
|
1527
|
+
PREMIUM: 'premium',
|
|
1528
|
+
DEFAULT: '',
|
|
1529
|
+
} as const
|
|
1529
1530
|
|
|
1530
1531
|
type BadgeLabelParamsKeys =
|
|
1531
|
-
|
|
|
1532
|
-
|
|
|
1533
|
-
|
|
|
1534
|
-
|
|
|
1535
|
-
|
|
|
1536
|
-
type BadgeLabelParams = Partial<Record<BadgeLabelParamsKeys, boolean
|
|
1532
|
+
| 'isNew'
|
|
1533
|
+
| 'isSoldOut'
|
|
1534
|
+
| 'isOnlineOnly'
|
|
1535
|
+
| 'isSustainable'
|
|
1536
|
+
| 'isPremium'
|
|
1537
|
+
type BadgeLabelParams = Partial<Record<BadgeLabelParamsKeys, boolean>>
|
|
1537
1538
|
|
|
1538
1539
|
const getBadgeLabel = (params: BadgeLabelParams = {}): string => {
|
|
1539
1540
|
if (!params) {
|
|
1540
|
-
return BadgeLabel.DEFAULT
|
|
1541
|
+
return BadgeLabel.DEFAULT
|
|
1541
1542
|
}
|
|
1542
1543
|
const { isNew, isSoldOut, isOnlineOnly, isSustainable, isPremium } =
|
|
1543
|
-
params
|
|
1544
|
+
params
|
|
1544
1545
|
|
|
1545
1546
|
if (isNew) {
|
|
1546
|
-
return BadgeLabel.NEW
|
|
1547
|
+
return BadgeLabel.NEW
|
|
1547
1548
|
} else if (isSoldOut) {
|
|
1548
|
-
return BadgeLabel.SOLD_OUT
|
|
1549
|
+
return BadgeLabel.SOLD_OUT
|
|
1549
1550
|
} else if (isOnlineOnly) {
|
|
1550
|
-
return BadgeLabel.ONLINE_EXCLUSIVE
|
|
1551
|
+
return BadgeLabel.ONLINE_EXCLUSIVE
|
|
1551
1552
|
} else if (isSustainable) {
|
|
1552
|
-
return BadgeLabel.SUSTAINABLE
|
|
1553
|
+
return BadgeLabel.SUSTAINABLE
|
|
1553
1554
|
} else if (isPremium) {
|
|
1554
|
-
return BadgeLabel.PREMIUM
|
|
1555
|
+
return BadgeLabel.PREMIUM
|
|
1555
1556
|
} else {
|
|
1556
|
-
return BadgeLabel.DEFAULT
|
|
1557
|
+
return BadgeLabel.DEFAULT
|
|
1557
1558
|
}
|
|
1558
|
-
}
|
|
1559
|
+
}
|
|
1559
1560
|
```
|
|
1560
1561
|
|
|
1561
1562
|
- **\[💥 BREAKING\]** We've standardized our configuration to use `sapi` (Storefront API) throughout the codebase, replacing the deprecated `bapi` keyword. This change improves clarity and consistency by removing the `initBapi` function, replacing the `bapiClient` property with `sapiClient` within the `RPCContext`, and updating all code references accordingly. `BapiConfig` is not exported anymore and has been superseded by `SapiConfig`.
|
|
1562
|
-
|
|
1563
1563
|
- **NOTE:** These changes impact your environment variables used for deployments. Please check your infrastructure and deployment setup and adapt accordingly!
|
|
1564
1564
|
- _Previous `bapi` Configuration in `nuxt.config.ts`_
|
|
1565
1565
|
|
|
@@ -1571,15 +1571,15 @@ See [Overriding core RPC Methods](https://scayle.dev/en/core-documentation/store
|
|
|
1571
1571
|
storefront: {
|
|
1572
1572
|
// ...
|
|
1573
1573
|
bapi: {
|
|
1574
|
-
host:
|
|
1575
|
-
token:
|
|
1574
|
+
host: '...',
|
|
1575
|
+
token: '...',
|
|
1576
1576
|
},
|
|
1577
1577
|
// ...
|
|
1578
1578
|
},
|
|
1579
1579
|
// ...
|
|
1580
1580
|
},
|
|
1581
1581
|
// ...
|
|
1582
|
-
}
|
|
1582
|
+
}
|
|
1583
1583
|
```
|
|
1584
1584
|
|
|
1585
1585
|
- _Legacy Environment Variables:_
|
|
@@ -1599,15 +1599,15 @@ See [Overriding core RPC Methods](https://scayle.dev/en/core-documentation/store
|
|
|
1599
1599
|
storefront: {
|
|
1600
1600
|
// ...
|
|
1601
1601
|
sapi: {
|
|
1602
|
-
host:
|
|
1603
|
-
token:
|
|
1602
|
+
host: '...',
|
|
1603
|
+
token: '...',
|
|
1604
1604
|
},
|
|
1605
1605
|
// ...
|
|
1606
1606
|
},
|
|
1607
1607
|
// ...
|
|
1608
1608
|
},
|
|
1609
1609
|
// ...
|
|
1610
|
-
}
|
|
1610
|
+
}
|
|
1611
1611
|
```
|
|
1612
1612
|
|
|
1613
1613
|
- _New Environment Variables:_
|
|
@@ -1620,28 +1620,26 @@ See [Overriding core RPC Methods](https://scayle.dev/en/core-documentation/store
|
|
|
1620
1620
|
- **\[💥 BREAKING\]** We've streamlined cache management by replacing the outdated `AY_CACHE_DISABLED` environment variable. Now, you can effortlessly control caching using either the `NUXT_STOREFRONT_CACHE_ENABLED` environment variable or the `storefront.cache.enabled` option within your `nuxt.config.ts` file, providing a more user-friendly experience.
|
|
1621
1621
|
- **\[💥 BREAKING\]** This release removes the `RedisCache` provider. We now use `UnstorageCache` which also supports Redis as a backing store.
|
|
1622
1622
|
- **\[💥 BREAKING\]** To improve security and streamline token management, we've updated how you access user `accessToken`. Instead of directly accessing the `storefrontAccessToken` field on the `UserAuthentication` interface, you'll now use the dedicated `getAccessToken` RPC. This change ensures a more secure and controlled method for handling sensitive user data within your application.
|
|
1623
|
-
|
|
1624
1623
|
- _Previous Usage of `user.authentication.storefrontAccessToken`:_
|
|
1625
1624
|
|
|
1626
1625
|
```ts
|
|
1627
1626
|
const { data, fetching, fetch, error, status } = useUser(
|
|
1628
|
-
|
|
1627
|
+
'getUser',
|
|
1629
1628
|
// ...
|
|
1630
|
-
)
|
|
1631
|
-
data.value.user.authentication.storefrontAccessToken
|
|
1629
|
+
)
|
|
1630
|
+
data.value.user.authentication.storefrontAccessToken
|
|
1632
1631
|
```
|
|
1633
1632
|
|
|
1634
1633
|
- _Current Usage of dedicated `getAccessToken` RPC method:_
|
|
1635
1634
|
|
|
1636
1635
|
```ts
|
|
1637
1636
|
const { data: accessToken } = useRpc(
|
|
1638
|
-
|
|
1637
|
+
'getAccessToken',
|
|
1639
1638
|
// ...
|
|
1640
|
-
)
|
|
1639
|
+
)
|
|
1641
1640
|
```
|
|
1642
1641
|
|
|
1643
1642
|
- **\[💥 BREAKING\]** We've enhanced security for basket and wishlist keys by switching the default hashing algorithm from MD5 to the more robust SHA256.
|
|
1644
|
-
|
|
1645
1643
|
- _Overriding default `hashAlgorithm` in `nuxt.config.ts`:_
|
|
1646
1644
|
|
|
1647
1645
|
```ts
|
|
@@ -1660,32 +1658,31 @@ See [Overriding core RPC Methods](https://scayle.dev/en/core-documentation/store
|
|
|
1660
1658
|
// ...
|
|
1661
1659
|
},
|
|
1662
1660
|
// ...
|
|
1663
|
-
})
|
|
1661
|
+
})
|
|
1664
1662
|
```
|
|
1665
1663
|
|
|
1666
1664
|
- **\[💥 BREAKING\]** The attribute `loginShopId` is removed from the `ShopUser` interface as the shop now uses session cookies.
|
|
1667
1665
|
- **\[💥 BREAKING\]** We're streamlining the search experience as we transition to SCAYLE Search v2, focusing on a category-centric approach. To achieve this, we're consolidating search functionality. This means we're replacing the `searchProducts` RPC method with `getSearchSuggestions`, which provides both product suggestions (triggered by product IDs) and category suggestions (triggered by category-like terms, leading to filtered category pages).
|
|
1668
|
-
|
|
1669
1666
|
- _Previous Usage of `searchProducts` RPC method:_
|
|
1670
1667
|
|
|
1671
1668
|
```ts
|
|
1672
|
-
const getSearchSuggestionsRpc = useRpcCall(
|
|
1669
|
+
const getSearchSuggestionsRpc = useRpcCall('searchProducts')
|
|
1673
1670
|
|
|
1674
1671
|
data.value = await searchProducts({
|
|
1675
1672
|
term: String(searchQuery.value),
|
|
1676
1673
|
...params,
|
|
1677
|
-
})
|
|
1674
|
+
})
|
|
1678
1675
|
```
|
|
1679
1676
|
|
|
1680
1677
|
- _Current Usage of `getSearchSuggestions` RPC method:_
|
|
1681
1678
|
|
|
1682
1679
|
```ts
|
|
1683
|
-
const getSearchSuggestionsRpc = useRpcCall(
|
|
1680
|
+
const getSearchSuggestionsRpc = useRpcCall('getSearchSuggestions')
|
|
1684
1681
|
|
|
1685
1682
|
data.value = await getSearchSuggestionsRpc({
|
|
1686
1683
|
term: String(searchQuery.value),
|
|
1687
1684
|
...params,
|
|
1688
|
-
})
|
|
1685
|
+
})
|
|
1689
1686
|
```
|
|
1690
1687
|
|
|
1691
1688
|
- **\[💥 BREAKING\]** Improved basket updating: Adding an item to your basket with a reduced quantity will now correctly update the basket contents.
|
package/dist/api/customer.mjs
CHANGED
|
@@ -50,9 +50,7 @@ export class CustomerAPIClient {
|
|
|
50
50
|
if (response.ok) {
|
|
51
51
|
return await response.json();
|
|
52
52
|
}
|
|
53
|
-
if ((response.status === HttpStatusCode.UNAUTHORIZED && response.headers.get("WWW-Authenticate")?.includes(
|
|
54
|
-
"invalid_token"
|
|
55
|
-
) || response.status === HttpStatusCode.FORBIDDEN) && this.context.accessToken && this.context.refreshToken) {
|
|
53
|
+
if ((response.status === HttpStatusCode.UNAUTHORIZED && response.headers.get("WWW-Authenticate")?.includes("invalid_token") || response.status === HttpStatusCode.FORBIDDEN) && this.context.accessToken && this.context.refreshToken) {
|
|
56
54
|
if (retry) {
|
|
57
55
|
const client = getOAuthClient(this.context);
|
|
58
56
|
try {
|
package/dist/api/oauth.mjs
CHANGED
|
@@ -66,12 +66,15 @@ export function getOAuthClient(context) {
|
|
|
66
66
|
if (accessHeader) {
|
|
67
67
|
additionalHeaders["x-internal-access"] = accessHeader;
|
|
68
68
|
}
|
|
69
|
-
return new OAuthClient(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
69
|
+
return new OAuthClient(
|
|
70
|
+
{
|
|
71
|
+
clientId,
|
|
72
|
+
clientSecret,
|
|
73
|
+
apiHost,
|
|
74
|
+
additionalHeaders
|
|
75
|
+
},
|
|
76
|
+
context.log
|
|
77
|
+
);
|
|
75
78
|
}
|
|
76
79
|
export class OAuthClient {
|
|
77
80
|
/**
|
|
@@ -53,9 +53,7 @@ export class UnstorageCache {
|
|
|
53
53
|
* @param tag The tag to purge.
|
|
54
54
|
*/
|
|
55
55
|
async purgeTag(tag) {
|
|
56
|
-
const keys = await this.storage.getItem(
|
|
57
|
-
this.getKey(`tag:${tag}`)
|
|
58
|
-
);
|
|
56
|
+
const keys = await this.storage.getItem(this.getKey(`tag:${tag}`));
|
|
59
57
|
await this.purgeKeys(keys ?? []);
|
|
60
58
|
await this.storage.removeItem(this.getKey(`tag:${tag}`));
|
|
61
59
|
}
|
|
@@ -67,14 +67,7 @@ const MIN_WITH_PARAMS_BASKET = {
|
|
|
67
67
|
},
|
|
68
68
|
variants: {
|
|
69
69
|
attributes: {
|
|
70
|
-
withKey: [
|
|
71
|
-
"brand",
|
|
72
|
-
"name",
|
|
73
|
-
"price",
|
|
74
|
-
"size",
|
|
75
|
-
"shopSize",
|
|
76
|
-
"vendorSize"
|
|
77
|
-
]
|
|
70
|
+
withKey: ["brand", "name", "price", "size", "shopSize", "vendorSize"]
|
|
78
71
|
}
|
|
79
72
|
},
|
|
80
73
|
images: {
|
|
@@ -103,14 +96,7 @@ const MIN_WITH_PARAMS_WISHLIST = {
|
|
|
103
96
|
},
|
|
104
97
|
variants: {
|
|
105
98
|
attributes: {
|
|
106
|
-
withKey: [
|
|
107
|
-
"brand",
|
|
108
|
-
"name",
|
|
109
|
-
"price",
|
|
110
|
-
"size",
|
|
111
|
-
"shopSize",
|
|
112
|
-
"vendorSize"
|
|
113
|
-
]
|
|
99
|
+
withKey: ["brand", "name", "price", "size", "shopSize", "vendorSize"]
|
|
114
100
|
}
|
|
115
101
|
},
|
|
116
102
|
images: {
|
|
@@ -22,7 +22,9 @@ export const getAttributeValuesByGroupId = (attributes, groupId) => {
|
|
|
22
22
|
if (!attributes) {
|
|
23
23
|
return [];
|
|
24
24
|
}
|
|
25
|
-
const attribute = Object.values(attributes).find(
|
|
25
|
+
const attribute = Object.values(attributes).find(
|
|
26
|
+
(attribute2) => attribute2?.id === groupId
|
|
27
|
+
);
|
|
26
28
|
if (!attribute || !attribute.values) {
|
|
27
29
|
return [];
|
|
28
30
|
}
|