@stati/core 1.10.3 → 1.11.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 (38) hide show
  1. package/dist/core/build.d.ts.map +1 -1
  2. package/dist/core/build.js +52 -4
  3. package/dist/core/invalidate.d.ts.map +1 -1
  4. package/dist/core/invalidate.js +3 -110
  5. package/dist/core/utils/glob-patterns.d.ts +40 -0
  6. package/dist/core/utils/glob-patterns.d.ts.map +1 -0
  7. package/dist/core/utils/glob-patterns.js +127 -0
  8. package/dist/core/utils/index.d.ts +1 -0
  9. package/dist/core/utils/index.d.ts.map +1 -1
  10. package/dist/core/utils/index.js +2 -0
  11. package/dist/index.d.ts +3 -0
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +1 -0
  14. package/dist/rss/generator.d.ts +26 -0
  15. package/dist/rss/generator.d.ts.map +1 -0
  16. package/dist/rss/generator.js +331 -0
  17. package/dist/rss/index.d.ts +8 -0
  18. package/dist/rss/index.d.ts.map +1 -0
  19. package/dist/rss/index.js +6 -0
  20. package/dist/rss/utils/index.d.ts +6 -0
  21. package/dist/rss/utils/index.d.ts.map +1 -0
  22. package/dist/rss/utils/index.js +5 -0
  23. package/dist/rss/utils/pattern-matching.d.ts +33 -0
  24. package/dist/rss/utils/pattern-matching.d.ts.map +1 -0
  25. package/dist/rss/utils/pattern-matching.js +87 -0
  26. package/dist/rss/validation.d.ts +30 -0
  27. package/dist/rss/validation.d.ts.map +1 -0
  28. package/dist/rss/validation.js +124 -0
  29. package/dist/seo/sitemap.d.ts.map +1 -1
  30. package/dist/seo/sitemap.js +3 -52
  31. package/dist/types/config.d.ts +2 -0
  32. package/dist/types/config.d.ts.map +1 -1
  33. package/dist/types/index.d.ts +1 -0
  34. package/dist/types/index.d.ts.map +1 -1
  35. package/dist/types/rss.d.ts +247 -0
  36. package/dist/types/rss.d.ts.map +1 -0
  37. package/dist/types/rss.js +4 -0
  38. package/package.json +1 -1
@@ -3,6 +3,7 @@
3
3
  * @module seo/sitemap
4
4
  */
5
5
  import { escapeHtml, resolveAbsoluteUrl } from './utils/index.js';
6
+ import { urlMatchesAnyPattern } from '../rss/utils/index.js';
6
7
  /**
7
8
  * Maximum entries per sitemap file (per sitemap.org spec)
8
9
  */
@@ -42,39 +43,6 @@ function validateChangeFreq(changefreq) {
42
43
  }
43
44
  return undefined;
44
45
  }
