@rededor/site-front-end-lib 0.0.2 → 0.0.3-alpha.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.
Files changed (39) hide show
  1. package/esm2022/lib/helpers/getSiteUrl.func.mjs +11 -0
  2. package/esm2022/lib/helpers/index.mjs +4 -1
  3. package/esm2022/lib/helpers/removeHtmlTags.func.mjs +6 -0
  4. package/esm2022/lib/models/breadcrumb/breadcrumb-item.model.mjs +2 -0
  5. package/esm2022/lib/models/breadcrumb/breadcrumb-json-item.model.mjs +2 -0
  6. package/esm2022/lib/models/rdsl-post-category.model.mjs +2 -0
  7. package/esm2022/lib/models/seo/seo-data.model.mjs +2 -0
  8. package/esm2022/lib/models/seo/seo-unidade.model.mjs +2 -0
  9. package/esm2022/lib/models/social-meta-properties.model.mjs +2 -0
  10. package/esm2022/lib/models/wordpress/category/wpCategory.model.mjs +2 -0
  11. package/esm2022/lib/models/wordpress/post/post.model.mjs +2 -0
  12. package/esm2022/lib/services/index.mjs +3 -1
  13. package/esm2022/lib/services/log/log.service.mjs +3 -8
  14. package/esm2022/lib/services/seo/seo.service.mjs +469 -0
  15. package/esm2022/lib/services/server-response/server-response.service.mjs +86 -0
  16. package/esm2022/lib/tokens/LibConfig.mjs +1 -1
  17. package/esm2022/lib/tokens/express.tokens.mjs +4 -0
  18. package/esm2022/public-api.mjs +2 -1
  19. package/fesm2022/rededor-site-front-end-lib.mjs +590 -32
  20. package/fesm2022/rededor-site-front-end-lib.mjs.map +1 -1
  21. package/lib/helpers/getSiteUrl.func.d.ts +2 -0
  22. package/lib/helpers/index.d.ts +3 -0
  23. package/lib/helpers/removeHtmlTags.func.d.ts +2 -0
  24. package/lib/models/breadcrumb/breadcrumb-item.model.d.ts +6 -0
  25. package/lib/models/breadcrumb/breadcrumb-json-item.model.d.ts +8 -0
  26. package/lib/models/rdsl-post-category.model.d.ts +8 -0
  27. package/lib/models/seo/seo-data.model.d.ts +9 -0
  28. package/lib/models/seo/seo-unidade.model.d.ts +6 -0
  29. package/lib/models/social-meta-properties.model.d.ts +9 -0
  30. package/lib/models/wordpress/category/wpCategory.model.d.ts +14 -0
  31. package/lib/models/wordpress/post/post.model.d.ts +33 -0
  32. package/lib/services/index.d.ts +2 -0
  33. package/lib/services/log/log.service.d.ts +0 -1
  34. package/lib/services/seo/seo.service.d.ts +140 -0
  35. package/lib/services/server-response/server-response.service.d.ts +31 -0
  36. package/lib/tokens/LibConfig.d.ts +3 -0
  37. package/lib/tokens/express.tokens.d.ts +4 -0
  38. package/package.json +3 -1
  39. package/public-api.d.ts +1 -0
@@ -1,12 +1,14 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { InjectionToken, Injectable, Inject, PLATFORM_ID, Optional, makeStateKey, Component, CUSTOM_ELEMENTS_SCHEMA, HostBinding } from '@angular/core';
3
- import * as i1 from '@angular/common';
3
+ import * as i2 from '@angular/common';
4
4
  import { isPlatformBrowser, isPlatformServer, DOCUMENT, CommonModule } from '@angular/common';
5
5
  import algoliasearch from 'algoliasearch';
6
6
  import { from, fromEvent, startWith, Observable } from 'rxjs';
7
- import * as i1$1 from '@angular/common/http';
7
+ import * as i1 from '@angular/common/http';
8
8
  import { HttpHeaders } from '@angular/common/http';
9
- import * as i2 from 'ngx-device-detector';
9
+ import * as i2$1 from 'ngx-device-detector';
10
+ import * as he from 'he';
11
+ import * as i1$1 from '@angular/platform-browser';
10
12
 
11
13
  // Configura a lib com informações especificas de cada projeto.
12
14
  const LIB_CONFIG = new InjectionToken('libConfig');
@@ -166,6 +168,37 @@ var IconCuraDefaultType;
166
168
 
167
169
  const SSR_CURA_API = new InjectionToken('SSR Cura API');
168
170
 
