te.js 2.1.6 → 2.2.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.
Files changed (55) hide show
  1. package/README.md +1 -12
  2. package/auto-docs/analysis/handler-analyzer.test.js +106 -0
  3. package/auto-docs/analysis/source-resolver.test.js +58 -0
  4. package/auto-docs/constants.js +13 -2
  5. package/auto-docs/openapi/generator.js +7 -5
  6. package/auto-docs/openapi/generator.test.js +132 -0
  7. package/auto-docs/openapi/spec-builders.js +39 -19
  8. package/cli/docs-command.js +44 -36
  9. package/cors/index.test.js +82 -0
  10. package/docs/README.md +1 -2
  11. package/docs/api-reference.md +124 -186
  12. package/docs/configuration.md +0 -13
  13. package/docs/getting-started.md +19 -21
  14. package/docs/rate-limiting.md +59 -58
  15. package/lib/llm/client.js +7 -2
  16. package/lib/llm/index.js +14 -1
  17. package/lib/llm/parse.test.js +60 -0
  18. package/package.json +3 -1
  19. package/radar/index.js +382 -0
  20. package/rate-limit/base.js +12 -15
  21. package/rate-limit/index.js +19 -22
  22. package/rate-limit/index.test.js +93 -0
  23. package/rate-limit/storage/memory.js +13 -13
  24. package/rate-limit/storage/redis-install.js +70 -0
  25. package/rate-limit/storage/redis.js +94 -52
  26. package/server/ammo/body-parser.js +156 -152
  27. package/server/ammo/body-parser.test.js +79 -0
  28. package/server/ammo/enhancer.js +8 -4
  29. package/server/ammo.js +138 -12
  30. package/server/context/request-context.js +51 -0
  31. package/server/context/request-context.test.js +53 -0
  32. package/server/endpoint.js +15 -0
  33. package/server/error.js +56 -3
  34. package/server/error.test.js +45 -0
  35. package/server/errors/channels/channels.test.js +148 -0
  36. package/server/errors/channels/index.js +1 -1
  37. package/server/errors/llm-cache.js +1 -1
  38. package/server/errors/llm-cache.test.js +160 -0
  39. package/server/errors/llm-error-service.js +1 -1
  40. package/server/errors/llm-rate-limiter.test.js +105 -0
  41. package/server/files/uploader.js +38 -26
  42. package/server/handler.js +1 -1
  43. package/server/targets/registry.js +3 -3
  44. package/server/targets/registry.test.js +108 -0
  45. package/te.js +233 -183
  46. package/utils/auto-register.js +1 -1
  47. package/utils/configuration.js +23 -9
  48. package/utils/configuration.test.js +58 -0
  49. package/utils/errors-llm-config.js +74 -8
  50. package/utils/request-logger.js +49 -3
  51. package/utils/startup.js +80 -0
  52. package/database/index.js +0 -165
  53. package/database/mongodb.js +0 -146
  54. package/database/redis.js +0 -201
  55. package/docs/database.md +0 -390
@@ -18,15 +18,15 @@ const app = new Tejas(options);
18
18
 
19
19
  #### Options
20
20
 
21
- | Option | Type | Default | Description |
22
- |--------|------|---------|-------------|
23
- | `entry` | string | *(auto-resolved)* | Entry file for `tejas fly` |
24
- | `port` | number | `1403` | Server port |
25
- | `log.http_requests` | boolean | `false` | Enable request logging |
26
- | `log.exceptions` | boolean | `false` | Enable error logging |
27
- | `body.max_size` | number | `10485760` (10 MB) | Max body size (bytes) |
28
- | `body.timeout` | number | `30000` (30 s) | Body parsing timeout (ms) |
29
- | `dir.targets` | string | `"targets"` | Directory for auto-discovered `.target.js` files |
21
+ | Option | Type | Default | Description |
22
+ | ------------------- | ------- | ------------------ | ------------------------------------------------ |
23
+ | `entry` | string | _(auto-resolved)_ | Entry file for `tejas fly` |
24
+ | `port` | number | `1403` | Server port |
25
+ | `log.http_requests` | boolean | `false` | Enable request logging |
26
+ | `log.exceptions` | boolean | `false` | Enable error logging |
27
+ | `body.max_size` | number | `10485760` (10 MB) | Max body size (bytes) |
28
+ | `body.timeout` | number | `30000` (30 s) | Body parsing timeout (ms) |
29
+ | `dir.targets` | string | `"targets"` | Directory for auto-discovered `.target.js` files |
30
30
 
