mirror of
https://github.com/cupcakearmy/morphus.git
synced 2025-09-07 00:20:40 +00:00
support for s3 and minio
This commit is contained in:
@@ -1,30 +1,63 @@
|
||||
import { FastifyInstance } from 'fastify'
|
||||
import { Config, StorageType } from '../config'
|
||||
import { Local } from './local'
|
||||
import { Minio } from './minio'
|
||||
|
||||
export abstract class Storage {
|
||||
abstract init(): Promise<void>
|
||||
|
||||
abstract read(path: string): Promise<Buffer>
|
||||
abstract write(path: string, data: Buffer): Promise<void>
|
||||
abstract exists(path: string): Promise<boolean>
|
||||
abstract delete(path: string): Promise<void>
|
||||
|
||||
abstract readStream(path: string): Promise<NodeJS.ReadableStream>
|
||||
abstract writeStream(path: string): Promise<NodeJS.WritableStream>
|
||||
// list(path: string): Promise<string[]>
|
||||
|
||||
abstract init(): Promise<void>
|
||||
// list(path: string): Promise<string[]>
|
||||
abstract exists(path: string): Promise<boolean>
|
||||
abstract delete(path: string): Promise<void>
|
||||
}
|
||||
|
||||
export let storage: Storage
|
||||
|
||||
export async function init() {
|
||||
export async function init(App: FastifyInstance) {
|
||||
if (!storage) {
|
||||
switch (Config.storage) {
|
||||
case StorageType.Local:
|
||||
storage = new Local(Config.localAssets)
|
||||
break
|
||||
case StorageType.S3:
|
||||
// storage = new S3({
|
||||
// accessKeyId: Config.s3.accessKey,
|
||||
// secretAccessKey: Config.s3.secretKey,
|
||||
// bucket: Config.s3.bucket,
|
||||
// region: Config.s3.region,
|
||||
// })
|
||||
storage = new Minio({
|
||||
accessKey: Config.s3.accessKey,
|
||||
secretKey: Config.s3.secretKey,
|
||||
bucket: Config.s3.bucket,
|
||||
region: Config.s3.region,
|
||||
endpoint: 'https://s3.amazonaws.com',
|
||||
})
|
||||
break
|
||||
case StorageType.Minio:
|
||||
storage = new Minio({
|
||||
accessKey: Config.minio.accessKey,
|
||||
secretKey: Config.minio.secretKey,
|
||||
endpoint: Config.minio.endpoint,
|
||||
region: Config.minio.region,
|
||||
bucket: Config.minio.bucket,
|
||||
})
|
||||
break
|
||||
default:
|
||||
throw new Error(`Unknown storage type: ${Config.storage}`)
|
||||
}
|
||||
await storage.init()
|
||||
try {
|
||||
await storage.init()
|
||||
App.log.debug(`Storage initialized: ${Config.storage}`)
|
||||
} catch (e) {
|
||||
App.log.error(`Storage initialization failed: ${Config.storage}`)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
64
src/storage/minio.ts
Normal file
64
src/storage/minio.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { Client } from 'minio'
|
||||
import { PassThrough } from 'stream'
|
||||
|
||||
import { Storage } from '.'
|
||||
import { StreamUtils } from '../utils/utils'
|
||||
|
||||
export type MinioConfig = {
|
||||
accessKey: string
|
||||
secretKey: string
|
||||
endpoint: string
|
||||
region?: string
|
||||
bucket: string
|
||||
}
|
||||
|
||||
export class Minio implements Storage {
|
||||
client: Client
|
||||
|
||||
constructor(private options: MinioConfig) {
|
||||
const url = new URL(this.options.endpoint)
|
||||
this.client = new Client({
|
||||
accessKey: options.accessKey,
|
||||
secretKey: options.secretKey,
|
||||
endPoint: url.hostname,
|
||||
port: parseInt(url.port),
|
||||
useSSL: url.protocol === 'https:',
|
||||
})
|
||||
}
|
||||
|
||||
async init(): Promise<void> {
|
||||
await this.client.bucketExists(this.options.bucket)
|
||||
}
|
||||
|
||||
async read(path: string): Promise<Buffer> {
|
||||
const stream = await this.client.getObject(this.options.bucket, path)
|
||||
return StreamUtils.toBuffer(stream)
|
||||
}
|
||||
async write(path: string, data: Buffer): Promise<void> {
|
||||
const stream = await StreamUtils.fromBuffer(data)
|
||||
await this.client.putObject(this.options.bucket, path, stream)
|
||||
}
|
||||
|
||||
async readStream(path: string): Promise<NodeJS.ReadableStream> {
|
||||
const stream = await this.client.getObject(this.options.bucket, path)
|
||||
return stream
|
||||
}
|
||||
async writeStream(path: string): Promise<NodeJS.WritableStream> {
|
||||
const stream = new PassThrough()
|
||||
this.client.putObject(this.options.bucket, path, stream)
|
||||
return stream
|
||||
}
|
||||
|
||||
async exists(path: string): Promise<boolean> {
|
||||
try {
|
||||
await this.client.statObject(this.options.bucket, path)
|
||||
return true
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
delete(path: string): Promise<void> {
|
||||
throw new Error('Method not implemented. Delete')
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user