Files
smartsitemap/ts/interfaces/index.ts

278 lines
8.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ============================================================
// 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[];
}
// ============================================================
// SITEMAP EXTENSIONS
// ============================================================
export interface ISitemapImage {
/** URL of the image (required) */
loc: string;
/** Caption for the image */
caption?: string;
/** Title of the image */
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;
pubDate?: string;
author?: string;
content?: string;
contentSnippet?: string;
isoDate?: string;
id?: string;
categories?: string[];
enclosure?: {
url?: string;
type?: string;
length?: string;
};
[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 }>;
}