@gravito/constellation 1.0.0-alpha.6 → 1.0.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.
@@ -0,0 +1,821 @@
1
+ import { Job } from '@gravito/stream';
2
+ import { PlanetCore } from '@gravito/core';
3
+
4
+ type ChangeFreq = 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never';
5
+ interface AlternateUrl {
6
+ lang: string;
7
+ url: string;
8
+ }
9
+ interface SitemapImage {
10
+ loc: string;
11
+ title?: string | undefined;
12
+ caption?: string | undefined;
13
+ geo_location?: string | undefined;
14
+ license?: string | undefined;
15
+ }
16
+ interface SitemapVideo {
17
+ thumbnail_loc: string;
18
+ title: string;
19
+ description: string;
20
+ content_loc?: string | undefined;
21
+ player_loc?: string | undefined;
22
+ duration?: number | undefined;
23
+ expiration_date?: Date | string | undefined;
24
+ rating?: number | undefined;
25
+ view_count?: number | undefined;
26
+ publication_date?: Date | string | undefined;
27
+ family_friendly?: 'yes' | 'no' | undefined;
28
+ tag?: string[] | undefined;
29
+ category?: string | undefined;
30
+ restriction?: {
31
+ relationship: 'allow' | 'deny';
32
+ countries: string[];
33
+ } | undefined;
34
+ }
35
+ interface SitemapNews {
36
+ publication: {
37
+ name: string;
38
+ language: string;
39
+ };
40
+ publication_date: Date | string;
41
+ title: string;
42
+ genres?: string | undefined;
43
+ keywords?: string[] | undefined;
44
+ stock_tickers?: string[] | undefined;
45
+ }
46
+ interface SitemapEntry {
47
+ url: string;
48
+ lastmod?: Date | string | undefined;
49
+ changefreq?: ChangeFreq | undefined;
50
+ priority?: number | undefined;
51
+ alternates?: AlternateUrl[] | undefined;
52
+ images?: SitemapImage[] | undefined;
53
+ videos?: SitemapVideo[] | undefined;
54
+ news?: SitemapNews | undefined;
55
+ redirect?: {
56
+ from: string;
57
+ to: string;
58
+ type: 301 | 302;
59
+ canonical?: string;
60
+ };
61
+ }
62
+ interface SitemapIndexEntry {
63
+ url: string;
64
+ lastmod?: Date | string | undefined;
65
+ }
66
+ interface SitemapProvider {
67
+ getEntries(): Promise<SitemapEntry[]> | SitemapEntry[] | AsyncIterable<SitemapEntry>;
68
+ }
69
+ interface SitemapStreamOptions {
70
+ baseUrl: string;
71
+ pretty?: boolean | undefined;
72
+ }
73
+ interface SitemapStorage {
74
+ write(filename: string, content: string): Promise<void>;
75
+ read(filename: string): Promise<string | null>;
76
+ exists(filename: string): Promise<boolean>;
77
+ getUrl(filename: string): string;
78
+ writeShadow?(filename: string, content: string, shadowId?: string): Promise<void>;
79
+ commitShadow?(shadowId: string): Promise<void>;
80
+ listVersions?(filename: string): Promise<string[]>;
81
+ switchVersion?(filename: string, version: string): Promise<void>;
82
+ }
83
+ interface SitemapCache {
84
+ get(key: string): Promise<string | null>;
85
+ set(key: string, value: string, ttl?: number): Promise<void>;
86
+ has(key: string): Promise<boolean>;
87
+ }
88
+ interface SitemapLock {
89
+ acquire(resource: string, ttl: number): Promise<boolean>;
90
+ release(resource: string): Promise<void>;
91
+ }
92
+ interface SitemapProgress {
93
+ jobId: string;
94
+ status: 'pending' | 'processing' | 'completed' | 'failed';
95
+ total: number;
96
+ processed: number;
97
+ percentage: number;
98
+ startTime?: Date;
99
+ endTime?: Date;
100
+ error?: string;
101
+ }
102
+ interface SitemapProgressStorage {
103
+ get(jobId: string): Promise<SitemapProgress | null>;
104
+ set(jobId: string, progress: SitemapProgress): Promise<void>;
105
+ update(jobId: string, updates: Partial<SitemapProgress>): Promise<void>;
106
+ delete(jobId: string): Promise<void>;
107
+ list(limit?: number): Promise<SitemapProgress[]>;
108
+ }
109
+ type ChangeType = 'add' | 'update' | 'remove';
110
+ interface SitemapChange {
111
+ type: ChangeType;
112
+ url: string;
113
+ entry?: SitemapEntry;
114
+ timestamp: Date;
115
+ }
116
+ interface ChangeTracker {
117
+ track(change: SitemapChange): Promise<void>;
118
+ getChanges(since?: Date): Promise<SitemapChange[]>;
119
+ getChangesByUrl(url: string): Promise<SitemapChange[]>;
120
+ clear(since?: Date): Promise<void>;
121
+ }
122
+ interface RedirectRule {
123
+ from: string;
124
+ to: string;
125
+ type: 301 | 302;
126
+ createdAt?: Date;
127
+ }
128
+ interface RedirectManager {
129
+ register(redirect: RedirectRule): Promise<void>;
130
+ registerBatch(redirects: RedirectRule[]): Promise<void>;
131
+ get(from: string): Promise<RedirectRule | null>;
132
+ getAll(): Promise<RedirectRule[]>;
133
+ resolve(url: string, followChains?: boolean, maxChainLength?: number): Promise<string | null>;
134
+ }
135
+
136
+ interface MemoryChangeTrackerOptions {
137
+ maxChanges?: number;
138
+ }
139
+ /**
140
+ * 記憶體變更追蹤器實作
141
+ * 適用於單一進程或開發環境
142
+ */
143
+ declare class MemoryChangeTracker implements ChangeTracker {
144
+ private changes;
145
+ private maxChanges;
146
+ constructor(options?: MemoryChangeTrackerOptions);
147
+ track(change: SitemapChange): Promise<void>;
148
+ getChanges(since?: Date): Promise<SitemapChange[]>;
149
+ getChangesByUrl(url: string): Promise<SitemapChange[]>;
150
+ clear(since?: Date): Promise<void>;
151
+ }
152
+ interface RedisChangeTrackerOptions {
153
+ client: any;
154
+ keyPrefix?: string;
155
+ ttl?: number;
156
+ }
157
+ /**
158
+ * Redis 變更追蹤器實作
159
+ * 適用於分散式環境或多進程
160
+ */
161
+ declare class RedisChangeTracker implements ChangeTracker {
162
+ private client;
163
+ private keyPrefix;
164
+ private ttl;
165
+ constructor(options: RedisChangeTrackerOptions);
166
+ private getKey;
167
+ private getListKey;
168
+ track(change: SitemapChange): Promise<void>;
169
+ getChanges(since?: Date): Promise<SitemapChange[]>;
170
+ getChangesByUrl(url: string): Promise<SitemapChange[]>;
171
+ clear(since?: Date): Promise<void>;
172
+ }
173
+
174
+ interface DiffResult {
175
+ added: SitemapEntry[];
176
+ updated: SitemapEntry[];
177
+ removed: string[];
178
+ }
179
+ interface DiffCalculatorOptions {
180
+ batchSize?: number;
181
+ }
182
+ /**
183
+ * 差異計算器
184
+ * 比較兩個 sitemap 狀態,計算差異
185
+ */
186
+ declare class DiffCalculator {
187
+ private batchSize;
188
+ constructor(options?: DiffCalculatorOptions);
189
+ /**
190
+ * 計算兩個 sitemap 狀態的差異
191
+ */
192
+ calculate(oldEntries: SitemapEntry[], newEntries: SitemapEntry[]): DiffResult;
193
+ /**
194
+ * 批次計算差異(用於大量 URL)
195
+ */
196
+ calculateBatch(oldEntries: AsyncIterable<SitemapEntry>, newEntries: AsyncIterable<SitemapEntry>): Promise<DiffResult>;
197
+ /**
198
+ * 從變更記錄計算差異
199
+ */
200
+ calculateFromChanges(baseEntries: SitemapEntry[], changes: SitemapChange[]): DiffResult;
201
+ /**
202
+ * 檢查 entry 是否有變更
203
+ */
204
+ private hasChanged;
205
+ }
206
+
207
+ interface ShadowProcessorOptions {
208
+ storage: SitemapStorage;
209
+ mode: 'atomic' | 'versioned';
210
+ enabled: boolean;
211
+ }
212
+ interface ShadowOperation {
213
+ filename: string;
214
+ content: string;
215
+ shadowId?: string;
216
+ }
217
+ /**
218
+ * 影子處理器
219
+ * 管理影子生成流程,支援原子切換和版本化兩種模式
220
+ */
221
+ declare class ShadowProcessor {
222
+ private options;
223
+ private shadowId;
224
+ private operations;
225
+ constructor(options: ShadowProcessorOptions);
226
+ /**
227
+ * 添加一個影子操作
228
+ */
229
+ addOperation(operation: ShadowOperation): Promise<void>;
230
+ /**
231
+ * 提交所有影子操作
232
+ */
233
+ commit(): Promise<void>;
234
+ /**
235
+ * 取消所有影子操作
236
+ */
237
+ rollback(): Promise<void>;
238
+ /**
239
+ * 獲取當前影子 ID
240
+ */
241
+ getShadowId(): string;
242
+ /**
243
+ * 獲取所有操作
244
+ */
245
+ getOperations(): ShadowOperation[];
246
+ }
247
+
248
+ interface SitemapGeneratorOptions extends SitemapStreamOptions {
249
+ storage: SitemapStorage;
250
+ providers: SitemapProvider[];
251
+ maxEntriesPerFile?: number;
252
+ filename?: string;
253
+ shadow?: {
254
+ enabled: boolean;
255
+ mode: 'atomic' | 'versioned';
256
+ };
257
+ onProgress?: (progress: {
258
+ processed: number;
259
+ total: number;
260
+ percentage: number;
261
+ }) => void;
262
+ }
263
+ declare class SitemapGenerator {
264
+ private options;
265
+ private shadowProcessor;
266
+ constructor(options: SitemapGeneratorOptions);
267
+ run(): Promise<void>;
268
+ /**
269
+ * 獲取影子處理器(如果啟用)
270
+ */
271
+ getShadowProcessor(): ShadowProcessor | null;
272
+ }
273
+
274
+ interface IncrementalGeneratorOptions extends SitemapGeneratorOptions {
275
+ changeTracker: ChangeTracker;
276
+ diffCalculator?: DiffCalculator;
277
+ autoTrack?: boolean;
278
+ }
279
+ /**
280
+ * 增量生成器
281
+ * 只生成變更的 URL,不重新生成整個 sitemap
282
+ */
283
+ declare class IncrementalGenerator {
284
+ private options;
285
+ private changeTracker;
286
+ private diffCalculator;
287
+ private generator;
288
+ constructor(options: IncrementalGeneratorOptions);
289
+ /**
290
+ * 生成完整的 sitemap(首次生成)
291
+ */
292
+ generateFull(): Promise<void>;
293
+ /**
294
+ * 增量生成(只更新變更的部分)
295
+ */
296
+ generateIncremental(since?: Date): Promise<void>;
297
+ /**
298
+ * 手動追蹤變更
299
+ */
300
+ trackChange(change: SitemapChange): Promise<void>;
301
+ /**
302
+ * 獲取變更記錄
303
+ */
304
+ getChanges(since?: Date): Promise<SitemapChange[]>;
305
+ /**
306
+ * 載入基礎 entries(從現有 sitemap)
307
+ */
308
+ private loadBaseEntries;
309
+ /**
310
+ * 生成差異部分
311
+ */
312
+ private generateDiff;
313
+ /**
314
+ * 將 AsyncIterable 轉換為陣列
315
+ */
316
+ private toArray;
317
+ }
318
+
319
+ interface ProgressTrackerOptions {
320
+ storage: SitemapProgressStorage;
321
+ updateInterval?: number;
322
+ }
323
+ /**
324
+ * 進度追蹤器
325
+ * 追蹤 sitemap 生成進度
326
+ */
327
+ declare class ProgressTracker {
328
+ private storage;
329
+ private updateInterval;
330
+ private currentProgress;
331
+ private updateTimer;
332
+ constructor(options: ProgressTrackerOptions);
333
+ /**
334
+ * 初始化進度追蹤
335
+ */
336
+ init(jobId: string, total: number): Promise<void>;
337
+ /**
338
+ * 更新進度
339
+ */
340
+ update(processed: number, status?: SitemapProgress['status']): Promise<void>;
341
+ /**
342
+ * 完成進度追蹤
343
+ */
344
+ complete(): Promise<void>;
345
+ /**
346
+ * 標記為失敗
347
+ */
348
+ fail(error: string): Promise<void>;
349
+ /**
350
+ * 刷新進度到儲存
351
+ */
352
+ private flush;
353
+ /**
354
+ * 停止更新計時器
355
+ */
356
+ private stop;
357
+ /**
358
+ * 獲取當前進度
359
+ */
360
+ getCurrentProgress(): SitemapProgress | null;
361
+ }
362
+
363
+ declare class SitemapIndex {
364
+ private options;
365
+ private entries;
366
+ constructor(options: SitemapStreamOptions);
367
+ add(entry: string | SitemapIndexEntry): this;
368
+ addAll(entries: (string | SitemapIndexEntry)[]): this;
369
+ toXML(): string;
370
+ private escape;
371
+ }
372
+
373
+ declare class SitemapStream {
374
+ private options;
375
+ private entries;
376
+ constructor(options: SitemapStreamOptions);
377
+ add(entry: string | SitemapEntry): this;
378
+ addAll(entries: (string | SitemapEntry)[]): this;
379
+ toXML(): string;
380
+ private renderUrl;
381
+ private hasImages;
382
+ private hasVideos;
383
+ private hasNews;
384
+ private hasAlternates;
385
+ private escape;
386
+ }
387
+
388
+ /**
389
+ * Interface representing basic structure needed to generate i18n entries.
390
+ * Partial of SitemapEntry because url is generated dynamically.
391
+ */
392
+ type I18nSitemapEntryOptions = Omit<SitemapEntry, 'url' | 'alternates'>;
393
+ /**
394
+ * Generate fully cross-referenced SitemapEntries for multiple locales.
395
+ *
396
+ * @param path The path relative to the locale prefix (e.g. '/docs/intro')
397
+ * @param locales List of supported locales (e.g. ['en', 'zh', 'jp'])
398
+ * @param baseUrl The domain root (e.g. 'https://gravito.dev'). IF provided, URLs will be absolute. If not, they remain relative paths but include the locale prefix.
399
+ * @param options Additional SitemapEntry options (lastmod, priority, etc.)
400
+ */
401
+ declare function generateI18nEntries(path: string, locales: string[], baseUrl?: string, options?: I18nSitemapEntryOptions): SitemapEntry[];
402
+
403
+ interface GenerateSitemapJobOptions {
404
+ generatorOptions: SitemapGeneratorOptions;
405
+ jobId: string;
406
+ progressTracker?: ProgressTracker;
407
+ shadowProcessor?: ShadowProcessor;
408
+ onProgress?: (progress: {
409
+ processed: number;
410
+ total: number;
411
+ percentage: number;
412
+ }) => void;
413
+ onComplete?: () => void;
414
+ onError?: (error: Error) => void;
415
+ }
416
+ /**
417
+ * Sitemap 生成背景任務
418
+ * 整合背景任務處理和進度追蹤
419
+ */
420
+ declare class GenerateSitemapJob extends Job {
421
+ private options;
422
+ private generator;
423
+ private totalEntries;
424
+ private processedEntries;
425
+ constructor(options: GenerateSitemapJobOptions);
426
+ handle(): Promise<void>;
427
+ /**
428
+ * 計算總 URL 數
429
+ */
430
+ private calculateTotal;
431
+ /**
432
+ * 帶進度追蹤的生成
433
+ */
434
+ private generateWithProgress;
435
+ }
436
+
437
+ interface DynamicSitemapOptions extends SitemapStreamOptions {
438
+ path?: string | undefined;
439
+ providers: SitemapProvider[];
440
+ cacheSeconds?: number | undefined;
441
+ storage?: SitemapStorage | undefined;
442
+ lock?: SitemapLock | undefined;
443
+ }
444
+ interface StaticSitemapOptions extends SitemapStreamOptions {
445
+ outDir: string;
446
+ filename?: string | undefined;
447
+ providers: SitemapProvider[];
448
+ storage?: SitemapStorage | undefined;
449
+ incremental?: {
450
+ enabled: boolean;
451
+ changeTracker: ChangeTracker;
452
+ autoTrack?: boolean;
453
+ };
454
+ redirect?: {
455
+ enabled: boolean;
456
+ manager: RedirectManager;
457
+ strategy?: 'remove_old_add_new' | 'keep_relation' | 'update_url' | 'dual_mark';
458
+ followChains?: boolean;
459
+ maxChainLength?: number;
460
+ };
461
+ shadow?: {
462
+ enabled: boolean;
463
+ mode: 'atomic' | 'versioned';
464
+ };
465
+ progressStorage?: SitemapProgressStorage;
466
+ }
467
+ declare class OrbitSitemap {
468
+ private options;
469
+ private mode;
470
+ private constructor();
471
+ /**
472
+ * Create a dynamic sitemap configuration.
473
+ *
474
+ * @param options - The dynamic sitemap options.
475
+ * @returns An OrbitSitemap instance configured for dynamic generation.
476
+ */
477
+ static dynamic(options: DynamicSitemapOptions): OrbitSitemap;
478
+ /**
479
+ * Create a static sitemap configuration.
480
+ *
481
+ * @param options - The static sitemap options.
482
+ * @returns An OrbitSitemap instance configured for static generation.
483
+ */
484
+ static static(options: StaticSitemapOptions): OrbitSitemap;
485
+ /**
486
+ * Install the sitemap module into PlanetCore.
487
+ *
488
+ * @param core - The PlanetCore instance.
489
+ */
490
+ install(core: PlanetCore): void;
491
+ private installDynamic;
492
+ /**
493
+ * Generate the sitemap (static mode only).
494
+ *
495
+ * @returns A promise that resolves when generation is complete.
496
+ * @throws {Error} If called in dynamic mode.
497
+ */
498
+ generate(): Promise<void>;
499
+ /**
500
+ * Generate incremental sitemap updates (static mode only).
501
+ *
502
+ * @param since - Only include items modified since this date.
503
+ * @returns A promise that resolves when incremental generation is complete.
504
+ * @throws {Error} If called in dynamic mode, or if incremental generation is not enabled/configured.
505
+ */
506
+ generateIncremental(since?: Date): Promise<void>;
507
+ /**
508
+ * Generate sitemap asynchronously in the background (static mode only).
509
+ *
510
+ * @param options - Options for the async generation job.
511
+ * @returns A promise resolving to the job ID.
512
+ * @throws {Error} If called in dynamic mode.
513
+ */
514
+ generateAsync(options?: {
515
+ incremental?: boolean;
516
+ since?: Date;
517
+ onProgress?: (progress: {
518
+ processed: number;
519
+ total: number;
520
+ percentage: number;
521
+ }) => void;
522
+ onComplete?: () => void;
523
+ onError?: (error: Error) => void;
524
+ }): Promise<string>;
525
+ /**
526
+ * Install API endpoints for triggering and monitoring sitemap generation.
527
+ *
528
+ * @param core - The PlanetCore instance.
529
+ * @param basePath - The base path for the API endpoints (default: '/admin/sitemap').
530
+ */
531
+ installApiEndpoints(core: PlanetCore, basePath?: string): void;
532
+ /**
533
+ * Convert an AsyncIterable to an array.
534
+ */
535
+ private toArray;
536
+ }
537
+
538
+ interface RouteScannerOptions {
539
+ include?: string[] | undefined;
540
+ exclude?: string[] | undefined;
541
+ defaultChangefreq?: ChangeFreq | undefined;
542
+ defaultPriority?: number | undefined;
543
+ }
544
+ declare class RouteScanner implements SitemapProvider {
545
+ private router;
546
+ private options;
547
+ constructor(router: any, options?: RouteScannerOptions);
548
+ getEntries(): SitemapEntry[];
549
+ private extractRoutes;
550
+ private shouldInclude;
551
+ }
552
+ declare function routeScanner(router: any, options?: RouteScannerOptions): RouteScanner;
553
+
554
+ interface AutoDetectOptions {
555
+ enabled: boolean;
556
+ timeout?: number;
557
+ maxConcurrent?: number;
558
+ cache?: boolean;
559
+ cacheTtl?: number;
560
+ }
561
+ interface DatabaseDetectOptions {
562
+ enabled: boolean;
563
+ table: string;
564
+ columns: {
565
+ from: string;
566
+ to: string;
567
+ type: string;
568
+ };
569
+ connection: any;
570
+ }
571
+ interface ConfigDetectOptions {
572
+ enabled: boolean;
573
+ path: string;
574
+ watch?: boolean;
575
+ }
576
+ interface RedirectDetectorOptions {
577
+ baseUrl: string;
578
+ autoDetect?: AutoDetectOptions;
579
+ database?: DatabaseDetectOptions;
580
+ config?: ConfigDetectOptions;
581
+ }
582
+ /**
583
+ * 轉址偵測器
584
+ * 支援多種偵測方式:自動偵測、資料庫、設定檔
585
+ */
586
+ declare class RedirectDetector {
587
+ private options;
588
+ private cache;
589
+ constructor(options: RedirectDetectorOptions);
590
+ /**
591
+ * 偵測單一 URL 的轉址
592
+ */
593
+ detect(url: string): Promise<RedirectRule | null>;
594
+ /**
595
+ * 批次偵測轉址
596
+ */
597
+ detectBatch(urls: string[]): Promise<Map<string, RedirectRule | null>>;
598
+ /**
599
+ * 從資料庫偵測
600
+ */
601
+ private detectFromDatabase;
602
+ /**
603
+ * 從設定檔偵測
604
+ */
605
+ private detectFromConfig;
606
+ /**
607
+ * 自動偵測(透過 HTTP 請求)
608
+ */
609
+ private detectAuto;
610
+ /**
611
+ * 快取結果
612
+ */
613
+ private cacheResult;
614
+ }
615
+
616
+ type RedirectHandlingStrategy = 'remove_old_add_new' | 'keep_relation' | 'update_url' | 'dual_mark';
617
+ interface RedirectHandlerOptions {
618
+ manager: RedirectManager;
619
+ strategy: RedirectHandlingStrategy;
620
+ followChains?: boolean;
621
+ maxChainLength?: number;
622
+ }
623
+ /**
624
+ * 轉址處理器
625
+ * 處理 sitemap entries 中的轉址
626
+ */
627
+ declare class RedirectHandler {
628
+ private options;
629
+ constructor(options: RedirectHandlerOptions);
630
+ /**
631
+ * 處理 entries 中的轉址
632
+ */
633
+ processEntries(entries: SitemapEntry[]): Promise<SitemapEntry[]>;
634
+ /**
635
+ * 策略一:移除舊 URL,加入新 URL
636
+ */
637
+ private handleRemoveOldAddNew;
638
+ /**
639
+ * 策略二:保留關聯,使用 canonical link
640
+ */
641
+ private handleKeepRelation;
642
+ /**
643
+ * 策略三:僅更新 URL
644
+ */
645
+ private handleUpdateUrl;
646
+ /**
647
+ * 策略四:雙重標記
648
+ */
649
+ private handleDualMark;
650
+ }
651
+
652
+ interface MemoryRedirectManagerOptions {
653
+ maxRules?: number;
654
+ }
655
+ /**
656
+ * 記憶體轉址管理器實作
657
+ */
658
+ declare class MemoryRedirectManager implements RedirectManager {
659
+ private rules;
660
+ private maxRules;
661
+ constructor(options?: MemoryRedirectManagerOptions);
662
+ register(redirect: RedirectRule): Promise<void>;
663
+ registerBatch(redirects: RedirectRule[]): Promise<void>;
664
+ get(from: string): Promise<RedirectRule | null>;
665
+ getAll(): Promise<RedirectRule[]>;
666
+ resolve(url: string, followChains?: boolean, maxChainLength?: number): Promise<string | null>;
667
+ }
668
+ interface RedisRedirectManagerOptions {
669
+ client: any;
670
+ keyPrefix?: string;
671
+ ttl?: number;
672
+ }
673
+ /**
674
+ * Redis 轉址管理器實作
675
+ */
676
+ declare class RedisRedirectManager implements RedirectManager {
677
+ private client;
678
+ private keyPrefix;
679
+ private ttl;
680
+ constructor(options: RedisRedirectManagerOptions);
681
+ private getKey;
682
+ private getListKey;
683
+ register(redirect: RedirectRule): Promise<void>;
684
+ registerBatch(redirects: RedirectRule[]): Promise<void>;
685
+ get(from: string): Promise<RedirectRule | null>;
686
+ getAll(): Promise<RedirectRule[]>;
687
+ resolve(url: string, followChains?: boolean, maxChainLength?: number): Promise<string | null>;
688
+ }
689
+
690
+ declare class DiskSitemapStorage implements SitemapStorage {
691
+ private outDir;
692
+ private baseUrl;
693
+ constructor(outDir: string, baseUrl: string);
694
+ write(filename: string, content: string): Promise<void>;
695
+ read(filename: string): Promise<string | null>;
696
+ exists(filename: string): Promise<boolean>;
697
+ getUrl(filename: string): string;
698
+ }
699
+
700
+ interface GCPSitemapStorageOptions {
701
+ bucket: string;
702
+ prefix?: string;
703
+ baseUrl?: string;
704
+ shadow?: {
705
+ enabled: boolean;
706
+ mode: 'atomic' | 'versioned';
707
+ };
708
+ keyFilename?: string;
709
+ projectId?: string;
710
+ }
711
+ /**
712
+ * Google Cloud Storage 儲存實作
713
+ * 支援影子處理和版本化
714
+ */
715
+ declare class GCPSitemapStorage implements SitemapStorage {
716
+ private bucket;
717
+ private prefix;
718
+ private baseUrl;
719
+ private shadowEnabled;
720
+ private shadowMode;
721
+ private storageClient;
722
+ private bucketInstance;
723
+ constructor(options: GCPSitemapStorageOptions);
724
+ private getStorageClient;
725
+ private getKey;
726
+ write(filename: string, content: string): Promise<void>;
727
+ read(filename: string): Promise<string | null>;
728
+ exists(filename: string): Promise<boolean>;
729
+ getUrl(filename: string): string;
730
+ writeShadow(filename: string, content: string, shadowId?: string): Promise<void>;
731
+ commitShadow(shadowId: string): Promise<void>;
732
+ listVersions(filename: string): Promise<string[]>;
733
+ switchVersion(filename: string, version: string): Promise<void>;
734
+ }
735
+
736
+ /**
737
+ * 記憶體進度儲存實作
738
+ * 適用於單一進程或開發環境
739
+ */
740
+ declare class MemoryProgressStorage implements SitemapProgressStorage {
741
+ private storage;
742
+ get(jobId: string): Promise<SitemapProgress | null>;
743
+ set(jobId: string, progress: SitemapProgress): Promise<void>;
744
+ update(jobId: string, updates: Partial<SitemapProgress>): Promise<void>;
745
+ delete(jobId: string): Promise<void>;
746
+ list(limit?: number): Promise<SitemapProgress[]>;
747
+ }
748
+
749
+ declare class MemorySitemapStorage implements SitemapStorage {
750
+ private baseUrl;
751
+ private files;
752
+ constructor(baseUrl: string);
753
+ write(filename: string, content: string): Promise<void>;
754
+ read(filename: string): Promise<string | null>;
755
+ exists(filename: string): Promise<boolean>;
756
+ getUrl(filename: string): string;
757
+ }
758
+
759
+ interface RedisProgressStorageOptions {
760
+ client: any;
761
+ keyPrefix?: string;
762
+ ttl?: number;
763
+ }
764
+ /**
765
+ * Redis 進度儲存實作
766
+ * 適用於分散式環境或多進程
767
+ */
768
+ declare class RedisProgressStorage implements SitemapProgressStorage {
769
+ private client;
770
+ private keyPrefix;
771
+ private ttl;
772
+ constructor(options: RedisProgressStorageOptions);
773
+ private getKey;
774
+ private getListKey;
775
+ get(jobId: string): Promise<SitemapProgress | null>;
776
+ set(jobId: string, progress: SitemapProgress): Promise<void>;
777
+ update(jobId: string, updates: Partial<SitemapProgress>): Promise<void>;
778
+ delete(jobId: string): Promise<void>;
779
+ list(limit?: number): Promise<SitemapProgress[]>;
780
+ }
781
+
782
+ interface S3SitemapStorageOptions {
783
+ bucket: string;
784
+ region?: string;
785
+ prefix?: string;
786
+ baseUrl?: string;
787
+ shadow?: {
788
+ enabled: boolean;
789
+ mode: 'atomic' | 'versioned';
790
+ };
791
+ credentials?: {
792
+ accessKeyId: string;
793
+ secretAccessKey: string;
794
+ };
795
+ }
796
+ /**
797
+ * AWS S3 儲存實作
798
+ * 支援影子處理和版本化
799
+ */
800
+ declare class S3SitemapStorage implements SitemapStorage {
801
+ private bucket;
802
+ private region?;
803
+ private prefix;
804
+ private baseUrl;
805
+ private shadowEnabled;
806
+ private shadowMode;
807
+ private s3Client;
808
+ constructor(options: S3SitemapStorageOptions);
809
+ private getS3Client;
810
+ private getKey;
811
+ write(filename: string, content: string): Promise<void>;
812
+ read(filename: string): Promise<string | null>;
813
+ exists(filename: string): Promise<boolean>;
814
+ getUrl(filename: string): string;
815
+ writeShadow(filename: string, content: string, shadowId?: string): Promise<void>;
816
+ commitShadow(shadowId: string): Promise<void>;
817
+ listVersions(filename: string): Promise<string[]>;
818
+ switchVersion(filename: string, version: string): Promise<void>;
819
+ }
820
+
821
+ export { type AlternateUrl, type ChangeFreq, type ChangeTracker, type ChangeType, DiffCalculator, DiskSitemapStorage, type DynamicSitemapOptions, GCPSitemapStorage, type GCPSitemapStorageOptions, GenerateSitemapJob, type GenerateSitemapJobOptions, type I18nSitemapEntryOptions, IncrementalGenerator, type IncrementalGeneratorOptions, MemoryChangeTracker, MemoryProgressStorage, MemoryRedirectManager, type MemoryRedirectManagerOptions, MemorySitemapStorage, OrbitSitemap, ProgressTracker, type ProgressTrackerOptions, RedirectDetector, type RedirectDetectorOptions, RedirectHandler, type RedirectHandlerOptions, type RedirectHandlingStrategy, type RedirectManager, type RedirectRule, RedisChangeTracker, RedisProgressStorage, type RedisProgressStorageOptions, RedisRedirectManager, type RedisRedirectManagerOptions, RouteScanner, type RouteScannerOptions, S3SitemapStorage, type S3SitemapStorageOptions, ShadowProcessor, type ShadowProcessorOptions, type SitemapCache, type SitemapChange, type SitemapEntry, SitemapGenerator, type SitemapGeneratorOptions, type SitemapImage, SitemapIndex, type SitemapIndexEntry, type SitemapLock, type SitemapNews, type SitemapProgress, type SitemapProgressStorage, type SitemapProvider, type SitemapStorage, SitemapStream, type SitemapStreamOptions, type SitemapVideo, type StaticSitemapOptions, generateI18nEntries, routeScanner };