@engjts/nexus 0.1.8 → 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/package.json +1 -1
- package/BENCHMARK_REPORT.md +0 -343
- 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 -1956
- 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 -250
- package/src/advanced/playground/types.ts +0 -49
- 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 -1453
- package/src/core/context-pool.ts +0 -79
- package/src/core/context.ts +0 -856
- package/src/core/index.ts +0 -94
- package/src/core/middleware.ts +0 -272
- 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 -623
- package/src/core/router/index.ts +0 -260
- package/src/core/router/radix-tree.ts +0 -242
- package/src/core/serializer.ts +0 -397
- 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 -616
- 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 -281
- 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,329 +0,0 @@
|
|
|
1
|
-
# Dependency Injection
|
|
2
|
-
|
|
3
|
-
Nexus Framework menyediakan sistem **Dependency Injection (DI)** yang type-safe untuk mengelola dependencies seperti database, cache, mailer, dan service lainnya.
|
|
4
|
-
|
|
5
|
-
## Quick Start
|
|
6
|
-
|
|
7
|
-
```typescript
|
|
8
|
-
import { createApp } from 'nexus';
|
|
9
|
-
|
|
10
|
-
// 1. Define dependencies
|
|
11
|
-
const db = new Database();
|
|
12
|
-
const cache = new RedisCache();
|
|
13
|
-
const mailer = new Mailer();
|
|
14
|
-
|
|
15
|
-
// 2. Create app dan provide dependencies
|
|
16
|
-
const app = createApp()
|
|
17
|
-
.provide({ db, cache, mailer });
|
|
18
|
-
|
|
19
|
-
// 3. Gunakan di handler - auto-injected & fully typed!
|
|
20
|
-
app.get('/users', async (ctx, { db, cache }) => {
|
|
21
|
-
const cached = await cache.get('users');
|
|
22
|
-
if (cached) return { users: cached, source: 'cache' };
|
|
23
|
-
|
|
24
|
-
const users = await db.query('SELECT * FROM users');
|
|
25
|
-
await cache.set('users', users);
|
|
26
|
-
return { users, source: 'database' };
|
|
27
|
-
});
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## API Reference
|
|
31
|
-
|
|
32
|
-
### `app.provide(dependencies)`
|
|
33
|
-
|
|
34
|
-
Register dependencies yang akan di-inject ke semua route handlers.
|
|
35
|
-
|
|
36
|
-
```typescript
|
|
37
|
-
interface Dependencies {
|
|
38
|
-
db: Database;
|
|
39
|
-
cache: CacheService;
|
|
40
|
-
mailer: MailerService;
|
|
41
|
-
// ... tambahkan sesuai kebutuhan
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const app = createApp().provide<Dependencies>({
|
|
45
|
-
db: new Database(),
|
|
46
|
-
cache: new RedisCache(),
|
|
47
|
-
mailer: new Mailer()
|
|
48
|
-
});
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
**Returns:** `Application` (chainable)
|
|
52
|
-
|
|
53
|
-
## Usage Patterns
|
|
54
|
-
|
|
55
|
-
### Pattern 1: Simple Function Handler
|
|
56
|
-
|
|
57
|
-
Paling simple - langsung destructure dependencies di parameter kedua:
|
|
58
|
-
|
|
59
|
-
```typescript
|
|
60
|
-
app.get('/users', async (ctx, { db }) => {
|
|
61
|
-
const users = await db.getUsers();
|
|
62
|
-
return { users };
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
app.post('/send-email', async (ctx, { mailer }) => {
|
|
66
|
-
await mailer.send({
|
|
67
|
-
to: ctx.body.email,
|
|
68
|
-
subject: 'Welcome!',
|
|
69
|
-
body: 'Thanks for signing up.'
|
|
70
|
-
});
|
|
71
|
-
return { sent: true };
|
|
72
|
-
});
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
### Pattern 2: Access All Dependencies
|
|
76
|
-
|
|
77
|
-
Jika butuh akses ke semua dependencies:
|
|
78
|
-
|
|
79
|
-
```typescript
|
|
80
|
-
app.post('/users', async (ctx, deps) => {
|
|
81
|
-
// deps berisi semua: db, cache, mailer, dll
|
|
82
|
-
const user = await deps.db.createUser(ctx.body);
|
|
83
|
-
await deps.cache.invalidate('users');
|
|
84
|
-
await deps.mailer.send({
|
|
85
|
-
to: user.email,
|
|
86
|
-
subject: 'Welcome!'
|
|
87
|
-
});
|
|
88
|
-
return { user };
|
|
89
|
-
});
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
### Pattern 3: Config Object dengan Explicit Inject
|
|
93
|
-
|
|
94
|
-
Untuk kontrol lebih detail, gunakan config object:
|
|
95
|
-
|
|
96
|
-
```typescript
|
|
97
|
-
app.get('/users/:id', {
|
|
98
|
-
inject: ['db', 'cache'], // Explicit specify dependencies
|
|
99
|
-
handler: async (ctx, { db, cache }) => {
|
|
100
|
-
const id = ctx.params.id;
|
|
101
|
-
|
|
102
|
-
// Check cache first
|
|
103
|
-
const cached = await cache.get(`user:${id}`);
|
|
104
|
-
if (cached) return cached;
|
|
105
|
-
|
|
106
|
-
// Fetch from DB
|
|
107
|
-
const user = await db.getUserById(id);
|
|
108
|
-
await cache.set(`user:${id}`, user, { ttl: 3600 });
|
|
109
|
-
|
|
110
|
-
return { user };
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
## Type Safety
|
|
116
|
-
|
|
117
|
-
Dependencies sepenuhnya type-safe. TypeScript akan:
|
|
118
|
-
- Autocomplete nama dependency
|
|
119
|
-
- Type-check penggunaan dependency
|
|
120
|
-
- Error jika dependency tidak ada
|
|
121
|
-
|
|
122
|
-
```typescript
|
|
123
|
-
interface AppDeps {
|
|
124
|
-
db: {
|
|
125
|
-
getUsers(): Promise<User[]>;
|
|
126
|
-
getUserById(id: string): Promise<User>;
|
|
127
|
-
};
|
|
128
|
-
cache: {
|
|
129
|
-
get<T>(key: string): Promise<T | null>;
|
|
130
|
-
set(key: string, value: any): Promise<void>;
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const app = createApp().provide<AppDeps>({
|
|
135
|
-
db: new PostgresDB(),
|
|
136
|
-
cache: new Redis()
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
// ✅ TypeScript knows db.getUsers() returns Promise<User[]>
|
|
140
|
-
app.get('/users', async (ctx, { db }) => {
|
|
141
|
-
const users = await db.getUsers();
|
|
142
|
-
return { users };
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
// ❌ TypeScript error: 'unknown' does not exist on AppDeps
|
|
146
|
-
app.get('/test', async (ctx, { unknown }) => {
|
|
147
|
-
// Error!
|
|
148
|
-
});
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
## Real-World Example
|
|
152
|
-
|
|
153
|
-
```typescript
|
|
154
|
-
import { createApp } from 'nexus';
|
|
155
|
-
import { z } from 'zod';
|
|
156
|
-
|
|
157
|
-
// === Services ===
|
|
158
|
-
class Database {
|
|
159
|
-
private users = [
|
|
160
|
-
{ id: 1, name: 'John', email: 'john@example.com' },
|
|
161
|
-
{ id: 2, name: 'Jane', email: 'jane@example.com' }
|
|
162
|
-
];
|
|
163
|
-
|
|
164
|
-
async getUsers() { return this.users; }
|
|
165
|
-
async getUserById(id: number) { return this.users.find(u => u.id === id); }
|
|
166
|
-
async createUser(data: { name: string; email: string }) {
|
|
167
|
-
const user = { id: this.users.length + 1, ...data };
|
|
168
|
-
this.users.push(user);
|
|
169
|
-
return user;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
class CacheService {
|
|
174
|
-
private store = new Map<string, { data: any; expiry: number }>();
|
|
175
|
-
|
|
176
|
-
async get<T>(key: string): Promise<T | null> {
|
|
177
|
-
const item = this.store.get(key);
|
|
178
|
-
if (!item || item.expiry < Date.now()) return null;
|
|
179
|
-
return item.data;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
async set(key: string, data: any, ttl = 60000) {
|
|
183
|
-
this.store.set(key, { data, expiry: Date.now() + ttl });
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
async invalidate(pattern: string) {
|
|
187
|
-
for (const key of this.store.keys()) {
|
|
188
|
-
if (key.includes(pattern)) this.store.delete(key);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
class MailerService {
|
|
194
|
-
async send(opts: { to: string; subject: string; body?: string }) {
|
|
195
|
-
console.log(`📧 Sending email to ${opts.to}: ${opts.subject}`);
|
|
196
|
-
return true;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// === App Setup ===
|
|
201
|
-
const app = createApp()
|
|
202
|
-
.provide({
|
|
203
|
-
db: new Database(),
|
|
204
|
-
cache: new CacheService(),
|
|
205
|
-
mailer: new MailerService()
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
// === Routes ===
|
|
209
|
-
|
|
210
|
-
// GET /users - with caching
|
|
211
|
-
app.get('/users', async (ctx, { db, cache }) => {
|
|
212
|
-
const cached = await cache.get<any[]>('users');
|
|
213
|
-
if (cached) {
|
|
214
|
-
return { users: cached, source: 'cache' };
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
const users = await db.getUsers();
|
|
218
|
-
await cache.set('users', users);
|
|
219
|
-
return { users, source: 'database' };
|
|
220
|
-
});
|
|
221
|
-
|
|
222
|
-
// GET /users/:id
|
|
223
|
-
app.get('/users/:id', async (ctx, { db }) => {
|
|
224
|
-
const user = await db.getUserById(parseInt(ctx.params.id));
|
|
225
|
-
if (!user) {
|
|
226
|
-
return ctx.response.status(404).json({ error: 'User not found' });
|
|
227
|
-
}
|
|
228
|
-
return { user };
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
// POST /users - create with email notification
|
|
232
|
-
app.post('/users', async (ctx, { db, cache, mailer }) => {
|
|
233
|
-
const user = await db.createUser(ctx.body);
|
|
234
|
-
await cache.invalidate('users');
|
|
235
|
-
await mailer.send({
|
|
236
|
-
to: user.email,
|
|
237
|
-
subject: 'Welcome!',
|
|
238
|
-
body: 'Thanks for joining us.'
|
|
239
|
-
});
|
|
240
|
-
return { user, message: 'User created and welcome email sent' };
|
|
241
|
-
});
|
|
242
|
-
|
|
243
|
-
app.listen(3000);
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
## Best Practices
|
|
247
|
-
|
|
248
|
-
### 1. Define Interface untuk Dependencies
|
|
249
|
-
|
|
250
|
-
```typescript
|
|
251
|
-
interface AppDependencies {
|
|
252
|
-
db: DatabaseService;
|
|
253
|
-
cache: CacheService;
|
|
254
|
-
mailer: MailerService;
|
|
255
|
-
logger: LoggerService;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
const app = createApp().provide<AppDependencies>({ ... });
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
### 2. Gunakan Factory Functions
|
|
262
|
-
|
|
263
|
-
```typescript
|
|
264
|
-
function createDependencies(config: Config): AppDependencies {
|
|
265
|
-
return {
|
|
266
|
-
db: new Database(config.database),
|
|
267
|
-
cache: new Redis(config.redis),
|
|
268
|
-
mailer: new Mailer(config.smtp),
|
|
269
|
-
logger: new Logger(config.logging)
|
|
270
|
-
};
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
const app = createApp().provide(createDependencies(config));
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
### 3. Lazy Initialization
|
|
277
|
-
|
|
278
|
-
```typescript
|
|
279
|
-
class LazyDatabase {
|
|
280
|
-
private _connection?: Connection;
|
|
281
|
-
|
|
282
|
-
async getConnection() {
|
|
283
|
-
if (!this._connection) {
|
|
284
|
-
this._connection = await Database.connect();
|
|
285
|
-
}
|
|
286
|
-
return this._connection;
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
### 4. Testing dengan Mock Dependencies
|
|
292
|
-
|
|
293
|
-
```typescript
|
|
294
|
-
// test/users.test.ts
|
|
295
|
-
import { createApp } from 'nexus';
|
|
296
|
-
import { TestClient } from 'nexus/testing';
|
|
297
|
-
|
|
298
|
-
const mockDb = {
|
|
299
|
-
getUsers: jest.fn().mockResolvedValue([{ id: 1, name: 'Test' }])
|
|
300
|
-
};
|
|
301
|
-
|
|
302
|
-
const app = createApp().provide({ db: mockDb });
|
|
303
|
-
app.get('/users', async (ctx, { db }) => {
|
|
304
|
-
return { users: await db.getUsers() };
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
const client = new TestClient(app);
|
|
308
|
-
|
|
309
|
-
test('GET /users returns users', async () => {
|
|
310
|
-
const res = await client.get('/users');
|
|
311
|
-
expect(res.status).toBe(200);
|
|
312
|
-
expect(mockDb.getUsers).toHaveBeenCalled();
|
|
313
|
-
});
|
|
314
|
-
```
|
|
315
|
-
|
|
316
|
-
## Comparison dengan Framework Lain
|
|
317
|
-
|
|
318
|
-
| Feature | Nexus | Express | Fastify | NestJS |
|
|
319
|
-
|---------|-------|---------|---------|--------|
|
|
320
|
-
| Built-in DI | ✅ | ❌ | ❌ | ✅ |
|
|
321
|
-
| Type-safe | ✅ | ❌ | Partial | ✅ |
|
|
322
|
-
| Zero config | ✅ | - | - | ❌ |
|
|
323
|
-
| Decorator-free | ✅ | - | - | ❌ |
|
|
324
|
-
|
|
325
|
-
## See Also
|
|
326
|
-
|
|
327
|
-
- [Lifecycle Hooks](./28-lifecycle-hooks.md) - Request lifecycle hooks
|
|
328
|
-
- [Context Store](./26-context-store.md) - State management
|
|
329
|
-
- [Testing](./24-testing-utilities.md) - Testing with mock dependencies
|