Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
monarch-orm
Advanced tools
Monarch ORM is a type-safe ORM for MongoDB, designed to provide a seamless and efficient way to interact with your MongoDB database in a type-safe manner. Monarch ensures that your data models are strictly enforced, reducing the risk of runtime errors and enhancing code maintainability.
NPM:
npm install monarch-orm
Or Yarn:
yarn add monarch-orm
import { boolean, createClient, createDatabase, createSchema, number, string } from "monarch-orm";
const UserSchema = createSchema("users", {
name: string().nullable(),
email: string().lowercase().optional(),
age: number().optional().default(10),
isVerified: boolean(),
});
const client = createClient(/** db uri **//)
const { collections } = createDatabase(client.db(), {
users: UserSchema,
});
const newUser = await collections.users
.insert()
.values({
name: "anon",
email: "anon@gmail.com",
age: 0,
isVerified: true,
})
.exec();
const users = await collections.users.find().where({}).exec();
Use the createSchema function to define the structure of your model. Specify the fields and their types, using the available types and modifiers.
const UserSchema = createSchema("users", {
name: string(),
isVerified: boolean(),
});
Create a database instance using any client you deem fit and drop it into the createDatabase function
Or you can use the built-in createClient function.
Then you pass your schemas to the second arguement
const { collections } = createDatabase(client.db(), {
users: UserSchema,
});
You can insert new documents into your collection using the insert method. Ensure that the data conforms to the defined schema.
Example: Inserting a new user
const newUser = await collections.users
.insert()
.values({
name: "Alice",
email: "alice@example.com",
age: 25,
isVerified: true,
})
.exec();
Retrieve documents from your collection using the find or findOne methods.
Example: Querying all users
const users = await collections.users.find().where({}).exec();
console.log(users);
// Or just...
const users = await collections.users.find({}).exec();
console.log(users);
// For finding one
const user = await collections.users.find().where({
name: "Alice"
}).exec();
console.log(users);
// Or...
const user = await collections.users.findOne({
name: "Alice"
}).exec();
console.log(users);
Update documents in your collection using the update method. You can update a single document or multiple documents based on a filter.
Example: Updating a single user's email
const updatedUser = await collections.users
.updateOne()
.set({
email: "alice.updated@example.com",
})
.where({
name: "Alice",
})
.exec();
console.log(updatedUser);
Example: Updating multiple users' isVerified field
const updatedUsers = await collections.users
.updateMany()
.set({
isVerified: true,
})
.where({
isVerified: false,
})
.exec();
console.log(updatedUsers);
Note: The update method returns the number of documents updated.
You can also decentralize the models
const { db } = createDatabase(client);
const UserSchema = createSchema("users", {
name: string(),
isVerified: boolean(),
});
const UserModel = db(UserSchema);
export default UserModel;
And use it like this
const user = await UserModel.findOne({
name: "Alice"
}).exec();
console.log(users);
Defines a field that accepts string values.
const UserSchema = createSchema("users", {
name: string().required(),
});
.lowercase()
: Transforms the value to lowercase before storing..uppercase()
: Transforms the value to uppercase before storing.const UserSchema = createSchema("users", {
name: string().lowercase(),
});
Defines a field that accepts numeric values.
const UserSchema = createSchema("users", {
age: number().optional(),
});
Defines a field that accepts boolean values (true or false).
const UserSchema = createSchema("users", {
isVerified: boolean(),
});
Defines a field that accepts JavaScript Date objects.
const UserSchema = createSchema("users", {
birthDate: date(),
});
Defines a field that accepts date strings in ISO format.
const UserSchema = createSchema("users", {
registrationDate: dateString(),
});
.nullable()
: Allows the field to accept null values..default()
: Sets a default value if none is provided..optional()
: Makes the field optional, allowing it to be omitted.The literal()
type allows you to define a schema with fixed possible values, similar to enums in TypeScript. This is useful for enforcing specific, predefined values for a field.
const UserRoleSchema = createSchema("userRoles", {
role: literal("admin", "moderator", "customer"),
});
const user = {
role: "admin", // Valid
};
// Invalid example will throw a type error
const invalidUser = {
role: "guest", // Error: Type '"guest"' is not assignable to type '"admin" | "moderator" | "customer"'
};
// all properties are required by default
const UserSchema = object({
name: string(),
age: number(),
});
// extract the inferred type like this
type User = InferSchemaInput<typeof UserSchema>;
// equivalent to:
type User = {
name: string;
age: number;
};
A record()
allows you to define a flexible schema where each user can have a varying number of subjects and grades without needing to define a fixed schema for each subject.
// Define the User schema with a record for grades
const UserSchema = createSchema("users", {
name: string().required(),
email: string().required(),
grades: record(number()), // Each subject will have a numeric grade
});
// Example of inserting a user with grades
const { collections } = createDatabase(client.db(), {
users: UserSchema,
});
// Inserting a new user with grades for different subjects
const newUser = await collections.users
.insert()
.values({
name: "Alice",
email: "alice@example.com",
grades: {
math: 90,
science: 85,
history: 88,
},
})
.exec();
// Querying the user to retrieve grades
const user = await collections.users.findOne().where({ email: "alice@example.com" }).exec();
console.log(user.grades);
// Output: { math: 90, science: 85, history: 88 }
// For Example
const ResultSchema = object({
name: string(),
scores: array(number()),
});
// extract the inferred type like this
type Result = InferSchemaInput<typeof ResultSchema>;
// equivalent to:
type Result = {
name: string;
scores: number[];
};
Unlike arrays, A tuple()
has a fixed number of elements but each element can have a different type.
// all properties are required by default
const ControlSchema = object({
location: tuple([number(), number()]),
});
// extract the inferred type like this
type Control = InferSchemaInput<typeof ControlSchema>;
// equivalent to:
type Control = {
location: [number, number];
};
The taggedUnion()
allows you to define a schema for related types, each with its own structure, distinguished by a common "tag" field. This is useful for representing variable types in a type-safe manner.
// You need:
// - a tag: A string identifying the type
// value: An object containing specific fields for that type.
const NotificationSchema = createSchema("notifications", {
notification: taggedUnion({
email: object({
subject: string(),
body: string(),
}),
sms: object({
phoneNumber: string(),
message: string(),
}),
push: object({
title: string(),
content: string(),
}),
}),
});
const notification = ;
await collections.notifications.insert().values({ notification: {
tag: "email",
value: {
subject: "Welcome!",
body: "Thank you for joining us.",
},
} }).exec();
The union()
type allows you to define a field that can accept multiple different types. It's useful when a field can legitimately contain values of different types. Each type provided to union()
acts as a possible variant for the field.
const MilfSchema = createSchema("milf", {
phoneOrEmail: union(string(), number()),
});
// Output Type : {
// phoneOrEmail: string | number
// }
The mixed()
type allows you to define a field that can accept any type of value. This is useful when you need maximum flexibility for a field's contents. However, use it sparingly as it bypasses TypeScript's type checking.
const AnythingSchema = createSchema("help", {
anything: mixed(),
});
FAQs
Type safe Object Document Mapper (ODM) for MongoDB
The npm package monarch-orm receives a total of 177 weekly downloads. As such, monarch-orm popularity was classified as not popular.
We found that monarch-orm demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.