te.js 2.2.0 → 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.
- package/README.md +1 -12
- package/docs/README.md +1 -2
- package/docs/api-reference.md +124 -186
- package/docs/configuration.md +0 -13
- package/docs/getting-started.md +19 -21
- package/docs/rate-limiting.md +59 -58
- package/lib/llm/client.js +1 -1
- package/package.json +1 -1
- package/radar/index.js +191 -90
- package/rate-limit/base.js +12 -15
- package/rate-limit/index.js +12 -12
- package/rate-limit/index.test.js +45 -16
- package/rate-limit/storage/memory.js +13 -13
- package/rate-limit/storage/redis-install.js +70 -0
- package/rate-limit/storage/redis.js +94 -52
- package/server/ammo.js +3 -2
- package/te.js +64 -143
- package/utils/errors-llm-config.js +63 -0
- package/utils/startup.js +80 -0
- package/database/index.js +0 -167
- package/database/mongodb.js +0 -152
- package/database/redis.js +0 -210
- package/docs/database.md +0 -390
package/README.md
CHANGED
|
@@ -41,7 +41,6 @@ api.register('/hello/:name', (ammo) => {
|
|
|
41
41
|
app.takeoff();
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
|
|
45
44
|
## Features
|
|
46
45
|
|
|
47
46
|
- **AI-Native (MCP)** — Ship with an MCP server so AI assistants can scaffold projects, generate routes, and write correct code with full framework knowledge
|
|
@@ -50,14 +49,12 @@ app.takeoff();
|
|
|
50
49
|
- **Zero-Config Error Handling** — No try-catch needed! Tejas catches all errors automatically. Opt in to have an LLM determine error code and message when you don't specify them (see [Error Handling](./docs/error-handling.md))
|
|
51
50
|
- **Built-in Rate Limiting** — Three algorithms (Token Bucket, Sliding Window, Fixed Window) with memory or Redis storage
|
|
52
51
|
- **Method Safety & CORS** — Opt-in method restriction per route (`register(path, { methods }, handler)` or `ammo.only('GET')`), global allowed-methods filter, and `app.withCORS()` for cross-origin requests
|
|
53
|
-
- **Database Ready** — First-class Redis and MongoDB support with auto-install of drivers
|
|
54
52
|
- **File Uploads** — Easy file handling with size limits and type validation
|
|
55
53
|
- **Auto-Documentation** — Generate OpenAPI specs from your code with LLM-powered analysis (`tejas generate:docs`)
|
|
56
54
|
- **Interactive API Docs** — Serve a Scalar API reference UI with `app.serveDocs()`
|
|
57
55
|
- **Auto-Discovery** — Automatic route registration from `.target.js` files
|
|
58
56
|
- **Request Logging** — Built-in HTTP request and exception logging
|
|
59
57
|
|
|
60
|
-
|
|
61
58
|
## AI-Assisted Setup (MCP)
|
|
62
59
|
|
|
63
60
|
> **Recommended** — The best way to get started with Tejas in the age of AI.
|
|
@@ -79,8 +76,7 @@ The [Tejas MCP server](https://www.npmjs.com/package/tejas-mcp) gives your IDE's
|
|
|
79
76
|
|
|
80
77
|
**Other MCP-compatible IDEs** — run `npx tejas-mcp` as the server command (stdio transport, no config needed).
|
|
81
78
|
|
|
82
|
-
Once connected, prompt your AI with things like
|
|
83
|
-
|
|
79
|
+
Once connected, prompt your AI with things like _"Scaffold a new te.js project called my-api"_ or _"Create a REST API with user CRUD routes"_ — the assistant will generate framework-correct code using real te.js patterns.
|
|
84
80
|
|
|
85
81
|
## Quick Start
|
|
86
82
|
|
|
@@ -132,7 +128,6 @@ node index.js
|
|
|
132
128
|
# Server running at http://localhost:3000
|
|
133
129
|
```
|
|
134
130
|
|
|
135
|
-
|
|
136
131
|
## Core Concepts
|
|
137
132
|
|
|
138
133
|
| Tejas Term | Purpose | Express Equivalent |
|
|
@@ -144,7 +139,6 @@ node index.js
|
|
|
144
139
|
| `midair()` | Register middleware | `use()` |
|
|
145
140
|
| `takeoff()` | Start server | `listen()` |
|
|
146
141
|
|
|
147
|
-
|
|
148
142
|
## CLI
|
|
149
143
|
|
|
150
144
|
```bash
|
|
@@ -153,7 +147,6 @@ tejas generate:docs [--ci] # Generate OpenAPI docs (interactive or CI mode)
|
|
|
153
147
|
tejas docs:on-push # Auto-generate docs when pushing to production branch
|
|
154
148
|
```
|
|
155
149
|
|
|
156
|
-
|
|
157
150
|
## API Documentation
|
|
158
151
|
|
|
159
152
|
Generate and serve interactive API docs:
|
|
@@ -168,7 +161,6 @@ app.takeoff();
|
|
|
168
161
|
// Visit http://localhost:1403/docs
|
|
169
162
|
```
|
|
170
163
|
|
|
171
|
-
|
|
172
164
|
## Documentation
|
|
173
165
|
|
|
174
166
|
For comprehensive documentation, see the [docs folder](./docs) or visit [tejas-documentation.vercel.app](https://tejas-documentation.vercel.app).
|
|
@@ -179,19 +171,16 @@ For comprehensive documentation, see the [docs folder](./docs) or visit [tejas-d
|
|
|
179
171
|
- [Ammo](./docs/ammo.md) — Request/response handling
|
|
180
172
|
- [Middleware](./docs/middleware.md) — Global, target, and route middleware
|
|
181
173
|
- [Error Handling](./docs/error-handling.md) — Zero-config error handling
|
|
182
|
-
- [Database](./docs/database.md) — Redis and MongoDB integration
|
|
183
174
|
- [Rate Limiting](./docs/rate-limiting.md) — API protection
|
|
184
175
|
- [File Uploads](./docs/file-uploads.md) — File handling
|
|
185
176
|
- [CLI Reference](./docs/cli.md) — Command-line interface
|
|
186
177
|
- [Auto-Documentation](./docs/auto-docs.md) — OpenAPI generation
|
|
187
178
|
- [API Reference](./docs/api-reference.md) — Complete API docs
|
|
188
179
|
|
|
189
|
-
|
|
190
180
|
## Contributing
|
|
191
181
|
|
|
192
182
|
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
193
183
|
|
|
194
|
-
|
|
195
184
|
## License
|
|
196
185
|
|
|
197
186
|
ISC © [Hirak Chhatbar](https://github.com/hirakchhatbar)
|
package/docs/README.md
CHANGED
|
@@ -18,8 +18,7 @@ Welcome to the documentation for **Tejas** — a Node.js framework for building
|
|
|
18
18
|
|
|
19
19
|
### Features
|
|
20
20
|
|
|
21
|
-
- [
|
|
22
|
-
- [Rate Limiting](./rate-limiting.md) — Three algorithms, two storage backends, custom headers
|
|
21
|
+
- [Rate Limiting](./rate-limiting.md) — Three algorithms, memory or Redis storage, custom headers
|
|
23
22
|
- [File Uploads](./file-uploads.md) — Single and multiple file handling with validation
|
|
24
23
|
|
|
25
24
|
### Tooling
|
package/docs/api-reference.md
CHANGED
|
@@ -18,15 +18,15 @@ const app = new Tejas(options);
|
|
|
18
18
|
|
|
19
19
|
#### Options
|
|
20
20
|
|
|
21
|
-
| Option
|
|
22
|
-
|
|
23
|
-
| `entry`
|
|
24
|
-
| `port`
|
|
25
|
-
| `log.http_requests` | boolean | `false`
|
|
26
|
-
| `log.exceptions`
|
|
27
|
-
| `body.max_size`
|
|
28
|
-
| `body.timeout`
|
|
29
|
-
| `dir.targets`
|
|
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
|
|
95
|
-
|
|
96
|
-
| `maxRequests`
|
|
97
|
-
| `timeWindowSeconds`
|
|
98
|
-
| `algorithm`
|
|
99
|
-
| `store`
|
|
100
|
-
| `keyGenerator`
|
|
101
|
-
| `keyPrefix`
|
|
102
|
-
| `headerFormat.type`
|
|
103
|
-
| `headerFormat.draft7` | boolean
|
|
104
|
-
| `headerFormat.draft8` | boolean
|
|
105
|
-
| `onRateLimited`
|
|
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
|
|
121
|
-
|
|
122
|
-
| `specPath`
|
|
123
|
-
| `scalarConfig` | object |
|
|
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(
|
|
91
|
+
#### takeoff()
|
|
130
92
|
|
|
131
|
-
Start the HTTP server.
|
|
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
|
|
157
|
-
|
|
158
|
-
| `basePath` | string | `''`
|
|
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(
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
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
|
|
191
|
-
|
|
192
|
-
| `path`
|
|
193
|
-
| `metadata`
|
|
194
|
-
| `middlewares` | function[] |
|
|
195
|
-
| `handler`
|
|
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
|
|
208
|
-
|
|
209
|
-
| `GET`
|
|
210
|
-
| `POST`
|
|
211
|
-
| `PUT`
|
|
212
|
-
| `DELETE`
|
|
213
|
-
| `PATCH`
|
|
214
|
-
| `HEAD`
|
|
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
|
|
220
|
-
|
|
221
|
-
| `method`
|
|
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`
|
|
185
|
+
| `headers` | object | Request headers (lowercase keys) |
|
|
186
|
+
| `ip` | string | Client IP address |
|
|
225
187
|
|
|
226
188
|
#### URL Data
|
|
227
189
|
|
|
228
|
-
| Property
|
|
229
|
-
|
|
230
|
-
| `path`
|
|
231
|
-
| `endpoint` | string | Path without query string
|
|
232
|
-
| `protocol` | string | `'http'` or `'https'`
|
|
233
|
-
| `hostname` | string | Request hostname
|
|
234
|
-
| `fullURL`
|
|
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
|
|
239
|
-
|
|
240
|
-
| `req`
|
|
241
|
-
| `res`
|
|
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
|
|
246
|
-
|
|
247
|
-
| `dispatchedData` | any
|
|
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
|
|
256
|
-
|
|
257
|
-
| `fire()`
|
|
258
|
-
| `fire("text")`
|
|
259
|
-
| `fire({ json })`
|
|
260
|
-
| `fire(201)`
|
|
261
|
-
| `fire(201, data)`
|
|
262
|
-
| `fire(200, html, "text/html")` | 200
|
|
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
|
|
269
|
-
|
|
270
|
-
| `throw()`
|
|
271
|
-
| `throw(404)`
|
|
272
|
-
| `throw(404, "msg")`
|
|
273
|
-
| `throw(new TejError(code, msg))`
|
|
274
|
-
| `throw(new Error("msg"))`
|
|
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');
|
|
283
|
-
ammo.redirect('/new-path', 301);
|
|
244
|
+
ammo.redirect('/new-path'); // 302 temporary
|
|
245
|
+
ammo.redirect('/new-path', 301); // 301 permanent
|
|
284
246
|
```
|
|
285
247
|
|
|
286
|
-
| Parameter
|
|
287
|
-
|
|
288
|
-
| `url`
|
|
289
|
-
| `statusCode` | number | `302`
|
|
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
|
|
320
|
-
|
|
281
|
+
| Parameter | Type | Description |
|
|
282
|
+
| ------------ | ------ | ----------------------------------------------------------------------- |
|
|
321
283
|
| `statusCode` | number | HTTP status code (optional when LLM infers; otherwise use for override) |
|
|
322
|
-
| `message`
|
|
284
|
+
| `message` | string | Error message (optional when LLM infers; otherwise use for override) |
|
|
323
285
|
|
|
324
|
-
| Property
|
|
325
|
-
|
|
326
|
-
| `code`
|
|
327
|
-
| `message` | string | Error message
|
|
328
|
-
| `name`
|
|
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
|
|
337
|
-
| 408
|
|
338
|
-
| 413
|
|
339
|
-
| 415
|
|
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
|
|
356
|
-
|
|
357
|
-
| `destination` | string | Directory to save uploaded files
|
|
358
|
-
| `name`
|
|
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();
|
|
409
|
-
const grouped = listAllEndpoints(true);
|
|
370
|
+
const routes = listAllEndpoints(); // ['/', '/users', '/api/data']
|
|
371
|
+
const grouped = listAllEndpoints(true); // { users: [...], api: [...] }
|
|
410
372
|
```
|
|
411
373
|
|
|
412
|
-
| Parameter | Type
|
|
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) {
|
|
486
|
-
async set(key, value, ttl) {
|
|
487
|
-
async increment(key) {
|
|
488
|
-
async delete(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
|
```
|
package/docs/configuration.md
CHANGED
|
@@ -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
|
package/docs/getting-started.md
CHANGED
|
@@ -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
|
|
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
|
-
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
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
|
|
105
|
-
|
|
106
|
-
| `Tejas`
|
|
107
|
-
| `Target`
|
|
108
|
-
| `Ammo`
|
|
109
|
-
| `fire()`
|
|
110
|
-
| `throw()`
|
|
111
|
-
| `midair()`
|
|
112
|
-
| `takeoff()` | `listen()`
|
|
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
|
-
|
|
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
|
|
186
|
-
app.takeoff(
|
|
187
|
-
withRedis: { url: 'redis://localhost:6379' }
|
|
188
|
-
});
|
|
185
|
+
// Start the server
|
|
186
|
+
app.takeoff();
|
|
189
187
|
```
|
|
190
188
|
|
|
191
189
|
```javascript
|