Created
July 2, 2024 10:02
-
-
Save erfanium/ebc49c288f41be2dbf5be60278642792 to your computer and use it in GitHub Desktop.
bucket url pattern
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
BucketItem, | |
BucketStream, | |
Client, | |
ItemBucketMetadata, | |
RemoveOptions, | |
UploadedObjectInfo, | |
} from 'minio'; | |
import pino from 'pino'; | |
import { Readable } from 'stream'; | |
const logger = pino({ | |
name: 's3', | |
}); | |
const { ENSURE_BUCKETS } = process.env; | |
const enableEnsure = ENSURE_BUCKETS === 'true'; | |
export interface Bucket { | |
name: string; | |
getObject(objectName: string): Promise<Readable>; | |
putObject( | |
objectName: string, | |
stream: Readable | Buffer | string, | |
metaData?: ItemBucketMetadata, | |
): Promise<UploadedObjectInfo>; | |
removeObject(objectName: string, removeOpts?: RemoveOptions): Promise<void>; | |
listObjects(prefix?: string, recursive?: boolean): BucketStream<BucketItem>; | |
ensure(): Promise<void>; | |
exists(): Promise<boolean>; | |
setPolicy(bucketPolicy: string): Promise<void>; | |
remove(): Promise<void>; | |
make(): Promise<void>; | |
} | |
const cache = new Map<string, Bucket>(); | |
const createNullBucket = (name: string, envName: string): Bucket => { | |
return { | |
name, | |
getObject() { | |
throw new Error(`bucket not initialized. please set ${envName} env`); | |
}, | |
putObject() { | |
throw new Error(`bucket not initialized. please set ${envName} env`); | |
}, | |
removeObject() { | |
throw new Error(`bucket not initialized. please set ${envName} env`); | |
}, | |
listObjects() { | |
throw new Error(`bucket not initialized. please set ${envName} env`); | |
}, | |
setPolicy() { | |
throw new Error(`bucket not initialized. please set ${envName} env`); | |
}, | |
ensure() { | |
throw new Error(`bucket not initialized. please set ${envName} env`); | |
}, | |
exists() { | |
throw new Error(`bucket not initialized. please set ${envName} env`); | |
}, | |
remove() { | |
throw new Error(`bucket not initialized. please set ${envName} env`); | |
}, | |
make() { | |
throw new Error(`bucket not initialized. please set ${envName} env`); | |
}, | |
}; | |
}; | |
export async function ensureBucket(client: Client, bucketName: string) { | |
const exists = await client.bucketExists(bucketName); | |
if (!exists) { | |
await client.makeBucket(bucketName); | |
} | |
} | |
export const getBucket = (name: string, envName: string): Bucket => { | |
const fromCache = cache.get(envName); | |
if (fromCache) return fromCache; | |
const _url: string | undefined = process.env[envName]; | |
if (!_url) return createNullBucket(name, envName); | |
const url = new URL(_url); | |
const client = new Client({ | |
endPoint: url.hostname, | |
port: url.port ? Number(url.port) : 9000, | |
useSSL: url.protocol.startsWith('https'), | |
accessKey: decodeURIComponent(url.username), | |
secretKey: decodeURIComponent(url.password), | |
}); | |
const bucketName = url.pathname.replace('/', ''); | |
const bucket: Bucket = { | |
name, | |
getObject: (objectName) => client.getObject(bucketName, objectName), | |
putObject: (...rest) => client.putObject(bucketName, ...rest), | |
removeObject: (...rest) => client.removeObject(bucketName, ...rest), | |
listObjects: (...rest) => client.listObjects(bucketName, ...rest), | |
setPolicy: (...rest) => client.setBucketPolicy(bucketName, ...rest), | |
ensure: () => ensureBucket(client, bucketName), | |
exists: () => client.bucketExists(bucketName), | |
remove: () => client.removeBucket(bucketName), | |
make: () => client.makeBucket(bucketName), | |
}; | |
// do not await this | |
if (enableEnsure) { | |
bucket | |
.ensure() | |
.catch((e) => logger.error(e, `Error while ensureBucket for ${envName}`)); | |
} | |
cache.set(envName, bucket); | |
return bucket; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment