FileStorageBase implementation for Box.com cloud storage

This provider allows working with files stored in Box.com. It supports authentication via access token, refresh token, or client credentials (JWT).

Remarks

This implementation requires at least one of the following authentication methods:

  1. Access Token:

    • STORAGE_BOX_ACCESS_TOKEN - A valid Box API access token
  2. Refresh Token:

    • STORAGE_BOX_REFRESH_TOKEN - A valid Box API refresh token
    • STORAGE_BOX_CLIENT_ID - Your Box application client ID
    • STORAGE_BOX_CLIENT_SECRET - Your Box application client secret
  3. Client Credentials (JWT):

    • STORAGE_BOX_CLIENT_ID - Your Box application client ID
    • STORAGE_BOX_CLIENT_SECRET - Your Box application client secret
    • STORAGE_BOX_ENTERPRISE_ID - Your Box enterprise ID

Optional configuration:

  • STORAGE_BOX_ROOT_FOLDER_ID - ID of a Box folder to use as the root (defaults to '0' which is the root)

Example

// Set required environment variables for JWT auth
process.env.STORAGE_BOX_CLIENT_ID = 'your-client-id';
process.env.STORAGE_BOX_CLIENT_SECRET = 'your-client-secret';
process.env.STORAGE_BOX_ENTERPRISE_ID = 'your-enterprise-id';

// Create the provider
const storage = new BoxFileStorage();
await storage.initialize(); // Required for JWT auth

// Upload a file
const fileContent = Buffer.from('Hello, Box!');
await storage.PutObject('documents/hello.txt', fileContent, 'text/plain');

// Download a file
const downloadedContent = await storage.GetObject('documents/hello.txt');

// Get a temporary download URL
const downloadUrl = await storage.CreatePreAuthDownloadUrl('documents/hello.txt');

Hierarchy (view full)

Constructors

Properties

_accessToken: string

Box API access token

_baseApiUrl: string = 'https://api.box.com/2.0'

Base URL for Box API

_client: BoxClient

Box SDK client for making API calls

_clientId: string

Box application client ID

_clientSecret: string

Box application client secret

_enterpriseId: string

Box enterprise ID for JWT auth

_refreshToken: string

Box API refresh token

_rootFolderId: string

ID of the Box folder to use as root

_tokenExpiresAt: number = 0

Timestamp when current access token expires

_uploadApiUrl: string = 'https://upload.box.com/api/2.0'

Base URL for Box Upload API

providerName: "Box" = 'Box'

The name of this storage provider

Accessors