31
31
  See [Configuration](./configuration.md) for all options including the `docs` section.
32
32
 
@@ -40,44 +40,6 @@ Register global middleware. These run for every incoming request.
40
40
  app.midair(middleware1, middleware2);
41
41
  ```
42
42
 
43
- #### withRedis(config)
44
-
45
- Initialize a Redis connection. Auto-installs the `redis` package if needed.
46
-
47
- ```javascript
48
- app.withRedis({
49
- url: 'redis://localhost:6379',
50
- isCluster: false
51
- });
52
- ```
53
-
54
- | Option | Type | Default | Description |
55
- |--------|------|---------|-------------|
56
- | `url` | string | — | Redis connection URL |
57
- | `isCluster` | boolean | `false` | Use Redis Cluster |
58
- | `socket.host` | string | — | Redis host |
59
- | `socket.port` | number | — | Redis port |
60
- | `socket.tls` | boolean | `false` | Use TLS |
61
- | `password` | string | — | Redis password |
62
-
63
- **Returns:** `Promise<Tejas>` (for chaining)
64
-
65
- #### withMongo(config)
66
-
67
- Initialize a MongoDB connection. Auto-installs `mongoose` if needed.
68
-
69
- ```javascript
70
- app.withMongo({
71
- uri: 'mongodb://localhost:27017/myapp'
72
- });
73
- ```
74
-
75
- | Option | Type | Description |
76
- |--------|------|-------------|
77
- | `uri` | string | MongoDB connection URI |
78
-
79
- **Returns:** `Tejas` (for chaining)
80
-
81
43
  #### withRateLimit(config)
82
44
 
83
45
  Enable global rate limiting.
@@ -87,22 +49,22 @@ app.withRateLimit({
87
49
  maxRequests: 100,
88
50
  timeWindowSeconds: 60,
89
51
  algorithm: 'sliding-window',
90
- store: 'memory'
52
+ store: 'memory', // or { type: 'redis', url: 'redis://...' }
91
53
  });
92
54
  ```
93
55
 
94
- | Option | Type | Default | Description |
95
- |--------|------|---------|-------------|
96
- | `maxRequests` | number | `60` | Max requests per window |
97
- | `timeWindowSeconds` | number | `60` | Time window in seconds |
98
- | `algorithm` | string | `'sliding-window'` | `'sliding-window'`, `'token-bucket'`, or `'fixed-window'` |
99
- | `store` | string | `'memory'` | `'memory'` or `'redis'` |
100
- | `keyGenerator` | function | `(ammo) => ammo.ip` | Generates unique key per client |
101
- | `keyPrefix` | string | `'rl:'` | Storage key prefix |
102
- | `headerFormat.type` | string | `'standard'` | `'standard'`, `'legacy'`, or `'both'` |
103
- | `headerFormat.draft7` | boolean | `false` | Include `RateLimit-Policy` header |
104
- | `headerFormat.draft8` | boolean | `false` | Use delta-seconds for `RateLimit-Reset` |
105
- | `onRateLimited` | function | — | Custom handler when rate limited |
56
+ | Option | Type | Default | Description |
57
+ | --------------------- | -------------- | ------------------- | ------------------------------------------------------------------------- |
58
+ | `maxRequests` | number | `60` | Max requests per window |
59
+ | `timeWindowSeconds` | number | `60` | Time window in seconds |
60
+ | `algorithm` | string | `'sliding-window'` | `'sliding-window'`, `'token-bucket'`, or `'fixed-window'` |
61
+ | `store` | string\|Object | `'memory'` | `'memory'` or `{ type: 'redis', url: '...' }` for distributed deployments |
62
+ | `keyGenerator` | function | `(ammo) => ammo.ip` | Generates unique key per client |
63
+ | `keyPrefix` | string | `'rl:'` | Storage key prefix |
64
+ | `headerFormat.type` | string | `'standard'` | `'standard'`, `'legacy'`, or `'both'` |
65
+ | `headerFormat.draft7` | boolean | `false` | Include `RateLimit-Policy` header |
66
+ | `headerFormat.draft8` | boolean | `false` | Use delta-seconds for `RateLimit-Reset` |
67
+ | `onRateLimited` | function | — | Custom handler when rate limited |
106
68
 
