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

@innv/nexus

v0.3.0

Published

Cliente HTTP declarativo e type-safe para NestJS, parte do ecossistema innv-genesis.

Downloads

16

Readme

@innv/nexus

Cliente HTTP declarativo, type-safe e com tratamento de erro explícito para NestJS, parte do ecossistema innv-genesis.

@innv/nexus transforma a maneira como você consome APIs externas em uma aplicação NestJS. Em vez de injetar HttpService e construir requisições manualmente, você define uma interface abstrata com decorators, e o Nexus cuida de toda a implementação, validação e tratamento de erro para você.


🚀 Core Features

Totalmente Declarativo: Defina suas APIs usando decorators (@ApiClient, @Get, @Post, @Path, @Body, etc.).

🛡️ Type-Safe de Ponta a Ponta: Retorna um tipo Result<T, E>, forçando você a tratar explicitamente os casos de sucesso (Ok<T>) e de erro (Err<E>).

🤖 Validação Automática: Valida automaticamente DTOs de erro (via @ErrorResponse) usando class-validator, garantindo que até seus erros sejam type-safe.

⚙️ Integrado ao NestJS: Integra-se perfeitamente com o ConfigService do NestJS para resolver URLs base, timeouts e mais a partir de variáveis de ambiente.

🔍 Auto-Discovery: Quando usado com @innv/nest-initializer, seus clientes de API são descobertos e registrados automaticamente na injeção de dependência.


📦 Instalação

# Usando pnpm (recomendado)
pnpm add @innv/nexus reflect-metadata

# Usando npm
npm install @innv/nexus reflect-metadata

# Usando yarn
yarn add @innv/nexus reflect-metadata

Peer Dependencies

O @innv/nexus requer que você tenha as seguintes bibliotecas em seu projeto:

  • @nestjs/common
  • @nestjs/core
  • reflect-metadata

Se você planeja usar a resolução de configuração via variáveis de ambiente (recomendado), você também precisará:

  • @nestjs/config

⚙️ Configuração (Setup)

Importe o NexusModule no seu módulo raiz (ex: AppModule) para prover os serviços internos que o Nexus utiliza.

// src/app.module.ts
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { NexusModule } from '@innv/nexus';

@Module({
  imports: [ConfigModule.forRoot({ isGlobal: true }), NexusModule],
})
export class AppModule {}

🧠 Guia de Uso Completo

Passo 1: Definir os DTOs

// src/users/dtos/user.dto.ts
import { Expose } from 'class-transformer';
import { IsInt, IsString, IsEmail } from 'class-validator';

export class UserDto {
  @Expose() @IsInt() id!: number;
  @Expose() @IsString() name!: string;
  @Expose() @IsEmail() email!: string;
}
// src/users/dtos/user-api-error.dto.ts
import { Expose } from 'class-transformer';
import { IsString, IsArray } from 'class-validator';

export class NotFoundErrorDto {
  @Expose() @IsString() message!: string;
  @Expose() @IsString() errorCode: string = 'NOT_FOUND';
}

export class ValidationErrorDto {
  @Expose() @IsString() message: string = 'Validation Failed';
  @Expose() @IsArray() @IsString({ each: true }) fields!: string[];
}

Passo 2: Definir a Interface do Cliente

// src/users/users.client.ts
import { ApiClient, Get, Post, Path, Query, Body, Header, ErrorResponse, Result } from '@innv/nexus';
import { UserDto } from './dtos/user.dto';
import { NotFoundErrorDto, ValidationErrorDto } from './dtos/user-api-error.dto';

@ApiClient({ baseUrlEnvKey: 'USERS_API_URL', timeoutEnvKey: 'USERS_API_TIMEOUT' })
export abstract class UsersApiClient {
  @Get('/users/:id')
  @ErrorResponse(404, NotFoundErrorDto)
  getUserById(
    @Path('id') id: number,
    @Query('includeDetails') details?: boolean,
    @Header('X-Tenant-Id') tenantId?: string,
  ): Promise<Result<UserDto, NotFoundErrorDto>>;

  @Post('/users')
  @ErrorResponse(400, ValidationErrorDto)
  createUser(@Body() user: Omit<UserDto, 'id'>): Promise<Result<UserDto, ValidationErrorDto>>;
}

Passo 3: Registrar o Cliente

Opção A: Registro Automático (Recomendado)

await AppInitializer.bootstrap(AppModule, (app) => {
  app.withAutoDiscovery({ basePath: __dirname });
});

Opção B: Registro Manual

// src/users/users.module.ts
import { Module } from '@nestjs/common';
import { createNexusClientProvider } from '@innv/nexus';
import { UsersApiClient } from './users.client';
import { UsersService } from './users.service';

@Module({
  providers: [UsersService, createNexusClientProvider(UsersApiClient)],
  exports: [UsersService],
})
export class UsersModule {}

Passo 4: Usar o Cliente em um Serviço

// src/users/users.service.ts
import { Injectable, NotFoundException } from '@nestjs/common';
import { UsersApiClient } from './users.client';
import { UserDto } from './dtos/user.dto';

@Injectable()
export class UsersService {
  constructor(private readonly usersApi: UsersApiClient) {}

  async findUser(id: number): Promise<UserDto> {
    const result = await this.usersApi.getUserById(id);
    if (result.isOk) return result.value;
    throw new NotFoundException(result.error.message);
  }
}

🧩 Referência da API (Decorators)

@ApiClient(options: ApiClientOptions)

Define um cliente HTTP.
Opções:

| Opção | Tipo | Obrigatório | Descrição | | :------------ | :--------------------- | :--------------------- | :-------------------------------------- | | baseUrl | string | Sim (ou baseUrlEnvKey) | URL base da API | | baseUrlEnvKey | string | Sim (ou baseUrl) | Chave de ambiente para URL | | timeout | number | Não | Timeout fixo (ms) | | timeoutEnvKey | string | Não | Timeout via variável de ambiente | | staticHeaders | Record<string, string> | Não | Headers fixos para todas as requisições |

Decorators de Método

  • @Get(path: string)
  • @Post(path: string)
  • @Put(path: string)
  • @Patch(path: string)
  • @Delete(path: string)

Decorators de Parâmetro

  • @Path(name: string)
  • @Query(name: string)
  • @Body()
  • @Header(name: string)

Decorator de Erro

  • @ErrorResponse(status: number, dto: Type<any>)

📜 Licença

Distribuído sob a licença MIT. Veja o arquivo LICENSE para mais informações.