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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@onivoro/server-common

v24.33.4

Published

Common server utilities, DTOs, decorators, and foundational components for NestJS applications.

Readme

@onivoro/server-common

Common server utilities, DTOs, decorators, and foundational components for NestJS applications.

Installation

npm install @onivoro/server-common

Overview

This library provides a comprehensive set of utilities, decorators, DTOs, pipes, and functions commonly used in NestJS server applications. It includes error handling, API decorators, validation pipes, and various utility functions.

Module Setup

import { Module } from '@nestjs/common';
import { ServerCommonModule } from '@onivoro/server-common';

@Module({
  imports: [ServerCommonModule]
})
export class AppModule {}

Error Filters

ErrorFilter

Base error filter for handling exceptions:

import { ErrorFilter } from '@onivoro/server-common';

// Use globally
app.useGlobalFilters(new ErrorFilter());

// Or in a controller
@UseFilters(ErrorFilter)
@Controller('users')
export class UsersController {}

TypeormErrorFilter

Specialized filter for TypeORM database errors:

import { TypeormErrorFilter } from '@onivoro/server-common';

app.useGlobalFilters(new TypeormErrorFilter());

Decorators

API Documentation Decorators

import {
  ApiBodyUnspecified,
  ApiQueryPagedParams,
  ApiResponsePaged,
  ApiResponseUnspecified,
  ApiResponseUnspecifiedArray,
  DefaultApiController
} from '@onivoro/server-common';

@DefaultApiController('users')  // Combines @Controller and @ApiTags
export class UsersController {
  
  @Get()
  @ApiResponsePaged(UserDto)  // Documents paginated response
  @ApiQueryPagedParams()      // Documents pagination query params
  findAll(@QueryPagedParams() params: any) {
    // Implementation
  }

  @Post()
  @ApiBodyUnspecified()         // For dynamic body types
  @ApiResponseUnspecified()     // For dynamic response types
  create(@Body() data: any) {
    // Implementation
  }

  @Get('list')
  @ApiResponseUnspecifiedArray() // For dynamic array responses
  getList() {
    // Implementation
  }
}

Environment Configuration Decorator

import { EnvironmentClass } from '@onivoro/server-common';

@EnvironmentClass()
export class AppConfig {
  API_URL: string;
  DATABASE_URL: string;
  PORT?: number = 3000;  // With default
}

Query Parameter Decorators

import { QueryPagedParams } from '@onivoro/server-common';

@Get()
findAll(@QueryPagedParams() params: {
  page?: number;
  pageSize?: number;
  sortBy?: string;
  sortDirection?: 'asc' | 'desc';
}) {
  // Implementation
}

DTOs (Data Transfer Objects)

Common DTOs

import {
  AccountUserDto,
  BodyDto,
  EmailDto,
  HealthDto,
  PagedResponseDto,
  PutPasswordDto,
  SuccessDto,
  StringArrayDto,
  UrlDto,
  UserIdDto,
  ValueDto,
  ValuesDto,
  LookupDto
} from '@onivoro/server-common';

// Account user information
const user: AccountUserDto = {
  id: 'user-123',
  email: '[email protected]',
  name: 'John Doe'
};

// Paginated response
const response: PagedResponseDto<UserDto> = {
  data: users,
  total: 100,
  page: 1,
  pageSize: 10
};

// Simple value wrapper
const value: ValueDto<string> = {
  value: 'some-value'
};

// Multiple values
const values: ValuesDto<number> = {
  values: [1, 2, 3, 4, 5]
};

// Lookup/dropdown option
const option: LookupDto<string, number> = {
  display: 'Option One',
  value: 1
};

Validation Pipes

Date and Time Pipes

import {
  ParseDateOptionalPipe,
  ParseMonthPipe,
  ParseYearPipe
} from '@onivoro/server-common';

@Get('by-date')
findByDate(
  @Query('date', ParseDateOptionalPipe) date?: Date,
  @Query('month', ParseMonthPipe) month?: number,
  @Query('year', ParseYearPipe) year?: number
) {
  // Implementation
}

UUID Pipes

import {
  ParseUuidOptionalPipe,
  ParseUuidsPipe
} from '@onivoro/server-common';

@Get(':id')
findOne(@Param('id', ParseUuidOptionalPipe) id?: string) {
  // Implementation
}

@Post('batch')
findMany(@Body('ids', ParseUuidsPipe) ids: string[]) {
  // Implementation
}

Zod Validation Pipe

import { ZodValidationPipe } from '@onivoro/server-common';
import { z } from 'zod';

const UserSchema = z.object({
  name: z.string().min(1),
  email: z.string().email(),
  age: z.number().positive()
});

@Post()
create(@Body(new ZodValidationPipe(UserSchema)) user: z.infer<typeof UserSchema>) {
  // Implementation
}

Utility Functions

