@akinon/next 1.108.0-rc.87 → 1.108.0

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.
@@ -1,6 +1,15 @@
1
1
  import { resolve } from 'path';
2
2
  import type { NextConfig } from 'next';
3
- const findBaseDir = require('../utils/find-base-dir');
3
+
4
+ function findBaseDir() {
5
+ const insideNodeModules = __dirname.includes('node_modules');
6
+
7
+ if (insideNodeModules) {
8
+ return resolve(__dirname, '../../../../');
9
+ } else {
10
+ return resolve(__dirname, '../../../apps/projectzeronext');
11
+ }
12
+ }
4
13
 
5
14
  const baseDir = findBaseDir();
6
15
 
@@ -2,7 +2,6 @@
2
2
 
3
3
  const runScript = require('./run-script');
4
4
 
5
- runScript('pz-run-tests.js');
6
5
  runScript('pz-install-theme.js');
7
6
  runScript('pz-pre-check-dist.js');
8
7
  runScript('pz-generate-translations.js');
@@ -1,8 +1,6 @@
1
1
  import clsx from 'clsx';
2
2
  import { forwardRef, FocusEvent, useState, Ref } from 'react';
3
3
  import { Controller } from 'react-hook-form';
4
-
5
- // @ts-ignore
6
4
  import { PatternFormat, PatternFormatProps } from 'react-number-format';
7
5
  import { InputProps } from '../types';
8
6
  import { twMerge } from 'tailwind-merge';
@@ -10,9 +10,7 @@ type LinkProps = Omit<
10
10
  React.AnchorHTMLAttributes<HTMLAnchorElement>,
11
11
  keyof NextLinkProps
12
12
  > &
13
- NextLinkProps & {
14
- href: string;
15
- };
13
+ NextLinkProps;
16
14
 
17
15
  export const Link = ({ children, href, ...rest }: LinkProps) => {
18
16
  const { locale, defaultLocaleValue, localeUrlStrategy } = useLocalization();
@@ -28,21 +26,19 @@ export const Link = ({ children, href, ...rest }: LinkProps) => {
28
26
  return href;
29
27
  }
30
28
 
31
- if (typeof href === 'string' && !href.startsWith('http')) {
32
- const pathnameWithoutLocale = href.replace(urlLocaleMatcherRegex, '');
33
- const hrefWithLocale = `/${locale}${pathnameWithoutLocale}`;
34
-
35
- if (localeUrlStrategy === LocaleUrlStrategy.ShowAllLocales) {
36
- return hrefWithLocale;
37
- } else if (
38
- localeUrlStrategy === LocaleUrlStrategy.HideDefaultLocale &&
39
- locale !== defaultLocaleValue
40
- ) {
41
- return hrefWithLocale;
42
- }
29
+ const pathnameWithoutLocale = href.replace(urlLocaleMatcherRegex, '');
30
+ const hrefWithLocale = `/${locale}${pathnameWithoutLocale}`;
31
+
32
+ if (localeUrlStrategy === LocaleUrlStrategy.ShowAllLocales) {
33
+ return hrefWithLocale;
34
+ } else if (
35
+ localeUrlStrategy === LocaleUrlStrategy.HideDefaultLocale &&
36
+ locale !== defaultLocaleValue
37
+ ) {
38
+ return hrefWithLocale;
43
39
  }
44
40
 
45
- return href;
41
+ return href || '#';
46
42
  }, [href, defaultLocaleValue, locale, localeUrlStrategy]);
47
43
 
