hrms-edm/Services/server/src/utils/minio.ts

91 lines
3 KiB
TypeScript
Raw Normal View History

2023-11-27 14:11:27 +07:00
import { StorageFolder } from "../interfaces/storage-fs";
import * as Minio from "minio";
2023-11-27 09:45:30 +07:00
import minioClient from "../minio";
2023-11-17 09:03:31 +07:00
/**
2023-11-27 09:45:30 +07:00
* Replace illegal character eg. ? % < > / \ : | that can't be in path with other char with dash by default.
2023-11-21 09:57:48 +07:00
* @param path - string to check and replace
2023-11-27 09:45:30 +07:00
* @param replace - string to replace illegal character
* @returns illegal character replaced path
2023-11-21 09:57:48 +07:00
*/
2023-11-27 09:45:30 +07:00
export function replaceIllegalChars(path: string, replace = "-") {
return path.replace(/[/\\?%*:|"<>]/g, replace);
2023-11-21 09:57:48 +07:00
}
/**
2023-11-27 09:45:30 +07:00
* Check if folder really exist by using ".keep" object.
2023-11-21 09:57:48 +07:00
*/
2023-11-17 09:03:31 +07:00
export async function pathExist(path: string): Promise<boolean> {
2023-11-27 09:45:30 +07:00
return Boolean(
await minioClient.statObject("ehr", `${path.replace(/^\/|\/$/g, "")}/.keep`).catch((e) => {
2023-11-17 09:03:31 +07:00
if (e.code === "NotFound") return false;
2023-11-27 09:45:30 +07:00
throw new Error("เกิดข้อผิดพลาดกับระบบจัดการไฟล์");
}),
);
2023-11-17 09:03:31 +07:00
}
2023-11-21 09:57:48 +07:00
/**
* Utility function to list folder by using .keep file with prefix in minio.
* @param path - path to list
* @return list of folder with metadata
*/
2023-11-27 14:11:27 +07:00
export async function listFolder(bucket: string, path?: string): Promise<StorageFolder[]> {
2023-11-27 09:45:30 +07:00
if (path) path = `${path.replace(/^\/|\/$/g, "")}/`;
2023-11-17 09:03:31 +07:00
2023-11-27 09:45:30 +07:00
const list = await new Promise<{ pathname: string; name: string }[]>((resolve, reject) => {
const item: { pathname: string; name: string }[] = [];
2023-11-17 09:03:31 +07:00
2023-11-27 09:45:30 +07:00
const stream = minioClient.listObjectsV2(bucket, path ?? "");
2023-11-17 09:03:31 +07:00
stream.on("data", (v) => {
2023-11-27 09:45:30 +07:00
if (v && v.prefix) {
item.push({
pathname: v.prefix,
name: v.prefix.slice(path?.length).split("/")[0],
});
}
2023-11-17 09:03:31 +07:00
});
2023-11-27 09:45:30 +07:00
stream.on("end", () => resolve(item));
stream.on("error", () => reject(new Error("เกิดข้อผิดพลาดกับระบบจัดการไฟล์")));
});
2023-11-17 09:03:31 +07:00
2023-11-27 09:45:30 +07:00
const folder = await Promise.all(
list.map(async (v) => {
// Get stat from hidden object that used to mark as folder as minio doesn't really have folder
const stat = await minioClient
.statObject(bucket, `${v.pathname}.keep`)
.catch((e) => console.error(`MinIO Error: ${e}`));
2023-11-27 09:45:30 +07:00
if (!stat) return undefined;
2023-11-27 09:45:30 +07:00
const { createdat, createdby } = stat.metaData;
2023-11-17 09:03:31 +07:00
2023-11-27 09:45:30 +07:00
return {
...v,
createdAt: createdat ?? "n/a",
createdBy: createdby ?? "n/a",
2023-11-27 14:11:27 +07:00
} satisfies StorageFolder;
2023-11-27 09:45:30 +07:00
}),
);
2023-11-27 14:11:27 +07:00
return folder.filter((v: (typeof folder)[number]): v is StorageFolder => !!v);
2023-11-17 09:03:31 +07:00
}
2023-11-27 09:45:30 +07:00
export async function listItem(
bucket: string,
path: string,
recursive = false,
): Promise<Minio.BucketItem[]> {
return new Promise((resolve, reject) => {
2023-11-27 09:45:30 +07:00
const stream = minioClient.listObjectsV2(bucket, path, recursive);
const item: Minio.BucketItem[] = [];
stream.on("data", (v) => {
if (v && v.name) item.push(v);
});
stream.on("end", () => resolve(item));
2023-11-27 09:45:30 +07:00
stream.on("error", () => reject(new Error("เกิดข้อผิดพลาดกับระบบจัดการไฟล์")));
});
}
2023-11-27 09:45:30 +07:00
export const copyCond = new Minio.CopyConditions();