|
|
@ -26,6 +26,7 @@ interface MinioEndpointConfig {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function parseMainEndpointUrl(endpoint: string): MinioEndpointConfig {
|
|
|
|
function parseMainEndpointUrl(endpoint: string): MinioEndpointConfig {
|
|
|
|
|
|
|
|
if (!endpoint) throw new Error('Empty endpoint');
|
|
|
|
const url = new URL(endpoint);
|
|
|
|
const url = new URL(endpoint);
|
|
|
|
const result: Partial<MinioEndpointConfig> = {};
|
|
|
|
const result: Partial<MinioEndpointConfig> = {};
|
|
|
|
if (url.pathname !== '/') throw new Error('Main MinIO endpoint URL of a sub-directory is not supported.');
|
|
|
|
if (url.pathname !== '/') throw new Error('Main MinIO endpoint URL of a sub-directory is not supported.');
|
|
|
@ -116,20 +117,36 @@ class StorageService {
|
|
|
|
|
|
|
|
|
|
|
|
async put(target: string, file: string | Buffer | Readable, meta: ItemBucketMetadata = {}) {
|
|
|
|
async put(target: string, file: string | Buffer | Readable, meta: ItemBucketMetadata = {}) {
|
|
|
|
if (typeof file === 'string') file = createReadStream(file);
|
|
|
|
if (typeof file === 'string') file = createReadStream(file);
|
|
|
|
|
|
|
|
try {
|
|
|
|
return await this.client.putObject(this.opts.bucket, target, file, meta);
|
|
|
|
return await this.client.putObject(this.opts.bucket, target, file, meta);
|
|
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
|
|
e.stack = new Error().stack;
|
|
|
|
|
|
|
|
throw e;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async get(target: string, path?: string) {
|
|
|
|
async get(target: string, path?: string) {
|
|
|
|
|
|
|
|
try {
|
|
|
|
if (path) return await this.client.fGetObject(this.opts.bucket, target, path);
|
|
|
|
if (path) return await this.client.fGetObject(this.opts.bucket, target, path);
|
|
|
|
return await this.client.getObject(this.opts.bucket, target);
|
|
|
|
return await this.client.getObject(this.opts.bucket, target);
|
|
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
|
|
e.stack = new Error().stack;
|
|
|
|
|
|
|
|
throw e;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async del(target: string | string[]) {
|
|
|
|
async del(target: string | string[]) {
|
|
|
|
|
|
|
|
try {
|
|
|
|
if (typeof target === 'string') return await this.client.removeObject(this.opts.bucket, target);
|
|
|
|
if (typeof target === 'string') return await this.client.removeObject(this.opts.bucket, target);
|
|
|
|
return await this.client.removeObjects(this.opts.bucket, target);
|
|
|
|
return await this.client.removeObjects(this.opts.bucket, target);
|
|
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
|
|
e.stack = new Error().stack;
|
|
|
|
|
|
|
|
throw e;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async list(target: string, recursive = true) {
|
|
|
|
async list(target: string, recursive = true) {
|
|
|
|
|
|
|
|
try {
|
|
|
|
const stream = this.client.listObjects(this.opts.bucket, target, recursive);
|
|
|
|
const stream = this.client.listObjects(this.opts.bucket, target, recursive);
|
|
|
|
return await new Promise<BucketItem[]>((resolve, reject) => {
|
|
|
|
return await new Promise<BucketItem[]>((resolve, reject) => {
|
|
|
|
const results: BucketItem[] = [];
|
|
|
|
const results: BucketItem[] = [];
|
|
|
@ -145,14 +162,24 @@ class StorageService {
|
|
|
|
stream.on('end', () => resolve(results));
|
|
|
|
stream.on('end', () => resolve(results));
|
|
|
|
stream.on('error', reject);
|
|
|
|
stream.on('error', reject);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
|
|
e.stack = new Error().stack;
|
|
|
|
|
|
|
|
throw e;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async getMeta(target: string) {
|
|
|
|
async getMeta(target: string) {
|
|
|
|
|
|
|
|
try {
|
|
|
|
const result = await this.client.statObject(this.opts.bucket, target);
|
|
|
|
const result = await this.client.statObject(this.opts.bucket, target);
|
|
|
|
return { ...result.metaData, ...result };
|
|
|
|
return { ...result.metaData, ...result };
|
|
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
|
|
e.stack = new Error().stack;
|
|
|
|
|
|
|
|
throw e;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async signDownloadLink(target: string, filename?: string, noExpire = false, useAlternativeEndpointFor?: 'user' | 'judge'): Promise<string> {
|
|
|
|
async signDownloadLink(target: string, filename?: string, noExpire = false, useAlternativeEndpointFor?: 'user' | 'judge'): Promise<string> {
|
|
|
|
|
|
|
|
try {
|
|
|
|
const url = await this.client.presignedGetObject(
|
|
|
|
const url = await this.client.presignedGetObject(
|
|
|
|
this.opts.bucket,
|
|
|
|
this.opts.bucket,
|
|
|
|
target,
|
|
|
|
target,
|
|
|
@ -163,6 +190,10 @@ class StorageService {
|
|
|
|
);
|
|
|
|
);
|
|
|
|
if (useAlternativeEndpointFor) return this.replaceWithAlternativeUrlFor[useAlternativeEndpointFor](url);
|
|
|
|
if (useAlternativeEndpointFor) return this.replaceWithAlternativeUrlFor[useAlternativeEndpointFor](url);
|
|
|
|
return url;
|
|
|
|
return url;
|
|
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
|
|
e.stack = new Error().stack;
|
|
|
|
|
|
|
|
throw e;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|