create-fluxstack 1.10.1 → 1.12.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/.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 +242 -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 +285 -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,297 @@
|
|
|
1
|
+
# Anti-Patterns
|
|
2
|
+
|
|
3
|
+
**Version:** 1.11.0 | **Updated:** 2025-02-08
|
|
4
|
+
|
|
5
|
+
## Quick Facts
|
|
6
|
+
|
|
7
|
+
- FluxStack has strict rules to maintain type safety and stability
|
|
8
|
+
- Violations break type inference, cause runtime errors, or introduce security issues
|
|
9
|
+
- Most issues stem from ignoring the core/app separation
|
|
10
|
+
|
|
11
|
+
## Core Directory Violations
|
|
12
|
+
|
|
13
|
+
### Never Modify `core/`
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
// ❌ NEVER do this
|
|
17
|
+
// Editing core/server/framework.ts
|
|
18
|
+
// Editing core/plugins/manager.ts
|
|
19
|
+
// Editing core/utils/config-schema.ts
|
|
20
|
+
|
|
21
|
+
// ✅ Use extension points instead
|
|
22
|
+
// Create plugins in plugins/
|
|
23
|
+
// Override configs in config/
|
|
24
|
+
// Add business logic in app/
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**Why**: `core/` is framework code. Changes break on updates and can't be merged upstream.
|
|
28
|
+
|
|
29
|
+
## Eden Treaty Anti-Patterns
|
|
30
|
+
|
|
31
|
+
### Never Wrap Eden Treaty
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
// ❌ WRONG - Wrapping breaks type inference
|
|
35
|
+
async function apiCall<T>(fn: () => Promise<any>): Promise<T> {
|
|
36
|
+
try {
|
|
37
|
+
const result = await fn()
|
|
38
|
+
return result.data as T // Type cast = lost inference
|
|
39
|
+
} catch (error) {
|
|
40
|
+
throw error
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const user = await apiCall<User>(() => api.users({ id: 1 }).get())
|
|
45
|
+
// user type is manually cast, not inferred
|
|
46
|
+
|
|
47
|
+
// ✅ CORRECT - Use Eden Treaty directly
|
|
48
|
+
const { data, error } = await api.users({ id: 1 }).get()
|
|
49
|
+
// data is automatically typed as UserResponse
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Why**: Eden Treaty's power is automatic type inference. Wrappers destroy this.
|
|
53
|
+
|
|
54
|
+
### Never Omit Response Schemas
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
// ❌ WRONG - No response schema
|
|
58
|
+
export const usersRoutes = new Elysia({ prefix: '/users' })
|
|
59
|
+
.get('/', () => {
|
|
60
|
+
return { users: [] } // Response type is 'unknown' in Eden
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
// ✅ CORRECT - Always define response schema
|
|
64
|
+
export const usersRoutes = new Elysia({ prefix: '/users' })
|
|
65
|
+
.get('/', () => {
|
|
66
|
+
return { users: [] }
|
|
67
|
+
}, {
|
|
68
|
+
response: t.Object({
|
|
69
|
+
users: t.Array(t.Object({
|
|
70
|
+
id: t.Number(),
|
|
71
|
+
name: t.String()
|
|
72
|
+
}))
|
|
73
|
+
})
|
|
74
|
+
})
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Why**: Response schemas enable type inference AND generate Swagger docs.
|
|
78
|
+
|
|
79
|
+
### Never Define Types Manually for API Responses
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
// ❌ WRONG - Manual type definitions
|
|
83
|
+
interface UserResponse {
|
|
84
|
+
id: number
|
|
85
|
+
name: string
|
|
86
|
+
}
|
|
87
|
+
const { data } = await api.users.get()
|
|
88
|
+
const users = data as UserResponse[] // Type assertion
|
|
89
|
+
|
|
90
|
+
// ✅ CORRECT - Let Eden Treaty infer types
|
|
91
|
+
const { data, error } = await api.users.get()
|
|
92
|
+
// TypeScript automatically knows data.users is User[]
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Configuration Anti-Patterns
|
|
96
|
+
|
|
97
|
+
### Never Use process.env Directly
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
// ❌ WRONG - No validation, no type safety
|
|
101
|
+
const port = process.env.PORT || 3000
|
|
102
|
+
const debug = process.env.DEBUG === 'true'
|
|
103
|
+
|
|
104
|
+
// ✅ CORRECT - Use config system
|
|
105
|
+
import { appConfig } from '@config/app.config'
|
|
106
|
+
const port = appConfig.port // number, validated
|
|
107
|
+
const debug = appConfig.debug // boolean, validated
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Never Hardcode Configuration
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
// ❌ WRONG - Hardcoded values
|
|
114
|
+
const corsOrigins = ['http://localhost:5173', 'https://myapp.com']
|
|
115
|
+
|
|
116
|
+
// ✅ CORRECT - Use environment-based config
|
|
117
|
+
import { serverConfig } from '@config/server.config'
|
|
118
|
+
const corsOrigins = serverConfig.cors.origins
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Never Mix Config Layers
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
// ❌ WRONG - Accessing system config from app code
|
|
125
|
+
import { systemConfig } from '@config/system.config'
|
|
126
|
+
console.log(systemConfig.framework.name) // Framework details in app
|
|
127
|
+
|
|
128
|
+
// ✅ CORRECT - Use appropriate config layer
|
|
129
|
+
import { appConfig } from '@config/app.config'
|
|
130
|
+
console.log(appConfig.name)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Import Path Anti-Patterns
|
|
134
|
+
|
|
135
|
+
### Never Use Deep Relative Imports
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
// ❌ WRONG - Brittle, hard to refactor
|
|
139
|
+
import { api } from '../../../lib/eden-api'
|
|
140
|
+
import type { User } from '../../../../shared/types'
|
|
141
|
+
|
|
142
|
+
// ✅ CORRECT - Use path aliases
|
|
143
|
+
import { api } from '@client/lib/eden-api'
|
|
144
|
+
import type { User } from '@shared/types'
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Never Import Core Internals
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
// ❌ WRONG - Internal implementation details
|
|
151
|
+
import { internalHelper } from '@core/framework/internal/utils'
|
|
152
|
+
|
|
153
|
+
// ✅ CORRECT - Use public exports only
|
|
154
|
+
import { publicUtil } from '@core/utils'
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Plugin Security Anti-Patterns
|
|
158
|
+
|
|
159
|
+
### Never Enable NPM Discovery Without Whitelist
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
# ❌ WRONG - All NPM plugins auto-loaded (dangerous!)
|
|
163
|
+
PLUGINS_DISCOVER_NPM=true
|
|
164
|
+
# No PLUGINS_ALLOWED set
|
|
165
|
+
|
|
166
|
+
# ✅ CORRECT - Whitelist required packages
|
|
167
|
+
PLUGINS_DISCOVER_NPM=true
|
|
168
|
+
PLUGINS_ALLOWED=fluxstack-plugin-auth,@acme/fplugin-payments
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Never Skip Plugin Auditing
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
# ❌ WRONG - Installing without audit
|
|
175
|
+
bun add some-random-plugin
|
|
176
|
+
|
|
177
|
+
# ✅ CORRECT - Use plugin:add with audit
|
|
178
|
+
bun run fluxstack plugin:add some-random-plugin
|
|
179
|
+
# Automatically audits before install
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Never Trust Plugin Config Blindly
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
// ❌ WRONG - Using unvalidated plugin config
|
|
186
|
+
const pluginConfig = await loadPluginConfig(pluginName)
|
|
187
|
+
database.connect(pluginConfig.connectionString) // Potential injection
|
|
188
|
+
|
|
189
|
+
// ✅ CORRECT - Validate with schema
|
|
190
|
+
const schema = {
|
|
191
|
+
connectionString: config.string('DB_URL', '', true)
|
|
192
|
+
}
|
|
193
|
+
const validatedConfig = defineConfig(schema)
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Route Definition Anti-Patterns
|
|
197
|
+
|
|
198
|
+
### Never Mix Business Logic in Routes
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
// ❌ WRONG - Database logic in route
|
|
202
|
+
export const usersRoutes = new Elysia({ prefix: '/users' })
|
|
203
|
+
.get('/', async () => {
|
|
204
|
+
const db = await connectDB()
|
|
205
|
+
const users = await db.query('SELECT * FROM users')
|
|
206
|
+
await db.close()
|
|
207
|
+
return { users }
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
// ✅ CORRECT - Use controller/service pattern
|
|
211
|
+
export const usersRoutes = new Elysia({ prefix: '/users' })
|
|
212
|
+
.get('/', async () => {
|
|
213
|
+
return await userController.list()
|
|
214
|
+
})
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Never Forget Error Handling
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
// ❌ WRONG - Unhandled errors
|
|
221
|
+
.post('/', async ({ body }) => {
|
|
222
|
+
const user = await createUser(body) // May throw
|
|
223
|
+
return { user }
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
// ✅ CORRECT - Handle errors properly
|
|
227
|
+
.post('/', async ({ body, error }) => {
|
|
228
|
+
try {
|
|
229
|
+
const user = await createUser(body)
|
|
230
|
+
return { success: true, user }
|
|
231
|
+
} catch (e) {
|
|
232
|
+
return error(400, { success: false, message: e.message })
|
|
233
|
+
}
|
|
234
|
+
})
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Testing Anti-Patterns
|
|
238
|
+
|
|
239
|
+
### Never Test Against Real API
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
// ❌ WRONG - Real API calls in tests
|
|
243
|
+
it('should fetch users', async () => {
|
|
244
|
+
const { data } = await api.users.get() // Hits real backend
|
|
245
|
+
expect(data.users).toBeDefined()
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
// ✅ CORRECT - Mock Eden Treaty
|
|
249
|
+
vi.mock('@client/lib/eden-api', () => ({
|
|
250
|
+
api: {
|
|
251
|
+
users: {
|
|
252
|
+
get: vi.fn().mockResolvedValue({
|
|
253
|
+
data: { users: [{ id: 1, name: 'Test' }] },
|
|
254
|
+
error: undefined
|
|
255
|
+
})
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}))
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## Build Anti-Patterns
|
|
262
|
+
|
|
263
|
+
### Never Import Dev Dependencies in Production
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
// ❌ WRONG - Conditional import that still bundles
|
|
267
|
+
import { DevTools } from 'react-devtools' // Always bundled
|
|
268
|
+
|
|
269
|
+
if (process.env.NODE_ENV === 'development') {
|
|
270
|
+
DevTools.init()
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// ✅ CORRECT - Dynamic import for dev-only
|
|
274
|
+
if (import.meta.env.DEV) {
|
|
275
|
+
const { DevTools } = await import('react-devtools')
|
|
276
|
+
DevTools.init()
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## Summary Table
|
|
281
|
+
|
|
282
|
+
| Anti-Pattern | Impact | Solution |
|
|
283
|
+
|-------------|--------|----------|
|
|
284
|
+
| Modifying `core/` | Update conflicts | Use plugins/app |
|
|
285
|
+
| Wrapping Eden Treaty | Lost type inference | Use directly |
|
|
286
|
+
| Missing response schemas | Unknown types | Always define schemas |
|
|
287
|
+
| Direct process.env | No validation | Use config system |
|
|
288
|
+
| Deep relative imports | Fragile paths | Use aliases |
|
|
289
|
+
| NPM plugins without whitelist | Security risk | Set PLUGINS_ALLOWED |
|
|
290
|
+
| Business logic in routes | Unmaintainable | Use controllers |
|
|
291
|
+
|
|
292
|
+
## Related
|
|
293
|
+
|
|
294
|
+
- [Project Structure](./project-structure.md)
|
|
295
|
+
- [Type Safety](./type-safety.md)
|
|
296
|
+
- [Plugin Security](../core/plugin-system.md)
|
|
297
|
+
- [Routes with Eden Treaty](../resources/routes-eden.md)
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
# Project Structure
|
|
2
|
+
|
|
3
|
+
**Version:** 1.11.0 | **Updated:** 2025-02-08
|
|
4
|
+
|
|
5
|
+
## Quick Facts
|
|
6
|
+
|
|
7
|
+
- `core/` is **read-only** framework code - NEVER modify
|
|
8
|
+
- `app/` contains all user application code
|
|
9
|
+
- `config/` holds declarative configuration files
|
|
10
|
+
- `plugins/` is for external plugin development
|
|
11
|
+
- Path aliases simplify imports across the project
|
|
12
|
+
|
|
13
|
+
## Directory Organization
|
|
14
|
+
|
|
15
|
+
### core/ - Framework Code (READ-ONLY)
|
|
16
|
+
|
|
17
|
+
**Rule:** NEVER modify files in `core/`
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
core/
|
|
21
|
+
├── framework/ # Core framework server and lifecycle
|
|
22
|
+
├── plugins/ # Plugin system (manager, registry, types)
|
|
23
|
+
├── server/ # Server utilities (live components, middleware)
|
|
24
|
+
├── client/ # Client-side framework utilities
|
|
25
|
+
├── build/ # Build system and bundling
|
|
26
|
+
├── cli/ # CLI commands and generators
|
|
27
|
+
├── utils/ # Framework utilities
|
|
28
|
+
├── types/ # Framework type definitions
|
|
29
|
+
└── templates/ # Code generation templates
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Why read-only?**
|
|
33
|
+
- Framework updates would overwrite your changes
|
|
34
|
+
- Breaking changes could occur on version upgrades
|
|
35
|
+
- Customization should happen through plugins or app code
|
|
36
|
+
|
|
37
|
+
**What to do instead:**
|
|
38
|
+
- Create plugins in `plugins/` for framework extensions
|
|
39
|
+
- Override behavior using plugin hooks
|
|
40
|
+
- Implement custom logic in `app/`
|
|
41
|
+
|
|
42
|
+
### app/ - Application Code (MODIFY HERE)
|
|
43
|
+
|
|
44
|
+
**Rule:** All your application code goes here
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
app/
|
|
48
|
+
├── server/ # Backend code
|
|
49
|
+
│ ├── routes/ # API route definitions (Eden Treaty)
|
|
50
|
+
│ ├── controllers/# Business logic and services
|
|
51
|
+
│ ├── live/ # Live component implementations
|
|
52
|
+
│ ├── websockets/ # WebSocket handlers
|
|
53
|
+
│ ├── utils/ # Server-side utilities
|
|
54
|
+
│ ├── app.ts # Elysia app configuration
|
|
55
|
+
│ └── index.ts # Server entrypoint
|
|
56
|
+
├── client/ # Frontend code
|
|
57
|
+
│ ├── src/ # React application source
|
|
58
|
+
│ │ ├── components/ # React components
|
|
59
|
+
│ │ ├── pages/ # Page components
|
|
60
|
+
│ │ ├── hooks/ # Custom React hooks
|
|
61
|
+
│ │ ├── stores/ # State management (Zustand)
|
|
62
|
+
│ │ ├── utils/ # Client-side utilities
|
|
63
|
+
│ │ ├── App.tsx # Root component
|
|
64
|
+
│ │ └── main.tsx # React entrypoint
|
|
65
|
+
│ ├── public/ # Static assets
|
|
66
|
+
│ └── index.html # HTML template
|
|
67
|
+
└── shared/ # Shared code between client and server
|
|
68
|
+
└── types/ # Shared TypeScript types
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**Organization principles:**
|
|
72
|
+
- **server/routes/**: Define API endpoints with schemas
|
|
73
|
+
- **server/controllers/**: Implement business logic (keep routes thin)
|
|
74
|
+
- **client/src/**: All React code and frontend logic
|
|
75
|
+
- **shared/types/**: Types used by both frontend and backend
|
|
76
|
+
|
|
77
|
+
### config/ - Configuration Files
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
config/
|
|
81
|
+
├── system/ # Framework system configs (rarely modified)
|
|
82
|
+
│ ├── app.config.ts
|
|
83
|
+
│ ├── server.config.ts
|
|
84
|
+
│ ├── client.config.ts
|
|
85
|
+
│ ├── build.config.ts
|
|
86
|
+
│ ├── plugins.config.ts
|
|
87
|
+
│ └── ...
|
|
88
|
+
├── app.config.ts # Application-specific config
|
|
89
|
+
├── server.config.ts # Server configuration
|
|
90
|
+
├── client.config.ts # Client configuration
|
|
91
|
+
├── database.config.ts # Database configuration
|
|
92
|
+
├── plugins.config.ts # Plugin configuration
|
|
93
|
+
└── index.ts # Config aggregator
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Two-tier system:**
|
|
97
|
+
- `config/system/`: Framework defaults (use `defineConfig`)
|
|
98
|
+
- `config/*.config.ts`: User overrides and custom configs
|
|
99
|
+
|
|
100
|
+
**Best practices:**
|
|
101
|
+
- Override system configs by creating same-named file in `config/`
|
|
102
|
+
- Use `defineConfig` for type safety and validation
|
|
103
|
+
- Keep sensitive values in environment variables
|
|
104
|
+
|
|
105
|
+
### plugins/ - External Plugins
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
plugins/
|
|
109
|
+
└── your-plugin/
|
|
110
|
+
├── index.ts # Plugin entrypoint
|
|
111
|
+
├── server/ # Server-side plugin code
|
|
112
|
+
├── client/ # Client-side plugin code
|
|
113
|
+
└── package.json # Plugin metadata
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**When to create a plugin:**
|
|
117
|
+
- Reusable functionality across projects
|
|
118
|
+
- Framework extensions (new hooks, middleware)
|
|
119
|
+
- Third-party integrations
|
|
120
|
+
- Shareable with community
|
|
121
|
+
|
|
122
|
+
**When NOT to use plugins:**
|
|
123
|
+
- Application-specific business logic → use `app/`
|
|
124
|
+
- Simple utilities → use `app/server/utils/` or `app/client/utils/`
|
|
125
|
+
|
|
126
|
+
## File Naming Conventions
|
|
127
|
+
|
|
128
|
+
### General Rules
|
|
129
|
+
|
|
130
|
+
- **kebab-case** for directories: `user-management/`, `auth-service/`
|
|
131
|
+
- **kebab-case** for files: `user-controller.ts`, `auth-utils.ts`
|
|
132
|
+
- **PascalCase** for React components: `UserProfile.tsx`, `LoginForm.tsx`
|
|
133
|
+
- **camelCase** for utility files: `formatDate.ts`, `apiClient.ts`
|
|
134
|
+
|
|
135
|
+
### Specific Patterns
|
|
136
|
+
|
|
137
|
+
**Routes:**
|
|
138
|
+
```
|
|
139
|
+
app/server/routes/
|
|
140
|
+
├── users.ts # /users endpoints
|
|
141
|
+
├── auth.ts # /auth endpoints
|
|
142
|
+
└── admin/
|
|
143
|
+
└── dashboard.ts # /admin/dashboard endpoints
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Controllers:**
|
|
147
|
+
```
|
|
148
|
+
app/server/controllers/
|
|
149
|
+
├── UserController.ts
|
|
150
|
+
├── AuthController.ts
|
|
151
|
+
└── services/
|
|
152
|
+
├── UserService.ts
|
|
153
|
+
└── AuthService.ts
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**React Components:**
|
|
157
|
+
```
|
|
158
|
+
app/client/src/components/
|
|
159
|
+
├── UserProfile.tsx
|
|
160
|
+
├── LoginForm.tsx
|
|
161
|
+
└── common/
|
|
162
|
+
├── Button.tsx
|
|
163
|
+
└── Input.tsx
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Types:**
|
|
167
|
+
```
|
|
168
|
+
app/shared/types/
|
|
169
|
+
├── user.types.ts
|
|
170
|
+
├── auth.types.ts
|
|
171
|
+
└── api.types.ts
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Import Path Aliases
|
|
175
|
+
|
|
176
|
+
**Configured in `tsconfig.json`:**
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
{
|
|
180
|
+
"paths": {
|
|
181
|
+
"@core/*": ["./core/*"], // Framework code
|
|
182
|
+
"@app/*": ["./app/*"], // Application root
|
|
183
|
+
"@server/*": ["./app/server/*"], // Server code
|
|
184
|
+
"@client/*": ["./app/client/*"], // Client code
|
|
185
|
+
"@shared/*": ["./app/shared/*"], // Shared code
|
|
186
|
+
"@config": ["./config/index.ts"], // Config aggregator
|
|
187
|
+
"@config/*": ["./config/*"] // Individual configs
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Usage Examples
|
|
193
|
+
|
|
194
|
+
**Server-side imports:**
|
|
195
|
+
```typescript
|
|
196
|
+
// ✅ Good - Use aliases
|
|
197
|
+
import { UserController } from '@server/controllers/UserController'
|
|
198
|
+
import { UserType } from '@shared/types/user.types'
|
|
199
|
+
import { serverConfig } from '@config'
|
|
200
|
+
|
|
201
|
+
// ❌ Bad - Relative paths
|
|
202
|
+
import { UserController } from '../../server/controllers/UserController'
|
|
203
|
+
import { UserType } from '../../../shared/types/user.types'
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
**Client-side imports:**
|
|
207
|
+
```typescript
|
|
208
|
+
// ✅ Good - Use aliases
|
|
209
|
+
import { UserProfile } from '@client/components/UserProfile'
|
|
210
|
+
import { useAuth } from '@client/hooks/useAuth'
|
|
211
|
+
import { UserType } from '@shared/types/user.types'
|
|
212
|
+
|
|
213
|
+
// ❌ Bad - Relative paths
|
|
214
|
+
import { UserProfile } from '../components/UserProfile'
|
|
215
|
+
import { useAuth } from '../../hooks/useAuth'
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
**Plugin imports:**
|
|
219
|
+
```typescript
|
|
220
|
+
// ✅ Good - Import from core for plugin development
|
|
221
|
+
import type { FluxStackPlugin } from '@core/types/plugin.types'
|
|
222
|
+
import { logger } from '@core/utils/logger'
|
|
223
|
+
|
|
224
|
+
// ✅ Good - Import app code if needed
|
|
225
|
+
import { UserType } from '@shared/types/user.types'
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Alias Rules
|
|
229
|
+
|
|
230
|
+
1. **Always use aliases** for cross-directory imports
|
|
231
|
+
2. **Relative paths OK** for same-directory imports: `./utils`, `./types`
|
|
232
|
+
3. **Never import from `core/`** in app code (except types)
|
|
233
|
+
4. **Use `@shared/*`** for code used by both client and server
|
|
234
|
+
|
|
235
|
+
## Common Patterns
|
|
236
|
+
|
|
237
|
+
### Creating a New Feature
|
|
238
|
+
|
|
239
|
+
1. **Define types** in `app/shared/types/feature.types.ts`
|
|
240
|
+
2. **Create route** in `app/server/routes/feature.ts`
|
|
241
|
+
3. **Implement controller** in `app/server/controllers/FeatureController.ts`
|
|
242
|
+
4. **Build UI** in `app/client/src/pages/FeaturePage.tsx`
|
|
243
|
+
5. **Use Eden Treaty** in client to call API with type safety
|
|
244
|
+
|
|
245
|
+
### Adding Configuration
|
|
246
|
+
|
|
247
|
+
1. **Create config file** in `config/feature.config.ts`
|
|
248
|
+
2. **Use `defineConfig`** for schema and validation
|
|
249
|
+
3. **Export from** `config/index.ts`
|
|
250
|
+
4. **Import with** `@config` alias
|
|
251
|
+
|
|
252
|
+
### Creating a Plugin
|
|
253
|
+
|
|
254
|
+
1. **Create directory** in `plugins/my-plugin/`
|
|
255
|
+
2. **Implement interface** from `@core/types/plugin.types`
|
|
256
|
+
3. **Add to whitelist** in `config/plugins.config.ts`
|
|
257
|
+
4. **Framework auto-discovers** on startup
|
|
258
|
+
|
|
259
|
+
## Related
|
|
260
|
+
|
|
261
|
+
- [Type Safety Patterns](./type-safety.md)
|
|
262
|
+
- [Anti-Patterns](./anti-patterns.md)
|
|
263
|
+
- [Plugin Development](../resources/plugins-external.md)
|
|
264
|
+
- [Configuration System](../config/declarative-system.md)
|