Files
smartsitemap/ts/interfaces/index.ts

278 lines
8.1 KiB
TypeScript
Raw Normal View History

// ============================================================
// CORE TYPES
// ============================================================
/**
* Change frequency values per the sitemap protocol specification.
* Note: Google ignores changefreq, but other search engines may use it.
*/
export type TChangeFreq =
| 'always'
| 'hourly'
| 'daily'
| 'weekly'
| 'monthly'
| 'yearly'
| 'never';
/** Supported output formats */
export type TOutputFormat = 'xml' | 'txt' | 'json';
// ============================================================
// URL ENTRY — the core unit of a sitemap
// ============================================================
/**
* A single URL entry in a sitemap, supporting all standard extensions.
*/
export interface ISitemapUrl {
/** Absolute URL of the page (required, max 2048 chars) */
loc: string;
/** Last modification date — accepts Date, ISO string, or Unix timestamp (ms) */
lastmod?: Date | string | number;
/** How frequently the page changes */
changefreq?: TChangeFreq;
/** Priority relative to other URLs on your site, 0.0 to 1.0 */
priority?: number;
/** Image sitemap extension entries */
images?: ISitemapImage[];
/** Video sitemap extension entries */
videos?: ISitemapVideo[];
/** News sitemap extension */
news?: ISitemapNews;
/** Alternate language versions (hreflang) */
alternates?: ISitemapAlternate[];
2020-10-28 17:43:58 +00:00
}
// ============================================================
// SITEMAP EXTENSIONS
// ============================================================
export interface ISitemapImage {
/** URL of the image (required) */
loc: string;
/** Caption for the image */
caption?: string;
/** Title of the image */
2020-10-28 17:43:58 +00:00
title?: string;
/** Geographic location (e.g. "New York, USA") */
geoLocation?: string;
/** URL to the image license */
licenseUrl?: string;
}
export interface ISitemapVideo {
/** URL to the video thumbnail (required) */
thumbnailLoc: string;
/** Title of the video (required) */
title: string;
/** Description of the video, max 2048 chars (required) */
description: string;
/** URL of the actual video media file */
contentLoc?: string;
/** URL of the embeddable player — at least one of contentLoc or playerLoc required */
playerLoc?: string;
/** Duration in seconds (128800) */
duration?: number;
/** Rating 0.0 to 5.0 */
rating?: number;
/** Number of views */
viewCount?: number;
/** Publication date */
publicationDate?: Date | string;
/** Whether the video is family friendly (default true) */
familyFriendly?: boolean;
/** Tags for the video (max 32) */
tags?: string[];
/** Whether this is a live stream */
live?: boolean;
/** Whether a subscription is required to view */
requiresSubscription?: boolean;
}
export interface ISitemapNews {
/** Publication information */
publication: {
/** Publication name (e.g. "The New York Times") */
name: string;
/** Language code (ISO 639, e.g. "en", "de", "zh-cn") */
language: string;
};
/** Publication date of the article */
publicationDate: Date | string | number;
/** Article title */
title: string;
/** Keywords (array or comma-separated string) */
keywords?: string[] | string;
}
export interface ISitemapAlternate {
/** Language code (ISO 639) or 'x-default' for the default version */
hreflang: string;
/** URL for this language version */
href: string;
}
// ============================================================
// SITEMAP INDEX
// ============================================================
export interface ISitemapIndexEntry {
/** URL to the sitemap file */
loc: string;
/** Last modification date of the referenced sitemap */
lastmod?: Date | string | number;
}
// ============================================================
// CONFIGURATION
// ============================================================
export interface ISitemapOptions {
/** Base URL for the website (used to resolve relative URLs and for auto-split filenames) */
baseUrl?: string;
/** XSL stylesheet URL for browser-viewable sitemaps */
xslUrl?: string;
/** Default changefreq for URLs that don't specify one */
defaultChangeFreq?: TChangeFreq;
/** Default priority for URLs that don't specify one (0.01.0) */
defaultPriority?: number;
/** Whether to pretty-print XML output (default: true) */
prettyPrint?: boolean;
/** Maximum URLs per sitemap file before auto-splitting (default: 50000, max: 50000) */
maxUrlsPerSitemap?: number;
/** Enable gzip compression for toGzipBuffer() */
gzip?: boolean;
/** Whether to validate URLs and fields (default: true) */
validate?: boolean;
}
export interface INewsSitemapOptions extends ISitemapOptions {
/** Publication name — required for news sitemaps */
publicationName: string;
/** Publication language (default: 'en') */
publicationLanguage?: string;
}
export interface IFeedImportOptions {
/** Publication name for news sitemap mapping */
publicationName?: string;
/** Publication language for news sitemap mapping */
publicationLanguage?: string;
/** Only include items newer than this date */
newerThan?: Date | number;
/** Maximum number of items to import */
limit?: number;
/** Custom mapping function from feed item to sitemap URL (return null to skip) */
mapItem?: (item: IFeedItem) => ISitemapUrl | null;
}
/** Shape of a parsed RSS/Atom feed item */
export interface IFeedItem {
title?: string;
link?: string;
2020-10-28 17:43:58 +00:00
pubDate?: string;
author?: string;
2020-10-28 17:43:58 +00:00
content?: string;
contentSnippet?: string;
2020-10-28 17:43:58 +00:00
isoDate?: string;
id?: string;
2020-10-28 17:43:58 +00:00
categories?: string[];
enclosure?: {
url?: string;
type?: string;
length?: string;
2021-01-03 02:48:45 +00:00
};
[key: string]: any;
}
// ============================================================
// YAML CONFIG
// ============================================================
/**
* Enhanced YAML configuration format for defining sitemaps declaratively.
* Supports per-frequency URL groups, default settings, and feed imports.
*/
export interface ISitemapYamlConfig {
/** Base URL to prepend to relative paths */
baseUrl?: string;
/** Default values for all URLs */
defaults?: {
changefreq?: TChangeFreq;
priority?: number;
};
/** URL groups organized by change frequency */
urls?: { [K in TChangeFreq]?: string[] };
/** RSS/Atom feeds to import */
feeds?: Array<{
url: string;
type: 'news' | 'standard';
publicationName?: string;
publicationLanguage?: string;
}>;
}
// ============================================================
// PARSED SITEMAP (bidirectional)
// ============================================================
export interface IParsedSitemap {
/** Whether this is a urlset or a sitemap index */
type: 'urlset' | 'sitemapindex';
/** Parsed URL entries (populated when type is 'urlset') */
urls: ISitemapUrl[];
/** Parsed index entries (populated when type is 'sitemapindex') */
sitemaps: ISitemapIndexEntry[];
}
// ============================================================
// VALIDATION
// ============================================================
export interface IValidationError {
field: string;
message: string;
url?: string;
}
export interface IValidationWarning {
field: string;
message: string;
url?: string;
}
export interface IValidationResult {
valid: boolean;
errors: IValidationError[];
warnings: IValidationWarning[];
stats: ISitemapStats;
}
// ============================================================
// STATISTICS
// ============================================================
export interface ISitemapStats {
urlCount: number;
imageCount: number;
videoCount: number;
newsCount: number;
alternateCount: number;
estimatedSizeBytes: number;
needsIndex: boolean;
}
// ============================================================
// AUTO-SPLIT OUTPUT
// ============================================================
export interface ISitemapSet {
/** Whether the URL count exceeded maxUrlsPerSitemap */
needsIndex: boolean;
/** The sitemap index XML (null if all URLs fit in one sitemap) */
indexXml: string | null;
/** Individual sitemap chunks */
sitemaps: Array<{ filename: string; xml: string }>;
2021-01-03 02:48:45 +00:00
}