3.0.0 • Published 2 years ago
nestjs-objection v3.0.0
NestJS Objection
Table of Contents
Description
Integrates Objection.js and Knex with Nest
Installation
$ npm install nestjs-objection knex objection
You can also use the interactive CLI
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
$ npm install nestjs-objection knex objection sqlite3
Models
// 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?)
// 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?)
// 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?)
// 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
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;
}
ObjectionModule.forRoot({
Model: SoftDeleteModel,
config: { /* ... */ }
})
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
// src/index.d.ts
declare module 'objection' {
interface WhereMethod<QB extends AnyQueryBuilder> {
<T>(columns: Partial<T>): QB;
<T>(column: Partial<keyof T>, op: string, value: any): QB;
}
interface OrderByMethod<QB extends AnyQueryBuilder> {
<T>(column: keyof T, order?: 'asc' | 'desc'): QB;
<T>(columns: (Array<{ column: keyof T; order?: 'asc' | 'desc' }>)): QB;
}
interface SelectMethod<QB extends AnyQueryBuilder> {
<T>(...columnNames: Array<Partial<keyof T>>): QB;
<T>(columnNames: Array<Partial<keyof T>>): QB;
}
interface QueryBuilder<M extends Model, R = M[]> extends Promise<R> {
forceDelete(): this;
withDeleted(): this;
onlyDeleted(): this;
softDelete(): this;
restore(): this;
}
}
// with type-safe
const users = await this.userModel
.query()
.select<User>(['name'])
.where<User>({ name: 'Name' })
.orderBy<User>('name', 'desc')
.withGraphFetched('posts')
.modifyGraph('posts', q => q.select<Post>(['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
3.0.0-test.1
2 years ago
3.0.0-test.2
2 years ago
3.0.0
2 years ago
2.2.0
4 years ago
2.2.0-test.1
4 years ago
2.1.0
4 years ago
2.1.0-test.2
4 years ago
2.1.0-test.1
4 years ago
2.0.1
4 years ago
2.0.0-test.5
4 years ago
2.0.0-test.6
4 years ago
2.0.0-test.3
4 years ago
2.0.0-test.4
4 years ago
2.0.0-test.2
4 years ago
2.0.0-test.1
4 years ago
2.0.0
4 years ago
1.1.0
4 years ago
1.0.1
4 years ago
1.0.0
4 years ago
0.3.2
4 years ago
0.3.1
4 years ago
0.3.0
4 years ago
0.2.3
4 years ago
0.2.2
4 years ago
0.2.1
4 years ago
0.2.0
4 years ago
0.1.0
4 years ago
0.0.8
4 years ago
0.0.7
4 years ago
0.0.6
4 years ago
0.0.5
4 years ago
0.0.3
4 years ago
0.0.4
4 years ago
0.0.2
4 years ago
0.0.1
4 years ago