UNPKG

@adobe/aio-lib-files

Version:

An abstraction on top of blob cloud storage exposing a file like API

406 lines (394 loc) 17.3 kB
/** * Read, Write, Delete permission enum */ export type FilePermissions = any; /** * external, internal URL type enum */ export type UrlType = any; /** * Cloud Files Abstraction */ export class Files { /** * @param filePath - {@link RemotePathString} * @returns normalized path */ protected static _normalizeRemotePath(filePath: RemotePathString): string; /** * @param filePath - {@link RemotePathString} * @returns true if it's the root */ protected static _isRemoteRoot(filePath: RemotePathString): boolean; /** * @param filePath - {@link RemotePathString} * @returns true if the file is public */ protected static _isRemotePublic(filePath: RemotePathString): boolean; /** * @param filePath - {@link RemotePathString} * @returns true if path is a directory */ protected static _isRemoteDirectory(filePath: RemotePathString): boolean; /** * @param filePath - {@link RemotePathString} * @param details - pass details to error for debugging purpose (e.g. calling function params) */ protected static _throwIfRemoteDirectory(filePath: RemotePathString, details: any): void; /** * Reads a stream into a buffer * @param stream - readableStream * @returns buffer */ protected static _readStream(stream: NodeJS.ReadableStream): Promise<Buffer>; /** * Wraps errors for request to the cloud provider * @param requestPromise - the promise resolving to the response or error * @param details - pass details to error for debugging purpose (e.g. pass function params) * @param filePathToThrowOn404 - path to the file on which the request was made, if specified will throw on 404 * @returns promise resolving to same value as requestPromise */ protected _wrapProviderRequest(requestPromise: Promise, details: any, filePathToThrowOn404: string): Promise; /** * @param filePath - {@link RemotePathString} * @returns resolves to array of {@link RemoteFileProperties} */ protected _listFolder(filePath: RemotePathString): Promise<RemoteFileProperties[]>; /** * @param filePath - {@link RemotePathString} * @returns resolves to boolean */ protected _fileExists(filePath: RemotePathString): Promise<boolean>; /** * @param filePath - {@link RemotePathString} * @returns resolves to boolean */ protected _deleteFile(filePath: RemotePathString): Promise<boolean>; /** * @param filePath - {@link RemotePathString} * @returns resolve to {@link RemoteFileProperties} */ protected getFileInfo(filePath: RemotePathString): Promise<RemoteFileProperties>; /** * **NODEJS ONLY** * @param filePath - {@link RemotePathString} * @param [options = {}] - createReadStreamOptions * @param [options.position] - read start position of the file. By default is set to 0. If set to bigger than * size, throws an ERROR_OUT_OF_RANGE error * @param [options.length] - number of bytes to read. By default reads everything since starting position. If * set to bigger than file size, reads until end. * @returns a readable stream */ protected _createReadStream(filePath: RemotePathString, options?: { position?: number; length?: number; }): Promise<NodeJS.ReadableStream>; /** * **NODEJS ONLY** * @param filePath - {@link RemotePathString} * @returns a writable stream */ protected _createWriteStream(filePath: RemotePathString): Promise<NodeJS.WritableStream>; /** * **NODEJS ONLY** * @param filePath - {@link RemotePathString} * @param content - to be written * @returns resolves to number of bytes written */ protected _writeStream(filePath: RemotePathString, content: NodeJS.ReadableStream): Promise<number>; /** * @param filePath - {@link RemotePathString} * @param content - to be written * @returns resolves to number of bytes written */ protected _writeBuffer(filePath: RemotePathString, content: Buffer): Promise<number>; /** * **Does not work for directories.** * copies a file from a remote location to another. * @param srcPath - {@link RemotePathString} * @param destPath - {@link RemotePathString} */ protected _copyRemoteToRemoteFile(srcPath: RemotePathString, destPath: RemotePathString): void; /** * @param filePath - {@link RemotePathString} * @param urlType - type of URL to return public | runtime, defaults to external * @returns resolves to url */ protected _getUrl(filePath: RemotePathString, urlType: string): string; /** * [INTERNAL] * @param e - provider error response * @returns status code */ protected _statusFromProviderError(e: Error): number; /** * Lists files. Depending on the input the behavior is different: * - If a path has a trailing '/' it is considered as a directory and * list returns files recursively contained below that path. If the * directory is empty, an empty array is returned. * - If a path has no trailing '/' it will ALWAYS be considered a file and we * will return the file (and its properties) in an array. If that file * doesn't exist we return an empty array EVEN if listing a directory with the * same name would return some files (directories are subpaths, not entities per se). * @param [filePath] - {@link RemotePathString} Use a * trailing '/' otherwise this is considered as a file. If not specified * list all files. * @returns resolves to array of * {@link RemoteFileProperties} */ public list(filePath?: RemotePathString): Promise<RemoteFileProperties[]>; /** * Deletes a remote file or directory * @param filePath - {@link RemotePathString} * @param [options = {}] - remoteDeleteOptions * @param [options.progressCallback] - cb(RemoteFile) is called after * the operation completed on each file * @returns resolves to array of deleted paths */ public delete(filePath: RemotePathString, options?: { progressCallback?: (...params: any[]) => any; }): Promise<string[]>; /** * ***NodeJS only (streams). Does not work on directories.*** * * Creates a read stream * @param filePath - {@link RemotePathString} * @param [options = {}] - createReadStreamOptions * @param [options.position] - read start position of the file. By default is set to 0. If set to bigger than * size, throws an ERROR_OUT_OF_RANGE error * @param [options.length] - number of bytes to read. By default reads everything since starting position. If * set to bigger than file size, reads until end. * @returns a readable stream */ public createReadStream(filePath: RemotePathString, options?: { position?: number; length?: number; }): Promise<NodeJS.ReadableStream>; /** * **[UNSTABLE] please prefer using `write(<NodeJS.ReadableStream>)`** * * ***NodeJS only (streams). Does not work on directories.*** * * Returns a write stream. * Use `stream.on('finish', (bytesWritten) => {})` to listen on completion event * @param filePath - {@link RemotePathString} * @returns a writable stream */ public createWriteStream(filePath: RemotePathString): Promise<NodeJS.WritableStream>; /** * ***Does not work on directories.*** * * Reads a remote file content * @param filePath - {@link RemotePathString} * @param [options = {}] - remoteReadOptions * @param [options.position] - read start position of the file. By default is set to 0. If set to bigger than * size, throws an ERROR_OUT_OF_RANGE error * @param [options.length] - number of bytes to read. By default reads everything since starting position. If * set to bigger than file size, reads until end. * @returns buffer holding content */ public read(filePath: RemotePathString, options?: { position?: number; length?: number; }): Promise<Buffer>; /** * ***Does not work on directories.*** * * Writes content to a file * @param filePath - {@link RemotePathString} * @param content - to be written, * `ReadableStream` input works for **NodeJS only** * @returns resolves to number of bytes written */ public write(filePath: RemotePathString, content: string | Buffer | NodeJS.ReadableStream): Promise<number>; /** * Reads properties of a file or directory * @param filePath - {@link RemotePathString} * @returns resolves {@link RemoteFileProperties} */ getProperties(filePath: RemotePathString): Promise<RemoteFileProperties>; /** * ***NodeJS only (streams + fs).*** * * A utility function to copy files and directories across remote and local Files. This * is comparable to the `scp` command * * Rules for copy files are: * 1. Remote => Remote * - a/ (dir) => b/: b/a/ * - a (file) => b/: b/a *does nothing if b/a exists and noOverwrite=true* * - a (file) => b : b *does nothing if b exists and noOverwrite=true* * - a/ (dir) => b : b/ *always allowed: in remote Files we can have both b and b/* * 2. Remote => Local * - a/ => b/: b/a/ * - a => b/: b/a *does nothing if b/a exists and noOverwrite=true* * - a => b : b *does nothing if b exists and noOverwrite=true* * - a/ => b : b/ *throws an error if b exists and is a file: cannot copy a remote * dir to a local file* * 3. Local => Remote * - a/ => b/: b/a/ * - a => b/: b/a *does nothing if b/a exists and noOverwrite=true* * - a => b : b *does nothing if b exists and noOverwrite=true* * - a/ => b: b/ *always allowed: in remote Files we can have both b and b/* * 4. Local => Local * - not supported * @param srcPath - copy source path to a file or directory. If srcPath * points to a local file set `options.localSrc` to true * @param destPath - copy destination path to a file or directory. If * destPath points to a local file set `options.localDest` to true * @param [options = {}] - remoteCopyOptions * @param [options.localSrc = false] - Set this option to true to copy files * from the local file system. Cannot be combined with localDest. * @param [options.localDest = false] - Set this option to true to copy files to * the local file system. Cannot be combined with localSrc. * @param [options.noOverwrite = false] - set to true to not overwrite existing * dest files * @param [options.progressCallback] - a function that will be called every * time the operation completes on a single file,the srcPath and destPath to the copied * file are passed as argument to the callback `progressCallback(srcPath, destPath)` * @returns returns a promise resolving to an object * containing all copied files from src to dest `{ srcFilePath: destFilePath }` */ copy(srcPath: RemotePathString, destPath: RemotePathString, options?: { localSrc?: boolean; localDest?: boolean; noOverwrite?: boolean; progressCallback?: (...params: any[]) => any; }): Promise<{ key: string; }>; /** * Generate pre-sign URLs for a private file * @param filePath - {@link RemotePathString} * @param options - Options to generate presign URL * @param options.expiryInSeconds - presign URL expiry duration * @param options.permissions - permissions for presigned URL (any combination of rwd) * @param options.urlType - default 'external', type of URL to return 'internal' or 'external' * @returns Presign URL for the given file */ generatePresignURL(filePath: RemotePathString, options: { expiryInSeconds: number; permissions: string; urlType: string; }): Promise<string>; /** * Revoke all generated pre-sign URLs */ revokeAllPresignURLs(): void; } /** * Initializes and returns the cloud files SDK. * * To use the SDK you must either provide provide your * [OpenWhisk credentials]{@link OpenWhiskCredentials} in * `credentials.ow` or your own * [Azure blob storage credentials]{@link AzureCredentialsAccount} in `credentials.azure`. * * OpenWhisk credentials can also be read from environment variables (`__OW_NAMESPACE` and `__OW_API_KEY`). * @param [config = {}] - configuration used to init the sdk * @param [config.ow] - {@link OpenWhiskCredentials}. Set those if you want * to use ootb credentials to access the state management service. OpenWhisk * namespace and auth can also be passed through environment variables: * `__OW_NAMESPACE` and `__OW_API_KEY` * @param [config.azure] - bring your own [Azure SAS credentials]{@link AzureCredentialsSAS} or * [Azure storage account credentials]{@link AzureCredentialsAccount} * @param [config.tvm] - tvm configuration, applies only when passing OpenWhisk credentials * @param [config.tvm.apiUrl] - alternative tvm api url. * @param [config.tvm.cacheFile] - alternative tvm cache file, set to `false` to disable caching of temporary credentials. * @returns A Files instance */ export function init(config?: { ow?: OpenWhiskCredentials; azure?: AzureCredentialsAccount | AzureCredentialsSAS; tvm?: { apiUrl?: string; cacheFile?: string; }; }): Promise<Files>; /** * An object holding the OpenWhisk credentials * @property namespace - user namespace * @property auth - auth key */ export type OpenWhiskCredentials = { namespace: string; auth: string; }; /** * SAS Azure credentials. The sdk needs two SAS credentials to allow access to * two already existing containers, a private and a public one (with access=`blob`). * @property sasURLPrivate - sas url to existing private azure blob * container * @property sasURLPublic - sas url to existing public (with * access=`blob`) azure blob container */ export type AzureCredentialsSAS = { sasURLPrivate: string; sasURLPublic: string; }; /** * Azure account credentials. Must have the permission to create containers. * @property storageAccount - name of azure storage account * @property storageAccessKey - access key for azure storage account * @property containerName - name of container to store files. * Another `${containerName}-public` will also be used for public files. * @property [hostName] - custom domain for returned URLs */ export type AzureCredentialsAccount = { storageAccount: string; storageAccessKey: string; containerName: string; hostName?: string; }; /** * a string to the remote path. If the path ends with a `/` it will * be treated as a directory, if not it will be treated as a file. */ export type RemotePathString = string; /** * File properties * @property name - unique name of this file, it is the full path * @property creationTime - utc datetime string when file was created * @property lastModified - utc datetime string when file last modified * @property etag - unique ( per modification ) etag for the asset * @property contentLength - size, in bytes * @property contentType - mime/type * @property isDirectory - true if file is a directory * @property isPublic - true if file is public * @property url - remote file URL with URI encoded path, use decodeURIComponent to decode the URL. * @property internalUrl - remote file URL which allows file access only from Adobe I/O Runtime actions. */ export type RemoteFileProperties = { name: string; creationTime: string; lastModified: string; etag: string; contentLength: number; contentType: string; isDirectory: boolean; isPublic: boolean; url: string; internalUrl: string; }; export type FilesLibError = Error; /** * Files lib custom errors. * * `e.sdkDetails` provides additional context for each error (e.g. function parameter) * @property ERROR_BAD_ARGUMENT - this error is thrown when an argument is missing or has invalid type * @property ERROR_NOT_IMPLEMENTED - this error is thrown when a method is not implemented or when calling * methods directly on the abstract class (Files). * @property ERROR_BAD_CREDENTIALS - this error is thrown when the supplied init credentials are invalid. * @property ERROR_INTERNAL - this error is thrown when an unknown error is thrown by the underlying * provider or TVM server for credential exchange. More details can be found in `e.sdkDetails._internal`. * @property ERROR_FILE_NOT_EXISTS - this error is thrown when the filePath does not exists for operations * that need the file to exists (e.g. read) * @property ERROR_BAD_FILE_TYPE - this error is thrown when the filePath is not the expected type for * operations that need the file to be of a specific type, e.g. write on a dir would fail */ export type FilesLibErrors = { ERROR_BAD_ARGUMENT: FilesLibError; ERROR_NOT_IMPLEMENTED: FilesLibError; ERROR_BAD_CREDENTIALS: FilesLibError; ERROR_INTERNAL: FilesLibError; ERROR_FILE_NOT_EXISTS: FilesLibError; ERROR_BAD_FILE_TYPE: FilesLibError; };