@scayle/storefront-core 8.61.1 → 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.
Files changed (33) hide show
  1. package/CHANGELOG-V7.md +1 -11
  2. package/CHANGELOG.md +96 -103
  3. package/dist/api/customer.mjs +1 -3
  4. package/dist/api/oauth.mjs +9 -6
  5. package/dist/cache/providers/unstorage.mjs +1 -3
  6. package/dist/constants/withParameters.mjs +2 -16
  7. package/dist/helpers/attributeHelpers.mjs +3 -1
  8. package/dist/helpers/filterHelper.mjs +11 -8
  9. package/dist/helpers/productHelpers.mjs +1 -3
  10. package/dist/helpers/sanitizationHelpers.mjs +1 -4
  11. package/dist/helpers/sortingHelper.mjs +1 -3
  12. package/dist/rpc/methods/basket/basket.d.ts +2 -2
  13. package/dist/rpc/methods/basket/basket.mjs +334 -321
  14. package/dist/rpc/methods/brands.mjs +26 -20
  15. package/dist/rpc/methods/campaign.mjs +32 -23
  16. package/dist/rpc/methods/categories.mjs +156 -135
  17. package/dist/rpc/methods/cbd.mjs +52 -49
  18. package/dist/rpc/methods/checkout/checkout.mjs +42 -39
  19. package/dist/rpc/methods/checkout/order.mjs +46 -40
  20. package/dist/rpc/methods/checkout/shopUser.mjs +112 -106
  21. package/dist/rpc/methods/navigationTrees.mjs +50 -32
  22. package/dist/rpc/methods/oauth/idp.mjs +64 -55
  23. package/dist/rpc/methods/products.mjs +224 -212
  24. package/dist/rpc/methods/promotion.mjs +46 -31
  25. package/dist/rpc/methods/search.mjs +26 -20
  26. package/dist/rpc/methods/session.mjs +289 -260
  27. package/dist/rpc/methods/shopConfiguration.mjs +12 -9
  28. package/dist/rpc/methods/user.mjs +87 -78
  29. package/dist/rpc/methods/variants.mjs +17 -14
  30. package/dist/rpc/methods/wishlist.mjs +71 -62
  31. package/dist/utils/hash.mjs +2 -7
  32. package/dist/utils/sapi.mjs +10 -7
  33. package/package.json +1 -1
@@ -21,93 +21,102 @@ const getUser = defineRpcHandler(
21
21
  // We use POST here to prevent user data to be leaking into caches.
22
22
  { method: "POST" }
23
23
  );
