@jackiemacklein/nettz-utils
Version:
Serviços de imagem, e-mail, códigos de barras, utilitários numéricos e componentes React para apps Node.js com TypeScript
483 lines (367 loc) • 14.4 kB
Markdown
# 📦 @jackiemacklein/nettz-utils
Biblioteca com serviços utilitários para aplicações Node.js/TypeScript, incluindo:
- 📸 Processamento de Imagens com [sharp](https://www.npmjs.com/package/sharp) _(Backend)_
- 📧 Envio de E-mails via SMTP com [nodemailer](https://www.npmjs.com/package/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
```bash
npm install @jackiemacklein/nettz-utils
# ou
yarn add @jackiemacklein/nettz-utils
```
## 🌐 Compatibilidade
### 🔧 Backend (Node.js)
```ts
// 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)
```ts
// 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](./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
```tsx
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: "joao@exemplo.com",
status: "Ativo",
createdAt: "2024-01-15",
},
{
id: 2,
name: "Maria Santos",
email: "maria@exemplo.com",
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
```tsx
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
```ts
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
```ts
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
```ts
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()`:
```ts
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@dominio.com",
SMTP_PASSWORD: "senha",
SMTP_FROM_NAME: "Minha App",
SMTP_FROM_EMAIL: "email@dominio.com",
});
```
### ✉️ Enviando um e-mail simples
```ts
await EmailService.sendSimpleEmail(
"destinatario@exemplo.com",
"Assunto do e-mail",
"Mensagem em texto ou HTML",
true // define se é HTML
);
```
### 📑 Enviando com opções avançadas
```ts
await EmailService.sendEmail({
to: ["user@exemplo.com"],
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
```ts
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
```ts
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
```ts
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
```ts
// 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
```ts
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](mailto:jackiemacklein@gmail.com) • Onside Tecnologia / Nettz
## 💬 Contato
Tem dúvidas ou sugestões? Entre em contato:
- 📧 jackiemacklein@gmail.com
- 🌐 [onsidetecnologia.com.br](https://onsidetecnologia.com.br)