@scayle/storefront-core 8.60.0 → 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 +128 -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,46 @@
|
|
|
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
|
+
|
|
36
|
+
## 8.60.1
|
|
37
|
+
|
|
38
|
+
### Patch Changes
|
|
39
|
+
|
|
40
|
+
**Dependencies**
|
|
41
|
+
|
|
42
|
+
- Updated dependency to @scayle/unstorage-scayle-kv-driver@2.1.1
|
|
43
|
+
|
|
3
44
|
## 8.60.0
|
|
4
45
|
|
|
5
46
|
### Minor Changes
|
|
@@ -50,33 +91,33 @@
|
|
|
50
91
|
**Migration:**
|
|
51
92
|
|
|
52
93
|
```ts
|
|
53
|
-
import baseSlugify from
|
|
94
|
+
import baseSlugify from "slugify";
|
|
54
95
|
|
|
55
96
|
const slugify = (url: string | undefined): string => {
|
|
56
|
-
return baseSlugify(url ??
|
|
97
|
+
return baseSlugify(url ?? "", {
|
|
57
98
|
lower: true,
|
|
58
99
|
remove: /[*+~.()'"!:@/#?]/g,
|
|
59
|
-
})
|
|
60
|
-
}
|
|
100
|
+
});
|
|
101
|
+
};
|
|
61
102
|
|
|
62
|
-
const localePath = useLocalePath()
|
|
103
|
+
const localePath = useLocalePath();
|
|
63
104
|
|
|
64
105
|
const getProductDetailRoute = (
|
|
65
106
|
id: number,
|
|
66
107
|
name?: string,
|
|
67
|
-
locale?: Locale
|
|
108
|
+
locale?: Locale
|
|
68
109
|
): string => {
|
|
69
110
|
return localePath(
|
|
70
111
|
{
|
|
71
|
-
name:
|
|
112
|
+
name: "p-productName-id",
|
|
72
113
|
params: {
|
|
73
114
|
productName: slugify(name),
|
|
74
115
|
id: `${id}`,
|
|
75
116
|
},
|
|
76
117
|
},
|
|
77
|
-
locale
|
|
78
|
-
)
|
|
79
|
-
}
|
|
118
|
+
locale
|
|
119
|
+
);
|
|
120
|
+
};
|
|
80
121
|
```
|
|
81
122
|
|
|
82
123
|
## 8.59.1
|
|
@@ -257,10 +298,10 @@
|
|
|
257
298
|
Example:
|
|
258
299
|
|
|
259
300
|
```ts
|
|
260
|
-
import { sha256 } from
|
|
301
|
+
import { sha256 } from "@scayle/storefront-core";
|
|
261
302
|
|
|
262
|
-
const hash = await sha256(
|
|
263
|
-
console.log(hash) // '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824'
|
|
303
|
+
const hash = await sha256("hello");
|
|
304
|
+
console.log(hash); // '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824'
|
|
264
305
|
```
|
|
265
306
|
|
|
266
307
|
### Patch Changes
|
|
@@ -320,8 +361,8 @@
|
|
|
320
361
|
customer: {
|
|
321
362
|
groups: context.user?.groups,
|
|
322
363
|
},
|
|
323
|
-
}
|
|
324
|
-
})
|
|
364
|
+
};
|
|
365
|
+
});
|
|
325
366
|
```
|
|
326
367
|
|
|
327
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).
|
|
@@ -354,32 +395,32 @@
|
|
|
354
395
|
#### Looking up by name (existing, now renamed):
|
|
355
396
|
|
|
356
397
|
```typescript
|
|
357
|
-
import { getAttributeValuesByName } from
|
|
398
|
+
import { getAttributeValuesByName } from "@scayle/storefront-core";
|
|
358
399
|
|
|
359
400
|
// Single-select attribute
|
|
360
|
-
const sizes = getAttributeValuesByName(product.attributes,
|
|
401
|
+
const sizes = getAttributeValuesByName(product.attributes, "size");
|
|
361
402
|
// Returns: [{ id: 1, label: 'M', value: 'medium' }]
|
|
362
403
|
|
|
363
404
|
// Multi-select attribute
|
|
364
|
-
const colors = getAttributeValuesByName(product.attributes,
|
|
405
|
+
const colors = getAttributeValuesByName(product.attributes, "color");
|
|
365
406
|
// Returns: [{ id: 1, label: 'Red' }, { id: 2, label: 'Blue' }]
|
|
366
407
|
|
|
367
408
|
// Non-existent attribute
|
|
368
|
-
const missing = getAttributeValuesByName(product.attributes,
|
|
409
|
+
const missing = getAttributeValuesByName(product.attributes, "doesNotExist");
|
|
369
410
|
// Returns: []
|
|
370
411
|
```
|
|
371
412
|
|
|
372
413
|
#### Looking up by group ID (new):
|
|
373
414
|
|
|
374
415
|
```typescript
|
|
375
|
-
import { getAttributeValuesByGroupId } from
|
|
416
|
+
import { getAttributeValuesByGroupId } from "@scayle/storefront-core";
|
|
376
417
|
|
|
377
418
|
// Look up attribute by its numeric ID from the SCAYLE API
|
|
378
|
-
const promotionValues = getAttributeValuesByGroupId(product.attributes, 42)
|
|
419
|
+
const promotionValues = getAttributeValuesByGroupId(product.attributes, 42);
|
|
379
420
|
// Returns: [{ id: 123, label: 'Summer Sale', value: 'summer-2024' }]
|
|
380
421
|
|
|
381
422
|
// Non-existent attribute group
|
|
382
|
-
const missing = getAttributeValuesByGroupId(product.attributes, 9999)
|
|
423
|
+
const missing = getAttributeValuesByGroupId(product.attributes, 9999);
|
|
383
424
|
// Returns: []
|
|
384
425
|
```
|
|
385
426
|
|
|
@@ -475,10 +516,10 @@
|
|
|
475
516
|
|
|
476
517
|
```ts
|
|
477
518
|
const isComboDealType = (
|
|
478
|
-
promotion?: Promotion | null
|
|
519
|
+
promotion?: Promotion | null
|
|
479
520
|
): promotion is Promotion<ComboDealEffect> => {
|
|
480
|
-
return promotion?.effect?.type === PromotionEffectType.COMBO_DEAL
|
|
481
|
-
}
|
|
521
|
+
return promotion?.effect?.type === PromotionEffectType.COMBO_DEAL;
|
|
522
|
+
};
|
|
482
523
|
```
|
|
483
524
|
|
|
484
525
|
### Patch Changes
|
|
@@ -750,23 +791,23 @@
|
|
|
750
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.
|
|
751
792
|
|
|
752
793
|
```ts
|
|
753
|
-
const { data } = useRpc(
|
|
794
|
+
const { data } = useRpc("getFilters", "getFiltersKey", () => ({
|
|
754
795
|
where: {
|
|
755
796
|
minReduction: 10,
|
|
756
797
|
maxReduction: 20,
|
|
757
798
|
},
|
|
758
|
-
}))
|
|
799
|
+
}));
|
|
759
800
|
|
|
760
801
|
const { data } = useRpc(
|
|
761
|
-
|
|
762
|
-
|
|
802
|
+
"getProductsByCategory",
|
|
803
|
+
"getProductsByCategoryKey",
|
|
763
804
|
() => ({
|
|
764
805
|
where: {
|
|
765
806
|
minReduction: 10,
|
|
766
807
|
maxReduction: 20,
|
|
767
808
|
},
|
|
768
|
-
})
|
|
769
|
-
)
|
|
809
|
+
})
|
|
810
|
+
);
|
|
770
811
|
```
|
|
771
812
|
|
|
772
813
|
## 8.30.3
|
|
@@ -797,28 +838,28 @@ No changes in this release.
|
|
|
797
838
|
|
|
798
839
|
```ts
|
|
799
840
|
export const existingHandlerWithoutParams = async (_context: RpcContext) => {
|
|
800
|
-
return
|
|
801
|
-
}
|
|
841
|
+
return "existing handler";
|
|
842
|
+
};
|
|
802
843
|
|
|
803
844
|
export const existingHandlerWithParams = async (
|
|
804
845
|
{ name }: { name: string },
|
|
805
|
-
_context: RpcContext
|
|
846
|
+
_context: RpcContext
|
|
806
847
|
) => {
|
|
807
|
-
return name
|
|
808
|
-
}
|
|
848
|
+
return name;
|
|
849
|
+
};
|
|
809
850
|
|
|
810
851
|
// will become
|
|
811
852
|
|
|
812
853
|
export const existingHandlerWithoutParams = defineRpcHandler(
|
|
813
854
|
async (_context: RpcContext) => {
|
|
814
|
-
return
|
|
815
|
-
}
|
|
816
|
-
)
|
|
855
|
+
return "existing handler";
|
|
856
|
+
}
|
|
857
|
+
);
|
|
817
858
|
export const existingHandlerWithParams = defineRpcHandler(
|
|
818
859
|
async ({ name }: { name: string }, _context: RpcContext) => {
|
|
819
|
-
return name
|
|
820
|
-
}
|
|
821
|
-
)
|
|
860
|
+
return name;
|
|
861
|
+
}
|
|
862
|
+
);
|
|
822
863
|
```
|
|
823
864
|
|
|
824
865
|
### Patch Changes
|
|
@@ -835,15 +876,15 @@ No changes in this release.
|
|
|
835
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.
|
|
836
877
|
|
|
837
878
|
```ts
|
|
838
|
-
import { rpcMethods } from
|
|
879
|
+
import { rpcMethods } from "@scayle/storefront-core";
|
|
839
880
|
|
|
840
|
-
rpcMethods.getCategoryTree({ hideEmptyCategories: true }, rpcContext)
|
|
881
|
+
rpcMethods.getCategoryTree({ hideEmptyCategories: true }, rpcContext);
|
|
841
882
|
```
|
|
842
883
|
|
|
843
884
|
or
|
|
844
885
|
|
|
845
886
|
```ts
|
|
846
|
-
import { useCategoryTree } from
|
|
887
|
+
import { useCategoryTree } from "#storefront/composables";
|
|
847
888
|
|
|
848
889
|
const { data: rootCategories, status } = useCategoryTree(
|
|
849
890
|
{
|
|
@@ -851,8 +892,8 @@ No changes in this release.
|
|
|
851
892
|
hideEmptyCategories: true,
|
|
852
893
|
},
|
|
853
894
|
},
|
|
854
|
-
|
|
855
|
-
)
|
|
895
|
+
"category-navigation-tree"
|
|
896
|
+
);
|
|
856
897
|
```
|
|
857
898
|
|
|
858
899
|
### Patch Changes
|
|
@@ -1284,12 +1325,12 @@ To get the default campaign key, you can call the RPC method:
|
|
|
1284
1325
|
```typescript
|
|
1285
1326
|
// Before
|
|
1286
1327
|
async function rpcMethod(context) {
|
|
1287
|
-
const campaignKey = { context }
|
|
1328
|
+
const campaignKey = { context };
|
|
1288
1329
|
// ...
|
|
1289
1330
|
}
|
|
1290
1331
|
// After
|
|
1291
1332
|
async function rpcMethod(context) {
|
|
1292
|
-
const campaignKey = await context.callRpc?.(
|
|
1333
|
+
const campaignKey = await context.callRpc?.("getCampaignKey");
|
|
1293
1334
|
// ...
|
|
1294
1335
|
}
|
|
1295
1336
|
```
|
|
@@ -1478,43 +1519,43 @@ See [Overriding core RPC Methods](https://scayle.dev/en/core-documentation/store
|
|
|
1478
1519
|
|
|
1479
1520
|
```ts
|
|
1480
1521
|
const BadgeLabel = {
|
|
1481
|
-
NEW:
|
|
1482
|
-
SOLD_OUT:
|
|
1483
|
-
ONLINE_EXCLUSIVE:
|
|
1484
|
-
SUSTAINABLE:
|
|
1485
|
-
PREMIUM:
|
|
1486
|
-
DEFAULT:
|
|
1487
|
-
} 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;
|
|
1488
1529
|
|
|
1489
1530
|
type BadgeLabelParamsKeys =
|
|
1490
|
-
|
|
|
1491
|
-
|
|
|
1492
|
-
|
|
|
1493
|
-
|
|
|
1494
|
-
|
|
|
1495
|
-
type BadgeLabelParams = Partial<Record<BadgeLabelParamsKeys, boolean
|
|
1531
|
+
| "isNew"
|
|
1532
|
+
| "isSoldOut"
|
|
1533
|
+
| "isOnlineOnly"
|
|
1534
|
+
| "isSustainable"
|
|
1535
|
+
| "isPremium";
|
|
1536
|
+
type BadgeLabelParams = Partial<Record<BadgeLabelParamsKeys, boolean>>;
|
|
1496
1537
|
|
|
1497
1538
|
const getBadgeLabel = (params: BadgeLabelParams = {}): string => {
|
|
1498
1539
|
if (!params) {
|
|
1499
|
-
return BadgeLabel.DEFAULT
|
|
1540
|
+
return BadgeLabel.DEFAULT;
|
|
1500
1541
|
}
|
|
1501
1542
|
const { isNew, isSoldOut, isOnlineOnly, isSustainable, isPremium } =
|
|
1502
|
-
params
|
|
1543
|
+
params;
|
|
1503
1544
|
|
|
1504
1545
|
if (isNew) {
|
|
1505
|
-
return BadgeLabel.NEW
|
|
1546
|
+
return BadgeLabel.NEW;
|
|
1506
1547
|
} else if (isSoldOut) {
|
|
1507
|
-
return BadgeLabel.SOLD_OUT
|
|
1548
|
+
return BadgeLabel.SOLD_OUT;
|
|
1508
1549
|
} else if (isOnlineOnly) {
|
|
1509
|
-
return BadgeLabel.ONLINE_EXCLUSIVE
|
|
1550
|
+
return BadgeLabel.ONLINE_EXCLUSIVE;
|
|
1510
1551
|
} else if (isSustainable) {
|
|
1511
|
-
return BadgeLabel.SUSTAINABLE
|
|
1552
|
+
return BadgeLabel.SUSTAINABLE;
|
|
1512
1553
|
} else if (isPremium) {
|
|
1513
|
-
return BadgeLabel.PREMIUM
|
|
1554
|
+
return BadgeLabel.PREMIUM;
|
|
1514
1555
|
} else {
|
|
1515
|
-
return BadgeLabel.DEFAULT
|
|
1556
|
+
return BadgeLabel.DEFAULT;
|
|
1516
1557
|
}
|
|
1517
|
-
}
|
|
1558
|
+
};
|
|
1518
1559
|
```
|
|
1519
1560
|
|
|
1520
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`.
|
|
@@ -1530,15 +1571,15 @@ See [Overriding core RPC Methods](https://scayle.dev/en/core-documentation/store
|
|
|
1530
1571
|
storefront: {
|
|
1531
1572
|
// ...
|
|
1532
1573
|
bapi: {
|
|
1533
|
-
host:
|
|
1534
|
-
token:
|
|
1574
|
+
host: "...",
|
|
1575
|
+
token: "...",
|
|
1535
1576
|
},
|
|
1536
1577
|
// ...
|
|
1537
1578
|
},
|
|
1538
1579
|
// ...
|
|
1539
1580
|
},
|
|
1540
1581
|
// ...
|
|
1541
|
-
}
|
|
1582
|
+
};
|
|
1542
1583
|
```
|
|
1543
1584
|
|
|
1544
1585
|
- _Legacy Environment Variables:_
|
|
@@ -1558,15 +1599,15 @@ See [Overriding core RPC Methods](https://scayle.dev/en/core-documentation/store
|
|
|
1558
1599
|
storefront: {
|
|
1559
1600
|
// ...
|
|
1560
1601
|
sapi: {
|
|
1561
|
-
host:
|
|
1562
|
-
token:
|
|
1602
|
+
host: "...",
|
|
1603
|
+
token: "...",
|
|
1563
1604
|
},
|
|
1564
1605
|
// ...
|
|
1565
1606
|
},
|
|
1566
1607
|
// ...
|
|
1567
1608
|
},
|
|
1568
1609
|
// ...
|
|
1569
|
-
}
|
|
1610
|
+
};
|
|
1570
1611
|
```
|
|
1571
1612
|
|
|
1572
1613
|
- _New Environment Variables:_
|
|
@@ -1584,19 +1625,19 @@ See [Overriding core RPC Methods](https://scayle.dev/en/core-documentation/store
|
|
|
1584
1625
|
|
|
1585
1626
|
```ts
|
|
1586
1627
|
const { data, fetching, fetch, error, status } = useUser(
|
|
1587
|
-
|
|
1628
|
+
"getUser"
|
|
1588
1629
|
// ...
|
|
1589
|
-
)
|
|
1590
|
-
data.value.user.authentication.storefrontAccessToken
|
|
1630
|
+
);
|
|
1631
|
+
data.value.user.authentication.storefrontAccessToken;
|
|
1591
1632
|
```
|
|
1592
1633
|
|
|
1593
1634
|
- _Current Usage of dedicated `getAccessToken` RPC method:_
|
|
1594
1635
|
|
|
1595
1636
|
```ts
|
|
1596
1637
|
const { data: accessToken } = useRpc(
|
|
1597
|
-
|
|
1638
|
+
"getAccessToken"
|
|
1598
1639
|
// ...
|
|
1599
|
-
)
|
|
1640
|
+
);
|
|
1600
1641
|
```
|
|
1601
1642
|
|
|
1602
1643
|
- **\[💥 BREAKING\]** We've enhanced security for basket and wishlist keys by switching the default hashing algorithm from MD5 to the more robust SHA256.
|
|
@@ -1619,7 +1660,7 @@ See [Overriding core RPC Methods](https://scayle.dev/en/core-documentation/store
|
|
|
1619
1660
|
// ...
|
|
1620
1661
|
},
|
|
1621
1662
|
// ...
|
|
1622
|
-
})
|
|
1663
|
+
});
|
|
1623
1664
|
```
|
|
1624
1665
|
|
|
1625
1666
|
- **\[💥 BREAKING\]** The attribute `loginShopId` is removed from the `ShopUser` interface as the shop now uses session cookies.
|
|
@@ -1628,23 +1669,23 @@ See [Overriding core RPC Methods](https://scayle.dev/en/core-documentation/store
|
|
|
1628
1669
|
- _Previous Usage of `searchProducts` RPC method:_
|
|
1629
1670
|
|
|
1630
1671
|
```ts
|
|
1631
|
-
const getSearchSuggestionsRpc = useRpcCall(
|
|
1672
|
+
const getSearchSuggestionsRpc = useRpcCall("searchProducts");
|
|
1632
1673
|
|
|
1633
1674
|
data.value = await searchProducts({
|
|
1634
1675
|
term: String(searchQuery.value),
|
|
1635
1676
|
...params,
|
|
1636
|
-
})
|
|
1677
|
+
});
|
|
1637
1678
|
```
|
|
1638
1679
|
|
|
1639
1680
|
- _Current Usage of `getSearchSuggestions` RPC method:_
|
|
1640
1681
|
|
|
1641
1682
|
```ts
|
|
1642
|
-
const getSearchSuggestionsRpc = useRpcCall(
|
|
1683
|
+
const getSearchSuggestionsRpc = useRpcCall("getSearchSuggestions");
|
|
1643
1684
|
|
|
1644
1685
|
data.value = await getSearchSuggestionsRpc({
|
|
1645
1686
|
term: String(searchQuery.value),
|
|
1646
1687
|
...params,
|
|
1647
|
-
})
|
|
1688
|
+
});
|
|
1648
1689
|
```
|
|
1649
1690
|
|
|
1650
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