@akinon/next 1.14.0 → 1.14.1

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 (119) hide show
  1. package/.eslintrc.js +40 -40
  2. package/.prettierrc +13 -13
  3. package/CHANGELOG.md +6 -0
  4. package/api/auth.ts +231 -231
  5. package/api/cache.ts +44 -44
  6. package/api/client.ts +174 -174
  7. package/api/logout.ts +42 -42
  8. package/bin/pz-check-dependencies.js +98 -98
  9. package/bin/pz-install-plugins.js +33 -33
  10. package/bin/pz-install-theme.js +58 -58
  11. package/bin/pz-postbuild.js +1 -1
  12. package/bin/pz-postdev.js +1 -1
  13. package/bin/pz-postinstall.js +6 -6
  14. package/bin/pz-poststart.js +1 -1
  15. package/bin/pz-prebuild.js +4 -4
  16. package/bin/pz-predev.js +4 -4
  17. package/bin/pz-prestart.js +1 -1
  18. package/bin/run-script.js +44 -44
  19. package/components/accordion.tsx +52 -52
  20. package/components/button.tsx +46 -46
  21. package/components/client-root.tsx +19 -19
  22. package/components/icon.tsx +18 -18
  23. package/components/image.tsx +133 -133
  24. package/components/index.ts +17 -17
  25. package/components/input.tsx +110 -110
  26. package/components/lazy-component.tsx +33 -33
  27. package/components/loader-spinner.tsx +23 -23
  28. package/components/mobile-app-toggler.tsx +26 -26
  29. package/components/oauth-login.tsx +24 -24
  30. package/components/price.tsx +55 -55
  31. package/components/pz-providers.tsx +24 -24
  32. package/components/pz-root.tsx +21 -21
  33. package/components/radio.tsx +18 -18
  34. package/components/react-portal.tsx +45 -45
  35. package/components/redirect-three-d/content/index.tsx +74 -74
  36. package/components/redirect-three-d/index.tsx +17 -17
  37. package/components/trans.tsx +39 -39
  38. package/data/client/account.ts +208 -208
  39. package/data/client/api.ts +85 -85
  40. package/data/client/basket.ts +82 -82
  41. package/data/client/misc.ts +101 -101
  42. package/data/client/product.ts +89 -89
  43. package/data/client/user.ts +99 -99
  44. package/data/client/wishlist.ts +118 -118
  45. package/data/server/category.ts +132 -132
  46. package/data/server/flatpage.ts +21 -21
  47. package/data/server/form.ts +22 -22
  48. package/data/server/index.ts +10 -10
  49. package/data/server/landingpage.ts +24 -24
  50. package/data/server/list.ts +67 -67
  51. package/data/server/menu.ts +35 -35
  52. package/data/server/product.ts +86 -86
  53. package/data/server/seo.ts +48 -48
  54. package/data/server/special-page.ts +47 -47
  55. package/data/server/widget.ts +27 -27
  56. package/data/urls.ts +221 -221
  57. package/hocs/client/index.ts +1 -1
  58. package/hocs/client/with-segment-defaults.tsx +25 -25
  59. package/hocs/server/index.ts +1 -1
  60. package/hocs/server/with-segment-defaults.tsx +85 -85
  61. package/hooks/index.ts +10 -10
  62. package/hooks/use-captcha.tsx +76 -76
  63. package/hooks/use-common-product-attributes.ts +36 -36
  64. package/hooks/use-debounce.ts +20 -20
  65. package/hooks/use-localization.ts +78 -78
  66. package/hooks/use-media-query.ts +36 -36
  67. package/hooks/use-mobile-iframe-handler.ts +23 -23
  68. package/hooks/use-on-click-outside.tsx +28 -28
  69. package/hooks/use-router.ts +45 -45
  70. package/hooks/use-translation.ts +14 -14
  71. package/lib/cache.ts +215 -215
  72. package/localization/index.ts +5 -5
  73. package/localization/provider.tsx +58 -58
  74. package/middlewares/currency.ts +100 -100
  75. package/middlewares/default.ts +256 -256
  76. package/middlewares/index.ts +29 -29
  77. package/middlewares/locale.ts +68 -68
  78. package/middlewares/oauth-login.ts +79 -79
  79. package/middlewares/pretty-url.ts +104 -104
  80. package/middlewares/redirection-payment.ts +160 -160
  81. package/middlewares/three-d-redirection.ts +159 -159
  82. package/middlewares/url-redirection.ts +65 -65
  83. package/package.json +2 -2
  84. package/redux/hooks.ts +7 -7
  85. package/redux/middlewares/index.ts +50 -50
  86. package/redux/reducers/checkout.ts +184 -184
  87. package/redux/reducers/config.ts +28 -28
  88. package/redux/reducers/header.ts +59 -59
  89. package/redux/reducers/root.ts +61 -61
  90. package/sentry/index.ts +27 -27
  91. package/tailwind/rtl.js +137 -137
  92. package/types/commerce/account.ts +64 -64
  93. package/types/commerce/address.ts +94 -94
  94. package/types/commerce/basket.ts +43 -43
  95. package/types/commerce/category.ts +114 -114
  96. package/types/commerce/checkout.ts +143 -143
  97. package/types/commerce/flatpage.ts +7 -7
  98. package/types/commerce/form.ts +66 -66
  99. package/types/commerce/index.ts +12 -12
  100. package/types/commerce/landingpage.ts +7 -7
  101. package/types/commerce/misc.ts +127 -127
  102. package/types/commerce/order.ts +119 -119
  103. package/types/commerce/product.ts +109 -109
  104. package/types/commerce/widget.ts +28 -28
  105. package/types/gtm.ts +16 -16
  106. package/types/index.ts +274 -274
  107. package/types/metadata.ts +7 -7
  108. package/types/next-auth.d.ts +24 -24
  109. package/utils/app-fetch.ts +69 -69
  110. package/utils/deep-merge.js +24 -24
  111. package/utils/image-loader.ts +31 -31
  112. package/utils/index.ts +150 -150
  113. package/utils/localization.ts +29 -29
  114. package/utils/log.ts +138 -138
  115. package/utils/menu-generator.ts +27 -27
  116. package/utils/mobile-3d-iframe.ts +77 -77
  117. package/utils/server-translation.ts +57 -57
  118. package/utils/server-variables.ts +9 -9
  119. package/with-pz-config.js +94 -94
