150 lines
3.8 KiB
TypeScript
150 lines
3.8 KiB
TypeScript
import { minioClient } from '@/app.ts';
|
||
import { bucketName } from '@/modules/minio.ts';
|
||
import { CopyDestinationOptions, CopySourceOptions } from 'minio';
|
||
type MinioListOpt = {
|
||
prefix: string;
|
||
recursive?: boolean;
|
||
};
|
||
export type MinioFile = {
|
||
name: string;
|
||
size: number;
|
||
lastModified: Date;
|
||
etag: string;
|
||
};
|
||
export type MinioDirectory = {
|
||
prefix: string;
|
||
size: number;
|
||
};
|
||
export type MinioList = (MinioFile | MinioDirectory)[];
|
||
export const getMinioList = async (opts: MinioListOpt): Promise<MinioList> => {
|
||
const prefix = opts.prefix;
|
||
const recursive = opts.recursive ?? false;
|
||
return await new Promise((resolve, reject) => {
|
||
let res: any[] = [];
|
||
let hasError = false;
|
||
minioClient
|
||
.listObjectsV2(bucketName, prefix, recursive)
|
||
.on('data', (data) => {
|
||
res.push(data);
|
||
})
|
||
.on('error', (err) => {
|
||
console.error('minio error', opts.prefix, err);
|
||
hasError = true;
|
||
})
|
||
.on('end', () => {
|
||
if (hasError) {
|
||
reject();
|
||
return;
|
||
} else {
|
||
resolve(res);
|
||
}
|
||
});
|
||
});
|
||
};
|
||
export const getFileStat = async (prefix: string, isFile?: boolean): Promise<any> => {
|
||
try {
|
||
const obj = await minioClient.statObject(bucketName, prefix);
|
||
if (isFile && obj.size === 0) {
|
||
return null;
|
||
}
|
||
return obj;
|
||
} catch (e) {
|
||
if (e.code === 'NotFound') {
|
||
return null;
|
||
}
|
||
console.error('get File Stat Error not handle', e);
|
||
return null;
|
||
}
|
||
};
|
||
|
||
export const deleteFile = async (prefix: string): Promise<{ code: number; message: string }> => {
|
||
try {
|
||
const fileStat = await getFileStat(prefix);
|
||
if (!fileStat) {
|
||
console.warn(`File not found: ${prefix}`);
|
||
return {
|
||
code: 404,
|
||
message: 'file not found',
|
||
};
|
||
}
|
||
await minioClient.removeObject(bucketName, prefix, {
|
||
versionId: 'null',
|
||
forceDelete: true, // 强制删除
|
||
});
|
||
return {
|
||
code: 200,
|
||
message: 'delete success',
|
||
};
|
||
} catch (e) {
|
||
console.error('delete File Error not handle', e);
|
||
return {
|
||
code: 500,
|
||
message: 'delete failed',
|
||
};
|
||
}
|
||
};
|
||
|
||
// 批量删除文件
|
||
export const deleteFiles = async (prefixs: string[]): Promise<any> => {
|
||
try {
|
||
await minioClient.removeObjects(bucketName, prefixs);
|
||
return true;
|
||
} catch (e) {
|
||
console.error('delete Files Error not handle', e);
|
||
return false;
|
||
}
|
||
};
|
||
|
||
type GetMinioListAndSetToAppListOpts = {
|
||
username: string;
|
||
appKey: string;
|
||
version: string;
|
||
};
|
||
// 批量列出文件,并设置到appList的files中
|
||
export const getMinioListAndSetToAppList = async (opts: GetMinioListAndSetToAppListOpts) => {
|
||
const { username, appKey, version } = opts;
|
||
const minioList = await getMinioList({ prefix: `${username}/${appKey}/${version}`, recursive: true });
|
||
const files = minioList;
|
||
return files as MinioFile[];
|
||
};
|
||
|
||
/**
|
||
* 更新文件的元数据
|
||
* @param prefix 文件前缀
|
||
* @param newMetadata 新的元数据
|
||
* @returns
|
||
*/
|
||
export const updateFileStat = async (
|
||
prefix: string,
|
||
newMetadata: Record<string, string>,
|
||
): Promise<{
|
||
code: number;
|
||
data: any;
|
||
message?: string;
|
||
}> => {
|
||
try {
|
||
const source = new CopySourceOptions({ Bucket: bucketName, Object: prefix });
|
||
const destination = new CopyDestinationOptions({
|
||
Bucket: bucketName,
|
||
Object: prefix,
|
||
UserMetadata: newMetadata,
|
||
MetadataDirective: 'REPLACE',
|
||
});
|
||
const copyResult = await minioClient.copyObject(source, destination);
|
||
console.log('copyResult', copyResult);
|
||
console.log(`Metadata for ${prefix} updated successfully.`);
|
||
return {
|
||
code: 200,
|
||
data: copyResult,
|
||
message: 'update metadata success',
|
||
};
|
||
} catch (e) {
|
||
console.error('Error updating file stat', e);
|
||
return {
|
||
code: 500,
|
||
data: null,
|
||
message: `update metadata failed. ${e.message}`,
|
||
};
|
||
}
|
||
};
|