@akinon/next 1.99.0-snapshot-ZERO-3640-20250919140935 → 1.100.0-rc.71

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 (54) hide show
  1. package/CHANGELOG.md +1337 -51
  2. package/__tests__/next-config.test.ts +1 -10
  3. package/__tests__/redirect.test.ts +319 -0
  4. package/api/cache.ts +41 -5
  5. package/api/form.ts +84 -0
  6. package/api/image-proxy.ts +75 -0
  7. package/api/similar-product-list.ts +84 -0
  8. package/api/similar-products.ts +120 -0
  9. package/bin/pz-generate-routes.js +105 -0
  10. package/bin/pz-prebuild.js +1 -0
  11. package/bin/pz-predev.js +1 -0
  12. package/components/accordion.tsx +20 -5
  13. package/components/file-input.tsx +65 -3
  14. package/components/input.tsx +2 -0
  15. package/components/link.tsx +16 -12
  16. package/components/modal.tsx +32 -16
  17. package/components/plugin-module.tsx +32 -4
  18. package/data/client/checkout.ts +4 -2
  19. package/data/server/basket.ts +72 -0
  20. package/data/server/category.ts +48 -26
  21. package/data/server/flatpage.ts +20 -13
  22. package/data/server/form.ts +4 -1
  23. package/data/server/landingpage.ts +20 -13
  24. package/data/server/list.ts +25 -14
  25. package/data/server/menu.ts +4 -1
  26. package/data/server/product.ts +68 -40
  27. package/data/server/seo.ts +4 -1
  28. package/data/server/special-page.ts +18 -13
  29. package/data/server/widget.ts +4 -1
  30. package/data/urls.ts +6 -2
  31. package/hocs/server/with-segment-defaults.tsx +5 -2
  32. package/hooks/use-localization.ts +2 -3
  33. package/jest.config.js +7 -1
  34. package/lib/cache-handler.mjs +365 -87
  35. package/lib/cache.ts +254 -25
  36. package/middlewares/complete-gpay.ts +2 -1
  37. package/middlewares/complete-masterpass.ts +2 -1
  38. package/middlewares/default.ts +50 -13
  39. package/middlewares/locale.ts +9 -1
  40. package/middlewares/pretty-url.ts +21 -6
  41. package/middlewares/redirection-payment.ts +2 -1
  42. package/middlewares/saved-card-redirection.ts +2 -1
  43. package/middlewares/three-d-redirection.ts +2 -2
  44. package/middlewares/url-redirection.ts +8 -14
  45. package/package.json +4 -3
  46. package/plugins.d.ts +8 -5
  47. package/plugins.js +3 -1
  48. package/redux/middlewares/checkout.ts +5 -1
  49. package/types/commerce/order.ts +1 -0
  50. package/types/index.ts +35 -1
  51. package/utils/app-fetch.ts +7 -2
  52. package/utils/redirect-ignore.ts +35 -0
  53. package/utils/redirect.ts +31 -6
  54. package/with-pz-config.js +1 -5
package/plugins.js CHANGED
@@ -16,5 +16,7 @@ module.exports = [
16
16
  'pz-tabby-extension',
17
17
  'pz-apple-pay',
18
18
  'pz-tamara-extension',
19
- 'pz-flow-payment'
19
+ 'pz-hepsipay',
20
+ 'pz-flow-payment',
21
+ 'pz-similar-products'
20
22
  ];
