hrms-edm/Services/server/src/controllers/storageController.ts
2023-11-28 08:58:06 +07:00

104 lines
3.5 KiB
TypeScript

import { Body, Controller, Get, Path, Post, Put, Query, Route, SuccessResponse } from "tsoa";
import { replaceIllegalChars } from "../utils/minio";
import minioClient from "../minio";
import HttpStatusCode from "../interfaces/http-status";
import HttpError from "../interfaces/http-error";
const DEFAULT_BUCKET = process.env.MINIO_BUCKET;
const DEFAULT_INDEX = process.env.ELASTICSEARCH_INDEX;
if (!DEFAULT_BUCKET) throw Error("Default MinIO bucket must be specified.");
if (!DEFAULT_INDEX) throw Error("Default ElasticSearch index must be specified.");
@Route("/storage/d")
export class StorageController extends Controller {
@Get()
@SuccessResponse(HttpStatusCode.OK, "Success")
public async getFolder(@Query() path: string, @Query() bucket?: string) {
const list = await new Promise<{ pathname: string; name: string }[]>((resolve, reject) => {
const item: { pathname: string; name: string }[] = [];
const stream = minioClient.listObjectsV2(bucket ?? DEFAULT_BUCKET!, path);
stream.on("data", (v) => {
if (v && v.prefix) {
item.push({
pathname: v.prefix,
name: v.prefix.slice(path?.length).split("/")[0],
});
}
});
stream.on("end", () => resolve(item));
stream.on("error", () => reject(new Error("เกิดข้อผิดพลาดกับระบบจัดการไฟล์")));
});
return list;
}
@Post()
@SuccessResponse(HttpStatusCode.CREATED, "Success")
public async createFolder(@Query() path: string, @Query() bucket?: string) {
const fragments = path.split("/").filter(Boolean);
await Promise.all(
fragments.map(async (_, i, a) => {
const path = [...a.slice(0, i + 1)].map((x) => replaceIllegalChars(x)).join("/");
const created = await minioClient
.putObject(bucket ?? DEFAULT_BUCKET!, `${path}/.keep`, "", 0)
.catch((e) => console.error(e));
if (!created) throw new Error("เกิดข้อผิดพลาดกับระบบจัดการไฟล์");
}),
);
return this.setStatus(HttpStatusCode.CREATED);
}
@Put()
@SuccessResponse(HttpStatusCode.NO_CONTENT, "Success")
public async updateFolder(
@Body()
body: {
from: {
bucket: string;
path: string;
};
to: {
bucket: string;
path: string;
};
},
) {
const src = body.from.path.split("/").filter(Boolean).join("/");
const dst = body.to.path.split("/").filter(Boolean).join("/");
if (
!Boolean(
await minioClient
.statObject(DEFAULT_BUCKET!, `${dst.replace(/^\/|\/$/g, "")}/.keep`)
.catch((e) => {
if (e.code === "NotFound") return false;
throw new Error(`Minio Error: ${e}`);
}),
)
)
throw new HttpError(HttpStatusCode.NOT_FOUND, "Destination Not Found");
const list = await new Promise<{ pathname: string; name: string }[]>((resolve, reject) => {
const item: { pathname: string; name: string }[] = [];
const stream = minioClient.listObjectsV2(body.from.bucket, src);
stream.on("data", (v) => {
if (v && v.prefix) {
item.push({
pathname: v.prefix,
name: v.prefix.slice(src.length).split("/")[0],
});
}
});
stream.on("error", (e) => reject(new Error(`Minio Error: ${e}`)));
stream.on("end", () => resolve(item));
});
return this.setStatus(HttpStatusCode.NO_CONTENT);
}
}