@scayle/storefront-core 8.60.1 → 8.61.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 +120 -87
- package/dist/api/INFO.md +1 -1
- package/dist/cache/providers/unstorage.mjs +3 -1
- package/dist/constants/withParameters.mjs +16 -2
- package/dist/helpers/productHelpers.mjs +3 -1
- package/dist/helpers/sanitizationHelpers.mjs +4 -1
- package/dist/rpc/methods/basket/basket.mjs +10 -9
- package/dist/rpc/methods/brands.mjs +2 -2
- package/dist/rpc/methods/campaign.mjs +2 -2
- package/dist/rpc/methods/categories.mjs +5 -5
- package/dist/rpc/methods/cbd.mjs +1 -1
- package/dist/rpc/methods/checkout/checkout.mjs +2 -2
- package/dist/rpc/methods/checkout/order.mjs +2 -2
- package/dist/rpc/methods/checkout/shopUser.mjs +2 -2
- package/dist/rpc/methods/checkout/shopUserAddresses.mjs +3 -1
- package/dist/rpc/methods/navigationTrees.mjs +3 -3
- package/dist/rpc/methods/oauth/idp.mjs +2 -2
- package/dist/rpc/methods/products.mjs +65 -61
- package/dist/rpc/methods/promotion.mjs +3 -3
- package/dist/rpc/methods/search.mjs +2 -2
- package/dist/rpc/methods/session.mjs +7 -7
- package/dist/rpc/methods/shopConfiguration.mjs +1 -1
- package/dist/rpc/methods/user.mjs +6 -4
- package/dist/rpc/methods/variants.mjs +1 -1
- package/dist/rpc/methods/wishlist.mjs +14 -6
- package/dist/types/api/rpc.d.ts +15 -2
- package/dist/utils/hash.mjs +7 -2
- package/dist/utils/index.d.ts +2 -1
- package/dist/utils/index.mjs +1 -1
- package/dist/utils/rpc.d.ts +23 -6
- package/dist/utils/rpc.mjs +4 -3
- package/package.json +10 -16
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
# @scayle/storefront-core
|
|
2
2
|
|
|
3
|
+
## 8.61.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- **[RPC]** `defineRpcHandler` now accepts an optional `method` option (`'GET' | 'POST' | 'PUT' | 'DELETE'`) to declare the HTTP method for the handler. Defaults to `'POST'`, so existing handlers behave exactly as before. Updated built-in RPC methods to use `GET` for safe, cacheable reads and `PUT`/`POST`/`DELETE` for mutations, enabling CDN and browser caching for public data fetches.
|
|
8
|
+
|
|
9
|
+
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
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { defineRpcHandler, type RpcContext } from "@scayle/storefront-core";
|
|
13
|
+
|
|
14
|
+
// Safe, public read — eligible for CDN/browser caching
|
|
15
|
+
export const getNavigation = defineRpcHandler(
|
|
16
|
+
async (context: RpcContext) => {
|
|
17
|
+
/* ... */
|
|
18
|
+
},
|
|
19
|
+
{ method: "GET" }
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
// User-specific / Mutation — uses POST to prevent cache leakage
|
|
23
|
+
export const getBasket = defineRpcHandler(
|
|
24
|
+
async (context: RpcContext) => {
|
|
25
|
+
/* ... */
|
|
26
|
+
}
|
|
27
|
+
// method defaults to 'POST'
|
|
28
|
+
);
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Patch Changes
|
|
32
|
+
|
|
33
|
+
- Updated dependency `@scayle/storefront-api@workspace:*` to `@scayle/storefront-api@catalog:`
|
|
34
|
+
- Updated dependency `@scayle/unstorage-scayle-kv-driver@workspace:*` to `@scayle/unstorage-scayle-kv-driver@catalog:`
|
|
35
|
+
|
|
3
36
|
## 8.60.1
|
|
4
37
|
|
|
5
38
|
### Patch Changes
|
|
@@ -58,33 +91,33 @@
|
|
|
58
91
|
**Migration:**
|
|
59
92
|
|
|
60
93
|
```ts
|
|
61
|
-
import baseSlugify from
|
|
94
|
+
import baseSlugify from "slugify";
|
|
62
95
|
|
|
63
96
|
const slugify = (url: string | undefined): string => {
|
|
64
|
-
return baseSlugify(url ??
|
|
97
|
+
return baseSlugify(url ?? "", {
|
|
65
98
|
lower: true,
|
|
66
99
|
remove: /[*+~.()'"!:@/#?]/g,
|
|
67
|
-
})
|
|
68
|
-
}
|
|
100
|
+
});
|
|
101
|
+
};
|
|
69
102
|
|
|
70
|
-
const localePath = useLocalePath()
|
|
103
|
+
const localePath = useLocalePath();
|
|
71
104
|
|
|
72
105
|
const getProductDetailRoute = (
|
|
73
106
|
id: number,
|
|
74
107
|
name?: string,
|
|
75
|
-
locale?: Locale
|
|
108
|
+
locale?: Locale
|
|
76
109
|
): string => {
|
|
77
110
|
return localePath(
|
|
78
111
|
{
|
|
79
|
-
name:
|
|
112
|
+
name: "p-productName-id",
|
|
80
113
|
params: {
|
|
81
114
|
productName: slugify(name),
|
|
82
115
|
id: `${id}`,
|
|
83
116
|
},
|
|
84
117
|
},
|
|
85
|
-
locale
|
|
86
|
-
)
|
|
87
|
-
}
|
|
118
|
+
locale
|
|
119
|
+
);
|
|
120
|
+
};
|
|
88
121
|
```
|
|
89
122
|
|
|
90
123
|
## 8.59.1
|
|
@@ -265,10 +298,10 @@
|
|
|
265
298
|
Example:
|
|
266
299
|
|
|
267
300
|
```ts
|
|
268
|
-
import { sha256 } from
|
|
301
|
+
import { sha256 } from "@scayle/storefront-core";
|
|
269
302
|
|
|
270
|
-
const hash = await sha256(
|
|
271
|
-
console.log(hash) // '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824'
|
|
303
|
+
const hash = await sha256("hello");
|
|
304
|
+
console.log(hash); // '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824'
|
|
272
305
|
```
|
|
273
306
|
|
|
274
307
|
### Patch Changes
|
|
@@ -328,8 +361,8 @@
|
|
|
328
361
|
customer: {
|
|
329
362
|
groups: context.user?.groups,
|
|
330
363
|
},
|
|
331
|
-
}
|
|
332
|
-
})
|
|
364
|
+
};
|
|
365
|
+
});
|
|
333
366
|
```
|
|
334
367
|
|
|
335
368
|
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).
|
|
@@ -362,32 +395,32 @@
|
|
|
362
395
|
#### Looking up by name (existing, now renamed):
|
|
363
396
|
|
|
364
397
|
```typescript
|
|
365
|
-
import { getAttributeValuesByName } from
|
|
398
|
+
import { getAttributeValuesByName } from "@scayle/storefront-core";
|
|
366
399
|
|
|
367
400
|
// Single-select attribute
|
|
368
|
-
const sizes = getAttributeValuesByName(product.attributes,
|
|
401
|
+
const sizes = getAttributeValuesByName(product.attributes, "size");
|
|
369
402
|
// Returns: [{ id: 1, label: 'M', value: 'medium' }]
|
|
370
403
|
|
|
371
404
|
// Multi-select attribute
|
|
372
|
-
const colors = getAttributeValuesByName(product.attributes,
|
|
405
|
+
const colors = getAttributeValuesByName(product.attributes, "color");
|
|
373
406
|
// Returns: [{ id: 1, label: 'Red' }, { id: 2, label: 'Blue' }]
|
|
374
407
|
|
|
375
408
|
// Non-existent attribute
|
|
376
|
-
const missing = getAttributeValuesByName(product.attributes,
|
|
409
|
+
const missing = getAttributeValuesByName(product.attributes, "doesNotExist");
|
|
377
410
|
// Returns: []
|
|
378
411
|
```
|
|
379
412
|
|
|
380
413
|
#### Looking up by group ID (new):
|
|
381
414
|
|
|
382
415
|
```typescript
|
|
383
|
-
import { getAttributeValuesByGroupId } from
|
|
416
|
+
import { getAttributeValuesByGroupId } from "@scayle/storefront-core";
|
|
384
417
|
|
|
385
418
|
// Look up attribute by its numeric ID from the SCAYLE API
|
|
386
|
-
const promotionValues = getAttributeValuesByGroupId(product.attributes, 42)
|
|
419
|
+
const promotionValues = getAttributeValuesByGroupId(product.attributes, 42);
|
|
387
420
|
// Returns: [{ id: 123, label: 'Summer Sale', value: 'summer-2024' }]
|
|
388
421
|
|
|
389
422
|
// Non-existent attribute group
|
|
390
|
-
const missing = getAttributeValuesByGroupId(product.attributes, 9999)
|
|
423
|
+
const missing = getAttributeValuesByGroupId(product.attributes, 9999);
|
|
391
424
|
// Returns: []
|
|
392
425
|
```
|
|
393
426
|
|
|
@@ -483,10 +516,10 @@
|
|
|
483
516
|
|
|
484
517
|
```ts
|
|
485
518
|
const isComboDealType = (
|
|
486
|
-
promotion?: Promotion | null
|
|
519
|
+
promotion?: Promotion | null
|
|
487
520
|
): promotion is Promotion<ComboDealEffect> => {
|
|
488
|
-
return promotion?.effect?.type === PromotionEffectType.COMBO_DEAL
|
|
489
|
-
}
|
|
521
|
+
return promotion?.effect?.type === PromotionEffectType.COMBO_DEAL;
|
|
522
|
+
};
|
|
490
523
|
```
|
|
491
524
|
|
|
492
525
|
### Patch Changes
|
|
@@ -758,23 +791,23 @@
|
|
|
758
791
|
- 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.
|
|
759
792
|
|
|
760
793
|
```ts
|
|
761
|
-
const { data } = useRpc(
|
|
794
|
+
const { data } = useRpc("getFilters", "getFiltersKey", () => ({
|
|
762
795
|
where: {
|
|
763
796
|
minReduction: 10,
|
|
764
797
|
maxReduction: 20,
|
|
765
798
|
},
|
|
766
|
-
}))
|
|
799
|
+
}));
|
|
767
800
|
|
|
768
801
|
const { data } = useRpc(
|
|
769
|
-
|
|
770
|
-
|
|
802
|
+
"getProductsByCategory",
|
|
803
|
+
"getProductsByCategoryKey",
|
|
771
804
|
() => ({
|
|
772
805
|
where: {
|
|
773
806
|
minReduction: 10,
|
|
774
807
|
maxReduction: 20,
|
|
775
808
|
},
|
|
776
|
-
})
|
|
777
|
-
)
|
|
809
|
+
})
|
|
810
|
+
);
|
|
778
811
|
```
|
|
779
812
|
|
|
780
813
|
## 8.30.3
|
|
@@ -805,28 +838,28 @@ No changes in this release.
|
|
|
805
838
|
|
|
806
839
|
```ts
|
|
807
840
|
export const existingHandlerWithoutParams = async (_context: RpcContext) => {
|
|
808
|
-
return
|
|
809
|
-
}
|
|
841
|
+
return "existing handler";
|
|
842
|
+
};
|
|
810
843
|
|
|
811
844
|
export const existingHandlerWithParams = async (
|
|
812
845
|
{ name }: { name: string },
|
|
813
|
-
_context: RpcContext
|
|
846
|
+
_context: RpcContext
|
|
814
847
|
) => {
|
|
815
|
-
return name
|
|
816
|
-
}
|
|
848
|
+
return name;
|
|
849
|
+
};
|
|
817
850
|
|
|
818
851
|
// will become
|
|
819
852
|
|
|
820
853
|
export const existingHandlerWithoutParams = defineRpcHandler(
|
|
821
854
|
async (_context: RpcContext) => {
|
|
822
|
-
return
|
|
823
|
-
}
|
|
824
|
-
)
|
|
855
|
+
return "existing handler";
|
|
856
|
+
}
|
|
857
|
+
);
|
|
825
858
|
export const existingHandlerWithParams = defineRpcHandler(
|
|
826
859
|
async ({ name }: { name: string }, _context: RpcContext) => {
|
|
827
|
-
return name
|
|
828
|
-
}
|
|
829
|
-
)
|
|
860
|
+
return name;
|
|
861
|
+
}
|
|
862
|
+
);
|
|
830
863
|
```
|
|
831
864
|
|
|
832
865
|
### Patch Changes
|
|
@@ -843,15 +876,15 @@ No changes in this release.
|
|
|
843
876
|
- 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.
|
|
844
877
|
|
|
845
878
|
```ts
|
|
846
|
-
import { rpcMethods } from
|
|
879
|
+
import { rpcMethods } from "@scayle/storefront-core";
|
|
847
880
|
|
|
848
|
-
rpcMethods.getCategoryTree({ hideEmptyCategories: true }, rpcContext)
|
|
881
|
+
rpcMethods.getCategoryTree({ hideEmptyCategories: true }, rpcContext);
|
|
849
882
|
```
|
|
850
883
|
|
|
851
884
|
or
|
|
852
885
|
|
|
853
886
|
```ts
|
|
854
|
-
import { useCategoryTree } from
|
|
887
|
+
import { useCategoryTree } from "#storefront/composables";
|
|
855
888
|
|
|
856
889
|
const { data: rootCategories, status } = useCategoryTree(
|
|
857
890
|
{
|
|
@@ -859,8 +892,8 @@ No changes in this release.
|
|
|
859
892
|
hideEmptyCategories: true,
|
|
860
893
|
},
|
|
861
894
|
},
|
|
862
|
-
|
|
863
|
-
)
|
|
895
|
+
"category-navigation-tree"
|
|
896
|
+
);
|
|
864
897
|
```
|
|
865
898
|
|
|
866
899
|
### Patch Changes
|
|
@@ -1292,12 +1325,12 @@ To get the default campaign key, you can call the RPC method:
|
|
|
1292
1325
|
```typescript
|
|
1293
1326
|
// Before
|
|
1294
1327
|
async function rpcMethod(context) {
|
|
1295
|
-
const campaignKey = { context }
|
|
1328
|
+
const campaignKey = { context };
|
|
1296
1329
|
// ...
|
|
1297
1330
|
}
|
|
1298
1331
|
// After
|
|
1299
1332
|
async function rpcMethod(context) {
|
|
1300
|
-
const campaignKey = await context.callRpc?.(
|
|
1333
|
+
const campaignKey = await context.callRpc?.("getCampaignKey");
|
|
1301
1334
|
// ...
|
|
1302
1335
|
}
|
|
1303
1336
|
```
|
|
@@ -1486,43 +1519,43 @@ See [Overriding core RPC Methods](https://scayle.dev/en/core-documentation/store
|
|
|
1486
1519
|
|
|
1487
1520
|
```ts
|
|
1488
1521
|
const BadgeLabel = {
|
|
1489
|
-
NEW:
|
|
1490
|
-
SOLD_OUT:
|
|
1491
|
-
ONLINE_EXCLUSIVE:
|
|
1492
|
-
SUSTAINABLE:
|
|
1493
|
-
PREMIUM:
|
|
1494
|
-
DEFAULT:
|
|
1495
|
-
} as const
|
|
1522
|
+
NEW: "new",
|
|
1523
|
+
SOLD_OUT: "sold_out",
|
|
1524
|
+
ONLINE_EXCLUSIVE: "online_exclusive",
|
|
1525
|
+
SUSTAINABLE: "sustainable",
|
|
1526
|
+
PREMIUM: "premium",
|
|
1527
|
+
DEFAULT: "",
|
|
1528
|
+
} as const;
|
|
1496
1529
|
|
|
1497
1530
|
type BadgeLabelParamsKeys =
|
|
1498
|
-
|
|
|
1499
|
-
|
|
|
1500
|
-
|
|
|
1501
|
-
|
|
|
1502
|
-
|
|
|
1503
|
-
type BadgeLabelParams = Partial<Record<BadgeLabelParamsKeys, boolean
|
|
1531
|
+
| "isNew"
|
|
1532
|
+
| "isSoldOut"
|
|
1533
|
+
| "isOnlineOnly"
|
|
1534
|
+
| "isSustainable"
|
|
1535
|
+
| "isPremium";
|
|
1536
|
+
type BadgeLabelParams = Partial<Record<BadgeLabelParamsKeys, boolean>>;
|
|
1504
1537
|
|
|
1505
1538
|
const getBadgeLabel = (params: BadgeLabelParams = {}): string => {
|
|
1506
1539
|
if (!params) {
|
|
1507
|
-
return BadgeLabel.DEFAULT
|
|
1540
|
+
return BadgeLabel.DEFAULT;
|
|
1508
1541
|
}
|
|
1509
1542
|
const { isNew, isSoldOut, isOnlineOnly, isSustainable, isPremium } =
|
|
1510
|
-
params
|
|
1543
|
+
params;
|
|
1511
1544
|
|
|
1512
1545
|
if (isNew) {
|
|
1513
|
-
return BadgeLabel.NEW
|
|
1546
|
+
return BadgeLabel.NEW;
|
|
1514
1547
|
} else if (isSoldOut) {
|
|
1515
|
-
return BadgeLabel.SOLD_OUT
|
|
1548
|
+
return BadgeLabel.SOLD_OUT;
|
|
1516
1549
|
} else if (isOnlineOnly) {
|
|
1517
|
-
return BadgeLabel.ONLINE_EXCLUSIVE
|
|
1550
|
+
return BadgeLabel.ONLINE_EXCLUSIVE;
|
|
1518
1551
|
} else if (isSustainable) {
|
|
1519
|
-
return BadgeLabel.SUSTAINABLE
|
|
1552
|
+
return BadgeLabel.SUSTAINABLE;
|
|
1520
1553
|
} else if (isPremium) {
|
|
1521
|
-
return BadgeLabel.PREMIUM
|
|
1554
|
+
return BadgeLabel.PREMIUM;
|
|
1522
1555
|
} else {
|
|
1523
|
-
return BadgeLabel.DEFAULT
|
|
1556
|
+
return BadgeLabel.DEFAULT;
|
|
1524
1557
|
}
|
|
1525
|
-
}
|
|
1558
|
+
};
|
|
1526
1559
|
```
|
|
1527
1560
|
|
|
1528
1561
|
- **\[💥 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`.
|
|
@@ -1538,15 +1571,15 @@ See [Overriding core RPC Methods](https://scayle.dev/en/core-documentation/store
|
|
|
1538
1571
|
storefront: {
|
|
1539
1572
|
// ...
|
|
1540
1573
|
bapi: {
|
|
1541
|
-
host:
|
|
1542
|
-
token:
|
|
1574
|
+
host: "...",
|
|
1575
|
+
token: "...",
|
|
1543
1576
|
},
|
|
1544
1577
|
// ...
|
|
1545
1578
|
},
|
|
1546
1579
|
// ...
|
|
1547
1580
|
},
|
|
1548
1581
|
// ...
|
|
1549
|
-
}
|
|
1582
|
+
};
|
|
1550
1583
|
```
|
|
1551
1584
|
|
|
1552
1585
|
- _Legacy Environment Variables:_
|
|
@@ -1566,15 +1599,15 @@ See [Overriding core RPC Methods](https://scayle.dev/en/core-documentation/store
|
|
|
1566
1599
|
storefront: {
|
|
1567
1600
|
// ...
|
|
1568
1601
|
sapi: {
|
|
1569
|
-
host:
|
|
1570
|
-
token:
|
|
1602
|
+
host: "...",
|
|
1603
|
+
token: "...",
|
|
1571
1604
|
},
|
|
1572
1605
|
// ...
|
|
1573
1606
|
},
|
|
1574
1607
|
// ...
|
|
1575
1608
|
},
|
|
1576
1609
|
// ...
|
|
1577
|
-
}
|
|
1610
|
+
};
|
|
1578
1611
|
```
|
|
1579
1612
|
|
|
1580
1613
|
- _New Environment Variables:_
|
|
@@ -1592,19 +1625,19 @@ See [Overriding core RPC Methods](https://scayle.dev/en/core-documentation/store
|
|
|
1592
1625
|
|
|
1593
1626
|
```ts
|
|
1594
1627
|
const { data, fetching, fetch, error, status } = useUser(
|
|
1595
|
-
|
|
1628
|
+
"getUser"
|
|
1596
1629
|
// ...
|
|
1597
|
-
)
|
|
1598
|
-
data.value.user.authentication.storefrontAccessToken
|
|
1630
|
+
);
|
|
1631
|
+
data.value.user.authentication.storefrontAccessToken;
|
|
1599
1632
|
```
|
|
1600
1633
|
|
|
1601
1634
|
- _Current Usage of dedicated `getAccessToken` RPC method:_
|
|
1602
1635
|
|
|
1603
1636
|
```ts
|
|
1604
1637
|
const { data: accessToken } = useRpc(
|
|
1605
|
-
|
|
1638
|
+
"getAccessToken"
|
|
1606
1639
|
// ...
|
|
1607
|
-
)
|
|
1640
|
+
);
|
|
1608
1641
|
```
|
|
1609
1642
|
|
|
1610
1643
|
- **\[💥 BREAKING\]** We've enhanced security for basket and wishlist keys by switching the default hashing algorithm from MD5 to the more robust SHA256.
|
|
@@ -1627,7 +1660,7 @@ See [Overriding core RPC Methods](https://scayle.dev/en/core-documentation/store
|
|
|
1627
1660
|
// ...
|
|
1628
1661
|
},
|
|
1629
1662
|
// ...
|
|
1630
|
-
})
|
|
1663
|
+
});
|
|
1631
1664
|
```
|
|
1632
1665
|
|
|
1633
1666
|
- **\[💥 BREAKING\]** The attribute `loginShopId` is removed from the `ShopUser` interface as the shop now uses session cookies.
|
|
@@ -1636,23 +1669,23 @@ See [Overriding core RPC Methods](https://scayle.dev/en/core-documentation/store
|
|
|
1636
1669
|
- _Previous Usage of `searchProducts` RPC method:_
|
|
1637
1670
|
|
|
1638
1671
|
```ts
|
|
1639
|
-
const getSearchSuggestionsRpc = useRpcCall(
|
|
1672
|
+
const getSearchSuggestionsRpc = useRpcCall("searchProducts");
|
|
1640
1673
|
|
|
1641
1674
|
data.value = await searchProducts({
|
|
1642
1675
|
term: String(searchQuery.value),
|
|
1643
1676
|
...params,
|
|
1644
|
-
})
|
|
1677
|
+
});
|
|
1645
1678
|
```
|
|
1646
1679
|
|
|
1647
1680
|
- _Current Usage of `getSearchSuggestions` RPC method:_
|
|
1648
1681
|
|
|
1649
1682
|
```ts
|
|
1650
|
-
const getSearchSuggestionsRpc = useRpcCall(
|
|
1683
|
+
const getSearchSuggestionsRpc = useRpcCall("getSearchSuggestions");
|
|
1651
1684
|
|
|
1652
1685
|
data.value = await getSearchSuggestionsRpc({
|
|
1653
1686
|
term: String(searchQuery.value),
|
|
1654
1687
|
...params,
|
|
1655
|
-
})
|
|
1688
|
+
});
|
|
1656
1689
|
```
|
|
1657
1690
|
|
|
1658
1691
|
- **\[💥 BREAKING\]** Improved basket updating: Adding an item to your basket with a reduced quantity will now correctly update the basket contents.
|
package/dist/api/INFO.md
CHANGED
|
@@ -4,4 +4,4 @@
|
|
|
4
4
|
|
|
5
5
|
This directory is the home of "mini" API clients. While some SCAYLE APIs provide a TypeScript SDK as an npm package (e.g. SAPI) others do not. When the API is simple enough, we may create a "mini" SDK within `storefront-core`. This way we can provide a TypeScript native abstraction over the API but not suffer the overhead of an additional package to maintain.
|
|
6
6
|
|
|
7
|
-
The SDKs created here should generally be a single file. The goal should be to make them as self-contained as possible, but it is ok if they need to pull a type or utility function from elsewhere in `storefront-core`.
|
|
7
|
+
The SDKs created here should generally be a single file. The goal should be to make them as self-contained as possible, but it is ok if they need to pull a type or utility function from elsewhere in `storefront-core`.
|
|
@@ -53,7 +53,9 @@ 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(
|
|
56
|
+
const keys = await this.storage.getItem(
|
|
57
|
+
this.getKey(`tag:${tag}`)
|
|
58
|
+
);
|
|
57
59
|
await this.purgeKeys(keys ?? []);
|
|
58
60
|
await this.storage.removeItem(this.getKey(`tag:${tag}`));
|
|
59
61
|
}
|
|
@@ -67,7 +67,14 @@ const MIN_WITH_PARAMS_BASKET = {
|
|
|
67
67
|
},
|
|
68
68
|
variants: {
|
|
69
69
|
attributes: {
|
|
70
|
-
withKey: [
|
|
70
|
+
withKey: [
|
|
71
|
+
"brand",
|
|
72
|
+
"name",
|
|
73
|
+
"price",
|
|
74
|
+
"size",
|
|
75
|
+
"shopSize",
|
|
76
|
+
"vendorSize"
|
|
77
|
+
]
|
|
71
78
|
}
|
|
72
79
|
},
|
|
73
80
|
images: {
|
|
@@ -96,7 +103,14 @@ const MIN_WITH_PARAMS_WISHLIST = {
|
|
|
96
103
|
},
|
|
97
104
|
variants: {
|
|
98
105
|
attributes: {
|
|
99
|
-
withKey: [
|
|
106
|
+
withKey: [
|
|
107
|
+
"brand",
|
|
108
|
+
"name",
|
|
109
|
+
"price",
|
|
110
|
+
"size",
|
|
111
|
+
"shopSize",
|
|
112
|
+
"vendorSize"
|
|
113
|
+
]
|
|
100
114
|
}
|
|
101
115
|
},
|
|
102
116
|
images: {
|
|
@@ -50,7 +50,9 @@ export const getAllSizesFromVariants = (variantsAttributes, attributeName = "sho
|
|
|
50
50
|
const array = variantsAttributes.map(
|
|
51
51
|
(variant) => getFirstAttributeValue(variant.attributes, attributeName)
|
|
52
52
|
).filter(Boolean);
|
|
53
|
-
return [
|
|
53
|
+
return [
|
|
54
|
+
...new Map(array.map((item) => [item?.id ?? item, item])).values()
|
|
55
|
+
];
|
|
54
56
|
};
|
|
55
57
|
export const getProductSiblings = (product, colorAttributeName = "colorDetail") => {
|
|
56
58
|
if (!product) {
|
|
@@ -15,7 +15,10 @@ export const purifySensitiveData = (data = {}, blacklistedKeys = ["password", "t
|
|
|
15
15
|
(excludedKey) => key.includes(excludedKey)
|
|
16
16
|
);
|
|
17
17
|
if (isSensitiveData && value) {
|
|
18
|
-
purifiedPayload[key] = purifySensitiveValue(
|
|
18
|
+
purifiedPayload[key] = purifySensitiveValue(
|
|
19
|
+
value,
|
|
20
|
+
showFirstAndLastChar
|
|
21
|
+
);
|
|
19
22
|
} else {
|
|
20
23
|
purifiedPayload[key] = value;
|
|
21
24
|
}
|
|
@@ -95,7 +95,7 @@ export const addItemToBasket = defineRpcHandler(async ({
|
|
|
95
95
|
}
|
|
96
96
|
);
|
|
97
97
|
}
|
|
98
|
-
});
|
|
98
|
+
}, { method: "PUT" });
|
|
99
99
|
export const addItemsToBasket = defineRpcHandler(async (params, context) => {
|
|
100
100
|
if (!hasSession(context)) {
|
|
101
101
|
return new ErrorResponse(
|
|
@@ -162,7 +162,7 @@ export const addItemsToBasket = defineRpcHandler(async (params, context) => {
|
|
|
162
162
|
}
|
|
163
163
|
);
|
|
164
164
|
}
|
|
165
|
-
});
|
|
165
|
+
}, { method: "PUT" });
|
|
166
166
|
export const getBasket = defineRpcHandler(async (options, context) => {
|
|
167
167
|
if (!hasSession(context)) {
|
|
168
168
|
return new ErrorResponse(
|
|
@@ -200,7 +200,7 @@ export const getBasket = defineRpcHandler(async (options, context) => {
|
|
|
200
200
|
);
|
|
201
201
|
}
|
|
202
202
|
return { basket: response.basket };
|
|
203
|
-
});
|
|
203
|
+
}, { method: "POST" });
|
|
204
204
|
export const removeItemFromBasket = defineRpcHandler(async (options, context) => {
|
|
205
205
|
if (!hasSession(context)) {
|
|
206
206
|
return new ErrorResponse(
|
|
@@ -235,7 +235,7 @@ export const removeItemFromBasket = defineRpcHandler(async (options, context) =>
|
|
|
235
235
|
);
|
|
236
236
|
}
|
|
237
237
|
return { basket: response };
|
|
238
|
-
});
|
|
238
|
+
}, { method: "DELETE" });
|
|
239
239
|
export const clearBasket = defineRpcHandler(
|
|
240
240
|
async (context) => {
|
|
241
241
|
const getBasketResponse = await getBasket({}, context);
|
|
@@ -253,7 +253,8 @@ export const clearBasket = defineRpcHandler(
|
|
|
253
253
|
}
|
|
254
254
|
}
|
|
255
255
|
return true;
|
|
256
|
-
}
|
|
256
|
+
},
|
|
257
|
+
{ method: "DELETE" }
|
|
257
258
|
);
|
|
258
259
|
export const mergeBaskets = defineRpcHandler(async ({ fromBasketKey, toBasketKey, with: _with, orderCustomData }, context) => {
|
|
259
260
|
const resolvedWith = getWithParams(
|
|
@@ -270,7 +271,7 @@ export const mergeBaskets = defineRpcHandler(async ({ fromBasketKey, toBasketKey
|
|
|
270
271
|
},
|
|
271
272
|
context
|
|
272
273
|
);
|
|
273
|
-
});
|
|
274
|
+
}, { method: "POST" });
|
|
274
275
|
export const updateBasketItem = defineRpcHandler(async ({ basketItemKey, update, with: _with, orderCustomData }, context) => {
|
|
275
276
|
if (!hasSession(context)) {
|
|
276
277
|
return new ErrorResponse(
|
|
@@ -317,7 +318,7 @@ export const updateBasketItem = defineRpcHandler(async ({ basketItemKey, update,
|
|
|
317
318
|
}
|
|
318
319
|
);
|
|
319
320
|
}
|
|
320
|
-
});
|
|
321
|
+
}, { method: "PUT" });
|
|
321
322
|
export const getApplicablePromotionsByCode = defineRpcHandler(async ({ promotionCode, with: _with }, context) => {
|
|
322
323
|
if (!hasSession(context)) {
|
|
323
324
|
return new ErrorResponse(
|
|
@@ -358,7 +359,7 @@ export const getApplicablePromotionsByCode = defineRpcHandler(async ({ promotion
|
|
|
358
359
|
} else {
|
|
359
360
|
return { basket: result.basket };
|
|
360
361
|
}
|
|
361
|
-
});
|
|
362
|
+
}, { method: "POST" });
|
|
362
363
|
export const updatePromotions = defineRpcHandler(async (params, context) => {
|
|
363
364
|
if (!hasSession(context)) {
|
|
364
365
|
return new ErrorResponse(
|
|
@@ -398,7 +399,7 @@ export const updatePromotions = defineRpcHandler(async (params, context) => {
|
|
|
398
399
|
);
|
|
399
400
|
}
|
|
400
401
|
return { basket: result.basket };
|
|
401
|
-
});
|
|
402
|
+
}, { method: "PUT" });
|
|
402
403
|
function parseBasketError(response) {
|
|
403
404
|
const parsedError = {
|
|
404
405
|
message: "",
|
|
@@ -11,7 +11,7 @@ export const getBrands = defineRpcHandler(async ({ pagination }, context) => {
|
|
|
11
11
|
perPage: pagination?.perPage ? Math.min(pagination.perPage, MAX_PER_PAGE) : void 0
|
|
12
12
|
}
|
|
13
13
|
});
|
|
14
|
-
});
|
|
14
|
+
}, { method: "GET" });
|
|
15
15
|
export const getBrandById = defineRpcHandler(async ({ brandId }, context) => {
|
|
16
16
|
const { sapiClient, cached } = context;
|
|
17
17
|
return await cached(
|
|
@@ -20,4 +20,4 @@ export const getBrandById = defineRpcHandler(async ({ brandId }, context) => {
|
|
|
20
20
|
cacheKeyPrefix: `getBrandById-${brandId}`
|
|
21
21
|
}
|
|
22
22
|
)(brandId);
|
|
23
|
-
});
|
|
23
|
+
}, { method: "GET" });
|
|
@@ -22,7 +22,7 @@ const getCampaigns = async (context) => {
|
|
|
22
22
|
export const getCampaign = defineRpcHandler(async (context) => {
|
|
23
23
|
const campaigns = await getCampaigns(context);
|
|
24
24
|
return campaigns.find(isCampaignActive);
|
|
25
|
-
});
|
|
25
|
+
}, { method: "GET" });
|
|
26
26
|
export const getCampaignKey = defineRpcHandler(async (context) => {
|
|
27
27
|
if (context.campaignKey) {
|
|
28
28
|
return context.campaignKey;
|
|
@@ -30,4 +30,4 @@ export const getCampaignKey = defineRpcHandler(async (context) => {
|
|
|
30
30
|
const campaigns = await getCampaigns(context);
|
|
31
31
|
const campaign = campaigns.find(isCampaignActive);
|
|
32
32
|
return campaign?.key;
|
|
33
|
-
});
|
|
33
|
+
}, { method: "GET" });
|
|
@@ -13,7 +13,7 @@ export const getRootCategories = defineRpcHandler(async ({ children = 1, include
|
|
|
13
13
|
categories: result,
|
|
14
14
|
activeNode: void 0
|
|
15
15
|
};
|
|
16
|
-
});
|
|
16
|
+
}, { method: "GET" });
|
|
17
17
|
export const getCategoryByPath = defineRpcHandler(async ({ path, children = 1, includeHidden, properties, includeProductSorting }, context) => {
|
|
18
18
|
const { cached, sapiClient } = context;
|
|
19
19
|
const sanitizedPath = splitAndRemoveEmpty(path);
|
|
@@ -26,7 +26,7 @@ export const getCategoryByPath = defineRpcHandler(async ({ path, children = 1, i
|
|
|
26
26
|
with: { children, properties, includeProductSorting },
|
|
27
27
|
includeHidden
|
|
28
28
|
});
|
|
29
|
-
});
|
|
29
|
+
}, { method: "GET" });
|
|
30
30
|
export const getCategoriesByPath = defineRpcHandler(async ({ path, children = 1, includeHidden, properties, includeProductSorting }, context) => {
|
|
31
31
|
const { cached, sapiClient } = context;
|
|
32
32
|
if (path === "/") {
|
|
@@ -79,7 +79,7 @@ export const getCategoriesByPath = defineRpcHandler(async ({ path, children = 1,
|
|
|
79
79
|
lastNode = rootPath[i];
|
|
80
80
|
}
|
|
81
81
|
return { categories: tree, activeNode: result };
|
|
82
|
-
});
|
|
82
|
+
}, { method: "GET" });
|
|
83
83
|
export const getCategoryById = defineRpcHandler(async ({ id, children = 1, includeHidden, properties, includeProductSorting }, context) => {
|
|
84
84
|
const { cached, sapiClient } = context;
|
|
85
85
|
return await cached(
|
|
@@ -96,7 +96,7 @@ export const getCategoryById = defineRpcHandler(async ({ id, children = 1, inclu
|
|
|
96
96
|
},
|
|
97
97
|
includeHidden
|
|
98
98
|
});
|
|
99
|
-
});
|
|
99
|
+
}, { method: "GET" });
|
|
100
100
|
export const getCategoryTree = defineRpcHandler(async ({
|
|
101
101
|
children,
|
|
102
102
|
includeHidden,
|
|
@@ -143,4 +143,4 @@ export const getCategoryTree = defineRpcHandler(async ({
|
|
|
143
143
|
return categoryTree.filter(
|
|
144
144
|
(category) => categoryProductCountTable[category.id] > 0
|
|
145
145
|
);
|
|
146
|
-
});
|
|
146
|
+
}, { method: "GET" });
|
package/dist/rpc/methods/cbd.mjs
CHANGED