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

@quadcore-lib/core-server

v0.1.0

Published

Utilidades base de servidor para apps NestJS de Quadcore: bootstrap estandarizado, sobre de respuesta `ApiResponse<T>`, manejo de errores, validación de entorno (fail-fast), health check y paginación. Es la contraparte de servidor de `@quadcore-lib/core`.

Downloads

38

Readme

@quadcore-lib/core-server

Utilidades base de servidor para apps NestJS de Quadcore: bootstrap estandarizado, sobre de respuesta ApiResponse<T>, manejo de errores, validación de entorno (fail-fast), health check y paginación. Es la contraparte de servidor de @quadcore-lib/core.

Instalación

npm install @quadcore-lib/core-server

Requisitos

Peer dependencies que la app consumidora debe tener instaladas:

npm install @nestjs/common @nestjs/core class-validator class-transformer reflect-metadata rxjs

Uso

1. Bootstrap (reemplaza tu main.ts)

// main.ts
import 'reflect-metadata';
import { bootstrapQuadcoreApp } from '@quadcore-lib/core-server';
import { AppModule } from './app.module';

bootstrapQuadcoreApp(AppModule);

Aplica automáticamente: ValidationPipe global (whitelist + transform), helmet, CORS desde FRONTEND_URL, prefijo global /api, ResponseEnvelopeInterceptor, HttpExceptionFilter y listen(PORT).

⚠️ Adopción del sobre { data }. El interceptor envuelve toda respuesta en { data }. Si ya tenés un frontend consumiendo endpoints crudos (p. ej. @quadcore-lib/auth leyendo /auth/me), al adoptarlo el frontend debe desenvolver tolerante (const x = res.data ?? res) y la ruta pasa a /api/.... Podés escalonar el cambio con las flags useResponseEnvelope / globalPrefix de BootstrapOptions.

2. Validar variables de entorno (fail-fast)

import { z } from 'zod';
import { QuadcoreConfigModule, QUADCORE_CONFIG } from '@quadcore-lib/core-server';

const envSchema = z.object({
  DATABASE_URL: z.string().url(),
  FRONTEND_URL: z.string().url().optional(),
  PORT: z.coerce.number().default(3000),
});
export type AppEnv = z.infer<typeof envSchema>;

// app.module.ts → imports: [ QuadcoreConfigModule.forRoot(envSchema) ]
// inyectar con: @Inject(QUADCORE_CONFIG) private readonly config: AppEnv

Si falta una variable requerida, la app no arranca y reporta cuál.

3. Health check

QuadcoreCoreModule.forRoot() registra GET /health (→ GET /api/health con el prefijo global).

4. Paginación

import { parsePagination, Paginated } from '@quadcore-lib/core-server';

const { skip, take, page, pageSize } = parsePagination(query); // { page, pageSize, skip, take }
const [items, total] = await repo.findAndCount({ skip, take });
const result: Paginated<Item> = { items, total, page, pageSize };

API

Funciones

| Export | Descripción | |---|---| | bootstrapQuadcoreApp(AppModule, options?) | Crea la app Nest con pipe + helmet + CORS + prefijo /api + envelope + filter y hace listen. | | validateEnv(schema, source?) | Valida un objeto (default process.env) contra un schema zod. Lanza con detalle si falla. | | parsePagination(query) | Normaliza { page, pageSize } a { page, pageSize, skip, take } (pageSize máx. 100). |

Módulos

| Export | Descripción | |---|---| | QuadcoreConfigModule.forRoot(schema) | @Global(). Valida env al arrancar y provee el resultado bajo el token QUADCORE_CONFIG. | | QuadcoreCoreModule.forRoot(options?) | @Global(). Registra HealthController; opcionalmente el interceptor/filter como APP_INTERCEPTOR/APP_FILTER. |

Interceptor / Filter

| Export | Descripción | |---|---| | ResponseEnvelopeInterceptor | Envuelve toda respuesta en { data } (idempotente). Produce ApiResponse<T>. | | HttpExceptionFilter | Normaliza errores a { error, statusCode, path, timestamp }. Loguea los 5xx. |

Tipos

| Export | Forma | |---|---| | ApiResponse<T> | { data: T; error?: string } | | ApiErrorResponse | { error, statusCode, path, timestamp } | | Paginated<T> | { items: T[]; total; page; pageSize } | | BootstrapOptions | opciones de bootstrapQuadcoreApp (globalPrefix, port, corsOrigin, useResponseEnvelope, useExceptionFilter, useHelmet, swagger?: { title, version?, description?, path? }, beforeListen) |

Flujo de una respuesta

Request → ValidationPipe → Handler → ResponseEnvelopeInterceptor → { data }
          (si hay error) → HttpExceptionFilter → { error, statusCode, path, timestamp }

Rate limiting (throttler)

QuadcoreCoreModule.forRoot() registra @nestjs/throttler como guard global por IP (default 100 req/min), cubriendo las rutas públicas (creación de órdenes/pagos, validación de cupones, alta de tickets). Configurable o desactivable:

