create-fluxstack 1.0.13 → 1.0.14
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 +46 -2
- 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,362 +0,0 @@
|
|
|
1
|
-
# 🔥 Eden Treaty - Guia Completo para FluxStack
|
|
2
|
-
|
|
3
|
-
> **Eden Treaty é o coração do FluxStack**: Type safety automática end-to-end sem declarações manuais
|
|
4
|
-
|
|
5
|
-
## 🎯 **Visão Geral**
|
|
6
|
-
|
|
7
|
-
Eden Treaty é um cliente HTTP que **automaticamente infere tipos** das rotas Elysia.js, eliminando duplicação de código e garantindo sincronização perfeita entre client e server.
|
|
8
|
-
|
|
9
|
-
### ✨ **Benefícios**
|
|
10
|
-
- **🔒 Type Safety**: Inferência automática de tipos
|
|
11
|
-
- **📖 Autocomplete**: IntelliSense perfeito no editor
|
|
12
|
-
- **🚀 Zero Config**: Funciona sem configuração manual
|
|
13
|
-
- **🔄 Sync Automático**: Mudanças no server refletem automaticamente no client
|
|
14
|
-
- **⚡ Performance**: Otimizado para aplicações modernas
|
|
15
|
-
|
|
16
|
-
## ❌ **Erro Comum: Wrapper que Quebra Tipos**
|
|
17
|
-
|
|
18
|
-
### 🚨 **PROBLEMA (Antes da Refatoração)**
|
|
19
|
-
```typescript
|
|
20
|
-
// ❌ Wrapper que quebrava a inferência automática
|
|
21
|
-
export async function apiCall(apiPromise: Promise<any>) {
|
|
22
|
-
const { data, error } = await apiPromise
|
|
23
|
-
if (error) throw new APIException(...)
|
|
24
|
-
return data // ❌ Retorna 'any' - perdeu todos os tipos!
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// ❌ Uso que perde type safety
|
|
28
|
-
const users = await apiCall(api.users.get())
|
|
29
|
-
// users é 'any' - perdeu autocomplete e verificação de tipos! 😞
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
### ✅ **SOLUÇÃO (Após Refatoração)**
|
|
33
|
-
```typescript
|
|
34
|
-
// ✅ Eden Treaty nativo - inferência perfeita!
|
|
35
|
-
const { data: users, error } = await api.users.get()
|
|
36
|
-
|
|
37
|
-
if (error) {
|
|
38
|
-
// error tem tipo correto com status, message, etc.
|
|
39
|
-
console.log(`API Error: ${error.status}`)
|
|
40
|
-
return
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// ✅ TypeScript sabe que users é: { users: User[] }
|
|
44
|
-
console.log(users.users.length) // ✨ Autocomplete perfeito!
|
|
45
|
-
console.log(users.users[0].name) // ✨ Type-safe!
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
## 🏗️ **Configuração Correta**
|
|
49
|
-
|
|
50
|
-
### **1. Server App Export (app/server/app.ts)**
|
|
51
|
-
```typescript
|
|
52
|
-
import { Elysia } from "elysia"
|
|
53
|
-
import { apiRoutes } from "./routes"
|
|
54
|
-
|
|
55
|
-
// ✅ Exportar tipo correto para Eden Treaty
|
|
56
|
-
const appInstance = new Elysia()
|
|
57
|
-
.use(apiRoutes)
|
|
58
|
-
|
|
59
|
-
export type App = typeof appInstance
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
### **2. Cliente Eden Treaty (app/client/src/lib/eden-api.ts)**
|
|
63
|
-
```typescript
|
|
64
|
-
import { treaty } from '@elysiajs/eden'
|
|
65
|
-
import type { App } from '../../../server/app'
|
|
66
|
-
|
|
67
|
-
// ✅ Criar cliente com typing correto
|
|
68
|
-
const client = treaty<App>(getBaseUrl())
|
|
69
|
-
|
|
70
|
-
// ✅ Exportar API diretamente para inferência perfeita
|
|
71
|
-
export const api = client.api
|
|
72
|
-
|
|
73
|
-
// ✅ Export apenas para error handling (opcional)
|
|
74
|
-
export { getErrorMessage } from './error-utils'
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
### **3. Response Schemas (app/server/routes/*.ts)**
|
|
78
|
-
```typescript
|
|
79
|
-
import { Elysia, t } from "elysia"
|
|
80
|
-
|
|
81
|
-
export const usersRoutes = new Elysia({ prefix: "/users" })
|
|
82
|
-
.get("/", () => UsersController.getUsers(), {
|
|
83
|
-
// ✅ Schema de resposta para inferência automática
|
|
84
|
-
response: t.Object({
|
|
85
|
-
users: t.Array(t.Object({
|
|
86
|
-
id: t.Number(),
|
|
87
|
-
name: t.String(),
|
|
88
|
-
email: t.String(),
|
|
89
|
-
createdAt: t.Date()
|
|
90
|
-
}))
|
|
91
|
-
})
|
|
92
|
-
})
|
|
93
|
-
.post("/", async ({ body }) => {
|
|
94
|
-
return await UsersController.createUser(body)
|
|
95
|
-
}, {
|
|
96
|
-
body: t.Object({
|
|
97
|
-
name: t.String({ minLength: 2 }),
|
|
98
|
-
email: t.String({ format: "email" })
|
|
99
|
-
}),
|
|
100
|
-
// ✅ Schema de resposta para POST
|
|
101
|
-
response: t.Object({
|
|
102
|
-
success: t.Boolean(),
|
|
103
|
-
user: t.Optional(t.Object({
|
|
104
|
-
id: t.Number(),
|
|
105
|
-
name: t.String(),
|
|
106
|
-
email: t.String(),
|
|
107
|
-
createdAt: t.Date()
|
|
108
|
-
})),
|
|
109
|
-
message: t.Optional(t.String())
|
|
110
|
-
})
|
|
111
|
-
})
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
## 💡 **Padrões de Uso Correto**
|
|
115
|
-
|
|
116
|
-
### **✅ Padrão 1: GET Simples**
|
|
117
|
-
```typescript
|
|
118
|
-
// Server Route
|
|
119
|
-
.get("/users", () => UsersController.getUsers())
|
|
120
|
-
|
|
121
|
-
// Client Usage - Eden Treaty nativo
|
|
122
|
-
const { data: response, error } = await api.users.get()
|
|
123
|
-
|
|
124
|
-
if (error) {
|
|
125
|
-
console.log(`Erro: ${error.status} - ${error.message}`)
|
|
126
|
-
return
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// ✨ TypeScript infere: response = { users: User[] }
|
|
130
|
-
response.users.forEach(user => {
|
|
131
|
-
console.log(user.name) // ✨ Autocomplete perfeito!
|
|
132
|
-
})
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
### **✅ Padrão 2: POST com Body**
|
|
136
|
-
```typescript
|
|
137
|
-
// Server Route
|
|
138
|
-
.post("/users", async ({ body }) => UsersController.createUser(body))
|
|
139
|
-
|
|
140
|
-
// Client Usage
|
|
141
|
-
const { data: result, error } = await api.users.post({
|
|
142
|
-
name: "João Silva",
|
|
143
|
-
email: "joao@example.com"
|
|
144
|
-
})
|
|
145
|
-
|
|
146
|
-
if (error) {
|
|
147
|
-
console.log(`Erro na criação: ${error.status}`)
|
|
148
|
-
return
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// ✨ TypeScript infere: result = UserResponse
|
|
152
|
-
if (result.success && result.user) {
|
|
153
|
-
console.log(`Usuário criado: ${result.user.name}`)
|
|
154
|
-
}
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
### **✅ Padrão 3: GET com Parâmetros**
|
|
158
|
-
```typescript
|
|
159
|
-
// Server Route
|
|
160
|
-
.get("/:id", async ({ params: { id } }) => UsersController.getUserById(+id))
|
|
161
|
-
|
|
162
|
-
// Client Usage
|
|
163
|
-
const { data: response, error } = await api.users({ id: 123 }).get()
|
|
164
|
-
|
|
165
|
-
if (error) {
|
|
166
|
-
console.log(`Usuário não encontrado: ${error.status}`)
|
|
167
|
-
return
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// ✨ TypeScript infere: response = { user: User }
|
|
171
|
-
console.log(`Nome: ${response.user.name}`)
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
### **✅ Padrão 4: DELETE**
|
|
175
|
-
```typescript
|
|
176
|
-
// Server Route
|
|
177
|
-
.delete("/:id", ({ params: { id } }) => UsersController.deleteUser(+id))
|
|
178
|
-
|
|
179
|
-
// Client Usage
|
|
180
|
-
const { data: result, error } = await api.users({ id: userId }).delete()
|
|
181
|
-
|
|
182
|
-
if (error) {
|
|
183
|
-
console.log(`Erro ao deletar: ${error.status}`)
|
|
184
|
-
return
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// ✨ TypeScript infere: result = UserResponse
|
|
188
|
-
if (result.success) {
|
|
189
|
-
console.log(`Usuário deletado: ${result.message}`)
|
|
190
|
-
}
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
## 🔧 **Error Handling Elegante**
|
|
194
|
-
|
|
195
|
-
### **✅ Padrão Global de Error Handling**
|
|
196
|
-
```typescript
|
|
197
|
-
// utils/api-helpers.ts
|
|
198
|
-
export function handleApiError(error: any, context: string) {
|
|
199
|
-
console.error(`[${context}] API Error:`, {
|
|
200
|
-
status: error.status,
|
|
201
|
-
message: error.message,
|
|
202
|
-
details: error.details
|
|
203
|
-
})
|
|
204
|
-
|
|
205
|
-
// Tratamento específico por status
|
|
206
|
-
switch (error.status) {
|
|
207
|
-
case 400: return "Dados inválidos fornecidos"
|
|
208
|
-
case 401: return "Acesso não autorizado"
|
|
209
|
-
case 404: return "Recurso não encontrado"
|
|
210
|
-
case 500: return "Erro interno do servidor"
|
|
211
|
-
default: return "Erro desconhecido"
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
// Uso nos componentes
|
|
216
|
-
const { data: users, error } = await api.users.get()
|
|
217
|
-
|
|
218
|
-
if (error) {
|
|
219
|
-
const userMessage = handleApiError(error, "Lista de Usuários")
|
|
220
|
-
showToast("error", userMessage)
|
|
221
|
-
return
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
// Continuar com dados válidos...
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
## 🎯 **Dicas Avançadas**
|
|
228
|
-
|
|
229
|
-
### **💡 Dica 1: Type Guards**
|
|
230
|
-
```typescript
|
|
231
|
-
// Verificar sucesso com type safety
|
|
232
|
-
const { data, error } = await api.users.post(userData)
|
|
233
|
-
|
|
234
|
-
if (error) return // Early return
|
|
235
|
-
|
|
236
|
-
// Aqui TypeScript sabe que data é o tipo de sucesso
|
|
237
|
-
if (data.success && data.user) {
|
|
238
|
-
// data.user é garantidamente User
|
|
239
|
-
updateUsersList(data.user)
|
|
240
|
-
}
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
### **💡 Dica 2: Loading States**
|
|
244
|
-
```typescript
|
|
245
|
-
const [loading, setLoading] = useState(false)
|
|
246
|
-
const [users, setUsers] = useState<User[]>([])
|
|
247
|
-
|
|
248
|
-
const loadUsers = async () => {
|
|
249
|
-
setLoading(true)
|
|
250
|
-
try {
|
|
251
|
-
const { data, error } = await api.users.get()
|
|
252
|
-
|
|
253
|
-
if (error) {
|
|
254
|
-
showError(handleApiError(error, "Carregar Usuários"))
|
|
255
|
-
return
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
setUsers(data.users) // ✨ Type-safe assignment
|
|
259
|
-
} finally {
|
|
260
|
-
setLoading(false)
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
### **💡 Dica 3: Optimistic Updates**
|
|
266
|
-
```typescript
|
|
267
|
-
const deleteUser = async (userId: number) => {
|
|
268
|
-
// Otimistic update
|
|
269
|
-
setUsers(prev => prev.filter(u => u.id !== userId))
|
|
270
|
-
|
|
271
|
-
try {
|
|
272
|
-
const { error } = await api.users({ id: userId }).delete()
|
|
273
|
-
|
|
274
|
-
if (error) {
|
|
275
|
-
// Reverter mudança otimística
|
|
276
|
-
loadUsers() // Recarregar estado real
|
|
277
|
-
showError(handleApiError(error, "Deletar Usuário"))
|
|
278
|
-
}
|
|
279
|
-
} catch (err) {
|
|
280
|
-
loadUsers() // Recarregar em caso de erro de rede
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
## ⚠️ **Problemas Comuns & Soluções**
|
|
286
|
-
|
|
287
|
-
### **❌ Problema: Tipos `unknown`**
|
|
288
|
-
```typescript
|
|
289
|
-
// Se você vir isso:
|
|
290
|
-
const { data, error } = await api.users.get()
|
|
291
|
-
// data é 'unknown' em vez do tipo correto
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
**✅ Soluções:**
|
|
295
|
-
1. **Verificar response schema** nas rotas do servidor
|
|
296
|
-
2. **Confirmar export** do tipo App correto
|
|
297
|
-
3. **Reiniciar** TypeScript server no editor
|
|
298
|
-
4. **Verificar** se não há conflitos de tipos
|
|
299
|
-
|
|
300
|
-
### **❌ Problema: Error 'Property does not exist'**
|
|
301
|
-
```typescript
|
|
302
|
-
// Erro: Property 'users' does not exist on type 'unknown'
|
|
303
|
-
console.log(data.users) // ❌
|
|
304
|
-
```
|
|
305
|
-
|
|
306
|
-
**✅ Solução:**
|
|
307
|
-
```typescript
|
|
308
|
-
// Verificar schema da rota:
|
|
309
|
-
response: t.Object({
|
|
310
|
-
users: t.Array(/* User schema */)
|
|
311
|
-
})
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
### **❌ Problema: Parâmetros não funcionam**
|
|
315
|
-
```typescript
|
|
316
|
-
// ❌ Sintaxe incorreta
|
|
317
|
-
await api.users[userId].get() // Error!
|
|
318
|
-
|
|
319
|
-
// ✅ Sintaxe correta
|
|
320
|
-
await api.users({ id: userId }).get()
|
|
321
|
-
```
|
|
322
|
-
|
|
323
|
-
## 🧪 **Testing com Eden Treaty**
|
|
324
|
-
|
|
325
|
-
### **✅ Teste de Integração**
|
|
326
|
-
```typescript
|
|
327
|
-
// tests/api.test.ts
|
|
328
|
-
import { describe, it, expect } from 'vitest'
|
|
329
|
-
import { api } from '../app/client/src/lib/eden-api'
|
|
330
|
-
|
|
331
|
-
describe('Users API', () => {
|
|
332
|
-
it('should create and fetch user', async () => {
|
|
333
|
-
// Criar usuário
|
|
334
|
-
const { data: createResult, error: createError } = await api.users.post({
|
|
335
|
-
name: "Test User",
|
|
336
|
-
email: "test@example.com"
|
|
337
|
-
})
|
|
338
|
-
|
|
339
|
-
expect(createError).toBeUndefined()
|
|
340
|
-
expect(createResult.success).toBe(true)
|
|
341
|
-
expect(createResult.user).toBeDefined()
|
|
342
|
-
|
|
343
|
-
// Buscar usuário criado
|
|
344
|
-
const { data: getResult, error: getError } = await api.users({
|
|
345
|
-
id: createResult.user!.id
|
|
346
|
-
}).get()
|
|
347
|
-
|
|
348
|
-
expect(getError).toBeUndefined()
|
|
349
|
-
expect(getResult.user.name).toBe("Test User")
|
|
350
|
-
})
|
|
351
|
-
})
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
## 📚 **Recursos Adicionais**
|
|
355
|
-
|
|
356
|
-
- **[Eden Treaty Docs](https://elysiajs.com/eden/overview.html)** - Documentação oficial
|
|
357
|
-
- **[Elysia Validation](https://elysiajs.com/validation/overview.html)** - Schemas TypeBox
|
|
358
|
-
- **[TypeScript Inference](https://www.typescriptlang.org/docs/handbook/type-inference.html)** - Como funciona
|
|
359
|
-
|
|
360
|
-
---
|
|
361
|
-
|
|
362
|
-
**🎯 Com Eden Treaty nativo, você tem type safety total, autocomplete perfeito e zero duplicação de código entre client e server!**
|