feat: object storage

This commit is contained in:
Thomas Way 2023-10-11 15:42:36 +01:00
parent 8d5bf93360
commit f66a79fe08
No known key found for this signature in database
GPG key ID: F98E7FF1F9F8C217
5 changed files with 2721 additions and 3 deletions

2615
server/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -39,6 +39,8 @@
"api:generate": "node ./bin/sync-spec-version.js && bash ./bin/generate-open-api.sh"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.427.0",
"@aws-sdk/lib-storage": "^3.427.0",
"@babel/runtime": "^7.22.11",
"@nestjs/bullmq": "^10.0.1",
"@nestjs/common": "^10.2.2",

View file

@ -0,0 +1,27 @@
import { Readable, Writable } from "stream";
export interface FS {
// create creates an object with the given name.
create(name: string): Promise<Writable>;
// open opens the named object.
open(name: string): Promise<Readable>;
// remove removes the named object.
remove(name: string): Promise<void>;
}
// export interface FS {
// // create creates an object with the given name.
// create(name: string): Promise<Writable>;
// // open opens the object with the given name.
// open(name: string): Promise<Object>;
// // remove removes the named object.
// remove(name: string): Promise<void>;
// }
// export interface Object {
// createReadableStream(): Promise<Readable>;
// }

View file

@ -0,0 +1,21 @@
import { constants, open, unlink } from "fs/promises";
import { join } from "path";
import { Readable, Writable } from "stream";
export class LocalFS {
constructor(private dir: string) { }
async create(name: string): Promise<Writable> {
const file = await open(join(this.dir, name), constants.O_WRONLY);
return file.createWriteStream();
}
async open(name: string): Promise<Readable> {
const file = await open(join(this.dir, name), constants.O_RDONLY);
return file.createReadStream();
}
async remove(name: string): Promise<void> {
await unlink(join(this.dir, name));
}
}

View file

@ -0,0 +1,59 @@
import { PassThrough, Readable, Writable } from "stream";
import { S3 } from "@aws-sdk/client-s3";
import { FS } from "./fs";
import { Upload } from "@aws-sdk/lib-storage";
export class S3FS implements FS {
s3: S3;
constructor(private bucket: string) {
this.s3 = new S3();
}
async create(name: string): Promise<Writable> {
const stream = new PassThrough();
const upload = new Upload({
client: this.s3,
params: {
Body: stream,
Bucket: this.bucket,
Key: name,
},
});
// Abort the upload if the stream has finished. Should be a
// no-op if the upload has already finished.
stream.on('close', () => void upload.abort());
// Close the stream when the upload is finished.
upload.done().then(() => void stream.end());
return stream;
}
async open(name: string): Promise<Readable> {
const stream = new PassThrough();
return stream;
const obj = await this.s3.getObject({
Bucket: this.bucket,
Key: name,
});
return obj.Body as Readable;
}
async remove(name: string): Promise<void> {
await this.s3.deleteObject({
Bucket: this.bucket,
Key: name,
})
}
}
// class ObjectReadable extends Readable {
// constructor(private s3: S3, private bucket: string) { }
// }