@engjts/nexus 0.1.7 → 0.1.9
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/dist/advanced/playground/generatePlaygroundHTML.d.ts.map +1 -1
- package/dist/advanced/playground/generatePlaygroundHTML.js +107 -0
- package/dist/advanced/playground/generatePlaygroundHTML.js.map +1 -1
- package/dist/advanced/playground/playground.d.ts +19 -0
- package/dist/advanced/playground/playground.d.ts.map +1 -1
- package/dist/advanced/playground/playground.js +70 -0
- package/dist/advanced/playground/playground.js.map +1 -1
- package/dist/advanced/playground/types.d.ts +20 -0
- package/dist/advanced/playground/types.d.ts.map +1 -1
- package/dist/core/application.d.ts +14 -0
- package/dist/core/application.d.ts.map +1 -1
- package/dist/core/application.js +173 -71
- package/dist/core/application.js.map +1 -1
- package/dist/core/context-pool.d.ts +2 -13
- package/dist/core/context-pool.d.ts.map +1 -1
- package/dist/core/context-pool.js +7 -45
- package/dist/core/context-pool.js.map +1 -1
- package/dist/core/context.d.ts +108 -5
- package/dist/core/context.d.ts.map +1 -1
- package/dist/core/context.js +449 -53
- package/dist/core/context.js.map +1 -1
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +9 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/middleware.d.ts +6 -0
- package/dist/core/middleware.d.ts.map +1 -1
- package/dist/core/middleware.js +83 -84
- package/dist/core/middleware.js.map +1 -1
- package/dist/core/performance/fast-json.d.ts +149 -0
- package/dist/core/performance/fast-json.d.ts.map +1 -0
- package/dist/core/performance/fast-json.js +473 -0
- package/dist/core/performance/fast-json.js.map +1 -0
- package/dist/core/router/file-router.d.ts +20 -7
- package/dist/core/router/file-router.d.ts.map +1 -1
- package/dist/core/router/file-router.js +41 -13
- package/dist/core/router/file-router.js.map +1 -1
- package/dist/core/router/index.d.ts +6 -0
- package/dist/core/router/index.d.ts.map +1 -1
- package/dist/core/router/index.js +33 -6
- package/dist/core/router/index.js.map +1 -1
- package/dist/core/router/radix-tree.d.ts +4 -1
- package/dist/core/router/radix-tree.d.ts.map +1 -1
- package/dist/core/router/radix-tree.js +7 -3
- package/dist/core/router/radix-tree.js.map +1 -1
- package/dist/core/serializer.d.ts +251 -0
- package/dist/core/serializer.d.ts.map +1 -0
- package/dist/core/serializer.js +290 -0
- package/dist/core/serializer.js.map +1 -0
- package/dist/core/types.d.ts +39 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -2
- package/dist/index.js.map +1 -1
- package/package.json +3 -1
- package/documentation/01-getting-started.md +0 -240
- package/documentation/02-context.md +0 -335
- package/documentation/03-routing.md +0 -397
- package/documentation/04-middleware.md +0 -483
- package/documentation/05-validation.md +0 -514
- package/documentation/06-error-handling.md +0 -465
- package/documentation/07-performance.md +0 -364
- package/documentation/08-adapters.md +0 -470
- package/documentation/09-api-reference.md +0 -548
- package/documentation/10-examples.md +0 -582
- package/documentation/11-deployment.md +0 -477
- package/documentation/12-sentry.md +0 -620
- package/documentation/13-sentry-data-storage.md +0 -996
- package/documentation/14-sentry-data-reference.md +0 -457
- package/documentation/15-sentry-summary.md +0 -409
- package/documentation/16-alerts-system.md +0 -745
- package/documentation/17-alert-adapters.md +0 -696
- package/documentation/18-alerts-implementation-summary.md +0 -385
- package/documentation/19-class-based-routing.md +0 -840
- package/documentation/20-websocket-realtime.md +0 -813
- package/documentation/21-cache-system.md +0 -510
- package/documentation/22-job-queue.md +0 -772
- package/documentation/23-sentry-plugin.md +0 -551
- package/documentation/24-testing-utilities.md +0 -1287
- package/documentation/25-api-versioning.md +0 -533
- package/documentation/26-context-store.md +0 -607
- package/documentation/27-dependency-injection.md +0 -329
- package/documentation/28-lifecycle-hooks.md +0 -521
- package/documentation/29-package-structure.md +0 -196
- package/documentation/30-plugin-system.md +0 -414
- package/documentation/31-jwt-authentication.md +0 -597
- package/documentation/32-cli.md +0 -268
- package/documentation/ALERTS-COMPLETE-SUMMARY.md +0 -429
- package/documentation/ALERTS-INDEX.md +0 -330
- package/documentation/ALERTS-QUICK-REFERENCE.md +0 -286
- package/documentation/README.md +0 -178
- package/documentation/index.html +0 -34
- package/modern_framework_paper.md +0 -1870
- package/public/css/style.css +0 -87
- package/public/index.html +0 -34
- package/public/js/app.js +0 -27
- package/src/advanced/cache/InMemoryCacheStore.ts +0 -68
- package/src/advanced/cache/MultiTierCache.ts +0 -194
- package/src/advanced/cache/RedisCacheStore.ts +0 -341
- package/src/advanced/cache/index.ts +0 -5
- package/src/advanced/cache/types.ts +0 -40
- package/src/advanced/graphql/SimpleDataLoader.ts +0 -42
- package/src/advanced/graphql/index.ts +0 -22
- package/src/advanced/graphql/server.ts +0 -252
- package/src/advanced/graphql/types.ts +0 -42
- package/src/advanced/jobs/InMemoryQueueStore.ts +0 -68
- package/src/advanced/jobs/JobQueue.ts +0 -556
- package/src/advanced/jobs/RedisQueueStore.ts +0 -367
- package/src/advanced/jobs/index.ts +0 -5
- package/src/advanced/jobs/types.ts +0 -70
- package/src/advanced/observability/APMManager.ts +0 -163
- package/src/advanced/observability/AlertManager.ts +0 -109
- package/src/advanced/observability/MetricRegistry.ts +0 -151
- package/src/advanced/observability/ObservabilityCenter.ts +0 -304
- package/src/advanced/observability/StructuredLogger.ts +0 -154
- package/src/advanced/observability/TracingManager.ts +0 -117
- package/src/advanced/observability/adapters.ts +0 -304
- package/src/advanced/observability/createObservabilityMiddleware.ts +0 -63
- package/src/advanced/observability/index.ts +0 -11
- package/src/advanced/observability/types.ts +0 -174
- package/src/advanced/playground/extractPathParams.ts +0 -6
- package/src/advanced/playground/generateFieldExample.ts +0 -31
- package/src/advanced/playground/generatePlaygroundHTML.ts +0 -1849
- package/src/advanced/playground/generateSummary.ts +0 -19
- package/src/advanced/playground/getTagFromPath.ts +0 -9
- package/src/advanced/playground/index.ts +0 -8
- package/src/advanced/playground/playground.ts +0 -170
- package/src/advanced/playground/types.ts +0 -20
- package/src/advanced/playground/zodToExample.ts +0 -16
- package/src/advanced/playground/zodToParams.ts +0 -15
- package/src/advanced/postman/buildAuth.ts +0 -31
- package/src/advanced/postman/buildBody.ts +0 -15
- package/src/advanced/postman/buildQueryParams.ts +0 -27
- package/src/advanced/postman/buildRequestItem.ts +0 -36
- package/src/advanced/postman/buildResponses.ts +0 -11
- package/src/advanced/postman/buildUrl.ts +0 -33
- package/src/advanced/postman/capitalize.ts +0 -4
- package/src/advanced/postman/generateCollection.ts +0 -59
- package/src/advanced/postman/generateEnvironment.ts +0 -34
- package/src/advanced/postman/generateExampleFromZod.ts +0 -21
- package/src/advanced/postman/generateFieldExample.ts +0 -45
- package/src/advanced/postman/generateName.ts +0 -20
- package/src/advanced/postman/generateUUID.ts +0 -11
- package/src/advanced/postman/getTagFromPath.ts +0 -10
- package/src/advanced/postman/index.ts +0 -28
- package/src/advanced/postman/postman.ts +0 -156
- package/src/advanced/postman/slugify.ts +0 -7
- package/src/advanced/postman/types.ts +0 -140
- package/src/advanced/realtime/index.ts +0 -18
- package/src/advanced/realtime/websocket.ts +0 -231
- package/src/advanced/sentry/index.ts +0 -1236
- package/src/advanced/sentry/types.ts +0 -355
- package/src/advanced/static/generateDirectoryListing.ts +0 -47
- package/src/advanced/static/generateETag.ts +0 -7
- package/src/advanced/static/getMimeType.ts +0 -9
- package/src/advanced/static/index.ts +0 -32
- package/src/advanced/static/isSafePath.ts +0 -13
- package/src/advanced/static/publicDir.ts +0 -21
- package/src/advanced/static/serveStatic.ts +0 -225
- package/src/advanced/static/spa.ts +0 -24
- package/src/advanced/static/types.ts +0 -159
- package/src/advanced/swagger/SwaggerGenerator.ts +0 -66
- package/src/advanced/swagger/buildOperation.ts +0 -61
- package/src/advanced/swagger/buildParameters.ts +0 -61
- package/src/advanced/swagger/buildRequestBody.ts +0 -21
- package/src/advanced/swagger/buildResponses.ts +0 -54
- package/src/advanced/swagger/capitalize.ts +0 -5
- package/src/advanced/swagger/convertPath.ts +0 -9
- package/src/advanced/swagger/createSwagger.ts +0 -12
- package/src/advanced/swagger/generateOperationId.ts +0 -21
- package/src/advanced/swagger/generateSpec.ts +0 -105
- package/src/advanced/swagger/generateSummary.ts +0 -24
- package/src/advanced/swagger/generateSwaggerUI.ts +0 -70
- package/src/advanced/swagger/generateThemeCss.ts +0 -53
- package/src/advanced/swagger/index.ts +0 -25
- package/src/advanced/swagger/swagger.ts +0 -237
- package/src/advanced/swagger/types.ts +0 -206
- package/src/advanced/swagger/zodFieldToOpenAPI.ts +0 -94
- package/src/advanced/swagger/zodSchemaToOpenAPI.ts +0 -50
- package/src/advanced/swagger/zodToOpenAPI.ts +0 -22
- package/src/advanced/testing/factory.ts +0 -509
- package/src/advanced/testing/harness.ts +0 -612
- package/src/advanced/testing/index.ts +0 -430
- package/src/advanced/testing/load-test.ts +0 -618
- package/src/advanced/testing/mock-server.ts +0 -498
- package/src/advanced/testing/mock.ts +0 -670
- package/src/cli/bin.ts +0 -9
- package/src/cli/cli.ts +0 -158
- package/src/cli/commands/add.ts +0 -178
- package/src/cli/commands/build.ts +0 -73
- package/src/cli/commands/create.ts +0 -166
- package/src/cli/commands/dev.ts +0 -85
- package/src/cli/commands/generate.ts +0 -99
- package/src/cli/commands/help.ts +0 -95
- package/src/cli/commands/init.ts +0 -91
- package/src/cli/commands/version.ts +0 -38
- package/src/cli/index.ts +0 -6
- package/src/cli/templates/generators.ts +0 -359
- package/src/cli/templates/index.ts +0 -680
- package/src/cli/utils/exec.ts +0 -52
- package/src/cli/utils/file-system.ts +0 -78
- package/src/cli/utils/logger.ts +0 -111
- package/src/core/adapter.ts +0 -88
- package/src/core/application.ts +0 -1335
- package/src/core/context-pool.ts +0 -127
- package/src/core/context.ts +0 -412
- package/src/core/index.ts +0 -80
- package/src/core/middleware.ts +0 -262
- package/src/core/performance/buffer-pool.ts +0 -108
- package/src/core/performance/middleware-optimizer.ts +0 -162
- package/src/core/plugin/PluginManager.ts +0 -435
- package/src/core/plugin/builder.ts +0 -358
- package/src/core/plugin/index.ts +0 -50
- package/src/core/plugin/types.ts +0 -214
- package/src/core/router/file-router.ts +0 -594
- package/src/core/router/index.ts +0 -227
- package/src/core/router/radix-tree.ts +0 -226
- package/src/core/store/index.ts +0 -30
- package/src/core/store/registry.ts +0 -178
- package/src/core/store/request-store.ts +0 -240
- package/src/core/store/types.ts +0 -233
- package/src/core/types.ts +0 -574
- package/src/database/adapter.ts +0 -35
- package/src/database/adapters/index.ts +0 -1
- package/src/database/adapters/mysql.ts +0 -669
- package/src/database/database.ts +0 -70
- package/src/database/dialect.ts +0 -388
- package/src/database/index.ts +0 -12
- package/src/database/migrations.ts +0 -86
- package/src/database/optimizer.ts +0 -125
- package/src/database/query-builder.ts +0 -404
- package/src/database/realtime.ts +0 -53
- package/src/database/schema.ts +0 -71
- package/src/database/transactions.ts +0 -56
- package/src/database/types.ts +0 -87
- package/src/deployment/cluster.ts +0 -471
- package/src/deployment/config.ts +0 -454
- package/src/deployment/docker.ts +0 -599
- package/src/deployment/graceful-shutdown.ts +0 -373
- package/src/deployment/index.ts +0 -56
- package/src/index.ts +0 -264
- package/src/security/adapter.ts +0 -318
- package/src/security/auth/JWTPlugin.ts +0 -234
- package/src/security/auth/JWTProvider.ts +0 -316
- package/src/security/auth/adapter.ts +0 -12
- package/src/security/auth/jwt.ts +0 -234
- package/src/security/auth/middleware.ts +0 -188
- package/src/security/csrf.ts +0 -220
- package/src/security/headers.ts +0 -108
- package/src/security/index.ts +0 -60
- package/src/security/rate-limit/adapter.ts +0 -7
- package/src/security/rate-limit/memory.ts +0 -108
- package/src/security/rate-limit/middleware.ts +0 -181
- package/src/security/sanitization.ts +0 -75
- package/src/security/types.ts +0 -240
- package/src/security/utils.ts +0 -52
- package/tsconfig.json +0 -39
|
@@ -1,414 +0,0 @@
|
|
|
1
|
-
# Plugin System
|
|
2
|
-
|
|
3
|
-
Nexus Framework mendukung plugin system yang powerful untuk extensibility. Plugin memungkinkan Anda untuk:
|
|
4
|
-
|
|
5
|
-
- Menambahkan middleware secara modular
|
|
6
|
-
- Menambahkan routes
|
|
7
|
-
- Mendekorasi context dengan properties baru
|
|
8
|
-
- Berbagi API antar plugin
|
|
9
|
-
- Lifecycle hooks yang terstruktur
|
|
10
|
-
|
|
11
|
-
## Quick Start
|
|
12
|
-
|
|
13
|
-
```typescript
|
|
14
|
-
import { createApp, definePlugin, createPlugin } from '@engjts/server';
|
|
15
|
-
|
|
16
|
-
// Simple plugin
|
|
17
|
-
const myPlugin = createPlugin({
|
|
18
|
-
name: 'my-plugin',
|
|
19
|
-
register: (ctx) => {
|
|
20
|
-
ctx.log.info('Hello from my plugin!');
|
|
21
|
-
}
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
const app = createApp()
|
|
25
|
-
.plugin(myPlugin);
|
|
26
|
-
|
|
27
|
-
await app.initialize();
|
|
28
|
-
app.listen(3000);
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## Creating Plugins
|
|
32
|
-
|
|
33
|
-
### Method 1: `createPlugin()` - Quick & Simple
|
|
34
|
-
|
|
35
|
-
```typescript
|
|
36
|
-
import { createPlugin } from '@engjts/server';
|
|
37
|
-
|
|
38
|
-
const loggerPlugin = createPlugin({
|
|
39
|
-
name: 'logger',
|
|
40
|
-
version: '1.0.0',
|
|
41
|
-
|
|
42
|
-
register: (ctx) => {
|
|
43
|
-
ctx.app.use(async (reqCtx, next) => {
|
|
44
|
-
console.log(`${reqCtx.method} ${reqCtx.path}`);
|
|
45
|
-
return next(reqCtx);
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
### Method 2: `definePlugin()` - Fluent Builder (Recommended)
|
|
52
|
-
|
|
53
|
-
```typescript
|
|
54
|
-
import { definePlugin } from '@engjts/server';
|
|
55
|
-
|
|
56
|
-
interface MyConfig {
|
|
57
|
-
apiKey: string;
|
|
58
|
-
timeout?: number;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const myPlugin = definePlugin('my-plugin')
|
|
62
|
-
.version('1.0.0')
|
|
63
|
-
.description('My awesome plugin')
|
|
64
|
-
.author('Your Name')
|
|
65
|
-
.tags('utility', 'awesome')
|
|
66
|
-
.priority('high')
|
|
67
|
-
|
|
68
|
-
// Type-safe configuration
|
|
69
|
-
.config<MyConfig>()
|
|
70
|
-
.defaults({ timeout: 5000 })
|
|
71
|
-
.validate((config) => {
|
|
72
|
-
if (!config.apiKey) return 'API key is required';
|
|
73
|
-
return true;
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
// Lifecycle hooks
|
|
77
|
-
.configure((ctx) => {
|
|
78
|
-
// Early setup, before other plugins
|
|
79
|
-
})
|
|
80
|
-
.register((ctx) => {
|
|
81
|
-
// Main registration logic
|
|
82
|
-
})
|
|
83
|
-
.boot((ctx) => {
|
|
84
|
-
// After all plugins registered
|
|
85
|
-
})
|
|
86
|
-
.ready((ctx) => {
|
|
87
|
-
// Server is listening
|
|
88
|
-
})
|
|
89
|
-
.shutdown((ctx) => {
|
|
90
|
-
// Cleanup on shutdown
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
.build();
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
## Plugin Lifecycle
|
|
97
|
-
|
|
98
|
-
Plugins go through these phases in order:
|
|
99
|
-
|
|
100
|
-
```
|
|
101
|
-
configure → register → boot → ready → shutdown
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
| Phase | Description | Use Case |
|
|
105
|
-
|-------|-------------|----------|
|
|
106
|
-
| `configure` | Early setup, before anything else | Set up configuration, environment |
|
|
107
|
-
| `register` | Main registration | Add routes, middleware, stores |
|
|
108
|
-
| `boot` | After all plugins registered | Connect to databases, external services |
|
|
109
|
-
| `ready` | Server is listening | Log startup info, notify services |
|
|
110
|
-
| `shutdown` | App is shutting down | Cleanup, close connections |
|
|
111
|
-
|
|
112
|
-
## Plugin Features
|
|
113
|
-
|
|
114
|
-
### Adding Middleware
|
|
115
|
-
|
|
116
|
-
```typescript
|
|
117
|
-
definePlugin('auth')
|
|
118
|
-
.middleware((ctx) => {
|
|
119
|
-
return async (reqCtx, next) => {
|
|
120
|
-
// Auth logic using ctx.config
|
|
121
|
-
const token = reqCtx.headers.authorization;
|
|
122
|
-
reqCtx.user = await verifyToken(token, ctx.config.secret);
|
|
123
|
-
return next(reqCtx);
|
|
124
|
-
};
|
|
125
|
-
})
|
|
126
|
-
.build();
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
### Adding Routes
|
|
130
|
-
|
|
131
|
-
```typescript
|
|
132
|
-
definePlugin('api')
|
|
133
|
-
.routes((ctx) => [
|
|
134
|
-
{
|
|
135
|
-
method: 'GET',
|
|
136
|
-
path: '/api/status',
|
|
137
|
-
handler: async (reqCtx) => ({ status: 'ok' }),
|
|
138
|
-
meta: { tags: ['System'] }
|
|
139
|
-
},
|
|
140
|
-
{
|
|
141
|
-
method: 'POST',
|
|
142
|
-
path: '/api/webhook',
|
|
143
|
-
handler: async (reqCtx) => {
|
|
144
|
-
// Handle webhook
|
|
145
|
-
return { received: true };
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
])
|
|
149
|
-
.build();
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
### Decorating Context
|
|
153
|
-
|
|
154
|
-
```typescript
|
|
155
|
-
definePlugin('auth')
|
|
156
|
-
.decorate((ctx) => {
|
|
157
|
-
ctx.auth = {
|
|
158
|
-
user: null,
|
|
159
|
-
isAuthenticated: false,
|
|
160
|
-
hasRole: (role: string) => false
|
|
161
|
-
};
|
|
162
|
-
})
|
|
163
|
-
.build();
|
|
164
|
-
|
|
165
|
-
// Now in any route:
|
|
166
|
-
app.get('/profile', async (ctx) => {
|
|
167
|
-
if (!ctx.auth.isAuthenticated) {
|
|
168
|
-
return ctx.response.status(401).json({ error: 'Login required' });
|
|
169
|
-
}
|
|
170
|
-
return { user: ctx.auth.user };
|
|
171
|
-
});
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
### Exporting APIs
|
|
175
|
-
|
|
176
|
-
Plugins can export APIs for other plugins to use:
|
|
177
|
-
|
|
178
|
-
```typescript
|
|
179
|
-
interface AuthExports {
|
|
180
|
-
verify: (token: string) => Promise<User | null>;
|
|
181
|
-
sign: (user: User) => string;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
const authPlugin = definePlugin('auth')
|
|
185
|
-
.export<AuthExports>((ctx) => ({
|
|
186
|
-
verify: async (token) => {
|
|
187
|
-
// Verify logic
|
|
188
|
-
},
|
|
189
|
-
sign: (user) => {
|
|
190
|
-
// Sign logic
|
|
191
|
-
}
|
|
192
|
-
}))
|
|
193
|
-
.build();
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
Using exports from another plugin:
|
|
197
|
-
|
|
198
|
-
```typescript
|
|
199
|
-
const userPlugin = definePlugin('user')
|
|
200
|
-
.depends(['auth']) // Declare dependency
|
|
201
|
-
.register((ctx) => {
|
|
202
|
-
const auth = ctx.getPlugin<AuthExports>('auth');
|
|
203
|
-
|
|
204
|
-
// Use auth API
|
|
205
|
-
const token = auth.sign({ id: 1, name: 'John' });
|
|
206
|
-
})
|
|
207
|
-
.build();
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
### Plugin Dependencies
|
|
211
|
-
|
|
212
|
-
```typescript
|
|
213
|
-
definePlugin('user-service')
|
|
214
|
-
// Required dependencies (will fail if not installed)
|
|
215
|
-
.depends(['auth', 'database'])
|
|
216
|
-
|
|
217
|
-
// Optional dependencies (won't fail if missing)
|
|
218
|
-
.optionalDeps(['cache', 'metrics'])
|
|
219
|
-
|
|
220
|
-
// Conflicting plugins (can't be installed together)
|
|
221
|
-
.conflicts(['legacy-auth'])
|
|
222
|
-
|
|
223
|
-
.register((ctx) => {
|
|
224
|
-
// Check for optional dependency
|
|
225
|
-
if (ctx.hasPlugin('cache')) {
|
|
226
|
-
const cache = ctx.getPlugin('cache');
|
|
227
|
-
// Use cache
|
|
228
|
-
}
|
|
229
|
-
})
|
|
230
|
-
.build();
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
### Plugin Storage
|
|
234
|
-
|
|
235
|
-
Each plugin has isolated storage that persists across lifecycle phases:
|
|
236
|
-
|
|
237
|
-
```typescript
|
|
238
|
-
definePlugin('rate-limiter')
|
|
239
|
-
.configure((ctx) => {
|
|
240
|
-
ctx.storage.set('requests', new Map());
|
|
241
|
-
})
|
|
242
|
-
|
|
243
|
-
.middleware((ctx) => {
|
|
244
|
-
return async (reqCtx, next) => {
|
|
245
|
-
const requests = ctx.storage.get('requests');
|
|
246
|
-
const ip = reqCtx.headers['x-forwarded-for'] || 'unknown';
|
|
247
|
-
|
|
248
|
-
const count = requests.get(ip) || 0;
|
|
249
|
-
if (count > 100) {
|
|
250
|
-
return reqCtx.response.status(429).json({ error: 'Too many requests' });
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
requests.set(ip, count + 1);
|
|
254
|
-
return next(reqCtx);
|
|
255
|
-
};
|
|
256
|
-
})
|
|
257
|
-
|
|
258
|
-
.export((ctx) => ({
|
|
259
|
-
getStats: () => {
|
|
260
|
-
const requests = ctx.storage.get('requests');
|
|
261
|
-
return { uniqueIPs: requests.size };
|
|
262
|
-
}
|
|
263
|
-
}))
|
|
264
|
-
.build();
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
## Using Plugins in Application
|
|
268
|
-
|
|
269
|
-
```typescript
|
|
270
|
-
const app = createApp({ debug: true });
|
|
271
|
-
|
|
272
|
-
// Register plugins with configuration
|
|
273
|
-
app
|
|
274
|
-
.plugin(loggerPlugin)
|
|
275
|
-
.plugin(authPlugin, {
|
|
276
|
-
secret: process.env.JWT_SECRET!,
|
|
277
|
-
expiry: 3600
|
|
278
|
-
})
|
|
279
|
-
.plugin(userPlugin);
|
|
280
|
-
|
|
281
|
-
// Initialize all plugins (configure → register → boot)
|
|
282
|
-
await app.initialize();
|
|
283
|
-
|
|
284
|
-
// Add routes
|
|
285
|
-
app.get('/health', async () => ({ status: 'ok' }));
|
|
286
|
-
|
|
287
|
-
// Start server (triggers ready phase)
|
|
288
|
-
app.listen(3000, () => {
|
|
289
|
-
console.log('Server running');
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
// Graceful shutdown (triggers shutdown phase)
|
|
293
|
-
process.on('SIGTERM', async () => {
|
|
294
|
-
await app.shutdown();
|
|
295
|
-
});
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
## Plugin Manager API
|
|
299
|
-
|
|
300
|
-
```typescript
|
|
301
|
-
const pm = app.getPluginManager();
|
|
302
|
-
|
|
303
|
-
// Check if plugin exists
|
|
304
|
-
if (pm.has('auth')) {
|
|
305
|
-
// Get plugin exports
|
|
306
|
-
const auth = pm.getExports<AuthExports>('auth');
|
|
307
|
-
auth.verify(token);
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
// Get plugin metadata
|
|
311
|
-
const meta = pm.getMeta('auth');
|
|
312
|
-
console.log(meta?.version);
|
|
313
|
-
|
|
314
|
-
// Get all plugins
|
|
315
|
-
const plugins = pm.getAll();
|
|
316
|
-
plugins.forEach(p => console.log(p.meta.name, p.state));
|
|
317
|
-
|
|
318
|
-
// Listen to events
|
|
319
|
-
pm.on('plugin:ready', (meta) => {
|
|
320
|
-
console.log(`Plugin ${meta.name} is ready`);
|
|
321
|
-
});
|
|
322
|
-
|
|
323
|
-
pm.on('plugin:error', (meta, error) => {
|
|
324
|
-
console.error(`Plugin ${meta.name} failed:`, error);
|
|
325
|
-
});
|
|
326
|
-
```
|
|
327
|
-
|
|
328
|
-
## Plugin Priority
|
|
329
|
-
|
|
330
|
-
Plugins can declare priority to control loading order:
|
|
331
|
-
|
|
332
|
-
```typescript
|
|
333
|
-
definePlugin('critical-plugin')
|
|
334
|
-
.priority('critical') // Loads first
|
|
335
|
-
.build();
|
|
336
|
-
|
|
337
|
-
definePlugin('normal-plugin')
|
|
338
|
-
.priority('normal') // Default
|
|
339
|
-
.build();
|
|
340
|
-
|
|
341
|
-
definePlugin('lazy-plugin')
|
|
342
|
-
.priority('low') // Loads last
|
|
343
|
-
.build();
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
Priority levels: `critical` → `high` → `normal` → `low`
|
|
347
|
-
|
|
348
|
-
## Best Practices
|
|
349
|
-
|
|
350
|
-
1. **Use dependencies** - Declare what your plugin needs
|
|
351
|
-
2. **Validate config** - Fail fast with clear error messages
|
|
352
|
-
3. **Use lifecycle hooks** - Put logic in the right phase
|
|
353
|
-
4. **Export APIs** - Make functionality available to other plugins
|
|
354
|
-
5. **Handle shutdown** - Clean up resources properly
|
|
355
|
-
6. **Log appropriately** - Use `ctx.log` for scoped logging
|
|
356
|
-
7. **Type your exports** - Use TypeScript generics
|
|
357
|
-
|
|
358
|
-
## TypeScript Support
|
|
359
|
-
|
|
360
|
-
Full TypeScript support with generic types:
|
|
361
|
-
|
|
362
|
-
```typescript
|
|
363
|
-
interface MyConfig {
|
|
364
|
-
apiKey: string;
|
|
365
|
-
baseUrl: string;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
interface MyExports {
|
|
369
|
-
fetch: (endpoint: string) => Promise<any>;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
const myPlugin = definePlugin('my-plugin')
|
|
373
|
-
.config<MyConfig>()
|
|
374
|
-
.export<MyExports>((ctx) => ({
|
|
375
|
-
fetch: async (endpoint) => {
|
|
376
|
-
const response = await fetch(ctx.config.baseUrl + endpoint, {
|
|
377
|
-
headers: { 'X-API-Key': ctx.config.apiKey }
|
|
378
|
-
});
|
|
379
|
-
return response.json();
|
|
380
|
-
}
|
|
381
|
-
}))
|
|
382
|
-
.build();
|
|
383
|
-
|
|
384
|
-
// Type-safe usage
|
|
385
|
-
const exports = app.getPluginExports<MyExports>('my-plugin');
|
|
386
|
-
const data = await exports?.fetch('/users');
|
|
387
|
-
```
|
|
388
|
-
|
|
389
|
-
## Migration from Legacy Plugin
|
|
390
|
-
|
|
391
|
-
If you have existing plugins using the old format:
|
|
392
|
-
|
|
393
|
-
```typescript
|
|
394
|
-
// Old format (still supported)
|
|
395
|
-
const legacyPlugin = {
|
|
396
|
-
name: 'legacy',
|
|
397
|
-
version: '1.0.0',
|
|
398
|
-
install: (app) => {
|
|
399
|
-
app.use(myMiddleware);
|
|
400
|
-
}
|
|
401
|
-
};
|
|
402
|
-
|
|
403
|
-
// New format (recommended)
|
|
404
|
-
const modernPlugin = definePlugin('modern')
|
|
405
|
-
.version('1.0.0')
|
|
406
|
-
.register((ctx) => {
|
|
407
|
-
ctx.app.use(myMiddleware);
|
|
408
|
-
})
|
|
409
|
-
.build();
|
|
410
|
-
|
|
411
|
-
// Both work
|
|
412
|
-
app.plugin(legacyPlugin);
|
|
413
|
-
app.plugin(modernPlugin);
|
|
414
|
-
```
|