QuadcoreCoreModule.forRoot({ throttle: { ttl: 60000, limit: 100 } }); // default
QuadcoreCoreModule.forRoot({ throttle: false });                       // sin rate-limit

Por ruta podés afinar con @Throttle() / @SkipThrottle() de @nestjs/throttler.

Swagger / OpenAPI

Una línea en bootstrapQuadcoreApp habilita /api/docs (Swagger UI + spec OpenAPI):

bootstrapQuadcoreApp(AppModule, {
  swagger: { title: 'Mi API', version: '1.0', description: 'API de mi tienda' },
});

Sin la opción swagger, no se registra ningún endpoint ni se genera ningún documento — DocumentBuilder/SwaggerModule.setup simplemente no se llaman. @nestjs/swagger en sí sí queda instalado para cualquiera que instale core-server (es dependency, no peer, mismo criterio que @nestjs/throttler) — lo que la opción evita es el costo de configurarlo vos, no el de tenerlo en node_modules. path es configurable (default: ${globalPrefix}/docs, ej. api/docs).

Los DTOs necesitan decoradores @ApiProperty()/@ApiPropertyOptional() (de @nestjs/swagger) para aparecer con detalle en el spec — sin ellos, Swagger igual arranca pero los campos del body no se documentan. @quadcore-lib/products-server tiene CreateProductDto totalmente anotado como referencia (UpdateProductDto extends PartialType(CreateProductDto), mismo patrón recomendado para el resto: derivar el DTO de update del de create en vez de duplicar decoradores). El resto de los paquetes todavía no tiene sus DTOs anotados — es mecánico (sin decisiones de diseño), podés hacerlo incrementalmente paquete por paquete siguiendo ese mismo patrón.

Migraciones de DB

bootstrapQuadcoreApp no configura TypeORM — cada proyecto arma su propio TypeOrmModule.forRoot(...) (o DataSource) en su AppModule/data-source.ts, combinando las entidades de los paquetes de @quadcore-lib que instale. Las migraciones siguen el mismo criterio: cada paquete que define entidades trae sus propias migraciones en dist/src/migrations/*.js (compiladas junto al resto del paquete, mismo tsc), y el consumidor las junta en su DataSource.

Como ningún paquete usa FK entre tablas de distintos paquetes (referencias sueltas por id — ver "Lo que ya está bien" en el roadmap), no importa en qué orden corran las migraciones de paquetes distintos entre sí. Dentro de un mismo paquete si hay FK real (ej. orders-server: order_itemsorders), eso ya está resuelto en un único archivo de migración por paquete.

Setup en el proyecto consumidor

npm install -D typeorm ts-node
// data-source.ts (raíz del proyecto)
import 'reflect-metadata';
import { DataSource } from 'typeorm';
import { UserEntity } from '@quadcore-lib/auth-server';
import { ProductEntity } from '@quadcore-lib/products-server';
import { OrderEntity, OrderItemEntity } from '@quadcore-lib/orders-server';
// ...una entidad por cada paquete que instalaste

export const AppDataSource = new DataSource({
  type: 'postgres',
  url: process.env.DATABASE_URL,
  synchronize: false, // ver nota abajo
  entities: [UserEntity, ProductEntity, OrderEntity, OrderItemEntity /* ... */],
  migrations: [
    'node_modules/@quadcore-lib/auth-server/dist/src/migrations/*.js',
    'node_modules/@quadcore-lib/products-server/dist/src/migrations/*.js',
    'node_modules/@quadcore-lib/orders-server/dist/src/migrations/*.js',
    // ...un glob por cada paquete instalado que tenga entidades
    'dist/migrations/*.js', // las tuyas propias, si tenés
  ],
});
npx typeorm-ts-node-commonjs migration:run -d data-source.ts

typeorm-ts-node-commonjs es un bin que ya viene incluido dentro del paquete typeorm (no es un paquete npm aparte que haya que instalar) — por eso no aparece en el npm install de arriba.

Los paquetes sin entidades (core-server, mailer-server, storage-server, jobs-server, y los providers reales — storage-s3, mailer-resend, jobs-bullmq, payments-mercadopago) no tienen migrations/, no hace falta listarlos.

synchronize: true vs. migraciones

synchronize: true (auto-sync del schema contra las entidades) es cómodo en desarrollo pero no se recomienda en producción: puede aplicar cambios destructivos sin aviso y no dos instancias corriendo synchronize: true a la vez se pisan entre sí. La librería en sí misma no fuerza ningún default (no hay código que setee synchronize, es 100% config del consumidor) — la recomendación es synchronize: true en dev/test, false + migration:run en staging/producción.

Generar tus propias migraciones (para tus entidades, no las de la librería)

Si tu proyecto define entidades propias además de las de @quadcore-lib/*, generalas con TypeORM CLI de la forma estándar (necesita una DB de dev con synchronize:true para diffear contra):

npx typeorm-ts-node-commonjs migration:generate ./src/migrations/MiCambio -d data-source.ts

Máquina de estados (assertTransition)

Helper para enforzar transiciones de estado: assertTransition(map, from, to) no-opea si from===to y lanza 400 si la transición no está en el mapa. Lo usan orders y tickets.