119 lines
2.7 KiB
JavaScript
Executable File

import path from "node:path"
import { Client } from "minio"
export const generateDefaultBucketPolicy = (payload) => {
const { bucketName } = payload
if (!bucketName) {
throw new Error("bucketName is required")
}
return {
Version: "2012-10-17",
Statement: [
{
Action: ["s3:GetObject"],
Effect: "Allow",
Principal: {
AWS: ["*"],
},
Resource: [`arn:aws:s3:::${bucketName}/*`],
Sid: "",
},
],
}
}
export class StorageClient extends Client {
constructor(options) {
super(options)
this.defaultBucket = String(options.defaultBucket)
this.defaultRegion = String(options.defaultRegion)
this.setupBucket = Boolean(options.setupBucket)
this.cdnUrl = options.cdnUrl
}
composeRemoteURL = (key, extraKey) => {
let _path = path.join(this.defaultBucket, key)
if (typeof extraKey === "string") {
_path = path.join(_path, extraKey)
}
if (this.cdnUrl) {
return `${this.cdnUrl}/${_path}`
}
return `${this.protocol}//${this.host}:${this.port}/${_path}`
}
setDefaultBucketPolicy = async (bucketName) => {
const policy = generateDefaultBucketPolicy({ bucketName })
return this.setBucketPolicy(bucketName, JSON.stringify(policy))
}
initialize = async () => {
console.log("🔌 Checking if storage client have default bucket...")
if (this.setupBucket !== false) {
try {
const bucketExists = await this.bucketExists(this.defaultBucket)
if (!bucketExists) {
console.warn(
"🪣 Default bucket not exists! Creating new bucket...",
)
await this.makeBucket(this.defaultBucket, "s3")
// set default bucket policy
await this.setDefaultBucketPolicy(this.defaultBucket)
}
} catch (error) {
console.error(
`Failed to check if default bucket exists or create default bucket >`,
error,
)
}
try {
// check if default bucket policy exists
const bucketPolicy = await this.getBucketPolicy(
this.defaultBucket,
).catch(() => {
return null
})
if (!bucketPolicy) {
// set default bucket policy
await this.setDefaultBucketPolicy(this.defaultBucket)
}
} catch (error) {
console.error(
`Failed to get or set default bucket policy >`,
error,
)
}
}
console.log("✅ Storage client is ready.")
}
}
export const createStorageClientInstance = (options) => {
return new StorageClient({
endPoint: process.env.S3_ENDPOINT,
port: Number(process.env.S3_PORT),
useSSL: ToBoolean(process.env.S3_USE_SSL),
accessKey: process.env.S3_ACCESS_KEY,
secretKey: process.env.S3_SECRET_KEY,
defaultBucket: process.env.S3_BUCKET,
defaultRegion: process.env.S3_REGION,
...options,
})
}
export default createStorageClientInstance