@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/api/client.ts CHANGED
@@ -1,174 +1,174 @@
1
- import { ClientRequestOptions } from '../types';
2
- import { NextResponse } from 'next/server';
3
- import settings from 'settings';
4
- import logger from '../utils/log';
5
-
6
- interface RouteParams {
7
- params: {
8
- slug: string[];
9
- };
10
- }
11
-
12
- async function proxyRequest(...args) {
13
- const [req, { params }] = args as [req: Request, params: RouteParams];
14
- const { searchParams } = new URL(req.url);
15
- const commerceUrl = settings.commerceUrl;
16
-
17
- if (commerceUrl === 'default') {
18
- return NextResponse.json(
19
- { error: 'Commerce URL not found' },
20
- { status: 404 }
21
- );
22
- }
23
-
24
- const options: ClientRequestOptions = {
25
- useTrailingSlash: true,
26
- useFormData: false,
27
- contentType: null,
28
- accept: 'application/json',
29
- responseType: 'json'
30
- };
31
-
32
- const slug = `${params.slug.join('/')}/`;
33
- const options_ = JSON.parse(
34
- decodeURIComponent((searchParams.get('options') as string) ?? '{}')
35
- );
36
- const urlSearchParams = new URLSearchParams();
37
-
38
- Object.assign(options, options_);
39
-
40
- Array.from(searchParams.keys())
41
- .filter((key) => !['slug', 'options'].includes(key))
42
- .forEach((key) => {
43
- urlSearchParams.append(key, `${searchParams.get(key)}`);
44
- });
45
-
46
- const extraHeaders = Object.fromEntries(req.headers.entries());
47
-
48
- [
49
- 'x-forwarded-host',
50
- 'x-forwarded-for',
51
- 'x-forwarded-proto',
52
- 'x-forwarded-port',
53
- 'origin',
54
- 'host',
55
- 'referer',
56
- 'accept',
57
- 'content-length',
58
- 'content-type'
59
- ].forEach((header) => delete extraHeaders[header]);
60
-
61
- const fetchOptions = {
62
- method: req.method,
63
- headers: {
64
- ...extraHeaders,
65
- 'X-Requested-With': 'XMLHttpRequest',
66
- Referer: commerceUrl,
67
- Accept: options.accept
68
- }
69
- } as RequestInit;
70
-
71
- if (options.contentType) {
72
- fetchOptions.headers['Content-Type'] = options.contentType;
73
- }
74
-
75
- if (req.method !== 'GET') {
76
- const formData = new URLSearchParams();
77
- let body = {};
78
-
79
- try {
80
- body = await req.json();
81
- } catch (error) {
82
- logger.error(
83
- `Client Proxy Request - Error while parsing request body to JSON`,
84
- {
85
- url: req.url,
86
- error
87
- }
88
- );
89
- }
90
-
91
- Object.keys(body ?? {}).forEach((key) => {
92
- if (body[key]) {
93
- formData.append(key, body[key]);
94
- }
95
- });
96
-
97
- fetchOptions.body = !options.useFormData ? JSON.stringify(body) : formData;
98
- }
99
-
100
- let url = `${commerceUrl}/${slug.replace(/,/g, '/')}`;
101
-
102
- if (!options.useTrailingSlash) {
103
- url = url.replace(/\/$/, '');
104
- }
105
-
106
- if (urlSearchParams.toString().length) {
107
- url += `?${urlSearchParams.toString()}`;
108
- }
109
-
110
- try {
111
- const request = await fetch(url, fetchOptions);
112
- let response = {} as any;
113
-
114
- try {
115
- response = await (options.responseType === 'text'
116
- ? request.text()
117
- : request.json());
118
- } catch (error) {
119
- logger.error(
120
- `Client Proxy Request - Error while parsing response body to ${options.responseType}`,
121
- {
122
- url,
123
- status: request.status,
124
- fetchOptions: JSON.stringify(fetchOptions),
125
- error
126
- }
127
- );
128
- }
129
-
130
- const setCookieHeader = request.headers.get('set-cookie');
131
- const responseHeaders: any = {};
132
-
133
- if (setCookieHeader) {
134
- responseHeaders['set-cookie'] = setCookieHeader;
135
- }
136
-
137
- const statusCode = new RegExp(/^20./).test(request.status.toString())
138
- ? 200
139
- : request.status;
140
-
141
- return NextResponse.json(
142
- options.responseType === 'text' ? { result: response } : response,
143
- { status: statusCode, headers: responseHeaders }
144
- );
145
- } catch (error) {
146
- logger.error('Client proxy request failed', error);
147
-
148
- return NextResponse.json({ error }, { status: 500 });
149
- }
150
- }
151
-
152
- export async function GET(...args) {
153
- return proxyRequest(...args);
154
- }
155
-
156
- export async function POST(...args) {
157
- return proxyRequest(...args);
158
- }
159
-
160
- export async function PUT(...args) {
161
- return proxyRequest(...args);
162
- }
163
-
164
- export async function PATCH(...args) {
165
- return proxyRequest(...args);
166
- }
167
-
168
- export async function DELETE(...args) {
169
- return proxyRequest(...args);
170
- }
171
-
172
- export async function HEAD(...args) {
173
- return proxyRequest(...args);
174
- }
1
+ import { ClientRequestOptions } from '../types';
2
+ import { NextResponse } from 'next/server';
3
+ import settings from 'settings';
4
+ import logger from '../utils/log';
5
+
6
+ interface RouteParams {
7
+ params: {
8
+ slug: string[];
9
+ };
10
+ }
11
+
12
+ async function proxyRequest(...args) {
13
+ const [req, { params }] = args as [req: Request, params: RouteParams];
14
+ const { searchParams } = new URL(req.url);
15
+ const commerceUrl = settings.commerceUrl;
16
+
17
+ if (commerceUrl === 'default') {
18
+ return NextResponse.json(
19
+ { error: 'Commerce URL not found' },
20
+ { status: 404 }
21
+ );
22
+ }
23
+
24
+ const options: ClientRequestOptions = {
25
+ useTrailingSlash: true,
26
+ useFormData: false,
27
+ contentType: null,
28
+ accept: 'application/json',
29
+ responseType: 'json'
30
+ };
31
+
32
+ const slug = `${params.slug.join('/')}/`;
33
+ const options_ = JSON.parse(
34
+ decodeURIComponent((searchParams.get('options') as string) ?? '{}')
35
+ );
36
+ const urlSearchParams = new URLSearchParams();
37
+
38
+ Object.assign(options, options_);
39
+
40
+ Array.from(searchParams.keys())
41
+ .filter((key) => !['slug', 'options'].includes(key))
42
+ .forEach((key) => {
43
+ urlSearchParams.append(key, `${searchParams.get(key)}`);
44
+ });
45
+
46
+ const extraHeaders = Object.fromEntries(req.headers.entries());
47
+
48
+ [
49
+ 'x-forwarded-host',
50
+ 'x-forwarded-for',
51
+ 'x-forwarded-proto',
52
+ 'x-forwarded-port',
53
+ 'origin',
54
+ 'host',
55
+ 'referer',
56
+ 'accept',
57
+ 'content-length',
58
+ 'content-type'
59
+ ].forEach((header) => delete extraHeaders[header]);
60
+
61
+ const fetchOptions = {
62
+ method: req.method,
63
+ headers: {
64
+ ...extraHeaders,
65
+ 'X-Requested-With': 'XMLHttpRequest',
66
+ Referer: commerceUrl,
67
+ Accept: options.accept
68
+ }
69
+ } as RequestInit;
70
+
71
+ if (options.contentType) {
72
+ fetchOptions.headers['Content-Type'] = options.contentType;
73
+ }
74
+
75
+ if (req.method !== 'GET') {
76
+ const formData = new URLSearchParams();
77
+ let body = {};
78
+
79
+ try {
80
+ body = await req.json();
81
+ } catch (error) {
82
+ logger.error(
83
+ `Client Proxy Request - Error while parsing request body to JSON`,
84
+ {
85
+ url: req.url,
86
+ error
87
+ }
88
+ );
89
+ }
90
+
91
+ Object.keys(body ?? {}).forEach((key) => {
92
+ if (body[key]) {
93
+ formData.append(key, body[key]);
94
+ }
95
+ });
96
+
97
+ fetchOptions.body = !options.useFormData ? JSON.stringify(body) : formData;
98
+ }
99
+
100
+ let url = `${commerceUrl}/${slug.replace(/,/g, '/')}`;
101
+
102
+ if (!options.useTrailingSlash) {
103
+ url = url.replace(/\/$/, '');
104
+ }
105
+
106
+ if (urlSearchParams.toString().length) {
107
+ url += `?${urlSearchParams.toString()}`;
108
+ }
109
+
110
+ try {
111
+ const request = await fetch(url, fetchOptions);
112
+ let response = {} as any;
113
+
114
+ try {
115
+ response = await (options.responseType === 'text'
116
+ ? request.text()
117
+ : request.json());
118
+ } catch (error) {
119
+ logger.error(
120
+ `Client Proxy Request - Error while parsing response body to ${options.responseType}`,
121
+ {
122
+ url,
123
+ status: request.status,
124
+ fetchOptions: JSON.stringify(fetchOptions),
125
+ error
126
+ }
127
+ );
128
+ }
129
+
130
+ const setCookieHeader = request.headers.get('set-cookie');
131
+ const responseHeaders: any = {};
132
+
133
+ if (setCookieHeader) {
134
+ responseHeaders['set-cookie'] = setCookieHeader;
135
+ }
136
+
137
+ const statusCode = new RegExp(/^20./).test(request.status.toString())
138
+ ? 200
139
+ : request.status;
140
+
141
+ return NextResponse.json(
142
+ options.responseType === 'text' ? { result: response } : response,
143
+ { status: statusCode, headers: responseHeaders }
144
+ );
145
+ } catch (error) {
146
+ logger.error('Client proxy request failed', error);
147
+
148
+ return NextResponse.json({ error }, { status: 500 });
149
+ }
150
+ }
151
+
152
+ export async function GET(...args) {
153
+ return proxyRequest(...args);
154
+ }
155
+
156
+ export async function POST(...args) {
157
+ return proxyRequest(...args);
158
+ }
159
+
160
+ export async function PUT(...args) {
161
+ return proxyRequest(...args);
162
+ }
163
+
164
+ export async function PATCH(...args) {
165
+ return proxyRequest(...args);
166
+ }
167
+
168
+ export async function DELETE(...args) {
169
+ return proxyRequest(...args);
170
+ }
171
+
172
+ export async function HEAD(...args) {
173
+ return proxyRequest(...args);
174
+ }
package/api/logout.ts CHANGED
@@ -1,42 +1,42 @@
1
- import { URLS } from '../data/urls';
2
- import { NextResponse } from 'next/server';
3
-
4
- export async function POST(req: Request) {
5
- const regexText1 = /name=['|"]csrfmiddlewaretoken['|"] value=['|"]\w+/gi;
6
- const regexText2 = /name=['|"]csrfmiddlewaretoken['|"] value=['|"]/gi;
7
- let sessionCookie;
8
-
9
- if (req.headers.get('osessionid')) {
10
- sessionCookie = `osessionid=${req.headers.get('osessionid')}`;
11
- }
12
-
13
- const requestLogoutStep1 = await fetch(URLS.user.logout, {
14
- method: 'POST',
15
- headers: {
16
- Cookie: `${sessionCookie}`
17
- }
18
- });
19
-
20
- const responseHtml = await requestLogoutStep1.text();
21
- const csrfTokenMatch = responseHtml.match(regexText1);
22
- const csrfToken = csrfTokenMatch?.[0].replace(regexText2, '') || '';
23
- const formData = new URLSearchParams();
24
-
25
- formData.append('csrfmiddlewaretoken', csrfToken);
26
-
27
- try {
28
- const requestLogoutStep2 = await fetch(URLS.user.logout, {
29
- method: 'POST',
30
- headers: {
31
- Cookie: `csrftoken=${csrfToken}; ${sessionCookie}`
32
- },
33
- body: formData
34
- });
35
-
36
- return NextResponse.json(requestLogoutStep2, {
37
- status: requestLogoutStep2.status
38
- });
39
- } catch (error) {
40
- return NextResponse.json(error, { status: 500 });
41
- }
42
- }
1
+ import { URLS } from '../data/urls';
2
+ import { NextResponse } from 'next/server';
3
+
4
+ export async function POST(req: Request) {
5
+ const regexText1 = /name=['|"]csrfmiddlewaretoken['|"] value=['|"]\w+/gi;
6
+ const regexText2 = /name=['|"]csrfmiddlewaretoken['|"] value=['|"]/gi;
7
+ let sessionCookie;
8
+
9
+ if (req.headers.get('osessionid')) {
10
+ sessionCookie = `osessionid=${req.headers.get('osessionid')}`;
11
+ }
12
+
13
+ const requestLogoutStep1 = await fetch(URLS.user.logout, {
14
+ method: 'POST',
15
+ headers: {
16
+ Cookie: `${sessionCookie}`
17
+ }
18
+ });
19
+
20
+ const responseHtml = await requestLogoutStep1.text();
21
+ const csrfTokenMatch = responseHtml.match(regexText1);
22
+ const csrfToken = csrfTokenMatch?.[0].replace(regexText2, '') || '';
23
+ const formData = new URLSearchParams();
24
+
25
+ formData.append('csrfmiddlewaretoken', csrfToken);
26
+
27
+ try {
28
+ const requestLogoutStep2 = await fetch(URLS.user.logout, {
29
+ method: 'POST',
30
+ headers: {
31
+ Cookie: `csrftoken=${csrfToken}; ${sessionCookie}`
32
+ },
33
+ body: formData
34
+ });
35
+
36
+ return NextResponse.json(requestLogoutStep2, {
37
+ status: requestLogoutStep2.status
38
+ });
39
+ } catch (error) {
40
+ return NextResponse.json(error, { status: 500 });
41
+ }
42
+ }
@@ -1,98 +1,98 @@
1
- #!/usr/bin/env node
2
-
3
- const fs = require('fs');
4
- const path = require('path');
5
- const semver = require('semver');
6
-
7
- function checkDir() {
8
- let currentDir = __dirname;
9
-
10
- while (currentDir !== path.resolve(currentDir, '..')) {
11
- if (
12
- fs.existsSync(
13
- path.join(currentDir, 'node_modules/@akinon/next/package.json')
14
- )
15
- ) {
16
- return currentDir;
17
- }
18
- currentDir = path.resolve(currentDir, '..');
19
- }
20
-
21
- return path.resolve(__dirname, '../../../../');
22
- }
23
-
24
- const BASE_DIR = checkDir();
25
-
26
- try {
27
- const akinonNextPackagePath = fs.existsSync(
28
- path.join(BASE_DIR, 'packages/akinon-next/package.json')
29
- )
30
- ? path.join(BASE_DIR, 'packages/akinon-next/package.json')
31
- : path.join(BASE_DIR, 'node_modules/@akinon/next/package.json');
32
-
33
- let akinonNextPackage = JSON.parse(
34
- fs.readFileSync(akinonNextPackagePath, 'utf8')
35
- );
36
-
37
- const projectZeroPwaPackagePath = path.join(BASE_DIR, 'package.json');
38
-
39
- const projectZeroPwaPackage = JSON.parse(
40
- fs.readFileSync(projectZeroPwaPackagePath, 'utf8')
41
- );
42
-
43
- const { peerDependencies } = akinonNextPackage;
44
-
45
- let hasErrors = false;
46
-
47
- let errorMessages = [];
48
-
49
- for (const dependency in peerDependencies) {
50
- const requiredVersion = peerDependencies[dependency];
51
-
52
- const installedVersion =
53
- projectZeroPwaPackage.dependencies[dependency] ||
54
- projectZeroPwaPackage.devDependencies[dependency];
55
-
56
- if (!installedVersion) {
57
- errorMessages.push(
58
- `Dependency ${dependency} is missing in projectzeropwa.`
59
- );
60
- hasErrors = true;
61
- } else {
62
- const requiredSemver = semver.coerce(requiredVersion);
63
-
64
- const installedSemver = semver.coerce(installedVersion);
65
-
66
- if (!requiredSemver || !installedSemver) {
67
- errorMessages.push(
68
- `Invalid semver for ${dependency}: required ${requiredVersion}, found ${installedVersion}`
69
- );
70
- hasErrors = true;
71
- } else if (
72
- requiredSemver.major !== installedSemver.major ||
73
- requiredSemver.minor !== installedSemver.minor
74
- ) {
75
- errorMessages.push(
76
- `Version mismatch for ${dependency}: expected ${requiredVersion} or higher but found ${installedVersion}`
77
- );
78
- hasErrors = true;
79
- }
80
- }
81
- }
82
-
83
- if (hasErrors) {
84
- console.error(
85
- '\x1b[31mDependency errors found:\n' +
86
- errorMessages.join('\n') +
87
- '\x1b[0m'
88
- );
89
- process.exit(1);
90
- }
91
-
92
- console.log(
93
- 'All dependencies are installed and compatible in projectzeropwa.'
94
- );
95
- } catch (error) {
96
- console.error('\x1b[31mError:', error.message + '\x1b[0m');
97
- process.exit(1);
98
- }
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const semver = require('semver');
6
+
7
+ function checkDir() {
8
+ let currentDir = __dirname;
9
+
10
+ while (currentDir !== path.resolve(currentDir, '..')) {
11
+ if (
12
+ fs.existsSync(
13
+ path.join(currentDir, 'node_modules/@akinon/next/package.json')
14
+ )
15
+ ) {
16
+ return currentDir;
17
+ }
18
+ currentDir = path.resolve(currentDir, '..');
19
+ }
20
+
21
+ return path.resolve(__dirname, '../../../../');
22
+ }
23
+
24
+ const BASE_DIR = checkDir();
25
+
26
+ try {
27
+ const akinonNextPackagePath = fs.existsSync(
28
+ path.join(BASE_DIR, 'packages/akinon-next/package.json')
29
+ )
30
+ ? path.join(BASE_DIR, 'packages/akinon-next/package.json')
31
+ : path.join(BASE_DIR, 'node_modules/@akinon/next/package.json');
32
+
33
+ let akinonNextPackage = JSON.parse(
34
+ fs.readFileSync(akinonNextPackagePath, 'utf8')
35
+ );
36
+
37
+ const projectZeroPwaPackagePath = path.join(BASE_DIR, 'package.json');
38
+
39
+ const projectZeroPwaPackage = JSON.parse(
40
+ fs.readFileSync(projectZeroPwaPackagePath, 'utf8')
41
+ );
42
+
43
+ const { peerDependencies } = akinonNextPackage;
44
+
45
+ let hasErrors = false;
46
+
47
+ let errorMessages = [];
48
+
49
+ for (const dependency in peerDependencies) {
50
+ const requiredVersion = peerDependencies[dependency];
51
+
52
+ const installedVersion =
53
+ projectZeroPwaPackage.dependencies[dependency] ||
54
+ projectZeroPwaPackage.devDependencies[dependency];
55
+
56
+ if (!installedVersion) {
57
+ errorMessages.push(
58
+ `Dependency ${dependency} is missing in projectzeropwa.`
59
+ );
60
+ hasErrors = true;
61
+ } else {
62
+ const requiredSemver = semver.coerce(requiredVersion);
63
+
64
+ const installedSemver = semver.coerce(installedVersion);
65
+
66
+ if (!requiredSemver || !installedSemver) {
67
+ errorMessages.push(
68
+ `Invalid semver for ${dependency}: required ${requiredVersion}, found ${installedVersion}`
69
+ );
70
+ hasErrors = true;
71
+ } else if (
72
+ requiredSemver.major !== installedSemver.major ||
73
+ requiredSemver.minor !== installedSemver.minor
74
+ ) {
75
+ errorMessages.push(
76
+ `Version mismatch for ${dependency}: expected ${requiredVersion} or higher but found ${installedVersion}`
77
+ );
78
+ hasErrors = true;
79
+ }
80
+ }
81
+ }
82
+
83
+ if (hasErrors) {
84
+ console.error(
85
+ '\x1b[31mDependency errors found:\n' +
86
+ errorMessages.join('\n') +
87
+ '\x1b[0m'
88
+ );
89
+ process.exit(1);
90
+ }
91
+
92
+ console.log(
93
+ 'All dependencies are installed and compatible in projectzeropwa.'
94
+ );
95
+ } catch (error) {
96
+ console.error('\x1b[31mError:', error.message + '\x1b[0m');
97
+ process.exit(1);
98
+ }