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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@jackiemacklein/nettz-utils

v1.2.9

Published

Serviços de imagem, e-mail, códigos de barras, utilitários numéricos e componentes React para apps Node.js com TypeScript

Downloads

257

Readme

📦 @jackiemacklein/nettz-utils

Biblioteca com serviços utilitários para aplicações Node.js/TypeScript, incluindo:

  • 📸 Processamento de Imagens com sharp (Backend)
  • 📧 Envio de E-mails via SMTP com nodemailer (Backend)
  • 🏷️ Análise de Códigos de Barras (Boletos e Tributos) (Web + Backend)
  • 🔢 Utilitários Numéricos (Conversão de valores monetários) (Web + Backend)
  • 🎨 ImageUtils - Análise de brilho de imagens (Web)
  • 📊 OnTable - Componente de tabela avançada com React (Web)
  • 🛠️ Utils - Utilitários para banco de dados (Backend)

📦 Instalação

npm install @jackiemacklein/nettz-utils
# ou
yarn add @jackiemacklein/nettz-utils

🌐 Compatibilidade

🔧 Backend (Node.js)

// Importação completa (Node.js)
import nettzUtils from "@jackiemacklein/nettz-utils";

// Ou importação específica para backend
import {
  Image,
  Mail,
  Number,
  Utils,
} from "@jackiemacklein/nettz-utils/backend";

// Utilitários de banco de dados
import { buildWhereConditions } from "@jackiemacklein/nettz-utils/Utils";

🌍 Web (Browser + Node.js)

// Importação específica para web
import {
  Barcode,
  Number,
  OnTable,
  ImageUtils,
} from "@jackiemacklein/nettz-utils/web";

// Componente OnTable
import OnTable from "@jackiemacklein/nettz-utils/OnTable";

// Ou importação individual
import { analyzeBarcode } from "@jackiemacklein/nettz-utils/web";
import { toInteger, fromInteger } from "@jackiemacklein/nettz-utils/web";
import { detectImageBrightness } from "@jackiemacklein/nettz-utils/web";

📖 Para mais detalhes sobre compatibilidade, consulte COMPATIBILITY.md


📊 OnTable (Web)

Componente React avançado para exibição de tabelas com funcionalidades completas de seleção, ordenação, filtragem, paginação e personalização.

✨ Exemplos de uso

import OnTable from "@jackiemacklein/nettz-utils/OnTable";

const columns = [
  { key: "id", label: "ID", type: "number", align: "center", sortable: true },
  {
    key: "name",
    label: "Nome",
    type: "string",
    align: "left",
    filterable: true,
  },
  { key: "email", label: "E-mail", type: "string", align: "left" },
  { key: "status", label: "Status", type: "string", align: "center" },
  { key: "createdAt", label: "Data", type: "date", align: "center" },
];

const data = [
  {
    id: 1,
    name: "João Silva",
    email: "[email protected]",
    status: "Ativo",
    createdAt: "2024-01-15",
  },
  {
    id: 2,
    name: "Maria Santos",
    email: "[email protected]",
    status: "Inativo",
    createdAt: "2024-01-10",
  },
];

function MyTable() {
  return (
    <OnTable
      data={data}
      columns={columns}
      selectable={true}
      onSelectionChange={(selected) => console.log(selected)}
      onSort={(sortConfig) => console.log(sortConfig)}
      onFilter={(filters) => console.log(filters)}
      currentPage={1}
      totalPages={5}
      onPageChange={(page) => console.log(page)}
    />
  );
}

🔧 Funcionalidades disponíveis

| Funcionalidade | Descrição | | --------------- | --------------------------------------- | | Seleção | Seleção individual e múltipla de linhas | | Ordenação | Ordenação por múltiplas colunas | | Filtragem | Filtros avançados por coluna | | Paginação | Paginação com navegação intuitiva | | Colunas | Mostrar/ocultar colunas dinamicamente | | Drag & Drop | Reordenação de colunas por arraste | | Responsivo | Design adaptável para mobile | | Loading | Estado de carregamento | | Ações | Ações personalizadas por linha/célula |

📋 Propriedades principais

interface TableProps<T> {
  data: T[]; // Dados da tabela
  columns: Column<T>[]; // Configuração das colunas
  selectable?: boolean; // Habilita seleção
  onSelectionChange?: (items: T[]) => void;
  onSort?: (config: SortConfig[]) => void;
  onFilter?: (filters: Record<string, string>) => void;
  currentPage?: number; // Página atual
  totalPages?: number; // Total de páginas
  onPageChange?: (page: number) => void;
  loading?: boolean; // Estado de carregamento
  customButtons?: React.ReactNode; // Botões personalizados
}

🎨 Componentes incluídos

  • Button: Botões com variantes e tamanhos
  • Modal: Modal responsivo para filtros
  • Form: Formulários com validação
  • Pagination: Paginação avançada
  • Popover: Popover para seleção de colunas

