@void-snippets/nestjs

TypeORM

forTypeOrmResource() and the VSBaseEntity family — register a TypeORM-backed resource.

#forTypeOrmResource — register a TypeORM resource

The one-liner that builds the repository, service, and controller for a TypeORM-backed resource and wires them into your module:

typescript
// contacts.module.ts
import { Module } from '@nestjs/common';
import { forTypeOrmResource } from '@void-snippets/nestjs/typeorm';
import { Contact } from './contact.entity';

@Module({
  imports: [
    forTypeOrmResource(Contact, {
      softDelete: 'deletedAt', // any defineResource option goes here
    }),
  ],
})
export class ContactsModule {}

That's the whole module — no ContactsController, ContactsService, or ContactsRepository classes. The REST base path (/contacts) is derived by pluralizing the entity's class name, and the id field defaults to "id".

#Base entity classes

Most TypeORM entities want the same starting point: a primary key and maintained createdAt/updatedAt columns. These abstract base classes give you that in one line:

typescript
// contact.entity.ts
import { Column, Entity } from 'typeorm';
import { VSBaseEntity } from '@void-snippets/nestjs/typeorm';

@Entity('contacts')
export class Contact extends VSBaseEntity {
  // id, createdAt, updatedAt already provided by VSBaseEntity
  @Column() name!: string;
  @Column() email!: string;
  @Column({ type: 'datetime', nullable: true }) deletedAt!: Date | null;
}
Base classGives you
VSBaseEntityAuto-increment integer id, createdAt, updatedAt
VSBaseUuidEntityUUID id instead of auto-increment, createdAt, updatedAt
VSBaseVersionedEntityEverything VSBaseEntity has, plus a version column ready for optimisticLock: 'version'

#Soft delete on TypeORM — add the column yourself

Unlike Mongoose (where createBaseSchema can add the field for you), TypeORM's soft-delete column type is different per database — timestamptz on Postgres, datetime on MySQL/SQLite. Add it directly on your entity with whatever type your database uses:

typescript
@Column({ type: 'timestamptz', nullable: true })  // Postgres
// @Column({ type: 'datetime', nullable: true })  // MySQL / SQLite
deletedAt!: Date | null;

Deliberately don't use TypeORM's own @DeleteDateColumn() decorator here — that opts into TypeORM's built-in soft-delete behavior, which conflicts with how this package's softDelete/includeDeleted options work.

#Registering an existing definition

If you build the defineResource() config separately (for example, because a hand-written controller subclass also needs to reference it — see Adding Custom Logic), pass the definition as the first argument instead of the inline config:

typescript
import { defineResource } from '@void-snippets/nestjs';
import { forTypeOrmResource } from '@void-snippets/nestjs/typeorm';
import { Contact } from './contact.entity';

export const contactsResource = defineResource({ entity: Contact, name: 'contacts', id: 'id' });

// elsewhere:
forTypeOrmResource(contactsResource, Contact);