UNPKG

@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
/* * */ 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; } } }