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

nest-validation-view

v0.2.5

Published

NestJS exception filter and decorator for rendering validation errors back to server-side views.

Readme

nest-validation-view

Filtro e decorator para aplicações NestJS que usam views server-side e precisam renderizar erros de validação de volta no formulário.

Instalação

npm install nest-validation-view

Uso

Configure o ValidationPipe para usar o payload de erros do pacote:

import { BadRequestException, ValidationPipe } from '@nestjs/common';
import { buildValidationErrorPayload } from 'nest-validation-view';

app.useGlobalPipes(
  new ValidationPipe({
    whitelist: true,
    transform: true,
    exceptionFactory: (errors) =>
      new BadRequestException(buildValidationErrorPayload(errors)),
  }),
);

Use o decorator no controller. No POST de criação, a view volta para o formulário de cadastro com os dados enviados:

import { Body, Controller, Post } from '@nestjs/common';
import { ValidationView, toBoolean } from 'nest-validation-view';

@Controller('produtos')
export class ProdutoController {
  @Post()
  @ValidationView('produto/criar', ({ request, errors }) => ({
    produto: {
      ...request.body,
      ativo: toBoolean(request.body.ativo, true),
    },
    errors,
  }))
  create(@Body() body: unknown) {
    return body;
  }
}

No POST de atualização, use a mesma ideia para voltar para a view de edição. Se a rota tiver :id, repasse o id para a view junto com os dados do formulário:

import { Body, Controller, Param, Post } from '@nestjs/common';
import { ValidationView, toBoolean } from 'nest-validation-view';

@Controller('produtos')
export class ProdutoController {
  @Post(':id')
  @ValidationView('produto/editar', ({ request, errors }) => ({
    produto: {
      id: request.params.id,
      ...request.body,
      ativo: toBoolean(request.body.ativo, false),
    },
    errors,
  }))
  update(@Param('id') id: string, @Body() body: unknown) {
    return { id, ...body };
  }
}

Para usar o helper nas views, registre validationErrorsHelper nos locals do Express. Assim a view pode chamar validationErrors(locals.errors) sem quebrar quando ainda não houver erros:

import { type Application } from 'express';
import {
  type ValidationErrorsViewModel,
  validationErrorsHelper,
} from 'nest-validation-view';

type ViewHelpers = {
  validationErrors: (
    errors: ValidationErrorsViewModel | null | undefined,
  ) => ValidationErrorsViewModel;
};

export const registerHelpers = (app: Application): void => {
  const helpers: ViewHelpers = {
    validationErrors: validationErrorsHelper,
  };

  Object.assign(app.locals, helpers);
};

Depois chame esse registro na inicialização da aplicação:

const expressApp = app.getHttpAdapter().getInstance();
registerHelpers(expressApp);

Formas de usar errors na view

Em uma view EJS, normalize os erros uma vez no inicio do arquivo. Todos os exemplos abaixo partem dessa variável:

<% const erros = validationErrors(locals.errors); %>

Esse objeto sempre tem o mesmo formato, mesmo quando não houver erros:

type ValidationErrorsViewModel = {
  all: string[];
  fields: Record<string, string[]>;
  get: (field: string) => string[];
  first: (field: string) => string | null;
  has: (field: string) => boolean;
};

Resumo com todos os erros usando erros.all:

<% if (erros.all.length) { %>
  <div class="alert alert-danger">
    <h5>Nao foi possivel salvar.</h5>
    <ul>
      <% erros.all.forEach((mensagem) => { %>
        <li><%= mensagem %></li>
      <% }) %>
    </ul>
  </div>
<% } %>

Campo com classe de erro usando erros.has('campo'):

<input
  type="text"
  name="nome"
  class="form-control <%= erros.has('nome') ? 'is-invalid' : '' %>"
  value="<%= locals.formData?.nome || '' %>"
>

Primeira mensagem de um campo usando erros.first('campo'):

<% if (erros.has('nome')) { %>
  <div class="invalid-feedback d-block">
    <%= erros.first('nome') %>
  </div>
<% } %>

Todas as mensagens de um campo usando erros.get('campo'):

<% erros.get('preco').forEach((mensagem) => { %>
  <div class="invalid-feedback d-block">
    <%= mensagem %>
  </div>
<% }) %>

Todos os campos que possuem erro usando erros.fields:

<% Object.entries(erros.fields).forEach(([campo, mensagens]) => { %>
  <strong><%= campo %></strong>
  <ul>
    <% mensagens.forEach((mensagem) => { %>
      <li><%= mensagem %></li>
    <% }) %>
  </ul>
<% }) %>

Campos aninhados usam o caminho completo gerado pela validação:

<% if (erros.has('endereco.cep')) { %>
  <div class="invalid-feedback d-block">
    <%= erros.first('endereco.cep') %>
  </div>
<% } %>

Se quiser importar apenas tipos, use o subpath types:

import type {
  ValidationErrorsViewModel,
  ValidationFieldErrors,
  ValidationViewMetadata,
} from 'nest-validation-view/types';

Também é possível importar módulos específicos quando quiser reduzir a superfície do import:

import { buildValidationErrorPayload } from 'nest-validation-view/validation-errors';
import { validationErrorsHelper } from 'nest-validation-view/validation-errors.helper';
import { ValidationView } from 'nest-validation-view/validation-view.decorator';
import { ValidationViewFilter } from 'nest-validation-view/validation-view.filter';

API

  • ValidationView(view, data?, statusCode?): adiciona metadados para o filtro renderizar a view quando houver BadRequestException.
  • ValidationViewFilter: filtro NestJS usado internamente pelo decorator para capturar erros de validação e renderizar a view configurada.
  • buildValidationErrorPayload(errors): converte ValidationError[] em { message, fieldErrors }.
  • validationErrorsHelper(errors): garante um objeto de erros seguro para uso nas views, mesmo quando errors for null ou undefined.
  • toBoolean(value, defaultValue): normaliza valores comuns de formulário como true, "true" e "on".

Changelog

0.2.5 - 06/05/2026

  • Reorganizada a documentação de uso de errors nas views.
  • Removida a seção de publicação do README para evitar confusão no uso do pacote.
  • Documentados exemplos mais claros para erros.all, erros.has, erros.first, erros.get, erros.fields e campos aninhados.

0.2.4 - 06/05/2026

  • Adicionado exemplo de registro do validationErrorsHelper nos locals do Express.
  • Adicionado exemplo de uso do helper em views EJS com validationErrors(locals.errors).
  • Documentado o fluxo de inicialização com registerHelpers(expressApp).

0.2.3 - 06/05/2026

  • Adicionado o novo módulo validation-errors.helper.
  • Exportados validationErrorsHelper, ensureValidationErrorsViewModel, createEmptyValidationErrorsViewModel e seus tipos pelo import principal do pacote.
  • Adicionado o subpath nest-validation-view/validation-errors.helper para importação direta do helper.
  • Atualizado o typesVersions para resolver os tipos do novo helper no TypeScript.
  • Melhorado o buildValidationErrorPayload para mesclar mensagens repetidas por campo e evitar mensagens duplicadas no array message.
  • Documentado o novo helper nos exemplos de importação e na API.