UNPKG

svelte-sitemap

Version:

Small helper which scans your Svelte routes folder and generates static sitemap.xml

166 lines (165 loc) 7.38 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.writeSitemap = exports.detectErrors = exports.removeHtml = void 0; exports.prepareData = prepareData; const fast_glob_1 = __importDefault(require("fast-glob")); const fs_1 = __importDefault(require("fs")); const xmlbuilder2_1 = require("xmlbuilder2"); const package_json_1 = require("../../package.json"); const global_interface_1 = require("../interfaces/global.interface"); const vars_1 = require("../vars"); const vars_helper_1 = require("./vars.helper"); const getUrl = (url, domain, options) => { var _a; let slash = getSlash(domain); let trimmed = url .split(((_a = options === null || options === void 0 ? void 0 : options.outDir) !== null && _a !== void 0 ? _a : vars_1.OUT_DIR) + '/') .pop() .replace('index.html', ''); trimmed = (0, exports.removeHtml)(trimmed); // Add all traling slashes if (options === null || options === void 0 ? void 0 : options.trailingSlashes) { trimmed = trimmed.length && !trimmed.endsWith('/') ? trimmed + '/' : trimmed; } else { trimmed = trimmed.endsWith('/') ? trimmed.slice(0, -1) : trimmed; slash = trimmed ? slash : ''; } return `${domain}${slash}${trimmed}`; }; const removeHtml = (fileName) => { if (fileName === null || fileName === void 0 ? void 0 : fileName.endsWith('.html')) { return fileName.slice(0, -5); } return fileName; }; exports.removeHtml = removeHtml; async function prepareData(domain, options) { var _a; console.log(vars_helper_1.cliColors.cyanAndBold, `> Using ${vars_1.APP_NAME}`); const FOLDER = (_a = options === null || options === void 0 ? void 0 : options.outDir) !== null && _a !== void 0 ? _a : vars_1.OUT_DIR; const ignore = prepareIgnored(options === null || options === void 0 ? void 0 : options.ignore, options === null || options === void 0 ? void 0 : options.outDir); const changeFreq = prepareChangeFreq(options); const pages = await (0, fast_glob_1.default)(`${FOLDER}/**/*.html`, { ignore }); if (options.additional) pages.push(...options.additional); const results = pages.map((page) => { return { page: getUrl(page, domain, options), changeFreq: changeFreq, lastMod: (options === null || options === void 0 ? void 0 : options.resetTime) ? new Date().toISOString().split('T')[0] : '' }; }); (0, exports.detectErrors)({ folder: !fs_1.default.existsSync(FOLDER), htmlFiles: !pages.length }); return results; } const detectErrors = ({ folder, htmlFiles }) => { if (folder && htmlFiles) { console.error(vars_helper_1.cliColors.red, (0, vars_helper_1.errorMsgFolder)(vars_1.OUT_DIR)); } else if (htmlFiles) { // If no page exists, then the static adapter is probably not used console.error(vars_helper_1.cliColors.red, (0, vars_helper_1.errorMsgHtmlFiles)(vars_1.OUT_DIR)); } }; exports.detectErrors = detectErrors; const writeSitemap = (items, options, domain) => { var _a; const outDir = (_a = options === null || options === void 0 ? void 0 : options.outDir) !== null && _a !== void 0 ? _a : vars_1.OUT_DIR; if ((items === null || items === void 0 ? void 0 : items.length) <= vars_1.CHUNK.maxSize) { createFile(items, options, outDir); } else { // If the number of pages is greater than the chunk size, then we split the sitemap into multiple files // and create an index file that links to all of them // https://support.google.com/webmasters/answer/183668?hl=en const numberOfChunks = Math.ceil(items.length / vars_1.CHUNK.maxSize); console.log(vars_helper_1.cliColors.cyanAndBold, `> Oh, your site is huge! Writing sitemap in chunks of ${numberOfChunks} pages and its index sitemap.xml`); for (let i = 0; i < items.length; i += vars_1.CHUNK.maxSize) { const chunk = items.slice(i, i + vars_1.CHUNK.maxSize); createFile(chunk, options, outDir, i / vars_1.CHUNK.maxSize + 1); } createIndexFile(numberOfChunks, outDir, options, domain); } }; exports.writeSitemap = writeSitemap; const createFile = (items, options, outDir, chunkId) => { const sitemap = createXml('urlset'); addAttribution(sitemap, options); for (const item of items) { const page = sitemap.ele('url'); page.ele('loc').txt(item.page); if (item.changeFreq) { page.ele('changefreq').txt(item.changeFreq); } if (item.lastMod) { page.ele('lastmod').txt(item.lastMod); } } const xml = finishXml(sitemap); const fileName = chunkId ? `sitemap-${chunkId}.xml` : 'sitemap.xml'; try { fs_1.default.writeFileSync(`${outDir}/${fileName}`, xml); console.log(vars_helper_1.cliColors.green, (0, vars_helper_1.successMsg)(outDir, fileName)); } catch (e) { console.error(vars_helper_1.cliColors.red, (0, vars_helper_1.errorMsgWrite)(outDir, fileName), e); } }; const createIndexFile = (numberOfChunks, outDir, options, domain) => { const FILENAME = 'sitemap.xml'; const slash = getSlash(domain); const sitemap = createXml('sitemapindex'); addAttribution(sitemap, options); for (let i = 1; i <= numberOfChunks; i++) { sitemap.ele('sitemap').ele('loc').txt(`${domain}${slash}sitemap-${i}.xml`); } const xml = finishXml(sitemap); try { fs_1.default.writeFileSync(`${outDir}/${FILENAME}`, xml); console.log(vars_helper_1.cliColors.green, (0, vars_helper_1.successMsg)(outDir, FILENAME)); } catch (e) { console.error(vars_helper_1.cliColors.red, (0, vars_helper_1.errorMsgWrite)(outDir, FILENAME), e); } }; const prepareIgnored = (ignored, outDir = vars_1.OUT_DIR) => { let ignore; if (ignored) { ignore = Array.isArray(ignored) ? ignored : [ignored]; ignore = ignore.map((ignoredPage) => `${outDir}/${ignoredPage}`); } return ignore; }; const prepareChangeFreq = (options) => { let result = null; if (options === null || options === void 0 ? void 0 : options.changeFreq) { if (global_interface_1.changeFreq.includes(options.changeFreq)) { result = options.changeFreq; } else { console.log(vars_helper_1.cliColors.red, ` × Option \`--change-freq ${options.changeFreq}\` is not a valid value. See docs: https://github.com/bartholomej/svelte-sitemap#options`); } } return result; }; const getSlash = (domain) => (domain.split('/').pop() ? '/' : ''); const createXml = (elementName) => { return (0, xmlbuilder2_1.create)({ version: '1.0', encoding: 'UTF-8' }).ele(elementName, { xmlns: 'http://www.sitemaps.org/schemas/sitemap/0.9' }); }; const finishXml = (sitemap) => { return sitemap.end({ prettyPrint: true }); }; const addAttribution = (sitemap, options) => { if ((options === null || options === void 0 ? void 0 : options.attribution) !== false) { sitemap.com(` This file was automatically generated by https://github.com/bartholomej/svelte-sitemap v${package_json_1.version} `); } };