Interfaces & Types
StorageModuleOptions
interface StorageModuleOptions<T extends Record<string, DiskOptions> = Record<string, DiskOptions>> {
default: keyof T; // name of the default disk
signSecret?: string; // enables local-disk signed URLs
disks: T; // disk name -> DiskOptions
drivers?: Driver[]; // custom/override driver factories
fakes?: FakesConfig; // where StorageService.fake() persists faked content; defaults to a temp dir
}
interface DiskOptions<T extends StorageDriver = StorageDriver> {
driver: T;
namingStrategy?: NamingStrategy; // overrides the disk's default (UuidNamingStrategy)
config: /* LocalDriverOptions | S3DriverOptions | R2DriverOptions | GCSDriverOptions | AzureDriverOptions, based on T */;
}
type StorageDriver = 'local' | 's3' | 'r2' | 'gcs' | 'azure' | (string & {});
interface Driver {
name: StorageDriver;
driver: (options: unknown) => DriverContract; // DriverContract is flydrive's driver interface
}Async options
interface AsyncStorageModuleOptions {
imports?: ModuleMetadata['imports'];
inject?: Array<Type<any> | string | symbol | Abstract<any> | Function>;
useClass?: Type<StorageOptionsFactory>;
useFactory?: (...args: any[]) => StorageModuleOptions | Promise<StorageModuleOptions>;
}
interface StorageOptionsFactory {
createStorageOptions(): StorageModuleOptions | Promise<StorageModuleOptions>;
}Exactly one of useFactory / useClass is expected. With useClass, the class is itself registered as a provider and must implement StorageOptionsFactory.
Driver config types
See each driver's page for a config example: Local, S3, R2, GCS, Azure.
type LocalDriverOptions = Omit<FSDriverOptions, 'visibility'> & {
url?: string;
visibility?: 'public' | 'private'; // default: 'private'
};
type S3DriverOptions = BaseS3DriverOptions & { cdn: CdnOptions };
// BaseS3DriverOptions: bucket, region, credentials, endpoint?, supportsACL?, cdnUrl?, visibility?, ...
type R2DriverOptions = Omit<S3DriverOptions, 'visibility' | 'supportsACL' | 'endpoint' | 'region' | 'credentials'> & {
credentials: { accessKeyId: string; secretAccessKey: string };
endpoint: S3ClientConfig['endpoint']; // required
region?: S3ClientConfig['region']; // defaults to 'auto'
};
type AzureDriverOptions = {
containerName: string;
visibility?: ObjectVisibility;
cdnUrl?: string;
} & (
| { connectionString: string; accountName?: undefined; accountKey?: undefined }
| { accountName: string; accountKey: string; connectionString?: undefined }
);
type CdnProvider = 'cloudfront' | (string & {});
type CdnOptions<T extends CdnProvider = CdnProvider> = {
provider: T;
signingKeyId: T extends 'cloudfront' ? string : never;
signingKey: T extends 'cloudfront' ? string : never;
[key: string]: unknown;
};StoredFile
Produced by the upload interceptors:
interface StoredFile {
disk: string; // the disk it was written to
path: string; // key/path within that disk
size: number;
mimetype: string;
originalName: string; // original client-provided filename
}FakeDisk / FakesConfig
Used by StorageService.fake():
interface FakeDisk extends Disk {
assertExists(paths: string | string[]): void;
assertMissing(paths: string | string[]): void;
clear(): void;
}
interface FakesConfig {
location: URL | string; // root dir the fake writes under; default: <tmpdir>/oxth-nestjs-storage-fakes
urlBuilder?: FakeUrlBuilder;
}NamingStrategy
type NamingStrategy<T = Uint8Array> = (file: T, originalName: string) => string | Promise<string>;StorageFileInterceptorOptions
Accepted by all four upload interceptors:
interface StorageFileInterceptorOptions {
disk?: string;
path?: string;
namingStrategy?: NamingStrategy;
fileFilter?: (req: any, file: any, cb: any) => void; // passed straight to multer
limits?: { fileSize?: number; files?: number }; // passed straight to multer
}FileExtensionValidator
A @nestjs/common FileValidator for use with ParseFilePipe — see File validation:
interface FileExtensionValidatorOptions {
allowedExtensions: string[]; // leading dot optional, matched case-insensitively
}
class FileExtensionValidator extends FileValidator<FileExtensionValidatorOptions> {
isValid(file?: Express.Multer.File): boolean;
buildErrorMessage(file: Express.Multer.File): string;
}Helper functions
Exported for reuse outside the built-in interceptors/guard/middleware — see Signed URLs for verifySignedUrl in context:
function verifySignedUrl(
req: Pick<Request, 'query' | 'originalUrl' | 'protocol' | 'host'>,
signSecret: string,
): SignedUrlVerificationResult;
type SignedUrlRejectionReason =
| 'Missing signature parameters'
| 'URL has expired'
| 'Invalid signature';
type SignedUrlVerificationResult =
| { valid: true }
| { valid: false; reason: SignedUrlRejectionReason };
function generateFileName(
strategy: NamingStrategy,
file: Express.Multer.File,
storedPath?: string,
): Promise<string>;
// path.join(storedPath ?? '', await strategy(file.buffer, file.originalname))generateFileName is what every upload interceptor uses internally to turn a naming strategy's result into a full stored path; only worth reaching for directly if you're building a fully custom interceptor from scratch instead of using the four built-in ones.
LocalDriver
The only concrete driver class exported directly (the s3/r2/gcs/azure drivers are resolved lazily by name and not part of the public API). It's flydrive's FSDriver with a local-specific URL builder (plain or HMAC-signed, depending on whether signSecret was set). See Custom Drivers if you want to extend or wrap it.
SignedURLOptions, WriteOptions, ObjectMetaData, ObjectVisibility, FileSnapshot, DriverContract are flydrive types (flydrive/types). Disk, DriveFile, DriveDirectory are flydrive classes (flydrive). For the exhaustive version of every type here, plus internal driver behavior, see llm-full.md.