@@ -51,7 +51,11 @@ export const errorMiddleware: Middleware = ({ dispatch }: MiddlewareParams) => {
51
51
  const result: CheckoutResult = next(action);
52
52
  const errors = result?.payload?.errors;
53
53
 
54
- if (errors) {
54
+ if (
55
+ !!errors &&
56
+ ((typeof errors === 'object' && Object.keys(errors).length > 0) ||
57
+ (Array.isArray(errors) && errors.length > 0))
58
+ ) {
55
59
  dispatch(setErrors(errors));
56
60
  }
57
61
 
@@ -114,6 +114,7 @@ export interface Order {
114
114
  pk: number;
115
115
  name: string;
116
116
  slug: string;
117
+ logo: string;
117
118
  [key: string]: any;
118
119
  };
119
120
  }
package/types/index.ts CHANGED
@@ -83,6 +83,12 @@ export interface Settings {
83
83
  };
84
84
  usePrettyUrlRoute?: boolean;
85
85
  commerceUrl: string;
86
+ /**
87
+ * This option allows you to track Sentry events on the client side, in addition to server and edge environments.
88
+ *
89
+ * It overrides process.env.NEXT_PUBLIC_SENTRY_DSN and process.env.SENTRY_DSN.
90
+ */
91
+ sentryDsn?: string;
86
92
  redis: {
87
93
  defaultExpirationTime: number;
88
94
  };
@@ -216,6 +222,7 @@ export interface CacheOptions {
216
222
  cache?: boolean;
217
223
  expire?: number;
218
224
  useProxy?: boolean;
225
+ compressed?: boolean;
219
226
  }
220
227
 
221
228
  export interface SetCookieOptions {
@@ -291,7 +298,13 @@ export interface ButtonProps
291
298
  target?: '_blank' | '_self' | '_parent' | '_top';
292
299
  }
293
300
 
294
- export type FileInputProps = React.HTMLProps<HTMLInputElement>;
301
+ export interface FileInputProps extends React.HTMLProps<HTMLInputElement> {
302
+ fileClassName?: string;
303
+ fileNameWrapperClassName?: string;
304
+ fileInputClassName?: string;
305
+ onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
306
+ buttonClassName?: string;
307
+ }
295
308
 
296
309
  export interface PriceProps {
297
310
  currencyCode?: string;
@@ -312,15 +325,19 @@ export interface InputProps extends React.HTMLProps<HTMLInputElement> {
312
325
 
313
326
  export interface AccordionProps {
314
327
  isCollapse?: boolean;
328
+ collapseClassName?: string;
315
329
  title?: string;
316
330
  subTitle?: string;
317
331
  icons?: string[];
318
332
  iconSize?: number;
319
333
  iconColor?: string;
320
334
  children?: ReactNode;
335
+ headerClassName?: string;
321
336
  className?: string;
322
337
  titleClassName?: string;
338
+ subTitleClassName?: string;
323
339
  dataTestId?: string;
340
+ contentClassName?: string;
324
341
  }
325
342
 
326
343
  export interface PluginModuleComponentProps {
@@ -345,3 +362,20 @@ export interface PaginationProps {
345
362
  direction?: 'next' | 'prev';
346
363
  isLoading?: boolean;
347
364
  }
365
+
366
+ export interface ModalProps {
367
+ portalId: string;
368
+ children?: React.ReactNode;
369
+ open?: boolean;
370
+ setOpen?: (open: boolean) => void;
371
+ title?: React.ReactNode;
372
+ showCloseButton?: React.ReactNode;
373
+ className?: string;
374
+ overlayClassName?: string;
375
+ headerWrapperClassName?: string;
376
+ titleClassName?: string;
377
+ closeButtonClassName?: string;
378
+ iconName?: string;
379
+ iconSize?: number;
380
+ iconClassName?: string;
381
+ }
@@ -43,12 +43,12 @@ const appFetch = async <T>({
43
43
  const requestURL = `${decodeURIComponent(commerceUrl)}${url}`;
44
44
 
45
45
  init.headers = {
46
+ cookie: nextCookies.toString(),
46
47
  ...(init.headers ?? {}),
47
48
  ...(ServerVariables.globalHeaders ?? {}),
48
49
  'Accept-Language': currentLocale.apiValue,
49
50
  'x-currency': currency,
50
- 'x-forwarded-for': ip,
51
- cookie: nextCookies.toString()
51
+ 'x-forwarded-for': ip
52
52
  };
53
53
 
54
54
  init.next = {
@@ -60,6 +60,11 @@ const appFetch = async <T>({
60
60
  status = req.status;
61
61
  logger.debug(`FETCH END ${url}`, { status: req.status, ip });
62
62
 
63
+ if (!req.ok) {
64
+ const errorMessage = `HTTP ${req.status}: ${req.statusText}`;
65
+ throw new Error(errorMessage);
66
+ }
67
+
63
68
  if (responseType === FetchResponseType.JSON) {
64
69
  response = (await req.json()) as T;
65
70
  } else {
@@ -0,0 +1,35 @@
1
+ import settings from 'settings';
2
+ import { getUrlPathWithLocale } from './localization';
3
+
4
+ type IgnorePath = string | RegExp;
5
+
6
+ const defaultIgnoreList: string[] = [];
7
+
8
+ const extraIgnores: IgnorePath[] = Array.isArray(
9
+ settings.commerceRedirectionIgnoreList
10
+ )
11
+ ? settings.commerceRedirectionIgnoreList.map((path) => {
12
+ if (path === '/users/reset') {
13
+ return /^\/users\/reset\/[^/]+\/[^/]+\/$/;
14
+ }
15
+ return path;
16
+ })
17
+ : [];
18
+
19
+ export function shouldIgnoreRedirect(
20
+ pathname: string,
21
+ locale: string
22
+ ): boolean {
23
+ if (!pathname) return false;
24
+
25
+ const rawIgnoreList: IgnorePath[] = [...defaultIgnoreList, ...extraIgnores];
26
+
27
+ return rawIgnoreList.some((ignorePath) => {
28
+ if (ignorePath instanceof RegExp) {
29
+ return ignorePath.test(pathname);
30
+ }
31
+
32
+ const localized = getUrlPathWithLocale(ignorePath, locale);
33
+ return localized === pathname;
34
+ });
35
+ }
package/utils/redirect.ts CHANGED
@@ -1,23 +1,48 @@
1
1
  import { redirect as nextRedirect, RedirectType } from 'next/navigation';
2
2
  import Settings from 'settings';
3
- import { headers } from 'next/headers';
4
- import { ServerVariables } from '@akinon/next/utils/server-variables';
3
+ import { headers, cookies } from 'next/headers';
5
4
  import { getUrlPathWithLocale } from '@akinon/next/utils/localization';
5
+ import { urlLocaleMatcherRegex } from '@akinon/next/utils';
6
6
 
7
7
  export const redirect = (path: string, type?: RedirectType) => {
8
8
  const nextHeaders = headers();
9
+ const nextCookies = cookies();
9
10
  const pageUrl = new URL(
10
- nextHeaders.get('pz-url') ?? process.env.NEXT_PUBLIC_URL
11
+ nextHeaders.get('pz-url') ?? process.env.NEXT_PUBLIC_URL ?? ''
11
12
  );
12
13
 
14
+ let currentLocaleValue = Settings.localization.defaultLocaleValue;
15
+ const urlLocaleMatch = pageUrl.pathname.match(urlLocaleMatcherRegex);
16
+
17
+ if (urlLocaleMatch && urlLocaleMatch[0]) {
18
+ currentLocaleValue = urlLocaleMatch[0].replace('/', '');
19
+ } else {
20
+ const cookieLocale = nextCookies.get('pz-locale')?.value;
21
+ if (
22
+ cookieLocale &&
23
+ Settings.localization.locales.find((l) => l.value === cookieLocale)
24
+ ) {
25
+ currentLocaleValue = cookieLocale;
26
+ }
27
+ }
28
+
13
29
  const currentLocale = Settings.localization.locales.find(
14
- (locale) => locale.value === ServerVariables.locale
30
+ (locale) => locale.value === currentLocaleValue
15
31
  );
16
32
 
17
- const callbackUrl = pageUrl.pathname;
33
+ if (!currentLocale) {
34
+ currentLocaleValue = Settings.localization.defaultLocaleValue;
35
+ }
36
+
37
+ const searchParams = new URLSearchParams(pageUrl.search);
38
+
39
+ const callbackUrl =
40
+ pageUrl.pathname.replace(urlLocaleMatcherRegex, '') +
41
+ (searchParams.toString() ? `?${searchParams.toString()}` : '');
42
+
18
43
  const redirectUrlWithLocale = getUrlPathWithLocale(
19
44
  path,
20
- currentLocale.localePath ?? currentLocale.value
45
+ currentLocale?.value
21
46
  );
22
47
 
23
48
  const redirectUrl = `${redirectUrlWithLocale}?callbackUrl=${callbackUrl}`;
package/with-pz-config.js CHANGED
@@ -16,12 +16,8 @@ const defaultConfig = {
16
16
  remotePatterns: [
17
17
  {
18
18
  protocol: 'https',
19
- hostname: '**.akinoncloud.com'
19
+ hostname: '**'
20
20
  },
21
- {
22
- protocol: 'https',
23
- hostname: '**.akinoncdn.com'
24
- }
25
21
  ]
26
22
  },
27
23
  modularizeImports: {