File size: 1,736 Bytes
d594446
0d57d79
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
874bd3c
0d57d79
 
874bd3c
0d57d79
 
874bd3c
0d57d79
 
 
d594446
0d57d79
 
 
874bd3c
0d57d79
 
874bd3c
0d57d79
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import { assertValidPath, assertValidPrefix, type BucketStore, type StoreEntry } from './store';

/**
 * Confines another store to `<prefix>/`, so several apps (or test runs) can share one
 * bucket under different directories. Paths seen by callers never include the prefix.
 */
export class PrefixedStore implements BucketStore {
	private readonly prefix: string;

	constructor(
		private readonly inner: BucketStore,
		prefix: string
	) {
		const trimmed = prefix.replace(/^\/+|\/+$/g, '');
		assertValidPath(trimmed);
		this.prefix = `${trimmed}/`;
	}

	private full(path: string): string {
		assertValidPath(path);
		return this.prefix + path;
	}

	async get(path: string): Promise<Uint8Array | null> {
		return this.inner.get(this.full(path));
	}
	async put(path: string, bytes: Uint8Array, contentType?: string): Promise<void> {
		return this.inner.put(this.full(path), bytes, contentType);
	}
	async append(path: string, bytes: Uint8Array): Promise<void> {
		return this.inner.append(this.full(path), bytes);
	}
	async list(prefix: string): Promise<StoreEntry[]> {
		assertValidPrefix(prefix);
		const entries = await this.inner.list(this.prefix + prefix);
		return entries.map((e) => ({ ...e, path: e.path.slice(this.prefix.length) }));
	}
	async delete(paths: string[]): Promise<void> {
		return this.inner.delete(paths.map((p) => this.full(p)));
	}
	async copy(src: string, dst: string): Promise<void> {
		return this.inner.copy(this.full(src), this.full(dst));
	}

	/** Deletes every object under this store's prefix. Returns how many were deleted. */
	async wipe(): Promise<number> {
		const entries = await this.inner.list(this.prefix);
		await this.inner.delete(entries.map((e) => e.path));
		return entries.length;
	}
}