@gensx/storage
Version:
Cloud storage, blobs, sqlite, and vector database providers/hooks for GenSX.
1 lines • 40.8 kB
Source Map (JSON)
{"version":3,"file":"filesystem.cjs","sources":["@gensx/storage/../../../../src/blob/filesystem.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/only-throw-error */\n\nimport * as crypto from \"node:crypto\";\nimport { createReadStream, createWriteStream } from \"node:fs\";\nimport * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { Readable } from \"node:stream\";\n\nimport { fromBase64UrlSafe, toBase64UrlSafe } from \"../utils/base64.js\";\nimport {\n Blob,\n BlobConflictError,\n BlobError,\n BlobInternalError,\n BlobNotFoundError,\n BlobOptions,\n BlobPermissionDeniedError,\n BlobResponse,\n BlobStorage,\n DeleteBlobResult,\n ListBlobsOptions,\n ListBlobsResponse,\n} from \"./types.js\";\n\n/**\n * Helper to convert between filesystem errors and BlobErrors\n * @param err The error to convert\n * @param operation The operation that failed\n * @param path The path where the error occurred\n * @throws BlobError with appropriate error code and message\n */\nfunction handleFsError(err: unknown, operation: string, path: string): never {\n if (err instanceof Error) {\n const nodeErr = err as NodeJS.ErrnoException;\n\n if (nodeErr.code === \"ENOENT\") {\n throw new BlobNotFoundError(`Blob not found at path: ${path}`, err);\n } else if (nodeErr.code === \"EACCES\") {\n throw new BlobPermissionDeniedError(\n `Permission denied for operation ${operation} on path: ${path}`,\n err,\n );\n } else if (nodeErr.code === \"EEXIST\") {\n throw new BlobConflictError(`File already exists at path: ${path}`, err);\n } else if (nodeErr.code === \"ENOTEMPTY\") {\n throw new BlobConflictError(`Directory not empty at path: ${path}`, err);\n } else if (nodeErr.code === \"ENOTDIR\") {\n throw new BlobInternalError(`Path is not a directory: ${path}`, err);\n }\n }\n\n // Default error case\n throw new BlobInternalError(\n `Error during ${operation}: ${String(err)}`,\n err as Error,\n );\n}\n\n/**\n * Calculate an MD5 hash of the content for use as an ETag\n * @param content The content to hash\n * @returns The MD5 hash as a hex string\n */\nfunction calculateEtag(content: string | Buffer): string {\n return crypto.createHash(\"md5\").update(content).digest(\"hex\");\n}\n\n/**\n * Generate a unique filename for metadata\n * @param filePath The path to the blob file\n * @returns The path to the metadata file\n */\nfunction getMetadataPath(filePath: string): string {\n return `${filePath}.metadata.json`;\n}\n\n/**\n * Implementation of Blob interface for filesystem storage\n * @template T The type of data stored in the blob\n */\nclass FileSystemBlob<T> implements Blob<T> {\n private filePath: string;\n private metadataPath: string;\n\n /**\n * Create a new FileSystemBlob\n * @param filePath The path to the blob file\n */\n constructor(filePath: string) {\n this.filePath = filePath;\n this.metadataPath = getMetadataPath(filePath);\n }\n\n /**\n * Get JSON data from the blob\n * @returns The JSON data or null if the blob doesn't exist\n * @throws BlobError if there's an error reading the blob\n */\n async getJSON<R>(): Promise<R | null> {\n try {\n const content = await fs.readFile(this.filePath, \"utf8\");\n return JSON.parse(content) as R;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") {\n return null;\n }\n throw handleFsError(err, \"getJSON\", this.filePath);\n }\n }\n\n /**\n * Get string data from the blob\n * @returns The string data or null if the blob doesn't exist\n * @throws BlobError if there's an error reading the blob\n */\n async getString(): Promise<string | null> {\n try {\n return await fs.readFile(this.filePath, \"utf8\");\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") {\n return null;\n }\n throw handleFsError(err, \"getString\", this.filePath);\n }\n }\n\n /**\n * Get a readable stream from the blob\n * @returns A readable stream of the blob content\n * @throws BlobError if there's an error creating the stream\n */\n async getStream(): Promise<Readable> {\n try {\n // Check if file exists first\n try {\n await fs.access(this.filePath);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") {\n throw new BlobNotFoundError(\n `Blob not found at path: ${this.filePath}`,\n );\n }\n throw err;\n }\n\n // Create and return readable stream\n const stream = createReadStream(this.filePath);\n\n // Handle stream errors\n stream.on(\"error\", (err) => {\n throw handleFsError(err, \"getStream:read\", this.filePath);\n });\n\n return stream;\n } catch (err) {\n throw handleFsError(err, \"getStream\", this.filePath);\n }\n }\n\n /**\n * Get raw binary data from the blob\n * @returns The raw data and metadata or null if the blob doesn't exist\n * @throws BlobError if there's an error reading the blob\n */\n async getRaw(): Promise<BlobResponse<Buffer> | null> {\n try {\n // Read the raw buffer\n const content = await fs.readFile(this.filePath);\n const stats = await fs.stat(this.filePath);\n const metadataResult = await this.getMetadata();\n\n const etag = calculateEtag(content);\n\n // Check if content is base64 encoded\n const isBase64 = metadataResult?.isBase64 === \"true\";\n const decodedContent = isBase64\n ? Buffer.from(content.toString(), \"base64\")\n : content;\n\n // Remove contentType and etag from metadata if they exist\n const { contentType, etag: _, ...metadata } = metadataResult ?? {};\n\n return {\n content: decodedContent,\n etag,\n lastModified: stats.mtime,\n size: stats.size,\n contentType: metadataResult?.contentType ?? \"application/octet-stream\",\n metadata: metadataResult\n ? Object.keys(metadata).length > 0\n ? metadata\n : undefined\n : undefined,\n };\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") {\n return null;\n }\n throw handleFsError(err, \"getRaw\", this.filePath);\n }\n }\n\n /**\n * Put JSON data into the blob\n * @param value The JSON data to store\n * @param options Optional metadata and ETag\n * @returns The ETag of the stored data\n * @throws BlobError if there's an error storing the data\n */\n async putJSON(value: T, options?: BlobOptions): Promise<{ etag: string }> {\n try {\n await fs.mkdir(path.dirname(this.filePath), { recursive: true });\n const content = JSON.stringify(value);\n const newEtag = calculateEtag(content);\n\n if (options?.etag) {\n try {\n const existingContent = await fs.readFile(this.filePath, \"utf8\");\n const existingEtag = calculateEtag(existingContent);\n\n if (existingEtag !== options.etag) {\n throw new BlobConflictError(\n `ETag mismatch: expected ${options.etag} but found ${existingEtag}`,\n );\n }\n } catch (err) {\n // If the error is already a BlobError, rethrow it\n if (err instanceof BlobError) {\n throw err;\n }\n // Only use handleFsError for filesystem errors\n if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw handleFsError(err, \"putJSON:etag-check\", this.filePath);\n }\n }\n }\n\n await fs.writeFile(this.filePath, content, \"utf8\");\n\n // Always create metadata file with content type\n const metadata = {\n ...(options?.metadata ?? {}),\n contentType: options?.contentType ?? \"application/json\",\n };\n await this.updateMetadata(metadata);\n\n return { etag: newEtag };\n } catch (err) {\n // If the error is already a BlobError, rethrow it\n if (err instanceof BlobError) {\n throw err;\n }\n throw handleFsError(err, \"putJSON\", this.filePath);\n }\n }\n\n /**\n * Put string data into the blob\n * @param value The string data to store\n * @param options Optional metadata and ETag\n * @returns The ETag of the stored data\n * @throws BlobError if there's an error storing the data\n */\n async putString(\n value: string,\n options?: BlobOptions,\n ): Promise<{ etag: string }> {\n try {\n await fs.mkdir(path.dirname(this.filePath), { recursive: true });\n const newEtag = calculateEtag(value);\n\n if (options?.etag) {\n try {\n const existingContent = await fs.readFile(this.filePath, \"utf8\");\n const existingEtag = calculateEtag(existingContent);\n\n if (existingEtag !== options.etag) {\n throw new BlobConflictError(\n `ETag mismatch: expected ${options.etag} but found ${existingEtag}`,\n );\n }\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw handleFsError(err, \"putString:etag-check\", this.filePath);\n }\n }\n }\n\n await fs.writeFile(this.filePath, value, \"utf8\");\n\n // Always create metadata file with content type\n const metadata = {\n ...(options?.metadata ?? {}),\n contentType: options?.contentType ?? \"text/plain\",\n };\n await this.updateMetadata(metadata);\n\n return { etag: newEtag };\n } catch (err) {\n throw handleFsError(err, \"putString\", this.filePath);\n }\n }\n\n /**\n * Put raw binary data into the blob\n * @param value The binary data to store\n * @param options Optional metadata and ETag\n * @returns The ETag of the stored data\n * @throws BlobError if there's an error storing the data\n */\n async putRaw(\n value: Buffer,\n options?: BlobOptions,\n ): Promise<{ etag: string }> {\n try {\n await fs.mkdir(path.dirname(this.filePath), { recursive: true });\n const newEtag = calculateEtag(value);\n\n if (options?.etag) {\n try {\n const existingContent = await fs.readFile(this.filePath);\n const existingEtag = calculateEtag(existingContent);\n\n if (existingEtag !== options.etag) {\n throw new BlobConflictError(\n `ETag mismatch: expected ${options.etag} but found ${existingEtag}`,\n );\n }\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw handleFsError(err, \"putRaw:etag-check\", this.filePath);\n }\n }\n }\n\n // Write the raw buffer\n await fs.writeFile(this.filePath, value);\n\n // Always create metadata file with content type\n const metadata = {\n ...(options?.metadata ?? {}),\n contentType: options?.contentType ?? \"application/octet-stream\",\n };\n await this.updateMetadata(metadata);\n\n return { etag: newEtag };\n } catch (err) {\n throw handleFsError(err, \"putRaw\", this.filePath);\n }\n }\n\n /**\n * Get the blob content and metadata\n * @returns The blob content and metadata or null if the blob doesn't exist\n * @throws BlobError if there's an error reading the blob\n */\n async get(): Promise<BlobResponse<T> | null> {\n try {\n const content = await fs.readFile(this.filePath, \"utf8\");\n const stats = await fs.stat(this.filePath);\n const metadata = await this.getMetadata();\n\n const etag = calculateEtag(content);\n\n return {\n content: JSON.parse(content) as T,\n etag,\n lastModified: stats.mtime,\n size: stats.size,\n contentType: metadata?.contentType ?? \"application/json\",\n metadata: metadata ?? undefined,\n };\n } catch (err) {\n if (\n err instanceof Error &&\n (err as NodeJS.ErrnoException).code === \"ENOENT\"\n ) {\n return null; // File doesn't exist\n }\n throw handleFsError(err, \"get\", this.filePath);\n }\n }\n\n /**\n * Put data from a stream into the blob\n * @param stream The stream to read from\n * @param options Optional metadata and ETag\n * @returns The ETag of the stored data\n * @throws BlobError if there's an error storing the data\n */\n async putStream(\n stream: Readable,\n options?: BlobOptions,\n ): Promise<{ etag: string }> {\n try {\n await fs.mkdir(path.dirname(this.filePath), { recursive: true });\n\n // Create write stream\n const writeStream = createWriteStream(this.filePath);\n const chunks: Buffer[] = [];\n\n // Handle stream errors\n stream.on(\"error\", (err) => {\n writeStream.destroy();\n throw handleFsError(err, \"putStream:read\", this.filePath);\n });\n\n writeStream.on(\"error\", (err) => {\n stream.destroy();\n throw handleFsError(err, \"putStream:write\", this.filePath);\n });\n\n // Collect chunks and write to file\n for await (const chunk of stream) {\n const buffer = Buffer.from(chunk as ArrayBufferLike);\n chunks.push(buffer);\n writeStream.write(buffer);\n }\n\n // Wait for write to complete\n await new Promise<void>((resolve, reject) => {\n writeStream.end((err?: Error | null) => {\n if (err) reject(err);\n else resolve();\n });\n });\n\n // Calculate etag from all chunks\n const buffer = Buffer.concat(chunks);\n const etag = calculateEtag(buffer);\n\n // Always create metadata file with content type\n const metadata = {\n ...(options?.metadata ?? {}),\n contentType: options?.contentType ?? \"application/octet-stream\",\n };\n await this.updateMetadata(metadata);\n\n return { etag };\n } catch (err) {\n throw handleFsError(err, \"putStream\", this.filePath);\n }\n }\n\n /**\n * Delete the blob\n * @throws BlobError if there's an error deleting the blob\n */\n async delete(): Promise<void> {\n try {\n try {\n await fs.unlink(this.filePath);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw handleFsError(err, \"delete:file\", this.filePath);\n }\n // File already doesn't exist, continue to delete metadata\n }\n\n // Also delete metadata file if it exists\n try {\n await fs.unlink(this.metadataPath);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw handleFsError(err, \"delete:metadata\", this.metadataPath);\n }\n // Metadata file doesn't exist, ignore\n }\n } catch (err) {\n throw handleFsError(err, \"delete\", this.filePath);\n }\n }\n\n /**\n * Check if the blob exists\n * @returns true if the blob exists, false otherwise\n */\n async exists(): Promise<boolean> {\n try {\n await fs.access(this.filePath);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Get the blob metadata\n * @returns The blob metadata or null if the blob doesn't exist\n * @throws BlobError if there's an error reading the metadata\n */\n async getMetadata(): Promise<Record<string, string> | null> {\n try {\n const content = await fs.readFile(this.metadataPath, \"utf8\");\n const metadata = JSON.parse(content) as Record<string, string>;\n\n // Calculate etag from the blob content instead of the metadata content\n try {\n const blobContent = await fs.readFile(this.filePath);\n const etag = calculateEtag(blobContent);\n return { ...metadata, etag };\n } catch (blobErr) {\n if ((blobErr as NodeJS.ErrnoException).code === \"ENOENT\") {\n // If blob doesn't exist but metadata does, return metadata without etag\n return metadata;\n }\n throw handleFsError(blobErr, \"getMetadata:blob\", this.filePath);\n }\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") {\n return null; // Metadata file doesn't exist\n }\n throw handleFsError(err, \"getMetadata\", this.metadataPath);\n }\n }\n\n /**\n * Update metadata associated with the blob\n * @param metadata The new metadata to store\n * @param options Optional ETag for conditional update\n * @throws BlobError if there's an error updating the metadata\n */\n async updateMetadata(\n metadata: Record<string, string>,\n options?: BlobOptions,\n ): Promise<void> {\n try {\n // If etag is provided, verify it matches before updating\n if (options?.etag) {\n try {\n const existingContent = await fs.readFile(this.filePath);\n const existingEtag = calculateEtag(existingContent);\n\n if (existingEtag !== options.etag) {\n throw new BlobConflictError(\n `ETag mismatch: expected ${options.etag} but found ${existingEtag}`,\n );\n }\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw handleFsError(\n err,\n \"updateMetadata:etag-check\",\n this.filePath,\n );\n }\n }\n }\n\n await fs.mkdir(path.dirname(this.metadataPath), { recursive: true });\n\n // Get existing metadata to preserve contentType\n let existingMetadata: Record<string, string> = {};\n try {\n const content = await fs.readFile(this.metadataPath, \"utf8\");\n existingMetadata = JSON.parse(content) as Record<string, string>;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw handleFsError(err, \"updateMetadata:read\", this.metadataPath);\n }\n }\n\n // Preserve contentType if it exists in existing metadata\n const contentType = existingMetadata.contentType;\n const newMetadata = { ...metadata };\n if (contentType) {\n newMetadata.contentType = contentType;\n }\n\n await fs.writeFile(\n this.metadataPath,\n JSON.stringify(newMetadata),\n \"utf8\",\n );\n } catch (err) {\n throw handleFsError(err, \"updateMetadata\", this.metadataPath);\n }\n }\n}\n\n/**\n * FileSystem implementation of blob storage\n */\nexport class FileSystemBlobStorage implements BlobStorage {\n /**\n * Create a new FileSystemBlobStorage\n * @param rootDir The root directory for blob storage\n * @param defaultPrefix Optional default prefix for all blob keys\n */\n constructor(\n private rootDir: string,\n private defaultPrefix?: string,\n ) {\n // Ensure rootDir exists on instantiation\n void this.ensureRootDir();\n }\n\n /**\n * Ensure the root directory exists\n * @throws BlobError if there's an error creating the directory\n */\n private async ensureRootDir(): Promise<void> {\n try {\n await fs.mkdir(this.rootDir, { recursive: true });\n } catch (err) {\n throw handleFsError(err, \"ensureRootDir\", this.rootDir);\n }\n }\n\n /**\n * Get the full path for a blob key\n * @param key The blob key\n * @returns The full path to the blob\n */\n private getFullPath(key: string): string {\n // Normalize key by removing leading/trailing slashes\n const normalizedKey = key.replace(/^\\/+|\\/+$/g, \"\");\n\n // Apply default prefix if specified\n const prefixedKey = this.defaultPrefix\n ? `${this.defaultPrefix}/${normalizedKey}`\n : normalizedKey;\n\n return path.join(this.rootDir, prefixedKey);\n }\n\n /**\n * Get a blob by key\n * @param key The blob key\n * @returns A Blob instance for the given key\n */\n getBlob<T>(key: string): Blob<T> {\n return new FileSystemBlob<T>(this.getFullPath(key));\n }\n\n /**\n * List all blobs with optional pagination\n * @param options Options for listing blobs including prefix and pagination\n * @returns A paginated list of blob keys\n * @throws BlobError if there's an error listing blobs\n */\n async listBlobs(options?: ListBlobsOptions): Promise<ListBlobsResponse> {\n try {\n const {\n prefix = \"\",\n limit = 100,\n cursor = undefined,\n } = (options ?? {}) as {\n prefix?: string;\n limit?: number;\n cursor?: string;\n };\n // Normalize prefixes by removing trailing slashes\n const normalizedDefaultPrefix = this.defaultPrefix?.replace(/\\/$/, \"\");\n const normalizedPrefix = prefix.replace(/\\/$/, \"\");\n\n // Build the search prefix\n const searchPrefix = normalizedDefaultPrefix\n ? normalizedPrefix\n ? `${normalizedDefaultPrefix}/${normalizedPrefix}`\n : normalizedDefaultPrefix\n : normalizedPrefix;\n\n const searchPath = path.join(this.rootDir, searchPrefix);\n\n try {\n // Check if directory exists\n await fs.access(searchPath);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") {\n return { blobs: [], nextCursor: undefined }; // Directory doesn't exist\n }\n throw handleFsError(err, \"listBlobs:access\", searchPath);\n }\n\n // Recursive function to list files with stats\n const listFilesRecursively = async (\n dir: string,\n baseDir: string,\n ): Promise<{ key: string; lastModified: string; size: number }[]> => {\n const items = await fs.readdir(dir, { withFileTypes: true });\n const files: { key: string; lastModified: string; size: number }[] = [];\n\n for (const item of items) {\n const fullPath = path.join(dir, item.name);\n const relativePath = path.relative(baseDir, fullPath);\n\n if (item.isDirectory()) {\n const subFiles = await listFilesRecursively(fullPath, baseDir);\n files.push(...subFiles);\n } else if (!item.name.endsWith(\".metadata.json\")) {\n // Get file stats\n const stats = await fs.stat(fullPath);\n files.push({\n key: relativePath,\n lastModified: stats.mtime.toISOString(),\n size: stats.size,\n });\n }\n }\n\n return files.sort((a, b) => a.key.localeCompare(b.key)); // Sort for consistent pagination\n };\n\n let allFiles = await listFilesRecursively(searchPath, this.rootDir);\n\n // Remove default prefix from results if it exists\n if (normalizedDefaultPrefix) {\n allFiles = allFiles\n .filter(\n (file) =>\n file.key === normalizedDefaultPrefix ||\n file.key.startsWith(`${normalizedDefaultPrefix}/`),\n )\n .map((file) => ({\n ...file,\n key:\n file.key === normalizedDefaultPrefix\n ? \"\"\n : file.key.slice(normalizedDefaultPrefix.length + 1),\n }));\n }\n\n // Handle cursor-based pagination\n let startIndex = 0;\n if (cursor) {\n const decodedCursor = fromBase64UrlSafe(cursor);\n startIndex = allFiles.findIndex((file) => file.key > decodedCursor);\n if (startIndex === -1) startIndex = allFiles.length;\n }\n\n // Handle limit\n const endIndex = Math.min(startIndex + limit, allFiles.length);\n const items = allFiles.slice(startIndex, endIndex);\n\n // Generate next cursor\n const nextCursor =\n endIndex < allFiles.length\n ? toBase64UrlSafe(allFiles[endIndex - 1].key)\n : undefined;\n\n return {\n blobs: items,\n nextCursor,\n };\n } catch (err) {\n throw handleFsError(err, \"listBlobs\", this.rootDir);\n }\n }\n\n /**\n * Check if a blob exists\n * @param key The blob key\n * @returns True if the blob exists, false otherwise\n */\n async blobExists(key: string): Promise<boolean> {\n const blob = this.getBlob(key);\n return blob.exists();\n }\n\n /**\n * Delete a blob\n * @param key The blob key\n * @returns The result of the delete operation\n */\n async deleteBlob(key: string): Promise<DeleteBlobResult> {\n try {\n const blob = this.getBlob(key);\n const existed = await blob.exists();\n await blob.delete();\n return { deleted: existed };\n } catch (err) {\n if (err instanceof BlobError) {\n throw err;\n }\n throw handleFsError(err, \"deleteBlob\", this.getFullPath(key));\n }\n }\n}\n"],"names":["BlobNotFoundError","BlobPermissionDeniedError","BlobConflictError","BlobInternalError","crypto","fs","createReadStream","path","BlobError","createWriteStream","fromBase64UrlSafe","toBase64UrlSafe"],"mappings":"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"}