@stati/core 1.6.4 → 1.7.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 (81) hide show
  1. package/README.md +1 -1
  2. package/dist/core/build.d.ts.map +1 -1
  3. package/dist/core/build.js +42 -6
  4. package/dist/core/content.d.ts.map +1 -1
  5. package/dist/core/content.js +1 -2
  6. package/dist/core/dev.d.ts.map +1 -1
  7. package/dist/core/dev.js +2 -5
  8. package/dist/core/index.d.ts +13 -0
  9. package/dist/core/index.d.ts.map +1 -0
  10. package/dist/core/index.js +12 -0
  11. package/dist/core/invalidate.js +2 -2
  12. package/dist/core/isg/build-lock.js +1 -1
  13. package/dist/core/isg/deps.d.ts.map +1 -1
  14. package/dist/core/isg/deps.js +1 -3
  15. package/dist/core/isg/hash.js +1 -1
  16. package/dist/core/isg/index.d.ts +16 -0
  17. package/dist/core/isg/index.d.ts.map +1 -0
  18. package/dist/core/isg/index.js +22 -0
  19. package/dist/core/isg/manifest.js +1 -1
  20. package/dist/core/preview.d.ts.map +1 -1
  21. package/dist/core/preview.js +1 -2
  22. package/dist/core/templates.d.ts.map +1 -1
  23. package/dist/core/templates.js +4 -7
  24. package/dist/core/utils/index.d.ts +16 -0
  25. package/dist/core/utils/index.d.ts.map +1 -0
  26. package/dist/core/utils/index.js +22 -0
  27. package/dist/core/utils/partial-validation.d.ts.map +1 -1
  28. package/dist/core/utils/partial-validation.js +2 -1
  29. package/dist/index.d.ts +6 -8
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +3 -4
  32. package/dist/seo/auto-inject.d.ts +48 -0
  33. package/dist/seo/auto-inject.d.ts.map +1 -0
  34. package/dist/seo/auto-inject.js +108 -0
  35. package/dist/seo/generator.d.ts +77 -0
  36. package/dist/seo/generator.d.ts.map +1 -0
  37. package/dist/seo/generator.js +320 -0
  38. package/dist/seo/index.d.ts +12 -0
  39. package/dist/seo/index.d.ts.map +1 -0
  40. package/dist/seo/index.js +15 -0
  41. package/dist/seo/robots.d.ts +84 -0
  42. package/dist/seo/robots.d.ts.map +1 -0
  43. package/dist/seo/robots.js +165 -0
  44. package/dist/seo/sitemap.d.ts +37 -0
  45. package/dist/seo/sitemap.d.ts.map +1 -0
  46. package/dist/seo/sitemap.js +320 -0
  47. package/dist/seo/utils/escape-and-validation.d.ts +99 -0
  48. package/dist/seo/utils/escape-and-validation.d.ts.map +1 -0
  49. package/dist/seo/utils/escape-and-validation.js +319 -0
  50. package/dist/seo/utils/index.d.ts +7 -0
  51. package/dist/seo/utils/index.d.ts.map +1 -0
  52. package/dist/seo/utils/index.js +8 -0
  53. package/dist/seo/utils/url.d.ts +46 -0
  54. package/dist/seo/utils/url.d.ts.map +1 -0
  55. package/dist/seo/utils/url.js +66 -0
  56. package/dist/seo/utils.d.ts +94 -0
  57. package/dist/seo/utils.d.ts.map +1 -0
  58. package/dist/seo/utils.js +304 -0
  59. package/dist/types/config.d.ts +58 -0
  60. package/dist/types/config.d.ts.map +1 -1
  61. package/dist/types/content.d.ts +181 -0
  62. package/dist/types/content.d.ts.map +1 -1
  63. package/dist/types/index.d.ts +5 -2
  64. package/dist/types/index.d.ts.map +1 -1
  65. package/dist/types/index.js +1 -1
  66. package/dist/types/seo.d.ts +69 -0
  67. package/dist/types/seo.d.ts.map +1 -0
  68. package/dist/types/seo.js +36 -0
  69. package/dist/types/sitemap.d.ts +94 -0
  70. package/dist/types/sitemap.d.ts.map +1 -0
  71. package/dist/types/sitemap.js +4 -0
  72. package/package.json +1 -1
  73. package/dist/core/utils/partials.d.ts +0 -24
  74. package/dist/core/utils/partials.d.ts.map +0 -1
  75. package/dist/core/utils/partials.js +0 -85
  76. package/dist/tests/utils/test-mocks.d.ts +0 -69
  77. package/dist/tests/utils/test-mocks.d.ts.map +0 -1
  78. package/dist/tests/utils/test-mocks.js +0 -125
  79. package/dist/types.d.ts +0 -543
  80. package/dist/types.d.ts.map +0 -1
  81. package/dist/types.js +0 -1
