@snabcentr/client-core 3.10.0 → 3.11.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.
@@ -7741,12 +7741,6 @@ class SchemaOrgFactory {
7741
7741
  name: category.name,
7742
7742
  ...(description && { description }),
7743
7743
  },
7744
- // Информация о сайте.
7745
- isPartOf: {
7746
- '@type': 'WebSite',
7747
- name: this.companyInfo.name,
7748
- url: this.urls.siteUrl,
7749
- },
7750
7744
  // Связанные страницы.
7751
7745
  relatedLink: [
7752
7746
  `${this.urls.siteUrl}${categoryPath.replace(':id', '')}`,
@@ -7824,6 +7818,72 @@ class SchemaOrgFactory {
7824
7818
  }),
7825
7819
  };
7826
7820
  }
7821
+ /**
7822
+ * Генерирует и возвращает схему данных для указанной новости.
7823
+ *
7824
+ * @param news Данные о новости.
7825
+ * @param newsPath Url путь к новости. В пути должен присутствовать шаблон ':id', обозначающий идентификатор новости для подстановки.
7826
+ * @param id Необязательный идентификатор сущности для поля `@id` в JSON-LD.
7827
+ */
7828
+ generateForNewsArticle(news, newsPath, id) {
7829
+ const newsUrl = `${this.urls.siteUrl}${newsPath.replace(':id', news.id.toString())}`;
7830
+ const image = this.mediaImageTransformerPipe.transform(news.image, true);
7831
+ const headline = news.seo?.title ?? news.subject;
7832
+ const description = news.seo?.description;
7833
+ const datePublished = this.normalizeSchemaDate(news.createdAt);
7834
+ const articleBody = news.text ? this.stripHtml(news.text) : undefined;
7835
+ return {
7836
+ '@context': 'https://schema.org',
7837
+ '@type': 'NewsArticle',
7838
+ ...(id && { '@id': id }),
7839
+ headline,
7840
+ ...(description && { description }),
7841
+ ...(image && { image }),
7842
+ ...(datePublished && { datePublished }),
7843
+ ...(articleBody && { articleBody }),
7844
+ url: newsUrl,
7845
+ mainEntityOfPage: newsUrl,
7846
+ author: {
7847
+ '@type': 'Organization',
7848
+ name: this.companyInfo.name,
7849
+ url: this.urls.siteUrl,
7850
+ },
7851
+ publisher: {
7852
+ '@type': 'Organization',
7853
+ name: this.companyInfo.name,
7854
+ logo: {
7855
+ '@type': 'ImageObject',
7856
+ url: this.urls.logoUrl,
7857
+ },
7858
+ },
7859
+ };
7860
+ }
7861
+ /**
7862
+ * Генерирует и возвращает схему данных FAQPage для страницы с вопросами и ответами.
7863
+ *
7864
+ * @param items Список вопросов и ответов.
7865
+ * @param pagePath Url путь к странице FAQ.
7866
+ * @param pageName Необязательное название страницы.
7867
+ * @param id Необязательный идентификатор сущности для поля `@id` в JSON-LD.
7868
+ */
7869
+ generateForFaqPage(items, pagePath, pageName, id) {
7870
+ const pageUrl = `${this.urls.siteUrl}${pagePath}`;
7871
+ return {
7872
+ '@context': 'https://schema.org',
7873
+ '@type': 'FAQPage',
7874
+ ...(id && { '@id': id }),
7875
+ ...(pageName && { name: pageName }),
7876
+ url: pageUrl,
7877
+ mainEntity: items.map((item) => ({
7878
+ '@type': 'Question',
7879
+ name: item.question,
7880
+ acceptedAnswer: {
7881
+ '@type': 'Answer',
7882
+ text: this.stripHtml(item.answer),
7883
+ },
7884
+ })),
7885
+ };
7886
+ }
7827
7887
  /**
7828
7888
  * Объединяет несколько JSON-LD сущностей в один документ с `@graph`.
7829
7889
  *
@@ -7891,6 +7951,53 @@ class SchemaOrgFactory {
7891
7951
  }
7892
7952
  return contactPoints;
7893
7953
  }
7954
+ /**
7955
+ * Удаляет HTML-разметку из текста.
7956
+ *
7957
+ * @param html Текст с HTML-разметкой.
7958
+ */
7959
+ // eslint-disable-next-line class-methods-use-this
7960
+ stripHtml(html) {
7961
+ const withoutTags = html
7962
+ .split('<')
7963
+ .map((part, index) => {
7964
+ if (index === 0) {
7965
+ return part;
7966
+ }
7967
+ const closeTagIndex = part.indexOf('>');
7968
+ return closeTagIndex === -1 ? part : ` ${part.slice(closeTagIndex + 1)}`;
7969
+ })
7970
+ .join('');
7971
+ return withoutTags
7972
+ .replaceAll(/\s+/g, ' ')
7973
+ .replaceAll(/ ([.,!?;:])/g, '$1')
7974
+ .trim();
7975
+ }
7976
+ /**
7977
+ * Нормализует дату в формат Schema.org (ISO 8601).
7978
+ *
7979
+ * @param dateValue Дата для нормализации.
7980
+ */
7981
+ // eslint-disable-next-line class-methods-use-this
7982
+ normalizeSchemaDate(dateValue) {
7983
+ if (!dateValue) {
7984
+ return undefined;
7985
+ }
7986
+ if (/^\d{4}-\d{2}-\d{2}/.test(dateValue)) {
7987
+ return dateValue;
7988
+ }
7989
+ const withTimeMatch = /^(\d{2})\.(\d{2})\.(\d{4}) (\d{2}):(\d{2})$/.exec(dateValue);
7990
+ if (withTimeMatch) {
7991
+ const [, day, month, year, hours, minutes] = withTimeMatch;
7992
+ return `${year}-${month}-${day}T${hours}:${minutes}:00`;
7993
+ }
7994
+ const dateOnlyMatch = /^(\d{2})\.(\d{2})\.(\d{4})$/.exec(dateValue);
7995
+ if (!dateOnlyMatch) {
7996
+ return undefined;
7997
+ }
7998
+ const [, day, month, year] = dateOnlyMatch;
7999
+ return `${year}-${month}-${day}`;
8000
+ }
7894
8001
  /**
7895
8002
  * Нормализует дату окончания цены в формат Schema.org (YYYY-MM-DD).
7896
8003
  *
@@ -8133,8 +8240,9 @@ class ScSeoService {
8133
8240
  * @param resource Ресурс на основе которого необходимо установить мета-теги.
8134
8241
  * @param img Изображение. Если не пришло, то будет установлено значение по умолчанию.
8135
8242
  * @param robots Список robots-тегов для страницы.
8243
+ * @param schemaOrgData Данные Schema.org для встраивания на странице.
8136
8244
  */
