@snabcentr/client-core 4.4.0 → 4.5.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.
@@ -1,5 +1,5 @@
1
1
  import * as i1 from 'rxjs';
2
- import { of, startWith as startWith$1, Subject, ReplaySubject, partition, combineLatest, map as map$1, debounceTime, switchMap, tap, filter, shareReplay, distinctUntilChanged, BehaviorSubject, materialize, dematerialize, merge, distinctUntilKeyChanged, skip, first, catchError as catchError$1, throwError, expand, takeWhile, toArray, EMPTY, from, take, defaultIfEmpty, concatMap, finalize, takeUntil, interval, share, scan } from 'rxjs';
2
+ import { of, startWith as startWith$1, Subject, ReplaySubject, partition, combineLatest, map as map$1, debounceTime, switchMap, tap, filter, shareReplay, distinctUntilChanged, BehaviorSubject, materialize, dematerialize, merge, distinctUntilKeyChanged, skip, first, catchError as catchError$1, throwError, expand, takeWhile, toArray, EMPTY, take, defaultIfEmpty, concatMap, finalize, takeUntil, interval, share, scan } from 'rxjs';
3
3
  import { map, startWith, catchError } from 'rxjs/operators';
4
4
  import { parseISO, parse, isValid, format } from 'date-fns';
5
5
  import { isString, isNil, isObject, isDate, isMatch, isArray, get, isNumber, isBoolean } from 'lodash-es';
@@ -267,7 +267,17 @@ const IS_SERVER = new InjectionToken('IS_SERVER', {
267
267
  factory: () => isPlatformServer(inject(PLATFORM_ID)),
268
268
  });
269
269
  /**
270
- * Токен для получения данных об ответе на запрос.
270
+ * Токен для получения данных об ответе на запрос (Express `Response`), доступен только на сервере при SSR.
271
+ *
272
+ * Переходное состояние: `server.ts` приложений сейчас работает на `CommonEngine` из `@angular/ssr/node`,
273
+ * который провайдит этот кастомный токен per-request. `CommonEngine` помечен deprecated; целевой стек —
274
+ * `AngularNodeAppEngine` + `createNodeRequestHandler`. При миграции `server.ts` на этот стек откажитесь от
275
+ * данного токена в пользу нативного `RESPONSE_INIT` (`InjectionToken<ResponseInit | null>` из `@angular/core`):
276
+ * движок провайдит его автоматически и применяет `status`/`headers` к ответу после рендера. До миграции
277
+ * `server.ts` токен остаётся рабочим механизмом SSR-редиректов и менять его не требуется.
278
+ *
279
+ * @deprecated Переходный токен SSR-ответа: при миграции `server.ts` на `AngularNodeAppEngine` будет заменён
280
+ * нативным `RESPONSE_INIT`. Метка-напоминание; до миграции токен остаётся рабочим, удалять/менять не требуется.
271
281
  */
272
282
  const RESPONSE = new InjectionToken('RESPONSE');
273
283
 
@@ -3575,10 +3585,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
3575
3585
  * Сервис редиректа на родительскую категорию при недоступности (HTTP 404) товара или категории.
3576
3586
  *
3577
3587
  * Запрашивает у бэкенда родительскую категорию недоступной сущности и выполняет редирект:
3578
- * - на сервере (SSR) — выставляет HTTP-статус 302 и заголовок `Location` для корректного редиректа поисковых ботов;
3579
- * - в браузеревыполняет навигацию средствами {@link Router}.
3588
+ * - на сервере (SSR) при доступном {@link RESPONSE} — выставляет HTTP-статус 302 и заголовок `Location` для корректного редиректа поисковых ботов;
3589
+ * - на сервере без {@link RESPONSE} (например, dev-сервер `ng serve`) завершает поток ошибкой 404, чтобы отобразилась страница ошибки;
3590
+ * - в браузере — выполняет полную навигацию на родительскую категорию.
3580
3591
  *
3581
- * Если родительская категория не найдена, поток завершается ошибкой {@link HttpErrorResponse},
3592
+ * Если родительская категория не найдена, поток также завершается ошибкой {@link HttpErrorResponse},
3582
3593
  * чтобы вызывающий код отобразил страницу ошибки.
3583
3594
  */
