|
|
@ -5,20 +5,39 @@ import {IncomingMessage} from 'http';
|
|
|
|
import * as fse from 'fs-extra';
|
|
|
|
import * as fse from 'fs-extra';
|
|
|
|
import * as minio from 'minio';
|
|
|
|
import * as minio from 'minio';
|
|
|
|
|
|
|
|
|
|
|
|
// The minio typings appear to be quite stale. Extend them here to avoid
|
|
|
|
// The minio-js v8.0.0 typings are sometimes incorrect. Here are some workarounds.
|
|
|
|
// lots of casts to any.
|
|
|
|
interface MinIOClient extends
|
|
|
|
type MinIOClient = minio.Client & {
|
|
|
|
// Some of them are not directly extendable, must be omitted first and then redefined.
|
|
|
|
statObject(bucket: string, key: string, options: {versionId?: string}): Promise<MinIOBucketItemStat>;
|
|
|
|
Omit<minio.Client, "listObjects" | "getBucketVersioning" | "removeObjects">
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// The official typing returns `Promise<Readable>`, dropping some useful metadata.
|
|
|
|
getObject(bucket: string, key: string, options: {versionId?: string}): Promise<IncomingMessage>;
|
|
|
|
getObject(bucket: string, key: string, options: {versionId?: string}): Promise<IncomingMessage>;
|
|
|
|
|
|
|
|
// The official typing dropped "options" in their .d.ts file, but it is present in the underlying impl.
|
|
|
|
listObjects(bucket: string, key: string, recursive: boolean,
|
|
|
|
listObjects(bucket: string, key: string, recursive: boolean,
|
|
|
|
options: {IncludeVersion?: boolean}): minio.BucketStream<minio.BucketItem>;
|
|
|
|
options: {IncludeVersion?: boolean}): minio.BucketStream<minio.BucketItem>;
|
|
|
|
removeObjects(bucket: string, versions: Array<{name: string, versionId: string}>): Promise<void>;
|
|
|
|
// The released v8.0.0 wrongly returns `Promise<void>`; borrowed from PR #1297
|
|
|
|
};
|
|
|
|
getBucketVersioning(bucketName: string): Promise<MinIOVersioningStatus>;
|
|
|
|
|
|
|
|
// The released v8.0.0 typing is outdated; copied over from commit 8633968.
|
|
|
|
|
|
|
|
removeObjects(bucketName: string, objectsList: RemoveObjectsParam): Promise<RemoveObjectsResponse[]>
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type MinIOBucketItemStat = minio.BucketItemStat & {
|
|
|
|
type MinIOVersioningStatus = "" | {
|
|
|
|
versionId?: string;
|
|
|
|
Status: "Enabled" | "Suspended",
|
|
|
|
metaData?: Record<string, string>;
|
|
|
|
MFADelete?: string,
|
|
|
|
};
|
|
|
|
ExcludeFolders?: boolean,
|
|
|
|
|
|
|
|
ExcludedPrefixes?: {Prefix: string}[]
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type RemoveObjectsParam = string[] | { name: string, versionId?: string }[]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type RemoveObjectsResponse = null | undefined | {
|
|
|
|
|
|
|
|
Error?: {
|
|
|
|
|
|
|
|
Code?: string
|
|
|
|
|
|
|
|
Message?: string
|
|
|
|
|
|
|
|
Key?: string
|
|
|
|
|
|
|
|
VersionId?: string
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* An external store implemented using the MinIO client, which
|
|
|
|
* An external store implemented using the MinIO client, which
|
|
|
@ -38,7 +57,7 @@ export class MinIOExternalStorage implements ExternalStorage {
|
|
|
|
region: string
|
|
|
|
region: string
|
|
|
|
},
|
|
|
|
},
|
|
|
|
private _batchSize?: number,
|
|
|
|
private _batchSize?: number,
|
|
|
|
private _s3 = new minio.Client(options) as MinIOClient
|
|
|
|
private _s3 = new minio.Client(options) as unknown as MinIOClient
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -70,7 +89,7 @@ export class MinIOExternalStorage implements ExternalStorage {
|
|
|
|
public async upload(key: string, fname: string, metadata?: ObjMetadata) {
|
|
|
|
public async upload(key: string, fname: string, metadata?: ObjMetadata) {
|
|
|
|
const stream = fse.createReadStream(fname);
|
|
|
|
const stream = fse.createReadStream(fname);
|
|
|
|
const result = await this._s3.putObject(
|
|
|
|
const result = await this._s3.putObject(
|
|
|
|
this.bucket, key, stream,
|
|
|
|
this.bucket, key, stream, undefined,
|
|
|
|
metadata ? {Metadata: toExternalMetadata(metadata)} : undefined
|
|
|
|
metadata ? {Metadata: toExternalMetadata(metadata)} : undefined
|
|
|
|
);
|
|
|
|
);
|
|
|
|
// Empirically VersionId is available in result for buckets with versioning enabled.
|
|
|
|
// Empirically VersionId is available in result for buckets with versioning enabled.
|
|
|
@ -111,7 +130,9 @@ export class MinIOExternalStorage implements ExternalStorage {
|
|
|
|
|
|
|
|
|
|
|
|
public async hasVersioning(): Promise<Boolean> {
|
|
|
|
public async hasVersioning(): Promise<Boolean> {
|
|
|
|
const versioning = await this._s3.getBucketVersioning(this.bucket);
|
|
|
|
const versioning = await this._s3.getBucketVersioning(this.bucket);
|
|
|
|
return versioning && versioning.Status === 'Enabled';
|
|
|
|
// getBucketVersioning() may return an empty string when versioning has never been enabled.
|
|
|
|
|
|
|
|
// This situation is not addressed in minio-js v8.0.0, but included in our workaround.
|
|
|
|
|
|
|
|
return versioning !== '' && versioning?.Status === 'Enabled';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public async versions(key: string, options?: { includeDeleteMarkers?: boolean }) {
|
|
|
|
public async versions(key: string, options?: { includeDeleteMarkers?: boolean }) {
|
|
|
|