@gravito/constellation 2.0.0 → 3.0.1
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.
- package/dist/index.cjs +28 -17
- package/dist/index.d.cts +905 -29
- package/dist/index.d.ts +905 -29
- package/dist/index.js +28 -17
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,144 +1,507 @@
|
|
|
1
1
|
import { Job } from '@gravito/stream';
|
|
2
|
-
import { PlanetCore } from '@gravito/core';
|
|
2
|
+
import { GravitoOrbit, PlanetCore } from '@gravito/core';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Supported change frequency values for sitemap entries.
|
|
6
|
+
*
|
|
7
|
+
* @public
|
|
8
|
+
* @since 3.0.0
|
|
9
|
+
*/
|
|
4
10
|
type ChangeFreq = 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never';
|
|
11
|
+
/**
|
|
12
|
+
* Represents an alternate language or regional version of a URL.
|
|
13
|
+
*
|
|
14
|
+
* @public
|
|
15
|
+
* @since 3.0.0
|
|
16
|
+
*/
|
|
5
17
|
interface AlternateUrl {
|
|
18
|
+
/** The language code (e.g., 'en', 'zh-TW') or 'x-default'. */
|
|
6
19
|
lang: string;
|
|
20
|
+
/** The full URL of the alternate version. */
|
|
7
21
|
url: string;
|
|
8
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Image metadata for a sitemap entry.
|
|
25
|
+
*
|
|
26
|
+
* @public
|
|
27
|
+
* @since 3.0.0
|
|
28
|
+
*/
|
|
9
29
|
interface SitemapImage {
|
|
30
|
+
/** The full URL of the image. */
|
|
10
31
|
loc: string;
|
|
32
|
+
/** The title of the image. */
|
|
11
33
|
title?: string | undefined;
|
|
34
|
+
/** A caption for the image. */
|
|
12
35
|
caption?: string | undefined;
|
|
36
|
+
/** The geographic location of the image. */
|
|
13
37
|
geo_location?: string | undefined;
|
|
38
|
+
/** A URL to the license for the image. */
|
|
14
39
|
license?: string | undefined;
|
|
15
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Video metadata for a sitemap entry.
|
|
43
|
+
*
|
|
44
|
+
* @public
|
|
45
|
+
* @since 3.0.0
|
|
46
|
+
*/
|
|
16
47
|
interface SitemapVideo {
|
|
48
|
+
/** The URL of the video thumbnail. */
|
|
17
49
|
thumbnail_loc: string;
|
|
50
|
+
/** The title of the video. */
|
|
18
51
|
title: string;
|
|
52
|
+
/** A description of the video. */
|
|
19
53
|
description: string;
|
|
54
|
+
/** The URL of the actual video file. */
|
|
20
55
|
content_loc?: string | undefined;
|
|
56
|
+
/** The URL of the video player. */
|
|
21
57
|
player_loc?: string | undefined;
|
|
58
|
+
/** Duration of the video in seconds. */
|
|
22
59
|
duration?: number | undefined;
|
|
60
|
+
/** When the video will no longer be available. */
|
|
23
61
|
expiration_date?: Date | string | undefined;
|
|
62
|
+
/** Rating of the video (0.0 to 5.0). */
|
|
24
63
|
rating?: number | undefined;
|
|
64
|
+
/** Number of times the video has been viewed. */
|
|
25
65
|
view_count?: number | undefined;
|
|
66
|
+
/** When the video was first published. */
|
|
26
67
|
publication_date?: Date | string | undefined;
|
|
68
|
+
/** Whether the video is suitable for children. */
|
|
27
69
|
family_friendly?: 'yes' | 'no' | undefined;
|
|
70
|
+
/** Tags associated with the video. */
|
|
28
71
|
tag?: string[] | undefined;
|
|
72
|
+
/** The category of the video. */
|
|
29
73
|
category?: string | undefined;
|
|
74
|
+
/** Regional restrictions for the video. */
|
|
30
75
|
restriction?: {
|
|
31
76
|
relationship: 'allow' | 'deny';
|
|
32
77
|
countries: string[];
|
|
33
78
|
} | undefined;
|
|
34
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* News metadata for a sitemap entry.
|
|
82
|
+
*
|
|
83
|
+
* @public
|
|
84
|
+
* @since 3.0.0
|
|
85
|
+
*/
|
|
35
86
|
interface SitemapNews {
|
|
87
|
+
/** The publication that the news article belongs to. */
|
|
36
88
|
publication: {
|
|
89
|
+
/** Name of the news publication. */
|
|
37
90
|
name: string;
|
|
91
|
+
/** Language of the news publication (ISO 639 code). */
|
|
38
92
|
language: string;
|
|
39
93
|
};
|
|
94
|
+
/** The publication date of the news article. */
|
|
40
95
|
publication_date: Date | string;
|
|
96
|
+
/** The title of the news article. */
|
|
41
97
|
title: string;
|
|
98
|
+
/** Genres of the news article (e.g., 'PressRelease', 'Blog'). */
|
|
42
99
|
genres?: string | undefined;
|
|
100
|
+
/** Keywords for the news article. */
|
|
43
101
|
keywords?: string[] | undefined;
|
|
102
|
+
/** Stock tickers for the news article. */
|
|
44
103
|
stock_tickers?: string[] | undefined;
|
|
45
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Represents a single URL entry in an XML sitemap.
|
|
107
|
+
*
|
|
108
|
+
* Supports standard sitemap properties as well as Google-specific extensions
|
|
109
|
+
* for images, videos, and news.
|
|
110
|
+
*
|
|
111
|
+
* @public
|
|
112
|
+
* @since 3.0.0
|
|
113
|
+
*/
|
|
46
114
|
interface SitemapEntry {
|
|
115
|
+
/** The full URL of the page including protocol and domain. */
|
|
47
116
|
url: string;
|
|
117
|
+
/** The date of last modification of the page. */
|
|
48
118
|
lastmod?: Date | string | undefined;
|
|
119
|
+
/** How frequently the page is likely to change. */
|
|
49
120
|
changefreq?: ChangeFreq | undefined;
|
|
121
|
+
/** The priority of this URL relative to other URLs on your site (0.0 to 1.0). @default 0.5 */
|
|
50
122
|
priority?: number | undefined;
|
|
123
|
+
/** Alternate language or regional versions of this URL (i18n). */
|
|
51
124
|
alternates?: AlternateUrl[] | undefined;
|
|
125
|
+
/** Image information associated with this URL. */
|
|
52
126
|
images?: SitemapImage[] | undefined;
|
|
127
|
+
/** Video information associated with this URL. */
|
|
53
128
|
videos?: SitemapVideo[] | undefined;
|
|
129
|
+
/** News-specific information for this URL. */
|
|
54
130
|
news?: SitemapNews | undefined;
|
|
131
|
+
/** Optional redirect metadata for SEO and tracking purposes. */
|
|
55
132
|
redirect?: {
|
|
133
|
+
/** The source URL path that redirects to this entry. */
|
|
56
134
|
from: string;
|
|
135
|
+
/** The destination URL path. */
|
|
57
136
|
to: string;
|
|
137
|
+
/** The HTTP redirect status code. */
|
|
58
138
|
type: 301 | 302;
|
|
139
|
+
/** The preferred canonical URL for this page. */
|
|
59
140
|
canonical?: string;
|
|
60
141
|
};
|
|
61
142
|
}
|
|
143
|
+
/**
|
|
144
|
+
* Represents an entry in a sitemap index file.
|
|
145
|
+
*
|
|
146
|
+
* @public
|
|
147
|
+
* @since 3.0.0
|
|
148
|
+
*/
|
|
62
149
|
interface SitemapIndexEntry {
|
|
150
|
+
/** URL of the sub-sitemap file. */
|
|
63
151
|
url: string;
|
|
152
|
+
/** Last modification time of the sub-sitemap. */
|
|
64
153
|
lastmod?: Date | string | undefined;
|
|
65
154
|
}
|
|
155
|
+
/**
|
|
156
|
+
* A provider responsible for yielding sitemap entries.
|
|
157
|
+
*
|
|
158
|
+
* Providers can be implemented to scan databases, file systems, or
|
|
159
|
+
* external APIs to discover content that should be included in the sitemap.
|
|
160
|
+
*
|
|
161
|
+
* @public
|
|
162
|
+
* @since 3.0.0
|
|
163
|
+
*/
|
|
66
164
|
interface SitemapProvider {
|
|
165
|
+
/**
|
|
166
|
+
* Generates a collection of sitemap entries.
|
|
167
|
+
*
|
|
168
|
+
* @returns An array, a promise of an array, or an async iterable of sitemap entries.
|
|
169
|
+
*/
|
|
67
170
|
getEntries(): Promise<SitemapEntry[]> | SitemapEntry[] | AsyncIterable<SitemapEntry>;
|
|
68
171
|
}
|
|
172
|
+
/**
|
|
173
|
+
* Configuration for the sitemap XML generation stream.
|
|
174
|
+
*
|
|
175
|
+
* @public
|
|
176
|
+
* @since 3.0.0
|
|
177
|
+
*/
|
|
69
178
|
interface SitemapStreamOptions {
|
|
179
|
+
/** Base domain used to normalize relative URLs. */
|
|
70
180
|
baseUrl: string;
|
|
181
|
+
/** Whether to output formatted and indented XML. @default false */
|
|
71
182
|
pretty?: boolean | undefined;
|
|
72
183
|
}
|
|
184
|
+
/**
|
|
185
|
+
* Persistence layer for storing generated sitemap files.
|
|
186
|
+
*
|
|
187
|
+
* Supports atomic deployments via "shadow" areas and provides hooks for
|
|
188
|
+
* version management and rollbacks.
|
|
189
|
+
*
|
|
190
|
+
* @public
|
|
191
|
+
* @since 3.0.0
|
|
192
|
+
*/
|
|
73
193
|
interface SitemapStorage {
|
|
194
|
+
/**
|
|
195
|
+
* Write sitemap content to the storage backend.
|
|
196
|
+
*
|
|
197
|
+
* @param filename - The destination filename.
|
|
198
|
+
* @param content - The raw XML content.
|
|
199
|
+
*/
|
|
74
200
|
write(filename: string, content: string): Promise<void>;
|
|
201
|
+
/**
|
|
202
|
+
* Read sitemap content from the storage backend.
|
|
203
|
+
*
|
|
204
|
+
* @param filename - The filename to read.
|
|
205
|
+
* @returns The XML content as a string, or null if not found.
|
|
206
|
+
*/
|
|
75
207
|
read(filename: string): Promise<string | null>;
|
|
208
|
+
/**
|
|
209
|
+
* Check if a sitemap file exists in storage.
|
|
210
|
+
*
|
|
211
|
+
* @param filename - The filename to check.
|
|
212
|
+
* @returns True if the file exists, false otherwise.
|
|
213
|
+
*/
|
|
76
214
|
exists(filename: string): Promise<boolean>;
|
|
215
|
+
/**
|
|
216
|
+
* Get the public URL for a given sitemap filename.
|
|
217
|
+
*
|
|
218
|
+
* @param filename - The sitemap filename.
|
|
219
|
+
* @returns The full public URL.
|
|
220
|
+
*/
|
|
77
221
|
getUrl(filename: string): string;
|
|
222
|
+
/**
|
|
223
|
+
* Write content to a non-public staging area for atomic deployment.
|
|
224
|
+
*
|
|
225
|
+
* @param filename - The target filename.
|
|
226
|
+
* @param content - The XML content.
|
|
227
|
+
* @param shadowId - Optional session identifier.
|
|
228
|
+
*/
|
|
78
229
|
writeShadow?(filename: string, content: string, shadowId?: string): Promise<void>;
|
|
230
|
+
/**
|
|
231
|
+
* Commit all staged files in a shadow session to production.
|
|
232
|
+
*
|
|
233
|
+
* @param shadowId - The identifier of the session to commit.
|
|
234
|
+
*/
|
|
79
235
|
commitShadow?(shadowId: string): Promise<void>;
|
|
236
|
+
/**
|
|
237
|
+
* List available archived versions of a specific sitemap.
|
|
238
|
+
*
|
|
239
|
+
* @param filename - The sitemap filename.
|
|
240
|
+
* @returns An array of version identifiers.
|
|
241
|
+
*/
|
|
80
242
|
listVersions?(filename: string): Promise<string[]>;
|
|
243
|
+
/**
|
|
244
|
+
* Revert a sitemap to a previously archived version.
|
|
245
|
+
*
|
|
246
|
+
* @param filename - The sitemap filename.
|
|
247
|
+
* @param version - The version identifier to switch to.
|
|
248
|
+
*/
|
|
81
249
|
switchVersion?(filename: string, version: string): Promise<void>;
|
|
82
250
|
}
|
|
251
|
+
/**
|
|
252
|
+
* Cache interface for storing frequently accessed sitemap fragments.
|
|
253
|
+
*
|
|
254
|
+
* @public
|
|
255
|
+
* @since 3.0.0
|
|
256
|
+
*/
|
|
83
257
|
interface SitemapCache {
|
|
258
|
+
/**
|
|
259
|
+
* Retrieve a cached XML fragment.
|
|
260
|
+
*
|
|
261
|
+
* @param key - The cache key.
|
|
262
|
+
* @returns The cached XML string, or null if miss.
|
|
263
|
+
*/
|
|
84
264
|
get(key: string): Promise<string | null>;
|
|
265
|
+
/**
|
|
266
|
+
* Store an XML fragment in the cache.
|
|
267
|
+
*
|
|
268
|
+
* @param key - The cache key.
|
|
269
|
+
* @param value - The XML content to cache.
|
|
270
|
+
* @param ttl - Optional time-to-live in seconds.
|
|
271
|
+
*/
|
|
85
272
|
set(key: string, value: string, ttl?: number): Promise<void>;
|
|
273
|
+
/**
|
|
274
|
+
* Check if a specific fragment is currently cached.
|
|
275
|
+
*
|
|
276
|
+
* @param key - The cache key.
|
|
277
|
+
* @returns True if hit, false otherwise.
|
|
278
|
+
*/
|
|
86
279
|
has(key: string): Promise<boolean>;
|
|
87
280
|
}
|
|
281
|
+
/**
|
|
282
|
+
* Distributed lock interface to prevent concurrent sitemap generation.
|
|
283
|
+
*
|
|
284
|
+
* @public
|
|
285
|
+
* @since 3.0.0
|
|
286
|
+
*/
|
|
88
287
|
interface SitemapLock {
|
|
288
|
+
/**
|
|
289
|
+
* Attempt to acquire a lock on a resource.
|
|
290
|
+
*
|
|
291
|
+
* @param resource - Identifier for the resource to lock.
|
|
292
|
+
* @param ttl - Lock expiration time in milliseconds.
|
|
293
|
+
* @returns True if the lock was acquired, false otherwise.
|
|
294
|
+
*/
|
|
89
295
|
acquire(resource: string, ttl: number): Promise<boolean>;
|
|
296
|
+
/**
|
|
297
|
+
* Release a previously held lock.
|
|
298
|
+
*
|
|
299
|
+
* @param resource - Identifier for the resource to unlock.
|
|
300
|
+
*/
|
|
90
301
|
release(resource: string): Promise<void>;
|
|
91
302
|
}
|
|
303
|
+
/**
|
|
304
|
+
* Progress tracking data for large-scale sitemap generation jobs.
|
|
305
|
+
*
|
|
306
|
+
* @public
|
|
307
|
+
* @since 3.0.0
|
|
308
|
+
*/
|
|
92
309
|
interface SitemapProgress {
|
|
310
|
+
/** Unique identifier for the generation job. */
|
|
93
311
|
jobId: string;
|
|
312
|
+
/** Current state of the generation process. */
|
|
94
313
|
status: 'pending' | 'processing' | 'completed' | 'failed';
|
|
314
|
+
/** Total number of URLs to be processed. */
|
|
95
315
|
total: number;
|
|
316
|
+
/** Number of URLs already processed. */
|
|
96
317
|
processed: number;
|
|
318
|
+
/** Completion percentage (0 to 100). */
|
|
97
319
|
percentage: number;
|
|
320
|
+
/** Timestamp when the job was started. */
|
|
98
321
|
startTime?: Date;
|
|
322
|
+
/** Timestamp when the job was finished or failed. */
|
|
99
323
|
endTime?: Date;
|
|
324
|
+
/** Error message if the status is 'failed'. */
|
|
100
325
|
error?: string;
|
|
101
326
|
}
|
|
327
|
+
/**
|
|
328
|
+
* Interface for persisting and retrieving sitemap job progress.
|
|
329
|
+
*
|
|
330
|
+
* @public
|
|
331
|
+
* @since 3.0.0
|
|
332
|
+
*/
|
|
102
333
|
interface SitemapProgressStorage {
|
|
334
|
+
/**
|
|
335
|
+
* Retrieve progress for a specific generation job.
|
|
336
|
+
*
|
|
337
|
+
* @param jobId - The job identifier.
|
|
338
|
+
*/
|
|
103
339
|
get(jobId: string): Promise<SitemapProgress | null>;
|
|
340
|
+
/**
|
|
341
|
+
* Initialize or overwrite a progress record.
|
|
342
|
+
*
|
|
343
|
+
* @param jobId - The job identifier.
|
|
344
|
+
* @param progress - The initial progress state.
|
|
345
|
+
*/
|
|
104
346
|
set(jobId: string, progress: SitemapProgress): Promise<void>;
|
|
347
|
+
/**
|
|
348
|
+
* Update specific fields of an existing progress record.
|
|
349
|
+
*
|
|
350
|
+
* @param jobId - The job identifier.
|
|
351
|
+
* @param updates - Object containing fields to update.
|
|
352
|
+
*/
|
|
105
353
|
update(jobId: string, updates: Partial<SitemapProgress>): Promise<void>;
|
|
354
|
+
/**
|
|
355
|
+
* Delete a progress record from storage.
|
|
356
|
+
*
|
|
357
|
+
* @param jobId - The job identifier.
|
|
358
|
+
*/
|
|
106
359
|
delete(jobId: string): Promise<void>;
|
|
360
|
+
/**
|
|
361
|
+
* List recent sitemap generation jobs.
|
|
362
|
+
*
|
|
363
|
+
* @param limit - Maximum number of records to return. @default 100
|
|
364
|
+
* @returns An array of progress records.
|
|
365
|
+
*/
|
|
107
366
|
list(limit?: number): Promise<SitemapProgress[]>;
|
|
108
367
|
}
|
|
368
|
+
/**
|
|
369
|
+
* The nature of a structural change detected in the site.
|
|
370
|
+
*
|
|
371
|
+
* @public
|
|
372
|
+
* @since 3.0.0
|
|
373
|
+
*/
|
|
109
374
|
type ChangeType = 'add' | 'update' | 'remove';
|
|
375
|
+
/**
|
|
376
|
+
* Represents a single structural change detected in the site.
|
|
377
|
+
*
|
|
378
|
+
* @public
|
|
379
|
+
* @since 3.0.0
|
|
380
|
+
*/
|
|
110
381
|
interface SitemapChange {
|
|
382
|
+
/** The nature of the change (add, update, or remove). */
|
|
111
383
|
type: ChangeType;
|
|
384
|
+
/** The target URL that was affected. */
|
|
112
385
|
url: string;
|
|
386
|
+
/** The sitemap entry representation of the URL (for additions and updates). */
|
|
113
387
|
entry?: SitemapEntry;
|
|
388
|
+
/** When the change was detected. */
|
|
114
389
|
timestamp: Date;
|
|
115
390
|
}
|
|
391
|
+
/**
|
|
392
|
+
* Interface for tracking and querying site structure changes over time.
|
|
393
|
+
*
|
|
394
|
+
* Change trackers are used by the `IncrementalGenerator` to perform
|
|
395
|
+
* partial sitemap updates.
|
|
396
|
+
*
|
|
397
|
+
* @public
|
|
398
|
+
* @since 3.0.0
|
|
399
|
+
*/
|
|
116
400
|
interface ChangeTracker {
|
|
401
|
+
/**
|
|
402
|
+
* Record a new site structure change.
|
|
403
|
+
*
|
|
404
|
+
* @param change - The change event to record.
|
|
405
|
+
*/
|
|
117
406
|
track(change: SitemapChange): Promise<void>;
|
|
407
|
+
/**
|
|
408
|
+
* Retrieve all changes recorded since a specific time.
|
|
409
|
+
*
|
|
410
|
+
* @param since - Optional start date for the query.
|
|
411
|
+
* @returns An array of change events.
|
|
412
|
+
*/
|
|
118
413
|
getChanges(since?: Date): Promise<SitemapChange[]>;
|
|
414
|
+
/**
|
|
415
|
+
* Retrieve the full change history for a specific URL.
|
|
416
|
+
*
|
|
417
|
+
* @param url - The URL to query history for.
|
|
418
|
+
* @returns An array of change events.
|
|
419
|
+
*/
|
|
119
420
|
getChangesByUrl(url: string): Promise<SitemapChange[]>;
|
|
421
|
+
/**
|
|
422
|
+
* Purge old change records from storage.
|
|
423
|
+
*
|
|
424
|
+
* @param since - If provided, only records older than this date will be cleared.
|
|
425
|
+
*/
|
|
120
426
|
clear(since?: Date): Promise<void>;
|
|
121
427
|
}
|
|
428
|
+
/**
|
|
429
|
+
* Defines a 301 or 302 redirect rule managed by Constellation.
|
|
430
|
+
*
|
|
431
|
+
* @public
|
|
432
|
+
* @since 3.0.0
|
|
433
|
+
*/
|
|
122
434
|
interface RedirectRule {
|
|
435
|
+
/** The incoming URL path or glob pattern. */
|
|
123
436
|
from: string;
|
|
437
|
+
/** The destination URL path or absolute URL. */
|
|
124
438
|
to: string;
|
|
439
|
+
/** The HTTP status code (301 for permanent, 302 for temporary). */
|
|
125
440
|
type: 301 | 302;
|
|
441
|
+
/** Timestamp when the redirect rule was created. */
|
|
126
442
|
createdAt?: Date;
|
|
127
443
|
}
|
|
444
|
+
/**
|
|
445
|
+
* Manager for registering and resolving redirect rules.
|
|
446
|
+
*
|
|
447
|
+
* @public
|
|
448
|
+
* @since 3.0.0
|
|
449
|
+
*/
|
|
128
450
|
interface RedirectManager {
|
|
451
|
+
/**
|
|
452
|
+
* Register a single redirect rule.
|
|
453
|
+
*
|
|
454
|
+
* @param redirect - The redirect rule to add.
|
|
455
|
+
*/
|
|
129
456
|
register(redirect: RedirectRule): Promise<void>;
|
|
457
|
+
/**
|
|
458
|
+
* Register multiple redirect rules at once.
|
|
459
|
+
*
|
|
460
|
+
* @param redirects - An array of redirect rules.
|
|
461
|
+
*/
|
|
130
462
|
registerBatch(redirects: RedirectRule[]): Promise<void>;
|
|
463
|
+
/**
|
|
464
|
+
* Retrieve a specific redirect rule by its source path.
|
|
465
|
+
*
|
|
466
|
+
* @param from - The source path.
|
|
467
|
+
* @returns The redirect rule, or null if not found.
|
|
468
|
+
*/
|
|
131
469
|
get(from: string): Promise<RedirectRule | null>;
|
|
470
|
+
/**
|
|
471
|
+
* Retrieve all registered redirect rules.
|
|
472
|
+
*
|
|
473
|
+
* @returns An array of all redirect rules.
|
|
474
|
+
*/
|
|
132
475
|
getAll(): Promise<RedirectRule[]>;
|
|
476
|
+
/**
|
|
477
|
+
* Resolve a URL through the redirect table.
|
|
478
|
+
*
|
|
479
|
+
* @param url - The URL to resolve.
|
|
480
|
+
* @param followChains - Whether to recursively resolve if redirects point to other redirects.
|
|
481
|
+
* @param maxChainLength - Maximum depth for chain resolution to prevent infinite loops.
|
|
482
|
+
* @returns The final destination URL, or null if no redirect matches.
|
|
483
|
+
*/
|
|
133
484
|
resolve(url: string, followChains?: boolean, maxChainLength?: number): Promise<string | null>;
|
|
134
485
|
}
|
|
135
486
|
|
|
487
|
+
/**
|
|
488
|
+
* Options for configuring the `MemoryChangeTracker`.
|
|
489
|
+
*
|
|
490
|
+
* @public
|
|
491
|
+
* @since 3.0.0
|
|
492
|
+
*/
|
|
136
493
|
interface MemoryChangeTrackerOptions {
|
|
494
|
+
/** Maximum number of changes to keep in memory. @default 100000 */
|
|
137
495
|
maxChanges?: number;
|
|
138
496
|
}
|
|
139
497
|
/**
|
|
140
|
-
*
|
|
141
|
-
*
|
|
498
|
+
* MemoryChangeTracker is a simple, in-memory implementation of the `ChangeTracker`.
|
|
499
|
+
*
|
|
500
|
+
* It is suitable for single-process applications or development environments where
|
|
501
|
+
* persistence of change history across restarts is not required.
|
|
502
|
+
*
|
|
503
|
+
* @public
|
|
504
|
+
* @since 3.0.0
|
|
142
505
|
*/
|
|
143
506
|
declare class MemoryChangeTracker implements ChangeTracker {
|
|
144
507
|
private changes;
|
|
@@ -149,14 +512,29 @@ declare class MemoryChangeTracker implements ChangeTracker {
|
|
|
149
512
|
getChangesByUrl(url: string): Promise<SitemapChange[]>;
|
|
150
513
|
clear(since?: Date): Promise<void>;
|
|
151
514
|
}
|
|
515
|
+
/**
|
|
516
|
+
* Options for configuring the `RedisChangeTracker`.
|
|
517
|
+
*
|
|
518
|
+
* @public
|
|
519
|
+
* @since 3.0.0
|
|
520
|
+
*/
|
|
152
521
|
interface RedisChangeTrackerOptions {
|
|
522
|
+
/** The Redis client instance. */
|
|
153
523
|
client: any;
|
|
524
|
+
/** Prefix for Redis keys to avoid collisions. @default 'sitemap:changes:' */
|
|
154
525
|
keyPrefix?: string;
|
|
526
|
+
/** Time-to-live for change records in seconds. @default 604800 (7 days) */
|
|
155
527
|
ttl?: number;
|
|
156
528
|
}
|
|
157
529
|
/**
|
|
158
|
-
*
|
|
159
|
-
*
|
|
530
|
+
* RedisChangeTracker provides a distributed implementation of the `ChangeTracker`.
|
|
531
|
+
*
|
|
532
|
+
* It uses Redis to store change records, making it suitable for multi-process
|
|
533
|
+
* or distributed environments where multiple instances of Gravito need to
|
|
534
|
+
* share change history.
|
|
535
|
+
*
|
|
536
|
+
* @public
|
|
537
|
+
* @since 3.0.0
|
|
160
538
|
*/
|
|
161
539
|
declare class RedisChangeTracker implements ChangeTracker {
|
|
162
540
|
private client;
|
|
@@ -171,17 +549,39 @@ declare class RedisChangeTracker implements ChangeTracker {
|
|
|
171
549
|
clear(since?: Date): Promise<void>;
|
|
172
550
|
}
|
|
173
551
|
|
|
552
|
+
/**
|
|
553
|
+
* Result of a sitemap difference calculation.
|
|
554
|
+
*
|
|
555
|
+
* @public
|
|
556
|
+
* @since 3.0.0
|
|
557
|
+
*/
|
|
174
558
|
interface DiffResult {
|
|
559
|
+
/** Entries that are present in the new set but not in the old one. */
|
|
175
560
|
added: SitemapEntry[];
|
|
561
|
+
/** Entries that are present in both sets but have different metadata. */
|
|
176
562
|
updated: SitemapEntry[];
|
|
563
|
+
/** URLs that were present in the old set but are missing from the new one. */
|
|
177
564
|
removed: string[];
|
|
178
565
|
}
|
|
566
|
+
/**
|
|
567
|
+
* Options for configuring the `DiffCalculator`.
|
|
568
|
+
*
|
|
569
|
+
* @public
|
|
570
|
+
* @since 3.0.0
|
|
571
|
+
*/
|
|
179
572
|
interface DiffCalculatorOptions {
|
|
573
|
+
/** Batch size for processing large datasets. @default 10000 */
|
|
180
574
|
batchSize?: number;
|
|
181
575
|
}
|
|
182
576
|
/**
|
|
183
|
-
*
|
|
184
|
-
*
|
|
577
|
+
* DiffCalculator compares two sets of sitemap entries to identify changes.
|
|
578
|
+
*
|
|
579
|
+
* It is used for incremental sitemap generation, allowing the system to
|
|
580
|
+
* update only the parts of the sitemap that have actually changed (added,
|
|
581
|
+
* updated, or removed).
|
|
582
|
+
*
|
|
583
|
+
* @public
|
|
584
|
+
* @since 3.0.0
|
|
185
585
|
*/
|
|
186
586
|
declare class DiffCalculator {
|
|
187
587
|
private batchSize;
|
|
@@ -204,19 +604,47 @@ declare class DiffCalculator {
|
|
|
204
604
|
private hasChanged;
|
|
205
605
|
}
|
|
206
606
|
|
|
607
|
+
/**
|
|
608
|
+
* Options for configuring the `ShadowProcessor`.
|
|
609
|
+
*
|
|
610
|
+
* @public
|
|
611
|
+
* @since 3.0.0
|
|
612
|
+
*/
|
|
207
613
|
interface ShadowProcessorOptions {
|
|
614
|
+
/** The storage backend used for writing files. */
|
|
208
615
|
storage: SitemapStorage;
|
|
616
|
+
/**
|
|
617
|
+
* Deployment mode:
|
|
618
|
+
* - `atomic`: All files are swapped at once when committed.
|
|
619
|
+
* - `versioned`: Each file is committed individually, potentially creating a new version.
|
|
620
|
+
*/
|
|
209
621
|
mode: 'atomic' | 'versioned';
|
|
622
|
+
/** Whether shadow processing is enabled. */
|
|
210
623
|
enabled: boolean;
|
|
211
624
|
}
|
|
625
|
+
/**
|
|
626
|
+
* Represents a single file write operation within a shadow session.
|
|
627
|
+
*
|
|
628
|
+
* @public
|
|
629
|
+
* @since 3.0.0
|
|
630
|
+
*/
|
|
212
631
|
interface ShadowOperation {
|
|
632
|
+
/** The destination filename. */
|
|
213
633
|
filename: string;
|
|
634
|
+
/** The file content to be written. */
|
|
214
635
|
content: string;
|
|
636
|
+
/** Optional unique identifier for the shadow session. */
|
|
215
637
|
shadowId?: string;
|
|
216
638
|
}
|
|
217
639
|
/**
|
|
218
|
-
*
|
|
219
|
-
*
|
|
640
|
+
* ShadowProcessor manages the staging and atomic deployment of generated files.
|
|
641
|
+
*
|
|
642
|
+
* It allows files to be written to a "shadow" location before being "committed"
|
|
643
|
+
* (swapped) to their final destination, ensuring zero-downtime and atomic updates
|
|
644
|
+
* for sitemaps and indexes.
|
|
645
|
+
*
|
|
646
|
+
* @public
|
|
647
|
+
* @since 3.0.0
|
|
220
648
|
*/
|
|
221
649
|
declare class ShadowProcessor {
|
|
222
650
|
private options;
|
|
@@ -245,21 +673,55 @@ declare class ShadowProcessor {
|
|
|
245
673
|
getOperations(): ShadowOperation[];
|
|
246
674
|
}
|
|
247
675
|
|
|
676
|
+
/**
|
|
677
|
+
* Options for configuring the `SitemapGenerator`.
|
|
678
|
+
*
|
|
679
|
+
* @public
|
|
680
|
+
* @since 3.0.0
|
|
681
|
+
*/
|
|
248
682
|
interface SitemapGeneratorOptions extends SitemapStreamOptions {
|
|
683
|
+
/** The storage backend where the sitemap files will be written. */
|
|
249
684
|
storage: SitemapStorage;
|
|
685
|
+
/** An array of providers that supply the entries to be included in the sitemap. */
|
|
250
686
|
providers: SitemapProvider[];
|
|
687
|
+
/** Maximum number of entries per individual sitemap file. @default 50000 */
|
|
251
688
|
maxEntriesPerFile?: number;
|
|
689
|
+
/** The name of the main sitemap or sitemap index file. @default 'sitemap.xml' */
|
|
252
690
|
filename?: string;
|
|
691
|
+
/** Configuration for staging files before atomic deployment. */
|
|
253
692
|
shadow?: {
|
|
693
|
+
/** Whether shadow processing is enabled. */
|
|
254
694
|
enabled: boolean;
|
|
695
|
+
/** Deployment mode: 'atomic' or 'versioned'. */
|
|
255
696
|
mode: 'atomic' | 'versioned';
|
|
256
697
|
};
|
|
698
|
+
/** Optional callback to track generation progress. */
|
|
257
699
|
onProgress?: (progress: {
|
|
258
700
|
processed: number;
|
|
259
701
|
total: number;
|
|
260
702
|
percentage: number;
|
|
261
703
|
}) => void;
|
|
262
704
|
}
|
|
705
|
+
/**
|
|
706
|
+
* SitemapGenerator is the primary orchestrator for creating sitemaps in Gravito.
|
|
707
|
+
*
|
|
708
|
+
* It coordinates multiple `SitemapProvider`s, handles file sharding when
|
|
709
|
+
* URL limits are reached, and uses a `ShadowProcessor` for atomic deployments.
|
|
710
|
+
* It automatically generates a sitemap index if multiple files are produced.
|
|
711
|
+
*
|
|
712
|
+
* @example
|
|
713
|
+
* ```typescript
|
|
714
|
+
* const generator = new SitemapGenerator({
|
|
715
|
+
* baseUrl: 'https://example.com',
|
|
716
|
+
* storage: new DiskSitemapStorage('./public'),
|
|
717
|
+
* providers: [new RouteScanner()]
|
|
718
|
+
* });
|
|
719
|
+
* await generator.run();
|
|
720
|
+
* ```
|
|
721
|
+
*
|
|
722
|
+
* @public
|
|
723
|
+
* @since 3.0.0
|
|
724
|
+
*/
|
|
263
725
|
declare class SitemapGenerator {
|
|
264
726
|
private options;
|
|
265
727
|
private shadowProcessor;
|
|
@@ -271,14 +733,31 @@ declare class SitemapGenerator {
|
|
|
271
733
|
getShadowProcessor(): ShadowProcessor | null;
|
|
272
734
|
}
|
|
273
735
|
|
|
736
|
+
/**
|
|
737
|
+
* Options for configuring the `IncrementalGenerator`.
|
|
738
|
+
*
|
|
739
|
+
* Extends `SitemapGeneratorOptions` to include change tracking and difference
|
|
740
|
+
* calculation components.
|
|
741
|
+
*
|
|
742
|
+
* @public
|
|
743
|
+
* @since 3.0.0
|
|
744
|
+
*/
|
|
274
745
|
interface IncrementalGeneratorOptions extends SitemapGeneratorOptions {
|
|
746
|
+
/** The change tracker used to store and retrieve sitemap changes. */
|
|
275
747
|
changeTracker: ChangeTracker;
|
|
748
|
+
/** Optional difference calculator. Defaults to a new `DiffCalculator` instance. */
|
|
276
749
|
diffCalculator?: DiffCalculator;
|
|
750
|
+
/** Whether to automatically track changes during full generation. @default true */
|
|
277
751
|
autoTrack?: boolean;
|
|
278
752
|
}
|
|
279
753
|
/**
|
|
280
|
-
*
|
|
281
|
-
*
|
|
754
|
+
* IncrementalGenerator optimizes sitemap updates by processing only changed URLs.
|
|
755
|
+
*
|
|
756
|
+
* Instead of regenerating the entire sitemap from scratch, it uses a `ChangeTracker`
|
|
757
|
+
* to identify new, updated, or removed URLs and updates the sitemap incrementally.
|
|
758
|
+
*
|
|
759
|
+
* @public
|
|
760
|
+
* @since 3.0.0
|
|
282
761
|
*/
|
|
283
762
|
declare class IncrementalGenerator {
|
|
284
763
|
private options;
|
|
@@ -316,13 +795,26 @@ declare class IncrementalGenerator {
|
|
|
316
795
|
private toArray;
|
|
317
796
|
}
|
|
318
797
|
|
|
798
|
+
/**
|
|
799
|
+
* Options for configuring the `ProgressTracker`.
|
|
800
|
+
*
|
|
801
|
+
* @public
|
|
802
|
+
* @since 3.0.0
|
|
803
|
+
*/
|
|
319
804
|
interface ProgressTrackerOptions {
|
|
805
|
+
/** The storage backend used to persist progress information. */
|
|
320
806
|
storage: SitemapProgressStorage;
|
|
807
|
+
/** Update interval in milliseconds. @default 1000 */
|
|
321
808
|
updateInterval?: number;
|
|
322
809
|
}
|
|
323
810
|
/**
|
|
324
|
-
*
|
|
325
|
-
*
|
|
811
|
+
* ProgressTracker monitors and persists the progress of sitemap generation jobs.
|
|
812
|
+
*
|
|
813
|
+
* It provides methods to initialize, update, and complete progress tracking,
|
|
814
|
+
* ensuring that long-running generation tasks can be monitored via the storage backend.
|
|
815
|
+
*
|
|
816
|
+
* @public
|
|
817
|
+
* @since 3.0.0
|
|
326
818
|
*/
|
|
327
819
|
declare class ProgressTracker {
|
|
328
820
|
private storage;
|
|
@@ -360,6 +852,23 @@ declare class ProgressTracker {
|
|
|
360
852
|
getCurrentProgress(): SitemapProgress | null;
|
|
361
853
|
}
|
|
362
854
|
|
|
855
|
+
/**
|
|
856
|
+
* SitemapIndex handles the generation of sitemap index files.
|
|
857
|
+
*
|
|
858
|
+
* A sitemap index is used when a site has multiple sitemap files, usually
|
|
859
|
+
* because the number of URLs exceeds the 50,000 limit per sitemap.
|
|
860
|
+
*
|
|
861
|
+
* @example
|
|
862
|
+
* ```typescript
|
|
863
|
+
* const index = new SitemapIndex({ baseUrl: 'https://example.com' });
|
|
864
|
+
* index.add('sitemap-posts.xml');
|
|
865
|
+
* index.add({ url: 'sitemap-pages.xml', lastmod: new Date() });
|
|
866
|
+
* const xml = index.toXML();
|
|
867
|
+
* ```
|
|
868
|
+
*
|
|
869
|
+
* @public
|
|
870
|
+
* @since 3.0.0
|
|
871
|
+
*/
|
|
363
872
|
declare class SitemapIndex {
|
|
364
873
|
private options;
|
|
365
874
|
private entries;
|
|
@@ -370,6 +879,26 @@ declare class SitemapIndex {
|
|
|
370
879
|
private escape;
|
|
371
880
|
}
|
|
372
881
|
|
|
882
|
+
/**
|
|
883
|
+
* SitemapStream handles the low-level generation of sitemap XML content.
|
|
884
|
+
*
|
|
885
|
+
* It supports standard sitemap tags as well as Google-specific extensions for
|
|
886
|
+
* images, videos, news, and internationalization (i18n) via `xhtml:link`.
|
|
887
|
+
*
|
|
888
|
+
* @example
|
|
889
|
+
* ```typescript
|
|
890
|
+
* const stream = new SitemapStream({ baseUrl: 'https://example.com' });
|
|
891
|
+
* stream.add({
|
|
892
|
+
* url: '/contact',
|
|
893
|
+
* changefreq: 'monthly',
|
|
894
|
+
* priority: 0.5
|
|
895
|
+
* });
|
|
896
|
+
* const xml = stream.toXML();
|
|
897
|
+
* ```
|
|
898
|
+
*
|
|
899
|
+
* @public
|
|
900
|
+
* @since 3.0.0
|
|
901
|
+
*/
|
|
373
902
|
declare class SitemapStream {
|
|
374
903
|
private options;
|
|
375
904
|
private entries;
|
|
@@ -400,22 +929,41 @@ type I18nSitemapEntryOptions = Omit<SitemapEntry, 'url' | 'alternates'>;
|
|
|
400
929
|
*/
|
|
401
930
|
declare function generateI18nEntries(path: string, locales: string[], baseUrl?: string, options?: I18nSitemapEntryOptions): SitemapEntry[];
|
|
402
931
|
|
|
932
|
+
/**
|
|
933
|
+
* Options for configuring the `GenerateSitemapJob`.
|
|
934
|
+
*
|
|
935
|
+
* @public
|
|
936
|
+
* @since 3.0.0
|
|
937
|
+
*/
|
|
403
938
|
interface GenerateSitemapJobOptions {
|
|
939
|
+
/** Options for the underlying sitemap generator. */
|
|
404
940
|
generatorOptions: SitemapGeneratorOptions;
|
|
941
|
+
/** Unique identifier for the generation job. */
|
|
405
942
|
jobId: string;
|
|
943
|
+
/** Optional progress tracker to monitor execution state. */
|
|
406
944
|
progressTracker?: ProgressTracker;
|
|
945
|
+
/** Optional shadow processor for atomic deployments. */
|
|
407
946
|
shadowProcessor?: ShadowProcessor;
|
|
947
|
+
/** Optional callback triggered during progress updates. */
|
|
408
948
|
onProgress?: (progress: {
|
|
409
949
|
processed: number;
|
|
410
950
|
total: number;
|
|
411
951
|
percentage: number;
|
|
412
952
|
}) => void;
|
|
953
|
+
/** Optional callback triggered when the job completes successfully. */
|
|
413
954
|
onComplete?: () => void;
|
|
955
|
+
/** Optional callback triggered when the job encounters an error. */
|
|
414
956
|
onError?: (error: Error) => void;
|
|
415
957
|
}
|
|
416
958
|
/**
|
|
417
|
-
*
|
|
418
|
-
*
|
|
959
|
+
* GenerateSitemapJob is a background task for processing large-scale sitemaps.
|
|
960
|
+
*
|
|
961
|
+
* It integrates with Gravito's `stream` module to provide asynchronous,
|
|
962
|
+
* observable sitemap generation with real-time progress tracking and
|
|
963
|
+
* atomic deployment support.
|
|
964
|
+
*
|
|
965
|
+
* @public
|
|
966
|
+
* @since 3.0.0
|
|
419
967
|
*/
|
|
420
968
|
declare class GenerateSitemapJob extends Job {
|
|
421
969
|
private options;
|
|
@@ -434,37 +982,110 @@ declare class GenerateSitemapJob extends Job {
|
|
|
434
982
|
private generateWithProgress;
|
|
435
983
|
}
|
|
436
984
|
|
|
985
|
+
/**
|
|
986
|
+
* Configuration for a dynamically generated sitemap that is built upon request.
|
|
987
|
+
*
|
|
988
|
+
* Useful for small to medium sites where fresh data is critical. Dynamic sitemaps
|
|
989
|
+
* are generated on-the-fly and can be cached at the HTTP level.
|
|
990
|
+
*
|
|
991
|
+
* @public
|
|
992
|
+
* @since 3.0.0
|
|
993
|
+
*/
|
|
437
994
|
interface DynamicSitemapOptions extends SitemapStreamOptions {
|
|
995
|
+
/** The URL path where the sitemap will be exposed. @default '/sitemap.xml' */
|
|
438
996
|
path?: string | undefined;
|
|
997
|
+
/** List of sitemap entry providers to scan for content. */
|
|
439
998
|
providers: SitemapProvider[];
|
|
999
|
+
/** Cache duration in seconds for the HTTP response. @default undefined (no-cache) */
|
|
440
1000
|
cacheSeconds?: number | undefined;
|
|
1001
|
+
/** Persistence backend for cached XML files. Defaults to MemorySitemapStorage. */
|
|
441
1002
|
storage?: SitemapStorage | undefined;
|
|
1003
|
+
/** Optional distributed lock to prevent "cache stampede" during heavy generation. */
|
|
442
1004
|
lock?: SitemapLock | undefined;
|
|
443
1005
|
}
|
|
1006
|
+
/**
|
|
1007
|
+
* Configuration for a statically pre-generated sitemap.
|
|
1008
|
+
*
|
|
1009
|
+
* Recommended for large sites or high-traffic applications. Static sitemaps
|
|
1010
|
+
* are built (usually as part of a build process) and served as static files.
|
|
1011
|
+
*
|
|
1012
|
+
* @public
|
|
1013
|
+
* @since 3.0.0
|
|
1014
|
+
*/
|
|
444
1015
|
interface StaticSitemapOptions extends SitemapStreamOptions {
|
|
1016
|
+
/** Local directory where generated XML files will be saved. */
|
|
445
1017
|
outDir: string;
|
|
1018
|
+
/** The name of the root sitemap file. @default 'sitemap.xml' */
|
|
446
1019
|
filename?: string | undefined;
|
|
1020
|
+
/** List of sitemap entry providers to scan for content. */
|
|
447
1021
|
providers: SitemapProvider[];
|
|
1022
|
+
/** Custom storage backend. Defaults to DiskSitemapStorage using `outDir`. */
|
|
448
1023
|
storage?: SitemapStorage | undefined;
|
|
1024
|
+
/** Optional incremental generation settings to only update changed URLs. */
|
|
449
1025
|
incremental?: {
|
|
1026
|
+
/** Whether to enable incremental builds. */
|
|
450
1027
|
enabled: boolean;
|
|
1028
|
+
/** Backend for tracking structural site changes. */
|
|
451
1029
|
changeTracker: ChangeTracker;
|
|
1030
|
+
/** Whether to automatically record new changes during scan. @default false */
|
|
452
1031
|
autoTrack?: boolean;
|
|
453
1032
|
};
|
|
1033
|
+
/** Optional SEO redirect orchestration settings. */
|
|
454
1034
|
redirect?: {
|
|
1035
|
+
/** Whether to automatically handle 301/302 redirects found in sitemap. */
|
|
455
1036
|
enabled: boolean;
|
|
1037
|
+
/** Backend for managing and resolving redirect rules. */
|
|
456
1038
|
manager: RedirectManager;
|
|
1039
|
+
/** Strategy for resolving conflicting or chained redirects. @default 'remove_old_add_new' */
|
|
457
1040
|
strategy?: 'remove_old_add_new' | 'keep_relation' | 'update_url' | 'dual_mark';
|
|
1041
|
+
/** Whether to resolve redirect chains into a single jump. @default false */
|
|
458
1042
|
followChains?: boolean;
|
|
1043
|
+
/** Maximum number of redirect jumps to follow. @default 5 */
|
|
459
1044
|
maxChainLength?: number;
|
|
460
1045
|
};
|
|
1046
|
+
/** Deployment settings for atomic sitemap updates via shadow staging. */
|
|
461
1047
|
shadow?: {
|
|
1048
|
+
/** Whether to enable "shadow" (atomic staging) mode. */
|
|
462
1049
|
enabled: boolean;
|
|
1050
|
+
/** The update strategy: 'atomic' (full swap) or 'versioned' (archived). @default 'atomic' */
|
|
463
1051
|
mode: 'atomic' | 'versioned';
|
|
464
1052
|
};
|
|
1053
|
+
/** Persistence backend for long-running job progress tracking. */
|
|
465
1054
|
progressStorage?: SitemapProgressStorage;
|
|
466
1055
|
}
|
|
467
|
-
|
|
1056
|
+
/**
|
|
1057
|
+
* OrbitSitemap is the enterprise SEO orchestration module for Gravito.
|
|
1058
|
+
*
|
|
1059
|
+
* It provides advanced sitemap generation supporting large-scale indexing,
|
|
1060
|
+
* automatic 301/302 redirect handling, and atomic sitemap deployments.
|
|
1061
|
+
*
|
|
1062
|
+
* It can operate in two modes:
|
|
1063
|
+
* 1. **Dynamic**: Sitemaps are generated on-the-fly and cached.
|
|
1064
|
+
* 2. **Static**: Sitemaps are pre-built (e.g., during CI/CD) and served from disk or cloud storage.
|
|
1065
|
+
*
|
|
1066
|
+
* @example Dynamic Mode
|
|
1067
|
+
* ```typescript
|
|
1068
|
+
* const sitemap = OrbitSitemap.dynamic({
|
|
1069
|
+
* baseUrl: 'https://example.com',
|
|
1070
|
+
* providers: [new PostSitemapProvider()]
|
|
1071
|
+
* });
|
|
1072
|
+
* core.addOrbit(sitemap);
|
|
1073
|
+
* ```
|
|
1074
|
+
*
|
|
1075
|
+
* @example Static Mode
|
|
1076
|
+
* ```typescript
|
|
1077
|
+
* const sitemap = OrbitSitemap.static({
|
|
1078
|
+
* baseUrl: 'https://example.com',
|
|
1079
|
+
* outDir: './public',
|
|
1080
|
+
* shadow: { enabled: true, mode: 'atomic' }
|
|
1081
|
+
* });
|
|
1082
|
+
* await sitemap.generate();
|
|
1083
|
+
* ```
|
|
1084
|
+
*
|
|
1085
|
+
* @public
|
|
1086
|
+
* @since 3.0.0
|
|
1087
|
+
*/
|
|
1088
|
+
declare class OrbitSitemap implements GravitoOrbit {
|
|
468
1089
|
private options;
|
|
469
1090
|
private mode;
|
|
470
1091
|
private constructor();
|
|
@@ -535,53 +1156,149 @@ declare class OrbitSitemap {
|
|
|
535
1156
|
private toArray;
|
|
536
1157
|
}
|
|
537
1158
|
|
|
1159
|
+
/**
|
|
1160
|
+
* Options for configuring the `RouteScanner`.
|
|
1161
|
+
*
|
|
1162
|
+
* @public
|
|
1163
|
+
* @since 3.0.0
|
|
1164
|
+
*/
|
|
538
1165
|
interface RouteScannerOptions {
|
|
1166
|
+
/** Glob patterns of routes to explicitly include. */
|
|
539
1167
|
include?: string[] | undefined;
|
|
1168
|
+
/** Glob patterns of routes to exclude from the sitemap. */
|
|
540
1169
|
exclude?: string[] | undefined;
|
|
1170
|
+
/** Default change frequency for scanned routes. @default 'weekly' */
|
|
541
1171
|
defaultChangefreq?: ChangeFreq | undefined;
|
|
1172
|
+
/** Default priority for scanned routes (0.0 to 1.0). @default 0.5 */
|
|
542
1173
|
defaultPriority?: number | undefined;
|
|
543
1174
|
}
|
|
1175
|
+
/**
|
|
1176
|
+
* RouteScanner automatically discovers static GET routes from the Gravito router.
|
|
1177
|
+
*
|
|
1178
|
+
* It filters out routes with parameters (e.g., /user/:id) and non-GET routes
|
|
1179
|
+
* by default, ensuring that only crawlable pages are included in the sitemap.
|
|
1180
|
+
*
|
|
1181
|
+
* @example
|
|
1182
|
+
* ```typescript
|
|
1183
|
+
* const scanner = new RouteScanner(app.router, {
|
|
1184
|
+
* exclude: ['/admin/*', '/internal/*']
|
|
1185
|
+
* });
|
|
1186
|
+
* ```
|
|
1187
|
+
*
|
|
1188
|
+
* @public
|
|
1189
|
+
* @since 3.0.0
|
|
1190
|
+
*/
|
|
544
1191
|
declare class RouteScanner implements SitemapProvider {
|
|
545
1192
|
private router;
|
|
546
1193
|
private options;
|
|
547
1194
|
constructor(router: any, options?: RouteScannerOptions);
|
|
1195
|
+
/**
|
|
1196
|
+
* Scan the router and return discovered entries.
|
|
1197
|
+
*
|
|
1198
|
+
* @returns An array of sitemap entries.
|
|
1199
|
+
*/
|
|
548
1200
|
getEntries(): SitemapEntry[];
|
|
549
1201
|
private extractRoutes;
|
|
550
1202
|
private shouldInclude;
|
|
551
1203
|
}
|
|
1204
|
+
/**
|
|
1205
|
+
* Functional factory for creating a `RouteScanner`.
|
|
1206
|
+
*
|
|
1207
|
+
* @param router - The Gravito router instance.
|
|
1208
|
+
* @param options - Optional scanner configuration.
|
|
1209
|
+
* @returns A new RouteScanner instance.
|
|
1210
|
+
*
|
|
1211
|
+
* @public
|
|
1212
|
+
* @since 3.0.0
|
|
1213
|
+
*/
|
|
552
1214
|
declare function routeScanner(router: any, options?: RouteScannerOptions): RouteScanner;
|
|
553
1215
|
|
|
1216
|
+
/**
|
|
1217
|
+
* Options for automatic redirect detection via HTTP probes.
|
|
1218
|
+
*
|
|
1219
|
+
* @public
|
|
1220
|
+
* @since 3.0.0
|
|
1221
|
+
*/
|
|
554
1222
|
interface AutoDetectOptions {
|
|
1223
|
+
/** Whether automatic HTTP detection is enabled. */
|
|
555
1224
|
enabled: boolean;
|
|
1225
|
+
/** HTTP request timeout in milliseconds. @default 5000 */
|
|
556
1226
|
timeout?: number;
|
|
1227
|
+
/** Maximum number of concurrent HTTP probes. @default 10 */
|
|
557
1228
|
maxConcurrent?: number;
|
|
1229
|
+
/** Whether to cache detection results in memory. @default false */
|
|
558
1230
|
cache?: boolean;
|
|
1231
|
+
/** Cache time-to-live in seconds. @default 3600 */
|
|
559
1232
|
cacheTtl?: number;
|
|
560
1233
|
}
|
|
1234
|
+
/**
|
|
1235
|
+
* Options for redirect detection from a database table.
|
|
1236
|
+
*
|
|
1237
|
+
* @public
|
|
1238
|
+
* @since 3.0.0
|
|
1239
|
+
*/
|
|
561
1240
|
interface DatabaseDetectOptions {
|
|
1241
|
+
/** Whether database detection is enabled. */
|
|
562
1242
|
enabled: boolean;
|
|
1243
|
+
/** The name of the table containing redirect rules. */
|
|
563
1244
|
table: string;
|
|
1245
|
+
/** Column mapping for the redirect table. */
|
|
564
1246
|
columns: {
|
|
565
1247
|
from: string;
|
|
566
1248
|
to: string;
|
|
567
1249
|
type: string;
|
|
568
1250
|
};
|
|
1251
|
+
/** Database connection instance (e.g., Knex, Atlas). */
|
|
569
1252
|
connection: any;
|
|
570
1253
|
}
|
|
1254
|
+
/**
|
|
1255
|
+
* Options for redirect detection from a static configuration file.
|
|
1256
|
+
*
|
|
1257
|
+
* @public
|
|
1258
|
+
* @since 3.0.0
|
|
1259
|
+
*/
|
|
571
1260
|
interface ConfigDetectOptions {
|
|
1261
|
+
/** Whether configuration file detection is enabled. */
|
|
572
1262
|
enabled: boolean;
|
|
1263
|
+
/** Path to the JSON configuration file. */
|
|
573
1264
|
path: string;
|
|
1265
|
+
/** Whether to watch the file for changes. @default false */
|
|
574
1266
|
watch?: boolean;
|
|
575
1267
|
}
|
|
1268
|
+
/**
|
|
1269
|
+
* Options for configuring the `RedirectDetector`.
|
|
1270
|
+
*
|
|
1271
|
+
* @public
|
|
1272
|
+
* @since 3.0.0
|
|
1273
|
+
*/
|
|
576
1274
|
interface RedirectDetectorOptions {
|
|
1275
|
+
/** The base URL of the site being scanned. */
|
|
577
1276
|
baseUrl: string;
|
|
1277
|
+
/** Configuration for automatic HTTP probing. */
|
|
578
1278
|
autoDetect?: AutoDetectOptions;
|
|
1279
|
+
/** Configuration for database-driven detection. */
|
|
579
1280
|
database?: DatabaseDetectOptions;
|
|
1281
|
+
/** Configuration for file-driven detection. */
|
|
580
1282
|
config?: ConfigDetectOptions;
|
|
581
1283
|
}
|
|
582
1284
|
/**
|
|
583
|
-
*
|
|
584
|
-
*
|
|
1285
|
+
* RedirectDetector identifies 301 and 302 redirects for URLs.
|
|
1286
|
+
*
|
|
1287
|
+
* It supports multiple detection strategies including database lookups,
|
|
1288
|
+
* static configuration files, and live HTTP probing. This ensures that
|
|
1289
|
+
* sitemaps always point to final destination URLs, improving SEO efficiency.
|
|
1290
|
+
*
|
|
1291
|
+
* @example
|
|
1292
|
+
* ```typescript
|
|
1293
|
+
* const detector = new RedirectDetector({
|
|
1294
|
+
* baseUrl: 'https://example.com',
|
|
1295
|
+
* autoDetect: { enabled: true }
|
|
1296
|
+
* });
|
|
1297
|
+
* const rule = await detector.detect('/old-path');
|
|
1298
|
+
* ```
|
|
1299
|
+
*
|
|
1300
|
+
* @public
|
|
1301
|
+
* @since 3.0.0
|
|
585
1302
|
*/
|
|
586
1303
|
declare class RedirectDetector {
|
|
587
1304
|
private options;
|
|
@@ -613,16 +1330,45 @@ declare class RedirectDetector {
|
|
|
613
1330
|
private cacheResult;
|
|
614
1331
|
}
|
|
615
1332
|
|
|
616
|
-
|
|
1333
|
+
/**
|
|
1334
|
+
* Strategies for handling URLs that have redirects in the sitemap.
|
|
1335
|
+
*
|
|
1336
|
+
* @public
|
|
1337
|
+
* @since 3.0.0
|
|
1338
|
+
*/
|
|
1339
|
+
type RedirectHandlingStrategy =
|
|
1340
|
+
/** Replace the old URL with the final destination URL. (Default) */
|
|
1341
|
+
'remove_old_add_new'
|
|
1342
|
+
/** Keep the old URL in the sitemap but mark the final destination as canonical. */
|
|
1343
|
+
| 'keep_relation'
|
|
1344
|
+
/** Silently update the URL to the destination without extra metadata. */
|
|
1345
|
+
| 'update_url'
|
|
1346
|
+
/** Include both the original and destination URLs in the sitemap. */
|
|
1347
|
+
| 'dual_mark';
|
|
1348
|
+
/**
|
|
1349
|
+
* Options for configuring the `RedirectHandler`.
|
|
1350
|
+
*
|
|
1351
|
+
* @public
|
|
1352
|
+
* @since 3.0.0
|
|
1353
|
+
*/
|
|
617
1354
|
interface RedirectHandlerOptions {
|
|
1355
|
+
/** The redirect manager used to resolve rules. */
|
|
618
1356
|
manager: RedirectManager;
|
|
1357
|
+
/** The strategy to use when a redirect is found. */
|
|
619
1358
|
strategy: RedirectHandlingStrategy;
|
|
1359
|
+
/** Whether to follow redirect chains to the final destination. @default false */
|
|
620
1360
|
followChains?: boolean;
|
|
1361
|
+
/** Maximum number of redirect jumps to follow. @default 5 */
|
|
621
1362
|
maxChainLength?: number;
|
|
622
1363
|
}
|
|
623
1364
|
/**
|
|
624
|
-
*
|
|
625
|
-
*
|
|
1365
|
+
* RedirectHandler processes sitemap entries to ensure they handle 301/302 redirects correctly.
|
|
1366
|
+
*
|
|
1367
|
+
* It uses a `RedirectManager` to resolve final destinations and applies one of
|
|
1368
|
+
* the supported `RedirectHandlingStrategy` options to the entry list.
|
|
1369
|
+
*
|
|
1370
|
+
* @public
|
|
1371
|
+
* @since 3.0.0
|
|
626
1372
|
*/
|
|
627
1373
|
declare class RedirectHandler {
|
|
628
1374
|
private options;
|
|
@@ -649,11 +1395,24 @@ declare class RedirectHandler {
|
|
|
649
1395
|
private handleDualMark;
|
|
650
1396
|
}
|
|
651
1397
|
|
|
1398
|
+
/**
|
|
1399
|
+
* Options for configuring the `MemoryRedirectManager`.
|
|
1400
|
+
*
|
|
1401
|
+
* @public
|
|
1402
|
+
* @since 3.0.0
|
|
1403
|
+
*/
|
|
652
1404
|
interface MemoryRedirectManagerOptions {
|
|
1405
|
+
/** Maximum number of rules to keep in memory. @default 100000 */
|
|
653
1406
|
maxRules?: number;
|
|
654
1407
|
}
|
|
655
1408
|
/**
|
|
656
|
-
*
|
|
1409
|
+
* MemoryRedirectManager is a fast, in-memory implementation of the `RedirectManager`.
|
|
1410
|
+
*
|
|
1411
|
+
* It is suitable for development environments or small sites where redirect
|
|
1412
|
+
* rules do not need to persist across application restarts.
|
|
1413
|
+
*
|
|
1414
|
+
* @public
|
|
1415
|
+
* @since 3.0.0
|
|
657
1416
|
*/
|
|
658
1417
|
declare class MemoryRedirectManager implements RedirectManager {
|
|
659
1418
|
private rules;
|
|
@@ -665,13 +1424,29 @@ declare class MemoryRedirectManager implements RedirectManager {
|
|
|
665
1424
|
getAll(): Promise<RedirectRule[]>;
|
|
666
1425
|
resolve(url: string, followChains?: boolean, maxChainLength?: number): Promise<string | null>;
|
|
667
1426
|
}
|
|
1427
|
+
/**
|
|
1428
|
+
* Options for configuring the `RedisRedirectManager`.
|
|
1429
|
+
*
|
|
1430
|
+
* @public
|
|
1431
|
+
* @since 3.0.0
|
|
1432
|
+
*/
|
|
668
1433
|
interface RedisRedirectManagerOptions {
|
|
1434
|
+
/** The Redis client instance. */
|
|
669
1435
|
client: any;
|
|
1436
|
+
/** Prefix for Redis keys to avoid collisions. @default 'sitemap:redirects:' */
|
|
670
1437
|
keyPrefix?: string;
|
|
1438
|
+
/** Time-to-live for redirect rules in seconds. If not set, rules are permanent. */
|
|
671
1439
|
ttl?: number;
|
|
672
1440
|
}
|
|
673
1441
|
/**
|
|
674
|
-
*
|
|
1442
|
+
* RedisRedirectManager provides a persistent, distributed implementation of the `RedirectManager`.
|
|
1443
|
+
*
|
|
1444
|
+
* It uses Redis to store redirect rules, making it suitable for production
|
|
1445
|
+
* environments where multiple application instances need to share the same
|
|
1446
|
+
* redirect configuration.
|
|
1447
|
+
*
|
|
1448
|
+
* @public
|
|
1449
|
+
* @since 3.0.0
|
|
675
1450
|
*/
|
|
676
1451
|
declare class RedisRedirectManager implements RedirectManager {
|
|
677
1452
|
private client;
|
|
@@ -687,6 +1462,22 @@ declare class RedisRedirectManager implements RedirectManager {
|
|
|
687
1462
|
resolve(url: string, followChains?: boolean, maxChainLength?: number): Promise<string | null>;
|
|
688
1463
|
}
|
|
689
1464
|
|
|
1465
|
+
/**
|
|
1466
|
+
* DiskSitemapStorage persists sitemap files to the local file system.
|
|
1467
|
+
*
|
|
1468
|
+
* It is the default storage backend for single-server Gravito deployments.
|
|
1469
|
+
* It automatically handles directory creation and ensures filenames are sanitized
|
|
1470
|
+
* to prevent path traversal attacks.
|
|
1471
|
+
*
|
|
1472
|
+
* @example
|
|
1473
|
+
* ```typescript
|
|
1474
|
+
* const storage = new DiskSitemapStorage('./public/sitemaps', 'https://example.com/sitemaps');
|
|
1475
|
+
* await storage.write('sitemap.xml', '...');
|
|
1476
|
+
* ```
|
|
1477
|
+
*
|
|
1478
|
+
* @public
|
|
1479
|
+
* @since 3.0.0
|
|
1480
|
+
*/
|
|
690
1481
|
declare class DiskSitemapStorage implements SitemapStorage {
|
|
691
1482
|
private outDir;
|
|
692
1483
|
private baseUrl;
|
|
@@ -697,20 +1488,48 @@ declare class DiskSitemapStorage implements SitemapStorage {
|
|
|
697
1488
|
getUrl(filename: string): string;
|
|
698
1489
|
}
|
|
699
1490
|
|
|
1491
|
+
/**
|
|
1492
|
+
* Options for configuring the `GCPSitemapStorage`.
|
|
1493
|
+
*
|
|
1494
|
+
* @public
|
|
1495
|
+
* @since 3.0.0
|
|
1496
|
+
*/
|
|
700
1497
|
interface GCPSitemapStorageOptions {
|
|
1498
|
+
/** The Google Cloud Storage bucket name. */
|
|
701
1499
|
bucket: string;
|
|
1500
|
+
/** Optional prefix (folder path) within the bucket. */
|
|
702
1501
|
prefix?: string;
|
|
1502
|
+
/** Optional base URL for resolving sitemap locations. Defaults to the standard GCS public URL. */
|
|
703
1503
|
baseUrl?: string;
|
|
1504
|
+
/** Configuration for staging files before atomic deployment. */
|
|
704
1505
|
shadow?: {
|
|
1506
|
+
/** Whether shadow processing is enabled. */
|
|
705
1507
|
enabled: boolean;
|
|
1508
|
+
/** Deployment mode: 'atomic' or 'versioned'. */
|
|
706
1509
|
mode: 'atomic' | 'versioned';
|
|
707
1510
|
};
|
|
1511
|
+
/** Path to the service account key file. */
|
|
708
1512
|
keyFilename?: string;
|
|
1513
|
+
/** The Google Cloud Project ID. */
|
|
709
1514
|
projectId?: string;
|
|
710
1515
|
}
|
|
711
1516
|
/**
|
|
712
|
-
* Google Cloud Storage
|
|
713
|
-
*
|
|
1517
|
+
* GCPSitemapStorage persists sitemap files to Google Cloud Storage.
|
|
1518
|
+
*
|
|
1519
|
+
* It supports atomic deployments via shadow processing and file versioning,
|
|
1520
|
+
* allowing for reliable updates in high-traffic cloud environments.
|
|
1521
|
+
*
|
|
1522
|
+
* @example
|
|
1523
|
+
* ```typescript
|
|
1524
|
+
* const storage = new GCPSitemapStorage({
|
|
1525
|
+
* bucket: 'my-sitemaps',
|
|
1526
|
+
* prefix: 'prod/',
|
|
1527
|
+
* shadow: { enabled: true, mode: 'atomic' }
|
|
1528
|
+
* });
|
|
1529
|
+
* ```
|
|
1530
|
+
*
|
|
1531
|
+
* @public
|
|
1532
|
+
* @since 3.0.0
|
|
714
1533
|
*/
|
|
715
1534
|
declare class GCPSitemapStorage implements SitemapStorage {
|
|
716
1535
|
private bucket;
|
|
@@ -746,6 +1565,21 @@ declare class MemoryProgressStorage implements SitemapProgressStorage {
|
|
|
746
1565
|
list(limit?: number): Promise<SitemapProgress[]>;
|
|
747
1566
|
}
|
|
748
1567
|
|
|
1568
|
+
/**
|
|
1569
|
+
* MemorySitemapStorage is a non-persistent, in-memory storage backend for sitemaps.
|
|
1570
|
+
*
|
|
1571
|
+
* It is primarily used for testing or for applications where sitemaps are
|
|
1572
|
+
* generated on-the-fly and served directly from memory.
|
|
1573
|
+
*
|
|
1574
|
+
* @example
|
|
1575
|
+
* ```typescript
|
|
1576
|
+
* const storage = new MemorySitemapStorage('https://example.com');
|
|
1577
|
+
* await storage.write('sitemap.xml', '...');
|
|
1578
|
+
* ```
|
|
1579
|
+
*
|
|
1580
|
+
* @public
|
|
1581
|
+
* @since 3.0.0
|
|
1582
|
+
*/
|
|
749
1583
|
declare class MemorySitemapStorage implements SitemapStorage {
|
|
750
1584
|
private baseUrl;
|
|
751
1585
|
private files;
|
|
@@ -756,14 +1590,28 @@ declare class MemorySitemapStorage implements SitemapStorage {
|
|
|
756
1590
|
getUrl(filename: string): string;
|
|
757
1591
|
}
|
|
758
1592
|
|
|
1593
|
+
/**
|
|
1594
|
+
* Options for configuring the `RedisProgressStorage`.
|
|
1595
|
+
*
|
|
1596
|
+
* @public
|
|
1597
|
+
* @since 3.0.0
|
|
1598
|
+
*/
|
|
759
1599
|
interface RedisProgressStorageOptions {
|
|
1600
|
+
/** The Redis client instance. */
|
|
760
1601
|
client: any;
|
|
1602
|
+
/** Prefix for Redis keys to avoid collisions. @default 'sitemap:progress:' */
|
|
761
1603
|
keyPrefix?: string;
|
|
1604
|
+
/** Time-to-live for progress records in seconds. @default 86400 (24 hours) */
|
|
762
1605
|
ttl?: number;
|
|
763
1606
|
}
|
|
764
1607
|
/**
|
|
765
|
-
* Redis
|
|
766
|
-
*
|
|
1608
|
+
* RedisProgressStorage persists sitemap generation progress to Redis.
|
|
1609
|
+
*
|
|
1610
|
+
* It is designed for multi-process or distributed environments where progress
|
|
1611
|
+
* needs to be tracked across multiple worker instances.
|
|
1612
|
+
*
|
|
1613
|
+
* @public
|
|
1614
|
+
* @since 3.0.0
|
|
767
1615
|
*/
|
|
768
1616
|
declare class RedisProgressStorage implements SitemapProgressStorage {
|
|
769
1617
|
private client;
|
|
@@ -779,23 +1627,51 @@ declare class RedisProgressStorage implements SitemapProgressStorage {
|
|
|
779
1627
|
list(limit?: number): Promise<SitemapProgress[]>;
|
|
780
1628
|
}
|
|
781
1629
|
|
|
1630
|
+
/**
|
|
1631
|
+
* Options for configuring the `S3SitemapStorage`.
|
|
1632
|
+
*
|
|
1633
|
+
* @public
|
|
1634
|
+
* @since 3.0.0
|
|
1635
|
+
*/
|
|
782
1636
|
interface S3SitemapStorageOptions {
|
|
1637
|
+
/** The AWS S3 bucket name. */
|
|
783
1638
|
bucket: string;
|
|
1639
|
+
/** The AWS region where the bucket is located. @default 'us-east-1' */
|
|
784
1640
|
region?: string;
|
|
1641
|
+
/** Optional prefix (folder path) within the bucket. */
|
|
785
1642
|
prefix?: string;
|
|
1643
|
+
/** Optional base URL for resolving sitemap locations. Defaults to standard S3 URL. */
|
|
786
1644
|
baseUrl?: string;
|
|
1645
|
+
/** Configuration for staging files before atomic deployment. */
|
|
787
1646
|
shadow?: {
|
|
1647
|
+
/** Whether shadow processing is enabled. */
|
|
788
1648
|
enabled: boolean;
|
|
1649
|
+
/** Deployment mode: 'atomic' or 'versioned'. */
|
|
789
1650
|
mode: 'atomic' | 'versioned';
|
|
790
1651
|
};
|
|
1652
|
+
/** Optional AWS credentials. If not provided, the SDK will use environment defaults. */
|
|
791
1653
|
credentials?: {
|
|
792
1654
|
accessKeyId: string;
|
|
793
1655
|
secretAccessKey: string;
|
|
794
1656
|
};
|
|
795
1657
|
}
|
|
796
1658
|
/**
|
|
797
|
-
* AWS S3
|
|
798
|
-
*
|
|
1659
|
+
* S3SitemapStorage persists sitemap files to AWS S3.
|
|
1660
|
+
*
|
|
1661
|
+
* It provides robust cloud storage with support for shadow processing
|
|
1662
|
+
* and file versioning, ensuring safe and atomic sitemap updates.
|
|
1663
|
+
*
|
|
1664
|
+
* @example
|
|
1665
|
+
* ```typescript
|
|
1666
|
+
* const storage = new S3SitemapStorage({
|
|
1667
|
+
* bucket: 'my-sitemaps',
|
|
1668
|
+
* region: 'ap-northeast-1',
|
|
1669
|
+
* shadow: { enabled: true, mode: 'atomic' }
|
|
1670
|
+
* });
|
|
1671
|
+
* ```
|
|
1672
|
+
*
|
|
1673
|
+
* @public
|
|
1674
|
+
* @since 3.0.0
|
|
799
1675
|
*/
|
|
800
1676
|
declare class S3SitemapStorage implements SitemapStorage {
|
|
801
1677
|
private bucket;
|