Storage Options
Complete reference for configuring createStorage.
Required Options
bucket
Target bucket name for object operations.
const storage = createStorage({
bucket: "my-bucket",
// ...
});adapter
S3 provider integration used for presigned URLs and object operations. See Adapters for a full list of supported adapters.
import { aws } from "vs3/adapters";
const storage = createStorage({
bucket: "my-bucket",
adapter: aws({
region: "us-east-1",
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
},
}),
// ...
});Validation Options
maxFileSize
The maximum allowed file size in bytes. Files larger than this value will be rejected from uploads with a FILE_TOO_LARGE error. Value must be a positive number. Defaults to undefined (no restriction).
createStorage({
// ...
maxFileSize: 10 * 1024 * 1024, // 10MB
});allowedFileTypes
Allowlist of MIME types and/or extensions. Accepts a string array of MIME types and/or extensions. Defaults to undefined (no restriction).
createStorage({
// ...
allowedFileTypes: ["image/png", "image/jpeg", ".pdf"],
});contentValidators
Custom content validators for uploads. Validators are run sequentially after built-in validations (size, file type). If any validator fails, the upload is rejected with a CONTENT_VALIDATION_ERROR. Validators can be synchronous or asynchronous functions. Each validator receives the file info and parsed metadata, and must return a validation result.
Simple validator
const storage = createStorage({
// ...
contentValidators: [
(ctx) => {
if (ctx.fileInfo.name.includes("tmp")) {
return { valid: false, reason: "Temporary files are not allowed." };
}
return { valid: true };
},
];
})Named validator
const storage = createStorage({
// ...
contentValidators: [
{
name: "quota-check",
validate: async (ctx) => {
const usage = await getUserUsage(ctx.metadata.userId);
return usage < 1024 * 1024 * 1024
? { valid: true }
: { valid: false, reason: "Quota exceeded." };
},
},
];
})Named validators provide better error messages when validation fails.
contentValidatorTimeoutMs
Timeout in milliseconds for each content validator. If a validator takes longer than this, the upload is rejected. Defaults to undefined (no timeout).
createStorage({
// ...
contentValidatorTimeoutMs: 5000, // 5 seconds
});Metadata and Key Options
metadataSchema
Schema used to validate metadata at endpoint boundaries. Defaults to undefined (no validation). See Metadata Schemas for more information.
createStorage({
// ...
metadataSchema: z.object({
userId: z.string(),
}),
});generateKey
Custom function to generate the object key for the uploaded file. Defaults to undefined (uses a default key generator). The function receives the file info and metadata, and must return a string or promise resolving to a string.
createStorage({
// ...
generateKey: (fileInfo, metadata) => {
return `uploads/${metadata.userId}/${Date.now()}-${fileInfo.name}`,
}
});This can be helpful when you want to sort different types of uploads into different directories.
API Surface Options
baseUrl
The base URL of the API. Defaults to http://localhost:3000.
createStorage({
// ...
baseUrl: "https://example.com",
});apiPath
The api path where the API handler is mounted. Defaults to /api/storage.
createStorage({
// ...
apiPath: "/api/files",
});Middleware Option
middlewares
Global middleware chain executed before endpoint logic. Defaults to [] (no middlewares applied). Middlewares are applied in the order they are provided. See Middleware Overview for more information.
middlewares: [
createLoggingMiddleware({ logger: console.log }),
createRateLimitMiddleware({
maxRequests: 100,
windowMs: 60_000,
store: createInMemoryRateLimitStore(),
}),
];Hook Options
For more information on hooks, see Hooks. The storage instance supports the following hooks:
beforeUploadafterUploadbeforeDownloadafterDownload