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,617 @@
|
|
|
1
|
+
# External Plugins
|
|
2
|
+
|
|
3
|
+
**Version:** 1.11.0 | **Updated:** 2025-02-08
|
|
4
|
+
|
|
5
|
+
## Quick Facts
|
|
6
|
+
|
|
7
|
+
- Plugins extend FluxStack with custom functionality
|
|
8
|
+
- Located in `plugins/[plugin-name]/` directory
|
|
9
|
+
- Use lifecycle hooks for integration
|
|
10
|
+
- Support declarative configuration system
|
|
11
|
+
- Can add CLI commands, routes, and middleware
|
|
12
|
+
- Auto-discovered and loaded at startup
|
|
13
|
+
|
|
14
|
+
## Plugin Structure
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
plugins/my-plugin/
|
|
18
|
+
├── index.ts # Main plugin file (required)
|
|
19
|
+
├── package.json # Plugin metadata
|
|
20
|
+
├── config/
|
|
21
|
+
│ └── index.ts # Plugin configuration
|
|
22
|
+
├── server/
|
|
23
|
+
│ ├── index.ts # Server-side code
|
|
24
|
+
│ └── middleware.ts # Middleware
|
|
25
|
+
├── client/
|
|
26
|
+
│ └── index.ts # Client-side code
|
|
27
|
+
└── cli/
|
|
28
|
+
└── commands.ts # CLI commands
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Basic Plugin Template
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
// plugins/my-plugin/index.ts
|
|
35
|
+
import type { FluxStack, PluginContext } from "@core/plugins/types"
|
|
36
|
+
import { Elysia } from "elysia"
|
|
37
|
+
|
|
38
|
+
export const myPlugin: FluxStack.Plugin = {
|
|
39
|
+
name: "my-plugin",
|
|
40
|
+
version: "1.0.0",
|
|
41
|
+
description: "My custom plugin",
|
|
42
|
+
author: "Your Name",
|
|
43
|
+
priority: 100,
|
|
44
|
+
category: "utility",
|
|
45
|
+
tags: ["custom", "utility"],
|
|
46
|
+
dependencies: [],
|
|
47
|
+
|
|
48
|
+
setup: async (context: PluginContext) => {
|
|
49
|
+
context.logger.info('My plugin initialized')
|
|
50
|
+
|
|
51
|
+
// Initialize plugin services
|
|
52
|
+
// Register middleware
|
|
53
|
+
// Setup database connections
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
onServerStart: async (context: PluginContext) => {
|
|
57
|
+
context.logger.info('Server started with my plugin')
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
onRequest: async (requestContext) => {
|
|
61
|
+
// Process incoming requests
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
onResponse: async (responseContext) => {
|
|
65
|
+
// Process outgoing responses
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export default myPlugin
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Plugin Interface
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
interface Plugin {
|
|
76
|
+
// Metadata
|
|
77
|
+
name: string
|
|
78
|
+
version?: string
|
|
79
|
+
description?: string
|
|
80
|
+
author?: string
|
|
81
|
+
dependencies?: string[]
|
|
82
|
+
priority?: number | 'highest' | 'high' | 'normal' | 'low' | 'lowest'
|
|
83
|
+
category?: string
|
|
84
|
+
tags?: string[]
|
|
85
|
+
|
|
86
|
+
// Lifecycle hooks
|
|
87
|
+
setup?: (context: PluginContext) => void | Promise<void>
|
|
88
|
+
onConfigLoad?: (context: ConfigLoadContext) => void | Promise<void>
|
|
89
|
+
onBeforeServerStart?: (context: PluginContext) => void | Promise<void>
|
|
90
|
+
onServerStart?: (context: PluginContext) => void | Promise<void>
|
|
91
|
+
onAfterServerStart?: (context: PluginContext) => void | Promise<void>
|
|
92
|
+
onBeforeServerStop?: (context: PluginContext) => void | Promise<void>
|
|
93
|
+
onServerStop?: (context: PluginContext) => void | Promise<void>
|
|
94
|
+
|
|
95
|
+
// Request/Response hooks
|
|
96
|
+
onRequest?: (context: RequestContext) => void | Promise<void>
|
|
97
|
+
onBeforeRoute?: (context: RequestContext) => void | Promise<void>
|
|
98
|
+
onAfterRoute?: (context: RouteContext) => void | Promise<void>
|
|
99
|
+
onBeforeResponse?: (context: ResponseContext) => void | Promise<void>
|
|
100
|
+
onResponse?: (context: ResponseContext) => void | Promise<void>
|
|
101
|
+
onRequestValidation?: (context: ValidationContext) => void | Promise<void>
|
|
102
|
+
onResponseTransform?: (context: TransformContext) => void | Promise<void>
|
|
103
|
+
|
|
104
|
+
// Error handling
|
|
105
|
+
onError?: (context: ErrorContext) => void | Promise<void>
|
|
106
|
+
|
|
107
|
+
// Build hooks
|
|
108
|
+
onBeforeBuild?: (context: BuildContext) => void | Promise<void>
|
|
109
|
+
onBuild?: (context: BuildContext) => void | Promise<void>
|
|
110
|
+
onBuildComplete?: (context: BuildContext) => void | Promise<void>
|
|
111
|
+
onBuildError?: (context: BuildErrorContext) => void | Promise<void>
|
|
112
|
+
|
|
113
|
+
// CLI commands
|
|
114
|
+
commands?: CliCommand[]
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Lifecycle Hooks
|
|
119
|
+
|
|
120
|
+
### setup
|
|
121
|
+
|
|
122
|
+
Called during plugin initialization, before server starts:
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
setup: async (context: PluginContext) => {
|
|
126
|
+
// Initialize services
|
|
127
|
+
const service = new MyService(context.config)
|
|
128
|
+
|
|
129
|
+
// Store in global for access in other hooks
|
|
130
|
+
;(global as any).myService = service
|
|
131
|
+
|
|
132
|
+
// Register with plugin registry
|
|
133
|
+
context.logger.info('Plugin initialized')
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### onServerStart
|
|
138
|
+
|
|
139
|
+
Called when server starts:
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
onServerStart: async (context: PluginContext) => {
|
|
143
|
+
context.logger.info('Server started')
|
|
144
|
+
|
|
145
|
+
// Start background tasks
|
|
146
|
+
// Connect to external services
|
|
147
|
+
// Initialize monitoring
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### onRequest
|
|
152
|
+
|
|
153
|
+
Process incoming requests:
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
onRequest: async (requestContext) => {
|
|
157
|
+
// Log request
|
|
158
|
+
console.log(`${requestContext.method} ${requestContext.path}`)
|
|
159
|
+
|
|
160
|
+
// Add custom headers
|
|
161
|
+
requestContext.headers['x-custom'] = 'value'
|
|
162
|
+
|
|
163
|
+
// Authenticate user
|
|
164
|
+
const user = await authenticateRequest(requestContext)
|
|
165
|
+
requestContext.user = user
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### onResponse
|
|
170
|
+
|
|
171
|
+
Process outgoing responses:
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
onResponse: async (responseContext) => {
|
|
175
|
+
// Log response
|
|
176
|
+
console.log(`${responseContext.statusCode} - ${responseContext.duration}ms`)
|
|
177
|
+
|
|
178
|
+
// Track metrics
|
|
179
|
+
if (responseContext.user) {
|
|
180
|
+
trackUserActivity(responseContext.user, responseContext.path)
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### onError
|
|
186
|
+
|
|
187
|
+
Handle errors:
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
onError: async (errorContext) => {
|
|
191
|
+
// Log error
|
|
192
|
+
console.error('Request error:', errorContext.error)
|
|
193
|
+
|
|
194
|
+
// Send to error tracking service
|
|
195
|
+
await sendToSentry(errorContext.error)
|
|
196
|
+
|
|
197
|
+
// Mark as handled to prevent default error handler
|
|
198
|
+
errorContext.handled = true
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Plugin Configuration
|
|
203
|
+
|
|
204
|
+
Use declarative config system:
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
// plugins/my-plugin/config/index.ts
|
|
208
|
+
import { defineConfig, config } from '@core/utils/config-schema'
|
|
209
|
+
|
|
210
|
+
const myPluginConfigSchema = {
|
|
211
|
+
enabled: config.boolean('MY_PLUGIN_ENABLED', true),
|
|
212
|
+
apiKey: config.string('MY_PLUGIN_API_KEY', '', true), // required
|
|
213
|
+
timeout: config.number('MY_PLUGIN_TIMEOUT', 5000, false),
|
|
214
|
+
features: config.array('MY_PLUGIN_FEATURES', ['feature1', 'feature2'])
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export const myPluginConfig = defineConfig(myPluginConfigSchema)
|
|
218
|
+
export type MyPluginConfig = typeof myPluginConfig
|
|
219
|
+
export default myPluginConfig
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Use in plugin:
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
// plugins/my-plugin/index.ts
|
|
226
|
+
import { myPluginConfig } from "./config"
|
|
227
|
+
|
|
228
|
+
export const myPlugin: FluxStack.Plugin = {
|
|
229
|
+
name: "my-plugin",
|
|
230
|
+
|
|
231
|
+
setup: async (context) => {
|
|
232
|
+
if (!myPluginConfig.enabled) {
|
|
233
|
+
context.logger.info('Plugin disabled')
|
|
234
|
+
return
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const service = new MyService({
|
|
238
|
+
apiKey: myPluginConfig.apiKey,
|
|
239
|
+
timeout: myPluginConfig.timeout
|
|
240
|
+
})
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## Adding Routes (Elysia Plugin)
|
|
246
|
+
|
|
247
|
+
Plugins can add routes using Elysia:
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
import { Elysia, t } from "elysia"
|
|
251
|
+
|
|
252
|
+
export const myPlugin: FluxStack.Plugin = {
|
|
253
|
+
name: "my-plugin",
|
|
254
|
+
|
|
255
|
+
// @ts-ignore - plugin property supported but not in official types
|
|
256
|
+
plugin: new Elysia({ prefix: "/api/my-plugin", tags: ['MyPlugin'] })
|
|
257
|
+
.get("/status", () => ({
|
|
258
|
+
status: "ok",
|
|
259
|
+
version: "1.0.0"
|
|
260
|
+
}), {
|
|
261
|
+
response: t.Object({
|
|
262
|
+
status: t.String(),
|
|
263
|
+
version: t.String()
|
|
264
|
+
}),
|
|
265
|
+
detail: {
|
|
266
|
+
summary: 'Plugin Status',
|
|
267
|
+
description: 'Returns plugin status information'
|
|
268
|
+
}
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
.post("/action", async ({ body }) => {
|
|
272
|
+
// Handle action
|
|
273
|
+
return { success: true }
|
|
274
|
+
}, {
|
|
275
|
+
body: t.Object({
|
|
276
|
+
data: t.String()
|
|
277
|
+
}),
|
|
278
|
+
response: t.Object({
|
|
279
|
+
success: t.Boolean()
|
|
280
|
+
})
|
|
281
|
+
})
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
## Adding CLI Commands
|
|
286
|
+
|
|
287
|
+
```typescript
|
|
288
|
+
// plugins/my-plugin/cli/my-command.ts
|
|
289
|
+
import type { CliCommand } from "@core/plugins/types"
|
|
290
|
+
|
|
291
|
+
export const myCommand: CliCommand = {
|
|
292
|
+
name: "my:command",
|
|
293
|
+
description: "Does something useful",
|
|
294
|
+
usage: "flux my:command [options]",
|
|
295
|
+
examples: [
|
|
296
|
+
"flux my:command --option value"
|
|
297
|
+
],
|
|
298
|
+
options: [
|
|
299
|
+
{
|
|
300
|
+
name: "option",
|
|
301
|
+
alias: "o",
|
|
302
|
+
description: "An option",
|
|
303
|
+
type: "string",
|
|
304
|
+
required: false
|
|
305
|
+
}
|
|
306
|
+
],
|
|
307
|
+
handler: async (args, options, context) => {
|
|
308
|
+
context.logger.info('Running my command')
|
|
309
|
+
|
|
310
|
+
// Access config
|
|
311
|
+
const config = context.config
|
|
312
|
+
|
|
313
|
+
// Perform action
|
|
314
|
+
console.log('Option value:', options.option)
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
Register in plugin:
|
|
320
|
+
|
|
321
|
+
```typescript
|
|
322
|
+
import { myCommand } from "./cli/my-command"
|
|
323
|
+
|
|
324
|
+
export const myPlugin: FluxStack.Plugin = {
|
|
325
|
+
name: "my-plugin",
|
|
326
|
+
commands: [myCommand]
|
|
327
|
+
}
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
## Middleware Pattern
|
|
331
|
+
|
|
332
|
+
Create reusable middleware:
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
// plugins/my-plugin/server/middleware.ts
|
|
336
|
+
export class MyMiddleware {
|
|
337
|
+
constructor(private config: any) {}
|
|
338
|
+
|
|
339
|
+
async handle(requestContext: RequestContext) {
|
|
340
|
+
// Validate request
|
|
341
|
+
if (!this.validateRequest(requestContext)) {
|
|
342
|
+
throw new Error('Invalid request')
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// Add data to context
|
|
346
|
+
requestContext.user = await this.getUser(requestContext)
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
private validateRequest(context: RequestContext): boolean {
|
|
350
|
+
// Validation logic
|
|
351
|
+
return true
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
private async getUser(context: RequestContext) {
|
|
355
|
+
// Get user from headers
|
|
356
|
+
return { id: 1, name: 'User' }
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
Use in plugin:
|
|
362
|
+
|
|
363
|
+
```typescript
|
|
364
|
+
import { MyMiddleware } from "./server/middleware"
|
|
365
|
+
|
|
366
|
+
export const myPlugin: FluxStack.Plugin = {
|
|
367
|
+
name: "my-plugin",
|
|
368
|
+
|
|
369
|
+
setup: async (context) => {
|
|
370
|
+
const middleware = new MyMiddleware(myPluginConfig)
|
|
371
|
+
;(global as any).myMiddleware = middleware
|
|
372
|
+
},
|
|
373
|
+
|
|
374
|
+
onRequest: async (requestContext) => {
|
|
375
|
+
const middleware = (global as any).myMiddleware
|
|
376
|
+
await middleware.handle(requestContext)
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
## Package.json Metadata
|
|
382
|
+
|
|
383
|
+
```json
|
|
384
|
+
{
|
|
385
|
+
"name": "@fluxstack/my-plugin",
|
|
386
|
+
"version": "1.0.0",
|
|
387
|
+
"description": "My FluxStack plugin",
|
|
388
|
+
"main": "index.ts",
|
|
389
|
+
"types": "index.ts",
|
|
390
|
+
"exports": {
|
|
391
|
+
".": {
|
|
392
|
+
"import": "./index.ts",
|
|
393
|
+
"types": "./index.ts"
|
|
394
|
+
},
|
|
395
|
+
"./server": {
|
|
396
|
+
"import": "./server/index.ts",
|
|
397
|
+
"types": "./server/index.ts"
|
|
398
|
+
},
|
|
399
|
+
"./client": {
|
|
400
|
+
"import": "./client/index.ts",
|
|
401
|
+
"types": "./client/index.ts"
|
|
402
|
+
}
|
|
403
|
+
},
|
|
404
|
+
"keywords": [
|
|
405
|
+
"fluxstack",
|
|
406
|
+
"plugin"
|
|
407
|
+
],
|
|
408
|
+
"author": "Your Name",
|
|
409
|
+
"license": "MIT",
|
|
410
|
+
"dependencies": {},
|
|
411
|
+
"fluxstack": {
|
|
412
|
+
"plugin": true,
|
|
413
|
+
"version": "^1.0.0",
|
|
414
|
+
"hooks": [
|
|
415
|
+
"setup",
|
|
416
|
+
"onServerStart",
|
|
417
|
+
"onRequest"
|
|
418
|
+
],
|
|
419
|
+
"category": "utility",
|
|
420
|
+
"tags": ["custom"]
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
## Plugin Dependencies
|
|
426
|
+
|
|
427
|
+
Declare dependencies on other plugins:
|
|
428
|
+
|
|
429
|
+
```typescript
|
|
430
|
+
export const myPlugin: FluxStack.Plugin = {
|
|
431
|
+
name: "my-plugin",
|
|
432
|
+
dependencies: ["crypto-auth", "database"],
|
|
433
|
+
|
|
434
|
+
setup: async (context) => {
|
|
435
|
+
// Dependencies are loaded first
|
|
436
|
+
// Access other plugin services
|
|
437
|
+
const authService = (global as any).cryptoAuthService
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
## Plugin Priority
|
|
443
|
+
|
|
444
|
+
Control load order with priority:
|
|
445
|
+
|
|
446
|
+
```typescript
|
|
447
|
+
export const myPlugin: FluxStack.Plugin = {
|
|
448
|
+
name: "my-plugin",
|
|
449
|
+
priority: 100, // Higher = loads first
|
|
450
|
+
// or use named priorities:
|
|
451
|
+
// priority: 'highest' | 'high' | 'normal' | 'low' | 'lowest'
|
|
452
|
+
}
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
Load order:
|
|
456
|
+
1. Highest priority (or 1000+)
|
|
457
|
+
2. High priority (or 500-999)
|
|
458
|
+
3. Normal priority (or 100-499) - default
|
|
459
|
+
4. Low priority (or 50-99)
|
|
460
|
+
5. Lowest priority (or 0-49)
|
|
461
|
+
|
|
462
|
+
## Security Considerations
|
|
463
|
+
|
|
464
|
+
### Plugin Whitelist
|
|
465
|
+
|
|
466
|
+
Only whitelisted plugins are loaded:
|
|
467
|
+
|
|
468
|
+
```typescript
|
|
469
|
+
// config/system/plugins.config.ts
|
|
470
|
+
export const pluginsConfig = defineConfig({
|
|
471
|
+
whitelist: config.array('PLUGINS_WHITELIST', [
|
|
472
|
+
'crypto-auth',
|
|
473
|
+
'my-plugin'
|
|
474
|
+
])
|
|
475
|
+
})
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
### Validate Input
|
|
479
|
+
|
|
480
|
+
Always validate user input in plugin routes:
|
|
481
|
+
|
|
482
|
+
```typescript
|
|
483
|
+
.post("/action", async ({ body, set }) => {
|
|
484
|
+
if (!body.data || typeof body.data !== 'string') {
|
|
485
|
+
set.status = 400
|
|
486
|
+
return { error: 'Invalid data' }
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
// Process validated data
|
|
490
|
+
}, {
|
|
491
|
+
body: t.Object({
|
|
492
|
+
data: t.String({ minLength: 1, maxLength: 1000 })
|
|
493
|
+
})
|
|
494
|
+
})
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
### Secure Configuration
|
|
498
|
+
|
|
499
|
+
Never expose sensitive config in responses:
|
|
500
|
+
|
|
501
|
+
```typescript
|
|
502
|
+
// ❌ BAD
|
|
503
|
+
.get("/config", () => myPluginConfig)
|
|
504
|
+
|
|
505
|
+
// ✅ GOOD
|
|
506
|
+
.get("/config", () => ({
|
|
507
|
+
enabled: myPluginConfig.enabled,
|
|
508
|
+
features: myPluginConfig.features
|
|
509
|
+
// Don't expose apiKey or secrets
|
|
510
|
+
}))
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
## Testing Plugins
|
|
514
|
+
|
|
515
|
+
```typescript
|
|
516
|
+
// plugins/my-plugin/__tests__/plugin.test.ts
|
|
517
|
+
import { describe, it, expect, beforeAll } from 'vitest'
|
|
518
|
+
import { myPlugin } from '../index'
|
|
519
|
+
|
|
520
|
+
describe('MyPlugin', () => {
|
|
521
|
+
it('should have correct metadata', () => {
|
|
522
|
+
expect(myPlugin.name).toBe('my-plugin')
|
|
523
|
+
expect(myPlugin.version).toBe('1.0.0')
|
|
524
|
+
})
|
|
525
|
+
|
|
526
|
+
it('should initialize correctly', async () => {
|
|
527
|
+
const mockContext = {
|
|
528
|
+
config: {},
|
|
529
|
+
logger: { info: vi.fn() },
|
|
530
|
+
app: {},
|
|
531
|
+
utils: {}
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
await myPlugin.setup?.(mockContext)
|
|
535
|
+
|
|
536
|
+
expect(mockContext.logger.info).toHaveBeenCalled()
|
|
537
|
+
})
|
|
538
|
+
})
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
## Example: Crypto Auth Plugin
|
|
542
|
+
|
|
543
|
+
Reference implementation in `plugins/crypto-auth/`:
|
|
544
|
+
|
|
545
|
+
```typescript
|
|
546
|
+
export const cryptoAuthPlugin: FluxStack.Plugin = {
|
|
547
|
+
name: "crypto-auth",
|
|
548
|
+
version: "1.0.0",
|
|
549
|
+
description: "Ed25519 cryptographic authentication",
|
|
550
|
+
priority: 100,
|
|
551
|
+
category: "auth",
|
|
552
|
+
tags: ["authentication", "ed25519", "security"],
|
|
553
|
+
dependencies: [],
|
|
554
|
+
|
|
555
|
+
setup: async (context) => {
|
|
556
|
+
if (!cryptoAuthConfig.enabled) return
|
|
557
|
+
|
|
558
|
+
const authService = new CryptoAuthService({
|
|
559
|
+
maxTimeDrift: cryptoAuthConfig.maxTimeDrift,
|
|
560
|
+
adminKeys: cryptoAuthConfig.adminKeys,
|
|
561
|
+
logger: context.logger
|
|
562
|
+
})
|
|
563
|
+
|
|
564
|
+
;(global as any).cryptoAuthService = authService
|
|
565
|
+
},
|
|
566
|
+
|
|
567
|
+
plugin: new Elysia({ prefix: "/api/auth" })
|
|
568
|
+
.get("/info", () => ({
|
|
569
|
+
name: "FluxStack Crypto Auth",
|
|
570
|
+
version: "1.0.0"
|
|
571
|
+
})),
|
|
572
|
+
|
|
573
|
+
onResponse: async (context) => {
|
|
574
|
+
if (!cryptoAuthConfig.enableMetrics) return
|
|
575
|
+
|
|
576
|
+
// Log authentication metrics
|
|
577
|
+
if (context.user) {
|
|
578
|
+
console.debug("Authenticated request", {
|
|
579
|
+
publicKey: context.user.publicKey,
|
|
580
|
+
path: context.path
|
|
581
|
+
})
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
## Plugin Discovery
|
|
588
|
+
|
|
589
|
+
Plugins are auto-discovered from:
|
|
590
|
+
|
|
591
|
+
1. `plugins/` directory (project plugins)
|
|
592
|
+
2. `node_modules/@fluxstack/*-plugin` (npm plugins)
|
|
593
|
+
3. Whitelisted in `config/system/plugins.config.ts`
|
|
594
|
+
|
|
595
|
+
## Critical Rules
|
|
596
|
+
|
|
597
|
+
**ALWAYS:**
|
|
598
|
+
- Export plugin as default export
|
|
599
|
+
- Use declarative config system
|
|
600
|
+
- Validate all user input
|
|
601
|
+
- Handle errors gracefully
|
|
602
|
+
- Document plugin hooks and dependencies
|
|
603
|
+
- Test plugin functionality
|
|
604
|
+
|
|
605
|
+
**NEVER:**
|
|
606
|
+
- Modify core framework files
|
|
607
|
+
- Expose sensitive configuration
|
|
608
|
+
- Block server startup in setup hook
|
|
609
|
+
- Ignore security best practices
|
|
610
|
+
- Forget to cleanup in onServerStop
|
|
611
|
+
|
|
612
|
+
## Related
|
|
613
|
+
|
|
614
|
+
- [Plugin System](../core/plugin-system.md)
|
|
615
|
+
- [Plugin Hooks Reference](../reference/plugin-hooks.md)
|
|
616
|
+
- [Configuration System](../config/declarative-system.md)
|
|
617
|
+
- [CLI Commands](../reference/cli-commands.md)
|