3584
3595
  class ScCatalogRedirectService {
@@ -3601,8 +3612,18 @@ class ScCatalogRedirectService {
3601
3612
  this.isServer = inject(IS_SERVER);
3602
3613
  /**
3603
3614
  * Данные об ответе на запрос (доступны только на сервере при SSR).
3615
+ *
3616
+ * Angular 21 (миграция SSR): {@link RESPONSE} — кастомный Express-токен, который провайдится в `server.ts`
3617
+ * через CommonEngine. На upgrade-ветке `server.ts` остался на CommonEngine, поэтому при слиянии здесь
3618
+ * ничего менять не нужно. Если `server.ts` мигрируют на `AngularNodeAppEngine` + `createNodeRequestHandler`,
3619
+ * замените {@link RESPONSE} на нативный `RESPONSE_INIT` (`InjectionToken<ResponseInit | null>` из `@angular/core`);
3620
+ * см. серверную ветку в {@link redirectToParentCategory$}.
3604
3621
  */
3605
3622
  this.response = inject(RESPONSE, { optional: true });
3623
+ /**
3624
+ * Документ текущей страницы.
3625
+ */
3626
+ this.document = inject(DOCUMENT);
3606
3627
  }
3607
3628
  /**
3608
3629
  * Выполняет редирект на родительскую категорию недоступной категории.
@@ -3637,13 +3658,35 @@ class ScCatalogRedirectService {
3637
3658
  return throwError(() => new HttpErrorResponse({ status: 404 }));
3638
3659
  }
3639
3660
  const urlTree = this.router.createUrlTree(['/catalog', target]);
3661
+ const targetUrl = this.router.serializeUrl(urlTree);
3640
3662
  if (this.isServer) {
3641
- // SSR: выставляем 302 и заголовок Location для корректного редиректа поисковых ботов.
3642
- this.response?.setHeader('Location', this.router.serializeUrl(urlTree));
3643
- this.response?.status(302);
3644
- return EMPTY;
3663
+ // SSR с доступным RESPONSE (прод-сервер): выставляем 302 и заголовок Location для корректного редиректа поисковых ботов.
3664
+ //
3665
+ // Angular 21 (миграция SSR): при переходе server.ts на AngularNodeAppEngine выставляйте статус/заголовок
3666
+ // через нативный RESPONSE_INIT вместо Express-методов response.setHeader/response.status:
3667
+ // if (this.responseInit) { this.responseInit.status = 302; (this.responseInit.headers as Record<string, string>)['Location'] = targetUrl; }
3668
+ if (this.response) {
3669
+ this.response.setHeader('Location', targetUrl);
3670
+ this.response.status(302);
3671
+ return EMPTY;
3672
+ }
3673
+ // SSR без RESPONSE (например, dev-сервер ng serve): серверный редирект невозможен,
3674
+ // поэтому отображаем страницу ошибки, как до внедрения редиректа, вместо бесконечного лоадера.
3675
+ //
3676
+ // Angular 21 (миграция SSR): этот фолбэк нужен, пока ng serve не исполняет server.ts (он на CommonEngine).
3677
+ // После миграции server.ts на createNodeRequestHandler dev-сервер начнёт исполнять server.ts, и RESPONSE/RESPONSE_INIT
3678
+ // станет доступен в ng serve — тогда эту ветку с throwError(404) можно удалить.
3679
+ return throwError(() => new HttpErrorResponse({ status: 404 }));
3645
3680
  }
3646
- return from(this.router.navigateByUrl(urlTree, { replaceUrl: true })).pipe(switchMap(() => EMPTY));
3681
+ // Браузер: поток данных категории (SC_CATEGORY_INFO) завершается ошибкой при 404 и не возобновляется
3682
+ // при навигации в рамках того же маршрута, поэтому редирект выполняется полной перезагрузкой страницы.
3683
+ // location.replace не добавляет запись в историю, чтобы кнопка «Назад» не возвращала на недоступную страницу.
3684
+ //
3685
+ // Angular 21 (миграция SSR): эту строку апгрейд НЕ снимает — причина в рантайме приложения (мёртвый поток
3686
+ // SC_CATEGORY_INFO при SPA-навигации), а не в SSR. Вернуть SPA-навигацию (router.navigateByUrl) можно только
3687
+ // сделав SC_CATEGORY_INFO устойчивым к 404 (ловить ошибку внутри switchMap) либо унеся редирект в guard + RedirectCommand.
3688
+ this.document.location.replace(targetUrl);
3689
+ return EMPTY;
3647
3690
  }));
3648
3691
  }
3649
3692
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: ScCatalogRedirectService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }