import { CreatePreAuthUploadUrlPayload, FileStorageBase, FileSearchOptions, FileSearchResultSet, GetObjectParams, GetObjectMetadataParams, GetObjectStreamParams, ObjectStreamResult, StorageListResult, StorageObjectMetadata } from '../generic/FileStorageBase.js'; import { StorageProviderConfig } from '../generic/FileStorageBase.js'; /** * Configuration interface for Google Drive storage provider. * Supports OAuth2 authentication with refresh token. * Extends StorageProviderConfig to include accountId and accountName. */ interface GoogleDriveConfig extends StorageProviderConfig { /** OAuth2 Client ID */ clientID?: string; /** OAuth2 Client Secret */ clientSecret?: string; /** OAuth2 Refresh Token (never expires) */ refreshToken?: string; /** Optional root folder ID to restrict operations */ rootFolderID?: string; } /** * Google Drive implementation of the FileStorageBase interface. * * This class provides methods for interacting with Google Drive as a file storage provider. * It implements most of the abstract methods defined in FileStorageBase and handles * Google Drive-specific authentication, authorization, and file operations. * * Unlike other storage providers like S3 or Azure, Google Drive has native concepts of * folders and files with hierarchical paths, which makes some operations more natural * while others (like pre-authenticated upload URLs) are not directly supported. * * It requires one of the following environment variables to be set: * - STORAGE_GDRIVE_KEY_FILE: Path to a service account key file with Drive permissions * - STORAGE_GDRIVE_CREDENTIALS_JSON: A JSON object containing service account credentials * * Optionally, you can set: * - STORAGE_GDRIVE_ROOT_FOLDER_ID: ID of a folder to use as the root (for isolation) * * @example * ```typescript * // Create an instance of GoogleDriveFileStorage * const driveStorage = new GoogleDriveFileStorage(); * * // Generate a pre-authenticated download URL * const downloadUrl = await driveStorage.CreatePreAuthDownloadUrl('documents/report.pdf'); * * // List files in a directory * const files = await driveStorage.ListObjects('documents/'); * * // Upload a file directly * const uploaded = await driveStorage.PutObject('documents/report.pdf', fileData); * ``` */ export declare class GoogleDriveFileStorage extends FileStorageBase { /** The name of this storage provider, used in error messages */ protected readonly providerName = "Google Drive"; /** The Google Drive API client */ private _drive; /** Optional root folder ID to restrict operations to a specific folder */ private _rootFolderId?; /** OAuth2 credentials for configuration checking */ private _clientID?; private _clientSecret?; private _refreshToken?; /** * Creates a new instance of GoogleDriveFileStorage. * * Initializes the connection to Google Drive using either a service account * key file or credentials provided directly in environment variables. * Throws an error if neither authentication method is properly configured. */ constructor(); /** * Checks if Google Drive provider is properly configured. * Returns true if all required OAuth credentials are present. * Logs detailed error messages if configuration is incomplete. */ get IsConfigured(): boolean; /** * Initialize Google Drive storage provider. * * **Always call this method** after creating an instance. * * @example Simple Deployment (Environment Variables) * const storage = new GoogleDriveFileStorage(); // Constructor loads env vars * await storage.initialize(); // No config - uses env vars * await storage.ListObjects('/'); * * @example Multi-Tenant (Database Credentials) * const storage = new GoogleDriveFileStorage(); * await storage.initialize({ * accountId: '12345', * accountName: 'Google Drive Account', * clientID: '...', * clientSecret: '...', * refreshToken: '...', * rootFolderID: 'optional-folder-id' * }); * * @param config - Optional. Omit to use env vars, provide to override with database creds. */ initialize(config?: GoogleDriveConfig): Promise; /** * Finds a file or folder by path. * * This helper method navigates the Google Drive folder structure to find * a file or folder at the specified path. It starts from the root (or the * configured root folder) and traverses the path components one by one. * * @param path - The path to the file or folder to find * @returns A Promise resolving to the Google Drive file object * @throws Error if the path cannot be found * @private */ private _getItemByPath; /** * Finds a parent folder by path and creates it if it doesn't exist. * * This helper method is used to ensure a folder path exists before * creating or moving files. It navigates through each path component, * creating folders as needed if they don't exist yet. * * @param path - The path to the folder to find or create * @returns A Promise resolving to the ID of the folder * @private */ private _getOrCreateParentFolder; /** * Helper method to convert Google Drive file objects to StorageObjectMetadata. * * This method transforms the Google Drive API's file representation into * the standardized StorageObjectMetadata format used by the FileStorageBase * interface. It handles special properties like folder detection and paths. * * @param file - The Google Drive file object to convert * @param parentPath - The parent path to use for constructing the full path * @returns A StorageObjectMetadata representation of the file * @private */ private _fileToMetadata; /** * Creates a pre-authenticated upload URL for an object in Google Drive. * * Google Drive doesn't directly support pre-signed upload URLs in the same * way as other storage providers like S3 or Azure. Instead, uploads * should be performed using the PutObject method. * * @param objectName - The name of the object to upload * @throws UnsupportedOperationError as this operation is not supported */ CreatePreAuthUploadUrl(objectName: string): Promise; /** * Creates a pre-authenticated download URL for an object in Google Drive. * * This method creates a temporary, public sharing link for a file that allows * anyone with the link to access the file for a limited time (10 minutes). * It uses Google Drive's permissions system to create a temporary reader * permission for 'anyone' with an expiration time. * * @param objectName - The path to the file to download * @returns A Promise resolving to the download URL * @throws Error if the file cannot be found or the URL creation fails * * @example * ```typescript * // Generate a pre-authenticated download URL for a PDF file * const downloadUrl = await driveStorage.CreatePreAuthDownloadUrl('documents/report.pdf'); * * // The URL can be shared with users or used in applications for direct download * console.log(downloadUrl); * ``` */ /** * Map of Google Workspace MIME types to their export formats. * Google Workspace files must be exported to these formats for download. */ private static readonly GOOGLE_WORKSPACE_EXPORT_MAP; CreatePreAuthDownloadUrl(objectName: string): Promise; /** * Moves an object from one location to another within Google Drive. * * This method first locates the file to be moved, then gets or creates the * destination folder, and finally updates the file's name and parent folder. * Google Drive has native support for moving files between folders. * * @param oldObjectName - The current path of the object * @param newObjectName - The new path for the object * @returns A Promise resolving to a boolean indicating success * * @example * ```typescript * // Move a file from drafts to published folder * const success = await driveStorage.MoveObject( * 'drafts/report.docx', * 'published/final-report.docx' * ); * * if (success) { * console.log('File successfully moved'); * } else { * console.log('Failed to move file'); * } * ``` */ MoveObject(oldObjectName: string, newObjectName: string): Promise; /** * Deletes an object from Google Drive. * * This method locates the specified file by path and deletes it from Google Drive. * By default, this moves the file to the trash rather than permanently deleting it, * unless your Drive settings are configured for immediate permanent deletion. * * @param objectName - The path to the file to delete * @returns A Promise resolving to a boolean indicating success * * @example * ```typescript * // Delete a temporary file * const deleted = await driveStorage.DeleteObject('temp/report-draft.pdf'); * * if (deleted) { * console.log('File successfully deleted'); * } else { * console.log('Failed to delete file'); * } * ``` */ DeleteObject(objectName: string): Promise; /** * Lists objects in a directory in Google Drive. * * This method retrieves all files and folders directly inside the specified * folder path. It handles Google Drive's native folder structure and converts * the Drive API responses to the standardized StorageListResult format. * * @param prefix - The path to the directory to list * @param delimiter - Delimiter character (unused in Google Drive implementation) * @returns A Promise resolving to a StorageListResult containing objects and prefixes * * @example * ```typescript * // List all files and directories in the documents folder * const result = await driveStorage.ListObjects('documents/'); * * // Process files * for (const file of result.objects) { * console.log(`File: ${file.name}, Size: ${file.size}, Type: ${file.contentType}`); * } * * // Process subdirectories * for (const dir of result.prefixes) { * console.log(`Directory: ${dir}`); * } * ``` */ ListObjects(prefix: string, delimiter?: string): Promise; /** * Creates a directory in Google Drive. * * This method creates a folder at the specified path, creating parent * folders as needed if they don't exist. Google Drive natively supports * folders as a special file type with the 'application/vnd.google-apps.folder' * MIME type. * * @param directoryPath - The path of the directory to create * @returns A Promise resolving to a boolean indicating success * * @example * ```typescript * // Create a new directory structure * const created = await driveStorage.CreateDirectory('documents/reports/annual/'); * * if (created) { * console.log('Directory created successfully'); * } else { * console.log('Failed to create directory'); * } * ``` */ CreateDirectory(directoryPath: string): Promise; /** * Deletes a directory and optionally its contents from Google Drive. * * This method deletes a folder at the specified path. If recursive is false, * it will fail if the folder has any contents. If recursive is true, it * deletes the folder and all its contents. * * @param directoryPath - The path of the directory to delete * @param recursive - If true, deletes all contents recursively (default: false) * @returns A Promise resolving to a boolean indicating success * * @example * ```typescript * // Delete an empty directory * const deleted = await driveStorage.DeleteDirectory('documents/temp/'); * * // Delete a directory and all its contents * const recursivelyDeleted = await driveStorage.DeleteDirectory('documents/old_projects/', true); * ``` */ DeleteDirectory(directoryPath: string, recursive?: boolean): Promise; /** * Retrieves metadata for a specific object in Google Drive. * * This method fetches the file information without downloading its content, * which is more efficient for checking file attributes like size, type, * and last modified date. * * @param params - Object identifier (prefer objectId for performance, fallback to fullPath) * @returns A Promise resolving to a StorageObjectMetadata object * @throws Error if the file doesn't exist or cannot be accessed * * @example * ```typescript * try { * // Fast path: Use objectId (Google Drive file ID) * const metadata = await driveStorage.GetObjectMetadata({ objectId: '1a2b3c4d5e' }); * * // Slow path: Use path * const metadata2 = await driveStorage.GetObjectMetadata({ fullPath: 'documents/report.pdf' }); * * console.log(`File: ${metadata.name}`); * console.log(`Size: ${metadata.size} bytes`); * console.log(`Last modified: ${metadata.lastModified}`); * } catch (error) { * console.error('File does not exist or cannot be accessed'); * } * ``` */ GetObjectMetadata(params: GetObjectMetadataParams): Promise; /** * Downloads an object's content from Google Drive. * * This method retrieves the full content of a file and returns it * as a Buffer for processing in memory. * * @param params - Object identifier (prefer objectId for performance, fallback to fullPath) * @returns A Promise resolving to a Buffer containing the file's data * @throws Error if the file doesn't exist or cannot be downloaded * * @example * ```typescript * try { * // Fast path: Use objectId (Google Drive file ID) * const content = await driveStorage.GetObject({ objectId: '1a2b3c4d5e' }); * * // Slow path: Use path * const content2 = await driveStorage.GetObject({ fullPath: 'documents/config.json' }); * * // Parse the JSON content * const config = JSON.parse(content.toString('utf8')); * console.log('Configuration loaded:', config); * } catch (error) { * console.error('Failed to download file:', error.message); * } * ``` */ GetObject(params: GetObjectParams): Promise; /** * Google Drive supports ranged streaming of regular (non-Workspace) files via the * `files.get({ alt: 'media' })` endpoint with a `Range` header. */ get SupportsStreaming(): boolean; /** * Streams a file's content from Google Drive, optionally honoring a byte range. * * Uses `files.get({ fileId, alt: 'media' }, { responseType: 'stream', headers: { Range } })`, * which returns a Node.js readable stream — the file is never buffered fully in memory. The * Drive media endpoint honors the HTTP `Range` header, so the inclusive `Range` is encoded via * the shared {@link BuildHttpRangeHeader}. The streamed response doesn't reliably surface the * total object size, so this method resolves size/content-type via {@link GetObjectMetadata} * (mirroring the Box driver) and clamps the range to the object size. * * **Google Workspace files** (Docs/Sheets/Slides/Drawings) are not directly downloadable — they * must be exported to a concrete format, which has no Range semantics — so streaming throws for * those types. Callers should fall back to {@link GetObject} (which performs the export). * * @param params - Object identifier (prefer objectId) plus optional Range. * @returns A Promise resolving to an {@link ObjectStreamResult}. * @throws Error if the file doesn't exist, is a Google Workspace file, or cannot be streamed. */ GetObjectStream(params: GetObjectStreamParams): Promise; /** * Uploads data to an object in Google Drive. * * This method directly uploads a Buffer of data to a file with the specified path. * It will create any necessary parent folders if they don't exist, and will update * the file if it already exists or create a new one if it doesn't. * * @param objectName - The path to the file to upload * @param data - The Buffer containing the data to upload * @param contentType - Optional MIME type for the file (inferred from name if not provided) * @param metadata - Optional key-value pairs of custom metadata (not supported in current implementation) * @returns A Promise resolving to a boolean indicating success * * @example * ```typescript * // Upload a text file * const content = Buffer.from('Hello, World!', 'utf8'); * const uploaded = await driveStorage.PutObject( * 'documents/hello.txt', * content, * 'text/plain' * ); * * if (uploaded) { * console.log('File uploaded successfully'); * } else { * console.log('Failed to upload file'); * } * ``` */ PutObject(objectName: string, data: Buffer, contentType?: string, metadata?: Record): Promise; /** * Copies an object within Google Drive. * * This method creates a copy of a file at a new location without removing the original. * It uses the Google Drive API's native file copying capabilities. * * @param sourceObjectName - The path to the file to copy * @param destinationObjectName - The path where the copy should be created * @returns A Promise resolving to a boolean indicating success * * @example * ```typescript * // Create a backup copy of an important file * const copied = await driveStorage.CopyObject( * 'documents/contract.pdf', * 'backups/contract_2024-05-16.pdf' * ); * * if (copied) { * console.log('File copied successfully'); * } else { * console.log('Failed to copy file'); * } * ``` */ CopyObject(sourceObjectName: string, destinationObjectName: string): Promise; /** * Checks if an object exists in Google Drive. * * This method verifies the existence of a file at the specified path * without downloading its content. * * @param objectName - The path to the file to check * @returns A Promise resolving to a boolean indicating if the file exists * * @example * ```typescript * // Check if a file exists before attempting to use it * const exists = await driveStorage.ObjectExists('documents/report.pdf'); * * if (exists) { * console.log('File exists, proceeding with download'); * const content = await driveStorage.GetObject('documents/report.pdf'); * // Process the content... * } else { * console.log('File does not exist'); * } * ``` */ ObjectExists(objectName: string): Promise; /** * Checks if a directory exists in Google Drive. * * This method verifies the existence of a folder at the specified path. * It also checks that the item is actually a folder (has the correct MIME type), * not a file with the same name. * * @param directoryPath - The path of the directory to check * @returns A Promise resolving to a boolean indicating if the directory exists * * @example * ```typescript * // Check if a directory exists before trying to save files to it * const exists = await driveStorage.DirectoryExists('documents/reports/'); * * if (!exists) { * console.log('Directory does not exist, creating it first'); * await driveStorage.CreateDirectory('documents/reports/'); * } * * // Now safe to use the directory * await driveStorage.PutObject('documents/reports/new-report.pdf', fileData); * ``` */ DirectoryExists(directoryPath: string): Promise; /** * Searches for files in Google Drive using the Drive API search capabilities. * * Google Drive search syntax supports: * - Simple terms: "report" matches files containing "report" * - Exact phrases: "quarterly report" matches that exact phrase * - Boolean OR: "budget OR forecast" * - Exclusion: "report -draft" excludes files with "draft" * - Wildcards: Not supported in Drive API * * Content search is always enabled for supported file types (Docs, Sheets, PDFs, etc.) * when searchContent option is true. * * @param query - Search query using Google Drive search syntax * @param options - Search options * @returns Promise resolving to search results * * @example * ```typescript * // Simple name search * const results = await storage.SearchFiles('quarterly report'); * * // Search with file type filter * const pdfResults = await storage.SearchFiles('budget', { * fileTypes: ['pdf'], * modifiedAfter: new Date('2024-01-01') * }); * * // Content search * const contentResults = await storage.SearchFiles('machine learning', { * searchContent: true, * pathPrefix: 'documents/research/' * }); * ``` */ SearchFiles(query: string, options?: FileSearchOptions): Promise; /** * Escapes special characters in search queries for Google Drive. * @private */ private _escapeQuery; /** * Gets the full path of a file from its ID by traversing up the parent chain. * @private */ private _getFilePathFromId; } export {}; //# sourceMappingURL=GoogleDriveFileStorage.d.ts.map