@akinon/next 1.118.0 → 1.119.0-rc.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.
- package/CHANGELOG.md +32 -0
- package/api/barcode-search.ts +59 -0
- package/bin/pz-generate-routes.js +10 -1
- package/components/plugin-module.tsx +2 -2
- package/data/client/account.ts +12 -1
- package/data/client/checkout.ts +100 -70
- package/data/urls.ts +5 -1
- package/lib/cache-handler.mjs +8 -2
- package/lib/cache.ts +8 -3
- package/middlewares/bfcache-headers.ts +18 -0
- package/middlewares/complete-gpay.ts +6 -5
- package/middlewares/complete-masterpass.ts +6 -5
- package/middlewares/complete-wallet.ts +6 -5
- package/middlewares/default.ts +62 -19
- package/middlewares/index.ts +3 -1
- package/middlewares/masterpass-rest-callback.ts +13 -8
- package/middlewares/redirection-payment.ts +6 -5
- package/middlewares/saved-card-redirection.ts +6 -5
- package/middlewares/three-d-redirection.ts +6 -5
- package/middlewares/wallet-complete-redirection.ts +6 -5
- package/package.json +2 -2
- package/plugins.d.ts +10 -0
- package/plugins.js +1 -0
- package/redux/middlewares/checkout.ts +11 -1
- package/redux/middlewares/pre-order/installment-option.ts +9 -1
- package/types/index.ts +6 -0
- package/utils/get-checkout-path.ts +3 -0
- package/utils/index.ts +21 -1
- package/utils/mobile-3d-iframe.ts +8 -2
- package/utils/redirection-iframe.ts +8 -2
- package/with-pz-config.js +1 -4
package/data/urls.ts
CHANGED
|
@@ -183,7 +183,11 @@ 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}
|
|
186
|
+
`/bundle-product/${productPk}/?${queryString}`,
|
|
187
|
+
similarProducts: (params?: string) =>
|
|
188
|
+
`/similar-products${params ? `?${params}` : ''}`,
|
|
189
|
+
similarProductsList: (params?: string) =>
|
|
190
|
+
`/similar-product-list${params ? `?${params}` : ''}`
|
|
187
191
|
};
|
|
188
192
|
|
|
189
193
|
export const wishlist = {
|
package/lib/cache-handler.mjs
CHANGED
|
@@ -364,11 +364,17 @@ CacheHandler.onCreation(async () => {
|
|
|
364
364
|
};
|
|
365
365
|
}
|
|
366
366
|
|
|
367
|
-
const
|
|
367
|
+
const redisOptions = {
|
|
368
368
|
client,
|
|
369
369
|
timeoutMs: CACHE_CONFIG.redis.timeoutMs,
|
|
370
370
|
keyExpirationStrategy: 'EXPIREAT'
|
|
371
|
-
}
|
|
371
|
+
};
|
|
372
|
+
|
|
373
|
+
if (process.env.CACHE_PASSWORD) {
|
|
374
|
+
redisOptions.password = process.env.CACHE_PASSWORD;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
const redisHandler = createRedisHandler(redisOptions);
|
|
372
378
|
|
|
373
379
|
const localHandler = createLruHandler(CACHE_CONFIG.lru);
|
|
374
380
|
|
package/lib/cache.ts
CHANGED
|
@@ -155,9 +155,14 @@ export class Cache {
|
|
|
155
155
|
process.env.CACHE_PORT
|
|
156
156
|
}/${process.env.CACHE_BUCKET ?? '0'}`;
|
|
157
157
|
|
|
158
|
-
const
|
|
159
|
-
url: redisUrl
|
|
160
|
-
|
|
158
|
+
const options = {
|
|
159
|
+
url: redisUrl,
|
|
160
|
+
...(process.env.CACHE_PASSWORD && {
|
|
161
|
+
password: process.env.CACHE_PASSWORD
|
|
162
|
+
})
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
const client: RedisClientType = createClient(options);
|
|
161
166
|
|
|
162
167
|
client.on('error', (error) => {
|
|
163
168
|
logger.error('Redis client error', { redisUrl, error });
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { NextMiddleware } from 'next/server';
|
|
2
|
+
|
|
3
|
+
const withBfcacheHeaders = (middleware: NextMiddleware): NextMiddleware => {
|
|
4
|
+
return async (req, event) => {
|
|
5
|
+
const response = await middleware(req, event);
|
|
6
|
+
|
|
7
|
+
if (process.env.BF_CACHE === 'true' && response) {
|
|
8
|
+
response.headers.set(
|
|
9
|
+
'Cache-Control',
|
|
10
|
+
'private, no-cache, max-age=0, must-revalidate'
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return response;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default withBfcacheHeaders;
|
|
@@ -4,6 +4,7 @@ import { Buffer } from 'buffer';
|
|
|
4
4
|
import logger from '../utils/log';
|
|
5
5
|
import { getUrlPathWithLocale } from '../utils/localization';
|
|
6
6
|
import { PzNextRequest } from '.';
|
|
7
|
+
import { getCheckoutPath } from '../utils';
|
|
7
8
|
|
|
8
9
|
const streamToString = async (stream: ReadableStream<Uint8Array> | null) => {
|
|
9
10
|
if (stream) {
|
|
@@ -40,7 +41,8 @@ const withCompleteGpay =
|
|
|
40
41
|
return middleware(req, event);
|
|
41
42
|
}
|
|
42
43
|
|
|
43
|
-
const
|
|
44
|
+
const isPostCheckout = req.cookies.get('pz-post-checkout-flow')?.value === 'true';
|
|
45
|
+
const requestUrl = `${Settings.commerceUrl}${getCheckoutPath(isPostCheckout)}${url.search}`;
|
|
44
46
|
const requestHeaders = {
|
|
45
47
|
'X-Requested-With': 'XMLHttpRequest',
|
|
46
48
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
@@ -108,10 +110,9 @@ const withCompleteGpay =
|
|
|
108
110
|
});
|
|
109
111
|
|
|
110
112
|
// Add error cookie
|
|
111
|
-
errorResponse.
|
|
112
|
-
'
|
|
113
|
-
|
|
114
|
-
);
|
|
113
|
+
errorResponse.cookies.set('pz-pos-error', JSON.stringify(errors), {
|
|
114
|
+
path: '/'
|
|
115
|
+
});
|
|
115
116
|
|
|
116
117
|
return errorResponse;
|
|
117
118
|
}
|
|
@@ -5,6 +5,7 @@ import logger from '../utils/log';
|
|
|
5
5
|
import { getUrlPathWithLocale } from '../utils/localization';
|
|
6
6
|
import { PzNextRequest } from '.';
|
|
7
7
|
import { ServerVariables } from '../utils/server-variables';
|
|
8
|
+
import { getCheckoutPath } from '../utils';
|
|
8
9
|
|
|
9
10
|
const streamToString = async (stream: ReadableStream<Uint8Array> | null) => {
|
|
10
11
|
if (stream) {
|
|
@@ -41,7 +42,8 @@ const withCompleteMasterpass =
|
|
|
41
42
|
return middleware(req, event);
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
const
|
|
45
|
+
const isPostCheckout = req.cookies.get('pz-post-checkout-flow')?.value === 'true';
|
|
46
|
+
const requestUrl = `${Settings.commerceUrl}${getCheckoutPath(isPostCheckout)}${url.search}`;
|
|
45
47
|
const requestHeaders = {
|
|
46
48
|
'X-Requested-With': 'XMLHttpRequest',
|
|
47
49
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
@@ -109,10 +111,9 @@ const withCompleteMasterpass =
|
|
|
109
111
|
});
|
|
110
112
|
|
|
111
113
|
// Add error cookie
|
|
112
|
-
errorResponse.
|
|
113
|
-
'
|
|
114
|
-
|
|
115
|
-
);
|
|
114
|
+
errorResponse.cookies.set('pz-pos-error', JSON.stringify(errors), {
|
|
115
|
+
path: '/'
|
|
116
|
+
});
|
|
116
117
|
|
|
117
118
|
return errorResponse;
|
|
118
119
|
}
|
|
@@ -4,6 +4,7 @@ import { Buffer } from 'buffer';
|
|
|
4
4
|
import logger from '../utils/log';
|
|
5
5
|
import { getUrlPathWithLocale } from '../utils/localization';
|
|
6
6
|
import { PzNextRequest } from '.';
|
|
7
|
+
import { getCheckoutPath } from '../utils';
|
|
7
8
|
|
|
8
9
|
const streamToString = async (stream: ReadableStream<Uint8Array> | null) => {
|
|
9
10
|
if (stream) {
|
|
@@ -39,7 +40,8 @@ const withCompleteWallet =
|
|
|
39
40
|
return middleware(req, event);
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
const
|
|
43
|
+
const isPostCheckout = req.cookies.get('pz-post-checkout-flow')?.value === 'true';
|
|
44
|
+
const requestUrl = `${Settings.commerceUrl}${getCheckoutPath(isPostCheckout)}${url.search}`;
|
|
43
45
|
const requestHeaders = {
|
|
44
46
|
'X-Requested-With': 'XMLHttpRequest',
|
|
45
47
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
@@ -105,10 +107,9 @@ const withCompleteWallet =
|
|
|
105
107
|
});
|
|
106
108
|
|
|
107
109
|
// Add error cookie
|
|
108
|
-
errorResponse.
|
|
109
|
-
'
|
|
110
|
-
|
|
111
|
-
);
|
|
110
|
+
errorResponse.cookies.set('pz-pos-error', JSON.stringify(errors), {
|
|
111
|
+
path: '/'
|
|
112
|
+
});
|
|
112
113
|
|
|
113
114
|
return errorResponse;
|
|
114
115
|
}
|
package/middlewares/default.ts
CHANGED
|
@@ -14,7 +14,8 @@ import {
|
|
|
14
14
|
withUrlRedirection,
|
|
15
15
|
withCompleteWallet,
|
|
16
16
|
withWalletCompleteRedirection,
|
|
17
|
-
withMasterpassRestCallback
|
|
17
|
+
withMasterpassRestCallback,
|
|
18
|
+
withBfcacheHeaders
|
|
18
19
|
} from '.';
|
|
19
20
|
import { urlLocaleMatcherRegex } from '../utils';
|
|
20
21
|
import withCurrency from './currency';
|
|
@@ -25,6 +26,8 @@ import { getUrlPathWithLocale } from '../utils/localization';
|
|
|
25
26
|
import getRootHostname from '../utils/get-root-hostname';
|
|
26
27
|
import { LocaleUrlStrategy } from '../localization';
|
|
27
28
|
|
|
29
|
+
const POST_CHECKOUT_COOKIE_MAX_AGE_MS = 1000 * 60 * 30; // 30 minutes
|
|
30
|
+
|
|
28
31
|
const withPzDefault =
|
|
29
32
|
(middleware: NextMiddleware) =>
|
|
30
33
|
async (req: PzNextRequest, event: NextFetchEvent) => {
|
|
@@ -101,6 +104,7 @@ const withPzDefault =
|
|
|
101
104
|
if (
|
|
102
105
|
req.nextUrl.pathname.includes('/orders/hooks/') ||
|
|
103
106
|
req.nextUrl.pathname.includes('/orders/checkout-with-token/') ||
|
|
107
|
+
req.nextUrl.pathname.includes('/orders/post-checkout-redirect/') ||
|
|
104
108
|
req.nextUrl.pathname.includes('/hooks/cash_register/complete/') ||
|
|
105
109
|
req.nextUrl.pathname.includes('/hooks/cash_register/pre_order/')
|
|
106
110
|
) {
|
|
@@ -128,8 +132,13 @@ const withPzDefault =
|
|
|
128
132
|
}
|
|
129
133
|
|
|
130
134
|
if (req.nextUrl.pathname.startsWith('/orders/redirection/')) {
|
|
135
|
+
const queryString = searchParams.toString();
|
|
131
136
|
return NextResponse.rewrite(
|
|
132
|
-
new URL(
|
|
137
|
+
new URL(
|
|
138
|
+
`${encodeURI(Settings.commerceUrl)}/orders/redirection/${
|
|
139
|
+
queryString ? `?${queryString}` : ''
|
|
140
|
+
}`
|
|
141
|
+
)
|
|
133
142
|
);
|
|
134
143
|
}
|
|
135
144
|
|
|
@@ -147,21 +156,35 @@ const withPzDefault =
|
|
|
147
156
|
);
|
|
148
157
|
}
|
|
149
158
|
|
|
150
|
-
// If commerce redirects to /orders/checkout/ without locale
|
|
159
|
+
// If commerce redirects to /orders/checkout/ or /orders/post-checkout/ without locale
|
|
160
|
+
const isPostCheckout = !!req.nextUrl.pathname.match(
|
|
161
|
+
new RegExp('^/orders/post-checkout/$')
|
|
162
|
+
);
|
|
163
|
+
const checkoutLocalePath = getUrlPathWithLocale(
|
|
164
|
+
'/orders/checkout/',
|
|
165
|
+
req.cookies.get('pz-locale')?.value
|
|
166
|
+
);
|
|
151
167
|
if (
|
|
152
|
-
req.nextUrl.
|
|
153
|
-
req.nextUrl.
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
req.cookies.get('pz-locale')?.value
|
|
157
|
-
) !== req.nextUrl.pathname
|
|
168
|
+
(isPostCheckout && req.nextUrl.searchParams.size === 0) ||
|
|
169
|
+
(req.nextUrl.pathname.match(new RegExp('^/orders/checkout/$')) &&
|
|
170
|
+
req.nextUrl.searchParams.size === 0 &&
|
|
171
|
+
checkoutLocalePath !== req.nextUrl.pathname)
|
|
158
172
|
) {
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
)
|
|
173
|
+
const response = NextResponse.redirect(
|
|
174
|
+
`${url.origin}${checkoutLocalePath}`,
|
|
175
|
+
303
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
if (isPostCheckout) {
|
|
179
|
+
response.cookies.set('pz-post-checkout-flow', 'true', {
|
|
180
|
+
path: '/',
|
|
181
|
+
sameSite: 'none',
|
|
182
|
+
secure: true,
|
|
183
|
+
expires: new Date(Date.now() + POST_CHECKOUT_COOKIE_MAX_AGE_MS)
|
|
184
|
+
});
|
|
185
|
+
}
|
|
163
186
|
|
|
164
|
-
return
|
|
187
|
+
return response;
|
|
165
188
|
}
|
|
166
189
|
|
|
167
190
|
// Dynamically handle any payment gateway without specifying names
|
|
@@ -233,10 +256,11 @@ const withPzDefault =
|
|
|
233
256
|
withCompleteWallet(
|
|
234
257
|
withWalletCompleteRedirection(
|
|
235
258
|
withMasterpassRestCallback(
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
259
|
+
withBfcacheHeaders(
|
|
260
|
+
async (
|
|
261
|
+
req: PzNextRequest,
|
|
262
|
+
event: NextFetchEvent
|
|
263
|
+
) => {
|
|
240
264
|
let middlewareResult: NextResponse | void =
|
|
241
265
|
NextResponse.next();
|
|
242
266
|
|
|
@@ -420,6 +444,25 @@ const withPzDefault =
|
|
|
420
444
|
);
|
|
421
445
|
}
|
|
422
446
|
|
|
447
|
+
if (
|
|
448
|
+
req.cookies.get(
|
|
449
|
+
'pz-post-checkout-flow'
|
|
450
|
+
)
|
|
451
|
+
) {
|
|
452
|
+
if (
|
|
453
|
+
pathnameWithoutLocale.startsWith(
|
|
454
|
+
'/orders/completed/'
|
|
455
|
+
) ||
|
|
456
|
+
pathnameWithoutLocale.startsWith(
|
|
457
|
+
'/basket'
|
|
458
|
+
)
|
|
459
|
+
) {
|
|
460
|
+
middlewareResult.cookies.delete(
|
|
461
|
+
'pz-post-checkout-flow'
|
|
462
|
+
);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
423
466
|
if (process.env.ACC_APP_VERSION) {
|
|
424
467
|
middlewareResult.headers.set(
|
|
425
468
|
'acc-app-version',
|
|
@@ -457,7 +500,7 @@ const withPzDefault =
|
|
|
457
500
|
}
|
|
458
501
|
|
|
459
502
|
return middlewareResult;
|
|
460
|
-
}
|
|
503
|
+
})
|
|
461
504
|
)
|
|
462
505
|
)
|
|
463
506
|
)
|
package/middlewares/index.ts
CHANGED
|
@@ -12,6 +12,7 @@ import withSavedCardRedirection from './saved-card-redirection';
|
|
|
12
12
|
import withCompleteWallet from './complete-wallet';
|
|
13
13
|
import withWalletCompleteRedirection from './wallet-complete-redirection';
|
|
14
14
|
import withMasterpassRestCallback from './masterpass-rest-callback';
|
|
15
|
+
import withBfcacheHeaders from './bfcache-headers';
|
|
15
16
|
import { NextRequest } from 'next/server';
|
|
16
17
|
|
|
17
18
|
export {
|
|
@@ -28,7 +29,8 @@ export {
|
|
|
28
29
|
withSavedCardRedirection,
|
|
29
30
|
withCompleteWallet,
|
|
30
31
|
withWalletCompleteRedirection,
|
|
31
|
-
withMasterpassRestCallback
|
|
32
|
+
withMasterpassRestCallback,
|
|
33
|
+
withBfcacheHeaders
|
|
32
34
|
};
|
|
33
35
|
|
|
34
36
|
export interface PzNextRequest extends NextRequest {
|
|
@@ -3,6 +3,7 @@ import Settings from 'settings';
|
|
|
3
3
|
import logger from '../utils/log';
|
|
4
4
|
import { getUrlPathWithLocale } from '../utils/localization';
|
|
5
5
|
import { PzNextRequest } from '.';
|
|
6
|
+
import { getCheckoutPath } from '../utils';
|
|
6
7
|
|
|
7
8
|
const withMasterpassRestCallback =
|
|
8
9
|
(middleware: NextMiddleware) =>
|
|
@@ -19,7 +20,9 @@ const withMasterpassRestCallback =
|
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
try {
|
|
22
|
-
const
|
|
23
|
+
const isPostCheckout = req.cookies.get('pz-post-checkout-flow')?.value === 'true';
|
|
24
|
+
const requestUrl = new URL(getCheckoutPath(isPostCheckout), Settings.commerceUrl);
|
|
25
|
+
|
|
23
26
|
url.searchParams.forEach((value, key) => {
|
|
24
27
|
requestUrl.searchParams.set(key, value);
|
|
25
28
|
});
|
|
@@ -56,18 +59,20 @@ const withMasterpassRestCallback =
|
|
|
56
59
|
ip
|
|
57
60
|
});
|
|
58
61
|
|
|
59
|
-
|
|
62
|
+
const errorResponse = NextResponse.redirect(
|
|
60
63
|
`${url.origin}${getUrlPathWithLocale(
|
|
61
64
|
'/orders/checkout/',
|
|
62
65
|
req.cookies.get('pz-locale')?.value
|
|
63
66
|
)}`,
|
|
64
|
-
|
|
65
|
-
status: 303,
|
|
66
|
-
headers: {
|
|
67
|
-
'Set-Cookie': `pz-pos-error=${encodeURIComponent(JSON.stringify(errors))}; path=/;`
|
|
68
|
-
}
|
|
69
|
-
}
|
|
67
|
+
303
|
|
70
68
|
);
|
|
69
|
+
|
|
70
|
+
// Add error cookie
|
|
71
|
+
errorResponse.cookies.set('pz-pos-error', JSON.stringify(errors), {
|
|
72
|
+
path: '/'
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
return errorResponse;
|
|
71
76
|
}
|
|
72
77
|
|
|
73
78
|
const redirectUrl =
|
|
@@ -4,6 +4,7 @@ import Settings from 'settings';
|
|
|
4
4
|
import logger from '../utils/log';
|
|
5
5
|
import { PzNextRequest } from '.';
|
|
6
6
|
import { getUrlPathWithLocale } from '../utils/localization';
|
|
7
|
+
import { getCheckoutPath } from '../utils';
|
|
7
8
|
|
|
8
9
|
const streamToString = async (stream: ReadableStream<Uint8Array> | null) => {
|
|
9
10
|
if (stream) {
|
|
@@ -41,7 +42,8 @@ const withRedirectionPayment =
|
|
|
41
42
|
return middleware(req, event);
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
const
|
|
45
|
+
const isPostCheckout = req.cookies.get('pz-post-checkout-flow')?.value === 'true';
|
|
46
|
+
const requestUrl = `${Settings.commerceUrl}${getCheckoutPath(isPostCheckout)}${url.search}`;
|
|
45
47
|
const requestHeaders = {
|
|
46
48
|
'X-Requested-With': 'XMLHttpRequest',
|
|
47
49
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
@@ -109,10 +111,9 @@ const withRedirectionPayment =
|
|
|
109
111
|
});
|
|
110
112
|
|
|
111
113
|
// Add error cookie
|
|
112
|
-
errorResponse.
|
|
113
|
-
'
|
|
114
|
-
|
|
115
|
-
);
|
|
114
|
+
errorResponse.cookies.set('pz-pos-error', JSON.stringify(errors), {
|
|
115
|
+
path: '/'
|
|
116
|
+
});
|
|
116
117
|
|
|
117
118
|
return errorResponse;
|
|
118
119
|
}
|
|
@@ -5,6 +5,7 @@ import logger from '../utils/log';
|
|
|
5
5
|
import { getUrlPathWithLocale } from '../utils/localization';
|
|
6
6
|
import { PzNextRequest } from '.';
|
|
7
7
|
import { ServerVariables } from '../utils/server-variables';
|
|
8
|
+
import { getCheckoutPath } from '../utils';
|
|
8
9
|
|
|
9
10
|
const streamToString = async (stream: ReadableStream<Uint8Array> | null) => {
|
|
10
11
|
if (stream) {
|
|
@@ -41,7 +42,8 @@ const withSavedCardRedirection =
|
|
|
41
42
|
return middleware(req, event);
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
const
|
|
45
|
+
const isPostCheckout = req.cookies.get('pz-post-checkout-flow')?.value === 'true';
|
|
46
|
+
const requestUrl = `${Settings.commerceUrl}${getCheckoutPath(isPostCheckout)}${url.search}`;
|
|
45
47
|
const requestHeaders = {
|
|
46
48
|
'X-Requested-With': 'XMLHttpRequest',
|
|
47
49
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
@@ -109,10 +111,9 @@ const withSavedCardRedirection =
|
|
|
109
111
|
});
|
|
110
112
|
|
|
111
113
|
// Add error cookie
|
|
112
|
-
errorResponse.
|
|
113
|
-
'
|
|
114
|
-
|
|
115
|
-
);
|
|
114
|
+
errorResponse.cookies.set('pz-pos-error', JSON.stringify(errors), {
|
|
115
|
+
path: '/'
|
|
116
|
+
});
|
|
116
117
|
|
|
117
118
|
return errorResponse;
|
|
118
119
|
}
|
|
@@ -4,6 +4,7 @@ import { Buffer } from 'buffer';
|
|
|
4
4
|
import logger from '../utils/log';
|
|
5
5
|
import { getUrlPathWithLocale } from '../utils/localization';
|
|
6
6
|
import { PzNextRequest } from '.';
|
|
7
|
+
import { getCheckoutPath } from '../utils';
|
|
7
8
|
|
|
8
9
|
const streamToString = async (stream: ReadableStream<Uint8Array> | null) => {
|
|
9
10
|
if (stream) {
|
|
@@ -40,7 +41,8 @@ const withThreeDRedirection =
|
|
|
40
41
|
return middleware(req, event);
|
|
41
42
|
}
|
|
42
43
|
|
|
43
|
-
const
|
|
44
|
+
const isPostCheckout = req.cookies.get('pz-post-checkout-flow')?.value === 'true';
|
|
45
|
+
const requestUrl = `${Settings.commerceUrl}${getCheckoutPath(isPostCheckout)}${url.search}`;
|
|
44
46
|
const requestHeaders = {
|
|
45
47
|
'X-Requested-With': 'XMLHttpRequest',
|
|
46
48
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
@@ -108,10 +110,9 @@ const withThreeDRedirection =
|
|
|
108
110
|
});
|
|
109
111
|
|
|
110
112
|
// Add error cookie
|
|
111
|
-
errorResponse.
|
|
112
|
-
'
|
|
113
|
-
|
|
114
|
-
);
|
|
113
|
+
errorResponse.cookies.set('pz-pos-error', JSON.stringify(errors), {
|
|
114
|
+
path: '/'
|
|
115
|
+
});
|
|
115
116
|
|
|
116
117
|
return errorResponse;
|
|
117
118
|
}
|
|
@@ -4,6 +4,7 @@ import { Buffer } from 'buffer';
|
|
|
4
4
|
import logger from '../utils/log';
|
|
5
5
|
import { getUrlPathWithLocale } from '../utils/localization';
|
|
6
6
|
import { PzNextRequest } from '.';
|
|
7
|
+
import { getCheckoutPath } from '../utils';
|
|
7
8
|
|
|
8
9
|
const streamToString = async (stream: ReadableStream<Uint8Array> | null) => {
|
|
9
10
|
if (stream) {
|
|
@@ -39,7 +40,8 @@ const withWalletCompleteRedirection =
|
|
|
39
40
|
return middleware(req, event);
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
const
|
|
43
|
+
const isPostCheckout = req.cookies.get('pz-post-checkout-flow')?.value === 'true';
|
|
44
|
+
const requestUrl = `${Settings.commerceUrl}${getCheckoutPath(isPostCheckout)}${url.search}`;
|
|
43
45
|
const requestHeaders = {
|
|
44
46
|
'X-Requested-With': 'XMLHttpRequest',
|
|
45
47
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
@@ -129,10 +131,9 @@ const withWalletCompleteRedirection =
|
|
|
129
131
|
});
|
|
130
132
|
|
|
131
133
|
// Add error cookie
|
|
132
|
-
errorResponse.
|
|
133
|
-
'
|
|
134
|
-
|
|
135
|
-
);
|
|
134
|
+
errorResponse.cookies.set('pz-pos-error', JSON.stringify(errors), {
|
|
135
|
+
path: '/'
|
|
136
|
+
});
|
|
136
137
|
|
|
137
138
|
return errorResponse;
|
|
138
139
|
}
|
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.
|
|
4
|
+
"version": "1.119.0-rc.1",
|
|
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.
|
|
38
|
+
"@akinon/eslint-plugin-projectzero": "1.119.0-rc.1",
|
|
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
|
@@ -37,6 +37,16 @@ declare module '@akinon/pz-cybersource-uc/src/redux/middleware' {
|
|
|
37
37
|
export default middleware as any;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
declare module '@akinon/pz-apple-pay' {}
|
|
41
|
+
|
|
42
|
+
declare module '@akinon/pz-similar-products' {
|
|
43
|
+
export const SimilarProductsModal: any;
|
|
44
|
+
export const SimilarProductsFilterSidebar: any;
|
|
45
|
+
export const SimilarProductsResultsGrid: any;
|
|
46
|
+
export const SimilarProductsPlugin: any;
|
|
47
|
+
export const SimilarProductsButtonPlugin: any;
|
|
48
|
+
}
|
|
49
|
+
|
|
40
50
|
declare module '@akinon/pz-cybersource-uc/src/redux/reducer' {
|
|
41
51
|
export default reducer as any;
|
|
42
52
|
}
|
package/plugins.js
CHANGED
|
@@ -204,15 +204,25 @@ export const contextListMiddleware: Middleware = ({
|
|
|
204
204
|
(ctx) => ctx.page_name === 'DeliveryOptionSelectionPage'
|
|
205
205
|
)
|
|
206
206
|
) {
|
|
207
|
+
const isCreditCardPayment =
|
|
208
|
+
preOrder?.payment_option?.payment_type === 'credit_card' ||
|
|
209
|
+
preOrder?.payment_option?.payment_type === 'masterpass';
|
|
210
|
+
|
|
207
211
|
if (context.page_context.card_type) {
|
|
208
212
|
dispatch(setCardType(context.page_context.card_type));
|
|
213
|
+
} else if (isCreditCardPayment) {
|
|
214
|
+
dispatch(setCardType(null));
|
|
209
215
|
}
|
|
210
216
|
|
|
211
217
|
if (
|
|
212
218
|
context.page_context.installments &&
|
|
213
219
|
preOrder?.payment_option?.payment_type !== 'masterpass_rest'
|
|
214
220
|
) {
|
|
215
|
-
|
|
221
|
+
if (!isCreditCardPayment || context.page_context.card_type) {
|
|
222
|
+
dispatch(
|
|
223
|
+
setInstallmentOptions(context.page_context.installments)
|
|
224
|
+
);
|
|
225
|
+
}
|
|
216
226
|
}
|
|
217
227
|
}
|
|
218
228
|
|
|
@@ -14,9 +14,17 @@ export const installmentOptionMiddleware: Middleware = ({
|
|
|
14
14
|
return result;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
const { installmentOptions } = getState().checkout;
|
|
17
|
+
const { installmentOptions, cardType } = getState().checkout;
|
|
18
18
|
const { endpoints: apiEndpoints } = checkoutApi;
|
|
19
19
|
|
|
20
|
+
const isCreditCardPayment =
|
|
21
|
+
preOrder?.payment_option?.payment_type === 'credit_card' ||
|
|
22
|
+
preOrder?.payment_option?.payment_type === 'masterpass';
|
|
23
|
+
|
|
24
|
+
if (isCreditCardPayment && !cardType) {
|
|
25
|
+
return result;
|
|
26
|
+
}
|
|
27
|
+
|
|
20
28
|
if (
|
|
21
29
|
!preOrder?.installment &&
|
|
22
30
|
preOrder?.payment_option?.payment_type !== 'saved_card' &&
|
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
|
};
|
package/utils/index.ts
CHANGED
|
@@ -7,6 +7,7 @@ export * from './get-currency';
|
|
|
7
7
|
export * from './menu-generator';
|
|
8
8
|
export * from './generate-commerce-search-params';
|
|
9
9
|
export * from './get-currency-label';
|
|
10
|
+
export * from './get-checkout-path';
|
|
10
11
|
|
|
11
12
|
export function getCookie(name: string) {
|
|
12
13
|
if (typeof document === 'undefined') {
|
|
@@ -194,7 +195,9 @@ export const urlLocaleMatcherRegex = new RegExp(
|
|
|
194
195
|
|
|
195
196
|
export const getPosError = () => {
|
|
196
197
|
const cookieValue = getCookie('pz-pos-error');
|
|
197
|
-
const error = JSON.parse(
|
|
198
|
+
const error = JSON.parse(
|
|
199
|
+
cookieValue ? decodeURIComponent(cookieValue) : '{}'
|
|
200
|
+
);
|
|
198
201
|
|
|
199
202
|
// delete 'pz-pos-error' cookie when refreshing or closing page
|
|
200
203
|
window.addEventListener('beforeunload', () => {
|
|
@@ -204,6 +207,23 @@ export const getPosError = () => {
|
|
|
204
207
|
return error;
|
|
205
208
|
};
|
|
206
209
|
|
|
210
|
+
export const checkPaymentWillRedirect = (response: {
|
|
211
|
+
context_list?: Array<{
|
|
212
|
+
page_name: string;
|
|
213
|
+
page_context?: { context_data?: { redirect_url?: string } };
|
|
214
|
+
}>;
|
|
215
|
+
redirect_url?: string;
|
|
216
|
+
errors?: unknown;
|
|
217
|
+
}): boolean => {
|
|
218
|
+
if (!response) return false;
|
|
219
|
+
|
|
220
|
+
const hasThankYouPage = response.context_list?.some(
|
|
221
|
+
(c) => c.page_name === 'ThankYouPage'
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
return Boolean(hasThankYouPage || response.redirect_url);
|
|
225
|
+
};
|
|
226
|
+
|
|
207
227
|
export const urlSchemes = [
|
|
208
228
|
'http',
|
|
209
229
|
'tel:',
|