-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(sitemap-generator): implement a first basic sitemap generator (b…
…eta) (#63)
- Loading branch information
Showing
7 changed files
with
247 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
93 changes: 93 additions & 0 deletions
93
src/sitemap-generator/__tests__/v-sitemap-generator.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import {VSitemapGenerator} from "../v-sitemap-generator"; | ||
import {VSitemapGeneratorConfig} from "../v-sitemap-generator-config"; | ||
|
||
describe('VSitemapGenerator', () => { | ||
|
||
let generator: VSitemapGenerator; | ||
|
||
beforeEach(() => generator = new VSitemapGenerator()); | ||
|
||
describe('Empty', () => { | ||
it('should generate nothing when config is empty', () => { | ||
const xml = generator.generate({}); | ||
expect(xml).toEqual('<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"></urlset>'); | ||
}); | ||
|
||
it('should generate nothing when there are no Vienna routes provided', () => { | ||
const xml = generator.generate({routes: []}); | ||
expect(xml).toEqual('<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"></urlset>'); | ||
}); | ||
|
||
it('should generate nothing when there are no manual items provided', () => { | ||
const xml = generator.generate({manual: []}); | ||
expect(xml).toEqual('<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"></urlset>'); | ||
}); | ||
}); | ||
|
||
|
||
describe('Vienna route', () => { | ||
it('should generate with priority 1.0', () => { | ||
const config: VSitemapGeneratorConfig = { | ||
routes: [ | ||
{path: '/a', component: {}} | ||
] | ||
} | ||
const xml = generator.generate(config); | ||
expect(xml).toEqual('<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"><url><loc>/a</loc><priority>1.0</priority></url></urlset>'); | ||
}); | ||
|
||
it('should not generate it when the route has a guard', () => { | ||
const config: VSitemapGeneratorConfig = { | ||
routes: [ | ||
{path: '/a', component: {}, guards: [jest.fn()]} | ||
] | ||
} | ||
const xml = generator.generate(config); | ||
expect(xml).toEqual('<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"></urlset>'); | ||
}); | ||
}); | ||
|
||
describe('Manual', () => { | ||
it('should generate', () => { | ||
const config: VSitemapGeneratorConfig = { | ||
manual: [ | ||
{location: '/b'} | ||
] | ||
} | ||
const xml = generator.generate(config); | ||
expect(xml).toEqual('<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"><url><loc>/b</loc></url></urlset>'); | ||
}); | ||
|
||
it('should add changefreq', () => { | ||
const config: VSitemapGeneratorConfig = { | ||
manual: [ | ||
{location: '/b', changefreq: 'always'} | ||
] | ||
} | ||
const xml = generator.generate(config); | ||
expect(xml).toEqual('<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"><url><loc>/b</loc><changefreq>always</changefreq></url></urlset>'); | ||
}); | ||
|
||
it('should add priority', () => { | ||
const config: VSitemapGeneratorConfig = { | ||
manual: [ | ||
{location: '/b', priority: 0.5} | ||
] | ||
} | ||
const xml = generator.generate(config); | ||
expect(xml).toEqual('<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"><url><loc>/b</loc><priority>0.5</priority></url></urlset>'); | ||
}); | ||
|
||
it.each([-0.1, 1.1, -10, 10, null, undefined])('should not add priority when value is %s', (priority) => { | ||
const config: VSitemapGeneratorConfig = { | ||
manual: [ | ||
{location: '/b', priority} | ||
] | ||
} | ||
const xml = generator.generate(config); | ||
expect(xml).toEqual('<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"><url><loc>/b</loc></url></urlset>'); | ||
}); | ||
}); | ||
|
||
|
||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export * from './v-sitemap-changefreq'; | ||
export * from './v-sitemap-generator'; | ||
export * from './v-sitemap-generator-config'; | ||
export * from './v-sitemap-manual-item'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export type VSitemapChangefreq = 'never' | 'yearly' | 'monthly' | 'weekly' | 'daily' | 'hourly' | 'always'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import {VRoute} from "../core"; | ||
import {VSitemapManualItem} from "./v-sitemap-manual-item"; | ||
|
||
export interface VSitemapGeneratorConfig { | ||
routes?: VRoute[]; | ||
manual?: VSitemapManualItem[] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import {VSitemapGeneratorConfig} from "./v-sitemap-generator-config"; | ||
|
||
const HEAD = `<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">` | ||
|
||
export class VSitemapGenerator { | ||
|
||
/** | ||
* Returns an xml string that contains a sitemap for the provided config. | ||
* @param config | ||
*/ | ||
generate(config: VSitemapGeneratorConfig): string | void { | ||
return this.createXmlByConfig(config); | ||
} | ||
|
||
/** | ||
* Writes a file to the provided output for the provided config. | ||
* Example output: '/my/location/sitemap.xml' | ||
* @param config | ||
* @param output | ||
*/ | ||
generateAndWriteToFile(config: VSitemapGeneratorConfig, output: string): void { | ||
const xml = this.createXmlByConfig(config); | ||
const fs = require("fs"); | ||
const writeStream = fs.createWriteStream(output); | ||
writeStream.write(xml); | ||
writeStream.end(); | ||
} | ||
|
||
private createXmlByConfig(config: VSitemapGeneratorConfig): string { | ||
if (this.isEmptyConfig(config)) { | ||
return `${HEAD}</urlset>`; | ||
} | ||
|
||
let xml = HEAD; | ||
if (config.routes) { | ||
xml = config.routes | ||
.filter(route => !(route.guards && route.guards.length > 0)) | ||
.reduce((x, route) => { | ||
// Since this are root Vienna routes, we assume these routes contain important pages, | ||
// such as homepage, information pages and so on. Hence, we add the priority 1.0. | ||
// See: https://www.v9digital.com/insights/sitemap-xml-why-changefreq-priority-are-important/ | ||
x += `<url><loc>${route.path}</loc><priority>1.0</priority></url>`; | ||
return x; | ||
}, xml); | ||
} | ||
|
||
if (config.manual) { | ||
xml = config.manual.reduce((x, item) => { | ||
x += '<url>'; | ||
x += `<loc>${item.location}</loc>`; | ||
if (item.changefreq) { | ||
x += `<changefreq>${item.changefreq}</changefreq>`; | ||
} | ||
if (item.priority && item.priority >= 0 && item.priority <= 1) { | ||
x += `<priority>${item.priority.toFixed(1)}</priority>`; | ||
} | ||
x += '</url>'; | ||
return x; | ||
}, xml); | ||
} | ||
|
||
return `${xml}</urlset>`; | ||
} | ||
|
||
private isEmptyConfig(config: VSitemapGeneratorConfig): boolean { | ||
return (!config.routes || config.routes.length < 1) | ||
&& (!config.manual || config.manual.length < 1); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import {VSitemapChangefreq} from "./v-sitemap-changefreq"; | ||
|
||
export interface VSitemapManualItem { | ||
location: string; | ||
changefreq?: VSitemapChangefreq; | ||
priority?: number; | ||
} |