Zodel is a model layer for Deno applications that combines the power of Zod schemas with MongoDB-compatible databases like dengo.
- JSON Schema to Zod: Convert JSON Schema to Zod schemas for powerful validation
- MongoDB API: Use MongoDB-compatible APIs for data storage
- Type Safety: First-class TypeScript support with generics
- Validation: Automatic validation of documents, queries, and updates
- References: Support for references between collections
# Import directly
import createModels from "https://raw.githubusercontent.com/yourusername/zodel/main/index.ts";
import createModels from "./zodel/index.ts";
import { Collection } from "dengo";
// Define your schemas using JSON Schema
const schemas = {
User: {
type: "object",
properties: {
_id: { type: "objectId" },
name: { type: "string" },
email: { type: "string", format: "email" },
age: { type: "number" },
},
required: ["name", "email"],
},
};
// Create models from schemas
const models = createModels(schemas);
// Connect to a database (using dengo in this example)
const kv = await Deno.openKv(":memory:");
const userCollection = new Collection(kv, "users");
// Inject the collection into the model
models.User.collection = userCollection;
// Now you can use the model to interact with the database
const result = await models.User.insertOne({
name: "John Doe",
email: "john@example.com",
age: 30,
});
// Find a user
const user = await models.User.findOne({ name: "John Doe" });
console.log(user.data);
Zodel works with dengo, a MongoDB-compatible API for Deno KV. However, there are some compatibility issues to be aware of. See the TODO.md file in the dengo folder for details.
When using zodel with dengo, the following operations are fully supported:
- insertOne: Insert a single document
- insertMany: Insert multiple documents
- findOne: Find a single document using simple equality queries
- find: Find multiple documents using simple equality queries
The following operations have limitations:
- Query Operators: Complex query operators like
$gt
,$lt
,$in
, etc. are not fully supported - Update Operators: Update operators like
$inc
,$set
with nested paths are not fully supported - Delete Operations: Delete operations may not return the correct counts
- Reference Population: Population of references is not fully supported
For now, we recommend using simple equality queries and avoiding complex operators:
// Instead of this:
const user = await models.User.findOne({ age: { $gt: 30 } });
// Use this:
const user = await models.User.findOne({ name: "John" });
For updates, fetch the document, modify it, and save it back:
// Instead of this:
await models.User.updateOne(
{ name: "John" },
{ $inc: { age: 1 } }
);
// Use this:
const user = await models.User.findOne({ name: "John" });
user.data.age += 1;
await models.User.updateOne(
{ _id: user.data._id },
{ $set: user.data }
);
MIT