45
- /**
46
- * Escapes regex special characters in a string, except glob wildcards
47
- * @param str - String to escape
48
- * @returns String with regex special characters escaped
49
- */
50
- function escapeRegexExceptGlob(str) {
51
- // Escape all regex special characters except * and ?
52
- return str.replace(/[.+^${}()|[\]\\]/g, '\\$&');
53
- }
54
- /**
55
- * Checks if a page URL matches a list of patterns.
56
- * @param url - The URL to check.
57
- * @param patterns - An array of glob-style patterns.
58
- * @returns `true` if the URL matches any pattern, `false` otherwise.
59
- */
60
- function urlMatchesAnyPattern(url, patterns) {
61
- for (const pattern of patterns) {
62
- // Simple glob patterns
63
- if (pattern.includes('*') || pattern.includes('?')) {
64
- // Escape regex special characters first, then convert glob wildcards
65
- const escapedPattern = escapeRegexExceptGlob(pattern);
66
- const regexPattern = escapedPattern.replace(/\*/g, '.*').replace(/\?/g, '.');
67
- const regex = new RegExp('^' + regexPattern + '$');
68
- if (regex.test(url)) {
69
- return true;
70
- }
71
- }
72
- else if (url === pattern || url.startsWith(pattern)) {
73
- return true;
74
- }
75
- }
76
- return false;
77
- }
78
46
  /**
79
47
  * Checks if a page matches exclude patterns
80
48
  * @param page - Page to check
@@ -113,25 +81,8 @@ function determinePriority(page, rules, defaultPriority = 0.5) {
113
81
  // Check each rule in order (first match wins)
114
82
  for (const rule of rules) {
115
83
  const pattern = rule.pattern;
116
- if (pattern.includes('*') || pattern.includes('?')) {
117
- // Escape regex special characters first, then convert glob wildcards
118
- const escapedPattern = escapeRegexExceptGlob(pattern);
119
- const regexPattern = escapedPattern.replace(/\*/g, '.*').replace(/\?/g, '.');
120
- const regex = new RegExp('^' + regexPattern + '$');
121
- if (regex.test(page.url)) {
122
- return validatePriority(rule.priority);
123
- }
124
- }
125
- else {
126
- // For non-glob patterns, check exact match or path prefix
127
- if (page.url === pattern) {
128
- return validatePriority(rule.priority);
129
- }
130
- // For path prefix matching, ensure we match at path boundaries
131
- // e.g., "/api" matches "/api/foo" but "/" only matches "/" exactly
132
- if (pattern !== '/' && page.url.startsWith(pattern + '/')) {
133
- return validatePriority(rule.priority);
134
- }
84
+ if (urlMatchesAnyPattern(page.url, [pattern])) {
85
+ return validatePriority(rule.priority);
135
86
  }
136
87
  }
137
88
  return defaultPriority;