171
+ const removeDuplicateObjectsFromArray = (arr, key) => {
172
+ return [...new Map(arr.map((item) => [item[key], item])).values()];
173
+ };
174
+
175
+ const removeDuplicateValuesFromArray = (arr) => {
176
+ return Array.from(new Set(arr));
177
+ };
178
+
179
+ const getSiteUrl = (siteUrl = '', siteSufix = '') => {
180
+ const baseUrl = siteUrl.endsWith('/')
181
+ ? siteUrl.substring(0, siteUrl.length - 1)
182
+ : siteUrl;
183
+ const baseSufix = siteSufix.endsWith('/')
184
+ ? siteSufix.substring(0, siteSufix.length - 1)
185
+ : siteSufix;
186
+ return `${baseUrl}${baseSufix}`;
187
+ };
188
+
189
+ function removeHtmlTags(content) {
190
+ content = content.replace(/<.*?>/g, "");
191
+ return content;
192
+ }
193
+
194
+ /**
195
+ * Converte JSON para query string.
196
+ * @param params JSON
197
+ */
198
+ function toQueryParams(params) {
199
+ return params ? `?${Object.keys(params).map(key => key + "=" + params[key]).join("&")}` : "";
200
+ }
201
+
169
202
  class LogService {
170
203
  constructor(libConfig, platformId, location) {
171
204
  this.libConfig = libConfig;
@@ -184,16 +217,10 @@ class LogService {
184
217
  log404(component) {
185
218
  this.logMsg(`${this.getPageURL()}${component ? ' - ' + component : ''}`, '404');
186
219
  }
187
- getSiteUrl() {
188
- const baseUrl = this.libConfig?.siteUrl.endsWith('/')
189
- ? this.libConfig?.siteUrl.substring(0, this.libConfig?.siteUrl.length - 1)
190
- : this.libConfig?.siteUrl;
191
- return `${baseUrl}${this.libConfig?.siteSufix ?? ''}`;
192
- }
193
220
  getPageURL() {
194
- return `${this.getSiteUrl()}${this.location.path()}`;
221
+ return `${getSiteUrl(this.libConfig?.siteUrl, this.libConfig?.siteSufix)}${this.location.path()}`;
195
222
  }
196
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: LogService, deps: [{ token: LIB_CONFIG }, { token: PLATFORM_ID }, { token: i1.Location }], target: i0.ɵɵFactoryTarget.Injectable }); }
223
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: LogService, deps: [{ token: LIB_CONFIG }, { token: PLATFORM_ID }, { token: i2.Location }], target: i0.ɵɵFactoryTarget.Injectable }); }
197
224
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: LogService, providedIn: 'root' }); }
198
225
  }
199
226
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: LogService, decorators: [{
@@ -207,7 +234,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImpo
207
234
  }] }, { type: undefined, decorators: [{
208
235
  type: Inject,
209
236
  args: [PLATFORM_ID]
210
- }] }, { type: i1.Location }] });
237
+ }] }, { type: i2.Location }] });
211
238
 
212
239
  class CuraService {
213
240
  constructor(log, platformId, document, libConfig, ssrCuraAPI) {
@@ -343,7 +370,7 @@ class HttpClientService {
343
370
  getOriginDevice() {
344
371
  return `app-${this.deviceService.getDeviceInfo().os}`;
345
372
  }
346
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: HttpClientService, deps: [{ token: PLATFORM_ID }, { token: LIB_CONFIG }, { token: i1$1.HttpClient }, { token: i2.DeviceDetectorService }], target: i0.ɵɵFactoryTarget.Injectable }); }
373
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: HttpClientService, deps: [{ token: PLATFORM_ID }, { token: LIB_CONFIG }, { token: i1.HttpClient }, { token: i2$1.DeviceDetectorService }], target: i0.ɵɵFactoryTarget.Injectable }); }
347
374
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: HttpClientService, providedIn: 'root' }); }
348
375
  }
349
376
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: HttpClientService, decorators: [{
@@ -355,7 +382,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImpo
355
382
  }] }, { type: undefined, decorators: [{
356
383
  type: Inject,
357
384
  args: [LIB_CONFIG]
358
- }] }, { type: i1$1.HttpClient }, { type: i2.DeviceDetectorService }] });
385
+ }] }, { type: i1.HttpClient }, { type: i2$1.DeviceDetectorService }] });
359
386
 
360
387
  class NguCarouselService {
361
388
  constructor() {
@@ -436,14 +463,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImpo
436
463
  }]
437
464
  }] });
438
465
 
