···
+
import type { StandardSchemaV1 } from "@standard-schema/spec";
···
import { ObjectId } from "mongodb";
import { getDb } from "./client.ts";
+
export class Model<T extends StandardSchemaV1<unknown, Document>> {
+
private collection: Collection<StandardSchemaV1.InferOutput<T>>;
constructor(collectionName: string, schema: T) {
+
this.collection = getDb().collection<
+
StandardSchemaV1.InferOutput<T> & Document
+
data: StandardSchemaV1.InferInput<T>,
+
): Promise<InsertOneResult<StandardSchemaV1.InferOutput<T>>> {
+
const result = this.schema["~standard"].validate(data);
+
if (result instanceof Promise) {
+
throw new Error("Async validation not supported");
+
throw new Error(`Validation failed: ${JSON.stringify(result.issues)}`);
return await this.collection.insertOne(
+
result.value as OptionalUnlessRequiredId<StandardSchemaV1.InferOutput<T>>,
+
data: StandardSchemaV1.InferInput<T>[],
+
): Promise<InsertManyResult<StandardSchemaV1.InferOutput<T>>> {
+
const validatedData = data.map((item) => {
+
const result = this.schema["~standard"].validate(item);
+
if (result instanceof Promise) {
+
throw new Error("Async validation not supported");
+
throw new Error(`Validation failed: ${JSON.stringify(result.issues)}`);
return await this.collection.insertMany(
+
validatedData as OptionalUnlessRequiredId<
+
StandardSchemaV1.InferOutput<T>
+
query: Filter<StandardSchemaV1.InferOutput<T>>,
+
): Promise<(WithId<StandardSchemaV1.InferOutput<T>>)[]> {
return await this.collection.find(query).toArray();
+
query: Filter<StandardSchemaV1.InferOutput<T>>,
+
): Promise<WithId<StandardSchemaV1.InferOutput<T>> | null> {
return await this.collection.findOne(query);
+
): Promise<WithId<StandardSchemaV1.InferOutput<T>> | null> {
const objectId = typeof id === "string" ? new ObjectId(id) : id;
+
return await this.findOne(
+
{ _id: objectId } as Filter<StandardSchemaV1.InferOutput<T>>,
+
query: Filter<StandardSchemaV1.InferOutput<T>>,
+
data: Partial<StandardSchemaV1.InferOutput<T>>,
): Promise<UpdateResult> {
return await this.collection.updateMany(query, { $set: data });
+
query: Filter<StandardSchemaV1.InferOutput<T>>,
+
data: Partial<StandardSchemaV1.InferOutput<T>>,
): Promise<UpdateResult> {
return await this.collection.updateOne(query, { $set: data });
+
query: Filter<StandardSchemaV1.InferOutput<T>>,
+
data: StandardSchemaV1.InferInput<T>,
): Promise<UpdateResult> {
+
const result = this.schema["~standard"].validate(data);
+
if (result instanceof Promise) {
+
throw new Error("Async validation not supported");
+
throw new Error(`Validation failed: ${JSON.stringify(result.issues)}`);
return await this.collection.replaceOne(
+
result.value as OptionalUnlessRequiredId<StandardSchemaV1.InferOutput<T>>,
+
query: Filter<StandardSchemaV1.InferOutput<T>>,
+
): Promise<DeleteResult> {
return await this.collection.deleteMany(query);
+
query: Filter<StandardSchemaV1.InferOutput<T>>,
+
): Promise<DeleteResult> {
return await this.collection.deleteOne(query);
+
async count(query: Filter<StandardSchemaV1.InferOutput<T>>): Promise<number> {
return await this.collection.countDocuments(query);
···
// Pagination support for find
+
query: Filter<StandardSchemaV1.InferOutput<T>>,
options: { skip?: number; limit?: number; sort?: Document } = {},
+
): Promise<(WithId<StandardSchemaV1.InferOutput<T>>)[]> {
return await this.collection