Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/svtslv/nestjs-objection
Objection module for NestJS
https://github.com/svtslv/nestjs-objection
database knex knexjs nest nestjs objection objectionjs orm
Last synced: 8 days ago
JSON representation
Objection module for NestJS
- Host: GitHub
- URL: https://github.com/svtslv/nestjs-objection
- Owner: svtslv
- License: mit
- Created: 2020-02-25T23:54:17.000Z (almost 5 years ago)
- Default Branch: master
- Last Pushed: 2024-06-18T07:54:38.000Z (6 months ago)
- Last Synced: 2024-12-12T03:04:19.468Z (16 days ago)
- Topics: database, knex, knexjs, nest, nestjs, objection, objectionjs, orm
- Language: TypeScript
- Homepage:
- Size: 1.48 MB
- Stars: 24
- Watchers: 4
- Forks: 4
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# NestJS Objection
## Table of Contents
- [Description](#description)
- [Installation](#installation)
- [Features](#features)
- [Examples](#examples)
- [Typescript](#typescript)
- [License](#license)## Description
Integrates Objection.js and Knex with Nest
## Installation
```bash
$ npm install nestjs-objection knex objection
```You can also use the interactive CLI
```sh
npx nestjs-modules
```## Features
- Decorators ```@InjectModel, @Table, @Column, @Relation ```
- Synchronization ```synchronize(model, force?)```
- SoftDelete ```@Table({ softDelete: true })```#### Table options
| Name | Type | Required | Default |
| ------------ | ------------------ | -------- | ----------------- |
| `tableName` | `string` | `true` | `className` |
| `softDelete` | `boolean / string` | `false` | `false` |#### Column options
| Name | Type | Required | Default |
| --------------- | --------------- | -------- | ----------------- |
| `type` | `columnTypes` | `true` | `---` |
| `default` | `any` | `false` | `---` |
| `columnName` | `string` | `false` | `false` |
| `nullable` | `boolean` | `false` | `false` |
| `notNullable` | `boolean` | `false` | `false` |
| `unique` | `boolean` | `false` | `false` |
| `unsigned` | `boolean` | `false` | `false` |
| `primary` | `boolean` | `false` | `false` |#### synchronize(model, force?)
| Name | Type | Required | Default |
| --------------- | --------------- | -------- | ----------------- |
| `model` | `Model` | `true` | `---` |
| `force` | `boolean` | `false` | `false` |#### softDelete
| Method | Type | Options | Return |
| --------------- | --------------- | -------------- | ----------------- |
| `delete` | `function` | `---` | `QueryBuilder` |
| `softDelete` | `function` | `---` | `QueryBuilder` |
| `forceDelete` | `function` | `---` | `QueryBuilder` |
| `withDeleted` | `function` | `---` | `QueryBuilder` |
| `onlyDeleted` | `function` | `---` | `QueryBuilder` |
| `restore` | `function` | `---` | `QueryBuilder` |#### columnTypes
| --- | --- | --- | --- |
| --------------- | --------------- | -------------- | ----------------- |
| `increments` | `bigIncrements` | `integer` | `bigInteger` |
| `text` | `string` | `float` | `decimal` |
| `boolean` | `date` | `datetime` | `time` |
| `timestamp` | `timestamps` | `binary` | `json` |
| `jsonb` | `uuid` | | |## Examples
```bash
$ npm install nestjs-objection knex objection sqlite3
```#### Models
```ts
// app.models.ts
import {
Model, Column, Relation, Table, relationTypes, columnTypes,
} from 'nestjs-objection';@Table({ tableName: 'posts' })
export class Post extends Model {
@Column({ type: columnTypes.increments })
id: number;
@Column({ type: columnTypes.integer })
userId: number;
@Column({ type: columnTypes.string })
title: string;
@Column({ type: columnTypes.json })
json: object;
}@Table({ tableName: 'users' })
export class User extends Model {
@Column({ type: columnTypes.increments })
id: number;
@Column({ type: columnTypes.string })
name: string;
@Relation({
modelClass: Post,
relation: relationTypes.HasManyRelation,
join: { from: 'users.id', to: 'posts.userId' }
})
posts: Post[];
}
```#### ObjectionModule.forRoot(options, connection?)
```ts
// app.module.ts
import { Module } from '@nestjs/common';
import { ObjectionModule, Model } from 'nestjs-objection'
import { AppController } from './app.controller';
import { User, Post } from './app.models';@Module({
imports: [
ObjectionModule.forRoot({
Model,
config: {
client: "sqlite3",
useNullAsDefault: true,
connection: ':memory:',
}
}),
ObjectionModule.forFeature([User, Post]),
],
controllers: [AppController],
})
export class AppModule {}
```#### ObjectionModule.forRootAsync(options, connection?)
```ts
// app.module.ts
import { Module } from '@nestjs/common';
import { ObjectionModule, Model } from 'nestjs-objection'
import { AppController } from './app.controller';
import { User, Post } from './app.models';@Module({
imports: [
ObjectionModule.forRootAsync({
useFactory: () => ({
Model,
config: {
client: "sqlite3",
useNullAsDefault: true,
connection: ':memory:',
},
}),
}),
ObjectionModule.forFeature([User, Post]),
],
controllers: [AppController],
})
export class AppModule {}
```#### InjectModel(Model, connection?)
```ts
// app.controller.ts
import { Controller, Get } from '@nestjs/common';
import {
InjectModel,
synchronize,
InjectConnection,
Connection,
} from 'nestjs-objection';
import { User, Post } from './app.models';@Controller()
export class AppController {
constructor(
@InjectModel(User) private readonly userModel: typeof User,
@InjectModel(Post) private readonly postModel: typeof Post,
@InjectConnection() private readonly connection: Connection,
) {}@Get()
async getHello() {
await synchronize(User);
await synchronize(Post);
await this.userModel.query().insert({ name: 'Name' });
await this.postModel.query().insert({ title: 'Title', userId: 1 });const users = await this.userModel
.query()
.select(['users.name'])
.withGraphJoined('posts')
.modifyGraph('posts', q => q.select(['posts.title']));const posts = await this.connection.table('posts');
return { users, posts };
}
}
```#### SoftDeleteModel
```ts
import { SoftDeleteModel, columnTypes } from 'nestjs-objection';@Table({ tableName: 'users', softDelete: true })
export class User extends SoftDeleteModel {
@Column({ type: columnTypes.increments })
id: number;
@Column({ type: columnTypes.datetime })
deletedAt: Date;
}
``````ts
ObjectionModule.forRoot({
Model: SoftDeleteModel,
config: { /* ... */ }
})
``````ts
this.userModel.query().where({ id: 1 }).delete(); // or softDelete()
this.userModel.query().where({ id: 1 }).withDeleted();
this.userModel.query().where({ id: 1 }).onlyDeleted();
this.userModel.query().where({ id: 1 }).forceDelete();
this.userModel.query().where({ id: 1 }).restore();
```## Typescript
```ts
// src/index.d.ts
declare module 'objection' {
interface WhereMethod {
(columns: Partial): QB;
(column: Partial, op: string, value: any): QB;
}
interface OrderByMethod {
(column: keyof T, order?: 'asc' | 'desc'): QB;
(columns: (Array<{ column: keyof T; order?: 'asc' | 'desc' }>)): QB;
}
interface SelectMethod {
(...columnNames: Array>): QB;
(columnNames: Array>): QB;
}
interface QueryBuilder extends Promise {
forceDelete(): this;
withDeleted(): this;
onlyDeleted(): this;
softDelete(): this;
restore(): this;
}
}
``````ts
// with type-safe
const users = await this.userModel
.query()
.select(['name'])
.where({ name: 'Name' })
.orderBy('name', 'desc')
.withGraphFetched('posts')
.modifyGraph('posts', q => q.select(['title']));// without type-safe
const users = await this.userModel
.query()
.select(['name'])
.where({ name: 'Name' })
.orderBy('name', 'desc')
.withGraphFetched('posts')
.modifyGraph('posts', q => q.select(['title']));
```## License
MIT