@snabcentr/client-core 2.69.0 → 2.70.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.
@@ -7710,12 +7710,6 @@ class SchemaOrgFactory {
7710
7710
  name: category.name,
7711
7711
  ...(description && { description }),
7712
7712
  },
7713
- // Информация о сайте.
7714
- isPartOf: {
7715
- '@type': 'WebSite',
7716
- name: this.companyInfo.name,
7717
- url: this.urls.siteUrl,
7718
- },
7719
7713
  // Связанные страницы.
7720
7714
  relatedLink: [
7721
7715
  `${this.urls.siteUrl}${categoryPath.replace(':id', '')}`,
@@ -7793,6 +7787,72 @@ class SchemaOrgFactory {
7793
7787
  }),
7794
7788
  };
7795
7789
  }
7790
+ /**
7791
+ * Генерирует и возвращает схему данных для указанной новости.
7792
+ *
7793
+ * @param news Данные о новости.
7794
+ * @param newsPath Url путь к новости. В пути должен присутствовать шаблон ':id', обозначающий идентификатор новости для подстановки.
7795
+ * @param id Необязательный идентификатор сущности для поля `@id` в JSON-LD.
7796
+ */
7797
+ generateForNewsArticle(news, newsPath, id) {
7798
+ const newsUrl = `${this.urls.siteUrl}${newsPath.replace(':id', news.id.toString())}`;
7799
+ const image = this.mediaImageTransformerPipe.transform(news.image, true);
7800
+ const headline = news.seo?.title ?? news.subject;
7801
+ const description = news.seo?.description;
7802
+ const datePublished = this.normalizeSchemaDate(news.createdAt);
7803
+ const articleBody = news.text ? this.stripHtml(news.text) : undefined;
7804
+ return {
7805
+ '@context': 'https://schema.org',
7806
+ '@type': 'NewsArticle',
7807
+ ...(id && { '@id': id }),
7808
+ headline,
7809
+ ...(description && { description }),
7810
+ ...(image && { image }),
7811
+ ...(datePublished && { datePublished }),
7812
+ ...(articleBody && { articleBody }),
7813
+ url: newsUrl,
7814
+ mainEntityOfPage: newsUrl,
7815
+ author: {
7816
+ '@type': 'Organization',
7817
+ name: this.companyInfo.name,
7818
+ url: this.urls.siteUrl,
7819
+ },
7820
+ publisher: {
7821
+ '@type': 'Organization',
7822
+ name: this.companyInfo.name,
7823
+ logo: {
7824
+ '@type': 'ImageObject',
7825
+ url: this.urls.logoUrl,
7826
+ },
7827
+ },
7828
+ };
7829
+ }
7830
+ /**
7831
+ * Генерирует и возвращает схему данных FAQPage для страницы с вопросами и ответами.
7832
+ *
7833
+ * @param items Список вопросов и ответов.
7834
+ * @param pagePath Url путь к странице FAQ.
7835
+ * @param pageName Необязательное название страницы.
7836
+ * @param id Необязательный идентификатор сущности для поля `@id` в JSON-LD.
7837
+ */
7838
+ generateForFaqPage(items, pagePath, pageName, id) {
7839
+ const pageUrl = `${this.urls.siteUrl}${pagePath}`;
7840
+ return {
7841
+ '@context': 'https://schema.org',
7842
+ '@type': 'FAQPage',
7843
+ ...(id && { '@id': id }),
7844
+ ...(pageName && { name: pageName }),
7845
+ url: pageUrl,
7846
+ mainEntity: items.map((item) => ({
7847
+ '@type': 'Question',
7848
+ name: item.question,
7849
+ acceptedAnswer: {
7850
+ '@type': 'Answer',
7851
+ text: this.stripHtml(item.answer),
7852
+ },
7853
+ })),
7854
+ };
7855
+ }
7796
7856
  /**
7797
7857
  * Объединяет несколько JSON-LD сущностей в один документ с `@graph`.
7798
7858
  *
@@ -7860,6 +7920,53 @@ class SchemaOrgFactory {
7860
7920
  }
7861
7921
  return contactPoints;
7862
7922
  }
7923
+ /**
7924
+ * Удаляет HTML-разметку из текста.
7925
+ *
7926
+ * @param html Текст с HTML-разметкой.
7927
+ */
7928
+ // eslint-disable-next-line class-methods-use-this
7929
+ stripHtml(html) {
7930
+ const withoutTags = html
7931
+ .split('<')
7932
+ .map((part, index) => {
7933
+ if (index === 0) {
7934
+ return part;
7935
+ }
7936
+ const closeTagIndex = part.indexOf('>');
7937
+ return closeTagIndex === -1 ? part : ` ${part.slice(closeTagIndex + 1)}`;
7938
+ })
7939
+ .join('');
7940
+ return withoutTags
7941
+ .replaceAll(/\s+/g, ' ')
7942
+ .replaceAll(/ ([.,!?;:])/g, '$1')
7943
+ .trim();
7944
+ }
7945
+ /**
7946
+ * Нормализует дату в формат Schema.org (ISO 8601).
7947
+ *
7948
+ * @param dateValue Дата для нормализации.
7949
+ */
7950
+ // eslint-disable-next-line class-methods-use-this
7951
+ normalizeSchemaDate(dateValue) {
7952
+ if (!dateValue) {
7953
+ return undefined;
7954
+ }
7955
+ if (/^\d{4}-\d{2}-\d{2}/.test(dateValue)) {
7956
+ return dateValue;
7957
+ }
7958
+ const withTimeMatch = /^(\d{2})\.(\d{2})\.(\d{4}) (\d{2}):(\d{2})$/.exec(dateValue);
7959
+ if (withTimeMatch) {
7960
+ const [, day, month, year, hours, minutes] = withTimeMatch;
7961
+ return `${year}-${month}-${day}T${hours}:${minutes}:00`;
7962
+ }
7963
+ const dateOnlyMatch = /^(\d{2})\.(\d{2})\.(\d{4})$/.exec(dateValue);
7964
+ if (!dateOnlyMatch) {
7965
+ return undefined;
7966
+ }
7967
+ const [, day, month, year] = dateOnlyMatch;
7968
+ return `${year}-${month}-${day}`;
7969
+ }
7863
7970
  /**
7864
7971
  * Нормализует дату окончания цены в формат Schema.org (YYYY-MM-DD).
7865
7972
  *
@@ -8102,8 +8209,9 @@ class ScSeoService {
8102
8209
  * @param resource Ресурс на основе которого необходимо установить мета-теги.
8103
8210
  * @param img Изображение. Если не пришло, то будет установлено значение по умолчанию.
8104
8211
  * @param robots Список robots-тегов для страницы.
8212
+ * @param schemaOrgData Данные Schema.org для встраивания на странице.
8105
8213
  */
