@akinon/next 2.0.135-rc.1 → 2.0.135

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/data/urls.ts CHANGED
@@ -40,11 +40,10 @@ export const account = {
40
40
  shipping_option_slug
41
41
  ? `&shipping_option_slug${shipping_option_operator}${shipping_option_slug}`
42
42
  : ''
43
- }${currency ? `&currency=${currency}` : ''}${
44
- filterType && filterValue ? `&${filterType}=${filterValue}` : ''
45
- }`,
43
+ }${currency ? `&currency=${currency}` : ''}
44
+ ${filterType && filterValue ? `&${filterType}=${filterValue}` : ''}`,
46
45
  getOldOrders: ({ page, limit }: { page?: number; limit?: number }) =>
47
- `/users/old-orders/?page=${page || 1}&limit=${limit || 12}`,
46
+ `/users/old-orders/?page=${page || 1}&limit=${limit || 12}}`,
48
47
  getQuotations: (page?: number, status?: string, limit?: number) =>
49
48
  `/b2b/my-quotations/?page=${page || 1}` +
50
49
  (status ? `&status=${status}` : '') +
@@ -184,20 +183,12 @@ export const product = {
184
183
  breadcrumbUrl: (menuitemmodel: string) =>
185
184
  `/menus/generate_breadcrumb/?item=${menuitemmodel}&generator_name=menu_item`,
186
185
  bundleProduct: (productPk: string, queryString: string) =>
187
- `/bundle-product/${productPk}/?${queryString}`,
188
- similarProducts: (params?: string) =>
189
- `/similar-products${params ? `?${params}` : ''}`,
190
- similarProductsList: (params?: string) =>
191
- `/similar-product-list${params ? `?${params}` : ''}`
186
+ `/bundle-product/${productPk}/?${queryString}`
192
187
  };
193
188
 