24
- const fetchUser = defineRpcHandler(async ({ accessToken }, context) => {
25
- const { shopId } = context;
26
- const client = new CustomerAPIClient(context);
27
- const user = await client.getMe(shopId, accessToken);
28
- if (!user.authentication) {
29
- user.authentication = {
30
- type: "idp"
31
- };
32
- }
33
- if (user.email) {
34
- user.emailHash = await sha256(user.email);
35
- }
36
- user.orderSummary = user.orderSummary?.filter(
37
- ({ shopId: shopId2 }) => shopId2 === context.shopId
38
- );
39
- return user;
40
- }, { method: "POST" });
41
- const refreshUser = defineRpcHandler(async (context) => {
42
- if (!hasSession(context)) {
43
- return new ErrorResponse(
44
- HttpStatusCode.BAD_REQUEST,
45
- HttpStatusMessage.BAD_REQUEST,
46
- "No Session found"
24
+ const fetchUser = defineRpcHandler(
25
+ async ({ accessToken }, context) => {
26
+ const { shopId } = context;
27
+ const client = new CustomerAPIClient(context);
28
+ const user = await client.getMe(shopId, accessToken);
29
+ if (!user.authentication) {
30
+ user.authentication = {
31
+ type: "idp"
32
+ };
33
+ }
34
+ if (user.email) {
35
+ user.emailHash = await sha256(user.email);
36
+ }
37
+ user.orderSummary = user.orderSummary?.filter(
38
+ ({ shopId: shopId2 }) => shopId2 === context.shopId
47
39
  );
48
- }
49
- const { accessToken } = context;
50
- if (!accessToken) {
51
- return { user: void 0 };
52
- }
53
- try {
54
- const user = await context.callRpc?.("fetchUser", { accessToken });
55
- if (!user) {
40
+ return user;
41
+ },
42
+ { method: "POST" }
43
+ );
44
+ const refreshUser = defineRpcHandler(
45
+ async (context) => {
46
+ if (!hasSession(context)) {
47
+ return new ErrorResponse(
48
+ HttpStatusCode.BAD_REQUEST,
49
+ HttpStatusMessage.BAD_REQUEST,
50
+ "No Session found"
51
+ );
52
+ }
53
+ const { accessToken } = context;
54
+ if (!accessToken) {
56
55
  return { user: void 0 };
57
56
  }
58
- context.updateUser(user);
59
- return { user };
60
- } catch {
61
- await context.destroySession();
62
- return { user: void 0 };
63
- }
64
- }, { method: "POST" });
65
- const getAccessToken = defineRpcHandler(async ({ forceTokenRefresh = false } = { forceTokenRefresh: false }, context) => {
66
- if (!hasSession(context)) {
67
- return new ErrorResponse(
68
- HttpStatusCode.BAD_REQUEST,
69
- HttpStatusMessage.BAD_REQUEST,
70
- "No Session found"
71
- );
72
- }
73
- if (!context.accessToken) {
74
- return new ErrorResponse(
75
- HttpStatusCode.UNAUTHORIZED,
76
- HttpStatusMessage.UNAUTHORIZED,
77
- "No access token present"
78
- );
79
- }
80
- if (forceTokenRefresh) {
81
- if (!context.refreshToken) {
57
+ try {
58
+ const user = await context.callRpc?.("fetchUser", { accessToken });
59
+ if (!user) {
60
+ return { user: void 0 };
61
+ }
62
+ context.updateUser(user);
63
+ return { user };
64
+ } catch {
65
+ await context.destroySession();
66
+ return { user: void 0 };
67
+ }
68
+ },
69
+ { method: "POST" }
70
+ );
71
+ const getAccessToken = defineRpcHandler(
72
+ async ({ forceTokenRefresh = false } = { forceTokenRefresh: false }, context) => {
73
+ if (!hasSession(context)) {
74
+ return new ErrorResponse(
75
+ HttpStatusCode.BAD_REQUEST,
76
+ HttpStatusMessage.BAD_REQUEST,
77
+ "No Session found"
78
+ );
79
+ }
80
+ if (!context.accessToken) {
82
81
  return new ErrorResponse(
83
82
  HttpStatusCode.UNAUTHORIZED,
84
83
  HttpStatusMessage.UNAUTHORIZED,
85
- "No refresh token present"
84
+ "No access token present"
86
85
  );
87
86
  }
88
- const client = getOAuthClient(context);
89
- try {
90
- const tokens = await client.refreshToken({
91
- grant_type: "refresh_token",
92
- refresh_token: context.refreshToken
93
- });
94
- context.updateTokens({
95
- accessToken: tokens.access_token,
96
- refreshToken: tokens.refresh_token
97
- });
98
- } catch (e) {
99
- if (e instanceof FetchError && e.response.status === HttpStatusCode.UNAUTHORIZED) {
100
- context.log.debug(
101
- "Failed to refresh Checkout Token due to invalid refresh token. Deleting session"
102
- );
103
- await context.destroySession();
104
- } else {
105
- context.log.debug(
106
- "Failed to refresh Checkout Token for unknown reason."
87
+ if (forceTokenRefresh) {
88
+ if (!context.refreshToken) {
89
+ return new ErrorResponse(
90
+ HttpStatusCode.UNAUTHORIZED,
91
+ HttpStatusMessage.UNAUTHORIZED,
92
+ "No refresh token present"
107
93
  );
108
94
  }
95
+ const client = getOAuthClient(context);
96
+ try {
97
+ const tokens = await client.refreshToken({
98
+ grant_type: "refresh_token",
99
+ refresh_token: context.refreshToken
100
+ });
101
+ context.updateTokens({
102
+ accessToken: tokens.access_token,
103
+ refreshToken: tokens.refresh_token
104
+ });
105
+ } catch (e) {
106
+ if (e instanceof FetchError && e.response.status === HttpStatusCode.UNAUTHORIZED) {
107
+ context.log.debug(
108
+ "Failed to refresh Checkout Token due to invalid refresh token. Deleting session"
109
+ );
110
+ await context.destroySession();
111
+ } else {
112
+ context.log.debug(
113
+ "Failed to refresh Checkout Token for unknown reason."
114
+ );
115
+ }
116
+ }
109
117
  }
110
- }
111
- return context.accessToken;
112
- }, { method: "POST" });
118
+ return context.accessToken;
119
+ },
120
+ { method: "POST" }
121
+ );
113
122
  export { getUser, fetchUser, refreshUser, getAccessToken };
@@ -3,17 +3,20 @@ import { defineRpcHandler } from "../../utils/rpc.mjs";
3
3
  const defaultWith = {
4
4
  attributes: "all"
5
5
  };
6
- export const getVariantById = defineRpcHandler(async ({ ids, include = defaultWith, pricePromotionKey = "default" }, context) => {
7
- const { sapiClient, cached, withParams } = context;
8
- const campaignKey = await context.callRpc?.("getCampaignKey");
9
- const resolvedWith = include ?? withParams?.variant ?? defaultWith;
10
- return await cached(
11
- mapSAPIFetchErrorToResponse(sapiClient.variants.getByIds),
12
- {
13
- cacheKeyPrefix: "getByIds-variants"
14
- }
15
- )(
16
- ids,
17
- include ? { with: resolvedWith, campaignKey, pricePromotionKey } : void 0
18
- );
19
- }, { method: "GET" });
6
+ export const getVariantById = defineRpcHandler(
7
+ async ({ ids, include = defaultWith, pricePromotionKey = "default" }, context) => {
8
+ const { sapiClient, cached, withParams } = context;
9
+ const campaignKey = await context.callRpc?.("getCampaignKey");
10
+ const resolvedWith = include ?? withParams?.variant ?? defaultWith;
11
+ return await cached(
12
+ mapSAPIFetchErrorToResponse(sapiClient.variants.getByIds),
13
+ {
14
+ cacheKeyPrefix: "getByIds-variants"
15
+ }
16
+ )(
17
+ ids,
18
+ include ? { with: resolvedWith, campaignKey, pricePromotionKey } : void 0
19
+ );
20
+ },
21
+ { method: "GET" }
22
+ );
@@ -22,9 +22,12 @@ export const getWishlist = defineRpcHandler(
22
22
  }
23
23
  const { sapiClient, wishlistKey } = context;
24
24
  const campaignKey = await context.callRpc?.("getCampaignKey");
25
- const { pricePromotionKey, ...resolvedWith } = getWithParams({
26
- with: options
27
- }, context);
25
+ const { pricePromotionKey, ...resolvedWith } = getWithParams(
26
+ {
27
+ with: options
28
+ },
29
+ context
30
+ );
28
31
  return await mapSAPIFetchErrorToResponse(sapiClient.wishlist.get)(
29
32
  wishlistKey,
30
33
  {
@@ -36,69 +39,75 @@ export const getWishlist = defineRpcHandler(
36
39
  },
37
40
  { method: "POST" }
38
41
  );
39
- export const addItemToWishlist = defineRpcHandler(async (options, context) => {
40
- if (!hasSession(context)) {
41
- return new ErrorResponse(
42
- HttpStatusCode.BAD_REQUEST,
43
- HttpStatusMessage.BAD_REQUEST,
44
- "No Session found"
45
- );
46
- }
47
- const { sapiClient, wishlistKey } = context;
48
- const campaignKey = await context.callRpc?.("getCampaignKey");
49
- const { productId, variantId } = options;
50
- const { pricePromotionKey, ...resolvedWith } = getWithParams(
51
- options,
52
- context
53
- );
54
- if (!productId && !variantId) {
55
- return new ErrorResponse(
56
- HttpStatusCode.BAD_REQUEST,
57
- HttpStatusMessage.BAD_REQUEST,
58
- "No productId or variantId given"
42
+ export const addItemToWishlist = defineRpcHandler(
43
+ async (options, context) => {
44
+ if (!hasSession(context)) {
45
+ return new ErrorResponse(
46
+ HttpStatusCode.BAD_REQUEST,
47
+ HttpStatusMessage.BAD_REQUEST,
48
+ "No Session found"
49
+ );
50
+ }
51
+ const { sapiClient, wishlistKey } = context;
52
+ const campaignKey = await context.callRpc?.("getCampaignKey");
53
+ const { productId, variantId } = options;
54
+ const { pricePromotionKey, ...resolvedWith } = getWithParams(
55
+ options,
56
+ context
59
57
  );
60
- }
61
- const result = await sapiClient.wishlist.addItem(
62
- wishlistKey,
63
- variantId ? { variantId } : { productId },
64
- {
65
- with: resolvedWith,
66
- campaignKey,
67
- pricePromotionKey: pricePromotionKey ?? ""
58
+ if (!productId && !variantId) {
59
+ return new ErrorResponse(
60
+ HttpStatusCode.BAD_REQUEST,
61
+ HttpStatusMessage.BAD_REQUEST,
62
+ "No productId or variantId given"
63
+ );
68
64
  }
69
- );
70
- if (result.type === "success") {
71
- return result.wishlist;
72
- } else {
73
- const { statusCode: code, kind, type } = result;
74
- context.log.error("Adding to wishlist failed", result.wishlist);
75
- return new Response(JSON.stringify({ kind, type }), { status: code });
76
- }
77
- }, { method: "PUT" });
78
- export const removeItemFromWishlist = defineRpcHandler(async (options, context) => {
79
- if (!hasSession(context)) {
80
- return new ErrorResponse(
81
- HttpStatusCode.BAD_REQUEST,
82
- HttpStatusMessage.BAD_REQUEST,
83
- "No Session found"
65
+ const result = await sapiClient.wishlist.addItem(
66
+ wishlistKey,
67
+ variantId ? { variantId } : { productId },
68
+ {
69
+ with: resolvedWith,
70
+ campaignKey,
71
+ pricePromotionKey: pricePromotionKey ?? ""
72
+ }
84
73
  );
85
- }
86
- const { sapiClient, wishlistKey } = context;
87
- const campaignKey = await context.callRpc?.("getCampaignKey");
88
- const { pricePromotionKey, ...resolvedWith } = getWithParams(
89
- options,
90
- context
91
- );
92
- return await mapSAPIFetchErrorToResponse(sapiClient.wishlist.deleteItem)(
93
- wishlistKey,
94
- options.itemKey,
95
- {
96
- with: resolvedWith,
97
- campaignKey,
98
- pricePromotionKey: pricePromotionKey ?? ""
74
+ if (result.type === "success") {
75
+ return result.wishlist;
76
+ } else {
77
+ const { statusCode: code, kind, type } = result;
78
+ context.log.error("Adding to wishlist failed", result.wishlist);
79
+ return new Response(JSON.stringify({ kind, type }), { status: code });
99
80
  }
100
- );
101
- }, { method: "DELETE" });
81
+ },
82
+ { method: "PUT" }
83
+ );
84
+ export const removeItemFromWishlist = defineRpcHandler(
85
+ async (options, context) => {
86
+ if (!hasSession(context)) {
87
+ return new ErrorResponse(
88
+ HttpStatusCode.BAD_REQUEST,
89
+ HttpStatusMessage.BAD_REQUEST,
90
+ "No Session found"
91
+ );
92
+ }
93
+ const { sapiClient, wishlistKey } = context;
94
+ const campaignKey = await context.callRpc?.("getCampaignKey");
95
+ const { pricePromotionKey, ...resolvedWith } = getWithParams(
96
+ options,
97
+ context
98
+ );
99
+ return await mapSAPIFetchErrorToResponse(sapiClient.wishlist.deleteItem)(
100
+ wishlistKey,
101
+ options.itemKey,
102
+ {
103
+ with: resolvedWith,
104
+ campaignKey,
105
+ pricePromotionKey: pricePromotionKey ?? ""
106
+ }
107
+ );
108
+ },
109
+ { method: "DELETE" }
110
+ );
102
111
  export const clearWishlist = defineRpcHandler(
103
112
  async (context) => {
104
113
  const wishlistResponse = await getWishlist({}, context);
@@ -35,15 +35,10 @@ export const hmac = async (value, secret, algorithm = "SHA-256") => {
35
35
  };
36
36
  function base64ToBytes(base64) {
37
37
  const binString = atob(base64);
38
- return Uint8Array.from(
39
- binString,
40
- (m) => m.codePointAt(0)
41
- );
38
+ return Uint8Array.from(binString, (m) => m.codePointAt(0));
42
39
  }
43
40
  function bytesToBase64(bytes) {
44
- const binString = Array.from(bytes, (x) => String.fromCodePoint(x)).join(
45
- ""
46
- );
41
+ const binString = Array.from(bytes, (x) => String.fromCodePoint(x)).join("");
47
42
  return btoa(binString);
48
43
  }
49
44
  export const encodeBase64 = (string) => {
@@ -6,13 +6,16 @@ export function mapSAPIFetchErrorToResponse(func) {
6
6
  } catch (e) {
7
7
  if (e instanceof FetchError) {
8
8
  const response = e.response;
9
- return Response.json({
10
- statusCode: response.status,
11
- statusMessage: response.statusText
12
- }, {
13
- status: response.status,
14
- statusText: response.statusText
15
- });
9
+ return Response.json(
10
+ {
11
+ statusCode: response.status,
12
+ statusMessage: response.statusText
13
+ },
14
+ {
15
+ status: response.status,
16
+ statusText: response.statusText
17
+ }
18
+ );
16
19
  }
17
20
  throw e;
18
21
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scayle/storefront-core",
3
- "version": "8.61.1",
3
+ "version": "8.61.2",
4
4
  "description": "Collection of essential utilities to work with the Storefront API",
5
5
  "author": "SCAYLE Commerce Engine",
6
6
  "license": "MIT",