Picsur/backend/src/collections/filestorage-db/services/filestorage-local.ts
2023-03-15 15:41:23 +01:00

85 lines
2.2 KiB
TypeScript

import { Logger } from '@nestjs/common';
import * as fs from 'fs';
import afs from 'fs/promises';
import pathlib from 'path';
import { AsyncFailable, Fail, FT, HasFailed } from 'picsur-shared/dist/types';
import { FSConfigService } from '../../../config/late/fs.config.service';
import { FileStorageService } from './filestorage-service';
export class FileStorageLocalService extends FileStorageService {
private readonly logger = new Logger(FileStorageLocalService.name);
private path = './temp';
constructor(config: FSConfigService) {
super(config);
}
async onStorageInit() {
this.path = await this.config.getLocalPath();
await this.ensureFileDir(this.path);
}
public async putFile(key: string, data: Buffer): AsyncFailable<string> {
const path = this.getKeyFilePath(key);
const result = await this.ensureFileDir(path);
if (HasFailed(result)) return result;
try {
await afs.writeFile(path, data);
return key;
} catch (e) {
return Fail(FT.FileStorage, e);
}
}
public async getFile(key: string): AsyncFailable<Buffer> {
const path = this.getKeyFilePath(key);
try {
const result = await afs.readFile(path);
return result;
} catch (e) {
return Fail(FT.FileStorage, e);
}
}
public async deleteFile(key: string): AsyncFailable<true> {
const path = this.getKeyFilePath(key);
try {
await afs.unlink(path);
return true;
} catch (e) {
return Fail(FT.FileStorage, e);
}
}
public async deleteFiles(keys: string[]): AsyncFailable<true> {
const paths = keys.map((key) => this.getKeyFilePath(key));
try {
await Promise.all(paths.map((path) => afs.unlink(path)));
return true;
} catch (e) {
return Fail(FT.FileStorage, e);
}
}
private getKeyFilePath(key: string): string {
const subfolder = key.slice(0, 4);
return pathlib.resolve(this.path, subfolder, key);
}
private async ensureFileDir(path: string): AsyncFailable<true> {
try {
const dir = path.split('/').slice(0, -1).join('/');
if (!fs.existsSync(dir)) {
await afs.mkdir(dir, {
recursive: true,
});
}
return true;
} catch (e) {
return Fail(FT.FileStorage, e);
}
}
}