@visionfi/desktop-sdk
Version:
Desktop SDK for VisionFI Cloud Run services with Azure AD authentication
111 lines (97 loc) • 3.29 kB
text/typescript
/**
* Document Client - handles document operations for packages in Desktop SDK
* Copyright (c) 2024-2025 VisionFI. All Rights Reserved.
*/
import { AxiosInstance } from 'axios';
import {
AddDocumentsOptions,
AddDocumentsResponse,
DeleteDocumentResponse,
VisionFiError
} from '@visionfi/core';
import { UploadProgress } from '../../types.js';
export class DocumentClient {
private apiClient: AxiosInstance;
constructor(apiClient: AxiosInstance) {
this.apiClient = apiClient;
}
/**
* Add documents to a package
*/
async add(packageId: string, options: AddDocumentsOptions): Promise<AddDocumentsResponse> {
try {
const response = await this.apiClient.post(`/operations/packages/${packageId}/documents`, options);
return response.data;
} catch (error) {
throw this.handleError(error, 'Failed to add documents to package');
}
}
/**
* Add a single file to a package with optional progress tracking
*/
async addFile(
packageId: string,
fileBase64: string,
fileName: string,
onProgress?: (progress: UploadProgress) => void
): Promise<AddDocumentsResponse> {
try {
const totalBytes = Math.floor(fileBase64.length * 0.75); // Approximate size from base64
let bytesUploaded = 0;
const startTime = Date.now();
// Simulate progress for demo (in real implementation, use axios upload progress)
if (onProgress) {
const progressInterval = setInterval(() => {
bytesUploaded = Math.min(bytesUploaded + totalBytes / 10, totalBytes);
const percentage = Math.round((bytesUploaded / totalBytes) * 100);
const elapsedTime = (Date.now() - startTime) / 1000;
const speed = bytesUploaded / elapsedTime;
const remainingTime = (totalBytes - bytesUploaded) / speed;
onProgress({
fileName,
bytesUploaded,
totalBytes,
percentage,
speed,
remainingTime
});
if (bytesUploaded >= totalBytes) {
clearInterval(progressInterval);
}
}, 100);
}
const response = await this.apiClient.post(`/operations/packages/${packageId}/documents`, {
files: [{
fileName,
fileBase64
}]
});
return response.data;
} catch (error) {
throw this.handleError(error, 'Failed to add file to package');
}
}
/**
* Delete a document from a package
*/
async delete(packageId: string, documentUuid: string): Promise<DeleteDocumentResponse> {
try {
const response = await this.apiClient.delete(`/operations/packages/${packageId}/documents/${documentUuid}`);
return response.data;
} catch (error) {
throw this.handleError(error, 'Failed to delete document from package');
}
}
/**
* Handle errors consistently
*/
private handleError(error: any, defaultMessage: string): Error {
if (error instanceof VisionFiError) {
return error;
}
const message = error.response?.data?.message || error.message || defaultMessage;
const statusCode = error.response?.status;
const code = error.response?.data?.code || 'unknown_error';
return new VisionFiError(message, statusCode, code);
}
}