import { StorageFolder } from "../interfaces/storage-fs"; import * as Minio from "minio"; import minioClient from "../minio"; /** * Replace illegal character eg. ? % < > / \ : | that can't be in path with other char with dash by default. * @param path - string to check and replace * @param replace - string to replace illegal character * @returns illegal character replaced path */ export function replaceIllegalChars(path: string, replace = "-") { return path.replace(/[/\\?%*:|"<>]/g, replace); } /** * Check if folder really exist by using ".keep" object. */ export async function pathExist(bucket: string, path: string): Promise { return Boolean( await minioClient.statObject(bucket, `${path.replace(/^\/|\/$/g, "")}/.keep`).catch((e) => { if (e.code === "NotFound") return false; throw new Error("เกิดข้อผิดพลาดกับระบบจัดการไฟล์"); }), ); } /** * Utility function to list folder by using .keep file with prefix in minio. * @param path - path to list * @return list of folder with metadata */ export async function listFolder(bucket: string, path?: string): Promise { if (path) path = `${path.replace(/^\/|\/$/g, "")}/`; const list = await new Promise<{ pathname: string; name: string }[]>((resolve, reject) => { const item: { pathname: string; name: string }[] = []; const stream = minioClient.listObjectsV2(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("เกิดข้อผิดพลาดกับระบบจัดการไฟล์"))); }); 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}`)); if (!stat) return undefined; const { createdat, createdby } = stat.metaData; return { ...v, createdAt: createdat ?? "n/a", createdBy: createdby ?? "n/a", } satisfies StorageFolder; }), ); return folder.filter((v: (typeof folder)[number]): v is StorageFolder => !!v); } export async function listItem( bucket: string, path: string, recursive = false, ): Promise { return new Promise((resolve, reject) => { 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)); stream.on("error", () => reject(new Error("เกิดข้อผิดพลาดกับระบบจัดการไฟล์"))); }); } export const copyCond = new Minio.CopyConditions();