@flight-framework/http 0.0.2 → 0.0.4
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 +485 -61
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,40 @@
|
|
|
1
1
|
# @flight-framework/http
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
HTTP server for Flight Framework. Built on Web Standard APIs with radix-tree routing for maximum performance. Runs on Node.js, Bun, and Deno.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Features](#features)
|
|
8
|
+
- [Installation](#installation)
|
|
9
|
+
- [Quick Start](#quick-start)
|
|
10
|
+
- [Routing](#routing)
|
|
11
|
+
- [Route Parameters](#route-parameters)
|
|
12
|
+
- [Middleware](#middleware)
|
|
13
|
+
- [Context API](#context-api)
|
|
14
|
+
- [Request Handling](#request-handling)
|
|
15
|
+
- [Response Helpers](#response-helpers)
|
|
16
|
+
- [Error Handling](#error-handling)
|
|
17
|
+
- [Sub-Routers](#sub-routers)
|
|
18
|
+
- [Runtime Adapters](#runtime-adapters)
|
|
19
|
+
- [Static Files](#static-files)
|
|
20
|
+
- [CORS](#cors)
|
|
21
|
+
- [API Reference](#api-reference)
|
|
22
|
+
- [License](#license)
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Features
|
|
27
|
+
|
|
28
|
+
- Radix-tree routing for fast path matching
|
|
29
|
+
- Native Request/Response APIs (Web Standard)
|
|
30
|
+
- Multi-runtime support: Node.js, Bun, Deno
|
|
31
|
+
- Middleware with async/await
|
|
32
|
+
- Type-safe route parameters
|
|
33
|
+
- Built-in helpers for JSON, HTML, redirects
|
|
34
|
+
- Zero external runtime dependencies
|
|
35
|
+
- Full TypeScript support
|
|
36
|
+
|
|
37
|
+
---
|
|
4
38
|
|
|
5
39
|
## Installation
|
|
6
40
|
|
|
@@ -8,6 +42,8 @@ Ultra-fast HTTP server for Flight Framework, built on Web Standards.
|
|
|
8
42
|
npm install @flight-framework/http
|
|
9
43
|
```
|
|
10
44
|
|
|
45
|
+
---
|
|
46
|
+
|
|
11
47
|
## Quick Start
|
|
12
48
|
|
|
13
49
|
```typescript
|
|
@@ -16,140 +52,528 @@ import { serve } from '@flight-framework/http/node';
|
|
|
16
52
|
|
|
17
53
|
const app = createServer();
|
|
18
54
|
|
|
19
|
-
// Simple JSON response
|
|
20
55
|
app.get('/', (c) => c.json({ message: 'Hello Flight!' }));
|
|
21
56
|
|
|
22
|
-
// Route params
|
|
23
57
|
app.get('/users/:id', (c) => {
|
|
24
58
|
return c.json({ userId: c.params.id });
|
|
25
59
|
});
|
|
26
60
|
|
|
27
|
-
// POST with body
|
|
28
61
|
app.post('/users', async (c) => {
|
|
29
62
|
const body = await c.req.json();
|
|
30
|
-
return c.json({ created: true,
|
|
63
|
+
return c.json({ created: true, user: body }, 201);
|
|
31
64
|
});
|
|
32
65
|
|
|
33
|
-
// Start server
|
|
34
66
|
serve(app, { port: 3000 });
|
|
67
|
+
console.log('Server running at http://localhost:3000');
|
|
35
68
|
```
|
|
36
69
|
|
|
37
|
-
|
|
70
|
+
---
|
|
38
71
|
|
|
39
|
-
|
|
40
|
-
- **Web Standards** - Uses native Request/Response APIs
|
|
41
|
-
- **Multi-runtime** - Works with Node.js, Bun, and Deno
|
|
42
|
-
- **Lightweight** - Minimal dependencies (~3kb core)
|
|
43
|
-
- **TypeScript** - Full type safety out of the box
|
|
72
|
+
## Routing
|
|
44
73
|
|
|
45
|
-
|
|
74
|
+
Register routes using HTTP method helpers:
|
|
46
75
|
|
|
47
|
-
|
|
76
|
+
```typescript
|
|
77
|
+
app.get('/path', handler); // GET
|
|
78
|
+
app.post('/path', handler); // POST
|
|
79
|
+
app.put('/path', handler); // PUT
|
|
80
|
+
app.patch('/path', handler); // PATCH
|
|
81
|
+
app.delete('/path', handler); // DELETE
|
|
82
|
+
app.options('/path', handler); // OPTIONS
|
|
83
|
+
app.head('/path', handler); // HEAD
|
|
84
|
+
|
|
85
|
+
// All methods
|
|
86
|
+
app.all('/path', handler);
|
|
87
|
+
|
|
88
|
+
// Multiple methods
|
|
89
|
+
app.on(['GET', 'POST'], '/path', handler);
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Route Patterns
|
|
48
93
|
|
|
49
94
|
```typescript
|
|
50
|
-
|
|
51
|
-
|
|
95
|
+
// Static path
|
|
96
|
+
app.get('/about', handler);
|
|
52
97
|
|
|
53
|
-
|
|
98
|
+
// Single parameter
|
|
99
|
+
app.get('/users/:id', handler);
|
|
100
|
+
|
|
101
|
+
// Multiple parameters
|
|
102
|
+
app.get('/posts/:year/:month/:slug', handler);
|
|
103
|
+
|
|
104
|
+
// Optional parameter
|
|
105
|
+
app.get('/files/:path?', handler);
|
|
106
|
+
|
|
107
|
+
// Wildcard (catch-all)
|
|
108
|
+
app.get('/assets/*', handler);
|
|
109
|
+
|
|
110
|
+
// Named wildcard
|
|
111
|
+
app.get('/docs/:path*', handler);
|
|
54
112
|
```
|
|
55
113
|
|
|
56
|
-
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Route Parameters
|
|
117
|
+
|
|
118
|
+
Access route parameters from the context:
|
|
57
119
|
|
|
58
120
|
```typescript
|
|
59
|
-
|
|
60
|
-
|
|
121
|
+
// Route: /users/:id/posts/:postId
|
|
122
|
+
app.get('/users/:id/posts/:postId', (c) => {
|
|
123
|
+
const { id, postId } = c.params;
|
|
124
|
+
return c.json({ userId: id, postId });
|
|
125
|
+
});
|
|
61
126
|
|
|
62
|
-
|
|
127
|
+
// Wildcard parameters
|
|
128
|
+
// Route: /files/*
|
|
129
|
+
// Request: /files/images/photo.jpg
|
|
130
|
+
app.get('/files/*', (c) => {
|
|
131
|
+
const path = c.params['*']; // "images/photo.jpg"
|
|
132
|
+
return c.text(`File: ${path}`);
|
|
133
|
+
});
|
|
63
134
|
```
|
|
64
135
|
|
|
65
|
-
###
|
|
136
|
+
### Type-Safe Parameters
|
|
66
137
|
|
|
67
138
|
```typescript
|
|
68
|
-
import {
|
|
69
|
-
import { serve } from '@flight-framework/http/deno';
|
|
139
|
+
import type { Context } from '@flight-framework/http';
|
|
70
140
|
|
|
71
|
-
|
|
141
|
+
interface UserParams {
|
|
142
|
+
id: string;
|
|
143
|
+
postId: string;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
app.get('/users/:id/posts/:postId', (c: Context<UserParams>) => {
|
|
147
|
+
c.params.id; // string (typed)
|
|
148
|
+
c.params.postId; // string (typed)
|
|
149
|
+
});
|
|
72
150
|
```
|
|
73
151
|
|
|
152
|
+
---
|
|
153
|
+
|
|
74
154
|
## Middleware
|
|
75
155
|
|
|
156
|
+
Middleware functions run before route handlers:
|
|
157
|
+
|
|
76
158
|
```typescript
|
|
77
|
-
//
|
|
159
|
+
// Global middleware (runs on all routes)
|
|
78
160
|
app.use(async (c, next) => {
|
|
79
161
|
const start = performance.now();
|
|
80
162
|
const response = await next();
|
|
81
163
|
const duration = performance.now() - start;
|
|
82
|
-
console.log(`${c.req.method} ${c.req.url} - ${duration}ms`);
|
|
164
|
+
console.log(`${c.req.method} ${c.req.url} - ${duration.toFixed(2)}ms`);
|
|
83
165
|
return response;
|
|
84
166
|
});
|
|
85
167
|
|
|
86
|
-
//
|
|
87
|
-
app.use(async (c, next) => {
|
|
88
|
-
|
|
168
|
+
// Path-specific middleware
|
|
169
|
+
app.use('/api/*', async (c, next) => {
|
|
170
|
+
// Only runs on /api/* routes
|
|
171
|
+
return next();
|
|
172
|
+
});
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Authentication Middleware
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
const authMiddleware = async (c, next) => {
|
|
179
|
+
const token = c.header('Authorization')?.replace('Bearer ', '');
|
|
180
|
+
|
|
89
181
|
if (!token) {
|
|
90
182
|
return c.json({ error: 'Unauthorized' }, 401);
|
|
91
183
|
}
|
|
92
|
-
|
|
184
|
+
|
|
185
|
+
const user = await verifyToken(token);
|
|
186
|
+
if (!user) {
|
|
187
|
+
return c.json({ error: 'Invalid token' }, 401);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Store user in context for later use
|
|
191
|
+
c.set('user', user);
|
|
93
192
|
return next();
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
// Apply to specific routes
|
|
196
|
+
app.use('/api/*', authMiddleware);
|
|
197
|
+
|
|
198
|
+
// Access in route handler
|
|
199
|
+
app.get('/api/profile', (c) => {
|
|
200
|
+
const user = c.get('user');
|
|
201
|
+
return c.json(user);
|
|
94
202
|
});
|
|
95
203
|
```
|
|
96
204
|
|
|
97
|
-
|
|
205
|
+
### Middleware Chain
|
|
206
|
+
|
|
207
|
+
Multiple middleware functions run in order:
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
app.get('/protected',
|
|
211
|
+
authMiddleware,
|
|
212
|
+
rateLimitMiddleware,
|
|
213
|
+
validationMiddleware,
|
|
214
|
+
(c) => {
|
|
215
|
+
return c.json({ data: 'secret' });
|
|
216
|
+
}
|
|
217
|
+
);
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## Context API
|
|
223
|
+
|
|
224
|
+
The context object provides access to request data and response helpers:
|
|
98
225
|
|
|
99
226
|
```typescript
|
|
100
227
|
app.get('/demo', (c) => {
|
|
101
|
-
//
|
|
102
|
-
|
|
228
|
+
// Request object (Web Standard)
|
|
229
|
+
c.req; // Request
|
|
230
|
+
c.req.method; // "GET"
|
|
231
|
+
c.req.url; // Full URL
|
|
103
232
|
|
|
104
|
-
//
|
|
105
|
-
|
|
233
|
+
// Route parameters
|
|
234
|
+
c.params; // { id: "123" }
|
|
235
|
+
c.params.id; // "123"
|
|
106
236
|
|
|
107
|
-
//
|
|
108
|
-
|
|
237
|
+
// Query parameters
|
|
238
|
+
c.query('page'); // "1" or undefined
|
|
239
|
+
c.query('page', '1'); // "1" (with default)
|
|
240
|
+
c.queries('tags'); // ["a", "b"] (array)
|
|
109
241
|
|
|
110
|
-
//
|
|
111
|
-
|
|
242
|
+
// Headers
|
|
243
|
+
c.header('Content-Type'); // "application/json"
|
|
244
|
+
c.header('X-Custom'); // Custom header value
|
|
112
245
|
|
|
113
|
-
//
|
|
114
|
-
|
|
246
|
+
// Cookies
|
|
247
|
+
c.cookie('session'); // Cookie value
|
|
115
248
|
|
|
116
|
-
//
|
|
117
|
-
|
|
249
|
+
// Context storage
|
|
250
|
+
c.set('key', 'value'); // Store value
|
|
251
|
+
c.get('key'); // Retrieve value
|
|
118
252
|
|
|
119
|
-
|
|
120
|
-
const id = c.params.id;
|
|
253
|
+
return c.json({ ok: true });
|
|
121
254
|
});
|
|
122
255
|
```
|
|
123
256
|
|
|
124
|
-
|
|
257
|
+
---
|
|
125
258
|
|
|
126
|
-
|
|
259
|
+
## Request Handling
|
|
127
260
|
|
|
128
|
-
|
|
261
|
+
### JSON Body
|
|
129
262
|
|
|
130
|
-
|
|
263
|
+
```typescript
|
|
264
|
+
app.post('/api/users', async (c) => {
|
|
265
|
+
const body = await c.req.json();
|
|
266
|
+
// body is parsed JSON
|
|
267
|
+
return c.json({ received: body });
|
|
268
|
+
});
|
|
269
|
+
```
|
|
131
270
|
|
|
132
|
-
|
|
271
|
+
### Form Data
|
|
133
272
|
|
|
134
|
-
|
|
273
|
+
```typescript
|
|
274
|
+
app.post('/upload', async (c) => {
|
|
275
|
+
const form = await c.req.formData();
|
|
276
|
+
const name = form.get('name');
|
|
277
|
+
const file = form.get('file'); // File object
|
|
278
|
+
|
|
279
|
+
return c.json({ name, fileName: file?.name });
|
|
280
|
+
});
|
|
281
|
+
```
|
|
135
282
|
|
|
136
|
-
|
|
283
|
+
### Raw Text
|
|
137
284
|
|
|
138
|
-
|
|
285
|
+
```typescript
|
|
286
|
+
app.post('/webhook', async (c) => {
|
|
287
|
+
const text = await c.req.text();
|
|
288
|
+
return c.text(`Received: ${text}`);
|
|
289
|
+
});
|
|
290
|
+
```
|
|
139
291
|
|
|
140
|
-
|
|
292
|
+
### Raw Binary
|
|
141
293
|
|
|
142
|
-
|
|
294
|
+
```typescript
|
|
295
|
+
app.post('/binary', async (c) => {
|
|
296
|
+
const buffer = await c.req.arrayBuffer();
|
|
297
|
+
return c.json({ bytes: buffer.byteLength });
|
|
298
|
+
});
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## Response Helpers
|
|
304
|
+
|
|
305
|
+
```typescript
|
|
306
|
+
// JSON response
|
|
307
|
+
c.json({ data: 'value' });
|
|
308
|
+
c.json({ created: true }, 201);
|
|
309
|
+
c.json({ error: 'Not found' }, 404);
|
|
310
|
+
|
|
311
|
+
// Text response
|
|
312
|
+
c.text('Hello, World!');
|
|
313
|
+
c.text('Created', 201);
|
|
314
|
+
|
|
315
|
+
// HTML response
|
|
316
|
+
c.html('<h1>Hello</h1>');
|
|
317
|
+
c.html('<!DOCTYPE html>...', 200);
|
|
318
|
+
|
|
319
|
+
// Redirect
|
|
320
|
+
c.redirect('/new-location');
|
|
321
|
+
c.redirect('/login', 302); // Temporary (default)
|
|
322
|
+
c.redirect('/moved', 301); // Permanent
|
|
323
|
+
|
|
324
|
+
// No Content
|
|
325
|
+
c.body(null, 204);
|
|
326
|
+
|
|
327
|
+
// Custom response
|
|
328
|
+
return new Response(body, {
|
|
329
|
+
status: 200,
|
|
330
|
+
headers: { 'X-Custom': 'value' },
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
// Set response headers
|
|
334
|
+
c.header('X-Request-Id', requestId);
|
|
335
|
+
c.header('Cache-Control', 'max-age=3600');
|
|
336
|
+
|
|
337
|
+
// Set cookies
|
|
338
|
+
c.cookie('session', token, {
|
|
339
|
+
httpOnly: true,
|
|
340
|
+
secure: true,
|
|
341
|
+
sameSite: 'Strict',
|
|
342
|
+
maxAge: 60 * 60 * 24, // 1 day
|
|
343
|
+
});
|
|
344
|
+
```
|
|
143
345
|
|
|
144
|
-
|
|
346
|
+
---
|
|
145
347
|
|
|
146
|
-
|
|
348
|
+
## Error Handling
|
|
147
349
|
|
|
148
|
-
|
|
350
|
+
### Global Error Handler
|
|
149
351
|
|
|
150
|
-
|
|
352
|
+
```typescript
|
|
353
|
+
app.onError((error, c) => {
|
|
354
|
+
console.error('Error:', error);
|
|
355
|
+
|
|
356
|
+
if (error instanceof ValidationError) {
|
|
357
|
+
return c.json({ error: error.message }, 400);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
return c.json({ error: 'Internal Server Error' }, 500);
|
|
361
|
+
});
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
### 404 Not Found
|
|
365
|
+
|
|
366
|
+
```typescript
|
|
367
|
+
app.notFound((c) => {
|
|
368
|
+
return c.json({
|
|
369
|
+
error: 'Not Found',
|
|
370
|
+
path: new URL(c.req.url).pathname,
|
|
371
|
+
}, 404);
|
|
372
|
+
});
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
### Throwing Errors
|
|
376
|
+
|
|
377
|
+
```typescript
|
|
378
|
+
import { HTTPException } from '@flight-framework/http';
|
|
379
|
+
|
|
380
|
+
app.get('/protected', (c) => {
|
|
381
|
+
if (!c.get('user')) {
|
|
382
|
+
throw new HTTPException(401, 'Unauthorized');
|
|
383
|
+
}
|
|
384
|
+
return c.json({ secret: 'data' });
|
|
385
|
+
});
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
## Sub-Routers
|
|
391
|
+
|
|
392
|
+
Organize routes into modules:
|
|
393
|
+
|
|
394
|
+
```typescript
|
|
395
|
+
// routes/users.ts
|
|
396
|
+
import { createServer } from '@flight-framework/http';
|
|
397
|
+
|
|
398
|
+
export const users = createServer();
|
|
399
|
+
|
|
400
|
+
users.get('/', (c) => c.json({ users: [] }));
|
|
401
|
+
users.get('/:id', (c) => c.json({ id: c.params.id }));
|
|
402
|
+
users.post('/', (c) => c.json({ created: true }));
|
|
403
|
+
|
|
404
|
+
// main.ts
|
|
405
|
+
import { createServer } from '@flight-framework/http';
|
|
406
|
+
import { users } from './routes/users';
|
|
407
|
+
|
|
408
|
+
const app = createServer();
|
|
409
|
+
|
|
410
|
+
// Mount sub-router
|
|
411
|
+
app.route('/api/users', users);
|
|
412
|
+
|
|
413
|
+
// Routes:
|
|
414
|
+
// GET /api/users
|
|
415
|
+
// GET /api/users/:id
|
|
416
|
+
// POST /api/users
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
## Runtime Adapters
|
|
422
|
+
|
|
423
|
+
### Node.js
|
|
424
|
+
|
|
425
|
+
```typescript
|
|
426
|
+
import { createServer } from '@flight-framework/http';
|
|
427
|
+
import { serve } from '@flight-framework/http/node';
|
|
428
|
+
|
|
429
|
+
const app = createServer();
|
|
430
|
+
|
|
431
|
+
serve(app, {
|
|
432
|
+
port: 3000,
|
|
433
|
+
hostname: '0.0.0.0',
|
|
434
|
+
});
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
### Bun
|
|
438
|
+
|
|
439
|
+
```typescript
|
|
440
|
+
import { createServer } from '@flight-framework/http';
|
|
441
|
+
import { serve } from '@flight-framework/http/bun';
|
|
442
|
+
|
|
443
|
+
const app = createServer();
|
|
444
|
+
|
|
445
|
+
serve(app, { port: 3000 });
|
|
446
|
+
|
|
447
|
+
// Or use Bun's native API
|
|
448
|
+
Bun.serve({
|
|
449
|
+
port: 3000,
|
|
450
|
+
fetch: app.fetch,
|
|
451
|
+
});
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
### Deno
|
|
455
|
+
|
|
456
|
+
```typescript
|
|
457
|
+
import { createServer } from '@flight-framework/http';
|
|
458
|
+
import { serve } from '@flight-framework/http/deno';
|
|
459
|
+
|
|
460
|
+
const app = createServer();
|
|
461
|
+
|
|
462
|
+
serve(app, { port: 3000 });
|
|
463
|
+
|
|
464
|
+
// Or use Deno's native API
|
|
465
|
+
Deno.serve({ port: 3000 }, app.fetch);
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
### Cloudflare Workers
|
|
469
|
+
|
|
470
|
+
```typescript
|
|
471
|
+
import { createServer } from '@flight-framework/http';
|
|
472
|
+
|
|
473
|
+
const app = createServer();
|
|
474
|
+
|
|
475
|
+
// ... define routes
|
|
476
|
+
|
|
477
|
+
export default {
|
|
478
|
+
fetch: app.fetch,
|
|
479
|
+
};
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
---
|
|
483
|
+
|
|
484
|
+
## Static Files
|
|
485
|
+
|
|
486
|
+
Serve static files from a directory:
|
|
487
|
+
|
|
488
|
+
```typescript
|
|
489
|
+
import { serveStatic } from '@flight-framework/http/static';
|
|
490
|
+
|
|
491
|
+
// Serve from 'public' directory
|
|
492
|
+
app.use('/static/*', serveStatic({ root: './public' }));
|
|
493
|
+
|
|
494
|
+
// With options
|
|
495
|
+
app.use('/assets/*', serveStatic({
|
|
496
|
+
root: './assets',
|
|
497
|
+
maxAge: 60 * 60 * 24, // 1 day cache
|
|
498
|
+
index: 'index.html',
|
|
499
|
+
}));
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
---
|
|
503
|
+
|
|
504
|
+
## CORS
|
|
505
|
+
|
|
506
|
+
Enable Cross-Origin Resource Sharing:
|
|
507
|
+
|
|
508
|
+
```typescript
|
|
509
|
+
import { cors } from '@flight-framework/http/cors';
|
|
510
|
+
|
|
511
|
+
// Allow all origins
|
|
512
|
+
app.use(cors());
|
|
513
|
+
|
|
514
|
+
// Specific origins
|
|
515
|
+
app.use(cors({
|
|
516
|
+
origin: 'https://example.com',
|
|
517
|
+
methods: ['GET', 'POST', 'PUT', 'DELETE'],
|
|
518
|
+
headers: ['Content-Type', 'Authorization'],
|
|
519
|
+
credentials: true,
|
|
520
|
+
maxAge: 86400,
|
|
521
|
+
}));
|
|
522
|
+
|
|
523
|
+
// Dynamic origin
|
|
524
|
+
app.use(cors({
|
|
525
|
+
origin: (origin) => {
|
|
526
|
+
return origin.endsWith('.example.com');
|
|
527
|
+
},
|
|
528
|
+
}));
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
---
|
|
532
|
+
|
|
533
|
+
## API Reference
|
|
534
|
+
|
|
535
|
+
### createServer(options?)
|
|
536
|
+
|
|
537
|
+
Create a new Flight HTTP server.
|
|
151
538
|
|
|
152
|
-
|
|
539
|
+
| Option | Type | Default | Description |
|
|
540
|
+
|--------|------|---------|-------------|
|
|
541
|
+
| `strict` | `boolean` | `true` | Strict routing (trailing slash matters) |
|
|
542
|
+
| `getPath` | `function` | - | Custom path extraction |
|
|
543
|
+
|
|
544
|
+
### Context Methods
|
|
545
|
+
|
|
546
|
+
| Method | Description |
|
|
547
|
+
|--------|-------------|
|
|
548
|
+
| `c.req` | Web Standard Request object |
|
|
549
|
+
| `c.params` | Route parameters |
|
|
550
|
+
| `c.query(name, default?)` | Get query parameter |
|
|
551
|
+
| `c.queries(name)` | Get all values for query param |
|
|
552
|
+
| `c.header(name)` | Get request header |
|
|
553
|
+
| `c.cookie(name)` | Get cookie value |
|
|
554
|
+
| `c.set(key, value)` | Store value in context |
|
|
555
|
+
| `c.get(key)` | Retrieve value from context |
|
|
556
|
+
| `c.json(data, status?)` | JSON response |
|
|
557
|
+
| `c.text(text, status?)` | Text response |
|
|
558
|
+
| `c.html(html, status?)` | HTML response |
|
|
559
|
+
| `c.redirect(url, status?)` | Redirect response |
|
|
560
|
+
| `c.body(body, status?)` | Raw body response |
|
|
561
|
+
|
|
562
|
+
### App Methods
|
|
563
|
+
|
|
564
|
+
| Method | Description |
|
|
565
|
+
|--------|-------------|
|
|
566
|
+
| `app.get/post/put/delete/patch(path, ...handlers)` | Register route |
|
|
567
|
+
| `app.all(path, ...handlers)` | All HTTP methods |
|
|
568
|
+
| `app.on(methods[], path, ...handlers)` | Specific methods |
|
|
569
|
+
| `app.use(...middleware)` | Add middleware |
|
|
570
|
+
| `app.use(path, ...middleware)` | Path-specific middleware |
|
|
571
|
+
| `app.route(path, subRouter)` | Mount sub-router |
|
|
572
|
+
| `app.notFound(handler)` | Custom 404 handler |
|
|
573
|
+
| `app.onError(handler)` | Custom error handler |
|
|
574
|
+
| `app.fetch(request)` | Handle request (Web Standard) |
|
|
575
|
+
|
|
576
|
+
---
|
|
153
577
|
|
|
154
578
|
## License
|
|
155
579
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flight-framework/http",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "Ultra-fast HTTP server for Flight Framework - Built on Web Standards",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"flight",
|
|
@@ -54,4 +54,4 @@
|
|
|
54
54
|
"typescript": "^5.7.0",
|
|
55
55
|
"vitest": "^2.0.0"
|
|
56
56
|
}
|
|
57
|
-
}
|
|
57
|
+
}
|