@nuxtjs/sitemap 8.2.2 → 8.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.
Files changed (41) hide show
  1. package/README.md +1 -1
  2. package/dist/module.json +1 -1
  3. package/dist/module.mjs +8 -3
  4. package/dist/runtime/server/kit.js +9 -2
  5. package/dist/runtime/server/plugins/compression.js +57 -13
  6. package/dist/runtime/server/plugins/stream-transport.d.ts +2 -0
  7. package/dist/runtime/server/plugins/stream-transport.js +16 -0
  8. package/dist/runtime/server/routes/__sitemap__/debug.d.ts +1 -0
  9. package/dist/runtime/server/routes/__zero-runtime/sitemap/[sitemap].xml.d.ts +1 -1
  10. package/dist/runtime/server/routes/__zero-runtime/sitemap.xml.d.ts +1 -1
  11. package/dist/runtime/server/routes/__zero-runtime/sitemap_index.xml.d.ts +1 -1
  12. package/dist/runtime/server/routes/sitemap/[sitemap].xml.d.ts +1 -1
  13. package/dist/runtime/server/routes/sitemap.xml.d.ts +1 -1
  14. package/dist/runtime/server/routes/sitemap_index.xml.d.ts +1 -1
  15. package/dist/runtime/server/sitemap/builder/index-xml.d.ts +13 -0
  16. package/dist/runtime/server/sitemap/builder/index-xml.js +70 -0
  17. package/dist/runtime/server/sitemap/builder/sitemap-index.d.ts +1 -4
  18. package/dist/runtime/server/sitemap/builder/sitemap-index.js +2 -34
  19. package/dist/runtime/server/sitemap/builder/sitemap.d.ts +1 -1
  20. package/dist/runtime/server/sitemap/builder/sitemap.js +36 -25
  21. package/dist/runtime/server/sitemap/builder/xml.d.ts +8 -0
  22. package/dist/runtime/server/sitemap/builder/xml.js +35 -6
  23. package/dist/runtime/server/sitemap/event-handlers.d.ts +3 -3
  24. package/dist/runtime/server/sitemap/event-handlers.js +18 -10
  25. package/dist/runtime/server/sitemap/nitro.d.ts +3 -1
  26. package/dist/runtime/server/sitemap/nitro.js +107 -20
  27. package/dist/runtime/server/sitemap/stream.d.ts +30 -0
  28. package/dist/runtime/server/sitemap/stream.js +144 -0
  29. package/dist/runtime/server/sitemap/urlset/normalise.d.ts +6 -1
  30. package/dist/runtime/server/sitemap/urlset/normalise.js +15 -4
  31. package/dist/runtime/server/sitemap/urlset/sort.js +12 -3
  32. package/dist/runtime/server/sitemap/urlset/sources.js +3 -3
  33. package/dist/runtime/server/utils.d.ts +0 -1
  34. package/dist/runtime/server/utils.js +12 -12
  35. package/dist/runtime/types.d.ts +14 -3
  36. package/dist/runtime/utils-pure.d.ts +5 -4
  37. package/dist/runtime/utils-pure.js +41 -19
  38. package/dist/utils.d.mts +30 -2
  39. package/dist/utils.d.ts +30 -2
  40. package/dist/utils.mjs +646 -43
  41. package/package.json +22 -22
@@ -1,8 +1,9 @@
1
1
  import type { FilterInput } from './types.js';
2
2
  export { createFilter, type CreateFilterOptions } from 'nuxtseo-shared/utils';
3
3
  export declare const logger: import("consola").ConsolaInstance;
