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

@tresdoce-nestjs-toolkit/core

v2.0.12

Published

Tresdoce NestJS Toolkit - Funcionalidades a nivel core

Downloads

3,224

Readme

Módulo central del toolkit que provee tipos, helpers, decoradores, guards y utilidades que son utilizados transversalmente por los demás paquetes. Está pensado para ser utilizado en NestJS Starter o en cualquier proyecto que siga la misma arquitectura de configuración centralizada.

Glosario


📝 Requerimientos básicos

🛠️ Instalar dependencia

npm install -S @tresdoce-nestjs-toolkit/core
yarn add @tresdoce-nestjs-toolkit/core

📦 Dependencias internas

Este paquete no tiene dependencias internas del toolkit. Puede utilizarse de forma independiente.

👨‍💻 Uso

Typings — Configuración centralizada

El namespace Typings expone todas las interfaces y enums que modelan la configuración centralizada de la aplicación (config).

// ./src/config/configuration.ts
import { Typings } from '@tresdoce-nestjs-toolkit/core';
import { registerAs } from '@nestjs/config';

export default registerAs('config', (): Typings.AppConfig => {
  return {
    project: {
      apiPrefix: process.env.API_PREFIX,
      name: process.env.npm_package_name,
      version: process.env.npm_package_version,
      description: process.env.npm_package_description,
      author: {
        name: process.env.npm_package_author_name,
        email: process.env.npm_package_author_email,
        url: process.env.npm_package_author_url,
      },
      repository: {
        type: 'git',
        url: process.env.npm_package_repository_url,
      },
      bugs: {
        url: process.env.npm_package_bugs_url,
      },
      homepage: process.env.npm_package_homepage,
    },
    server: {
      isProd: process.env.NODE_ENV === 'production',
      appStage: process.env.APP_STAGE as Typings.TAppStage,
      port: parseInt(process.env.PORT, 10) || 8080,
      context: process.env.CONTEXT,
      origins: process.env.ORIGINS.split(','),
      allowedHeaders: process.env.ALLOWED_HEADERS,
      allowedMethods: process.env.ALLOWED_METHODS,
      corsEnabled: process.env.CORS_ENABLED === 'true',
      corsCredentials: process.env.CORS_CREDENTIALS === 'true',
      propagateHeaders: process.env.PROPAGATE_HEADERS
        ? process.env.PROPAGATE_HEADERS.split(',')
        : [],
    },
    swagger: {
      path: process.env.SWAGGER_PATH,
      enabled: process.env.SWAGGER_ENABLED === 'true',
    },
  };
});

Validation Schema

La función validateSchemaForApp genera un schema Joi que combina las validaciones base obligatorias del starter con las validaciones custom del proyecto.

// ./src/config/validationSchema.ts
import Joi from 'joi';
import { validateSchemaForApp } from '@tresdoce-nestjs-toolkit/core';

export const validationSchema = validateSchemaForApp({
  // Parámetros custom de la aplicación
  RICK_AND_MORTY_API_URL: Joi.string().required(),
});

Si la aplicación implementa CSRF, también hay que extender con validationSchemaCsrf:

// ./src/config/validationSchema.ts
import Joi from 'joi';
import { validateSchemaForApp, validationSchemaCsrf } from '@tresdoce-nestjs-toolkit/core';

export const validationSchema = validateSchemaForApp({
  ...validationSchemaCsrf,
  // Parámetros custom adicionales
  RICK_AND_MORTY_API_URL: Joi.string().required(),
});

Regla de validación de CSRF_SECRET: En entornos prod es obligatorio y debe ser una cadena de exactamente 32 caracteres que incluya al menos una minúscula, una mayúscula, un dígito y un carácter especial (^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z\d]).{32}$). En otros entornos es opcional.


corePathsExcludes

Retorna un array de objetos { path, method } que representa las rutas core que deben excluirse del prefix global y de funcionalidades como logging.

// ./src/main.ts
import { corePathsExcludes } from '@tresdoce-nestjs-toolkit/core';

async function bootstrap() {
  //...
  app.setGlobalPrefix(`${server.context}`, {
    exclude: [...corePathsExcludes()],
  });
  //...
}

Las rutas excluidas son: /health/liveness, /health/readiness, /info y /metrics (con su prefijo de contexto si CONTEXT está definido).

excludePaths

Versión simplificada de corePathsExcludes() que retorna solo los strings de path (sin el método HTTP), útil para filtros de middleware o loggers.

import { excludePaths } from '@tresdoce-nestjs-toolkit/core';

