Spaces:
Sleeping
Sleeping
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;
}
}
|