48
44
  return (
@@ -35,10 +35,8 @@ import {
35
35
 
36
36
  interface CheckoutResponse {
37
37
  pre_order?: PreOrder;
38
- errors?: {
39
- non_field_errors?: string;
40
- sample_products?: string[];
41
- [key: string]: string | string[] | undefined;
38
+ errors: {
39
+ non_field_errors: string;
42
40
  };
43
41
  context_list?: CheckoutContext[];
44
42
  template_name?: string;
@@ -499,12 +497,22 @@ export const checkoutApi = api.injectEndpoints({
499
497
  dispatch(setPaymentStepBusy(false));
500
498
  }
501
499
  }),
502
- setWalletCompletePage: build.mutation<CheckoutResponse, boolean>({
503
- query: (success: boolean) => ({
504
- url: buildClientRequestUrl(checkout.setWalletCompletePage),
500
+ setWalletCompletePage: build.mutation<
501
+ CheckoutResponse,
502
+ {
503
+ success: boolean;
504
+ cko_payment_id?: string;
505
+ [key: string]: any;
506
+ }
507
+ >({
508
+ query: ({ success, ...additionalParams }) => ({
509
+ url: buildClientRequestUrl(checkout.setWalletCompletePage, {
510
+ useFormData: true
511
+ }),
505
512
  method: 'POST',
506
513
  body: {
507
- success
514
+ success,
515
+ ...additionalParams
508
516
  }
509
517
  }),
510
518
  async onQueryStarted(arg, { dispatch, queryFulfilled }) {
@@ -5,6 +5,7 @@ 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';
8
9
  import { ServerVariables } from '../../utils/server-variables';
9
10
 
10
11
  function getCategoryDataHandler(
@@ -17,30 +18,19 @@ function getCategoryDataHandler(
17
18
  return async function () {
18
19
  const params = generateCommerceSearchParams(searchParams);
19
20
 
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
- }
21
+ const rawData = await appFetch<string>({
22
+ url: `${category.getCategoryByPk(pk)}${params ? params : ''}`,
23
+ locale,
24
+ currency,
25
+ init: {
26
+ headers: {
27
+ Accept: 'application/json',
28
+ 'Content-Type': 'application/json',
29
+ ...(headers ?? {})
30
+ }
31
+ },
32
+ responseType: FetchResponseType.TEXT
33
+ });
44
34
 
45
35
  let data: GetCategoryResponse;
46
36
 
@@ -74,27 +64,17 @@ function getCategoryDataHandler(
74
64
  return { data, breadcrumbData: undefined };
75
65
  }
76
66
 
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
- }
67
+ const breadcrumbData = await appFetch<any>({
68
+ url: product.breadcrumbUrl(menuItemModel),
69
+ locale,
70
+ currency,
71
+ init: {
72
+ headers: {
73
+ Accept: 'application/json',
74
+ 'Content-Type': 'application/json'
89
75
  }
90
- });
91
- } catch (error) {
92
- logger.warn('Failed to fetch breadcrumb data', {
93
- handler: 'getCategoryDataHandler',
94
- pk,
95
- error: error.message
96
- });
97
- }
76
+ }
77
+ });
98
78
 
99
79
  return { data, breadcrumbData: breadcrumbData?.menu };
100
80
  };
@@ -11,24 +11,20 @@ const getFlatPageDataHandler = (
11
11
  headers?: Record<string, string>
12
12
  ) => {
13
13
  return async function () {
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
- }
14
+ const data = await appFetch<FlatPage>({
15
+ url: flatpage.getFlatPageByPk(pk),
16
+ locale,
17
+ currency,
18
+ init: {
19
+ headers: {
20
+ Accept: 'application/json',
21
+ 'Content-Type': 'application/json',
22
+ ...(headers ?? {})
25
23
  }
26
- });
24
+ }
25
+ });
27
26
 
28
- return data;
29
- } catch (error) {
30
- return null;
31
- }
27
+ return data;
32
28
  };
33
29
  };
34
30
 
@@ -11,24 +11,20 @@ const getLandingPageHandler = (
11
11
  headers?: Record<string, string>
12
12
  ) => {
13
13
  return async function () {
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
- }
14
+ const data = await appFetch<LandingPage>({
15
+ url: landingpage.getLandingPageByPk(pk),
16
+ locale,
17
+ currency,
18
+ init: {
19
+ headers: {
20
+ Accept: 'application/json',
21
+ 'Content-Type': 'application/json',
22
+ ...(headers ?? {})
25
23
  }
26
- });
24
+ }
25
+ });
27
26
 
28
- return data;
29
- } catch (error) {
30
- return null;
31
- }
27
+ return data;
32
28
  };
33
29
  };
34
30
 
@@ -16,29 +16,19 @@ const getListDataHandler = (
16
16
  return async function () {
17
17
  const params = generateCommerceSearchParams(searchParams);
18
18
 
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
- }
19
+ const rawData = await appFetch<string>({
20
+ url: `${category.list}${params}`,
21
+ locale,
22
+ currency,
23
+ init: {
24
+ headers: {
25
+ Accept: 'application/json',
26
+ 'Content-Type': 'application/json',
27
+ ...(headers ?? {})
28
+ }
29
+ },
30
+ responseType: FetchResponseType.TEXT
31
+ });
42
32
 
43
33
  let data: GetCategoryResponse;
44
34
 
@@ -15,24 +15,20 @@ const getSpecialPageDataHandler = (
15
15
  return async function () {
16
16
  const params = generateCommerceSearchParams(searchParams);
17
17
 
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
- }
18
+ const data: GetCategoryResponse = await appFetch({
19
+ url: `${category.getSpecialPageByPk(pk)}${params}`,
20
+ locale,
21
+ currency,
22
+ init: {
23
+ headers: {
24
+ Accept: 'application/json',
25
+ 'Content-Type': 'application/json',
26
+ ...(headers ?? {})
29
27
  }
30
- });
28
+ }
29
+ });
31
30
 
