@akinon/next 1.92.0 → 1.93.0-rc.46
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 +1166 -28
- package/__tests__/next-config.test.ts +1 -10
- package/__tests__/redirect.test.ts +758 -0
- package/api/image-proxy.ts +75 -0
- package/api/similar-product-list.ts +84 -0
- package/api/similar-products.ts +120 -0
- package/bin/pz-prebuild.js +0 -1
- package/components/accordion.tsx +20 -5
- package/components/file-input.tsx +65 -3
- package/components/input.tsx +2 -0
- package/components/link.tsx +16 -12
- package/components/modal.tsx +32 -16
- package/components/plugin-module.tsx +35 -3
- package/components/selected-payment-option-view.tsx +11 -0
- package/data/client/checkout.ts +25 -4
- package/data/server/basket.ts +72 -0
- package/data/server/category.ts +48 -28
- package/data/server/flatpage.ts +16 -12
- package/data/server/landingpage.ts +16 -12
- package/data/server/list.ts +23 -13
- package/data/server/product.ts +66 -39
- package/data/server/special-page.ts +16 -12
- package/data/urls.ts +7 -2
- package/hocs/server/with-segment-defaults.tsx +5 -2
- package/hooks/use-localization.ts +2 -3
- package/hooks/use-loyalty-availability.ts +21 -0
- package/instrumentation/node.ts +15 -13
- package/jest.config.js +7 -1
- package/lib/cache-handler.mjs +225 -16
- package/lib/cache.ts +2 -0
- package/middlewares/checkout-provider.ts +1 -1
- package/middlewares/complete-gpay.ts +6 -2
- package/middlewares/complete-masterpass.ts +7 -2
- package/middlewares/default.ts +232 -183
- package/middlewares/index.ts +3 -1
- package/middlewares/locale.ts +9 -1
- package/middlewares/redirection-payment.ts +6 -2
- package/middlewares/saved-card-redirection.ts +7 -2
- package/middlewares/three-d-redirection.ts +7 -2
- package/middlewares/url-redirection.ts +9 -15
- package/middlewares/wallet-complete-redirection.ts +203 -0
- package/package.json +3 -3
- package/plugins.d.ts +10 -0
- package/plugins.js +4 -1
- package/redux/middlewares/checkout.ts +15 -2
- package/redux/reducers/checkout.ts +9 -1
- package/sentry/index.ts +54 -17
- package/types/commerce/order.ts +1 -0
- package/types/index.ts +42 -1
- package/utils/app-fetch.ts +7 -2
- package/utils/index.ts +34 -10
- package/utils/redirect-ignore.ts +35 -0
- package/utils/redirect.ts +31 -6
- package/with-pz-config.js +1 -5
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { Cache, CacheKey } from '../../lib/cache';
|
|
2
|
+
import { basket } from '../../data/urls';
|
|
3
|
+
import { Basket } from '../../types';
|
|
4
|
+
import appFetch from '../../utils/app-fetch';
|
|
5
|
+
import { ServerVariables } from '../../utils/server-variables';
|
|
6
|
+
import logger from '../../utils/log';
|
|
7
|
+
|
|
8
|
+
type GetBasketParams = {
|
|
9
|
+
locale?: string;
|
|
10
|
+
currency?: string;
|
|
11
|
+
namespace?: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const getBasketDataHandler = ({
|
|
15
|
+
locale,
|
|
16
|
+
currency,
|
|
17
|
+
namespace
|
|
18
|
+
}: GetBasketParams) => {
|
|
19
|
+
return async function () {
|
|
20
|
+
try {
|
|
21
|
+
const url = namespace
|
|
22
|
+
? basket.getBasketDetail(namespace)
|
|
23
|
+
: basket.getBasket;
|
|
24
|
+
|
|
25
|
+
const basketData = await appFetch<{ basket: Basket }>({
|
|
26
|
+
url,
|
|
27
|
+
locale,
|
|
28
|
+
currency,
|
|
29
|
+
init: {
|
|
30
|
+
headers: {
|
|
31
|
+
Accept: 'application/json',
|
|
32
|
+
'Content-Type': 'application/json'
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
if (!basketData?.basket) {
|
|
38
|
+
logger.warn('Basket data is undefined', {
|
|
39
|
+
handler: 'getBasketDataHandler',
|
|
40
|
+
namespace
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return basketData;
|
|
45
|
+
} catch (error) {
|
|
46
|
+
logger.error('Error fetching basket data', {
|
|
47
|
+
handler: 'getBasketDataHandler',
|
|
48
|
+
error,
|
|
49
|
+
namespace
|
|
50
|
+
});
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export const getBasketData = async ({
|
|
57
|
+
locale = ServerVariables.locale,
|
|
58
|
+
currency = ServerVariables.currency,
|
|
59
|
+
namespace
|
|
60
|
+
}: GetBasketParams = {}) => {
|
|
61
|
+
return Cache.wrap(
|
|
62
|
+
CacheKey.Basket(namespace),
|
|
63
|
+
locale,
|
|
64
|
+
getBasketDataHandler({ locale, currency, namespace }),
|
|
65
|
+
{
|
|
66
|
+
expire: 0,
|
|
67
|
+
cache: false
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
|
package/data/server/category.ts
CHANGED
|
@@ -5,7 +5,6 @@ import { category, product } from '../urls';
|
|
|
5
5
|
import { Cache, CacheKey } from '../../lib/cache';
|
|
6
6
|
import { parse } from 'lossless-json';
|
|
7
7
|
import logger from '../../utils/log';
|
|
8
|
-
import { headers as nHeaders } from 'next/headers';
|
|
9
8
|
import { ServerVariables } from '../../utils/server-variables';
|
|
10
9
|
|
|
11
10
|
function getCategoryDataHandler(
|
|
@@ -18,19 +17,30 @@ function getCategoryDataHandler(
|
|
|
18
17
|
return async function () {
|
|
19
18
|
const params = generateCommerceSearchParams(searchParams);
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
20
|
+
let rawData: string;
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
rawData = await appFetch<string>({
|
|
24
|
+
url: `${category.getCategoryByPk(pk)}${params ? params : ''}`,
|
|
25
|
+
locale,
|
|
26
|
+
currency,
|
|
27
|
+
init: {
|
|
28
|
+
headers: {
|
|
29
|
+
Accept: 'application/json',
|
|
30
|
+
'Content-Type': 'application/json',
|
|
31
|
+
...(headers ?? {})
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
responseType: FetchResponseType.TEXT
|
|
35
|
+
});
|
|
36
|
+
} catch (error) {
|
|
37
|
+
logger.error('Failed to fetch category data', {
|
|
38
|
+
handler: 'getCategoryDataHandler',
|
|
39
|
+
pk,
|
|
40
|
+
error: error.message
|
|
41
|
+
});
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
34
44
|
|
|
35
45
|
let data: GetCategoryResponse;
|
|
36
46
|
|
|
@@ -48,8 +58,8 @@ function getCategoryDataHandler(
|
|
|
48
58
|
logger.fatal('Error while parsing category data', {
|
|
49
59
|
handler: 'getCategoryDataHandler',
|
|
50
60
|
error,
|
|
51
|
-
rawData: rawData
|
|
52
|
-
? `${rawData
|
|
61
|
+
rawData: rawData?.startsWith?.('<!DOCTYPE html>')
|
|
62
|
+
? `${rawData?.substring(0, 50)}...`
|
|
53
63
|
: rawData
|
|
54
64
|
});
|
|
55
65
|
}
|
|
@@ -64,17 +74,27 @@ function getCategoryDataHandler(
|
|
|
64
74
|
return { data, breadcrumbData: undefined };
|
|
65
75
|
}
|
|
66
76
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
77
|
+
let breadcrumbData: { menu?: unknown } = {};
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
breadcrumbData = await appFetch<{ menu?: unknown }>({
|
|
81
|
+
url: product.breadcrumbUrl(menuItemModel),
|
|
82
|
+
locale,
|
|
83
|
+
currency,
|
|
84
|
+
init: {
|
|
85
|
+
headers: {
|
|
86
|
+
Accept: 'application/json',
|
|
87
|
+
'Content-Type': 'application/json'
|
|
88
|
+
}
|
|
75
89
|
}
|
|
76
|
-
}
|
|
77
|
-
})
|
|
90
|
+
});
|
|
91
|
+
} catch (error) {
|
|
92
|
+
logger.warn('Failed to fetch breadcrumb data', {
|
|
93
|
+
handler: 'getCategoryDataHandler',
|
|
94
|
+
pk,
|
|
95
|
+
error: error.message
|
|
96
|
+
});
|
|
97
|
+
}
|
|
78
98
|
|
|
79
99
|
return { data, breadcrumbData: breadcrumbData?.menu };
|
|
80
100
|
};
|
|
@@ -138,8 +158,8 @@ function getCategoryBySlugDataHandler(
|
|
|
138
158
|
logger.fatal('Error while parsing category data', {
|
|
139
159
|
handler: 'getCategoryBySlugDataHandler',
|
|
140
160
|
error,
|
|
141
|
-
rawData: rawData
|
|
142
|
-
? `${rawData
|
|
161
|
+
rawData: rawData?.startsWith?.('<!DOCTYPE html>')
|
|
162
|
+
? `${rawData?.substring(0, 50)}...`
|
|
143
163
|
: rawData
|
|
144
164
|
});
|
|
145
165
|
}
|
package/data/server/flatpage.ts
CHANGED
|
@@ -11,20 +11,24 @@ const getFlatPageDataHandler = (
|
|
|
11
11
|
headers?: Record<string, string>
|
|
12
12
|
) => {
|
|
13
13
|
return async function () {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
14
|
+
try {
|
|
15
|
+
const data = await appFetch<FlatPage>({
|
|
16
|
+
url: flatpage.getFlatPageByPk(pk),
|
|
17
|
+
locale,
|
|
18
|
+
currency,
|
|
19
|
+
init: {
|
|
20
|
+
headers: {
|
|
21
|
+
Accept: 'application/json',
|
|
22
|
+
'Content-Type': 'application/json',
|
|
23
|
+
...(headers ?? {})
|
|
24
|
+
}
|
|
23
25
|
}
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
+
});
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
return data;
|
|
29
|
+
} catch (error) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
28
32
|
};
|
|
29
33
|
};
|
|
30
34
|
|
|
@@ -11,20 +11,24 @@ const getLandingPageHandler = (
|
|
|
11
11
|
headers?: Record<string, string>
|
|
12
12
|
) => {
|
|
13
13
|
return async function () {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
14
|
+
try {
|
|
15
|
+
const data = await appFetch<LandingPage>({
|
|
16
|
+
url: landingpage.getLandingPageByPk(pk),
|
|
17
|
+
locale,
|
|
18
|
+
currency,
|
|
19
|
+
init: {
|
|
20
|
+
headers: {
|
|
21
|
+
Accept: 'application/json',
|
|
22
|
+
'Content-Type': 'application/json',
|
|
23
|
+
...(headers ?? {})
|
|
24
|
+
}
|
|
23
25
|
}
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
+
});
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
return data;
|
|
29
|
+
} catch (error) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
28
32
|
};
|
|
29
33
|
};
|
|
30
34
|
|
package/data/server/list.ts
CHANGED
|
@@ -16,19 +16,29 @@ const getListDataHandler = (
|
|
|
16
16
|
return async function () {
|
|
17
17
|
const params = generateCommerceSearchParams(searchParams);
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
19
|
+
let rawData: string;
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
rawData = await appFetch<string>({
|
|
23
|
+
url: `${category.list}${params}`,
|
|
24
|
+
locale,
|
|
25
|
+
currency,
|
|
26
|
+
init: {
|
|
27
|
+
headers: {
|
|
28
|
+
Accept: 'application/json',
|
|
29
|
+
'Content-Type': 'application/json',
|
|
30
|
+
...(headers ?? {})
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
responseType: FetchResponseType.TEXT
|
|
34
|
+
});
|
|
35
|
+
} catch (error) {
|
|
36
|
+
logger.error('Failed to fetch list data', {
|
|
37
|
+
handler: 'getListDataHandler',
|
|
38
|
+
error: error.message
|
|
39
|
+
});
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
32
42
|
|
|
33
43
|
let data: GetCategoryResponse;
|
|
34
44
|
|
package/data/server/product.ts
CHANGED
|
@@ -35,57 +35,84 @@ const getProductDataHandler = ({
|
|
|
35
35
|
.join('&');
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
38
|
+
let data: ProductResult;
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
data = await appFetch<ProductResult>({
|
|
42
|
+
url,
|
|
43
|
+
locale,
|
|
44
|
+
currency,
|
|
45
|
+
init: {
|
|
46
|
+
headers: {
|
|
47
|
+
Accept: 'application/json',
|
|
48
|
+
'Content-Type': 'application/json',
|
|
49
|
+
...(headers ?? {})
|
|
50
|
+
}
|
|
47
51
|
}
|
|
48
|
-
}
|
|
49
|
-
})
|
|
52
|
+
});
|
|
53
|
+
} catch (error) {
|
|
54
|
+
logger.error('Failed to fetch product data', {
|
|
55
|
+
handler: 'getProductDataHandler',
|
|
56
|
+
pk,
|
|
57
|
+
error: error.message,
|
|
58
|
+
url
|
|
59
|
+
});
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
50
62
|
|
|
51
63
|
const categoryUrl = product.categoryUrl(data.product.pk);
|
|
52
64
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
65
|
+
let productCategoryData: ProductCategoryResult;
|
|
66
|
+
let breadcrumbData: { menu?: unknown } = {};
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
productCategoryData = await appFetch<ProductCategoryResult>({
|
|
70
|
+
url: categoryUrl,
|
|
71
|
+
locale,
|
|
72
|
+
currency,
|
|
73
|
+
init: {
|
|
74
|
+
headers: {
|
|
75
|
+
Accept: 'application/json',
|
|
76
|
+
'Content-Type': 'application/json'
|
|
77
|
+
}
|
|
61
78
|
}
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const menuItemModel = productCategoryData?.results[0]?.menuitemmodel;
|
|
82
|
+
|
|
83
|
+
if (!menuItemModel) {
|
|
84
|
+
logger.warn(
|
|
85
|
+
'menuItemModel is undefined, skipping breadcrumbData fetch',
|
|
86
|
+
{
|
|
87
|
+
handler: 'getProductDataHandler',
|
|
88
|
+
pk
|
|
89
|
+
}
|
|
90
|
+
);
|
|
91
|
+
return { data, breadcrumbData: undefined };
|
|
62
92
|
}
|
|
63
|
-
});
|
|
64
93
|
|
|
65
|
-
|
|
94
|
+
const breadcrumbUrl = product.breadcrumbUrl(menuItemModel);
|
|
66
95
|
|
|
67
|
-
|
|
68
|
-
|
|
96
|
+
breadcrumbData = await appFetch<{ menu?: unknown }>({
|
|
97
|
+
url: breadcrumbUrl,
|
|
98
|
+
locale,
|
|
99
|
+
currency,
|
|
100
|
+
init: {
|
|
101
|
+
headers: {
|
|
102
|
+
Accept: 'application/json',
|
|
103
|
+
'Content-Type': 'application/json'
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
} catch (error) {
|
|
108
|
+
logger.warn('Failed to fetch breadcrumb data', {
|
|
69
109
|
handler: 'getProductDataHandler',
|
|
70
|
-
pk
|
|
110
|
+
pk,
|
|
111
|
+
error: error.message
|
|
71
112
|
});
|
|
72
|
-
|
|
113
|
+
// Continue without breadcrumb data
|
|
73
114
|
}
|
|
74
115
|
|
|
75
|
-
const breadcrumbUrl = product.breadcrumbUrl(menuItemModel);
|
|
76
|
-
|
|
77
|
-
const breadcrumbData = await appFetch<any>({
|
|
78
|
-
url: breadcrumbUrl,
|
|
79
|
-
locale,
|
|
80
|
-
currency,
|
|
81
|
-
init: {
|
|
82
|
-
headers: {
|
|
83
|
-
Accept: 'application/json',
|
|
84
|
-
'Content-Type': 'application/json'
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
|
|
89
116
|
return {
|
|
90
117
|
data,
|
|
91
118
|
breadcrumbData: breadcrumbData?.menu
|
|
@@ -15,20 +15,24 @@ const getSpecialPageDataHandler = (
|
|
|
15
15
|
return async function () {
|
|
16
16
|
const params = generateCommerceSearchParams(searchParams);
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
try {
|
|
19
|
+
const data: GetCategoryResponse = await appFetch({
|
|
20
|
+
url: `${category.getSpecialPageByPk(pk)}${params}`,
|
|
21
|
+
locale,
|
|
22
|
+
currency,
|
|
23
|
+
init: {
|
|
24
|
+
headers: {
|
|
25
|
+
Accept: 'application/json',
|
|
26
|
+
'Content-Type': 'application/json',
|
|
27
|
+
...(headers ?? {})
|
|
28
|
+
}
|
|
27
29
|
}
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
+
});
|
|
30
31
|
|
|
31
|
-
|
|
32
|
+
return data;
|
|
33
|
+
} catch (error) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
32
36
|
};
|
|
33
37
|
};
|
|
34
38
|
|
package/data/urls.ts
CHANGED
|
@@ -142,7 +142,8 @@ export const checkout = {
|
|
|
142
142
|
setOrderSelectionPage: '/orders/checkout/?page=OrderSelectionPage',
|
|
143
143
|
loyaltyCardPage: '/orders/checkout/?page=LoyaltyCardPage',
|
|
144
144
|
sendSmsPage: '/orders/checkout/?page=SendSmsPage',
|
|
145
|
-
verifySmsPage: '/orders/checkout/?page=VerifySmsPage'
|
|
145
|
+
verifySmsPage: '/orders/checkout/?page=VerifySmsPage',
|
|
146
|
+
saveSampleProducts: '/orders/checkout/?page=SampleProductPage'
|
|
146
147
|
};
|
|
147
148
|
|
|
148
149
|
export const flatpage = {
|
|
@@ -182,7 +183,11 @@ export const product = {
|
|
|
182
183
|
breadcrumbUrl: (menuitemmodel: string) =>
|
|
183
184
|
`/menus/generate_breadcrumb/?item=${menuitemmodel}&generator_name=menu_item`,
|
|
184
185
|
bundleProduct: (productPk: string, queryString: string) =>
|
|
185
|
-
`/bundle-product/${productPk}/?${queryString}
|
|
186
|
+
`/bundle-product/${productPk}/?${queryString}`,
|
|
187
|
+
similarProducts: (params?: string) =>
|
|
188
|
+
`/similar-products${params ? `?${params}` : ''}`,
|
|
189
|
+
similarProductsList: (params?: string) =>
|
|
190
|
+
`/similar-product-list${params ? `?${params}` : ''}`
|
|
186
191
|
};
|
|
187
192
|
|
|
188
193
|
export const wishlist = {
|
|
@@ -72,10 +72,13 @@ const addRootLayoutProps = async (componentProps: RootLayoutProps) => {
|
|
|
72
72
|
const checkRedisVariables = () => {
|
|
73
73
|
const requiredVariableValues = [
|
|
74
74
|
process.env.CACHE_HOST,
|
|
75
|
-
process.env.CACHE_PORT
|
|
76
|
-
process.env.CACHE_SECRET
|
|
75
|
+
process.env.CACHE_PORT
|
|
77
76
|
];
|
|
78
77
|
|
|
78
|
+
if (!settings.usePrettyUrlRoute) {
|
|
79
|
+
requiredVariableValues.push(process.env.CACHE_SECRET);
|
|
80
|
+
}
|
|
81
|
+
|
|
79
82
|
if (
|
|
80
83
|
!requiredVariableValues.every((v) => v) &&
|
|
81
84
|
process.env.NODE_ENV === 'production'
|
|
@@ -4,7 +4,6 @@ import { LocalizationContext } from '../localization/provider';
|
|
|
4
4
|
import { useContext } from 'react';
|
|
5
5
|
import { setCookie, urlLocaleMatcherRegex } from '../utils';
|
|
6
6
|
import { LocaleUrlStrategy } from '../localization';
|
|
7
|
-
import { useRouter } from 'next/navigation';
|
|
8
7
|
|
|
9
8
|
export const useLocalization = () => {
|
|
10
9
|
const {
|
|
@@ -18,8 +17,6 @@ export const useLocalization = () => {
|
|
|
18
17
|
localeUrlStrategy
|
|
19
18
|
} = useContext(LocalizationContext);
|
|
20
19
|
|
|
21
|
-
const router = useRouter();
|
|
22
|
-
|
|
23
20
|
/**
|
|
24
21
|
* Sets the locale in the URL.
|
|
25
22
|
* @param locale Locale value defined in the settings.
|
|
@@ -30,6 +27,8 @@ export const useLocalization = () => {
|
|
|
30
27
|
|
|
31
28
|
let targetUrl;
|
|
32
29
|
|
|
30
|
+
setCookie('pz-locale', locale);
|
|
31
|
+
|
|
33
32
|
if (localeUrlStrategy === LocaleUrlStrategy.Subdomain) {
|
|
34
33
|
const hostParts = hostname.split('.');
|
|
35
34
|
const subDomain = hostParts[0];
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useAppSelector } from '../redux/hooks';
|
|
2
|
+
|
|
3
|
+
export const useLoyaltyAvailability = () => {
|
|
4
|
+
const { paymentOptions, unavailablePaymentOptions } = useAppSelector(
|
|
5
|
+
(state) => state.checkout
|
|
6
|
+
);
|
|
7
|
+
|
|
8
|
+
const hasLoyaltyInAvailable = paymentOptions.some(
|
|
9
|
+
(option) =>
|
|
10
|
+
option.payment_type === 'loyalty_money' ||
|
|
11
|
+
option.payment_type === 'loyalty'
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
const hasLoyaltyInUnavailable = unavailablePaymentOptions.some(
|
|
15
|
+
(option) =>
|
|
16
|
+
option.payment_type === 'loyalty_money' ||
|
|
17
|
+
option.payment_type === 'loyalty'
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
return hasLoyaltyInAvailable || hasLoyaltyInUnavailable;
|
|
21
|
+
};
|
package/instrumentation/node.ts
CHANGED
|
@@ -4,17 +4,19 @@ import { Resource } from '@opentelemetry/resources';
|
|
|
4
4
|
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';
|
|
5
5
|
import { SimpleSpanProcessor } from '@opentelemetry/sdk-trace-node';
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
new
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
7
|
+
if (process.env.NODE_ENV === 'development') {
|
|
8
|
+
const sdk = new NodeSDK({
|
|
9
|
+
resource: new Resource({
|
|
10
|
+
[SemanticResourceAttributes.SERVICE_NAME]: 'pz-next-app'
|
|
11
|
+
}),
|
|
12
|
+
spanProcessor: new SimpleSpanProcessor(
|
|
13
|
+
new OTLPTraceExporter({
|
|
14
|
+
url: `${
|
|
15
|
+
process.env.PZ_DASHBOARD_URL ?? 'http://localhost:3005'
|
|
16
|
+
}/api/traces`
|
|
17
|
+
})
|
|
18
|
+
)
|
|
19
|
+
});
|
|
19
20
|
|
|
20
|
-
sdk.start();
|
|
21
|
+
sdk.start();
|
|
22
|
+
}
|
package/jest.config.js
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
|
+
const findBaseDir = require('./utils/find-base-dir');
|
|
3
|
+
|
|
4
|
+
const baseDir = findBaseDir();
|
|
2
5
|
|
|
3
6
|
module.exports = {
|
|
4
7
|
preset: 'ts-jest',
|
|
5
8
|
testEnvironment: 'node',
|
|
6
9
|
rootDir: path.resolve(__dirname),
|
|
7
|
-
roots: [],
|
|
8
10
|
testMatch: ['**/*.test.ts'],
|
|
9
11
|
testPathIgnorePatterns: [],
|
|
12
|
+
roots: [path.resolve(__dirname)],
|
|
10
13
|
transformIgnorePatterns: [],
|
|
14
|
+
moduleNameMapper: {
|
|
15
|
+
'^settings$': path.resolve(baseDir, 'src/settings.js')
|
|
16
|
+
},
|
|
11
17
|
transform: {
|
|
12
18
|
'^.+\\.(tsx?|jsx?|mjs?)$': [
|
|
13
19
|
'ts-jest',
|