@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
@@ -57,278 +57,307 @@ export async function postLogin(context, tokens) {
57
57
  )
58
58
  ]);
59
59
  await context.createUserBoundSession();
60
- await context.callHook?.("storefront:afterLogin", {
61
- shopId: context.shopId,
62
- user,
63
- authenticationType: user.authentication?.type,
64
- accessToken: tokens.access_token
65
- }, context);
60
+ await context.callHook?.(
61
+ "storefront:afterLogin",
62
+ {
63
+ shopId: context.shopId,
64
+ user,
65
+ authenticationType: user.authentication?.type,
66
+ accessToken: tokens.access_token
67
+ },
68
+ context
69
+ );
66
70
  }
67
- export const oauthLogin = defineRpcHandler(async (login, context) => {
68
- if (!hasSession(context)) {
69
- return new ErrorResponse(
70
- HttpStatusCode.BAD_REQUEST,
71
- HttpStatusMessage.BAD_REQUEST,
72
- "No Session found"
73
- );
74
- }
75
- const shopId = context.shopId;
76
- const client = getOAuthClient(context);
77
- if (!login.email || !login.password) {
78
- return new ErrorResponse(
79
- HttpStatusCode.BAD_REQUEST,
80
- HttpStatusMessage.BAD_REQUEST,
81
- "Login or password are missing"
82
- );
83
- }
84
- try {
85
- const tokens = await client.login({ ...login, shop_id: shopId });
86
- const postLoginResponse = await postLogin(context, tokens);
87
- if (postLoginResponse instanceof ErrorResponse) {
88
- return postLoginResponse;
89
- }
90
- return new Response(null, { status: HttpStatusCode.NO_CONTENT });
91
- } catch (error) {
92
- context.log.error("OAuthClient.login failed", error);
93
- return convertErrorForRpcCall(error, [
94
- HttpStatusCode.BAD_REQUEST,
95
- HttpStatusCode.NOT_FOUND
96
- ]) ?? new ErrorResponse(
97
- HttpStatusCode.INTERNAL_SERVER_ERROR,
98
- HttpStatusMessage.INTERNAL_SERVER_ERROR,
99
- "Login failed"
100
- );
101
- }
102
- }, { method: "POST" });
103
- export const oauthRegister = defineRpcHandler(async (register, context) => {
104
- if (!hasSession(context)) {
105
- return new ErrorResponse(
106
- HttpStatusCode.BAD_REQUEST,
107
- HttpStatusMessage.BAD_REQUEST,
108
- "No Session found"
109
- );
110
- }
111
- const shopId = context.shopId;
112
- const client = getOAuthClient(context);
113
- try {
114
- const tokens = await client.register({
115
- ...register,
116
- shop_id: shopId
117
- });
118
- const postLoginResponse = await postLogin(context, tokens);
119
- if (postLoginResponse instanceof ErrorResponse) {
120
- return postLoginResponse;
121
- }
122
- return new Response(null, { status: HttpStatusCode.NO_CONTENT });
123
- } catch (error) {
124
- context.log.error("OAuthClient.register failed", error);
125
- return convertErrorForRpcCall(error, [
126
- HttpStatusCode.BAD_REQUEST,
127
- HttpStatusCode.CONFLICT,
128
- HttpStatusCode.UNPROCESSABLE_CONTENT
129
- ]) ?? new ErrorResponse(
130
- HttpStatusCode.INTERNAL_SERVER_ERROR,
131
- HttpStatusMessage.INTERNAL_SERVER_ERROR,
132
- "Register failed"
133
- );
134
- }
135
- }, { method: "POST" });
136
- export const oauthGuestLogin = defineRpcHandler(async (guest, context) => {
137
- if (!hasSession(context)) {
138
- return new ErrorResponse(
139
- HttpStatusCode.BAD_REQUEST,
140
- HttpStatusMessage.BAD_REQUEST,
141
- "No Session found"
142
- );
143
- }
144
- const shopId = context.shopId;
145
- const client = getOAuthClient(context);
146
- try {
147
- const tokens = await client.guestLogin({
148
- ...guest,
149
- shop_id: shopId
150
- });
151
- const postLoginResponse = await postLogin(context, tokens);
152
- if (postLoginResponse instanceof ErrorResponse) {
153
- return postLoginResponse;
71
+ export const oauthLogin = defineRpcHandler(
72
+ async (login, context) => {
73
+ if (!hasSession(context)) {
74
+ return new ErrorResponse(
75
+ HttpStatusCode.BAD_REQUEST,
76
+ HttpStatusMessage.BAD_REQUEST,
77
+ "No Session found"
78
+ );
154
79
  }
155
- return new Response(null, { status: HttpStatusCode.NO_CONTENT });
156
- } catch (error) {
157
- context.log.error("OAuthClient.guestLogin failed", error);
158
- return convertErrorForRpcCall(error, [
159
- HttpStatusCode.BAD_REQUEST,
160
- HttpStatusCode.CONFLICT
161
- ]) ?? new ErrorResponse(
162
- HttpStatusCode.INTERNAL_SERVER_ERROR,
163
- HttpStatusMessage.INTERNAL_SERVER_ERROR,
164
- "Guest login failed"
165
- );
166
- }
167
- }, { method: "POST" });
168
- export const refreshAccessToken = defineRpcHandler(async (context) => {
169
- if (!hasSession(context)) {
170
- return new ErrorResponse(
171
- HttpStatusCode.BAD_REQUEST,
172
- HttpStatusMessage.BAD_REQUEST,
173
- "No Session found"
174
- );
175
- }
176
- const refreshToken = context.refreshToken;
177
- const client = getOAuthClient(context);
178
- if (!refreshToken) {
179
- return new ErrorResponse(
180
- HttpStatusCode.BAD_REQUEST,
181
- HttpStatusMessage.BAD_REQUEST,
182
- "No refresh token present"
183
- );
184
- }
185
- try {
186
- const tokens = await client.refreshToken({
187
- grant_type: "refresh_token",
188
- refresh_token: refreshToken
189
- });
190
- context.updateTokens({
191
- accessToken: tokens?.access_token,
192
- refreshToken: tokens?.refresh_token
193
- });
194
- return { success: !!tokens };
195
- } catch (error) {
196
- const response = convertErrorForRpcCall(error, [
197
- HttpStatusCode.BAD_REQUEST,
198
- HttpStatusCode.UNAUTHORIZED
199
- ]);
200
- if (response && response.status === HttpStatusCode.UNAUTHORIZED) {
201
- context.log.debug(
202
- "Failed to refresh Checkout Token due to invalid refresh token. Deleting session"
80
+ const shopId = context.shopId;
81
+ const client = getOAuthClient(context);
82
+ if (!login.email || !login.password) {
83
+ return new ErrorResponse(
84
+ HttpStatusCode.BAD_REQUEST,
85
+ HttpStatusMessage.BAD_REQUEST,
86
+ "Login or password are missing"
203
87
  );
204
- await context.destroySession();
205
- } else {
206
- context.log.debug(
207
- "Failed to refresh Checkout Token for unknown reason."
88
+ }
89
+ try {
90
+ const tokens = await client.login({ ...login, shop_id: shopId });
91
+ const postLoginResponse = await postLogin(context, tokens);
92
+ if (postLoginResponse instanceof ErrorResponse) {
93
+ return postLoginResponse;
94
+ }
95
+ return new Response(null, { status: HttpStatusCode.NO_CONTENT });
96
+ } catch (error) {
97
+ context.log.error("OAuthClient.login failed", error);
98
+ return convertErrorForRpcCall(error, [
99
+ HttpStatusCode.BAD_REQUEST,
100
+ HttpStatusCode.NOT_FOUND
101
+ ]) ?? new ErrorResponse(
102
+ HttpStatusCode.INTERNAL_SERVER_ERROR,
103
+ HttpStatusMessage.INTERNAL_SERVER_ERROR,
104
+ "Login failed"
208
105
  );
209
106
  }
210
- if (response) {
211
- return response;
107
+ },
108
+ { method: "POST" }
109
+ );
110
+ export const oauthRegister = defineRpcHandler(
111
+ async (register, context) => {
112
+ if (!hasSession(context)) {
113
+ return new ErrorResponse(
114
+ HttpStatusCode.BAD_REQUEST,
115
+ HttpStatusMessage.BAD_REQUEST,
116
+ "No Session found"
117
+ );
212
118
  }
213
- return { success: false };
214
- }
215
- }, { method: "POST" });
216
- export const oauthRevokeToken = defineRpcHandler(async (context) => {
217
- if (!hasSession(context)) {
218
- return new ErrorResponse(
219
- HttpStatusCode.BAD_REQUEST,
220
- HttpStatusMessage.BAD_REQUEST,
221
- "No Session found"
222
- );
223
- }
224
- const accessToken = context.accessToken;
225
- if (!accessToken) {
226
- return new ErrorResponse(
227
- HttpStatusCode.UNAUTHORIZED,
228
- HttpStatusMessage.UNAUTHORIZED,
229
- "No access token present"
230
- );
231
- }
232
- const user = context.user;
233
- const client = getOAuthClient(context);
234
- await context.destroySession();
235
- try {
236
- await client.revokeToken(context.shopId, accessToken);
237
- await context.callHook?.("storefront:afterLogout", {
238
- shopId: context.shopId,
239
- user,
240
- authenticationType: user.authentication?.type
241
- }, context);
242
- return { result: true };
243
- } catch (error) {
244
- const response = convertErrorForRpcCall(error, [
245
- HttpStatusCode.BAD_REQUEST,
246
- HttpStatusCode.UNAUTHORIZED,
247
- HttpStatusCode.NOT_FOUND
248
- ]);
249
- if (response) {
250
- return response;
119
+ const shopId = context.shopId;
120
+ const client = getOAuthClient(context);
121
+ try {
122
+ const tokens = await client.register({
123
+ ...register,
124
+ shop_id: shopId
125
+ });
126
+ const postLoginResponse = await postLogin(context, tokens);
127
+ if (postLoginResponse instanceof ErrorResponse) {
128
+ return postLoginResponse;
129
+ }
130
+ return new Response(null, { status: HttpStatusCode.NO_CONTENT });
131
+ } catch (error) {
132
+ context.log.error("OAuthClient.register failed", error);
133
+ return convertErrorForRpcCall(error, [
134
+ HttpStatusCode.BAD_REQUEST,
135
+ HttpStatusCode.CONFLICT,
136
+ HttpStatusCode.UNPROCESSABLE_CONTENT
137
+ ]) ?? new ErrorResponse(
138
+ HttpStatusCode.INTERNAL_SERVER_ERROR,
139
+ HttpStatusMessage.INTERNAL_SERVER_ERROR,
140
+ "Register failed"
141
+ );
251
142
  }
252
- return { result: false };
253
- }
254
- }, { method: "POST" });
255
- export const oauthForgetPassword = defineRpcHandler(async ({ email }, context) => {
256
- if (!hasSession(context)) {
257
- return new ErrorResponse(
258
- HttpStatusCode.BAD_REQUEST,
259
- HttpStatusMessage.BAD_REQUEST,
260
- "No Session found"
261
- );
262
- }
263
- const shopId = context.shopId;
264
- const client = getOAuthClient(context);
265
- try {
266
- if (!context.auth.resetPasswordUrl) {
143
+ },
144
+ { method: "POST" }
145
+ );
146
+ export const oauthGuestLogin = defineRpcHandler(
147
+ async (guest, context) => {
148
+ if (!hasSession(context)) {
267
149
  return new ErrorResponse(
150
+ HttpStatusCode.BAD_REQUEST,
151
+ HttpStatusMessage.BAD_REQUEST,
152
+ "No Session found"
153
+ );
154
+ }
155
+ const shopId = context.shopId;
156
+ const client = getOAuthClient(context);
157
+ try {
158
+ const tokens = await client.guestLogin({
159
+ ...guest,
160
+ shop_id: shopId
161
+ });
162
+ const postLoginResponse = await postLogin(context, tokens);
163
+ if (postLoginResponse instanceof ErrorResponse) {
164
+ return postLoginResponse;
165
+ }
166
+ return new Response(null, { status: HttpStatusCode.NO_CONTENT });
167
+ } catch (error) {
168
+ context.log.error("OAuthClient.guestLogin failed", error);
169
+ return convertErrorForRpcCall(error, [
170
+ HttpStatusCode.BAD_REQUEST,
171
+ HttpStatusCode.CONFLICT
172
+ ]) ?? new ErrorResponse(
268
173
  HttpStatusCode.INTERNAL_SERVER_ERROR,
269
174
  HttpStatusMessage.INTERNAL_SERVER_ERROR,
270
- "Missing password reset URL"
175
+ "Guest login failed"
271
176
  );
272
177
  }
273
- const resetUrl = new URL(context.auth.resetPasswordUrl);
274
- if (!resetUrl.searchParams.has("hash")) {
275
- resetUrl.searchParams.append("hash", "{hash}");
276
- } else {
277
- resetUrl.searchParams.set("hash", "{hash}");
178
+ },
179
+ { method: "POST" }
180
+ );
181
+ export const refreshAccessToken = defineRpcHandler(
182
+ async (context) => {
183
+ if (!hasSession(context)) {
184
+ return new ErrorResponse(
185
+ HttpStatusCode.BAD_REQUEST,
186
+ HttpStatusMessage.BAD_REQUEST,
187
+ "No Session found"
188
+ );
278
189
  }
279
- await client.sendPasswordResetEmail({
280
- email,
281
- reset_url: decodeURI(resetUrl.toString()),
282
- shop_id: shopId
283
- });
284
- return { success: true };
285
- } catch (error) {
286
- const response = convertErrorForRpcCall(error, [
287
- HttpStatusCode.BAD_REQUEST,
288
- HttpStatusCode.NOT_FOUND,
289
- HttpStatusCode.UNAUTHORIZED,
290
- HttpStatusCode.FORBIDDEN
291
- ]);
292
- if (response) {
293
- return response;
190
+ const refreshToken = context.refreshToken;
191
+ const client = getOAuthClient(context);
192
+ if (!refreshToken) {
193
+ return new ErrorResponse(
194
+ HttpStatusCode.BAD_REQUEST,
195
+ HttpStatusMessage.BAD_REQUEST,
196
+ "No refresh token present"
197
+ );
294
198
  }
295
- return { success: false };
296
- }
297
- }, { method: "POST" });
298
- export const updatePasswordByHash = defineRpcHandler(async (passwordHash, context) => {
299
- if (!hasSession(context)) {
300
- return new ErrorResponse(
301
- HttpStatusCode.BAD_REQUEST,
302
- HttpStatusMessage.BAD_REQUEST,
303
- "No Session found"
304
- );
305
- }
306
- const shopId = context.shopId;
307
- const client = getOAuthClient(context);
308
- try {
309
- const tokens = await client.updatePasswordByHash({
310
- ...passwordHash,
311
- shop_id: shopId
312
- });
313
- context.updateTokens({
314
- accessToken: tokens.access_token,
315
- refreshToken: tokens.refresh_token
316
- });
317
- await context.createUserBoundSession();
318
- } catch (error) {
319
- const response = convertErrorForRpcCall(error, [
320
- HttpStatusCode.BAD_REQUEST,
321
- HttpStatusCode.UNAUTHORIZED,
322
- HttpStatusCode.NOT_ACCEPTABLE
323
- ]);
324
- if (response) {
325
- return response;
199
+ try {
200
+ const tokens = await client.refreshToken({
201
+ grant_type: "refresh_token",
202
+ refresh_token: refreshToken
203
+ });
204
+ context.updateTokens({
205
+ accessToken: tokens?.access_token,
206
+ refreshToken: tokens?.refresh_token
207
+ });
208
+ return { success: !!tokens };
209
+ } catch (error) {
210
+ const response = convertErrorForRpcCall(error, [
211
+ HttpStatusCode.BAD_REQUEST,
212
+ HttpStatusCode.UNAUTHORIZED
213
+ ]);
214
+ if (response && response.status === HttpStatusCode.UNAUTHORIZED) {
215
+ context.log.debug(
216
+ "Failed to refresh Checkout Token due to invalid refresh token. Deleting session"
217
+ );
218
+ await context.destroySession();
219
+ } else {
220
+ context.log.debug(
221
+ "Failed to refresh Checkout Token for unknown reason."
222
+ );
223
+ }
224
+ if (response) {
225
+ return response;
226
+ }
227
+ return { success: false };
326
228
  }
327
- return new ErrorResponse(
328
- HttpStatusCode.INTERNAL_SERVER_ERROR,
329
- HttpStatusMessage.INTERNAL_SERVER_ERROR,
330
- "Error during update password by hash"
331
- );
332
- }
333
- return new Response(null, { status: HttpStatusCode.NO_CONTENT });
334
- }, { method: "POST" });
229
+ },
230
+ { method: "POST" }
231
+ );
232
+ export const oauthRevokeToken = defineRpcHandler(
233
+ async (context) => {
234
+ if (!hasSession(context)) {
235
+ return new ErrorResponse(
236
+ HttpStatusCode.BAD_REQUEST,
237
+ HttpStatusMessage.BAD_REQUEST,
238
+ "No Session found"
239
+ );
240
+ }
241
+ const accessToken = context.accessToken;
242
+ if (!accessToken) {
243
+ return new ErrorResponse(
244
+ HttpStatusCode.UNAUTHORIZED,
245
+ HttpStatusMessage.UNAUTHORIZED,
246
+ "No access token present"
247
+ );
248
+ }
249
+ const user = context.user;
250
+ const client = getOAuthClient(context);
251
+ await context.destroySession();
252
+ try {
253
+ await client.revokeToken(context.shopId, accessToken);
254
+ await context.callHook?.(
255
+ "storefront:afterLogout",
256
+ {
257
+ shopId: context.shopId,
258
+ user,
259
+ authenticationType: user.authentication?.type
260
+ },
261
+ context
262
+ );
263
+ return { result: true };
264
+ } catch (error) {
265
+ const response = convertErrorForRpcCall(error, [
266
+ HttpStatusCode.BAD_REQUEST,
267
+ HttpStatusCode.UNAUTHORIZED,
268
+ HttpStatusCode.NOT_FOUND
269
+ ]);
270
+ if (response) {
271
+ return response;
272
+ }
273
+ return { result: false };
274
+ }
275
+ },
276
+ { method: "POST" }
277
+ );
278
+ export const oauthForgetPassword = defineRpcHandler(
279
+ async ({ email }, context) => {
280
+ if (!hasSession(context)) {
281
+ return new ErrorResponse(
282
+ HttpStatusCode.BAD_REQUEST,
283
+ HttpStatusMessage.BAD_REQUEST,
284
+ "No Session found"
285
+ );
286
+ }
287
+ const shopId = context.shopId;
288
+ const client = getOAuthClient(context);
289
+ try {
290
+ if (!context.auth.resetPasswordUrl) {
291
+ return new ErrorResponse(
292
+ HttpStatusCode.INTERNAL_SERVER_ERROR,
293
+ HttpStatusMessage.INTERNAL_SERVER_ERROR,
294
+ "Missing password reset URL"
295
+ );
296
+ }
297
+ const resetUrl = new URL(context.auth.resetPasswordUrl);
298
+ if (!resetUrl.searchParams.has("hash")) {
299
+ resetUrl.searchParams.append("hash", "{hash}");
300
+ } else {
301
+ resetUrl.searchParams.set("hash", "{hash}");
302
+ }
303
+ await client.sendPasswordResetEmail({
304
+ email,
305
+ reset_url: decodeURI(resetUrl.toString()),
306
+ shop_id: shopId
307
+ });
308
+ return { success: true };
309
+ } catch (error) {
310
+ const response = convertErrorForRpcCall(error, [
311
+ HttpStatusCode.BAD_REQUEST,
312
+ HttpStatusCode.NOT_FOUND,
313
+ HttpStatusCode.UNAUTHORIZED,
314
+ HttpStatusCode.FORBIDDEN
315
+ ]);
316
+ if (response) {
317
+ return response;
318
+ }
319
+ return { success: false };
320
+ }
321
+ },
322
+ { method: "POST" }
323
+ );
324
+ export const updatePasswordByHash = defineRpcHandler(
325
+ async (passwordHash, context) => {
326
+ if (!hasSession(context)) {
327
+ return new ErrorResponse(
328
+ HttpStatusCode.BAD_REQUEST,
329
+ HttpStatusMessage.BAD_REQUEST,
330
+ "No Session found"
331
+ );
332
+ }
333
+ const shopId = context.shopId;
334
+ const client = getOAuthClient(context);
335
+ try {
336
+ const tokens = await client.updatePasswordByHash({
337
+ ...passwordHash,
338
+ shop_id: shopId
339
+ });
340
+ context.updateTokens({
341
+ accessToken: tokens.access_token,
342
+ refreshToken: tokens.refresh_token
343
+ });
344
+ await context.createUserBoundSession();
345
+ } catch (error) {
346
+ const response = convertErrorForRpcCall(error, [
347
+ HttpStatusCode.BAD_REQUEST,
348
+ HttpStatusCode.UNAUTHORIZED,
349
+ HttpStatusCode.NOT_ACCEPTABLE
350
+ ]);
351
+ if (response) {
352
+ return response;
353
+ }
354
+ return new ErrorResponse(
355
+ HttpStatusCode.INTERNAL_SERVER_ERROR,
356
+ HttpStatusMessage.INTERNAL_SERVER_ERROR,
357
+ "Error during update password by hash"
358
+ );
359
+ }
360
+ return new Response(null, { status: HttpStatusCode.NO_CONTENT });
361
+ },
362
+ { method: "POST" }
363
+ );
@@ -1,12 +1,15 @@
1
1
  import { mapSAPIFetchErrorToResponse } from "../../utils/sapi.mjs";
2
2
  import { defineRpcHandler } from "../../utils/index.mjs";
3
- const getShopConfiguration = defineRpcHandler(async (context) => {
4
- const { cached, sapiClient } = context;
5
- return await cached(
6
- mapSAPIFetchErrorToResponse(sapiClient.shopConfiguration.get),
7
- {
8
- cacheKeyPrefix: "get-shopConfigurations"
9
- }
10
- )();
11
- }, { method: "GET" });
3
+ const getShopConfiguration = defineRpcHandler(
4
+ async (context) => {
5
+ const { cached, sapiClient } = context;
6
+ return await cached(
7
+ mapSAPIFetchErrorToResponse(sapiClient.shopConfiguration.get),
8
+ {
9
+ cacheKeyPrefix: "get-shopConfigurations"
10
+ }
11
+ )();
12
+ },
13
+ { method: "GET" }
14
+ );
12
15
  export { getShopConfiguration };