@snabcentr/client-core 2.69.0 → 2.70.1
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/esm2022/seo/classes/schema-org-factory.mjs +118 -10
- package/esm2022/seo/services/sc-seo.service.mjs +12 -10
- package/fesm2022/snabcentr-client-core.mjs +128 -18
- package/fesm2022/snabcentr-client-core.mjs.map +1 -1
- package/package.json +2 -2
- package/release_notes.tmp +7 -3
- package/seo/classes/schema-org-factory.d.ts +32 -1
- package/seo/services/sc-seo.service.d.ts +7 -5
|
@@ -7658,7 +7658,7 @@ class SchemaOrgFactory {
|
|
|
7658
7658
|
...(id && { '@id': id }),
|
|
7659
7659
|
name: product.name,
|
|
7660
7660
|
...(image && { image }),
|
|
7661
|
-
...(description && { description }),
|
|
7661
|
+
...(description && { description: this.stripHtml(description) }),
|
|
7662
7662
|
mpn: product.code,
|
|
7663
7663
|
url: productUrl,
|
|
7664
7664
|
offers: {
|
|
@@ -7694,7 +7694,7 @@ class SchemaOrgFactory {
|
|
|
7694
7694
|
'@type': 'CollectionPage',
|
|
7695
7695
|
...(id && { '@id': id }),
|
|
7696
7696
|
name: category.seo?.title ?? category.name,
|
|
7697
|
-
...(description && { description }),
|
|
7697
|
+
...(description && { description: this.stripHtml(description) }),
|
|
7698
7698
|
url: this.getCategoryCanonicalUrl(category, categoryPath),
|
|
7699
7699
|
...(image && { image }),
|
|
7700
7700
|
// SEO данные.
|
|
@@ -7708,13 +7708,7 @@ class SchemaOrgFactory {
|
|
|
7708
7708
|
'@type': 'CategoryCode',
|
|
7709
7709
|
codeValue: category.slug,
|
|
7710
7710
|
name: category.name,
|
|
7711
|
-
...(description && { description }),
|
|
7712
|
-
},
|
|
7713
|
-
// Информация о сайте.
|
|
7714
|
-
isPartOf: {
|
|
7715
|
-
'@type': 'WebSite',
|
|
7716
|
-
name: this.companyInfo.name,
|
|
7717
|
-
url: this.urls.siteUrl,
|
|
7711
|
+
...(description && { description: this.stripHtml(description) }),
|
|
7718
7712
|
},
|
|
7719
7713
|
// Связанные страницы.
|
|
7720
7714
|
relatedLink: [
|
|
@@ -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,54 @@ 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(/ /gi, ' ')
|
|
7942
|
+
.replaceAll(/\s+/g, ' ')
|
|
7943
|
+
.replaceAll(/ ([.,!?;:])/g, '$1')
|
|
7944
|
+
.trim();
|
|
7945
|
+
}
|
|
7946
|
+
/**
|
|
7947
|
+
* Нормализует дату в формат Schema.org (ISO 8601).
|
|
7948
|
+
*
|
|
7949
|
+
* @param dateValue Дата для нормализации.
|
|
7950
|
+
*/
|
|
7951
|
+
// eslint-disable-next-line class-methods-use-this
|
|
7952
|
+
normalizeSchemaDate(dateValue) {
|
|
7953
|
+
if (!dateValue) {
|
|
7954
|
+
return undefined;
|
|
7955
|
+
}
|
|
7956
|
+
if (/^\d{4}-\d{2}-\d{2}/.test(dateValue)) {
|
|
7957
|
+
return dateValue;
|
|
7958
|
+
}
|
|
7959
|
+
const withTimeMatch = /^(\d{2})\.(\d{2})\.(\d{4}) (\d{2}):(\d{2})$/.exec(dateValue);
|
|
7960
|
+
if (withTimeMatch) {
|
|
7961
|
+
const [, day, month, year, hours, minutes] = withTimeMatch;
|
|
7962
|
+
return `${year}-${month}-${day}T${hours}:${minutes}:00`;
|
|
7963
|
+
}
|
|
7964
|
+
const dateOnlyMatch = /^(\d{2})\.(\d{2})\.(\d{4})$/.exec(dateValue);
|
|
7965
|
+
if (!dateOnlyMatch) {
|
|
7966
|
+
return undefined;
|
|
7967
|
+
}
|
|
7968
|
+
const [, day, month, year] = dateOnlyMatch;
|
|
7969
|
+
return `${year}-${month}-${day}`;
|
|
7970
|
+
}
|
|
7863
7971
|
/**
|
|
7864
7972
|
* Нормализует дату окончания цены в формат Schema.org (YYYY-MM-DD).
|
|
7865
7973
|
*
|
|
@@ -8100,10 +8208,11 @@ class ScSeoService {
|
|
|
8100
8208
|
* Устанавливает seo параметры на основе указанного ресурса. Если какого-то тега нет, будет установлено значение по умолчанию.
|
|
8101
8209
|
*
|
|
8102
8210
|
* @param resource Ресурс на основе которого необходимо установить мета-теги.
|
|
8103
|
-
* @param img Изображение. Если не пришло, то будет установлено значение по
|
|
8104
|
-
* @param robots Список robots-тегов для страницы.
|
|
8211
|
+
* @param img Изображение. Если не пришло, то будет установлено значение по умолчанию (logo компании).
|
|
8212
|
+
* @param robots Список robots-тегов для страницы. Значение по умолчанию (['index', 'follow']).
|
|
8213
|
+
* @param schemaOrgData Данные Schema.org для встраивания на странице.
|
|
8105
8214
|
*/
|
|
8106
|
-
setFromResource(resource, img
|
|
8215
|
+
setFromResource(resource, img, robots, schemaOrgData) {
|
|
8107
8216
|
const updatedResource = {
|
|
8108
8217
|
title: this.replaceTemplates(resource?.title ?? this.defaultSeo.title, resource?.instanceData ?? {}),
|
|
8109
8218
|
description: this.replaceTemplates(resource?.description ?? this.defaultSeo.description, resource?.instanceData ?? {}),
|
|
@@ -8111,23 +8220,24 @@ class ScSeoService {
|
|
|
8111
8220
|
meta: resource?.meta ?? [],
|
|
8112
8221
|
};
|
|
8113
8222
|
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);
|
|
8223
|
+
this.setMetaTags(updatedResource.title, updatedResource.description, updatedResource.keywords, updatedResource.meta, robots ?? ['index', 'follow']);
|
|
8224
|
+
this.setOpenGraphMetaTags(updatedResource.title, updatedResource.description, url, img ?? this.urls.logoUrl);
|
|
8116
8225
|
this.setCanonicalLink(url);
|
|
8117
8226
|
// Устанавливаем Schema.org параметры.
|
|
8118
|
-
this.setSchemaOrgData(this.schemaOrgFactory.generateForOrganization());
|
|
8227
|
+
this.setSchemaOrgData(this.schemaOrgFactory.merge([this.schemaOrgFactory.generateForOrganization(), ...(schemaOrgData ? [schemaOrgData] : [])]));
|
|
8119
8228
|
}
|
|
8120
8229
|
/**
|
|
8121
8230
|
* Устанавливает seo параметры со значением по умолчанию.
|
|
8122
8231
|
*
|
|
8123
8232
|
* @param title Заголовок страницы.
|
|
8124
|
-
* @param robots Список robots тегов для страницы.
|
|
8233
|
+
* @param robots Список robots тегов для страницы. Значение по умолчанию (['index', 'follow']).
|
|
8234
|
+
* @param schemaOrgData Данные Schema.org для встраивания на странице.
|
|
8125
8235
|
*/
|
|
8126
|
-
setByDefault(title, robots
|
|
8236
|
+
setByDefault(title, robots, schemaOrgData) {
|
|
8127
8237
|
this.setFromResource({
|
|
8128
8238
|
title: `${title ?? this.defaultSeo.title} - ${this.companyInfo.name}`,
|
|
8129
8239
|
description: title ? `${title}, ${this.defaultSeo.description}` : this.defaultSeo.description,
|
|
8130
|
-
}, this.urls.logoUrl, robots);
|
|
8240
|
+
}, this.urls.logoUrl, robots ?? ['index', 'follow'], schemaOrgData);
|
|
8131
8241
|
}
|
|
8132
8242
|
/**
|
|
8133
8243
|
* Устанавливает seo параметры со значением по умолчанию. Устанавливает значение "не индексировать" для поисковых роботов.
|