@akinon/next 2.0.25-beta.0 → 2.0.25-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 +29 -2
- package/bin/pz-generate-routes.js +4 -1
- package/components/plugin-module.tsx +0 -1
- package/data/client/checkout.ts +0 -1
- package/data/server/category.ts +13 -1
- package/data/server/list.ts +12 -0
- package/data/server/product.ts +10 -0
- package/data/server/special-page.ts +13 -0
- package/data/server/widget.ts +14 -1
- package/data/urls.ts +5 -1
- package/hooks/use-captcha.tsx +1 -1
- package/middlewares/default.ts +254 -249
- package/middlewares/masterpass-rest-callback.ts +89 -202
- package/package.json +2 -2
- package/plugins.d.ts +10 -0
- package/plugins.js +1 -0
- package/redux/middlewares/checkout.ts +45 -3
- package/redux/middlewares/pre-order/installment-option.ts +9 -1
- package/types/index.ts +20 -9
- package/utils/csrf.ts +1 -1
- package/utils/payload-optimizer.ts +481 -0
- package/with-pz-config.js +3 -2
package/middlewares/default.ts
CHANGED
|
@@ -18,7 +18,11 @@ import {
|
|
|
18
18
|
withBfcacheHeaders
|
|
19
19
|
} from '.';
|
|
20
20
|
import { getCsrfCookieFlags, urlLocaleMatcherRegex } from '../utils';
|
|
21
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
getPzSegmentsConfig,
|
|
23
|
+
encodePzValue,
|
|
24
|
+
isLegacyMode
|
|
25
|
+
} from '../utils/pz-segments';
|
|
22
26
|
import withCurrency from './currency';
|
|
23
27
|
import withLocale from './locale';
|
|
24
28
|
import logger from '../utils/log';
|
|
@@ -262,98 +266,98 @@ const withPzDefault =
|
|
|
262
266
|
req: PzNextRequest,
|
|
263
267
|
event: NextFetchEvent
|
|
264
268
|
) => {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
269
|
+
let middlewareResult: NextResponse | void =
|
|
270
|
+
NextResponse.next();
|
|
271
|
+
|
|
272
|
+
try {
|
|
273
|
+
const { locale, prettyUrl, currency } =
|
|
274
|
+
req.middlewareParams.rewrites;
|
|
275
|
+
const { defaultLocaleValue } =
|
|
276
|
+
Settings.localization;
|
|
277
|
+
const url = req.nextUrl.clone();
|
|
278
|
+
const pathnameWithoutLocale =
|
|
279
|
+
url.pathname.replace(
|
|
280
|
+
urlLocaleMatcherRegex,
|
|
281
|
+
''
|
|
282
|
+
);
|
|
279
283
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
middlewareResult.headers.get(
|
|
294
|
-
'x-middleware-rewrite'
|
|
295
|
-
)
|
|
296
|
-
) {
|
|
297
|
-
const rewriteUrl = new URL(
|
|
284
|
+
middlewareResult = (await middleware(
|
|
285
|
+
req,
|
|
286
|
+
event
|
|
287
|
+
)) as NextResponse | void;
|
|
288
|
+
|
|
289
|
+
let customRewriteUrlDiff = '';
|
|
290
|
+
|
|
291
|
+
if (
|
|
292
|
+
middlewareResult instanceof
|
|
293
|
+
NextResponse &&
|
|
294
|
+
middlewareResult.headers.get(
|
|
295
|
+
'pz-override-response'
|
|
296
|
+
) &&
|
|
298
297
|
middlewareResult.headers.get(
|
|
299
298
|
'x-middleware-rewrite'
|
|
300
299
|
)
|
|
301
|
-
)
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
''
|
|
300
|
+
) {
|
|
301
|
+
const rewriteUrl = new URL(
|
|
302
|
+
middlewareResult.headers.get(
|
|
303
|
+
'x-middleware-rewrite'
|
|
304
|
+
)
|
|
307
305
|
);
|
|
308
|
-
|
|
306
|
+
const originalUrl = new URL(req.url);
|
|
307
|
+
customRewriteUrlDiff =
|
|
308
|
+
rewriteUrl.pathname.replace(
|
|
309
|
+
originalUrl.pathname,
|
|
310
|
+
''
|
|
311
|
+
);
|
|
312
|
+
}
|
|
309
313
|
|
|
310
|
-
|
|
314
|
+
let ordersPrefix: string;
|
|
311
315
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
}`.replace(/\/+/g, '/');
|
|
318
|
-
ordersPrefix = `/${currency}/orders`;
|
|
319
|
-
} else {
|
|
320
|
-
const pzConfig =
|
|
321
|
-
getPzSegmentsConfig(Settings);
|
|
322
|
-
const fullUrlPath =
|
|
323
|
-
`${customRewriteUrlDiff}${
|
|
316
|
+
if (isLegacyMode(Settings)) {
|
|
317
|
+
url.basePath = `/${commerceUrl}`;
|
|
318
|
+
url.pathname = `/${
|
|
319
|
+
locale.length ? `${locale}/` : ''
|
|
320
|
+
}${currency}/${customRewriteUrlDiff}${
|
|
324
321
|
prettyUrl ?? pathnameWithoutLocale
|
|
325
322
|
}`.replace(/\/+/g, '/');
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
323
|
+
ordersPrefix = `/${currency}/orders`;
|
|
324
|
+
} else {
|
|
325
|
+
const pzConfig =
|
|
326
|
+
getPzSegmentsConfig(Settings);
|
|
327
|
+
const fullUrlPath =
|
|
328
|
+
`${customRewriteUrlDiff}${
|
|
329
|
+
prettyUrl ?? pathnameWithoutLocale
|
|
330
|
+
}`.replace(/\/+/g, '/');
|
|
331
|
+
const fullUrl = `${req.nextUrl.origin}${fullUrlPath}`;
|
|
332
|
+
const resolvedLocale =
|
|
333
|
+
locale?.length > 0
|
|
334
|
+
? locale
|
|
335
|
+
: Settings.localization
|
|
336
|
+
.defaultLocaleValue;
|
|
337
|
+
const resolveContext = {
|
|
338
|
+
req,
|
|
339
|
+
event,
|
|
340
|
+
url,
|
|
341
|
+
locale: resolvedLocale,
|
|
342
|
+
currency,
|
|
343
|
+
pathname: pathnameWithoutLocale
|
|
344
|
+
};
|
|
345
|
+
const customSegments =
|
|
346
|
+
pzConfig.segments.filter(
|
|
347
|
+
(seg) =>
|
|
348
|
+
seg.name !== 'locale' &&
|
|
349
|
+
seg.name !== 'currency' &&
|
|
350
|
+
seg.name !== 'url'
|
|
351
|
+
);
|
|
352
|
+
const segmentValues: Record<
|
|
353
|
+
string,
|
|
354
|
+
string
|
|
355
|
+
> = {
|
|
356
|
+
locale: resolvedLocale,
|
|
357
|
+
currency,
|
|
358
|
+
url: encodeURIComponent(fullUrl),
|
|
359
|
+
...Object.fromEntries(
|
|
360
|
+
customSegments.map((seg) => [
|
|
357
361
|
seg.name,
|
|
358
362
|
req.middlewareParams.rewrites[
|
|
359
363
|
seg.name
|
|
@@ -362,105 +366,121 @@ const withPzDefault =
|
|
|
362
366
|
? seg.resolve(resolveContext)
|
|
363
367
|
: '')
|
|
364
368
|
])
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
const pzValue = encodePzValue(
|
|
369
|
-
segmentValues,
|
|
370
|
-
pzConfig
|
|
371
|
-
);
|
|
369
|
+
)
|
|
370
|
+
};
|
|
372
371
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
'/'
|
|
372
|
+
const pzValue = encodePzValue(
|
|
373
|
+
segmentValues,
|
|
374
|
+
pzConfig
|
|
377
375
|
);
|
|
378
|
-
ordersPrefix = `/${pzValue}/orders`;
|
|
379
|
-
}
|
|
380
376
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
)
|
|
389
|
-
)
|
|
390
|
-
) {
|
|
391
|
-
url.pathname =
|
|
392
|
-
url.pathname +
|
|
393
|
-
(/\/$/.test(url.pathname) ? '' : '/') +
|
|
394
|
-
`searchparams|${encodeURIComponent(
|
|
395
|
-
url.searchParams.toString()
|
|
396
|
-
)}`;
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
Settings.rewrites.forEach((rewrite) => {
|
|
400
|
-
url.pathname = url.pathname.replace(
|
|
401
|
-
rewrite.source,
|
|
402
|
-
rewrite.destination
|
|
403
|
-
);
|
|
404
|
-
});
|
|
377
|
+
url.pathname =
|
|
378
|
+
`/${pzValue}/${fullUrlPath}`.replace(
|
|
379
|
+
/\/+/g,
|
|
380
|
+
'/'
|
|
381
|
+
);
|
|
382
|
+
ordersPrefix = `/${pzValue}/orders`;
|
|
383
|
+
}
|
|
405
384
|
|
|
406
|
-
// if middleware.ts has a return value for current url
|
|
407
|
-
if (
|
|
408
|
-
middlewareResult instanceof NextResponse
|
|
409
|
-
) {
|
|
410
|
-
// pz-override-response header is used to prevent 404 page for custom responses.
|
|
411
385
|
if (
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
386
|
+
Settings.usePrettyUrlRoute &&
|
|
387
|
+
url.searchParams.toString().length >
|
|
388
|
+
0 &&
|
|
389
|
+
!Object.entries(ROUTES).find(
|
|
390
|
+
([, value]) =>
|
|
391
|
+
new RegExp(`^${value}/?$`).test(
|
|
392
|
+
pathnameWithoutLocale
|
|
393
|
+
)
|
|
394
|
+
)
|
|
415
395
|
) {
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
url.
|
|
396
|
+
url.pathname =
|
|
397
|
+
url.pathname +
|
|
398
|
+
(/\/$/.test(url.pathname)
|
|
399
|
+
? ''
|
|
400
|
+
: '/') +
|
|
401
|
+
`searchparams|${encodeURIComponent(
|
|
402
|
+
url.searchParams.toString()
|
|
403
|
+
)}`;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
Settings.rewrites.forEach((rewrite) => {
|
|
407
|
+
url.pathname = url.pathname.replace(
|
|
408
|
+
rewrite.source,
|
|
409
|
+
rewrite.destination
|
|
419
410
|
);
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
middlewareResult
|
|
425
|
-
'pz-override-response'
|
|
426
|
-
) === 'true'
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
// if middleware.ts has a return value for current url
|
|
414
|
+
if (
|
|
415
|
+
middlewareResult instanceof NextResponse
|
|
427
416
|
) {
|
|
417
|
+
// pz-override-response header is used to prevent 404 page for custom responses.
|
|
418
|
+
if (
|
|
419
|
+
middlewareResult.headers.get(
|
|
420
|
+
'pz-override-response'
|
|
421
|
+
) !== 'true'
|
|
422
|
+
) {
|
|
423
|
+
middlewareResult.headers.set(
|
|
424
|
+
'x-middleware-rewrite',
|
|
425
|
+
url.href
|
|
426
|
+
);
|
|
427
|
+
} else if (
|
|
428
|
+
middlewareResult.headers.get(
|
|
429
|
+
'x-middleware-rewrite'
|
|
430
|
+
) &&
|
|
431
|
+
middlewareResult.headers.get(
|
|
432
|
+
'pz-override-response'
|
|
433
|
+
) === 'true'
|
|
434
|
+
) {
|
|
435
|
+
middlewareResult =
|
|
436
|
+
NextResponse.rewrite(url);
|
|
437
|
+
}
|
|
438
|
+
} else {
|
|
439
|
+
// if middleware.ts doesn't have a return value.
|
|
440
|
+
// e.g. NextResponse.next() doesn't exist in middleware.ts
|
|
441
|
+
|
|
428
442
|
middlewareResult =
|
|
429
443
|
NextResponse.rewrite(url);
|
|
430
444
|
}
|
|
431
|
-
} else {
|
|
432
|
-
// if middleware.ts doesn't have a return value.
|
|
433
|
-
// e.g. NextResponse.next() doesn't exist in middleware.ts
|
|
434
445
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
446
|
+
const { localeUrlStrategy } =
|
|
447
|
+
Settings.localization;
|
|
448
|
+
|
|
449
|
+
const fallbackHost =
|
|
450
|
+
req.headers.get('x-forwarded-host') ||
|
|
451
|
+
req.headers.get('host');
|
|
452
|
+
const hostname =
|
|
453
|
+
process.env.NEXT_PUBLIC_URL ||
|
|
454
|
+
`https://${fallbackHost}`;
|
|
455
|
+
const rootHostname =
|
|
456
|
+
localeUrlStrategy ===
|
|
457
|
+
LocaleUrlStrategy.Subdomain
|
|
458
|
+
? getRootHostname(hostname)
|
|
459
|
+
: null;
|
|
460
|
+
|
|
461
|
+
if (
|
|
462
|
+
!url.pathname.startsWith(ordersPrefix)
|
|
463
|
+
) {
|
|
464
|
+
middlewareResult.cookies.set(
|
|
465
|
+
'pz-locale',
|
|
466
|
+
locale?.length > 0
|
|
467
|
+
? locale
|
|
468
|
+
: defaultLocaleValue,
|
|
469
|
+
{
|
|
470
|
+
domain: rootHostname,
|
|
471
|
+
sameSite: 'none',
|
|
472
|
+
secure: true,
|
|
473
|
+
expires: new Date(
|
|
474
|
+
Date.now() +
|
|
475
|
+
1000 * 60 * 60 * 24 * 7
|
|
476
|
+
) // 7 days
|
|
477
|
+
}
|
|
478
|
+
);
|
|
479
|
+
}
|
|
438
480
|
|
|
439
|
-
const { localeUrlStrategy } =
|
|
440
|
-
Settings.localization;
|
|
441
|
-
|
|
442
|
-
const fallbackHost =
|
|
443
|
-
req.headers.get('x-forwarded-host') ||
|
|
444
|
-
req.headers.get('host');
|
|
445
|
-
const hostname =
|
|
446
|
-
process.env.NEXT_PUBLIC_URL ||
|
|
447
|
-
`https://${fallbackHost}`;
|
|
448
|
-
const rootHostname =
|
|
449
|
-
localeUrlStrategy ===
|
|
450
|
-
LocaleUrlStrategy.Subdomain
|
|
451
|
-
? getRootHostname(hostname)
|
|
452
|
-
: null;
|
|
453
|
-
|
|
454
|
-
if (
|
|
455
|
-
!url.pathname.startsWith(
|
|
456
|
-
ordersPrefix
|
|
457
|
-
)
|
|
458
|
-
) {
|
|
459
481
|
middlewareResult.cookies.set(
|
|
460
|
-
'pz-
|
|
461
|
-
|
|
462
|
-
? locale
|
|
463
|
-
: defaultLocaleValue,
|
|
482
|
+
'pz-currency',
|
|
483
|
+
currency,
|
|
464
484
|
{
|
|
465
485
|
domain: rootHostname,
|
|
466
486
|
sameSite: 'none',
|
|
@@ -470,104 +490,89 @@ const withPzDefault =
|
|
|
470
490
|
) // 7 days
|
|
471
491
|
}
|
|
472
492
|
);
|
|
473
|
-
}
|
|
474
493
|
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
494
|
+
if (
|
|
495
|
+
req.cookies.get('pz-locale') &&
|
|
496
|
+
req.cookies.get('pz-locale').value !==
|
|
497
|
+
locale
|
|
498
|
+
) {
|
|
499
|
+
logger.debug('Locale changed', {
|
|
500
|
+
locale,
|
|
501
|
+
oldLocale:
|
|
502
|
+
req.cookies.get('pz-locale')?.value,
|
|
503
|
+
ip
|
|
504
|
+
});
|
|
485
505
|
}
|
|
486
|
-
);
|
|
487
|
-
|
|
488
|
-
if (
|
|
489
|
-
req.cookies.get('pz-locale') &&
|
|
490
|
-
req.cookies.get('pz-locale').value !==
|
|
491
|
-
locale
|
|
492
|
-
) {
|
|
493
|
-
logger.debug('Locale changed', {
|
|
494
|
-
locale,
|
|
495
|
-
oldLocale:
|
|
496
|
-
req.cookies.get('pz-locale')?.value,
|
|
497
|
-
ip
|
|
498
|
-
});
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
middlewareResult.headers.set(
|
|
502
|
-
'pz-url',
|
|
503
|
-
req.nextUrl.toString()
|
|
504
|
-
);
|
|
505
506
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
507
|
+
middlewareResult.headers.set(
|
|
508
|
+
'pz-url',
|
|
509
|
+
req.nextUrl.toString()
|
|
509
510
|
);
|
|
510
|
-
}
|
|
511
511
|
|
|
512
|
-
|
|
513
|
-
req.cookies.get(
|
|
514
|
-
'pz-post-checkout-flow'
|
|
515
|
-
)
|
|
516
|
-
) {
|
|
517
|
-
if (
|
|
518
|
-
pathnameWithoutLocale.startsWith(
|
|
519
|
-
'/orders/completed/'
|
|
520
|
-
) ||
|
|
521
|
-
pathnameWithoutLocale.startsWith(
|
|
522
|
-
'/basket'
|
|
523
|
-
)
|
|
524
|
-
) {
|
|
512
|
+
if (req.cookies.get('pz-set-currency')) {
|
|
525
513
|
middlewareResult.cookies.delete(
|
|
526
|
-
'pz-
|
|
514
|
+
'pz-set-currency'
|
|
527
515
|
);
|
|
528
516
|
}
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
if (process.env.ACC_APP_VERSION) {
|
|
532
|
-
middlewareResult.headers.set(
|
|
533
|
-
'acc-app-version',
|
|
534
|
-
process.env.ACC_APP_VERSION
|
|
535
|
-
);
|
|
536
|
-
}
|
|
537
517
|
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
518
|
+
if (
|
|
519
|
+
req.cookies.get('pz-post-checkout-flow')
|
|
520
|
+
) {
|
|
521
|
+
if (
|
|
522
|
+
pathnameWithoutLocale.startsWith(
|
|
523
|
+
'/orders/completed/'
|
|
524
|
+
) ||
|
|
525
|
+
pathnameWithoutLocale.startsWith(
|
|
526
|
+
'/basket'
|
|
527
|
+
)
|
|
528
|
+
) {
|
|
529
|
+
middlewareResult.cookies.delete(
|
|
530
|
+
'pz-post-checkout-flow'
|
|
531
|
+
);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
541
534
|
|
|
542
|
-
if (
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
middlewareResult.cookies.set(
|
|
547
|
-
'csrftoken',
|
|
548
|
-
csrf_token,
|
|
549
|
-
{
|
|
550
|
-
path: '/',
|
|
551
|
-
domain: rootHostname,
|
|
552
|
-
...getCsrfCookieFlags()
|
|
553
|
-
}
|
|
535
|
+
if (process.env.ACC_APP_VERSION) {
|
|
536
|
+
middlewareResult.headers.set(
|
|
537
|
+
'acc-app-version',
|
|
538
|
+
process.env.ACC_APP_VERSION
|
|
554
539
|
);
|
|
555
540
|
}
|
|
541
|
+
|
|
542
|
+
// Set CSRF token if not set
|
|
543
|
+
try {
|
|
544
|
+
const url = `${Settings.commerceUrl}${user.csrfToken}`;
|
|
545
|
+
|
|
546
|
+
if (!req.cookies.get('csrftoken')) {
|
|
547
|
+
const { csrf_token } = await (
|
|
548
|
+
await fetch(url)
|
|
549
|
+
).json();
|
|
550
|
+
middlewareResult.cookies.set(
|
|
551
|
+
'csrftoken',
|
|
552
|
+
csrf_token,
|
|
553
|
+
{
|
|
554
|
+
path: '/',
|
|
555
|
+
domain: rootHostname,
|
|
556
|
+
...getCsrfCookieFlags()
|
|
557
|
+
}
|
|
558
|
+
);
|
|
559
|
+
}
|
|
560
|
+
} catch (error) {
|
|
561
|
+
logger.error('CSRF Error', {
|
|
562
|
+
error,
|
|
563
|
+
ip
|
|
564
|
+
});
|
|
565
|
+
}
|
|
556
566
|
} catch (error) {
|
|
557
|
-
logger.error('
|
|
567
|
+
logger.error('withPzDefault Error', {
|
|
558
568
|
error,
|
|
559
569
|
ip
|
|
560
570
|
});
|
|
561
571
|
}
|
|
562
|
-
} catch (error) {
|
|
563
|
-
logger.error('withPzDefault Error', {
|
|
564
|
-
error,
|
|
565
|
-
ip
|
|
566
|
-
});
|
|
567
|
-
}
|
|
568
572
|
|
|
569
|
-
|
|
570
|
-
|
|
573
|
+
return middlewareResult;
|
|
574
|
+
}
|
|
575
|
+
)
|
|
571
576
|
)
|
|
572
577
|
)
|
|
573
578
|
)
|