From 69149725321467f078dbe9e11873283ba0003767 Mon Sep 17 00:00:00 2001 From: Patrick Weygand Date: Tue, 22 Dec 2020 18:49:53 -0800 Subject: [PATCH] investigated #335, #340 --- CHANGELOG.md | 5 +++-- examples/sitemapAndIndex.js | 17 ++++++++++++++--- lib/sitemap-item-stream.ts | 2 +- lib/types.ts | 4 ++++ package-lock.json | 2 +- package.json | 2 +- tests/sitemap-utils.test.ts | 34 ++++++++++++++++++++++++++++++++-- 7 files changed, 56 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 174d1342..795de23d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,10 @@ # Changelog -## unreleased +## 6.3.4 - bump dependencies -- correct return type of xmllint. Was Promise but actually returned Promise +- correct return type of xmllint. Was `Promise` but actually returned `Promise` +- add alternate option for lang, hreflang as that is the actual name of the printed attribute ## 6.3.3 diff --git a/examples/sitemapAndIndex.js b/examples/sitemapAndIndex.js index b881d66e..21d38e14 100644 --- a/examples/sitemapAndIndex.js +++ b/examples/sitemapAndIndex.js @@ -14,17 +14,19 @@ const sms = new SitemapAndIndexStream({ // for it to write the sitemap urls to and the expected url where that sitemap will be hosted getSitemapStream: (i) => { const sitemapStream = new SitemapStream({ - hostname: 'https://example.com', + hostname: 'https://example.ru/', }); const path = `./sitemap-${i}.xml`; + const ws = createWriteStream(resolve(path + '.gz')); sitemapStream .pipe(createGzip()) // compress the output of the sitemap - .pipe(createWriteStream(resolve(path + '.gz'))); // write it to sitemap-NUMBER.xml + .pipe(ws); // write it to sitemap-NUMBER.xml return [ new URL(path, 'https://example.com/subdir/').toString(), sitemapStream, + ws, ]; }, }); @@ -40,6 +42,15 @@ sms .pipe(createGzip()) .pipe(createWriteStream(resolve('./sitemap-index.xml.gz'))); -const arrayOfSitemapItems = [{ url: '/page-1/', changefreq: 'daily' }]; +const arrayOfSitemapItems = [ + { url: '/page-1/', changefreq: 'daily' }, + { + url: '/docs', + links: [ + { lang: 'ru', url: 'https://example.ru/docs' }, + { lang: 'en', url: 'https://example.com/docs' }, + ], + }, +]; arrayOfSitemapItems.forEach((item) => sms.write(item)); sms.end(); diff --git a/lib/sitemap-item-stream.ts b/lib/sitemap-item-stream.ts index 45a305bd..e7341bad 100644 --- a/lib/sitemap-item-stream.ts +++ b/lib/sitemap-item-stream.ts @@ -215,7 +215,7 @@ export class SitemapItemStream extends Transform { this.push( element(TagNames['xhtml:link'], { rel: 'alternate', - hreflang: link.lang, + hreflang: link.lang || link.hreflang, href: link.url, }) ); diff --git a/lib/types.ts b/lib/types.ts index e760eb3e..8aaae6c4 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -305,6 +305,10 @@ export interface LinkItem { * @example 'en' */ lang: string; + /** + * @example 'en-us' + */ + hreflang?: string; url: string; } diff --git a/package-lock.json b/package-lock.json index e54e69d2..8d2415a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "sitemap", - "version": "6.3.3", + "version": "6.3.4", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index b82226c5..6242880a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sitemap", - "version": "6.3.3", + "version": "6.3.4", "description": "Sitemap-generating lib/cli", "keywords": [ "sitemap", diff --git a/tests/sitemap-utils.test.ts b/tests/sitemap-utils.test.ts index 8a16b331..8e5168cb 100644 --- a/tests/sitemap-utils.test.ts +++ b/tests/sitemap-utils.test.ts @@ -5,6 +5,7 @@ import { ErrorLevel, SitemapItemLoose, EnumChangefreq, + SitemapStream, } from '../index'; import * as testUtil from './util'; import { @@ -13,6 +14,7 @@ import { normalizeURL, } from '../lib/utils'; import { Readable, Writable } from 'stream'; +import { streamToPromise } from '../lib/sitemap-stream'; describe('utils', () => { let itemTemplate: SitemapItem; @@ -693,7 +695,7 @@ describe('utils', () => { }); it('turns a line-separated stream into a sitemap', async () => { - await new Promise((resolve) => { + await new Promise((resolve) => { lineSeparatedURLsToSitemapOptions(rs).pipe(ws); ws.on('finish', () => resolve()); }); @@ -704,7 +706,7 @@ describe('utils', () => { it('turns a line-separated JSON stream into a sitemap', async () => { let osampleURLs: { url: string }[]; - await new Promise((resolve) => { + await new Promise((resolve) => { osampleURLs = sampleURLs.map((url) => ({ url })); content = osampleURLs.map((url) => JSON.stringify(url)).join('\n'); lineSeparatedURLsToSitemapOptions(rs, { isJSON: true }).pipe(ws); @@ -818,6 +820,34 @@ describe('utils', () => { ); }); + it('does not prepend provided hostname to links that already have a hostname', async () => { + const sms = new SitemapStream({ hostname: 'https://example.ru/' }); + sms.write({ + url: '/docs', + links: [ + { lang: 'ru', url: 'https://example.ru/docs' }, + { lang: 'en', url: 'https://example.com/docs' }, + ], + }); + sms.end(); + + expect((await streamToPromise(sms)).toString()).toContain( + 'https://example.com/docs' + ); + + const url = { + url: 'http://example.ru', + links: [ + { url: 'http://example.com/lang', lang: 'en-us' }, + { url: '/lang', lang: 'en-us' }, + ], + }; + expect(normalizeURL(url, 'http://example.ru').links[0]).toHaveProperty( + 'url', + 'http://example.com/lang' + ); + }); + describe('video', () => { it('is ensured to be an array', () => { expect(