Compare commits
No commits in common. "master" and "compatibilidade" have entirely different histories.
master
...
compatibil
63 changed files with 1413 additions and 2472 deletions
0
.gitignore
vendored
Executable file → Normal file
0
.gitignore
vendored
Executable file → Normal file
0
.npmignore
Executable file → Normal file
0
.npmignore
Executable file → Normal file
0
.npmrc
Executable file → Normal file
0
.npmrc
Executable file → Normal file
23
.vscode/settings.json
vendored
Executable file → Normal file
23
.vscode/settings.json
vendored
Executable file → Normal file
|
|
@ -4,10 +4,8 @@
|
||||||
"source.fixAll.biome": "always"
|
"source.fixAll.biome": "always"
|
||||||
},
|
},
|
||||||
"editor.defaultFormatter": "biomejs.biome",
|
"editor.defaultFormatter": "biomejs.biome",
|
||||||
"editor.formatOnSave": true,
|
|
||||||
|
|
||||||
"[javascript]": {
|
"[javascript]": {
|
||||||
"editor.defaultFormatter": "biomejs.biome"
|
"editor.defaultFormatter": "vscode.typescript-language-features"
|
||||||
},
|
},
|
||||||
"[javascriptreact]": {
|
"[javascriptreact]": {
|
||||||
"editor.defaultFormatter": "biomejs.biome"
|
"editor.defaultFormatter": "biomejs.biome"
|
||||||
|
|
@ -25,21 +23,6 @@
|
||||||
"editor.defaultFormatter": "biomejs.biome"
|
"editor.defaultFormatter": "biomejs.biome"
|
||||||
},
|
},
|
||||||
"[vue]": {
|
"[vue]": {
|
||||||
"editor.defaultFormatter": "biomejs.biome"
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
},
|
}
|
||||||
"[css]": {
|
|
||||||
"editor.defaultFormatter": "biomejs.biome"
|
|
||||||
},
|
|
||||||
"[html]": {
|
|
||||||
"editor.defaultFormatter": "biomejs.biome"
|
|
||||||
},
|
|
||||||
|
|
||||||
"typescript.preferences.importModuleSpecifier": "relative",
|
|
||||||
"typescript.suggest.autoImports": true,
|
|
||||||
"typescript.updateImportsOnFileMove.enabled": "always",
|
|
||||||
|
|
||||||
"editor.rulers": [100],
|
|
||||||
"files.eol": "\n",
|
|
||||||
"files.trimTrailingWhitespace": true,
|
|
||||||
"files.insertFinalNewline": true
|
|
||||||
}
|
}
|
||||||
234
AGENTS.md
234
AGENTS.md
|
|
@ -1,234 +0,0 @@
|
||||||
# AGENTS.md — Guia para Assistentes de IA
|
|
||||||
|
|
||||||
> **Este arquivo descreve os padrões, convenções e arquitetura do projeto `p-comuns`.**
|
|
||||||
> Leia este arquivo antes de sugerir ou gerar qualquer código.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🏗️ Visão Geral do Projeto
|
|
||||||
|
|
||||||
`p-comuns` é um **pacote compartilhado** (npm monorepo-like) usado como dependência em todos os subprojetos da plataforma **e-licencie**. Ele provê:
|
|
||||||
|
|
||||||
- Tipos TypeScript compartilhados (rotas, filtros, situações, UUIDs...)
|
|
||||||
- Utilitários de back-end (postgres, cache em memória, dayjs...)
|
|
||||||
- Utilitários de front-end (Vue 3 + TSX)
|
|
||||||
- Constantes e enums globais
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ⚙️ Stack Tecnológica
|
|
||||||
|
|
||||||
| Camada | Tecnologia | Versão |
|
|
||||||
|--------|-----------|--------|
|
|
||||||
| Linguagem | TypeScript | ~5.9.x |
|
|
||||||
| Runtime (back) | Node.js | ≥20 |
|
|
||||||
| Framework (front) | Vue 3 | Composition API + `<script setup>` |
|
|
||||||
| JSX/TSX | Vue TSX / React-like TSX | via `jsxRuntime` |
|
|
||||||
| Linter/Formatter | Biome | 2.4.x |
|
|
||||||
| Bundler | tsup | 8.x |
|
|
||||||
| Package manager | pnpm | com workspaces |
|
|
||||||
| Validação | Zod | 4.x |
|
|
||||||
| Utilitários de data | dayjs | 1.11.x |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📁 Estrutura do `src/`
|
|
||||||
|
|
||||||
```
|
|
||||||
src/
|
|
||||||
├── index.ts # Entry point — exporta tudo que é público
|
|
||||||
├── constantes.ts # Constantes globais (enums, valores fixos)
|
|
||||||
├── situacoes.ts # Status/situações dos processos
|
|
||||||
├── tipagemRotas.ts # Tipagem forte de rotas da API
|
|
||||||
├── tipoFiltro.26.ts # Sistema de filtros tipados (operadores PG)
|
|
||||||
├── uuid.ts # Geração e validação de UUIDs
|
|
||||||
├── dayjs26.ts # Wrapper do dayjs com locale e plugins
|
|
||||||
├── extensoes.ts # Extensões de tipos nativos
|
|
||||||
├── texto_busca.ts # Utilitários de busca em texto
|
|
||||||
├── variaveisComuns.ts # Variáveis de ambiente compartilhadas
|
|
||||||
├── postgres.ts # Cliente PostgreSQL base
|
|
||||||
├── cacheMemoria.ts # Cache em memória (Map com TTL)
|
|
||||||
├── aleatorio.ts # Utilitários de aleatoriedade
|
|
||||||
├── consulta.ts # Helpers de consulta SQL
|
|
||||||
├── instalarAmbiente.ts # Setup de ambiente (dev/prod)
|
|
||||||
├── graficosPilao.ts # Tipos para gráficos do PILÃO
|
|
||||||
├── ecosistema/ # Tipos do ecossistema de módulos
|
|
||||||
└── testes/ # Testes unitários (Vitest)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📐 Convenções de Código
|
|
||||||
|
|
||||||
### TypeScript
|
|
||||||
|
|
||||||
- **Strict mode** SEMPRE ligado (`"strict": true`)
|
|
||||||
- **Sem `any` explícito** — use tipos genéricos ou `unknown`
|
|
||||||
- **Sem `!` (non-null assertion)** — trate o `null`/`undefined` explicitamente
|
|
||||||
- **Arrays**: usar `T[]` em vez de `Array<T>` (shorthand)
|
|
||||||
- **Imports** ordenados automaticamente pelo Biome
|
|
||||||
- **Enums** sempre com inicializadores explícitos
|
|
||||||
- **Parâmetros** não podem ser reatribuídos
|
|
||||||
|
|
||||||
### Nomenclatura
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// Tipos e interfaces: PascalCase
|
|
||||||
type TipoUsuario = { ... }
|
|
||||||
interface IRepositorio { ... }
|
|
||||||
|
|
||||||
// Constantes: camelCase (sem SCREAMING_SNAKE_CASE, exceto enums legados)
|
|
||||||
const configuracaoBase = { ... }
|
|
||||||
|
|
||||||
// Funções: camelCase, verbos
|
|
||||||
const calcularTotal = (itens: Item[]) => { ... }
|
|
||||||
const buscarUsuarioPorId = async (id: UUID) => { ... }
|
|
||||||
|
|
||||||
// Arquivos: camelCase para utilitários, PascalCase para componentes Vue
|
|
||||||
// ✅ tipoFiltro.ts, variaveisComuns.ts
|
|
||||||
// ✅ MeuComponente.vue, BotaoAcao.vue
|
|
||||||
```
|
|
||||||
|
|
||||||
### Vue 3 (Composition API)
|
|
||||||
|
|
||||||
```vue
|
|
||||||
<script setup lang="ts">
|
|
||||||
// Sempre usar <script setup lang="ts">
|
|
||||||
// Macros globais disponíveis (sem import): defineProps, defineEmits,
|
|
||||||
// defineExpose, withDefaults, defineModel, defineOptions, defineSlots
|
|
||||||
|
|
||||||
const props = defineProps<{
|
|
||||||
titulo: string
|
|
||||||
itens: Item[]
|
|
||||||
}>()
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
|
||||||
selecionar: [item: Item]
|
|
||||||
fechar: []
|
|
||||||
}>()
|
|
||||||
</script>
|
|
||||||
```
|
|
||||||
|
|
||||||
- **Sem Vue Options API** — sempre Composition API
|
|
||||||
- **Props não devem ser desestruturadas** (quebra reatividade Vue 3)
|
|
||||||
- **`v-for` sempre com `:key`** — use o ID do item, nunca o índice!
|
|
||||||
- **`v-if` e `v-for` nunca no mesmo elemento** — use `<template v-for>`
|
|
||||||
- **Atributos em multiline** quando há mais de 2 props
|
|
||||||
|
|
||||||
### TSX (componentes em `.tsx`)
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
// Componente funcional Vue em TSX
|
|
||||||
import { defineComponent, ref } from "vue"
|
|
||||||
|
|
||||||
export const MeuComponente = defineComponent({
|
|
||||||
props: {
|
|
||||||
titulo: { type: String, required: true },
|
|
||||||
},
|
|
||||||
setup(props) {
|
|
||||||
const contador = ref(0)
|
|
||||||
return () => (
|
|
||||||
<div class="meu-componente">
|
|
||||||
<h1>{props.titulo}</h1>
|
|
||||||
<button onClick={() => contador.value++}>{contador.value}</button>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔧 Biome — Regras de Lint Importantes
|
|
||||||
|
|
||||||
### Erros (bloqueiam o build)
|
|
||||||
|
|
||||||
| Regra | Descrição |
|
|
||||||
|-------|-----------|
|
|
||||||
| `noUnusedVariables` | Variáveis definidas e não usadas |
|
|
||||||
| `noUnusedImports` | Imports não utilizados |
|
|
||||||
| `noVoidTypeReturn` | Função `void` retornando valor |
|
|
||||||
| `noVueDataObjectDeclaration` | Vue 2 `data: {}` — usar função |
|
|
||||||
| `noVueDuplicateKeys` | Chaves duplicadas em objetos Vue |
|
|
||||||
| `noVueSetupPropsReactivityLoss` | Desestruturar `props` em `setup()` |
|
|
||||||
| `noVueVIfWithVFor` | `v-if` + `v-for` no mesmo elemento |
|
|
||||||
| `useVueVForKey` | `v-for` sem `:key` |
|
|
||||||
| `useVueValidTemplateRoot` | Template sem raiz única (Vue 2) |
|
|
||||||
|
|
||||||
### Warnings (code smells — corrija quando possível)
|
|
||||||
|
|
||||||
| Regra | Descrição |
|
|
||||||
|-------|-----------|
|
|
||||||
| `useArrowFunction` | **Sempre use arrow function** — `function` é erro |
|
|
||||||
| `noNonNullAssertion` | Evite `!` — trate o null |
|
|
||||||
| `noDelete` | `delete obj.prop` é lento |
|
|
||||||
| `noEmptyBlockStatements` | Blocos `{}` vazios |
|
|
||||||
| `noArrayIndexKey` | `:key` com índice do array |
|
|
||||||
| `noDangerouslySetInnerHtml` | `innerHTML` perigoso |
|
|
||||||
| `noExcessiveCognitiveComplexity` | Função muito complexa (max: 20) |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📦 Como Outros Projetos Consomem Este Pacote
|
|
||||||
|
|
||||||
```json
|
|
||||||
// biome.json do subprojeto (ex: PILAO-FRONT)
|
|
||||||
{
|
|
||||||
"$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
|
|
||||||
"extends": ["./node_modules/p-comuns/Documentos/biome.json"],
|
|
||||||
"files": {
|
|
||||||
"includes": ["src/**/*.{js,ts,jsx,tsx,vue}"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
```json
|
|
||||||
// .vscode/settings.json do subprojeto
|
|
||||||
{
|
|
||||||
"editor.defaultFormatter": "biomejs.biome",
|
|
||||||
"editor.formatOnSave": true,
|
|
||||||
"editor.codeActionsOnSave": {
|
|
||||||
"source.organizeImports.biome": "always",
|
|
||||||
"source.fixAll.biome": "always"
|
|
||||||
},
|
|
||||||
"[vue]": { "editor.defaultFormatter": "biomejs.biome" },
|
|
||||||
"[typescript]": { "editor.defaultFormatter": "biomejs.biome" },
|
|
||||||
"[typescriptreact]": { "editor.defaultFormatter": "biomejs.biome" },
|
|
||||||
"editor.rulers": [100],
|
|
||||||
"files.eol": "\n"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 Scripts
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pnpm biome # Formata + lint com auto-fix
|
|
||||||
pnpm check # biome + tsc --noEmit (sem emitir arquivos)
|
|
||||||
pnpm build # Bump de versão + biome + tsup + pack
|
|
||||||
pnpm teste # Vitest (testes unitários)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ⚠️ O que NÃO fazer
|
|
||||||
|
|
||||||
- ❌ Não use `eslint` — o projeto usa Biome
|
|
||||||
- ❌ Não use `prettier` — o projeto usa Biome
|
|
||||||
- ❌ Não use `function` nomeada — sempre arrow function (`const fn = () => {}`)
|
|
||||||
- ❌ Não use Vue Options API — sempre Composition API
|
|
||||||
- ❌ Não desestrure `props` diretamente (quebra reatividade)
|
|
||||||
- ❌ Não use `any` — use `unknown` + type narrowing
|
|
||||||
- ❌ Não use índice como `:key` no `v-for`
|
|
||||||
- ❌ Não quebre linhas com mais de 100 caracteres
|
|
||||||
- ❌ Não use ponto-e-vírgula no final (Biome removerá)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📚 Referências
|
|
||||||
|
|
||||||
- [Biome 2.x Docs](https://biomejs.dev)
|
|
||||||
- [Vue 3 Composition API](https://vuejs.org/guide/composition-api)
|
|
||||||
- [Zod v4](https://zod.dev)
|
|
||||||
- [tsup](https://tsup.egoist.dev)
|
|
||||||
107
Documentos/biome.json
Executable file → Normal file
107
Documentos/biome.json
Executable file → Normal file
|
|
@ -6,20 +6,12 @@
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"rules": {
|
"rules": {
|
||||||
"recommended": true,
|
"recommended": true,
|
||||||
|
|
||||||
"correctness": {
|
"correctness": {
|
||||||
"noUnusedVariables": "error",
|
"noUnusedVariables": "error",
|
||||||
"noUnusedImports": "error",
|
"noUnusedImports": "error",
|
||||||
"noEmptyPattern": "off",
|
"noEmptyPattern": "off",
|
||||||
"useExhaustiveDependencies": "off",
|
"useExhaustiveDependencies": "off"
|
||||||
"noVoidTypeReturn": "error",
|
|
||||||
"noVueDataObjectDeclaration": "error",
|
|
||||||
"noVueDuplicateKeys": "error",
|
|
||||||
"noVueReservedKeys": "error",
|
|
||||||
"noVueReservedProps": "error",
|
|
||||||
"noVueSetupPropsReactivityLoss": "warn"
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"style": {
|
"style": {
|
||||||
"noParameterAssign": "error",
|
"noParameterAssign": "error",
|
||||||
"useAsConstAssertion": "error",
|
"useAsConstAssertion": "error",
|
||||||
|
|
@ -29,125 +21,44 @@
|
||||||
"useSingleVarDeclarator": "error",
|
"useSingleVarDeclarator": "error",
|
||||||
"noUnusedTemplateLiteral": "error",
|
"noUnusedTemplateLiteral": "error",
|
||||||
"useNumberNamespace": "error",
|
"useNumberNamespace": "error",
|
||||||
"noInferrableTypes": "error",
|
"noInferrableTypes": "error"
|
||||||
"useArrayLiterals": "error",
|
|
||||||
"useConsistentArrayType": {
|
|
||||||
"level": "error",
|
|
||||||
"options": { "syntax": "shorthand" }
|
|
||||||
},
|
},
|
||||||
"useShorthandAssign": "error",
|
|
||||||
"noNonNullAssertion": "warn"
|
|
||||||
},
|
|
||||||
|
|
||||||
"suspicious": {
|
"suspicious": {
|
||||||
"noDebugger": "off",
|
"noDebugger": "off",
|
||||||
"noDoubleEquals": "off",
|
"noDoubleEquals": "off",
|
||||||
"noExplicitAny": "off",
|
"noExplicitAny": "off",
|
||||||
"noApproximativeNumericConstant": "off",
|
"noApproximativeNumericConstant": "off",
|
||||||
"noAsyncPromiseExecutor": "off",
|
"noAsyncPromiseExecutor": "off"
|
||||||
"noEmptyBlockStatements": "off",
|
|
||||||
"noConsole": "off",
|
|
||||||
"noArrayIndexKey": "warn"
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"complexity": {
|
"complexity": {
|
||||||
"noUselessConstructor": "off",
|
"noUselessConstructor": "off",
|
||||||
"noBannedTypes": "off",
|
"noBannedTypes": "off",
|
||||||
"useLiteralKeys": "off",
|
"useLiteralKeys": "off",
|
||||||
"useArrowFunction": "error",
|
"useArrowFunction": "warn",
|
||||||
"useDateNow": "off",
|
"useDateNow": "off",
|
||||||
"noUselessFragments": "off",
|
"noUselessFragments": "off"
|
||||||
"noExcessiveCognitiveComplexity": "off",
|
|
||||||
"noImportantStyles": "off"
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"performance": {
|
"performance": {
|
||||||
"noAccumulatingSpread": "off",
|
"noAccumulatingSpread": "off"
|
||||||
"noDelete": "off"
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"a11y": {
|
"a11y": {
|
||||||
"useSemanticElements": "off",
|
"useSemanticElements": "off"
|
||||||
"useAltText": "warn",
|
|
||||||
"useButtonType": "warn"
|
|
||||||
},
|
|
||||||
|
|
||||||
"security": {
|
|
||||||
"noDangerouslySetInnerHtml": "warn"
|
|
||||||
},
|
|
||||||
|
|
||||||
"nursery": {
|
|
||||||
"noVueArrowFuncInWatch": "warn",
|
|
||||||
"noVueVIfWithVFor": "error",
|
|
||||||
"useVueConsistentDefinePropsDeclaration": "warn",
|
|
||||||
"useVueConsistentVBindStyle": "warn",
|
|
||||||
"useVueConsistentVOnStyle": "warn",
|
|
||||||
"useVueDefineMacrosOrder": "warn",
|
|
||||||
"useVueVForKey": "error",
|
|
||||||
"useVueValidTemplateRoot": "error",
|
|
||||||
"useVueValidVBind": "error",
|
|
||||||
"useVueValidVIf": "error",
|
|
||||||
"useVueValidVElse": "error",
|
|
||||||
"useVueValidVElseIf": "error",
|
|
||||||
"useVueValidVOn": "warn",
|
|
||||||
"useVueValidVHtml": "warn"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"formatter": {
|
"formatter": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"indentStyle": "space",
|
"indentStyle": "space",
|
||||||
"indentWidth": 2,
|
"indentWidth": 2
|
||||||
"lineWidth": 100,
|
|
||||||
"lineEnding": "lf"
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"javascript": {
|
"javascript": {
|
||||||
"globals": [
|
|
||||||
"defineProps",
|
|
||||||
"defineEmits",
|
|
||||||
"defineExpose",
|
|
||||||
"withDefaults",
|
|
||||||
"defineModel",
|
|
||||||
"defineOptions",
|
|
||||||
"defineSlots"
|
|
||||||
],
|
|
||||||
"parser": {
|
|
||||||
"unsafeParameterDecoratorsEnabled": true
|
|
||||||
},
|
|
||||||
"formatter": {
|
"formatter": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"semicolons": "asNeeded",
|
"semicolons": "asNeeded",
|
||||||
"arrowParentheses": "always",
|
"arrowParentheses": "always",
|
||||||
"bracketSameLine": false,
|
"bracketSameLine": false,
|
||||||
"trailingCommas": "all",
|
"trailingCommas": "all",
|
||||||
"attributePosition": "multiline",
|
"attributePosition": "multiline"
|
||||||
"quoteStyle": "double",
|
|
||||||
"jsxQuoteStyle": "double",
|
|
||||||
"bracketSpacing": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
"css": {
|
|
||||||
"formatter": {
|
|
||||||
"enabled": true,
|
|
||||||
"indentStyle": "space",
|
|
||||||
"indentWidth": 2,
|
|
||||||
"lineWidth": 100,
|
|
||||||
"quoteStyle": "double"
|
|
||||||
},
|
|
||||||
"linter": {
|
|
||||||
"enabled": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
"html": {
|
|
||||||
"formatter": {
|
|
||||||
"enabled": true,
|
|
||||||
"indentStyle": "space",
|
|
||||||
"indentWidth": 2,
|
|
||||||
"lineWidth": 100
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
188
README.md
Executable file → Normal file
188
README.md
Executable file → Normal file
|
|
@ -1,202 +1,90 @@
|
||||||
# `p-comuns` — Pacote Compartilhado e-licencie
|
## ✅ Uso do BiomeJS para Autoformatação
|
||||||
|
|
||||||
Pacote de tipos, utilitários e configurações compartilhadas entre todos os subprojetos da plataforma **e-licencie** (back-end Node.js, front-end Vue 3 / TSX).
|
Este guia mostra como configurar o [BiomeJS](https://biomejs.dev) para formatar e analisar código JavaScript/TypeScript no seu projeto.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ✅ Configuração do BiomeJS nos Subprojetos
|
### 1. Incluir o pacote de configuração comum
|
||||||
|
|
||||||
Este guia mostra como usar a configuração base do Biome disponível neste pacote (`Documentos/biome.json`). Todos os subprojetos herdam essas regras via `extends`.
|
Certifique-se de que o pacote `p-comuns` (ou outro com a configuração compartilhada) esteja disponível no seu projeto. Ele deve conter o arquivo `Documentos/biome.json`.
|
||||||
|
|
||||||
### 1. Adicionar o `p-comuns` como dependência
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pnpm add --save-dev p-comuns
|
|
||||||
# ou atualizar se já existir:
|
|
||||||
pnpm up p-comuns
|
pnpm up p-comuns
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 2. Instalar o Biome
|
### 2. Instalar o Biome com `pnpm`
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pnpm add --save-dev --save-exact @biomejs/biome@2.4.0
|
pnpm add --save-dev --save-exact @biomejs/biome@2.1.4
|
||||||
```
|
```
|
||||||
|
|
||||||
> 🎯 Use `--save-exact` para garantir consistência de versões entre ambientes.
|
> 🎯 Use `--save-exact` para garantir consistência de versões entre ambientes.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 3. Criar `biome.json` na raiz do subprojeto
|
### 3. Criar o arquivo de configuração na raiz do projeto
|
||||||
|
|
||||||
|
Crie um arquivo chamado `biome.json` com o seguinte conteúdo:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"$schema": "node_modules/@biomejs/biome/configuration_schema.json",
|
"$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
|
||||||
"extends": ["node_modules/p-comuns/Documentos/biome.json"],
|
"extends": ["./node_modules/p-comuns/Documentos/biome.json"],
|
||||||
"vcs": {
|
|
||||||
"enabled": true,
|
|
||||||
"clientKind": "git",
|
|
||||||
"useIgnoreFile": true
|
|
||||||
},
|
|
||||||
"files": {
|
"files": {
|
||||||
"includes": ["**/*.{ts,tsx,vue}"]
|
"includes": ["src/**/*.{js,ts,jsx,tsx}"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
> `vcs.useIgnoreFile: true` faz o Biome respeitar o `.gitignore` automaticamente — arquivos como `dist/`, `node_modules/` etc. são ignorados sem configuração adicional.
|
> ⚠️ Verifique o caminho correto do `extends` relativo à raiz do seu projeto. Use `./` sempre que possível para evitar erros de resolução.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 4. Adicionar scripts no `package.json`
|
### 4. Adicionar script no `package.json`
|
||||||
|
|
||||||
|
Inclua o comando abaixo em `"scripts"`:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"biome": "pnpm exec biome check --write",
|
"biome": "pnpm exec biome check --write",
|
||||||
"check": "pnpm run biome && npx tsc --noEmit"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Isso permite executar:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm biome
|
||||||
|
```
|
||||||
|
|
||||||
|
> O comando irá **formatar e aplicar as regras de lint** nos arquivos do diretório `src/`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 5. Configurar o VS Code (`.vscode/settings.json`)
|
### ✅ Dica extra: formatar todos os arquivos
|
||||||
|
|
||||||
|
Se quiser aplicar o Biome a todo o projeto (não só `src/`), altere o include:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
|
"includes": ["**/*.{js,ts,jsx,tsx}"]
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
adicionar em .vscode/settings.json
|
||||||
|
|
||||||
{
|
{
|
||||||
"editor.defaultFormatter": "biomejs.biome",
|
"editor.defaultFormatter": "biomejs.biome",
|
||||||
"editor.formatOnSave": true,
|
|
||||||
"editor.codeActionsOnSave": {
|
|
||||||
"source.organizeImports.biome": "always",
|
|
||||||
"source.fixAll.biome": "always"
|
|
||||||
},
|
|
||||||
"[javascript]": { "editor.defaultFormatter": "biomejs.biome" },
|
"[javascript]": { "editor.defaultFormatter": "biomejs.biome" },
|
||||||
"[javascriptreact]": { "editor.defaultFormatter": "biomejs.biome" },
|
"[javascriptreact]": { "editor.defaultFormatter": "biomejs.biome" },
|
||||||
"[typescript]": { "editor.defaultFormatter": "biomejs.biome" },
|
"[typescript]": { "editor.defaultFormatter": "biomejs.biome" },
|
||||||
"[typescriptreact]": { "editor.defaultFormatter": "biomejs.biome" },
|
"[typescriptreact]": { "editor.defaultFormatter": "biomejs.biome" },
|
||||||
"[vue]": { "editor.defaultFormatter": "biomejs.biome" },
|
|
||||||
"[css]": { "editor.defaultFormatter": "biomejs.biome" },
|
|
||||||
"[json]": { "editor.defaultFormatter": "biomejs.biome" },
|
"[json]": { "editor.defaultFormatter": "biomejs.biome" },
|
||||||
"[jsonc]": { "editor.defaultFormatter": "biomejs.biome" },
|
"[jsonc]": { "editor.defaultFormatter": "biomejs.biome" },
|
||||||
"editor.rulers": [100],
|
"[vue]": {"editor.defaultFormatter": "octref.vetur"},
|
||||||
"files.eol": "\n",
|
"editor.codeActionsOnSave": {
|
||||||
"files.trimTrailingWhitespace": true,
|
"source.organizeImports.biome": "always",
|
||||||
"files.insertFinalNewline": true
|
"source.fixAll.biome": "always"
|
||||||
}
|
}
|
||||||
```
|
|
||||||
|
|
||||||
> 💡 **Biome formata Vue `.vue` nativamente desde a v2.3** — não precisa do Prettier ou Vetur para formatação!
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔑 Regras da configuração base (Documentos/biome.json)
|
|
||||||
|
|
||||||
### O que está ativado:
|
|
||||||
|
|
||||||
| Categoria | Regras notáveis |
|
|
||||||
|-----------|----------------|
|
|
||||||
| **Correctness** | `noUnusedVariables`, `noUnusedImports`, `noVueSetupPropsReactivityLoss` |
|
|
||||||
| **Vue 3 específico** | `noVueVIfWithVFor`, `useVueVForKey`, `noVueDuplicateKeys`, `noVueReservedKeys` |
|
|
||||||
| **Style** | `useAsConstAssertion`, `useSelfClosingElements`, `useConsistentArrayType` (shorthand `T[]`) |
|
|
||||||
| **Nursery Vue** | `noVueArrowFuncInWatch`, `useVueDefineMacrosOrder`, `useVueConsistentVBindStyle` |
|
|
||||||
| **Security** | `noDangerouslySetInnerHtml` (warn) |
|
|
||||||
|
|
||||||
### Globals do Vue (sem necessidade de importar):
|
|
||||||
|
|
||||||
`defineProps`, `defineEmits`, `defineExpose`, `withDefaults`, `defineModel`, `defineOptions`, `defineSlots`
|
|
||||||
|
|
||||||
### Formatação:
|
|
||||||
|
|
||||||
- Indentação: **2 espaços**
|
|
||||||
- Linha máxima: **100 caracteres**
|
|
||||||
- Aspas: **duplas**
|
|
||||||
- Ponto-e-vírgula: **apenas quando necessário**
|
|
||||||
- Trailing comma: **sempre**
|
|
||||||
- Line ending: **LF (`\n`)**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ Sistema de Filtros (tipoFiltro26)
|
|
||||||
|
|
||||||
O sistema `tipoFiltro26` foi projetado para gerar automaticamente a tipagem de filtros compatíveis com operadores padrão do PostgreSQL, a partir de um tipo base `T`.
|
|
||||||
|
|
||||||
**Principais características:**
|
|
||||||
- Tipagem forte e segura (TypeScript)
|
|
||||||
- Suporte a aninhamento de objetos
|
|
||||||
- Operadores lógicos `E` (AND) e `OU` (OR)
|
|
||||||
- Validação de operadores permitidos por tipo de dado (string, number, boolean)
|
|
||||||
|
|
||||||
### Estrutura do Filtro
|
|
||||||
|
|
||||||
#### 1. Campos Simples
|
|
||||||
```typescript
|
|
||||||
{ idade: { ">=": 18 } }
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 2. Campos Aninhados
|
|
||||||
```typescript
|
|
||||||
{ carro: { ano: { "=": 2020 } } }
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 3. Operadores Lógicos
|
|
||||||
|
|
||||||
**Operador E (AND):** Todos devem ser verdadeiros.
|
|
||||||
```typescript
|
|
||||||
{
|
|
||||||
E: [
|
|
||||||
{ idade: { ">=": 18 } },
|
|
||||||
{ nome: { like: "%pa%" } }
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
```
|
|
||||||
|
|
||||||
**Operador OU (OR):** Pelo menos um deve ser verdadeiro.
|
|
||||||
```typescript
|
|
||||||
{
|
|
||||||
OU: [
|
|
||||||
{ idade: { "<": 18 } },
|
|
||||||
{ idade: { ">=": 60 } }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 4. Exemplo Complexo Completo
|
|
||||||
```typescript
|
|
||||||
{
|
|
||||||
idade: { ">=": 18 },
|
|
||||||
OU: [
|
|
||||||
{ nome: { like: "%pa%" } },
|
|
||||||
{
|
|
||||||
E: [
|
|
||||||
{ carro: { ano: { "=": 2020 } } },
|
|
||||||
{ carro: { modelo: { in: ["Civic"] } } }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Operadores Suportados (`operadores26`)
|
|
||||||
|
|
||||||
- **Number**: `=`, `!=`, `>`, `>=`, `<`, `<=`, `in`
|
|
||||||
- **String**: `=`, `!=`, `like`, `in`
|
|
||||||
- **Boolean**: `=`, `!=`, `in`
|
|
||||||
|
|
||||||
### Validação em Tempo de Execução (Zod)
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { zFiltro26 } from "p-comuns"
|
|
||||||
|
|
||||||
// Valida a estrutura (não checa existência de colunas no DB)
|
|
||||||
zFiltro26.parse(objetoFiltro)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📚 Veja também
|
|
||||||
|
|
||||||
- [`AGENTS.md`](./AGENTS.md) — Guia para assistentes de IA (padrões, convenções, arquitetura)
|
|
||||||
- [Biome 2.x Docs](https://biomejs.dev)
|
|
||||||
- [Vue 3 Composition API](https://vuejs.org/guide/composition-api)
|
|
||||||
|
|
|
||||||
2
biome.json
Executable file → Normal file
2
biome.json
Executable file → Normal file
|
|
@ -2,6 +2,6 @@
|
||||||
"$schema": "node_modules/@biomejs/biome/configuration_schema.json",
|
"$schema": "node_modules/@biomejs/biome/configuration_schema.json",
|
||||||
"extends": ["Documentos/biome.json"],
|
"extends": ["Documentos/biome.json"],
|
||||||
"files": {
|
"files": {
|
||||||
"includes": ["src/**/*.{js,ts,jsx,tsx,vue}"]
|
"includes": ["src/**/*.{js,ts,jsx,tsx}"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
0
build.config.ts
Executable file → Normal file
0
build.config.ts
Executable file → Normal file
|
|
@ -1,16 +0,0 @@
|
||||||
"use strict";
|
|
||||||
var __defProp = Object.defineProperty;
|
|
||||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
||||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
||||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
||||||
var __copyProps = (to, from, except, desc) => {
|
|
||||||
if (from && typeof from === "object" || typeof from === "function") {
|
|
||||||
for (let key of __getOwnPropNames(from))
|
|
||||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
||||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
||||||
}
|
|
||||||
return to;
|
|
||||||
};
|
|
||||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
||||||
var auditoria_exports = {};
|
|
||||||
module.exports = __toCommonJS(auditoria_exports);
|
|
||||||
|
|
@ -46,7 +46,17 @@ var operadores = /* @__PURE__ */ ((operadores2) => {
|
||||||
operadores2["isNull"] = "isNull";
|
operadores2["isNull"] = "isNull";
|
||||||
return operadores2;
|
return operadores2;
|
||||||
})(operadores || {});
|
})(operadores || {});
|
||||||
const zOperadores = import_zod.default.enum(["=", "!=", ">", ">=", "<", "<=", "like", "in", "isNull"]);
|
const zOperadores = import_zod.default.enum([
|
||||||
|
"=",
|
||||||
|
"!=",
|
||||||
|
">",
|
||||||
|
">=",
|
||||||
|
"<",
|
||||||
|
"<=",
|
||||||
|
"like",
|
||||||
|
"in",
|
||||||
|
"isNull"
|
||||||
|
]);
|
||||||
const zFiltro = import_zod.default.object({
|
const zFiltro = import_zod.default.object({
|
||||||
coluna: import_zod.default.string(),
|
coluna: import_zod.default.string(),
|
||||||
valor: import_zod.default.any(),
|
valor: import_zod.default.any(),
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,18 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
||||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||||
var dayjs_exports = {};
|
var dayjs_exports = {};
|
||||||
__export(dayjs_exports, {
|
__export(dayjs_exports, {
|
||||||
definirDayjsbr: () => definirDayjsbr
|
dayjsbr: () => import_dayjs.default,
|
||||||
|
duration: () => import_duration.default,
|
||||||
|
isSameOrAfter: () => import_isSameOrAfter.default,
|
||||||
|
isSameOrBefore: () => import_isSameOrBefore.default,
|
||||||
|
minMax: () => import_minMax.default,
|
||||||
|
relativeTime: () => import_relativeTime.default,
|
||||||
|
timezone: () => import_timezone.default,
|
||||||
|
utc: () => import_utc.default,
|
||||||
|
weekOfYear: () => import_weekOfYear.default
|
||||||
});
|
});
|
||||||
module.exports = __toCommonJS(dayjs_exports);
|
module.exports = __toCommonJS(dayjs_exports);
|
||||||
|
var import_dayjs = __toESM(require("dayjs"));
|
||||||
var import_duration = __toESM(require("dayjs/plugin/duration"));
|
var import_duration = __toESM(require("dayjs/plugin/duration"));
|
||||||
var import_isSameOrAfter = __toESM(require("dayjs/plugin/isSameOrAfter"));
|
var import_isSameOrAfter = __toESM(require("dayjs/plugin/isSameOrAfter"));
|
||||||
var import_isSameOrBefore = __toESM(require("dayjs/plugin/isSameOrBefore"));
|
var import_isSameOrBefore = __toESM(require("dayjs/plugin/isSameOrBefore"));
|
||||||
|
|
@ -40,19 +49,24 @@ var import_timezone = __toESM(require("dayjs/plugin/timezone"));
|
||||||
var import_utc = __toESM(require("dayjs/plugin/utc"));
|
var import_utc = __toESM(require("dayjs/plugin/utc"));
|
||||||
var import_weekOfYear = __toESM(require("dayjs/plugin/weekOfYear"));
|
var import_weekOfYear = __toESM(require("dayjs/plugin/weekOfYear"));
|
||||||
var import_pt_br = require("dayjs/locale/pt-br");
|
var import_pt_br = require("dayjs/locale/pt-br");
|
||||||
const definirDayjsbr = (dayjsEntrada) => {
|
import_dayjs.default.locale("pt-br");
|
||||||
dayjsEntrada.locale("pt-br");
|
import_dayjs.default.extend(import_utc.default);
|
||||||
dayjsEntrada.extend(import_utc.default);
|
import_dayjs.default.extend(import_timezone.default);
|
||||||
dayjsEntrada.extend(import_timezone.default);
|
import_dayjs.default.extend(import_weekOfYear.default);
|
||||||
dayjsEntrada.extend(import_weekOfYear.default);
|
import_dayjs.default.extend(import_isSameOrBefore.default);
|
||||||
dayjsEntrada.extend(import_isSameOrBefore.default);
|
import_dayjs.default.extend(import_isSameOrAfter.default);
|
||||||
dayjsEntrada.extend(import_isSameOrAfter.default);
|
import_dayjs.default.extend(import_minMax.default);
|
||||||
dayjsEntrada.extend(import_minMax.default);
|
import_dayjs.default.extend(import_relativeTime.default);
|
||||||
dayjsEntrada.extend(import_relativeTime.default);
|
import_dayjs.default.extend(import_duration.default);
|
||||||
dayjsEntrada.extend(import_duration.default);
|
|
||||||
return dayjsEntrada;
|
|
||||||
};
|
|
||||||
// Annotate the CommonJS export names for ESM import in node:
|
// Annotate the CommonJS export names for ESM import in node:
|
||||||
0 && (module.exports = {
|
0 && (module.exports = {
|
||||||
definirDayjsbr
|
dayjsbr,
|
||||||
|
duration,
|
||||||
|
isSameOrAfter,
|
||||||
|
isSameOrBefore,
|
||||||
|
minMax,
|
||||||
|
relativeTime,
|
||||||
|
timezone,
|
||||||
|
utc,
|
||||||
|
weekOfYear
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
"use strict";
|
|
||||||
var __defProp = Object.defineProperty;
|
|
||||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
||||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
||||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
||||||
var __export = (target, all) => {
|
|
||||||
for (var name in all)
|
|
||||||
__defProp(target, name, { get: all[name], enumerable: true });
|
|
||||||
};
|
|
||||||
var __copyProps = (to, from, except, desc) => {
|
|
||||||
if (from && typeof from === "object" || typeof from === "function") {
|
|
||||||
for (let key of __getOwnPropNames(from))
|
|
||||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
||||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
||||||
}
|
|
||||||
return to;
|
|
||||||
};
|
|
||||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
||||||
var dayjs26_exports = {};
|
|
||||||
__export(dayjs26_exports, {
|
|
||||||
defineDayjsBr: () => defineDayjsBr
|
|
||||||
});
|
|
||||||
module.exports = __toCommonJS(dayjs26_exports);
|
|
||||||
const defineDayjsBr = ({
|
|
||||||
dayjs,
|
|
||||||
duration,
|
|
||||||
isSameOrAfter,
|
|
||||||
isSameOrBefore,
|
|
||||||
minMax,
|
|
||||||
relativeTime,
|
|
||||||
timezone,
|
|
||||||
utc,
|
|
||||||
weekOfYear
|
|
||||||
}) => {
|
|
||||||
dayjs.extend(utc);
|
|
||||||
dayjs.extend(timezone);
|
|
||||||
dayjs.extend(weekOfYear);
|
|
||||||
dayjs.extend(isSameOrBefore);
|
|
||||||
dayjs.extend(isSameOrAfter);
|
|
||||||
dayjs.extend(minMax);
|
|
||||||
dayjs.extend(relativeTime);
|
|
||||||
dayjs.extend(duration);
|
|
||||||
dayjs.locale("pt-br");
|
|
||||||
return dayjs;
|
|
||||||
};
|
|
||||||
// Annotate the CommonJS export names for ESM import in node:
|
|
||||||
0 && (module.exports = {
|
|
||||||
defineDayjsBr
|
|
||||||
});
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
"use strict";
|
|
||||||
var __defProp = Object.defineProperty;
|
|
||||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
||||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
||||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
||||||
var __export = (target, all) => {
|
|
||||||
for (var name in all)
|
|
||||||
__defProp(target, name, { get: all[name], enumerable: true });
|
|
||||||
};
|
|
||||||
var __copyProps = (to, from, except, desc) => {
|
|
||||||
if (from && typeof from === "object" || typeof from === "function") {
|
|
||||||
for (let key of __getOwnPropNames(from))
|
|
||||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
||||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
||||||
}
|
|
||||||
return to;
|
|
||||||
};
|
|
||||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
||||||
var graficosPilao_exports = {};
|
|
||||||
__export(graficosPilao_exports, {
|
|
||||||
graficos_pilao: () => graficos_pilao
|
|
||||||
});
|
|
||||||
module.exports = __toCommonJS(graficosPilao_exports);
|
|
||||||
const graficos_pilao = {
|
|
||||||
Condicionantes: {
|
|
||||||
grafico: "condicionantes-criadas",
|
|
||||||
titulo: "Condicionantes Criadas"
|
|
||||||
},
|
|
||||||
Licen\u00E7as: {
|
|
||||||
grafico: "licencas-criadas",
|
|
||||||
titulo: "Licen\xE7as Criadas"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// Annotate the CommonJS export names for ESM import in node:
|
|
||||||
0 && (module.exports = {
|
|
||||||
graficos_pilao
|
|
||||||
});
|
|
||||||
|
|
@ -16,15 +16,16 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
||||||
var index_exports = {};
|
var index_exports = {};
|
||||||
module.exports = __toCommonJS(index_exports);
|
module.exports = __toCommonJS(index_exports);
|
||||||
__reExport(index_exports, require("./aleatorio"), module.exports);
|
__reExport(index_exports, require("./aleatorio"), module.exports);
|
||||||
__reExport(index_exports, require("./auditoria"), module.exports);
|
|
||||||
__reExport(index_exports, require("./cacheMemoria"), module.exports);
|
__reExport(index_exports, require("./cacheMemoria"), module.exports);
|
||||||
__reExport(index_exports, require("./constantes"), module.exports);
|
__reExport(index_exports, require("./constantes"), module.exports);
|
||||||
__reExport(index_exports, require("./consulta"), module.exports);
|
__reExport(index_exports, require("./consulta"), module.exports);
|
||||||
__reExport(index_exports, require("./dayjs26"), module.exports);
|
__reExport(index_exports, require("./dayjs"), module.exports);
|
||||||
__reExport(index_exports, require("./ecosistema"), module.exports);
|
__reExport(index_exports, require("./ecosistema"), module.exports);
|
||||||
__reExport(index_exports, require("./extensoes"), module.exports);
|
__reExport(index_exports, require("./extensoes"), module.exports);
|
||||||
__reExport(index_exports, require("./extensoes"), module.exports);
|
__reExport(index_exports, require("./extensoes"), module.exports);
|
||||||
__reExport(index_exports, require("./local"), module.exports);
|
__reExport(index_exports, require("./local"), module.exports);
|
||||||
|
__reExport(index_exports, require("./logger"), module.exports);
|
||||||
|
__reExport(index_exports, require("./logger"), module.exports);
|
||||||
__reExport(index_exports, require("./postgres"), module.exports);
|
__reExport(index_exports, require("./postgres"), module.exports);
|
||||||
__reExport(index_exports, require("./produtos"), module.exports);
|
__reExport(index_exports, require("./produtos"), module.exports);
|
||||||
__reExport(index_exports, require("./situacoes"), module.exports);
|
__reExport(index_exports, require("./situacoes"), module.exports);
|
||||||
|
|
@ -32,22 +33,22 @@ __reExport(index_exports, require("./testes-de-variaveis"), module.exports);
|
||||||
__reExport(index_exports, require("./texto_busca"), module.exports);
|
__reExport(index_exports, require("./texto_busca"), module.exports);
|
||||||
__reExport(index_exports, require("./tipagemRotas"), module.exports);
|
__reExport(index_exports, require("./tipagemRotas"), module.exports);
|
||||||
__reExport(index_exports, require("./tipagemRotas"), module.exports);
|
__reExport(index_exports, require("./tipagemRotas"), module.exports);
|
||||||
__reExport(index_exports, require("./tipoFiltro.26"), module.exports);
|
|
||||||
__reExport(index_exports, require("./unidades_medida"), module.exports);
|
__reExport(index_exports, require("./unidades_medida"), module.exports);
|
||||||
__reExport(index_exports, require("./uuid"), module.exports);
|
__reExport(index_exports, require("./uuid"), module.exports);
|
||||||
__reExport(index_exports, require("./variaveisComuns"), module.exports);
|
__reExport(index_exports, require("./variaveisComuns"), module.exports);
|
||||||
// Annotate the CommonJS export names for ESM import in node:
|
// Annotate the CommonJS export names for ESM import in node:
|
||||||
0 && (module.exports = {
|
0 && (module.exports = {
|
||||||
...require("./aleatorio"),
|
...require("./aleatorio"),
|
||||||
...require("./auditoria"),
|
|
||||||
...require("./cacheMemoria"),
|
...require("./cacheMemoria"),
|
||||||
...require("./constantes"),
|
...require("./constantes"),
|
||||||
...require("./consulta"),
|
...require("./consulta"),
|
||||||
...require("./dayjs26"),
|
...require("./dayjs"),
|
||||||
...require("./ecosistema"),
|
...require("./ecosistema"),
|
||||||
...require("./extensoes"),
|
...require("./extensoes"),
|
||||||
...require("./extensoes"),
|
...require("./extensoes"),
|
||||||
...require("./local"),
|
...require("./local"),
|
||||||
|
...require("./logger"),
|
||||||
|
...require("./logger"),
|
||||||
...require("./postgres"),
|
...require("./postgres"),
|
||||||
...require("./produtos"),
|
...require("./produtos"),
|
||||||
...require("./situacoes"),
|
...require("./situacoes"),
|
||||||
|
|
@ -55,7 +56,6 @@ __reExport(index_exports, require("./variaveisComuns"), module.exports);
|
||||||
...require("./texto_busca"),
|
...require("./texto_busca"),
|
||||||
...require("./tipagemRotas"),
|
...require("./tipagemRotas"),
|
||||||
...require("./tipagemRotas"),
|
...require("./tipagemRotas"),
|
||||||
...require("./tipoFiltro.26"),
|
|
||||||
...require("./unidades_medida"),
|
...require("./unidades_medida"),
|
||||||
...require("./uuid"),
|
...require("./uuid"),
|
||||||
...require("./variaveisComuns")
|
...require("./variaveisComuns")
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ __export(local_exports, {
|
||||||
});
|
});
|
||||||
module.exports = __toCommonJS(local_exports);
|
module.exports = __toCommonJS(local_exports);
|
||||||
const localValor = (chave_, valor) => {
|
const localValor = (chave_, valor) => {
|
||||||
const localStorage = "localStorage" in globalThis ? globalThis.localStorage : void 0;
|
const localStorage = globalThis.localStorage;
|
||||||
if (typeof localStorage == "undefined") return null;
|
if (typeof localStorage == "undefined") return null;
|
||||||
const chave = typeof chave_ === "string" ? chave_ : encodeURIComponent(JSON.stringify(chave_));
|
const chave = typeof chave_ === "string" ? chave_ : encodeURIComponent(JSON.stringify(chave_));
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
106
dist-back/logger.js
Normal file
106
dist-back/logger.js
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
"use strict";
|
||||||
|
var __create = Object.create;
|
||||||
|
var __defProp = Object.defineProperty;
|
||||||
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||||
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||||
|
var __getProtoOf = Object.getPrototypeOf;
|
||||||
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||||
|
var __export = (target, all) => {
|
||||||
|
for (var name in all)
|
||||||
|
__defProp(target, name, { get: all[name], enumerable: true });
|
||||||
|
};
|
||||||
|
var __copyProps = (to, from, except, desc) => {
|
||||||
|
if (from && typeof from === "object" || typeof from === "function") {
|
||||||
|
for (let key of __getOwnPropNames(from))
|
||||||
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||||
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||||
|
}
|
||||||
|
return to;
|
||||||
|
};
|
||||||
|
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||||
|
// If the importer is in node compatibility mode or this is not an ESM
|
||||||
|
// file that has been converted to a CommonJS file using a Babel-
|
||||||
|
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||||
|
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||||
|
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||||
|
mod
|
||||||
|
));
|
||||||
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||||
|
var logger_exports = {};
|
||||||
|
__export(logger_exports, {
|
||||||
|
defineCwd: () => defineCwd,
|
||||||
|
logger: () => logger,
|
||||||
|
postLogger: () => postLogger
|
||||||
|
});
|
||||||
|
module.exports = __toCommonJS(logger_exports);
|
||||||
|
var import_cross_fetch = __toESM(require("cross-fetch"));
|
||||||
|
var import_variaveisComuns = require("./variaveisComuns");
|
||||||
|
const LOKI_BASE_URL = "https://log.idz.one";
|
||||||
|
const LOKI_ENDPOINT = "/loki/api/v1/push";
|
||||||
|
const postLogger = async ({
|
||||||
|
objeto
|
||||||
|
}) => {
|
||||||
|
const response = await (0, import_cross_fetch.default)(`${LOKI_BASE_URL}${LOKI_ENDPOINT}`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify(objeto)
|
||||||
|
}).catch((a) => a);
|
||||||
|
if (!response.ok) {
|
||||||
|
return [objeto, `Erro ${response.status}: ${await response?.text?.()}`];
|
||||||
|
}
|
||||||
|
return [objeto];
|
||||||
|
};
|
||||||
|
let cwd = "";
|
||||||
|
const defineCwd = (novoCwd) => {
|
||||||
|
cwd = novoCwd;
|
||||||
|
};
|
||||||
|
const logger = ({ app: app_e, eProducao, parametros: parametrosAmbiente }) => ({ inquilino, usuario, parametros: parametrosSessao }) => async (level, mensagem, op_tipoLog) => {
|
||||||
|
let {
|
||||||
|
__filename,
|
||||||
|
detalhes,
|
||||||
|
local,
|
||||||
|
parametros: parametrosLog
|
||||||
|
} = op_tipoLog || {};
|
||||||
|
const app = `${eProducao ? "" : "DEV-"}${app_e}`;
|
||||||
|
if (cwd && __filename) {
|
||||||
|
__filename = __filename.replace(cwd, "");
|
||||||
|
}
|
||||||
|
if (local) {
|
||||||
|
detalhes = [`${(0, import_variaveisComuns.nomeVariavel)({ local })}="${local}"`, ...detalhes || []];
|
||||||
|
}
|
||||||
|
if (__filename) {
|
||||||
|
detalhes = [
|
||||||
|
`${(0, import_variaveisComuns.nomeVariavel)({ __filename })}="${__filename}"`,
|
||||||
|
...detalhes || []
|
||||||
|
];
|
||||||
|
}
|
||||||
|
const timestamp = `${Date.now()}000000`;
|
||||||
|
const mainLog = detalhes?.length ? `${mensagem} | ${detalhes.map((d) => JSON.stringify(d)).join(" | ")}` : mensagem;
|
||||||
|
const payload = {
|
||||||
|
stream: {
|
||||||
|
app,
|
||||||
|
inquilino,
|
||||||
|
usuario,
|
||||||
|
level,
|
||||||
|
...parametrosAmbiente || {},
|
||||||
|
...parametrosSessao || {},
|
||||||
|
...parametrosLog || {}
|
||||||
|
},
|
||||||
|
values: [
|
||||||
|
[
|
||||||
|
timestamp,
|
||||||
|
mainLog
|
||||||
|
// Linha de log direta
|
||||||
|
]
|
||||||
|
]
|
||||||
|
};
|
||||||
|
const objeto = { streams: [payload] };
|
||||||
|
const response = await postLogger({ objeto });
|
||||||
|
return response;
|
||||||
|
};
|
||||||
|
// Annotate the CommonJS export names for ESM import in node:
|
||||||
|
0 && (module.exports = {
|
||||||
|
defineCwd,
|
||||||
|
logger,
|
||||||
|
postLogger
|
||||||
|
});
|
||||||
|
|
@ -56,8 +56,9 @@ class TipagemRotas {
|
||||||
** "http://localhost:3000/caminho?q=query"
|
** "http://localhost:3000/caminho?q=query"
|
||||||
*/
|
*/
|
||||||
endereco(query, usarComoHash) {
|
endereco(query, usarComoHash) {
|
||||||
const win = typeof globalThis !== "undefined" && globalThis.window || void 0;
|
const url = new URL(
|
||||||
const url = new URL(win ? win.location.href : "http://localhost");
|
typeof window !== "undefined" ? window.location.href : "http://localhost"
|
||||||
|
);
|
||||||
url.pathname = this.caminho;
|
url.pathname = this.caminho;
|
||||||
url.search = "";
|
url.search = "";
|
||||||
const queryKeys = Object.entries(query);
|
const queryKeys = Object.entries(query);
|
||||||
|
|
@ -79,9 +80,8 @@ class TipagemRotas {
|
||||||
if (this._acaoIr) {
|
if (this._acaoIr) {
|
||||||
this._acaoIr(this.endereco({ ...query }));
|
this._acaoIr(this.endereco({ ...query }));
|
||||||
} else {
|
} else {
|
||||||
const win = typeof globalThis !== "undefined" && globalThis.window || void 0;
|
if (typeof window != "undefined") {
|
||||||
if (win) {
|
window.location.href = this.endereco({ ...query });
|
||||||
win.location.href = this.endereco({ ...query });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -91,13 +91,15 @@ class TipagemRotas {
|
||||||
*/
|
*/
|
||||||
parametros(urlEntrada) {
|
parametros(urlEntrada) {
|
||||||
const url = urlEntrada ? new URL(urlEntrada) : new URL(
|
const url = urlEntrada ? new URL(urlEntrada) : new URL(
|
||||||
typeof globalThis !== "undefined" && globalThis.window ? globalThis.window.location.href : "http://localhost"
|
typeof window !== "undefined" ? window.location.href : "http://localhost"
|
||||||
);
|
);
|
||||||
const query = url.searchParams;
|
const query = url.searchParams;
|
||||||
let queryObj = Object.fromEntries(query.entries());
|
let queryObj = Object.fromEntries(query.entries());
|
||||||
const hash = url.hash;
|
const hash = url.hash;
|
||||||
if (hash) {
|
if (hash) {
|
||||||
const hashObj = Object.fromEntries(new URLSearchParams(hash.slice(1)).entries());
|
const hashObj = Object.fromEntries(
|
||||||
|
new URLSearchParams(hash.slice(1)).entries()
|
||||||
|
);
|
||||||
queryObj = { ...queryObj, ...hashObj };
|
queryObj = { ...queryObj, ...hashObj };
|
||||||
}
|
}
|
||||||
for (const chave in queryObj) {
|
for (const chave in queryObj) {
|
||||||
|
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
"use strict";
|
|
||||||
var __defProp = Object.defineProperty;
|
|
||||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
||||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
||||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
||||||
var __export = (target, all) => {
|
|
||||||
for (var name in all)
|
|
||||||
__defProp(target, name, { get: all[name], enumerable: true });
|
|
||||||
};
|
|
||||||
var __copyProps = (to, from, except, desc) => {
|
|
||||||
if (from && typeof from === "object" || typeof from === "function") {
|
|
||||||
for (let key of __getOwnPropNames(from))
|
|
||||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
||||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
||||||
}
|
|
||||||
return to;
|
|
||||||
};
|
|
||||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
||||||
var tipoFiltro_26_exports = {};
|
|
||||||
__export(tipoFiltro_26_exports, {
|
|
||||||
agrupadores26: () => agrupadores26,
|
|
||||||
criarFiltro26: () => criarFiltro26,
|
|
||||||
operadores26: () => operadores26,
|
|
||||||
zFiltro26: () => zFiltro26
|
|
||||||
});
|
|
||||||
module.exports = __toCommonJS(tipoFiltro_26_exports);
|
|
||||||
var import_zod = require("zod");
|
|
||||||
var operadores26 = /* @__PURE__ */ ((operadores262) => {
|
|
||||||
operadores262["="] = "=";
|
|
||||||
operadores262["!="] = "!=";
|
|
||||||
operadores262[">"] = ">";
|
|
||||||
operadores262[">="] = ">=";
|
|
||||||
operadores262["<"] = "<";
|
|
||||||
operadores262["<="] = "<=";
|
|
||||||
operadores262["like"] = "like";
|
|
||||||
operadores262["in"] = "in";
|
|
||||||
return operadores262;
|
|
||||||
})(operadores26 || {});
|
|
||||||
var agrupadores26 = /* @__PURE__ */ ((agrupadores262) => {
|
|
||||||
agrupadores262["E"] = "E";
|
|
||||||
agrupadores262["OU"] = "OU";
|
|
||||||
return agrupadores262;
|
|
||||||
})(agrupadores26 || {});
|
|
||||||
const zOperadores = import_zod.z.nativeEnum(operadores26);
|
|
||||||
const zValor = import_zod.z.any();
|
|
||||||
const zCondicao = import_zod.z.record(zOperadores, zValor);
|
|
||||||
const zFiltro26 = import_zod.z.lazy(
|
|
||||||
() => import_zod.z.object({
|
|
||||||
E: import_zod.z.array(zFiltro26).optional(),
|
|
||||||
OU: import_zod.z.array(zFiltro26).optional()
|
|
||||||
}).catchall(import_zod.z.union([zCondicao, zFiltro26]))
|
|
||||||
);
|
|
||||||
const criarFiltro26 = (filtro) => filtro;
|
|
||||||
const _filtro = criarFiltro26({
|
|
||||||
idade: { [">=" /* >= */]: 18 },
|
|
||||||
["OU" /* OU */]: [
|
|
||||||
{ nome: { ["like" /* like */]: "%pa%" } },
|
|
||||||
{
|
|
||||||
["E" /* E */]: [
|
|
||||||
{ carro: { ano: { ["=" /* = */]: 2020 } } },
|
|
||||||
{ carro: { modelo: { ["in" /* in */]: ["Civic", "Corolla"] } } }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
// Annotate the CommonJS export names for ESM import in node:
|
|
||||||
0 && (module.exports = {
|
|
||||||
agrupadores26,
|
|
||||||
criarFiltro26,
|
|
||||||
operadores26,
|
|
||||||
zFiltro26
|
|
||||||
});
|
|
||||||
|
|
@ -22,7 +22,9 @@ __export(variaveisComuns_exports, {
|
||||||
nomeVariavel: () => nomeVariavel
|
nomeVariavel: () => nomeVariavel
|
||||||
});
|
});
|
||||||
module.exports = __toCommonJS(variaveisComuns_exports);
|
module.exports = __toCommonJS(variaveisComuns_exports);
|
||||||
const esperar = (ms) => new Promise((resolve) => setTimeout(() => resolve(true), ms));
|
const esperar = (ms) => new Promise(
|
||||||
|
(resolve) => setTimeout(() => resolve(true), ms)
|
||||||
|
);
|
||||||
const nomeVariavel = (v) => Object.keys(v).join("/");
|
const nomeVariavel = (v) => Object.keys(v).join("/");
|
||||||
// Annotate the CommonJS export names for ESM import in node:
|
// Annotate the CommonJS export names for ESM import in node:
|
||||||
0 && (module.exports = {
|
0 && (module.exports = {
|
||||||
|
|
|
||||||
|
|
@ -1,41 +1,17 @@
|
||||||
import z, { z as z$1 } from 'zod';
|
import z from 'zod';
|
||||||
import _dayjs from 'dayjs';
|
export { Dayjs, ManipulateType, default as dayjsbr } from 'dayjs';
|
||||||
export { Dayjs, ManipulateType } from 'dayjs';
|
export { default as duration } from 'dayjs/plugin/duration';
|
||||||
import _duration from 'dayjs/plugin/duration';
|
export { default as isSameOrAfter } from 'dayjs/plugin/isSameOrAfter';
|
||||||
import _isSameOrAfter from 'dayjs/plugin/isSameOrAfter';
|
export { default as isSameOrBefore } from 'dayjs/plugin/isSameOrBefore';
|
||||||
import _isSameOrBefore from 'dayjs/plugin/isSameOrBefore';
|
export { default as minMax } from 'dayjs/plugin/minMax';
|
||||||
import _minMax from 'dayjs/plugin/minMax';
|
export { default as relativeTime } from 'dayjs/plugin/relativeTime';
|
||||||
import _relativeTime from 'dayjs/plugin/relativeTime';
|
export { default as timezone } from 'dayjs/plugin/timezone';
|
||||||
import _timezone from 'dayjs/plugin/timezone';
|
export { default as utc } from 'dayjs/plugin/utc';
|
||||||
import _utc from 'dayjs/plugin/utc';
|
export { default as weekOfYear } from 'dayjs/plugin/weekOfYear';
|
||||||
import _weekOfYear from 'dayjs/plugin/weekOfYear';
|
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
|
|
||||||
declare const aleatorio: (tamanho?: number) => string;
|
declare const aleatorio: (tamanho?: number) => string;
|
||||||
|
|
||||||
type TipoPayloadAuditoria = {
|
|
||||||
/** UUID do registro de auditoria */
|
|
||||||
codigo?: string | null;
|
|
||||||
/** UUID do usuario da acao (pode ser null se for processo do sistema que não registrou) */
|
|
||||||
usuario_criacao: string | null;
|
|
||||||
/** Timestamp ou data de criacao / execucao */
|
|
||||||
data_criacao: string | Date;
|
|
||||||
/** Nome exato da tabela no banco que originou o registro */
|
|
||||||
tabela_origem: string;
|
|
||||||
/** Código único (UUID) do registro na tabela original */
|
|
||||||
codigo_origem: string;
|
|
||||||
/** JSON contendo o snapshot das colunas novas / editadas */
|
|
||||||
novo: Record<string, any>;
|
|
||||||
/** JSON contendo o snapshot das colunas antes da edição */
|
|
||||||
anterior: Record<string, any>;
|
|
||||||
/** Hash ou controle de versao do item, usualmente preenchido por new.ver_seg */
|
|
||||||
__versao: string;
|
|
||||||
/** Tipo de operação que gerou a auditoria */
|
|
||||||
acao: "criar" | "atualizar" | "deletar" | string;
|
|
||||||
/** Versão do sistema no momento em que a ação ocorreu */
|
|
||||||
versao_sistema: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** gerar uma função de cache para uso em memoria */
|
/** gerar uma função de cache para uso em memoria */
|
||||||
declare const cacheM: <T>(chave: any, valor?: T, validadeSeg?: number) => T | undefined;
|
declare const cacheM: <T>(chave: any, valor?: T, validadeSeg?: number) => T | undefined;
|
||||||
declare const verCacheM: () => {
|
declare const verCacheM: () => {
|
||||||
|
|
@ -124,70 +100,6 @@ declare const zFiltro: z.ZodObject<{
|
||||||
ou: z.ZodOptional<z.ZodBoolean>;
|
ou: z.ZodOptional<z.ZodBoolean>;
|
||||||
}, z.core.$strip>;
|
}, z.core.$strip>;
|
||||||
|
|
||||||
/**
|
|
||||||
* Utilitário de configuração do Dayjs focado em compatibilidade com SSR.
|
|
||||||
*
|
|
||||||
* PROBLEMA:
|
|
||||||
* A importação direta do `dayjs` e seus plugins frequentemente causa conflitos em ambientes
|
|
||||||
* de Renderização do Lado do Servidor (SSR), como Nuxt ou Next.js, devido a discrepâncias
|
|
||||||
* na resolução de módulos (ESM vs CJS) e instabilidades de importação.
|
|
||||||
*
|
|
||||||
* SOLUÇÃO:
|
|
||||||
* Este módulo utiliza o padrão de Injeção de Dependência. Ele expõe apenas tipagens e
|
|
||||||
* uma função de configuração (`defineDayjsBr`). A responsabilidade de importar as
|
|
||||||
* bibliotecas "vivas" é delegada à aplicação consumidora (o cliente da função).
|
|
||||||
*
|
|
||||||
* Isso permite que o bundler da aplicação principal (Vite, Webpack, etc.) gerencie as
|
|
||||||
* instâncias, garantindo consistência e evitando erros de "module not found" ou
|
|
||||||
* instâncias duplicadas/não inicializadas adequadamente.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Inicializa e configura o Dayjs com o locale 'pt-br' e plugins essenciais.
|
|
||||||
*
|
|
||||||
* MODO DE USO:
|
|
||||||
* Importe os pacotes reais na sua aplicação e passe-os para esta função.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts
|
|
||||||
* // Em seu arquivo de configuração (ex: plugins/dayjs.ts):
|
|
||||||
* import dayjs from "dayjs"
|
|
||||||
* import duration from "dayjs/plugin/duration"
|
|
||||||
* import isSameOrAfter from "dayjs/plugin/isSameOrAfter"
|
|
||||||
* import isSameOrBefore from "dayjs/plugin/isSameOrBefore"
|
|
||||||
* import minMax from "dayjs/plugin/minMax"
|
|
||||||
* import relativeTime from "dayjs/plugin/relativeTime"
|
|
||||||
* import timezone from "dayjs/plugin/timezone"
|
|
||||||
* import utc from "dayjs/plugin/utc"
|
|
||||||
* import weekOfYear from "dayjs/plugin/weekOfYear"
|
|
||||||
* import { defineDayjsBr } from "p-comuns"
|
|
||||||
* import "dayjs/locale/pt-br" // Importante: importar o locale!
|
|
||||||
|
|
||||||
* export const dayjsbr = defineDayjsBr({
|
|
||||||
* dayjs,
|
|
||||||
* duration,
|
|
||||||
* isSameOrAfter,
|
|
||||||
* isSameOrBefore,
|
|
||||||
* minMax,
|
|
||||||
* relativeTime,
|
|
||||||
* timezone,
|
|
||||||
* utc,
|
|
||||||
* weekOfYear,
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
declare const defineDayjsBr: ({ dayjs, duration, isSameOrAfter, isSameOrBefore, minMax, relativeTime, timezone, utc, weekOfYear, }: {
|
|
||||||
dayjs: typeof _dayjs;
|
|
||||||
duration: typeof _duration;
|
|
||||||
isSameOrAfter: typeof _isSameOrAfter;
|
|
||||||
isSameOrBefore: typeof _isSameOrBefore;
|
|
||||||
minMax: typeof _minMax;
|
|
||||||
relativeTime: typeof _relativeTime;
|
|
||||||
timezone: typeof _timezone;
|
|
||||||
utc: typeof _utc;
|
|
||||||
weekOfYear: typeof _weekOfYear;
|
|
||||||
}) => typeof _dayjs;
|
|
||||||
|
|
||||||
declare const link_paiol = "https://paiol.idz.one";
|
declare const link_paiol = "https://paiol.idz.one";
|
||||||
|
|
||||||
type tiposArquivo = "imagem" | "documento" | "vídeo" | "outros";
|
type tiposArquivo = "imagem" | "documento" | "vídeo" | "outros";
|
||||||
|
|
@ -209,6 +121,46 @@ declare const tipoArquivo: (nomeArquivo: string | null | undefined) => tiposArqu
|
||||||
*/
|
*/
|
||||||
declare const localValor: <T>(chave_: string | any, valor?: T | null) => T | null;
|
declare const localValor: <T>(chave_: string | any, valor?: T | null) => T | null;
|
||||||
|
|
||||||
|
type tipoLokiObjeto = {
|
||||||
|
streams: {
|
||||||
|
stream: {
|
||||||
|
[k: string]: string;
|
||||||
|
};
|
||||||
|
values: [string, string][];
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
declare const postLogger: ({ objeto, }: {
|
||||||
|
objeto: tipoLokiObjeto;
|
||||||
|
}) => Promise<[objeto: tipoLokiObjeto, erro?: string]>;
|
||||||
|
/** define a localização da pasta do projeto */
|
||||||
|
declare const defineCwd: (novoCwd: string) => void;
|
||||||
|
type tipoLevel = "info" | "warn" | "error";
|
||||||
|
type tipoOpSessao = {
|
||||||
|
inquilino: string;
|
||||||
|
usuario: string;
|
||||||
|
parametros?: {
|
||||||
|
[k: string]: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
type tipoLog = {
|
||||||
|
detalhes?: unknown[];
|
||||||
|
__filename?: string;
|
||||||
|
local?: string;
|
||||||
|
parametros?: {
|
||||||
|
[k: string]: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
type tipoLoggerLog = (level: tipoLevel, mensagem: string, op_tipoLog?: tipoLog) => Promise<[objeto: tipoLokiObjeto, erro?: string]>;
|
||||||
|
type TipoLoggerSessao = (sess: tipoOpSessao) => tipoLoggerLog;
|
||||||
|
type tipoLogger = (amb: {
|
||||||
|
app: string;
|
||||||
|
eProducao: boolean;
|
||||||
|
parametros?: {
|
||||||
|
[k: string]: string;
|
||||||
|
};
|
||||||
|
}) => TipoLoggerSessao;
|
||||||
|
declare const logger: tipoLogger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trata um objeto para ser imput para postgres
|
* Trata um objeto para ser imput para postgres
|
||||||
* @param entrada
|
* @param entrada
|
||||||
|
|
@ -347,151 +299,6 @@ declare class TipagemRotas<T extends {
|
||||||
parametros(urlEntrada?: string): Partial<T>;
|
parametros(urlEntrada?: string): Partial<T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* =============================================================================
|
|
||||||
* tipoFiltro26<T>
|
|
||||||
* =============================================================================
|
|
||||||
*
|
|
||||||
* OBJETIVO
|
|
||||||
* -----------------------------------------------------------------------------
|
|
||||||
* Gerar automaticamente a tipagem de filtros compatíveis com operadores
|
|
||||||
* padrão do PostgreSQL, a partir de um tipo base T.
|
|
||||||
*
|
|
||||||
* Este tipo foi projetado para:
|
|
||||||
* - Construção de filtros dinâmicos
|
|
||||||
* - Geração posterior de WHERE (Knex / SQL)
|
|
||||||
* - Uso seguro por IA (evita filtros inválidos em nível de tipo)
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* FORMATO DO FILTRO
|
|
||||||
* -----------------------------------------------------------------------------
|
|
||||||
* 1) Campos simples:
|
|
||||||
*
|
|
||||||
* {
|
|
||||||
* idade: { ">=": 18 }
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* 2) Campos aninhados:
|
|
||||||
*
|
|
||||||
* {
|
|
||||||
* carro: {
|
|
||||||
* ano: { "=": 2020 }
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* 3) Operador E (AND):
|
|
||||||
*
|
|
||||||
* {
|
|
||||||
* E: [
|
|
||||||
* { idade: { ">=": 18 } },
|
|
||||||
* { nome: { like: "%pa%" } }
|
|
||||||
* ]
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* 4) Operador OU (OR):
|
|
||||||
*
|
|
||||||
* {
|
|
||||||
* OU: [
|
|
||||||
* { idade: { "<": 18 } },
|
|
||||||
* { idade: { ">=": 60 } }
|
|
||||||
* ]
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* 5) Combinação complexa:
|
|
||||||
*
|
|
||||||
* {
|
|
||||||
* idade: { ">=": 18 },
|
|
||||||
* OU: [
|
|
||||||
* { nome: { like: "%pa%" } },
|
|
||||||
* {
|
|
||||||
* E: [
|
|
||||||
* { carro: { ano: { "=": 2020 } } },
|
|
||||||
* { carro: { modelo: { in: ["Civic"] } } }
|
|
||||||
* ]
|
|
||||||
* }
|
|
||||||
* ]
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* REGRAS IMPORTANTES (PARA IA)
|
|
||||||
* -----------------------------------------------------------------------------
|
|
||||||
* - Apenas campos existentes em T podem ser usados.
|
|
||||||
* - Operadores são restritos por tipo do campo.
|
|
||||||
* - Objetos são tratados recursivamente.
|
|
||||||
* - Arrays NÃO são tratados como objeto recursivo.
|
|
||||||
* - Funções NÃO são consideradas campos filtráveis.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* OPERADORES SUPORTADOS
|
|
||||||
* -----------------------------------------------------------------------------
|
|
||||||
* number:
|
|
||||||
* =, !=, >, >=, <, <=, in
|
|
||||||
*
|
|
||||||
* string:
|
|
||||||
* =, !=, like, in
|
|
||||||
*
|
|
||||||
* boolean:
|
|
||||||
* =, !=, in
|
|
||||||
*
|
|
||||||
* Não há suporte automático a:
|
|
||||||
* - null
|
|
||||||
* - date
|
|
||||||
* - jsonb
|
|
||||||
* - arrays
|
|
||||||
*
|
|
||||||
* Essas extensões devem ser adicionadas explicitamente.
|
|
||||||
*
|
|
||||||
* =============================================================================
|
|
||||||
*/
|
|
||||||
declare enum operadores26 {
|
|
||||||
"=" = "=",
|
|
||||||
"!=" = "!=",
|
|
||||||
">" = ">",
|
|
||||||
">=" = ">=",
|
|
||||||
"<" = "<",
|
|
||||||
"<=" = "<=",
|
|
||||||
like = "like",
|
|
||||||
in = "in"
|
|
||||||
}
|
|
||||||
declare enum agrupadores26 {
|
|
||||||
E = "E",
|
|
||||||
OU = "OU"
|
|
||||||
}
|
|
||||||
type PgOpsNumber = {
|
|
||||||
[K in Extract<operadores26, "=" | "!=" | ">" | ">=" | "<" | "<=">]?: number;
|
|
||||||
} & {
|
|
||||||
[K in Extract<operadores26, "in">]?: number[];
|
|
||||||
};
|
|
||||||
type PgOpsString = {
|
|
||||||
[K in Extract<operadores26, "=" | "!=" | "like">]?: string;
|
|
||||||
} & {
|
|
||||||
[K in Extract<operadores26, "in">]?: string[];
|
|
||||||
};
|
|
||||||
type PgOpsBoolean = {
|
|
||||||
[K in Extract<operadores26, "=" | "!=">]?: boolean;
|
|
||||||
} & {
|
|
||||||
[K in Extract<operadores26, "in">]?: boolean[];
|
|
||||||
};
|
|
||||||
type PgOpsFor<V> = V extends number ? PgOpsNumber : V extends string ? PgOpsString : V extends boolean ? PgOpsBoolean : never;
|
|
||||||
type IsPlainObject<T> = T extends object ? T extends Function ? false : T extends readonly any[] ? false : true : false;
|
|
||||||
type FiltroCampos<T> = {
|
|
||||||
[K in keyof T]?: IsPlainObject<T[K]> extends true ? tipoFiltro26<T[K]> : PgOpsFor<T[K]>;
|
|
||||||
};
|
|
||||||
type tipoFiltro26<T> = FiltroCampos<T> & {
|
|
||||||
/**
|
|
||||||
* E => AND lógico
|
|
||||||
* Todos os filtros dentro do array devem ser verdadeiros.
|
|
||||||
*/
|
|
||||||
E?: tipoFiltro26<T>[];
|
|
||||||
/**
|
|
||||||
* OU => OR lógico
|
|
||||||
* Pelo menos um filtro dentro do array deve ser verdadeiro.
|
|
||||||
*/
|
|
||||||
OU?: tipoFiltro26<T>[];
|
|
||||||
};
|
|
||||||
declare const zFiltro26: z$1.ZodType<any>;
|
|
||||||
declare const criarFiltro26: <T>(filtro: tipoFiltro26<T>) => tipoFiltro26<T>;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Essa variável se conecta a tabela_lidades
|
* Essa variável se conecta a tabela_lidades
|
||||||
*
|
*
|
||||||
|
|
@ -560,4 +367,4 @@ declare const nomeVariavel: (v: {
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}) => string;
|
}) => string;
|
||||||
|
|
||||||
export { Produtos, TipagemRotas, type TipoPayloadAuditoria, agrupadores26, aleatorio, cacheM, cacheMFixo, cacheMemoria, camposComuns, criarFiltro26, defineDayjsBr, erUuid, esperar, extensoes, type interfaceConsulta, link_paiol, localValor, nomeVariavel, objetoPg, operadores, operadores26, paraObjetoRegistroPg, pgObjeto, siglas_unidades_medida, texto_busca, tipoArquivo, type tipoFiltro, type tipoFiltro26, tipoUsuarioResiduos, tiposSituacoesElicencie, tx, umaFuncao, umaVariavel, unidades_medida, uuid, uuidV3, uuidV4, uuid_null, validarUuid, verCacheM, zFiltro, zFiltro26, zOperadores };
|
export { Produtos, TipagemRotas, type TipoLoggerSessao, aleatorio, cacheM, cacheMFixo, cacheMemoria, camposComuns, defineCwd, erUuid, esperar, extensoes, type interfaceConsulta, link_paiol, localValor, logger, nomeVariavel, objetoPg, operadores, paraObjetoRegistroPg, pgObjeto, postLogger, siglas_unidades_medida, texto_busca, tipoArquivo, type tipoFiltro, type tipoLogger, type tipoLoggerLog, type tipoLokiObjeto, tipoUsuarioResiduos, tiposSituacoesElicencie, tx, umaFuncao, umaVariavel, unidades_medida, uuid, uuidV3, uuidV4, uuid_null, validarUuid, verCacheM, zFiltro, zOperadores };
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
26
package.json
26
package.json
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "p-comuns",
|
"name": "p-comuns",
|
||||||
"version": "0.336.0",
|
"version": "0.303.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "./dist-front/index.mjs",
|
"main": "./dist-front/index.mjs",
|
||||||
"module": "./dist-front/index.mjs",
|
"module": "./dist-front/index.mjs",
|
||||||
|
|
@ -17,8 +17,7 @@
|
||||||
"check": "pnpm run biome && npx tsc --noEmit",
|
"check": "pnpm run biome && npx tsc --noEmit",
|
||||||
"build": "npm --no-git-tag-version version minor && pnpm run biome && tsup --config ./tsup/tsup.config.ts && pnpm run pacote",
|
"build": "npm --no-git-tag-version version minor && pnpm run biome && tsup --config ./tsup/tsup.config.ts && pnpm run pacote",
|
||||||
"teste": "npx vitest run src/testes/TipagemRotas.test.ts",
|
"teste": "npx vitest run src/testes/TipagemRotas.test.ts",
|
||||||
"pacote": "npm pack && npm pack && mv $(npm pack --silent) pacote.tgz",
|
"pacote": "npm pack && npm pack && mv $(npm pack --silent) pacote.tgz"
|
||||||
"postinstall": "node ./scripts/atualizar-biome.js"
|
|
||||||
},
|
},
|
||||||
"author": {
|
"author": {
|
||||||
"name": "AZTECA SOFTWARE LTDA",
|
"name": "AZTECA SOFTWARE LTDA",
|
||||||
|
|
@ -26,21 +25,24 @@
|
||||||
"url": "https://e-licencie.com.br"
|
"url": "https://e-licencie.com.br"
|
||||||
},
|
},
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {},
|
"dependencies": {
|
||||||
"devDependencies": {
|
"cross-fetch": "4.1.0",
|
||||||
"uuid": "^11.1.0",
|
|
||||||
"zod": "4.3.6",
|
|
||||||
"dayjs": "^1.11.18",
|
"dayjs": "^1.11.18",
|
||||||
"@biomejs/biome": "2.4.12",
|
"uuid": "^11.1.0",
|
||||||
"@types/node": "^22",
|
"zod": "4.1.4"
|
||||||
"tsup": "8.5.1",
|
},
|
||||||
"typescript": "^6",
|
"devDependencies": {
|
||||||
|
"@biomejs/biome": "2.4.0",
|
||||||
|
"@types/node": "^20.19.22",
|
||||||
|
"tsup": "8.5.0",
|
||||||
|
"typescript": "~5.9.3",
|
||||||
"unbuild": "^3.6.1",
|
"unbuild": "^3.6.1",
|
||||||
"vitest": "^3.2.4"
|
"vitest": "^3.2.4"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
|
"cross-fetch": "4.1.0",
|
||||||
"dayjs": "^1.11.18",
|
"dayjs": "^1.11.18",
|
||||||
"uuid": "^11.1.0",
|
"uuid": "^11.1.0",
|
||||||
"zod": "4.3.6"
|
"zod": "4.1.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
BIN
pacote.tgz
BIN
pacote.tgz
Binary file not shown.
1843
pnpm-lock.yaml
generated
Executable file → Normal file
1843
pnpm-lock.yaml
generated
Executable file → Normal file
File diff suppressed because it is too large
Load diff
0
requisicoes.rest
Executable file → Normal file
0
requisicoes.rest
Executable file → Normal file
|
|
@ -1,96 +0,0 @@
|
||||||
const fs = require('node:fs');
|
|
||||||
const path = require('node:path');
|
|
||||||
|
|
||||||
const initCwd = process.env.INIT_CWD;
|
|
||||||
|
|
||||||
// Se não tiver INIT_CWD, não foi chamado pelo npm/pnpm install
|
|
||||||
if (!initCwd) {
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// O próprio p-comuns não precisa se atualizar na sua pasta interna
|
|
||||||
if (initCwd === process.cwd()) {
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
const me = require('../package.json');
|
|
||||||
const biomeVersion = me.devDependencies && me.devDependencies['@biomejs/biome'];
|
|
||||||
|
|
||||||
if (!biomeVersion) {
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Lê os arquivos do diretório em busca de package.json
|
|
||||||
*/
|
|
||||||
function findPackageJson(dir) {
|
|
||||||
let results = [];
|
|
||||||
try {
|
|
||||||
const list = fs.readdirSync(dir);
|
|
||||||
for (const file of list) {
|
|
||||||
const filePath = path.join(dir, file);
|
|
||||||
const stat = fs.statSync(filePath);
|
|
||||||
if (stat && stat.isDirectory()) {
|
|
||||||
// Ignora pastas que não devemos varrer
|
|
||||||
if (
|
|
||||||
![
|
|
||||||
'node_modules',
|
|
||||||
'.git',
|
|
||||||
'dist',
|
|
||||||
'build',
|
|
||||||
'.nuxt',
|
|
||||||
'.output',
|
|
||||||
'.vscode',
|
|
||||||
'.idea',
|
|
||||||
].includes(file)
|
|
||||||
) {
|
|
||||||
results = results.concat(findPackageJson(filePath));
|
|
||||||
}
|
|
||||||
} else if (file === 'package.json') {
|
|
||||||
results.push(filePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
// ignora pastas sem acesso
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
const files = findPackageJson(initCwd);
|
|
||||||
let updated = 0;
|
|
||||||
|
|
||||||
for (const file of files) {
|
|
||||||
try {
|
|
||||||
const content = fs.readFileSync(file, 'utf8');
|
|
||||||
// Detecta se usa tab ou espaço
|
|
||||||
const indent = content.match(/^[ \t]+/m) ? content.match(/^[ \t]+/m)[0] : '\t';
|
|
||||||
|
|
||||||
const json = JSON.parse(content);
|
|
||||||
let changed = false;
|
|
||||||
|
|
||||||
const updateDeps = (tipo) => {
|
|
||||||
if (json[tipo] && json[tipo]['@biomejs/biome']) {
|
|
||||||
if (json[tipo]['@biomejs/biome'] !== biomeVersion) {
|
|
||||||
json[tipo]['@biomejs/biome'] = biomeVersion;
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
updateDeps('dependencies');
|
|
||||||
updateDeps('devDependencies');
|
|
||||||
updateDeps('peerDependencies');
|
|
||||||
|
|
||||||
if (changed) {
|
|
||||||
fs.writeFileSync(file, JSON.stringify(json, null, indent) + '\n', 'utf8');
|
|
||||||
updated++;
|
|
||||||
console.log(`[p-comuns] @biomejs/biome atualizado para ${biomeVersion} em: ${path.relative(initCwd, file)}`);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error(`[p-comuns] Erro ao atualizar ${file}: ${e.message}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (updated > 0) {
|
|
||||||
console.log(`[p-comuns] Total de package.json atualizados: ${updated}`);
|
|
||||||
}
|
|
||||||
0
src/aleatorio.ts
Executable file → Normal file
0
src/aleatorio.ts
Executable file → Normal file
|
|
@ -1,31 +0,0 @@
|
||||||
export type TipoPayloadAuditoria = {
|
|
||||||
/** UUID do registro de auditoria */
|
|
||||||
codigo?: string | null
|
|
||||||
|
|
||||||
/** UUID do usuario da acao (pode ser null se for processo do sistema que não registrou) */
|
|
||||||
usuario_criacao: string | null
|
|
||||||
|
|
||||||
/** Timestamp ou data de criacao / execucao */
|
|
||||||
data_criacao: string | Date
|
|
||||||
|
|
||||||
/** Nome exato da tabela no banco que originou o registro */
|
|
||||||
tabela_origem: string
|
|
||||||
|
|
||||||
/** Código único (UUID) do registro na tabela original */
|
|
||||||
codigo_origem: string
|
|
||||||
|
|
||||||
/** JSON contendo o snapshot das colunas novas / editadas */
|
|
||||||
novo: Record<string, any>
|
|
||||||
|
|
||||||
/** JSON contendo o snapshot das colunas antes da edição */
|
|
||||||
anterior: Record<string, any>
|
|
||||||
|
|
||||||
/** Hash ou controle de versao do item, usualmente preenchido por new.ver_seg */
|
|
||||||
__versao: string
|
|
||||||
|
|
||||||
/** Tipo de operação que gerou a auditoria */
|
|
||||||
acao: "criar" | "atualizar" | "deletar" | string
|
|
||||||
|
|
||||||
/** Versão do sistema no momento em que a ação ocorreu */
|
|
||||||
versao_sistema: string
|
|
||||||
}
|
|
||||||
6
src/cacheMemoria.ts
Executable file → Normal file
6
src/cacheMemoria.ts
Executable file → Normal file
|
|
@ -12,7 +12,11 @@ const _cache: {
|
||||||
|
|
||||||
;(globalThis as any).cacheMemoria_cache = _cache
|
;(globalThis as any).cacheMemoria_cache = _cache
|
||||||
|
|
||||||
export const cacheM = <T>(chave: any, valor?: T, validadeSeg?: number): T | undefined => {
|
export const cacheM = <T>(
|
||||||
|
chave: any,
|
||||||
|
valor?: T,
|
||||||
|
validadeSeg?: number,
|
||||||
|
): T | undefined => {
|
||||||
// converte a chave e string
|
// converte a chave e string
|
||||||
const txChave: string =
|
const txChave: string =
|
||||||
typeof chave == "string"
|
typeof chave == "string"
|
||||||
|
|
|
||||||
0
src/constantes.ts
Executable file → Normal file
0
src/constantes.ts
Executable file → Normal file
12
src/consulta.ts
Executable file → Normal file
12
src/consulta.ts
Executable file → Normal file
|
|
@ -30,7 +30,17 @@ export type interfaceConsulta = {
|
||||||
apenasContagem?: boolean
|
apenasContagem?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export const zOperadores = z.enum(["=", "!=", ">", ">=", "<", "<=", "like", "in", "isNull"])
|
export const zOperadores = z.enum([
|
||||||
|
"=",
|
||||||
|
"!=",
|
||||||
|
">",
|
||||||
|
">=",
|
||||||
|
"<",
|
||||||
|
"<=",
|
||||||
|
"like",
|
||||||
|
"in",
|
||||||
|
"isNull",
|
||||||
|
])
|
||||||
|
|
||||||
export const zFiltro = z.object({
|
export const zFiltro = z.object({
|
||||||
coluna: z.string(),
|
coluna: z.string(),
|
||||||
|
|
|
||||||
34
src/dayjs.ts
Executable file → Normal file
34
src/dayjs.ts
Executable file → Normal file
|
|
@ -1,5 +1,4 @@
|
||||||
import type dayjs from "dayjs"
|
import dayjsbr, { type Dayjs } from "dayjs"
|
||||||
import type { Dayjs } from "dayjs"
|
|
||||||
|
|
||||||
export type { ManipulateType } from "dayjs"
|
export type { ManipulateType } from "dayjs"
|
||||||
|
|
||||||
|
|
@ -12,18 +11,27 @@ import timezone from "dayjs/plugin/timezone"
|
||||||
import utc from "dayjs/plugin/utc"
|
import utc from "dayjs/plugin/utc"
|
||||||
import weekOfYear from "dayjs/plugin/weekOfYear"
|
import weekOfYear from "dayjs/plugin/weekOfYear"
|
||||||
import "dayjs/locale/pt-br"
|
import "dayjs/locale/pt-br"
|
||||||
|
dayjsbr.locale("pt-br")
|
||||||
|
|
||||||
export const definirDayjsbr = (dayjsEntrada: typeof dayjs) => {
|
dayjsbr.extend(utc)
|
||||||
dayjsEntrada.locale("pt-br")
|
dayjsbr.extend(timezone)
|
||||||
dayjsEntrada.extend(utc)
|
dayjsbr.extend(weekOfYear)
|
||||||
dayjsEntrada.extend(timezone)
|
dayjsbr.extend(isSameOrBefore)
|
||||||
dayjsEntrada.extend(weekOfYear)
|
dayjsbr.extend(isSameOrAfter)
|
||||||
dayjsEntrada.extend(isSameOrBefore)
|
dayjsbr.extend(minMax)
|
||||||
dayjsEntrada.extend(isSameOrAfter)
|
dayjsbr.extend(relativeTime)
|
||||||
dayjsEntrada.extend(minMax)
|
dayjsbr.extend(duration)
|
||||||
dayjsEntrada.extend(relativeTime)
|
|
||||||
dayjsEntrada.extend(duration)
|
export {
|
||||||
return dayjsEntrada
|
dayjsbr,
|
||||||
|
duration,
|
||||||
|
isSameOrAfter,
|
||||||
|
isSameOrBefore,
|
||||||
|
minMax,
|
||||||
|
relativeTime,
|
||||||
|
timezone,
|
||||||
|
utc,
|
||||||
|
weekOfYear,
|
||||||
}
|
}
|
||||||
|
|
||||||
export type { Dayjs }
|
export type { Dayjs }
|
||||||
|
|
|
||||||
106
src/dayjs26.ts
106
src/dayjs26.ts
|
|
@ -1,106 +0,0 @@
|
||||||
/**
|
|
||||||
* Utilitário de configuração do Dayjs focado em compatibilidade com SSR.
|
|
||||||
*
|
|
||||||
* PROBLEMA:
|
|
||||||
* A importação direta do `dayjs` e seus plugins frequentemente causa conflitos em ambientes
|
|
||||||
* de Renderização do Lado do Servidor (SSR), como Nuxt ou Next.js, devido a discrepâncias
|
|
||||||
* na resolução de módulos (ESM vs CJS) e instabilidades de importação.
|
|
||||||
*
|
|
||||||
* SOLUÇÃO:
|
|
||||||
* Este módulo utiliza o padrão de Injeção de Dependência. Ele expõe apenas tipagens e
|
|
||||||
* uma função de configuração (`defineDayjsBr`). A responsabilidade de importar as
|
|
||||||
* bibliotecas "vivas" é delegada à aplicação consumidora (o cliente da função).
|
|
||||||
*
|
|
||||||
* Isso permite que o bundler da aplicação principal (Vite, Webpack, etc.) gerencie as
|
|
||||||
* instâncias, garantindo consistência e evitando erros de "module not found" ou
|
|
||||||
* instâncias duplicadas/não inicializadas adequadamente.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import type _dayjs from "dayjs"
|
|
||||||
import type { Dayjs } from "dayjs"
|
|
||||||
|
|
||||||
export type { ManipulateType } from "dayjs"
|
|
||||||
|
|
||||||
// Importação apenas de TIPOS para evitar bundling indesejado neste arquivo
|
|
||||||
import type _duration from "dayjs/plugin/duration"
|
|
||||||
import type _isSameOrAfter from "dayjs/plugin/isSameOrAfter"
|
|
||||||
import type _isSameOrBefore from "dayjs/plugin/isSameOrBefore"
|
|
||||||
import type _minMax from "dayjs/plugin/minMax"
|
|
||||||
import type _relativeTime from "dayjs/plugin/relativeTime"
|
|
||||||
import type _timezone from "dayjs/plugin/timezone"
|
|
||||||
import type _utc from "dayjs/plugin/utc"
|
|
||||||
import type _weekOfYear from "dayjs/plugin/weekOfYear"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Inicializa e configura o Dayjs com o locale 'pt-br' e plugins essenciais.
|
|
||||||
*
|
|
||||||
* MODO DE USO:
|
|
||||||
* Importe os pacotes reais na sua aplicação e passe-os para esta função.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts
|
|
||||||
* // Em seu arquivo de configuração (ex: plugins/dayjs.ts):
|
|
||||||
* import dayjs from "dayjs"
|
|
||||||
* import duration from "dayjs/plugin/duration"
|
|
||||||
* import isSameOrAfter from "dayjs/plugin/isSameOrAfter"
|
|
||||||
* import isSameOrBefore from "dayjs/plugin/isSameOrBefore"
|
|
||||||
* import minMax from "dayjs/plugin/minMax"
|
|
||||||
* import relativeTime from "dayjs/plugin/relativeTime"
|
|
||||||
* import timezone from "dayjs/plugin/timezone"
|
|
||||||
* import utc from "dayjs/plugin/utc"
|
|
||||||
* import weekOfYear from "dayjs/plugin/weekOfYear"
|
|
||||||
* import { defineDayjsBr } from "p-comuns"
|
|
||||||
* import "dayjs/locale/pt-br" // Importante: importar o locale!
|
|
||||||
|
|
||||||
* export const dayjsbr = defineDayjsBr({
|
|
||||||
* dayjs,
|
|
||||||
* duration,
|
|
||||||
* isSameOrAfter,
|
|
||||||
* isSameOrBefore,
|
|
||||||
* minMax,
|
|
||||||
* relativeTime,
|
|
||||||
* timezone,
|
|
||||||
* utc,
|
|
||||||
* weekOfYear,
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
const defineDayjsBr = ({
|
|
||||||
dayjs,
|
|
||||||
duration,
|
|
||||||
isSameOrAfter,
|
|
||||||
isSameOrBefore,
|
|
||||||
minMax,
|
|
||||||
relativeTime,
|
|
||||||
timezone,
|
|
||||||
utc,
|
|
||||||
weekOfYear,
|
|
||||||
}: {
|
|
||||||
dayjs: typeof _dayjs
|
|
||||||
duration: typeof _duration
|
|
||||||
isSameOrAfter: typeof _isSameOrAfter
|
|
||||||
isSameOrBefore: typeof _isSameOrBefore
|
|
||||||
minMax: typeof _minMax
|
|
||||||
relativeTime: typeof _relativeTime
|
|
||||||
timezone: typeof _timezone
|
|
||||||
utc: typeof _utc
|
|
||||||
weekOfYear: typeof _weekOfYear
|
|
||||||
}) => {
|
|
||||||
// Extensão da biblioteca com os plugins fornecidos
|
|
||||||
dayjs.extend(utc)
|
|
||||||
dayjs.extend(timezone)
|
|
||||||
dayjs.extend(weekOfYear)
|
|
||||||
dayjs.extend(isSameOrBefore)
|
|
||||||
dayjs.extend(isSameOrAfter)
|
|
||||||
dayjs.extend(minMax)
|
|
||||||
dayjs.extend(relativeTime)
|
|
||||||
dayjs.extend(duration)
|
|
||||||
|
|
||||||
// Definição do locale global
|
|
||||||
dayjs.locale("pt-br")
|
|
||||||
|
|
||||||
return dayjs
|
|
||||||
}
|
|
||||||
|
|
||||||
export type { Dayjs }
|
|
||||||
export { defineDayjsBr }
|
|
||||||
0
src/ecosistema/index.ts
Executable file → Normal file
0
src/ecosistema/index.ts
Executable file → Normal file
0
src/ecosistema/urls.ts
Executable file → Normal file
0
src/ecosistema/urls.ts
Executable file → Normal file
4
src/extensoes.ts
Executable file → Normal file
4
src/extensoes.ts
Executable file → Normal file
|
|
@ -162,7 +162,9 @@ export const extensoes: {
|
||||||
* @param nomeArquivo
|
* @param nomeArquivo
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const tipoArquivo = (nomeArquivo: string | null | undefined): tiposArquivo => {
|
export const tipoArquivo = (
|
||||||
|
nomeArquivo: string | null | undefined,
|
||||||
|
): tiposArquivo => {
|
||||||
// extenssão do arquivo
|
// extenssão do arquivo
|
||||||
const extArquivo = String(nomeArquivo || "")
|
const extArquivo = String(nomeArquivo || "")
|
||||||
.toLocaleLowerCase()
|
.toLocaleLowerCase()
|
||||||
|
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
export const graficos_pilao: {
|
|
||||||
[k: string]: { grafico: string; titulo: string }
|
|
||||||
} = {
|
|
||||||
Condicionantes: {
|
|
||||||
grafico: "condicionantes-criadas",
|
|
||||||
titulo: "Condicionantes Criadas",
|
|
||||||
},
|
|
||||||
Licenças: {
|
|
||||||
grafico: "licencas-criadas",
|
|
||||||
titulo: "Licenças Criadas",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
6
src/index.ts
Executable file → Normal file
6
src/index.ts
Executable file → Normal file
|
|
@ -1,13 +1,14 @@
|
||||||
export * from "./aleatorio"
|
export * from "./aleatorio"
|
||||||
export * from "./auditoria"
|
|
||||||
export * from "./cacheMemoria"
|
export * from "./cacheMemoria"
|
||||||
export * from "./constantes"
|
export * from "./constantes"
|
||||||
export * from "./consulta"
|
export * from "./consulta"
|
||||||
export * from "./dayjs26"
|
export * from "./dayjs"
|
||||||
export * from "./ecosistema"
|
export * from "./ecosistema"
|
||||||
export * from "./extensoes"
|
export * from "./extensoes"
|
||||||
export * from "./extensoes"
|
export * from "./extensoes"
|
||||||
export * from "./local"
|
export * from "./local"
|
||||||
|
export * from "./logger"
|
||||||
|
export * from "./logger"
|
||||||
export * from "./postgres"
|
export * from "./postgres"
|
||||||
export * from "./produtos"
|
export * from "./produtos"
|
||||||
export * from "./situacoes"
|
export * from "./situacoes"
|
||||||
|
|
@ -15,7 +16,6 @@ export * from "./testes-de-variaveis"
|
||||||
export * from "./texto_busca"
|
export * from "./texto_busca"
|
||||||
export * from "./tipagemRotas"
|
export * from "./tipagemRotas"
|
||||||
export * from "./tipagemRotas"
|
export * from "./tipagemRotas"
|
||||||
export * from "./tipoFiltro.26"
|
|
||||||
export * from "./unidades_medida"
|
export * from "./unidades_medida"
|
||||||
export * from "./uuid"
|
export * from "./uuid"
|
||||||
export * from "./variaveisComuns"
|
export * from "./variaveisComuns"
|
||||||
|
|
|
||||||
0
src/instalarAmbiente.ts
Executable file → Normal file
0
src/instalarAmbiente.ts
Executable file → Normal file
13
src/local/index.ts
Executable file → Normal file
13
src/local/index.ts
Executable file → Normal file
|
|
@ -2,11 +2,18 @@
|
||||||
* LocalStorage Tipado
|
* LocalStorage Tipado
|
||||||
* Lê ou grava um valor no localStorage, mantendo o tipo genérico <T>.
|
* Lê ou grava um valor no localStorage, mantendo o tipo genérico <T>.
|
||||||
*/
|
*/
|
||||||
export const localValor = <T>(chave_: string | any, valor?: T | null): T | null => {
|
export const localValor = <T>(
|
||||||
const localStorage = "localStorage" in globalThis ? (globalThis as any).localStorage : undefined
|
chave_: string | any,
|
||||||
|
valor?: T | null,
|
||||||
|
): T | null => {
|
||||||
|
const localStorage = globalThis.localStorage
|
||||||
|
|
||||||
if (typeof localStorage == "undefined") return null
|
if (typeof localStorage == "undefined") return null
|
||||||
|
|
||||||
const chave = typeof chave_ === "string" ? chave_ : encodeURIComponent(JSON.stringify(chave_))
|
const chave =
|
||||||
|
typeof chave_ === "string"
|
||||||
|
? chave_
|
||||||
|
: encodeURIComponent(JSON.stringify(chave_))
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Grava valor se fornecido
|
// Grava valor se fornecido
|
||||||
|
|
|
||||||
126
src/logger.ts
Normal file
126
src/logger.ts
Normal file
|
|
@ -0,0 +1,126 @@
|
||||||
|
import crossFetch from "cross-fetch"
|
||||||
|
import { nomeVariavel } from "./variaveisComuns"
|
||||||
|
|
||||||
|
const LOKI_BASE_URL = "https://log.idz.one"
|
||||||
|
const LOKI_ENDPOINT = "/loki/api/v1/push"
|
||||||
|
export type tipoLokiObjeto = {
|
||||||
|
streams: {
|
||||||
|
stream: {
|
||||||
|
[k: string]: string
|
||||||
|
}
|
||||||
|
values: [string, string][]
|
||||||
|
}[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export const postLogger = async ({
|
||||||
|
objeto,
|
||||||
|
}: {
|
||||||
|
objeto: tipoLokiObjeto
|
||||||
|
}): Promise<[objeto: tipoLokiObjeto, erro?: string]> => {
|
||||||
|
const response = await crossFetch(`${LOKI_BASE_URL}${LOKI_ENDPOINT}`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify(objeto),
|
||||||
|
}).catch((a) => a)
|
||||||
|
if (!response.ok) {
|
||||||
|
return [objeto, `Erro ${response.status}: ${await response?.text?.()}`]
|
||||||
|
}
|
||||||
|
return [objeto]
|
||||||
|
}
|
||||||
|
|
||||||
|
let cwd = ""
|
||||||
|
|
||||||
|
/** define a localização da pasta do projeto */
|
||||||
|
export const defineCwd = (novoCwd: string) => {
|
||||||
|
cwd = novoCwd
|
||||||
|
}
|
||||||
|
|
||||||
|
type tipoLevel = "info" | "warn" | "error"
|
||||||
|
|
||||||
|
type tipoOpSessao = {
|
||||||
|
inquilino: string
|
||||||
|
usuario: string
|
||||||
|
parametros?: { [k: string]: string }
|
||||||
|
}
|
||||||
|
|
||||||
|
type tipoLog = {
|
||||||
|
detalhes?: unknown[]
|
||||||
|
__filename?: string
|
||||||
|
local?: string
|
||||||
|
parametros?: { [k: string]: string }
|
||||||
|
}
|
||||||
|
|
||||||
|
export type tipoLoggerLog = (
|
||||||
|
level: tipoLevel,
|
||||||
|
mensagem: string,
|
||||||
|
op_tipoLog?: tipoLog,
|
||||||
|
) => Promise<[objeto: tipoLokiObjeto, erro?: string]>
|
||||||
|
|
||||||
|
export type TipoLoggerSessao = (sess: tipoOpSessao) => tipoLoggerLog
|
||||||
|
|
||||||
|
export type tipoLogger = (amb: {
|
||||||
|
app: string
|
||||||
|
eProducao: boolean
|
||||||
|
parametros?: {
|
||||||
|
[k: string]: string
|
||||||
|
}
|
||||||
|
}) => TipoLoggerSessao
|
||||||
|
|
||||||
|
export const logger: tipoLogger =
|
||||||
|
({ app: app_e, eProducao, parametros: parametrosAmbiente }) =>
|
||||||
|
({ inquilino, usuario, parametros: parametrosSessao }) =>
|
||||||
|
async (level, mensagem, op_tipoLog) => {
|
||||||
|
let {
|
||||||
|
__filename,
|
||||||
|
detalhes,
|
||||||
|
local,
|
||||||
|
parametros: parametrosLog,
|
||||||
|
} = op_tipoLog || {}
|
||||||
|
|
||||||
|
const app = `${eProducao ? "" : "DEV-"}${app_e}`
|
||||||
|
|
||||||
|
if (cwd && __filename) {
|
||||||
|
__filename = __filename.replace(cwd, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (local) {
|
||||||
|
detalhes = [`${nomeVariavel({ local })}="${local}"`, ...(detalhes || [])]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (__filename) {
|
||||||
|
detalhes = [
|
||||||
|
`${nomeVariavel({ __filename })}="${__filename}"`,
|
||||||
|
...(detalhes || []),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
const timestamp = `${Date.now()}000000`
|
||||||
|
|
||||||
|
const mainLog = detalhes?.length
|
||||||
|
? `${mensagem} | ${detalhes.map((d) => JSON.stringify(d)).join(" | ")}`
|
||||||
|
: mensagem
|
||||||
|
|
||||||
|
const payload: tipoLokiObjeto["streams"][number] = {
|
||||||
|
stream: {
|
||||||
|
app,
|
||||||
|
inquilino,
|
||||||
|
usuario,
|
||||||
|
level,
|
||||||
|
...(parametrosAmbiente || {}),
|
||||||
|
...(parametrosSessao || {}),
|
||||||
|
...(parametrosLog || {}),
|
||||||
|
},
|
||||||
|
values: [
|
||||||
|
[
|
||||||
|
timestamp,
|
||||||
|
mainLog, // Linha de log direta
|
||||||
|
],
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
const objeto: tipoLokiObjeto = { streams: [payload] }
|
||||||
|
|
||||||
|
const response = await postLogger({ objeto })
|
||||||
|
|
||||||
|
return response
|
||||||
|
}
|
||||||
4
src/postgres.ts
Executable file → Normal file
4
src/postgres.ts
Executable file → Normal file
|
|
@ -14,7 +14,9 @@ export const paraObjetoRegistroPg = (entrada: {
|
||||||
k,
|
k,
|
||||||
v === undefined || v == null
|
v === undefined || v == null
|
||||||
? v
|
? v
|
||||||
: typeof v == "string" || typeof v == "number" || typeof v == "boolean"
|
: typeof v == "string" ||
|
||||||
|
typeof v == "number" ||
|
||||||
|
typeof v == "boolean"
|
||||||
? v
|
? v
|
||||||
: JSON.stringify(v, null, 2),
|
: JSON.stringify(v, null, 2),
|
||||||
]),
|
]),
|
||||||
|
|
|
||||||
0
src/teste.ts
Executable file → Normal file
0
src/teste.ts
Executable file → Normal file
0
src/testes-de-variaveis/index.ts
Executable file → Normal file
0
src/testes-de-variaveis/index.ts
Executable file → Normal file
0
src/testes-de-variaveis/umaFuncao.ts
Executable file → Normal file
0
src/testes-de-variaveis/umaFuncao.ts
Executable file → Normal file
0
src/testes-de-variaveis/umaVariavel.ts
Executable file → Normal file
0
src/testes-de-variaveis/umaVariavel.ts
Executable file → Normal file
0
src/testes/TipagemRotas.test.ts
Executable file → Normal file
0
src/testes/TipagemRotas.test.ts
Executable file → Normal file
0
src/texto_busca.ts
Executable file → Normal file
0
src/texto_busca.ts
Executable file → Normal file
18
src/tipagemRotas.ts
Executable file → Normal file
18
src/tipagemRotas.ts
Executable file → Normal file
|
|
@ -63,8 +63,9 @@ export class TipagemRotas<T extends { [q: string]: any }> {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
endereco(query: T, usarComoHash?: boolean) {
|
endereco(query: T, usarComoHash?: boolean) {
|
||||||
const win = (typeof globalThis !== "undefined" && (globalThis as any).window) || undefined
|
const url = new URL(
|
||||||
const url = new URL(win ? win.location.href : "http://localhost")
|
typeof window !== "undefined" ? window.location.href : "http://localhost",
|
||||||
|
)
|
||||||
|
|
||||||
url.pathname = this.caminho
|
url.pathname = this.caminho
|
||||||
|
|
||||||
|
|
@ -94,9 +95,8 @@ export class TipagemRotas<T extends { [q: string]: any }> {
|
||||||
if (this._acaoIr) {
|
if (this._acaoIr) {
|
||||||
this._acaoIr(this.endereco({ ...query }))
|
this._acaoIr(this.endereco({ ...query }))
|
||||||
} else {
|
} else {
|
||||||
const win = (typeof globalThis !== "undefined" && (globalThis as any).window) || undefined
|
if (typeof window != "undefined") {
|
||||||
if (win) {
|
window.location.href = this.endereco({ ...query })
|
||||||
win.location.href = this.endereco({ ...query })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -110,8 +110,8 @@ export class TipagemRotas<T extends { [q: string]: any }> {
|
||||||
const url = urlEntrada
|
const url = urlEntrada
|
||||||
? new URL(urlEntrada)
|
? new URL(urlEntrada)
|
||||||
: new URL(
|
: new URL(
|
||||||
typeof globalThis !== "undefined" && (globalThis as any).window
|
typeof window !== "undefined"
|
||||||
? (globalThis as any).window.location.href
|
? window.location.href
|
||||||
: "http://localhost",
|
: "http://localhost",
|
||||||
)
|
)
|
||||||
const query = url.searchParams
|
const query = url.searchParams
|
||||||
|
|
@ -120,7 +120,9 @@ export class TipagemRotas<T extends { [q: string]: any }> {
|
||||||
// pegar hash
|
// pegar hash
|
||||||
const hash = url.hash
|
const hash = url.hash
|
||||||
if (hash) {
|
if (hash) {
|
||||||
const hashObj = Object.fromEntries(new URLSearchParams(hash.slice(1)).entries())
|
const hashObj = Object.fromEntries(
|
||||||
|
new URLSearchParams(hash.slice(1)).entries(),
|
||||||
|
)
|
||||||
queryObj = { ...queryObj, ...hashObj } as T
|
queryObj = { ...queryObj, ...hashObj } as T
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,233 +0,0 @@
|
||||||
import { z } from "zod"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* =============================================================================
|
|
||||||
* tipoFiltro26<T>
|
|
||||||
* =============================================================================
|
|
||||||
*
|
|
||||||
* OBJETIVO
|
|
||||||
* -----------------------------------------------------------------------------
|
|
||||||
* Gerar automaticamente a tipagem de filtros compatíveis com operadores
|
|
||||||
* padrão do PostgreSQL, a partir de um tipo base T.
|
|
||||||
*
|
|
||||||
* Este tipo foi projetado para:
|
|
||||||
* - Construção de filtros dinâmicos
|
|
||||||
* - Geração posterior de WHERE (Knex / SQL)
|
|
||||||
* - Uso seguro por IA (evita filtros inválidos em nível de tipo)
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* FORMATO DO FILTRO
|
|
||||||
* -----------------------------------------------------------------------------
|
|
||||||
* 1) Campos simples:
|
|
||||||
*
|
|
||||||
* {
|
|
||||||
* idade: { ">=": 18 }
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* 2) Campos aninhados:
|
|
||||||
*
|
|
||||||
* {
|
|
||||||
* carro: {
|
|
||||||
* ano: { "=": 2020 }
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* 3) Operador E (AND):
|
|
||||||
*
|
|
||||||
* {
|
|
||||||
* E: [
|
|
||||||
* { idade: { ">=": 18 } },
|
|
||||||
* { nome: { like: "%pa%" } }
|
|
||||||
* ]
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* 4) Operador OU (OR):
|
|
||||||
*
|
|
||||||
* {
|
|
||||||
* OU: [
|
|
||||||
* { idade: { "<": 18 } },
|
|
||||||
* { idade: { ">=": 60 } }
|
|
||||||
* ]
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* 5) Combinação complexa:
|
|
||||||
*
|
|
||||||
* {
|
|
||||||
* idade: { ">=": 18 },
|
|
||||||
* OU: [
|
|
||||||
* { nome: { like: "%pa%" } },
|
|
||||||
* {
|
|
||||||
* E: [
|
|
||||||
* { carro: { ano: { "=": 2020 } } },
|
|
||||||
* { carro: { modelo: { in: ["Civic"] } } }
|
|
||||||
* ]
|
|
||||||
* }
|
|
||||||
* ]
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* REGRAS IMPORTANTES (PARA IA)
|
|
||||||
* -----------------------------------------------------------------------------
|
|
||||||
* - Apenas campos existentes em T podem ser usados.
|
|
||||||
* - Operadores são restritos por tipo do campo.
|
|
||||||
* - Objetos são tratados recursivamente.
|
|
||||||
* - Arrays NÃO são tratados como objeto recursivo.
|
|
||||||
* - Funções NÃO são consideradas campos filtráveis.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* OPERADORES SUPORTADOS
|
|
||||||
* -----------------------------------------------------------------------------
|
|
||||||
* number:
|
|
||||||
* =, !=, >, >=, <, <=, in
|
|
||||||
*
|
|
||||||
* string:
|
|
||||||
* =, !=, like, in
|
|
||||||
*
|
|
||||||
* boolean:
|
|
||||||
* =, !=, in
|
|
||||||
*
|
|
||||||
* Não há suporte automático a:
|
|
||||||
* - null
|
|
||||||
* - date
|
|
||||||
* - jsonb
|
|
||||||
* - arrays
|
|
||||||
*
|
|
||||||
* Essas extensões devem ser adicionadas explicitamente.
|
|
||||||
*
|
|
||||||
* =============================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* =============================================================================
|
|
||||||
OPERADORES POSTGRESQL POR TIPO
|
|
||||||
============================================================================= */
|
|
||||||
|
|
||||||
export enum operadores26 {
|
|
||||||
"=" = "=",
|
|
||||||
"!=" = "!=",
|
|
||||||
">" = ">",
|
|
||||||
">=" = ">=",
|
|
||||||
"<" = "<",
|
|
||||||
"<=" = "<=",
|
|
||||||
like = "like",
|
|
||||||
in = "in",
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum agrupadores26 {
|
|
||||||
E = "E",
|
|
||||||
OU = "OU",
|
|
||||||
}
|
|
||||||
|
|
||||||
type PgOpsNumber = {
|
|
||||||
[K in Extract<operadores26, "=" | "!=" | ">" | ">=" | "<" | "<=">]?: number
|
|
||||||
} & {
|
|
||||||
[K in Extract<operadores26, "in">]?: number[]
|
|
||||||
}
|
|
||||||
|
|
||||||
type PgOpsString = {
|
|
||||||
[K in Extract<operadores26, "=" | "!=" | "like">]?: string
|
|
||||||
} & {
|
|
||||||
[K in Extract<operadores26, "in">]?: string[]
|
|
||||||
}
|
|
||||||
|
|
||||||
type PgOpsBoolean = {
|
|
||||||
[K in Extract<operadores26, "=" | "!=">]?: boolean
|
|
||||||
} & {
|
|
||||||
[K in Extract<operadores26, "in">]?: boolean[]
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =============================================================================
|
|
||||||
SELEÇÃO AUTOMÁTICA DE OPERADORES BASEADA NO TIPO DO CAMPO
|
|
||||||
============================================================================= */
|
|
||||||
|
|
||||||
type PgOpsFor<V> = V extends number
|
|
||||||
? PgOpsNumber
|
|
||||||
: V extends string
|
|
||||||
? PgOpsString
|
|
||||||
: V extends boolean
|
|
||||||
? PgOpsBoolean
|
|
||||||
: never
|
|
||||||
|
|
||||||
/* =============================================================================
|
|
||||||
UTILITÁRIO: DETECTAR OBJETO PLANO
|
|
||||||
============================================================================= */
|
|
||||||
|
|
||||||
type IsPlainObject<T> = T extends object
|
|
||||||
? T extends Function
|
|
||||||
? false
|
|
||||||
: T extends readonly any[]
|
|
||||||
? false
|
|
||||||
: true
|
|
||||||
: false
|
|
||||||
|
|
||||||
/* =============================================================================
|
|
||||||
FILTRO RECURSIVO POR CAMPOS
|
|
||||||
============================================================================= */
|
|
||||||
|
|
||||||
type FiltroCampos<T> = {
|
|
||||||
[K in keyof T]?: IsPlainObject<T[K]> extends true ? tipoFiltro26<T[K]> : PgOpsFor<T[K]>
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =============================================================================
|
|
||||||
TIPO PRINCIPAL EXPORTADO
|
|
||||||
============================================================================= */
|
|
||||||
|
|
||||||
export type tipoFiltro26<T> = FiltroCampos<T> & {
|
|
||||||
/**
|
|
||||||
* E => AND lógico
|
|
||||||
* Todos os filtros dentro do array devem ser verdadeiros.
|
|
||||||
*/
|
|
||||||
E?: tipoFiltro26<T>[]
|
|
||||||
|
|
||||||
/**
|
|
||||||
* OU => OR lógico
|
|
||||||
* Pelo menos um filtro dentro do array deve ser verdadeiro.
|
|
||||||
*/
|
|
||||||
OU?: tipoFiltro26<T>[]
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =============================================================================
|
|
||||||
VALIDAÇÃO ESTRUTURAL (ZOD)
|
|
||||||
============================================================================= */
|
|
||||||
|
|
||||||
const zOperadores = z.nativeEnum(operadores26)
|
|
||||||
const zValor = z.any()
|
|
||||||
const zCondicao = z.record(zOperadores, zValor)
|
|
||||||
|
|
||||||
export const zFiltro26: z.ZodType<any> = z.lazy(() =>
|
|
||||||
z
|
|
||||||
.object({
|
|
||||||
E: z.array(zFiltro26).optional(),
|
|
||||||
OU: z.array(zFiltro26).optional(),
|
|
||||||
})
|
|
||||||
.catchall(z.union([zCondicao, zFiltro26])),
|
|
||||||
)
|
|
||||||
|
|
||||||
/* =============================================================================
|
|
||||||
EXEMPLO DE USO
|
|
||||||
============================================================================= */
|
|
||||||
|
|
||||||
type Pessoa = {
|
|
||||||
codigo: string
|
|
||||||
nome: string
|
|
||||||
idade: number
|
|
||||||
carro: {
|
|
||||||
modelo: string
|
|
||||||
ano: number
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const criarFiltro26 = <T>(filtro: tipoFiltro26<T>) => filtro
|
|
||||||
|
|
||||||
const _filtro = criarFiltro26<Pessoa>({
|
|
||||||
idade: { [operadores26[">="]]: 18 },
|
|
||||||
|
|
||||||
[agrupadores26.OU]: [
|
|
||||||
{ nome: { [operadores26.like]: "%pa%" } },
|
|
||||||
{
|
|
||||||
[agrupadores26.E]: [
|
|
||||||
{ carro: { ano: { [operadores26["="]]: 2020 } } },
|
|
||||||
{ carro: { modelo: { [operadores26.in]: ["Civic", "Corolla"] } } },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
0
src/unidades_medida.ts
Executable file → Normal file
0
src/unidades_medida.ts
Executable file → Normal file
3
src/uuid.ts
Executable file → Normal file
3
src/uuid.ts
Executable file → Normal file
|
|
@ -6,7 +6,8 @@ import { NIL, v3, v4 } from "uuid"
|
||||||
* @param valor - A string que será validada.
|
* @param valor - A string que será validada.
|
||||||
* @returns booleano indicando se é um UUID válido.
|
* @returns booleano indicando se é um UUID válido.
|
||||||
*/
|
*/
|
||||||
export const erUuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
|
export const erUuid =
|
||||||
|
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
|
||||||
|
|
||||||
export const validarUuid = (uuid: string | number | undefined | null) => {
|
export const validarUuid = (uuid: string | number | undefined | null) => {
|
||||||
const retorno = erUuid.test(String(uuid || ""))
|
const retorno = erUuid.test(String(uuid || ""))
|
||||||
|
|
|
||||||
7
src/variaveisComuns.ts
Executable file → Normal file
7
src/variaveisComuns.ts
Executable file → Normal file
|
|
@ -1,5 +1,7 @@
|
||||||
export const esperar = (ms: number): Promise<true> =>
|
export const esperar = (ms: number): Promise<true> =>
|
||||||
new Promise((resolve: (r: true) => void) => setTimeout(() => resolve(true), ms))
|
new Promise((resolve: (r: true) => void) =>
|
||||||
|
setTimeout(() => resolve(true), ms),
|
||||||
|
)
|
||||||
/**
|
/**
|
||||||
* Usado para retronat o no de uma variável, deve ser usado dentro de um objeto
|
* Usado para retronat o no de uma variável, deve ser usado dentro de um objeto
|
||||||
* const nomex = {a: 1, b: 2}
|
* const nomex = {a: 1, b: 2}
|
||||||
|
|
@ -7,4 +9,5 @@ export const esperar = (ms: number): Promise<true> =>
|
||||||
* @param v
|
* @param v
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const nomeVariavel = (v: { [key: string]: any }) => Object.keys(v).join("/")
|
export const nomeVariavel = (v: { [key: string]: any }) =>
|
||||||
|
Object.keys(v).join("/")
|
||||||
|
|
|
||||||
0
tsconfig-back.json
Executable file → Normal file
0
tsconfig-back.json
Executable file → Normal file
0
tsconfig-front.json
Executable file → Normal file
0
tsconfig-front.json
Executable file → Normal file
10
tsconfig.json
Executable file → Normal file
10
tsconfig.json
Executable file → Normal file
|
|
@ -6,15 +6,13 @@
|
||||||
/* Linguagem e Ambiente */
|
/* Linguagem e Ambiente */
|
||||||
"target": "ES2020" /* Define a versão do JavaScript para o código emitido. */,
|
"target": "ES2020" /* Define a versão do JavaScript para o código emitido. */,
|
||||||
"lib": [
|
"lib": [
|
||||||
"ES2020",
|
"dom.iterable"
|
||||||
"DOM",
|
|
||||||
"DOM.Iterable"
|
|
||||||
] /* Especifica as bibliotecas padrão a serem incluídas, como DOM para iteradores. */,
|
] /* Especifica as bibliotecas padrão a serem incluídas, como DOM para iteradores. */,
|
||||||
"experimentalDecorators": true /* Habilita o suporte experimental a decoradores. */,
|
"experimentalDecorators": true /* Habilita o suporte experimental a decoradores. */,
|
||||||
"emitDecoratorMetadata": true /* Emite metadados de tipos de design para declarações decoradas. */,
|
"emitDecoratorMetadata": true /* Emite metadados de tipos de design para declarações decoradas. */,
|
||||||
|
|
||||||
/* Módulos */
|
/* Módulos */
|
||||||
"moduleResolution": "bundler" /* Define como o TypeScript resolve módulos. */,
|
"moduleResolution": "node" /* Define como o TypeScript resolve módulos. */,
|
||||||
"rootDir": "./src" /* Define a pasta raiz para os arquivos de origem. */,
|
"rootDir": "./src" /* Define a pasta raiz para os arquivos de origem. */,
|
||||||
|
|
||||||
/* Emissão */
|
/* Emissão */
|
||||||
|
|
@ -25,9 +23,7 @@
|
||||||
|
|
||||||
/* Verificação de Tipos */
|
/* Verificação de Tipos */
|
||||||
"strict": true /* Habilita todas as opções de verificação estrita de tipos. */,
|
"strict": true /* Habilita todas as opções de verificação estrita de tipos. */,
|
||||||
"skipLibCheck": true /* Ignora a verificação de tipos em arquivos de declaração de bibliotecas. */,
|
"skipLibCheck": true /* Ignora a verificação de tipos em arquivos de declaração de bibliotecas. */
|
||||||
// IA manter "ignoreDeprecations": "6.0",
|
|
||||||
"ignoreDeprecations": "6.0"
|
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"src/**/*"
|
"src/**/*"
|
||||||
|
|
|
||||||
0
tsup/como usar.md
Executable file → Normal file
0
tsup/como usar.md
Executable file → Normal file
4
tsup/tsup.config.back.ts
Executable file → Normal file
4
tsup/tsup.config.back.ts
Executable file → Normal file
|
|
@ -18,10 +18,6 @@ export const tsup_config_back: Options = {
|
||||||
minify: false, // Geralmente não minificamos o código do backend em produção, mas você pode mudar
|
minify: false, // Geralmente não minificamos o código do backend em produção, mas você pode mudar
|
||||||
platform: "node",
|
platform: "node",
|
||||||
outExtension: () => ({ js: ".js" }),
|
outExtension: () => ({ js: ".js" }),
|
||||||
loader: {
|
|
||||||
".svg": "text",
|
|
||||||
".md": "text",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exporta a configuração padrão usando defineConfig
|
// Exporta a configuração padrão usando defineConfig
|
||||||
|
|
|
||||||
0
tsup/tsup.config.front.interno.ts
Executable file → Normal file
0
tsup/tsup.config.front.interno.ts
Executable file → Normal file
6
tsup/tsup.config.front.ts
Executable file → Normal file
6
tsup/tsup.config.front.ts
Executable file → Normal file
|
|
@ -16,13 +16,9 @@ export const tsup_config_front: Options = {
|
||||||
sourcemap: false,
|
sourcemap: false,
|
||||||
minify: true, // Recomendado para builds de produção
|
minify: true, // Recomendado para builds de produção
|
||||||
platform: "browser",
|
platform: "browser",
|
||||||
external: ['dayjs', 'cross-fetch', 'uuid', 'zod'],
|
external: ['dayjs'],
|
||||||
outExtension: () => ({ js: ".mjs" }),
|
outExtension: () => ({ js: ".mjs" }),
|
||||||
shims: false,
|
shims: false,
|
||||||
loader: {
|
|
||||||
".svg": "text",
|
|
||||||
".md": "text",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exporta a configuração padrão usando defineConfig
|
// Exporta a configuração padrão usando defineConfig
|
||||||
|
|
|
||||||
0
tsup/tsup.config.interno.ts
Executable file → Normal file
0
tsup/tsup.config.interno.ts
Executable file → Normal file
0
tsup/tsup.config.ts
Executable file → Normal file
0
tsup/tsup.config.ts
Executable file → Normal file
Loading…
Add table
Add a link
Reference in a new issue