API Configuration

import {
  createApiApp,
  configureApiApp,
  initOpenapi
} from '@onivoro/server-common';

// Create NestJS application with default settings
const app = await createApiApp(AppModule);

// Configure with custom settings
await configureApiApp(app, {
  cors: true,
  globalPrefix: 'api',
  port: 3000
});

// Initialize OpenAPI/Swagger
initOpenapi(app, {
  title: 'My API',
  description: 'API Documentation',
  version: '1.0.0'
});

Environment and Package Utilities

import {
  loadDotEnvForKey,
  getPackageVersion,
  parsePackageJson,
  generateAppMetadata
} from '@onivoro/server-common';

// Load environment file
loadDotEnvForKey('development');

// Get package version (async)
const version = await getPackageVersion();

// Parse package.json
const packageInfo = parsePackageJson();

// Generate app metadata
const metadata = generateAppMetadata();

File Operations

import {
  readFileAsJson,
  saveFileAsJson,
  readSslCertificate
} from '@onivoro/server-common';

// Read JSON file
const data = await readFileAsJson<ConfigType>('config.json');

// Save JSON file
await saveFileAsJson('output.json', { data: 'value' });

// Read SSL certificate
const cert = await readSslCertificate('cert.pem');

String and Code Generation

import {
  getRandomString,
  generateUniqueCode,
  generateFirestoreId,
  encode,
  decode
} from '@onivoro/server-common';

// Random string
const random = getRandomString(16);

// Unique code (6 characters)
const code = generateUniqueCode();

// Firestore-style ID
const id = generateFirestoreId();

// Base64 encoding/decoding
const encoded = encode('hello world');
const decoded = decode(encoded);

Database Utilities

import { asInsert } from '@onivoro/server-common';

// Convert object to INSERT statement
const sql = asInsert('users', {
  name: 'John',
  email: '[email protected]',
  created_at: new Date()
});
// Returns: INSERT INTO users (name, email, created_at) VALUES ($1, $2, $3)

System Utilities

import {
  getMemoryStats,
  isPortInUse,
  shell,
  tryCatch
} from '@onivoro/server-common';

// Memory statistics
const stats = getMemoryStats();

// Check if port is in use
const inUse = await isPortInUse(3000);

// Execute shell command
const result = await shell('ls -la');

// Try-catch wrapper
const [result, error] = await tryCatch(async () => {
  return await riskyOperation();
});

Request Parsing

import { parseBody } from '@onivoro/server-common';

// Parse request body
app.use((req, res, next) => {
  parseBody(req, (err, body) => {
    if (err) return next(err);
    req.body = body;
    next();
  });
});

Providers

Version Provider

import { VersionProvider, VERSION_PROVIDER_TOKEN } from '@onivoro/server-common';

@Module({
  providers: [VersionProvider],
  exports: [VERSION_PROVIDER_TOKEN]
})
export class AppModule {}

// Inject in service
@Injectable()
export class AppService {
  constructor(
    @Inject(VERSION_PROVIDER_TOKEN) private version: string
  ) {}
}

Constants

import {
  API_ID_HEADER,
  API_KEY_HEADER
} from '@onivoro/server-common';

// Use in guards or middleware
const apiKey = request.headers[API_KEY_HEADER];
const apiId = request.headers[API_ID_HEADER];

Module Factory

import { moduleFactory } from '@onivoro/server-common';

// Create dynamic module with environment config
const MyModule = moduleFactory({
  providers: [MyService],
  exports: [MyService]
});

Complete Example

import {
  ServerCommonModule,
  DefaultApiController,
  ApiResponsePaged,
  QueryPagedParams,
  PagedResponseDto,
  EnvironmentClass,
  ZodValidationPipe,
  getPackageVersion,
  ErrorFilter
} from '@onivoro/server-common';
import { z } from 'zod';

// Configuration
@EnvironmentClass()
class AppConfig {
  PORT: number = 3000;
  DATABASE_URL: string;
}

// DTO
const UserSchema = z.object({
  name: z.string(),
  email: z.string().email()
});

// Controller
@DefaultApiController('users')
export class UsersController {
  @Get()
  @ApiResponsePaged(UserDto)
  async findAll(@QueryPagedParams() params: any): Promise<PagedResponseDto<UserDto>> {
    const users = await this.userService.findAll(params);
    return {
      data: users.data,
      total: users.total,
      page: params.page || 1,
      pageSize: params.pageSize || 10
    };
  }

  @Post()
  create(@Body(new ZodValidationPipe(UserSchema)) user: z.infer<typeof UserSchema>) {
    return this.userService.create(user);
  }
}

// Bootstrap
async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalFilters(new ErrorFilter());
  
  const version = await getPackageVersion();
  console.log(`Starting app v${version}`);
  
  await app.listen(3000);
}

License

MIT