@@ -74,6 +74,8 @@ export interface StatiConfig {
74
74
  sitemap?: SitemapConfig;
75
75
  /** Robots.txt generation configuration */
76
76
  robots?: RobotsTxtConfig;
77
+ /** RSS feed generation configuration */
78
+ rss?: import('./rss.js').RSSConfig;
77
79
  /** Development server configuration */
78
80
  dev?: {
79
81
  /** Port for development server (default: 3000) */
@@ -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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"}
@@ -8,6 +8,7 @@ export type { FrontMatter, PageModel, CollectionData, TemplateContext, SEOMetada
8
8
  export type { SEOContext, SEOValidationResult } from './seo.js';
9
9
  export { SEOTagType } from './seo.js';
10
10
  export type { ChangeFrequency, SitemapEntry, SitemapConfig, SitemapGenerationResult, } from './sitemap.js';
11
+ export type { RSSConfig, RSSFeedConfig, RSSGenerationResult } from './rss.js';
11
12
  export type { NavNode } from './navigation.js';
12
13
  export type { Logger } from './logging.js';
13
14
  //# 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,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"}
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,SAAS,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAG9E,YAAY,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAG/C,YAAY,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,247 @@
1
+ /**
2
+ * RSS feed generation type definitions
3
+ */
4
+ import type { PageModel } from './content.js';
5
+ import type { StatiConfig } from './config.js';
6
+ /**
7
+ * Configuration for a single RSS feed.
8
+ * Defines feed metadata, content selection, and item mapping.
9
+ */
10
+ export interface RSSFeedConfig {
11
+ /**
12
+ * Filename for the RSS feed (e.g., 'feed.xml', 'blog.xml')
13
+ * Will be written to the output directory.
14
+ */
15
+ filename: string;
16
+ /**
17
+ * Feed title (required)
18
+ * @example 'My Blog Posts'
19
+ */
20
+ title: string;
21
+ /**
22
+ * Feed description (required)
23
+ * @example 'Latest articles from my blog'
24
+ */
25
+ description: string;
26
+ /**
27
+ * Feed link - the URL of the website (not the feed itself)
28
+ * If not provided, uses site.baseUrl from config
29
+ * @example 'https://example.com'
30
+ */
31
+ link?: string;
32
+ /**
33
+ * Feed language code (optional)
34
+ * @example 'en-US'
35
+ */
36
+ language?: string;
37
+ /**
38
+ * Copyright notice (optional)
39
+ * @example 'Copyright 2024 My Company'
40
+ */
41
+ copyright?: string;
42
+ /**
43
+ * Managing editor email (optional)
44
+ * @example 'editor@example.com (Jane Doe)'
45
+ */
46
+ managingEditor?: string;
47
+ /**
48
+ * Webmaster email (optional)
49
+ * @example 'webmaster@example.com (John Smith)'
50
+ */
51
+ webMaster?: string;
52
+ /**
53
+ * Feed category (optional)
54
+ * @example 'Technology'
55
+ */
56
+ category?: string;
57
+ /**
58
+ * TTL (Time To Live) in minutes - how long feed can be cached
59
+ * @example 60
60
+ */
61
+ ttl?: number;
62
+ /**
63
+ * Image for the feed (optional)
64
+ */
65
+ image?: {
66
+ /** URL of the image */
67
+ url: string;
68
+ /** Alt text for the image */
69
+ title: string;
70
+ /** URL the image links to */
71
+ link: string;
72
+ /** Width in pixels (max 144) */
73
+ width?: number;
74
+ /** Height in pixels (max 400) */
75
+ height?: number;
76
+ };
77
+ /**
78
+ * Content directory patterns to include in this feed.
79
+ * Uses glob patterns to match content files.
80
+ * @example ['blog/**', 'news/**']
81
+ */
82
+ contentPatterns?: string[];
83
+ /**
84
+ * Glob patterns for pages to exclude from feed
85
+ * @example ['**\/draft-*', '**\/index.md']
86
+ */
87
+ excludePatterns?: string[];
88
+ /**
89
+ * Custom filter function for fine-grained control over item inclusion
90
+ * @param page - The page to potentially include
91
+ * @returns true to include, false to exclude
92
+ */
93
+ filter?: (page: PageModel) => boolean;
94
+ /**
95
+ * Maximum number of items to include in the feed
96
+ * @example 20
97
+ */
98
+ maxItems?: number;
99
+ /**
100
+ * How to sort items (default: by publishedAt date, newest first)
101
+ * - 'date-desc': Newest first (default)
102
+ * - 'date-asc': Oldest first
103
+ * - 'title-asc': Alphabetically by title
104
+ * - 'title-desc': Reverse alphabetically by title
105
+ * - 'custom': Use the sortFn function
106
+ */
107
+ sortBy?: 'date-desc' | 'date-asc' | 'title-asc' | 'title-desc' | 'custom';
108
+ /**
109
+ * Custom sort function when sortBy is 'custom'
110
+ * @param a - First page to compare
111
+ * @param b - Second page to compare
112
+ * @returns Negative if a < b, positive if a > b, 0 if equal
113
+ */
114
+ sortFn?: (a: PageModel, b: PageModel) => number;
115
+ /**
116
+ * Field mappings for RSS item elements.
117
+ * Maps RSS fields to page properties or functions.
118
+ */
119
+ itemMapping?: {
120
+ /**
121
+ * Title for each item
122
+ * Can be:
123
+ * - A string property name from frontMatter (e.g., 'title')
124
+ * - A function that returns the title
125
+ * @default 'title'
126
+ */
127
+ title?: string | ((page: PageModel) => string);
128
+ /**
129
+ * Description for each item
130
+ * Can be:
131
+ * - A string property name from frontMatter (e.g., 'description', 'excerpt')
132
+ * - A function that returns the description
133
+ * @default 'description'
134
+ */
135
+ description?: string | ((page: PageModel) => string);
136
+ /**
137
+ * Link for each item (URL to the page)
138
+ * By default uses the page's URL
139
+ * Can be customized with a function
140
+ */
141
+ link?: (page: PageModel, config: StatiConfig) => string;
142
+ /**
143
+ * Publication date for each item
144
+ * Can be:
145
+ * - A string property name from frontMatter (e.g., 'publishedAt', 'date')
146
+ * - A function that returns a Date or string
147
+ * @default 'publishedAt' or 'date'
148
+ */
149
+ pubDate?: string | ((page: PageModel) => Date | string);
150
+ /**
151
+ * Author for each item
152
+ * Can be:
153
+ * - A string property name from frontMatter (e.g., 'author')
154
+ * - A function that returns the author string
155
+ */
156
+ author?: string | ((page: PageModel) => string | undefined);
157
+ /**
158
+ * Category/categories for each item
159
+ * Can be:
160
+ * - A string property name from frontMatter (e.g., 'tags', 'category')
161
+ * - A function that returns string or array of strings
162
+ */
163
+ category?: string | ((page: PageModel) => string | string[] | undefined);
164
+ /**
165
+ * GUID (globally unique identifier) for each item
166
+ * By default uses the page URL
167
+ * Can be customized with a function
168
+ */
169
+ guid?: (page: PageModel, config: StatiConfig) => string;
170
+ /**
171
+ * Whether to include full HTML content in description
172
+ * If true, uses the rendered HTML content
173
+ * If false, uses description field only
174
+ * @default false
175
+ */
176
+ includeContent?: boolean;
177
+ };
178
+ /**
179
+ * Custom enclosures (e.g., podcast episodes, media files)
180
+ * Function that returns enclosure data for a page, or undefined if none
181
+ */
182
+ enclosure?: (page: PageModel) => {
183
+ url: string;
184
+ length: number;
185
+ type: string;
186
+ } | undefined;
187
+ /**
188
+ * Custom namespaces to add to the RSS feed
189
+ * @example { 'content': 'http://purl.org/rss/1.0/modules/content/' }
190
+ */
191
+ namespaces?: Record<string, string>;
192
+ /**
193
+ * Custom XML elements to add to each item
194
+ * Useful for extending RSS with custom tags
195
+ * @example (page) => ({ 'customTag': page.frontMatter.customValue })
196
+ */
197
+ customItemElements?: (page: PageModel) => Record<string, string | number | boolean | undefined>;
198
+ }
199
+ /**
200
+ * Main RSS configuration.
201
+ * Can define multiple feeds with different content and settings.
202
+ */
203
+ export interface RSSConfig {
204
+ /**
205
+ * Enable RSS feed generation (default: false)
206
+ * RSS feeds are only generated in production builds, not in dev mode
207
+ */
208
+ enabled?: boolean;
209
+ /**
210
+ * Array of feed configurations.
211
+ * Each feed can target different content with different settings.
212
+ *
213
+ * @example
214
+ * ```typescript
215
+ * feeds: [
216
+ * {
217
+ * filename: 'feed.xml',
218
+ * title: 'My Blog',
219
+ * description: 'Latest posts',
220
+ * contentPatterns: ['blog/**']
221
+ * },
222
+ * {
223
+ * filename: 'news.xml',
224
+ * title: 'News Feed',
225
+ * description: 'Latest news',
226
+ * contentPatterns: ['news/**']
227
+ * }
228
+ * ]
229
+ * ```
230
+ */
231
+ feeds: RSSFeedConfig[];
232
+ }
233
+ /**
234
+ * Result of RSS feed generation.
235
+ * Contains metadata about the generated feed.
236
+ */
237
+ export interface RSSGenerationResult {
238
+ /** Filename of the generated feed */
239
+ filename: string;
240
+ /** Number of items in the feed */
241
+ itemCount: number;
242
+ /** Size of the feed in bytes */
243
+ sizeInBytes: number;
244
+ /** Generated RSS XML content */
245
+ xml: string;
246
+ }
247
+ //# sourceMappingURL=rss.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rss.d.ts","sourceRoot":"","sources":["../../src/types/rss.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * RSS feed generation type definitions
3
+ */
4
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stati/core",
3
- "version": "1.10.3",
3
+ "version": "1.11.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",