@tmlmobilidade/interfaces
Version:
This package provides SDK-style connectors for interacting with databases (e.g., stops, plans, rides, alerts) and external providers (e.g., authentication, storage). It simplifies data access and integration across projects.
112 lines (111 loc) • 4.59 kB
JavaScript
/* * */
import { HTTP_STATUS, HttpException } from '@tmlmobilidade/consts';
import { mimeTypes } from '@tmlmobilidade/consts';
import { readFileSync } from 'node:fs';
import { OciError, Region, SimpleAuthenticationDetailsProvider } from 'oci-common';
import { ObjectStorageClient, UploadManager } from 'oci-objectstorage';
import { CreatePreauthenticatedRequestDetails } from 'oci-objectstorage/lib/model/create-preauthenticated-request-details.js';
/* * */
export class OCIStorageProvider {
bucketName;
namespace;
ociClient;
region;
constructor(config) {
this.ociClient = new ObjectStorageClient({
authenticationDetailsProvider: new SimpleAuthenticationDetailsProvider(config.tenancy, config.user, config.fingerprint, config.private_key_path ? readFileSync(config.private_key_path, 'utf8') : config.private_key, null, Region.fromRegionId(config.region)),
});
this.region = Region.fromRegionId(config.region);
this.namespace = config.namespace;
this.bucketName = config.bucket_name;
}
/**
* Copies a file from one location to another in the same bucket.
* @param source - The source object name.
* @param destination - The destination object name.
*/
async copyFile(source, destination) {
await this.ociClient.copyObject({
bucketName: this.bucketName,
copyObjectDetails: {
destinationBucket: this.bucketName,
destinationNamespace: this.namespace,
destinationObjectName: destination,
destinationRegion: this.region.regionId,
sourceObjectName: source,
},
namespaceName: this.namespace,
});
}
async deleteFile(key) {
await this.ociClient.deleteObject({
bucketName: this.bucketName,
namespaceName: this.namespace,
objectName: key,
});
}
async deleteFiles(keys) {
await Promise.all(keys.map(key => this.deleteFile(key)));
}
async fileExists(key) {
try {
await this.ociClient.headObject({
bucketName: this.bucketName,
namespaceName: this.namespace,
objectName: key,
});
return true;
}
catch (error) {
if (error instanceof OciError && error.statusCode === 404)
return false;
throw error;
}
}
async getFileUrl(key) {
if (!await this.fileExists(key)) {
throw new HttpException(HTTP_STATUS.NOT_FOUND, `File ${key} does not exist in bucket ${this.bucketName}`);
}
const response = await this.ociClient.createPreauthenticatedRequest({
bucketName: this.bucketName,
createPreauthenticatedRequestDetails: {
accessType: CreatePreauthenticatedRequestDetails.AccessType.ObjectRead,
name: 'public-download-link',
objectName: key,
timeExpires: new Date(Date.now() + 1000 * 60 * 60), // 1 hour
},
namespaceName: this.namespace,
});
return `https://objectstorage.${this.region.regionId}.oraclecloud.com${response.preauthenticatedRequest.accessUri}`;
}
async listFiles(prefix) {
const result = await this.ociClient.listObjects({
bucketName: this.bucketName,
namespaceName: this.namespace,
prefix,
});
return result.listObjects?.objects?.map(obj => obj.name) ?? [];
}
async uploadFile(key, body, mimeType) {
const isImage = mimeType === mimeTypes.png || mimeType === mimeTypes.jpg || mimeType === mimeTypes.jpeg || mimeType === mimeTypes.gif || mimeType === mimeTypes.svg;
const uploadManager = new UploadManager(this.ociClient, { enforceMD5: true });
try {
await uploadManager.upload({
content: body instanceof Buffer
? { blob: new Blob([new Uint8Array(body)], { type: mimeType }) }
: { stream: body },
requestDetails: {
bucketName: this.bucketName,
contentDisposition: isImage ? 'inline' : 'attachment',
contentType: mimeType,
namespaceName: this.namespace,
objectName: key,
},
});
}
catch (error) {
console.error('Error uploading file:', JSON.stringify(error, null, 2));
throw error;
}
}
}