create-fluxstack 1.0.13 → 1.0.15
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/.env.example +29 -29
- package/app/client/README.md +69 -69
- package/app/client/index.html +14 -13
- package/app/client/src/App.tsx +157 -524
- package/app/client/src/components/ErrorBoundary.tsx +107 -0
- package/app/client/src/components/ErrorDisplay.css +365 -0
- package/app/client/src/components/ErrorDisplay.tsx +258 -0
- package/app/client/src/components/FluxStackConfig.tsx +1321 -0
- package/app/client/src/components/HybridLiveCounter.tsx +140 -0
- package/app/client/src/components/LiveClock.tsx +286 -0
- package/app/client/src/components/MainLayout.tsx +390 -0
- package/app/client/src/components/SidebarNavigation.tsx +391 -0
- package/app/client/src/components/StateDemo.tsx +178 -0
- package/app/client/src/components/SystemMonitor.tsx +1038 -0
- package/app/client/src/components/Teste.tsx +104 -0
- package/app/client/src/components/UserProfile.tsx +809 -0
- package/app/client/src/hooks/useAuth.ts +39 -0
- package/app/client/src/hooks/useNotifications.ts +56 -0
- package/app/client/src/lib/eden-api.ts +189 -53
- package/app/client/src/lib/errors.ts +340 -0
- package/app/client/src/lib/hooks/useErrorHandler.ts +258 -0
- package/app/client/src/lib/index.ts +45 -0
- package/app/client/src/main.tsx +3 -2
- package/app/client/src/pages/ApiDocs.tsx +182 -0
- package/app/client/src/pages/Demo.tsx +174 -0
- package/app/client/src/pages/HybridLive.tsx +263 -0
- package/app/client/src/pages/Overview.tsx +155 -0
- package/app/client/src/store/README.md +43 -0
- package/app/client/src/store/index.ts +16 -0
- package/app/client/src/store/slices/uiSlice.ts +151 -0
- package/app/client/src/store/slices/userSlice.ts +161 -0
- package/app/client/src/test/README.md +257 -0
- package/app/client/src/test/setup.ts +70 -0
- package/app/client/src/test/types.ts +12 -0
- package/app/client/src/vite-env.d.ts +1 -1
- package/app/client/tsconfig.app.json +44 -43
- package/app/client/tsconfig.json +7 -7
- package/app/client/tsconfig.node.json +25 -25
- package/app/client/zustand-setup.md +65 -0
- package/app/server/controllers/users.controller.ts +68 -68
- package/app/server/index.ts +9 -1
- package/app/server/live/CounterComponent.ts +191 -0
- package/app/server/live/FluxStackConfig.ts +529 -0
- package/app/server/live/LiveClockComponent.ts +214 -0
- package/app/server/live/SidebarNavigation.ts +156 -0
- package/app/server/live/SystemMonitor.ts +594 -0
- package/app/server/live/SystemMonitorIntegration.ts +151 -0
- package/app/server/live/TesteComponent.ts +87 -0
- package/app/server/live/UserProfileComponent.ts +135 -0
- package/app/server/live/register-components.ts +28 -0
- package/app/server/middleware/auth.ts +136 -0
- package/app/server/middleware/errorHandling.ts +250 -0
- package/app/server/middleware/index.ts +10 -0
- package/app/server/middleware/rateLimit.ts +193 -0
- package/app/server/middleware/requestLogging.ts +215 -0
- package/app/server/middleware/validation.ts +270 -0
- package/app/server/routes/index.ts +14 -2
- package/app/server/routes/upload.ts +92 -0
- package/app/server/routes/users.routes.ts +2 -9
- package/app/server/services/NotificationService.ts +302 -0
- package/app/server/services/UserService.ts +222 -0
- package/app/server/services/index.ts +46 -0
- package/core/cli/commands/plugin-deps.ts +263 -0
- package/core/cli/generators/README.md +339 -0
- package/core/cli/generators/component.ts +770 -0
- package/core/cli/generators/controller.ts +299 -0
- package/core/cli/generators/index.ts +144 -0
- package/core/cli/generators/interactive.ts +228 -0
- package/core/cli/generators/prompts.ts +83 -0
- package/core/cli/generators/route.ts +513 -0
- package/core/cli/generators/service.ts +465 -0
- package/core/cli/generators/template-engine.ts +154 -0
- package/core/cli/generators/types.ts +71 -0
- package/core/cli/generators/utils.ts +192 -0
- package/core/cli/index.ts +69 -0
- package/core/cli/plugin-discovery.ts +16 -85
- package/core/client/fluxstack.ts +17 -0
- package/core/client/hooks/index.ts +7 -0
- package/core/client/hooks/state-validator.ts +130 -0
- package/core/client/hooks/useAuth.ts +49 -0
- package/core/client/hooks/useChunkedUpload.ts +258 -0
- package/core/client/hooks/useHybridLiveComponent.ts +967 -0
- package/core/client/hooks/useWebSocket.ts +373 -0
- package/core/client/index.ts +47 -0
- package/core/client/state/createStore.ts +193 -0
- package/core/client/state/index.ts +15 -0
- package/core/config/env-dynamic.ts +1 -1
- package/core/config/env.ts +2 -1
- package/core/config/runtime-config.ts +3 -3
- package/core/config/schema.ts +84 -49
- package/core/framework/server.ts +30 -0
- package/core/index.ts +25 -0
- package/core/live/ComponentRegistry.ts +399 -0
- package/core/live/types.ts +164 -0
- package/core/plugins/built-in/live-components/commands/create-live-component.ts +1201 -0
- package/core/plugins/built-in/live-components/index.ts +27 -0
- package/core/plugins/built-in/logger/index.ts +1 -1
- package/core/plugins/built-in/monitoring/index.ts +1 -1
- package/core/plugins/built-in/static/index.ts +1 -1
- package/core/plugins/built-in/swagger/index.ts +1 -1
- package/core/plugins/built-in/vite/index.ts +1 -1
- package/core/plugins/dependency-manager.ts +384 -0
- package/core/plugins/index.ts +5 -1
- package/core/plugins/manager.ts +7 -3
- package/core/plugins/registry.ts +88 -10
- package/core/plugins/types.ts +11 -11
- package/core/server/framework.ts +43 -0
- package/core/server/index.ts +11 -1
- package/core/server/live/ComponentRegistry.ts +1017 -0
- package/core/server/live/FileUploadManager.ts +272 -0
- package/core/server/live/LiveComponentPerformanceMonitor.ts +930 -0
- package/core/server/live/SingleConnectionManager.ts +0 -0
- package/core/server/live/StateSignature.ts +644 -0
- package/core/server/live/WebSocketConnectionManager.ts +688 -0
- package/core/server/live/websocket-plugin.ts +435 -0
- package/core/server/middleware/errorHandling.ts +141 -0
- package/core/server/middleware/index.ts +16 -0
- package/core/server/plugins/static-files-plugin.ts +232 -0
- package/core/server/services/BaseService.ts +95 -0
- package/core/server/services/ServiceContainer.ts +144 -0
- package/core/server/services/index.ts +9 -0
- package/core/templates/create-project.ts +196 -33
- package/core/testing/index.ts +10 -0
- package/core/testing/setup.ts +74 -0
- package/core/types/build.ts +38 -14
- package/core/types/types.ts +319 -0
- package/core/utils/env-runtime.ts +7 -0
- package/core/utils/errors/handlers.ts +264 -39
- package/core/utils/errors/index.ts +528 -18
- package/core/utils/errors/middleware.ts +114 -0
- package/core/utils/logger/formatters.ts +222 -0
- package/core/utils/logger/index.ts +167 -48
- package/core/utils/logger/middleware.ts +253 -0
- package/core/utils/logger/performance.ts +384 -0
- package/core/utils/logger/transports.ts +365 -0
- package/create-fluxstack.ts +296 -296
- package/fluxstack.config.ts +17 -1
- package/package-template.json +66 -66
- package/package.json +31 -6
- package/public/README.md +16 -0
- package/vite.config.ts +29 -14
- package/.claude/settings.local.json +0 -74
- package/.github/workflows/ci-build-tests.yml +0 -480
- package/.github/workflows/dependency-management.yml +0 -324
- package/.github/workflows/release-validation.yml +0 -355
- package/.kiro/specs/fluxstack-architecture-optimization/design.md +0 -700
- package/.kiro/specs/fluxstack-architecture-optimization/requirements.md +0 -127
- package/.kiro/specs/fluxstack-architecture-optimization/tasks.md +0 -330
- package/CLAUDE.md +0 -200
- package/Dockerfile +0 -58
- package/Dockerfile.backend +0 -52
- package/Dockerfile.frontend +0 -54
- package/README-Docker.md +0 -85
- package/ai-context/00-QUICK-START.md +0 -86
- package/ai-context/README.md +0 -88
- package/ai-context/development/eden-treaty-guide.md +0 -362
- package/ai-context/development/patterns.md +0 -382
- package/ai-context/development/plugins-guide.md +0 -572
- package/ai-context/examples/crud-complete.md +0 -626
- package/ai-context/project/architecture.md +0 -399
- package/ai-context/project/overview.md +0 -213
- package/ai-context/recent-changes/eden-treaty-refactor.md +0 -281
- package/ai-context/recent-changes/type-inference-fix.md +0 -223
- package/ai-context/reference/environment-vars.md +0 -384
- package/ai-context/reference/troubleshooting.md +0 -407
- package/app/client/src/components/TestPage.tsx +0 -453
- package/bun.lock +0 -1063
- package/bunfig.toml +0 -16
- package/core/__tests__/integration.test.ts +0 -227
- package/core/build/index.ts +0 -186
- package/core/config/__tests__/config-loader.test.ts +0 -554
- package/core/config/__tests__/config-merger.test.ts +0 -657
- package/core/config/__tests__/env-converter.test.ts +0 -372
- package/core/config/__tests__/env-processor.test.ts +0 -431
- package/core/config/__tests__/env.test.ts +0 -452
- package/core/config/__tests__/integration.test.ts +0 -418
- package/core/config/__tests__/loader.test.ts +0 -331
- package/core/config/__tests__/schema.test.ts +0 -129
- package/core/config/__tests__/validator.test.ts +0 -318
- package/core/framework/__tests__/server.test.ts +0 -233
- package/core/plugins/__tests__/built-in.test.ts.disabled +0 -366
- package/core/plugins/__tests__/manager.test.ts +0 -398
- package/core/plugins/__tests__/monitoring.test.ts +0 -401
- package/core/plugins/__tests__/registry.test.ts +0 -335
- package/core/utils/__tests__/errors.test.ts +0 -139
- package/core/utils/__tests__/helpers.test.ts +0 -297
- package/core/utils/__tests__/logger.test.ts +0 -141
- package/create-test-app.ts +0 -156
- package/docker-compose.microservices.yml +0 -75
- package/docker-compose.simple.yml +0 -57
- package/docker-compose.yml +0 -71
- package/eslint.config.js +0 -23
- package/flux-cli.ts +0 -214
- package/nginx-lb.conf +0 -37
- package/publish.sh +0 -63
- package/run-clean.ts +0 -26
- package/run-env-tests.ts +0 -313
- package/tailwind.config.js +0 -34
- package/tests/__mocks__/api.ts +0 -56
- package/tests/fixtures/users.ts +0 -69
- package/tests/integration/api/users.routes.test.ts +0 -221
- package/tests/setup.ts +0 -29
- package/tests/unit/app/client/App-simple.test.tsx +0 -56
- package/tests/unit/app/client/App.test.tsx.skip +0 -237
- package/tests/unit/app/client/eden-api.test.ts +0 -186
- package/tests/unit/app/client/simple.test.tsx +0 -23
- package/tests/unit/app/controllers/users.controller.test.ts +0 -150
- package/tests/unit/core/create-project.test.ts.skip +0 -95
- package/tests/unit/core/framework.test.ts +0 -144
- package/tests/unit/core/plugins/logger.test.ts.skip +0 -268
- package/tests/unit/core/plugins/vite.test.ts.disabled +0 -188
- package/tests/utils/test-helpers.ts +0 -61
- package/vitest.config.ts +0 -50
- package/workspace.json +0 -6
|
@@ -1,281 +0,0 @@
|
|
|
1
|
-
# 🔥 Eden Treaty Refatoração - Mudança Crítica (Setembro 2025)
|
|
2
|
-
|
|
3
|
-
> **IMPORTANTE**: Esta refatoração eliminou um problema fundamental que quebrava a type inference do Eden Treaty
|
|
4
|
-
|
|
5
|
-
## 🎯 **Resumo da Mudança**
|
|
6
|
-
|
|
7
|
-
**Problema**: O wrapper `apiCall()` estava quebrando completamente a inferência automática de tipos do Eden Treaty, forçando uso de `any` e `unknown` types.
|
|
8
|
-
|
|
9
|
-
**Solução**: Refatoração completa para usar Eden Treaty **nativo**, restaurando 100% da type inference automática.
|
|
10
|
-
|
|
11
|
-
## ❌ **ANTES: Sistema Quebrado**
|
|
12
|
-
|
|
13
|
-
### **Problema 1: Wrapper que Quebrava Tipos**
|
|
14
|
-
```typescript
|
|
15
|
-
// ❌ Wrapper problemático (REMOVIDO)
|
|
16
|
-
export async function apiCall(apiPromise: Promise<any>) {
|
|
17
|
-
const { data, error } = await apiPromise
|
|
18
|
-
if (error) throw new APIException(...)
|
|
19
|
-
return data // ❌ Retornava 'any' - perdeu todos os tipos!
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// ❌ Uso que perdia type safety
|
|
23
|
-
const users = await apiCall(api.users.get())
|
|
24
|
-
// users era 'any' - sem autocomplete, sem verificação! 😞
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
### **Problema 2: Tipos Quebrados no Frontend**
|
|
28
|
-
```typescript
|
|
29
|
-
// ❌ TestPage.tsx (ANTES)
|
|
30
|
-
const users = await apiCall(api.users.get())
|
|
31
|
-
const newUser = await apiCall(api.users.post({...}))
|
|
32
|
-
|
|
33
|
-
// TypeScript erros:
|
|
34
|
-
// - Property 'users' does not exist on type 'unknown'
|
|
35
|
-
// - Property 'success' does not exist on type 'unknown'
|
|
36
|
-
// - Element implicitly has an 'any' type
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
### **Problema 3: App.tsx Problemático**
|
|
40
|
-
```typescript
|
|
41
|
-
// ❌ App.tsx (ANTES)
|
|
42
|
-
const data = await apiCall(api.users.get())
|
|
43
|
-
setUsers(data?.users || []) // ❌ Precisava usar '?' e '||'
|
|
44
|
-
|
|
45
|
-
const result = await apiCall(api.users.post({...}))
|
|
46
|
-
if (result?.success && result?.user) { // ❌ Verificações desnecessárias
|
|
47
|
-
setUsers(prev => [...prev, result.user])
|
|
48
|
-
}
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
## ✅ **DEPOIS: Sistema Funcionando**
|
|
52
|
-
|
|
53
|
-
### **Solução 1: Eden Treaty Nativo**
|
|
54
|
-
```typescript
|
|
55
|
-
// ✅ NOVO: Sem wrapper - Eden Treaty puro
|
|
56
|
-
const { data: users, error } = await api.users.get()
|
|
57
|
-
|
|
58
|
-
if (error) {
|
|
59
|
-
console.log(`API Error: ${error.status}`)
|
|
60
|
-
return
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// ✨ TypeScript agora SABE que users é: { users: User[] }
|
|
64
|
-
console.log(users.users.length) // ✨ Autocomplete perfeito!
|
|
65
|
-
console.log(users.users[0].name) // ✨ Type-safe!
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
### **Solução 2: TestPage.tsx Refatorado**
|
|
69
|
-
```typescript
|
|
70
|
-
// ✅ TestPage.tsx (DEPOIS)
|
|
71
|
-
try {
|
|
72
|
-
// ✨ Eden Treaty nativo com inferência perfeita
|
|
73
|
-
const { data: usersResponse, error: getUsersError } = await api.users.get()
|
|
74
|
-
|
|
75
|
-
if (getUsersError) {
|
|
76
|
-
throw new Error(`Get users failed: ${getUsersError.status}`)
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// ✨ Eden Treaty com inferência automática
|
|
80
|
-
const { data: newUser, error: createError } = await api.users.post({
|
|
81
|
-
name: "Test User",
|
|
82
|
-
email: "test@example.com"
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
if (createError) {
|
|
86
|
-
throw new Error(`Create user failed: ${createError.status}`)
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// ✨ TypeScript infere automaticamente: newUser é UserResponse
|
|
90
|
-
if (!newUser.success || !newUser.user) {
|
|
91
|
-
throw new Error('User creation failed')
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// ✨ Inferência automática de tipos
|
|
95
|
-
const { data: createdUser, error: getError } = await api.users({
|
|
96
|
-
id: newUser.user.id
|
|
97
|
-
}).get()
|
|
98
|
-
|
|
99
|
-
if (getError) {
|
|
100
|
-
throw new Error(`Get user failed: ${getError.status}`)
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// ✨ Eden Treaty infere: createdUser é { user: User }
|
|
104
|
-
if (!createdUser || !createdUser.user) {
|
|
105
|
-
throw new Error('User not found')
|
|
106
|
-
}
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
### **Solução 3: App.tsx Refatorado**
|
|
110
|
-
```typescript
|
|
111
|
-
// ✅ App.tsx (DEPOIS)
|
|
112
|
-
const { data, error } = await api.users.get()
|
|
113
|
-
|
|
114
|
-
if (error) {
|
|
115
|
-
showMessage('error', `Erro ao carregar usuários: ${error.status}`)
|
|
116
|
-
return
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// ✨ Eden Treaty infere automaticamente que data.users é User[]
|
|
120
|
-
setUsers(data.users || [])
|
|
121
|
-
|
|
122
|
-
// ✅ POST refatorado
|
|
123
|
-
const { data: result, error } = await api.users.post({
|
|
124
|
-
name: name.trim(),
|
|
125
|
-
email: email.trim()
|
|
126
|
-
})
|
|
127
|
-
|
|
128
|
-
if (error) {
|
|
129
|
-
showMessage('error', `Erro ao criar usuário: ${error.status}`)
|
|
130
|
-
return
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// ✨ Eden Treaty infere que result é UserResponse
|
|
134
|
-
if (result.success && result.user) {
|
|
135
|
-
setUsers(prev => [...prev, result.user])
|
|
136
|
-
showMessage('success', `Usuário ${name} adicionado com sucesso!`)
|
|
137
|
-
} else {
|
|
138
|
-
showMessage('error', result.message || 'Erro ao criar usuário')
|
|
139
|
-
}
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
## 🔧 **Mudanças Técnicas Implementadas**
|
|
143
|
-
|
|
144
|
-
### **1. Response Schemas Adicionados**
|
|
145
|
-
```typescript
|
|
146
|
-
// ✅ NOVO: Routes com response schemas explícitos
|
|
147
|
-
export const usersRoutes = new Elysia({ prefix: "/users" })
|
|
148
|
-
.get("/", () => UsersController.getUsers(), {
|
|
149
|
-
response: t.Object({
|
|
150
|
-
users: t.Array(t.Object({
|
|
151
|
-
id: t.Number(),
|
|
152
|
-
name: t.String(),
|
|
153
|
-
email: t.String(),
|
|
154
|
-
createdAt: t.Date()
|
|
155
|
-
}))
|
|
156
|
-
})
|
|
157
|
-
})
|
|
158
|
-
.post("/", async ({ body, set }) => {
|
|
159
|
-
return await UsersController.createUser(body)
|
|
160
|
-
}, {
|
|
161
|
-
response: t.Object({
|
|
162
|
-
success: t.Boolean(),
|
|
163
|
-
user: t.Optional(t.Object({
|
|
164
|
-
id: t.Number(),
|
|
165
|
-
name: t.String(),
|
|
166
|
-
email: t.String(),
|
|
167
|
-
createdAt: t.Date()
|
|
168
|
-
})),
|
|
169
|
-
message: t.Optional(t.String())
|
|
170
|
-
})
|
|
171
|
-
})
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
### **2. Types Compartilhados Criados**
|
|
175
|
-
```typescript
|
|
176
|
-
// ✅ NOVO: app/shared/types/index.ts
|
|
177
|
-
export interface User {
|
|
178
|
-
id: number
|
|
179
|
-
name: string
|
|
180
|
-
email: string
|
|
181
|
-
createdAt: Date
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
export interface CreateUserRequest {
|
|
185
|
-
name: string
|
|
186
|
-
email: string
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
export interface UserResponse {
|
|
190
|
-
success: boolean
|
|
191
|
-
user?: User
|
|
192
|
-
message?: string
|
|
193
|
-
}
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
### **3. Eden API Client Simplificado**
|
|
197
|
-
```typescript
|
|
198
|
-
// ✅ NOVO: app/client/src/lib/eden-api.ts (simplificado)
|
|
199
|
-
import { treaty } from '@elysiajs/eden'
|
|
200
|
-
import type { App } from '../../../server/app'
|
|
201
|
-
|
|
202
|
-
const client = treaty<App>(getBaseUrl())
|
|
203
|
-
|
|
204
|
-
// ✅ Export direto para inferência perfeita
|
|
205
|
-
export const api = client.api
|
|
206
|
-
|
|
207
|
-
// ✅ Apenas utilitários auxiliares (não wrapper)
|
|
208
|
-
export { getErrorMessage } from './error-utils'
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
## 📊 **Resultados da Refatoração**
|
|
212
|
-
|
|
213
|
-
### **✅ Antes vs Depois - TypeScript**
|
|
214
|
-
```bash
|
|
215
|
-
# ❌ ANTES
|
|
216
|
-
app/client/src/components/TestPage.tsx(157,20): Property 'success' does not exist on type 'unknown'
|
|
217
|
-
app/client/src/components/TestPage.tsx(157,40): Property 'user' does not exist on type 'unknown'
|
|
218
|
-
app/client/src/App.tsx(53,21): Property 'users' does not exist on type 'unknown'
|
|
219
|
-
|
|
220
|
-
# ✅ DEPOIS
|
|
221
|
-
Zero erros TypeScript - Inferência funcionando perfeitamente! 🎉
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
### **✅ Experiência do Desenvolvedor**
|
|
225
|
-
```typescript
|
|
226
|
-
// ✅ DEPOIS: Autocomplete perfeito
|
|
227
|
-
const { data: user, error } = await api.users.post({
|
|
228
|
-
name: "João", // ✨ Editor sugere campos obrigatórios
|
|
229
|
-
email: "joão@" // ✨ Editor valida formato email
|
|
230
|
-
})
|
|
231
|
-
|
|
232
|
-
if (!error) {
|
|
233
|
-
user.success // ✨ Autocomplete: boolean
|
|
234
|
-
user.user?.id // ✨ Autocomplete: number | undefined
|
|
235
|
-
user.user?.name // ✨ Autocomplete: string | undefined
|
|
236
|
-
}
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
### **✅ Error Handling Melhorado**
|
|
240
|
-
```typescript
|
|
241
|
-
// ✅ DEPOIS: Error types estruturados
|
|
242
|
-
if (error) {
|
|
243
|
-
error.status // ✨ number
|
|
244
|
-
error.message // ✨ string
|
|
245
|
-
error.details // ✨ any (dados específicos do erro)
|
|
246
|
-
}
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
## 🎯 **Lições Aprendidas**
|
|
250
|
-
|
|
251
|
-
### **❌ NÃO Fazer (Aprendizado)**
|
|
252
|
-
1. **Não criar wrappers** que quebram type inference
|
|
253
|
-
2. **Não ignorar** response schemas nas rotas
|
|
254
|
-
3. **Não forçar** types com `as any` ou `as unknown`
|
|
255
|
-
|
|
256
|
-
### **✅ SEMPRE Fazer (Boas Práticas)**
|
|
257
|
-
1. **Usar Eden Treaty nativo** para preservar type inference
|
|
258
|
-
2. **Definir response schemas** em todas as rotas
|
|
259
|
-
3. **Manter types compartilhados** atualizados
|
|
260
|
-
4. **Testar type safety** durante desenvolvimento
|
|
261
|
-
|
|
262
|
-
## 🚀 **Impacto no Futuro**
|
|
263
|
-
|
|
264
|
-
### **Desenvolvimento Mais Rápido**
|
|
265
|
-
- **Autocomplete perfeito** - menos erros de digitação
|
|
266
|
-
- **Validação em tempo real** - erros detectados no editor
|
|
267
|
-
- **Refactoring seguro** - mudanças no server refletem no client
|
|
268
|
-
|
|
269
|
-
### **Manutenção Simplificada**
|
|
270
|
-
- **Sincronização automática** - types sempre atualizados
|
|
271
|
-
- **Detecção precoce** - breaking changes detectados na compilação
|
|
272
|
-
- **Documentação viva** - tipos servem como documentação
|
|
273
|
-
|
|
274
|
-
### **Onboarding Melhorado**
|
|
275
|
-
- **Novos devs** entendem APIs através dos tipos
|
|
276
|
-
- **Menos bugs** relacionados a tipos incorretos
|
|
277
|
-
- **Padrões claros** para uso do Eden Treaty
|
|
278
|
-
|
|
279
|
-
---
|
|
280
|
-
|
|
281
|
-
**🎯 Esta refatoração transforma FluxStack em um framework verdadeiramente type-safe, onde Eden Treaty funciona como foi projetado: inferência automática sem compromissos!**
|
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
# 🔧 Type Inference Fix - Eden Treaty (Setembro 2025)
|
|
2
|
-
|
|
3
|
-
> **Consolidação dos descobrimentos**: Como resolvemos o problema de types `unknown` no Eden Treaty
|
|
4
|
-
|
|
5
|
-
## 📋 **Problema Original**
|
|
6
|
-
|
|
7
|
-
Durante o desenvolvimento, descobrimos que o Eden Treaty estava retornando types `unknown` em vez da inferência automática prometida. Esta era uma quebra fundamental da proposta de value do framework.
|
|
8
|
-
|
|
9
|
-
## 🔍 **Investigação e Descobertas**
|
|
10
|
-
|
|
11
|
-
### **Comparação ANTES vs DEPOIS**
|
|
12
|
-
|
|
13
|
-
#### ❌ **ANTES: Wrapper Quebrava Tipos**
|
|
14
|
-
```typescript
|
|
15
|
-
// ❌ apiCall wrapper (PROBLEMÁTICO)
|
|
16
|
-
export async function apiCall(apiPromise: Promise<any>) {
|
|
17
|
-
const { data, error } = await apiPromise
|
|
18
|
-
if (error) throw new APIException(...)
|
|
19
|
-
return data // ❌ Retornava 'any' - perdeu todos os tipos!
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// ❌ Uso que quebrava type inference
|
|
23
|
-
const newUser = await apiCall(api.users.post({...}))
|
|
24
|
-
// newUser era 'any' - perdeu type safety! 😞
|
|
25
|
-
|
|
26
|
-
const user = await apiCall(api.users({ id: (newUser as any).id }).get())
|
|
27
|
-
// Precisava usar 'as any' - perdeu autocomplete! 😞
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
#### ✅ **DEPOIS: Eden Treaty Nativo**
|
|
31
|
-
```typescript
|
|
32
|
-
// ✅ Eden Treaty puro - inferência perfeita!
|
|
33
|
-
const { data: newUser, error } = await api.users.post({
|
|
34
|
-
name: "João",
|
|
35
|
-
email: "joao@example.com"
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
if (error) throw new Error('Create failed')
|
|
39
|
-
|
|
40
|
-
// ✨ TypeScript sabe que newUser é: { success: boolean; user: User }
|
|
41
|
-
console.log(newUser.user.id) // ✨ Autocomplete perfeito!
|
|
42
|
-
console.log(newUser.user.name) // ✨ Type-safe!
|
|
43
|
-
|
|
44
|
-
const { data: user } = await api.users({ id: newUser.user.id }).get()
|
|
45
|
-
// ✨ TypeScript sabe que user é: { user: User }
|
|
46
|
-
console.log(user.user.email) // ✨ Autocomplete perfeito!
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
## 🎯 **Conclusões Críticas**
|
|
50
|
-
|
|
51
|
-
### **1. Eden Nativo vs Wrapper**
|
|
52
|
-
- **Eden nativo**: Type inference **PERFEITA** ✨
|
|
53
|
-
- **Com wrapper**: Type inference **QUEBRADA** ⚠️
|
|
54
|
-
|
|
55
|
-
### **2. Descoberta Importante**
|
|
56
|
-
O wrapper `apiCall()` não era apenas desnecessário - era **prejudicial**! Ele quebrava completamente o sistema de inferência automática que é o coração do Eden Treaty.
|
|
57
|
-
|
|
58
|
-
### **3. Lição Aprendida**
|
|
59
|
-
Eden Treaty foi projetado para funcionar **nativamente** sem wrappers. Qualquer abstração adicional quebra a mágica da inferência automática.
|
|
60
|
-
|
|
61
|
-
## 🔧 **Solução Implementada**
|
|
62
|
-
|
|
63
|
-
### **1. Remoção do Wrapper**
|
|
64
|
-
```typescript
|
|
65
|
-
// ❌ REMOVIDO: apiCall wrapper
|
|
66
|
-
// export async function apiCall(apiPromise: Promise<any>) { ... }
|
|
67
|
-
|
|
68
|
-
// ✅ NOVO: Eden Treaty direto
|
|
69
|
-
export const api = client.api
|
|
70
|
-
|
|
71
|
-
// ✅ Apenas utilitários opcionais
|
|
72
|
-
export { getErrorMessage } from './error-utils'
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
### **2. Response Schemas Adicionados**
|
|
76
|
-
```typescript
|
|
77
|
-
// ✅ CRÍTICO: Schemas para inferência automática
|
|
78
|
-
export const usersRoutes = new Elysia({ prefix: "/users" })
|
|
79
|
-
.get("/", () => UsersController.getUsers(), {
|
|
80
|
-
response: t.Object({
|
|
81
|
-
users: t.Array(t.Object({
|
|
82
|
-
id: t.Number(),
|
|
83
|
-
name: t.String(),
|
|
84
|
-
email: t.String(),
|
|
85
|
-
createdAt: t.Date()
|
|
86
|
-
}))
|
|
87
|
-
})
|
|
88
|
-
})
|
|
89
|
-
.post("/", async ({ body }) => UsersController.createUser(body), {
|
|
90
|
-
response: t.Object({
|
|
91
|
-
success: t.Boolean(),
|
|
92
|
-
user: t.Optional(t.Object({
|
|
93
|
-
id: t.Number(),
|
|
94
|
-
name: t.String(),
|
|
95
|
-
email: t.String(),
|
|
96
|
-
createdAt: t.Date()
|
|
97
|
-
})),
|
|
98
|
-
message: t.Optional(t.String())
|
|
99
|
-
})
|
|
100
|
-
})
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
### **3. Frontend Refatorado**
|
|
104
|
-
```typescript
|
|
105
|
-
// ✅ TestPage.tsx - Eden Treaty nativo
|
|
106
|
-
const { data: usersResponse, error: getUsersError } = await api.users.get()
|
|
107
|
-
|
|
108
|
-
if (getUsersError) {
|
|
109
|
-
throw new Error(`Get users failed: ${getUsersError.status}`)
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// ✨ Eden Treaty infere automaticamente: usersResponse.users é User[]
|
|
113
|
-
console.log(usersResponse.users.length)
|
|
114
|
-
|
|
115
|
-
// ✅ App.tsx - Eden Treaty nativo
|
|
116
|
-
const { data, error } = await api.users.get()
|
|
117
|
-
|
|
118
|
-
if (error) {
|
|
119
|
-
showMessage('error', `Erro ao carregar usuários: ${error.status}`)
|
|
120
|
-
return
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// ✨ Eden Treaty infere automaticamente que data.users é User[]
|
|
124
|
-
setUsers(data.users || [])
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
## 📊 **Resultados da Correção**
|
|
128
|
-
|
|
129
|
-
### **✅ Antes vs Depois - TypeScript**
|
|
130
|
-
```bash
|
|
131
|
-
# ❌ ANTES
|
|
132
|
-
app/client/src/components/TestPage.tsx(157,20): Property 'success' does not exist on type 'unknown'
|
|
133
|
-
app/client/src/components/TestPage.tsx(157,40): Property 'user' does not exist on type 'unknown'
|
|
134
|
-
app/client/src/App.tsx(53,21): Property 'users' does not exist on type 'unknown'
|
|
135
|
-
|
|
136
|
-
# ✅ DEPOIS
|
|
137
|
-
Zero erros relacionados a types unknown - Eden Treaty funcionando! 🎉
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
### **✅ Developer Experience**
|
|
141
|
-
```typescript
|
|
142
|
-
// ✅ DEPOIS: Autocomplete perfeito
|
|
143
|
-
const { data: user, error } = await api.users.post({
|
|
144
|
-
name: "João", // ✨ Editor sugere campos obrigatórios
|
|
145
|
-
email: "joão@" // ✨ Editor valida formato email
|
|
146
|
-
})
|
|
147
|
-
|
|
148
|
-
if (!error) {
|
|
149
|
-
user.success // ✨ Autocomplete: boolean
|
|
150
|
-
user.user?.id // ✨ Autocomplete: number | undefined
|
|
151
|
-
user.user?.name // ✨ Autocomplete: string | undefined
|
|
152
|
-
}
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
## 🎯 **Padrões Estabelecidos**
|
|
156
|
-
|
|
157
|
-
### **✅ SEMPRE Usar Eden Treaty Nativo**
|
|
158
|
-
```typescript
|
|
159
|
-
// ✅ Padrão correto
|
|
160
|
-
const { data, error } = await api.endpoint()
|
|
161
|
-
|
|
162
|
-
if (error) {
|
|
163
|
-
// Handle error with proper typing
|
|
164
|
-
console.log(`Error ${error.status}: ${error.message}`)
|
|
165
|
-
return
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// data agora tem tipo correto inferido automaticamente
|
|
169
|
-
console.log(data.someProperty) // ✨ Type-safe!
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
### **❌ NUNCA Usar Wrappers**
|
|
173
|
-
```typescript
|
|
174
|
-
// ❌ Não fazer - quebra tipos
|
|
175
|
-
const result = await apiCall(api.endpoint())
|
|
176
|
-
// result é 'any' - perdeu type safety
|
|
177
|
-
|
|
178
|
-
// ❌ Não fazer - type assertions
|
|
179
|
-
const data = (await api.endpoint()) as SomeType
|
|
180
|
-
// Manual e propenso a erros
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
### **✅ Response Schemas Obrigatórios**
|
|
184
|
-
```typescript
|
|
185
|
-
// ✅ Sempre definir response schemas
|
|
186
|
-
.get("/endpoint", handler, {
|
|
187
|
-
response: t.Object({
|
|
188
|
-
// Schema exato da resposta
|
|
189
|
-
data: t.Array(t.Object({...}))
|
|
190
|
-
})
|
|
191
|
-
})
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
## 💡 **Insights Importantes**
|
|
195
|
-
|
|
196
|
-
### **1. Eden Treaty é Mágico Quando Usado Corretamente**
|
|
197
|
-
- Inferência automática funciona perfeitamente
|
|
198
|
-
- Zero configuração manual de tipos
|
|
199
|
-
- Sincronização automática client/server
|
|
200
|
-
|
|
201
|
-
### **2. Abstrações Podem Ser Prejudiciais**
|
|
202
|
-
- Nem toda abstração é benéfica
|
|
203
|
-
- Wrappers podem quebrar funcionalidades avançadas
|
|
204
|
-
- Simplicidade às vezes é melhor
|
|
205
|
-
|
|
206
|
-
### **3. Response Schemas São Críticos**
|
|
207
|
-
- Não apenas para validação
|
|
208
|
-
- Essenciais para type inference
|
|
209
|
-
- Documentação automática via Swagger
|
|
210
|
-
|
|
211
|
-
## 🚀 **Impacto no Framework**
|
|
212
|
-
|
|
213
|
-
Esta correção transformou FluxStack de um framework com "type safety parcial" para um framework com **type safety automática completa**, realizando completamente a promessa do Eden Treaty.
|
|
214
|
-
|
|
215
|
-
### **Benefícios Alcançados:**
|
|
216
|
-
- **🔒 Type Safety Total**: Zero types `unknown` ou `any`
|
|
217
|
-
- **✨ Autocomplete Perfeito**: IntelliSense funcionando 100%
|
|
218
|
-
- **🔄 Sync Automático**: Mudanças server → client automáticas
|
|
219
|
-
- **📖 Self-Documenting**: Tipos servem como documentação viva
|
|
220
|
-
|
|
221
|
-
---
|
|
222
|
-
|
|
223
|
-
**🎯 Esta correção prova que Eden Treaty + FluxStack oferecem a melhor experiência de desenvolvimento TypeScript full-stack disponível!**
|