Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ name: CI

on:
pull_request:
paths-ignore:
- "docs/**"
push:
branches:
- main
paths-ignore:
- "docs/**"

jobs:
build:
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ node_modules
dist
.DS_Store
coverage
docs/.vitepress
docs/.vitepress/cache
docs/.vitepress/dist
7 changes: 3 additions & 4 deletions docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { defineConfig } from "vitepress";

export default defineConfig({
title: "Monarch ORM",
description: "Type safe Object Document Mapper (ODM) for MongoDB",
description: "Type safe ODM for MongoDB",
cleanUrls: true,
themeConfig: {
nav: [
Expand All @@ -17,6 +17,7 @@ export default defineConfig({
items: [
{ text: "Getting Started", link: "/guide/getting-started" },
{ text: "Schemas & Types", link: "/guide/schemas-and-types" },
{ text: "Queries & Operators", link: "/guide/queries-and-operators" },
{ text: "Advanced Schemas", link: "/guide/advanced-schemas" },
{ text: "Aggregations & Relations", link: "/guide/aggregation-and-relations" },
],
Expand All @@ -27,8 +28,6 @@ export default defineConfig({
},
],

socialLinks: [
{ icon: "github", link: "https://github.com/monarch-orm/monarch" },
],
socialLinks: [{ icon: "github", link: "https://github.com/monarch-orm/monarch" }],
},
});
10 changes: 5 additions & 5 deletions docs/guide/advanced-schemas.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ In expansive, microservice-like or component-based setups, placing all schemas i
import { defineSchemas, mergeSchemas } from "monarch-orm";

// 1. Module defined for Users
const userGroup = defineSchemas({ UserSchema }).withRelations((s) => ({
users: { tutor: s.users.$one.users({ from: "tutorId", to: "_id" }) },
const userGroup = defineSchemas({ UserSchema }).withRelations((r) => ({
users: { tutor: r.one.users({ from: r.users.tutorId, to: r.users._id }) },
}));

// 2. Module defined for Content
Expand All @@ -102,12 +102,12 @@ const contentGroup = defineSchemas({ PostSchema, CategorySchema });
const mergedGroups = mergeSchemas(userGroup, contentGroup);

// Optionally attach relationships ACROSS the groups post-merge
const finalSchema = mergedGroups.withRelations((s) => ({
const finalSchema = mergedGroups.withRelations((r) => ({
users: {
posts: s.users.$many.posts({ from: "_id", to: "authorId" }),
posts: r.many.posts({ from: r.users._id, to: r.posts.authorId }),
},
posts: {
author: s.posts.$one.users({ from: "authorId", to: "_id" }),
author: r.one.users({ from: r.posts.authorId, to: r.users._id }),
},
}));

Expand Down
10 changes: 5 additions & 5 deletions docs/guide/aggregation-and-relations.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Monarch ORM provides powerful ways to connect collections through relations and

## Relations

You can establish relations between collections after defining your schemas. Use the `defineSchemas` higher-order function to bundle schemas and the `.withRelations` method to establish `$one` and `$many` connections between them.
You can establish relations between collections after defining your schemas. Use the `defineSchemas` higher-order function to bundle schemas and the `.withRelations` method to establish `one` and `many` connections between them.

### Defining Relations

Expand All @@ -29,13 +29,13 @@ const schemas = defineSchemas({
});

// Configure the relationships
const relations = schemas.withRelations((s) => ({
const relations = schemas.withRelations((r) => ({
users: {
tutor: s.users.$one.users({ from: "tutorId", to: "_id" }),
posts: s.users.$many.posts({ from: "_id", to: "authorId" }),
tutor: r.one.users({ from: r.users.tutorId, to: r.users._id }),
posts: r.many.posts({ from: r.users._id, to: r.posts.authorId }),
},
posts: {
author: s.posts.$one.users({ from: "authorId", to: "_id" }),
author: r.one.users({ from: r.posts.authorId, to: r.users._id }),
},
}));

Expand Down
32 changes: 13 additions & 19 deletions docs/guide/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ pnpm add monarch-orm
## Basic Usage

```typescript
import { boolean, createClient, createDatabase, createSchema, number, string } from "monarch-orm";
import { createClient, createDatabase, createSchema, defineSchemas } from "monarch-orm";
import { boolean, number, string } from "monarch-orm/types";

const UserSchema = createSchema("users", {
name: string().nullable(),
Expand Down Expand Up @@ -125,28 +126,20 @@ Update documents in your collection using the `updateOne` or `updateMany` method
Example: Updating a single user's email

```typescript
const updatedUser = await collections.users
.updateOne()
.set({
email: "alice.updated@example.com",
})
.where({
name: "Alice",
});
const updatedUser = await collections.users.updateOne(
{ name: "Alice" },
{ $set: { email: "alice.updated@example.com" } }
);
console.log(updatedUser);
```

Example: Updating multiple users' `isVerified` field

```typescript
const updatedUsers = await collections.users
.updateMany()
.set({
isVerified: true,
})
.where({
isVerified: false,
});
const updatedUsers = await collections.users.updateMany(
{ isVerified: false },
{ $set: { isVerified: true } }
);
console.log(updatedUsers);
```

Expand All @@ -157,14 +150,15 @@ Note: The update method returns the number of documents updated.
You can also decentralize the models:

```typescript
const { db } = createDatabase(client.db());
import { createDatabase, defineSchemas } from "monarch-orm";

const UserSchema = createSchema("users", {
name: string(),
isVerified: boolean(),
});

const UserModel = db(UserSchema);
const monarchDb = createDatabase(client.db(), defineSchemas({ users: UserSchema }));
const UserModel = monarchDb.use(UserSchema);
export default UserModel;
```

Expand Down
122 changes: 122 additions & 0 deletions docs/guide/queries-and-operators.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# Queries & Operators

Monarch ORM provides a powerful, type-safe API for querying your MongoDB collections. By using the query builders and exported operators, you can construct complex filters without losing type safety.

## Query Modifiers

When you use `.find()` or `.findOne()`, Monarch returns a lazy query builder. The query is not executed until you `await` it. This allows you to chain modifiers to shape your results.

### Selecting & Omitting Fields

You can control exactly which fields are returned from the database using `.select()` and `.omit()`.

```typescript
// Only return the name and email fields
const users = await db.collections.users
.find()
.select({ name: true, email: true });

// Return everything EXCEPT the age and password fields
const publicUsers = await db.collections.users
.find()
.omit({ age: true, password: true });
```

### Sorting, Limiting, and Skipping

Use these modifiers to paginate and order your results.

```typescript
const latestUsers = await db.collections.users
.find({ isVerified: true })
.sort({ createdAt: -1 }) // Sort descending by createdAt
.limit(10) // Return max 10 documents
.skip(20); // Skip the first 20 documents
```

### Cursors

For large datasets where you don't want to load everything into memory at once, you can use `.cursor()` to iterate over documents one by one.

```typescript
const cursor = await db.collections.users.find({ isVerified: true }).cursor();

for await (const user of cursor) {
console.log(user.name);
}
```

## Operators

Monarch provides typed wrapper functions for standard MongoDB query operators. These functions enforce type safety and ensure your queries align with your schema.

You can import them from `monarch-orm/operators`.

```typescript
import { eq, gt, or, inArray } from "monarch-orm/operators";
```

### Comparison Operators

- **`eq(value)`**: Matches values equal to the specified value.
- **`neq(value)`**: Matches values not equal to the specified value.
- **`gt(value)`**: Matches values greater than the specified value.
- **`lt(value)`**: Matches values less than the specified value.
- **`gte(value)`**: Matches values greater than or equal to the specified value.
- **`lte(value)`**: Matches values less than or equal to the specified value.

```typescript
const adults = await db.collections.users.find({
age: gte(18)
});
```

### Logical Operators

- **`and(...expressions)`**: Matches documents that satisfy all expressions.
- **`or(...expressions)`**: Matches documents that satisfy at least one expression.
- **`nor(...expressions)`**: Matches documents that fail all expressions.
- **`not(expression)`**: Inverts the effect of a filter expression.

```typescript
const specificUsers = await db.collections.users.find(
or(
{ age: lt(18) },
{ isVerified: false }
)
);
```

### Array Operators

- **`inArray(values)`**: Matches values that exist in the specified array.
- **`notInArray(values)`**: Matches values that do not exist in the specified array.
- **`size(value)`**: Matches arrays with the specified number of elements.

```typescript
const targetedUsers = await db.collections.users.find({
role: inArray(["admin", "moderator"])
});
```

### Element Operators

- **`exists()`**: Matches documents where the field exists.
- **`notExists()`**: Matches documents where the field does not exist.

```typescript
const usersWithPhone = await db.collections.users.find({
phoneNumber: exists()
});
```

## Native MongoDB Syntax

Because Monarch wraps the underlying MongoDB Node.js driver, you are still free to use native MongoDB query syntax if you prefer. The fields and operators are fully typed based on your schema.

```typescript
const activeUsers = await db.collections.users.find({
age: { $gte: 18 },
role: { $in: ["admin", "moderator"] }
});
```
26 changes: 0 additions & 26 deletions docs/guide/schemas-and-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,6 @@ Monarch provides a rich set of schema builders to strictly enforce your MongoDB

## Primitives

### Shape `createShape()`

Use `createShape()` when you want to define a reusable shape for schemas or objects.

```typescript
const addressShape = createShape({
street: string(),
city: string(),
});

const userSchema = createSchema("users", {
name: string(),
address: object(addressShape),
});
```

### String `string()`

Defines a field that accepts string values.
Expand Down Expand Up @@ -70,16 +54,6 @@ const UserSchema = createSchema("users", {
});
```

### Date String `dateString()`

Defines a field that accepts date strings in ISO format.

```typescript
const UserSchema = createSchema("users", {
registrationDate: dateString(),
});
```

### UUID `uuid()`

Defines a field that accepts MongoDB `UUID` values or valid UUID strings.
Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ layout: home

hero:
name: "Monarch ORM"
text: "Type safe Object Document Mapper (ODM) for MongoDB"
text: "Type-safe ODM for MongoDB"
tagline: "Designed to provide a seamless and efficient way to interact with your MongoDB database in a type-safe manner."
actions:
- theme: brand
Expand Down
12 changes: 12 additions & 0 deletions docs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "monarch-docs",
"private": true,
"scripts": {
"dev": "vitepress dev .",
"build": "vitepress build .",
"preview": "vitepress preview ."
},
"devDependencies": {
"vitepress": "^1.6.4"
}
}
Loading
Loading