@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.
Files changed (33) hide show
  1. package/CHANGELOG-V7.md +1 -11
  2. package/CHANGELOG.md +100 -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 +4 -4
@@ -1,23 +1,29 @@
1
1
  import { mapSAPIFetchErrorToResponse } from "../../utils/sapi.mjs";
2
2
  import { defineRpcHandler } from "../../utils/index.mjs";
3
3
  const MAX_PER_PAGE = 100;
4
- export const getBrands = defineRpcHandler(async ({ pagination }, context) => {
5
- const { sapiClient, cached } = context;
6
- return await cached(mapSAPIFetchErrorToResponse(sapiClient.brands.get), {
7
- cacheKeyPrefix: "getBrands"
8
- })({
9
- pagination: {
10
- page: pagination?.page,
11
- perPage: pagination?.perPage ? Math.min(pagination.perPage, MAX_PER_PAGE) : void 0
12
- }
13
- });
14
- }, { method: "GET" });
15
- export const getBrandById = defineRpcHandler(async ({ brandId }, context) => {
16
- const { sapiClient, cached } = context;
17
- return await cached(
18
- mapSAPIFetchErrorToResponse(sapiClient.brands.getById),
19
- {
20
- cacheKeyPrefix: `getBrandById-${brandId}`
21
- }
22
- )(brandId);
23
- }, { method: "GET" });
4
+ export const getBrands = defineRpcHandler(
5
+ async ({ pagination }, context) => {
6
+ const { sapiClient, cached } = context;
7
+ return await cached(mapSAPIFetchErrorToResponse(sapiClient.brands.get), {
8
+ cacheKeyPrefix: "getBrands"
9
+ })({
10
+ pagination: {
11
+ page: pagination?.page,
12
+ perPage: pagination?.perPage ? Math.min(pagination.perPage, MAX_PER_PAGE) : void 0
13
+ }
14
+ });
15
+ },
16
+ { method: "GET" }
17
+ );
18
+ export const getBrandById = defineRpcHandler(
19
+ async ({ brandId }, context) => {
20
+ const { sapiClient, cached } = context;
21
+ return await cached(
22
+ mapSAPIFetchErrorToResponse(sapiClient.brands.getById),
23
+ {
24
+ cacheKeyPrefix: `getBrandById-${brandId}`
25
+ }
26
+ )(brandId);
27
+ },
28
+ { method: "GET" }
29
+ );
@@ -6,28 +6,37 @@ import {
6
6
  import { defineRpcHandler } from "../../utils/index.mjs";
7
7
  const getCampaigns = async (context) => {
8
8
  const { cached, sapiClient } = context;
9
- const { campaigns } = await cached(async () => {
10
- const { entities } = await sapiClient.campaigns.get();
11
- return {
12
- campaigns: entities.filter((campaign) => {
13
- return campaignHasNotEnded(campaign);
14
- }).sort(sortCampaignsByDateAscending)
15
- };
16
- }, {
17
- cacheKeyPrefix: "get-campaigns",
18
- ttl: 5 * 60
19
- })();
9
+ const { campaigns } = await cached(
10
+ async () => {
11
+ const { entities } = await sapiClient.campaigns.get();
12
+ return {
13
+ campaigns: entities.filter((campaign) => {
14
+ return campaignHasNotEnded(campaign);
15
+ }).sort(sortCampaignsByDateAscending)
16
+ };
17
+ },
18
+ {
19
+ cacheKeyPrefix: "get-campaigns",
20
+ ttl: 5 * 60
21
+ }
22
+ )();
20
23
  return campaigns;
21
24
  };
22
- export const getCampaign = defineRpcHandler(async (context) => {
23
- const campaigns = await getCampaigns(context);
24
- return campaigns.find(isCampaignActive);
25
- }, { method: "GET" });
26
- export const getCampaignKey = defineRpcHandler(async (context) => {
27
- if (context.campaignKey) {
28
- return context.campaignKey;
29
- }
30
- const campaigns = await getCampaigns(context);
31
- const campaign = campaigns.find(isCampaignActive);
32
- return campaign?.key;
33
- }, { method: "GET" });
25
+ export const getCampaign = defineRpcHandler(
26
+ async (context) => {
27
+ const campaigns = await getCampaigns(context);
28
+ return campaigns.find(isCampaignActive);
29
+ },
30
+ { method: "GET" }
31
+ );
32
+ export const getCampaignKey = defineRpcHandler(
33
+ async (context) => {
34
+ if (context.campaignKey) {
35
+ return context.campaignKey;
36
+ }
37
+ const campaigns = await getCampaigns(context);
38
+ const campaign = campaigns.find(isCampaignActive);
39
+ return campaign?.key;
40
+ },
41
+ { method: "GET" }
42
+ );
@@ -1,146 +1,167 @@
1
1
  import { splitAndRemoveEmpty } from "../../helpers/index.mjs";
2
2
  import { mapSAPIFetchErrorToResponse } from "../../utils/sapi.mjs";
3
3
  import { defineRpcHandler } from "../../utils/index.mjs";
4
- export const getRootCategories = defineRpcHandler(async ({ children = 1, includeHidden, properties, includeProductSorting }, context) => {
5
- const { cached, sapiClient } = context;
6
- const result = await cached(sapiClient.categories.getRoots, {
7
- cacheKeyPrefix: "root-categories"
8
- })({
9
- with: { children, properties, includeProductSorting },
10
- includeHidden
11
- });
12
- return {
13
- categories: result,
14
- activeNode: void 0
15
- };
16
- }, { method: "GET" });
17
- export const getCategoryByPath = defineRpcHandler(async ({ path, children = 1, includeHidden, properties, includeProductSorting }, context) => {
18
- const { cached, sapiClient } = context;
19
- const sanitizedPath = splitAndRemoveEmpty(path);
20
- return await cached(
21
- mapSAPIFetchErrorToResponse(sapiClient.categories.getByPath),
22
- {
23
- cacheKeyPrefix: `getByPath-category-${sanitizedPath}`
4
+ export const getRootCategories = defineRpcHandler(
5
+ async ({ children = 1, includeHidden, properties, includeProductSorting }, context) => {
6
+ const { cached, sapiClient } = context;
7
+ const result = await cached(sapiClient.categories.getRoots, {
8
+ cacheKeyPrefix: "root-categories"
9
+ })({
10
+ with: { children, properties, includeProductSorting },
11
+ includeHidden
12
+ });
13
+ return {
14
+ categories: result,
15
+ activeNode: void 0
16
+ };
17
+ },
18
+ { method: "GET" }
19
+ );
20
+ export const getCategoryByPath = defineRpcHandler(
21
+ async ({ path, children = 1, includeHidden, properties, includeProductSorting }, context) => {
22
+ const { cached, sapiClient } = context;
23
+ const sanitizedPath = splitAndRemoveEmpty(path);
24
+ return await cached(
25
+ mapSAPIFetchErrorToResponse(sapiClient.categories.getByPath),
26
+ {
27
+ cacheKeyPrefix: `getByPath-category-${sanitizedPath}`
28
+ }
29
+ )(sanitizedPath, {
30
+ with: { children, properties, includeProductSorting },
31
+ includeHidden
32
+ });
33
+ },
34
+ { method: "GET" }
35
+ );
36
+ export const getCategoriesByPath = defineRpcHandler(
37
+ async ({ path, children = 1, includeHidden, properties, includeProductSorting }, context) => {
38
+ const { cached, sapiClient } = context;
39
+ if (path === "/") {
40
+ return getRootCategories(
41
+ { children, includeHidden, properties, includeProductSorting },
42
+ context
43
+ );
24
44
  }
25
- )(sanitizedPath, {
26
- with: { children, properties, includeProductSorting },
27
- includeHidden
28
- });
29
- }, { method: "GET" });
30
- export const getCategoriesByPath = defineRpcHandler(async ({ path, children = 1, includeHidden, properties, includeProductSorting }, context) => {
31
- const { cached, sapiClient } = context;
32
- if (path === "/") {
33
- return getRootCategories(
34
- { children, includeHidden, properties, includeProductSorting },
35
- context
45
+ const sanitizedPath = splitAndRemoveEmpty(path);
46
+ const result = await cached(
47
+ mapSAPIFetchErrorToResponse(sapiClient.categories.getByPath),
48
+ {
49
+ cacheKeyPrefix: `getByPath-categories-${sanitizedPath}`
50
+ }
51
+ )(sanitizedPath, {
52
+ with: { children, properties, includeProductSorting },
53
+ includeHidden
54
+ });
55
+ if (result instanceof Response) {
56
+ return result;
57
+ }
58
+ const rootPath = await Promise.all(
59
+ (result.rootlineIds || []).map((id) => {
60
+ return cached(sapiClient.categories.getById, {
61
+ cacheKeyPrefix: `getById-categories-${id}`
62
+ })(id, {
63
+ with: {
64
+ children,
65
+ parents: "all",
66
+ properties,
67
+ includeProductSorting
68
+ },
69
+ includeHidden
70
+ });
71
+ })
36
72
  );
37
- }
38
- const sanitizedPath = splitAndRemoveEmpty(path);
39
- const result = await cached(
40
- mapSAPIFetchErrorToResponse(sapiClient.categories.getByPath),
41
- {
42
- cacheKeyPrefix: `getByPath-categories-${sanitizedPath}`
73
+ let tree = rootPath[rootPath.length - 1];
74
+ let lastNode = null;
75
+ for (let i = 0; i < rootPath.length; i++) {
76
+ if (lastNode === null) {
77
+ tree = rootPath[i];
78
+ } else if (lastNode.children) {
79
+ const activeElement = lastNode.children?.find(
80
+ (c) => c?.id === rootPath[i]?.id
81
+ );
82
+ if (activeElement) {
83
+ activeElement.children = rootPath[i].children;
84
+ }
85
+ }
86
+ lastNode = rootPath[i];
43
87
  }
44
- )(sanitizedPath, {
45
- with: { children, properties, includeProductSorting },
46
- includeHidden
47
- });
48
- if (result instanceof Response) {
49
- return result;
50
- }
51
- const rootPath = await Promise.all(
52
- (result.rootlineIds || []).map((id) => {
53
- return cached(sapiClient.categories.getById, {
88
+ return { categories: tree, activeNode: result };
89
+ },
90
+ { method: "GET" }
91
+ );
92
+ export const getCategoryById = defineRpcHandler(
93
+ async ({ id, children = 1, includeHidden, properties, includeProductSorting }, context) => {
94
+ const { cached, sapiClient } = context;
95
+ return await cached(
96
+ mapSAPIFetchErrorToResponse(sapiClient.categories.getById),
97
+ {
54
98
  cacheKeyPrefix: `getById-categories-${id}`
55
- })(id, {
56
- with: {
57
- children,
58
- parents: "all",
59
- properties,
60
- includeProductSorting
61
- },
62
- includeHidden
63
- });
64
- })
65
- );
66
- let tree = rootPath[rootPath.length - 1];
67
- let lastNode = null;
68
- for (let i = 0; i < rootPath.length; i++) {
69
- if (lastNode === null) {
70
- tree = rootPath[i];
71
- } else if (lastNode.children) {
72
- const activeElement = lastNode.children?.find(
73
- (c) => c?.id === rootPath[i]?.id
74
- );
75
- if (activeElement) {
76
- activeElement.children = rootPath[i].children;
77
99
  }
100
+ )(id, {
101
+ with: {
102
+ children,
103
+ parents: "all",
104
+ properties,
105
+ includeProductSorting
106
+ },
107
+ includeHidden
108
+ });
109
+ },
110
+ { method: "GET" }
111
+ );
112
+ export const getCategoryTree = defineRpcHandler(
113
+ async ({
114
+ children,
115
+ includeHidden,
116
+ properties,
117
+ hideEmptyCategories,
118
+ includeProductSorting
119
+ }, context) => {
120
+ const { cached, sapiClient, callRpc } = context;
121
+ const categoryTree = await cached(sapiClient.categories.getRoots, {
122
+ cacheKeyPrefix: "root-categories"
123
+ })({
124
+ with: { children, properties, includeProductSorting },
125
+ includeHidden
126
+ });
127
+ if (!hideEmptyCategories) {
128
+ return categoryTree;
78
129
  }
79
- lastNode = rootPath[i];
80
- }
81
- return { categories: tree, activeNode: result };
82
- }, { method: "GET" });
83
- export const getCategoryById = defineRpcHandler(async ({ id, children = 1, includeHidden, properties, includeProductSorting }, context) => {
84
- const { cached, sapiClient } = context;
85
- return await cached(
86
- mapSAPIFetchErrorToResponse(sapiClient.categories.getById),
87
- {
88
- cacheKeyPrefix: `getById-categories-${id}`
89
- }
90
- )(id, {
91
- with: {
92
- children,
93
- parents: "all",
94
- properties,
95
- includeProductSorting
96
- },
97
- includeHidden
98
- });
99
- }, { method: "GET" });
100
- export const getCategoryTree = defineRpcHandler(async ({
101
- children,
102
- includeHidden,
103
- properties,
104
- hideEmptyCategories,
105
- includeProductSorting
106
- }, context) => {
107
- const { cached, sapiClient, callRpc } = context;
108
- const categoryTree = await cached(sapiClient.categories.getRoots, {
109
- cacheKeyPrefix: "root-categories"
110
- })({
111
- with: { children, properties, includeProductSorting },
112
- includeHidden
113
- });
114
- if (!hideEmptyCategories) {
115
- return categoryTree;
116
- }
117
- const campaignKey = await callRpc?.("getCampaignKey");
118
- const categoryProductCountTable = await cached(async () => {
119
- const productCount = await sapiClient.filters.getValues("categoryids", {
120
- campaignKey
130
+ const campaignKey = await callRpc?.("getCampaignKey");
131
+ const categoryProductCountTable = await cached(
132
+ async () => {
133
+ const productCount = await sapiClient.filters.getValues(
134
+ "categoryids",
135
+ {
136
+ campaignKey
137
+ }
138
+ );
139
+ return Object.fromEntries(
140
+ productCount.map(({ id, productCount: productCount2 }) => [id, productCount2])
141
+ );
142
+ },
143
+ {
144
+ cacheKey: `category-product-count-table-${campaignKey || "no-campaign"}`,
145
+ ttl: 3600
146
+ // 1 hour
147
+ }
148
+ )();
149
+ const removeEmptyCategories = (category) => {
150
+ if (category.children) {
151
+ category.children = category.children.filter(
152
+ (child) => categoryProductCountTable[child.id] > 0
153
+ );
154
+ category.children.forEach((child) => {
155
+ removeEmptyCategories(child);
156
+ });
157
+ }
158
+ };
159
+ categoryTree.forEach((category) => {
160
+ removeEmptyCategories(category);
121
161
  });
122
- return Object.fromEntries(
123
- productCount.map(({ id, productCount: productCount2 }) => [id, productCount2])
162
+ return categoryTree.filter(
163
+ (category) => categoryProductCountTable[category.id] > 0
124
164
  );
125
- }, {
126
- cacheKey: `category-product-count-table-${campaignKey || "no-campaign"}`,
127
- ttl: 3600
128
- // 1 hour
129
- })();
130
- const removeEmptyCategories = (category) => {
131
- if (category.children) {
132
- category.children = category.children.filter(
133
- (child) => categoryProductCountTable[child.id] > 0
134
- );
135
- category.children.forEach((child) => {
136
- removeEmptyCategories(child);
137
- });
138
- }
139
- };
140
- categoryTree.forEach((category) => {
141
- removeEmptyCategories(category);
142
- });
143
- return categoryTree.filter(
144
- (category) => categoryProductCountTable[category.id] > 0
145
- );
146
- }, { method: "GET" });
165
+ },
166
+ { method: "GET" }
167
+ );
@@ -2,56 +2,59 @@ import { HttpStatusCode, HttpStatusMessage } from "../../constants/index.mjs";
2
2
  import { ErrorResponse } from "../../errors/index.mjs";
3
3
  import { defineRpcHandler } from "../../utils/index.mjs";
4
4
  import { encodeBase64, verifyOrderSuccessToken } from "../../utils/hash.mjs";
5
- export const getOrderDataByCbd = defineRpcHandler(async ({ cbdToken }, context) => {
6
- const payload = await verifyOrderSuccessToken(
7
- cbdToken,
8
- context.checkout.secret
9
- );
10
- if (!payload) {
11
- context.log.warn(
12
- "Unable to verify CBD token. Please check that you configured the correct Checkout Secret"
5
+ export const getOrderDataByCbd = defineRpcHandler(
6
+ async ({ cbdToken }, context) => {
7
+ const payload = await verifyOrderSuccessToken(
8
+ cbdToken,
9
+ context.checkout.secret
13
10
  );
14
- return new ErrorResponse(
15
- HttpStatusCode.BAD_REQUEST,
16
- HttpStatusMessage.BAD_REQUEST,
17
- "Unable to verify CBD token."
18
- );
19
- }
20
- if (context.checkout.cbdExpiration && Math.floor(Date.now() / 1e3) - payload.issued_at > context.checkout.cbdExpiration) {
21
- context.log.warn("Attempting to use expired CBD token");
22
- return new ErrorResponse(
23
- HttpStatusCode.BAD_REQUEST,
24
- HttpStatusMessage.BAD_REQUEST,
25
- "The CBD token has expired."
11
+ if (!payload) {
12
+ context.log.warn(
13
+ "Unable to verify CBD token. Please check that you configured the correct Checkout Secret"
14
+ );
15
+ return new ErrorResponse(
16
+ HttpStatusCode.BAD_REQUEST,
17
+ HttpStatusMessage.BAD_REQUEST,
18
+ "Unable to verify CBD token."
19
+ );
20
+ }
21
+ if (context.checkout.cbdExpiration && Math.floor(Date.now() / 1e3) - payload.issued_at > context.checkout.cbdExpiration) {
22
+ context.log.warn("Attempting to use expired CBD token");
23
+ return new ErrorResponse(
24
+ HttpStatusCode.BAD_REQUEST,
25
+ HttpStatusMessage.BAD_REQUEST,
26
+ "The CBD token has expired."
27
+ );
28
+ }
29
+ const checkoutUrl = context.checkout.url;
30
+ const basicAuth = encodeBase64(
31
+ `${context.checkout.user}:${context.checkout.token}`
26
32
  );
27
- }
28
- const checkoutUrl = context.checkout.url;
29
- const basicAuth = encodeBase64(
30
- `${context.checkout.user}:${context.checkout.token}`
31
- );
32
- const response = await fetch(
33
- `${checkoutUrl}/api/v1/orders/${payload.order_id}`,
34
- {
35
- headers: {
36
- Accept: "application/json",
37
- Authorization: `Basic ${basicAuth}`,
38
- "X-Shop-Id": context.shopId.toString(),
39
- ...context.internalAccessHeader ? { "x-internal-access": context.internalAccessHeader } : {}
33
+ const response = await fetch(
34
+ `${checkoutUrl}/api/v1/orders/${payload.order_id}`,
35
+ {
36
+ headers: {
37
+ Accept: "application/json",
38
+ Authorization: `Basic ${basicAuth}`,
39
+ "X-Shop-Id": context.shopId.toString(),
40
+ ...context.internalAccessHeader ? { "x-internal-access": context.internalAccessHeader } : {}
41
+ }
40
42
  }
43
+ );
44
+ if (response.ok) {
45
+ return await response.json();
41
46
  }
42
- );
43
- if (response.ok) {
44
- return await response.json();
45
- }
46
- context.log.error(
47
- `Unexpected status code when fetching order from Checkout API: ${response.status}`
48
- );
49
- return new ErrorResponse(
50
- HttpStatusCode.INTERNAL_SERVER_ERROR,
51
- HttpStatusMessage.INTERNAL_SERVER_ERROR,
52
- "Unknown error",
53
- {
54
- detail: `Fetching order failed with status code ${response.status}`
55
- }
56
- );
57
- }, { method: "POST" });
47
+ context.log.error(
48
+ `Unexpected status code when fetching order from Checkout API: ${response.status}`
49
+ );
50
+ return new ErrorResponse(
51
+ HttpStatusCode.INTERNAL_SERVER_ERROR,
52
+ HttpStatusMessage.INTERNAL_SERVER_ERROR,
53
+ "Unknown error",
54
+ {
55
+ detail: `Fetching order failed with status code ${response.status}`
56
+ }
57
+ );
58
+ },
59
+ { method: "POST" }
60
+ );
@@ -5,44 +5,47 @@ import { HttpStatusCode, HttpStatusMessage } from "../../../constants/index.mjs"
5
5
  import { getAccessToken } from "../user.mjs";
6
6
  import { defineRpcHandler } from "../../../utils/rpc.mjs";
7
7
  const ACCESS_TOKEN_REFRESH_THRESHOLD_IN_MILLISECONDS = 30 * 60 * 1e3;
8
- export const getCheckoutToken = defineRpcHandler(async (jwtPayload = {}, context) => {
9
- if (!hasSession(context)) {
10
- return new ErrorResponse(
11
- HttpStatusCode.BAD_REQUEST,
12
- HttpStatusMessage.BAD_REQUEST,
13
- "No Session found"
14
- );
15
- }
16
- let refreshedAccessToken;
17
- if (context.accessToken) {
18
- const accessTokenPayload = decodeJwt(context.accessToken);
19
- const shouldRefresh = !!accessTokenPayload.exp && accessTokenPayload.exp * 1e3 - Date.now() <= ACCESS_TOKEN_REFRESH_THRESHOLD_IN_MILLISECONDS;
20
- refreshedAccessToken = await getAccessToken(
21
- { forceTokenRefresh: shouldRefresh },
22
- context
23
- );
24
- if (refreshedAccessToken instanceof Response) {
25
- return refreshedAccessToken;
8
+ export const getCheckoutToken = defineRpcHandler(
9
+ async (jwtPayload = {}, context) => {
10
+ if (!hasSession(context)) {
11
+ return new ErrorResponse(
12
+ HttpStatusCode.BAD_REQUEST,
13
+ HttpStatusMessage.BAD_REQUEST,
14
+ "No Session found"
15
+ );
26
16
  }
27
- }
28
- const secret = new TextEncoder().encode(context.checkout.secret);
29
- const now = /* @__PURE__ */ new Date();
30
- const { voucher, customData, preferredCollectionPoint, carrier } = jwtPayload;
31
- const campaignKey = await context.callRpc?.("getCampaignKey");
32
- const orderCustomData = await context.callRpc?.("getOrderCustomData");
33
- const checkoutJwt = await new SignJWT({
34
- voucher,
35
- preferredCollectionPoint,
36
- carrier,
37
- basketId: context.basketKey,
38
- campaignKey,
39
- customData: {
40
- ...customData,
41
- ...orderCustomData
17
+ let refreshedAccessToken;
18
+ if (context.accessToken) {
19
+ const accessTokenPayload = decodeJwt(context.accessToken);
20
+ const shouldRefresh = !!accessTokenPayload.exp && accessTokenPayload.exp * 1e3 - Date.now() <= ACCESS_TOKEN_REFRESH_THRESHOLD_IN_MILLISECONDS;
21
+ refreshedAccessToken = await getAccessToken(
22
+ { forceTokenRefresh: shouldRefresh },
23
+ context
24
+ );
25
+ if (refreshedAccessToken instanceof Response) {
26
+ return refreshedAccessToken;
27
+ }
42
28
  }
43
- }).setIssuedAt(now).setNotBefore(now).setExpirationTime("1h").setIssuer(`${"@scayle/storefront-core"}@${"8.61.0"}`).setProtectedHeader({ alg: "HS256", typ: "JWT" }).sign(secret);
44
- return {
45
- accessToken: refreshedAccessToken,
46
- checkoutJwt
47
- };
48
- }, { method: "POST" });
29
+ const secret = new TextEncoder().encode(context.checkout.secret);
30
+ const now = /* @__PURE__ */ new Date();
31
+ const { voucher, customData, preferredCollectionPoint, carrier } = jwtPayload;
32
+ const campaignKey = await context.callRpc?.("getCampaignKey");
33
+ const orderCustomData = await context.callRpc?.("getOrderCustomData");
34
+ const checkoutJwt = await new SignJWT({
35
+ voucher,
36
+ preferredCollectionPoint,
37
+ carrier,
38
+ basketId: context.basketKey,
39
+ campaignKey,
40
+ customData: {
41
+ ...customData,
42
+ ...orderCustomData
43
+ }
44
+ }).setIssuedAt(now).setNotBefore(now).setExpirationTime("1h").setIssuer(`${"@scayle/storefront-core"}@${"8.61.2"}`).setProtectedHeader({ alg: "HS256", typ: "JWT" }).sign(secret);
45
+ return {
46
+ accessToken: refreshedAccessToken,
47
+ checkoutJwt
48
+ };
49
+ },
50
+ { method: "POST" }
51
+ );