{"id":19237967,"url":"https://github.com/svtslv/nestjs-objection","last_synced_at":"2026-03-09T13:46:48.705Z","repository":{"id":42831432,"uuid":"243128156","full_name":"svtslv/nestjs-objection","owner":"svtslv","description":"Objection module for NestJS","archived":false,"fork":false,"pushed_at":"2024-06-18T07:54:38.000Z","size":1555,"stargazers_count":24,"open_issues_count":4,"forks_count":4,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-12-12T03:04:19.468Z","etag":null,"topics":["database","knex","knexjs","nest","nestjs","objection","objectionjs","orm"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/svtslv.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-02-25T23:54:17.000Z","updated_at":"2024-09-01T21:30:55.000Z","dependencies_parsed_at":"2023-02-09T03:16:31.635Z","dependency_job_id":"250ad339-ecaa-4b5f-896f-86921edba55a","html_url":"https://github.com/svtslv/nestjs-objection","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/svtslv%2Fnestjs-objection","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/svtslv%2Fnestjs-objection/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/svtslv%2Fnestjs-objection/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/svtslv%2Fnestjs-objection/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/svtslv","download_url":"https://codeload.github.com/svtslv/nestjs-objection/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230532443,"owners_count":18240792,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["database","knex","knexjs","nest","nestjs","objection","objectionjs","orm"],"created_at":"2024-11-09T16:28:52.184Z","updated_at":"2026-03-09T13:46:48.655Z","avatar_url":"https://github.com/svtslv.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NestJS Objection\n\n\u003ca href=\"https://www.npmjs.com/package/nestjs-objection\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/nestjs-objection.svg\" alt=\"NPM Version\" /\u003e\u003c/a\u003e\n\u003ca href=\"https://www.npmjs.com/package/nestjs-objection\"\u003e\u003cimg src=\"https://img.shields.io/npm/dm/nestjs-objection.svg\" alt=\"NPM Downloads\" /\u003e\u003c/a\u003e\n\u003ca href=\"https://www.npmjs.com/package/nestjs-objection\"\u003e\u003cimg src=\"https://img.shields.io/npm/l/nestjs-objection.svg\" alt=\"Package License\" /\u003e\u003c/a\u003e\n\n## Table of Contents\n\n- [Description](#description)\n- [Installation](#installation)\n- [Features](#features)\n- [Examples](#examples)\n- [Typescript](#typescript)\n- [License](#license)\n\n## Description\n\nIntegrates Objection.js and Knex with Nest\n\n## Installation\n\n```bash\n$ npm install nestjs-objection knex objection\n```\n\nYou can also use the interactive CLI\n\n```sh\nnpx nestjs-modules\n```\n\n## Features\n\n- Decorators      ```@InjectModel, @Table, @Column, @Relation ```\n- Synchronization ```synchronize(model, force?)```\n- SoftDelete      ```@Table({ softDelete: true })```\n\n#### Table options\n\n| Name         | Type               | Required | Default           |\n| ------------ | ------------------ | -------- | ----------------- |\n| `tableName`  | `string`           | `true`   | `className`       |\n| `softDelete` | `boolean / string` | `false`  | `false`           |\n\n#### Column options\n\n| Name            | Type            | Required | Default           |\n| --------------- | --------------- | -------- | ----------------- |\n| `type`          | `columnTypes`   | `true`   | `---`             |\n| `default`       | `any`           | `false`  | `---`             |\n| `columnName`    | `string`        | `false`  | `false`           |\n| `nullable`      | `boolean`       | `false`  | `false`           |\n| `notNullable`   | `boolean`       | `false`  | `false`           |\n| `unique`        | `boolean`       | `false`  | `false`           |\n| `unsigned`      | `boolean`       | `false`  | `false`           |\n| `primary`       | `boolean`       | `false`  | `false`           |\n\n#### synchronize(model, force?)\n\n| Name            | Type            | Required | Default           |\n| --------------- | --------------- | -------- | ----------------- |\n| `model`         | `Model`         | `true`   | `---`             |\n| `force`         | `boolean`       | `false`  | `false`           |\n\n#### softDelete\n\n| Method           | Type           | Options        | Return            |\n| --------------- | --------------- | -------------- | ----------------- |\n| `delete`        | `function`      | `---`          | `QueryBuilder`    |\n| `softDelete`    | `function`      | `---`          | `QueryBuilder`    |\n| `forceDelete`   | `function`      | `---`          | `QueryBuilder`    |\n| `withDeleted`   | `function`      | `---`          | `QueryBuilder`    |\n| `onlyDeleted`   | `function`      | `---`          | `QueryBuilder`    |\n| `restore`       | `function`      | `---`          | `QueryBuilder`    |\n\n#### columnTypes\n\n| ---             | ---             | ---            | ---               |\n| --------------- | --------------- | -------------- | ----------------- |\n| `increments`    | `bigIncrements` | `integer`      | `bigInteger`      |\n| `text`          | `string`        | `float`        | `decimal`         |\n| `boolean`       | `date`          | `datetime`     | `time`            |\n| `timestamp`     | `timestamps`    | `binary`       | `json`            |\n| `jsonb`         | `uuid`          |                |                   |\n\n## Examples\n\n```bash\n$ npm install nestjs-objection knex objection sqlite3\n```\n\n#### Models\n\n```ts\n// app.models.ts\nimport { \n  Model, Column, Relation, Table, relationTypes, columnTypes, \n} from 'nestjs-objection';\n\n@Table({ tableName: 'posts' })\nexport class Post extends Model {\n  @Column({ type: columnTypes.increments })\n  id: number;\n  @Column({ type: columnTypes.integer })\n  userId: number;\n  @Column({ type: columnTypes.string })\n  title: string;\n  @Column({ type: columnTypes.json })\n  json: object;\n}\n\n@Table({ tableName: 'users' })\nexport class User extends Model {\n  @Column({ type: columnTypes.increments })\n  id: number;\n  @Column({ type: columnTypes.string })\n  name: string;\n  @Relation({ \n    modelClass: Post, \n    relation: relationTypes.HasManyRelation, \n    join: { from: 'users.id', to: 'posts.userId' } \n  })\n  posts: Post[];\n}\n```\n\n#### ObjectionModule.forRoot(options, connection?)\n\n```ts\n// app.module.ts\nimport { Module } from '@nestjs/common';\nimport { ObjectionModule, Model } from 'nestjs-objection'\nimport { AppController } from './app.controller';\nimport { User, Post } from './app.models';\n\n@Module({\n  imports: [\n    ObjectionModule.forRoot({\n      Model,\n      config: {\n        client: \"sqlite3\",\n        useNullAsDefault: true,\n        connection: ':memory:',\n      }\n    }),\n    ObjectionModule.forFeature([User, Post]),\n  ],\n  controllers: [AppController],\n})\nexport class AppModule {}\n```\n\n#### ObjectionModule.forRootAsync(options, connection?)\n\n```ts\n// app.module.ts\nimport { Module } from '@nestjs/common';\nimport { ObjectionModule, Model } from 'nestjs-objection'\nimport { AppController } from './app.controller';\nimport { User, Post } from './app.models';\n\n@Module({\n  imports: [\n    ObjectionModule.forRootAsync({\n      useFactory: () =\u003e ({\n        Model,\n        config: {\n          client: \"sqlite3\",\n          useNullAsDefault: true,\n          connection: ':memory:',\n        },\n      }),\n    }),\n    ObjectionModule.forFeature([User, Post]),\n  ],\n  controllers: [AppController],\n})\nexport class AppModule {}\n```\n\n#### InjectModel(Model, connection?)\n\n```ts\n// app.controller.ts\nimport { Controller, Get } from '@nestjs/common';\nimport { \n  InjectModel, \n  synchronize, \n  InjectConnection, \n  Connection, \n} from 'nestjs-objection';\nimport { User, Post } from './app.models';\n\n@Controller()\nexport class AppController {\n  constructor(\n    @InjectModel(User) private readonly userModel: typeof User,\n    @InjectModel(Post) private readonly postModel: typeof Post,\n    @InjectConnection() private readonly connection: Connection,\n  ) {}\n\n  @Get()\n  async getHello() {\n    await synchronize(User);\n    await synchronize(Post);\n    await this.userModel.query().insert({ name: 'Name' });\n    await this.postModel.query().insert({ title: 'Title', userId: 1 });\n\n    const users = await this.userModel\n      .query()\n      .select(['users.name'])\n      .withGraphJoined('posts')\n      .modifyGraph('posts', q =\u003e q.select(['posts.title']));\n\n    const posts = await this.connection.table('posts');\n\n    return { users, posts };\n  }\n}\n```\n\n#### SoftDeleteModel\n\n```ts\nimport { SoftDeleteModel, columnTypes } from 'nestjs-objection';\n\n@Table({ tableName: 'users', softDelete: true })\nexport class User extends SoftDeleteModel {\n  @Column({ type: columnTypes.increments })\n  id: number;\n  @Column({ type: columnTypes.datetime })\n  deletedAt: Date;\n}\n```\n\n```ts\nObjectionModule.forRoot({\n  Model: SoftDeleteModel,\n  config: { /* ... */ }\n})\n```\n\n```ts\nthis.userModel.query().where({ id: 1 }).delete(); // or softDelete()\nthis.userModel.query().where({ id: 1 }).withDeleted();\nthis.userModel.query().where({ id: 1 }).onlyDeleted();\nthis.userModel.query().where({ id: 1 }).forceDelete();\nthis.userModel.query().where({ id: 1 }).restore();\n```\n\n## Typescript\n\n```ts\n// src/index.d.ts\ndeclare module 'objection' {\n  interface WhereMethod\u003cQB extends AnyQueryBuilder\u003e {\n    \u003cT\u003e(columns: Partial\u003cT\u003e): QB;\n    \u003cT\u003e(column: Partial\u003ckeyof T\u003e, op: string, value: any): QB;\n  }\n  interface OrderByMethod\u003cQB extends AnyQueryBuilder\u003e {\n    \u003cT\u003e(column: keyof T, order?: 'asc' | 'desc'): QB;\n    \u003cT\u003e(columns: (Array\u003c{ column: keyof T; order?: 'asc' | 'desc' }\u003e)): QB;\n  }\n  interface SelectMethod\u003cQB extends AnyQueryBuilder\u003e {\n    \u003cT\u003e(...columnNames: Array\u003cPartial\u003ckeyof T\u003e\u003e): QB;\n    \u003cT\u003e(columnNames: Array\u003cPartial\u003ckeyof T\u003e\u003e): QB;\n  }\n  interface QueryBuilder\u003cM extends Model, R = M[]\u003e extends Promise\u003cR\u003e {\n    forceDelete(): this;\n    withDeleted(): this;\n    onlyDeleted(): this;\n    softDelete(): this;\n    restore(): this;\n  }\n}\n```\n\n```ts\n// with type-safe\nconst users = await this.userModel\n  .query()\n  .select\u003cUser\u003e(['name'])\n  .where\u003cUser\u003e({ name: 'Name' })\n  .orderBy\u003cUser\u003e('name', 'desc')\n  .withGraphFetched('posts')\n  .modifyGraph('posts', q =\u003e q.select\u003cPost\u003e(['title']));\n\n// without type-safe\nconst users = await this.userModel\n  .query()\n  .select(['name'])\n  .where({ name: 'Name' })\n  .orderBy('name', 'desc')\n  .withGraphFetched('posts')\n  .modifyGraph('posts', q =\u003e q.select(['title']));\n```\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsvtslv%2Fnestjs-objection","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsvtslv%2Fnestjs-objection","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsvtslv%2Fnestjs-objection/lists"}