Methods

  • Returns the current Box API access token

    This method ensures a valid token is available before returning it, refreshing or generating a new token if necessary.

    Returns Promise<string>

    A Promise that resolves to a valid access token string

    Example

    // Get a valid Box access token
    const token = await storage.AccessToken();
    console.log(`Using access token: ${token}`);
  • Copies a file from one location to another

    This method creates a copy of a file at a new location. The original file remains unchanged.

    Parameters

    • sourceObjectName: string

      Path to the source file (e.g., 'templates/report-template.docx')

    • destinationObjectName: string

      Path where the copy should be created (e.g., 'documents/new-report.docx')

    Returns Promise<boolean>

    A Promise that resolves to true if successful, false if an error occurs

    Remarks

    • Only files can be copied; folders cannot be copied with this method
    • Parent directories in the destination path will be created automatically if they don't exist
    • If a file with the same name exists at the destination, it will be replaced

    Example

    // Copy a template file to a new location with a different name
    const copyResult = await storage.CopyObject(
    'templates/financial-report.xlsx',
    'reports/2023/q1-financial-report.xlsx'
    );

    if (copyResult) {
    console.log('File copied successfully');
    } else {
    console.error('Failed to copy file');
    }
  • Creates a new directory (folder) in Box storage

    This method creates a folder at the specified path, automatically creating any parent folders that don't exist.

    Parameters

    • directoryPath: string

      Path where the directory should be created (e.g., 'documents/reports/2023')

    Returns Promise<boolean>

    A Promise that resolves to true if successful, false if an error occurs

    Remarks

    • Creates parent directories recursively if they don't exist
    • Returns true if the directory already exists (idempotent operation)
    • Trailing slashes in the path are automatically removed

    Example

    // Create a nested directory structure
    const createResult = await storage.CreateDirectory('documents/reports/2023/Q1');

    if (createResult) {
    console.log('Directory created successfully');

    // Now we can put files in this directory
    await storage.PutObject(
    'documents/reports/2023/Q1/financial-summary.xlsx',
    fileContent,
    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    );
    } else {
    console.error('Failed to create directory');
    }
  • Creates a pre-authenticated download URL for a file

    This method generates a time-limited URL that can be used to download a file without authentication. The URL typically expires after 60 minutes.

    Parameters

    • objectName: string

      Path to the file to download (e.g., 'documents/report.pdf')

    Returns Promise<string>

    A Promise that resolves to the download URL string

    Throws

    Error if the file doesn't exist or URL creation fails

    Remarks

    • Cannot be used with upload sessions that haven't been completed
    • Box download URLs typically expire after 60 minutes
    • Generated URLs can be shared with users who don't have Box access

    Example

    try {
    // Generate a pre-authenticated download URL
    const downloadUrl = await storage.CreatePreAuthDownloadUrl('documents/financial-report.pdf');

    console.log(`Download the file using this URL: ${downloadUrl}`);

    // The URL can be shared or used in a browser to download the file
    // without requiring Box authentication
    } catch (error) {
    console.error('Error creating download URL:', error.message);
    }
  • Creates a pre-authenticated upload URL for a file

    This method creates a Box upload session and returns a URL that can be used to upload file content directly to Box without requiring authentication.

    Parameters

    • objectName: string

      Path where the file should be uploaded (e.g., 'documents/report.pdf')

    Returns Promise<CreatePreAuthUploadUrlPayload>

    A Promise that resolves to an object containing the upload URL and provider key

    Throws

    Error if the URL creation fails

    Remarks

    • The parent folder structure will be created automatically if it doesn't exist
    • The returned provider key contains the session ID needed to complete the upload
    • Box upload sessions expire after a certain period (typically 1 hour)

    Example

    try {
    // Generate a pre-authenticated upload URL
    const uploadInfo = await storage.CreatePreAuthUploadUrl('presentations/quarterly-results.pptx');

    // The URL can be used to upload content directly
    console.log(`Upload URL: ${uploadInfo.UploadUrl}`);

    // Make sure to save the provider key, as it's needed to reference the upload
    console.log(`Provider Key: ${uploadInfo.ProviderKey}`);

    // You can use fetch or another HTTP client to upload to this URL
    await fetch(uploadInfo.UploadUrl, {
    method: 'PUT',
    headers: { 'Content-Type': 'application/octet-stream' },
    body: fileContent
    });
    } catch (error) {
    console.error('Error creating upload URL:', error.message);
    }
  • Deletes a directory from Box storage

    This method deletes a folder and optionally its contents. By default, it will only delete empty folders unless recursive is set to true.

    Parameters

    • directoryPath: string

      Path to the directory to delete (e.g., 'documents/old-reports')

    • recursive: boolean = false

      If true, delete the directory and all its contents; if false, only delete if empty

    Returns Promise<boolean>

    A Promise that resolves to true if successful, false if an error occurs

    Remarks

    • Returns true if the directory doesn't exist (idempotent operation)
    • If recursive=false and the directory contains files, the operation will fail
    • Box puts deleted folders in the trash, where they can be recovered for a limited time
    • Trailing slashes in the path are automatically removed

    Example

    // Try to delete an empty folder
    const deleteResult = await storage.DeleteDirectory('temp/empty-folder');

    // Delete a folder and all its contents
    const recursiveDeleteResult = await storage.DeleteDirectory('archive/old-data', true);

    if (recursiveDeleteResult) {
    console.log('Folder and all its contents deleted successfully');
    } else {
    console.error('Failed to delete folder');
    }
  • Deletes a file or folder from Box storage

    This method permanently deletes a file or folder. It can also handle special cases like incomplete upload sessions.

    Parameters

    • objectName: string

      Path to the object to delete (e.g., 'documents/old-report.docx')

    Returns Promise<boolean>

    A Promise that resolves to true if successful, false if an error occurs

    Remarks

    • Returns true if the object doesn't exist (for idempotency)
    • Can handle special provider keys like upload sessions
    • Box puts deleted items in the trash, where they can be recovered for a limited time
    • To permanently delete folder contents, use DeleteDirectory with recursive=true

    Example

    // Delete a file
    const deleteResult = await storage.DeleteObject('temp/draft-document.docx');

    if (deleteResult) {
    console.log('File deleted successfully or already didn\'t exist');
    } else {
    console.error('Failed to delete file');
    }

    // Delete an upload session
    await storage.DeleteObject('session:1234567890:documents/large-file.zip');
  • Checks if a directory exists

    This method verifies whether a folder exists at the specified path. Unlike ObjectExists, this method also checks that the item is a folder.

    Parameters

    • directoryPath: string

      Path to check (e.g., 'documents/reports')

    Returns Promise<boolean>

    A Promise that resolves to true if the directory exists, false otherwise

    Remarks

    • Returns false if the path exists but points to a file instead of a folder
    • Trailing slashes in the path are automatically removed

    Example

    // Check if a directory exists before creating a file in it
    const dirExists = await storage.DirectoryExists('documents/reports');

    if (!dirExists) {
    // Create the directory first
    await storage.CreateDirectory('documents/reports');
    }

    // Now we can safely put a file in this directory
    await storage.PutObject('documents/reports/annual-summary.pdf', fileContent, 'application/pdf');
  • Gets file representation information for a Box file

    This method retrieves information about available representations (such as thumbnails, previews, or other formats) for a specific file.

    Parameters

    • fileId: string

      The Box file ID to get representations for

    • repHints: string = 'png?dimensions=2048x2048'

      The representation hints string (format and options)

    Returns Promise<JSON>

    A Promise that resolves to a JSON object containing representations data

    Throws

    Error if the request fails

    Remarks

    • Requires a valid file ID (not a path)
    • The repHints parameter controls what type of representations are returned
    • Common representation types include thumbnails, preview images, and text extractions

    Example

    try {
    // Get a high-resolution PNG representation of a file
    const fileId = '12345';
    const representations = await storage.GetFileRepresentations(
    fileId,
    'png?dimensions=2048x2048'
    );

    // Process the representation information
    console.log('Available representations:', representations);
    } catch (error) {
    console.error('Error getting representations:', error.message);
    }
  • Downloads a file's contents

    This method retrieves the raw content of a file as a Buffer.

    Parameters

    Returns Promise<Buffer>

    A Promise that resolves to a Buffer containing the file's contents

    Throws

    Error if the file doesn't exist or cannot be downloaded

    Remarks

    • This method will throw an error if the object is a folder
    • For large files, consider using CreatePreAuthDownloadUrl instead
    • For upload sessions that haven't been completed, this method will fail

    Example

    try {
    // Download a text file
    const fileContent = await storage.GetObject('documents/notes.txt');

    // Convert Buffer to string for text files
    const textContent = fileContent.toString('utf8');
    console.log('File content:', textContent);

    // For binary files, you can write the buffer to disk
    // or process it as needed
    } catch (error) {
    console.error('Error downloading file:', error.message);
    }
  • Gets metadata for a file or folder

    This method retrieves metadata about a file or folder in Box storage, such as size, type, and modification date.

    Parameters

    Returns Promise<StorageObjectMetadata>

    A Promise that resolves to a StorageObjectMetadata object

    Throws

    Error if the object doesn't exist or cannot be accessed

    Example

    try {
    // Get metadata for a file
    const metadata = await storage.GetObjectMetadata('presentations/quarterly-update.pptx');

    console.log(`Name: ${metadata.name}`);
    console.log(`Path: ${metadata.path}`);
    console.log(`Size: ${metadata.size} bytes`);
    console.log(`Content Type: ${metadata.contentType}`);
    console.log(`Last Modified: ${metadata.lastModified}`);
    console.log(`Is Directory: ${metadata.isDirectory}`);

    // Box-specific metadata is available in customMetadata
    console.log(`Box ID: ${metadata.customMetadata.id}`);
    } catch (error) {
    console.error('Error getting metadata:', error.message);
    }
  • Lists files and folders in a given directory

    This method retrieves all files and subfolders in the specified directory. It returns both a list of object metadata and a list of directory prefixes.

    Parameters

    • prefix: string

      Path to the directory to list (e.g., 'documents/reports')

    • delimiter: string = '/'

      Optional delimiter character (default: '/')

    Returns Promise<StorageListResult>

    A Promise that resolves to a StorageListResult containing objects and prefixes

    Remarks

    • The objects array includes both files and folders
    • The prefixes array includes only folder paths (with trailing slashes)
    • Returns empty arrays if the directory doesn't exist
    • The delimiter parameter is included for interface compatibility but not used internally

    Example

    // List all files and folders in the 'documents' directory
    const result = await storage.ListObjects('documents');

    // Process files and folders
    console.log(`Found ${result.objects.length} items:`);
    for (const obj of result.objects) {
    console.log(`- ${obj.name} (${obj.isDirectory ? 'Folder' : 'File'}, ${obj.size} bytes)`);
    }

    // List subfolders only
    console.log(`Found ${result.prefixes.length} subfolders:`);
    for (const prefix of result.prefixes) {
    console.log(`- ${prefix}`);
    }
  • Moves a file or folder from one location to another

    This method moves a file or folder to a new location in Box storage. It handles both renaming and changing the parent folder.

    Parameters

    • oldObjectName: string

      Current path of the object (e.g., 'old-folder/document.docx')

    • newObjectName: string

      New path for the object (e.g., 'new-folder/renamed-document.docx')

    Returns Promise<boolean>

    A Promise that resolves to true if successful, false otherwise

    Remarks

    • Parent folders will be created automatically if they don't exist
    • Works with both files and folders
    • For folders, all contents will move with the folder

    Example

    // Move a file to a different folder and rename it
    const moveResult = await storage.MoveObject(
    'documents/old-report.pdf',
    'archive/2023/annual-report.pdf'
    );

    if (moveResult) {
    console.log('File moved successfully');
    } else {
    console.error('Failed to move file');
    }
  • Checks if a file or folder exists

    This method verifies whether an object (file or folder) exists at the specified path.

    Parameters

    • objectName: string

      Path to check (e.g., 'documents/report.pdf')

    Returns Promise<boolean>

    A Promise that resolves to true if the object exists, false otherwise

    Example

    // Check if a file exists before attempting to download it
    const exists = await storage.ObjectExists('presentations/quarterly-update.pptx');

    if (exists) {
    // File exists, proceed with download
    const fileContent = await storage.GetObject('presentations/quarterly-update.pptx');
    // Process the file...
    } else {
    console.log('File does not exist');
    }
  • Uploads a file to Box storage

    This method uploads a file to the specified path in Box storage. It automatically determines whether to use a simple upload or chunked upload based on file size.

    Parameters

    • objectName: string

      Path where the file should be uploaded (e.g., 'documents/report.pdf')

    • data: Buffer

      Buffer containing the file content

    • Optional contentType: string

      Optional MIME type of the file (if not provided, it will be guessed from the filename)

    • Optional metadata: Record<string, string>

      Optional metadata to associate with the file (not used in Box implementation)

    Returns Promise<boolean>

    A Promise that resolves to true if successful, false if an error occurs

    Remarks

    • Automatically creates parent directories if they don't exist
    • Files smaller than 50MB use a simple upload
    • Files 50MB or larger use a chunked upload process
    • If a file with the same name exists, it will be replaced

    Example

    // Create a simple text file
    const textContent = Buffer.from('This is a sample document', 'utf8');
    const uploadResult = await storage.PutObject(
    'documents/sample.txt',
    textContent,
    'text/plain'
    );

    // Upload a large file using chunked upload
    const largeFileBuffer = fs.readFileSync('/path/to/large-presentation.pptx');
    const largeUploadResult = await storage.PutObject(
    'presentations/quarterly-results.pptx',
    largeFileBuffer,
    'application/vnd.openxmlformats-officedocument.presentationml.presentation'
    );

    if (largeUploadResult) {
    console.log('Large file uploaded successfully');
    } else {
    console.error('Failed to upload large file');
    }
  • Search files in Box using Box Search API.

    This method provides full-text search capabilities across file names and content using Box's native search functionality. It supports filtering by file type, date ranges, and path prefixes.

    Parameters

    • query: string

      The search query string. Supports boolean operators (AND, OR, NOT) and exact phrases in quotes

    • Optional options: FileSearchOptions

      Optional search options to filter and customize results

    Returns Promise<FileSearchResultSet>

    A Promise resolving to a FileSearchResultSet containing matching files

    Remarks

    • Box searches both file names and content by default
    • The searchContent option is provided for interface compatibility but doesn't restrict Box's behavior
    • File types can be specified as extensions or MIME types
    • Date filters use Box's created_at_range parameter
    • Path prefix is implemented by filtering results to ancestor folder IDs
    • Results are sorted by relevance when available

    Example

    // Search for PDF files containing "quarterly report"
    const results = await storage.SearchFiles('quarterly report', {
    fileTypes: ['pdf'],
    pathPrefix: 'documents/reports',
    modifiedAfter: new Date('2023-01-01'),
    maxResults: 50
    });

    console.log(`Found ${results.results.length} matching files`);
    for (const file of results.results) {
    console.log(`- ${file.path} (${file.size} bytes, score: ${file.relevance})`);
    if (file.excerpt) {
    console.log(` Excerpt: ${file.excerpt}`);
    }
    }
  • Private

    Builds a list of file extensions from file type specifications

    This helper method converts generic file type specifications (extensions or MIME types) into Box API fileExtensions parameter values.

    Parameters

    • fileTypes: string[]

      Array of file extensions (e.g., 'pdf', 'docx') or MIME types

    Returns string[]

    Array of file extension strings (without dots)

  • Private

    Finds a Box folder ID by traversing a path string

    This helper method navigates through the Box folder hierarchy, following each segment of the path to find the ID of the target folder. It uses pagination to handle large folders efficiently.

    Parameters

    • path: string

      The path string to resolve (e.g., 'documents/reports/2023')

    Returns Promise<string>

    A Promise that resolves to the Box folder ID

    Throws

    Error if any segment of the path cannot be found

  • Private

    Obtains an access token using client credentials flow

    This method requests a new access token using the Box client credentials flow (JWT) with the enterprise as the subject.

    Returns Promise<string>

    A Promise that resolves with the access token

    Throws

    Error if token acquisition fails

  • Private

    Resolves a path string to a Box item ID

    This helper method navigates the Box folder hierarchy to find the item at the specified path, returning its Box ID.

    Parameters

    • path: string

      The path to resolve

    Returns Promise<string>

    A Promise that resolves to the Box item ID

    Throws

    Error if the item does not exist

  • Gets both ID and type information for an item at the given path

    Parameters

    • path: string

      Path to the item

    Returns Promise<{
        id: string;
        type: string;
    }>

    Object with id and type, or null if not found

  • Checks if a string is a Box Object ID (numeric) vs a path (contains /)

    Parameters

    • identifier: string

      String to check

    Returns boolean

    True if it's a Box file/folder ID, false if it's a path

  • Private

    Parses a path string into Box API components

    This helper method converts a standard path string (e.g., 'documents/reports/file.txt') into components used by the Box API (folder ID, name, parent path).

    Parameters

    • path: string

      The path to parse

    Returns {
        id: string;
        name: string;
        parent: string;
    }

    An object containing the parsed components: id, name, and parent

    • id: string
    • name: string
    • parent: string
  • Private

    Reconstructs the full path to a Box item from its pathCollection

    This helper method builds the complete path by traversing the parent folder hierarchy stored in the item's pathCollection.

    Parameters

    • item: any

      The Box item with pathCollection data

    Returns string

    The full path string (e.g., 'documents/reports/file.pdf')

  • Initializes the Box storage driver

    This method must be called after creating a BoxFileStorage instance. It initializes the Box SDK and creates the client for API calls.

    Returns Promise<void>

    A Promise that resolves when initialization is complete

    Example

    const storage = new BoxFileStorage();
    await storage.initialize();
    // Now the storage provider is ready to use
  • Helper method to throw an UnsupportedOperationError with appropriate context. This method simplifies implementation of methods not supported by specific providers.

    Parameters

    • methodName: string

      The name of the method that is not supported

    Returns never

    Throws

    UnsupportedOperationError with information about the unsupported method and provider