hrms-edm/Services/server/src/utils/minio.ts
2023-11-27 16:07:32 +07:00

90 lines
3 KiB
TypeScript

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<boolean> {
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<StorageFolder[]> {
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<Minio.BucketItem[]> {
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();