@akinon/next 2.0.0-beta.12 → 2.0.0-beta.13
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 +282 -29
- package/api/auth.ts +99 -77
- package/api/cache.ts +41 -5
- package/api/client.ts +3 -3
- package/api/form.ts +85 -0
- package/api/image-proxy.ts +75 -0
- package/api/product-categories.ts +53 -0
- package/api/similar-product-list.ts +63 -0
- package/api/similar-products.ts +111 -0
- package/api/virtual-try-on.ts +382 -0
- package/bin/pz-generate-routes.js +105 -0
- package/bin/pz-prebuild.js +1 -1
- package/bin/pz-predev.js +1 -0
- package/components/accordion.tsx +21 -6
- package/components/button.tsx +1 -1
- package/components/file-input.tsx +65 -3
- package/components/input.tsx +2 -2
- package/components/modal.tsx +32 -16
- package/components/plugin-module.tsx +61 -3
- package/components/select.tsx +2 -2
- package/components/selected-payment-option-view.tsx +21 -0
- package/data/client/checkout.ts +130 -74
- package/data/server/category.ts +11 -9
- package/data/server/flatpage.ts +4 -1
- package/data/server/form.ts +4 -1
- package/data/server/landingpage.ts +4 -1
- package/data/server/list.ts +5 -4
- package/data/server/menu.ts +4 -1
- package/data/server/product.ts +97 -52
- package/data/server/seo.ts +4 -1
- package/data/server/special-page.ts +5 -4
- package/data/server/widget.ts +4 -1
- package/data/urls.ts +3 -2
- package/hocs/client/with-segment-defaults.tsx +2 -2
- package/hocs/server/with-segment-defaults.tsx +65 -20
- package/hooks/index.ts +1 -0
- package/hooks/use-loyalty-availability.ts +21 -0
- package/hooks/use-payment-options.ts +2 -1
- package/hooks/use-pz-params.ts +37 -0
- package/instrumentation/index.ts +0 -1
- package/instrumentation/node.ts +2 -20
- package/jest.config.js +7 -1
- package/lib/cache-handler.mjs +527 -15
- package/lib/cache.ts +260 -31
- package/localization/provider.tsx +2 -5
- package/middlewares/checkout-provider.ts +1 -1
- package/middlewares/complete-gpay.ts +33 -26
- package/middlewares/complete-masterpass.ts +34 -26
- package/middlewares/complete-wallet.ts +183 -0
- package/middlewares/default.ts +346 -235
- package/middlewares/index.ts +8 -2
- package/middlewares/locale.ts +0 -1
- package/middlewares/masterpass-rest-callback.ts +220 -0
- package/middlewares/pretty-url.ts +21 -8
- package/middlewares/redirection-payment.ts +33 -26
- package/middlewares/saved-card-redirection.ts +34 -26
- package/middlewares/three-d-redirection.ts +33 -26
- package/middlewares/url-redirection.ts +9 -15
- package/middlewares/wallet-complete-redirection.ts +207 -0
- package/package.json +20 -11
- package/plugins.d.ts +19 -4
- package/plugins.js +9 -1
- package/redux/actions.ts +47 -0
- package/redux/middlewares/checkout.ts +20 -8
- package/redux/middlewares/index.ts +12 -10
- package/redux/middlewares/pre-order/address.ts +1 -1
- package/redux/middlewares/pre-order/attribute-based-shipping-option.ts +1 -1
- package/redux/middlewares/pre-order/data-source-shipping-option.ts +1 -1
- package/redux/middlewares/pre-order/delivery-option.ts +1 -1
- package/redux/middlewares/pre-order/index.ts +3 -1
- package/redux/middlewares/pre-order/installment-option.ts +2 -1
- package/redux/middlewares/pre-order/payment-option-reset.ts +37 -0
- package/redux/middlewares/pre-order/payment-option.ts +1 -1
- package/redux/middlewares/pre-order/pre-order-validation.ts +4 -3
- package/redux/middlewares/pre-order/redirection.ts +2 -2
- package/redux/middlewares/pre-order/set-pre-order.ts +2 -2
- package/redux/middlewares/pre-order/shipping-option.ts +1 -1
- package/redux/middlewares/pre-order/shipping-step.ts +1 -1
- package/redux/reducers/checkout.ts +9 -1
- package/redux/reducers/index.ts +5 -1
- package/sentry/index.ts +54 -17
- package/types/commerce/checkout.ts +11 -1
- package/types/index.ts +96 -6
- package/types/next-auth.d.ts +2 -2
- package/utils/app-fetch.ts +2 -2
- package/utils/generate-commerce-search-params.ts +3 -2
- package/utils/get-checkout-path.ts +3 -0
- package/utils/index.ts +38 -11
- package/utils/override-middleware.ts +1 -0
- package/utils/pz-segments.ts +92 -0
- package/utils/redirect-ignore.ts +35 -0
- package/utils/redirect.ts +9 -3
- package/with-pz-config.js +10 -4
package/data/server/menu.ts
CHANGED
|
@@ -48,6 +48,9 @@ export const getMenu = async (params?: MenuHandlerParams) => {
|
|
|
48
48
|
return Cache.wrap(
|
|
49
49
|
CacheKey.Menu(params?.depth ?? DEFAULT_DEPTH, params?.parent),
|
|
50
50
|
params?.locale ?? ServerVariables.locale,
|
|
51
|
-
getMenuHandler(params)
|
|
51
|
+
getMenuHandler(params),
|
|
52
|
+
{
|
|
53
|
+
compressed: true
|
|
54
|
+
}
|
|
52
55
|
);
|
|
53
56
|
};
|
package/data/server/product.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { Cache, CacheKey } from '../../lib/cache';
|
|
2
2
|
import { product } from '../urls';
|
|
3
|
-
import { ProductCategoryResult, ProductResult } from '../../types';
|
|
3
|
+
import { ProductCategoryResult, ProductResult, SearchParams } from '../../types';
|
|
4
4
|
import appFetch from '../../utils/app-fetch';
|
|
5
5
|
import { ServerVariables } from '../../utils/server-variables';
|
|
6
6
|
import logger from '../../utils/log';
|
|
7
7
|
|
|
8
8
|
type GetProduct = {
|
|
9
|
-
pk: number;
|
|
9
|
+
pk: number | string;
|
|
10
10
|
locale?: string;
|
|
11
11
|
currency?: string;
|
|
12
|
-
searchParams?:
|
|
12
|
+
searchParams?: SearchParams;
|
|
13
13
|
groupProduct?: boolean;
|
|
14
14
|
headers?: Record<string, string>;
|
|
15
15
|
};
|
|
@@ -23,9 +23,21 @@ const getProductDataHandler = ({
|
|
|
23
23
|
headers
|
|
24
24
|
}: GetProduct) => {
|
|
25
25
|
return async function () {
|
|
26
|
+
// Convert pk to number if it's a string and validate
|
|
27
|
+
const numericPk = typeof pk === 'string' ? parseInt(pk, 10) : pk;
|
|
28
|
+
|
|
29
|
+
if (isNaN(numericPk)) {
|
|
30
|
+
logger.warn('Invalid product pk provided', {
|
|
31
|
+
handler: 'getProductDataHandler',
|
|
32
|
+
pk,
|
|
33
|
+
numericPk
|
|
34
|
+
});
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
|
|
26
38
|
let url = groupProduct
|
|
27
|
-
? product.getGroupProductByPk(
|
|
28
|
-
: product.getProductByPk(
|
|
39
|
+
? product.getGroupProductByPk(numericPk)
|
|
40
|
+
: product.getProductByPk(numericPk);
|
|
29
41
|
|
|
30
42
|
if (searchParams) {
|
|
31
43
|
url +=
|
|
@@ -35,61 +47,81 @@ const getProductDataHandler = ({
|
|
|
35
47
|
.join('&');
|
|
36
48
|
}
|
|
37
49
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
50
|
+
try {
|
|
51
|
+
const data = await appFetch<ProductResult>({
|
|
52
|
+
url,
|
|
53
|
+
locale,
|
|
54
|
+
currency,
|
|
55
|
+
init: {
|
|
56
|
+
headers: {
|
|
57
|
+
Accept: 'application/json',
|
|
58
|
+
'Content-Type': 'application/json',
|
|
59
|
+
...(headers ?? {})
|
|
60
|
+
}
|
|
47
61
|
}
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// If product data is not found, return null to trigger 404
|
|
65
|
+
if (!data?.product?.pk) {
|
|
66
|
+
logger.warn('Product not found', {
|
|
67
|
+
handler: 'getProductDataHandler',
|
|
68
|
+
pk: numericPk,
|
|
69
|
+
hasData: !!data,
|
|
70
|
+
hasProduct: !!data?.product
|
|
71
|
+
});
|
|
72
|
+
return null;
|
|
48
73
|
}
|
|
49
|
-
});
|
|
50
74
|
|
|
51
|
-
|
|
75
|
+
const categoryUrl = product.categoryUrl(data.product.pk);
|
|
52
76
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
77
|
+
const productCategoryData = await appFetch<ProductCategoryResult>({
|
|
78
|
+
url: categoryUrl,
|
|
79
|
+
locale,
|
|
80
|
+
currency,
|
|
81
|
+
init: {
|
|
82
|
+
headers: {
|
|
83
|
+
Accept: 'application/json',
|
|
84
|
+
'Content-Type': 'application/json'
|
|
85
|
+
}
|
|
61
86
|
}
|
|
62
|
-
}
|
|
63
|
-
});
|
|
87
|
+
});
|
|
64
88
|
|
|
65
|
-
|
|
89
|
+
const menuItemModel = productCategoryData?.results[0]?.menuitemmodel;
|
|
66
90
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
91
|
+
if (!menuItemModel) {
|
|
92
|
+
logger.warn('menuItemModel is undefined, skipping breadcrumbData fetch', {
|
|
93
|
+
handler: 'getProductDataHandler',
|
|
94
|
+
pk: numericPk
|
|
95
|
+
});
|
|
96
|
+
return { data, breadcrumbData: undefined };
|
|
97
|
+
}
|
|
74
98
|
|
|
75
|
-
|
|
99
|
+
const breadcrumbUrl = product.breadcrumbUrl(menuItemModel);
|
|
76
100
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
101
|
+
const breadcrumbData = await appFetch<any>({
|
|
102
|
+
url: breadcrumbUrl,
|
|
103
|
+
locale,
|
|
104
|
+
currency,
|
|
105
|
+
init: {
|
|
106
|
+
headers: {
|
|
107
|
+
Accept: 'application/json',
|
|
108
|
+
'Content-Type': 'application/json'
|
|
109
|
+
}
|
|
85
110
|
}
|
|
86
|
-
}
|
|
87
|
-
});
|
|
111
|
+
});
|
|
88
112
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
113
|
+
return {
|
|
114
|
+
data,
|
|
115
|
+
breadcrumbData: breadcrumbData?.menu
|
|
116
|
+
};
|
|
117
|
+
} catch (error) {
|
|
118
|
+
logger.error('Error in getProductDataHandler', {
|
|
119
|
+
handler: 'getProductDataHandler',
|
|
120
|
+
pk: numericPk,
|
|
121
|
+
error: error.message
|
|
122
|
+
});
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
93
125
|
};
|
|
94
126
|
};
|
|
95
127
|
|
|
@@ -101,9 +133,12 @@ export const getProductData = async ({
|
|
|
101
133
|
groupProduct,
|
|
102
134
|
headers
|
|
103
135
|
}: GetProduct) => {
|
|
104
|
-
|
|
136
|
+
// Convert pk to number for cache key if it's a string
|
|
137
|
+
const numericPkForCache = typeof pk === 'string' ? parseInt(pk, 10) : pk;
|
|
138
|
+
|
|
139
|
+
const result = await Cache.wrap(
|
|
105
140
|
CacheKey[groupProduct ? 'GroupProduct' : 'Product'](
|
|
106
|
-
|
|
141
|
+
numericPkForCache,
|
|
107
142
|
searchParams ?? new URLSearchParams()
|
|
108
143
|
),
|
|
109
144
|
locale,
|
|
@@ -116,7 +151,17 @@ export const getProductData = async ({
|
|
|
116
151
|
headers
|
|
117
152
|
}),
|
|
118
153
|
{
|
|
119
|
-
expire: 300
|
|
154
|
+
expire: 300,
|
|
155
|
+
compressed: true
|
|
120
156
|
}
|
|
121
157
|
);
|
|
158
|
+
|
|
159
|
+
// If product data is not found, throw 404 error
|
|
160
|
+
if (!result) {
|
|
161
|
+
const error = new Error('Product not found') as Error & { status: number };
|
|
162
|
+
error.status = 404;
|
|
163
|
+
throw error;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return result;
|
|
122
167
|
};
|
package/data/server/seo.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Cache, CacheKey } from '../../lib/cache';
|
|
2
2
|
import { category } from '../urls';
|
|
3
|
-
import { GetCategoryResponse } from '../../types';
|
|
3
|
+
import { GetCategoryResponse, SearchParams } from '../../types';
|
|
4
4
|
import { generateCommerceSearchParams } from '../../utils';
|
|
5
5
|
import appFetch from '../../utils/app-fetch';
|
|
6
6
|
import { ServerVariables } from '../../utils/server-variables';
|
|
@@ -9,7 +9,7 @@ const getSpecialPageDataHandler = (
|
|
|
9
9
|
pk: number,
|
|
10
10
|
locale: string,
|
|
11
11
|
currency: string,
|
|
12
|
-
searchParams:
|
|
12
|
+
searchParams: SearchParams,
|
|
13
13
|
headers?: Record<string, string>
|
|
14
14
|
) => {
|
|
15
15
|
return async function () {
|
|
@@ -42,7 +42,7 @@ export const getSpecialPageData = async ({
|
|
|
42
42
|
pk: number;
|
|
43
43
|
locale?: string;
|
|
44
44
|
currency?: string;
|
|
45
|
-
searchParams:
|
|
45
|
+
searchParams: SearchParams;
|
|
46
46
|
headers?: Record<string, string>;
|
|
47
47
|
}) => {
|
|
48
48
|
return Cache.wrap(
|
|
@@ -50,7 +50,8 @@ export const getSpecialPageData = async ({
|
|
|
50
50
|
locale,
|
|
51
51
|
getSpecialPageDataHandler(pk, locale, currency, searchParams, headers),
|
|
52
52
|
{
|
|
53
|
-
expire: 300
|
|
53
|
+
expire: 300,
|
|
54
|
+
compressed: true
|
|
54
55
|
}
|
|
55
56
|
);
|
|
56
57
|
};
|
package/data/server/widget.ts
CHANGED
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 = {
|
|
@@ -246,7 +247,7 @@ export const widgets = {
|
|
|
246
247
|
};
|
|
247
248
|
|
|
248
249
|
export const form = {
|
|
249
|
-
getForm: (pk: number) => `/forms/${pk}/generate
|
|
250
|
+
getForm: (pk: number) => `/forms/${pk}/generate`
|
|
250
251
|
};
|
|
251
252
|
|
|
252
253
|
const URLS = {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ResolvedLayoutProps, ResolvedPageProps, ResolvedRootLayoutProps } from '../../types';
|
|
2
2
|
import React, { JSX } from 'react';
|
|
3
3
|
|
|
4
4
|
type SegmentType = 'client-root' | 'layout' | 'page';
|
|
@@ -8,7 +8,7 @@ interface SegmentDefaultsOptions {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
export const withSegmentDefaults =
|
|
11
|
-
<T extends
|
|
11
|
+
<T extends ResolvedPageProps | ResolvedLayoutProps | ResolvedRootLayoutProps>(
|
|
12
12
|
Component: (
|
|
13
13
|
props?: T
|
|
14
14
|
) => null | JSX.Element | Promise<JSX.Element> | Promise<JSX.Element[]>,
|
|
@@ -1,10 +1,20 @@
|
|
|
1
|
-
import settings from 'settings';
|
|
2
1
|
import { JSX } from 'react';
|
|
3
|
-
import
|
|
2
|
+
import settings from 'settings';
|
|
3
|
+
import {
|
|
4
|
+
ResolvedPageProps,
|
|
5
|
+
ResolvedLayoutProps,
|
|
6
|
+
ResolvedRootLayoutProps
|
|
7
|
+
} from '../../types';
|
|
4
8
|
import { redirect } from 'next/navigation';
|
|
5
9
|
import { ServerVariables } from '../../utils/server-variables';
|
|
6
10
|
import { ROUTES } from 'routes';
|
|
7
11
|
import logger from '../../utils/log';
|
|
12
|
+
import {
|
|
13
|
+
decodePzValue,
|
|
14
|
+
getPzSegmentsConfig,
|
|
15
|
+
getBuiltInSegments,
|
|
16
|
+
isLegacyMode
|
|
17
|
+
} from '../../utils/pz-segments';
|
|
8
18
|
|
|
9
19
|
type SegmentType = 'root-layout' | 'layout' | 'page';
|
|
10
20
|
|
|
@@ -13,27 +23,50 @@ interface SegmentDefaultsOptions {
|
|
|
13
23
|
}
|
|
14
24
|
|
|
15
25
|
export const withSegmentDefaults =
|
|
16
|
-
<T extends
|
|
26
|
+
<T extends ResolvedPageProps | ResolvedLayoutProps | ResolvedRootLayoutProps>(
|
|
17
27
|
Component: (
|
|
18
28
|
props?: T
|
|
19
29
|
) => null | JSX.Element | Promise<JSX.Element> | Promise<JSX.Element[]>,
|
|
20
30
|
options: SegmentDefaultsOptions
|
|
21
31
|
) =>
|
|
22
|
-
async (props:
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
32
|
+
async (props: any) => {
|
|
33
|
+
const resolvedParams = await props.params;
|
|
34
|
+
const resolvedSearchParams = props.searchParams
|
|
35
|
+
? await props.searchParams
|
|
36
|
+
: undefined;
|
|
37
|
+
|
|
38
|
+
let componentProps = {
|
|
39
|
+
...props,
|
|
40
|
+
params: resolvedParams,
|
|
41
|
+
searchParams: resolvedSearchParams,
|
|
42
|
+
...('children' in props ? { children: (props as any).children } : {})
|
|
43
|
+
} as T;
|
|
44
|
+
|
|
45
|
+
let localeValue: string;
|
|
46
|
+
let currencyValue: string;
|
|
47
|
+
|
|
48
|
+
if (isLegacyMode(settings)) {
|
|
49
|
+
localeValue = resolvedParams.locale;
|
|
50
|
+
currencyValue = resolvedParams.currency;
|
|
51
|
+
} else {
|
|
52
|
+
const pzConfig = getPzSegmentsConfig(settings);
|
|
53
|
+
const parsed = decodePzValue(resolvedParams.pz, pzConfig);
|
|
54
|
+
const builtIn = getBuiltInSegments(parsed, settings);
|
|
55
|
+
localeValue = builtIn.locale;
|
|
56
|
+
currencyValue = builtIn.currency;
|
|
57
|
+
}
|
|
26
58
|
|
|
27
59
|
if (options.segmentType === 'root-layout') {
|
|
28
60
|
componentProps = (await addRootLayoutProps(
|
|
29
|
-
componentProps as
|
|
61
|
+
componentProps as ResolvedRootLayoutProps,
|
|
62
|
+
localeValue
|
|
30
63
|
)) as T;
|
|
31
64
|
|
|
32
65
|
checkRedisVariables();
|
|
33
66
|
}
|
|
34
67
|
|
|
35
|
-
ServerVariables.locale =
|
|
36
|
-
ServerVariables.currency =
|
|
68
|
+
ServerVariables.locale = localeValue;
|
|
69
|
+
ServerVariables.currency = currencyValue;
|
|
37
70
|
|
|
38
71
|
return await (
|
|
39
72
|
<>
|
|
@@ -42,12 +75,21 @@ export const withSegmentDefaults =
|
|
|
42
75
|
);
|
|
43
76
|
};
|
|
44
77
|
|
|
45
|
-
const addRootLayoutProps = async (
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
78
|
+
const addRootLayoutProps = async (
|
|
79
|
+
componentProps: ResolvedRootLayoutProps,
|
|
80
|
+
localeValue: string
|
|
81
|
+
) => {
|
|
82
|
+
if (isLegacyMode(settings)) {
|
|
83
|
+
const params = componentProps.params;
|
|
84
|
+
if (
|
|
85
|
+
params.commerce !==
|
|
86
|
+
encodeURIComponent(decodeURI(settings.commerceUrl)) ||
|
|
87
|
+
!settings.localization.locales.find((l) => l.value === localeValue)
|
|
88
|
+
) {
|
|
89
|
+
return redirect(ROUTES.HOME);
|
|
90
|
+
}
|
|
91
|
+
} else if (
|
|
92
|
+
!settings.localization.locales.find((l) => l.value === localeValue)
|
|
51
93
|
) {
|
|
52
94
|
return redirect(ROUTES.HOME);
|
|
53
95
|
}
|
|
@@ -55,12 +97,12 @@ const addRootLayoutProps = async (componentProps: RootLayoutProps) => {
|
|
|
55
97
|
const { getTranslations } = settings.useOptimizedTranslations
|
|
56
98
|
? require('translations')
|
|
57
99
|
: require('../../utils/server-translation');
|
|
58
|
-
const translations = await getTranslations(
|
|
100
|
+
const translations = await getTranslations(localeValue);
|
|
59
101
|
|
|
60
102
|
componentProps.translations = translations;
|
|
61
103
|
|
|
62
104
|
const locale = settings.localization.locales.find(
|
|
63
|
-
(l) => l.value ===
|
|
105
|
+
(l) => l.value === localeValue
|
|
64
106
|
);
|
|
65
107
|
const [isoCode] = locale.value.split('-');
|
|
66
108
|
|
|
@@ -75,10 +117,13 @@ const addRootLayoutProps = async (componentProps: RootLayoutProps) => {
|
|
|
75
117
|
const checkRedisVariables = () => {
|
|
76
118
|
const requiredVariableValues = [
|
|
77
119
|
process.env.CACHE_HOST,
|
|
78
|
-
process.env.CACHE_PORT
|
|
79
|
-
process.env.CACHE_SECRET
|
|
120
|
+
process.env.CACHE_PORT
|
|
80
121
|
];
|
|
81
122
|
|
|
123
|
+
if (!settings.usePrettyUrlRoute) {
|
|
124
|
+
requiredVariableValues.push(process.env.CACHE_SECRET);
|
|
125
|
+
}
|
|
126
|
+
|
|
82
127
|
if (
|
|
83
128
|
!requiredVariableValues.every((v) => v) &&
|
|
84
129
|
process.env.NODE_ENV === 'production'
|
package/hooks/index.ts
CHANGED
|
@@ -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
|
+
};
|
|
@@ -21,7 +21,8 @@ export const usePaymentOptions = () => {
|
|
|
21
21
|
credit_payment: 'pz-credit-payment',
|
|
22
22
|
masterpass: 'pz-masterpass',
|
|
23
23
|
saved_card: 'pz-saved-card',
|
|
24
|
-
gpay: 'pz-gpay'
|
|
24
|
+
gpay: 'pz-gpay',
|
|
25
|
+
masterpass_rest: 'pz-masterpass-rest'
|
|
25
26
|
};
|
|
26
27
|
|
|
27
28
|
const isInitialTypeIncluded = (type: string) => initialTypes.has(type);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useParams } from 'next/navigation';
|
|
4
|
+
import settings from 'settings';
|
|
5
|
+
import {
|
|
6
|
+
decodePzValue,
|
|
7
|
+
getPzSegmentsConfig,
|
|
8
|
+
getBuiltInSegments,
|
|
9
|
+
isLegacyMode
|
|
10
|
+
} from '../utils/pz-segments';
|
|
11
|
+
|
|
12
|
+
export function usePzParams(): {
|
|
13
|
+
locale: string;
|
|
14
|
+
currency: string;
|
|
15
|
+
[key: string]: string;
|
|
16
|
+
} {
|
|
17
|
+
const params = useParams() as Record<string, string>;
|
|
18
|
+
|
|
19
|
+
if (isLegacyMode(settings)) {
|
|
20
|
+
return {
|
|
21
|
+
locale:
|
|
22
|
+
params.locale ?? settings.localization.defaultLocaleValue,
|
|
23
|
+
currency:
|
|
24
|
+
params.currency ?? settings.localization.defaultCurrencyCode
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const pzValue = params.pz ?? '';
|
|
29
|
+
const config = getPzSegmentsConfig(settings);
|
|
30
|
+
const parsed = decodePzValue(pzValue, config);
|
|
31
|
+
const builtIn = getBuiltInSegments(parsed, settings);
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
...parsed,
|
|
35
|
+
...builtIn
|
|
36
|
+
};
|
|
37
|
+
}
|
package/instrumentation/index.ts
CHANGED
package/instrumentation/node.ts
CHANGED
|
@@ -1,20 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import { Resource } from '@opentelemetry/resources';
|
|
4
|
-
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';
|
|
5
|
-
import { SimpleSpanProcessor } from '@opentelemetry/sdk-trace-node';
|
|
6
|
-
|
|
7
|
-
const sdk = new NodeSDK({
|
|
8
|
-
resource: new Resource({
|
|
9
|
-
[SemanticResourceAttributes.SERVICE_NAME]: 'pz-next-app'
|
|
10
|
-
}),
|
|
11
|
-
spanProcessor: new SimpleSpanProcessor(
|
|
12
|
-
new OTLPTraceExporter({
|
|
13
|
-
url: `${
|
|
14
|
-
process.env.PZ_DASHBOARD_URL ?? 'http://localhost:3005'
|
|
15
|
-
}/api/traces`
|
|
16
|
-
})
|
|
17
|
-
)
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
sdk.start();
|
|
1
|
+
// OpenTelemetry tracing is handled by Sentry.
|
|
2
|
+
// Custom NodeSDK setup removed due to version incompatibility with Sentry 10's OpenTelemetry v2.x requirements.
|
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',
|