107
69
  **Returns:** `Tejas` (for chaining)
108
70
 
@@ -113,30 +75,25 @@ Serve an interactive API documentation UI (Scalar) from a pre-generated OpenAPI
113
75
  ```javascript
114
76
  app.serveDocs({
115
77
  specPath: './openapi.json',
116
- scalarConfig: { layout: 'modern', theme: 'default' }
78
+ scalarConfig: { layout: 'modern', theme: 'default' },
117
79
  });
118
80
  ```
119
81
 
120
- | Option | Type | Default | Description |
121
- |--------|------|---------|-------------|
122
- | `specPath` | string | `'./openapi.json'` | Path to the OpenAPI spec file |
123
- | `scalarConfig` | object | *(defaults)* | Scalar UI configuration options |
82
+ | Option | Type | Default | Description |
83
+ | -------------- | ------ | ------------------ | ------------------------------- |
84
+ | `specPath` | string | `'./openapi.json'` | Path to the OpenAPI spec file |
85
+ | `scalarConfig` | object | _(defaults)_ | Scalar UI configuration options |
124
86
 
125
87
  Registers `GET /docs` (HTML UI) and `GET /docs/openapi.json` (spec JSON).
126
88
 
127
89
  **Returns:** `Tejas` (for chaining)
128
90
 
129
- #### takeoff(options)
91
+ #### takeoff()
130
92
 
131
- Start the HTTP server. Optionally initializes database connections.
93
+ Start the HTTP server.
132
94
 
133
95
  ```javascript
134
96
  app.takeoff();
135
-
136
- app.takeoff({
137
- withRedis: { url: 'redis://localhost:6379' },
138
- withMongo: { uri: 'mongodb://localhost:27017/db' }
139
- });
140
97
  ```
141
98
 
142
99
  ---
@@ -153,9 +110,9 @@ import { Target } from 'te.js';
153
110
  const target = new Target(basePath);
154
111
  ```
155
112
 
156
- | Parameter | Type | Default | Description |
157
- |-----------|------|---------|-------------|
158
- | `basePath` | string | `''` | Base path for all routes in this target |
113
+ | Parameter | Type | Default | Description |
114
+ | ---------- | ------ | ------- | --------------------------------------- |
115
+ | `basePath` | string | `''` | Base path for all routes in this target |
159
116
 
160
117
  ### Methods
161
118
 
@@ -179,20 +136,25 @@ target.register('/path', handler);
179
136
  target.register('/path', middleware1, middleware2, handler);
180
137
 
181
138
  // With metadata (for auto-docs)
182
- target.register('/path', {
183
- summary: 'Description',
184
- methods: ['GET', 'POST'],
185
- request: { name: { type: 'string', required: true } },
186
- response: { 200: { description: 'Success' } }
187
- }, middleware1, handler);
139
+ target.register(
140
+ '/path',
141
+ {
142
+ summary: 'Description',
143
+ methods: ['GET', 'POST'],
144
+ request: { name: { type: 'string', required: true } },
145
+ response: { 200: { description: 'Success' } },
146
+ },
147
+ middleware1,
148
+ handler,
149
+ );
188
150
  ```
189
151
 
190
- | Parameter | Type | Description |
191
- |-----------|------|-------------|
192
- | `path` | string | Route path (supports `:param` for parameters) |
193
- | `metadata` | object | *(optional)* Metadata for OpenAPI generation |
194
- | `middlewares` | function[] | *(optional)* Route-specific middleware |
195
- | `handler` | function | Route handler `(ammo) => {}` (always the last argument) |
152
+ | Parameter | Type | Description |
153
+ | ------------- | ---------- | ------------------------------------------------------- |
154
+ | `path` | string | Route path (supports `:param` for parameters) |
155
+ | `metadata` | object | _(optional)_ Metadata for OpenAPI generation |
156
+ | `middlewares` | function[] | _(optional)_ Route-specific middleware |
157
+ | `handler` | function | Route handler `(ammo) => {}` (always the last argument) |
196
158
 
197
159
  ---
198
160
 
@@ -204,47 +166,47 @@ Request/response wrapper created for each incoming request.
204
166
 
205
167
  #### HTTP Method Flags
206
168
 
