@push.rocks/smartregistry 2.3.0 → 2.5.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.
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.smartregistry.d.ts +33 -2
- package/dist_ts/classes.smartregistry.js +38 -5
- package/dist_ts/core/classes.authmanager.d.ts +30 -80
- package/dist_ts/core/classes.authmanager.js +63 -337
- package/dist_ts/core/classes.defaultauthprovider.d.ts +78 -0
- package/dist_ts/core/classes.defaultauthprovider.js +311 -0
- package/dist_ts/core/classes.registrystorage.d.ts +70 -4
- package/dist_ts/core/classes.registrystorage.js +165 -5
- package/dist_ts/core/index.d.ts +3 -0
- package/dist_ts/core/index.js +7 -2
- package/dist_ts/core/interfaces.auth.d.ts +83 -0
- package/dist_ts/core/interfaces.auth.js +2 -0
- package/dist_ts/core/interfaces.core.d.ts +35 -0
- package/dist_ts/core/interfaces.storage.d.ts +120 -0
- package/dist_ts/core/interfaces.storage.js +2 -0
- package/dist_ts/upstream/classes.baseupstream.d.ts +2 -2
- package/dist_ts/upstream/classes.baseupstream.js +16 -14
- package/dist_ts/upstream/classes.upstreamcache.d.ts +69 -22
- package/dist_ts/upstream/classes.upstreamcache.js +207 -50
- package/package.json +1 -1
- package/readme.md +225 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.smartregistry.ts +39 -4
- package/ts/core/classes.authmanager.ts +74 -412
- package/ts/core/classes.defaultauthprovider.ts +393 -0
- package/ts/core/classes.registrystorage.ts +199 -5
- package/ts/core/index.ts +8 -1
- package/ts/core/interfaces.auth.ts +91 -0
- package/ts/core/interfaces.core.ts +39 -0
- package/ts/core/interfaces.storage.ts +130 -0
- package/ts/upstream/classes.baseupstream.ts +20 -15
- package/ts/upstream/classes.upstreamcache.ts +256 -53
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import type { TRegistryProtocol } from './interfaces.core.js';
|
|
2
|
+
/**
|
|
3
|
+
* Actor information from request context
|
|
4
|
+
*/
|
|
5
|
+
export interface IStorageActor {
|
|
6
|
+
userId?: string;
|
|
7
|
+
tokenId?: string;
|
|
8
|
+
ip?: string;
|
|
9
|
+
userAgent?: string;
|
|
10
|
+
orgId?: string;
|
|
11
|
+
sessionId?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Metadata about the storage operation
|
|
15
|
+
*/
|
|
16
|
+
export interface IStorageMetadata {
|
|
17
|
+
/** Content type of the object */
|
|
18
|
+
contentType?: string;
|
|
19
|
+
/** Size in bytes */
|
|
20
|
+
size?: number;
|
|
21
|
+
/** Content digest (e.g., sha256:abc123) */
|
|
22
|
+
digest?: string;
|
|
23
|
+
/** Package/artifact name */
|
|
24
|
+
packageName?: string;
|
|
25
|
+
/** Version */
|
|
26
|
+
version?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Context passed to storage hooks
|
|
30
|
+
*/
|
|
31
|
+
export interface IStorageHookContext {
|
|
32
|
+
/** Type of operation */
|
|
33
|
+
operation: 'put' | 'delete' | 'get';
|
|
34
|
+
/** Storage key/path */
|
|
35
|
+
key: string;
|
|
36
|
+
/** Protocol that triggered this operation */
|
|
37
|
+
protocol: TRegistryProtocol;
|
|
38
|
+
/** Actor who performed the operation (if known) */
|
|
39
|
+
actor?: IStorageActor;
|
|
40
|
+
/** Metadata about the object */
|
|
41
|
+
metadata?: IStorageMetadata;
|
|
42
|
+
/** Timestamp of the operation */
|
|
43
|
+
timestamp: Date;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Result from a beforePut hook that can modify the operation
|
|
47
|
+
*/
|
|
48
|
+
export interface IBeforePutResult {
|
|
49
|
+
/** Whether to allow the operation */
|
|
50
|
+
allowed: boolean;
|
|
51
|
+
/** Optional reason for rejection */
|
|
52
|
+
reason?: string;
|
|
53
|
+
/** Optional modified metadata */
|
|
54
|
+
metadata?: IStorageMetadata;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Result from a beforeDelete hook
|
|
58
|
+
*/
|
|
59
|
+
export interface IBeforeDeleteResult {
|
|
60
|
+
/** Whether to allow the operation */
|
|
61
|
+
allowed: boolean;
|
|
62
|
+
/** Optional reason for rejection */
|
|
63
|
+
reason?: string;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Storage event hooks for quota tracking, audit logging, cache invalidation, etc.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```typescript
|
|
70
|
+
* const quotaHooks: IStorageHooks = {
|
|
71
|
+
* async beforePut(context) {
|
|
72
|
+
* const quota = await getQuota(context.actor?.orgId);
|
|
73
|
+
* const currentUsage = await getUsage(context.actor?.orgId);
|
|
74
|
+
* if (currentUsage + (context.metadata?.size || 0) > quota) {
|
|
75
|
+
* return { allowed: false, reason: 'Quota exceeded' };
|
|
76
|
+
* }
|
|
77
|
+
* return { allowed: true };
|
|
78
|
+
* },
|
|
79
|
+
*
|
|
80
|
+
* async afterPut(context) {
|
|
81
|
+
* await updateUsage(context.actor?.orgId, context.metadata?.size || 0);
|
|
82
|
+
* await auditLog('storage.put', context);
|
|
83
|
+
* },
|
|
84
|
+
*
|
|
85
|
+
* async afterDelete(context) {
|
|
86
|
+
* await invalidateCache(context.key);
|
|
87
|
+
* }
|
|
88
|
+
* };
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
export interface IStorageHooks {
|
|
92
|
+
/**
|
|
93
|
+
* Called before storing an object.
|
|
94
|
+
* Return { allowed: false } to reject the operation.
|
|
95
|
+
* Use for quota checks, virus scanning, validation, etc.
|
|
96
|
+
*/
|
|
97
|
+
beforePut?(context: IStorageHookContext): Promise<IBeforePutResult>;
|
|
98
|
+
/**
|
|
99
|
+
* Called after successfully storing an object.
|
|
100
|
+
* Use for quota tracking, audit logging, notifications, etc.
|
|
101
|
+
*/
|
|
102
|
+
afterPut?(context: IStorageHookContext): Promise<void>;
|
|
103
|
+
/**
|
|
104
|
+
* Called before deleting an object.
|
|
105
|
+
* Return { allowed: false } to reject the operation.
|
|
106
|
+
* Use for preventing deletion of protected resources.
|
|
107
|
+
*/
|
|
108
|
+
beforeDelete?(context: IStorageHookContext): Promise<IBeforeDeleteResult>;
|
|
109
|
+
/**
|
|
110
|
+
* Called after successfully deleting an object.
|
|
111
|
+
* Use for quota updates, audit logging, cache invalidation, etc.
|
|
112
|
+
*/
|
|
113
|
+
afterDelete?(context: IStorageHookContext): Promise<void>;
|
|
114
|
+
/**
|
|
115
|
+
* Called after reading an object.
|
|
116
|
+
* Use for access logging, analytics, etc.
|
|
117
|
+
* Note: This is called even for cache hits.
|
|
118
|
+
*/
|
|
119
|
+
afterGet?(context: IStorageHookContext): Promise<void>;
|
|
120
|
+
}
|
|
@@ -54,11 +54,11 @@ export declare abstract class BaseUpstream {
|
|
|
54
54
|
/**
|
|
55
55
|
* Invalidate cache for a resource pattern.
|
|
56
56
|
*/
|
|
57
|
-
invalidateCache(pattern: RegExp): number
|
|
57
|
+
invalidateCache(pattern: RegExp): Promise<number>;
|
|
58
58
|
/**
|
|
59
59
|
* Clear all cache entries.
|
|
60
60
|
*/
|
|
61
|
-
clearCache(): void
|
|
61
|
+
clearCache(): Promise<void>;
|
|
62
62
|
/**
|
|
63
63
|
* Stop the upstream (cleanup resources).
|
|
64
64
|
*/
|
|
@@ -79,8 +79,15 @@ export class BaseUpstream {
|
|
|
79
79
|
if (!this.config.enabled) {
|
|
80
80
|
return null;
|
|
81
81
|
}
|
|
82
|
+
// Get applicable upstreams sorted by priority
|
|
83
|
+
const applicableUpstreams = this.getApplicableUpstreams(context.resource);
|
|
84
|
+
if (applicableUpstreams.length === 0) {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
// Use the first applicable upstream's URL for cache key
|
|
88
|
+
const primaryUpstreamUrl = applicableUpstreams[0]?.url;
|
|
82
89
|
// Check cache first
|
|
83
|
-
const cached = this.cache.get(context);
|
|
90
|
+
const cached = await this.cache.get(context, primaryUpstreamUrl);
|
|
84
91
|
if (cached && !cached.stale) {
|
|
85
92
|
return {
|
|
86
93
|
success: true,
|
|
@@ -93,7 +100,7 @@ export class BaseUpstream {
|
|
|
93
100
|
};
|
|
94
101
|
}
|
|
95
102
|
// Check for negative cache (recent 404)
|
|
96
|
-
if (this.cache.hasNegative(context)) {
|
|
103
|
+
if (await this.cache.hasNegative(context, primaryUpstreamUrl)) {
|
|
97
104
|
return {
|
|
98
105
|
success: false,
|
|
99
106
|
status: 404,
|
|
@@ -103,11 +110,6 @@ export class BaseUpstream {
|
|
|
103
110
|
latencyMs: 0,
|
|
104
111
|
};
|
|
105
112
|
}
|
|
106
|
-
// Get applicable upstreams sorted by priority
|
|
107
|
-
const applicableUpstreams = this.getApplicableUpstreams(context.resource);
|
|
108
|
-
if (applicableUpstreams.length === 0) {
|
|
109
|
-
return null;
|
|
110
|
-
}
|
|
111
113
|
// If we have stale cache, return it immediately and revalidate in background
|
|
112
114
|
if (cached?.stale && this.cacheConfig.staleWhileRevalidate) {
|
|
113
115
|
// Fire and forget revalidation
|
|
@@ -132,11 +134,11 @@ export class BaseUpstream {
|
|
|
132
134
|
const result = await withCircuitBreaker(breaker, () => this.fetchFromUpstream(upstream, context));
|
|
133
135
|
// Cache successful responses
|
|
134
136
|
if (result.success && result.body) {
|
|
135
|
-
this.cache.set(context, Buffer.isBuffer(result.body) ? result.body : Buffer.from(JSON.stringify(result.body)), result.headers['content-type'] || 'application/octet-stream', result.headers, upstream.id);
|
|
137
|
+
await this.cache.set(context, Buffer.isBuffer(result.body) ? result.body : Buffer.from(JSON.stringify(result.body)), result.headers['content-type'] || 'application/octet-stream', result.headers, upstream.id, upstream.url);
|
|
136
138
|
}
|
|
137
139
|
// Cache 404 responses
|
|
138
140
|
if (result.status === 404) {
|
|
139
|
-
this.cache.setNegative(context, upstream.id);
|
|
141
|
+
await this.cache.setNegative(context, upstream.id, upstream.url);
|
|
140
142
|
}
|
|
141
143
|
return result;
|
|
142
144
|
}
|
|
@@ -160,14 +162,14 @@ export class BaseUpstream {
|
|
|
160
162
|
/**
|
|
161
163
|
* Invalidate cache for a resource pattern.
|
|
162
164
|
*/
|
|
163
|
-
invalidateCache(pattern) {
|
|
165
|
+
async invalidateCache(pattern) {
|
|
164
166
|
return this.cache.invalidatePattern(pattern);
|
|
165
167
|
}
|
|
166
168
|
/**
|
|
167
169
|
* Clear all cache entries.
|
|
168
170
|
*/
|
|
169
|
-
clearCache() {
|
|
170
|
-
this.cache.clear();
|
|
171
|
+
async clearCache() {
|
|
172
|
+
await this.cache.clear();
|
|
171
173
|
}
|
|
172
174
|
/**
|
|
173
175
|
* Stop the upstream (cleanup resources).
|
|
@@ -392,7 +394,7 @@ export class BaseUpstream {
|
|
|
392
394
|
try {
|
|
393
395
|
const result = await withCircuitBreaker(breaker, () => this.fetchFromUpstream(upstream, context));
|
|
394
396
|
if (result.success && result.body) {
|
|
395
|
-
this.cache.set(context, Buffer.isBuffer(result.body) ? result.body : Buffer.from(JSON.stringify(result.body)), result.headers['content-type'] || 'application/octet-stream', result.headers, upstream.id);
|
|
397
|
+
await this.cache.set(context, Buffer.isBuffer(result.body) ? result.body : Buffer.from(JSON.stringify(result.body)), result.headers['content-type'] || 'application/octet-stream', result.headers, upstream.id, upstream.url);
|
|
396
398
|
return; // Successfully revalidated
|
|
397
399
|
}
|
|
398
400
|
}
|
|
@@ -406,4 +408,4 @@ export class BaseUpstream {
|
|
|
406
408
|
}
|
|
407
409
|
}
|
|
408
410
|
}
|
|
409
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5iYXNldXBzdHJlYW0uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy91cHN0cmVhbS9jbGFzc2VzLmJhc2V1cHN0cmVhbS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQztBQVl6QyxPQUFPLEVBQ0wsb0JBQW9CLEVBQ3BCLHlCQUF5QixHQUMxQixNQUFNLDBCQUEwQixDQUFDO0FBQ2xDLE9BQU8sRUFBRSxjQUFjLEVBQUUsZ0JBQWdCLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNuRyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFM0Q7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCxNQUFNLE9BQWdCLFlBQVk7SUFJaEMsNkJBQTZCO0lBQ1YsTUFBTSxDQUEwQjtJQUVuRCxtQ0FBbUM7SUFDaEIsV0FBVyxDQUF1QjtJQUVyRCx3Q0FBd0M7SUFDckIsZ0JBQWdCLENBQTRCO0lBRS9ELG9DQUFvQztJQUNqQixlQUFlLEdBQWdDLElBQUksR0FBRyxFQUFFLENBQUM7SUFFNUUscUJBQXFCO0lBQ0YsS0FBSyxDQUFnQjtJQUV4QyxzQkFBc0I7SUFDSCxNQUFNLENBQTRCO0lBRXJELFlBQVksTUFBK0IsRUFBRSxNQUFrQztRQUM3RSxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsV0FBVyxHQUFHLEVBQUUsR0FBRyxvQkFBb0IsRUFBRSxHQUFHLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNoRSxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsRUFBRSxHQUFHLHlCQUF5QixFQUFFLEdBQUcsTUFBTSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQy9FLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxhQUFhLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ2pELElBQUksQ0FBQyxNQUFNLEdBQUcs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
|
|
411
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5iYXNldXBzdHJlYW0uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy91cHN0cmVhbS9jbGFzc2VzLmJhc2V1cHN0cmVhbS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQztBQVl6QyxPQUFPLEVBQ0wsb0JBQW9CLEVBQ3BCLHlCQUF5QixHQUMxQixNQUFNLDBCQUEwQixDQUFDO0FBQ2xDLE9BQU8sRUFBRSxjQUFjLEVBQUUsZ0JBQWdCLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNuRyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFM0Q7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCxNQUFNLE9BQWdCLFlBQVk7SUFJaEMsNkJBQTZCO0lBQ1YsTUFBTSxDQUEwQjtJQUVuRCxtQ0FBbUM7SUFDaEIsV0FBVyxDQUF1QjtJQUVyRCx3Q0FBd0M7SUFDckIsZ0JBQWdCLENBQTRCO0lBRS9ELG9DQUFvQztJQUNqQixlQUFlLEdBQWdDLElBQUksR0FBRyxFQUFFLENBQUM7SUFFNUUscUJBQXFCO0lBQ0YsS0FBSyxDQUFnQjtJQUV4QyxzQkFBc0I7SUFDSCxNQUFNLENBQTRCO0lBRXJELFlBQVksTUFBK0IsRUFBRSxNQUFrQztRQUM3RSxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsV0FBVyxHQUFHLEVBQUUsR0FBRyxvQkFBb0IsRUFBRSxHQUFHLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNoRSxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsRUFBRSxHQUFHLHlCQUF5QixFQUFFLEdBQUcsTUFBTSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQy9FLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxhQUFhLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ2pELElBQUksQ0FBQyxNQUFNLEdBQUcs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
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ICacheEntry, IUpstreamCacheConfig, IUpstreamFetchContext } from './interfaces.upstream.js';
|
|
2
|
+
import type { IStorageBackend } from '../core/interfaces.core.js';
|
|
2
3
|
/**
|
|
3
|
-
*
|
|
4
|
+
* S3-backed upstream cache with in-memory hot layer.
|
|
4
5
|
*
|
|
5
6
|
* Features:
|
|
6
7
|
* - TTL-based expiration
|
|
@@ -8,58 +9,76 @@ import type { ICacheEntry, IUpstreamCacheConfig, IUpstreamFetchContext } from '.
|
|
|
8
9
|
* - Negative caching (404s)
|
|
9
10
|
* - Content-type aware caching
|
|
10
11
|
* - ETag support for conditional requests
|
|
12
|
+
* - Multi-upstream support via URL-based cache paths
|
|
13
|
+
* - Persistent S3 storage with in-memory hot layer
|
|
11
14
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
15
|
+
* Cache paths are structured as:
|
|
16
|
+
* cache/{escaped-upstream-url}/{protocol}:{method}:{path}
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* // In-memory only (default)
|
|
21
|
+
* const cache = new UpstreamCache(config);
|
|
22
|
+
*
|
|
23
|
+
* // With S3 persistence
|
|
24
|
+
* const cache = new UpstreamCache(config, 10000, storage);
|
|
25
|
+
* ```
|
|
14
26
|
*/
|
|
15
27
|
export declare class UpstreamCache {
|
|
16
|
-
/**
|
|
17
|
-
private readonly
|
|
28
|
+
/** In-memory hot cache */
|
|
29
|
+
private readonly memoryCache;
|
|
18
30
|
/** Configuration */
|
|
19
31
|
private readonly config;
|
|
20
|
-
/** Maximum cache entries
|
|
21
|
-
private readonly
|
|
32
|
+
/** Maximum in-memory cache entries */
|
|
33
|
+
private readonly maxMemoryEntries;
|
|
34
|
+
/** S3 storage backend (optional) */
|
|
35
|
+
private readonly storage?;
|
|
22
36
|
/** Cleanup interval handle */
|
|
23
37
|
private cleanupInterval;
|
|
24
|
-
constructor(config?: Partial<IUpstreamCacheConfig>,
|
|
38
|
+
constructor(config?: Partial<IUpstreamCacheConfig>, maxMemoryEntries?: number, storage?: IStorageBackend);
|
|
25
39
|
/**
|
|
26
40
|
* Check if caching is enabled.
|
|
27
41
|
*/
|
|
28
42
|
isEnabled(): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Check if S3 storage is configured.
|
|
45
|
+
*/
|
|
46
|
+
hasStorage(): boolean;
|
|
29
47
|
/**
|
|
30
48
|
* Get cached entry for a request context.
|
|
49
|
+
* Checks memory first, then falls back to S3.
|
|
31
50
|
* Returns null if not found or expired (unless stale-while-revalidate).
|
|
32
51
|
*/
|
|
33
|
-
get(context: IUpstreamFetchContext): ICacheEntry | null
|
|
52
|
+
get(context: IUpstreamFetchContext, upstreamUrl?: string): Promise<ICacheEntry | null>;
|
|
34
53
|
/**
|
|
35
|
-
* Store a response in the cache.
|
|
54
|
+
* Store a response in the cache (memory and optionally S3).
|
|
36
55
|
*/
|
|
37
|
-
set(context: IUpstreamFetchContext, data: Buffer, contentType: string, headers: Record<string, string>, upstreamId: string, options?: ICacheSetOptions): void
|
|
56
|
+
set(context: IUpstreamFetchContext, data: Buffer, contentType: string, headers: Record<string, string>, upstreamId: string, upstreamUrl: string, options?: ICacheSetOptions): Promise<void>;
|
|
38
57
|
/**
|
|
39
58
|
* Store a negative cache entry (404 response).
|
|
40
59
|
*/
|
|
41
|
-
setNegative(context: IUpstreamFetchContext, upstreamId: string): void
|
|
60
|
+
setNegative(context: IUpstreamFetchContext, upstreamId: string, upstreamUrl: string): Promise<void>;
|
|
42
61
|
/**
|
|
43
62
|
* Check if there's a negative cache entry for this context.
|
|
44
63
|
*/
|
|
45
|
-
hasNegative(context: IUpstreamFetchContext): boolean
|
|
64
|
+
hasNegative(context: IUpstreamFetchContext, upstreamUrl?: string): Promise<boolean>;
|
|
46
65
|
/**
|
|
47
66
|
* Invalidate a specific cache entry.
|
|
48
67
|
*/
|
|
49
|
-
invalidate(context: IUpstreamFetchContext): boolean
|
|
68
|
+
invalidate(context: IUpstreamFetchContext, upstreamUrl?: string): Promise<boolean>;
|
|
50
69
|
/**
|
|
51
70
|
* Invalidate all entries matching a pattern.
|
|
52
71
|
* Useful for invalidating all versions of a package.
|
|
53
72
|
*/
|
|
54
|
-
invalidatePattern(pattern: RegExp): number
|
|
73
|
+
invalidatePattern(pattern: RegExp): Promise<number>;
|
|
55
74
|
/**
|
|
56
75
|
* Invalidate all entries from a specific upstream.
|
|
57
76
|
*/
|
|
58
|
-
invalidateUpstream(upstreamId: string): number
|
|
77
|
+
invalidateUpstream(upstreamId: string): Promise<number>;
|
|
59
78
|
/**
|
|
60
|
-
* Clear all cache entries.
|
|
79
|
+
* Clear all cache entries (memory and S3).
|
|
61
80
|
*/
|
|
62
|
-
clear(): void
|
|
81
|
+
clear(): Promise<void>;
|
|
63
82
|
/**
|
|
64
83
|
* Get cache statistics.
|
|
65
84
|
*/
|
|
@@ -68,8 +87,34 @@ export declare class UpstreamCache {
|
|
|
68
87
|
* Stop the cache and cleanup.
|
|
69
88
|
*/
|
|
70
89
|
stop(): void;
|
|
90
|
+
/**
|
|
91
|
+
* Build storage path for a cache key.
|
|
92
|
+
* Escapes upstream URL for safe use in S3 paths.
|
|
93
|
+
*/
|
|
94
|
+
private buildStoragePath;
|
|
95
|
+
/**
|
|
96
|
+
* Build storage path for cache metadata.
|
|
97
|
+
*/
|
|
98
|
+
private buildMetadataPath;
|
|
99
|
+
/**
|
|
100
|
+
* Load a cache entry from S3 storage.
|
|
101
|
+
*/
|
|
102
|
+
private loadFromStorage;
|
|
103
|
+
/**
|
|
104
|
+
* Save a cache entry to S3 storage.
|
|
105
|
+
*/
|
|
106
|
+
private saveToStorage;
|
|
107
|
+
/**
|
|
108
|
+
* Delete a cache entry from S3 storage.
|
|
109
|
+
*/
|
|
110
|
+
private deleteFromStorage;
|
|
111
|
+
/**
|
|
112
|
+
* Escape a URL for safe use in storage paths.
|
|
113
|
+
*/
|
|
114
|
+
private escapeUrl;
|
|
71
115
|
/**
|
|
72
116
|
* Build a unique cache key for a request context.
|
|
117
|
+
* Includes escaped upstream URL for multi-upstream support.
|
|
73
118
|
*/
|
|
74
119
|
private buildCacheKey;
|
|
75
120
|
/**
|
|
@@ -89,7 +134,7 @@ export declare class UpstreamCache {
|
|
|
89
134
|
*/
|
|
90
135
|
private startCleanup;
|
|
91
136
|
/**
|
|
92
|
-
* Remove all expired entries.
|
|
137
|
+
* Remove all expired entries from memory cache.
|
|
93
138
|
*/
|
|
94
139
|
private cleanup;
|
|
95
140
|
}
|
|
@@ -106,7 +151,7 @@ export interface ICacheSetOptions {
|
|
|
106
151
|
* Cache statistics.
|
|
107
152
|
*/
|
|
108
153
|
export interface ICacheStats {
|
|
109
|
-
/** Total number of cached entries */
|
|
154
|
+
/** Total number of cached entries in memory */
|
|
110
155
|
totalEntries: number;
|
|
111
156
|
/** Number of fresh (non-expired) entries */
|
|
112
157
|
freshEntries: number;
|
|
@@ -114,10 +159,12 @@ export interface ICacheStats {
|
|
|
114
159
|
staleEntries: number;
|
|
115
160
|
/** Number of negative cache entries */
|
|
116
161
|
negativeEntries: number;
|
|
117
|
-
/** Total size of cached data in bytes */
|
|
162
|
+
/** Total size of cached data in bytes (memory only) */
|
|
118
163
|
totalSizeBytes: number;
|
|
119
|
-
/** Maximum allowed entries */
|
|
164
|
+
/** Maximum allowed memory entries */
|
|
120
165
|
maxEntries: number;
|
|
121
166
|
/** Whether caching is enabled */
|
|
122
167
|
enabled: boolean;
|
|
168
|
+
/** Whether S3 storage is configured */
|
|
169
|
+
hasStorage: boolean;
|
|
123
170
|
}
|