// Retorna: ['/api/health/liveness', '/api/health/readiness', '/api/info', '/api/metrics']
const paths = excludePaths();

corePathsExcludesGlobs

Array estático de patrones glob equivalentes a las rutas core excluidas. Útil para configurar middlewares que aceptan globs (e.g., morgan, winston).

import { corePathsExcludesGlobs } from '@tresdoce-nestjs-toolkit/core';

// ['**/health/liveness', '**/health/readiness', '**/info', '**/metrics']
console.log(corePathsExcludesGlobs);

setHttpsOptions

Configura las opciones HTTPS para la aplicación NestJS leyendo el certificado y la clave privada desde el filesystem.

// ./src/main.ts
import { setHttpsOptions } from '@tresdoce-nestjs-toolkit/core';

const certPath = './path/to/secrets/public-certificate.pem';
const pkeyPath = './path/to/secrets/private-key.pem';

async function bootstrap() {
  const app = await NestFactory.create(AppModule, {
    httpsOptions: setHttpsOptions(certPath, pkeyPath),
  });
  //...
}

Si alguno de los archivos no existe, retorna { cert: '', key: '' } sin lanzar error.


Cross-site request forgery (CSRF)

Cross-Site Request Forgery (CSRF) es un tipo de ataque de seguridad que ocurre cuando un atacante engaña a un usuario autenticado para que realice acciones no deseadas en una aplicación web. El middleware de protección genera y valida tokens CSRF únicos asociados a la sesión del usuario. Si el token no está presente o es inválido, la solicitud es rechazada con HTTP 403 Forbidden.

Configuración

El CSRF funciona utilizando cookies y requiere CSRF_SECRET en las variables de entorno. La configuración se integra en la configuración centralizada de la app:

// ./src/config/configuration.ts
import { Typings } from '@tresdoce-nestjs-toolkit/core';
import { registerAs } from '@nestjs/config';

export default registerAs('config', (): Typings.AppConfig => {
  return {
    //...
    server: {
      //...
      csrf: {
        secret: process.env.CSRF_SECRET,
        // Propiedades opcionales — los defaults están documentados abajo
      },
    },
    //...
  };
});

Y en el schema de validación:

// ./src/config/validationSchema.ts
import { validateSchemaForApp, validationSchemaCsrf } from '@tresdoce-nestjs-toolkit/core';

export const validationSchema = validateSchemaForApp({
  ...validationSchemaCsrf,
});

key: Nombre de la cookie que almacena el secreto de sesión CSRF.

  • Type: String
  • Default: _csrf
  • Example: csrf_key

cookieName: Nombre de la cookie que contiene el token CSRF enviado al cliente.

  • Type: String
  • Default: xsrf-token
  • Example: token-xsrf

secret: Frase secreta utilizada para firmar el token CSRF. En entornos prod debe tener exactamente 32 caracteres con mayúsculas, minúsculas, dígitos y caracteres especiales.

  • Type: String
  • Default: ''
  • Example: 9r@F5z!X8w*L3q&H2s^J7p#K1n$Y4m?A

sameSite: Atributo SameSite de la cookie CSRF.

  • Type: String
  • Values: strict | lax | none
  • Default: strict

httpOnly: Indica si la cookie no es accesible desde JavaScript del navegador.

  • Type: Boolean
  • Default: true

signed: Indica si la cookie debe estar firmada con el secret.

  • Type: Boolean
  • Default: true

path: Ruta para la que es válida la cookie.

  • Type: String
  • Default: /

secure: Si es true, la cookie solo se envía por HTTPS. El middleware lo establece automáticamente en true cuando NODE_ENV === 'production'.

  • Type: Boolean
  • Default: false (en local/test), true (en production)

maxAge: Tiempo de vida de la cookie en segundos.

  • Type: Number
  • Default: 300 (5 minutos)

Implementación del middleware

// ./src/main.ts
import { csrfToken } from '@tresdoce-nestjs-toolkit/core';
import cookieParser from 'cookie-parser';

async function bootstrap() {
  //...
  const appConfig = app.get<ConfigService>(ConfigService)['internalConfig']['config'];
  //...
  app.use([
    cookieParser(appConfig.server.csrf.secret),
    csrfToken(appConfig.server.csrf),
    //...
  ]);
  //...
}
(async () => await bootstrap())();

Decorador @Csrf()

Protege un endpoint o un controller completo aplicando el CsrfGuard. Al decorar un controller, protege todos sus endpoints.

