Loading...
Loading...
Compare original and translation side by side
@rytass/storages@rytass/storages@rytass/storages@rytass/storages@rytass/storages-adapter-s3@rytass/storages-adapter-gcs@rytass/storages-adapter-r2@rytass/storages-adapter-azure-blob@rytass/storages-adapter-local@rytass/storages@rytass/storages@rytass/storages-adapter-s3@rytass/storages-adapter-gcs@rytass/storages-adapter-r2@rytass/storages-adapter-azure-blob@rytass/storages-adapter-local@rytass/storages (Base Package)
│
├── StorageInterface # Core interface all adapters must implement
├── Storage<O> # Base class with helper methods (not abstract)
├── ConverterManager # File converter pipeline system (from @rytass/file-converter)
├── Types & Interfaces # Shared type definitions
└── Error Handling # StorageError, ErrorCode enums
@rytass/storages-adapter-* # Provider implementations
│
├── [Provider]Storage # Extends Storage<ProviderOptions>
├── typings.ts # Provider-specific option types
└── index.ts # Package exports@rytass/storages (Base Package)
│
├── StorageInterface # Core interface all adapters must implement
├── Storage<O> # Base class with helper methods (not abstract)
├── ConverterManager # File converter pipeline system (from @rytass/file-converter)
├── Types & Interfaces # Shared type definitions
└── Error Handling # StorageError, ErrorCode enums
@rytass/storages-adapter-* # Provider implementations
│
├── [Provider]Storage # Extends Storage<ProviderOptions>
├── typings.ts # Provider-specific option types
└── index.ts # Package exportsBuffer | Readable{ key: string }Buffer | Readable{ key: string }npm install @rytass/storagesnpm install @rytass/storagesStorageInterfaceinterface StorageInterface {
// Upload operations (Note: options are NOT part of the interface)
write(file: InputFile): Promise<StorageFile>;
batchWrite(files: InputFile[]): Promise<StorageFile[]>;
// Download operations
read(key: string): Promise<Readable>;
read(key: string, options: ReadBufferFileOptions): Promise<Buffer>;
read(key: string, options: ReadStreamFileOptions): Promise<Readable>;
// File management
remove(key: string): Promise<void>;
// Note: isExists() is NOT part of the interface, it's in Storage class
}Storage<O>class Storage<O extends Record<string, unknown> = Record<string, unknown>>
implements StorageInterface {
// Provided by base class
readonly converterManager: ConverterManager;
readonly hashAlgorithm: FilenameHashAlgorithm;
constructor(options?: StorageOptions<O>);
// File type detection helpers
getExtension(file: InputFile): Promise<FileTypeResult | undefined>;
getBufferFilename(buffer: Buffer): Promise<[string, string | undefined]>;
getStreamFilename(stream: Readable): Promise<[string, string | undefined]>;
// Methods to override (throw Error by default, subclasses must override)
write(file: InputFile, options?: WriteFileOptions): Promise<StorageFile>;
batchWrite(files: InputFile[], options?: WriteFileOptions[]): Promise<StorageFile[]>;
read(key: string): Promise<Readable>;
read(key: string, options: ReadBufferFileOptions): Promise<Buffer>;
read(key: string, options: ReadStreamFileOptions): Promise<Readable>;
remove(key: string): Promise<void>;
// Additional method to override (NOT in StorageInterface)
isExists(key: string): Promise<boolean>;
}Note: Theclass is NOT abstract. Instead, methods throwStorageby default, requiring subclasses to override them. TheError('Method not implemented.')andwritemethods acceptbatchWriteparameter in the implementation but NOT inoptions.StorageInterface
StorageInterfaceinterface StorageInterface {
// Upload operations (Note: options are NOT part of the interface)
write(file: InputFile): Promise<StorageFile>;
batchWrite(files: InputFile[]): Promise<StorageFile[]>;
// Download operations
read(key: string): Promise<Readable>;
read(key: string, options: ReadBufferFileOptions): Promise<Buffer>;
read(key: string, options: ReadStreamFileOptions): Promise<Readable>;
// File management
remove(key: string): Promise<void>;
// Note: isExists() is NOT part of the interface, it's in Storage class
}Storage<O>class Storage<O extends Record<string, unknown> = Record<string, unknown>>
implements StorageInterface {
// Provided by base class
readonly converterManager: ConverterManager;
readonly hashAlgorithm: FilenameHashAlgorithm;
constructor(options?: StorageOptions<O>);
// File type detection helpers
getExtension(file: InputFile): Promise<FileTypeResult | undefined>;
getBufferFilename(buffer: Buffer): Promise<[string, string | undefined]>;
getStreamFilename(stream: Readable): Promise<[string, string | undefined]>;
// Methods to override (throw Error by default, subclasses must override)
write(file: InputFile, options?: WriteFileOptions): Promise<StorageFile>;
batchWrite(files: InputFile[], options?: WriteFileOptions[]): Promise<StorageFile[]>;
read(key: string): Promise<Readable>;
read(key: string, options: ReadBufferFileOptions): Promise<Buffer>;
read(key: string, options: ReadStreamFileOptions): Promise<Readable>;
remove(key: string): Promise<void>;
// Additional method to override (NOT in StorageInterface)
isExists(key: string): Promise<boolean>;
}注意:类并非抽象类。默认情况下,其方法会抛出Storage,要求子类重写这些方法。Error('Method not implemented.')和write方法在实现中支持batchWrite参数,但该参数并未包含在options中。StorageInterface
Storage<O>| Method | Source | Description |
|---|---|---|
| Storage class (options not in interface) | Upload a single file and return storage key |
| Storage class (options not in interface) | Upload multiple files in parallel |
| StorageInterface | Download file as Buffer or Stream |
| StorageInterface | Delete a file |
| Storage class only | Check if file exists (not in interface) |
Note:is defined in theisExists()class but NOT inStorage. This means adapters must implement it, but code depending only onStorageInterfacecannot assume it exists. Similarly, theStorageInterfaceparameter foroptionsandwriteis only in thebatchWriteclass implementation.Storage
Storage<O>| 方法 | 来源 | 描述 |
|---|---|---|
| Storage类(options未在接口中定义) | 上传单个文件并返回存储键 |
| Storage类(options未在接口中定义) | 并行上传多个文件 |
| StorageInterface | 将文件下载为Buffer或Stream |
| StorageInterface | 删除文件 |
| 仅Storage类 | 检查文件是否存在(未在接口中定义) |
注意:定义在isExists()类中,但并未包含在Storage里。这意味着adapter必须实现该方法,但仅依赖StorageInterface的代码无法假定该方法存在。同样,StorageInterface和write的batchWrite参数仅在Storage类的实现中存在。options
| Method | Description | Example |
|---|---|---|
| Generate presigned/signed URL for temporary access | Cloud adapters (S3, GCS, R2, Azure) |
| Custom helpers | Provider-specific utilities | |
| 方法 | 描述 | 示例 |
|---|---|---|
| 生成预签名/签名URL以提供临时访问权限 | 云adapter(S3、GCS、R2、Azure) |
| 自定义辅助方法 | 提供商特定的工具函数 | 本地adapter中的 |
// Input/Output Types (from @rytass/file-converter)
type ConvertableFile = Readable | Buffer;
type InputFile = ConvertableFile; // Re-exported alias
type FileKey = string;
interface StorageFile {
readonly key: FileKey;
}
// Options Types
interface StorageOptions<O extends Record<string, unknown>> {
converters?: FileConverter<O>[];
hashAlgorithm?: 'sha1' | 'sha256';
}
interface WriteFileOptions {
filename?: string; // Custom filename (overrides hash-based generation)
contentType?: string; // MIME type for the file
}
// Read Format Options
interface ReadBufferFileOptions {
format: 'buffer';
}
interface ReadStreamFileOptions {
format: 'stream';
}// Input/Output Types (from @rytass/file-converter)
type ConvertableFile = Readable | Buffer;
type InputFile = ConvertableFile; // Re-exported alias
type FileKey = string;
interface StorageFile {
readonly key: FileKey;
}
// Options Types
interface StorageOptions<O extends Record<string, unknown>> {
converters?: FileConverter<O>[];
hashAlgorithm?: 'sha1' | 'sha256';
}
interface WriteFileOptions {
filename?: string; // Custom filename (overrides hash-based generation)
contentType?: string; // MIME type for the file
}
// Read Format Options
interface ReadBufferFileOptions {
format: 'buffer';
}
interface ReadStreamFileOptions {
format: 'stream';
}enum ErrorCode {
WRITE_FILE_ERROR = '101', // Failed to upload file
READ_FILE_ERROR = '102', // Failed to download file
REMOVE_FILE_ERROR = '103', // Failed to delete file
UNRECOGNIZED_ERROR = '104', // Unknown error
DIRECTORY_NOT_FOUND = '201', // Directory doesn't exist (Local adapter)
FILE_NOT_FOUND = '202', // File doesn't exist
}enum ErrorCode {
WRITE_FILE_ERROR = '101', // Failed to upload file
READ_FILE_ERROR = '102', // Failed to download file
REMOVE_FILE_ERROR = '103', // Failed to delete file
UNRECOGNIZED_ERROR = '104', // Unknown error
DIRECTORY_NOT_FOUND = '201', // Directory doesn't exist (Local adapter)
FILE_NOT_FOUND = '202', // File doesn't exist
}Storage<YourOptions>getBufferFilename()getStreamFilename()converterManager.convert()StorageErrorErrorCodeStorage<YourOptions>getBufferFilename()getStreamFilename()converterManager.convert()ErrorCodeStorageError// From @rytass/file-converter
type ConvertableFile = Readable | Buffer;
interface FileConverter<O = Record<string, unknown>> {
convert<Buffer>(file: ConvertableFile): Promise<Buffer>;
convert<Readable>(file: ConvertableFile): Promise<Readable>;
}
class ConverterManager {
constructor(converters: FileConverter[]);
convert<ConvertableFileFormat extends ConvertableFile>(file: ConvertableFile): Promise<ConvertableFileFormat>;
}
// Usage in adapter
const convertedFile = await this.converterManager.convert(inputFile);// From @rytass/file-converter
type ConvertableFile = Readable | Buffer;
interface FileConverter<O = Record<string, unknown>> {
convert<Buffer>(file: ConvertableFile): Promise<Buffer>;
convert<Readable>(file: ConvertableFile): Promise<Readable>;
}
class ConverterManager {
constructor(converters: FileConverter[]);
convert<ConvertableFileFormat extends ConvertableFile>(file: ConvertableFile): Promise<ConvertableFileFormat>;
}
// Usage in adapter
const convertedFile = await this.converterManager.convert(inputFile);