forlogic-core 1.12.1 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +106 -3
- package/dist/README.md +106 -3
- package/dist/bin/validate-lib-first.js +238 -0
- package/dist/index.css +1 -3
- package/dist/index.css.map +1 -1
- package/dist/index.esm.js +1 -10
- package/dist/index.js +1 -10
- package/package.json +57 -56
package/README.md
CHANGED
|
@@ -49,6 +49,110 @@ Isso garante que todos os componentes compartilhem a mesma instância do i18next
|
|
|
49
49
|
|
|
50
50
|
---
|
|
51
51
|
|
|
52
|
+
## 📦 LIB-FIRST: Sempre Use Componentes da forlogic-core
|
|
53
|
+
|
|
54
|
+
> **⚠️ REGRA FUNDAMENTAL**: Antes de criar qualquer componente, serviço ou utilitário no projeto, VERIFIQUE se já existe na `forlogic-core`.
|
|
55
|
+
|
|
56
|
+
### 🤔 Por Quê?
|
|
57
|
+
|
|
58
|
+
A `forlogic-core` é a **biblioteca central** de componentes, serviços e utilitários compartilhados entre todos os projetos. Quando você cria um componente local que já existe na lib:
|
|
59
|
+
|
|
60
|
+
1. **❌ Drift de Design** - O componente local não acompanha evoluções futuras da lib
|
|
61
|
+
2. **❌ Duplicação de Código** - Aumenta tamanho do bundle e manutenção
|
|
62
|
+
3. **❌ Inconsistência** - UI/UX diferente entre projetos
|
|
63
|
+
4. **❌ Retrabalho** - Correções de bugs precisam ser feitas em múltiplos lugares
|
|
64
|
+
|
|
65
|
+
### 📋 Checklist OBRIGATÓRIO Antes de Criar Componentes
|
|
66
|
+
|
|
67
|
+
```markdown
|
|
68
|
+
- [ ] Pesquisei se o componente existe na forlogic-core?
|
|
69
|
+
- [ ] Verifiquei a documentação do Design System (/design_system)?
|
|
70
|
+
- [ ] Confirmei que a funcionalidade não pode ser alcançada com props/variantes existentes?
|
|
71
|
+
- [ ] Se não existe, solicitei a inclusão na lib para beneficiar todos os projetos?
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### ✅ CORRETO: Usar da Lib
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
// ✅ Sempre importe da forlogic-core
|
|
78
|
+
import {
|
|
79
|
+
Button,
|
|
80
|
+
Input,
|
|
81
|
+
Dialog,
|
|
82
|
+
Combobox,
|
|
83
|
+
SplitButton,
|
|
84
|
+
RichTextEditor,
|
|
85
|
+
createCrudPage,
|
|
86
|
+
cn,
|
|
87
|
+
formatDatetime
|
|
88
|
+
} from 'forlogic-core';
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### ❌ PROIBIDO: Criar Localmente (se existe na lib)
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
// ❌ NUNCA crie pastas/arquivos que já existem na lib
|
|
95
|
+
src/components/ui/button.tsx // Existe na lib
|
|
96
|
+
src/components/ui/dialog.tsx // Existe na lib
|
|
97
|
+
src/lib/utils.ts // cn() existe na lib
|
|
98
|
+
src/components/SplitButton.tsx // Existe na lib (a partir de v1.12.2)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### 🔄 Processo Quando Precisa de Customização
|
|
102
|
+
|
|
103
|
+
| Cenário | Ação Correta |
|
|
104
|
+
|---------|--------------|
|
|
105
|
+
| Componente não existe na lib | ✅ Criar localmente E solicitar inclusão na lib |
|
|
106
|
+
| Precisa de variante nova | ✅ Solicitar variante na lib (PR ou pedido) |
|
|
107
|
+
| Precisa de comportamento específico | ✅ Usar composição/wrapper ao invés de recriar |
|
|
108
|
+
| Bug no componente da lib | ✅ Reportar e corrigir na lib, não criar cópia local |
|
|
109
|
+
|
|
110
|
+
### 📖 Onde Verificar Componentes Disponíveis
|
|
111
|
+
|
|
112
|
+
| Recurso | Descrição |
|
|
113
|
+
|---------|-----------|
|
|
114
|
+
| `/design_system` | Design System com todos os componentes documentados |
|
|
115
|
+
| `forlogic-core/lib/exports/ui.ts` | Lista de exports de UI |
|
|
116
|
+
| `forlogic-core/lib/index.ts` | Index principal com todos os exports |
|
|
117
|
+
| `npx forlogic-core-pull-docs` | Baixa documentação atualizada |
|
|
118
|
+
| `npx forlogic-core-validate` | **Valida regra Lib-First** |
|
|
119
|
+
|
|
120
|
+
### 🔍 Validação Automática
|
|
121
|
+
|
|
122
|
+
Execute o script de validação para verificar se há componentes duplicados:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
npx forlogic-core-validate
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
O script verifica:
|
|
129
|
+
- ✅ Componentes UI em `src/components/ui/` que já existem na lib
|
|
130
|
+
- ✅ Utilitários em `src/lib/` como `utils.ts` ou `cn.ts`
|
|
131
|
+
- ✅ Hooks duplicados em `src/hooks/`
|
|
132
|
+
- ✅ Configuração do shadcn que pode criar duplicados
|
|
133
|
+
|
|
134
|
+
**Adicione ao CI/CD** para garantir conformidade:
|
|
135
|
+
|
|
136
|
+
```json
|
|
137
|
+
{
|
|
138
|
+
"scripts": {
|
|
139
|
+
"validate:lib-first": "forlogic-core-validate",
|
|
140
|
+
"prebuild": "forlogic-core-validate"
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### ⚠️ Exceções (quando PODE criar localmente)
|
|
146
|
+
|
|
147
|
+
1. **Componente específico de negócio** - Ex: `InvoiceCard`, `UserProfileWidget`
|
|
148
|
+
2. **Composição de componentes da lib** - Ex: wrapper que combina Dialog + Form
|
|
149
|
+
3. **Componente temporário** - Protótipo que será migrado para a lib depois
|
|
150
|
+
4. **Funcionalidade não generalizável** - Algo tão específico que não faz sentido na lib
|
|
151
|
+
|
|
152
|
+
> **📝 Mesmo nas exceções, avalie se o componente poderia ser generalizado e incluído na lib para beneficiar outros projetos.**
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
52
156
|
## 🤖 REGRAS CRÍTICAS
|
|
53
157
|
|
|
54
158
|
> **📋 Schema Padrão**: Veja no **Custom Knowledge** do projeto (Settings → Manage Knowledge) qual é o schema padrão deste projeto específico.
|
|
@@ -1016,7 +1120,7 @@ O comando usa credenciais públicas do Supabase do forlogic-core e não requer c
|
|
|
1016
1120
|
|
|
1017
1121
|
### 📚 Estatísticas da Documentação
|
|
1018
1122
|
|
|
1019
|
-
**50 Componentes UI** | **6 Tokens** | **
|
|
1123
|
+
**50 Componentes UI** | **6 Tokens** | **4 Ferramentas CRUD**
|
|
1020
1124
|
|
|
1021
1125
|
---
|
|
1022
1126
|
|
|
@@ -1034,7 +1138,7 @@ O comando usa credenciais públicas do Supabase do forlogic-core e não requer c
|
|
|
1034
1138
|
|
|
1035
1139
|
- [Accordion & Collapsible](./docs/DESIGN_SYSTEM.md#accordion) - Componentes de expansão/colapso para revelar conteúdo. Accordion para múltiplos itens, Collapsible para item único.
|
|
1036
1140
|
- [Action Button](./docs/DESIGN_SYSTEM.md#actionbutton) - Botão compacto otimizado para ações em linhas de tabela e menus dropdown.
|
|
1037
|
-
- [Alert](./docs/DESIGN_SYSTEM.md#alert) - Exibe uma mensagem de destaque para chamar a atenção do usuário.
|
|
1141
|
+
- [Alert](./docs/DESIGN_SYSTEM.md#alert) - Exibe uma mensagem de destaque para chamar a atenção do usuário. O componente inclui ícone automático baseado na variante.
|
|
1038
1142
|
- [AppHeader](./docs/DESIGN_SYSTEM.md#appheader) - Header principal da aplicação com título dinâmico, busca global integrada ao CRUD, ações customizáveis e informações do usuário. Altura fixa de 56px (h-14).
|
|
1039
1143
|
- [AppSidebar](./docs/DESIGN_SYSTEM.md#appsidebar) - Sidebar de navegação principal da aplicação com suporte a menu colapsável, permissões, redimensionamento e navegação hierárquica.
|
|
1040
1144
|
- [Avatar](./docs/DESIGN_SYSTEM.md#avatar) - Um elemento de imagem com fallback para representar o usuário.
|
|
@@ -1085,7 +1189,6 @@ O comando usa credenciais públicas do Supabase do forlogic-core e não requer c
|
|
|
1085
1189
|
|
|
1086
1190
|
### 🚀 Sistema CRUD
|
|
1087
1191
|
|
|
1088
|
-
- [CRUD Básico](./docs/DESIGN_SYSTEM.md#crudbasic) - Padrão de tabela CRUD simples com busca, filtros, ações por linha e paginação. Inclui dialogs interativos para visualização, criação, edição, duplicação, alteração de status e exclusão de itens.
|
|
1089
1192
|
- [CRUD com Alternância de Visualização](./docs/DESIGN_SYSTEM.md#crudviewtoggle) - Padrão de CRUD que permite alternar entre visualização em lista (cards horizontais) e grade (cards em grid). Inclui todas as operações CRUD com dialogs, exportação/importação e ações em massa.
|
|
1090
1193
|
- [CRUD de Fornecedores](./docs/DESIGN_SYSTEM.md#crudusers) - Padrão completo de CRUD para gestão de fornecedores com 16 campos, incluindo ordenação, filtros avançados, exportação/importação e ações em massa.
|
|
1091
1194
|
- [CRUD System](./docs/DESIGN_SYSTEM.md#crudsystem) - Sistema completo para criação rápida de interfaces CRUD com validação, busca, paginação e muito mais.
|
package/dist/README.md
CHANGED
|
@@ -49,6 +49,110 @@ Isso garante que todos os componentes compartilhem a mesma instância do i18next
|
|
|
49
49
|
|
|
50
50
|
---
|
|
51
51
|
|
|
52
|
+
## 📦 LIB-FIRST: Sempre Use Componentes da forlogic-core
|
|
53
|
+
|
|
54
|
+
> **⚠️ REGRA FUNDAMENTAL**: Antes de criar qualquer componente, serviço ou utilitário no projeto, VERIFIQUE se já existe na `forlogic-core`.
|
|
55
|
+
|
|
56
|
+
### 🤔 Por Quê?
|
|
57
|
+
|
|
58
|
+
A `forlogic-core` é a **biblioteca central** de componentes, serviços e utilitários compartilhados entre todos os projetos. Quando você cria um componente local que já existe na lib:
|
|
59
|
+
|
|
60
|
+
1. **❌ Drift de Design** - O componente local não acompanha evoluções futuras da lib
|
|
61
|
+
2. **❌ Duplicação de Código** - Aumenta tamanho do bundle e manutenção
|
|
62
|
+
3. **❌ Inconsistência** - UI/UX diferente entre projetos
|
|
63
|
+
4. **❌ Retrabalho** - Correções de bugs precisam ser feitas em múltiplos lugares
|
|
64
|
+
|
|
65
|
+
### 📋 Checklist OBRIGATÓRIO Antes de Criar Componentes
|
|
66
|
+
|
|
67
|
+
```markdown
|
|
68
|
+
- [ ] Pesquisei se o componente existe na forlogic-core?
|
|
69
|
+
- [ ] Verifiquei a documentação do Design System (/design_system)?
|
|
70
|
+
- [ ] Confirmei que a funcionalidade não pode ser alcançada com props/variantes existentes?
|
|
71
|
+
- [ ] Se não existe, solicitei a inclusão na lib para beneficiar todos os projetos?
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### ✅ CORRETO: Usar da Lib
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
// ✅ Sempre importe da forlogic-core
|
|
78
|
+
import {
|
|
79
|
+
Button,
|
|
80
|
+
Input,
|
|
81
|
+
Dialog,
|
|
82
|
+
Combobox,
|
|
83
|
+
SplitButton,
|
|
84
|
+
RichTextEditor,
|
|
85
|
+
createCrudPage,
|
|
86
|
+
cn,
|
|
87
|
+
formatDatetime
|
|
88
|
+
} from 'forlogic-core';
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### ❌ PROIBIDO: Criar Localmente (se existe na lib)
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
// ❌ NUNCA crie pastas/arquivos que já existem na lib
|
|
95
|
+
src/components/ui/button.tsx // Existe na lib
|
|
96
|
+
src/components/ui/dialog.tsx // Existe na lib
|
|
97
|
+
src/lib/utils.ts // cn() existe na lib
|
|
98
|
+
src/components/SplitButton.tsx // Existe na lib (a partir de v1.12.2)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### 🔄 Processo Quando Precisa de Customização
|
|
102
|
+
|
|
103
|
+
| Cenário | Ação Correta |
|
|
104
|
+
|---------|--------------|
|
|
105
|
+
| Componente não existe na lib | ✅ Criar localmente E solicitar inclusão na lib |
|
|
106
|
+
| Precisa de variante nova | ✅ Solicitar variante na lib (PR ou pedido) |
|
|
107
|
+
| Precisa de comportamento específico | ✅ Usar composição/wrapper ao invés de recriar |
|
|
108
|
+
| Bug no componente da lib | ✅ Reportar e corrigir na lib, não criar cópia local |
|
|
109
|
+
|
|
110
|
+
### 📖 Onde Verificar Componentes Disponíveis
|
|
111
|
+
|
|
112
|
+
| Recurso | Descrição |
|
|
113
|
+
|---------|-----------|
|
|
114
|
+
| `/design_system` | Design System com todos os componentes documentados |
|
|
115
|
+
| `forlogic-core/lib/exports/ui.ts` | Lista de exports de UI |
|
|
116
|
+
| `forlogic-core/lib/index.ts` | Index principal com todos os exports |
|
|
117
|
+
| `npx forlogic-core-pull-docs` | Baixa documentação atualizada |
|
|
118
|
+
| `npx forlogic-core-validate` | **Valida regra Lib-First** |
|
|
119
|
+
|
|
120
|
+
### 🔍 Validação Automática
|
|
121
|
+
|
|
122
|
+
Execute o script de validação para verificar se há componentes duplicados:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
npx forlogic-core-validate
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
O script verifica:
|
|
129
|
+
- ✅ Componentes UI em `src/components/ui/` que já existem na lib
|
|
130
|
+
- ✅ Utilitários em `src/lib/` como `utils.ts` ou `cn.ts`
|
|
131
|
+
- ✅ Hooks duplicados em `src/hooks/`
|
|
132
|
+
- ✅ Configuração do shadcn que pode criar duplicados
|
|
133
|
+
|
|
134
|
+
**Adicione ao CI/CD** para garantir conformidade:
|
|
135
|
+
|
|
136
|
+
```json
|
|
137
|
+
{
|
|
138
|
+
"scripts": {
|
|
139
|
+
"validate:lib-first": "forlogic-core-validate",
|
|
140
|
+
"prebuild": "forlogic-core-validate"
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### ⚠️ Exceções (quando PODE criar localmente)
|
|
146
|
+
|
|
147
|
+
1. **Componente específico de negócio** - Ex: `InvoiceCard`, `UserProfileWidget`
|
|
148
|
+
2. **Composição de componentes da lib** - Ex: wrapper que combina Dialog + Form
|
|
149
|
+
3. **Componente temporário** - Protótipo que será migrado para a lib depois
|
|
150
|
+
4. **Funcionalidade não generalizável** - Algo tão específico que não faz sentido na lib
|
|
151
|
+
|
|
152
|
+
> **📝 Mesmo nas exceções, avalie se o componente poderia ser generalizado e incluído na lib para beneficiar outros projetos.**
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
52
156
|
## 🤖 REGRAS CRÍTICAS
|
|
53
157
|
|
|
54
158
|
> **📋 Schema Padrão**: Veja no **Custom Knowledge** do projeto (Settings → Manage Knowledge) qual é o schema padrão deste projeto específico.
|
|
@@ -1016,7 +1120,7 @@ O comando usa credenciais públicas do Supabase do forlogic-core e não requer c
|
|
|
1016
1120
|
|
|
1017
1121
|
### 📚 Estatísticas da Documentação
|
|
1018
1122
|
|
|
1019
|
-
**50 Componentes UI** | **6 Tokens** | **
|
|
1123
|
+
**50 Componentes UI** | **6 Tokens** | **4 Ferramentas CRUD**
|
|
1020
1124
|
|
|
1021
1125
|
---
|
|
1022
1126
|
|
|
@@ -1034,7 +1138,7 @@ O comando usa credenciais públicas do Supabase do forlogic-core e não requer c
|
|
|
1034
1138
|
|
|
1035
1139
|
- [Accordion & Collapsible](./docs/DESIGN_SYSTEM.md#accordion) - Componentes de expansão/colapso para revelar conteúdo. Accordion para múltiplos itens, Collapsible para item único.
|
|
1036
1140
|
- [Action Button](./docs/DESIGN_SYSTEM.md#actionbutton) - Botão compacto otimizado para ações em linhas de tabela e menus dropdown.
|
|
1037
|
-
- [Alert](./docs/DESIGN_SYSTEM.md#alert) - Exibe uma mensagem de destaque para chamar a atenção do usuário.
|
|
1141
|
+
- [Alert](./docs/DESIGN_SYSTEM.md#alert) - Exibe uma mensagem de destaque para chamar a atenção do usuário. O componente inclui ícone automático baseado na variante.
|
|
1038
1142
|
- [AppHeader](./docs/DESIGN_SYSTEM.md#appheader) - Header principal da aplicação com título dinâmico, busca global integrada ao CRUD, ações customizáveis e informações do usuário. Altura fixa de 56px (h-14).
|
|
1039
1143
|
- [AppSidebar](./docs/DESIGN_SYSTEM.md#appsidebar) - Sidebar de navegação principal da aplicação com suporte a menu colapsável, permissões, redimensionamento e navegação hierárquica.
|
|
1040
1144
|
- [Avatar](./docs/DESIGN_SYSTEM.md#avatar) - Um elemento de imagem com fallback para representar o usuário.
|
|
@@ -1085,7 +1189,6 @@ O comando usa credenciais públicas do Supabase do forlogic-core e não requer c
|
|
|
1085
1189
|
|
|
1086
1190
|
### 🚀 Sistema CRUD
|
|
1087
1191
|
|
|
1088
|
-
- [CRUD Básico](./docs/DESIGN_SYSTEM.md#crudbasic) - Padrão de tabela CRUD simples com busca, filtros, ações por linha e paginação. Inclui dialogs interativos para visualização, criação, edição, duplicação, alteração de status e exclusão de itens.
|
|
1089
1192
|
- [CRUD com Alternância de Visualização](./docs/DESIGN_SYSTEM.md#crudviewtoggle) - Padrão de CRUD que permite alternar entre visualização em lista (cards horizontais) e grade (cards em grid). Inclui todas as operações CRUD com dialogs, exportação/importação e ações em massa.
|
|
1090
1193
|
- [CRUD de Fornecedores](./docs/DESIGN_SYSTEM.md#crudusers) - Padrão completo de CRUD para gestão de fornecedores com 16 campos, incluindo ordenação, filtros avançados, exportação/importação e ações em massa.
|
|
1091
1194
|
- [CRUD System](./docs/DESIGN_SYSTEM.md#crudsystem) - Sistema completo para criação rápida de interfaces CRUD com validação, busca, paginação e muito mais.
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
#!/usr/bin/env node
|
|
3
|
+
import * as fs from 'fs';
|
|
4
|
+
import * as path from 'path';
|
|
5
|
+
|
|
6
|
+
const LIB_UI_COMPONENTS = [
|
|
7
|
+
// Layout components
|
|
8
|
+
"accordion",
|
|
9
|
+
"alert",
|
|
10
|
+
"alert-dialog",
|
|
11
|
+
"avatar",
|
|
12
|
+
"breadcrumb",
|
|
13
|
+
"button",
|
|
14
|
+
"button-group",
|
|
15
|
+
"badge",
|
|
16
|
+
"calendar",
|
|
17
|
+
"card",
|
|
18
|
+
"checkbox",
|
|
19
|
+
"collapsible",
|
|
20
|
+
"color-picker",
|
|
21
|
+
"command",
|
|
22
|
+
"context-menu",
|
|
23
|
+
"combobox",
|
|
24
|
+
"data-list",
|
|
25
|
+
"date-picker",
|
|
26
|
+
"dialog",
|
|
27
|
+
"drawer",
|
|
28
|
+
"dropdown-menu",
|
|
29
|
+
"empty-state",
|
|
30
|
+
"form",
|
|
31
|
+
"grid",
|
|
32
|
+
"hover-card",
|
|
33
|
+
"icon-picker",
|
|
34
|
+
"input",
|
|
35
|
+
"input-group",
|
|
36
|
+
"label",
|
|
37
|
+
"loading-state",
|
|
38
|
+
"menubar",
|
|
39
|
+
"navigation-menu",
|
|
40
|
+
"page-breadcrumb",
|
|
41
|
+
"pagination",
|
|
42
|
+
"popover",
|
|
43
|
+
"progress",
|
|
44
|
+
"radio-group",
|
|
45
|
+
"resizable",
|
|
46
|
+
"rich-text-editor",
|
|
47
|
+
"scroll-area",
|
|
48
|
+
"select",
|
|
49
|
+
"separator",
|
|
50
|
+
"sheet",
|
|
51
|
+
"sidebar",
|
|
52
|
+
"skeleton",
|
|
53
|
+
"skeleton-variants",
|
|
54
|
+
"slider",
|
|
55
|
+
"sonner",
|
|
56
|
+
"spinner",
|
|
57
|
+
"split-button",
|
|
58
|
+
"stack",
|
|
59
|
+
"switch",
|
|
60
|
+
"tab-page-layout",
|
|
61
|
+
"table",
|
|
62
|
+
"table-resize-handle",
|
|
63
|
+
"tabs",
|
|
64
|
+
"textarea",
|
|
65
|
+
"toggle",
|
|
66
|
+
"toggle-group",
|
|
67
|
+
"tooltip",
|
|
68
|
+
"truncated-cell",
|
|
69
|
+
"typography",
|
|
70
|
+
"action-button",
|
|
71
|
+
"chart"
|
|
72
|
+
];
|
|
73
|
+
const LIB_HOOKS = [
|
|
74
|
+
"useDebounce",
|
|
75
|
+
"useActiveModules",
|
|
76
|
+
"usePageTitle",
|
|
77
|
+
"usePermissionQuery",
|
|
78
|
+
"useSidebarResize",
|
|
79
|
+
"useColumnResize",
|
|
80
|
+
"useRowResize",
|
|
81
|
+
"useI18nFormatters"
|
|
82
|
+
];
|
|
83
|
+
const LIB_SERVICES = [
|
|
84
|
+
"BaseService",
|
|
85
|
+
"ErrorService",
|
|
86
|
+
"EmailService",
|
|
87
|
+
"QualiexEnrichmentService",
|
|
88
|
+
"TranslationService"
|
|
89
|
+
];
|
|
90
|
+
const DIRECTORIES_TO_CHECK = [
|
|
91
|
+
"src/components/ui",
|
|
92
|
+
"src/lib",
|
|
93
|
+
"src/utils",
|
|
94
|
+
"src/hooks",
|
|
95
|
+
"src/services",
|
|
96
|
+
"components/ui",
|
|
97
|
+
"lib"
|
|
98
|
+
];
|
|
99
|
+
function kebabToPascal(str) {
|
|
100
|
+
return str.split("-").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
|
|
101
|
+
}
|
|
102
|
+
function normalizeFileName(fileName) {
|
|
103
|
+
return fileName.replace(/\.(tsx?|jsx?)$/, "").toLowerCase().replace(/[-_]/g, "-");
|
|
104
|
+
}
|
|
105
|
+
function findDuplicateComponents(projectRoot) {
|
|
106
|
+
const results = [];
|
|
107
|
+
for (const dir of DIRECTORIES_TO_CHECK) {
|
|
108
|
+
const fullPath = path.join(projectRoot, dir);
|
|
109
|
+
if (!fs.existsSync(fullPath)) {
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
const files = fs.readdirSync(fullPath);
|
|
113
|
+
for (const file of files) {
|
|
114
|
+
const filePath = path.join(fullPath, file);
|
|
115
|
+
const stat = fs.statSync(filePath);
|
|
116
|
+
if (stat.isDirectory()) {
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
const normalizedName = normalizeFileName(file);
|
|
120
|
+
if (dir.includes("components/ui") || dir.includes("components\\ui")) {
|
|
121
|
+
const match = LIB_UI_COMPONENTS.find(
|
|
122
|
+
(comp) => normalizedName === comp || normalizedName === comp.replace(/-/g, "") || normalizedName.includes(comp)
|
|
123
|
+
);
|
|
124
|
+
if (match) {
|
|
125
|
+
results.push({
|
|
126
|
+
type: "error",
|
|
127
|
+
file: path.relative(projectRoot, filePath),
|
|
128
|
+
message: `Componente "${kebabToPascal(match)}" j\xE1 existe na forlogic-core`,
|
|
129
|
+
suggestion: `import { ${kebabToPascal(match)} } from 'forlogic-core';`
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (normalizedName === "utils" || normalizedName === "cn") {
|
|
134
|
+
results.push({
|
|
135
|
+
type: "error",
|
|
136
|
+
file: path.relative(projectRoot, filePath),
|
|
137
|
+
message: "Utilit\xE1rios (cn, etc.) j\xE1 existem na forlogic-core",
|
|
138
|
+
suggestion: `import { cn } from 'forlogic-core';`
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
for (const hook of LIB_HOOKS) {
|
|
142
|
+
if (normalizedName.toLowerCase() === hook.toLowerCase().replace("use", "use-")) {
|
|
143
|
+
results.push({
|
|
144
|
+
type: "error",
|
|
145
|
+
file: path.relative(projectRoot, filePath),
|
|
146
|
+
message: `Hook "${hook}" j\xE1 existe na forlogic-core`,
|
|
147
|
+
suggestion: `import { ${hook} } from 'forlogic-core';`
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
for (const service of LIB_SERVICES) {
|
|
152
|
+
if (normalizedName.toLowerCase().includes(service.toLowerCase().replace("service", ""))) {
|
|
153
|
+
results.push({
|
|
154
|
+
type: "warning",
|
|
155
|
+
file: path.relative(projectRoot, filePath),
|
|
156
|
+
message: `Service similar a "${service}" pode existir na forlogic-core`,
|
|
157
|
+
suggestion: `Verifique se pode usar: import { ${service} } from 'forlogic-core';`
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return results;
|
|
164
|
+
}
|
|
165
|
+
function checkForShadcnConfig(projectRoot) {
|
|
166
|
+
const results = [];
|
|
167
|
+
const componentsJsonPath = path.join(projectRoot, "components.json");
|
|
168
|
+
if (fs.existsSync(componentsJsonPath)) {
|
|
169
|
+
const content = fs.readFileSync(componentsJsonPath, "utf-8");
|
|
170
|
+
const config = JSON.parse(content);
|
|
171
|
+
if (config.aliases?.components?.includes("src/components")) {
|
|
172
|
+
results.push({
|
|
173
|
+
type: "warning",
|
|
174
|
+
file: "components.json",
|
|
175
|
+
message: "shadcn/ui configurado para criar componentes em src/components/ui",
|
|
176
|
+
suggestion: "Use componentes da forlogic-core ao inv\xE9s de adicionar via shadcn CLI"
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return results;
|
|
181
|
+
}
|
|
182
|
+
function printResults(results) {
|
|
183
|
+
const errors = results.filter((r) => r.type === "error");
|
|
184
|
+
const warnings = results.filter((r) => r.type === "warning");
|
|
185
|
+
console.log("\n");
|
|
186
|
+
console.log("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501");
|
|
187
|
+
console.log(" \u{1F50D} VALIDA\xC7\xC3O LIB-FIRST - forlogic-core");
|
|
188
|
+
console.log("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n");
|
|
189
|
+
if (results.length === 0) {
|
|
190
|
+
console.log(" \u2705 Nenhuma duplica\xE7\xE3o encontrada!\n");
|
|
191
|
+
console.log(" Seu projeto est\xE1 seguindo a regra Lib-First corretamente.\n");
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (errors.length > 0) {
|
|
195
|
+
console.log(` \u274C ERROS (${errors.length}):
|
|
196
|
+
`);
|
|
197
|
+
console.log(" Componentes locais que DEVEM ser removidos:\n");
|
|
198
|
+
for (const error of errors) {
|
|
199
|
+
console.log(` \u{1F4C1} ${error.file}`);
|
|
200
|
+
console.log(` \u26A0\uFE0F ${error.message}`);
|
|
201
|
+
console.log(` \u{1F4A1} ${error.suggestion}
|
|
202
|
+
`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if (warnings.length > 0) {
|
|
206
|
+
console.log(` \u26A0\uFE0F AVISOS (${warnings.length}):
|
|
207
|
+
`);
|
|
208
|
+
for (const warning of warnings) {
|
|
209
|
+
console.log(` \u{1F4C1} ${warning.file}`);
|
|
210
|
+
console.log(` \u2139\uFE0F ${warning.message}`);
|
|
211
|
+
console.log(` \u{1F4A1} ${warning.suggestion}
|
|
212
|
+
`);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
console.log("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501");
|
|
216
|
+
console.log(` \u{1F4CA} RESUMO: ${errors.length} erros, ${warnings.length} avisos`);
|
|
217
|
+
console.log("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n");
|
|
218
|
+
if (errors.length > 0) {
|
|
219
|
+
console.log(" \u{1F4D6} Documenta\xE7\xE3o: https://github.com/forlogic/forlogic-core#lib-first\n");
|
|
220
|
+
console.log(" \u{1F4A1} A\xE7\xF5es recomendadas:");
|
|
221
|
+
console.log(" 1. Remova os arquivos duplicados listados acima");
|
|
222
|
+
console.log(" 2. Atualize os imports para usar forlogic-core");
|
|
223
|
+
console.log(" 3. Execute novamente: npx forlogic-core-validate\n");
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
function main() {
|
|
227
|
+
const projectRoot = process.cwd();
|
|
228
|
+
console.log(`
|
|
229
|
+
\u{1F4C2} Analisando projeto: ${projectRoot}
|
|
230
|
+
`);
|
|
231
|
+
const duplicates = findDuplicateComponents(projectRoot);
|
|
232
|
+
const configWarnings = checkForShadcnConfig(projectRoot);
|
|
233
|
+
const allResults = [...duplicates, ...configWarnings];
|
|
234
|
+
printResults(allResults);
|
|
235
|
+
const hasErrors = allResults.some((r) => r.type === "error");
|
|
236
|
+
process.exit(hasErrors ? 1 : 0);
|
|
237
|
+
}
|
|
238
|
+
main();
|