/** * A type-safe builder for XML elements in a sitemap. * * ```ts * import { renderSitemap, s } from "jsr:@sondr3/radiant/sitemap"; * * const sitemap = s.document( * s.doctype(), * s.urlset( * s.url( * s.loc("http://www.example.com/"), * s.lastmod(new Date("2005-01-01")), * s.changefreq("monthly"), * s.priority(0.8), * ), * s.url( * s.loc("http://www.example.com/catalog?item=73&desc=vacation_new_zealand"), * s.lastmod(new Date("2004-12-23")), * s.changefreq("weekly"), * ), * s.url( * s.loc("http://www.example.com/catalog?item=74&desc=vacation_newfoundland"), * s.lastmod(new Date("2004-12-23T18:00:15Z")), * s.priority(0.3), * ), * ), * ); * * console.log(renderSitemap(sitemap, { pretty: true })); * ``` * * @module */ import { formatDate } from "./utils.js"; import { type XMLAttributes, type XMLDeclarationType, XMLDocument, XMLElement, type XMLStyleSheet, xmlDoctype, xmlStylesheet, } from "./xml.js"; export { renderDocument as renderSitemap } from "./render_xml.js"; type UrlSetAttributes = XMLAttributes & { xmlns: "http://www.sitemaps.org/schemas/sitemap/0.9"; [key: `; type LastModElement = XMLElement<"lastmod", XMLAttributes, string>; type ChangeFreqElement = XMLElement<"changefreq", XMLAttributes, string>; type PriorityElement = XMLElement<"priority", XMLAttributes, string>; type UrlElement = XMLElement<"url", XMLAttributes, LocElement | LastModElement | ChangeFreqElement | PriorityElement>; type UrlSetElement = XMLElement<"urlset", UrlSetAttributes, UrlElement>; type SitemapElement = XMLElement<"sitemap", XMLAttributes, LocElement | LastModElement>; type SitemapIndexElement = XMLElement<"sitemapindex", UrlSetAttributes, SitemapElement>; /** * Represents the possible XML elements that can be included in a sitemap. */ export type SitemapElements = | LocElement | LastModElement | ChangeFreqElement | PriorityElement | UrlElement | UrlSetElement | SitemapElement | SitemapIndexElement; const BaseAttributes: UrlSetAttributes = { xmlns: "http://www.sitemaps.org/schemas/sitemap/0.9" }; function urlsetElement(...children: Array): UrlSetElement; function urlsetElement(attributes: UrlSetAttributes, ...children: Array): UrlSetElement; function urlsetElement( attrsOrChild: UrlSetAttributes | UrlElement | Array, ...children: Array ): UrlSetElement { if (attrsOrChild instanceof XMLElement) { return new XMLElement("urlset", BaseAttributes, [attrsOrChild, ...children]); } if (Array.isArray(attrsOrChild)) { return new XMLElement("urlset", BaseAttributes, [...attrsOrChild, ...children]); } return new XMLElement("urlset", { ...BaseAttributes, ...attrsOrChild }, children); } type ChangeFreq = "always" | "hourly" | "daily" | "weekly" | "monthly" | "yearly" | "never"; function locElement(loc: string): LocElement { return new XMLElement("loc", {}, [loc]); } function lastModElement(date: Date): LastModElement { return new XMLElement("lastmod", {}, [formatDate(date)]); } function changeFreqElement(freq: ChangeFreq): ChangeFreqElement { return new XMLElement("changefreq", {}, [freq]); } function priorityElement(priority: number): PriorityElement { return new XMLElement("priority", {}, [priority.toString()]); } function urlElement(...children: Array): UrlElement { return new XMLElement("url", {}, children); } function sitemapIndexElement(...children: Array): SitemapIndexElement; function sitemapIndexElement(attributes: UrlSetAttributes, ...children: Array): SitemapIndexElement; function sitemapIndexElement( attrsOrChild: UrlSetAttributes | SitemapElement | Array, ...children: Array ): SitemapIndexElement { if (attrsOrChild instanceof XMLElement) { return new XMLElement("sitemapindex", BaseAttributes, [attrsOrChild, ...children]); } if (Array.isArray(attrsOrChild)) { return new XMLElement("sitemapindex", BaseAttributes, [...attrsOrChild, ...children]); } return new XMLElement("sitemapindex", { ...BaseAttributes, ...attrsOrChild }, children); } function sitemapElement(...children: Array): SitemapElement { return new XMLElement("sitemap", {}, children); } const document = ( doctype: XMLDeclarationType, ...children: Array ): XMLDocument => { return new XMLDocument(doctype, children); }; /** * A type-safe builder for XML elements in a sitemap. */ export const sitemap = { /** A type-safe builder for the `` element */ document: document, /** A type-safe builder for the `` element */ doctype: () => xmlDoctype, /** A type-safe builder for the `` element */ stylesheet: xmlStylesheet, /** A type-safe builder for the `` element */ urlset: urlsetElement, /** A type-safe builder for the `` element */ url: urlElement, /** A type-safe builder for the `` element */ loc: locElement, /** A type-safe builder for the `` element */ lastmod: lastModElement, /** A type-safe builder for the `` element */ changefreq: changeFreqElement, /** A type-safe builder for the `` element */ priority: priorityElement, /** A type-safe builder for the `` element */ sitemapindex: sitemapIndexElement, /** A type-safe builder for the `` element */ sitemap: sitemapElement, }; /** * A type-safe builder for XML elements in a sitemap. */ export const s = sitemap;