🛠️ Utils (Backend)

Utilitários para construção de consultas SQL e filtros de banco de dados.

✨ Exemplos de uso

import { buildWhereConditions } from "@jackiemacklein/nettz-utils/Utils";

// Filtros simples
const filters = {
  name: "João Silva",
  age: { value: 18, operator: ">" },
  status: { value: ["ACTIVE", "PENDING"], operator: "in" },
};

const whereConditions = buildWhereConditions(filters, {
  mainTable: "users",
  useUnaccent: true,
});

console.log(whereConditions);
// [
//   "unaccent(users.name) ilike unaccent('%João Silva%')",
//   "users.age > 18",
//   "users.status = ANY(ARRAY[ACTIVE,PENDING])"
// ]

🔧 Operadores suportados

| Operador | Descrição | Exemplo | | --------- | ------------------------- | ------------------------------------------- | | = | Igual | { value: "ativo", operator: "=" } | | != | Diferente | { value: "inativo", operator: "!=" } | | > | Maior que | { value: 18, operator: ">" } | | >= | Maior ou igual | { value: 18, operator: ">=" } | | < | Menor que | { value: 65, operator: "<" } | | <= | Menor ou igual | { value: 65, operator: "<=" } | | like | Contém (case sensitive) | { value: "silva", operator: "like" } | | ilike | Contém (case insensitive) | { value: "silva", operator: "ilike" } | | in | Está em lista | { value: ["A", "B"], operator: "in" } | | not in | Não está em lista | { value: ["X", "Y"], operator: "not in" } | | between | Entre valores | { value: [10, 20], operator: "between" } |

📋 Opções de configuração

interface WhereBuilderOptions {
  mainTable?: string; // Tabela principal
  useUnaccent?: boolean; // Usar função unaccent
  customConditions?: string[]; // Condições customizadas
}

📸 ImageService (Backend)

Classe utilitária para manipulação de imagens usando sharp.

✨ Exemplos de uso

import ImageService from "@jackiemacklein/nettz-utils/backend";
import fs from "fs";

const imageService = new ImageService();
const buffer = fs.readFileSync("input.jpg");

(async () => {
  const resized = await imageService.resize(buffer, 800, 600);
  fs.writeFileSync("resized.jpg", resized);

  const base64 = await imageService.toBase64(resized, "jpeg");
  console.log(base64);
})();

🔧 Métodos disponíveis

| Método | Descrição | | ------------------------ | ---------------------------------------- | | resize | Redimensiona mantendo proporção | | crop | Recorta com dimensões fixas | | compress | Comprime imagem com qualidade ajustável | | convert | Converte formato (jpeg, png, webp) | | addWatermark | Adiciona uma marca d'água | | toBase64 | Converte Buffer para base64 com header | | fromBase64 | Converte base64 para Buffer | | processAndReturnBase64 | Redimensiona, converte e retorna base64 |


📧 EmailService (Backend)

Classe Singleton para envio de e-mails usando SMTP.

⚙️ Configuração

Você precisa informar os parâmetros SMTP dinamicamente com setParameters():

import { EmailService } from "@jackiemacklein/nettz-utils/backend";

EmailService.setParameters({
  SMTP_INTEGRATION: "true",
  SMTP_PROVIDER: "Outlook", // "Gmail", "Outros", "Brevo"
  SMTP_HOST: "smtp.office365.com",
  SMTP_PORT: "587",
  SMTP_SECURITY: "STARTTLS",
  SMTP_USERNAME: "[email protected]",
  SMTP_PASSWORD: "senha",
  SMTP_FROM_NAME: "Minha App",
  SMTP_FROM_EMAIL: "[email protected]",
});

✉️ Enviando um e-mail simples

await EmailService.sendSimpleEmail(
  "[email protected]",
  "Assunto do e-mail",
  "Mensagem em texto ou HTML",
  true // define se é HTML
);

📑 Enviando com opções avançadas

await EmailService.sendEmail({
  to: ["[email protected]"],
  subject: "Assunto",
  html: "<h1>Olá</h1>",
  attachments: [
    {
      filename: "file.pdf",
      content: fs.readFileSync("file.pdf"),
    },
  ],
});

🏷️ BarcodeService (Web + Backend)

Módulo para análise e validação de códigos de barras brasileiros, incluindo boletos bancários e tributos.

✨ Exemplos de uso

import {
  analyzeBarcode,
  convertLineToBarcode,
} from "@jackiemacklein/nettz-utils/web";

// Analisando um código de barras
const barcode = "23793381286000000063305974530006339000063300";
const result = analyzeBarcode(barcode);

console.log(result);
// {
//   isValid: true,
//   type: "boleto_bancario",
//   value: "633.90",
//   dueDate: "15/12/2023"
// }

