@snabcentr/client-core 4.2.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, 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';
@@ -14,7 +14,7 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
14
14
  import { tuiIsPresent, TuiDay, TUI_TRUE_HANDLER } from '@taiga-ui/cdk';
15
15
  import { tuiCleanObject } from '@taiga-ui/addon-doc/utils';
16
16
  import * as i2 from '@angular/router';
17
- import { NavigationEnd, Router, ActivatedRoute } from '@angular/router';
17
+ import { Router, NavigationEnd, ActivatedRoute } from '@angular/router';
18
18
  import { toSnake, objectToSnake, objectToCamel } from 'ts-case-convert';
19
19
  import { Meta, Title } from '@angular/platform-browser';
20
20
 
@@ -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
 
@@ -3487,6 +3497,28 @@ class ScCatalogService {
3487
3497
  }
3488
3498
  }));
3489
3499
  }
3500
+ /**
3501
+ * Возвращает данные о родительской категории для редиректа, когда категория недоступна (HTTP 404).
3502
+ * Если у категории нет нескрытой родительской категории, возвращается пустой объект.
3503
+ *
3504
+ * @param categoryIdOrSlug Идентификатор или slug недоступной категории.
3505
+ */
3506
+ getCategoryParentCategory$(categoryIdOrSlug) {
3507
+ return this.http.get(`${this.urls.apiUrl}/catalog/categories/${categoryIdOrSlug}/parent-category`, {
3508
+ context: SC_IS_HIDDEN_ERROR_ALERT_HTTP_CONTEXT,
3509
+ });
3510
+ }
3511
+ /**
3512
+ * Возвращает данные о родительской категории для редиректа, когда товар недоступен (HTTP 404).
3513
+ * Если у товара нет нескрытой родительской категории, возвращается пустой объект.
3514
+ *
3515
+ * @param productIdOrSlug Идентификатор или slug недоступного товара.
3516
+ */
3517
+ getProductParentCategory$(productIdOrSlug) {
3518
+ return this.http.get(`${this.urls.apiUrl}/catalog/products/${productIdOrSlug}/parent-category`, {
3519
+ context: SC_IS_HIDDEN_ERROR_ALERT_HTTP_CONTEXT,
3520
+ });
3521
+ }
3490
3522
  getProductDataCached$(productIdOrSlug) {
3491
3523
  const valueFromMap = this.productIdOrSlugMap.get(productIdOrSlug);
3492
3524
  if (valueFromMap) {
@@ -3549,6 +3581,124 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
3549
3581
  args: [SC_CACHE_LIFETIME]
3550
3582
  }] }, { type: ScUserMetrikaService }] });
3551
3583
 