@@ -0,0 +1,304 @@
1
+ /**
2
+ * SEO utility functions for HTML escaping, validation, and tag detection
3
+ */
4
+ import { URL } from 'node:url';
5
+ import { SEOTagType as SEOTagTypeEnum } from '../types/seo.js';
6
+ /**
7
+ * HTML escape cache for performance optimization.
8
+ * Stores up to 1000 frequently used strings to avoid repeated escaping.
9
+ */
10
+ const escapeHtmlCache = new Map();
11
+ const ESCAPE_CACHE_MAX_SIZE = 1000;
12
+ /**
13
+ * Escape HTML entities to prevent XSS attacks.
14
+ * Uses memoization for performance with frequently repeated strings.
15
+ *
16
+ * Implements LRU-style cache eviction: when the cache is full, it's cleared
17
+ * and the new entry is added. This prevents unbounded memory growth while
18
+ * still providing caching benefits for repeated strings.
19
+ *
20
+ * @param text - The text to escape
21
+ * @returns HTML-safe string with special characters escaped
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * escapeHtml('<script>alert("xss")</script>');
26
+ * // Returns: '&lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;'
27
+ * ```
28
+ */
29
+ export function escapeHtml(text) {
30
+ // Check cache
31
+ const cached = escapeHtmlCache.get(text);
32
+ if (cached !== undefined) {
33
+ return cached;
34
+ }
35
+ // Compute result
36
+ const htmlEscapes = {
37
+ '&': '&amp;',
38
+ '<': '&lt;',
39
+ '>': '&gt;',
40
+ '"': '&quot;',
41
+ "'": '&#39;',
42
+ };
43
+ const result = text.replace(/[&<>"']/g, (char) => htmlEscapes[char] || char);
44
+ // Store in cache with size limit
45
+ if (escapeHtmlCache.size < ESCAPE_CACHE_MAX_SIZE) {
46
+ escapeHtmlCache.set(text, result);
47
+ }
48
+ else {
49
+ // Clear cache when full (prevents unbounded growth)
50
+ // This is a simple LRU-style eviction strategy
51
+ escapeHtmlCache.clear();
52
+ escapeHtmlCache.set(text, result);
53
+ }
54
+ return result;
55
+ }
56
+ /**
57
+ * Sanitize structured data to prevent XSS attacks and ensure safe JSON-LD output.
58
+ * Recursively processes objects and arrays, escaping string values and enforcing depth limits.
59
+ *
60
+ * @param data - The data to sanitize
61
+ * @param depth - Current recursion depth (internal use)
62
+ * @param maxDepth - Maximum allowed recursion depth (default: 50)
63
+ * @returns Sanitized data safe for JSON-LD output
64
+ *
65
+ * @example
66
+ * ```typescript
67
+ * const data = {
68
+ * name: '<script>alert("xss")</script>',
69
+ * nested: { value: 'test' }
70
+ * };
71
+ * sanitizeStructuredData(data);
72
+ * // Returns: { name: '&lt;script&gt;...', nested: { value: 'test' } }
73
+ * ```
74
+ */
75
+ export function sanitizeStructuredData(data, depth = 0, maxDepth = 50) {
76
+ // Prevent stack overflow from deeply nested objects
77
+ if (depth > maxDepth) {
78
+ console.warn(`Structured data exceeds maximum nesting depth of ${maxDepth}, truncating`);
79
+ return '[Object: max depth exceeded]';
80
+ }
81
+ // Handle primitives
82
+ if (typeof data === 'string') {
83
+ return escapeHtml(data);
84
+ }
85
+ if (typeof data !== 'object' || data === null) {
86
+ return data;
87
+ }
88
+ // Handle arrays
89
+ if (Array.isArray(data)) {
90
+ return data.map((item) => sanitizeStructuredData(item, depth + 1, maxDepth));
91
+ }
92
+ // Handle objects
93
+ const sanitized = {};
94
+ for (const [key, value] of Object.entries(data)) {
95
+ sanitized[key] = sanitizeStructuredData(value, depth + 1, maxDepth);
96
+ }
97
+ return sanitized;
98
+ }
99
+ /**
100
+ * Generate robots meta tag content from SEO metadata and robots configuration.
101
+ * Combines noindex flag and robots directives into a comma-separated string.
102
+ *
103
+ * @param seo - SEO metadata containing robots configuration
104
+ * @returns Comma-separated robots directives, or empty string if none
105
+ *
106
+ * @example
107
+ * ```typescript
108
+ * generateRobotsContent({ noindex: true, robots: { follow: false } });
109
+ * // Returns: 'noindex, nofollow'
110
+ * ```
111
+ */
112
+ export function generateRobotsContent(seo) {
113
+ const directives = [];
114
+ // Collect directives from noindex flag
115
+ if (seo.noindex) {
116
+ directives.push('noindex');
117
+ }
118
+ // Handle robots config
119
+ if (typeof seo.robots === 'string') {
120
+ // If string doesn't include noindex but flag is set, prepend it
121
+ if (seo.noindex && !seo.robots.includes('noindex')) {
122
+ return `noindex, ${seo.robots}`;
123
+ }
124
+ return seo.robots;
125
+ }
126
+ else if (seo.robots) {
127
+ const robots = seo.robots;
128
+ // Only add if not already added via noindex flag
129
+ if (robots.index === false && !directives.includes('noindex')) {
130
+ directives.push('noindex');
131
+ }
132
+ if (robots.follow === false) {
133
+ directives.push('nofollow');
134
+ }
135
+ if (robots.archive === false) {
136
+ directives.push('noarchive');
137
+ }
138
+ if (robots.snippet === false) {
139
+ directives.push('nosnippet');
140
+ }
141
+ if (robots.imageindex === false) {
142
+ directives.push('noimageindex');
143
+ }
144
+ if (robots.translate === false) {
145
+ directives.push('notranslate');
146
+ }
147
+ if (robots.maxSnippet !== undefined) {
148
+ directives.push(`max-snippet:${robots.maxSnippet}`);
149
+ }
150
+ if (robots.maxImagePreview) {
151
+ directives.push(`max-image-preview:${robots.maxImagePreview}`);
152
+ }
153
+ if (robots.maxVideoPreview !== undefined) {
154
+ directives.push(`max-video-preview:${robots.maxVideoPreview}`);
155
+ }
156
+ }
157
+ return directives.length > 0 ? directives.join(', ') : '';
158
+ }
159
+ /**
160
+ * Validate URL format (http or https only).
161
+ *
162
+ * @param url - The URL to validate
163
+ * @returns True if the URL is valid
164
+ */
165
+ function isValidUrl(url) {
166
+ try {
167
+ const parsed = new URL(url);
168
+ return parsed.protocol === 'http:' || parsed.protocol === 'https:';
169
+ }
170
+ catch {
171
+ return false;
172
+ }
173
+ }
174
+ /**
175
+ * Validate SEO metadata before processing.
176
+ * Checks for common issues like invalid URLs, improper lengths, and malformed data.
177
+ *
178
+ * @param seo - SEO metadata to validate
179
+ * @param _pageUrl - URL of the page being validated (for context in error messages)
180
+ * @returns Validation result with valid flag, errors, and warnings
181
+ *
182
+ * @example
183
+ * ```typescript
184
+ * const result = validateSEOMetadata({
185
+ * title: 'My Page',
186
+ * canonical: 'invalid-url'
187
+ * }, '/my-page');
188
+ * // Returns: { valid: false, errors: ['Invalid canonical URL...'], warnings: [] }
189
+ * ```
190
+ */
191
+ export function validateSEOMetadata(seo, _pageUrl) {
192
+ const errors = [];
193
+ const warnings = [];
194
+ // Validate title length
195
+ if (seo.title) {
196
+ if (seo.title.length < 5) {
197
+ warnings.push(`Title is only ${seo.title.length} characters (recommended: 50-60)`);
198
+ }
199
+ else if (seo.title.length > 70) {
200
+ warnings.push(`Title is ${seo.title.length} characters (recommended: 50-60)`);
201
+ }
202
+ }
203
+ // Validate description length
204
+ if (seo.description) {
205
+ if (seo.description.length < 50) {
206
+ warnings.push(`Description is only ${seo.description.length} characters (recommended: 150-160)`);
207
+ }
208
+ else if (seo.description.length > 160) {
209
+ warnings.push(`Description is ${seo.description.length} characters (recommended: 150-160)`);
210
+ }
211
+ }
212
+ // Validate canonical URL
213
+ if (seo.canonical && !isValidUrl(seo.canonical)) {
214
+ errors.push(`Invalid canonical URL: ${seo.canonical}`);
215
+ }
216
+ // Validate Open Graph image URL and dimensions
217
+ if (seo.openGraph?.image) {
218
+ const imageUrl = typeof seo.openGraph.image === 'string' ? seo.openGraph.image : seo.openGraph.image.url;
219
+ if (!isValidUrl(imageUrl) && !imageUrl.startsWith('/')) {
220
+ warnings.push(`Open Graph image URL may be invalid: ${imageUrl}`);
221
+ }
222
+ // Validate image dimensions if provided
223
+ if (typeof seo.openGraph.image !== 'string') {
224
+ const { width, height } = seo.openGraph.image;
225
+ if (width !== undefined && (!Number.isInteger(width) || width <= 0)) {
226
+ errors.push(`Open Graph image width must be a positive integer (got ${width})`);
227
+ }
228
+ if (height !== undefined && (!Number.isInteger(height) || height <= 0)) {
229
+ errors.push(`Open Graph image height must be a positive integer (got ${height})`);
230
+ }
231
+ }
232
+ }
233
+ // Validate Twitter image URL
234
+ if (seo.twitter?.image && !isValidUrl(seo.twitter.image) && !seo.twitter.image.startsWith('/')) {
235
+ warnings.push(`Twitter Card image URL may be invalid: ${seo.twitter.image}`);
236
+ }
237
+ // Validate structured data size
238
+ if (seo.structuredData) {
239
+ const jsonSize = JSON.stringify(seo.structuredData).length;
240
+ const maxSize = 100 * 1024; // 100KB limit
241
+ if (jsonSize > maxSize) {
242
+ warnings.push(`Structured data is ${(jsonSize / 1024).toFixed(2)}KB (recommended: <100KB)`);
243
+ }
244
+ }
245
+ // Validate priority value
246
+ if (seo.priority !== undefined) {
247
+ if (typeof seo.priority !== 'number' || seo.priority < 0 || seo.priority > 1) {
248
+ errors.push('Priority must be a number between 0.0 and 1.0');
249
+ }
250
+ }
251
+ return { valid: errors.length === 0, errors, warnings };
252
+ }
253
+ /**
254
+ * Detect existing SEO tags in HTML to avoid duplication during auto-injection.
255
+ * Uses enhanced regex patterns to handle multi-line attributes and edge cases.
256
+ *
257
+ * Returns a Set of SEOTagType enum values indicating which tag types are already present.
258
+ * This allows for granular control: only missing tags will be generated.
259
+ *
260
+ * @param html - The HTML content to scan
261
+ * @returns Set of SEOTagType enum values for existing tags
262
+ *
263
+ * @example
264
+ * ```typescript
265
+ * const html = '<head><title>My Page</title><meta name="description" content="..."></head>';
266
+ * const existing = detectExistingSEOTags(html);
267
+ * // Returns: Set { SEOTagType.Title, SEOTagType.Description }
268
+ * ```
269
+ */
270
+ export function detectExistingSEOTags(html) {
271
+ const existingTags = new Set();
272
+ // Extract just the <head> section for more efficient parsing
273
+ const headMatch = html.match(/<head[^>]*>([\s\S]*?)<\/head>/i);
274
+ if (!headMatch) {
275
+ console.warn('No <head> tag found in HTML, SEO auto-injection may not work correctly');
276
+ return existingTags;
277
+ }
278
+ const headContent = headMatch[1];
279
+ // More robust regex patterns that handle multi-line attributes and edge cases
280
+ const patterns = [
281
+ { regex: /<title\s*>/i, type: SEOTagTypeEnum.Title },
282
+ {
283
+ regex: /<meta\s+[^>]*name\s*=\s*["']description["'][^>]*>/i,
284
+ type: SEOTagTypeEnum.Description,
285
+ },
286
+ { regex: /<meta\s+[^>]*name\s*=\s*["']keywords["'][^>]*>/i, type: SEOTagTypeEnum.Keywords },
287
+ { regex: /<meta\s+[^>]*name\s*=\s*["']author["'][^>]*>/i, type: SEOTagTypeEnum.Author },
288
+ { regex: /<meta\s+[^>]*name\s*=\s*["']robots["'][^>]*>/i, type: SEOTagTypeEnum.Robots },
289
+ { regex: /<link\s+[^>]*rel\s*=\s*["']canonical["'][^>]*>/i, type: SEOTagTypeEnum.Canonical },
290
+ { regex: /<meta\s+[^>]*property\s*=\s*["']og:/i, type: SEOTagTypeEnum.OpenGraph },
291
+ { regex: /<meta\s+[^>]*name\s*=\s*["']twitter:/i, type: SEOTagTypeEnum.Twitter },
292
+ {
293
+ regex: /<script\s+[^>]*type\s*=\s*["']application\/ld\+json["'][^>]*>/i,
294
+ type: SEOTagTypeEnum.StructuredData,
295
+ },
296
+ ];
297
+ // Check all patterns in a single pass
298
+ for (const { regex, type } of patterns) {
299
+ if (headContent && regex.test(headContent)) {
300
+ existingTags.add(type);
301
+ }
302
+ }
303
+ return existingTags;
304
+ }
@@ -1,4 +1,6 @@
1
1
  import type MarkdownIt from 'markdown-it';
2
+ import type { SitemapConfig } from './sitemap.js';
3
+ import type { AuthorConfig } from './content.js';
2
4
  /**
3
5
  * Configuration related type definitions
4
6
  */
@@ -66,6 +68,12 @@ export interface StatiConfig {
66
68
  };
67
69
  /** Incremental Static Generation configuration */
68
70
  isg?: import('./isg.js').ISGConfig;
71
+ /** SEO configuration */
72
+ seo?: SEOConfig;
73
+ /** Sitemap generation configuration */
74
+ sitemap?: SitemapConfig;
75
+ /** Robots.txt generation configuration */
76
+ robots?: RobotsTxtConfig;
69
77
  /** Development server configuration */
70
78
  dev?: {
71
79
  /** Port for development server (default: 3000) */
@@ -78,6 +86,56 @@ export interface StatiConfig {
78
86
  /** Build lifecycle hooks */
79
87
  hooks?: BuildHooks;
80
88
  }
89
+ /**
90
+ * SEO configuration for the site.
91
+ * Controls automatic SEO metadata injection and site-wide defaults.
92
+ */
93
+ export interface SEOConfig {
94
+ /** Default author for all pages (can be overridden per-page) */
95
+ defaultAuthor?: AuthorConfig;
96
+ /** Automatically inject SEO tags into <head> if not present (default: true) */
97
+ autoInject?: boolean;
98
+ /** Enable debug logging for SEO generation (default: false) */
99
+ debug?: boolean;
100
+ }
101
+ /**
102
+ * Robots.txt generation configuration.
103
+ * Controls how the robots.txt file is generated.
104
+ */
105
+ export interface RobotsTxtConfig {
106
+ /** Enable robots.txt generation (default: false) */
107
+ enabled?: boolean;
108
+ /**
109
+ * User agent specific rules.
110
+ * Each entry defines rules for a specific user agent.
111
+ *
112
+ * @example
113
+ * ```typescript
114
+ * userAgents: [
115
+ * {
116
+ * userAgent: 'Googlebot',
117
+ * allow: ['/public/'],
118
+ * disallow: ['/admin/']
119
+ * }
120
+ * ]
121
+ * ```
122
+ */
123
+ userAgents?: Array<{
124
+ userAgent: string;
125
+ allow?: string[];
126
+ disallow?: string[];
127
+ }>;
128
+ /** Global allow rules (applies to all user agents) */
129
+ allow?: string[];
130
+ /** Global disallow rules (applies to all user agents) */
131
+ disallow?: string[];
132
+ /** Crawl delay in seconds (time between requests) */
133
+ crawlDelay?: number;
134
+ /** Sitemap URL or boolean to auto-include sitemap.xml (default: true if sitemap enabled) */
135
+ sitemap?: string | boolean;
136
+ /** Custom lines to append to robots.txt */
137
+ customLines?: string[];
138
+ }
81
139
  /**
82
140
  * Build context passed to build lifecycle hooks.
83
141
  * Contains the full configuration and all loaded pages.
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"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"}
@@ -32,15 +32,192 @@ export interface FrontMatter {
32
32
  order?: number;
33
33
  /** Publication date as ISO string */
34
34
  publishedAt?: string;
35
+ /** Publication date (alias for publishedAt) */
36
+ date?: string;
37
+ /** Last updated date as ISO string */
38
+ updated?: string;
35
39
  /** Custom cache TTL in seconds (overrides global ISG settings) */
36
40
  ttlSeconds?: number;
37
41
  /** Custom max age cap in days (overrides global ISG settings) */
38
42
  maxAgeCapDays?: number;
39
43
  /** Whether the page is a draft (excludes from build) */
40
44
  draft?: boolean;
45
+ /** SEO configuration for the page */
46
+ seo?: SEOMetadata;
47
+ /** Sitemap configuration for the page */
48
+ sitemap?: SitemapMetadata;
41
49
  /** Additional custom properties */
42
50
  [key: string]: unknown;
43
51
  }
52
+ /**
53
+ * SEO metadata configuration for a page.
54
+ * Provides comprehensive control over meta tags, Open Graph, Twitter Cards, and structured data.
55
+ *
56
+ * @example
57
+ * ```typescript
58
+ * const seo: SEOMetadata = {
59
+ * title: 'Custom SEO Title',
60
+ * description: 'A compelling description for search engines',
61
+ * keywords: ['seo', 'static-site', 'performance'],
62
+ * canonical: 'https://example.com/canonical-url',
63
+ * openGraph: {
64
+ * type: 'article',
65
+ * image: { url: '/og-image.jpg', alt: 'Article preview' }
66
+ * }
67
+ * };
68
+ * ```
69
+ */
70
+ export interface SEOMetadata {
71
+ /** Override page title for SEO */
72
+ title?: string;
73
+ /** Meta description (150-160 chars recommended) */
74
+ description?: string;
75
+ /** Keywords for the page */
76
+ keywords?: string[];
77
+ /** Canonical URL */
78
+ canonical?: string;
79
+ /** Robots meta directives */
80
+ robots?: string | RobotsConfig;
81
+ /** Open Graph configuration */
82
+ openGraph?: OpenGraphConfig;
83
+ /** Twitter Card configuration */
84
+ twitter?: TwitterCardConfig;
85
+ /** JSON-LD structured data (will be sanitized and validated) */
86
+ structuredData?: Record<string, unknown>;
87
+ /** Author override for this page */
88
+ author?: string | AuthorConfig;
89
+ /** No-index flag */
90
+ noindex?: boolean;
91
+ /** Priority for sitemap (0.0-1.0) */
92
+ priority?: number;
93
+ /** Change frequency for sitemap */
94
+ changeFreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never';
95
+ }
96
+ /**
97
+ * Sitemap metadata configuration for a page.
98
+ * Controls how the page appears in the XML sitemap.
99
+ */
100
+ export interface SitemapMetadata {
101
+ /** Exclude this page from the sitemap */
102
+ exclude?: boolean;
103
+ /** Last modification date (ISO string or Date) */
104
+ lastmod?: string | Date;
105
+ /** Change frequency hint */
106
+ changefreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never';
107
+ /** Priority of this URL relative to others (0.0-1.0) */
108
+ priority?: number;
109
+ }
110
+ /**
111
+ * Robots meta tag configuration.
112
+ * Controls how search engines crawl and index the page.
113
+ */
114
+ export interface RobotsConfig {
115
+ /** Allow search engines to index this page */
116
+ index?: boolean;
117
+ /** Allow search engines to follow links on this page */
118
+ follow?: boolean;
119
+ /** Allow search engines to show cached version */
120
+ archive?: boolean;
121
+ /** Allow search engines to show snippets */
122
+ snippet?: boolean;
123
+ /** Allow search engines to index images */
124
+ imageindex?: boolean;
125
+ /** Allow search engines to translate this page */
126
+ translate?: boolean;
127
+ /** Maximum snippet length in characters */
128
+ maxSnippet?: number;
129
+ /** Maximum image preview size */
130
+ maxImagePreview?: 'none' | 'standard' | 'large';
131
+ /** Maximum video preview length in seconds */
132
+ maxVideoPreview?: number;
133
+ }
134
+ /**
135
+ * Open Graph protocol configuration.
136
+ * Used by social media platforms for rich previews.
137
+ *
138
+ * @see https://ogp.me/
139
+ */
140
+ export interface OpenGraphConfig {
141
+ /** Open Graph title */
142
+ title?: string;
143
+ /** Open Graph type (e.g., 'website', 'article') */
144
+ type?: string;
145
+ /** Open Graph description */
146
+ description?: string;
147
+ /** Open Graph image (URL string or full image object) */
148
+ image?: string | OpenGraphImage;
149
+ /** Open Graph URL */
150
+ url?: string;
151
+ /** Site name */
152
+ siteName?: string;
153
+ /** Locale (e.g., 'en_US') */
154
+ locale?: string;
155
+ /** Article-specific metadata */
156
+ article?: OpenGraphArticle;
157
+ }
158
+ /**
159
+ * Open Graph image configuration.
160
+ */
161
+ export interface OpenGraphImage {
162
+ /** Image URL */
163
+ url: string;
164
+ /** Image alt text */
165
+ alt?: string;
166
+ /** Image width in pixels */
167
+ width?: number;
168
+ /** Image height in pixels */
169
+ height?: number;
170
+ }
171
+ /**
172
+ * Open Graph article metadata.
173
+ * Used for article-type Open Graph content.
174
+ */
175
+ export interface OpenGraphArticle {
176
+ /** Publication timestamp */
177
+ publishedTime?: string;
178
+ /** Last modification timestamp */
179
+ modifiedTime?: string;
180
+ /** Article author */
181
+ author?: string;
182
+ /** Article section/category */
183
+ section?: string;
184
+ /** Article tags */
185
+ tags?: string[];
186
+ }
187
+ /**
188
+ * Twitter Card configuration.
189
+ * Controls how content appears when shared on Twitter.
190
+ *
191
+ * @see https://developer.twitter.com/en/docs/twitter-for-websites/cards/overview/abouts-cards
192
+ */
193
+ export interface TwitterCardConfig {
194
+ /** Twitter card type */
195
+ card?: 'summary' | 'summary_large_image' | 'app' | 'player';
196
+ /** @username of website */
197
+ site?: string;
198
+ /** @username of content creator */
199
+ creator?: string;
200
+ /** Title for the card */
201
+ title?: string;
202
+ /** Description for the card */
203
+ description?: string;
204
+ /** Image URL for the card */
205
+ image?: string;
206
+ /** Image alt text */
207
+ imageAlt?: string;
208
+ }
209
+ /**
210
+ * Author configuration.
211
+ * Represents content author information.
212
+ */
213
+ export interface AuthorConfig {
214
+ /** Author's full name */
215
+ name: string;
216
+ /** Author's email address */
217
+ email?: string;
218
+ /** Author's website or profile URL */
219
+ url?: string;
220
+ }
44
221
  /**
45
222
  * Represents a single page in the static site.
46
223
  * Contains all metadata, content, and URL information for a page.
@@ -106,6 +283,8 @@ export interface CollectionData {
106
283
  export interface TemplateContext {
107
284
  /** Site configuration and metadata */
108
285
  site: import('./config.js').SiteConfig;
286
+ /** Full Stati configuration (includes site, markdown, eta, etc.) */
287
+ config: import('./config.js').StatiConfig;
109
288
  /** Current page data including frontmatter and content */
110
289
  page: {
111
290
  path: string;
@@ -120,5 +299,7 @@ export interface TemplateContext {
120
299
  partials: Record<string, string>;
121
300
  /** Collection data for index pages (only available on collection index pages) */
122
301
  collection?: CollectionData;
302
+ /** Additional properties that may be added dynamically (e.g., custom filters, helpers) */
303
+ [key: string]: unknown;
123
304
  }
124
305
  //# sourceMappingURL=content.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../src/types/content.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,WAAW;IAC1B,qCAAqC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uCAAuC;IACvC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,2CAA2C;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wDAAwD;IACxD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,mCAAmC;IACnC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,SAAS;IACxB,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,+CAA+C;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,mCAAmC;IACnC,WAAW,EAAE,WAAW,CAAC;IACzB,4BAA4B;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,WAAW,CAAC,EAAE,IAAI,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,0CAA0C;IAC1C,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,2CAA2C;IAC3C,QAAQ,EAAE,SAAS,EAAE,CAAC;IACtB,6DAA6D;IAC7D,WAAW,EAAE,SAAS,EAAE,CAAC;IACzB,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;IACxC,0BAA0B;IAC1B,QAAQ,EAAE;QACR,0CAA0C;QAC1C,UAAU,EAAE,MAAM,CAAC;QACnB,yCAAyC;QACzC,WAAW,EAAE,OAAO,CAAC;QACrB,6BAA6B;QAC7B,cAAc,EAAE,MAAM,CAAC;QACvB,iDAAiD;QACjD,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;CACH;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,sCAAsC;IACtC,IAAI,EAAE,OAAO,aAAa,EAAE,UAAU,CAAC;IACvC,0DAA0D;IAC1D,IAAI,EAAE;QACJ,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,gCAAgC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,2BAA2B;IAC3B,UAAU,EAAE,OAAO,iBAAiB,EAAE,OAAO,EAAE,CAAC;IAChD,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,iFAAiF;IACjF,UAAU,CAAC,EAAE,cAAc,CAAC;CAC7B"}
1
+ {"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../src/types/content.ts"],"names":[],"mappings":"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"}
@@ -3,8 +3,11 @@
3
3
  * This file provides a single entry point for importing types
4
4
  */
5
5
  export type { AgingRule, ISGConfig, CacheEntry, CacheManifest } from './isg.js';
6
- export type { SiteConfig, StatiConfig, BuildContext, PageContext, BuildHooks, BuildStats, } from './config.js';
7
- export type { FrontMatter, PageModel, CollectionData, TemplateContext } from './content.js';
6
+ export type { SiteConfig, StatiConfig, BuildContext, PageContext, BuildHooks, BuildStats, SEOConfig, RobotsTxtConfig, } from './config.js';
7
+ export type { FrontMatter, PageModel, CollectionData, TemplateContext, SEOMetadata, SitemapMetadata, RobotsConfig, OpenGraphConfig, OpenGraphImage, OpenGraphArticle, TwitterCardConfig, AuthorConfig, } from './content.js';
8
+ export type { SEOContext, SEOValidationResult } from './seo.js';
9
+ export { SEOTagType } from './seo.js';
10
+ export type { ChangeFrequency, SitemapEntry, SitemapConfig, SitemapGenerationResult, } from './sitemap.js';
8
11
  export type { NavNode } from './navigation.js';
9
12
  export type { Logger } from './logging.js';
10
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGhF,YAAY,EACV,UAAU,EACV,WAAW,EACX,YAAY,EACZ,WAAW,EACX,UAAU,EACV,UAAU,GACX,MAAM,aAAa,CAAC;AAGrB,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAG5F,YAAY,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAG/C,YAAY,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGhF,YAAY,EACV,UAAU,EACV,WAAW,EACX,YAAY,EACZ,WAAW,EACX,UAAU,EACV,UAAU,EACV,SAAS,EACT,eAAe,GAChB,MAAM,aAAa,CAAC;AAGrB,YAAY,EACV,WAAW,EACX,SAAS,EACT,cAAc,EACd,eAAe,EACf,WAAW,EACX,eAAe,EACf,YAAY,EACZ,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,GACb,MAAM,cAAc,CAAC;AAGtB,YAAY,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAGtC,YAAY,EACV,eAAe,EACf,YAAY,EACZ,aAAa,EACb,uBAAuB,GACxB,MAAM,cAAc,CAAC;AAGtB,YAAY,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAG/C,YAAY,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC"}
@@ -2,4 +2,4 @@
2
2
  * Centralized exports for all type definitions
3
3
  * This file provides a single entry point for importing types
4
4
  */
5
- export {};
5
+ export { SEOTagType } from './seo.js';