194
189
  export const wishlist = {
195
190
  getFavorites: ({ page, limit }: { page?: number; limit?: number }) =>
196
191
  `/wishlists/favourite-products/?limit=${limit || 12}&page=${page || 1}`,
197
- getFavouriteProductIds: (productIds: Array<number | string>) =>
198
- `/wishlists/favourite-product-ids/?${productIds
199
- .map((id) => `product_id=${id}`)
200
- .join('&')}`,
201
192
  addFavorite: '/wishlists/favourite-products/',
202
193
  removeFavorite: (favPk: number) => `/wishlists/favourite-products/${favPk}/`,
203
194
  addStockAlert: '/wishlists/product-alerts/',
package/hooks/index.ts CHANGED
@@ -15,4 +15,3 @@ export * from './use-logger-context';
15
15
  export * from './use-sentry-uncaught-errors';
16
16
  export * from './use-pz-params';
17
17
  export * from './use-toast';
18
- export * from './use-client-env';
@@ -39,7 +39,7 @@ export const useCaptcha = () => {
39
39
  };
40
40
 
41
41
  if (csrfToken) {
42
- setCookie('csrftoken', csrfToken, { secure: true });
42
+ setCookie('csrftoken', csrfToken);
43
43
  }
44
44
 
45
45
  const onCaptchaChange = useCallback(async (response) => {
@@ -18,11 +18,7 @@ import {
18
18
  withBfcacheHeaders
19
19
  } from '.';
20
20
  import { getCsrfCookieFlags, urlLocaleMatcherRegex } from '../utils';
21
- import {
22
- getPzSegmentsConfig,
23
- encodePzValue,
24
- isLegacyMode
25
- } from '../utils/pz-segments';
21
+ import { getPzSegmentsConfig, encodePzValue, isLegacyMode } from '../utils/pz-segments';
26
22
  import withCurrency from './currency';
27
23
  import withLocale from './locale';
28
24
  import logger from '../utils/log';
@@ -30,6 +26,10 @@ import { user } from '../data/urls';
30
26
  import { getUrlPathWithLocale } from '../utils/localization';
31
27
  import getRootHostname from '../utils/get-root-hostname';
32
28
  import { LocaleUrlStrategy } from '../localization';
29
+ import {
30
+ THEME_EDITOR_HEALTH_PATH,
31
+ themeEditorHealthResponse
32
+ } from '../utils/theme-editor-health';
33
33
 
34
34
  const POST_CHECKOUT_COOKIE_MAX_AGE_MS = 1000 * 60 * 30; // 30 minutes
35
35
 
@@ -91,6 +91,13 @@ const withPzDefault =
91
91
  return NextResponse.json({ status: 'ok' });
92
92
  }
93
93
 
94
+ // Whether the theme editor can drive this storefront's preview — asked
95
+ // by the editor before it relies on the preview. Answered here, ahead of
96
+ // locale and route handling, because every brand's matcher skips /api.
97
+ if (url.pathname === THEME_EDITOR_HEALTH_PATH) {
98
+ return themeEditorHealthResponse(req);
99
+ }
100
+
94
101
  if (url.pathname.startsWith('/metrics')) {
95
102
  return new NextResponse(null, { status: 200 });
96
103
  }
@@ -336,98 +343,98 @@ const withPzDefault =
336
343
  req: PzNextRequest,
337
344
  event: NextFetchEvent
338
345
  ) => {
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
- );
353
-
354
- middlewareResult = (await middleware(
355
- req,
356
- event
357
- )) as NextResponse | void;
358
-
359
- let customRewriteUrlDiff = '';
346
+ let middlewareResult: NextResponse | void =
347
+ NextResponse.next();
348
+
349
+ try {
350
+ const { locale, prettyUrl, currency } =
351
+ req.middlewareParams.rewrites;
352
+ const { defaultLocaleValue } =
353
+ Settings.localization;
354
+ const url = req.nextUrl.clone();
355
+ const pathnameWithoutLocale =
356
+ url.pathname.replace(
357
+ urlLocaleMatcherRegex,
358
+ ''
359
+ );
360
360
 
361
- if (
362
- middlewareResult instanceof
363
- NextResponse &&
364
- middlewareResult.headers.get(
365
- 'pz-override-response'
366
- ) &&
361
+ middlewareResult = (await middleware(
362
+ req,
363
+ event
364
+ )) as NextResponse | void;
365
+
366
+ let customRewriteUrlDiff = '';
367
+
368
+ if (
369
+ middlewareResult instanceof
370
+ NextResponse &&
371
+ middlewareResult.headers.get(
372
+ 'pz-override-response'
373
+ ) &&
374
+ middlewareResult.headers.get(
375
+ 'x-middleware-rewrite'
376
+ )
377
+ ) {
378
+ const rewriteUrl = new URL(
367
379
  middlewareResult.headers.get(
368
380
  'x-middleware-rewrite'
369
381
  )
370
- ) {
371
- const rewriteUrl = new URL(
372
- middlewareResult.headers.get(
373
- 'x-middleware-rewrite'
374
- )
382
+ );
383
+ const originalUrl = new URL(req.url);
384
+ customRewriteUrlDiff =
385
+ rewriteUrl.pathname.replace(
386
+ originalUrl.pathname,
387
+ ''
375
388
  );
376
- const originalUrl = new URL(req.url);
377
- customRewriteUrlDiff =
378
- rewriteUrl.pathname.replace(
379
- originalUrl.pathname,
380
- ''
381
- );
382
- }
389
+ }
383
390
 
384
- let ordersPrefix: string;
391
+ let ordersPrefix: string;
385
392
 
386
- if (isLegacyMode(Settings)) {
387
- url.basePath = `/${commerceUrl}`;
388
- url.pathname = `/${
389
- locale.length ? `${locale}/` : ''
390
- }${currency}/${customRewriteUrlDiff}${
393
+ if (isLegacyMode(Settings)) {
394
+ url.basePath = `/${commerceUrl}`;
395
+ url.pathname =
396
+ `/${locale.length ? `${locale}/` : ''}${currency}/${customRewriteUrlDiff}${
391
397
  prettyUrl ?? pathnameWithoutLocale
392
398
  }`.replace(/\/+/g, '/');
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) => [
399
+ ordersPrefix = `/${currency}/orders`;
400
+ } else {
401
+ const pzConfig =
402
+ getPzSegmentsConfig(Settings);
403
+ const fullUrlPath =
404
+ `${customRewriteUrlDiff}${
405
+ prettyUrl ?? pathnameWithoutLocale
406
+ }`.replace(/\/+/g, '/');
407
+ const fullUrl = `${req.nextUrl.origin}${fullUrlPath}`;
408
+ const resolvedLocale =
409
+ locale?.length > 0
410
+ ? locale
411
+ : Settings.localization
412
+ .defaultLocaleValue;
413
+ const resolveContext = {
414
+ req,
415
+ event,
416
+ url,
417
+ locale: resolvedLocale,
418
+ currency,
419
+ pathname: pathnameWithoutLocale
420
+ };
421
+ const customSegments = pzConfig.segments
422
+ .filter(
423
+ (seg) =>
424
+ seg.name !== 'locale' &&
425
+ seg.name !== 'currency' &&
426
+ seg.name !== 'url'
427
+ );
428
+ const segmentValues: Record<
429
+ string,
430
+ string
431
+ > = {
432
+ locale: resolvedLocale,
433
+ currency,
434
+ url: encodeURIComponent(fullUrl),
435
+ ...Object.fromEntries(
436
+ customSegments
437
+ .map((seg) => [
431
438
  seg.name,
432
439
  req.middlewareParams.rewrites[
433
440
  seg.name
@@ -436,121 +443,105 @@ const withPzDefault =
436
443
  ? seg.resolve(resolveContext)
437
444
  : '')
438
445
  ])
439
- )
440
- };
446
+ )
447
+ };
448
+
449
+ const pzValue = encodePzValue(
450
+ segmentValues,
451
+ pzConfig
452
+ );
441
453
 
442
- const pzValue = encodePzValue(
443
- segmentValues,
444
- pzConfig
454
+ url.pathname =
455
+ `/${pzValue}/${fullUrlPath}`.replace(
456
+ /\/+/g,
457
+ '/'
445
458
  );
459
+ ordersPrefix = `/${pzValue}/orders`;
460
+ }
446
461
 
447
- url.pathname =
448
- `/${pzValue}/${fullUrlPath}`.replace(
449
- /\/+/g,
450
- '/'
451
- );
452
- ordersPrefix = `/${pzValue}/orders`;
453
- }
462
+ if (
463
+ Settings.usePrettyUrlRoute &&
464
+ url.searchParams.toString().length > 0 &&
465
+ !Object.entries(ROUTES).find(
466
+ ([, value]) =>
467
+ new RegExp(`^${value}/?$`).test(
468
+ pathnameWithoutLocale
469
+ )
470
+ )
471
+ ) {
472
+ url.pathname =
473
+ url.pathname +
474
+ (/\/$/.test(url.pathname) ? '' : '/') +
475
+ `searchparams|${encodeURIComponent(
476
+ url.searchParams.toString()
477
+ )}`;
478
+ }
479
+
480
+ Settings.rewrites.forEach((rewrite) => {
481
+ url.pathname = url.pathname.replace(
482
+ rewrite.source,
483
+ rewrite.destination
484
+ );
485
+ });
454
486
 
487
+ // if middleware.ts has a return value for current url
488
+ if (
489
+ middlewareResult instanceof NextResponse
490
+ ) {
491
+ // pz-override-response header is used to prevent 404 page for custom responses.
455
492
  if (
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
- )
493
+ middlewareResult.headers.get(
494
+ 'pz-override-response'
495
+ ) !== 'true'
465
496
  ) {
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
497
+ middlewareResult.headers.set(
498
+ 'x-middleware-rewrite',
499
+ url.href
480
500
  );
481
- });
482
-
483
- // if middleware.ts has a return value for current url
484
- if (
485
- middlewareResult instanceof NextResponse
501
+ } else if (
502
+ middlewareResult.headers.get(
503
+ 'x-middleware-rewrite'
504
+ ) &&
505
+ middlewareResult.headers.get(
506
+ 'pz-override-response'
507
+ ) === 'true'
486
508
  ) {
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
-
512
509
  middlewareResult =
513
510
  NextResponse.rewrite(url);
514
511
  }
512
+ } else {
513
+ // if middleware.ts doesn't have a return value.
514
+ // e.g. NextResponse.next() doesn't exist in middleware.ts
515
515
 
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;
530
-
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
- }
516
+ middlewareResult =
517
+ NextResponse.rewrite(url);
518
+ }
550
519
 
520
+ const { localeUrlStrategy } =
521
+ Settings.localization;
522
+
523
+ const fallbackHost =
524
+ req.headers.get('x-forwarded-host') ||
525
+ req.headers.get('host');
526
+ const hostname =
527
+ process.env.NEXT_PUBLIC_URL ||
528
+ `https://${fallbackHost}`;
529
+ const rootHostname =
530
+ localeUrlStrategy ===
531
+ LocaleUrlStrategy.Subdomain
532
+ ? getRootHostname(hostname)
533
+ : null;
534
+
535
+ if (
536
+ !url.pathname.startsWith(
537
+ ordersPrefix
538
+ )
539
+ ) {
551
540
  middlewareResult.cookies.set(
552
- 'pz-currency',
553
- currency,
541
+ 'pz-locale',
542
+ locale?.length > 0
543
+ ? locale
544
+ : defaultLocaleValue,
554
545
  {
555
546
  domain: rootHostname,
556
547
  sameSite: 'none',
@@ -560,89 +551,102 @@ const withPzDefault =
560
551
  ) // 7 days
561
552
  }
562
553
  );
554
+ }
563
555
 
564
- if (
565
- req.cookies.get('pz-locale') &&
566
- req.cookies.get('pz-locale').value !==
567
- locale
568
- ) {
569
- logger.debug('Locale changed', {
570
- locale,
571
- oldLocale:
572
- req.cookies.get('pz-locale')?.value,
573
- ip
574
- });
556
+ middlewareResult.cookies.set(
557
+ 'pz-currency',
558
+ currency,
559
+ {
560
+ domain: rootHostname,
561
+ sameSite: 'none',
562
+ secure: true,
563
+ expires: new Date(
564
+ Date.now() + 1000 * 60 * 60 * 24 * 7
565
+ ) // 7 days
575
566
  }
567
+ );
568
+
569
+ if (
570
+ req.cookies.get('pz-locale') &&
571
+ req.cookies.get('pz-locale').value !==
572
+ locale
573
+ ) {
574
+ logger.debug('Locale changed', {
575
+ locale,
576
+ oldLocale:
577
+ req.cookies.get('pz-locale')?.value,
578
+ ip
579
+ });
580
+ }
576
581
 
577
- middlewareResult.headers.set(
578
- 'pz-url',
579
- req.nextUrl.toString()
582
+ middlewareResult.headers.set(
583
+ 'pz-url',
584
+ req.nextUrl.toString()
585
+ );
586
+
587
+ if (req.cookies.get('pz-set-currency')) {
588
+ middlewareResult.cookies.delete(
589
+ 'pz-set-currency'
580
590
  );
591
+ }
581
592
 
582
- if (req.cookies.get('pz-set-currency')) {
593
+ if (
594
+ req.cookies.get('pz-post-checkout-flow')
595
+ ) {
596
+ if (
597
+ pathnameWithoutLocale.startsWith(
598
+ '/orders/completed/'
599
+ ) ||
600
+ pathnameWithoutLocale.startsWith(
601
+ '/basket'
602
+ )
603
+ ) {
583
604
  middlewareResult.cookies.delete(
584
- 'pz-set-currency'
605
+ 'pz-post-checkout-flow'
585
606
  );
586
607
  }
608
+ }
587
609
 
588
- if (
589
- req.cookies.get('pz-post-checkout-flow')
590
- ) {
591
- if (
592
- pathnameWithoutLocale.startsWith(
593
- '/orders/completed/'
594
- ) ||
595
- pathnameWithoutLocale.startsWith(
596
- '/basket'
597
- )
598
- ) {
599
- middlewareResult.cookies.delete(
600
- 'pz-post-checkout-flow'
601
- );
602
- }
603
- }
610
+ if (process.env.ACC_APP_VERSION) {
611
+ middlewareResult.headers.set(
612
+ 'acc-app-version',
613
+ process.env.ACC_APP_VERSION
614
+ );
615
+ }
604
616
 
605
- if (process.env.ACC_APP_VERSION) {
606
- middlewareResult.headers.set(
607
- 'acc-app-version',
608
- process.env.ACC_APP_VERSION
609
- );
610
- }
617
+ // Set CSRF token if not set
618
+ try {
619
+ const url = `${Settings.commerceUrl}${user.csrfToken}`;
611
620
 
612
- // Set CSRF token if not set
613
- try {
614
- const url = `${Settings.commerceUrl}${user.csrfToken}`;
615
-
616
- if (!req.cookies.get('csrftoken')) {
617
- const { csrf_token } = await (
618
- await fetch(url)
619
- ).json();
620
- middlewareResult.cookies.set(
621
- 'csrftoken',
622
- csrf_token,
623
- {
624
- path: '/',
625
- domain: rootHostname,
626
- ...getCsrfCookieFlags()
627
- }
628
- );
629
- }
630
- } catch (error) {
631
- logger.error('CSRF Error', {
632
- error,
633
- ip
634
- });
621
+ if (!req.cookies.get('csrftoken')) {
622
+ const { csrf_token } = await (
623
+ await fetch(url)
624
+ ).json();
625
+ middlewareResult.cookies.set(
626
+ 'csrftoken',
627
+ csrf_token,
628
+ {
629
+ path: '/',
630
+ domain: rootHostname,
631
+ ...getCsrfCookieFlags()
632
+ }
633
+ );
635
634
  }
636
635
  } catch (error) {
637
- logger.error('withPzDefault Error', {
636
+ logger.error('CSRF Error', {
638
637
  error,
639
638
  ip
640
639
  });
641
640
  }
642
-
643
- return middlewareResult;
641
+ } catch (error) {
642
+ logger.error('withPzDefault Error', {
643
+ error,
644
+ ip
645
+ });
644
646
  }
645
- )
647
+
648
+ return middlewareResult;
649
+ })
646
650
  )
647
651
  )
648
652
  )