/**
* Builder class to generate xml and robots.txt
* Returns only string values
*/
export class SitemapBuilder {
/**
* Create XML Template
* @param content
* @returns
*/
withXMLTemplate(content) {
return `\n\n${content}`;
}
/**
* Generates sitemap-index.xml
* @param allSitemaps
* @returns
*/
buildSitemapIndexXml(allSitemaps) {
return [
'',
'',
...(allSitemaps?.map((x) => `${x}`) ?? []),
'',
].join('\n');
}
/**
* Normalize sitemap field keys to stay consistent with order
* @link https://www.w3schools.com/xml/el_sequence.asp
* @link https://github.com/iamvishnusankar/next-sitemap/issues/345
* @param x
* @returns
*/
normalizeSitemapField(x) {
const { loc, lastmod, changefreq, priority, ...restProps } = x;
// Return keys in following order
return {
loc,
lastmod,
changefreq,
priority,
...restProps,
};
}
/**
* Generates sitemap.xml
* @param fields
* @returns
*/
buildSitemapXml(fields) {
const content = fields
.map((x) => {
// Normalize sitemap field keys to stay consistent with order
const field = this.normalizeSitemapField(x);
// Field array to keep track of properties
const fieldArr = [];
// Iterate all object keys and key value pair to field-set
for (const key of Object.keys(field)) {
// Skip reserved keys
if (['trailingSlash'].includes(key)) {
continue;
}
if (field[key]) {
if (key !== 'alternateRefs') {
fieldArr.push(`<${key}>${field[key]}${key}>`);
}
else {
const altRefField = this.buildAlternateRefsXml(field.alternateRefs);
fieldArr.push(altRefField);
}
}
}
// Append previous value and return
return `${fieldArr.join('')}\n`;
})
.join('');
return this.withXMLTemplate(content);
}
/**
* Generate alternate refs.xml
* @param alternateRefs
* @returns
*/
buildAlternateRefsXml(alternateRefs = []) {
return alternateRefs
.map((alternateRef) => {
return ``;
})
.join('');
}
}