@akinon/next 2.0.0-beta.1 → 2.0.0-beta.11
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 +56 -0
- package/__tests__/next-config.test.ts +83 -0
- package/__tests__/tsconfig.json +23 -0
- package/api/auth.ts +72 -5
- package/api/client.ts +18 -1
- package/babel.config.js +6 -0
- package/bin/pz-prebuild.js +1 -0
- package/bin/pz-run-tests.js +99 -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/price.tsx +2 -2
- 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-localization.ts +24 -10
- package/hooks/use-router.ts +5 -2
- package/hooks/use-sentry-uncaught-errors.ts +24 -0
- package/instrumentation/index.ts +10 -0
- package/jest.config.js +19 -0
- package/lib/cache-handler.mjs +2 -2
- package/lib/cache.ts +4 -4
- package/localization/index.ts +2 -1
- package/middlewares/default.ts +31 -4
- package/middlewares/locale.ts +35 -11
- package/middlewares/url-redirection.ts +16 -0
- package/package.json +8 -4
- package/plugins.js +2 -1
- package/redux/middlewares/checkout.ts +30 -130
- package/redux/middlewares/index.ts +6 -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/tailwind/content.js +16 -0
- package/types/commerce/account.ts +5 -1
- package/types/commerce/checkout.ts +23 -0
- package/types/index.ts +7 -2
- package/utils/get-root-hostname.ts +28 -0
- package/utils/index.ts +6 -2
- 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
|
@@ -4,6 +4,7 @@ import { RetailStore } from './misc';
|
|
|
4
4
|
import { PaymentOption } from './order';
|
|
5
5
|
import { Product } from './product';
|
|
6
6
|
import { JSX } from 'react';
|
|
7
|
+
import { RootState, TypedDispatch } from 'redux/store';
|
|
7
8
|
|
|
8
9
|
export enum CheckoutStep {
|
|
9
10
|
Shipping = 'shipping',
|
|
@@ -107,6 +108,7 @@ export interface PreOrder {
|
|
|
107
108
|
context_extras?: ExtraField;
|
|
108
109
|
token?: string;
|
|
109
110
|
agreement_confirmed?: boolean;
|
|
111
|
+
phone_number?: string;
|
|
110
112
|
}
|
|
111
113
|
|
|
112
114
|
export type ExtraField = Record<string, any>;
|
|
@@ -186,3 +188,24 @@ export interface AttributeBasedShippingOption {
|
|
|
186
188
|
attribute_key: string;
|
|
187
189
|
[key: string]: any;
|
|
188
190
|
}
|
|
191
|
+
|
|
192
|
+
export interface CheckoutResult {
|
|
193
|
+
payload: {
|
|
194
|
+
errors?: Record<string, string[]>;
|
|
195
|
+
pre_order?: PreOrder;
|
|
196
|
+
context_list?: CheckoutContext[];
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export interface MiddlewareParams {
|
|
201
|
+
getState: () => RootState;
|
|
202
|
+
dispatch: TypedDispatch;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export type SendSmsType = {
|
|
206
|
+
phone_number: string;
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
export type VerifySmsType = {
|
|
210
|
+
verify_code: string;
|
|
211
|
+
};
|
package/types/index.ts
CHANGED
|
@@ -199,15 +199,17 @@ export interface Settings {
|
|
|
199
199
|
extraPaymentTypes?: string[];
|
|
200
200
|
masterpassJsUrl?: string;
|
|
201
201
|
};
|
|
202
|
-
customNotFoundEnabled: boolean;
|
|
203
202
|
useOptimizedTranslations?: boolean;
|
|
204
203
|
plugins?: Record<string, Record<string, any>>;
|
|
205
204
|
includedProxyHeaders?: string[];
|
|
205
|
+
commerceRedirectionIgnoreList?: string[];
|
|
206
206
|
/**
|
|
207
207
|
* By default, the currency will be reset when the currency is changed.
|
|
208
208
|
* If you want to keep the basket when the currency is changed, you can set this option to `false`.
|
|
209
209
|
*/
|
|
210
210
|
resetBasketOnCurrencyChange?: boolean;
|
|
211
|
+
frontendIds?: Record<string, number>;
|
|
212
|
+
customNotFoundEnabled: boolean;
|
|
211
213
|
}
|
|
212
214
|
|
|
213
215
|
export interface CacheOptions {
|
|
@@ -275,7 +277,10 @@ export interface IconProps extends React.ComponentPropsWithRef<'i'> {
|
|
|
275
277
|
|
|
276
278
|
export interface ButtonProps
|
|
277
279
|
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
278
|
-
appearance?: 'filled' | 'outlined' | 'ghost';
|
|
280
|
+
appearance?: 'filled' | 'outlined' | 'ghost' | 'link' | string;
|
|
281
|
+
size?: 'sm' | 'md' | 'lg' | 'xl';
|
|
282
|
+
href?: string;
|
|
283
|
+
target?: '_blank' | '_self' | '_parent' | '_top';
|
|
279
284
|
}
|
|
280
285
|
|
|
281
286
|
export type FileInputProps = React.HTMLProps<HTMLInputElement>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import Settings from 'settings';
|
|
2
|
+
|
|
3
|
+
export default function getRootHostname(
|
|
4
|
+
url: string | undefined
|
|
5
|
+
): string | null {
|
|
6
|
+
if (!url) return null;
|
|
7
|
+
|
|
8
|
+
try {
|
|
9
|
+
const urlObj = new URL(url);
|
|
10
|
+
const hostname = urlObj.hostname;
|
|
11
|
+
const parts = hostname.split('.');
|
|
12
|
+
|
|
13
|
+
const firstPart = parts[0];
|
|
14
|
+
|
|
15
|
+
const isLocale = Settings.localization.locales.some(
|
|
16
|
+
(locale) => locale.value === firstPart
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
if (isLocale) {
|
|
20
|
+
const hostnameAfterLocale = parts.slice(1).join('.');
|
|
21
|
+
return `.${hostnameAfterLocale}`;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return `.${hostname}`;
|
|
25
|
+
} catch {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
}
|
package/utils/index.ts
CHANGED
|
@@ -152,11 +152,15 @@ export function buildCDNUrl(url: string, config?: CDNOptions) {
|
|
|
152
152
|
return `${rootWithoutOptions}${options}${fileExtension}`;
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
+
const { locales, localeUrlStrategy, defaultLocaleValue } =
|
|
156
|
+
settings.localization;
|
|
157
|
+
|
|
155
158
|
export const urlLocaleMatcherRegex = new RegExp(
|
|
156
159
|
`^/(${settings.localization.locales
|
|
157
160
|
.filter((l) =>
|
|
158
|
-
|
|
159
|
-
|
|
161
|
+
![LocaleUrlStrategy.ShowAllLocales, LocaleUrlStrategy.Subdomain].includes(
|
|
162
|
+
settings.localization.localeUrlStrategy
|
|
163
|
+
)
|
|
160
164
|
? l.value !== settings.localization.defaultLocaleValue
|
|
161
165
|
: l
|
|
162
166
|
)
|
package/utils/localization.ts
CHANGED
|
@@ -11,6 +11,10 @@ export const getUrlPathWithLocale = (
|
|
|
11
11
|
currentLocale = defaultLocaleValue;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
if (localeUrlStrategy === LocaleUrlStrategy.Subdomain) {
|
|
15
|
+
return pathname;
|
|
16
|
+
}
|
|
17
|
+
|
|
14
18
|
if (localeUrlStrategy === LocaleUrlStrategy.HideAllLocales) {
|
|
15
19
|
return pathname;
|
|
16
20
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Middleware } from '@reduxjs/toolkit';
|
|
2
|
+
|
|
3
|
+
export enum MiddlewareNames {
|
|
4
|
+
PreOrderValidationMiddleware = 'preOrderValidationMiddleware',
|
|
5
|
+
RedirectionMiddleware = 'redirectionMiddleware',
|
|
6
|
+
SetPreOrderMiddleware = 'setPreOrderMiddleware',
|
|
7
|
+
DeliveryOptionMiddleware = 'deliveryOptionMiddleware',
|
|
8
|
+
SetAddressMiddleware = 'setAddressMiddleware',
|
|
9
|
+
ShippingOptionMiddleware = 'shippingOptionMiddleware',
|
|
10
|
+
DataSourceShippingOptionMiddleware = 'dataSourceShippingOptionMiddleware',
|
|
11
|
+
AttributeBasedShippingOptionMiddleware = 'attributeBasedShippingOptionMiddleware',
|
|
12
|
+
PaymentOptionMiddleware = 'paymentOptionMiddleware',
|
|
13
|
+
InstallmentOptionMiddleware = 'installmentOptionMiddleware',
|
|
14
|
+
ShippingStepMiddleware = 'shippingStepMiddleware'
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const overrideMiddleware = (
|
|
18
|
+
originalMiddlewares: Middleware[],
|
|
19
|
+
overrides: Record<string, Middleware>
|
|
20
|
+
): Middleware[] => {
|
|
21
|
+
return originalMiddlewares.map((middleware) => {
|
|
22
|
+
const middlewareKey = middleware.name || middleware.toString();
|
|
23
|
+
return overrides[middlewareKey] || middleware;
|
|
24
|
+
});
|
|
25
|
+
};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
import { useLocalization } from '../hooks';
|
|
3
|
+
import { Button, Link } from '../components';
|
|
4
|
+
import { ROUTES } from 'routes';
|
|
5
|
+
|
|
6
|
+
export default function PzErrorPage({
|
|
7
|
+
error,
|
|
8
|
+
reset
|
|
9
|
+
}: {
|
|
10
|
+
error: Error & { digest?: string; isServerError?: boolean };
|
|
11
|
+
reset: () => void;
|
|
12
|
+
}) {
|
|
13
|
+
const [isServerError, setIsServerError] = useState(false);
|
|
14
|
+
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
if ('isServerError' in error) {
|
|
17
|
+
setIsServerError(true);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
setIsServerError(!!error.digest);
|
|
22
|
+
}, [error]);
|
|
23
|
+
|
|
24
|
+
return isServerError ? (
|
|
25
|
+
<ServerErrorUI />
|
|
26
|
+
) : (
|
|
27
|
+
<ClientErrorUI error={error} reset={reset} />
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function ClientErrorUI({
|
|
32
|
+
error,
|
|
33
|
+
reset
|
|
34
|
+
}: {
|
|
35
|
+
error: Error & { digest?: string };
|
|
36
|
+
reset: () => void;
|
|
37
|
+
}) {
|
|
38
|
+
const { t } = useLocalization();
|
|
39
|
+
|
|
40
|
+
const errorMessage = error?.message || 'Unknown error';
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<section className="text-center px-6 py-6 my-14 md:px-0 md:m-14">
|
|
44
|
+
<div className="text-4xl font-bold md:text-6xl text-red-500">500</div>
|
|
45
|
+
<h1 className="text-lg md:text-xl mt-4">
|
|
46
|
+
{t('common.client_error.title')}
|
|
47
|
+
</h1>
|
|
48
|
+
<p className="text-lg md:text-xl mt-2">
|
|
49
|
+
{t('common.client_error.description')}
|
|
50
|
+
</p>
|
|
51
|
+
|
|
52
|
+
<div className="mt-4 mx-auto max-w-lg">
|
|
53
|
+
<p className="text-xs text-gray-600 font-mono bg-gray-100 p-3 rounded overflow-auto text-left">
|
|
54
|
+
<span className="font-semibold">Error:</span> {errorMessage}
|
|
55
|
+
</p>
|
|
56
|
+
</div>
|
|
57
|
+
|
|
58
|
+
<div className="mt-6 flex flex-col gap-4 items-center justify-center">
|
|
59
|
+
<Link href={ROUTES.HOME} className="text-lg underline">
|
|
60
|
+
{t('common.client_error.link_text')}
|
|
61
|
+
</Link>
|
|
62
|
+
<Button onClick={reset} className="text-lg">
|
|
63
|
+
{t('common.try_again')}
|
|
64
|
+
</Button>
|
|
65
|
+
</div>
|
|
66
|
+
</section>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function ServerErrorUI() {
|
|
71
|
+
const { t } = useLocalization();
|
|
72
|
+
|
|
73
|
+
const reloadPage = () => {
|
|
74
|
+
window.location.reload();
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<section className="text-center px-6 my-14 md:px-0 md:m-14">
|
|
79
|
+
<div className="text-7xl font-bold md:text-8xl">500</div>
|
|
80
|
+
<h1 className="text-lg md:text-xl"> {t('common.page_500.title')} </h1>
|
|
81
|
+
<p className="text-lg md:text-xl"> {t('common.page_500.description')} </p>
|
|
82
|
+
|
|
83
|
+
<div className="mt-6 flex flex-col gap-4 items-center justify-center">
|
|
84
|
+
<Link href={ROUTES.HOME} className="text-lg underline">
|
|
85
|
+
{t('common.page_500.link_text')}
|
|
86
|
+
</Link>
|
|
87
|
+
<Button onClick={reloadPage} className="text-lg">
|
|
88
|
+
{t('common.try_again')}
|
|
89
|
+
</Button>
|
|
90
|
+
</div>
|
|
91
|
+
</section>
|
|
92
|
+
);
|
|
93
|
+
}
|
package/with-pz-config.js
CHANGED
|
@@ -44,8 +44,9 @@ const defaultConfig = {
|
|
|
44
44
|
value: 'max-age=63072000; includeSubDomains; preload'
|
|
45
45
|
},
|
|
46
46
|
{
|
|
47
|
-
key: '
|
|
48
|
-
value:
|
|
47
|
+
key: 'Content-Security-Policy',
|
|
48
|
+
value:
|
|
49
|
+
"frame-ancestors 'self' https://*.akifast.com akifast.com https://*.akinoncloud.com akinoncloud.com"
|
|
49
50
|
}
|
|
50
51
|
]
|
|
51
52
|
}
|
|
@@ -64,7 +65,7 @@ const defaultConfig = {
|
|
|
64
65
|
},
|
|
65
66
|
sentry: {
|
|
66
67
|
hideSourceMaps: true
|
|
67
|
-
}
|
|
68
|
+
} // TODO: This section will be reviewed again in the Sentry 8 update.
|
|
68
69
|
};
|
|
69
70
|
|
|
70
71
|
const withPzConfig = (
|