4
- export declare function mergeOnKey<T, K extends keyof T>(arr: T[], key: K): T[];
5
- export declare function splitForLocales(path: string, locales: string[]): [string | null, string];
4
+ export declare function xmlEscape(value: string | number | boolean | Date): string;
5
+ export declare function mergeOnKey<T, K extends keyof T>(arr: T[], key: K, onMerge?: (key: T[K]) => void): T[];
6
+ export declare function splitForLocales(path: string, locales: readonly string[] | Set<string>): [string | null, string];
6
7
  /**
7
8
  * Resolve which locale a multi-sitemap name belongs to.
8
9
  *
@@ -20,10 +21,10 @@ export declare function normalizeRuntimeFilters(input?: FilterInput[]): (RegExp
20
21
  export declare function createPathFilter(options?: {
21
22
  include?: (FilterInput | string | RegExp)[];
22
23
  exclude?: (FilterInput | string | RegExp)[];
23
- }, baseURL?: string): (loc: string) => boolean;
24
+ }, baseURL?: string): (loc: string, pathname?: string) => boolean;
24
25
  export interface PageMatch {
25
26
  mappings: Record<string, string | false>;
26
27
  paramSegments: string[];
27
28
  }
28
- export declare function findPageMapping(pathWithoutPrefix: string, pages: Record<string, Record<string, string | false>>): PageMatch | null;
29
+ export declare function findPageMapping(pathWithoutPrefix: string, pages: Record<string, Record<string, string | false>>, sortedKeys?: string[]): PageMatch | null;
29
30
  export declare function applyDynamicParams(customPath: string, paramSegments: string[]): string;
@@ -1,39 +1,59 @@
1
1
  import { createConsola } from "consola";
2
2
  import { createDefu } from "defu";
3
3
  import { createFilter } from "nuxtseo-shared/utils";
4
- import { parseURL, withLeadingSlash, withoutBase } from "ufo";
4
+ import { parseURL, withoutBase } from "ufo";
5
5
  export { createFilter } from "nuxtseo-shared/utils";
6
6
  export const logger = createConsola({
7
7
  defaults: {
8
8
  tag: "@nuxt/sitemap"
9
9
  }
10
10
  });
11
+ const XML_ENTITIES = {
12
+ "&": "&amp;",
13
+ "<": "&lt;",
14
+ ">": "&gt;",
15
+ '"': "&quot;",
16
+ "'": "&apos;"
17
+ };
18
+ const XML_SPECIAL_CHARS_RE = /[&<>"']/g;
19
+ const HAS_XML_SPECIAL_CHARS_RE = /[&<>"']/;
20
+ export function xmlEscape(value) {
21
+ const input = String(value);
22
+ return HAS_XML_SPECIAL_CHARS_RE.test(input) ? input.replace(XML_SPECIAL_CHARS_RE, (char) => XML_ENTITIES[char]) : input;
23
+ }
11
24
  const merger = createDefu((obj, key, value) => {
12
25
  if (Array.isArray(obj[key]) && Array.isArray(value))
13
26
  obj[key] = Array.from(/* @__PURE__ */ new Set([...obj[key], ...value]));
14
27
  return obj[key];
15
28
  });
