create-fluxstack 1.18.1 → 1.20.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/CHANGELOG.md +132 -0
- package/LLMD/INDEX.md +1 -1
- package/LLMD/MAINTENANCE.md +197 -197
- package/LLMD/MIGRATION.md +44 -1
- package/LLMD/agent.md +20 -7
- package/LLMD/config/declarative-system.md +268 -268
- package/LLMD/config/environment-vars.md +3 -6
- package/LLMD/config/runtime-reload.md +401 -401
- package/LLMD/core/build-system.md +599 -599
- package/LLMD/core/framework-lifecycle.md +249 -229
- package/LLMD/core/plugin-system.md +154 -100
- package/LLMD/patterns/anti-patterns.md +397 -397
- package/LLMD/patterns/project-structure.md +264 -264
- package/LLMD/patterns/type-safety.md +61 -5
- package/LLMD/reference/cli-commands.md +31 -7
- package/LLMD/reference/plugin-hooks.md +4 -2
- package/LLMD/reference/troubleshooting.md +364 -364
- package/LLMD/resources/controllers.md +465 -465
- package/LLMD/resources/live-auth.md +178 -1
- package/LLMD/resources/live-binary-delta.md +3 -1
- package/LLMD/resources/live-components.md +1192 -1041
- package/LLMD/resources/live-logging.md +3 -1
- package/LLMD/resources/live-rooms.md +1 -1
- package/LLMD/resources/live-upload.md +228 -181
- package/LLMD/resources/plugins-external.md +8 -7
- package/LLMD/resources/rest-auth.md +290 -290
- package/LLMD/resources/routes-eden.md +254 -254
- package/app/client/src/App.tsx +7 -7
- package/app/client/src/components/AppLayout.tsx +60 -23
- package/app/client/src/components/ColorWheel.tsx +195 -0
- package/app/client/src/components/DemoPage.tsx +5 -3
- package/app/client/src/components/LiveUploadWidget.tsx +1 -1
- package/app/client/src/components/ThemePicker.tsx +307 -0
- package/app/client/src/config/theme.config.ts +127 -0
- package/app/client/src/hooks/useThemeClock.ts +66 -0
- package/app/client/src/index.css +193 -0
- package/app/client/src/lib/theme-clock.ts +201 -0
- package/app/client/src/live/AuthDemo.tsx +9 -9
- package/app/client/src/live/CounterDemo.tsx +10 -10
- package/app/client/src/live/FormDemo.tsx +8 -8
- package/app/client/src/live/PingPongDemo.tsx +10 -10
- package/app/client/src/live/RoomChatDemo.tsx +10 -10
- package/app/client/src/live/SharedCounterDemo.tsx +5 -5
- package/app/client/src/pages/ApiTestPage.tsx +5 -5
- package/app/client/src/pages/HomePage.tsx +12 -12
- package/app/server/index.ts +8 -0
- package/app/server/live/auto-generated-components.ts +1 -1
- package/core/build/index.ts +1 -1
- package/core/cli/command-registry.ts +1 -1
- package/core/cli/commands/build.ts +25 -6
- package/core/cli/commands/plugin-deps.ts +1 -2
- package/core/cli/generators/plugin.ts +433 -581
- package/core/framework/server.ts +22 -8
- package/core/index.ts +6 -5
- package/core/plugins/index.ts +71 -199
- package/core/plugins/types.ts +76 -461
- package/core/server/index.ts +1 -1
- package/core/utils/logger/startup-banner.ts +26 -4
- package/create-fluxstack.ts +216 -107
- package/package.json +108 -107
- package/tsconfig.json +2 -1
- package/core/plugins/config.ts +0 -356
- package/core/plugins/dependency-manager.ts +0 -481
- package/core/plugins/discovery.ts +0 -379
- package/core/plugins/executor.ts +0 -353
- package/core/plugins/manager.ts +0 -645
- package/core/plugins/module-resolver.ts +0 -227
- package/core/plugins/registry.ts +0 -913
- package/vitest.config.live.ts +0 -69
|
@@ -1,264 +1,264 @@
|
|
|
1
|
-
# Project Structure
|
|
2
|
-
|
|
3
|
-
**Version:** 1.
|
|
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)
|
|
1
|
+
# Project Structure
|
|
2
|
+
|
|
3
|
+
**Version:** 1.19.0 | **Updated:** 2026-04-14
|
|
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)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Type Safety Patterns
|
|
2
2
|
|
|
3
|
-
**Version:** 1.
|
|
3
|
+
**Version:** 1.19.0 | **Updated:** 2026-04-14
|
|
4
4
|
|
|
5
5
|
## Quick Facts
|
|
6
6
|
|
|
@@ -65,18 +65,22 @@ export const usersRoutes = new Elysia({ prefix: '/users' })
|
|
|
65
65
|
**Step 2: Use Eden Treaty client**
|
|
66
66
|
|
|
67
67
|
```typescript
|
|
68
|
-
// app/client/src/lib/api.ts
|
|
69
|
-
import { createEdenClient } from '
|
|
68
|
+
// app/client/src/lib/eden-api.ts
|
|
69
|
+
import { createEdenClient, getErrorMessage } from '@/core/client/api'
|
|
70
70
|
import type { App } from '@server/app'
|
|
71
71
|
|
|
72
|
-
export const api = createEdenClient<App>(
|
|
72
|
+
export const api = createEdenClient<App>({
|
|
73
|
+
// Optional customization: tokenKey, getAuthToken, onUnauthorized, getBaseUrl, enableLogging
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
export { getErrorMessage }
|
|
73
77
|
```
|
|
74
78
|
|
|
75
79
|
**Step 3: Make typed API calls**
|
|
76
80
|
|
|
77
81
|
```typescript
|
|
78
82
|
// app/client/src/pages/UsersPage.tsx
|
|
79
|
-
import { api } from '@/lib/api'
|
|
83
|
+
import { api } from '@/lib/eden-api'
|
|
80
84
|
|
|
81
85
|
async function loadUsers() {
|
|
82
86
|
const { data, error } = await api.users.get()
|
|
@@ -215,6 +219,58 @@ const { data } = await api.users.get({
|
|
|
215
219
|
// ^? { users: User[], page: number, limit: number, total: number } | undefined
|
|
216
220
|
```
|
|
217
221
|
|
|
222
|
+
### Discriminated Union with t.Union
|
|
223
|
+
|
|
224
|
+
The real codebase uses `t.Union` for routes that return different shapes depending on success/failure. See `app/server/routes/users.routes.ts` for the canonical example:
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
// Backend — discriminated union response schema
|
|
228
|
+
const CreateUserResponseSchema = t.Union([
|
|
229
|
+
t.Object({
|
|
230
|
+
success: t.Literal(true),
|
|
231
|
+
user: UserSchema,
|
|
232
|
+
message: t.Optional(t.String())
|
|
233
|
+
}),
|
|
234
|
+
t.Object({
|
|
235
|
+
success: t.Literal(false),
|
|
236
|
+
error: t.String()
|
|
237
|
+
})
|
|
238
|
+
], {
|
|
239
|
+
description: 'Response after attempting to create a user'
|
|
240
|
+
})
|
|
241
|
+
|
|
242
|
+
// Route with per-status-code responses
|
|
243
|
+
.post('/', async ({ body, set }) => {
|
|
244
|
+
const result = await UsersController.createUser(body)
|
|
245
|
+
if (!result.success) {
|
|
246
|
+
set.status = 409
|
|
247
|
+
return result
|
|
248
|
+
}
|
|
249
|
+
set.status = 201
|
|
250
|
+
return result
|
|
251
|
+
}, {
|
|
252
|
+
body: CreateUserRequestSchema,
|
|
253
|
+
response: {
|
|
254
|
+
201: CreateUserResponseSchema,
|
|
255
|
+
400: t.Object({ success: t.Literal(false), error: t.String() }),
|
|
256
|
+
409: t.Object({ success: t.Literal(false), error: t.String() })
|
|
257
|
+
}
|
|
258
|
+
})
|
|
259
|
+
|
|
260
|
+
// Frontend — TypeScript narrows via the discriminant field
|
|
261
|
+
const { data, error } = await api.users.post({
|
|
262
|
+
name: 'Jane', email: 'jane@example.com'
|
|
263
|
+
})
|
|
264
|
+
|
|
265
|
+
if (data?.success) {
|
|
266
|
+
console.log(data.user.name) // TS knows `user` exists
|
|
267
|
+
} else if (data) {
|
|
268
|
+
console.error(data.error) // TS knows `error` exists
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
**Key takeaway:** Define `t.Union([...])` at the schema level (not just multiple status codes) so Eden Treaty infers a proper discriminated union type on the client. Use `t.Literal(true)` / `t.Literal(false)` on a shared field (like `success`) so TypeScript can narrow the type with a simple `if` check.
|
|
273
|
+
|
|
218
274
|
## Shared Types
|
|
219
275
|
|
|
220
276
|
For types used across client and server, define in `app/shared/types/`:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# CLI Commands Reference
|
|
2
2
|
|
|
3
|
-
**Version:** 1.
|
|
3
|
+
**Version:** 1.19.0 | **Updated:** 2026-04-14
|
|
4
4
|
|
|
5
5
|
## Quick Facts
|
|
6
6
|
|
|
@@ -227,12 +227,36 @@ bun run flux help generate
|
|
|
227
227
|
Standard npm scripts in `package.json`:
|
|
228
228
|
|
|
229
229
|
```bash
|
|
230
|
-
|
|
231
|
-
bun run
|
|
232
|
-
bun run
|
|
233
|
-
bun run
|
|
234
|
-
|
|
235
|
-
|
|
230
|
+
# Development
|
|
231
|
+
bun run dev # Full-stack dev (backend + frontend)
|
|
232
|
+
bun run dev:frontend # Frontend only (Vite, port 5173)
|
|
233
|
+
bun run dev:backend # Backend only (Elysia)
|
|
234
|
+
|
|
235
|
+
# Build
|
|
236
|
+
bun run build # Full production build (frontend + backend)
|
|
237
|
+
bun run build:frontend # Frontend build only
|
|
238
|
+
bun run build:backend # Backend build only
|
|
239
|
+
bun run build:exe # Build + compile to executable
|
|
240
|
+
|
|
241
|
+
# Production
|
|
242
|
+
bun run start # NODE_ENV=production bun dist/index.js
|
|
243
|
+
|
|
244
|
+
# Testing
|
|
245
|
+
bun run test # vitest (watch mode)
|
|
246
|
+
bun run test:ui # vitest with browser UI (--ui)
|
|
247
|
+
bun run test:coverage # vitest run with coverage report
|
|
248
|
+
bun run test:e2e # Playwright end-to-end tests
|
|
249
|
+
bun run test:e2e:ui # Playwright with interactive UI
|
|
250
|
+
bun run test:e2e:headed # Playwright in headed browser mode
|
|
251
|
+
|
|
252
|
+
# Code Quality
|
|
253
|
+
bun run typecheck:api # Type-check API routes (tsconfig.api-strict.json)
|
|
254
|
+
|
|
255
|
+
# Generators & Utilities
|
|
256
|
+
bun run make:component # Scaffold a new component via CLI
|
|
257
|
+
bun run sync-version # Sync version across package.json and version.ts
|
|
258
|
+
bun run cli # Direct access to FluxStack CLI
|
|
259
|
+
bun run create # Create new FluxStack project
|
|
236
260
|
```
|
|
237
261
|
|
|
238
262
|
## Environment Variables for CLI
|