@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.
- package/CHANGELOG-V7.md +1 -11
- package/CHANGELOG.md +96 -103
- package/dist/api/customer.mjs +1 -3
- package/dist/api/oauth.mjs +9 -6
- package/dist/cache/providers/unstorage.mjs +1 -3
- package/dist/constants/withParameters.mjs +2 -16
- package/dist/helpers/attributeHelpers.mjs +3 -1
- package/dist/helpers/filterHelper.mjs +11 -8
- package/dist/helpers/productHelpers.mjs +1 -3
- package/dist/helpers/sanitizationHelpers.mjs +1 -4
- package/dist/helpers/sortingHelper.mjs +1 -3
- package/dist/rpc/methods/basket/basket.d.ts +2 -2
- package/dist/rpc/methods/basket/basket.mjs +334 -321
- package/dist/rpc/methods/brands.mjs +26 -20
- package/dist/rpc/methods/campaign.mjs +32 -23
- package/dist/rpc/methods/categories.mjs +156 -135
- package/dist/rpc/methods/cbd.mjs +52 -49
- package/dist/rpc/methods/checkout/checkout.mjs +42 -39
- package/dist/rpc/methods/checkout/order.mjs +46 -40
- package/dist/rpc/methods/checkout/shopUser.mjs +112 -106
- package/dist/rpc/methods/navigationTrees.mjs +50 -32
- package/dist/rpc/methods/oauth/idp.mjs +64 -55
- package/dist/rpc/methods/products.mjs +224 -212
- package/dist/rpc/methods/promotion.mjs +46 -31
- package/dist/rpc/methods/search.mjs +26 -20
- package/dist/rpc/methods/session.mjs +289 -260
- package/dist/rpc/methods/shopConfiguration.mjs +12 -9
- package/dist/rpc/methods/user.mjs +87 -78
- package/dist/rpc/methods/variants.mjs +17 -14
- package/dist/rpc/methods/wishlist.mjs +71 -62
- package/dist/utils/hash.mjs +2 -7
- package/dist/utils/sapi.mjs +10 -7
- package/package.json +1 -1
|
@@ -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(
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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(
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
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(
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
{
|
|
23
|
-
|
|
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
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
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
|
|
123
|
-
|
|
162
|
+
return categoryTree.filter(
|
|
163
|
+
(category) => categoryProductCountTable[category.id] > 0
|
|
124
164
|
);
|
|
125
|
-
},
|
|
126
|
-
|
|
127
|
-
|
|
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
|
+
);
|
package/dist/rpc/methods/cbd.mjs
CHANGED
|
@@ -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(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"
|
|
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
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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(
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
+
);
|