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:
// 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:
// 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 class | Gives you |
|---|---|
VSBaseEntity | Auto-increment integer id, createdAt, updatedAt |
VSBaseUuidEntity | UUID id instead of auto-increment, createdAt, updatedAt |
VSBaseVersionedEntity | Everything 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:
@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:
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);