@akinon/next 2.0.0-beta.1 → 2.0.0-beta.10
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/.eslintrc.js +12 -0
- package/CHANGELOG.md +50 -0
- package/api/auth.ts +17 -0
- package/bin/run-prebuild-tests.js +46 -0
- package/components/accordion.tsx +1 -1
- package/components/button.tsx +51 -36
- package/components/client-root.tsx +20 -0
- package/components/input.tsx +1 -1
- package/components/modal.tsx +1 -1
- package/components/select.tsx +1 -1
- package/components/selected-payment-option-view.tsx +1 -1
- package/data/client/api.ts +2 -0
- package/data/client/basket.ts +27 -5
- package/data/client/checkout.ts +62 -7
- package/data/client/misc.ts +25 -1
- package/data/client/product.ts +19 -2
- package/data/client/user.ts +16 -8
- package/data/server/flatpage.ts +8 -4
- package/data/server/form.ts +12 -4
- package/data/server/landingpage.ts +8 -4
- package/data/server/menu.ts +7 -2
- package/data/server/product.ts +16 -5
- package/data/server/seo.ts +11 -4
- package/data/server/widget.ts +19 -4
- package/data/urls.ts +11 -3
- package/hooks/index.ts +1 -0
- package/hooks/use-router.ts +5 -2
- package/hooks/use-sentry-uncaught-errors.ts +24 -0
- package/instrumentation/index.ts +10 -0
- package/lib/cache-handler.mjs +2 -2
- package/lib/cache.ts +4 -4
- package/localization/index.ts +2 -1
- package/middlewares/default.ts +6 -15
- package/middlewares/locale.ts +31 -10
- package/middlewares/url-redirection.ts +16 -0
- package/package.json +4 -3
- package/plugins.js +2 -1
- package/redux/middlewares/checkout.ts +16 -144
- package/redux/middlewares/index.ts +4 -2
- package/redux/middlewares/pre-order/address.ts +50 -0
- package/redux/middlewares/pre-order/attribute-based-shipping-option.ts +46 -0
- package/redux/middlewares/pre-order/data-source-shipping-option.ts +43 -0
- package/redux/middlewares/pre-order/delivery-option.ts +40 -0
- package/redux/middlewares/pre-order/index.ts +29 -0
- package/redux/middlewares/pre-order/installment-option.ts +42 -0
- package/redux/middlewares/pre-order/payment-option.ts +34 -0
- package/redux/middlewares/pre-order/pre-order-validation.ts +24 -0
- package/redux/middlewares/pre-order/redirection.ts +40 -0
- package/redux/middlewares/pre-order/set-pre-order.ts +22 -0
- package/redux/middlewares/pre-order/shipping-option.ts +44 -0
- package/redux/middlewares/pre-order/shipping-step.ts +38 -0
- package/redux/reducers/checkout.ts +8 -2
- package/redux/reducers/index.ts +5 -3
- package/redux/reducers/root.ts +7 -2
- package/sentry/index.ts +36 -17
- package/types/commerce/account.ts +5 -1
- package/types/commerce/checkout.ts +23 -0
- package/types/index.ts +6 -2
- package/utils/index.ts +11 -8
- package/utils/localization.ts +4 -0
- package/utils/override-middleware.ts +25 -0
- package/views/error-page.tsx +93 -0
- package/with-pz-config.js +4 -3
package/data/server/flatpage.ts
CHANGED
|
@@ -7,7 +7,8 @@ import { ServerVariables } from '../../utils/server-variables';
|
|
|
7
7
|
const getFlatPageDataHandler = (
|
|
8
8
|
pk: number,
|
|
9
9
|
locale: string,
|
|
10
|
-
currency: string
|
|
10
|
+
currency: string,
|
|
11
|
+
headers?: Record<string, string>
|
|
11
12
|
) => {
|
|
12
13
|
return async function () {
|
|
13
14
|
const data = await appFetch<FlatPage>({
|
|
@@ -17,7 +18,8 @@ const getFlatPageDataHandler = (
|
|
|
17
18
|
init: {
|
|
18
19
|
headers: {
|
|
19
20
|
Accept: 'application/json',
|
|
20
|
-
'Content-Type': 'application/json'
|
|
21
|
+
'Content-Type': 'application/json',
|
|
22
|
+
...(headers ?? {})
|
|
21
23
|
}
|
|
22
24
|
}
|
|
23
25
|
});
|
|
@@ -29,15 +31,17 @@ const getFlatPageDataHandler = (
|
|
|
29
31
|
export const getFlatPageData = ({
|
|
30
32
|
pk,
|
|
31
33
|
locale = ServerVariables.locale,
|
|
32
|
-
currency = ServerVariables.currency
|
|
34
|
+
currency = ServerVariables.currency,
|
|
35
|
+
headers
|
|
33
36
|
}: {
|
|
34
37
|
pk: number;
|
|
35
38
|
locale?: string;
|
|
36
39
|
currency?: string;
|
|
40
|
+
headers?: Record<string, string>;
|
|
37
41
|
}) => {
|
|
38
42
|
return Cache.wrap(
|
|
39
43
|
CacheKey.FlatPage(pk),
|
|
40
44
|
locale,
|
|
41
|
-
getFlatPageDataHandler(pk, locale, currency)
|
|
45
|
+
getFlatPageDataHandler(pk, locale, currency, headers)
|
|
42
46
|
);
|
|
43
47
|
};
|
package/data/server/form.ts
CHANGED
|
@@ -5,7 +5,12 @@ import appFetch from '../../utils/app-fetch';
|
|
|
5
5
|
import { ServerVariables } from '../../utils/server-variables';
|
|
6
6
|
import { form } from '../urls';
|
|
7
7
|
|
|
8
|
-
const getFormDataHandler = (
|
|
8
|
+
const getFormDataHandler = (
|
|
9
|
+
pk: number,
|
|
10
|
+
locale: string,
|
|
11
|
+
currency: string,
|
|
12
|
+
headers?: Record<string, string>
|
|
13
|
+
) => {
|
|
9
14
|
return async function () {
|
|
10
15
|
const data = await appFetch<FormType>({
|
|
11
16
|
url: form.getForm(pk),
|
|
@@ -14,7 +19,8 @@ const getFormDataHandler = (pk: number, locale: string, currency: string) => {
|
|
|
14
19
|
init: {
|
|
15
20
|
headers: {
|
|
16
21
|
Accept: 'application/json',
|
|
17
|
-
'Content-Type': 'application/json'
|
|
22
|
+
'Content-Type': 'application/json',
|
|
23
|
+
...(headers ?? {})
|
|
18
24
|
}
|
|
19
25
|
}
|
|
20
26
|
});
|
|
@@ -26,15 +32,17 @@ const getFormDataHandler = (pk: number, locale: string, currency: string) => {
|
|
|
26
32
|
export const getFormData = ({
|
|
27
33
|
pk,
|
|
28
34
|
locale = ServerVariables.locale,
|
|
29
|
-
currency = ServerVariables.currency
|
|
35
|
+
currency = ServerVariables.currency,
|
|
36
|
+
headers
|
|
30
37
|
}: {
|
|
31
38
|
pk: number;
|
|
32
39
|
locale?: string;
|
|
33
40
|
currency?: string;
|
|
41
|
+
headers?: Record<string, string>;
|
|
34
42
|
}) => {
|
|
35
43
|
return Cache.wrap(
|
|
36
44
|
CacheKey.Form(pk),
|
|
37
45
|
locale,
|
|
38
|
-
getFormDataHandler(pk, locale, currency)
|
|
46
|
+
getFormDataHandler(pk, locale, currency, headers)
|
|
39
47
|
);
|
|
40
48
|
};
|
|
@@ -7,7 +7,8 @@ import { ServerVariables } from '../../utils/server-variables';
|
|
|
7
7
|
const getLandingPageHandler = (
|
|
8
8
|
pk: number,
|
|
9
9
|
locale: string,
|
|
10
|
-
currency: string
|
|
10
|
+
currency: string,
|
|
11
|
+
headers?: Record<string, string>
|
|
11
12
|
) => {
|
|
12
13
|
return async function () {
|
|
13
14
|
const data = await appFetch<LandingPage>({
|
|
@@ -17,7 +18,8 @@ const getLandingPageHandler = (
|
|
|
17
18
|
init: {
|
|
18
19
|
headers: {
|
|
19
20
|
Accept: 'application/json',
|
|
20
|
-
'Content-Type': 'application/json'
|
|
21
|
+
'Content-Type': 'application/json',
|
|
22
|
+
...(headers ?? {})
|
|
21
23
|
}
|
|
22
24
|
}
|
|
23
25
|
});
|
|
@@ -29,15 +31,17 @@ const getLandingPageHandler = (
|
|
|
29
31
|
export const getLandingPageData = ({
|
|
30
32
|
pk,
|
|
31
33
|
locale = ServerVariables.locale,
|
|
32
|
-
currency = ServerVariables.currency
|
|
34
|
+
currency = ServerVariables.currency,
|
|
35
|
+
headers
|
|
33
36
|
}: {
|
|
34
37
|
pk: number;
|
|
35
38
|
locale?: string;
|
|
36
39
|
currency?: string;
|
|
40
|
+
headers?: Record<string, string>;
|
|
37
41
|
}) => {
|
|
38
42
|
return Cache.wrap(
|
|
39
43
|
CacheKey.LandingPage(pk),
|
|
40
44
|
locale,
|
|
41
|
-
getLandingPageHandler(pk, locale, currency)
|
|
45
|
+
getLandingPageHandler(pk, locale, currency, headers)
|
|
42
46
|
);
|
|
43
47
|
};
|
package/data/server/menu.ts
CHANGED
|
@@ -13,6 +13,7 @@ interface MenuHandlerParams {
|
|
|
13
13
|
currency?: string;
|
|
14
14
|
depth?: number;
|
|
15
15
|
parent?: string;
|
|
16
|
+
headers?: Record<string, string>;
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
const DEFAULT_DEPTH = 3;
|
|
@@ -22,13 +23,17 @@ const getMenuHandler =
|
|
|
22
23
|
locale = ServerVariables.locale,
|
|
23
24
|
currency = ServerVariables.currency,
|
|
24
25
|
depth,
|
|
25
|
-
parent
|
|
26
|
+
parent,
|
|
27
|
+
headers
|
|
26
28
|
}: MenuHandlerParams = {}) =>
|
|
27
29
|
async () => {
|
|
28
30
|
const response = await appFetch<MenuResponse>({
|
|
29
31
|
url: misc.menus(depth ?? DEFAULT_DEPTH, parent),
|
|
30
32
|
locale,
|
|
31
|
-
currency
|
|
33
|
+
currency,
|
|
34
|
+
init: {
|
|
35
|
+
headers
|
|
36
|
+
}
|
|
32
37
|
});
|
|
33
38
|
|
|
34
39
|
return response?.menu;
|
package/data/server/product.ts
CHANGED
|
@@ -11,6 +11,7 @@ type GetProduct = {
|
|
|
11
11
|
currency?: string;
|
|
12
12
|
searchParams?: URLSearchParams;
|
|
13
13
|
groupProduct?: boolean;
|
|
14
|
+
headers?: Record<string, string>;
|
|
14
15
|
};
|
|
15
16
|
|
|
16
17
|
const getProductDataHandler = ({
|
|
@@ -18,7 +19,8 @@ const getProductDataHandler = ({
|
|
|
18
19
|
locale,
|
|
19
20
|
currency,
|
|
20
21
|
searchParams,
|
|
21
|
-
groupProduct
|
|
22
|
+
groupProduct,
|
|
23
|
+
headers
|
|
22
24
|
}: GetProduct) => {
|
|
23
25
|
return async function () {
|
|
24
26
|
let url = groupProduct
|
|
@@ -29,7 +31,7 @@ const getProductDataHandler = ({
|
|
|
29
31
|
url +=
|
|
30
32
|
'?' +
|
|
31
33
|
Object.keys(searchParams)
|
|
32
|
-
.map((key) => `${key}=${searchParams[key]}`)
|
|
34
|
+
.map((key) => `${key}=${encodeURIComponent(searchParams[key])}`)
|
|
33
35
|
.join('&');
|
|
34
36
|
}
|
|
35
37
|
|
|
@@ -40,7 +42,8 @@ const getProductDataHandler = ({
|
|
|
40
42
|
init: {
|
|
41
43
|
headers: {
|
|
42
44
|
Accept: 'application/json',
|
|
43
|
-
'Content-Type': 'application/json'
|
|
45
|
+
'Content-Type': 'application/json',
|
|
46
|
+
...(headers ?? {})
|
|
44
47
|
}
|
|
45
48
|
}
|
|
46
49
|
});
|
|
@@ -95,7 +98,8 @@ export const getProductData = async ({
|
|
|
95
98
|
locale = ServerVariables.locale,
|
|
96
99
|
currency = ServerVariables.currency,
|
|
97
100
|
searchParams,
|
|
98
|
-
groupProduct
|
|
101
|
+
groupProduct,
|
|
102
|
+
headers
|
|
99
103
|
}: GetProduct) => {
|
|
100
104
|
return Cache.wrap(
|
|
101
105
|
CacheKey[groupProduct ? 'GroupProduct' : 'Product'](
|
|
@@ -103,7 +107,14 @@ export const getProductData = async ({
|
|
|
103
107
|
searchParams ?? new URLSearchParams()
|
|
104
108
|
),
|
|
105
109
|
locale,
|
|
106
|
-
getProductDataHandler({
|
|
110
|
+
getProductDataHandler({
|
|
111
|
+
pk,
|
|
112
|
+
locale,
|
|
113
|
+
currency,
|
|
114
|
+
searchParams,
|
|
115
|
+
groupProduct,
|
|
116
|
+
headers
|
|
117
|
+
}),
|
|
107
118
|
{
|
|
108
119
|
expire: 300
|
|
109
120
|
}
|
package/data/server/seo.ts
CHANGED
|
@@ -7,9 +7,10 @@ interface SeoDataParams {
|
|
|
7
7
|
url: string;
|
|
8
8
|
locale?: string;
|
|
9
9
|
currency?: string;
|
|
10
|
+
headers?: Record<string, string>;
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
function getSeoDataHandler({ url, locale, currency }: SeoDataParams) {
|
|
13
|
+
function getSeoDataHandler({ url, locale, currency, headers }: SeoDataParams) {
|
|
13
14
|
return async function () {
|
|
14
15
|
let data = {} as {
|
|
15
16
|
title: string;
|
|
@@ -19,7 +20,12 @@ function getSeoDataHandler({ url, locale, currency }: SeoDataParams) {
|
|
|
19
20
|
};
|
|
20
21
|
|
|
21
22
|
try {
|
|
22
|
-
data = await appFetch({
|
|
23
|
+
data = await appFetch({
|
|
24
|
+
url: misc.cmsSeo(url),
|
|
25
|
+
locale,
|
|
26
|
+
currency,
|
|
27
|
+
init: { headers }
|
|
28
|
+
});
|
|
23
29
|
} catch (error) {
|
|
24
30
|
// logger.error('Error while fetching seo data', { url, error });
|
|
25
31
|
}
|
|
@@ -31,11 +37,12 @@ function getSeoDataHandler({ url, locale, currency }: SeoDataParams) {
|
|
|
31
37
|
export const getSeoData = async (
|
|
32
38
|
url,
|
|
33
39
|
locale = ServerVariables.locale,
|
|
34
|
-
currency = ServerVariables.currency
|
|
40
|
+
currency = ServerVariables.currency,
|
|
41
|
+
headers?: Record<string, string>
|
|
35
42
|
) => {
|
|
36
43
|
return Cache.wrap(
|
|
37
44
|
CacheKey.Seo(url),
|
|
38
45
|
locale,
|
|
39
|
-
getSeoDataHandler({ url, locale, currency })
|
|
46
|
+
getSeoDataHandler({ url, locale, currency, headers })
|
|
40
47
|
);
|
|
41
48
|
};
|
package/data/server/widget.ts
CHANGED
|
@@ -6,29 +6,44 @@ import { widgets } from '../urls';
|
|
|
6
6
|
import { ServerVariables } from '../../utils/server-variables';
|
|
7
7
|
|
|
8
8
|
const getWidgetDataHandler =
|
|
9
|
-
(
|
|
9
|
+
(
|
|
10
|
+
slug: string,
|
|
11
|
+
locale: string,
|
|
12
|
+
currency: string,
|
|
13
|
+
headers?: Record<string, string>
|
|
14
|
+
) =>
|
|
15
|
+
async () => {
|
|
10
16
|
if (!slug) {
|
|
11
17
|
return null;
|
|
12
18
|
}
|
|
13
19
|
|
|
14
|
-
return await appFetch({
|
|
20
|
+
return await appFetch({
|
|
21
|
+
url: widgets.getWidget(slug),
|
|
22
|
+
locale,
|
|
23
|
+
currency,
|
|
24
|
+
init: {
|
|
25
|
+
headers
|
|
26
|
+
}
|
|
27
|
+
});
|
|
15
28
|
};
|
|
16
29
|
|
|
17
30
|
export const getWidgetData = async <T>({
|
|
18
31
|
slug,
|
|
19
32
|
locale = ServerVariables.locale,
|
|
20
33
|
currency = ServerVariables.currency,
|
|
21
|
-
cacheOptions
|
|
34
|
+
cacheOptions,
|
|
35
|
+
headers
|
|
22
36
|
}: {
|
|
23
37
|
slug: string;
|
|
24
38
|
locale?: string;
|
|
25
39
|
currency?: string;
|
|
26
40
|
cacheOptions?: CacheOptions;
|
|
41
|
+
headers?: Record<string, string>;
|
|
27
42
|
}): Promise<WidgetResultType<T>> => {
|
|
28
43
|
return Cache.wrap(
|
|
29
44
|
CacheKey.Widget(slug),
|
|
30
45
|
locale,
|
|
31
|
-
getWidgetDataHandler(slug, locale, currency),
|
|
46
|
+
getWidgetDataHandler(slug, locale, currency, headers),
|
|
32
47
|
cacheOptions
|
|
33
48
|
);
|
|
34
49
|
};
|
package/data/urls.ts
CHANGED
|
@@ -74,7 +74,10 @@ export const address = {
|
|
|
74
74
|
|
|
75
75
|
export const basket = {
|
|
76
76
|
getBasket: '/baskets/basket/',
|
|
77
|
+
getMiniBasket: '/baskets/basket/mini/',
|
|
77
78
|
getBasketDetail: (namespace: string) => `/baskets/basket/${namespace}/`,
|
|
79
|
+
getMiniBasketDetail: (namespace: string) =>
|
|
80
|
+
`/baskets/basket/${namespace}/mini/`,
|
|
78
81
|
getAllBaskets: '/baskets/basket-list/',
|
|
79
82
|
removeBasket: (pk: number) => `/baskets/basket-list/${pk}/`,
|
|
80
83
|
selectMainBasket: (pk: number) => `/baskets/basket-list/id/${pk}/main/`,
|
|
@@ -137,7 +140,9 @@ export const checkout = {
|
|
|
137
140
|
'/orders/checkout/?page=AttributeBasedShippingOptionSelectionPage',
|
|
138
141
|
deliveryBagsPage: '/orders/checkout/?page=DeliveryBagsPage',
|
|
139
142
|
setOrderSelectionPage: '/orders/checkout/?page=OrderSelectionPage',
|
|
140
|
-
loyaltyCardPage: '/orders/checkout/?page=LoyaltyCardPage'
|
|
143
|
+
loyaltyCardPage: '/orders/checkout/?page=LoyaltyCardPage',
|
|
144
|
+
sendSmsPage: '/orders/checkout/?page=SendSmsPage',
|
|
145
|
+
verifySmsPage: '/orders/checkout/?page=VerifySmsPage'
|
|
141
146
|
};
|
|
142
147
|
|
|
143
148
|
export const flatpage = {
|
|
@@ -160,7 +165,8 @@ export const misc = {
|
|
|
160
165
|
parent ? `&parent=${parent}` : ''
|
|
161
166
|
}`,
|
|
162
167
|
cmsSeo: (slug: string | string[]) => `/cms/seo/?url=${slug ? slug : '/'}`,
|
|
163
|
-
setCurrency: '/users/activate-currency/'
|
|
168
|
+
setCurrency: '/users/activate-currency/',
|
|
169
|
+
bukalemunImageUrl: (params: string) => `/bukalemun/?${params}`
|
|
164
170
|
};
|
|
165
171
|
|
|
166
172
|
export const product = {
|
|
@@ -174,7 +180,9 @@ export const product = {
|
|
|
174
180
|
slug: (slug: string) => `/${slug}/`,
|
|
175
181
|
categoryUrl: (pk: number) => `/products/${pk}/category_nodes/?limit=1`,
|
|
176
182
|
breadcrumbUrl: (menuitemmodel: string) =>
|
|
177
|
-
`/menus/generate_breadcrumb/?item=${menuitemmodel}&generator_name=menu_item
|
|
183
|
+
`/menus/generate_breadcrumb/?item=${menuitemmodel}&generator_name=menu_item`,
|
|
184
|
+
bundleProduct: (productPk: string, queryString: string) =>
|
|
185
|
+
`/bundle-product/${productPk}/?${queryString}`
|
|
178
186
|
};
|
|
179
187
|
|
|
180
188
|
export const wishlist = {
|
package/hooks/index.ts
CHANGED
package/hooks/use-router.ts
CHANGED
|
@@ -27,8 +27,11 @@ export const useRouter = () => {
|
|
|
27
27
|
);
|
|
28
28
|
|
|
29
29
|
url.pathname = `${
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
localeUrlStrategy === LocaleUrlStrategy.Subdomain ||
|
|
31
|
+
(locale === defaultLocale?.value &&
|
|
32
|
+
[LocaleUrlStrategy.HideDefaultLocale].includes(
|
|
33
|
+
localeUrlStrategy as LocaleUrlStrategy
|
|
34
|
+
))
|
|
32
35
|
? ''
|
|
33
36
|
: `/${locale}`
|
|
34
37
|
}${pathnameWithoutLocale}`;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
import * as Sentry from '@sentry/nextjs';
|
|
3
|
+
import { ClientLogType } from '@akinon/next/sentry';
|
|
4
|
+
|
|
5
|
+
export const useSentryUncaughtErrors = (error: Error & { digest?: string }) => {
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
Sentry.withScope(function (scope) {
|
|
8
|
+
scope.setLevel('fatal');
|
|
9
|
+
scope.setTags({
|
|
10
|
+
APP_TYPE: 'ProjectZeroNext',
|
|
11
|
+
TYPE: 'Client',
|
|
12
|
+
LOG_TYPE: ClientLogType.UNCAUGHT_ERROR_PAGE
|
|
13
|
+
});
|
|
14
|
+
scope.setExtra('error', error);
|
|
15
|
+
|
|
16
|
+
const error_ = new Error('FATAL: Uncaught client error');
|
|
17
|
+
error_.name = 'UNCAUGHT_ERROR_PAGE';
|
|
18
|
+
|
|
19
|
+
Sentry.captureException(error_, {
|
|
20
|
+
fingerprint: ['UNCAUGHT_ERROR_PAGE', error.digest]
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
}, [error]);
|
|
24
|
+
};
|
package/instrumentation/index.ts
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
|
+
import { initSentry } from '../sentry';
|
|
2
|
+
import * as Sentry from '@sentry/nextjs';
|
|
3
|
+
|
|
1
4
|
export async function register() {
|
|
2
5
|
if (process.env.NEXT_RUNTIME === 'nodejs') {
|
|
3
6
|
await import('./node');
|
|
7
|
+
initSentry('Server');
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (process.env.NEXT_RUNTIME === 'edge') {
|
|
11
|
+
initSentry('Edge');
|
|
4
12
|
}
|
|
5
13
|
}
|
|
14
|
+
|
|
15
|
+
export const onRequestError = Sentry.captureRequestError;
|
package/lib/cache-handler.mjs
CHANGED
|
@@ -23,10 +23,10 @@ CacheHandler.onCreation(async () => {
|
|
|
23
23
|
timeoutMs: 5000
|
|
24
24
|
});
|
|
25
25
|
|
|
26
|
-
const localHandler = createLruHandler();
|
|
26
|
+
// const localHandler = createLruHandler();
|
|
27
27
|
|
|
28
28
|
return {
|
|
29
|
-
handlers: [redisHandler
|
|
29
|
+
handlers: [redisHandler]
|
|
30
30
|
};
|
|
31
31
|
});
|
|
32
32
|
|
package/lib/cache.ts
CHANGED
|
@@ -156,10 +156,6 @@ export class Cache {
|
|
|
156
156
|
handler: () => Promise<T>,
|
|
157
157
|
options?: CacheOptions
|
|
158
158
|
): Promise<T> {
|
|
159
|
-
if (Settings.usePrettyUrlRoute) {
|
|
160
|
-
return await handler();
|
|
161
|
-
}
|
|
162
|
-
|
|
163
159
|
const requiredVariables = [
|
|
164
160
|
process.env.CACHE_HOST,
|
|
165
161
|
process.env.CACHE_PORT,
|
|
@@ -178,6 +174,10 @@ export class Cache {
|
|
|
178
174
|
const _options = Object.assign(defaultOptions, options);
|
|
179
175
|
const formattedKey = Cache.formatKey(key, locale);
|
|
180
176
|
|
|
177
|
+
if (Settings.usePrettyUrlRoute) {
|
|
178
|
+
_options.expire = 120;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
181
|
logger.debug('Cache wrap', { key, formattedKey, _options });
|
|
182
182
|
|
|
183
183
|
if (_options.cache) {
|
package/localization/index.ts
CHANGED
package/middlewares/default.ts
CHANGED
|
@@ -95,7 +95,9 @@ const withPzDefault =
|
|
|
95
95
|
|
|
96
96
|
if (
|
|
97
97
|
req.nextUrl.pathname.includes('/orders/hooks/') ||
|
|
98
|
-
req.nextUrl.pathname.includes('/orders/checkout-with-token/')
|
|
98
|
+
req.nextUrl.pathname.includes('/orders/checkout-with-token/') ||
|
|
99
|
+
req.nextUrl.pathname.includes('/hooks/cash_register/complete/') ||
|
|
100
|
+
req.nextUrl.pathname.includes('/hooks/cash_register/pre_order/')
|
|
99
101
|
) {
|
|
100
102
|
const queryString = searchParams.toString();
|
|
101
103
|
const currency = searchParams.get('currency')?.toLowerCase();
|
|
@@ -285,20 +287,9 @@ const withPzDefault =
|
|
|
285
287
|
url.pathname =
|
|
286
288
|
url.pathname +
|
|
287
289
|
(/\/$/.test(url.pathname) ? '' : '/') +
|
|
288
|
-
`searchparams|${
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
if (
|
|
292
|
-
!req.middlewareParams.found &&
|
|
293
|
-
Settings.customNotFoundEnabled
|
|
294
|
-
) {
|
|
295
|
-
let pathname = url.pathname
|
|
296
|
-
.replace(/\/+$/, '')
|
|
297
|
-
.split('/');
|
|
298
|
-
url.pathname = url.pathname.replace(
|
|
299
|
-
pathname.pop(),
|
|
300
|
-
'pz-not-found'
|
|
301
|
-
);
|
|
290
|
+
`searchparams|${encodeURIComponent(
|
|
291
|
+
url.searchParams.toString()
|
|
292
|
+
)}`;
|
|
302
293
|
}
|
|
303
294
|
|
|
304
295
|
Settings.rewrites.forEach((rewrite) => {
|
package/middlewares/locale.ts
CHANGED
|
@@ -4,17 +4,32 @@ import { PzNextRequest } from '.';
|
|
|
4
4
|
import { LocaleUrlStrategy } from '../localization';
|
|
5
5
|
import { urlLocaleMatcherRegex } from '../utils';
|
|
6
6
|
import logger from '../utils/log';
|
|
7
|
+
import { getUrlPathWithLocale } from '../utils/localization';
|
|
7
8
|
|
|
8
|
-
const getMatchedLocale = (pathname: string) => {
|
|
9
|
+
const getMatchedLocale = (pathname: string, req: PzNextRequest) => {
|
|
9
10
|
let matchedLocale = pathname.match(urlLocaleMatcherRegex)?.[0] ?? '';
|
|
10
11
|
matchedLocale = matchedLocale.replace('/', '');
|
|
11
12
|
|
|
13
|
+
const { localeUrlStrategy, defaultLocaleValue } = settings.localization;
|
|
14
|
+
|
|
15
|
+
if (localeUrlStrategy === LocaleUrlStrategy.Subdomain) {
|
|
16
|
+
const host = req.headers.get('x-forwarded-host');
|
|
17
|
+
|
|
18
|
+
if (host) {
|
|
19
|
+
const subDomain = host.split('.')[0] || '';
|
|
20
|
+
const subDomainLocaleMatched = `/${subDomain}`.match(
|
|
21
|
+
urlLocaleMatcherRegex
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
if (subDomainLocaleMatched && subDomainLocaleMatched[0]) {
|
|
25
|
+
matchedLocale = subDomainLocaleMatched[0].slice(1);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
12
30
|
if (!matchedLocale.length) {
|
|
13
|
-
if (
|
|
14
|
-
|
|
15
|
-
LocaleUrlStrategy.ShowAllLocales
|
|
16
|
-
) {
|
|
17
|
-
matchedLocale = settings.localization.defaultLocaleValue;
|
|
31
|
+
if (localeUrlStrategy !== LocaleUrlStrategy.ShowAllLocales) {
|
|
32
|
+
matchedLocale = defaultLocaleValue;
|
|
18
33
|
}
|
|
19
34
|
}
|
|
20
35
|
|
|
@@ -28,7 +43,7 @@ const withLocale =
|
|
|
28
43
|
|
|
29
44
|
try {
|
|
30
45
|
const url = req.nextUrl.clone();
|
|
31
|
-
const matchedLocale = getMatchedLocale(url.pathname);
|
|
46
|
+
const matchedLocale = getMatchedLocale(url.pathname, req);
|
|
32
47
|
let { localeUrlStrategy, defaultLocaleValue, redirectToDefaultLocale } =
|
|
33
48
|
settings.localization;
|
|
34
49
|
|
|
@@ -50,8 +65,15 @@ const withLocale =
|
|
|
50
65
|
redirectToDefaultLocale &&
|
|
51
66
|
req.method === 'GET'
|
|
52
67
|
) {
|
|
53
|
-
|
|
54
|
-
|
|
68
|
+
// Redirect to existing or default locale
|
|
69
|
+
|
|
70
|
+
url.pathname = getUrlPathWithLocale(
|
|
71
|
+
url.pathname,
|
|
72
|
+
req.cookies.get('pz-locale')?.value
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
// Use 303 for POST requests
|
|
76
|
+
return NextResponse.redirect(url, 303);
|
|
55
77
|
}
|
|
56
78
|
|
|
57
79
|
req.middlewareParams.rewrites.locale = matchedLocale;
|
|
@@ -61,7 +83,6 @@ const withLocale =
|
|
|
61
83
|
ip
|
|
62
84
|
});
|
|
63
85
|
}
|
|
64
|
-
|
|
65
86
|
return middleware(req, event);
|
|
66
87
|
};
|
|
67
88
|
|
|
@@ -60,6 +60,22 @@ const withUrlRedirection =
|
|
|
60
60
|
|
|
61
61
|
const setCookies = request.headers.getSetCookie();
|
|
62
62
|
|
|
63
|
+
if (settings.commerceRedirectionIgnoreList) {
|
|
64
|
+
const shouldIgnoreRedirect =
|
|
65
|
+
settings.commerceRedirectionIgnoreList.some((ignorePath) =>
|
|
66
|
+
redirectUrl.pathname.startsWith(
|
|
67
|
+
getUrlPathWithLocale(
|
|
68
|
+
ignorePath,
|
|
69
|
+
req.middlewareParams.rewrites.locale
|
|
70
|
+
)
|
|
71
|
+
)
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
if (shouldIgnoreRedirect) {
|
|
75
|
+
return middleware(req, event);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
63
79
|
const response = NextResponse.redirect(redirectUrl.toString(), {
|
|
64
80
|
status: request.status
|
|
65
81
|
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akinon/next",
|
|
3
3
|
"description": "Core package for Project Zero Next",
|
|
4
|
-
"version": "2.0.0-beta.
|
|
4
|
+
"version": "2.0.0-beta.10",
|
|
5
5
|
"private": false,
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"bin": {
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"@opentelemetry/semantic-conventions": "1.19.0",
|
|
22
22
|
"@reduxjs/toolkit": "1.9.7",
|
|
23
23
|
"@neshca/cache-handler": "1.5.1",
|
|
24
|
+
"@sentry/nextjs": "9.5.0",
|
|
24
25
|
"cross-spawn": "7.0.3",
|
|
25
26
|
"generic-pool": "3.9.0",
|
|
26
27
|
"react-redux": "8.1.3",
|
|
@@ -30,13 +31,13 @@
|
|
|
30
31
|
"set-cookie-parser": "2.6.0"
|
|
31
32
|
},
|
|
32
33
|
"devDependencies": {
|
|
33
|
-
"@akinon/eslint-plugin-projectzero": "2.0.0-beta.
|
|
34
|
+
"@akinon/eslint-plugin-projectzero": "2.0.0-beta.10",
|
|
34
35
|
"@types/react-redux": "7.1.30",
|
|
35
36
|
"@types/set-cookie-parser": "2.4.7",
|
|
36
37
|
"@typescript-eslint/eslint-plugin": "8.18.2",
|
|
37
38
|
"@typescript-eslint/parser": "8.18.2",
|
|
38
39
|
"eslint": "9.17.0",
|
|
39
|
-
"eslint-config-next": "15.
|
|
40
|
+
"eslint-config-next": "15.3.2",
|
|
40
41
|
"eslint-config-prettier": "9.1.0"
|
|
41
42
|
}
|
|
42
43
|
}
|