Comparing version 1.2.3 to 2.0.0
export { default as Database } from "./lib/database.js"; | ||
export { default as Model } from "./lib/model.js"; | ||
export * from "./lib/functions.js"; | ||
export * from "./lib/schemas/index.js"; |
@@ -5,19 +5,20 @@ import { MongoClient } from "mongodb"; | ||
export default class Database { | ||
static #db = null; | ||
#db = null; | ||
#uri = null; | ||
static async connect(url, callback) { | ||
const { mongoURL, databaseName } = parseMongoURL(url); | ||
constructor(uri) { | ||
this.#uri = uri; | ||
} | ||
async connect() { | ||
const { mongoURL, databaseName } = parseMongoURL(this.#uri); | ||
const client = new MongoClient(mongoURL); | ||
await client.connect(); | ||
Database.#db = client.db(databaseName); | ||
if (callback) callback(); | ||
return Database.#db; | ||
this.#db = client.db(databaseName); | ||
} | ||
static getDB() { | ||
if (!Database.#db) { | ||
getDB() { | ||
if (!this.#db) { | ||
throw new Error( | ||
@@ -28,4 +29,4 @@ "Connection not established, please connect to the database first" | ||
return Database.#db; | ||
return this.#db; | ||
} | ||
} |
import { ObjectId } from "mongodb"; | ||
import Database from "./database.js"; | ||
export default class Model { | ||
#db; | ||
#schema; | ||
#collectionName; | ||
#collection; | ||
constructor(schema, collectionName) { | ||
constructor(db, schema, collectionName) { | ||
this.#db = db; | ||
this.#schema = schema; | ||
this.collectionName = collectionName; | ||
this.#collectionName = collectionName; | ||
this.#collection = null; | ||
@@ -16,3 +19,3 @@ } | ||
if (!this.#collection) | ||
this.#collection = Database.getDB().collection(this.collectionName); | ||
this.#collection = this.#db.getDB().collection(this.#collectionName); | ||
@@ -35,3 +38,3 @@ return this.#collection; | ||
const { data: result, error } = this.#schema.partial().safeParse(data); | ||
const { data: result, error } = this.#schema.safeParse(data); | ||
@@ -47,3 +50,3 @@ if (error) return { data: null, error: error.errors[0].message }; | ||
let validatedData = []; | ||
let errorMessage = false; | ||
let errorMessage = ""; | ||
@@ -53,4 +56,4 @@ for (const object of data) { | ||
if (error) { | ||
errorMessage = error.errors[0].message; | ||
if (typeof error === "string") { | ||
errorMessage = error; | ||
break; | ||
@@ -62,3 +65,3 @@ } | ||
return { data: validatedData, error: errorMessage }; | ||
return { data: validatedData, error: errorMessage ?? false }; | ||
} | ||
@@ -73,3 +76,3 @@ | ||
return { result: data, error: false }; | ||
return { result: data }; | ||
} | ||
@@ -95,3 +98,3 @@ | ||
return { result: data, error: false }; | ||
return { result: data }; | ||
} | ||
@@ -98,0 +101,0 @@ |
import { Db } from "mongodb"; | ||
export default class Database { | ||
private static db: Db; | ||
/** | ||
* Database class for managing the MongoDB connection. | ||
*/ | ||
declare class Database { | ||
#db: Db | null; | ||
#uri: string | null; | ||
static connect(url: string, callback: () => void): Promise<void>; | ||
/** | ||
* Creates an instance of Database. | ||
* | ||
* @param {string} uri The MongoDB connection URI. | ||
*/ | ||
constructor(uri: string); | ||
static getDB(): Db; | ||
/** | ||
* Connects to the MongoDB database. | ||
* | ||
* @returns {Promise<void>} A promise that resolves when the connection is established. | ||
*/ | ||
connect(): Promise<void>; | ||
/** | ||
* Retrieves the connected database instance. | ||
* | ||
* @returns {Db} The MongoDB database instance. | ||
* @throws {Error} If the connection is not established. | ||
*/ | ||
getDB(): Db; | ||
} | ||
export default Database; |
@@ -0,1 +1,6 @@ | ||
/** | ||
* Use this function to get the mongoDB url and the database name | ||
* @param {string} url The database url | ||
* @returns {{mongoURL: string, databaseName: string}} The url and the db name | ||
*/ | ||
export function parseMongoURL(url: string): { | ||
@@ -2,0 +7,0 @@ mongoURL: string; |
import { | ||
Db, | ||
ObjectId, | ||
Collection, | ||
Filter, | ||
FindOptions, | ||
UpdateOptions, | ||
DeleteOptions, | ||
FindOneAndUpdateOptions, | ||
FindOneAndDeleteOptions, | ||
InsertOneOptions, | ||
BulkWriteOptions, | ||
OptionalId, | ||
UpdateResult, | ||
Document, | ||
@@ -14,59 +16,164 @@ } from "mongodb"; | ||
export default class Model<T extends Document> { | ||
#schema: ZodSchema<T> | undefined; | ||
#collection: Collection<T>; | ||
collectionName: string; | ||
/** | ||
* Model class for interacting with a MongoDB collection. | ||
* | ||
* @template T The type of documents in the collection. | ||
*/ | ||
declare class Model<T extends Document> { | ||
#db: Db; | ||
#schema: ZodSchema<T> | null; | ||
#collection: Collection<T> | null; | ||
#collectionName: string; | ||
constructor(schema: ZodSchema<T> | undefined, collectionName: string); | ||
/** | ||
* Creates an instance of Model. | ||
* | ||
* @param {Db} db The database instance. | ||
* @param {ZodSchema<T>} schema The Zod schema for validating documents. | ||
* @param {string} collectionName The name of the collection in the database. | ||
*/ | ||
constructor(db: Db, schema: ZodSchema<T> | null, collectionName: string); | ||
/** | ||
* Gets the MongoDB collection. | ||
* | ||
* @private | ||
* @returns {Collection<T>} The MongoDB collection. | ||
*/ | ||
#getCollection(): Collection<T>; | ||
#validateSchema(data: unknown): { data: T | null; error: string | false }; | ||
#validatePartialSchema(data: unknown): { | ||
/** | ||
* Validates a document against the schema. | ||
* | ||
* @param {T} data The document to validate. | ||
* @returns {{ data: T | null, error: string | false }} The result of the validation. | ||
* @private | ||
*/ | ||
#validateSchema(data: T): { data: T | null; error: string | false }; | ||
/** | ||
* Validates a partial document against the schema. | ||
* | ||
* @param {Partial<T>} data The partial document to validate. | ||
* @returns {{ data: Partial<T> | null, error: string | false }} The result of the validation. | ||
* @private | ||
*/ | ||
#validatePartialSchema(data: Partial<T>): { | ||
data: Partial<T> | null; | ||
error: string | false; | ||
}; | ||
#validateArraySchema(data: unknown[]): { data: T[]; error: string | false }; | ||
find( | ||
query?: Filter<T>, | ||
options?: FindOptions<T> | ||
): Promise<{ result: T[]; error: false }>; | ||
/** | ||
* Validates an array of documents against the schema. | ||
* | ||
* @param {T[]} data The array of documents to validate. | ||
* @returns {{ data: T[] | null, error: string | false }} The result of the validation. | ||
* @private | ||
*/ | ||
#validateArraySchema(data: T[]): { data: T[] | null; error: string | false }; | ||
/** | ||
* Finds documents in the collection. | ||
* | ||
* @param {Filter<T>} [query={}] Search filters. | ||
* @param {FindOptions} [options={}] Search options. | ||
* @returns {Promise<{ result: T[] }>} The search result. | ||
*/ | ||
find(query?: Filter<T>, options?: FindOptions): Promise<{ result: T[] }>; | ||
/** | ||
* Finds a single document in the collection. | ||
* | ||
* @param {Filter<T>} query Search filters. | ||
* @param {FindOptions} [options={}] Search options. | ||
* @returns {Promise<{ result: T | null }>} The search result. | ||
*/ | ||
findOne( | ||
query: Filter<T>, | ||
options?: FindOptions<T> | ||
): Promise<{ result: T | null; error: false }>; | ||
findById( | ||
id: string, | ||
options?: FindOptions<T> | ||
): Promise<{ result: T | null; error: false }>; | ||
options?: FindOptions | ||
): Promise<{ result: T | null }>; | ||
insert( | ||
data: OptionalId<T>, | ||
options?: InsertOneOptions | ||
): Promise<{ result: T | null; error: string | false }>; | ||
/** | ||
* Finds a document by its ID. | ||
* | ||
* @param {string} id The ID of the document. | ||
* @param {FindOptions} [options={}] Search options. | ||
* @returns {Promise<{ result: T | null }>} The search result. | ||
*/ | ||
findById(id: string, options?: FindOptions): Promise<{ result: T | null }>; | ||
/** | ||
* Inserts a new document into the collection. | ||
* | ||
* @param {T} data The document to insert. | ||
* @param {InsertOneOptions} [options={}] Insert options. | ||
* @returns {Promise<{ result: T | null }>} The result of the insertion. | ||
*/ | ||
insert(data: T, options?: InsertOneOptions): Promise<{ result: T | null }>; | ||
/** | ||
* Inserts multiple documents into the collection. | ||
* | ||
* @param {T[]} data The documents to insert. | ||
* @param {BulkWriteOptions} [options={}] Insert options. | ||
* @returns {Promise<{ result: T[] | null, error: string | false }>} The result of the insertion. | ||
*/ | ||
insertMany( | ||
data: OptionalId<T>[], | ||
data: T[], | ||
options?: BulkWriteOptions | ||
): Promise<{ result: T[] | null; error: string | false }>; | ||
/** | ||
* Updates documents in the collection. | ||
* | ||
* @param {Filter<T>} query Search filters for the update. | ||
* @param {Partial<T>} data Data to update. | ||
* @param {FindOneAndUpdateOptions} [options={}] Update options. | ||
* @returns {Promise<{ result: UpdateResult<Document> | null, error: string | false }>} The result of the update. | ||
*/ | ||
update( | ||
query: Filter<T>, | ||
data: Partial<T>, | ||
options?: UpdateOptions | ||
): Promise<{ result: T | null; error: string | false }>; | ||
options?: FindOneAndUpdateOptions | ||
): Promise<{ result: UpdateResult<Document> | null; error: string | false }>; | ||
/** | ||
* Updates a document by its ID. | ||
* | ||
* @param {string} id The ID of the document to update. | ||
* @param {Partial<T>} data Data to update. | ||
* @param {FindOneAndUpdateOptions} [options={}] Update options. | ||
* @returns {Promise<{ result: UpdateResult<Document> | null, error: string | false }>} The result of the update. | ||
*/ | ||
updateById( | ||
id: string, | ||
data: Partial<T>, | ||
options?: UpdateOptions | ||
): Promise<{ result: T | null; error: string | false }>; | ||
options?: FindOneAndUpdateOptions | ||
): Promise<{ result: UpdateResult<Document> | null; error: string | false }>; | ||
/** | ||
* Deletes documents from the collection. | ||
* | ||
* @param {Filter<T>} query Search filters for the deletion. | ||
* @param {FindOneAndDeleteOptions} [options={}] Delete options. | ||
* @returns {Promise<{ result: T | null }>} The result of the deletion. | ||
*/ | ||
delete( | ||
query: Filter<T>, | ||
options?: DeleteOptions | ||
): Promise<{ result: T | null; error: false }>; | ||
options?: FindOneAndDeleteOptions | ||
): Promise<{ result: T | null }>; | ||
/** | ||
* Deletes a document by its ID. | ||
* | ||
* @param {string} id The ID of the document to delete. | ||
* @param {FindOneAndDeleteOptions} [options={}] Delete options. | ||
* @returns {Promise<{ result: T | null }>} The result of the deletion. | ||
*/ | ||
deleteById( | ||
id: string, | ||
options?: DeleteOptions | ||
): Promise<{ result: T | null; error: false }>; | ||
options?: FindOneAndDeleteOptions | ||
): Promise<{ result: T | null }>; | ||
} | ||
export default Model; |
{ | ||
"name": "odemongo", | ||
"version": "1.2.3", | ||
"version": "2.0.0", | ||
"description": "Odemongo is an ODM for MongoDB", | ||
@@ -26,3 +26,8 @@ "main": "index.js", | ||
"zod": "3.23.8" | ||
} | ||
}, | ||
"types": "./lib/types/index.d.ts", | ||
"files": [ | ||
"./lib", | ||
"./lib/types" | ||
] | ||
} |
# Odemongo | ||
**Odemongo** is an **ODM** for MongoDB. \ | ||
It allows you to work with the database with a custom model. | ||
It allows you to work with multiple databases with a custom model. | ||
@@ -10,4 +10,3 @@ # Usage | ||
**Odemongo** brings a you a function that you can use to connect to the DB. \ | ||
Callback is optional. | ||
**Odemongo** brings a you a class that you can use to connect to a DB. \ | ||
@@ -17,3 +16,5 @@ ``` | ||
await Database.connect(connection_string, callback?) | ||
const db = new Database(mongodb_url) | ||
await db.connect() | ||
``` | ||
@@ -23,4 +24,5 @@ | ||
A model allows to you to interact with a collection and validate data with zod. \ | ||
Just by passing a zod schema odemongo will validate it and in case of error it will return it | ||
A model allows to you to interact with an especific database and an especific collection. \ | ||
It also allows you to validate data with zod. \ | ||
Just by passing a zod schema odemongo will validate it and in case of error it will return it. | ||
@@ -30,3 +32,3 @@ ``` | ||
const YOUR_MODEL = new Model(zod_schema, collection_name) | ||
const YOUR_MODEL = new Model(db, zod_schema, collection_name) | ||
``` | ||
@@ -37,6 +39,7 @@ | ||
Now you can use all of the functions that **Odemongo** brings you with your model. \ | ||
All the functions return an object with a result and an error and are asynchronous. \ | ||
All the functions that receive data return an object with a result and an error and are asynchronous. \ | ||
The find functions only return a result. \ | ||
If there is a validation error the message will be in error and result will be null. \ | ||
If validation is correct result will contain all the data and error will be false. \ | ||
Options are all the default options that the MongoDB NodeJS driver has | ||
Options are all the default options that the MongoDB NodeJS driver has. | ||
@@ -46,3 +49,3 @@ ### Model.find(query?, options?) | ||
``` | ||
const { result, error } = await Model.find() | ||
const { result } = await Model.find() | ||
``` | ||
@@ -55,3 +58,3 @@ | ||
``` | ||
const { result, error } = await Model.findOne({name: "John Doe"}) | ||
const { result } = await Model.findOne({ name: "John Doe" }) | ||
``` | ||
@@ -64,3 +67,3 @@ | ||
``` | ||
const { result, error } = await Model.findById(id) | ||
const { result } = await Model.findById(id) | ||
``` | ||
@@ -67,0 +70,0 @@ |
16845
365
143