@akinon/next 2.0.33-beta.0 → 2.0.33-rc.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.
@@ -18,7 +18,11 @@ import {
18
18
  withBfcacheHeaders
19
19
  } from '.';
20
20
  import { getCsrfCookieFlags, urlLocaleMatcherRegex } from '../utils';
21
- import { getPzSegmentsConfig, encodePzValue, isLegacyMode } from '../utils/pz-segments';
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';
@@ -332,98 +336,98 @@ const withPzDefault =
332
336
  req: PzNextRequest,
333
337
  event: NextFetchEvent
334
338
  ) => {
335
- let middlewareResult: NextResponse | void =
336
- NextResponse.next();
337
-
338
- try {
339
- const { locale, prettyUrl, currency } =
340
- req.middlewareParams.rewrites;
341
- const { defaultLocaleValue } =
342
- Settings.localization;
343
- const url = req.nextUrl.clone();
344
- const pathnameWithoutLocale =
345
- url.pathname.replace(
346
- urlLocaleMatcherRegex,
347
- ''
348
- );
339
+ let middlewareResult: NextResponse | void =
340
+ NextResponse.next();
341
+
342
+ try {
343
+ const { locale, prettyUrl, currency } =
344
+ req.middlewareParams.rewrites;
345
+ const { defaultLocaleValue } =
346
+ Settings.localization;
347
+ const url = req.nextUrl.clone();
348
+ const pathnameWithoutLocale =
349
+ url.pathname.replace(
350
+ urlLocaleMatcherRegex,
351
+ ''
352
+ );
349
353
 
350
- middlewareResult = (await middleware(
351
- req,
352
- event
353
- )) as NextResponse | void;
354
+ middlewareResult = (await middleware(
355
+ req,
356
+ event
357
+ )) as NextResponse | void;
354
358
 
355
- let customRewriteUrlDiff = '';
359
+ let customRewriteUrlDiff = '';
356
360
 
357
- if (
358
- middlewareResult instanceof
359
- NextResponse &&
360
- middlewareResult.headers.get(
361
- 'pz-override-response'
362
- ) &&
363
- middlewareResult.headers.get(
364
- 'x-middleware-rewrite'
365
- )
366
- ) {
367
- const rewriteUrl = new URL(
361
+ if (
362
+ middlewareResult instanceof
363
+ NextResponse &&
364
+ middlewareResult.headers.get(
365
+ 'pz-override-response'
366
+ ) &&
368
367
  middlewareResult.headers.get(
369
368
  'x-middleware-rewrite'
370
369
  )
371
- );
372
- const originalUrl = new URL(req.url);
373
- customRewriteUrlDiff =
374
- rewriteUrl.pathname.replace(
375
- originalUrl.pathname,
376
- ''
370
+ ) {
371
+ const rewriteUrl = new URL(
372
+ middlewareResult.headers.get(
373
+ 'x-middleware-rewrite'
374
+ )
377
375
  );
378
- }
376
+ const originalUrl = new URL(req.url);
377
+ customRewriteUrlDiff =
378
+ rewriteUrl.pathname.replace(
379
+ originalUrl.pathname,
380
+ ''
381
+ );
382
+ }
379
383
 
380
- let ordersPrefix: string;
384
+ let ordersPrefix: string;
381
385
 
382
- if (isLegacyMode(Settings)) {
383
- url.basePath = `/${commerceUrl}`;
384
- url.pathname =
385
- `/${locale.length ? `${locale}/` : ''}${currency}/${customRewriteUrlDiff}${
386
- prettyUrl ?? pathnameWithoutLocale
387
- }`.replace(/\/+/g, '/');
388
- ordersPrefix = `/${currency}/orders`;
389
- } else {
390
- const pzConfig =
391
- getPzSegmentsConfig(Settings);
392
- const fullUrlPath =
393
- `${customRewriteUrlDiff}${
386
+ if (isLegacyMode(Settings)) {
387
+ url.basePath = `/${commerceUrl}`;
388
+ url.pathname = `/${
389
+ locale.length ? `${locale}/` : ''
390
+ }${currency}/${customRewriteUrlDiff}${
394
391
  prettyUrl ?? pathnameWithoutLocale
395
392
  }`.replace(/\/+/g, '/');
396
- const fullUrl = `${req.nextUrl.origin}${fullUrlPath}`;
397
- const resolvedLocale =
398
- locale?.length > 0
399
- ? locale
400
- : Settings.localization
401
- .defaultLocaleValue;
402
- const resolveContext = {
403
- req,
404
- event,
405
- url,
406
- locale: resolvedLocale,
407
- currency,
408
- pathname: pathnameWithoutLocale
409
- };
410
- const customSegments = pzConfig.segments
411
- .filter(
412
- (seg) =>
413
- seg.name !== 'locale' &&
414
- seg.name !== 'currency' &&
415
- seg.name !== 'url'
416
- );
417
- const segmentValues: Record<
418
- string,
419
- string
420
- > = {
421
- locale: resolvedLocale,
422
- currency,
423
- url: encodeURIComponent(fullUrl),
424
- ...Object.fromEntries(
425
- customSegments
426
- .map((seg) => [
393
+ ordersPrefix = `/${currency}/orders`;
394
+ } else {
395
+ const pzConfig =
396
+ getPzSegmentsConfig(Settings);
397
+ const fullUrlPath =
398
+ `${customRewriteUrlDiff}${
399
+ prettyUrl ?? pathnameWithoutLocale
400
+ }`.replace(/\/+/g, '/');
401
+ const fullUrl = `${req.nextUrl.origin}${fullUrlPath}`;
402
+ const resolvedLocale =
403
+ locale?.length > 0
404
+ ? locale
405
+ : Settings.localization
406
+ .defaultLocaleValue;
407
+ const resolveContext = {
408
+ req,
409
+ event,
410
+ url,
411
+ locale: resolvedLocale,
412
+ currency,
413
+ pathname: pathnameWithoutLocale
414
+ };
415
+ const customSegments =
416
+ pzConfig.segments.filter(
417
+ (seg) =>
418
+ seg.name !== 'locale' &&
419
+ seg.name !== 'currency' &&
420
+ seg.name !== 'url'
421
+ );
422
+ const segmentValues: Record<
423
+ string,
424
+ string
425
+ > = {
426
+ locale: resolvedLocale,
427
+ currency,
428
+ url: encodeURIComponent(fullUrl),
429
+ ...Object.fromEntries(
430
+ customSegments.map((seg) => [
427
431
  seg.name,
428
432
  req.middlewareParams.rewrites[
429
433
  seg.name
@@ -432,105 +436,121 @@ const withPzDefault =
432
436
  ? seg.resolve(resolveContext)
433
437
  : '')
434
438
  ])
435
- )
436
- };
437
-
438
- const pzValue = encodePzValue(
439
- segmentValues,
440
- pzConfig
441
- );
439
+ )
440
+ };
442
441
 
443
- url.pathname =
444
- `/${pzValue}/${fullUrlPath}`.replace(
445
- /\/+/g,
446
- '/'
442
+ const pzValue = encodePzValue(
443
+ segmentValues,
444
+ pzConfig
447
445
  );
448
- ordersPrefix = `/${pzValue}/orders`;
449
- }
450
446
 
451
- if (
452
- Settings.usePrettyUrlRoute &&
453
- url.searchParams.toString().length > 0 &&
454
- !Object.entries(ROUTES).find(
455
- ([, value]) =>
456
- new RegExp(`^${value}/?$`).test(
457
- pathnameWithoutLocale
458
- )
459
- )
460
- ) {
461
- url.pathname =
462
- url.pathname +
463
- (/\/$/.test(url.pathname) ? '' : '/') +
464
- `searchparams|${encodeURIComponent(
465
- url.searchParams.toString()
466
- )}`;
467
- }
468
-
469
- Settings.rewrites.forEach((rewrite) => {
470
- url.pathname = url.pathname.replace(
471
- rewrite.source,
472
- rewrite.destination
473
- );
474
- });
447
+ url.pathname =
448
+ `/${pzValue}/${fullUrlPath}`.replace(
449
+ /\/+/g,
450
+ '/'
451
+ );
452
+ ordersPrefix = `/${pzValue}/orders`;
453
+ }
475
454
 
476
- // if middleware.ts has a return value for current url
477
- if (
478
- middlewareResult instanceof NextResponse
479
- ) {
480
- // pz-override-response header is used to prevent 404 page for custom responses.
481
455
  if (
482
- middlewareResult.headers.get(
483
- 'pz-override-response'
484
- ) !== 'true'
456
+ Settings.usePrettyUrlRoute &&
457
+ url.searchParams.toString().length >
458
+ 0 &&
459
+ !Object.entries(ROUTES).find(
460
+ ([, value]) =>
461
+ new RegExp(`^${value}/?$`).test(
462
+ pathnameWithoutLocale
463
+ )
464
+ )
485
465
  ) {
486
- middlewareResult.headers.set(
487
- 'x-middleware-rewrite',
488
- url.href
466
+ url.pathname =
467
+ url.pathname +
468
+ (/\/$/.test(url.pathname)
469
+ ? ''
470
+ : '/') +
471
+ `searchparams|${encodeURIComponent(
472
+ url.searchParams.toString()
473
+ )}`;
474
+ }
475
+
476
+ Settings.rewrites.forEach((rewrite) => {
477
+ url.pathname = url.pathname.replace(
478
+ rewrite.source,
479
+ rewrite.destination
489
480
  );
490
- } else if (
491
- middlewareResult.headers.get(
492
- 'x-middleware-rewrite'
493
- ) &&
494
- middlewareResult.headers.get(
495
- 'pz-override-response'
496
- ) === 'true'
481
+ });
482
+
483
+ // if middleware.ts has a return value for current url
484
+ if (
485
+ middlewareResult instanceof NextResponse
497
486
  ) {
487
+ // pz-override-response header is used to prevent 404 page for custom responses.
488
+ if (
489
+ middlewareResult.headers.get(
490
+ 'pz-override-response'
491
+ ) !== 'true'
492
+ ) {
493
+ middlewareResult.headers.set(
494
+ 'x-middleware-rewrite',
495
+ url.href
496
+ );
497
+ } else if (
498
+ middlewareResult.headers.get(
499
+ 'x-middleware-rewrite'
500
+ ) &&
501
+ middlewareResult.headers.get(
502
+ 'pz-override-response'
503
+ ) === 'true'
504
+ ) {
505
+ middlewareResult =
506
+ NextResponse.rewrite(url);
507
+ }
508
+ } else {
509
+ // if middleware.ts doesn't have a return value.
510
+ // e.g. NextResponse.next() doesn't exist in middleware.ts
511
+
498
512
  middlewareResult =
499
513
  NextResponse.rewrite(url);
500
514
  }
501
- } else {
502
- // if middleware.ts doesn't have a return value.
503
- // e.g. NextResponse.next() doesn't exist in middleware.ts
504
515
 
505
- middlewareResult =
506
- NextResponse.rewrite(url);
507
- }
516
+ const { localeUrlStrategy } =
517
+ Settings.localization;
518
+
519
+ const fallbackHost =
520
+ req.headers.get('x-forwarded-host') ||
521
+ req.headers.get('host');
522
+ const hostname =
523
+ process.env.NEXT_PUBLIC_URL ||
524
+ `https://${fallbackHost}`;
525
+ const rootHostname =
526
+ localeUrlStrategy ===
527
+ LocaleUrlStrategy.Subdomain
528
+ ? getRootHostname(hostname)
529
+ : null;
508
530
 
509
- const { localeUrlStrategy } =
510
- Settings.localization;
511
-
512
- const fallbackHost =
513
- req.headers.get('x-forwarded-host') ||
514
- req.headers.get('host');
515
- const hostname =
516
- process.env.NEXT_PUBLIC_URL ||
517
- `https://${fallbackHost}`;
518
- const rootHostname =
519
- localeUrlStrategy ===
520
- LocaleUrlStrategy.Subdomain
521
- ? getRootHostname(hostname)
522
- : null;
531
+ if (
532
+ !url.pathname.startsWith(ordersPrefix)
533
+ ) {
534
+ middlewareResult.cookies.set(
535
+ 'pz-locale',
536
+ locale?.length > 0
537
+ ? locale
538
+ : defaultLocaleValue,
539
+ {
540
+ domain: rootHostname,
541
+ sameSite: 'none',
542
+ secure: true,
543
+ expires: new Date(
544
+ Date.now() +
545
+ 1000 * 60 * 60 * 24 * 7
546
+ ) // 7 days
547
+ }
548
+ );
549
+ }
523
550
 
524
- if (
525
- !url.pathname.startsWith(
526
- ordersPrefix
527
- )
528
- ) {
529
551
  middlewareResult.cookies.set(
530
- 'pz-locale',
531
- locale?.length > 0
532
- ? locale
533
- : defaultLocaleValue,
552
+ 'pz-currency',
553
+ currency,
534
554
  {
535
555
  domain: rootHostname,
536
556
  sameSite: 'none',
@@ -540,7 +560,6 @@ const withPzDefault =
540
560
  ) // 7 days
541
561
  }
542
562
  );
543
- }
544
563
 
545
564
  middlewareResult.cookies.set(
546
565
  'pz-currency',
@@ -583,59 +602,87 @@ const withPzDefault =
583
602
  req.cookies.get('pz-post-checkout-flow')
584
603
  ) {
585
604
  if (
586
- pathnameWithoutLocale.startsWith(
587
- '/orders/completed/'
588
- ) ||
589
- pathnameWithoutLocale.startsWith(
590
- '/basket'
591
- )
605
+ req.cookies.get('pz-locale') &&
606
+ req.cookies.get('pz-locale').value !==
607
+ locale
592
608
  ) {
593
- middlewareResult.cookies.delete(
594
- 'pz-post-checkout-flow'
595
- );
609
+ logger.debug('Locale changed', {
610
+ locale,
611
+ oldLocale:
612
+ req.cookies.get('pz-locale')?.value,
613
+ ip
614
+ });
596
615
  }
597
- }
598
616
 
599
- if (process.env.ACC_APP_VERSION) {
600
617
  middlewareResult.headers.set(
601
- 'acc-app-version',
602
- process.env.ACC_APP_VERSION
618
+ 'pz-url',
619
+ req.nextUrl.toString()
603
620
  );
604
- }
605
621
 
606
- // Set CSRF token if not set
607
- try {
608
- const url = `${Settings.commerceUrl}${user.csrfToken}`;
622
+ if (req.cookies.get('pz-set-currency')) {
623
+ middlewareResult.cookies.delete(
624
+ 'pz-set-currency'
625
+ );
626
+ }
609
627
 
610
- if (!req.cookies.get('csrftoken')) {
611
- const { csrf_token } = await (
612
- await fetch(url)
613
- ).json();
614
- middlewareResult.cookies.set(
615
- 'csrftoken',
616
- csrf_token,
617
- {
618
- path: '/',
619
- domain: rootHostname,
620
- ...getCsrfCookieFlags()
621
- }
628
+ if (
629
+ req.cookies.get('pz-post-checkout-flow')
630
+ ) {
631
+ if (
632
+ pathnameWithoutLocale.startsWith(
633
+ '/orders/completed/'
634
+ ) ||
635
+ pathnameWithoutLocale.startsWith(
636
+ '/basket'
637
+ )
638
+ ) {
639
+ middlewareResult.cookies.delete(
640
+ 'pz-post-checkout-flow'
641
+ );
642
+ }
643
+ }
644
+
645
+ if (process.env.ACC_APP_VERSION) {
646
+ middlewareResult.headers.set(
647
+ 'acc-app-version',
648
+ process.env.ACC_APP_VERSION
622
649
  );
623
650
  }
651
+
652
+ // Set CSRF token if not set
653
+ try {
654
+ const url = `${Settings.commerceUrl}${user.csrfToken}`;
655
+
656
+ if (!req.cookies.get('csrftoken')) {
657
+ const { csrf_token } = await (
658
+ await fetch(url)
659
+ ).json();
660
+ middlewareResult.cookies.set(
661
+ 'csrftoken',
662
+ csrf_token,
663
+ {
664
+ path: '/',
665
+ domain: rootHostname,
666
+ ...getCsrfCookieFlags()
667
+ }
668
+ );
669
+ }
670
+ } catch (error) {
671
+ logger.error('CSRF Error', {
672
+ error,
673
+ ip
674
+ });
675
+ }
624
676
  } catch (error) {
625
- logger.error('CSRF Error', {
677
+ logger.error('withPzDefault Error', {
626
678
  error,
627
679
  ip
628
680
  });
629
681
  }
630
- } catch (error) {
631
- logger.error('withPzDefault Error', {
632
- error,
633
- ip
634
- });
635
- }
636
682
 
637
- return middlewareResult;
638
- })
683
+ return middlewareResult;
684
+ }
685
+ )
639
686
  )
640
687
  )
641
688
  )