439
- /**
440
- * Converte JSON para query string.
441
- * @param params JSON
442
- */
443
- function toQueryParams(params) {
444
- return params ? `?${Object.keys(params).map(key => key + "=" + params[key]).join("&")}` : "";
445
- }
446
-
447
466
  var unidades = [
448
467
  {
449
468
  path: "/acreditar/",
@@ -32379,6 +32398,553 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImpo
32379
32398
  args: [PLATFORM_ID]
32380
32399
  }] }] });
32381
32400
 
32401
+ class SeoService {
32402
+ constructor(title, meta, location, libConfig, document) {
32403
+ this.title = title;
32404
+ this.meta = meta;
32405
+ this.location = location;
32406
+ this.libConfig = libConfig;
32407
+ this.document = document;
32408
+ this.separator = ' - ';
32409
+ this.defaultTitle = 'Rede D’Or';
32410
+ this.sameAs = [
32411
+ 'https://www.facebook.com/rededor/',
32412
+ 'https://www.instagram.com/rededor_oficial/',
32413
+ 'https://www.linkedin.com/company/rededor-saoluiz',
32414
+ 'https://twitter.com/rededor',
32415
+ ];
32416
+ this.twitterUser = '@rededor';
32417
+ this.jsonTagId = 'seoJSON';
32418
+ this.breadcrumbsJsonTagId = 'breadcrumbsJSON';
32419
+ this.unidade = null;
32420
+ this.unidadeName = "";
32421
+ this.unidadePath = "";
32422
+ this.unidadeSlug = "";
32423
+ }
32424
+ setFullSeo(data) {
32425
+ this.setTitle(data.title.text, !!data.title.sub);
32426
+ this.setDescription(data.description);
32427
+ this.setCanonicalHref(data.canonical);
32428
+ this.setPageJson();
32429
+ this.setSocialTags(data.socialTags);
32430
+ }
32431
+ /**
32432
+ * Define tag description da página
32433
+ * @param content conteúdo da descrição <string>
32434
+ */
32435
+ setDescription(content) {
32436
+ const descTag = this.meta.getTag("name='description'");
32437
+ if (content) {
32438
+ content = he.decode(content);
32439
+ content = removeHtmlTags(content);
32440
+ }
32441
+ else {
32442
+ content = '';
32443
+ }
32444
+ this.activeDescription = content;
32445
+ const tagContent = { name: 'description', content };
32446
+ if (descTag) {
32447
+ this.meta.updateTag(tagContent);
32448
+ }
32449
+ else {
32450
+ this.meta.addTag(tagContent);
32451
+ }
32452
+ return this;
32453
+ }
32454
+ /**
32455
+ * Define meta tags para a página
32456
+ * @param tag nome da tag meta
32457
+ * @param content conteúdo da tag meta
32458
+ * @param type tipo de tag meta
32459
+ */
32460
+ setMetaTag(tag, content, type = 'name') {
32461
+ const metatag = this.meta.getTag(`${type}='${tag}'`);
32462
+ content = he.decode(content);
32463
+ content = removeHtmlTags(content);
32464
+ const tagContent = {
32465
+ [type]: tag,
32466
+ content,
32467
+ };
32468
+ if (!metatag) {
32469
+ this.meta.addTag(tagContent);
32470
+ }
32471
+ else {
32472
+ this.meta.updateTag(tagContent);
32473
+ }
32474
+ return this;
32475
+ }
32476
+ /**
32477
+ * Remove meta tags da página
32478
+ * @param tag nome da tag meta
32479
+ * @param content conteúdo da tag meta
32480
+ * @param attr atributo da tag meta
32481
+ * @param type tipo de tag meta
32482
+ */
32483
+ removeTag(tag, content, attr, type = 'name') {
32484
+ const metatag = this.meta.getTag(`${type}='${tag}'`);
32485
+ if (metatag) {
32486
+ this.meta.removeTag(`${attr}=${content}`);
32487
+ }
32488
+ return this;
32489
+ }
32490
+ /**
32491
+ * Define meta tags para Facebook
32492
+ * @param title título para o facebook
32493
+ * @param description descrição para o facebook
32494
+ * @param url url para definição do facebook
32495
+ * @param img imagem para definição no facebook
32496
+ */
32497
+ setMetaFacebook(title, description, url, img = null) {
32498
+ this.setMetaTag('og:url', url, 'property');
32499
+ this.setMetaTag('og:title', title, 'property');
32500
+ this.setMetaTag('og:description', description, 'property');
32501
+ this.setMetaTag('og:type', 'website', 'property');
32502
+ this.setMetaTag('og:image', img ?? '', 'property');
32503
+ }
32504
+ /**
32505
+ * Define meta tags para Twitter
32506
+ * @param title título para o twitter
32507
+ * @param description descrição para o twitter
32508
+ * @param url url para o twitter
32509
+ * @param img imagem para definição no twitter
32510
+ */
32511
+ setMetaTwitter(title, description, url, img = null) {
32512
+ this.setMetaTag('twitter:site', url, 'name');
32513
+ this.setMetaTag('twitter:title', title, 'name');
32514
+ this.setMetaTag('twitter:description', description, 'name');
32515
+ this.setMetaTag("twitter:image", img ?? '', "name");
32516
+ }
32517
+ /**
32518
+ * Define tags de redes sociais (Twitter e Open Graph)
32519
+ * @param properties
32520
+ */
32521
+ setSocialTags(properties) {
32522
+ const pagePath = this.location.path();
32523
+ const siteurl = getSiteUrl(this.libConfig?.siteUrl, this.libConfig?.siteSufix);
32524
+ let defaultProperties = {
32525
+ twitterCard: 'summary',
32526
+ twitterSite: this.twitterUser,
32527
+ type: 'website',
32528
+ title: this.getTitle(),
32529
+ description: this.activeDescription || '',
32530
+ url: `${siteurl}${pagePath}`,
32531
+ image: `${siteurl}/assets/imgs/logo-novo-rededor-saoluiz-blue.png`,
32532
+ };
32533
+ if (properties) {
32534
+ defaultProperties = { ...defaultProperties, ...properties };
32535
+ }
32536
+ this.setMetaTag('twitter:card', defaultProperties.twitterCard || '', 'name')
32537
+ .setMetaTag('twitter:site', defaultProperties.twitterSite || '', 'name')
32538
+ .setMetaTag('og:type', defaultProperties.type || '', 'property')
32539
+ .setMetaTag('og:title', defaultProperties.title || '', 'property')
32540
+ .setMetaTag('og:description', defaultProperties.description || '', 'property')
32541
+ .setMetaTag('og:url', defaultProperties.url || '', 'property')
32542
+ .setMetaTag('og:image', defaultProperties.image || '', 'property');
32543
+ return this;
32544
+ }
32545
+ /**
32546
+ * Define título da página
32547
+ * @param title título da página <string>
32548
+ * @param sub Se é subsite acrescenta unidade <boolean>
32549
+ */
32550
+ setTitle(title, sub = false) {
32551
+ if (title && title !== '') {
32552
+ title = he.decode(title);
32553
+ title = removeHtmlTags(title);
32554
+ if (sub) {
32555
+ title = he.decode(`${title}${this.separator}${this.unidadeName}`);
32556
+ }
32557
+ this.title.setTitle(title);
32558
+ }
32559
+ return this;
32560
+ }
32561
+ /** Obtem título atual da página */
32562
+ getTitle() {
32563
+ return this.title.getTitle();
32564
+ }
32565
+ set404Title(component = 'Default Component') {
32566
+ if (component && component !== '') {
32567
+ component = he.decode(component);
32568
+ component = removeHtmlTags(component);
32569
+ if (this.unidadeName) {
32570
+ component = he.decode(`${component}${this.separator}${this.unidadeName}`);
32571
+ }
32572
+ }
32573
+ const title = `Erro 404 - ${component} - ${this.libConfig?.siteName} - ${this.location.path()}`;
32574
+ this.title.setTitle(title);
32575
+ console.log("set404Title", title);
32576
+ return this;
32577
+ }
32578
+ /** Cria tag script para JSON de breadcrumbs */
32579
+ createBreadcrumbsJSONTag() {
32580
+ const tag = this.document.createElement('script');
32581
+ tag.id = this.breadcrumbsJsonTagId;
32582
+ tag.type = 'application/ld+json';
32583
+ this.document.head.appendChild(tag);
32584
+ this.breadcrumbsJsonTag = tag;
32585
+ return tag;
32586
+ }
32587
+ /** Retorna tag para script json de breadcrumbs ou cria se não houver. */
32588
+ getBreadcrumbsJSONTag() {
32589
+ const elements = this.document.head.children;
32590
+ let i;
32591
+ for (i = 0; i < elements.length; i++) {
32592
+ const elem = elements[i];
32593
+ if (elem && elem.id === this.breadcrumbsJsonTagId) {
32594
+ return elem;
32595
+ }
32596
+ }
32597
+ return this.createBreadcrumbsJSONTag();
32598
+ }
32599
+ /** Define o JSON de breadcrumbs da página */
32600
+ setBreadcrumbsJson(items) {
32601
+ this.breadcrumbsJsonTag = this.getBreadcrumbsJSONTag();
32602
+ const json = {
32603
+ '@context': 'http://schema.org',
32604
+ '@type': 'BreadcrumbList',
32605
+ itemListElement: this.getJsonBreadcrumbItems(items),
32606
+ };
32607
+ this.breadcrumbsJsonTag.innerHTML = JSON.stringify(json);
32608
+ return this;
32609
+ }
32610
+ /** Converte itens do breadcrumb em itens do JSON */
32611
+ getJsonBreadcrumbItems(items) {
32612
+ const jsonItems = [
32613
+ {
32614
+ '@type': 'ListItem',
32615
+ position: 1,
32616
+ item: { '@id': this.getBreadcrumbItemUrl(['/']), name: he.encode('Página Inicial') },
32617
+ },
32618
+ ];
32619
+ items.forEach((item, i) => {
32620
+ const jsonItem = {
32621
+ '@type': 'ListItem',
32622
+ position: i + 2,
32623
+ item: { '@id': this.getBreadcrumbItemUrl(item?.url || []), name: he.encode(item.label) },
32624
+ };
32625
+ jsonItems.push(jsonItem);
32626
+ });
32627
+ return jsonItems;
32628
+ }
32629
+ /**
32630
+ * Monta a url do item de breadcrumb proveniente do array de urls
32631
+ * ou do caminho da própria página, conforme caso do último item.
32632
+ */
32633
+ getBreadcrumbItemUrl(url) {
32634
+ const siteurl = getSiteUrl(this.libConfig?.siteUrl, this.libConfig?.siteSufix);
32635
+ if (!url || url.length <= 0) {
32636
+ const pagePath = this.location.path();
32637
+ return `${siteurl}${pagePath}`;
32638
+ }
32639
+ url = url.filter(u => u !== this.unidadePath);
32640
+ const unidadePath = this.getUnidadePath();
32641
+ const fullPath = `${unidadePath}/${url.join("/").replace(/^\/?/, "")}`;
32642
+ return `${siteurl}/${fullPath}`.replace(/\/$/, '');
32643
+ }
32644
+ /** Cria tag script para o JSON de SEO */
32645
+ createJSONTag() {
32646
+ const tag = this.document.createElement('script');
32647
+ tag.id = this.jsonTagId;
32648
+ tag.type = 'application/ld+json';
32649
+ this.document.head.appendChild(tag);
32650
+ this.jsonTag = tag;
32651
+ return tag;
32652
+ }
32653
+ /** Retorna tag para script json de breadcrumbs ou cria se não houver. */
32654
+ getJSONTag() {
32655
+ const elements = this.document.head.children;
32656
+ let i;
32657
+ for (i = 0; i < elements.length; i++) {
32658
+ const elem = elements[i];
32659
+ if (elem && elem.id === this.jsonTagId) {
32660
+ return elem;
32661
+ }
32662
+ }
32663
+ return this.createJSONTag();
32664
+ }
32665
+ /** Define JSON para SEO somente quando no servidor */
32666
+ setPageJson() {
32667
+ this.jsonTag = this.getJSONTag();
32668
+ const graph = [this.getOrgJson(), this.getWebsiteJson(), this.getWebpageJson()];
32669
+ const json = { '@context': 'http://schema.org', '@graph': graph };
32670
+ this.jsonTag.innerHTML = JSON.stringify(json);
32671
+ return this;
32672
+ }
32673
+ /** Obtem JSON da Organização */
32674
+ getOrgJson() {
32675
+ const siteurl = getSiteUrl(this.libConfig?.siteUrl, this.libConfig?.siteSufix);
32676
+ return {
32677
+ '@type': 'Organization',
32678
+ '@id': `${siteurl}#organization`,
32679
+ name: this.defaultTitle,
32680
+ keywords: this.libConfig?.keywords,
32681
+ url: `${siteurl}`,
32682
+ sameAs: this.sameAs,
32683
+ };
32684
+ }
32685
+ /** Obtem JSON do Website (portal, unidades, etc) */
32686
+ getWebsiteJson() {
32687
+ const unidadePath = this.getUnidadePath();
32688
+ const siteurl = getSiteUrl(this.libConfig?.siteUrl, this.libConfig?.siteSufix);
32689
+ return {
32690
+ '@type': 'WebSite',
32691
+ '@id': `${siteurl}${unidadePath}#website`,
32692
+ url: `${siteurl}${unidadePath}`,
32693
+ name: this.unidadeName,
32694
+ keywords: this.libConfig?.keywords,
32695
+ };
32696
+ }
32697
+ /** Obtem Json da página */
32698
+ getWebpageJson() {
32699
+ const unidadePath = this.getUnidadePath();
32700
+ const siteURL = getSiteUrl(this.libConfig?.siteUrl, this.libConfig?.siteSufix);
32701
+ const pagePath = `${siteURL}${this.location.path()}`;
32702
+ const desc = this.activeDescription ? this.activeDescription : '';
32703
+ return {
32704
+ '@type': 'WebPage',
32705
+ '@id': `${pagePath}#webpage`,
32706
+ url: pagePath,
32707
+ inLanguage: 'pt-BR',
32708
+ name: this.getTitle(),
32709
+ isPartOf: { '@id': `${siteURL}${unidadePath}#website` },
32710
+ about: { '@id': `${siteURL}#organization` },
32711
+ description: desc,
32712
+ };
32713
+ }
32714
+ getUnidadePath() {
32715
+ let unidadePath = "";
32716
+ if (this.unidade && this.unidadePath) {
32717
+ unidadePath = this.unidade?.path === "/" ? "" : this.unidadePath?.substring(0, this.unidadePath?.length - 1);
32718
+ }
32719
+ return unidadePath;
32720
+ }
32721
+ /**
32722
+ * Obtém a URL canônica da página.
32723
+ * @returns A URL canônica da página.
32724
+ */
32725
+ getCanonicalHref() {
32726
+ if (!this.canonicalTag) {
32727
+ this.canonicalTag = this.getCanonicalTag();
32728
+ }
32729
+ return this.canonicalTag.href;
32730
+ }
32731
+ /** Cria tag para links canonicals no head */
32732
+ createCanonicalTag() {
32733
+ const tag = this.document.createElement('link');
32734
+ tag.setAttribute('rel', 'canonical');
32735
+ this.document.head.appendChild(tag);
32736
+ tag.setAttribute('href', this.document.URL);
32737
+ this.canonicalTag = tag;
32738
+ return tag;
32739
+ }
32740
+ /** Retorna tag para link canonical existe ou cria se não houver. */
32741
+ getCanonicalTag() {
32742
+ const elements = this.document.head.children;
32743
+ let i;
32744
+ for (i = 0; i < elements.length; i++) {
32745
+ const elem = elements[i];
32746
+ if (elem && elem.tagName === 'LINK' && elem.rel === 'canonical') {
32747
+ return elem;
32748
+ }
32749
+ }
32750
+ return this.createCanonicalTag();
32751
+ }
32752
+ /**
32753
+ * Define link canonical da página
32754
+ * @param url url canonical
32755
+ */
32756
+ setCanonicalHref(url) {
32757
+ if (!this.canonicalTag) {
32758
+ this.canonicalTag = this.getCanonicalTag();
32759
+ }
32760
+ let path = this.location.path();
32761
+ if (!path.startsWith('/')) {
32762
+ path = `/${path}`;
32763
+ }
32764
+ const canonicalUrl = url && this.isCustomCanonical(url) ? url : `${getSiteUrl(this.libConfig?.siteUrl, this.libConfig?.siteSufix)}${path}`;
32765
+ this.canonicalTag.setAttribute('href', canonicalUrl);
32766
+ return this;
32767
+ }
32768
+ /**
32769
+ * Verifica se a URL fornecida é um link canonical personalizado
32770
+ * @param url URL fornecida
32771
+ */
32772
+ isCustomCanonical(url) {
32773
+ const siteurl = getSiteUrl(this.libConfig?.siteUrl, this.libConfig?.siteSufix);
32774
+ return url.startsWith(siteurl);
32775
+ }
32776
+ /**
32777
+ * Obtém uma url válida na aplicação proveniente de uma URL gerada
32778
+ * pelo plugin Yoast para canonical automático.
32779
+ * Ex.: https://wp.rededorsaoluiz.com.br/brasil/especialidades/cardiologia/
32780
+ * @param urlFromWpApi URL canonica gerada pelo Yoast Plugin.
32781
+ */
32782
+ toLocalCanonical(urlFromWpApi) {
32783
+ const apiUrl = this.libConfig?.wpUrl ?? '';
32784
+ const siteurl = getSiteUrl(this.libConfig?.siteUrl, this.libConfig?.siteSufix);
32785
+ const unidadeSlug = this.unidadeSlug;
32786
+ let converted = urlFromWpApi.replace(apiUrl, siteurl);
32787
+ if (unidadeSlug !== "/" && converted.includes(`/${unidadeSlug}/`)) {
32788
+ converted = converted.replace(`/${unidadeSlug}/`, `${this.unidadePath}`);
32789
+ }
32790
+ return converted;
32791
+ }
32792
+ getPostContent(post) {
32793
+ const content = post.acf.rdsl_post_content.find((content) => content.acf_fc_layout === "text_html");
32794
+ return content.content || post.content.rendered || "";
32795
+ }
32796
+ addArticleScript(post, scriptName) {
32797
+ const postContent = this.getPostContent(post);
32798
+ const postHeaderImage = post.acf["rdsl_post_header_img"]
32799
+ ? {
32800
+ url: post.acf["rdsl_post_header_img"].url,
32801
+ width: post.acf["rdsl_post_header_img"].width,
32802
+ height: post.acf["rdsl_post_header_img"].height
32803
+ }
32804
+ : null;
32805
+ const structuredData = {
32806
+ "@context": "https://schema.org",
32807
+ "@type": "Article",
32808
+ mainEntityOfPage: `${getSiteUrl(this.libConfig?.siteUrl, this.libConfig?.siteSufix)}${this.location.path()}`,
32809
+ headline: post.title?.rendered,
32810
+ datePublished: post.date_gmt,
32811
+ publisher: {
32812
+ "@type": "Organization",
32813
+ name: "Rede D’Or"
32814
+ },
32815
+ description: post.title?.rendered,
32816
+ articleBody: removeHtmlTags(he.decode(postContent)),
32817
+ dateModified: post.modified_gmt,
32818
+ image: {
32819
+ "@type": "ImageObject",
32820
+ url: postHeaderImage?.url || post.featured_media_path || "",
32821
+ height: postHeaderImage?.height || "",
32822
+ width: postHeaderImage?.width || ""
32823
+ },
32824
+ author: {
32825
+ "@type": "Organization",
32826
+ name: "Rede D’Or"
32827
+ },
32828
+ wordcount: postContent.split(" ").length
32829
+ };
32830
+ const script = this.document.createElement("script");
32831
+ script.type = "application/ld+json";
32832
+ script.id = scriptName;
32833
+ script.innerHTML = JSON.stringify(structuredData);
32834
+ this.document.head.appendChild(script);
32835
+ }
32836
+ removeArticleScript(scriptName) {
32837
+ const script = this.document.getElementById(scriptName);
32838
+ script?.remove();
32839
+ }
32840
+ setUnidade({ unidade = null, unidadeName = "", unidadePath = "", unidadeSlug = "", }) {
32841
+ this.unidade = unidade;
32842
+ this.unidadeName = unidadeName;
32843
+ this.unidadePath = unidadePath;
32844
+ this.unidadeSlug = unidadeSlug;
32845
+ }
32846
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: SeoService, deps: [{ token: i1$1.Title }, { token: i1$1.Meta }, { token: i2.Location }, { token: LIB_CONFIG }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable }); }
32847
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: SeoService, providedIn: 'root' }); }
32848
+ }
32849
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: SeoService, decorators: [{
32850
+ type: Injectable,
32851
+ args: [{
32852
+ providedIn: 'root',
32853
+ }]
32854
+ }], ctorParameters: () => [{ type: i1$1.Title }, { type: i1$1.Meta }, { type: i2.Location }, { type: undefined, decorators: [{
32855
+ type: Inject,
32856
+ args: [LIB_CONFIG]
32857
+ }] }, { type: Document, decorators: [{
32858
+ type: Inject,
32859
+ args: [DOCUMENT]
32860
+ }] }] });
32861
+
32862
+ const REQUEST = new InjectionToken('REQUEST');
32863
+ const RESPONSE = new InjectionToken('RESPONSE');
32864
+
32865
+ class ServerResponseService {
32866
+ constructor(response) {
32867
+ this.response = response;
32868
+ }
32869
+ getHeader(key) {
32870
+ return this.response.getHeader(key);
32871
+ }
32872
+ setHeader(key, value) {
32873
+ if (this.response) {
32874
+ this.response.header(key, value);
32875
+ }
32876
+ return this;
32877
+ }
32878
+ appendHeader(key, value, delimiter = ',') {
32879
+ if (this.response) {
32880
+ const current = this.getHeader(key);
32881
+ if (!current) {
32882
+ return this.setHeader(key, value);
32883
+ }
32884
+ const newValue = [...current.split(delimiter), value].filter((el, i, a) => i === a.indexOf(el)).join(delimiter);
32885
+ this.response.header(key, newValue);
32886
+ }
32887
+ return this;
32888
+ }
32889
+ setHeaders(dictionary) {
32890
+ if (this.response) {
32891
+ Object.keys(dictionary).forEach((key) => this.setHeader(key, dictionary[key]));
32892
+ }
32893
+ return this;
32894
+ }
32895
+ setStatus(code, message) {
32896
+ if (this.response) {
32897
+ this.response.statusCode = code;
32898
+ if (message) {
32899
+ this.response.statusMessage = message;
32900
+ }
32901
+ }
32902
+ return this;
32903
+ }
32904
+ setNotFound(message = 'Não encontrado') {
32905
+ if (this.response) {
32906
+ this.response.statusCode = 404;
32907
+ this.response.statusMessage = message;
32908
+ }
32909
+ console.log(">>> setNotFound", this.response.statusCode, this.response.statusMessage);
32910
+ return this;
32911
+ }
32912
+ setUnauthorized(message = 'Não autorizado') {
32913
+ if (this.response) {
32914
+ this.response.statusCode = 401;
32915
+ this.response.statusMessage = message;
32916
+ }
32917
+ return this;
32918
+ }
32919
+ setError(message = 'Erro interno de servidor') {
32920
+ if (this.response) {
32921
+ this.response.statusCode = 500;
32922
+ this.response.statusMessage = message;
32923
+ }
32924
+ return this;
32925
+ }
32926
+ setRedirect(message = 'Redirecionado permanentemente') {
32927
+ if (this.response) {
32928
+ this.response.statusCode = 301;
32929
+ this.response.statusMessage = message;
32930
+ }
32931
+ return this;
32932
+ }
32933
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ServerResponseService, deps: [{ token: RESPONSE, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
32934
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ServerResponseService, providedIn: 'root' }); }
32935
+ }
32936
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ServerResponseService, decorators: [{
32937
+ type: Injectable,
32938
+ args: [{
32939
+ providedIn: 'root',
32940
+ }]
32941
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
32942
+ type: Optional
32943
+ }, {
32944
+ type: Inject,
32945
+ args: [RESPONSE]
32946
+ }] }] });
32947
+
32382
32948
  class SsrLoadingService {
32383
32949
  constructor(logService, platformId) {
32384
32950
  this.logService = logService;
@@ -32472,7 +33038,7 @@ class TestComponent {
32472
33038
  };
32473
33039
  }
32474
33040
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: TestComponent, deps: [{ token: CuraService }], target: i0.ɵɵFactoryTarget.Component }); }
32475
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: TestComponent, isStandalone: true, selector: "rdsite-test", host: { properties: { "style": "this.style" } }, ngImport: i0, template: "<p [ngStyle]=\"{'background-color': 'var(--color-dark)', 'color': 'var(--neutral-purewhite)'}\">test works!</p>\r\n<cura-button size=\"medium\" color=\"primary\" font-color=\"light\">CURA BUTTON</cura-button>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] }); }
33041
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: TestComponent, isStandalone: true, selector: "rdsite-test", host: { properties: { "style": "this.style" } }, ngImport: i0, template: "<p [ngStyle]=\"{'background-color': 'var(--color-dark)', 'color': 'var(--neutral-purewhite)'}\">test works!</p>\r\n<cura-button size=\"medium\" color=\"primary\" font-color=\"light\">CURA BUTTON</cura-button>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] }); }
32476
33042
  }
