nnestjs-drizzle-crud
Configuration

forFeature

Bind a service to its table, and override per-entity configuration.

DrizzleCrudModule.forFeature(entities) is called inside each feature module. It binds one or more services to their tables and constructs them with the correct merged configuration.

Signature

DrizzleCrudModule.forFeature(entities: CrudFeature[]): DynamicModule

Where CrudFeature is:

interface CrudFeature {
  service: typeof SqlBaseCrudService;
  table: any;                 // Drizzle table
  config?: Partial<SqlCrudConfig>;  // per-entity overrides
}

Basic usage

users/users.module.ts
import { Module } from '@nestjs/common';
import { DrizzleCrudModule } from 'nestjs-drizzle-crud';
import { users } from '../db/schema';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';

@Module({
  imports: [
    DrizzleCrudModule.forFeature([
      { service: UsersService, table: users },
    ]),
  ],
  controllers: [UsersController],
  providers: [UsersService],
})
export class UsersModule {}

The module registers UsersService as a provider, passing it a fully-built SqlCrudConfig derived from the global forRoot defaults + any per-entity overrides you supply here.

Per-entity overrides

Anything in config overrides the project defaults for that entity. The shape is SqlCrudConfig minus db and dialect (those are injected by forFeature).

posts/posts.module.ts
DrizzleCrudModule.forFeature([
  {
    service: PostsService,
    table: posts,
    config: {
      primaryKey: 'id',
      primaryKeyType: 'serial',
      softDelete: { enabled: true, column: 'deleted_at' },
      // Default ORDER BY for findAll() when the caller passes no sortBy.
      defaultSort: [
        { column: 'position', order: 'asc' },
        { column: 'created_at', order: 'desc' }, // tiebreaker
      ],
      relations: {
        author: { table: users, localKey: 'author_id', references: 'id' },
      },
    },
  },
])

What you can override

FieldEffect
primaryKeyColumn name for the primary key (default 'id').
primaryKeyType'serial' | 'bigserial' | 'int' | 'bigint' | 'uuid'. See Primary keys.
softDelete{ enabled: boolean; column: string }. Override the default deleted_at column name.
timestamps{ createdAt: string; updatedAt: string }. Override the default created_at / updated_at column names.
pagination{ defaultLimit: number; maxLimit: number }. Per-entity override of the global defaults.pagination.
defaultSortOrdered column list for findAll() when no sortBy is passed.
sqlPer-entity dialect tuning.
relationsMany-to-one relations, keyed by relation name. See Relations.

Multiple entities in one feature module

DrizzleCrudModule.forFeature([
  { service: UsersService, table: users },
  { service: PostsService, table: posts },
  { service: CommentsService, table: comments, config: { /* ... */ } },
])

Each service is registered as its own provider and is independently constructed.

@CrudService decorator

You can also attach per-entity config to the service class itself with the @CrudService decorator. The forFeature config field still wins when both are set — the merge order is global defaults → decorator metadata → forFeature config.

import { CrudService } from 'nestjs-drizzle-crud';

@CrudService({
  primaryKeyType: 'uuid',
  softDelete: { enabled: true, column: 'deleted_at' },
})
export class TagsService extends SqlBaseCrudService<Tag> {}

The decorator is mostly a convenience for keeping the config next to the service definition. Use forFeature config for config that's data-driven or varies per feature module.

Verifying the merged config

The fully-built config for each entity is available in the DRIZZLE_CRUD_CONFIG DI token. Inject it in tests to verify the merge worked:

import { Inject } from '@nestjs/common';
import { DRIZZLE_CRUD_CONFIG } from 'nestjs-drizzle-crud';

@Injectable()
export class ConfigInspector {
  constructor(@Inject(DRIZZLE_CRUD_CONFIG) public readonly cfg: any) {}
}

The injected DRIZZLE_CRUD_CONFIG is the normalized global config (the result of applying defaults). It does not include the per-entity overrides. To inspect a single entity's resolved config, use DRIZZLE_DB + read it off the constructed service instance.

Next

On this page