📦 Type-safe BullMQ integration with Zod schema validation
- 🔒 Type-safe job data and return types using Zod schemas
- ⚡ Seamless integration with BullMQ
- 🛡️ Runtime validation of job payloads
- 📝 TypeScript support out of the box
- 🚀 Zero runtime overhead when validation is disabled
- 🚀 Multiple job types in single queue
npm install bullmq-zod bullmq zod
# or
yarn add bullmq-zod bullmq zod
# or
pnpm add bullmq-zod bullmq zod
import { createQueue } from 'bullmq-zod';
import { z } from 'zod';
// Define your job schemas
const jobSchemas = {
sendEmail: z.object({
to: z.string().email(),
subject: z.string(),
content: z.string(),
}),
processImage: z.object({
imageUrl: z.string().url(),
width: z.number().positive(),
height: z.number().positive(),
format: z.enum(['jpeg', 'png', 'webp']),
}),
} as const;
// Create a type-safe queue
const queue = createQueue('my-queue', jobSchemas);
// Register job handlers
queue.registerHandler('sendEmail', async (job) => {
const { to, subject, content } = job.data; // Fully typed!
// Handle email sending
});
queue.registerHandler('processImage', async (job) => {
const { imageUrl, width, height, format } = job.data; // Fully typed!
// Handle image processing
});
// Initialize worker
queue.initWorker();
// Start the worker
await queue.startWorker();
// Add jobs - all payloads are type-checked!
await queue.addJob('sendEmail', {
to: '[email protected]',
subject: 'Hello',
content: 'World',
});
await queue.addJob('processImage', {
imageUrl: 'https://example.com/image.jpg',
width: 800,
height: 600,
format: 'webp',
});
// TypeScript will catch invalid payloads at compile time
await queue.addJob('sendEmail', {
to: 'invalid-email', // Type error!
subject: 123, // Type error!
});
// Zod will catch invalid payloads at runtime
await queue.addJob('processImage', {
imageUrl: 'not-a-url', // Runtime error!
width: -100, // Runtime error!
height: 600,
format: 'invalid', // Runtime error!
});
Creates a type-safe BullMQ queue with Zod schema validation.
function createQueue<T extends JobSchemaDefinition>(
queueName: string,
schemas: T,
queueOptions?: QueueOptions
): TypedQueue<T>
The main queue class with type-safe methods.
class TypedQueue<T extends JobSchemaDefinition> {
// Add a job to the queue
async addJob<K extends JobName<T>>(
jobName: K,
payload: JobPayloads<T>[K],
jobOptions?: JobsOptions
): Promise<Job<JobPayloads<T>[K]>>;
// Register a job handler
registerHandler<K extends JobName<T>>(
jobName: K,
handler: JobHandler<T, K>
): void;
// Initialize worker
async initWorker(
workerOptions?: WorkerOptions,
connection?: RedisConnection
): Promise<Worker>;
// Start the worker
async startWorker(
workerOptions?: WorkerOptions,
connection?: RedisConnection
): Promise<Worker>;
// Get the underlying BullMQ Queue instance
get queue(): Queue;
// Get the underlying BullMQ Worker instance
get worker(): Worker | null;
// Close the queue and worker
async close(): Promise<void>;
}
Contributions are welcome! Please feel free to submit a Pull Request.
MIT © AprilNEA