Nivel controller

import { Csrf } from '@tresdoce-nestjs-toolkit/core';

@Csrf()
export class MyController {
  @Get()
  async myEndpoint() {
    /*...*/
  }

  @Get('endpoint2')
  async myEndpoint2() {
    /*...*/
  }
}

Nivel endpoint

import { Csrf } from '@tresdoce-nestjs-toolkit/core';

export class MyController {
  @Get()
  @Csrf()
  async myEndpoint() {
    /*...*/
  }
}

En entornos test (NODE_ENV === 'test'), @Csrf() aplica el metadata skipCsrfGuard: true en lugar del guard, permitiendo ejecutar tests sin cookies CSRF.

Iniciar el token CSRF de sesión

El primer request debe generar el token de sesión llamando a req.csrfToken(). El lugar adecuado suele ser el endpoint de login o el primer endpoint público de la aplicación.

import { ICsrfRequest } from '@tresdoce-nestjs-toolkit/core';

export class AuthController {
  @Get('/login')
  async login(@Req() req: ICsrfRequest) {
    req.csrfToken(); // Genera y setea el token de sesión en la cookie
    //...
  }
}

A partir de ese punto, cada request válido que pase por CsrfGuard generará automáticamente un nuevo token.

Consideraciones

  • Agregar Access-Control-Allow-Credentials a la lista ALLOWED_HEADERS en las variables de entorno.
  • Configurar CORS_CREDENTIALS=true en las variables de entorno.
  • Si utilizas Axios, configurar las instancias con withCredentials: true.
  • Verificar que el navegador o herramienta de testing permita la configuración de cookies.

Decorators

@Public()

Marca un endpoint o controller como público (no requiere autenticación). Setea el metadata isPublic: true, que los guards de autenticación pueden leer con IS_PUBLIC_KEY.

import { Public } from '@tresdoce-nestjs-toolkit/core';

@Controller()
export class AppController {
  @Get('')
  @Public()
  getInfo(): string {
    return 'endpoint público';
  }

  @Get('private')
  getPrivate() {
    return 'endpoint privado';
  }
}

@Roles(...roles)

Setea metadata de roles sobre un endpoint o controller. Los guards de autorización pueden leer los roles con ROLES_KEY.

import { Roles } from '@tresdoce-nestjs-toolkit/core';

@Controller()
export class AppController {
  @Get('')
  @Roles('user')
  onlyUser(): string {
    return '...';
  }

  @Get('admin')
  @Roles('user', 'admin')
  userAndAdmin(): string {
    return '...';
  }
}

@ExcludeFilter()

Marca un endpoint o controller para que sea excluido de filtros globales (e.g., exception filters personalizados). Setea el metadata excludeFilter: true, que puede leerse con EXCLUDE_FILTER_KEY.

import { ExcludeFilter } from '@tresdoce-nestjs-toolkit/core';

@Controller()
export class HealthController {
  @Get('liveness')
  @ExcludeFilter()
  liveness() {
    return { status: 'ok' };
  }
}

Lectura del metadata en un filtro:

import { EXCLUDE_FILTER_KEY } from '@tresdoce-nestjs-toolkit/core';

const isExcluded = this.reflector.get<boolean>(EXCLUDE_FILTER_KEY, context.getHandler());

Param Decorators

@Pagination()

Extrae y valida los parámetros de paginación page y size del query string. Retorna un objeto PaginationParams.

import { Controller, Get } from '@nestjs/common';
import { Pagination, PaginationParams } from '@tresdoce-nestjs-toolkit/core';

@Controller('users')
export class UsersController {
  @Get()
  findAll(@Pagination() pagination: PaginationParams) {
    const { page, size } = pagination;
    console.log('Current page: ', page);
    console.log('Items per page: ', size);
    //...
  }
}

page: Número de página actual.

  • Type: number
  • Default: 1
  • Minimum: 1

size: Cantidad de elementos por página.

  • Type: number
  • Default: 10
  • Maximum: 100

Si page o size se proveen pero no son enteros positivos válidos, se lanza BadRequestException. Si size supera 100, también se lanza BadRequestException.

URL Example

  • Schema: <http|https>://<server_url><:port>/<context>/<endpoint>?page=<value>&size=<value>
  • Example: http://localhost:8080/v1/users?page=2&size=20

@Sorting(validFields)

Extrae y valida el parámetro sort del query string. Retorna un array de SortCriteria.

import { Controller, Get } from '@nestjs/common';
import { Sorting, SortCriteria } from '@tresdoce-nestjs-toolkit/core';