207
- | Property | Type | Description |
208
- |----------|------|-------------|
209
- | `GET` | boolean | `true` if GET request |
210
- | `POST` | boolean | `true` if POST request |
211
- | `PUT` | boolean | `true` if PUT request |
212
- | `DELETE` | boolean | `true` if DELETE request |
213
- | `PATCH` | boolean | `true` if PATCH request |
214
- | `HEAD` | boolean | `true` if HEAD request |
169
+ | Property | Type | Description |
170
+ | --------- | ------- | ------------------------- |
171
+ | `GET` | boolean | `true` if GET request |
172
+ | `POST` | boolean | `true` if POST request |
173
+ | `PUT` | boolean | `true` if PUT request |
174
+ | `DELETE` | boolean | `true` if DELETE request |
175
+ | `PATCH` | boolean | `true` if PATCH request |
176
+ | `HEAD` | boolean | `true` if HEAD request |
215
177
  | `OPTIONS` | boolean | `true` if OPTIONS request |
216
178
 
217
179
  #### Request Data
218
180
 
219
- | Property | Type | Description |
220
- |----------|------|-------------|
221
- | `method` | string | HTTP method string (e.g. `'GET'`) |
181
+ | Property | Type | Description |
182
+ | --------- | ------ | ------------------------------------------------------------------------------- |
183
+ | `method` | string | HTTP method string (e.g. `'GET'`) |
222
184
  | `payload` | object | Merged: query params + body + route params (route params have highest priority) |
223
- | `headers` | object | Request headers (lowercase keys) |
224
- | `ip` | string | Client IP address |
185
+ | `headers` | object | Request headers (lowercase keys) |
186
+ | `ip` | string | Client IP address |
225
187
 
226
188
  #### URL Data
227
189
 
228
- | Property | Type | Description |
229
- |----------|------|-------------|
230
- | `path` | string | Full URL path with query string |
231
- | `endpoint` | string | Path without query string |
232
- | `protocol` | string | `'http'` or `'https'` |
233
- | `hostname` | string | Request hostname |
234
- | `fullURL` | string | Complete URL |
190
+ | Property | Type | Description |
191
+ | ---------- | ------ | ------------------------------- |
192
+ | `path` | string | Full URL path with query string |
193
+ | `endpoint` | string | Path without query string |
194
+ | `protocol` | string | `'http'` or `'https'` |
195
+ | `hostname` | string | Request hostname |
196
+ | `fullURL` | string | Complete URL |
235
197
 
236
198
  #### Raw Objects
237
199
 
238
- | Property | Type | Description |
239
- |----------|------|-------------|
240
- | `req` | IncomingMessage | Node.js request object |
241
- | `res` | ServerResponse | Node.js response object |
200
+ | Property | Type | Description |
201
+ | -------- | --------------- | ----------------------- |
202
+ | `req` | IncomingMessage | Node.js request object |
203
+ | `res` | ServerResponse | Node.js response object |
242
204
 
243
205
  #### Response Data
244
206
 
245
- | Property | Type | Description |
246
- |----------|------|-------------|
247
- | `dispatchedData` | any | The data sent via the most recent `fire()` call. `undefined` until `fire()` is called |
207
+ | Property | Type | Description |
208
+ | ---------------- | ---- | ------------------------------------------------------------------------------------- |
209
+ | `dispatchedData` | any | The data sent via the most recent `fire()` call. `undefined` until `fire()` is called |
248
210
 
249
211
  ### Methods
250
212
 
@@ -252,41 +214,41 @@ Request/response wrapper created for each incoming request.
252
214
 
253
215
  Send a response to the client.
254
216
 
255
- | Signature | Status | Body | Content-Type |
256
- |-----------|--------|------|-------------|
257
- | `fire()` | 204 | *(empty)* | — |
258
- | `fire("text")` | 200 | text | `text/plain` |
259
- | `fire({ json })` | 200 | JSON string | `application/json` |
260
- | `fire(201)` | 201 | status message | `text/plain` |
261
- | `fire(201, data)` | 201 | data | auto-detected |
262
- | `fire(200, html, "text/html")` | 200 | html | `text/html` |
217
+ | Signature | Status | Body | Content-Type |
218
+ | ------------------------------ | ------ | -------------- | ------------------ |
219
+ | `fire()` | 204 | _(empty)_ | — |
220
+ | `fire("text")` | 200 | text | `text/plain` |
221
+ | `fire({ json })` | 200 | JSON string | `application/json` |
222
+ | `fire(201)` | 201 | status message | `text/plain` |
223
+ | `fire(201, data)` | 201 | data | auto-detected |
224
+ | `fire(200, html, "text/html")` | 200 | html | `text/html` |
263
225
 
