@storage-kit/express
v4.0.0
Published
Express.js adapter for Storage Kit - plug-and-play storage HTTP endpoints
Maintainers
Readme
@storage-kit/express
Express.js adapter for Storage Kit - plug-and-play storage HTTP endpoints.
Installation
npm install @storage-kit/express @storage-kit/core express
# or
pnpm add @storage-kit/express @storage-kit/core expressQuick Start
Recommended: Centralized Initialization
Create a single createStorageKit instance and use it throughout your app:
// store-kit.ts
import { createStorageKit } from "@storage-kit/express";
export const storeKit = createStorageKit({
provider: "minio",
endpoint: "http://localhost:9000",
accessKeyId: "minioadmin",
secretAccessKey: "minioadmin",
defaultBucket: "uploads",
});// app.ts
import express from "express";
import { storeKit } from "./store-kit";
const app = express();
app.use(express.json());
// Use as route handler
app.use("/api/storage", storeKit.routeHandler());
// Use as service (direct method calls)
app.get("/example/presigned-url", async (req, res) => {
const result = await storeKit.getPresignedUploadUrl("_", "uploads/file.png", {
contentType: "image/png",
expiresIn: 3600,
});
res.json(result);
});
app.listen(3000, () => {
console.log("Server running on http://localhost:3000");
console.log("API Reference: http://localhost:3000/api/storage/reference");
});Swagger UI is automatically available at /api/storage/reference - no additional setup required!
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.
// store-kit.ts
import { createStorageKit } from "@storage-kit/express";
export const storeKit = createStorageKit({
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",
});
// Use default provider (minio)
await storeKit.deleteFile("_", "old-file.png");
// Switch to R2 for specific operation
await storeKit.useProvider("cloudflare-r2").deleteFile("_", "cdn-file.png");
// Switch to S3 and get bucket-scoped service
const s3Archives = storeKit.useProvider("s3").bucket("archives");
await s3Archives.uploadFile(buffer, "backup.zip");See the Multi-Provider Guide for more details.
Service Methods
The createStorageKit instance provides direct access to storage operations:
import { storeKit } from "./store-kit";
// Upload file programmatically
const result = await storeKit.uploadFile(
"_",
buffer,
"avatar.png",
"users/123"
);
// Generate presigned URL
const url = await storeKit.getPresignedUploadUrl("_", "files/doc.pdf", {
contentType: "application/pdf",
expiresIn: 3600,
});
// Generate presigned download URL
const downloadUrl = await storeKit.getPresignedDownloadUrl(
"_",
"files/doc.pdf"
);
// Delete file
await storeKit.deleteFile("_", "users/123/avatar.png");
// Bulk delete
await storeKit.deleteFiles("_", ["file1.png", "file2.png"]);
// Health check
const health = await storeKit.healthCheck();
// Get bucket-scoped service
const avatarStorage = storeKit.bucket("avatars");
await avatarStorage.uploadFile(buffer, "user123.png");
// Access underlying storage service for advanced operations
const storageService = storeKit.storage;Note: Use
"_"as bucket parameter to use thedefaultBucketconfigured during initialization.
Endpoints
The adapter implements all endpoints defined in the OpenAPI specification:
| 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 |
Built-in Swagger UI
The adapter includes a built-in interactive API reference powered by Swagger UI. By default, it's available at the /reference path relative to your mount point.
Default Behavior
app.use("/api/storage", storeKit.routeHandler());
// Swagger UI available at: /api/storage/referenceCustomizing Swagger UI
export const storeKit = createStorageKit({
provider: "minio",
// ... credentials
swagger: {
enabled: true,
path: "/docs", // Custom path (default: "/reference")
title: "My Storage API", // Custom page title
},
});
// Swagger UI available at: /api/storage/docsDisabling Swagger UI
export const storeKit = createStorageKit({
provider: "minio",
// ... credentials
swagger: false, // Disable Swagger UI entirely
});Configuration
interface ExpressStorageKitConfig {
// 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;
// Adapter options
defaultBucket?: string; // Default bucket when using "_" placeholder
maxFileSize?: number; // Max file size in bytes (default: 10MB)
allowedMimeTypes?: string[]; // e.g., ["image/*", "application/pdf"]
// Swagger UI options
swagger?:
| boolean
| {
enabled?: boolean; // Enable/disable (default: true)
path?: string; // URL path (default: "/reference")
title?: string; // Page title
};
// Hooks
onUploadComplete?: (result) => void;
onError?: (error) => void;
// Custom storage instance
storage?: IStorageService;
}Usage Examples
File Upload
curl -X POST http://localhost:3000/api/storage/my-bucket/files \
-F "file=@/path/to/image.png" \
-F "path=avatars/user123"Delete File
curl -X DELETE http://localhost:3000/api/storage/my-bucket/files/avatars%2Fuser123%2Fimage.pngGenerate Signed URL
curl "http://localhost:3000/api/storage/my-bucket/signed-url?key=file.png&type=upload"Error Handling
The adapter automatically converts StorageError to HTTP responses. You can also use the standalone error handler:
import { storageErrorHandler } from "@storage-kit/express";
// Apply after your routes
app.use(storageErrorHandler());Legacy API (Deprecated)
The storageKit() function is deprecated. Please use createStorageKit() instead:
// ❌ Deprecated
import { storageKit } from "@storage-kit/express";
app.use("/api/storage", storageKit({ ... }));
// ✅ Recommended
import { createStorageKit } from "@storage-kit/express";
const storeKit = createStorageKit({ ... });
app.use("/api/storage", storeKit.routeHandler());License
MIT