@Controller('users')
export class UsersController {
  @Get()
  findAll(@Sorting(['id', 'email', 'name']) sorting: SortCriteria[]) {
    sorting.forEach(({ field, order }) => {
      console.log(`Sort by ${field} ${order}`);
    });
    //...
  }
}

field: Nombre del campo por el cual ordenar (debe ser uno de los campos declarados en el decorador).

  • Type: string

order: Dirección del ordenamiento.

  • Type: 'asc' | 'desc'
  • Default: 'asc'

Si el campo no está en la lista de campos válidos o el formato es inválido, se lanza BadRequestException.

URL Example

  • Schema: ?sort=<field1>:<order1>,<field2>:<order2>
  • Example: http://localhost:8080/v1/users?sort=id:asc,email:desc

@FilteringParams(validProperties)

Extrae y valida el parámetro filters del query string. Retorna un array de Filtering.

import { Controller, Get } from '@nestjs/common';
import { FilteringParams, Filtering } from '@tresdoce-nestjs-toolkit/core';

@Controller('users')
export class UsersController {
  @Get()
  findAll(@FilteringParams(['firstName', 'email', 'age']) filters: Filtering[]) {
    filters.forEach(({ property, rule, values }) => {
      console.log(`Filter: ${property} ${rule}`, values);
    });
    //...
  }
}

property: Nombre de la propiedad a filtrar (debe estar en la lista declarada).

  • Type: string

rule: Regla de filtrado.

  • Type: FilterRule
  • Enum: eq | neq | gt | gte | lt | lte | like | nlike | in | nin | isnull | isnotnull

values: Valores para el filtro según la regla. Para isnull y isnotnull es un array vacío.

  • Type: (string | number | boolean)[]

Si la propiedad, la regla o el formato son inválidos, se lanza BadRequestException.

URL Example

  • Schema: ?filters=<property1>:<rule1>:<value1>,<property2>:<rule2>:<value2>
  • Example: http://localhost:8080/v1/users?filters=age:gte:30,name:like:John,status:in:active,inactive

Paginación con calculatePagination

Función utilitaria que calcula los metadatos de paginación a partir de page, size y total.

import { calculatePagination } from '@tresdoce-nestjs-toolkit/core';

const meta = calculatePagination({ page: 2, size: 10, total: 100 });
// {
//   page: 2,
//   size: 10,
//   total: 100,
//   totalPages: 10,
//   hasNext: true,
//   hasPrevious: true,
// }

Para estructurar la respuesta paginada en Swagger, se proveen las clases PaginationMetaData y PaginationResponse<T>:

import { PaginationMetaData, PaginationResponse } from '@tresdoce-nestjs-toolkit/core';

// En un controller con Swagger:
@ApiOkResponse({ type: PaginationResponse })
@Get()
findAll(@Pagination() pagination: PaginationParams): PaginationResponse<UserEntity> {
  const [data, total] = await this.usersService.findAll(pagination);
  return {
    data,
    meta: calculatePagination({ ...pagination, total }),
  };
}

PaginationResponse<T> tiene las propiedades data: T[] y meta: PaginationMetaData.
PaginationMetaData incluye: page, size, total, totalPages?, hasNext?, hasPrevious?.


📖 API Reference

Namespace Typings

| Export | Descripción | | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | AppConfig | Interface raíz de la configuración centralizada. Incluye project, server, swagger, health, params, httpClient, services, database, redis, mailer, camunda, elasticsearch, tracing, redact, bcrypt, snowflakeUID, sqs. | | IProjectConfig | Datos del proyecto (apiPrefix, name, version, description, author, repository, bugs, homepage). | | IServerConfig | Configuración del servidor (isProd, appStage, port, context, origins, propagateHeaders, allowedHeaders, allowedMethods, corsEnabled, corsCredentials, csrf, rateLimits). | | IHealthConfig | Configuración de health checks (skipChecks, storage, memory). | | ISwaggerConfig | Configuración de Swagger (path, enabled). | | TAppStage | 'local' \| 'test' \| 'snd' \| 'dev' \| 'qa' \| 'homo' \| 'prod' | | EAppStage | Enum equivalente a TAppStage. | | TSkipHealthChecks | 'storage' \| 'memory' \| 'elasticsearch' \| 'camunda' \| 'typeorm' \| 'redis' | | ESkipHealthChecks | Enum equivalente a TSkipHealthChecks. |

Commons (rutas y CSRF)

