@storage-kit/nestjs
v4.0.0
Published
NestJS module for Storage Kit - plug-and-play storage HTTP endpoints
Maintainers
Readme
@storage-kit/nestjs
NestJS module for Storage Kit - plug-and-play storage HTTP endpoints.
Installation
npm install @storage-kit/nestjs @storage-kit/core @nestjs/platform-express
# or
pnpm add @storage-kit/nestjs @storage-kit/core @nestjs/platform-expressQuick Start
import { Module } from "@nestjs/common";
import { StorageKitModule } from "@storage-kit/nestjs";
@Module({
imports: [
StorageKitModule.forRoot({
provider: "minio",
endpoint: "http://localhost:9000",
accessKeyId: "minioadmin",
secretAccessKey: "minioadmin",
}),
],
})
export class AppModule {}Multi-Provider Configuration
Storage Kit supports configuring multiple storage providers and switching between them at runtime using useProvider(). This is useful for multi-region deployments, hybrid cloud strategies, and migrations.
import { Module } from "@nestjs/common";
import { StorageKitModule } from "@storage-kit/nestjs";
@Module({
imports: [
StorageKitModule.forRoot({
provider: "minio", // Default provider
providers: {
minio: {
endpoint: "http://localhost:9000",
accessKeyId: "minioadmin",
secretAccessKey: "minioadmin",
},
"cloudflare-r2": {
endpoint: "https://account.r2.cloudflarestorage.com",
accessKeyId: process.env.R2_ACCESS_KEY!,
secretAccessKey: process.env.R2_SECRET_KEY!,
},
s3: {
region: "us-east-1",
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
},
},
defaultBucket: "uploads",
}),
],
})
export class AppModule {}Using useProvider() in Services
import { Injectable } from "@nestjs/common";
import { StorageKitService } from "@storage-kit/nestjs";
@Injectable()
export class FileService {
constructor(private readonly storage: StorageKitService) {}
async uploadToCDN(file: Buffer, filename: string) {
// Use R2 for CDN-served files
return this.storage.useProvider("cloudflare-r2").uploadFile("cdn", file, filename);
}
async archiveFile(file: Buffer, filename: string) {
// Use S3 for archives
return this.storage.useProvider("s3").uploadFile("archives", file, filename);
}
async deleteFromDefault(key: string) {
// Use default provider (minio)
return this.storage.handleDelete("uploads", key);
}
}See the Multi-Provider Guide for more details.
Setting up Swagger UI
The module includes built-in Swagger UI support. Call setupSwagger in your main.ts:
import { NestFactory } from "@nestjs/core";
import { StorageKitModule } from "@storage-kit/nestjs";
import { AppModule } from "./app.module";
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// Setup Swagger UI (available at /reference by default)
StorageKitModule.setupSwagger(app);
await app.listen(3000);
console.log("Server running on http://localhost:3000");
console.log("API Reference: http://localhost:3000/reference");
}
bootstrap();Customizing Swagger UI
StorageKitModule.setupSwagger(app, {
path: "/docs", // Custom path (default: "/reference")
title: "My Storage API", // Custom page title
description: "Custom API description",
});Disabling Swagger UI
// Option 1: In module config
StorageKitModule.forRoot({
provider: "minio",
// ... credentials
swagger: false,
});
// Option 2: Simply don't call setupSwagger in main.tsAsync Configuration
import { Module } from "@nestjs/common";
import { ConfigModule, ConfigService } from "@nestjs/config";
import { StorageKitModule } from "@storage-kit/nestjs";
@Module({
imports: [
ConfigModule.forRoot(),
StorageKitModule.forRootAsync({
imports: [ConfigModule],
useFactory: (config: ConfigService) => ({
provider: "minio",
endpoint: config.get("MINIO_ENDPOINT"),
accessKeyId: config.get("MINIO_ACCESS_KEY"),
secretAccessKey: config.get("MINIO_SECRET_KEY"),
}),
inject: [ConfigService],
}),
],
})
export class AppModule {}Endpoints
The module automatically registers these endpoints:
| Method | Path | Description |
|--------|------|-------------|
| POST | /:bucket/files | Upload a file |
| DELETE | /:bucket/files/:filePath | Delete a single file |
| DELETE | /:bucket/files | Bulk delete files |
| GET | /:bucket/signed-url | Generate signed URL |
| GET | /health | Health check |
Using the Service
Inject StorageKitService to use storage operations in your own services:
import { Injectable } from "@nestjs/common";
import { StorageKitService, UploadedFile } from "@storage-kit/nestjs";
@Injectable()
export class AvatarService {
constructor(private storage: StorageKitService) {}
async uploadAvatar(file: UploadedFile, userId: string) {
return this.storage.handleUpload(
"avatars-bucket",
file,
`users/${userId}`
);
}
}Configuration
interface NestJSStorageKitConfig {
// Required
provider: "minio" | "backblaze" | "cloudflare-r2" | "s3" | "gcs" | "spaces" | "azure";
// Provider credentials
endpoint?: string;
accessKeyId?: string;
secretAccessKey?: string;
region?: string;
publicUrlBase?: string;
// Azure specific
connectionString?: string;
accountName?: string;
accountKey?: string;
// Module options
global?: boolean; // Make module global
routePrefix?: string; // Custom route prefix
// Adapter options
defaultBucket?: string;
maxFileSize?: number;
allowedMimeTypes?: string[];
// Swagger UI options
swagger?: boolean | {
enabled?: boolean; // Enable/disable (default: true)
path?: string; // URL path (default: "/reference")
title?: string; // Page title
description?: string; // API description
};
// Hooks
onUploadComplete?: (result) => void;
onError?: (error) => void;
// Custom storage instance
storage?: IStorageService;
}Exception Filters
Apply the built-in exception filter to handle StorageError:
import { StorageErrorFilter } from "@storage-kit/nestjs";
// In main.ts
app.useGlobalFilters(new StorageErrorFilter());
// Or on a controller
@UseFilters(StorageErrorFilter)
@Controller("storage")
export class MyStorageController {}Exported Tokens
For advanced use cases, you can inject the underlying services:
import { Inject } from "@nestjs/common";
import {
STORAGE_KIT_SERVICE, // IStorageService
STORAGE_KIT_HANDLER, // StorageHandler
STORAGE_KIT_CONFIG, // Config object
} from "@storage-kit/nestjs";License
MIT