// Convertendo linha digitável para código de barras
const linhaDigitavel = "23793.38128 60000.000633 05974.530006 3 39000063300";
const codigoBarras = convertLineToBarcode(linhaDigitavel);
console.log(codigoBarras); // "23793381286000000063305974530006339000063300"

🔧 Métodos disponíveis

| Método | Descrição | | ---------------------- | ---------------------------------------------- | | analyzeBarcode | Analisa e valida códigos de barras | | convertLineToBarcode | Converte linha digitável para código de barras | | validateDVModulo11 | Valida dígito verificador (módulo 11) | | checkBarcodeType | Identifica o tipo de código de barras |

📋 Tipos de Códigos Suportados

  • Boleto Bancário: Códigos de 44 ou 47 dígitos (linha digitável)
  • Tributo: Códigos de 44, 47 ou 48 dígitos que começam com "8"

📊 Estrutura de Retorno

interface BarcodeResult {
  isValid: boolean; // Se o código é válido
  type: BarcodeType; // Tipo do código (boleto_bancario, tributo, formato_invalido)
  value: string; // Valor em reais (formato "0.00")
  dueDate: string | null; // Data de vencimento (apenas para boletos)
}

interface BarcodeResultError {
  isValid: boolean; // Sempre false
  type: BarcodeType; // Tipo do erro
  value?: string; // Valor (se disponível)
  message: string; // Mensagem de erro
}

🔢 NumberService (Web + Backend)

Utilitários para conversão segura de valores numéricos, especialmente para valores monetários. Salva tudo como inteiro (centavos, gramas, etc.) evitando problemas de ponto flutuante.

✨ Exemplos de uso

import { toInteger, fromInteger } from "@jackiemacklein/nettz-utils/web";

// Convertendo string para inteiro (centavos)
const valor = toInteger("1.100.098,90"); // 110009890
const valorNegativo = toInteger("(934,33)"); // -93433

// Convertendo de volta para string formatada
const formatado = fromInteger(110009890, 2, "pt-BR", "BRL"); // "R$ 1.100.098,90"
const negativo = fromInteger(-93433, 2, "pt-BR", "BRL"); // "-R$ 934,33"

// Outros formatos
const dolares = fromInteger(100000, 2, "en-US", "USD"); // "$1,000.00"
const gramas = fromInteger(1500, 3, "pt-BR"); // "1,500"

🔧 Métodos disponíveis

| Método | Descrição | | ------------- | ----------------------------------------------- | | toInteger | Converte string/numero para inteiro (centavos) | | fromInteger | Converte inteiro de volta para string formatada |

📋 Formatos Aceitos

Entrada (toInteger):

  • ✅ Vírgula ou ponto como separador decimal: "1.234,56" ou "1,234.56"
  • ✅ Separadores de milhar: "1.100.098,90"
  • ✅ Negativos com - ou parênteses: "-123,45" ou "(123,45)"
  • ✅ Números já numéricos: 1234.56

Saída (fromInteger):

  • ✅ Formato monetário: "R$ 1.234,56"
  • ✅ Formato numérico: "1.234,56"
  • ✅ Locale configurável: "pt-BR", "en-US", etc.
  • ✅ Moeda configurável: "BRL", "USD", "EUR", etc.

⚙️ Parâmetros

toInteger(value, scale = 2)

  • value: Valor a ser convertido (string, number, etc.)
  • scale: Casas decimais (2 = centavos, 3 = milésimos, etc.)

fromInteger(value, scale = 2, locale = "pt-BR", currency?)

  • value: Inteiro salvo (ex.: centavos)
  • scale: Casas decimais que o inteiro representa
  • locale: Locale para formatação
  • currency: Moeda opcional ("BRL", "USD", etc.)

💡 Casos de Uso

// E-commerce - Preços
const preco = toInteger("R$ 1.299,99"); // 129999
const precoFormatado = fromInteger(129999, 2, "pt-BR", "BRL"); // "R$ 1.299,99"

// Contabilidade - Valores negativos
const despesa = toInteger("(2.450,67)"); // -245067
const despesaFormatada = fromInteger(-245067, 2, "pt-BR", "BRL"); // "-R$ 2.450,67"

// Medidas - Gramas/Miligramas
const peso = toInteger("1.500,250", 3); // 1500250 (miligramas)
const pesoFormatado = fromInteger(1500250, 3, "pt-BR"); // "1.500,250"

🧪 Teste de Conexão SMTP

const result = await EmailService.testConnection();
console.log(result);

✅ Tipagem incluída

Essa biblioteca é escrita em TypeScript e inclui tipagens automáticas ao instalar.


📄 Licença

Todos os direitos reservados © Jackiê Macklein • Onside Tecnologia / Nettz


💬 Contato

Tem dúvidas ou sugestões? Entre em contato: