sitemap-manager
Advanced tools
Comparing version 2.1.0 to 2.2.0
@@ -0,1 +1,19 @@ | ||
# [2.2.0](https://github.com/CBW2007/sitemap-manager/compare/v2.1.0...v2.2.0) (2022-01-22) | ||
### Bug Fixes | ||
* **main:** fix a bug that makes "isFinished" not work ([7be745f](https://github.com/CBW2007/sitemap-manager/commit/7be745fb6002a22b8047863bffb2a60ba3e3e9bf)) | ||
* **test:** remove rmDirSync, use rmSync instead ([0af6a53](https://github.com/CBW2007/sitemap-manager/commit/0af6a532909e98bb0d015ad8137080f64723337b)) | ||
### Features | ||
* add checks of the repeated and invalid url ([343ef17](https://github.com/CBW2007/sitemap-manager/commit/343ef17c485d75eb682fb4a72496d28327a90bc6)) | ||
* add hooks ([cfab1e9](https://github.com/CBW2007/sitemap-manager/commit/cfab1e99f9f782c9ac84f74fdcdd96f523335a85)) | ||
* allow to add single url obj ([789c48e](https://github.com/CBW2007/sitemap-manager/commit/789c48e7a0b83293f95be23a0ce148c07edfab80)) | ||
* export types as well ([5fc8d18](https://github.com/CBW2007/sitemap-manager/commit/5fc8d1884e1fb15027d0dc38c8d3aa5eccfc5718)) | ||
# [2.1.0](https://github.com/CBW2007/sitemap-manager/compare/v2.0.1...v2.1.0) (2021-08-04) | ||
@@ -2,0 +20,0 @@ |
@@ -1,20 +0,3 @@ | ||
interface Option { | ||
outDir?: string; | ||
siteURL: string; | ||
pathPrefix?: string; | ||
} | ||
interface Url { | ||
loc: string; | ||
lastmod?: string | Date; | ||
changefreq?: 'never' | 'yearly' | 'monthly' | 'weekly' | 'daily' | 'hourly' | 'always' | 1 | 2 | 3 | 4 | 5 | 6 | 7; | ||
priority?: number; | ||
} | ||
declare class SitemapManager { | ||
#private; | ||
options: Option; | ||
isFinished: Boolean; | ||
constructor(options: Option); | ||
addUrl(name: string, url: Array<Url>): void; | ||
finish(): Promise<void>; | ||
} | ||
export { SitemapManager }; | ||
import { SitemapManager } from './main'; | ||
import * as types from './types'; | ||
export { SitemapManager, types }; |
"use strict"; | ||
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); | ||
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
var _SitemapManager_urlDatas; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.SitemapManager = void 0; | ||
const fs_1 = __importDefault(require("fs")); | ||
const xml_1 = __importDefault(require("xml")); | ||
const url_1 = require("url"); | ||
const path_1 = __importDefault(require("path")); | ||
const xmlStylesheet = Buffer.from('PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjx4c2w6c3R5bGVzaGVldCB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIgeG1sbnM6c2l0ZW1hcD0iaHR0cDovL3d3dy5zaXRlbWFwcy5vcmcvc2NoZW1hcy9zaXRlbWFwLzAuOSIgeG1sbnM6Zm49Imh0dHA6Ly93d3cudzMub3JnLzIwMDUvMDIveHBhdGgtZnVuY3Rpb25zIiB2ZXJzaW9uPSIxLjAiPjx4c2w6dGVtcGxhdGUgbWF0Y2g9Ii8iPjxodG1sPjxoZWFkPjx0aXRsZT5TaXRlbWFwPC90aXRsZT48bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEsIG1heGltdW0tc2NhbGU9MSwgc2hyaW5rLXRvLWZpdD1ubyIvPjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+DQoJCSAJCS5hLW5vLXVsOjpiZWZvcmUgew0KCQkgCQkJZGlzcGxheTogbm9uZTsNCgkJIAkJfQ0KCQkJPC9zdHlsZT48IS0tIE1EVUkgQ1NTIC0tPjxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0L25wbS9tZHVpQDEuMC4xL2Rpc3QvY3NzL21kdWkubWluLmNzcyIgaW50ZWdyaXR5PSJzaGEzODQtY0xSck1xMzlIT1pkdkUwajZ5Qm9qTzQrMVBySGZCN2E5bDVxTGNtUm0vZmlXWFlZK0NuZEpQbXl1NUZWLzlUdyIgY3Jvc3NvcmlnaW49ImFub255bW91cyIvPjwvaGVhZD48Ym9keT48ZGl2IGNsYXNzPSJtZHVpLWNvbnRhaW5lciBtZHVpLXR5cG8iPjxoMSBzdHlsZT0idGV4dC1hbGlnbjpjZW50ZXIiPlNpdGVtYXA8L2gxPjxkaXYgY2xhc3M9Im1kdWktZGl2aWRlciIvPjx4c2w6aWYgdGVzdD0iY291bnQoc2l0ZW1hcDpzaXRlbWFwaW5kZXgvc2l0ZW1hcDpzaXRlbWFwKSAmbHQ7IDEiPjxhIGhyZWY9InNpdGVtYXAueG1sIiBjbGFzcz0ibWR1aS1idG4gYS1uby11bCI+PGkgY2xhc3M9Im1kdWktaWNvbiBtYXRlcmlhbC1pY29ucyI+7oybPC9pPmJhY2sgdG8gaW5kZXg8L2E+PC94c2w6aWY+PHhzbDppZiB0ZXN0PSJjb3VudChzaXRlbWFwOnNpdGVtYXBpbmRleC9zaXRlbWFwOnNpdGVtYXApICZsdDsgMSI+PHRhYmxlIGNsYXNzPSJtZHVpLXRhYmxlIj48dGhlYWQ+PHRyPjx0aCBzdHlsZT0id2lkdGg6NzAlIj5VUkw8L3RoPjx0aCBzdHlsZT0id2lkdGg6MjAlIj5MYXN0IG1vZGlmaWNhdGlvbiB0aW1lPC90aD48dGggc3R5bGU9IndpZHRoOjUlIj5DaGFuZ2UgZnJlcXVlbmNlPC90aD48dGggc3R5bGU9IndpZHRoOjUlIj5Qcmlvcml0eTwvdGg+PC90cj48L3RoZWFkPjx0Ym9keT48eHNsOmZvci1lYWNoIHNlbGVjdD0ic2l0ZW1hcDp1cmxzZXQvc2l0ZW1hcDp1cmwiPjx0cj48dGQ+PHhzbDp2YXJpYWJsZSBuYW1lPSJsb2NVcmwiPjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJzaXRlbWFwOmxvYyIvPjwveHNsOnZhcmlhYmxlPjxhIGhyZWY9InskbG9jVXJsfSI+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9InNpdGVtYXA6bG9jIi8+PC9hPjwvdGQ+PHRkPjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJzaXRlbWFwOmxhc3Rtb2QiLz48L3RkPjx0ZD48eHNsOnZhbHVlLW9mIHNlbGVjdD0ic2l0ZW1hcDpjaGFuZ2VmcmVxIi8+PC90ZD48dGQ+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9InNpdGVtYXA6cHJpb3JpdHkiLz48L3RkPjwvdHI+PC94c2w6Zm9yLWVhY2g+PC90Ym9keT48L3RhYmxlPjwveHNsOmlmPjx4c2w6aWYgdGVzdD0iY291bnQoc2l0ZW1hcDpzaXRlbWFwaW5kZXgvc2l0ZW1hcDpzaXRlbWFwKSAmZ3Q7IDAiPjx0YWJsZSBjbGFzcz0ibWR1aS10YWJsZSI+PHRoZWFkPjx0cj48dGggc3R5bGU9IndpZHRoOjgwJSI+VVJMPC90aD48dGggc3R5bGU9IndpZHRoOjIwJSI+TGFzdCBtb2RpZmljYXRpb24gdGltZTwvdGg+PC90cj48L3RoZWFkPjx0Ym9keT48eHNsOmZvci1lYWNoIHNlbGVjdD0ic2l0ZW1hcDpzaXRlbWFwaW5kZXgvc2l0ZW1hcDpzaXRlbWFwIj48dHI+PHRkPjx4c2w6dmFyaWFibGUgbmFtZT0ibG9jVXJsIj48eHNsOnZhbHVlLW9mIHNlbGVjdD0ic2l0ZW1hcDpsb2MiLz48L3hzbDp2YXJpYWJsZT48YSBocmVmPSJ7JGxvY1VybH0iPjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJzaXRlbWFwOmxvYyIvPjwvYT48L3RkPjx0ZD48eHNsOnZhbHVlLW9mIHNlbGVjdD0ic2l0ZW1hcDpsYXN0bW9kIi8+PC90ZD48L3RyPjwveHNsOmZvci1lYWNoPjwvdGJvZHk+PC90YWJsZT48L3hzbDppZj48L2Rpdj48IS0tIE1EVUkgSmF2YVNjcmlwdCAtLT48c2NyaXB0IHNyYz0iaHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0L25wbS9tZHVpQDEuMC4xL2Rpc3QvanMvbWR1aS5taW4uanMiIGludGVncml0eT0ic2hhMzg0LWdDTVpjc2hZS09HUlg5cjZ3YkRydkYrVGNDQ3N3U0hGdWNVelVQd2thK0dyK3VIZ2psWXZrQUJyOTVUQ096M0EiIGNyb3Nzb3JpZ2luPSJhbm9ueW1vdXMiLz48L2JvZHk+PC9odG1sPjwveHNsOnRlbXBsYXRlPjwveHNsOnN0eWxlc2hlZXQ+DQo=', 'base64').toString(); | ||
const xmlDeclaration = '<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/xsl" href="sitemap.xsl"?>'; | ||
const freqMap = ['', 'never', 'yearly', 'monthly', 'weekly', 'daily', 'hourly', 'always']; | ||
function dateConverter(date) { | ||
return new Date(date).toISOString(); | ||
} | ||
class SitemapManager { | ||
constructor(options) { | ||
_SitemapManager_urlDatas.set(this, new Map()); | ||
this.isFinished = false; | ||
this.options = options; | ||
} | ||
addUrl(name, url) { | ||
if (this.isFinished) { | ||
throw new Error('[SitemapManager] Error: Lifecycle finished'); | ||
} | ||
__classPrivateFieldGet(this, _SitemapManager_urlDatas, "f").set(name, [...(__classPrivateFieldGet(this, _SitemapManager_urlDatas, "f").get(name) || []), ...url]); | ||
} | ||
finish() { | ||
return new Promise((resolve, reject) => { | ||
var _a, _b; | ||
if (this.isFinished) { | ||
reject(new Error('[SitemapManager] Error: Lifecycle finished')); | ||
} | ||
// Create index sitemap | ||
let xmlContents = []; | ||
__classPrivateFieldGet(this, _SitemapManager_urlDatas, "f").forEach((v, k) => { | ||
xmlContents.push({ | ||
sitemap: [ | ||
{ loc: new url_1.URL(path_1.default.join(this.options.pathPrefix || '', `sitemap-${k}.xml`), this.options.siteURL).toString() }, | ||
{ lastmod: dateConverter(new Date()) } | ||
] | ||
}); | ||
}); | ||
try { | ||
fs_1.default.writeFileSync(path_1.default.resolve(((_a = this.options) === null || _a === void 0 ? void 0 : _a.outDir) || './public', 'sitemap.xml'), xmlDeclaration + xml_1.default({ sitemapindex: [{ _attr: { xmlns: 'http://www.sitemaps.org/schemas/sitemap/0.9' } }, ...xmlContents] })); | ||
} | ||
catch (e) { | ||
reject(new Error(`[SitemapManager] Failed to write file sitemap.xml: ${e.message}`)); | ||
} | ||
// Create each sitemap | ||
__classPrivateFieldGet(this, _SitemapManager_urlDatas, "f").forEach((value, key) => { | ||
var _a; | ||
xmlContents = []; | ||
value.forEach((node) => { | ||
const ele = [{ loc: node.loc }]; | ||
if (node.lastmod) | ||
ele.push({ lastmod: dateConverter(node.lastmod) }); | ||
if (node.changefreq && | ||
((typeof (node.changefreq) === 'number' && node.changefreq >= 1 && node.changefreq <= 7) || | ||
(typeof (node.changefreq) === 'string' && freqMap.includes(node.changefreq)))) { | ||
ele.push({ changefreq: typeof (node.changefreq) === 'string' ? node.changefreq : freqMap[node.changefreq] }); | ||
} | ||
else if (node.changefreq) { | ||
reject(new Error(`[SitemapManager] Invalid changefreq value: Expects a number ranges from 1 to 7(1 for the least, 7 for the most) or a string. See more: https://www.sitemaps.org/protocol.html#xmlTagDefinitions. Received ${node.changefreq}`)); | ||
} | ||
if (node.priority && node.priority >= 0 && node.priority <= 1) { | ||
ele.push({ priority: node.priority }); | ||
} | ||
else if (node.priority) { | ||
reject(new Error(`[SitemapManager] Invalid priority value: Expects a number ranges from 0.0 to 1.0. Received ${node.priority}`)); | ||
} | ||
xmlContents.push({ | ||
url: ele | ||
}); | ||
}); | ||
try { | ||
fs_1.default.writeFileSync(path_1.default.resolve(((_a = this.options) === null || _a === void 0 ? void 0 : _a.outDir) || './public', `sitemap-${key}.xml`), xmlDeclaration + xml_1.default({ urlset: [{ _attr: { xmlns: 'http://www.sitemaps.org/schemas/sitemap/0.9' } }, ...xmlContents] })); | ||
} | ||
catch (e) { | ||
reject(new Error(`[SitemapManager] Failed to write file sitemap-${key}.xml: ${e.message}`)); | ||
} | ||
}); | ||
// Create sitemap stylesheet | ||
try { | ||
fs_1.default.writeFileSync(path_1.default.resolve(((_b = this.options) === null || _b === void 0 ? void 0 : _b.outDir) || './public', 'sitemap.xsl'), xmlStylesheet); | ||
} | ||
catch (e) { | ||
reject(new Error(`[SitemapManager]: Failed to write file sitemap.xsl: ${e.message}`)); | ||
} | ||
resolve(); | ||
}); | ||
} | ||
} | ||
exports.SitemapManager = SitemapManager; | ||
_SitemapManager_urlDatas = new WeakMap(); | ||
exports.types = exports.SitemapManager = void 0; | ||
const main_1 = require("./main"); | ||
Object.defineProperty(exports, "SitemapManager", { enumerable: true, get: function () { return main_1.SitemapManager; } }); | ||
const types = __importStar(require("./types")); | ||
exports.types = types; |
{ | ||
"name": "sitemap-manager", | ||
"version": "2.1.0", | ||
"version": "2.2.0", | ||
"description": "An easy way to create sitemaps!", | ||
"main": "dist/index.js", | ||
"scripts": { | ||
"build": "tsc", | ||
"build": "rm -rf dist && tsc", | ||
"prepare": "npm run build", | ||
@@ -27,8 +27,5 @@ "pretest": "npm run build", | ||
"homepage": "https://github.com/CBW2007/sitemap-manager#readme", | ||
"dependencies": { | ||
"xml": "^1.0.1" | ||
}, | ||
"devDependencies": { | ||
"@tsconfig/node12": "^1.0.9", | ||
"@types/xml": "^1.0.5", | ||
"@types/node": "^16.9.1", | ||
"@typescript-eslint/eslint-plugin": "^4.28.5", | ||
@@ -35,0 +32,0 @@ "@typescript-eslint/parser": "^4.28.5", |
@@ -19,3 +19,3 @@ # sitemap-manager | ||
// For yarn users | ||
yarn add sitemap manager | ||
yarn add sitemap-manager | ||
``` | ||
@@ -22,0 +22,0 @@ |
const { SitemapManager } = require('../dist/index') | ||
const fs = require('fs') | ||
if (fs.existsSync('./public')) { fs.rmdirSync('./public', { recursive: true }) } | ||
if (fs.existsSync('./public')) { fs.rmSync('./public', { recursive: true }) } | ||
fs.mkdirSync('./public') | ||
@@ -9,3 +9,10 @@ | ||
siteURL: 'https://example.com/', | ||
pathPrefix: 'aaa' | ||
pathPrefix: 'aaa', | ||
hooks: { | ||
// warningHandler: (msg) => { console.log('#' + msg) }, | ||
/* fileHandler: (file, data) => { | ||
console.log(`===${file}===`) | ||
console.log(data) | ||
} */ | ||
} | ||
}) | ||
@@ -21,5 +28,6 @@ | ||
{ loc: 'https://example.com/aaa/b/a', changefreq: 4 }, | ||
{ loc: 'https://example.com/aaa/b/c', changefreq: 7 }, | ||
{ loc: 'https://example.com/aaa/b/c', changefreq: 'daily' } | ||
// { loc: 'https://example.com/aaa/b/c', changefreq: 'what' } // wrong case | ||
{ loc: 'https://example.com/aaa/b/b', changefreq: 7 }/*, | ||
{ loc: 'https://example.com/aaa/b/c', changefreq: 'daily' }, | ||
{ loc: 'https://example.com/aaa/b/d', changefreq: 114514 }, // wrong case, | ||
{ loc: 'https://example.com/aaa/b/e', changefreq: 'what' } // wrong case */ | ||
]) | ||
@@ -29,21 +37,21 @@ | ||
{ loc: 'https://example.com/aaa/c/a', priority: 0.3 }, | ||
{ loc: 'https://example.com/aaa/c/c', priority: 0.5 } | ||
// { loc: 'https://example.com/aaa/c/c', priority: 2 }, // wrong case | ||
// { loc: 'https://example.com/aaa/c/c', priority: -1 } // wrong case | ||
{ loc: 'https://example.com/aaa/c/b', priority: 0.5 }/*, | ||
{ loc: 'https://example.com/aaa/c/c', priority: 2 }, // wrong case | ||
{ loc: 'https://example.com/aaa/c/d', priority: -1 } // wrong case */ | ||
]) | ||
MySitemap.addUrl('mix', [{ | ||
MySitemap.addUrl('mix', { | ||
loc: 'https://example.com/aaa/d/a' | ||
}]) | ||
MySitemap.addUrl('mix', [{ | ||
}) | ||
MySitemap.addUrl('mix', { | ||
loc: 'https://example.com/aaa/d/b', | ||
changefreq: 3, | ||
lastmod: new Date() | ||
}]) | ||
MySitemap.addUrl('mix', [{ | ||
}) | ||
MySitemap.addUrl('mix', { | ||
loc: 'https://example.com/aaa/d/c', | ||
priority: 0.1, | ||
lastmod: new Date('1949-10-01T08:00:00') | ||
}]) | ||
MySitemap.addUrl('mix', [{ | ||
}) | ||
MySitemap.addUrl('mix', { | ||
loc: 'https://example.com/aaa/d/d', | ||
@@ -53,4 +61,10 @@ changefreq: 'always', | ||
priority: 0.9 | ||
}]) | ||
}) | ||
/* MySitemap.addUrl('mix', { // repeat case | ||
loc: 'https://example.com/aaa/d/d', | ||
changefreq: 'always', | ||
lastmod: '2007-03-13T08:00:00', | ||
priority: 0.9 | ||
}) */ | ||
MySitemap.finish() |
107
src/index.ts
@@ -1,105 +0,4 @@ | ||
import fs from 'fs' | ||
import xml from 'xml' | ||
import { URL } from 'url' | ||
import path from 'path' | ||
import { SitemapManager } from './main' | ||
import * as types from './types' | ||
const xmlStylesheet = Buffer.from('PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjx4c2w6c3R5bGVzaGVldCB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIgeG1sbnM6c2l0ZW1hcD0iaHR0cDovL3d3dy5zaXRlbWFwcy5vcmcvc2NoZW1hcy9zaXRlbWFwLzAuOSIgeG1sbnM6Zm49Imh0dHA6Ly93d3cudzMub3JnLzIwMDUvMDIveHBhdGgtZnVuY3Rpb25zIiB2ZXJzaW9uPSIxLjAiPjx4c2w6dGVtcGxhdGUgbWF0Y2g9Ii8iPjxodG1sPjxoZWFkPjx0aXRsZT5TaXRlbWFwPC90aXRsZT48bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEsIG1heGltdW0tc2NhbGU9MSwgc2hyaW5rLXRvLWZpdD1ubyIvPjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+DQoJCSAJCS5hLW5vLXVsOjpiZWZvcmUgew0KCQkgCQkJZGlzcGxheTogbm9uZTsNCgkJIAkJfQ0KCQkJPC9zdHlsZT48IS0tIE1EVUkgQ1NTIC0tPjxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0L25wbS9tZHVpQDEuMC4xL2Rpc3QvY3NzL21kdWkubWluLmNzcyIgaW50ZWdyaXR5PSJzaGEzODQtY0xSck1xMzlIT1pkdkUwajZ5Qm9qTzQrMVBySGZCN2E5bDVxTGNtUm0vZmlXWFlZK0NuZEpQbXl1NUZWLzlUdyIgY3Jvc3NvcmlnaW49ImFub255bW91cyIvPjwvaGVhZD48Ym9keT48ZGl2IGNsYXNzPSJtZHVpLWNvbnRhaW5lciBtZHVpLXR5cG8iPjxoMSBzdHlsZT0idGV4dC1hbGlnbjpjZW50ZXIiPlNpdGVtYXA8L2gxPjxkaXYgY2xhc3M9Im1kdWktZGl2aWRlciIvPjx4c2w6aWYgdGVzdD0iY291bnQoc2l0ZW1hcDpzaXRlbWFwaW5kZXgvc2l0ZW1hcDpzaXRlbWFwKSAmbHQ7IDEiPjxhIGhyZWY9InNpdGVtYXAueG1sIiBjbGFzcz0ibWR1aS1idG4gYS1uby11bCI+PGkgY2xhc3M9Im1kdWktaWNvbiBtYXRlcmlhbC1pY29ucyI+7oybPC9pPmJhY2sgdG8gaW5kZXg8L2E+PC94c2w6aWY+PHhzbDppZiB0ZXN0PSJjb3VudChzaXRlbWFwOnNpdGVtYXBpbmRleC9zaXRlbWFwOnNpdGVtYXApICZsdDsgMSI+PHRhYmxlIGNsYXNzPSJtZHVpLXRhYmxlIj48dGhlYWQ+PHRyPjx0aCBzdHlsZT0id2lkdGg6NzAlIj5VUkw8L3RoPjx0aCBzdHlsZT0id2lkdGg6MjAlIj5MYXN0IG1vZGlmaWNhdGlvbiB0aW1lPC90aD48dGggc3R5bGU9IndpZHRoOjUlIj5DaGFuZ2UgZnJlcXVlbmNlPC90aD48dGggc3R5bGU9IndpZHRoOjUlIj5Qcmlvcml0eTwvdGg+PC90cj48L3RoZWFkPjx0Ym9keT48eHNsOmZvci1lYWNoIHNlbGVjdD0ic2l0ZW1hcDp1cmxzZXQvc2l0ZW1hcDp1cmwiPjx0cj48dGQ+PHhzbDp2YXJpYWJsZSBuYW1lPSJsb2NVcmwiPjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJzaXRlbWFwOmxvYyIvPjwveHNsOnZhcmlhYmxlPjxhIGhyZWY9InskbG9jVXJsfSI+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9InNpdGVtYXA6bG9jIi8+PC9hPjwvdGQ+PHRkPjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJzaXRlbWFwOmxhc3Rtb2QiLz48L3RkPjx0ZD48eHNsOnZhbHVlLW9mIHNlbGVjdD0ic2l0ZW1hcDpjaGFuZ2VmcmVxIi8+PC90ZD48dGQ+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9InNpdGVtYXA6cHJpb3JpdHkiLz48L3RkPjwvdHI+PC94c2w6Zm9yLWVhY2g+PC90Ym9keT48L3RhYmxlPjwveHNsOmlmPjx4c2w6aWYgdGVzdD0iY291bnQoc2l0ZW1hcDpzaXRlbWFwaW5kZXgvc2l0ZW1hcDpzaXRlbWFwKSAmZ3Q7IDAiPjx0YWJsZSBjbGFzcz0ibWR1aS10YWJsZSI+PHRoZWFkPjx0cj48dGggc3R5bGU9IndpZHRoOjgwJSI+VVJMPC90aD48dGggc3R5bGU9IndpZHRoOjIwJSI+TGFzdCBtb2RpZmljYXRpb24gdGltZTwvdGg+PC90cj48L3RoZWFkPjx0Ym9keT48eHNsOmZvci1lYWNoIHNlbGVjdD0ic2l0ZW1hcDpzaXRlbWFwaW5kZXgvc2l0ZW1hcDpzaXRlbWFwIj48dHI+PHRkPjx4c2w6dmFyaWFibGUgbmFtZT0ibG9jVXJsIj48eHNsOnZhbHVlLW9mIHNlbGVjdD0ic2l0ZW1hcDpsb2MiLz48L3hzbDp2YXJpYWJsZT48YSBocmVmPSJ7JGxvY1VybH0iPjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJzaXRlbWFwOmxvYyIvPjwvYT48L3RkPjx0ZD48eHNsOnZhbHVlLW9mIHNlbGVjdD0ic2l0ZW1hcDpsYXN0bW9kIi8+PC90ZD48L3RyPjwveHNsOmZvci1lYWNoPjwvdGJvZHk+PC90YWJsZT48L3hzbDppZj48L2Rpdj48IS0tIE1EVUkgSmF2YVNjcmlwdCAtLT48c2NyaXB0IHNyYz0iaHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0L25wbS9tZHVpQDEuMC4xL2Rpc3QvanMvbWR1aS5taW4uanMiIGludGVncml0eT0ic2hhMzg0LWdDTVpjc2hZS09HUlg5cjZ3YkRydkYrVGNDQ3N3U0hGdWNVelVQd2thK0dyK3VIZ2psWXZrQUJyOTVUQ096M0EiIGNyb3Nzb3JpZ2luPSJhbm9ueW1vdXMiLz48L2JvZHk+PC9odG1sPjwveHNsOnRlbXBsYXRlPjwveHNsOnN0eWxlc2hlZXQ+DQo=', 'base64').toString() | ||
const xmlDeclaration = '<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/xsl" href="sitemap.xsl"?>' | ||
// src: src/sitemap.xsl | ||
interface Option { | ||
outDir?: string, | ||
siteURL: string, | ||
pathPrefix?: string | ||
} | ||
interface Url { | ||
loc: string, | ||
lastmod?: string | Date, | ||
changefreq?: 'never' | 'yearly' | 'monthly' | 'weekly' | 'daily' | 'hourly' | 'always' | 1 | 2 | 3 | 4 | 5 | 6 | 7, | ||
priority?: number | ||
} | ||
const freqMap = ['', 'never', 'yearly', 'monthly', 'weekly', 'daily', 'hourly', 'always'] | ||
function dateConverter (date: Date | string): string { | ||
return new Date(date).toISOString() | ||
} | ||
class SitemapManager { | ||
options: Option | ||
#urlDatas: Map<string, Array<Url>> = new Map() | ||
isFinished: Boolean = false | ||
constructor (options: Option) { | ||
this.options = options | ||
} | ||
addUrl (name: string, url: Array<Url>): void { | ||
if (this.isFinished) { throw new Error('[SitemapManager] Error: Lifecycle finished') } | ||
this.#urlDatas.set(name, [...(this.#urlDatas.get(name) || []), ...url]) | ||
} | ||
finish (): Promise<void> { | ||
return new Promise((resolve, reject) => { | ||
if (this.isFinished) { reject(new Error('[SitemapManager] Error: Lifecycle finished')) } | ||
// Create index sitemap | ||
let xmlContents:Array<any> = [] | ||
this.#urlDatas.forEach((v, k) => { | ||
xmlContents.push({ | ||
sitemap: [ | ||
{ loc: new URL(path.join(this.options.pathPrefix || '', `sitemap-${k}.xml`), this.options.siteURL).toString() }, | ||
{ lastmod: dateConverter(new Date()) } | ||
] | ||
}) | ||
}) | ||
try { | ||
fs.writeFileSync(path.resolve(this.options?.outDir || './public', 'sitemap.xml'), | ||
xmlDeclaration + xml({ sitemapindex: [{ _attr: { xmlns: 'http://www.sitemaps.org/schemas/sitemap/0.9' } }, ...xmlContents] })) | ||
} catch (e) { | ||
reject(new Error(`[SitemapManager] Failed to write file sitemap.xml: ${e.message}`)) | ||
} | ||
// Create each sitemap | ||
this.#urlDatas.forEach((value, key) => { | ||
xmlContents = [] | ||
value.forEach((node) => { | ||
const ele:Array<any> = [{ loc: node.loc }] | ||
if (node.lastmod) ele.push({ lastmod: dateConverter(node.lastmod) }) | ||
if (node.changefreq && | ||
((typeof (node.changefreq) === 'number' && node.changefreq >= 1 && node.changefreq <= 7) || | ||
(typeof (node.changefreq) === 'string' && freqMap.includes(node.changefreq)))) { | ||
ele.push({ changefreq: typeof (node.changefreq) === 'string' ? node.changefreq : freqMap[node.changefreq] }) | ||
} else if (node.changefreq) { | ||
reject(new Error(`[SitemapManager] Invalid changefreq value: Expects a number ranges from 1 to 7(1 for the least, 7 for the most) or a string. See more: https://www.sitemaps.org/protocol.html#xmlTagDefinitions. Received ${node.changefreq}`)) | ||
} | ||
if (node.priority && node.priority >= 0 && node.priority <= 1) { | ||
ele.push({ priority: node.priority }) | ||
} else if (node.priority) { | ||
reject(new Error(`[SitemapManager] Invalid priority value: Expects a number ranges from 0.0 to 1.0. Received ${node.priority}`)) | ||
} | ||
xmlContents.push({ | ||
url: ele | ||
}) | ||
}) | ||
try { | ||
fs.writeFileSync(path.resolve(this.options?.outDir || './public', `sitemap-${key}.xml`), | ||
xmlDeclaration + xml({ urlset: [{ _attr: { xmlns: 'http://www.sitemaps.org/schemas/sitemap/0.9' } }, ...xmlContents] })) | ||
} catch (e) { | ||
reject(new Error(`[SitemapManager] Failed to write file sitemap-${key}.xml: ${e.message}`)) | ||
} | ||
}) | ||
// Create sitemap stylesheet | ||
try { | ||
fs.writeFileSync(path.resolve(this.options?.outDir || './public', 'sitemap.xsl'), xmlStylesheet) | ||
} catch (e) { | ||
reject(new Error(`[SitemapManager]: Failed to write file sitemap.xsl: ${e.message}`)) | ||
} | ||
resolve() | ||
}) | ||
} | ||
} | ||
export { SitemapManager } | ||
export { SitemapManager, types } |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
36887
0
21
521
1
- Removedxml@^1.0.1
- Removedxml@1.0.1(transitive)