8106
- setFromResource(resource, img = this.urls.logoUrl, robots = ['index', 'follow']) {
8214
+ setFromResource(resource, img, robots, schemaOrgData) {
8107
8215
  const updatedResource = {
8108
8216
  title: this.replaceTemplates(resource?.title ?? this.defaultSeo.title, resource?.instanceData ?? {}),
8109
8217
  description: this.replaceTemplates(resource?.description ?? this.defaultSeo.description, resource?.instanceData ?? {}),
@@ -8111,23 +8219,24 @@ class ScSeoService {
8111
8219
  meta: resource?.meta ?? [],
8112
8220
  };
8113
8221
  const url = `${this.urls.siteUrl}${this.router.url}`;
8114
- this.setMetaTags(updatedResource.title, updatedResource.description, updatedResource.keywords, updatedResource.meta, robots);
8115
- this.setOpenGraphMetaTags(updatedResource.title, updatedResource.description, url, img);
8222
+ this.setMetaTags(updatedResource.title, updatedResource.description, updatedResource.keywords, updatedResource.meta, robots ?? ['index', 'follow']);
8223
+ this.setOpenGraphMetaTags(updatedResource.title, updatedResource.description, url, img ?? this.urls.logoUrl);
8116
8224
  this.setCanonicalLink(url);
8117
8225
  // Устанавливаем Schema.org параметры.
8118
- this.setSchemaOrgData(this.schemaOrgFactory.generateForOrganization());
8226
+ this.setSchemaOrgData(this.schemaOrgFactory.merge([this.schemaOrgFactory.generateForOrganization(), ...(schemaOrgData ? [schemaOrgData] : [])]));
8119
8227
  }
8120
8228
  /**
8121
8229
  * Устанавливает seo параметры со значением по умолчанию.
8122
8230
  *
8123
8231
  * @param title Заголовок страницы.
8124
8232
  * @param robots Список robots тегов для страницы.
8233
+ * @param schemaOrgData Данные Schema.org для встраивания на странице.
8125
8234
  */
8126
- setByDefault(title, robots = ['index', 'follow']) {
8235
+ setByDefault(title, robots, schemaOrgData) {
8127
8236
  this.setFromResource({
8128
8237
  title: `${title ?? this.defaultSeo.title} - ${this.companyInfo.name}`,
8129
8238
  description: title ? `${title}, ${this.defaultSeo.description}` : this.defaultSeo.description,
8130
- }, this.urls.logoUrl, robots);
8239
+ }, this.urls.logoUrl, robots ?? ['index', 'follow'], schemaOrgData);
8131
8240
  }
8132
8241
  /**
8133
8242
  * Устанавливает seo параметры со значением по умолчанию. Устанавливает значение "не индексировать" для поисковых роботов.