32477
33043
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: TestComponent, decorators: [{
32478
33044
  type: Component,
@@ -32484,14 +33050,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImpo
32484
33050
 
32485
33051
  // Components
32486
33052
 
32487
- const removeDuplicateObjectsFromArray = (arr, key) => {
32488
- return [...new Map(arr.map((item) => [item[key], item])).values()];
32489
- };
32490
-
32491
- const removeDuplicateValuesFromArray = (arr) => {
32492
- return Array.from(new Set(arr));
32493
- };
32494
-
32495
33053
  var Estados;
32496
33054
  (function (Estados) {
32497
33055
  Estados["AC"] = "Acre";
@@ -32543,5 +33101,5 @@ var EnumDoencaTaxonomyCat;
32543
33101
  * Generated bundle index. Do not edit.
32544
33102
  */
32545
33103
 
32546
- export { AlgoliaService, CuraService, EnumDoencaTaxonomy, EnumDoencaTaxonomyCat, Estados, HttpClientService, IconCuraDefaultType, LIB_CONFIG, LogService, NguCarouselService, SSR_CURA_API, SiteBackendService, SsrLoadingService, TestComponent, TransferStateService, removeDuplicateObjectsFromArray, removeDuplicateValuesFromArray };
33104
+ export { AlgoliaService, CuraService, EnumDoencaTaxonomy, EnumDoencaTaxonomyCat, Estados, HttpClientService, IconCuraDefaultType, LIB_CONFIG, LogService, NguCarouselService, REQUEST, RESPONSE, SSR_CURA_API, SeoService, ServerResponseService, SiteBackendService, SsrLoadingService, TestComponent, TransferStateService, getSiteUrl, removeDuplicateObjectsFromArray, removeDuplicateValuesFromArray, removeHtmlTags, toQueryParams };
32547
33105
  //# sourceMappingURL=rededor-site-front-end-lib.mjs.map