npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@studiosonrai/nestjs-audit-log

v1.1.3

Published

Audit logging module for NestJS + TypeORM: automatic CREATE/UPDATE capture via @Auditable entities, explicit DELETE, and queryable audit history

Readme

@studiosonrai/nestjs-audit-log

Audit logging for NestJS + TypeORM. Mark an entity @Auditable() and CREATE / UPDATE / DELETE are recorded automatically by a TypeORM subscriber — no per-service code — for repository.save(), repository.remove(), and repository.softRemove(). For legacy repository.delete(id) paths there's a single-line AuditService.logEntity() escape hatch. The acting user is captured from the request via CLS, so you never thread userId through your services. The auditLog table is created at startup and read/written via raw SQL through your existing DataSource, so no migration is required and you do not need to add AuditLog to your entities array (Microsoft SQL Server).

Installation

npm install @studiosonrai/nestjs-audit-log
# peers (already present in most NestJS apps):
npm install @nestjs/typeorm @nestjs/swagger typeorm class-validator class-transformer

Setup

import { AuditModule } from '@studiosonrai/nestjs-audit-log';
import { AuditLog } from '@studiosonrai/nestjs-audit-log';

@Module({
  imports: [
        AuditModule.forRootAsync({
        imports: [TypeOrmModule.forFeature([User])],          // for `resolveUser` if you want it
        inject: [LoggerFactory, getRepositoryToken(User)],
        useFactory: (
          loggerFactory: LoggerFactory,
          userRepo: Repository<User>,
        ) => ({
          // Required if you want any package logs — otherwise the package is silent.
          // Routes audit-log internal logs through your app's logger (winston,
          // App Insights, whatever) with one context per internal class.
          logger: (ctx) => loggerFactory.create(ctx),

          // Optional: turn `changedBy` (a user id) into a name/email on read.
          resolveUser: async (id) => {
            const user = await userRepo.findOneBy({ id });
            return user
              ? {
                  name: `${user.firstName} ${user.lastName ?? ''}`.trim(),
                  email: user.email,
                }
              : null;
          },
          // Optional: how to read the acting user id from the request.
          // Defaults to `request.user?.id`.
          getUserId: (req) => (req as RequestWithUser).user?.sub,
        }),
      }),
  ],
})
export class AppModule {}

Register the AuditLog entity with your DataSource (e.g. autoLoadEntities: true, or add AuditLog to your entities array / migrations) so the auditLog table exists.

The module mounts nestjs-cls middleware globally to carry the request user into the TypeORM subscriber. If your app already configures nestjs-cls, import AuditModule only once and avoid registering a second ClsModule.forRoot.

Automatic capture

import { Auditable } from '@studiosonrai/nestjs-audit-log';

@Auditable({
  entityType: 'Contact',                 // default: the class name (You can change to your preferred name)
  nameField: 'fullName',                 // property used as the human label
  exclude: ['createdBy', 'updatedBy'],   // omit from the diff (id/createdAt/updatedAt already excluded)
})
@Entity()
export class Contact { /* ... */ }
  • entityType? — logical type stored in the log (default: class name)
  • nameField? — property used as the human-readable name
  • exclude?: string[] — extra fields to omit from the diff (beyond id/createdAt/updatedAt)

CREATE and UPDATE are now logged automatically whenever the entity is inserted or saved (loaded-then-save()), inside the same transaction as the operation.

DELETE and manual logging

repository.delete(id) does not fire TypeORM remove subscribers, so record deletes explicitly:

await this.auditService.logEntity(contact, AuditActionType.DELETE);
await this.contactRepository.delete(id);

For full control use auditService.log({ entityType, entityId, action, changes, entityName }). changedBy is filled from CLS when omitted.

Querying

AuditService exposes findAll(filter) (paginated), findByEntity, findByUser, findByAction. Mount your own controller with your app's guards — the package ships no routes.