16
- export function mergeOnKey(arr, key) {
29
+ export function mergeOnKey(arr, key, onMerge) {
30
+ if (arr.length < 2)
31
+ return arr;
17
32
  const seen = /* @__PURE__ */ new Map();
18
33
  let resultLength = 0;
19
- const result = Array.from({ length: arr.length });
20
34
  for (const item of arr) {
21
35
  const k = item[key];
22
36
  if (seen.has(k)) {
23
37
  const existingIndex = seen.get(k);
24
- result[existingIndex] = merger(item, result[existingIndex]);
38
+ onMerge?.(item[key]);
39
+ arr[existingIndex] = merger(item, arr[existingIndex]);
25
40
  } else {
26
41
  seen.set(k, resultLength);
27
- result[resultLength++] = item;
42
+ arr[resultLength++] = item;
28
43
  }
29
44
  }
30
- result.length = resultLength;
31
- return result;
45
+ arr.length = resultLength;
46
+ return arr;
32
47
  }
33
48
  export function splitForLocales(path, locales) {
34
- const prefix = withLeadingSlash(path).split("/")[1];
35
- if (prefix && locales.includes(prefix))
36
- return [prefix, path.replace(`/${prefix}`, "")];
49
+ const start = path.charCodeAt(0) === 47 ? 1 : 0;
50
+ const end = path.indexOf("/", start);
51
+ const prefix = path.slice(start, end === -1 ? path.length : end);
52
+ const hasLocale = locales instanceof Set ? locales.has(prefix) : locales.includes(prefix);
53
+ if (prefix && hasLocale) {
54
+ const prefixEnd = start + prefix.length;
55
+ return [prefix, start === 1 ? path.slice(prefixEnd) : path];
56
+ }
37
57
  return [null, path];
38
58
  }
39
59
  export function resolveI18nSitemapLocaleKey(sitemapName, localeSitemapKeys) {
@@ -63,25 +83,27 @@ export function createPathFilter(options = {}, baseURL) {
63
83
  exclude: normalizeRuntimeFilters(options.exclude)
64
84
  });
65
85
  const hasBase = baseURL && baseURL !== "/";
66
- return (loc) => {
67
- let path = loc;
68
- try {
69
- path = parseURL(loc).pathname;
70
- } catch {
71
- return false;
86
+ return (loc, pathname) => {
87
+ let path = pathname;
88
+ if (typeof path !== "string") {
89
+ try {
90
+ path = parseURL(loc).pathname;
91
+ } catch {
92
+ return false;
93
+ }
72
94
  }
73
95
  if (hasBase)
74
96
  path = withoutBase(path, baseURL);
75
97
  return urlFilter(path);
76
98
  };
77
99
  }
78
- export function findPageMapping(pathWithoutPrefix, pages) {
100
+ export function findPageMapping(pathWithoutPrefix, pages, sortedKeys) {
79
101
  const stripped = pathWithoutPrefix[0] === "/" ? pathWithoutPrefix.slice(1) : pathWithoutPrefix;
80
102
  const pageKey = stripped.endsWith("/index") ? stripped.slice(0, -6) || "index" : stripped || "index";
81
103
  if (pages[pageKey])
82
104
  return { mappings: pages[pageKey], paramSegments: [] };
83
- const sortedKeys = Object.keys(pages).sort((a, b) => b.length - a.length);
84
- for (const key of sortedKeys) {
105
+ const keys = sortedKeys || Object.keys(pages).sort((a, b) => b.length - a.length);
106
+ for (const key of keys) {
85
107
  if (pageKey.startsWith(`${key}/`)) {
86
108
  const paramPath = pageKey.slice(key.length + 1);
87
109
  return { mappings: pages[key], paramSegments: paramPath.split("/") };
package/dist/utils.d.mts CHANGED
@@ -22,6 +22,34 @@ interface SitemapParseResult {
22
22
  urls: SitemapUrlInput[];
23
23
  warnings: SitemapWarning[];
24
24
  }
25
+ type SitemapXmlChunk = string | Uint8Array;
26
+ type SitemapXmlInput = SitemapXmlChunk | Iterable<SitemapXmlChunk> | AsyncIterable<SitemapXmlChunk> | ReadableStream<SitemapXmlChunk>;
27
+ interface SitemapStreamOptions {
28
+ maxEntryBytes?: number;
29
+ maxBufferBytes?: number;
30
+ }
31
+ type SitemapXmlStreamEvent = {
32
+ _tag: 'url';
33
+ url: SitemapUrlInput;
34
+ } | {
35
+ _tag: 'warning';
36
+ warning: SitemapWarning;
37
+ };
38
+ type SitemapIndexStreamEvent = {
39
+ _tag: 'sitemap';
40
+ sitemap: SitemapIndexEntry;
41
+ } | {
42
+ _tag: 'warning';
43
+ warning: SitemapWarning;
44
+ };
45
+ type SitemapKind = 'urlset' | 'index';
46
+ type SitemapStreamEvent = {
47
+ _tag: 'kind';
48
+ kind: SitemapKind;
49
+ } | SitemapXmlStreamEvent | SitemapIndexStreamEvent;
50
+ declare function parseSitemapStream(input: SitemapXmlInput, options?: SitemapStreamOptions): AsyncGenerator<SitemapStreamEvent>;
51
+ declare function parseSitemapXmlStream(input: SitemapXmlInput, options?: SitemapStreamOptions): AsyncGenerator<SitemapXmlStreamEvent>;
52
+ declare function parseSitemapIndexStream(input: SitemapXmlInput, options?: SitemapStreamOptions): AsyncGenerator<SitemapIndexStreamEvent>;
25
53
  declare function parseSitemapXml(xml: string): Promise<SitemapParseResult>;
26
54
 
27
55
  interface SitemapIndexEntry {
@@ -35,5 +63,5 @@ interface SitemapIndexParseResult {
35
63
  declare function parseSitemapIndex(xml: string): Promise<SitemapIndexParseResult>;
36
64
  declare function isSitemapIndex(xml: string): boolean;
37
65
 
38
- export { isSitemapIndex, parseHtmlExtractSitemapMeta, parseSitemapIndex, parseSitemapXml };
39
- export type { SitemapIndexEntry, SitemapIndexParseResult, SitemapParseResult, SitemapWarning };
66
+ export { isSitemapIndex, parseHtmlExtractSitemapMeta, parseSitemapIndex, parseSitemapIndexStream, parseSitemapStream, parseSitemapXml, parseSitemapXmlStream };
67
+ export type { SitemapIndexEntry, SitemapIndexParseResult, SitemapIndexStreamEvent, SitemapKind, SitemapParseResult, SitemapStreamEvent, SitemapStreamOptions, SitemapWarning, SitemapXmlChunk, SitemapXmlInput, SitemapXmlStreamEvent };
package/dist/utils.d.ts CHANGED
@@ -22,6 +22,34 @@ interface SitemapParseResult {
22
22
  urls: SitemapUrlInput[];
23
23
  warnings: SitemapWarning[];
24
24
  }
25
+ type SitemapXmlChunk = string | Uint8Array;
26
+ type SitemapXmlInput = SitemapXmlChunk | Iterable<SitemapXmlChunk> | AsyncIterable<SitemapXmlChunk> | ReadableStream<SitemapXmlChunk>;
27
+ interface SitemapStreamOptions {
28
+ maxEntryBytes?: number;
29
+ maxBufferBytes?: number;
30
+ }
31
+ type SitemapXmlStreamEvent = {
32
+ _tag: 'url';
33
+ url: SitemapUrlInput;
34
+ } | {
35
+ _tag: 'warning';
36
+ warning: SitemapWarning;
37
+ };
38
+ type SitemapIndexStreamEvent = {
39
+ _tag: 'sitemap';
40
+ sitemap: SitemapIndexEntry;
41
+ } | {
42
+ _tag: 'warning';
43
+ warning: SitemapWarning;
44
+ };
45
+ type SitemapKind = 'urlset' | 'index';
46
+ type SitemapStreamEvent = {
47
+ _tag: 'kind';
48
+ kind: SitemapKind;
49
+ } | SitemapXmlStreamEvent | SitemapIndexStreamEvent;
50
+ declare function parseSitemapStream(input: SitemapXmlInput, options?: SitemapStreamOptions): AsyncGenerator<SitemapStreamEvent>;
51
+ declare function parseSitemapXmlStream(input: SitemapXmlInput, options?: SitemapStreamOptions): AsyncGenerator<SitemapXmlStreamEvent>;
52
+ declare function parseSitemapIndexStream(input: SitemapXmlInput, options?: SitemapStreamOptions): AsyncGenerator<SitemapIndexStreamEvent>;
25
53
  declare function parseSitemapXml(xml: string): Promise<SitemapParseResult>;
26
54
 
27
55
  interface SitemapIndexEntry {
@@ -35,5 +63,5 @@ interface SitemapIndexParseResult {
35
63
  declare function parseSitemapIndex(xml: string): Promise<SitemapIndexParseResult>;
36
64
  declare function isSitemapIndex(xml: string): boolean;
37
65
 
38
- export { isSitemapIndex, parseHtmlExtractSitemapMeta, parseSitemapIndex, parseSitemapXml };
39
- export type { SitemapIndexEntry, SitemapIndexParseResult, SitemapParseResult, SitemapWarning };
66
+ export { isSitemapIndex, parseHtmlExtractSitemapMeta, parseSitemapIndex, parseSitemapIndexStream, parseSitemapStream, parseSitemapXml, parseSitemapXmlStream };
67
+ export type { SitemapIndexEntry, SitemapIndexParseResult, SitemapIndexStreamEvent, SitemapKind, SitemapParseResult, SitemapStreamEvent, SitemapStreamOptions, SitemapWarning, SitemapXmlChunk, SitemapXmlInput, SitemapXmlStreamEvent };