32
- return data;
33
- } catch (error) {
34
- return null;
35
- }
31
+ return data;
36
32
  };
37
33
  };
38
34
 
package/data/urls.ts CHANGED
@@ -183,11 +183,7 @@ export const product = {
183
183
  breadcrumbUrl: (menuitemmodel: string) =>
184
184
  `/menus/generate_breadcrumb/?item=${menuitemmodel}&generator_name=menu_item`,
185
185
  bundleProduct: (productPk: string, queryString: string) =>
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
+ `/bundle-product/${productPk}/?${queryString}`
191
187
  };
192
188
 
193
189
  export const wishlist = {
@@ -72,13 +72,10 @@ const addRootLayoutProps = async (componentProps: RootLayoutProps) => {
72
72
  const checkRedisVariables = () => {
73
73
  const requiredVariableValues = [
74
74
  process.env.CACHE_HOST,
75
- process.env.CACHE_PORT
75
+ process.env.CACHE_PORT,
76
+ process.env.CACHE_SECRET
76
77
  ];
77
78
 
78
- if (!settings.usePrettyUrlRoute) {
79
- requiredVariableValues.push(process.env.CACHE_SECRET);
80
- }
81
-
82
79
  if (
83
80
  !requiredVariableValues.every((v) => v) &&
84
81
  process.env.NODE_ENV === 'production'
@@ -4,6 +4,7 @@ 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';
7
8
 
8
9
  export const useLocalization = () => {
9
10
  const {
@@ -17,6 +18,8 @@ export const useLocalization = () => {
17
18
  localeUrlStrategy
18
19
  } = useContext(LocalizationContext);
19
20
 
21
+ const router = useRouter();
22
+
20
23
  /**
21
24
  * Sets the locale in the URL.
22
25
  * @param locale Locale value defined in the settings.
@@ -27,8 +30,6 @@ export const useLocalization = () => {
27
30
 
28
31
  let targetUrl;
29
32
 
30
- setCookie('pz-locale', locale);
31
-
32
33
  if (localeUrlStrategy === LocaleUrlStrategy.Subdomain) {
33
34
  const hostParts = hostname.split('.');
34
35
  const subDomain = hostParts[0];
@@ -148,8 +148,7 @@ const withCompleteGpay =
148
148
  logger.info('Redirecting to order success page', {
149
149
  middleware: 'complete-gpay',
150
150
  redirectUrlWithLocale,
151
- ip,
152
- setCookie: request.headers.get('set-cookie')
151
+ ip
153
152
  });
154
153
 
155
154
  // Using POST method while redirecting causes an error,
@@ -149,8 +149,7 @@ const withCompleteMasterpass =
149
149
  logger.info('Redirecting to order success page', {
150
150
  middleware: 'complete-masterpass',
151
151
  redirectUrlWithLocale,
152
- ip,
153
- setCookie: request.headers.get('set-cookie')
152
+ ip
154
153
  });
155
154
 
156
155
  // Using POST method while redirecting causes an error,
@@ -23,15 +23,7 @@ const getMatchedLocale = (pathname: string, req: PzNextRequest) => {
23
23
  );
24
24
 
25
25
  if (subDomainLocaleMatched && subDomainLocaleMatched[0]) {
26
- const subdomainLocale = subDomainLocaleMatched[0].slice(1);
27
-
28
- const isValidSubdomainLocale = settings.localization.locales.find(
29
- (l) => l.value === subdomainLocale
30
- );
31
-
32
- if (isValidSubdomainLocale) {
33
- matchedLocale = subdomainLocale;
34
- }
26
+ matchedLocale = subDomainLocaleMatched[0].slice(1);
35
27
  }
36
28
  }
37
29
  }
@@ -149,8 +149,7 @@ const withRedirectionPayment =
149
149
  logger.info('Redirecting to order success page', {
150
150
  middleware: 'redirection-payment',
151
151
  redirectUrlWithLocale,
152
- ip,
153
- setCookie: request.headers.get('set-cookie')
152
+ ip
154
153
  });
155
154
 
156
155
  // Using POST method while redirecting causes an error,
@@ -149,8 +149,7 @@ const withSavedCardRedirection =
149
149
  logger.info('Redirecting to order success page', {
150
150
  middleware: 'saved-card-redirection',
151
151
  redirectUrlWithLocale,
152
- ip,
153
- setCookie: request.headers.get('set-cookie')
152
+ ip
154
153
  });
155
154
 
156
155
  // Using POST method while redirecting causes an error,
@@ -148,8 +148,7 @@ const withThreeDRedirection =
148
148
  logger.info('Redirecting to order success page', {
149
149
  middleware: 'three-d-redirection',
150
150
  redirectUrlWithLocale,
151
- ip,
152
- setCookie: request.headers.get('set-cookie')
151
+ ip
153
152
  });
154
153
 
155
154
  // Using POST method while redirecting causes an error,
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": "1.108.0-rc.87",
4
+ "version": "1.108.0",
5
5
  "private": false,
6
6
  "license": "MIT",
7
7
  "bin": {
@@ -35,7 +35,7 @@
35
35
  "set-cookie-parser": "2.6.0"
36
36
  },
37
37
  "devDependencies": {
38
- "@akinon/eslint-plugin-projectzero": "1.108.0-rc.87",
38
+ "@akinon/eslint-plugin-projectzero": "1.108.0",
39
39
  "@babel/core": "7.26.10",
40
40
  "@babel/preset-env": "7.26.9",
41
41
  "@babel/preset-typescript": "7.27.0",
package/plugins.d.ts CHANGED
@@ -46,11 +46,3 @@ declare module '@akinon/pz-cybersource-uc' {
46
46
  }
47
47
 
48
48
  declare module '@akinon/pz-flow-payment' {}
49
-
50
- declare module '@akinon/pz-similar-products' {
51
- export const SimilarProductsModal: any;
52
- export const SimilarProductsFilterSidebar: any;
53
- export const SimilarProductsResultsGrid: any;
54
- export const SimilarProductsPlugin: any;
55
- export const SimilarProductsButtonPlugin: any;
56
- }
@@ -51,11 +51,7 @@ export const errorMiddleware: Middleware = ({ dispatch }: MiddlewareParams) => {
51
51
  const result: CheckoutResult = next(action);
52
52
  const errors = result?.payload?.errors;
53
53
 
54
- if (
55
- !!errors &&
56
- ((typeof errors === 'object' && Object.keys(errors).length > 0) ||
57
- (Array.isArray(errors) && errors.length > 0))
58
- ) {
54
+ if (errors) {
59
55
  dispatch(setErrors(errors));
60
56
  }
61
57
 
@@ -108,6 +108,7 @@ export interface PreOrder {
108
108
  token?: string;
109
109
  agreement_confirmed?: boolean;
110
110
  phone_number?: string;
111
+ number?: string;
111
112
  }
112
113
 
113
114
  export type ExtraField = Record<string, any>;
@@ -114,7 +114,6 @@ export interface Order {
114
114
  pk: number;
115
115
  name: string;
116
116
  slug: string;
117
- logo: string;
118
117
  [key: string]: any;
119
118
  };
120
119
  }
package/types/index.ts CHANGED
@@ -83,12 +83,6 @@ 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;
92
86
  redis: {
93
87
  defaultExpirationTime: number;
94
88
  };
@@ -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(),
47
46
  ...(init.headers ?? {}),
48
47
  ...(ServerVariables.globalHeaders ?? {}),
49
48
  'Accept-Language': currentLocale.apiValue,
50
49
  'x-currency': currency,
51
- 'x-forwarded-for': ip
50
+ 'x-forwarded-for': ip,
51
+ cookie: nextCookies.toString()
52
52
  };
53
53
 
54
54
  init.next = {
@@ -60,11 +60,6 @@ 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
-
68
63
  if (responseType === FetchResponseType.JSON) {
69
64
  response = (await req.json()) as T;
70
65
  } else {
package/utils/redirect.ts CHANGED
@@ -1,33 +1,18 @@
1
1
  import { redirect as nextRedirect, RedirectType } from 'next/navigation';
2
2
  import Settings from 'settings';
3
- import { headers, cookies } from 'next/headers';
3
+ import { headers } from 'next/headers';
4
+ import { ServerVariables } from '@akinon/next/utils/server-variables';
4
5
  import { getUrlPathWithLocale } from '@akinon/next/utils/localization';
5
6
  import { urlLocaleMatcherRegex } from '@akinon/next/utils';
6
7
 
7
8
  export const redirect = (path: string, type?: RedirectType) => {
8
9
  const nextHeaders = headers();
9
- const nextCookies = cookies();
10
10
  const pageUrl = new URL(
11
11
  nextHeaders.get('pz-url') ?? process.env.NEXT_PUBLIC_URL ?? ''
12
12
  );
13
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
-
29
14
  const currentLocale = Settings.localization.locales.find(
30
- (locale) => locale.value === currentLocaleValue
15
+ (locale) => locale.value === ServerVariables.locale
31
16
  );
32
17
 
33
18
  const searchParams = new URLSearchParams(pageUrl.search);