264
226
  #### throw()
265
227
 
266
228
  Send an error response. When [LLM-inferred errors](./error-handling.md#llm-inferred-errors) are enabled (`errors.llm.enabled`), calls without explicit status code or message use an LLM to infer code and message; explicit code/message always override.
267
229
 
268
- | Signature | Behavior |
269
- |-----------|----------|
270
- | `throw()` | 500 "Internal Server Error" (or LLM-inferred when `errors.llm.enabled`) |
271
- | `throw(404)` | 404 with default status message |
272
- | `throw(404, "msg")` | 404 with custom message |
273
- | `throw(new TejError(code, msg))` | Uses TejError's code and message |
274
- | `throw(new Error("msg"))` | 500 with error message, or LLM-inferred when `errors.llm.enabled` |
275
- | LLM-inferred (no explicit code/message, `errors.llm.enabled`) | Status and message derived by LLM from context |
230
+ | Signature | Behavior |
231
+ | ------------------------------------------------------------- | ----------------------------------------------------------------------- |
232
+ | `throw()` | 500 "Internal Server Error" (or LLM-inferred when `errors.llm.enabled`) |
233
+ | `throw(404)` | 404 with default status message |
234
+ | `throw(404, "msg")` | 404 with custom message |
235
+ | `throw(new TejError(code, msg))` | Uses TejError's code and message |
236
+ | `throw(new Error("msg"))` | 500 with error message, or LLM-inferred when `errors.llm.enabled` |
237
+ | LLM-inferred (no explicit code/message, `errors.llm.enabled`) | Status and message derived by LLM from context |
276
238
 
277
239
  #### redirect(url, statusCode)
278
240
 
279
241
  HTTP redirect.
280
242
 
281
243
  ```javascript
282
- ammo.redirect('/new-path'); // 302 temporary
283
- ammo.redirect('/new-path', 301); // 301 permanent
244
+ ammo.redirect('/new-path'); // 302 temporary
245
+ ammo.redirect('/new-path', 301); // 301 permanent
284
246
  ```
285
247
 
286
- | Parameter | Type | Default | Description |
287
- |-----------|------|---------|-------------|
288
- | `url` | string | — | Redirect URL |
289
- | `statusCode` | number | `302` | HTTP status code |
248
+ | Parameter | Type | Default | Description |
249
+ | ------------ | ------ | ------- | ---------------- |
250
+ | `url` | string | — | Redirect URL |
251
+ | `statusCode` | number | `302` | HTTP status code |
290
252
 
291
253
  #### notFound()
292
254
 
@@ -316,27 +278,27 @@ import { TejError } from 'te.js';
316
278
  throw new TejError(statusCode, message);
317
279
  ```
318
280
 
319
- | Parameter | Type | Description |
320
- |-----------|------|-------------|
281
+ | Parameter | Type | Description |
282
+ | ------------ | ------ | ----------------------------------------------------------------------- |
321
283
  | `statusCode` | number | HTTP status code (optional when LLM infers; otherwise use for override) |
322
- | `message` | string | Error message (optional when LLM infers; otherwise use for override) |
284
+ | `message` | string | Error message (optional when LLM infers; otherwise use for override) |
323
285
 
324
- | Property | Type | Description |
325
- |----------|------|-------------|
326
- | `code` | number | HTTP status code |
327
- | `message` | string | Error message |
328
- | `name` | string | `'TejError'` |
286
+ | Property | Type | Description |
287
+ | --------- | ------ | ---------------- |
288
+ | `code` | number | HTTP status code |
289
+ | `message` | string | Error message |
290
+ | `name` | string | `'TejError'` |
329
291
 
330
292
  ### BodyParserError
331
293
 
332
294
  A subclass of `TejError` thrown during request body parsing:
333
295
 
334
- | Status | Condition |
335
- |--------|-----------|
336
- | 400 | Malformed JSON, invalid URL-encoded data, or corrupted multipart data |
337
- | 408 | Body parsing timed out |
338
- | 413 | Request body exceeds `body.max_size` |
339
- | 415 | Unsupported content type |
296
+ | Status | Condition |
297
+ | ------ | --------------------------------------------------------------------- |
298
+ | 400 | Malformed JSON, invalid URL-encoded data, or corrupted multipart data |
299
+ | 408 | Body parsing timed out |
300
+ | 413 | Request body exceeds `body.max_size` |
301
+ | 415 | Unsupported content type |
340
302
 
341
303
  ---
342
304
 
@@ -352,10 +314,10 @@ import { TejFileUploader } from 'te.js';
352
314
  const upload = new TejFileUploader(options);
353
315
  ```
354
316
 
355
- | Option | Type | Description |
356
- |--------|------|-------------|
357
- | `destination` | string | Directory to save uploaded files |
358
- | `name` | string | Optional custom filename |
317
+ | Option | Type | Description |
318
+ | ------------- | ------ | ----------------------------------------------- |
319
+ | `destination` | string | Directory to save uploaded files |
320
+ | `name` | string | Optional custom filename |
359
321
  | `maxFileSize` | number | Max file size in bytes (throws 413 if exceeded) |
360
322
 
361
323
  ### Methods
@@ -405,12 +367,12 @@ Get all registered endpoints.
405
367
  ```javascript
406
368
  import { listAllEndpoints } from 'te.js';
407
369
 
408
- const routes = listAllEndpoints(); // ['/', '/users', '/api/data']
409
- const grouped = listAllEndpoints(true); // { users: [...], api: [...] }
370
+ const routes = listAllEndpoints(); // ['/', '/users', '/api/data']
371
+ const grouped = listAllEndpoints(true); // { users: [...], api: [...] }
410
372
  ```
411
373
 
412
- | Parameter | Type | Default | Description |
413
- |-----------|------|---------|-------------|
374
+ | Parameter | Type | Default | Description |
375
+ | --------- | ------- | ------- | --------------------------- |
414
376
  | `grouped` | boolean | `false` | Group by first path segment |
415
377
 
416
378
  ---
@@ -450,30 +412,6 @@ setEnv('CUSTOM_VAR', 'value');
450
412
 
451
413
  ---
452
414
 
453
- ## Database Manager
454
-
455
- ```javascript
456
- import dbManager from 'te.js/database/index.js';
457
-
458
- // Get connection
459
- const redis = dbManager.getConnection('redis');
460
- const mongo = dbManager.getConnection('mongodb');
461
-
462
- // Check connection status
463
- const status = dbManager.hasConnection('redis', {});
464
- // { exists: boolean, initializing: boolean }
465
-
466
- // Close connections
467
- await dbManager.closeConnection('redis');
468
- await dbManager.closeAllConnections();
469
-
470
- // Get all active connections
471
- const connections = dbManager.getActiveConnections();
472
- // Returns: Map
473
- ```
474
-
475
- ---
476
-
477
415
  ## RateLimitStorage Base Class
478
416
 
479
417
  Abstract base class for custom rate limit storage backends:
@@ -482,9 +420,9 @@ Abstract base class for custom rate limit storage backends:
482
420
  import RateLimitStorage from 'te.js/rate-limit/storage/base.js';
483
421
 
484
422
  class CustomStorage extends RateLimitStorage {
485
- async get(key) { } // Return object or null
486
- async set(key, value, ttl) { } // Store with TTL (seconds)
487
- async increment(key) { } // Return new value or null
488
- async delete(key) { } // Remove key
423
+ async get(key) {} // Return object or null
424
+ async set(key, value, ttl) {} // Store with TTL (seconds)
425
+ async increment(key) {} // Return new value or null
426
+ async delete(key) {} // Remove key
489
427
  }
490
428
  ```
@@ -301,19 +301,6 @@ To change the targets directory:
301
301
  }
302
302
  ```
303
303
 
304
- ## Database Configuration
305
-
306
- Database connections are configured via `takeoff()` options, not through the config file:
307
-
308
- ```javascript
309
- app.takeoff({
310
- withRedis: { url: 'redis://localhost:6379' },
311
- withMongo: { uri: 'mongodb://localhost:27017/myapp' },
312
- });
313
- ```
314
-
315
- See [Database Integration](./database.md) for details.
316
-
317
304
  ## Next Steps
318
305
 
319
306
  - [Getting Started](./getting-started.md) — Build your first Tejas application
@@ -8,7 +8,7 @@ Tejas is a lightweight Node.js framework for building powerful backend services.
8
8
  - **Zero-Config Error Handling** — No try-catch needed! Tejas catches all errors automatically
9
9
  - **Clean, Readable Code** — Aviation-inspired naming makes code self-documenting
10
10
  - **Express Compatible** — Use your existing Express middleware
11
- - **Built-in Features** — Rate limiting, file uploads, database connections out of the box
11
+ - **Built-in Features** — Rate limiting, file uploads out of the box
12
12
 
13
13
  ## AI-Assisted Setup (MCP) — Recommended
14
14
 
@@ -35,9 +35,9 @@ The fastest way to start building with Tejas is through your AI assistant. The *
35
35
 
36
36
  Once connected, prompt your assistant naturally:
37
37
 
38
- - *"Scaffold a new te.js project called my-api on port 5000"*
39
- - *"Create a REST API with user CRUD routes using te.js"*
40
- - *"Add a /health endpoint that returns system uptime"*
38
+ - _"Scaffold a new te.js project called my-api on port 5000"_
39
+ - _"Create a REST API with user CRUD routes using te.js"_
40
+ - _"Add a /health endpoint that returns system uptime"_
41
41
 
42
42
  The MCP server provides these tools: `scaffold_project`, `generate_target`, `generate_app_entry`, `generate_config`, `get_documentation`, and `search_docs`.
43
43
 
@@ -101,15 +101,15 @@ Your server is now running on `http://localhost:1403`
101
101
 
102
102
  Tejas uses aviation-inspired naming:
103
103
 
104
- | Term | Express Equivalent | Description |
105
- |------|-------------------|-------------|
106
- | `Tejas` | `express()` | Main application instance |
107
- | `Target` | `Router` | Route grouping |
108
- | `Ammo` | `req` + `res` | Request/response wrapper |
109
- | `fire()` | `res.send()` | Send response |
110
- | `throw()` | Error response | Send error |
111
- | `midair()` | `use()` | Register middleware |
112
- | `takeoff()` | `listen()` | Start server |
104
+ | Term | Express Equivalent | Description |
105
+ | ----------- | ------------------ | ------------------------- |
106
+ | `Tejas` | `express()` | Main application instance |
107
+ | `Target` | `Router` | Route grouping |
108
+ | `Ammo` | `req` + `res` | Request/response wrapper |
109
+ | `fire()` | `res.send()` | Send response |
110
+ | `throw()` | Error response | Send error |
111
+ | `midair()` | `use()` | Register middleware |
112
+ | `takeoff()` | `listen()` | Start server |
113
113
 
114
114
  ### Basic Structure
115
115
 
@@ -150,7 +150,7 @@ Your application never crashes from unhandled exceptions, and clients always rec
150
150
  - [Routing](./routing.md) — Deep dive into the Target-based routing system
151
151
  - [Ammo](./ammo.md) — Master request/response handling
152
152
  - [Middleware](./middleware.md) — Global, target, and route-level middleware
153
- - [Database](./database.md) — Connect to MongoDB or Redis
153
+
154
154
  - [Error Handling](./error-handling.md) — Zero-config error handling
155
155
  - [CLI Reference](./cli.md) — `tejas fly` and doc generation commands
156
156
  - [Auto-Documentation](./auto-docs.md) — Generate OpenAPI specs from your code
@@ -166,8 +166,8 @@ const app = new Tejas({
166
166
  port: 3000,
167
167
  log: {
168
168
  http_requests: true,
169
- exceptions: true
170
- }
169
+ exceptions: true,
170
+ },
171
171
  });
172
172
 
173
173
  // Global middleware
@@ -179,13 +179,11 @@ app.midair((ammo, next) => {
179
179
  // Rate limiting (in-memory)
180
180
  app.withRateLimit({
181
181
  maxRequests: 100,
182
- timeWindowSeconds: 60
182
+ timeWindowSeconds: 60,
183
183
  });
184
184
 
185
- // Start with optional Redis
186
- app.takeoff({
187
- withRedis: { url: 'redis://localhost:6379' }
188
- });
185
+ // Start the server
186
+ app.takeoff();
189
187
  ```
190
188
 
191
189
  ```javascript