create-fluxstack 1.10.1 → 1.12.1
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/.dockerignore +1 -2
- package/Dockerfile +8 -8
- package/LLMD/INDEX.md +64 -0
- package/LLMD/MAINTENANCE.md +197 -0
- package/LLMD/MIGRATION.md +156 -0
- package/LLMD/config/.gitkeep +1 -0
- package/LLMD/config/declarative-system.md +268 -0
- package/LLMD/config/environment-vars.md +327 -0
- package/LLMD/config/runtime-reload.md +401 -0
- package/LLMD/core/.gitkeep +1 -0
- package/LLMD/core/build-system.md +599 -0
- package/LLMD/core/framework-lifecycle.md +229 -0
- package/LLMD/core/plugin-system.md +451 -0
- package/LLMD/patterns/.gitkeep +1 -0
- package/LLMD/patterns/anti-patterns.md +297 -0
- package/LLMD/patterns/project-structure.md +264 -0
- package/LLMD/patterns/type-safety.md +440 -0
- package/LLMD/reference/.gitkeep +1 -0
- package/LLMD/reference/cli-commands.md +250 -0
- package/LLMD/reference/plugin-hooks.md +357 -0
- package/LLMD/reference/routing.md +39 -0
- package/LLMD/reference/troubleshooting.md +364 -0
- package/LLMD/resources/.gitkeep +1 -0
- package/LLMD/resources/controllers.md +465 -0
- package/LLMD/resources/live-components.md +703 -0
- package/LLMD/resources/live-rooms.md +482 -0
- package/LLMD/resources/live-upload.md +130 -0
- package/LLMD/resources/plugins-external.md +617 -0
- package/LLMD/resources/routes-eden.md +254 -0
- package/README.md +37 -17
- package/app/client/index.html +0 -1
- package/app/client/src/App.tsx +107 -150
- package/app/client/src/components/AppLayout.tsx +68 -0
- package/app/client/src/components/BackButton.tsx +13 -0
- package/app/client/src/components/DemoPage.tsx +20 -0
- package/app/client/src/components/LiveUploadWidget.tsx +204 -0
- package/app/client/src/lib/eden-api.ts +85 -60
- package/app/client/src/live/ChatDemo.tsx +107 -0
- package/app/client/src/live/CounterDemo.tsx +206 -0
- package/app/client/src/live/FormDemo.tsx +119 -0
- package/app/client/src/live/RoomChatDemo.tsx +161 -0
- package/app/client/src/live/UploadDemo.tsx +21 -0
- package/app/client/src/main.tsx +4 -1
- package/app/client/src/pages/ApiTestPage.tsx +108 -0
- package/app/client/src/pages/HomePage.tsx +76 -0
- package/app/server/app.ts +1 -4
- package/app/server/controllers/users.controller.ts +36 -44
- package/app/server/index.ts +25 -35
- package/app/server/live/LiveChat.ts +77 -0
- package/app/server/live/LiveCounter.ts +67 -0
- package/app/server/live/LiveForm.ts +63 -0
- package/app/server/live/LiveLocalCounter.ts +32 -0
- package/app/server/live/LiveRoomChat.ts +127 -0
- package/app/server/live/LiveUpload.ts +81 -0
- package/app/server/routes/index.ts +3 -1
- package/app/server/routes/room.routes.ts +117 -0
- package/app/server/routes/users.routes.ts +35 -27
- package/app/shared/types/index.ts +14 -2
- package/config/app.config.ts +2 -62
- package/config/client.config.ts +2 -95
- package/config/database.config.ts +2 -99
- package/config/fluxstack.config.ts +25 -45
- package/config/index.ts +57 -38
- package/config/monitoring.config.ts +2 -114
- package/config/plugins.config.ts +2 -80
- package/config/server.config.ts +2 -68
- package/config/services.config.ts +2 -130
- package/config/system/app.config.ts +29 -0
- package/config/system/build.config.ts +49 -0
- package/config/system/client.config.ts +68 -0
- package/config/system/database.config.ts +17 -0
- package/config/system/fluxstack.config.ts +114 -0
- package/config/{logger.config.ts → system/logger.config.ts} +3 -1
- package/config/system/monitoring.config.ts +114 -0
- package/config/system/plugins.config.ts +84 -0
- package/config/{runtime.config.ts → system/runtime.config.ts} +1 -1
- package/config/system/server.config.ts +68 -0
- package/config/system/services.config.ts +46 -0
- package/config/{system.config.ts → system/system.config.ts} +1 -1
- package/core/build/flux-plugins-generator.ts +325 -325
- package/core/build/index.ts +39 -27
- package/core/build/live-components-generator.ts +3 -3
- package/core/build/optimizer.ts +235 -235
- package/core/cli/command-registry.ts +6 -4
- package/core/cli/commands/build.ts +79 -0
- package/core/cli/commands/create.ts +54 -0
- package/core/cli/commands/dev.ts +101 -0
- package/core/cli/commands/help.ts +34 -0
- package/core/cli/commands/index.ts +34 -0
- package/core/cli/commands/make-plugin.ts +90 -0
- package/core/cli/commands/plugin-add.ts +197 -0
- package/core/cli/commands/plugin-deps.ts +2 -2
- package/core/cli/commands/plugin-list.ts +208 -0
- package/core/cli/commands/plugin-remove.ts +170 -0
- package/core/cli/generators/component.ts +769 -769
- package/core/cli/generators/controller.ts +1 -1
- package/core/cli/generators/index.ts +146 -146
- package/core/cli/generators/interactive.ts +227 -227
- package/core/cli/generators/plugin.ts +2 -2
- package/core/cli/generators/prompts.ts +82 -82
- package/core/cli/generators/route.ts +6 -6
- package/core/cli/generators/service.ts +2 -2
- package/core/cli/generators/template-engine.ts +4 -3
- package/core/cli/generators/types.ts +2 -2
- package/core/cli/generators/utils.ts +191 -191
- package/core/cli/index.ts +115 -686
- package/core/cli/plugin-discovery.ts +2 -2
- package/core/client/LiveComponentsProvider.tsx +60 -8
- package/core/client/api/eden.ts +183 -0
- package/core/client/api/index.ts +11 -0
- package/core/client/components/Live.tsx +104 -0
- package/core/client/fluxstack.ts +1 -9
- package/core/client/hooks/AdaptiveChunkSizer.ts +215 -215
- package/core/client/hooks/state-validator.ts +1 -1
- package/core/client/hooks/useAuth.ts +48 -48
- package/core/client/hooks/useChunkedUpload.ts +85 -35
- package/core/client/hooks/useLiveChunkedUpload.ts +87 -0
- package/core/client/hooks/useLiveComponent.ts +800 -0
- package/core/client/hooks/useLiveUpload.ts +71 -0
- package/core/client/hooks/useRoom.ts +409 -0
- package/core/client/hooks/useRoomProxy.ts +382 -0
- package/core/client/index.ts +17 -68
- package/core/client/standalone-entry.ts +8 -0
- package/core/client/standalone.ts +74 -53
- package/core/client/state/createStore.ts +192 -192
- package/core/client/state/index.ts +14 -14
- package/core/config/index.ts +70 -291
- package/core/config/schema.ts +42 -723
- package/core/framework/client.ts +131 -131
- package/core/framework/index.ts +7 -7
- package/core/framework/server.ts +47 -40
- package/core/framework/types.ts +2 -2
- package/core/index.ts +23 -4
- package/core/live/ComponentRegistry.ts +3 -3
- package/core/live/types.ts +77 -0
- package/core/plugins/built-in/index.ts +134 -134
- package/core/plugins/built-in/live-components/commands/create-live-component.ts +242 -1066
- package/core/plugins/built-in/live-components/index.ts +1 -1
- package/core/plugins/built-in/monitoring/index.ts +111 -47
- package/core/plugins/built-in/static/index.ts +1 -1
- package/core/plugins/built-in/swagger/index.ts +68 -265
- package/core/plugins/built-in/vite/index.ts +85 -185
- package/core/plugins/built-in/vite/vite-dev.ts +10 -16
- package/core/plugins/config.ts +9 -7
- package/core/plugins/dependency-manager.ts +31 -1
- package/core/plugins/discovery.ts +19 -7
- package/core/plugins/executor.ts +2 -2
- package/core/plugins/index.ts +203 -203
- package/core/plugins/manager.ts +27 -39
- package/core/plugins/module-resolver.ts +19 -8
- package/core/plugins/registry.ts +255 -19
- package/core/plugins/types.ts +20 -53
- package/core/server/framework.ts +66 -43
- package/core/server/index.ts +15 -15
- package/core/server/live/ComponentRegistry.ts +78 -71
- package/core/server/live/FileUploadManager.ts +23 -10
- package/core/server/live/LiveComponentPerformanceMonitor.ts +1 -1
- package/core/server/live/LiveRoomManager.ts +261 -0
- package/core/server/live/RoomEventBus.ts +234 -0
- package/core/server/live/RoomStateManager.ts +172 -0
- package/core/server/live/StateSignature.ts +643 -643
- package/core/server/live/WebSocketConnectionManager.ts +30 -19
- package/core/server/live/auto-generated-components.ts +21 -9
- package/core/server/live/index.ts +14 -0
- package/core/server/live/websocket-plugin.ts +214 -67
- package/core/server/middleware/elysia-helpers.ts +7 -2
- package/core/server/middleware/errorHandling.ts +1 -1
- package/core/server/middleware/index.ts +31 -31
- package/core/server/plugins/database.ts +180 -180
- package/core/server/plugins/static-files-plugin.ts +69 -69
- package/core/server/plugins/swagger.ts +1 -1
- package/core/server/rooms/RoomBroadcaster.ts +357 -0
- package/core/server/rooms/RoomSystem.ts +463 -0
- package/core/server/rooms/index.ts +13 -0
- package/core/server/services/BaseService.ts +1 -1
- package/core/server/services/ServiceContainer.ts +1 -1
- package/core/server/services/index.ts +8 -8
- package/core/templates/create-project.ts +12 -12
- package/core/testing/index.ts +9 -9
- package/core/testing/setup.ts +73 -73
- package/core/types/api.ts +168 -168
- package/core/types/build.ts +219 -219
- package/core/types/config.ts +56 -26
- package/core/types/index.ts +4 -4
- package/core/types/plugin.ts +107 -107
- package/core/types/types.ts +353 -14
- package/core/utils/build-logger.ts +324 -324
- package/core/utils/config-schema.ts +480 -480
- package/core/utils/env.ts +2 -8
- package/core/utils/errors/codes.ts +114 -114
- package/core/utils/errors/handlers.ts +36 -1
- package/core/utils/errors/index.ts +49 -5
- package/core/utils/errors/middleware.ts +113 -113
- package/core/utils/helpers.ts +6 -16
- package/core/utils/index.ts +17 -17
- package/core/utils/logger/colors.ts +114 -114
- package/core/utils/logger/config.ts +13 -9
- package/core/utils/logger/formatter.ts +82 -82
- package/core/utils/logger/group-logger.ts +101 -101
- package/core/utils/logger/index.ts +6 -1
- package/core/utils/logger/stack-trace.ts +3 -1
- package/core/utils/logger/startup-banner.ts +82 -82
- package/core/utils/logger/winston-logger.ts +152 -152
- package/core/utils/monitoring/index.ts +211 -211
- package/core/utils/sync-version.ts +66 -66
- package/core/utils/version.ts +1 -1
- package/create-fluxstack.ts +8 -7
- package/package.json +12 -13
- package/plugins/crypto-auth/cli/make-protected-route.command.ts +1 -1
- package/plugins/crypto-auth/client/CryptoAuthClient.ts +302 -302
- package/plugins/crypto-auth/client/components/index.ts +11 -11
- package/plugins/crypto-auth/client/index.ts +11 -11
- package/plugins/crypto-auth/config/index.ts +1 -1
- package/plugins/crypto-auth/index.ts +4 -4
- package/plugins/crypto-auth/package.json +65 -65
- package/plugins/crypto-auth/server/AuthMiddleware.ts +1 -1
- package/plugins/crypto-auth/server/CryptoAuthService.ts +185 -185
- package/plugins/crypto-auth/server/index.ts +21 -21
- package/plugins/crypto-auth/server/middlewares/cryptoAuthAdmin.ts +3 -3
- package/plugins/crypto-auth/server/middlewares/cryptoAuthOptional.ts +1 -1
- package/plugins/crypto-auth/server/middlewares/cryptoAuthPermissions.ts +2 -2
- package/plugins/crypto-auth/server/middlewares/cryptoAuthRequired.ts +2 -2
- package/plugins/crypto-auth/server/middlewares/helpers.ts +1 -1
- package/plugins/crypto-auth/server/middlewares/index.ts +22 -22
- package/tsconfig.api-strict.json +16 -0
- package/tsconfig.json +48 -52
- package/{app/client/tsconfig.node.json → tsconfig.node.json} +25 -25
- package/types/global.d.ts +29 -29
- package/types/vitest.d.ts +8 -8
- package/vite.config.ts +38 -62
- package/vitest.config.live.ts +10 -9
- package/vitest.config.ts +29 -17
- package/app/client/README.md +0 -69
- package/app/client/SIMPLIFICATION.md +0 -140
- package/app/client/frontend-only.ts +0 -12
- package/app/client/src/live/FileUploadExample.tsx +0 -359
- package/app/client/src/live/MinimalLiveClock.tsx +0 -47
- package/app/client/src/live/QuickUploadTest.tsx +0 -193
- package/app/client/tsconfig.app.json +0 -45
- package/app/client/tsconfig.json +0 -7
- package/app/client/zustand-setup.md +0 -65
- package/app/server/backend-only.ts +0 -18
- package/app/server/live/LiveClockComponent.ts +0 -215
- package/app/server/live/LiveFileUploadComponent.ts +0 -77
- package/app/server/routes/env-test.ts +0 -110
- package/core/client/hooks/index.ts +0 -7
- package/core/client/hooks/useHybridLiveComponent.ts +0 -685
- package/core/client/hooks/useTypedLiveComponent.ts +0 -133
- package/core/client/hooks/useWebSocket.ts +0 -361
- package/core/config/env.ts +0 -546
- package/core/config/loader.ts +0 -522
- package/core/config/runtime-config.ts +0 -327
- package/core/config/validator.ts +0 -540
- package/core/server/backend-entry.ts +0 -51
- package/core/server/standalone.ts +0 -106
- package/core/utils/regenerate-files.ts +0 -69
- package/fluxstack.config.ts +0 -354
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# Routes with Eden Treaty
|
|
2
|
+
|
|
3
|
+
**Version:** 1.11.0 | **Updated:** 2025-02-08
|
|
4
|
+
|
|
5
|
+
## Quick Facts
|
|
6
|
+
|
|
7
|
+
- Routes use Elysia with `t.Object()` validation schemas
|
|
8
|
+
- **Response schemas are REQUIRED** for Eden Treaty type inference
|
|
9
|
+
- Frontend gets automatic type inference via Eden Treaty
|
|
10
|
+
- Route grouping uses `prefix` option
|
|
11
|
+
- Validation happens automatically via schemas
|
|
12
|
+
|
|
13
|
+
## Route Definition Pattern
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { Elysia, t } from 'elysia'
|
|
17
|
+
|
|
18
|
+
export const usersRoutes = new Elysia({ prefix: '/users', tags: ['Users'] })
|
|
19
|
+
.get('/', async () => {
|
|
20
|
+
// Handler logic
|
|
21
|
+
return { success: true, users: [], count: 0 }
|
|
22
|
+
}, {
|
|
23
|
+
detail: {
|
|
24
|
+
summary: 'Get All Users',
|
|
25
|
+
description: 'Retrieves a list of all registered users',
|
|
26
|
+
tags: ['Users', 'CRUD']
|
|
27
|
+
},
|
|
28
|
+
response: t.Object({
|
|
29
|
+
success: t.Boolean(),
|
|
30
|
+
users: t.Array(UserSchema),
|
|
31
|
+
count: t.Number()
|
|
32
|
+
})
|
|
33
|
+
})
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Schema Definition
|
|
37
|
+
|
|
38
|
+
Define schemas at the top of route files:
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
const UserSchema = t.Object({
|
|
42
|
+
id: t.Number(),
|
|
43
|
+
name: t.String(),
|
|
44
|
+
email: t.String()
|
|
45
|
+
}, {
|
|
46
|
+
description: 'User object'
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
const CreateUserRequestSchema = t.Object({
|
|
50
|
+
name: t.String({ minLength: 2, description: 'User name (minimum 2 characters)' }),
|
|
51
|
+
email: t.String({ format: 'email', description: 'Valid email address' })
|
|
52
|
+
}, {
|
|
53
|
+
description: 'Request body for creating a new user'
|
|
54
|
+
})
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Response Schema (REQUIRED!)
|
|
58
|
+
|
|
59
|
+
**Every route MUST define a response schema** for Eden Treaty type inference:
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
.get('/users', async () => {
|
|
63
|
+
return { success: true, users: [] }
|
|
64
|
+
}, {
|
|
65
|
+
response: t.Object({
|
|
66
|
+
success: t.Boolean(),
|
|
67
|
+
users: t.Array(UserSchema)
|
|
68
|
+
})
|
|
69
|
+
})
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Without response schema, frontend loses type inference.
|
|
73
|
+
|
|
74
|
+
## Multiple Status Code Responses
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
.post('/', async ({ body, set }) => {
|
|
78
|
+
// Validation error
|
|
79
|
+
if (!body.name) {
|
|
80
|
+
set.status = 400
|
|
81
|
+
return { success: false, error: 'Name required' }
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Success
|
|
85
|
+
set.status = 201
|
|
86
|
+
return { success: true, user: newUser }
|
|
87
|
+
}, {
|
|
88
|
+
body: CreateUserRequestSchema,
|
|
89
|
+
response: {
|
|
90
|
+
201: t.Object({
|
|
91
|
+
success: t.Literal(true),
|
|
92
|
+
user: UserSchema
|
|
93
|
+
}),
|
|
94
|
+
400: t.Object({
|
|
95
|
+
success: t.Literal(false),
|
|
96
|
+
error: t.String()
|
|
97
|
+
})
|
|
98
|
+
}
|
|
99
|
+
})
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Route Parameters
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
.get('/:id', async ({ params }) => {
|
|
106
|
+
const id = Number(params.id)
|
|
107
|
+
return { success: true, user: foundUser }
|
|
108
|
+
}, {
|
|
109
|
+
params: t.Object({
|
|
110
|
+
id: t.String({ description: 'User ID' })
|
|
111
|
+
}),
|
|
112
|
+
response: {
|
|
113
|
+
200: GetUserResponseSchema,
|
|
114
|
+
404: ErrorResponseSchema
|
|
115
|
+
}
|
|
116
|
+
})
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Request Body Validation
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
.post('/', async ({ body }) => {
|
|
123
|
+
// body is automatically validated against schema
|
|
124
|
+
const user = await createUser(body)
|
|
125
|
+
return { success: true, user }
|
|
126
|
+
}, {
|
|
127
|
+
body: t.Object({
|
|
128
|
+
name: t.String({ minLength: 2 }),
|
|
129
|
+
email: t.String({ format: 'email' })
|
|
130
|
+
}),
|
|
131
|
+
response: CreateUserResponseSchema
|
|
132
|
+
})
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Route Grouping
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
// Main API routes with prefix
|
|
139
|
+
export const apiRoutes = new Elysia({ prefix: "/api" })
|
|
140
|
+
.get("/health", () => ({ status: "ok" }), {
|
|
141
|
+
response: t.Object({ status: t.String() })
|
|
142
|
+
})
|
|
143
|
+
// Register sub-routes
|
|
144
|
+
.use(usersRoutes)
|
|
145
|
+
.use(postsRoutes)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Frontend Usage (Eden Treaty)
|
|
149
|
+
|
|
150
|
+
Once routes are defined with response schemas, frontend gets automatic type inference:
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
import { api } from '@/lib/eden-api'
|
|
154
|
+
|
|
155
|
+
// GET request - types inferred from response schema
|
|
156
|
+
const { data, error } = await api.users.get()
|
|
157
|
+
// data: { success: boolean, users: User[], count: number } | undefined
|
|
158
|
+
// error: Error | undefined
|
|
159
|
+
|
|
160
|
+
// POST request - body type inferred from body schema
|
|
161
|
+
const { data, error } = await api.users.post({
|
|
162
|
+
name: 'John Doe',
|
|
163
|
+
email: 'john@example.com'
|
|
164
|
+
})
|
|
165
|
+
// TypeScript validates body matches CreateUserRequestSchema
|
|
166
|
+
|
|
167
|
+
// Path parameters
|
|
168
|
+
const { data } = await api.users({ id: '123' }).get()
|
|
169
|
+
|
|
170
|
+
// Query parameters
|
|
171
|
+
const { data } = await api.users.get({
|
|
172
|
+
query: { page: 1, limit: 10 }
|
|
173
|
+
})
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Type Flow Diagram
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
Backend Route Definition
|
|
180
|
+
↓
|
|
181
|
+
t.Object() Schema (response)
|
|
182
|
+
↓
|
|
183
|
+
Eden Treaty Type Inference
|
|
184
|
+
↓
|
|
185
|
+
Frontend api.users.get()
|
|
186
|
+
↓
|
|
187
|
+
Typed { data, error }
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Common Validation Types
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
// String validations
|
|
194
|
+
t.String({ minLength: 2, maxLength: 100 })
|
|
195
|
+
t.String({ format: 'email' })
|
|
196
|
+
t.String({ pattern: '^[a-z]+$' })
|
|
197
|
+
|
|
198
|
+
// Number validations
|
|
199
|
+
t.Number({ minimum: 0, maximum: 100 })
|
|
200
|
+
t.Integer()
|
|
201
|
+
|
|
202
|
+
// Arrays
|
|
203
|
+
t.Array(t.String())
|
|
204
|
+
t.Array(UserSchema, { minItems: 1 })
|
|
205
|
+
|
|
206
|
+
// Optional fields
|
|
207
|
+
t.Optional(t.String())
|
|
208
|
+
|
|
209
|
+
// Unions (multiple types)
|
|
210
|
+
t.Union([
|
|
211
|
+
t.Object({ success: t.Literal(true), data: t.Any() }),
|
|
212
|
+
t.Object({ success: t.Literal(false), error: t.String() })
|
|
213
|
+
])
|
|
214
|
+
|
|
215
|
+
// Enums
|
|
216
|
+
t.Union([t.Literal('active'), t.Literal('inactive')])
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## OpenAPI Documentation
|
|
220
|
+
|
|
221
|
+
The `detail` object generates OpenAPI/Swagger documentation:
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
.get('/users', handler, {
|
|
225
|
+
detail: {
|
|
226
|
+
summary: 'Get All Users',
|
|
227
|
+
description: 'Retrieves a list of all registered users',
|
|
228
|
+
tags: ['Users', 'CRUD']
|
|
229
|
+
},
|
|
230
|
+
response: ResponseSchema
|
|
231
|
+
})
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Access Swagger UI at `/swagger` when server is running.
|
|
235
|
+
|
|
236
|
+
## Critical Rules
|
|
237
|
+
|
|
238
|
+
**ALWAYS:**
|
|
239
|
+
- Define response schema for every route
|
|
240
|
+
- Use `t.Object()` for validation
|
|
241
|
+
- Set `set.status` for non-200 responses
|
|
242
|
+
- Define schemas at file top for reusability
|
|
243
|
+
|
|
244
|
+
**NEVER:**
|
|
245
|
+
- Omit response schema (breaks type inference)
|
|
246
|
+
- Use plain objects without `t.Object()`
|
|
247
|
+
- Forget to validate user input
|
|
248
|
+
- Mix route logic with business logic (use controllers)
|
|
249
|
+
|
|
250
|
+
## Related
|
|
251
|
+
|
|
252
|
+
- [Controllers & Services](./controllers.md)
|
|
253
|
+
- [Type Safety Patterns](../patterns/type-safety.md)
|
|
254
|
+
- [Anti-Patterns](../patterns/anti-patterns.md)
|
package/README.md
CHANGED
|
@@ -61,20 +61,35 @@
|
|
|
61
61
|
|
|
62
62
|
---
|
|
63
63
|
|
|
64
|
-
## 🚀 Quick Start
|
|
65
|
-
|
|
66
|
-
```bash
|
|
67
|
-
# Create a new FluxStack app
|
|
68
|
-
bunx create-fluxstack my-awesome-app
|
|
69
|
-
cd my-awesome-app
|
|
70
|
-
bun run dev
|
|
71
|
-
```
|
|
64
|
+
## 🚀 Quick Start
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# Create a new FluxStack app
|
|
68
|
+
bunx create-fluxstack my-awesome-app
|
|
69
|
+
cd my-awesome-app
|
|
70
|
+
bun run dev
|
|
71
|
+
```
|
|
72
72
|
|
|
73
73
|
**That's it!** Your full-stack app is running at:
|
|
74
74
|
|
|
75
75
|
- 🌐 **Frontend & Backend**: http://localhost:3000
|
|
76
76
|
- 📚 **API Documentation**: http://localhost:3000/swagger
|
|
77
|
-
- ⚡ **Hot Reload**: Automatic on file changes
|
|
77
|
+
- ⚡ **Hot Reload**: Automatic on file changes
|
|
78
|
+
|
|
79
|
+
### 🔀 Frontend Routes (React Router v7)
|
|
80
|
+
|
|
81
|
+
Default routes in the demo app:
|
|
82
|
+
|
|
83
|
+
- `/` Home
|
|
84
|
+
- `/counter` Live Counter
|
|
85
|
+
- `/form` Live Form
|
|
86
|
+
- `/upload` Live Upload
|
|
87
|
+
- `/api-test` Eden Treaty API Test
|
|
88
|
+
|
|
89
|
+
### 🧭 Router Package
|
|
90
|
+
|
|
91
|
+
This project now uses **React Router v7** via the `react-router` package (recommended by the v7 docs).
|
|
92
|
+
If you are upgrading from an older setup that used `react-router-dom`, update imports to `react-router`.
|
|
78
93
|
|
|
79
94
|
### Alternative Installation
|
|
80
95
|
|
|
@@ -111,7 +126,7 @@ bun run dev
|
|
|
111
126
|
- ✅ **Coordinated Hot Reload** - Backend and frontend reload independently
|
|
112
127
|
- ✅ **Auto-Generated Swagger** - API documentation updates automatically
|
|
113
128
|
- ✅ **Docker Templates** - Production-ready multi-stage builds included
|
|
114
|
-
- ✅ **AI-Focused Docs** -
|
|
129
|
+
- ✅ **AI-Focused Docs** - LLM-optimized documentation (`LLMD/`)
|
|
115
130
|
- ✅ **Declarative Config** - Laravel-inspired configuration system
|
|
116
131
|
- ✅ **WebSocket Support** - Real-time features built-in
|
|
117
132
|
- ✅ **Testing Setup** - Vitest + React Testing Library ready
|
|
@@ -200,10 +215,13 @@ FluxStack/
|
|
|
200
215
|
├── 🔌 plugins/ # External Plugins
|
|
201
216
|
│ └── crypto-auth/ # Example: Crypto authentication
|
|
202
217
|
│
|
|
203
|
-
├── 🤖
|
|
204
|
-
│ ├──
|
|
205
|
-
│ ├──
|
|
206
|
-
│
|
|
218
|
+
├── 🤖 LLMD/ # LLM-Optimized Documentation
|
|
219
|
+
│ ├── INDEX.md # Navigation hub
|
|
220
|
+
│ ├── core/ # Framework internals
|
|
221
|
+
│ ├── config/ # Configuration system
|
|
222
|
+
│ ├── resources/ # Creating routes, controllers
|
|
223
|
+
│ ├── patterns/ # Best practices
|
|
224
|
+
│ └── reference/ # CLI, hooks, troubleshooting
|
|
207
225
|
│
|
|
208
226
|
└── 📦 Package Files
|
|
209
227
|
├── package.json # Dependencies
|
|
@@ -445,10 +463,12 @@ if (featuresConfig.enableAnalytics) {
|
|
|
445
463
|
<td width="33%">
|
|
446
464
|
|
|
447
465
|
### 📖 **Documentation**
|
|
448
|
-
- [
|
|
449
|
-
- [
|
|
450
|
-
- [Development Patterns](./
|
|
466
|
+
- [LLM Documentation](./LLMD/) ⭐ **NEW**
|
|
467
|
+
- [LLMD Index](./LLMD/INDEX.md) - Navigation hub
|
|
468
|
+
- [Development Patterns](./LLMD/patterns/project-structure.md)
|
|
469
|
+
- [CLI Reference](./LLMD/reference/cli-commands.md)
|
|
451
470
|
- [CLAUDE.md](./CLAUDE.md)
|
|
471
|
+
- [AI Context (deprecated)](./ai-context/)
|
|
452
472
|
|
|
453
473
|
</td>
|
|
454
474
|
<td width="33%">
|
package/app/client/index.html
CHANGED
package/app/client/src/App.tsx
CHANGED
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
import { useState, useEffect } from 'react'
|
|
2
|
+
import { Routes, Route } from 'react-router'
|
|
2
3
|
import { api } from './lib/eden-api'
|
|
3
|
-
import { FaFire, FaBook, FaGithub, FaClock, FaImage } from 'react-icons/fa'
|
|
4
4
|
import { LiveComponentsProvider } from '@/core/client'
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { FormDemo } from './live/FormDemo'
|
|
6
|
+
import { CounterDemo } from './live/CounterDemo'
|
|
7
|
+
import { UploadDemo } from './live/UploadDemo'
|
|
8
|
+
import { ChatDemo } from './live/ChatDemo'
|
|
9
|
+
import { RoomChatDemo } from './live/RoomChatDemo'
|
|
10
|
+
import { AppLayout } from './components/AppLayout'
|
|
11
|
+
import { DemoPage } from './components/DemoPage'
|
|
12
|
+
import { HomePage } from './pages/HomePage'
|
|
13
|
+
import { ApiTestPage } from './pages/ApiTestPage'
|
|
7
14
|
|
|
8
15
|
function AppContent() {
|
|
9
16
|
const [apiStatus, setApiStatus] = useState<'checking' | 'online' | 'offline'>('checking')
|
|
10
|
-
const [
|
|
17
|
+
const [apiResponse, setApiResponse] = useState<string>('')
|
|
18
|
+
const [isLoading, setIsLoading] = useState(false)
|
|
11
19
|
|
|
12
20
|
useEffect(() => {
|
|
13
21
|
checkApiStatus()
|
|
@@ -22,159 +30,108 @@ function AppContent() {
|
|
|
22
30
|
}
|
|
23
31
|
}
|
|
24
32
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
className="px-4 py-2 bg-white/10 backdrop-blur-sm border border-white/20 text-white rounded-lg font-medium hover:bg-white/20 transition-all"
|
|
35
|
-
>
|
|
36
|
-
← Back
|
|
37
|
-
</button>
|
|
38
|
-
<h1 className="text-3xl font-bold bg-gradient-to-r from-blue-400 via-purple-400 to-pink-400 bg-clip-text text-transparent">
|
|
39
|
-
FluxStack Demos
|
|
40
|
-
</h1>
|
|
41
|
-
</div>
|
|
42
|
-
|
|
43
|
-
{/* Demo Content */}
|
|
44
|
-
<FileUploadExample />
|
|
45
|
-
</div>
|
|
46
|
-
</div>
|
|
47
|
-
)
|
|
33
|
+
const testHealthCheck = async () => {
|
|
34
|
+
setIsLoading(true)
|
|
35
|
+
try {
|
|
36
|
+
const { data, error } = await api.health.get()
|
|
37
|
+
setApiResponse(JSON.stringify(error ?? data, null, 2))
|
|
38
|
+
} catch (e) {
|
|
39
|
+
setApiResponse(`Error: ${e}`)
|
|
40
|
+
}
|
|
41
|
+
setIsLoading(false)
|
|
48
42
|
}
|
|
49
43
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
FluxStack
|
|
61
|
-
</h1>
|
|
62
|
-
|
|
63
|
-
{/* Subtitle */}
|
|
64
|
-
<p className="text-xl md:text-2xl text-gray-300 mb-8 max-w-2xl">
|
|
65
|
-
Full-stack TypeScript framework with{' '}
|
|
66
|
-
<span className="text-purple-400 font-semibold">Bun</span>,{' '}
|
|
67
|
-
<span className="text-blue-400 font-semibold">Elysia</span>, and{' '}
|
|
68
|
-
<span className="text-cyan-400 font-semibold">React</span>
|
|
69
|
-
</p>
|
|
70
|
-
|
|
71
|
-
{/* API Status Badge */}
|
|
72
|
-
<div className="mb-12">
|
|
73
|
-
<div className={`inline-flex items-center gap-2 px-4 py-2 rounded-full text-sm font-medium transition-all ${
|
|
74
|
-
apiStatus === 'online'
|
|
75
|
-
? 'bg-emerald-500/20 text-emerald-300 border border-emerald-500/30'
|
|
76
|
-
: apiStatus === 'offline'
|
|
77
|
-
? 'bg-red-500/20 text-red-300 border border-red-500/30'
|
|
78
|
-
: 'bg-yellow-500/20 text-yellow-300 border border-yellow-500/30'
|
|
79
|
-
}`}>
|
|
80
|
-
<div className={`w-2 h-2 rounded-full ${
|
|
81
|
-
apiStatus === 'online' ? 'bg-emerald-400' : apiStatus === 'offline' ? 'bg-red-400' : 'bg-yellow-400'
|
|
82
|
-
}`}></div>
|
|
83
|
-
<span>{apiStatus === 'checking' ? 'Checking API...' : apiStatus === 'online' ? 'API Online' : 'API Offline'}</span>
|
|
84
|
-
</div>
|
|
85
|
-
</div>
|
|
86
|
-
|
|
87
|
-
{/* Feature Cards */}
|
|
88
|
-
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-12 max-w-6xl">
|
|
89
|
-
<div className="bg-white/5 backdrop-blur-sm border border-white/10 rounded-2xl p-6 hover:bg-white/10 transition-all">
|
|
90
|
-
<div className="text-3xl mb-3">⚡</div>
|
|
91
|
-
<h3 className="text-lg font-semibold text-white mb-2">Ultra Rápido</h3>
|
|
92
|
-
<p className="text-gray-400 text-sm">Bun runtime 3x mais rápido que Node.js</p>
|
|
93
|
-
</div>
|
|
94
|
-
|
|
95
|
-
<div className="bg-white/5 backdrop-blur-sm border border-white/10 rounded-2xl p-6 hover:bg-white/10 transition-all">
|
|
96
|
-
<div className="text-3xl mb-3">🔒</div>
|
|
97
|
-
<h3 className="text-lg font-semibold text-white mb-2">Type Safe</h3>
|
|
98
|
-
<p className="text-gray-400 text-sm">Eden Treaty com inferência automática</p>
|
|
99
|
-
</div>
|
|
100
|
-
|
|
101
|
-
<div className="bg-white/5 backdrop-blur-sm border border-white/10 rounded-2xl p-6 hover:bg-white/10 transition-all">
|
|
102
|
-
<div className="text-3xl mb-3">🎨</div>
|
|
103
|
-
<h3 className="text-lg font-semibold text-white mb-2">Moderno</h3>
|
|
104
|
-
<p className="text-gray-400 text-sm">React 19 + Vite + Tailwind CSS</p>
|
|
105
|
-
</div>
|
|
106
|
-
|
|
107
|
-
{/* Live Clock Card */}
|
|
108
|
-
<div className="bg-white/5 backdrop-blur-sm border border-white/10 rounded-2xl p-6 hover:bg-white/10 transition-all">
|
|
109
|
-
<div className="flex items-center gap-3 mb-3">
|
|
110
|
-
<FaClock className="text-2xl text-emerald-400" />
|
|
111
|
-
<div>
|
|
112
|
-
<h3 className="text-lg font-semibold text-white">Live Clock</h3>
|
|
113
|
-
<p className="text-gray-400 text-sm">Provido via LiveComponent</p>
|
|
114
|
-
</div>
|
|
115
|
-
</div>
|
|
116
|
-
<MinimalLiveClock />
|
|
117
|
-
</div>
|
|
118
|
-
</div>
|
|
119
|
-
|
|
120
|
-
{/* Action Buttons */}
|
|
121
|
-
<div className="flex flex-wrap gap-4 justify-center">
|
|
122
|
-
<button
|
|
123
|
-
onClick={() => setShowDemo(true)}
|
|
124
|
-
className="inline-flex items-center gap-2 px-6 py-3 bg-gradient-to-r from-emerald-500 to-teal-600 text-white rounded-xl font-medium hover:shadow-lg hover:shadow-emerald-500/50 transition-all"
|
|
125
|
-
>
|
|
126
|
-
<FaImage />
|
|
127
|
-
View Demos
|
|
128
|
-
</button>
|
|
129
|
-
<a
|
|
130
|
-
href="/swagger"
|
|
131
|
-
target="_blank"
|
|
132
|
-
rel="noopener noreferrer"
|
|
133
|
-
className="inline-flex items-center gap-2 px-6 py-3 bg-gradient-to-r from-blue-500 to-purple-600 text-white rounded-xl font-medium hover:shadow-lg hover:shadow-purple-500/50 transition-all"
|
|
134
|
-
>
|
|
135
|
-
<FaBook />
|
|
136
|
-
API Docs
|
|
137
|
-
</a>
|
|
138
|
-
<a
|
|
139
|
-
href="https://github.com/MarcosBrendonDePaula/FluxStack"
|
|
140
|
-
target="_blank"
|
|
141
|
-
rel="noopener noreferrer"
|
|
142
|
-
className="inline-flex items-center gap-2 px-6 py-3 bg-white/10 backdrop-blur-sm border border-white/20 text-white rounded-xl font-medium hover:bg-white/20 transition-all"
|
|
143
|
-
>
|
|
144
|
-
<FaGithub />
|
|
145
|
-
GitHub
|
|
146
|
-
</a>
|
|
147
|
-
<a
|
|
148
|
-
href="/api"
|
|
149
|
-
target="_blank"
|
|
150
|
-
rel="noopener noreferrer"
|
|
151
|
-
className="inline-flex items-center gap-2 px-6 py-3 bg-white/10 backdrop-blur-sm border border-white/20 text-white rounded-xl font-medium hover:bg-white/20 transition-all"
|
|
152
|
-
>
|
|
153
|
-
🚀 API Root
|
|
154
|
-
</a>
|
|
155
|
-
</div>
|
|
44
|
+
const testGetUsers = async () => {
|
|
45
|
+
setIsLoading(true)
|
|
46
|
+
try {
|
|
47
|
+
const { data, error } = await api.users.get()
|
|
48
|
+
setApiResponse(JSON.stringify(error ?? data, null, 2))
|
|
49
|
+
} catch (e) {
|
|
50
|
+
setApiResponse(`Error: ${e}`)
|
|
51
|
+
}
|
|
52
|
+
setIsLoading(false)
|
|
53
|
+
}
|
|
156
54
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
55
|
+
const testCreateUser = async () => {
|
|
56
|
+
setIsLoading(true)
|
|
57
|
+
try {
|
|
58
|
+
const { data, error } = await api.users.post({
|
|
59
|
+
name: `Test User ${Date.now()}`,
|
|
60
|
+
email: `test${Date.now()}@example.com`
|
|
61
|
+
})
|
|
62
|
+
setApiResponse(JSON.stringify(error ?? data, null, 2))
|
|
63
|
+
} catch (e) {
|
|
64
|
+
setApiResponse(`Error: ${e}`)
|
|
65
|
+
}
|
|
66
|
+
setIsLoading(false)
|
|
67
|
+
}
|
|
162
68
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
69
|
+
return (
|
|
70
|
+
<Routes>
|
|
71
|
+
<Route element={<AppLayout />}>
|
|
72
|
+
<Route path="/" element={<HomePage apiStatus={apiStatus} />} />
|
|
73
|
+
<Route
|
|
74
|
+
path="/api-test"
|
|
75
|
+
element={
|
|
76
|
+
<ApiTestPage
|
|
77
|
+
apiResponse={apiResponse}
|
|
78
|
+
isLoading={isLoading}
|
|
79
|
+
onHealth={testHealthCheck}
|
|
80
|
+
onGetUsers={testGetUsers}
|
|
81
|
+
onCreateUser={testCreateUser}
|
|
82
|
+
/>
|
|
83
|
+
}
|
|
84
|
+
/>
|
|
85
|
+
<Route
|
|
86
|
+
path="/form"
|
|
87
|
+
element={
|
|
88
|
+
<DemoPage
|
|
89
|
+
note={<>? Este formul?rio usa <code className="text-purple-400">Live.use()</code> - cada campo sincroniza automaticamente com o servidor!</>}
|
|
90
|
+
>
|
|
91
|
+
<FormDemo />
|
|
92
|
+
</DemoPage>
|
|
93
|
+
}
|
|
94
|
+
/>
|
|
95
|
+
<Route
|
|
96
|
+
path="/counter"
|
|
97
|
+
element={
|
|
98
|
+
<DemoPage>
|
|
99
|
+
<CounterDemo />
|
|
100
|
+
</DemoPage>
|
|
101
|
+
}
|
|
102
|
+
/>
|
|
103
|
+
<Route
|
|
104
|
+
path="/upload"
|
|
105
|
+
element={
|
|
106
|
+
<DemoPage>
|
|
107
|
+
<UploadDemo />
|
|
108
|
+
</DemoPage>
|
|
109
|
+
}
|
|
110
|
+
/>
|
|
111
|
+
<Route
|
|
112
|
+
path="/chat"
|
|
113
|
+
element={
|
|
114
|
+
<DemoPage>
|
|
115
|
+
<ChatDemo />
|
|
116
|
+
</DemoPage>
|
|
117
|
+
}
|
|
118
|
+
/>
|
|
119
|
+
<Route
|
|
120
|
+
path="/room-chat"
|
|
121
|
+
element={
|
|
122
|
+
<DemoPage
|
|
123
|
+
note={<>🚀 Chat com múltiplas salas usando o novo sistema <code className="text-purple-400">$room</code>!</>}
|
|
124
|
+
>
|
|
125
|
+
<RoomChatDemo />
|
|
126
|
+
</DemoPage>
|
|
127
|
+
}
|
|
128
|
+
/>
|
|
129
|
+
<Route path="*" element={<HomePage apiStatus={apiStatus} />} />
|
|
130
|
+
</Route>
|
|
131
|
+
</Routes>
|
|
174
132
|
)
|
|
175
133
|
}
|
|
176
134
|
|
|
177
|
-
// Main App with LiveComponentsProvider
|
|
178
135
|
function App() {
|
|
179
136
|
return (
|
|
180
137
|
<LiveComponentsProvider
|