package/lib/cache.ts CHANGED
@@ -1,215 +1,215 @@
1
- import { RedisClientType } from 'redis';
2
- import Settings from 'settings';
3
- import { CacheOptions } from '../types';
4
- import logger from '../utils/log';
5
- import { ServerVariables } from '../utils/server-variables';
6
-
7
- const hashCacheKey = (object?: Record<string, string>) => {
8
- if (!object) {
9
- return '';
10
- }
11
- const sortedFilters = Object.entries(object).sort(([firstKey], [secondKey]) =>
12
- firstKey.localeCompare(secondKey)
13
- );
14
-
15
- const cacheKey = Buffer.from(
16
- JSON.stringify(Object.fromEntries(sortedFilters))
17
- ).toString('base64');
18
-
19
- return `_${encodeURIComponent(cacheKey)}`;
20
- };
21
- export const CacheKey = {
22
- List: (searchParams: URLSearchParams, headers?: Record<string, string>) =>
23
- `list_${encodeURIComponent(JSON.stringify(searchParams))}${hashCacheKey(
24
- headers
25
- )}`,
26
- Category: (
27
- pk: number,
28
- searchParams?: URLSearchParams,
29
- headers?: Record<string, string>
30
- ) =>
31
- `category_${pk}_${encodeURIComponent(
32
- JSON.stringify(searchParams)
33
- )}${hashCacheKey(headers)}`,
34
- CategorySlug: (slug: string) => `category_${slug}`,
35
- SpecialPage: (
36
- pk: number,
37
- searchParams: URLSearchParams,
38
- headers?: Record<string, string>
39
- ) =>
40
- `special_page_${pk}_${encodeURIComponent(
41
- JSON.stringify(searchParams)
42
- )}${hashCacheKey(headers)}`,
43
- Product: (pk: number, searchParams: URLSearchParams) =>
44
- `product_${pk}_${encodeURIComponent(JSON.stringify(searchParams))}`,
45
- GroupProduct: (pk: number, searchParams: URLSearchParams) =>
46
- `group_product_${pk}_${encodeURIComponent(JSON.stringify(searchParams))}`,
47
- FlatPage: (pk: number) => `flat_page_${pk}`,
48
- LandingPage: (pk: number) => `landing_page_${pk}`,
49
- Widget: (slug: string) => `widget_${slug}`,
50
- PrettyUrl: (pathname: string) => `pretty_url_${pathname}`,
51
- Menu: (depth: number, parent?: string) =>
52
- `menu_${depth}${parent ? `_${parent}` : ''}`,
53
- Seo: (url: string) => `seo_${url}`,
54
- RootSeo: 'root_seo',
55
- Form: (pk: number) => `form_${pk}`
56
- };
57
-
58
- export class Cache {
59
- static PROXY_URL = `${process.env.NEXT_PUBLIC_URL}/api/cache`;
60
-
61
- static formatKey(key: string) {
62
- return encodeURIComponent(
63
- `${Settings.commerceUrl}_${ServerVariables.locale}_${key}`
64
- );
65
- }
66
-
67
- static async getClient() {
68
- const { createClient } = await import('redis');
69
- const redisUrl = `redis://${process.env.CACHE_HOST}:${
70
- process.env.CACHE_PORT
71
- }/${process.env.CACHE_BUCKET ?? '0'}`;
72
-
73
- const client: RedisClientType = createClient({
74
- url: redisUrl
75
- });
76
-
77
- client.on('error', (error) => {
78
- logger.error('Redis client error', { redisUrl, error });
79
- });
80
-
81
- return client;
82
- }
83
-
84
- static async get(key: string) {
85
- let value;
86
- let client;
87
-
88
- try {
89
- client = await Cache.getClient();
90
- await client.connect();
91
- value = JSON.parse(await client.get(key));
92
-
93
- logger.debug('Redis get success', { key });
94
- logger.trace('Redis get success', { key, value });
95
- } catch (error) {
96
- logger.error('Redis get error', { key, error });
97
- } finally {
98
- await client?.disconnect();
99
- }
100
-
101
- return value;
102
- }
103
-
104
- static async set(key: string, value: string, expire?: number) {
105
- let success = false;
106
- let client;
107
-
108
- try {
109
- client = await Cache.getClient();
110
- await client.connect();
111
- await client.set(key, value, {
112
- EX: expire
113
- });
114
-
115
- success = true;
116
-
117
- logger.debug('Redis set success', { key });
118
- logger.trace('Redis set success', { key, value });
119
- } catch (error) {
120
- logger.error('Redis set error', { key, error });
121
- } finally {
122
- await client?.disconnect();
123
- }
124
-
125
- return success;
126
- }
127
-
128
- static async wrap<T = any>(
129
- key: string,
130
- handler: () => Promise<T>,
131
- options?: CacheOptions
132
- ): Promise<T> {
133
- const requiredVariables = [
134
- process.env.CACHE_HOST,
135
- process.env.CACHE_PORT,
136
- process.env.CACHE_SECRET
137
- ];
138
-
139
- if (!requiredVariables.every((v) => v)) {
140
- return await handler();
141
- }
142
-
143
- const defaultOptions: CacheOptions = {
144
- cache: true,
145
- expire: Settings.redis.defaultExpirationTime
146
- };
147
-
148
- const _options = Object.assign(defaultOptions, options);
149
- const formattedKey = Cache.formatKey(key);
150
-
151
- logger.debug('Cache wrap', { key, formattedKey, _options });
152
-
153
- if (_options.cache) {
154
- let cachedValue;
155
-
156
- if (_options.useProxy) {
157
- const body = new URLSearchParams();
158
-
159
- body.append('key', formattedKey);
160
-
161
- cachedValue = await Cache.proxyRequest('POST', body);
162
- logger.debug('Cache proxy request success', { key });
163
- logger.trace('Cache proxy request', { key, cachedValue });
164
- } else {
165
- cachedValue = await Cache.get(formattedKey);
166
- }
167
-
168
- if (cachedValue) {
169
- return cachedValue;
170
- }
171
- }
172
-
173
- logger.debug('Redis cache miss. Setting new value...', { key });
174
-
175
- const data = await handler();
176
-
177
- if (data && _options.cache) {
178
- if (_options.useProxy) {
179
- try {
180
- const body = new URLSearchParams();
181
-
182
- body.append('key', formattedKey);
183
- body.append('value', JSON.stringify(data));
184
- body.append(
185
- 'expire',
186
- String(_options?.expire ?? Settings.redis.defaultExpirationTime)
187
- );
188
- await Cache.proxyRequest('PUT', body);
189
-
190
- logger.debug('Cache proxy request', { key, body: body.toString() });
191
- } catch (error) {
192
- logger.error('Cache proxy error', error);
193
- }
194
- } else {
195
- await Cache.set(formattedKey, JSON.stringify(data), _options?.expire);
196
- }
197
- }
198
-
199
- return data;
200
- }
201
-
202
- static async proxyRequest(method: 'POST' | 'PUT', body: URLSearchParams) {
203
- const response = await (
204
- await fetch(Cache.PROXY_URL, {
205
- method,
206
- headers: {
207
- authorization: process.env.CACHE_SECRET
208
- },
209
- body
210
- })
211
- ).json();
212
-
213
- return response;
214
- }
215
- }
1
+ import { RedisClientType } from 'redis';
2
+ import Settings from 'settings';
3
+ import { CacheOptions } from '../types';
4
+ import logger from '../utils/log';
5
+ import { ServerVariables } from '../utils/server-variables';
6
+
7
+ const hashCacheKey = (object?: Record<string, string>) => {
8
+ if (!object) {
9
+ return '';
10
+ }
11
+ const sortedFilters = Object.entries(object).sort(([firstKey], [secondKey]) =>
12
+ firstKey.localeCompare(secondKey)
13
+ );
14
+
15
+ const cacheKey = Buffer.from(
16
+ JSON.stringify(Object.fromEntries(sortedFilters))
17
+ ).toString('base64');
18
+
19
+ return `_${encodeURIComponent(cacheKey)}`;
20
+ };
21
+ export const CacheKey = {
22
+ List: (searchParams: URLSearchParams, headers?: Record<string, string>) =>
23
+ `list_${encodeURIComponent(JSON.stringify(searchParams))}${hashCacheKey(
24
+ headers
25
+ )}`,
26
+ Category: (
27
+ pk: number,
28
+ searchParams?: URLSearchParams,
29
+ headers?: Record<string, string>
30
+ ) =>
31
+ `category_${pk}_${encodeURIComponent(
32
+ JSON.stringify(searchParams)
33
+ )}${hashCacheKey(headers)}`,
34
+ CategorySlug: (slug: string) => `category_${slug}`,
35
+ SpecialPage: (
36
+ pk: number,
37
+ searchParams: URLSearchParams,
38
+ headers?: Record<string, string>
39
+ ) =>
40
+ `special_page_${pk}_${encodeURIComponent(
41
+ JSON.stringify(searchParams)
42
+ )}${hashCacheKey(headers)}`,
43
+ Product: (pk: number, searchParams: URLSearchParams) =>
44
+ `product_${pk}_${encodeURIComponent(JSON.stringify(searchParams))}`,
45
+ GroupProduct: (pk: number, searchParams: URLSearchParams) =>
46
+ `group_product_${pk}_${encodeURIComponent(JSON.stringify(searchParams))}`,
47
+ FlatPage: (pk: number) => `flat_page_${pk}`,
48
+ LandingPage: (pk: number) => `landing_page_${pk}`,
49
+ Widget: (slug: string) => `widget_${slug}`,
50
+ PrettyUrl: (pathname: string) => `pretty_url_${pathname}`,
51
+ Menu: (depth: number, parent?: string) =>
52
+ `menu_${depth}${parent ? `_${parent}` : ''}`,
53
+ Seo: (url: string) => `seo_${url}`,
54
+ RootSeo: 'root_seo',
55
+ Form: (pk: number) => `form_${pk}`
56
+ };
57
+
58
+ export class Cache {
59
+ static PROXY_URL = `${process.env.NEXT_PUBLIC_URL}/api/cache`;
60
+
61
+ static formatKey(key: string) {
62
+ return encodeURIComponent(
63
+ `${Settings.commerceUrl}_${ServerVariables.locale}_${key}`
64
+ );
65
+ }
66
+
67
+ static async getClient() {
68
+ const { createClient } = await import('redis');
69
+ const redisUrl = `redis://${process.env.CACHE_HOST}:${
70
+ process.env.CACHE_PORT
71
+ }/${process.env.CACHE_BUCKET ?? '0'}`;
72
+
73
+ const client: RedisClientType = createClient({
74
+ url: redisUrl
75
+ });
76
+
77
+ client.on('error', (error) => {
78
+ logger.error('Redis client error', { redisUrl, error });
79
+ });
80
+
81
+ return client;
82
+ }
83
+
84
+ static async get(key: string) {
85
+ let value;
86
+ let client;
87
+
88
+ try {
89
+ client = await Cache.getClient();
90
+ await client.connect();
91
+ value = JSON.parse(await client.get(key));
92
+
93
+ logger.debug('Redis get success', { key });
94
+ logger.trace('Redis get success', { key, value });
95
+ } catch (error) {
96
+ logger.error('Redis get error', { key, error });
97
+ } finally {
98
+ await client?.disconnect();
99
+ }
100
+
101
+ return value;
102
+ }
103
+
104
+ static async set(key: string, value: string, expire?: number) {
105
+ let success = false;
106
+ let client;
107
+
108
+ try {
109
+ client = await Cache.getClient();
110
+ await client.connect();
111
+ await client.set(key, value, {
112
+ EX: expire
113
+ });
114
+
115
+ success = true;
116
+
117
+ logger.debug('Redis set success', { key });
118
+ logger.trace('Redis set success', { key, value });
119
+ } catch (error) {
120
+ logger.error('Redis set error', { key, error });
121
+ } finally {
122
+ await client?.disconnect();
123
+ }
124
+
125
+ return success;
126
+ }
127
+
128
+ static async wrap<T = any>(
129
+ key: string,
130
+ handler: () => Promise<T>,
131
+ options?: CacheOptions
132
+ ): Promise<T> {
133
+ const requiredVariables = [
134
+ process.env.CACHE_HOST,
135
+ process.env.CACHE_PORT,
136
+ process.env.CACHE_SECRET
137
+ ];
138
+
139
+ if (!requiredVariables.every((v) => v)) {
140
+ return await handler();
141
+ }
142
+
143
+ const defaultOptions: CacheOptions = {
144
+ cache: true,
145
+ expire: Settings.redis.defaultExpirationTime
146
+ };
147
+
148
+ const _options = Object.assign(defaultOptions, options);
149
+ const formattedKey = Cache.formatKey(key);
150
+
151
+ logger.debug('Cache wrap', { key, formattedKey, _options });
152
+
153
+ if (_options.cache) {
154
+ let cachedValue;
155
+
156
+ if (_options.useProxy) {
157
+ const body = new URLSearchParams();
158
+
159
+ body.append('key', formattedKey);
160
+
161
+ cachedValue = await Cache.proxyRequest('POST', body);
162
+ logger.debug('Cache proxy request success', { key });
163
+ logger.trace('Cache proxy request', { key, cachedValue });
164
+ } else {
165
+ cachedValue = await Cache.get(formattedKey);
166
+ }
167
+
168
+ if (cachedValue) {
169
+ return cachedValue;
170
+ }
171
+ }
172
+
173
+ logger.debug('Redis cache miss. Setting new value...', { key });
174
+
175
+ const data = await handler();
176
+
177
+ if (data && _options.cache) {
178
+ if (_options.useProxy) {
179
+ try {
180
+ const body = new URLSearchParams();
181
+
182
+ body.append('key', formattedKey);
183
+ body.append('value', JSON.stringify(data));
184
+ body.append(
185
+ 'expire',
186
+ String(_options?.expire ?? Settings.redis.defaultExpirationTime)
187
+ );
188
+ await Cache.proxyRequest('PUT', body);
189
+
190
+ logger.debug('Cache proxy request', { key, body: body.toString() });
191
+ } catch (error) {
192
+ logger.error('Cache proxy error', error);
193
+ }
194
+ } else {
195
+ await Cache.set(formattedKey, JSON.stringify(data), _options?.expire);
196
+ }
197
+ }
198
+
199
+ return data;
200
+ }
201
+
202
+ static async proxyRequest(method: 'POST' | 'PUT', body: URLSearchParams) {
203
+ const response = await (
204
+ await fetch(Cache.PROXY_URL, {
205
+ method,
206
+ headers: {
207
+ authorization: process.env.CACHE_SECRET
208
+ },
209
+ body
210
+ })
211
+ ).json();
212
+
213
+ return response;
214
+ }
215
+ }
@@ -1,5 +1,5 @@
1
- export enum LocaleUrlStrategy {
2
- HideAllLocales = 'hide-all-locales',
3
- HideDefaultLocale = 'hide-default-locale',
4
- ShowAllLocales = 'show-all-locales'
5
- }
1
+ export enum LocaleUrlStrategy {
2
+ HideAllLocales = 'hide-all-locales',
3
+ HideDefaultLocale = 'hide-default-locale',
4
+ ShowAllLocales = 'show-all-locales'
5
+ }
@@ -1,58 +1,58 @@
1
- 'use client';
2
-
3
- import React, { createContext } from 'react';
4
- import { getTranslateFn } from '../utils';
5
- import { useParams } from 'next/navigation';
6
- import { Currency, Locale } from '../types';
7
- import settings from 'settings';
8
-
9
- export const LocalizationContext = createContext(
10
- {} as {
11
- translate: (path: string) => string;
12
- locale: string;
13
- currency: string;
14
- locales: Locale[];
15
- currencies: Currency[];
16
- defaultLocaleValue: string;
17
- defaultCurrencyCode: string;
18
- localeUrlStrategy?: string;
19
- }
20
- );
21
-
22
- export default function LocalizationProvider({
23
- children,
24
- translations
25
- }: {
26
- children: React.ReactNode;
27
- translations: any;
28
- }) {
29
- const {
30
- locales,
31
- currencies,
32
- defaultLocaleValue,
33
- defaultCurrencyCode,
34
- localeUrlStrategy
35
- } = settings.localization;
36
-
37
- const { locale, currency } = useParams() as {
38
- locale: string;
39
- currency: string;
40
- };
41
-
42
- return (
43
- <LocalizationContext.Provider
44
- value={{
45
- translate: (path: string) => getTranslateFn(path, translations),
46
- locale,
47
- currency,
48
- locales,
49
- currencies,
50
- defaultLocaleValue,
51
- defaultCurrencyCode,
52
- localeUrlStrategy
53
- }}
54
- >
55
- {children}
56
- </LocalizationContext.Provider>
57
- );
58
- }
1
+ 'use client';
2
+
3
+ import React, { createContext } from 'react';
4
+ import { getTranslateFn } from '../utils';
5
+ import { useParams } from 'next/navigation';
6
+ import { Currency, Locale } from '../types';
7
+ import settings from 'settings';
8
+
9
+ export const LocalizationContext = createContext(
10
+ {} as {
11
+ translate: (path: string) => string;
12
+ locale: string;
13
+ currency: string;
14
+ locales: Locale[];
15
+ currencies: Currency[];
16
+ defaultLocaleValue: string;
17
+ defaultCurrencyCode: string;
18
+ localeUrlStrategy?: string;
19
+ }
20
+ );
21
+
22
+ export default function LocalizationProvider({
23
+ children,
24
+ translations
25
+ }: {
26
+ children: React.ReactNode;
27
+ translations: any;
28
+ }) {
29
+ const {
30
+ locales,
31
+ currencies,
32
+ defaultLocaleValue,
33
+ defaultCurrencyCode,
34
+ localeUrlStrategy
35
+ } = settings.localization;
36
+
37
+ const { locale, currency } = useParams() as {
38
+ locale: string;
39
+ currency: string;
40
+ };
41
+
42
+ return (
43
+ <LocalizationContext.Provider
44
+ value={{
45
+ translate: (path: string) => getTranslateFn(path, translations),
46
+ locale,
47
+ currency,
48
+ locales,
49
+ currencies,
50
+ defaultLocaleValue,
51
+ defaultCurrencyCode,
52
+ localeUrlStrategy
53
+ }}
54
+ >
55
+ {children}
56
+ </LocalizationContext.Provider>
57
+ );
58
+ }