83 lines
2.5 KiB
TypeScript
83 lines
2.5 KiB
TypeScript
import type * as interfaces from './interfaces/index.js';
|
|
import { XmlRenderer } from './smartsitemap.classes.xmlrenderer.js';
|
|
import { UrlsetBuilder } from './smartsitemap.classes.urlsetbuilder.js';
|
|
|
|
/**
|
|
* Builder for sitemap index files (<sitemapindex>).
|
|
* Used when you have multiple sitemaps that need to be referenced from a single index.
|
|
* Every mutating method returns `this` for fluent chaining.
|
|
*/
|
|
export class SitemapIndexBuilder {
|
|
private entries: interfaces.ISitemapIndexEntry[] = [];
|
|
private options: interfaces.ISitemapOptions;
|
|
|
|
constructor(options?: interfaces.ISitemapOptions) {
|
|
this.options = options ?? {};
|
|
}
|
|
|
|
/** Add a sitemap index entry */
|
|
add(entry: interfaces.ISitemapIndexEntry): this {
|
|
this.entries.push(entry);
|
|
return this;
|
|
}
|
|
|
|
/** Add a sitemap by URL, optionally with lastmod */
|
|
addSitemap(loc: string, lastmod?: Date | string | number): this {
|
|
const entry: interfaces.ISitemapIndexEntry = { loc };
|
|
if (lastmod != null) {
|
|
entry.lastmod = lastmod;
|
|
}
|
|
this.entries.push(entry);
|
|
return this;
|
|
}
|
|
|
|
/** Add multiple sitemap entries */
|
|
addSitemaps(entries: interfaces.ISitemapIndexEntry[]): this {
|
|
this.entries.push(...entries);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Build an index and individual sitemaps from a UrlsetBuilder that needs splitting.
|
|
* The builder's URLs are divided into chunks of maxUrlsPerSitemap.
|
|
*/
|
|
static fromBuilder(
|
|
builder: UrlsetBuilder,
|
|
baseUrl: string,
|
|
): { index: SitemapIndexBuilder; sitemaps: UrlsetBuilder[] } {
|
|
const urls = builder.getUrls();
|
|
const options = builder.getOptions();
|
|
const maxUrls = Math.min(options.maxUrlsPerSitemap ?? 50000, 50000);
|
|
|
|
const index = new SitemapIndexBuilder(options);
|
|
const sitemaps: UrlsetBuilder[] = [];
|
|
|
|
for (let i = 0; i < urls.length; i += maxUrls) {
|
|
const chunk = urls.slice(i, i + maxUrls);
|
|
const chunkBuilder = new UrlsetBuilder(options);
|
|
chunkBuilder.addUrls(chunk);
|
|
sitemaps.push(chunkBuilder);
|
|
|
|
const filename = `sitemap-${sitemaps.length}.xml`;
|
|
index.addSitemap(`${baseUrl.replace(/\/$/, '')}/${filename}`);
|
|
}
|
|
|
|
return { index, sitemaps };
|
|
}
|
|
|
|
/** Export as sitemap index XML string */
|
|
toXml(): string {
|
|
return XmlRenderer.renderIndex(this.entries, this.options);
|
|
}
|
|
|
|
/** Get all entries */
|
|
getEntries(): interfaces.ISitemapIndexEntry[] {
|
|
return [...this.entries];
|
|
}
|
|
|
|
/** Get the number of sitemaps in this index */
|
|
get count(): number {
|
|
return this.entries.length;
|
|
}
|
|
}
|