@agent-foundry/replay-server 1.0.0 → 1.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/.cursor/dev.mdc +941 -0
- package/.cursor/project.mdc +17 -2
- package/.env +30 -0
- package/Dockerfile +6 -0
- package/README.md +153 -12
- package/dist/cli/render.js +14 -4
- package/dist/cli/render.js.map +1 -1
- package/dist/renderer/PuppeteerRenderer.d.ts +12 -2
- package/dist/renderer/PuppeteerRenderer.d.ts.map +1 -1
- package/dist/renderer/PuppeteerRenderer.js +23 -16
- package/dist/renderer/PuppeteerRenderer.js.map +1 -1
- package/dist/server/index.d.ts +4 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +200 -46
- package/dist/server/index.js.map +1 -1
- package/dist/services/BundleManager.d.ts +99 -0
- package/dist/services/BundleManager.d.ts.map +1 -0
- package/dist/services/BundleManager.js +410 -0
- package/dist/services/BundleManager.js.map +1 -0
- package/dist/services/OSSClient.d.ts +51 -0
- package/dist/services/OSSClient.d.ts.map +1 -0
- package/dist/services/OSSClient.js +207 -0
- package/dist/services/OSSClient.js.map +1 -0
- package/dist/services/index.d.ts +7 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +7 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/types.d.ts +73 -0
- package/dist/services/types.d.ts.map +1 -0
- package/dist/services/types.js +5 -0
- package/dist/services/types.js.map +1 -0
- package/docker-compose.local.yml +8 -0
- package/env.example +30 -0
- package/package.json +7 -3
- package/restart.sh +5 -0
- package/samples/jump_arena_0_ja-mks5um2x-nksbmz.json +1907 -0
- package/scripts/render-pipeline.sh +657 -0
- package/scripts/test-bundle-preload.sh +20 -0
- package/scripts/test-service-sts.sh +176 -0
- package/src/cli/render.ts +18 -7
- package/src/renderer/PuppeteerRenderer.ts +41 -21
- package/src/server/index.ts +249 -68
- package/src/services/BundleManager.ts +503 -0
- package/src/services/OSSClient.ts +286 -0
- package/src/services/index.ts +7 -0
- package/src/services/types.ts +78 -0
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bundle Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages bundle lifecycle: download, extraction, caching, and cleanup.
|
|
5
|
+
* Uses LRU eviction to manage cache size.
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from 'fs';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
import { createGunzip } from 'zlib';
|
|
10
|
+
import { extract } from 'tar-stream';
|
|
11
|
+
/**
|
|
12
|
+
* Error thrown by bundle manager operations
|
|
13
|
+
*/
|
|
14
|
+
export class BundleManagerError extends Error {
|
|
15
|
+
code;
|
|
16
|
+
bundleId;
|
|
17
|
+
constructor(message, code, bundleId) {
|
|
18
|
+
super(message);
|
|
19
|
+
this.code = code;
|
|
20
|
+
this.bundleId = bundleId;
|
|
21
|
+
this.name = 'BundleManagerError';
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Bundle Manager for downloading, caching, and serving game bundles
|
|
26
|
+
*/
|
|
27
|
+
export class BundleManager {
|
|
28
|
+
bundlesDir;
|
|
29
|
+
maxCacheSize;
|
|
30
|
+
ossClient;
|
|
31
|
+
bundles = new Map();
|
|
32
|
+
downloadPromises = new Map();
|
|
33
|
+
bundlesInUse = new Set();
|
|
34
|
+
downloadStats = {
|
|
35
|
+
active: 0,
|
|
36
|
+
completed: 0,
|
|
37
|
+
failed: 0,
|
|
38
|
+
};
|
|
39
|
+
constructor(config) {
|
|
40
|
+
this.bundlesDir = config.bundlesDir;
|
|
41
|
+
this.maxCacheSize = config.maxCacheSize;
|
|
42
|
+
this.ossClient = config.ossClient;
|
|
43
|
+
// Ensure bundles directory exists
|
|
44
|
+
fs.mkdirSync(this.bundlesDir, { recursive: true });
|
|
45
|
+
// Load existing bundles from disk
|
|
46
|
+
this.loadCachedBundles();
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Ensure a bundle is available (download if needed)
|
|
50
|
+
* Returns the path to the bundle directory
|
|
51
|
+
*/
|
|
52
|
+
async ensureBundle(bundleId, bundleUrl) {
|
|
53
|
+
const bundlePath = path.join(this.bundlesDir, bundleId);
|
|
54
|
+
// Check if already cached
|
|
55
|
+
if (this.isCached(bundleId)) {
|
|
56
|
+
// Update last accessed time
|
|
57
|
+
const info = this.bundles.get(bundleId);
|
|
58
|
+
if (info) {
|
|
59
|
+
info.lastAccessedAt = new Date();
|
|
60
|
+
}
|
|
61
|
+
return bundlePath;
|
|
62
|
+
}
|
|
63
|
+
// Check if already downloading
|
|
64
|
+
if (this.downloadPromises.has(bundleId)) {
|
|
65
|
+
console.log(`[BundleManager] Waiting for existing download: ${bundleId}`);
|
|
66
|
+
return this.downloadPromises.get(bundleId);
|
|
67
|
+
}
|
|
68
|
+
// Need to download
|
|
69
|
+
if (!bundleUrl) {
|
|
70
|
+
throw new BundleManagerError(`Bundle ${bundleId} not cached and no bundleUrl provided`, 'BUNDLE_URL_REQUIRED', bundleId);
|
|
71
|
+
}
|
|
72
|
+
// Start download
|
|
73
|
+
const downloadPromise = this.downloadBundle(bundleId, bundleUrl);
|
|
74
|
+
this.downloadPromises.set(bundleId, downloadPromise);
|
|
75
|
+
try {
|
|
76
|
+
const result = await downloadPromise;
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
this.downloadPromises.delete(bundleId);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Check if a bundle is cached and ready
|
|
85
|
+
*/
|
|
86
|
+
isCached(bundleId) {
|
|
87
|
+
const bundlePath = path.join(this.bundlesDir, bundleId);
|
|
88
|
+
const indexPath = path.join(bundlePath, 'index.html');
|
|
89
|
+
return fs.existsSync(bundlePath) && fs.existsSync(indexPath);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Mark bundle as in use (prevents eviction during rendering)
|
|
93
|
+
*/
|
|
94
|
+
markInUse(bundleId) {
|
|
95
|
+
this.bundlesInUse.add(bundleId);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Mark bundle as no longer in use
|
|
99
|
+
*/
|
|
100
|
+
markNotInUse(bundleId) {
|
|
101
|
+
this.bundlesInUse.delete(bundleId);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Download and extract a bundle
|
|
105
|
+
*/
|
|
106
|
+
async downloadBundle(bundleId, bundleUrl) {
|
|
107
|
+
const bundlePath = path.join(this.bundlesDir, bundleId);
|
|
108
|
+
const tempPath = `${bundlePath}.downloading`;
|
|
109
|
+
const archivePath = `${bundlePath}.tar.gz`;
|
|
110
|
+
// Initialize bundle info
|
|
111
|
+
this.bundles.set(bundleId, {
|
|
112
|
+
bundleId,
|
|
113
|
+
bundleUrl,
|
|
114
|
+
status: 'downloading',
|
|
115
|
+
progress: 0,
|
|
116
|
+
});
|
|
117
|
+
this.downloadStats.active++;
|
|
118
|
+
try {
|
|
119
|
+
console.log(`[BundleManager] Downloading bundle ${bundleId} from ${bundleUrl}`);
|
|
120
|
+
// Ensure cache has space
|
|
121
|
+
await this.ensureCacheSpace(100 * 1024 * 1024); // Reserve 100MB
|
|
122
|
+
// Download archive
|
|
123
|
+
await this.ossClient.downloadFile(bundleUrl, archivePath, (percent) => {
|
|
124
|
+
const info = this.bundles.get(bundleId);
|
|
125
|
+
if (info) {
|
|
126
|
+
info.progress = percent;
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
console.log(`[BundleManager] Extracting bundle ${bundleId}...`);
|
|
130
|
+
// Create temp directory for extraction
|
|
131
|
+
fs.mkdirSync(tempPath, { recursive: true });
|
|
132
|
+
// Extract TAR.GZ
|
|
133
|
+
await this.extractTarGz(archivePath, tempPath);
|
|
134
|
+
// Clean up archive
|
|
135
|
+
fs.unlinkSync(archivePath);
|
|
136
|
+
// Move temp to final location
|
|
137
|
+
if (fs.existsSync(bundlePath)) {
|
|
138
|
+
fs.rmSync(bundlePath, { recursive: true });
|
|
139
|
+
}
|
|
140
|
+
fs.renameSync(tempPath, bundlePath);
|
|
141
|
+
// Verify extraction
|
|
142
|
+
const indexPath = path.join(bundlePath, 'index.html');
|
|
143
|
+
if (!fs.existsSync(indexPath)) {
|
|
144
|
+
throw new BundleManagerError(`Bundle extraction failed: index.html not found`, 'EXTRACTION_INVALID', bundleId);
|
|
145
|
+
}
|
|
146
|
+
// Calculate bundle size
|
|
147
|
+
const size = this.getDirectorySize(bundlePath);
|
|
148
|
+
// Update bundle info
|
|
149
|
+
this.bundles.set(bundleId, {
|
|
150
|
+
bundleId,
|
|
151
|
+
bundleUrl,
|
|
152
|
+
status: 'ready',
|
|
153
|
+
size,
|
|
154
|
+
cachedAt: new Date(),
|
|
155
|
+
lastAccessedAt: new Date(),
|
|
156
|
+
});
|
|
157
|
+
this.downloadStats.active--;
|
|
158
|
+
this.downloadStats.completed++;
|
|
159
|
+
console.log(`[BundleManager] Bundle ${bundleId} ready (${(size / 1024 / 1024).toFixed(2)} MB)`);
|
|
160
|
+
return bundlePath;
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
// Cleanup on error
|
|
164
|
+
for (const p of [tempPath, archivePath, bundlePath]) {
|
|
165
|
+
if (fs.existsSync(p)) {
|
|
166
|
+
try {
|
|
167
|
+
fs.rmSync(p, { recursive: true });
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
// Ignore cleanup errors
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
175
|
+
this.bundles.set(bundleId, {
|
|
176
|
+
bundleId,
|
|
177
|
+
bundleUrl,
|
|
178
|
+
status: 'error',
|
|
179
|
+
error: errorMessage,
|
|
180
|
+
});
|
|
181
|
+
this.downloadStats.active--;
|
|
182
|
+
this.downloadStats.failed++;
|
|
183
|
+
throw new BundleManagerError(`Failed to download bundle ${bundleId}: ${errorMessage}`, 'DOWNLOAD_FAILED', bundleId);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Extract TAR.GZ archive to destination directory
|
|
188
|
+
*/
|
|
189
|
+
async extractTarGz(archivePath, destPath) {
|
|
190
|
+
return new Promise((resolve, reject) => {
|
|
191
|
+
const extractStream = extract();
|
|
192
|
+
const entries = [];
|
|
193
|
+
extractStream.on('entry', (header, stream, next) => {
|
|
194
|
+
let filePath = path.join(destPath, header.name);
|
|
195
|
+
// Handle case where archive has a single root directory
|
|
196
|
+
// (common with GitHub releases: bundle-v1.0.0/index.html)
|
|
197
|
+
entries.push(header.name);
|
|
198
|
+
if (header.type === 'directory') {
|
|
199
|
+
fs.mkdirSync(filePath, { recursive: true });
|
|
200
|
+
stream.resume();
|
|
201
|
+
next();
|
|
202
|
+
}
|
|
203
|
+
else if (header.type === 'file') {
|
|
204
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
205
|
+
const writeStream = fs.createWriteStream(filePath);
|
|
206
|
+
stream.pipe(writeStream);
|
|
207
|
+
stream.on('end', () => {
|
|
208
|
+
writeStream.end();
|
|
209
|
+
next();
|
|
210
|
+
});
|
|
211
|
+
stream.on('error', reject);
|
|
212
|
+
writeStream.on('error', reject);
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
// Skip other types (symlinks, etc.)
|
|
216
|
+
stream.resume();
|
|
217
|
+
next();
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
extractStream.on('finish', () => {
|
|
221
|
+
// Check if all files are in a subdirectory
|
|
222
|
+
// If so, move them up one level
|
|
223
|
+
const subdirs = fs.readdirSync(destPath);
|
|
224
|
+
if (subdirs.length === 1) {
|
|
225
|
+
const subdir = path.join(destPath, subdirs[0]);
|
|
226
|
+
if (fs.statSync(subdir).isDirectory()) {
|
|
227
|
+
// Check if index.html is in subdirectory
|
|
228
|
+
if (fs.existsSync(path.join(subdir, 'index.html'))) {
|
|
229
|
+
// Move all files up
|
|
230
|
+
const files = fs.readdirSync(subdir);
|
|
231
|
+
for (const file of files) {
|
|
232
|
+
fs.renameSync(path.join(subdir, file), path.join(destPath, file));
|
|
233
|
+
}
|
|
234
|
+
fs.rmdirSync(subdir);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
resolve();
|
|
239
|
+
});
|
|
240
|
+
extractStream.on('error', reject);
|
|
241
|
+
const gunzip = createGunzip();
|
|
242
|
+
gunzip.on('error', reject);
|
|
243
|
+
const readStream = fs.createReadStream(archivePath);
|
|
244
|
+
readStream.on('error', reject);
|
|
245
|
+
readStream.pipe(gunzip).pipe(extractStream);
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Ensure cache has enough space by evicting old bundles
|
|
250
|
+
*/
|
|
251
|
+
async ensureCacheSpace(requiredBytes) {
|
|
252
|
+
const stats = this.getCacheStats();
|
|
253
|
+
const availableBytes = this.maxCacheSize - stats.used;
|
|
254
|
+
if (availableBytes >= requiredBytes) {
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
const bytesToFree = requiredBytes - availableBytes;
|
|
258
|
+
let freedBytes = 0;
|
|
259
|
+
// Get bundles sorted by last accessed time (oldest first)
|
|
260
|
+
const evictionCandidates = Array.from(this.bundles.entries())
|
|
261
|
+
.filter(([id, info]) => {
|
|
262
|
+
return (info.status === 'ready' &&
|
|
263
|
+
!this.bundlesInUse.has(id) &&
|
|
264
|
+
!this.downloadPromises.has(id));
|
|
265
|
+
})
|
|
266
|
+
.sort(([, a], [, b]) => {
|
|
267
|
+
const aTime = a.lastAccessedAt?.getTime() || 0;
|
|
268
|
+
const bTime = b.lastAccessedAt?.getTime() || 0;
|
|
269
|
+
return aTime - bTime;
|
|
270
|
+
});
|
|
271
|
+
for (const [bundleId, info] of evictionCandidates) {
|
|
272
|
+
if (freedBytes >= bytesToFree) {
|
|
273
|
+
break;
|
|
274
|
+
}
|
|
275
|
+
console.log(`[BundleManager] Evicting bundle ${bundleId} to free space`);
|
|
276
|
+
this.removeBundle(bundleId);
|
|
277
|
+
freedBytes += info.size || 0;
|
|
278
|
+
}
|
|
279
|
+
if (freedBytes < bytesToFree) {
|
|
280
|
+
throw new BundleManagerError(`Unable to free enough cache space (needed: ${bytesToFree}, freed: ${freedBytes})`, 'CACHE_FULL');
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Load existing bundles from disk
|
|
285
|
+
*/
|
|
286
|
+
loadCachedBundles() {
|
|
287
|
+
if (!fs.existsSync(this.bundlesDir)) {
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
const entries = fs.readdirSync(this.bundlesDir, { withFileTypes: true });
|
|
291
|
+
for (const entry of entries) {
|
|
292
|
+
if (!entry.isDirectory()) {
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
// Skip temp directories
|
|
296
|
+
if (entry.name.endsWith('.downloading') || entry.name.endsWith('.tar.gz')) {
|
|
297
|
+
// Clean up orphaned temp files
|
|
298
|
+
try {
|
|
299
|
+
fs.rmSync(path.join(this.bundlesDir, entry.name), { recursive: true });
|
|
300
|
+
}
|
|
301
|
+
catch {
|
|
302
|
+
// Ignore
|
|
303
|
+
}
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
const bundlePath = path.join(this.bundlesDir, entry.name);
|
|
307
|
+
const indexPath = path.join(bundlePath, 'index.html');
|
|
308
|
+
if (fs.existsSync(indexPath)) {
|
|
309
|
+
const stats = fs.statSync(bundlePath);
|
|
310
|
+
const size = this.getDirectorySize(bundlePath);
|
|
311
|
+
this.bundles.set(entry.name, {
|
|
312
|
+
bundleId: entry.name,
|
|
313
|
+
status: 'ready',
|
|
314
|
+
size,
|
|
315
|
+
cachedAt: stats.mtime,
|
|
316
|
+
lastAccessedAt: stats.mtime,
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
console.log(`[BundleManager] Loaded ${this.bundles.size} cached bundles`);
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Get directory size recursively
|
|
324
|
+
*/
|
|
325
|
+
getDirectorySize(dirPath) {
|
|
326
|
+
let size = 0;
|
|
327
|
+
try {
|
|
328
|
+
const files = fs.readdirSync(dirPath);
|
|
329
|
+
for (const file of files) {
|
|
330
|
+
const filePath = path.join(dirPath, file);
|
|
331
|
+
const stats = fs.statSync(filePath);
|
|
332
|
+
if (stats.isDirectory()) {
|
|
333
|
+
size += this.getDirectorySize(filePath);
|
|
334
|
+
}
|
|
335
|
+
else {
|
|
336
|
+
size += stats.size;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
catch {
|
|
341
|
+
// Ignore errors
|
|
342
|
+
}
|
|
343
|
+
return size;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* List all bundles
|
|
347
|
+
*/
|
|
348
|
+
listBundles() {
|
|
349
|
+
return Array.from(this.bundles.values());
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Get bundle info
|
|
353
|
+
*/
|
|
354
|
+
getBundleInfo(bundleId) {
|
|
355
|
+
return this.bundles.get(bundleId);
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Remove bundle from cache
|
|
359
|
+
*/
|
|
360
|
+
removeBundle(bundleId) {
|
|
361
|
+
const bundlePath = path.join(this.bundlesDir, bundleId);
|
|
362
|
+
if (fs.existsSync(bundlePath)) {
|
|
363
|
+
try {
|
|
364
|
+
fs.rmSync(bundlePath, { recursive: true });
|
|
365
|
+
}
|
|
366
|
+
catch (error) {
|
|
367
|
+
console.error(`[BundleManager] Failed to remove bundle ${bundleId}:`, error);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
this.bundles.delete(bundleId);
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Get cache statistics
|
|
374
|
+
*/
|
|
375
|
+
getCacheStats() {
|
|
376
|
+
let used = 0;
|
|
377
|
+
let count = 0;
|
|
378
|
+
for (const info of this.bundles.values()) {
|
|
379
|
+
if (info.status === 'ready' && info.size) {
|
|
380
|
+
used += info.size;
|
|
381
|
+
count++;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
return {
|
|
385
|
+
used,
|
|
386
|
+
max: this.maxCacheSize,
|
|
387
|
+
usedPercent: Math.round((used / this.maxCacheSize) * 100),
|
|
388
|
+
bundleCount: count,
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Get download statistics
|
|
393
|
+
*/
|
|
394
|
+
getDownloadStats() {
|
|
395
|
+
return { ...this.downloadStats };
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Get bundles directory path
|
|
399
|
+
*/
|
|
400
|
+
getBundlesDir() {
|
|
401
|
+
return this.bundlesDir;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Create a bundle manager instance
|
|
406
|
+
*/
|
|
407
|
+
export function createBundleManager(config) {
|
|
408
|
+
return new BundleManager(config);
|
|
409
|
+
}
|
|
410
|
+
//# sourceMappingURL=BundleManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BundleManager.js","sourceRoot":"","sources":["../../src/services/BundleManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OSS Client
|
|
3
|
+
*
|
|
4
|
+
* Handles authenticated downloads from Alibaba Cloud OSS using STS credentials
|
|
5
|
+
* obtained from the BFF API.
|
|
6
|
+
*/
|
|
7
|
+
import type { STSCredentials, OSSClientConfig } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Error thrown by OSS client operations
|
|
10
|
+
*/
|
|
11
|
+
export declare class OSSClientError extends Error {
|
|
12
|
+
readonly code: string;
|
|
13
|
+
readonly statusCode?: number | undefined;
|
|
14
|
+
constructor(message: string, code: string, statusCode?: number | undefined);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* OSS Client for downloading bundles with STS authentication
|
|
18
|
+
*/
|
|
19
|
+
export declare class OSSClient {
|
|
20
|
+
private readonly bffBaseUrl;
|
|
21
|
+
private readonly serviceToken?;
|
|
22
|
+
private readonly timeout;
|
|
23
|
+
private cachedCredentials;
|
|
24
|
+
private credentialsExpiresAt;
|
|
25
|
+
constructor(config: OSSClientConfig);
|
|
26
|
+
/**
|
|
27
|
+
* Get STS credentials from BFF API
|
|
28
|
+
* Caches credentials until they expire (with 5 minute buffer)
|
|
29
|
+
*
|
|
30
|
+
* Uses the /studio/service/sts endpoint which requires BFF_SERVICE_TOKEN
|
|
31
|
+
* (set to SUPABASE_JWT_SECRET) for service-to-service authentication.
|
|
32
|
+
*/
|
|
33
|
+
getSTSCredentials(): Promise<STSCredentials>;
|
|
34
|
+
/**
|
|
35
|
+
* Download file from OSS URL with STS authentication
|
|
36
|
+
*
|
|
37
|
+
* @param url - OSS URL to download from
|
|
38
|
+
* @param destPath - Local destination path
|
|
39
|
+
* @param onProgress - Optional progress callback (0-100)
|
|
40
|
+
*/
|
|
41
|
+
downloadFile(url: string, destPath: string, onProgress?: (percent: number) => void): Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* Clear cached credentials
|
|
44
|
+
*/
|
|
45
|
+
clearCredentialsCache(): void;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Create an OSS client instance
|
|
49
|
+
*/
|
|
50
|
+
export declare function createOSSClient(config: OSSClientConfig): OSSClient;
|
|
51
|
+
//# sourceMappingURL=OSSClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OSSClient.d.ts","sourceRoot":"","sources":["../../src/services/OSSClient.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElE;;GAEG;AACH,qBAAa,cAAe,SAAQ,KAAK;aAGjB,IAAI,EAAE,MAAM;aACZ,UAAU,CAAC,EAAE,MAAM;gBAFnC,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,YAAA;CAK1C;AAED;;GAEG;AACH,qBAAa,SAAS;IAClB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAEjC,OAAO,CAAC,iBAAiB,CAA+B;IACxD,OAAO,CAAC,oBAAoB,CAAqB;gBAErC,MAAM,EAAE,eAAe;IAMnC;;;;;;OAMG;IACG,iBAAiB,IAAI,OAAO,CAAC,cAAc,CAAC;IA8GlD;;;;;;OAMG;IACG,YAAY,CACd,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GACvC,OAAO,CAAC,IAAI,CAAC;IAoGhB;;OAEG;IACH,qBAAqB,IAAI,IAAI;CAIhC;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,CAElE"}
|