3584
+ /**
3585
+ * Сервис редиректа на родительскую категорию при недоступности (HTTP 404) товара или категории.
3586
+ *
3587
+ * Запрашивает у бэкенда родительскую категорию недоступной сущности и выполняет редирект:
3588
+ * - на сервере (SSR) при доступном {@link RESPONSE} — выставляет HTTP-статус 302 и заголовок `Location` для корректного редиректа поисковых ботов;
3589
+ * - на сервере без {@link RESPONSE} (например, dev-сервер `ng serve`) — завершает поток ошибкой 404, чтобы отобразилась страница ошибки;
3590
+ * - в браузере — выполняет полную навигацию на родительскую категорию.
3591
+ *
3592
+ * Если родительская категория не найдена, поток также завершается ошибкой {@link HttpErrorResponse},
3593
+ * чтобы вызывающий код отобразил страницу ошибки.
3594
+ */
3595
+ class ScCatalogRedirectService {
3596
+ constructor() {
3597
+ /**
3598
+ * Сервис для работы с каталогом.
3599
+ */
3600
+ this.catalogService = inject(ScCatalogService);
3601
+ /**
3602
+ * Сервис маршрутизации.
3603
+ */
3604
+ this.router = inject(Router);
3605
+ /**
3606
+ * Признак использования идентификатора или slug в маршрутах товаров и категорий.
3607
+ */
3608
+ this.idOrSlug = inject(SC_ID_OR_SLUG_IN_ROUTE);
3609
+ /**
3610
+ * Признак, что текущий скрипт исполняется на сервере.
3611
+ */
3612
+ this.isServer = inject(IS_SERVER);
3613
+ /**
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$}.
3621
+ */
3622
+ this.response = inject(RESPONSE, { optional: true });
3623
+ /**
3624
+ * Документ текущей страницы.
3625
+ */
3626
+ this.document = inject(DOCUMENT);
3627
+ }
3628
+ /**
3629
+ * Выполняет редирект на родительскую категорию недоступной категории.
3630
+ *
3631
+ * @param categoryIdOrSlug Идентификатор или slug недоступной категории.
3632
+ * @returns Поток, завершающийся после редиректа. Эмитит ошибку {@link HttpErrorResponse}, если родительская категория не найдена.
3633
+ */
3634
+ redirectToCategoryParent$(categoryIdOrSlug) {
3635
+ return this.redirectToParentCategory$(this.catalogService.getCategoryParentCategory$(categoryIdOrSlug));
3636
+ }
3637
+ /**
3638
+ * Выполняет редирект на родительскую категорию недоступного товара.
3639
+ *
3640
+ * @param productIdOrSlug Идентификатор или slug недоступного товара.
3641
+ * @returns Поток, завершающийся после редиректа. Эмитит ошибку {@link HttpErrorResponse}, если родительская категория не найдена.
3642
+ */
3643
+ redirectToProductParent$(productIdOrSlug) {
3644
+ return this.redirectToParentCategory$(this.catalogService.getProductParentCategory$(productIdOrSlug));
3645
+ }
3646
+ /**
3647
+ * Выполняет редирект на полученную родительскую категорию.
3648
+ *
3649
+ * @param parentCategory$ Поток с данными родительской категории.
3650
+ * @returns Поток, завершающийся после редиректа. Эмитит ошибку {@link HttpErrorResponse} с кодом 404, если родительская категория не найдена.
3651
+ */
3652
+ redirectToParentCategory$(parentCategory$) {
3653
+ return parentCategory$.pipe(switchMap((parentCategory) => {
3654
+ // eslint-disable-next-line security/detect-object-injection
3655
+ const target = parentCategory[this.idOrSlug];
3656
+ // Родительская категория не найдена — отображаем страницу ошибки.
3657
+ if (!tuiIsPresent(target)) {
3658
+ return throwError(() => new HttpErrorResponse({ status: 404 }));
3659
+ }
3660
+ const urlTree = this.router.createUrlTree(['/catalog', target]);
3661
+ const targetUrl = this.router.serializeUrl(urlTree);
3662
+ if (this.isServer) {
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 }));
3680
+ }
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;
3690
+ }));
3691
+ }
3692
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: ScCatalogRedirectService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3693
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: ScCatalogRedirectService, providedIn: 'root' }); }
3694
+ }
3695
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: ScCatalogRedirectService, decorators: [{
3696
+ type: Injectable,
3697
+ args: [{
3698
+ providedIn: 'root',
3699
+ }]
3700
+ }] });
3701
+
3552
3702
  /* eslint-disable no-param-reassign,no-return-assign,no-void */
3553
3703
  /**
3554
3704
  * Сервис для работы с избранными товарами и категориями.
@@ -8369,5 +8519,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
8369
8519
  * Generated bundle index. Do not edit.
8370
8520
  */
8371
8521
 
