{"version":3,"file":"sitemap.xml.mjs","names":[],"sources":["../../../src/astro/routes/sitemap.xml.ts"],"sourcesContent":["/**\n * Sitemap index endpoint\n *\n * GET /sitemap.xml - Sitemap index listing one sitemap per collection.\n *\n * Each collection with published, indexable content gets its own\n * child sitemap at /sitemap-{collection}.xml. The index includes\n * a <lastmod> per child derived from the most recently updated entry.\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { handleSitemapData } from \"#api/handlers/seo.js\";\nimport { getPublicOrigin } from \"#api/public-url.js\";\nimport { getSiteSettingsWithDb } from \"#settings/index.js\";\n\nexport const prerender = false;\n\nconst TRAILING_SLASH_RE = /\\/$/;\nconst AMP_RE = /&/g;\nconst LT_RE = /</g;\nconst GT_RE = />/g;\nconst QUOT_RE = /\"/g;\nconst APOS_RE = /'/g;\n\nexport const GET: APIRoute = async ({ locals, url }) => {\n\tconst { emdash } = locals;\n\n\tif (!emdash?.db) {\n\t\treturn new Response(\"<!-- EmDash not configured -->\", {\n\t\t\tstatus: 500,\n\t\t\theaders: { \"Content-Type\": \"application/xml\" },\n\t\t});\n\t}\n\n\ttry {\n\t\tconst settings = await getSiteSettingsWithDb(emdash.db);\n\t\tconst siteUrl = (settings.url || getPublicOrigin(url, emdash?.config)).replace(\n\t\t\tTRAILING_SLASH_RE,\n\t\t\t\"\",\n\t\t);\n\n\t\tconst result = await handleSitemapData(emdash.db);\n\n\t\tif (!result.success || !result.data) {\n\t\t\treturn new Response(\"<!-- Failed to generate sitemap -->\", {\n\t\t\t\tstatus: 500,\n\t\t\t\theaders: { \"Content-Type\": \"application/xml\" },\n\t\t\t});\n\t\t}\n\n\t\tconst { collections } = result.data;\n\n\t\tconst lines: string[] = [\n\t\t\t'<?xml version=\"1.0\" encoding=\"UTF-8\"?>',\n\t\t\t'<sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">',\n\t\t];\n\n\t\tfor (const col of collections) {\n\t\t\tconst loc = `${siteUrl}/sitemap-${encodeURIComponent(col.collection)}.xml`;\n\t\t\tlines.push(\"  <sitemap>\");\n\t\t\tlines.push(`    <loc>${escapeXml(loc)}</loc>`);\n\t\t\tlines.push(`    <lastmod>${escapeXml(col.lastmod)}</lastmod>`);\n\t\t\tlines.push(\"  </sitemap>\");\n\t\t}\n\n\t\tlines.push(\"</sitemapindex>\");\n\n\t\treturn new Response(lines.join(\"\\n\"), {\n\t\t\tstatus: 200,\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/xml; charset=utf-8\",\n\t\t\t\t\"Cache-Control\": \"public, max-age=3600\",\n\t\t\t},\n\t\t});\n\t} catch {\n\t\treturn new Response(\"<!-- Internal error generating sitemap -->\", {\n\t\t\tstatus: 500,\n\t\t\theaders: { \"Content-Type\": \"application/xml\" },\n\t\t});\n\t}\n};\n\n/** Escape special XML characters in a string */\nfunction escapeXml(str: string): string {\n\treturn str\n\t\t.replace(AMP_RE, \"&amp;\")\n\t\t.replace(LT_RE, \"&lt;\")\n\t\t.replace(GT_RE, \"&gt;\")\n\t\t.replace(QUOT_RE, \"&quot;\")\n\t\t.replace(APOS_RE, \"&apos;\");\n}\n"],"mappings":";;;;;;;;;;;;;;;AAgBA,MAAa,YAAY;AAEzB,MAAM,oBAAoB;AAC1B,MAAM,SAAS;AACf,MAAM,QAAQ;AACd,MAAM,QAAQ;AACd,MAAM,UAAU;AAChB,MAAM,UAAU;AAEhB,MAAa,MAAgB,OAAO,EAAE,QAAQ,UAAU;CACvD,MAAM,EAAE,WAAW;AAEnB,KAAI,CAAC,QAAQ,GACZ,QAAO,IAAI,SAAS,kCAAkC;EACrD,QAAQ;EACR,SAAS,EAAE,gBAAgB,mBAAmB;EAC9C,CAAC;AAGH,KAAI;EAEH,MAAM,YADW,MAAM,sBAAsB,OAAO,GAAG,EAC7B,OAAO,gBAAgB,KAAK,QAAQ,OAAO,EAAE,QACtE,mBACA,GACA;EAED,MAAM,SAAS,MAAM,kBAAkB,OAAO,GAAG;AAEjD,MAAI,CAAC,OAAO,WAAW,CAAC,OAAO,KAC9B,QAAO,IAAI,SAAS,uCAAuC;GAC1D,QAAQ;GACR,SAAS,EAAE,gBAAgB,mBAAmB;GAC9C,CAAC;EAGH,MAAM,EAAE,gBAAgB,OAAO;EAE/B,MAAM,QAAkB,CACvB,8CACA,uEACA;AAED,OAAK,MAAM,OAAO,aAAa;GAC9B,MAAM,MAAM,GAAG,QAAQ,WAAW,mBAAmB,IAAI,WAAW,CAAC;AACrE,SAAM,KAAK,cAAc;AACzB,SAAM,KAAK,YAAY,UAAU,IAAI,CAAC,QAAQ;AAC9C,SAAM,KAAK,gBAAgB,UAAU,IAAI,QAAQ,CAAC,YAAY;AAC9D,SAAM,KAAK,eAAe;;AAG3B,QAAM,KAAK,kBAAkB;AAE7B,SAAO,IAAI,SAAS,MAAM,KAAK,KAAK,EAAE;GACrC,QAAQ;GACR,SAAS;IACR,gBAAgB;IAChB,iBAAiB;IACjB;GACD,CAAC;SACK;AACP,SAAO,IAAI,SAAS,8CAA8C;GACjE,QAAQ;GACR,SAAS,EAAE,gBAAgB,mBAAmB;GAC9C,CAAC;;;;AAKJ,SAAS,UAAU,KAAqB;AACvC,QAAO,IACL,QAAQ,QAAQ,QAAQ,CACxB,QAAQ,OAAO,OAAO,CACtB,QAAQ,OAAO,OAAO,CACtB,QAAQ,SAAS,SAAS,CAC1B,QAAQ,SAAS,SAAS"}