| Export | Tipo | Descripción | | ----------------------------------------- | ------------------------------------------------- | ------------------------------------------------------ | | corePathsExcludes() | () => { path: string; method: RequestMethod }[] | Rutas core a excluir del prefix global. | | excludePaths() | () => string[] | Solo los paths de corePathsExcludes(). | | corePathsExcludesGlobs | string[] | Patrones glob de las rutas core. | | csrfToken(options?) | (options?: CsrfCookieOptions) => Middleware | Middleware Express que gestiona el token CSRF. | | CsrfCookieOptions | interface | Opciones de configuración de la cookie CSRF. | | ICsrfRequest | interface | Request extendido con cookieConfig y csrfToken(). | | getCsrfFromRequest(req) | function | Extrae el token CSRF de la request. | | getSecretFromRequest(req, name, cookie) | function | Extrae el secreto de la request. | | verify(secret, token) | function | Verifica si un token CSRF es válido contra su secreto. |

Validations

| Export | Tipo | Descripción | | ------------------------------- | ---------- | --------------------------------------------------------------------------------- | | validateSchemaForApp(schema) | function | Retorna un schema Joi compuesto por baseValidationSchemaApp + el schema custom. | | validateSchema(schema, input) | function | Valida un input contra un schema Joi, lanzando Error si falla. | | baseValidationSchema | object | Schema Joi con las variables de entorno obligatorias base. | | baseValidationSchemaApp | object | baseValidationSchema + variables de tracing opcionales. | | validationSchemaCsrf | object | Schema Joi para CSRF_SECRET. |

Decorators

| Export | Descripción | | ----------------------------- | ----------------------------------------------------------------------- | | Public() | Marca el endpoint/controller como público. | | IS_PUBLIC_KEY | 'isPublic' — clave de metadata del decorador @Public(). | | Roles(...roles) | Setea metadata de roles. | | ROLES_KEY | 'roles' — clave de metadata del decorador @Roles(). | | ExcludeFilter() | Excluye el endpoint/controller de filtros globales. | | EXCLUDE_FILTER_KEY | 'excludeFilter' — clave de metadata del decorador @ExcludeFilter(). | | Csrf() | Aplica CsrfGuard al endpoint/controller. | | Pagination() | Param decorator que extrae { page, size } del query string. | | Sorting(fields) | Param decorator que extrae y valida sort del query string. | | FilteringParams(properties) | Param decorator que extrae y valida filters del query string. |

Guards

| Export | Descripción | | ----------- | ---------------------------------------------------------------------------------------------------------------- | | CsrfGuard | Guard que valida el token CSRF, el User-Agent y la IP del cliente. Lanza 403 Forbidden si la validación falla. |

DTOs y Entities

| Export | Descripción | | ----------------------- | ---------------------------------------------------------------------------------- | | PaginationParamsDto | DTO con validación para page (default 1) y size (default 10, max 100). | | SortingParamsDto | DTO para el parámetro sort. | | FilteringParamsDto | DTO para el parámetro filters. | | SortCriteriaDto | DTO con field y order. | | FilteringCriteriaDto | DTO con property, rule y values. | | PaginationMetaData | Clase Swagger con page, size, total, totalPages, hasNext, hasPrevious. | | PaginationResponse<T> | Clase Swagger con data: T[] y meta: PaginationMetaData. |

Utils

| Export | Tipo | Descripción | | ------------------------------------- | ----------------------------------------------- | ----------------------------------------------------------- | | calculatePagination(params) | (params: PaginateDataParams) => IPaginateData | Calcula metadatos de paginación. | | PaginateDataParams | interface | { page, size, total } | | IPaginateData | interface | PaginateDataParams & { totalPages, hasNext, hasPrevious } | | getSkipHealthChecks(value) | (value: string) => TSkipHealthChecks[] | Parsea un string CSV de health checks a omitir. | | setHttpsOptions(certPath, pkeyPath) | function | Retorna { cert, key } para habilitar HTTPS. |

Types y Enums

| Export | Valores | | ------------------ | ------------------------------------------------------------------------------------------ | | FilterRule | eq \| neq \| gt \| gte \| lt \| lte \| like \| nlike \| in \| nin \| isnull \| isnotnull | | SortOrder | 'asc' \| 'desc' | | SortCriteria | { field: string; order: SortOrder } | | Filtering<T> | { property: string; rule: FilterRule; values: T[] } | | PaginationParams | { page: number; size: number } |

📄 Changelog

Todos los cambios notables de este paquete se documentarán en el archivo Changelog.