8372
- export { CATEGORY_PROVIDERS, EMPTY_CART, IS_BROWSER, IS_RUNNING_ON_TERMINAL, IS_SERVER, RESPONSE, SC_ACCESS_AUTH_TOKEN_STORAGE_KEY, SC_API_KEYS, SC_AUTH_ADD_HEADER_REQUIRED, SC_AUTH_AS_CLIENT_DEFAULT_OPTIONS, SC_AUTH_AS_CLIENT_OPTIONS, SC_CACHE_LIFETIME, SC_CACHE_SETTINGS, SC_CATALOG_ITEM_PAGE_META, SC_CATALOG_ROOT_PAGE_META, SC_CATEGORY_INFO, SC_COMPANY_INFO, SC_COMPANY_NAME, SC_CONFIGURATOR_COMPONENTS, SC_CONFIGURATOR_SETTINGS, SC_COUNT_FIRST_DISCOUNTED_PRODUCTS, SC_COUNT_LAST_NEWS, SC_DATE_FORMAT, SC_DEFAULT_PAGE_META, SC_FEEDBACK_API, SC_GUEST_ENDPOINTS_TOKEN, SC_GUEST_PARAMETER_NAME_TOKEN, SC_GUEST_TOKEN_STORAGE_KEY, SC_ID_OR_SLUG_IN_ROUTE, SC_IS_HEADER_REQUIRED, SC_IS_HIDDEN_ERROR_ALERT, SC_IS_HIDDEN_ERROR_ALERT_HTTP_CONTEXT, SC_IS_LOGOUT_REQUEST, SC_IS_REFRESH_REQUIRED, SC_LINEAR_VALUES, SC_LINEAR_VALUES_TOKEN, SC_MAX_LENGTH_SEARCH_TERM, SC_MIN_LENGTH_SEARCH_TERM, SC_NEXT_PAGE_PAGINATION_CLICK, SC_ORDER_LOADER, SC_ORDER_LOADING, SC_PATH_IMAGE_NOT_FOUND, SC_PRODUCT_PAGINATION_DEFAULT_OPTIONS, SC_PRODUCT_PAGINATION_OPTIONS, SC_REFRESH_AUTH_TOKEN_STORAGE_KEY, SC_RELEASE, SC_UPDATE_INTERVAL, SC_URLS, SC_USER_INFO, SC_VACANCIES_DATA_SOURCE, SC_VIRTUAL_CATEGORY_INFO, SC_VIRTUAL_CATEGORY_PROVIDERS, SEARCH_TERM, SEARCH_TERM_PROVIDERS, ScAuthAsClientGuard, ScAuthInterceptor, ScAuthService, ScBanner, ScBannerService, ScCacheInterceptor, ScCacheSettings, ScCachedData, ScCachedItem, ScCart, ScCartService, ScCatalogFilterService, ScCatalogFormat, ScCatalogItem, ScCatalogService, ScCatalogableItem, ScCategory, ScClientType, ScCodedIdentity, ScConfiguratorService, ScContactsService, ScContragentService, ScConvertInterceptor, ScConvertersService, ScDateFormatInterceptor, ScDeletableNamedIdentity, ScDeliveryAddressService, ScDeliveryCost, ScDeliveryType, ScDocumentInfoNode, ScDocumentInfoTypesEnum, ScErrorRequestState, ScErrorsInterceptor, ScFavoriteService, ScFeedbackForms, ScFeedbackService, ScFilesService, ScFrequentlyAskedQuestionsService, ScGuestInterceptor, ScHiddenCatalogableItem, ScIBreadcrumbItem, ScISuggestionType, ScIconTypesEnum, ScIdOrSlugGuard, ScIdOrSlugPipe, ScIdentity, ScImage, ScImageHelper, ScLoadingRequestState, ScLocationsService, ScMediaImageTransformerPipe, ScMimeTypes, ScNamedIdentity, ScNews, ScNewsService, ScNotificationActionTypes, ScNotificationLevelNames, ScNotificationsService, ScOpfList, ScOptionsInterceptor, ScOrder, ScOrderBase, ScOrderDraft, ScOrderDraftShort, ScOrderDraftType, ScOrderDraftsService, ScOrderItem, ScOrderShort, ScOrderStateStatus, ScOrdersService, ScPaginationService, ScPaymentStatus, ScPaymentType, ScPhoneService, ScPrimaryCatalogableItem, ScProduct, ScProductTileType, ScQuestionnaireService, ScQuestionnaireStatusEnum, ScReclamationService, ScReclamationStatus, ScRecommendationService, ScReference, ScReferenceName, ScReferencesService, ScRequestStateStatusEnum, ScRequisitesService, ScRouteKeys, ScSearchService, ScSeoService, ScSocialType, ScSuccessRequestState, ScSuggestionService, ScSum, ScTokenService, ScUIService, ScUTMService, ScUnitsHelper, ScUpdatableNamedIdentity, ScUploadedFile, ScUser, ScUserMetadata, ScUserMetrikaGoalsEnum, ScUserMetrikaService, ScUserService, ScUserType, ScVCardService, ScVacanciesList, ScVacanciesService, ScVacancy, ScVerificationService, ScVirtualCategory, ScWarehouseService, SchemaOrgFactory, TERMINAL_PROVIDERS, USER_AGENT_TERMINAL, filterChangedByKey, isExpiredToken, loadingPlaceholder, mapRequestStateToDataOrNull, mapToRequestState, runningOnTerminalFactory, scGetCurrentRoute, scOrderIsLoaded, searchTermFactory };
8522
+ export { CATEGORY_PROVIDERS, EMPTY_CART, IS_BROWSER, IS_RUNNING_ON_TERMINAL, IS_SERVER, RESPONSE, SC_ACCESS_AUTH_TOKEN_STORAGE_KEY, SC_API_KEYS, SC_AUTH_ADD_HEADER_REQUIRED, SC_AUTH_AS_CLIENT_DEFAULT_OPTIONS, SC_AUTH_AS_CLIENT_OPTIONS, SC_CACHE_LIFETIME, SC_CACHE_SETTINGS, SC_CATALOG_ITEM_PAGE_META, SC_CATALOG_ROOT_PAGE_META, SC_CATEGORY_INFO, SC_COMPANY_INFO, SC_COMPANY_NAME, SC_CONFIGURATOR_COMPONENTS, SC_CONFIGURATOR_SETTINGS, SC_COUNT_FIRST_DISCOUNTED_PRODUCTS, SC_COUNT_LAST_NEWS, SC_DATE_FORMAT, SC_DEFAULT_PAGE_META, SC_FEEDBACK_API, SC_GUEST_ENDPOINTS_TOKEN, SC_GUEST_PARAMETER_NAME_TOKEN, SC_GUEST_TOKEN_STORAGE_KEY, SC_ID_OR_SLUG_IN_ROUTE, SC_IS_HEADER_REQUIRED, SC_IS_HIDDEN_ERROR_ALERT, SC_IS_HIDDEN_ERROR_ALERT_HTTP_CONTEXT, SC_IS_LOGOUT_REQUEST, SC_IS_REFRESH_REQUIRED, SC_LINEAR_VALUES, SC_LINEAR_VALUES_TOKEN, SC_MAX_LENGTH_SEARCH_TERM, SC_MIN_LENGTH_SEARCH_TERM, SC_NEXT_PAGE_PAGINATION_CLICK, SC_ORDER_LOADER, SC_ORDER_LOADING, SC_PATH_IMAGE_NOT_FOUND, SC_PRODUCT_PAGINATION_DEFAULT_OPTIONS, SC_PRODUCT_PAGINATION_OPTIONS, SC_REFRESH_AUTH_TOKEN_STORAGE_KEY, SC_RELEASE, SC_UPDATE_INTERVAL, SC_URLS, SC_USER_INFO, SC_VACANCIES_DATA_SOURCE, SC_VIRTUAL_CATEGORY_INFO, SC_VIRTUAL_CATEGORY_PROVIDERS, SEARCH_TERM, SEARCH_TERM_PROVIDERS, ScAuthAsClientGuard, ScAuthInterceptor, ScAuthService, ScBanner, ScBannerService, ScCacheInterceptor, ScCacheSettings, ScCachedData, ScCachedItem, ScCart, ScCartService, ScCatalogFilterService, ScCatalogFormat, ScCatalogItem, ScCatalogRedirectService, ScCatalogService, ScCatalogableItem, ScCategory, ScClientType, ScCodedIdentity, ScConfiguratorService, ScContactsService, ScContragentService, ScConvertInterceptor, ScConvertersService, ScDateFormatInterceptor, ScDeletableNamedIdentity, ScDeliveryAddressService, ScDeliveryCost, ScDeliveryType, ScDocumentInfoNode, ScDocumentInfoTypesEnum, ScErrorRequestState, ScErrorsInterceptor, ScFavoriteService, ScFeedbackForms, ScFeedbackService, ScFilesService, ScFrequentlyAskedQuestionsService, ScGuestInterceptor, ScHiddenCatalogableItem, ScIBreadcrumbItem, ScISuggestionType, ScIconTypesEnum, ScIdOrSlugGuard, ScIdOrSlugPipe, ScIdentity, ScImage, ScImageHelper, ScLoadingRequestState, ScLocationsService, ScMediaImageTransformerPipe, ScMimeTypes, ScNamedIdentity, ScNews, ScNewsService, ScNotificationActionTypes, ScNotificationLevelNames, ScNotificationsService, ScOpfList, ScOptionsInterceptor, ScOrder, ScOrderBase, ScOrderDraft, ScOrderDraftShort, ScOrderDraftType, ScOrderDraftsService, ScOrderItem, ScOrderShort, ScOrderStateStatus, ScOrdersService, ScPaginationService, ScPaymentStatus, ScPaymentType, ScPhoneService, ScPrimaryCatalogableItem, ScProduct, ScProductTileType, ScQuestionnaireService, ScQuestionnaireStatusEnum, ScReclamationService, ScReclamationStatus, ScRecommendationService, ScReference, ScReferenceName, ScReferencesService, ScRequestStateStatusEnum, ScRequisitesService, ScRouteKeys, ScSearchService, ScSeoService, ScSocialType, ScSuccessRequestState, ScSuggestionService, ScSum, ScTokenService, ScUIService, ScUTMService, ScUnitsHelper, ScUpdatableNamedIdentity, ScUploadedFile, ScUser, ScUserMetadata, ScUserMetrikaGoalsEnum, ScUserMetrikaService, ScUserService, ScUserType, ScVCardService, ScVacanciesList, ScVacanciesService, ScVacancy, ScVerificationService, ScVirtualCategory, ScWarehouseService, SchemaOrgFactory, TERMINAL_PROVIDERS, USER_AGENT_TERMINAL, filterChangedByKey, isExpiredToken, loadingPlaceholder, mapRequestStateToDataOrNull, mapToRequestState, runningOnTerminalFactory, scGetCurrentRoute, scOrderIsLoaded, searchTermFactory };
8373
8523
  //# sourceMappingURL=snabcentr-client-core.mjs.map