Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/bpisano/monkey
A strongly typed, verbose implementation of Mongoose in Typescript.
https://github.com/bpisano/monkey
mongoose strongly-typed typescript verbose
Last synced: 9 days ago
JSON representation
A strongly typed, verbose implementation of Mongoose in Typescript.
- Host: GitHub
- URL: https://github.com/bpisano/monkey
- Owner: bpisano
- License: mit
- Created: 2022-07-09T17:23:18.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2023-01-09T10:37:14.000Z (almost 2 years ago)
- Last Synced: 2023-03-10T10:17:30.861Z (almost 2 years ago)
- Topics: mongoose, strongly-typed, typescript, verbose
- Language: TypeScript
- Homepage:
- Size: 779 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Monkey 🐒 (beta)
A strongly typed, verbose implementation of Mongoose in Typescript.
- **Strongly typed**: prevents query mistakes at compile time.
- **Verbose**: use natural language to create queries.
- **Flexible**: create your own modifiers that fits your needs.
- **Fast**: use Mongoose as the engine.```ts
const db = new MongoDB()
await db.connect('mongodb://127.0.0.1/my_database')const users = await db.perform(
MongoDBQuery.withModel(userModel)
.modifier(FindMany.whereKeyEquals('emailVerified', true))
.modifier(Sort.ascendingBy('name'))
.modifier(Populate.properties(['friends']))
)
```## Table of contents
- [Installation](installation)
- [Documentation](documentation)
- [Query modifiers](query-modifiers)
- [Performing a request](performing-a-request)
- [Creating query modifiers](creating-query-modifiers)
- [Mocking data](mocking-data)
- [Contribution](contribution)
- [Roadmap](roadmap)## Installation
This package is distributed with npm.
```bash
# npm
npm install monkey-db# yarn
yarn add monkey-db
```## Documentation
### Query modifiers
See all query modifiers in the [package documentation](./docs/README.md).
### Performing a request
To perform a request, you'll need to instantiate a `MongoDB` instance and connect it to your MongoDB database.
```ts
const db = new MongoDB()
await db.connect('mongodb://127.0.0.1/my_database')
```Then, use the `MongoDBQuery` with the model corresponding to the collection you want to query.
```ts
// Returns all the users
const users = await db.perform(
MongoDBQuery.withModel(userModel)
.modifier(FindMany.all())
)
```Use query modifiers to add parameters to your query using the `.modifier()` function. You can chain them, as many as you need, but note that query modifiers are order sensitive. That means you cannot start your query with a `Sort` modifier. For more infos, see [Creating query modifiers](#creating-query-modifiers).
```ts
// Returns all the users sorted by names
const users = await db.perform(
MongoDBQuery.withModel(userModel)
.modifier(FindMany.all())
.modifier(Sort.ascendingBy('name'))
)
```### Creating query modifiers
Monkey comes with a bunch of query modifiers, but you can easily create your to better fits your needs.
Query modifiers takes an input, and returns a new output. As an output, you usually want to return either a `DBQuery` or a `DBOperation` depending of your needs.
- `DBQuery` contains a `mongooseQuery` property that represents a MongoDB query such as **finding**, **sorting** or **filtering**.
- `DBOperation` contains a `mongooseOperation` property that represents a MongoDB operation such as **creating**, **updating** or **deleting**.Both of these types implements the `Performable` interface so you can always retrieve the mongoose query you are working with.
```ts
export interface Performable {
databaseQuery: MongooseQuery | MongooseOperation
}
```---
#### Creating a query
Say you want to create a query that finds all your users with a `emailVerified` property set to true. You query modifier will take as input your mongoose model, and will output a `DBQuery`.
Declare the `class` as the following:
```ts
export class FindVerifiedUsers implement QueryModifier, DBQuery> {}
```> `T` is the generic type that represents your mongoose model.
Then implements the `modifier()` method.
```ts
export class FindVerifiedUsers implement QueryModifier, DBQuery> {
public modifier(input: Model): DBOperation {
const query: MongooseQuery = input.find({ emailVerified: true })
return new DBQuery(query)
}
}
```You can then use your query this way:
```ts
// Returns all the users with verified email
const verifiedUsers = await db.perform(
MongoDBQuery.withModel(userModel)
.modifier(new FindVerifiedUsers())
)
```---
#### Creating an operation
Say you want to create an operation that create a new user and set its property `emailVerified` to true. You query modifier will take as input your mongoose model, and will output a `DBQuery`.
Declare the `class` as the following:
```ts
export class CreateVerifiedUser implement QueryModifier, DBOperation> {
public constructor(data: any) {}
}
```> `T` is the generic type that represents your mongoose model.
Then implements the `modifier()` method.
```ts
export class CreateVerifiedUser implement QueryModifier, DBOperation> {
public constructor(private readonly data: any) {}public modifier(input: Model): DBOperation {
const operation: MongooseOperation = input.create({ ...this.data, emailVerified: true })
return new DBOperation(operation)
}
}
```You can then use your operation this way:
```ts
// Returns the created user with a `emailVerified` property set to true
const users = await db.perform(
MongoDBQuery.withModel(userModel)
.modifier(new CreateVerifiedUser({ username: 'bpisano' }))
)
```## Contribution
Work is still in progress and contributions to Monkey are open and highly appreciated. When creating new query modifiers, make sure that:
- It it verbose. Make use of natural language as much as possible. This makes this package easy to get started with.
- It is generic enough. Try not to implement very specific use case in this package. Remember, anyone can easily create their own query modifier that fits their needs.## Roadmap
- [ ] Implementing all the the operations and queries used by mongoose as query modifiers.
- [ ] Improving verbosity of filters. It would be nice to have something like:
```ts
FindMany.where(Property.named('username').equals('bpisano'))
```