@tresdoce-nestjs-toolkit/utils
v2.0.12
Published
Tresdoce NestJS Toolkit - Utilitarios para proyectos y librerías
Readme
Este package también es re-exportado por
@tresdoce-nestjs-toolkit/paas, por lo que en proyectos basados en el starter puedes importar desde allí si lo deseas.
Este módulo está pensado para ser utilizado en NestJS Starter, o cualquier proyecto que utilice una configuración centralizada, siguiendo la misma arquitectura del starter.
Glosario
- 🥳 Demo
- 📝 Requerimientos básicos
- 🛠️ Instalar dependencia
- 🔖 Módulos disponibles
- 📖 API Reference
- 📄 Changelog
- 📜 License MIT
📝 Requerimientos básicos
- NestJS Starter
- Node.js v22.21.1 or higher (Download)
- YARN ≥ 1.22.22 o NPM ≥ 11.6.4
- NestJS v11.1.11 or higher (Documentación)
🛠️ Instalar dependencia
npm install -S @tresdoce-nestjs-toolkit/utilsyarn add @tresdoce-nestjs-toolkit/utils📦 Dependencias internas
Este paquete no tiene dependencias internas del toolkit. Puede utilizarse de forma independiente.
Redact
El módulo Redact está pensado para el ofuscamiento de datos sensibles tanto en librerías como en aplicaciones.
Utiliza como base fast-redact con algunas mejoras adicionales
(obfuscación parcial de valores desde la izquierda o la derecha).
⚙️ Configuración
Agregar los parámetros de configuración de Redact en configuration.ts utilizando la key redact:
//./src/config/configuration.ts
import { Typings } from '@tresdoce-nestjs-toolkit/core';
import { registerAs } from '@nestjs/config';
export default registerAs('config', (): Typings.AppConfig => {
return {
//...
redact: {
paths: process.env.REDACT_OBFUSCATE ? process.env.REDACT_OBFUSCATE.split(',') : [],
censor: '****',
obfuscateFrom: 'right',
},
//...
};
});paths: Array de strings con los paths a ofuscar. Se recomienda setearlos por variable de entorno separados por coma
para impactar sin re-deploy. Sigue la sintaxis estándar de EcmaScript.
Más info
- Type:
String[] - Example:
headers.request['authorization'],headers.request['apiKey'] - Ejemplos de sintaxis soportada:
a.b.ca['b'].ca["b-c"].d["a-b"].ca.b.*a[*].c*.ba[0].b
censor: Valor por el cual se reemplaza el dato sensible. La longitud del censor determina cuántos caracteres se
reemplazan en el valor original (los últimos N si obfuscateFrom es right, los primeros N si es left).
- Type:
String - Default:
**** - Example:
400012345678****
obfuscateFrom: Indica desde qué lado del valor se realiza el ofuscamiento.
- Type:
String - Default:
right - Values:
left | right - Example:
****123456784126(left) |400012345678****(right)
remove: Si es true, elimina la key y su valor del objeto en lugar de ofuscar.
- Type:
Boolean - Default:
false
strict: Si es true, lanza un error cuando un path indicado no existe en el objeto a ofuscar. Si es false
(por defecto), ignora los paths faltantes silenciosamente.
- Type:
Boolean - Default:
false
serialize: Controla la salida del proceso de ofuscamiento. Si es false, retorna el objeto JavaScript mutado.
Si es true, retorna el resultado de JSON.stringify. Si se proporciona una función, la utiliza como serializador
personalizado.
- Type:
Boolean | Function - Default:
false
👨💻 Uso con configuración centralizada
Importar RedactModule en el módulo raíz de la aplicación (recomendado como global):
//./src/app.module.ts
import { RedactModule } from '@tresdoce-nestjs-toolkit/utils';
@Module({
imports: [
//...
RedactModule,
//...
],
//...
})
export class AppModule {}👨💻 Uso con .register()
Para configurar el módulo de forma estática sin depender de ConfigService:
//./src/app.module.ts
import { RedactModule } from '@tresdoce-nestjs-toolkit/utils';
@Module({
imports: [
//...
RedactModule.register({
paths: ['my.path'],
censor: 'xxxx',
obfuscateFrom: 'left',
}),
//...
],
//...
})
export class AppModule {}👨💻 Uso con .registerAsync()
Para pasar las opciones de forma asincrónica:
//./src/app.module.ts
import { RedactModule } from '@tresdoce-nestjs-toolkit/utils';
import { ConfigModule, ConfigService } from '@nestjs/config';
@Module({
imports: [
//...
RedactModule.registerAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => configService.get('config.redact'),
inject: [ConfigService],
}),
//...
],
//...
})
export class AppModule {}Inyectando RedactService
⚠️
RedactModulees@Global(), por lo queRedactServiceestá disponible en toda la aplicación una vez importado el módulo enAppModule.
⚠️ El método
obfuscate()realiza una mutación del objeto recibido internamente (trabaja sobre una copia profunda). El objeto original no se modifica.
// ./my-service.ts
import { Injectable } from '@nestjs/common';
import { RedactService } from '@tresdoce-nestjs-toolkit/utils';
@Injectable()
export class MyService {
constructor(private readonly redactService: RedactService) {}
async funcOfService(data: object) {
// _serialize = true (default): retorna el objeto JavaScript con los valores ofuscados
const redacted = this.redactService.obfuscate(data);
// Return: { myKey: 'value-obfuscxxxx' }
// _serialize = false: retorna el resultado como string JSON
const redactedString = this.redactService.obfuscate(data, false);
// Return: '{"myKey":"value-obfuscxxxx"}'
}
}Format
El módulo Format expone el servicio FormatService con utilidades para formatear números y fechas.
FormatModule es un módulo global que puede importarse una sola vez en AppModule.
⚙️ Configuración
FormatModule no requiere configuración centralizada. Basta con importarlo en el módulo donde se necesite,
o en AppModule para disponibilizarlo globalmente:
//./src/app.module.ts
import { FormatModule } from '@tresdoce-nestjs-toolkit/utils';
@Module({
imports: [
//...
FormatModule,
//...
],
})
export class AppModule {}Si se prefiere usar FormatService sin importar el módulo global, puede agregarse directamente como provider:
// ./src/my.module.ts
import { Module } from '@nestjs/common';
import { FormatService } from '@tresdoce-nestjs-toolkit/utils';
@Module({
providers: [FormatService],
exports: [FormatService],
})
export class MyModule {}👨💻 Uso
Inyectar FormatService en el servicio:
// ./src/my.service.ts
import { Injectable } from '@nestjs/common';
import { FormatService } from '@tresdoce-nestjs-toolkit/utils';
@Injectable()
export class MyService {
constructor(private readonly formatService: FormatService) {}
}.formatNumber()
Formatea un número usando Intl.NumberFormat.
formatNumberToUSDCurrency() {
return this.formatService.formatNumber({
num: 123456.789,
locale: 'es-AR',
formatOptions: {
style: 'currency',
currency: 'USD',
currencyDisplay: 'narrowSymbol',
},
});
// Return: '$ 123.456,79'
}num: El número a formatear. Requerido.
- Type:
number - Example:
123456.789 | 16 | -3500
formatOptions: Opciones de formato de Intl.NumberFormat.
Documentación
- Type:
Intl.NumberFormatOptions - Example:
{ style: 'currency', currency: 'USD' }
locale: Locale de internacionalización.
Locales
- Type:
string - Default:
'es-AR' - Example:
'en-US' | 'de-DE' | 'en-IN' | 'en-GB'
.dateTimeRef()
Retorna la instancia DateTime de Luxon para usar directamente.
import {
FormatService,
DEFAULT_TIMEZONE,
DEFAULT_TIMEZONE_LOCALE,
} from '@tresdoce-nestjs-toolkit/utils';
myFunction() {
const cDate = this.formatService.dateTimeRef().now();
return {
'1': cDate, // Object DateTime de Luxon
'2': cDate.toISO(), // '2023-07-13T16:12:09.470+00:00'
'3': cDate.setZone(DEFAULT_TIMEZONE).toISO(), // '2023-07-13T16:12:09.473Z'
'4': cDate.setZone(DEFAULT_TIMEZONE_LOCALE).toISO(), // '2023-07-13T13:12:09.473-03:00'
};
}.formatDate()
Formatea un objeto Date en un string con el formato y zona horaria especificados.
myFunction() {
const cDate = new Date();
return {
'1': this.formatService.formatDate({ date: cDate }),
// Return: '20/12/2022 14:37:17.020'
'2': this.formatService.formatDate({
date: cDate,
formatDate: 'fff',
timezone: 'Europe/Paris',
locale: 'fr',
}),
// Return: '20 décembre 2022, 15:37.020 UTC+1'
};
}date: Fecha a formatear. Requerida.
- Type:
Date
formatDate: Formato de salida. Ver
tokens de Luxon.
- Type:
string - Default:
'dd/LL/yyyy TT.SSS'
timezone: Zona horaria para ajustar la fecha.
- Type:
string - Default:
'utc' - Example:
'America/Argentina/Buenos_Aires' | 'Europe/Paris'
locale: Locale de internacionalización.
- Type:
string - Default:
'es-AR'
.dateToISO()
Convierte un objeto Date a string en formato ISO 8601.
myFunction() {
const cDate = new Date();
return {
'1': this.formatService.dateToISO({ date: cDate }),
// Return: '2023-07-12T12:06:29.957Z'
'2': this.formatService.dateToISO({ date: cDate, timezone: DEFAULT_TIMEZONE_LOCALE }),
// Return: '2023-07-12T09:06:29.957-03:00'
};
}date: Fecha a convertir. Requerida.
- Type:
Date
timezone: Zona horaria para ajustar la fecha.
- Type:
string - Default:
'utc' - Example:
'America/Argentina/Buenos_Aires' | 'Europe/Paris'
.calculateTimestampDiff()
Calcula la diferencia entre dos timestamps en milisegundos (u otra unidad).
myFunction() {
const startTimestamp = 1689208308510;
const endTimestamp = 1689208308525;
return {
'1': this.formatService.calculateTimestampDiff({
startTime: startTimestamp,
endTime: endTimestamp,
}),
// Return: 15 (número, en milisegundos)
'2': this.formatService.calculateTimestampDiff({
startTime: startTimestamp,
endTime: endTimestamp,
options: { unit: 'seconds', addSuffix: true },
}),
// Return: '0.015s'
};
}startTime: Timestamp de inicio (más antiguo). Requerido.
- Type:
number - Example:
1689208308510
endTime: Timestamp de fin (más reciente). Requerido.
- Type:
number - Example:
1689208308525
options: Objeto de configuración opcional.
- Type:
TimestampDiffOptions - Default:
{ unit: 'milliseconds', addSuffix: false }unit: Unidad del resultado (TimeUnit). CuandoaddSuffixesfalsedevuelvenumber; cuando estruedevuelvestring.addSuffix: Agrega el sufijo de la unidad al resultado.
Bcrypt
El módulo Bcrypt proporciona funcionalidades para encriptar, hashear y comparar datos usando el algoritmo bcrypt.
⚙️ Configuración
BcryptModule toma su configuración desde la key bcrypt de configuration.ts. Si no se define, usa los valores por defecto.
//./src/config/configuration.ts
import { Typings } from '@tresdoce-nestjs-toolkit/core';
import { registerAs } from '@nestjs/config';
export default registerAs('config', (): Typings.AppConfig => {
return {
//...
bcrypt: {
rounds: 16, // default: 16
minor: 'b', // default: 'b'
},
//...
};
});rounds: Número de rondas de sal para la generación del hash. A mayor valor, más seguro pero más lento.
- Type:
number - Default:
16
minor: Versión menor de bcrypt a utilizar ('a' o 'b').
- Type:
BcryptVersion('a' | 'b') - Default:
'b'
👨💻 Uso
Importar BcryptModule en el módulo que lo requiera:
// ./src/my.module.ts
import { Module } from '@nestjs/common';
import { BcryptModule } from '@tresdoce-nestjs-toolkit/utils';
@Module({
imports: [BcryptModule],
})
export class MyModule {}Inyectar BcryptService en el servicio:
// ./src/my.service.ts
import { Injectable } from '@nestjs/common';
import { BcryptService } from '@tresdoce-nestjs-toolkit/utils';
@Injectable()
export class MyService {
constructor(private readonly bcryptService: BcryptService) {}
}encrypt (async)
async encryptExample() {
const encrypted = await this.bcryptService.encrypt('password');
console.log(encrypted); // '$2b$16$...'
}encryptSync (sync)
encryptSyncExample() {
const encrypted = this.bcryptService.encryptSync('password');
console.log(encrypted); // '$2b$16$...'
}compare (async)
async compareExample() {
const encrypted = await this.bcryptService.encrypt('password');
const isMatch = await this.bcryptService.compare('password', encrypted);
console.log(isMatch); // true
}compareSync (sync)
compareSyncExample() {
const encrypted = this.bcryptService.encryptSync('password');
const isMatch = this.bcryptService.compareSync('password', encrypted);
console.log(isMatch); // true
}generatePasswordHash
Genera un hash seguro para una contraseña de forma sincrónica.
generatePasswordHashExample() {
const hash = this.bcryptService.generatePasswordHash('password');
console.log(hash); // '$2b$16$...'
}validateHash
Valida si un hash fue generado con las rondas de sal actuales.
validateHashExample() {
const hash = this.bcryptService.generatePasswordHash('password');
const isValid = this.bcryptService.validateHash(hash);
console.log(isValid); // true
}generateSalt
Genera una nueva sal. Se ejecuta automáticamente en el constructor con los valores configurados.
// Usar con valores custom (sobreescribe la sal interna del servicio)
this.bcryptService.generateSalt(10, 'a');📖 API Reference
Módulos
| Módulo | Descripción | Global |
| -------------- | --------------------------------- | ------ |
| RedactModule | Ofuscamiento de datos sensibles | Sí |
| FormatModule | Formateo de números y fechas | Sí |
| BcryptModule | Encriptación y hashing con bcrypt | Sí |
Servicios
| Servicio | Módulo | Métodos |
| --------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------ |
| RedactService | RedactModule | obfuscate(data, serialize?) |
| FormatService | FormatModule | formatNumber(), dateTimeRef(), formatDate(), dateToISO(), calculateTimestampDiff() |
| BcryptService | BcryptModule | encrypt(), encryptSync(), compare(), compareSync(), generatePasswordHash(), validateHash(), generateSalt() |
Interfaces
| Interfaz | Descripción |
| ------------------------------- | ----------------------------------------------- |
| RedactOptions | Opciones del módulo Redact |
| RedactModuleOptions | Alias de RedactOptions |
| RedactModuleOptionsFactory | Factory para opciones async de Redact |
| RedactModuleAsyncOptions | Opciones async para registerAsync() |
| BcryptOptions | Opciones del módulo Bcrypt |
| FormatNumberOptions | Parámetros de formatNumber() |
| FormatDateOptions | Parámetros de formatDate() |
| ISOFormatDateOptions | Parámetros de dateToISO() |
| CalculateTimestampDiffOptions | Parámetros de calculateTimestampDiff() |
| TimestampDiffOptions | Sub-opciones de CalculateTimestampDiffOptions |
Tipos y enums
| Símbolo | Tipo | Valores / Descripción |
| --------------- | ---- | ------------------------------------------ | --------- | --------- | ------- | ------ | ------- | -------- | -------- |
| BcryptVersion | type | 'a' | 'b' |
| TimeUnit | type | 'milliseconds' | 'seconds' | 'minutes' | 'hours' | 'days' | 'weeks' | 'months' | 'years' |
| TimeSuffixes | enum | ms, s, min, h, d, w, mo, y |
Constantes
| Constante | Valor | Descripción |
| ------------------------------------------ | ------------------------------------------------------------------------------------------------- | ----------------------------------------- |
| DEFAULT_CENSOR | '****' | Censor por defecto de Redact |
| DEFAULT_OPTIONS_REDACT | { paths:[], obfuscateFrom:'right', censor:'****', remove:false, strict:false, serialize:false } | Opciones por defecto de Redact |
| REDACT_MODULE_OPTIONS | Symbol | Token de inyección de opciones del módulo |
| REDACT_PROVIDER | Symbol | Token del provider de fast-redact |
| DEFAULT_TIMEZONE | 'utc' | Zona horaria por defecto (UTC) |
| DEFAULT_LOCALE | 'es-AR' | Locale por defecto |
| DEFAULT_TIMEZONE_LOCALE | 'America/Argentina/Buenos_Aires' | Zona horaria de Buenos Aires |
| DEFAULT_FORMAT_DATE | 'dd/LL/yyyy TT.SSS' | Formato de fecha por defecto |
| DEFAULT_OPTIONS_CALCULATE_TIMESTAMP_DIFF | { unit: 'milliseconds', addSuffix: false } | Opciones por defecto del cálculo de diff |
| DEFAULT_SALT_ROUNDS | 16 | Rondas de sal por defecto de Bcrypt |
| DEFAULT_MINOR | 'b' | Versión menor por defecto de Bcrypt |
| BCRYPT_DEFAULT_OPTIONS | { rounds: 16, minor: 'b' } | Opciones por defecto de Bcrypt |
| BCRYPT_MODULE_OPTIONS | Symbol | Token de inyección de opciones de Bcrypt |
📄 Changelog
Todos los cambios notables de este paquete se documentarán en el archivo Changelog.
