UploadJob class for tracking individual file uploads

This class represents an individual file upload job in the Mosaia platform. Each UploadJob tracks one file being uploaded to drive via presigned URL. After successful upload, the storage-manager Lambda creates a DriveItem from the UploadJob.

Features:

  • Individual file upload tracking
  • Presigned URL management
  • Automatic quota reservation and reversion
  • TTL-based cleanup of expired uploads

Upload workflow:

  1. UploadJob created with file metadata → Drive quota reserved
  2. Client uploads file using presigned_url
  3. Upload triggers event → storage-manager creates DriveItem → UploadJob marked COMPLETED
  4. If upload fails → UploadJob marked FAILED → Quota automatically reverted
  5. If upload abandoned → TTL cleanup → Quota automatically reverted

Basic upload job:

import { UploadJob } from 'mosaia-node-sdk';

// UploadJob is typically created via Drive.items.uploadFiles()
// But can be queried directly:
const uploadJob = new UploadJob({
drive: 'drive-id',
filename: 'document.pdf',
size: 1024000,
status: 'PENDING'
});

Check upload status:

const drive = await mosaia.drives.get({}, 'drive-id');
const status = await drive.items.getUploadStatus('upload-job-id');
console.log('Status:', status.status);
console.log('Expired:', status.is_expired);

Mark upload as failed:

await drive.items.markUploadFailed('upload-job-id', {
error: 'upload timeout'
});
// Quota is automatically reverted

Hierarchy (View Summary)

Constructors

  • Creates a new UploadJob instance

    Initializes an upload job with the provided metadata and optional URI. The upload job represents a single file being uploaded to a drive.

    Parameters

    • data: Partial<UploadJobInterface>

      Upload job metadata

    • Optionaluri: string

      Optional URI path for the upload job endpoint. Defaults to '/drive/:driveId/upload'

    Returns UploadJob

    const uploadJob = new UploadJob({
    drive: 'drive-id',
    filename: 'report.pdf',
    original_filename: 'report.pdf',
    size: 2048000,
    mime_type: 'application/pdf',
    path: '/documents',
    status: 'PENDING',
    presigned_url_expires_at: new Date(Date.now() + 300000)
    });

Accessors

  • get presigned_url(): undefined | string

    Get the presigned URL

    Returns undefined | string

  • get presigned_url_expires_at(): undefined | string | Date

    Get the presigned URL expiration date

    Returns undefined | string | Date

Methods

  • Check if the entity is active

    This method checks the active status of the entity. Most entities in the system can be active or inactive, which affects their availability and usability in the platform.

    Returns boolean

    True if the entity is active, false otherwise

    const user = new User(userData);
    if (user.isActive()) {
    // Perform operations with active user
    } else {
    console.log('User is inactive');
    }
  • Convert model instance to interface data

    This method serializes the model instance to a plain object that matches the interface type. This is useful for:

    • Sending data to the API
    • Storing data in a database
    • Passing data between components
    • Debugging model state

    Returns UploadJobInterface

    The model data as a plain object matching the interface type

    const user = new User({
    email: 'user@example.com',
    firstName: 'John'
    });

    const data = user.toJSON();
    console.log(data); // { email: '...', firstName: '...' }

    // Use with JSON.stringify
    const json = JSON.stringify(user);
  • Convert model instance to API payload

    This method creates a payload suitable for API requests by:

    • Converting the model to a plain object
    • Removing read-only fields (like 'id')
    • Ensuring proper data format for the API

    Returns Partial<UploadJobInterface>

    A clean object suitable for API requests

    const user = new User({
    id: '123', // Will be removed from payload
    email: 'new@example.com',
    firstName: 'John'
    });

    const payload = user.toAPIPayload();
    // payload = { email: '...', firstName: '...' }
    // Note: 'id' is removed as it's read-only

    await apiClient.POST('/users', payload);
  • Update model data with new values

    This method updates the model's data and instance properties with new values. It performs a shallow merge of the updates with existing data, allowing for partial updates of the model's properties.

    Parameters

    Returns void

    const user = new User({
    email: 'old@example.com',
    firstName: 'John'
    });

    // Update multiple properties
    user.update({
    email: 'new@example.com',
    lastName: 'Doe'
    });

    // Save changes to API
    await user.save();

    This method only updates the local model instance. To persist changes to the API, call save after updating.

  • Save the model instance to the API

    This method persists the current state of the model to the API using a PUT request. It requires the model to have an ID (existing instance). For new instances, use the collection's create method instead.

    The method:

    1. Validates the model has an ID
    2. Sends current data to the API
    3. Updates local instance with API response

    Returns Promise<UploadJobInterface>

    Promise resolving to the updated model data

    When model has no ID

    When API request fails

    const user = new User({
    id: '123',
    email: 'user@example.com'
    });

    // Update and save
    user.update({ firstName: 'John' });
    await user.save();

    Error handling:

    try {
    await user.save();
    } catch (error) {
    if (error.message.includes('ID is required')) {
    // Handle missing ID error
    } else {
    // Handle API errors
    }
    }
  • Delete the model instance from the API

    This method permanently deletes the model instance from the API and clears the local data. This operation cannot be undone.

    The method:

    1. Validates the model has an ID
    2. Sends DELETE request to the API
    3. Clears local instance data on success

    Returns Promise<void>

    Promise that resolves when deletion is successful

    When model has no ID

    When API request fails

    Basic deletion:

    const user = await users.get({}, 'user-id');
    if (user) {
    await user.delete();
    // User is now deleted and instance is cleared
    }

    Error handling:

    try {
    await user.delete();
    console.log('User deleted successfully');
    } catch (error) {
    if (error.message.includes('ID is required')) {
    console.error('Cannot delete - no ID');
    } else {
    console.error('Deletion failed:', error.message);
    }
    }
  • Mark this upload job as failed

    Marks the upload as failed and automatically reverts the reserved drive quota. This should be called when the client-side upload fails. Uses the failed_url provided by the API.

    Parameters

    • OptionalerrorMessage: string

      Error message describing the failure

    Returns Promise<UploadJobInterface>

    Promise resolving to updated upload job data

    try {
    // Upload to failed
    await uploadJob.markFailed('Network timeout during upload');
    } catch (error) {
    console.error('Failed to mark upload as failed:', error);
    }

    When API request fails or failed_url not available

  • Check if the presigned URL has expired

    Returns boolean

    True if the presigned URL has expired

    if (uploadJob.isExpired()) {
    console.log('Presigned URL has expired - cannot upload');
    }
  • Upload item to drive using upload

    Uploads an item to the drive using the presigned URL with all required headers, including the server-side encryption header required by the bucket policy.

    Parameters

    • file: Blob | File

      The File or Blob to upload

    • Optionaloptions: { onProgress?: (progress: number) => void }

      Optional upload options

      • OptionalonProgress?: (progress: number) => void

        Optional progress callback that receives upload progress (0-100)

    Returns Promise<void>

    Promise that resolves when upload completes successfully

    const fileInput = document.getElementById('fileInput') as HTMLInputElement;
    const file = fileInput.files[0];

    const result = await drive.items.uploadFiles([file]);
    const uploadJob = result.uploadJobs[0];

    try {
    await uploadJob.upload(file, {
    onProgress: (progress) => {
    console.log(`Upload progress: ${progress}%`);
    }
    });
    console.log('Upload successful!');
    } catch (error) {
    console.error('Upload failed:', error);
    await uploadJob.markFailed(error.message);
    }

    When presigned URL is missing, expired, or upload fails