@nuxtjs/sitemap 7.2.10 → 7.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/200.html +9 -9
- package/dist/client/404.html +9 -9
- package/dist/client/_nuxt/Cp-IABpG.js +1 -0
- package/dist/client/_nuxt/{DDzCRRw4.js → DJVkgDQ2.js} +1 -1
- package/dist/client/_nuxt/SmY-NWqO.js +172 -0
- package/dist/client/_nuxt/builds/latest.json +1 -1
- package/dist/client/_nuxt/builds/meta/e48bfd5b-6605-4bbc-a466-32a664787616.json +1 -0
- package/dist/client/_nuxt/error-404.CtcyoHAN.css +1 -0
- package/dist/client/_nuxt/error-500.BIlfyoPk.css +1 -0
- package/dist/client/_nuxt/{DdvkoY3I.js → lL_X76lO.js} +1 -1
- package/dist/client/index.html +9 -9
- package/dist/module.cjs +57 -18
- package/dist/module.json +2 -2
- package/dist/module.mjs +58 -19
- package/dist/runtime/server/plugins/warm-up.js +20 -4
- package/dist/runtime/server/routes/__sitemap__/debug.js +2 -2
- package/dist/runtime/server/routes/sitemap/[sitemap].xml.js +37 -7
- package/dist/runtime/server/routes/sitemap_index.xml.js +11 -3
- package/dist/runtime/server/sitemap/builder/sitemap-index.d.ts +1 -1
- package/dist/runtime/server/sitemap/builder/sitemap-index.js +110 -16
- package/dist/runtime/server/sitemap/builder/sitemap.d.ts +1 -1
- package/dist/runtime/server/sitemap/builder/sitemap.js +62 -36
- package/dist/runtime/server/sitemap/builder/xml.d.ts +2 -3
- package/dist/runtime/server/sitemap/builder/xml.js +182 -80
- package/dist/runtime/server/sitemap/nitro.js +68 -20
- package/dist/runtime/server/sitemap/urlset/normalise.js +21 -19
- package/dist/runtime/server/sitemap/urlset/sort.d.ts +1 -1
- package/dist/runtime/server/sitemap/urlset/sort.js +9 -15
- package/dist/runtime/server/sitemap/utils/chunk.d.ts +10 -0
- package/dist/runtime/server/sitemap/utils/chunk.js +66 -0
- package/dist/runtime/types.d.ts +44 -0
- package/dist/runtime/utils-pure.js +13 -5
- package/package.json +23 -22
- package/dist/client/_nuxt/BLmTiKMJ.js +0 -1
- package/dist/client/_nuxt/BUP090M8.js +0 -172
- package/dist/client/_nuxt/builds/meta/3c351607-eab3-459a-b743-aba04e49a80e.json +0 -1
- package/dist/client/_nuxt/error-404.BMkETmdU.css +0 -1
- package/dist/client/_nuxt/error-500.C3_I-O7u.css +0 -1
- /package/dist/client/_nuxt/{entry.BrROiVtQ.css → entry.CgW0_noo.css} +0 -0
|
@@ -1,11 +1,33 @@
|
|
|
1
1
|
import { defu } from "defu";
|
|
2
2
|
import { joinURL } from "ufo";
|
|
3
|
+
import { defineCachedFunction } from "nitropack/runtime";
|
|
4
|
+
import { getHeader } from "h3";
|
|
3
5
|
import { normaliseDate } from "../urlset/normalise.js";
|
|
4
|
-
import { globalSitemapSources, resolveSitemapSources } from "../urlset/sources.js";
|
|
5
|
-
import {
|
|
6
|
-
import { escapeValueForXml
|
|
6
|
+
import { globalSitemapSources, childSitemapSources, resolveSitemapSources } from "../urlset/sources.js";
|
|
7
|
+
import { sortInPlace } from "../urlset/sort.js";
|
|
8
|
+
import { escapeValueForXml } from "./xml.js";
|
|
7
9
|
import { resolveSitemapEntries } from "./sitemap.js";
|
|
8
|
-
|
|
10
|
+
const buildSitemapIndexCached = defineCachedFunction(
|
|
11
|
+
async (event, resolvers, runtimeConfig, nitro) => {
|
|
12
|
+
return buildSitemapIndexInternal(resolvers, runtimeConfig, nitro);
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
name: "sitemap:index",
|
|
16
|
+
group: "sitemap",
|
|
17
|
+
maxAge: 60 * 10,
|
|
18
|
+
// 10 minutes default
|
|
19
|
+
base: "sitemap",
|
|
20
|
+
// Use the sitemap storage
|
|
21
|
+
getKey: (event) => {
|
|
22
|
+
const host = getHeader(event, "host") || getHeader(event, "x-forwarded-host") || "";
|
|
23
|
+
const proto = getHeader(event, "x-forwarded-proto") || "https";
|
|
24
|
+
return `sitemap-index-${proto}-${host}`;
|
|
25
|
+
},
|
|
26
|
+
swr: true
|
|
27
|
+
// Enable stale-while-revalidate
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
async function buildSitemapIndexInternal(resolvers, runtimeConfig, nitro) {
|
|
9
31
|
const {
|
|
10
32
|
sitemaps,
|
|
11
33
|
// enhancing
|
|
@@ -20,13 +42,32 @@ export async function buildSitemapIndex(resolvers, runtimeConfig, nitro) {
|
|
|
20
42
|
if (!sitemaps)
|
|
21
43
|
throw new Error("Attempting to build a sitemap index without required `sitemaps` configuration.");
|
|
22
44
|
function maybeSort(urls) {
|
|
23
|
-
return sortEntries ?
|
|
45
|
+
return sortEntries ? sortInPlace(urls) : urls;
|
|
24
46
|
}
|
|
25
|
-
const isChunking = typeof sitemaps.chunks !== "undefined";
|
|
26
47
|
const chunks = {};
|
|
27
|
-
|
|
48
|
+
for (const sitemapName in sitemaps) {
|
|
49
|
+
if (sitemapName === "index" || sitemapName === "chunks") continue;
|
|
50
|
+
const sitemapConfig = sitemaps[sitemapName];
|
|
51
|
+
if (sitemapConfig.chunks || sitemapConfig._isChunking) {
|
|
52
|
+
sitemapConfig._isChunking = true;
|
|
53
|
+
sitemapConfig._chunkSize = typeof sitemapConfig.chunks === "number" ? sitemapConfig.chunks : sitemapConfig.chunkSize || defaultSitemapsChunkSize || 1e3;
|
|
54
|
+
} else {
|
|
55
|
+
chunks[sitemapName] = chunks[sitemapName] || { urls: [] };
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (typeof sitemaps.chunks !== "undefined") {
|
|
28
59
|
const sitemap = sitemaps.chunks;
|
|
29
|
-
|
|
60
|
+
let sourcesInput = await globalSitemapSources();
|
|
61
|
+
if (nitro && resolvers.event) {
|
|
62
|
+
const ctx = {
|
|
63
|
+
event: resolvers.event,
|
|
64
|
+
sitemapName: sitemap.sitemapName,
|
|
65
|
+
sources: sourcesInput
|
|
66
|
+
};
|
|
67
|
+
await nitro.hooks.callHook("sitemap:sources", ctx);
|
|
68
|
+
sourcesInput = ctx.sources;
|
|
69
|
+
}
|
|
70
|
+
const sources = await resolveSitemapSources(sourcesInput, resolvers.event);
|
|
30
71
|
const resolvedCtx = {
|
|
31
72
|
urls: sources.flatMap((s) => s.urls),
|
|
32
73
|
sitemapName: sitemap.sitemapName,
|
|
@@ -41,12 +82,6 @@ export async function buildSitemapIndex(resolvers, runtimeConfig, nitro) {
|
|
|
41
82
|
chunks[chunkIndex] = chunks[chunkIndex] || { urls: [] };
|
|
42
83
|
chunks[chunkIndex].urls.push(url);
|
|
43
84
|
});
|
|
44
|
-
} else {
|
|
45
|
-
for (const sitemap in sitemaps) {
|
|
46
|
-
if (sitemap !== "index") {
|
|
47
|
-
chunks[sitemap] = chunks[sitemap] || { urls: [] };
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
85
|
}
|
|
51
86
|
const entries = [];
|
|
52
87
|
for (const name in chunks) {
|
|
@@ -62,6 +97,48 @@ export async function buildSitemapIndex(resolvers, runtimeConfig, nitro) {
|
|
|
62
97
|
entry.lastmod = normaliseDate(lastmod);
|
|
63
98
|
entries.push(entry);
|
|
64
99
|
}
|
|
100
|
+
for (const sitemapName in sitemaps) {
|
|
101
|
+
if (sitemapName !== "index" && sitemaps[sitemapName]._isChunking) {
|
|
102
|
+
const sitemapConfig = sitemaps[sitemapName];
|
|
103
|
+
const chunkSize = sitemapConfig._chunkSize || defaultSitemapsChunkSize || 1e3;
|
|
104
|
+
let sourcesInput = sitemapConfig.includeAppSources ? await globalSitemapSources() : [];
|
|
105
|
+
sourcesInput.push(...await childSitemapSources(sitemapConfig));
|
|
106
|
+
if (nitro && resolvers.event) {
|
|
107
|
+
const ctx = {
|
|
108
|
+
event: resolvers.event,
|
|
109
|
+
sitemapName: sitemapConfig.sitemapName,
|
|
110
|
+
sources: sourcesInput
|
|
111
|
+
};
|
|
112
|
+
await nitro.hooks.callHook("sitemap:sources", ctx);
|
|
113
|
+
sourcesInput = ctx.sources;
|
|
114
|
+
}
|
|
115
|
+
const sources = await resolveSitemapSources(sourcesInput, resolvers.event);
|
|
116
|
+
const resolvedCtx = {
|
|
117
|
+
urls: sources.flatMap((s) => s.urls),
|
|
118
|
+
sitemapName: sitemapConfig.sitemapName,
|
|
119
|
+
event: resolvers.event
|
|
120
|
+
};
|
|
121
|
+
await nitro?.hooks.callHook("sitemap:input", resolvedCtx);
|
|
122
|
+
const normalisedUrls = resolveSitemapEntries(sitemapConfig, resolvedCtx.urls, { autoI18n, isI18nMapped }, resolvers);
|
|
123
|
+
const totalUrls = normalisedUrls.length;
|
|
124
|
+
const chunkCount = Math.ceil(totalUrls / chunkSize);
|
|
125
|
+
sitemapConfig._chunkCount = chunkCount;
|
|
126
|
+
for (let i = 0; i < chunkCount; i++) {
|
|
127
|
+
const chunkName = `${sitemapName}-${i}`;
|
|
128
|
+
const entry = {
|
|
129
|
+
_sitemapName: chunkName,
|
|
130
|
+
sitemap: resolvers.canonicalUrlResolver(joinURL(sitemapsPathPrefix || "", `/${chunkName}.xml`))
|
|
131
|
+
};
|
|
132
|
+
const chunkUrls = normalisedUrls.slice(i * chunkSize, (i + 1) * chunkSize);
|
|
133
|
+
let lastmod = chunkUrls.filter((a) => !!a?.lastmod).map((a) => typeof a.lastmod === "string" ? new Date(a.lastmod) : a.lastmod).sort((a, b) => (b?.getTime() || 0) - (a?.getTime() || 0))?.[0];
|
|
134
|
+
if (!lastmod && autoLastmod)
|
|
135
|
+
lastmod = /* @__PURE__ */ new Date();
|
|
136
|
+
if (lastmod)
|
|
137
|
+
entry.lastmod = normaliseDate(lastmod);
|
|
138
|
+
entries.push(entry);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
65
142
|
if (sitemaps.index) {
|
|
66
143
|
entries.push(...sitemaps.index.sitemaps.map((entry) => {
|
|
67
144
|
return typeof entry === "string" ? { sitemap: entry } : entry;
|
|
@@ -77,9 +154,26 @@ export function urlsToIndexXml(sitemaps, resolvers, { version, xsl, credits, min
|
|
|
77
154
|
e.lastmod ? ` <lastmod>${escapeValueForXml(e.lastmod)}</lastmod>` : false,
|
|
78
155
|
" </sitemap>"
|
|
79
156
|
].filter(Boolean).join("\n")).join("\n");
|
|
80
|
-
|
|
157
|
+
const xmlParts = [
|
|
158
|
+
'<?xml version="1.0" encoding="UTF-8"?>'
|
|
159
|
+
];
|
|
160
|
+
if (xsl) {
|
|
161
|
+
const relativeBaseUrl = resolvers.relativeBaseUrlResolver?.(xsl) ?? xsl;
|
|
162
|
+
xmlParts.push(`<?xml-stylesheet type="text/xsl" href="${escapeValueForXml(relativeBaseUrl)}"?>`);
|
|
163
|
+
}
|
|
164
|
+
xmlParts.push(
|
|
81
165
|
'<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',
|
|
82
166
|
sitemapXml,
|
|
83
167
|
"</sitemapindex>"
|
|
84
|
-
|
|
168
|
+
);
|
|
169
|
+
if (credits) {
|
|
170
|
+
xmlParts.push(`<!-- XML Sitemap Index generated by @nuxtjs/sitemap v${version} at ${(/* @__PURE__ */ new Date()).toISOString()} -->`);
|
|
171
|
+
}
|
|
172
|
+
return minify ? xmlParts.join("").replace(/(?<!<[^>]*)\s(?![^<]*>)/g, "") : xmlParts.join("\n");
|
|
173
|
+
}
|
|
174
|
+
export async function buildSitemapIndex(resolvers, runtimeConfig, nitro) {
|
|
175
|
+
if (!import.meta.dev && !!runtimeConfig.cacheMaxAgeSeconds && runtimeConfig.cacheMaxAgeSeconds > 0 && resolvers.event) {
|
|
176
|
+
return buildSitemapIndexCached(resolvers.event, resolvers, runtimeConfig, nitro);
|
|
177
|
+
}
|
|
178
|
+
return buildSitemapIndexInternal(resolvers, runtimeConfig, nitro);
|
|
85
179
|
}
|
|
@@ -7,4 +7,4 @@ export interface NormalizedI18n extends ResolvedSitemapUrl {
|
|
|
7
7
|
}
|
|
8
8
|
export declare function resolveSitemapEntries(sitemap: SitemapDefinition, urls: SitemapUrlInput[], runtimeConfig: Pick<ModuleRuntimeConfig, 'autoI18n' | 'isI18nMapped'>, resolvers?: NitroUrlResolvers): ResolvedSitemapUrl[];
|
|
9
9
|
export declare function buildSitemapUrls(sitemap: SitemapDefinition, resolvers: NitroUrlResolvers, runtimeConfig: ModuleRuntimeConfig, nitro?: NitroApp): Promise<ResolvedSitemapUrl[]>;
|
|
10
|
-
export
|
|
10
|
+
export { urlsToXml } from './xml.js';
|
|
@@ -2,9 +2,9 @@ import { resolveSitePath } from "nuxt-site-config/urls";
|
|
|
2
2
|
import { joinURL, withHttps } from "ufo";
|
|
3
3
|
import { preNormalizeEntry } from "../urlset/normalise.js";
|
|
4
4
|
import { childSitemapSources, globalSitemapSources, resolveSitemapSources } from "../urlset/sources.js";
|
|
5
|
-
import {
|
|
5
|
+
import { sortInPlace } from "../urlset/sort.js";
|
|
6
6
|
import { createPathFilter, logger, splitForLocales } from "../../../utils-pure.js";
|
|
7
|
-
import {
|
|
7
|
+
import { parseChunkInfo, sliceUrlsForChunk } from "../utils/chunk.js";
|
|
8
8
|
export function resolveSitemapEntries(sitemap, urls, runtimeConfig, resolvers) {
|
|
9
9
|
const {
|
|
10
10
|
autoI18n,
|
|
@@ -85,9 +85,23 @@ export function resolveSitemapEntries(sitemap, urls, runtimeConfig, resolvers) {
|
|
|
85
85
|
});
|
|
86
86
|
} else {
|
|
87
87
|
for (const l of autoI18n.locales) {
|
|
88
|
-
let loc =
|
|
89
|
-
if (autoI18n.
|
|
90
|
-
|
|
88
|
+
let loc = e._pathWithoutPrefix;
|
|
89
|
+
if (autoI18n.pages) {
|
|
90
|
+
const pageKey = e._pathWithoutPrefix.replace(/^\//, "").replace(/\/index$/, "") || "index";
|
|
91
|
+
const pageMappings = autoI18n.pages[pageKey];
|
|
92
|
+
if (pageMappings && pageMappings[l.code] !== void 0) {
|
|
93
|
+
const customPath = pageMappings[l.code];
|
|
94
|
+
if (customPath === false)
|
|
95
|
+
continue;
|
|
96
|
+
if (typeof customPath === "string")
|
|
97
|
+
loc = customPath.startsWith("/") ? customPath : `/${customPath}`;
|
|
98
|
+
} else if (!autoI18n.differentDomains && !(["prefix_and_default", "prefix_except_default"].includes(autoI18n.strategy) && l.code === autoI18n.defaultLocale)) {
|
|
99
|
+
loc = joinURL(`/${l.code}`, e._pathWithoutPrefix);
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
if (!autoI18n.differentDomains && !(["prefix_and_default", "prefix_except_default"].includes(autoI18n.strategy) && l.code === autoI18n.defaultLocale))
|
|
103
|
+
loc = joinURL(`/${l.code}`, e._pathWithoutPrefix);
|
|
104
|
+
}
|
|
91
105
|
const _sitemap = isI18nMapped ? l._sitemap : void 0;
|
|
92
106
|
const newEntry = preNormalizeEntry({
|
|
93
107
|
_sitemap,
|
|
@@ -99,14 +113,30 @@ export function resolveSitemapEntries(sitemap, urls, runtimeConfig, resolvers) {
|
|
|
99
113
|
alternatives: [{ code: "x-default", _hreflang: "x-default" }, ...autoI18n.locales].map((locale) => {
|
|
100
114
|
const code = locale.code === "x-default" ? autoI18n.defaultLocale : locale.code;
|
|
101
115
|
const isDefault = locale.code === "x-default" || locale.code === autoI18n.defaultLocale;
|
|
102
|
-
let href =
|
|
103
|
-
if (autoI18n.
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
if (
|
|
107
|
-
|
|
108
|
-
|
|
116
|
+
let href = e._pathWithoutPrefix;
|
|
117
|
+
if (autoI18n.pages) {
|
|
118
|
+
const pageKey = e._pathWithoutPrefix.replace(/^\//, "").replace(/\/index$/, "") || "index";
|
|
119
|
+
const pageMappings = autoI18n.pages[pageKey];
|
|
120
|
+
if (pageMappings && pageMappings[code] !== void 0) {
|
|
121
|
+
const customPath = pageMappings[code];
|
|
122
|
+
if (customPath === false)
|
|
123
|
+
return false;
|
|
124
|
+
if (typeof customPath === "string")
|
|
125
|
+
href = customPath.startsWith("/") ? customPath : `/${customPath}`;
|
|
126
|
+
} else if (autoI18n.strategy === "prefix") {
|
|
109
127
|
href = joinURL("/", code, e._pathWithoutPrefix);
|
|
128
|
+
} else if (["prefix_and_default", "prefix_except_default"].includes(autoI18n.strategy)) {
|
|
129
|
+
if (!isDefault) {
|
|
130
|
+
href = joinURL("/", code, e._pathWithoutPrefix);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
} else {
|
|
134
|
+
if (autoI18n.strategy === "prefix") {
|
|
135
|
+
href = joinURL("/", code, e._pathWithoutPrefix);
|
|
136
|
+
} else if (["prefix_and_default", "prefix_except_default"].includes(autoI18n.strategy)) {
|
|
137
|
+
if (!isDefault) {
|
|
138
|
+
href = joinURL("/", code, e._pathWithoutPrefix);
|
|
139
|
+
}
|
|
110
140
|
}
|
|
111
141
|
}
|
|
112
142
|
if (!filterPath(href))
|
|
@@ -151,16 +181,12 @@ export async function buildSitemapUrls(sitemap, resolvers, runtimeConfig, nitro)
|
|
|
151
181
|
// chunking
|
|
152
182
|
defaultSitemapsChunkSize
|
|
153
183
|
} = runtimeConfig;
|
|
154
|
-
const
|
|
184
|
+
const chunkInfo = parseChunkInfo(sitemap.sitemapName, sitemaps, defaultSitemapsChunkSize);
|
|
155
185
|
function maybeSort(urls) {
|
|
156
|
-
return sortEntries ?
|
|
186
|
+
return sortEntries ? sortInPlace(urls) : urls;
|
|
157
187
|
}
|
|
158
188
|
function maybeSlice(urls) {
|
|
159
|
-
|
|
160
|
-
const chunk = Number(sitemap.sitemapName);
|
|
161
|
-
return urls.slice(chunk * defaultSitemapsChunkSize, (chunk + 1) * defaultSitemapsChunkSize);
|
|
162
|
-
}
|
|
163
|
-
return urls;
|
|
189
|
+
return sliceUrlsForChunk(urls, sitemap.sitemapName, sitemaps, defaultSitemapsChunkSize);
|
|
164
190
|
}
|
|
165
191
|
if (autoI18n?.differentDomains) {
|
|
166
192
|
const domain = autoI18n.locales.find((e) => [e.language, e.code].includes(sitemap.sitemapName))?.domain;
|
|
@@ -175,8 +201,22 @@ export async function buildSitemapUrls(sitemap, resolvers, runtimeConfig, nitro)
|
|
|
175
201
|
});
|
|
176
202
|
}
|
|
177
203
|
}
|
|
178
|
-
|
|
179
|
-
|
|
204
|
+
let effectiveSitemap = sitemap;
|
|
205
|
+
const baseSitemapName = chunkInfo.baseSitemapName;
|
|
206
|
+
if (chunkInfo.isChunked && baseSitemapName !== sitemap.sitemapName && sitemaps[baseSitemapName]) {
|
|
207
|
+
effectiveSitemap = sitemaps[baseSitemapName];
|
|
208
|
+
}
|
|
209
|
+
let sourcesInput = effectiveSitemap.includeAppSources ? await globalSitemapSources() : [];
|
|
210
|
+
sourcesInput.push(...await childSitemapSources(effectiveSitemap));
|
|
211
|
+
if (nitro && resolvers.event) {
|
|
212
|
+
const ctx = {
|
|
213
|
+
event: resolvers.event,
|
|
214
|
+
sitemapName: baseSitemapName,
|
|
215
|
+
sources: sourcesInput
|
|
216
|
+
};
|
|
217
|
+
await nitro.hooks.callHook("sitemap:sources", ctx);
|
|
218
|
+
sourcesInput = ctx.sources;
|
|
219
|
+
}
|
|
180
220
|
const sources = await resolveSitemapSources(sourcesInput, resolvers.event);
|
|
181
221
|
const resolvedCtx = {
|
|
182
222
|
urls: sources.flatMap((s) => s.urls),
|
|
@@ -193,18 +233,4 @@ export async function buildSitemapUrls(sitemap, resolvers, runtimeConfig, nitro)
|
|
|
193
233
|
const sortedUrls = maybeSort(filteredUrls);
|
|
194
234
|
return maybeSlice(sortedUrls);
|
|
195
235
|
}
|
|
196
|
-
export
|
|
197
|
-
const urlset = urls.map((e) => {
|
|
198
|
-
const keys = Object.keys(e).filter((k) => !k.startsWith("_"));
|
|
199
|
-
return [
|
|
200
|
-
" <url>",
|
|
201
|
-
keys.map((k) => handleEntry(k, e)).filter(Boolean).join("\n"),
|
|
202
|
-
" </url>"
|
|
203
|
-
].join("\n");
|
|
204
|
-
});
|
|
205
|
-
return wrapSitemapXml([
|
|
206
|
-
'<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd http://www.google.com/schemas/sitemap-image/1.1 http://www.google.com/schemas/sitemap-image/1.1/sitemap-image.xsd" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',
|
|
207
|
-
urlset.join("\n"),
|
|
208
|
-
"</urlset>"
|
|
209
|
-
], resolvers, { version, xsl, credits, minify });
|
|
210
|
-
}
|
|
236
|
+
export { urlsToXml } from "./xml.js";
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { ModuleRuntimeConfig, NitroUrlResolvers } from '../../../types.js';
|
|
2
|
-
export declare function handleEntry(k: string, e: Record<string, any> | (string | Record<string, any>)[]): string | false;
|
|
3
|
-
export declare function wrapSitemapXml(input: string[], resolvers: NitroUrlResolvers, options: Pick<ModuleRuntimeConfig, 'version' | 'xsl' | 'credits' | 'minify'>): string;
|
|
1
|
+
import type { ModuleRuntimeConfig, NitroUrlResolvers, ResolvedSitemapUrl } from '../../../types.js';
|
|
4
2
|
export declare function escapeValueForXml(value: boolean | string | number): string;
|
|
3
|
+
export declare function urlsToXml(urls: ResolvedSitemapUrl[], resolvers: NitroUrlResolvers, { version, xsl, credits, minify }: Pick<ModuleRuntimeConfig, 'version' | 'xsl' | 'credits' | 'minify'>): string;
|
|
@@ -1,86 +1,188 @@
|
|
|
1
|
-
function
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
case "videos":
|
|
6
|
-
return "video";
|
|
7
|
-
// news & others?
|
|
8
|
-
case "news":
|
|
9
|
-
return "news";
|
|
10
|
-
default:
|
|
11
|
-
return k;
|
|
12
|
-
}
|
|
1
|
+
export function escapeValueForXml(value) {
|
|
2
|
+
if (value === true || value === false)
|
|
3
|
+
return value ? "yes" : "no";
|
|
4
|
+
return String(value).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
13
5
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
6
|
+
const URLSET_OPENING_TAG = '<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd http://www.google.com/schemas/sitemap-image/1.1 http://www.google.com/schemas/sitemap-image/1.1/sitemap-image.xsd" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
|
|
7
|
+
function buildUrlXml(url) {
|
|
8
|
+
const capacity = 50;
|
|
9
|
+
const parts = Array.from({ length: capacity });
|
|
10
|
+
let partIndex = 0;
|
|
11
|
+
parts[partIndex++] = " <url>";
|
|
12
|
+
if (url.loc) {
|
|
13
|
+
parts[partIndex++] = ` <loc>${escapeValueForXml(url.loc)}</loc>`;
|
|
14
|
+
}
|
|
15
|
+
if (url.lastmod) {
|
|
16
|
+
parts[partIndex++] = ` <lastmod>${url.lastmod}</lastmod>`;
|
|
17
|
+
}
|
|
18
|
+
if (url.changefreq) {
|
|
19
|
+
parts[partIndex++] = ` <changefreq>${url.changefreq}</changefreq>`;
|
|
20
|
+
}
|
|
21
|
+
if (url.priority !== void 0) {
|
|
22
|
+
const priorityValue = Number.parseFloat(String(url.priority));
|
|
23
|
+
const formattedPriority = priorityValue % 1 === 0 ? String(priorityValue) : priorityValue.toFixed(1);
|
|
24
|
+
parts[partIndex++] = ` <priority>${formattedPriority}</priority>`;
|
|
25
|
+
}
|
|
26
|
+
const keys = Object.keys(url).filter((k) => !k.startsWith("_") && !["loc", "lastmod", "changefreq", "priority"].includes(k));
|
|
27
|
+
for (const key of keys) {
|
|
28
|
+
const value = url[key];
|
|
29
|
+
if (value === void 0 || value === null) continue;
|
|
30
|
+
switch (key) {
|
|
31
|
+
case "alternatives":
|
|
32
|
+
if (Array.isArray(value) && value.length > 0) {
|
|
33
|
+
for (const alt of value) {
|
|
34
|
+
const attrs = Object.entries(alt).map(([k, v]) => `${k}="${escapeValueForXml(v)}"`).join(" ");
|
|
35
|
+
parts[partIndex++] = ` <xhtml:link rel="alternate" ${attrs} />`;
|
|
27
36
|
}
|
|
28
|
-
const attributes = Object.entries(v).filter(([ssk]) => ssk !== sk).map(([ssk, ssv]) => `${ssk}="${escapeValueForXml(ssv)}"`).join(" ");
|
|
29
|
-
return [
|
|
30
|
-
` <${key}:${sk} ${attributes}>`,
|
|
31
|
-
// value is the same sk
|
|
32
|
-
v[sk],
|
|
33
|
-
`</${key}:${sk}>`
|
|
34
|
-
].join("");
|
|
35
|
-
}).join("\n");
|
|
36
|
-
}
|
|
37
|
-
if (typeof sv === "object") {
|
|
38
|
-
if (key === "video") {
|
|
39
|
-
const attributes = Object.entries(sv).filter(([ssk]) => ssk !== sk).map(([ssk, ssv]) => `${ssk}="${escapeValueForXml(ssv)}"`).join(" ");
|
|
40
|
-
return [
|
|
41
|
-
` <${key}:${sk} ${attributes}>`,
|
|
42
|
-
// value is the same sk
|
|
43
|
-
sv[sk],
|
|
44
|
-
`</${key}:${sk}>`
|
|
45
|
-
].join("");
|
|
46
37
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
38
|
+
break;
|
|
39
|
+
case "images":
|
|
40
|
+
if (Array.isArray(value) && value.length > 0) {
|
|
41
|
+
for (const img of value) {
|
|
42
|
+
parts[partIndex++] = " <image:image>";
|
|
43
|
+
parts[partIndex++] = ` <image:loc>${escapeValueForXml(img.loc)}</image:loc>`;
|
|
44
|
+
if (img.title) parts[partIndex++] = ` <image:title>${escapeValueForXml(img.title)}</image:title>`;
|
|
45
|
+
if (img.caption) parts[partIndex++] = ` <image:caption>${escapeValueForXml(img.caption)}</image:caption>`;
|
|
46
|
+
if (img.geo_location) parts[partIndex++] = ` <image:geo_location>${escapeValueForXml(img.geo_location)}</image:geo_location>`;
|
|
47
|
+
if (img.license) parts[partIndex++] = ` <image:license>${escapeValueForXml(img.license)}</image:license>`;
|
|
48
|
+
parts[partIndex++] = " </image:image>";
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
break;
|
|
52
|
+
case "videos":
|
|
53
|
+
if (Array.isArray(value) && value.length > 0) {
|
|
54
|
+
for (const video of value) {
|
|
55
|
+
parts[partIndex++] = " <video:video>";
|
|
56
|
+
parts[partIndex++] = ` <video:title>${escapeValueForXml(video.title)}</video:title>`;
|
|
57
|
+
if (video.thumbnail_loc) {
|
|
58
|
+
parts[partIndex++] = ` <video:thumbnail_loc>${escapeValueForXml(video.thumbnail_loc)}</video:thumbnail_loc>`;
|
|
59
|
+
}
|
|
60
|
+
parts[partIndex++] = ` <video:description>${escapeValueForXml(video.description)}</video:description>`;
|
|
61
|
+
if (video.content_loc) {
|
|
62
|
+
parts[partIndex++] = ` <video:content_loc>${escapeValueForXml(video.content_loc)}</video:content_loc>`;
|
|
63
|
+
}
|
|
64
|
+
if (video.player_loc) {
|
|
65
|
+
const attrs = video.player_loc.allow_embed ? ' allow_embed="yes"' : "";
|
|
66
|
+
const autoplay = video.player_loc.autoplay ? ' autoplay="yes"' : "";
|
|
67
|
+
parts[partIndex++] = ` <video:player_loc${attrs}${autoplay}>${escapeValueForXml(video.player_loc)}</video:player_loc>`;
|
|
68
|
+
}
|
|
69
|
+
if (video.duration !== void 0) {
|
|
70
|
+
parts[partIndex++] = ` <video:duration>${video.duration}</video:duration>`;
|
|
71
|
+
}
|
|
72
|
+
if (video.expiration_date) {
|
|
73
|
+
parts[partIndex++] = ` <video:expiration_date>${video.expiration_date}</video:expiration_date>`;
|
|
74
|
+
}
|
|
75
|
+
if (video.rating !== void 0) {
|
|
76
|
+
parts[partIndex++] = ` <video:rating>${video.rating}</video:rating>`;
|
|
77
|
+
}
|
|
78
|
+
if (video.view_count !== void 0) {
|
|
79
|
+
parts[partIndex++] = ` <video:view_count>${video.view_count}</video:view_count>`;
|
|
80
|
+
}
|
|
81
|
+
if (video.publication_date) {
|
|
82
|
+
parts[partIndex++] = ` <video:publication_date>${video.publication_date}</video:publication_date>`;
|
|
83
|
+
}
|
|
84
|
+
if (video.family_friendly !== void 0) {
|
|
85
|
+
parts[partIndex++] = ` <video:family_friendly>${video.family_friendly === "yes" || video.family_friendly === true ? "yes" : "no"}</video:family_friendly>`;
|
|
86
|
+
}
|
|
87
|
+
if (video.restriction) {
|
|
88
|
+
const relationship = video.restriction.relationship || "allow";
|
|
89
|
+
parts[partIndex++] = ` <video:restriction relationship="${relationship}">${escapeValueForXml(video.restriction.restriction)}</video:restriction>`;
|
|
90
|
+
}
|
|
91
|
+
if (video.platform) {
|
|
92
|
+
const relationship = video.platform.relationship || "allow";
|
|
93
|
+
parts[partIndex++] = ` <video:platform relationship="${relationship}">${escapeValueForXml(video.platform.platform)}</video:platform>`;
|
|
94
|
+
}
|
|
95
|
+
if (video.requires_subscription !== void 0) {
|
|
96
|
+
parts[partIndex++] = ` <video:requires_subscription>${video.requires_subscription === "yes" || video.requires_subscription === true ? "yes" : "no"}</video:requires_subscription>`;
|
|
97
|
+
}
|
|
98
|
+
if (video.price) {
|
|
99
|
+
const prices = Array.isArray(video.price) ? video.price : [video.price];
|
|
100
|
+
for (const price of prices) {
|
|
101
|
+
const attrs = [];
|
|
102
|
+
if (price.currency) attrs.push(`currency="${price.currency}"`);
|
|
103
|
+
if (price.type) attrs.push(`type="${price.type}"`);
|
|
104
|
+
const attrsStr = attrs.length > 0 ? " " + attrs.join(" ") : "";
|
|
105
|
+
parts[partIndex++] = ` <video:price${attrsStr}>${escapeValueForXml(price.price)}</video:price>`;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (video.uploader) {
|
|
109
|
+
const info = video.uploader.info ? ` info="${escapeValueForXml(video.uploader.info)}"` : "";
|
|
110
|
+
parts[partIndex++] = ` <video:uploader${info}>${escapeValueForXml(video.uploader.uploader)}</video:uploader>`;
|
|
111
|
+
}
|
|
112
|
+
if (video.live !== void 0) {
|
|
113
|
+
parts[partIndex++] = ` <video:live>${video.live === "yes" || video.live === true ? "yes" : "no"}</video:live>`;
|
|
114
|
+
}
|
|
115
|
+
if (video.tag) {
|
|
116
|
+
const tags = Array.isArray(video.tag) ? video.tag : [video.tag];
|
|
117
|
+
for (const tag of tags) {
|
|
118
|
+
parts[partIndex++] = ` <video:tag>${escapeValueForXml(tag)}</video:tag>`;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (video.category) {
|
|
122
|
+
parts[partIndex++] = ` <video:category>${escapeValueForXml(video.category)}</video:category>`;
|
|
123
|
+
}
|
|
124
|
+
if (video.gallery_loc) {
|
|
125
|
+
const title = video.gallery_loc.title ? ` title="${escapeValueForXml(video.gallery_loc.title)}"` : "";
|
|
126
|
+
parts[partIndex++] = ` <video:gallery_loc${title}>${escapeValueForXml(video.gallery_loc)}</video:gallery_loc>`;
|
|
127
|
+
}
|
|
128
|
+
parts[partIndex++] = " </video:video>";
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
break;
|
|
132
|
+
case "news":
|
|
133
|
+
if (value) {
|
|
134
|
+
parts[partIndex++] = " <news:news>";
|
|
135
|
+
parts[partIndex++] = " <news:publication>";
|
|
136
|
+
parts[partIndex++] = ` <news:name>${escapeValueForXml(value.publication.name)}</news:name>`;
|
|
137
|
+
parts[partIndex++] = ` <news:language>${escapeValueForXml(value.publication.language)}</news:language>`;
|
|
138
|
+
parts[partIndex++] = " </news:publication>";
|
|
139
|
+
if (value.title) {
|
|
140
|
+
parts[partIndex++] = ` <news:title>${escapeValueForXml(value.title)}</news:title>`;
|
|
141
|
+
}
|
|
142
|
+
if (value.publication_date) {
|
|
143
|
+
parts[partIndex++] = ` <news:publication_date>${value.publication_date}</news:publication_date>`;
|
|
144
|
+
}
|
|
145
|
+
if (value.access) {
|
|
146
|
+
parts[partIndex++] = ` <news:access>${value.access}</news:access>`;
|
|
147
|
+
}
|
|
148
|
+
if (value.genres) {
|
|
149
|
+
parts[partIndex++] = ` <news:genres>${escapeValueForXml(value.genres)}</news:genres>`;
|
|
150
|
+
}
|
|
151
|
+
if (value.keywords) {
|
|
152
|
+
parts[partIndex++] = ` <news:keywords>${escapeValueForXml(value.keywords)}</news:keywords>`;
|
|
153
|
+
}
|
|
154
|
+
if (value.stock_tickers) {
|
|
155
|
+
parts[partIndex++] = ` <news:stock_tickers>${escapeValueForXml(value.stock_tickers)}</news:stock_tickers>`;
|
|
156
|
+
}
|
|
157
|
+
parts[partIndex++] = " </news:news>";
|
|
158
|
+
}
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
66
161
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
export function handleEntry(k, e) {
|
|
70
|
-
return Array.isArray(e[k]) ? handleArray(k, e[k]) : typeof e[k] === "object" ? handleObject(k, e[k]) : ` <${k}>${escapeValueForXml(e[k])}</${k}>`;
|
|
162
|
+
parts[partIndex++] = " </url>";
|
|
163
|
+
return parts.slice(0, partIndex).join("\n");
|
|
71
164
|
}
|
|
72
|
-
export function
|
|
73
|
-
const
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
165
|
+
export function urlsToXml(urls, resolvers, { version, xsl, credits, minify }) {
|
|
166
|
+
const estimatedSize = urls.length + 5;
|
|
167
|
+
const xmlParts = Array.from({ length: estimatedSize });
|
|
168
|
+
let partIndex = 0;
|
|
169
|
+
const xslHref = xsl ? resolvers.relativeBaseUrlResolver(xsl) : false;
|
|
170
|
+
if (xslHref) {
|
|
171
|
+
xmlParts[partIndex++] = `<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/xsl" href="${xslHref}"?>`;
|
|
172
|
+
} else {
|
|
173
|
+
xmlParts[partIndex++] = '<?xml version="1.0" encoding="UTF-8"?>';
|
|
174
|
+
}
|
|
175
|
+
xmlParts[partIndex++] = URLSET_OPENING_TAG;
|
|
176
|
+
for (const url of urls) {
|
|
177
|
+
xmlParts[partIndex++] = buildUrlXml(url);
|
|
178
|
+
}
|
|
179
|
+
xmlParts[partIndex++] = "</urlset>";
|
|
180
|
+
if (credits) {
|
|
181
|
+
xmlParts[partIndex++] = `<!-- XML Sitemap generated by @nuxtjs/sitemap v${version} at ${(/* @__PURE__ */ new Date()).toISOString()} -->`;
|
|
182
|
+
}
|
|
183
|
+
const xmlContent = xmlParts.slice(0, partIndex);
|
|
184
|
+
if (minify) {
|
|
185
|
+
return xmlContent.join("").replace(/(?<!<[^>]*)\s(?![^<]*>)/g, "");
|
|
186
|
+
}
|
|
187
|
+
return xmlContent.join("\n");
|
|
86
188
|
}
|