8137
- setFromResource(resource, img = this.urls.logoUrl, robots = ['index', 'follow']) {
8245
+ setFromResource(resource, img, robots, schemaOrgData) {
8138
8246
  const updatedResource = {
8139
8247
  title: this.replaceTemplates(resource?.title ?? this.defaultSeo.title, resource?.instanceData ?? {}),
8140
8248
  description: this.replaceTemplates(resource?.description ?? this.defaultSeo.description, resource?.instanceData ?? {}),
@@ -8142,23 +8250,24 @@ class ScSeoService {
8142
8250
  meta: resource?.meta ?? [],
8143
8251
  };
8144
8252
  const url = `${this.urls.siteUrl}${this.router.url}`;
8145
- this.setMetaTags(updatedResource.title, updatedResource.description, updatedResource.keywords, updatedResource.meta, robots);
8146
- this.setOpenGraphMetaTags(updatedResource.title, updatedResource.description, url, img);
8253
+ this.setMetaTags(updatedResource.title, updatedResource.description, updatedResource.keywords, updatedResource.meta, robots ?? ['index', 'follow']);
8254
+ this.setOpenGraphMetaTags(updatedResource.title, updatedResource.description, url, img ?? this.urls.logoUrl);
8147
8255
  this.setCanonicalLink(url);
8148
8256
  // Устанавливаем Schema.org параметры.
8149
- this.setSchemaOrgData(this.schemaOrgFactory.generateForOrganization());
8257
+ this.setSchemaOrgData(this.schemaOrgFactory.merge([this.schemaOrgFactory.generateForOrganization(), ...(schemaOrgData ? [schemaOrgData] : [])]));
8150
8258
  }
8151
8259
  /**
8152
8260
  * Устанавливает seo параметры со значением по умолчанию.
8153
8261
  *
8154
8262
  * @param title Заголовок страницы.
8155
8263
  * @param robots Список robots тегов для страницы.
8264
+ * @param schemaOrgData Данные Schema.org для встраивания на странице.
8156
8265
  */
8157
- setByDefault(title, robots = ['index', 'follow']) {
8266
+ setByDefault(title, robots, schemaOrgData) {
8158
8267
  this.setFromResource({
8159
8268
  title: `${title ?? this.defaultSeo.title} - ${this.companyInfo.name}`,
8160
8269
  description: title ? `${title}, ${this.defaultSeo.description}` : this.defaultSeo.description,
8161
- }, this.urls.logoUrl, robots);
8270
+ }, this.urls.logoUrl, robots ?? ['index', 'follow'], schemaOrgData);
8162
8271
  }
8163
8272
  /**
8164
8273
  * Устанавливает seo параметры со значением по умолчанию. Устанавливает значение "не индексировать" для поисковых роботов.