@nextrush/types 3.0.0

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.
@@ -0,0 +1,915 @@
1
+ /**
2
+ * @nextrush/types - HTTP Type Definitions
3
+ *
4
+ * Core HTTP types used across the NextRush framework.
5
+ * These types provide a clean abstraction over HTTP primitives,
6
+ * designed to work across multiple runtimes (Node.js, Bun, Deno, Edge).
7
+ *
8
+ * @packageDocumentation
9
+ */
10
+ /**
11
+ * Standard HTTP methods supported by NextRush
12
+ */
13
+ type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS' | 'TRACE' | 'CONNECT';
14
+ /**
15
+ * Common HTTP methods for convenience
16
+ */
17
+ type CommonHttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
18
+ /**
19
+ * HTTP methods as readonly tuple for iteration.
20
+ *
21
+ * Note: TRACE and CONNECT are intentionally excluded from this constant.
22
+ * - TRACE enables Cross-Site Tracing (XST) attacks and is disabled by most servers.
23
+ * - CONNECT is used for HTTP tunneling (proxies) and is not relevant to application routing.
24
+ * Both remain in the `HttpMethod` type for completeness (e.g., custom proxy adapters).
25
+ */
26
+ declare const HTTP_METHODS: readonly ["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"];
27
+ /**
28
+ * Incoming request headers (read-only)
29
+ */
30
+ type IncomingHeaders = Readonly<Record<string, string | string[] | undefined>>;
31
+ /**
32
+ * Outgoing response headers (writable)
33
+ */
34
+ type OutgoingHeaders = Record<string, string | number | string[]>;
35
+ /**
36
+ * HTTP status codes
37
+ */
38
+ declare const HttpStatus: {
39
+ readonly OK: 200;
40
+ readonly CREATED: 201;
41
+ readonly ACCEPTED: 202;
42
+ readonly NO_CONTENT: 204;
43
+ readonly MOVED_PERMANENTLY: 301;
44
+ readonly FOUND: 302;
45
+ readonly SEE_OTHER: 303;
46
+ readonly NOT_MODIFIED: 304;
47
+ readonly TEMPORARY_REDIRECT: 307;
48
+ readonly PERMANENT_REDIRECT: 308;
49
+ readonly BAD_REQUEST: 400;
50
+ readonly UNAUTHORIZED: 401;
51
+ readonly PAYMENT_REQUIRED: 402;
52
+ readonly FORBIDDEN: 403;
53
+ readonly NOT_FOUND: 404;
54
+ readonly METHOD_NOT_ALLOWED: 405;
55
+ readonly NOT_ACCEPTABLE: 406;
56
+ readonly PROXY_AUTH_REQUIRED: 407;
57
+ readonly REQUEST_TIMEOUT: 408;
58
+ readonly CONFLICT: 409;
59
+ readonly GONE: 410;
60
+ readonly LENGTH_REQUIRED: 411;
61
+ readonly PRECONDITION_FAILED: 412;
62
+ readonly PAYLOAD_TOO_LARGE: 413;
63
+ readonly URI_TOO_LONG: 414;
64
+ readonly UNSUPPORTED_MEDIA_TYPE: 415;
65
+ readonly RANGE_NOT_SATISFIABLE: 416;
66
+ readonly EXPECTATION_FAILED: 417;
67
+ readonly IM_A_TEAPOT: 418;
68
+ readonly UNPROCESSABLE_ENTITY: 422;
69
+ readonly LOCKED: 423;
70
+ readonly FAILED_DEPENDENCY: 424;
71
+ readonly TOO_EARLY: 425;
72
+ readonly UPGRADE_REQUIRED: 426;
73
+ readonly PRECONDITION_REQUIRED: 428;
74
+ readonly TOO_MANY_REQUESTS: 429;
75
+ readonly REQUEST_HEADER_FIELDS_TOO_LARGE: 431;
76
+ readonly UNAVAILABLE_FOR_LEGAL_REASONS: 451;
77
+ readonly INTERNAL_SERVER_ERROR: 500;
78
+ readonly NOT_IMPLEMENTED: 501;
79
+ readonly BAD_GATEWAY: 502;
80
+ readonly SERVICE_UNAVAILABLE: 503;
81
+ readonly GATEWAY_TIMEOUT: 504;
82
+ readonly HTTP_VERSION_NOT_SUPPORTED: 505;
83
+ readonly VARIANT_ALSO_NEGOTIATES: 506;
84
+ readonly INSUFFICIENT_STORAGE: 507;
85
+ readonly LOOP_DETECTED: 508;
86
+ readonly NOT_EXTENDED: 510;
87
+ readonly NETWORK_AUTH_REQUIRED: 511;
88
+ };
89
+ type HttpStatusCode = (typeof HttpStatus)[keyof typeof HttpStatus];
90
+ /**
91
+ * Supported request body types after parsing
92
+ */
93
+ type ParsedBody = string | Uint8Array | Record<string, unknown> | unknown[] | null | undefined;
94
+ /**
95
+ * Supported response body types
96
+ *
97
+ * @remarks
98
+ * Uses structural stream interfaces to avoid coupling to any
99
+ * specific runtime (Node.js, Bun, Deno, Edge).
100
+ * Uint8Array and ArrayBuffer provide Web API compatibility.
101
+ */
102
+ type ResponseBody = string | Uint8Array | ArrayBuffer | NodeStreamLike | WebStreamLike | Record<string, unknown> | unknown[] | null | undefined;
103
+ /**
104
+ * Structural interface for Node.js-compatible readable streams.
105
+ * Matches Node.js `Readable` and `IncomingMessage` without importing `@types/node`.
106
+ */
107
+ interface NodeStreamLike {
108
+ pipe(destination: unknown): unknown;
109
+ }
110
+ /**
111
+ * Structural interface for Web API ReadableStreams.
112
+ * Matches the global `ReadableStream<Uint8Array>` without requiring DOM lib types.
113
+ */
114
+ interface WebStreamLike {
115
+ getReader(): unknown;
116
+ readonly locked: boolean;
117
+ }
118
+ /**
119
+ * Raw HTTP objects - generic to support multiple runtimes
120
+ *
121
+ * For Node.js: RawHttp<IncomingMessage, ServerResponse>
122
+ * For Bun: RawHttp<Request, Response>
123
+ * For Edge: RawHttp<Request, ResponseInit>
124
+ *
125
+ * @typeParam TReq - Raw request type for the runtime
126
+ * @typeParam TRes - Raw response type for the runtime
127
+ */
128
+ interface RawHttp<TReq = unknown, TRes = unknown> {
129
+ readonly req: TReq;
130
+ readonly res: TRes;
131
+ }
132
+ /**
133
+ * Common content types
134
+ */
135
+ declare const ContentType: {
136
+ readonly JSON: "application/json";
137
+ readonly HTML: "text/html";
138
+ readonly TEXT: "text/plain";
139
+ readonly XML: "application/xml";
140
+ readonly FORM: "application/x-www-form-urlencoded";
141
+ readonly MULTIPART: "multipart/form-data";
142
+ readonly OCTET_STREAM: "application/octet-stream";
143
+ };
144
+ type ContentTypeValue = (typeof ContentType)[keyof typeof ContentType];
145
+
146
+ /**
147
+ * @nextrush/types - Runtime Type Definitions
148
+ *
149
+ * Types for cross-runtime support in NextRush.
150
+ *
151
+ * @packageDocumentation
152
+ */
153
+
154
+ /**
155
+ * Supported JavaScript runtimes
156
+ *
157
+ * @remarks
158
+ * NextRush detects the runtime environment and exposes it via `ctx.runtime`.
159
+ * This enables runtime-specific optimizations while maintaining a unified API.
160
+ */
161
+ type Runtime = 'node' | 'bun' | 'deno' | 'deno-deploy' | 'cloudflare-workers' | 'vercel-edge' | 'edge' | 'unknown';
162
+ /**
163
+ * Runtime feature capabilities
164
+ *
165
+ * @remarks
166
+ * Different runtimes have different feature sets. Use this to check
167
+ * what's available before using runtime-specific features.
168
+ */
169
+ interface RuntimeCapabilities {
170
+ /** Supports Node.js streams (Readable, Writable) */
171
+ nodeStreams: boolean;
172
+ /** Supports Web Streams API (ReadableStream, WritableStream) */
173
+ webStreams: boolean;
174
+ /** Supports file system operations */
175
+ fileSystem: boolean;
176
+ /** Supports WebSocket */
177
+ webSocket: boolean;
178
+ /** Supports native fetch API */
179
+ fetch: boolean;
180
+ /** Supports crypto.subtle API */
181
+ cryptoSubtle: boolean;
182
+ /** Supports Web Workers / Worker Threads */
183
+ workers: boolean;
184
+ }
185
+ /**
186
+ * Runtime information object
187
+ */
188
+ interface RuntimeInfo {
189
+ /** Runtime identifier */
190
+ runtime: Runtime;
191
+ /** Runtime version (if available) */
192
+ version: string | undefined;
193
+ /** Runtime capabilities */
194
+ capabilities: RuntimeCapabilities;
195
+ }
196
+ /**
197
+ * Body source interface for cross-runtime body reading
198
+ *
199
+ * @remarks
200
+ * Different runtimes have different APIs for reading request bodies:
201
+ * - Node.js: `IncomingMessage` stream with `on('data')` events
202
+ * - Bun/Deno/Edge: Web `Request` with `text()`, `arrayBuffer()` methods
203
+ *
204
+ * `BodySource` provides a unified interface for body parsers to work
205
+ * across all runtimes without runtime-specific code.
206
+ *
207
+ * @example
208
+ * ```typescript
209
+ * // Works on any runtime
210
+ * async function parseJson(bodySource: BodySource): Promise<unknown> {
211
+ * const text = await bodySource.text();
212
+ * return JSON.parse(text);
213
+ * }
214
+ * ```
215
+ */
216
+ interface BodySource {
217
+ /**
218
+ * Read the body as a UTF-8 string
219
+ *
220
+ * @returns Promise resolving to the body as string
221
+ * @throws Error if body has already been consumed
222
+ */
223
+ text(): Promise<string>;
224
+ /**
225
+ * Read the body as a Uint8Array buffer
226
+ *
227
+ * @returns Promise resolving to the body as Uint8Array
228
+ * @throws Error if body has already been consumed
229
+ */
230
+ buffer(): Promise<Uint8Array>;
231
+ /**
232
+ * Read the body as JSON
233
+ *
234
+ * @returns Promise resolving to parsed JSON
235
+ * @throws BadRequestError if body is not valid JSON
236
+ * @throws Error if body has already been consumed
237
+ */
238
+ json<T = unknown>(): Promise<T>;
239
+ /**
240
+ * Get the body as a stream
241
+ *
242
+ * @remarks
243
+ * Returns the native stream type for the runtime:
244
+ * - Node.js: `Readable`
245
+ * - Web API: `ReadableStream<Uint8Array>`
246
+ *
247
+ * @returns The underlying stream
248
+ */
249
+ stream(): NodeStreamLike | WebStreamLike;
250
+ /**
251
+ * Whether the body has been consumed
252
+ *
253
+ * @remarks
254
+ * Most runtimes only allow the body to be read once. After calling
255
+ * `text()`, `buffer()`, `json()`, or `stream()`, subsequent calls
256
+ * may throw an error.
257
+ */
258
+ readonly consumed: boolean;
259
+ /**
260
+ * Content length from headers (if available)
261
+ *
262
+ * @remarks
263
+ * This is the value from the Content-Length header, which may not
264
+ * match the actual body size for chunked transfers.
265
+ */
266
+ readonly contentLength: number | undefined;
267
+ /**
268
+ * Content type from headers (if available)
269
+ */
270
+ readonly contentType: string | undefined;
271
+ }
272
+ /**
273
+ * Options for creating a BodySource
274
+ */
275
+ interface BodySourceOptions {
276
+ /** Maximum body size in bytes (default: 1MB) */
277
+ limit?: number;
278
+ /** Encoding for text() method (default: 'utf-8') */
279
+ encoding?: 'utf-8' | 'utf8' | 'ascii' | 'latin1' | 'iso-8859-1' | 'utf-16le' | 'utf-16be';
280
+ }
281
+
282
+ /**
283
+ * @nextrush/types - Context Type Definitions
284
+ *
285
+ * The Context object is the heart of NextRush's request/response handling.
286
+ * It provides a unified interface for accessing request data and sending responses.
287
+ *
288
+ * Design Philosophy:
289
+ * - ctx.body = request body (INPUT)
290
+ * - ctx.json() = send JSON response (OUTPUT)
291
+ * - ctx.next() = call next middleware
292
+ *
293
+ * @packageDocumentation
294
+ */
295
+
296
+ /**
297
+ * Route parameters extracted from URL path
298
+ * Example: /users/:id -> { id: '123' }
299
+ */
300
+ type RouteParams = Record<string, string>;
301
+ /**
302
+ * Query string parameters
303
+ * Example: ?page=1&limit=10 -> { page: '1', limit: '10' }
304
+ */
305
+ type QueryParams = Record<string, string | string[] | undefined>;
306
+ /**
307
+ * Request-scoped state object
308
+ * Use this to pass data between middleware
309
+ */
310
+ type ContextState = Record<string | symbol, unknown>;
311
+ /**
312
+ * The Context interface - core of NextRush request handling
313
+ *
314
+ * @example
315
+ * ```typescript
316
+ * app.get('/users/:id', async (ctx) => {
317
+ * // Request data (input)
318
+ * const { id } = ctx.params;
319
+ * const { name } = ctx.body;
320
+ *
321
+ * // Response (output)
322
+ * ctx.status = 200;
323
+ * ctx.json({ id, name });
324
+ * });
325
+ * ```
326
+ */
327
+ interface Context {
328
+ /**
329
+ * HTTP method (GET, POST, PUT, DELETE, etc.)
330
+ * @readonly
331
+ */
332
+ readonly method: HttpMethod;
333
+ /**
334
+ * Full request URL including query string
335
+ * @example '/users/123?include=posts'
336
+ * @readonly
337
+ */
338
+ readonly url: string;
339
+ /**
340
+ * Request path without query string
341
+ * @example '/users/123'
342
+ * @readonly
343
+ */
344
+ readonly path: string;
345
+ /**
346
+ * Parsed query string parameters
347
+ * @example { include: 'posts', limit: '10' }
348
+ * @readonly
349
+ */
350
+ readonly query: QueryParams;
351
+ /**
352
+ * Request headers (read-only)
353
+ * Use ctx.get() for case-insensitive access
354
+ * @readonly
355
+ */
356
+ readonly headers: IncomingHeaders;
357
+ /**
358
+ * Client IP address
359
+ * @readonly
360
+ */
361
+ readonly ip: string;
362
+ /**
363
+ * Parsed request body (input).
364
+ *
365
+ * Populated by body-parser middleware (json, urlencoded, multipart).
366
+ * This is the **request body**, not the response body.
367
+ * Use `ctx.json()`, `ctx.send()`, or `ctx.html()` to set response output.
368
+ *
369
+ * @example
370
+ * ```typescript
371
+ * app.post('/users', async (ctx) => {
372
+ * const { name, email } = ctx.body as CreateUserDto;
373
+ * });
374
+ * ```
375
+ */
376
+ body: unknown;
377
+ /**
378
+ * Route parameters from URL path
379
+ *
380
+ * @example
381
+ * ```typescript
382
+ * // Route: /users/:id/posts/:postId
383
+ * // URL: /users/123/posts/456
384
+ * ctx.params // { id: '123', postId: '456' }
385
+ * ```
386
+ */
387
+ params: RouteParams;
388
+ /**
389
+ * HTTP response status code
390
+ * @default 200
391
+ *
392
+ * @example
393
+ * ```typescript
394
+ * ctx.status = 201; // Created
395
+ * ctx.status = 404; // Not Found
396
+ * ```
397
+ */
398
+ status: number;
399
+ /**
400
+ * Send JSON response
401
+ * Automatically sets Content-Type: application/json
402
+ *
403
+ * @param data - Data to serialize as JSON
404
+ *
405
+ * @example
406
+ * ```typescript
407
+ * ctx.json({ users: [] });
408
+ * ctx.json({ error: 'Not found' });
409
+ * ```
410
+ */
411
+ json(data: unknown): void;
412
+ /**
413
+ * Send response (text, buffer, or stream)
414
+ * Automatically detects content type
415
+ *
416
+ * @param data - Response data
417
+ *
418
+ * @example
419
+ * ```typescript
420
+ * ctx.send('Hello World');
421
+ * ctx.send(Buffer.from('binary data'));
422
+ * ctx.send(fileStream);
423
+ * ```
424
+ */
425
+ send(data: ResponseBody): void;
426
+ /**
427
+ * Send HTML response
428
+ * Automatically sets Content-Type: text/html
429
+ *
430
+ * @param content - HTML string
431
+ *
432
+ * @example
433
+ * ```typescript
434
+ * ctx.html('<h1>Hello World</h1>');
435
+ * ```
436
+ */
437
+ html(content: string): void;
438
+ /**
439
+ * Redirect to another URL
440
+ *
441
+ * @param url - Target URL
442
+ * @param status - HTTP status code (default: 302)
443
+ *
444
+ * @example
445
+ * ```typescript
446
+ * ctx.redirect('/login');
447
+ * ctx.redirect('/new-page', 301); // Permanent redirect
448
+ * ```
449
+ */
450
+ redirect(url: string, status?: number): void;
451
+ /**
452
+ * Throw an HTTP error - stops execution and triggers error handler
453
+ *
454
+ * @param status - HTTP status code
455
+ * @param message - Error message (optional)
456
+ * @throws HttpError
457
+ *
458
+ * @example
459
+ * ```typescript
460
+ * ctx.throw(404, 'User not found');
461
+ * ctx.throw(401); // Uses default message "Unauthorized"
462
+ * ```
463
+ */
464
+ throw(status: number, message?: string): never;
465
+ /**
466
+ * Assert a condition, throw if falsy
467
+ *
468
+ * @param condition - Condition to check
469
+ * @param status - HTTP status code if assertion fails
470
+ * @param message - Error message (optional)
471
+ * @throws HttpError if condition is falsy
472
+ *
473
+ * @example
474
+ * ```typescript
475
+ * ctx.assert(user, 404, 'User not found');
476
+ * ctx.assert(user.isAdmin, 403, 'Admin access required');
477
+ * ctx.assert(ctx.body, 400); // Uses default "Bad Request"
478
+ * ```
479
+ */
480
+ assert(condition: unknown, status: number, message?: string): asserts condition;
481
+ /**
482
+ * Set response header
483
+ *
484
+ * @param field - Header name
485
+ * @param value - Header value (string, number, or array for multi-value headers like Set-Cookie)
486
+ *
487
+ * @example
488
+ * ```typescript
489
+ * ctx.set('X-Request-Id', '123');
490
+ * ctx.set('Cache-Control', 'no-cache');
491
+ * ctx.set('Set-Cookie', ['a=1; Path=/', 'b=2; Path=/']);
492
+ * ```
493
+ */
494
+ set(field: string, value: string | number | string[]): void;
495
+ /**
496
+ * Get request header (case-insensitive)
497
+ *
498
+ * @param field - Header name
499
+ * @returns Header value or undefined
500
+ *
501
+ * @example
502
+ * ```typescript
503
+ * const auth = ctx.get('Authorization');
504
+ * const contentType = ctx.get('content-type');
505
+ * ```
506
+ */
507
+ get(field: string): string | undefined;
508
+ /**
509
+ * Call the next middleware in the chain
510
+ * Modern syntax: ctx.next() instead of next()
511
+ *
512
+ * @example
513
+ * ```typescript
514
+ * app.use(async (ctx) => {
515
+ * console.log('Before');
516
+ * await ctx.next();
517
+ * console.log('After');
518
+ * });
519
+ * ```
520
+ */
521
+ next(): Promise<void>;
522
+ /**
523
+ * Set the next middleware function
524
+ * @internal Used by middleware compose to wire up ctx.next()
525
+ */
526
+ setNext?(fn: Next): void;
527
+ /**
528
+ * Whether a response has already been sent
529
+ *
530
+ * @remarks
531
+ * Useful for middleware that needs to check if downstream
532
+ * middleware has already sent a response.
533
+ */
534
+ readonly responded: boolean;
535
+ /**
536
+ * Request-scoped state object
537
+ * Use to pass data between middleware
538
+ *
539
+ * @example
540
+ * ```typescript
541
+ * // Auth middleware
542
+ * app.use(async (ctx) => {
543
+ * ctx.state.user = await validateToken(ctx.get('Authorization'));
544
+ * await ctx.next();
545
+ * });
546
+ *
547
+ * // Route handler
548
+ * app.get('/profile', (ctx) => {
549
+ * const user = ctx.state.user;
550
+ * });
551
+ * ```
552
+ */
553
+ state: ContextState;
554
+ /**
555
+ * Raw HTTP objects (platform-specific)
556
+ * Escape hatch for advanced use cases
557
+ *
558
+ * @remarks
559
+ * The type of `raw` depends on the adapter:
560
+ * - Node.js: `{ req: IncomingMessage, res: ServerResponse }`
561
+ * - Bun/Deno/Edge: `{ req: Request, res: Response | undefined }`
562
+ *
563
+ * @example
564
+ * ```typescript
565
+ * // Node.js adapter
566
+ * ctx.raw.req.socket.remoteAddress;
567
+ *
568
+ * // Web API adapter (Bun/Deno/Edge)
569
+ * ctx.raw.req.headers.get('authorization');
570
+ * ```
571
+ */
572
+ readonly raw: RawHttp;
573
+ /**
574
+ * Current JavaScript runtime
575
+ *
576
+ * @remarks
577
+ * Useful for runtime-specific optimizations or conditional logic.
578
+ *
579
+ * @example
580
+ * ```typescript
581
+ * if (ctx.runtime === 'bun') {
582
+ * // Bun-specific optimization
583
+ * }
584
+ * ```
585
+ */
586
+ readonly runtime: Runtime;
587
+ /**
588
+ * Body source for cross-runtime body reading
589
+ *
590
+ * @remarks
591
+ * Used by body parsers to read request bodies in a runtime-agnostic way.
592
+ * Most applications should use `ctx.body` (set by body-parser middleware)
593
+ * instead of accessing `bodySource` directly.
594
+ *
595
+ * @example
596
+ * ```typescript
597
+ * // In a custom body parser
598
+ * const text = await ctx.bodySource.text();
599
+ * const json = JSON.parse(text);
600
+ * ```
601
+ */
602
+ readonly bodySource: BodySource;
603
+ }
604
+ /**
605
+ * Next function type (traditional Koa-style)
606
+ */
607
+ type Next = () => Promise<void>;
608
+ /**
609
+ * Middleware function type
610
+ * Supports both modern and traditional syntax
611
+ *
612
+ * Modern syntax (ctx.next()):
613
+ * ```typescript
614
+ * app.use(async (ctx) => {
615
+ * await ctx.next();
616
+ * });
617
+ * ```
618
+ *
619
+ * Traditional syntax (next parameter):
620
+ * ```typescript
621
+ * app.use(async (ctx, next) => {
622
+ * await next();
623
+ * });
624
+ * ```
625
+ */
626
+ type Middleware = (ctx: Context, next: Next) => void | Promise<void>;
627
+ /**
628
+ * Route handler type (alias for middleware)
629
+ */
630
+ type RouteHandler = Middleware;
631
+ /**
632
+ * Options for creating a new context
633
+ */
634
+ interface ContextOptions {
635
+ /** HTTP method */
636
+ method: HttpMethod;
637
+ /** Request URL */
638
+ url: string;
639
+ /** Request headers */
640
+ headers?: IncomingHeaders;
641
+ /** Client IP */
642
+ ip?: string;
643
+ /** Raw HTTP objects */
644
+ raw: RawHttp;
645
+ }
646
+
647
+ /**
648
+ * @nextrush/types - Plugin Type Definitions
649
+ *
650
+ * Plugins are the extension mechanism for NextRush.
651
+ * They allow adding functionality without bloating the core.
652
+ *
653
+ * @packageDocumentation
654
+ */
655
+
656
+ /**
657
+ * Minimal Application interface for plugin registration
658
+ * The full Application class is in @nextrush/core
659
+ */
660
+ interface ApplicationLike {
661
+ /**
662
+ * Register middleware
663
+ */
664
+ use(middleware: Middleware): this;
665
+ /**
666
+ * Get installed plugin by name
667
+ */
668
+ getPlugin<T extends Plugin>(name: string): T | undefined;
669
+ }
670
+ /**
671
+ * Plugin interface for extending NextRush
672
+ *
673
+ * Plugins are installed via app.plugin() and can:
674
+ * - Add middleware
675
+ * - Extend context
676
+ * - Add lifecycle hooks
677
+ *
678
+ * @example
679
+ * ```typescript
680
+ * class LoggerPlugin implements Plugin {
681
+ * readonly name = 'logger';
682
+ * readonly version = '1.0.0';
683
+ *
684
+ * install(app: ApplicationLike) {
685
+ * app.use(async (ctx, next) => {
686
+ * const start = Date.now();
687
+ * await next();
688
+ * console.log(`${ctx.method} ${ctx.path} - ${Date.now() - start}ms`);
689
+ * });
690
+ * }
691
+ * }
692
+ * ```
693
+ */
694
+ interface Plugin {
695
+ /**
696
+ * Unique plugin name
697
+ * Used for identification and getPlugin() lookup
698
+ */
699
+ readonly name: string;
700
+ /**
701
+ * Plugin version (optional)
702
+ * Follows semver format
703
+ */
704
+ readonly version?: string;
705
+ /**
706
+ * Install plugin into application
707
+ * Called when app.plugin() is invoked
708
+ *
709
+ * @param app - Application instance
710
+ */
711
+ install(app: ApplicationLike): void | Promise<void>;
712
+ /**
713
+ * Cleanup when application shuts down (optional)
714
+ * Called during graceful shutdown
715
+ */
716
+ destroy?(): void | Promise<void>;
717
+ }
718
+ /**
719
+ * Extended plugin interface with lifecycle hooks
720
+ * For advanced plugins that need deeper integration
721
+ */
722
+ interface PluginWithHooks extends Plugin {
723
+ /**
724
+ * Called before each request
725
+ */
726
+ onRequest?(ctx: Context): void | Promise<void>;
727
+ /**
728
+ * Called after each response
729
+ */
730
+ onResponse?(ctx: Context): void | Promise<void>;
731
+ /**
732
+ * Called when an error occurs
733
+ */
734
+ onError?(error: Error, ctx: Context): void | Promise<void>;
735
+ /**
736
+ * Extend the context object
737
+ * Add custom properties or methods
738
+ */
739
+ extendContext?(ctx: Context): void;
740
+ }
741
+ /**
742
+ * Plugin factory function type
743
+ * Allows creating plugins with options
744
+ *
745
+ * @example
746
+ * ```typescript
747
+ * const logger = createLoggerPlugin({ level: 'info' });
748
+ * app.plugin(logger);
749
+ * ```
750
+ */
751
+ type PluginFactory<TOptions = unknown> = (options?: TOptions) => Plugin;
752
+ /**
753
+ * Plugin metadata for registration and discovery
754
+ */
755
+ interface PluginMeta {
756
+ /** Plugin name */
757
+ name: string;
758
+ /** Plugin version */
759
+ version: string;
760
+ /** Plugin description */
761
+ description?: string;
762
+ /** Plugin author */
763
+ author?: string;
764
+ /** Plugin repository URL */
765
+ repository?: string;
766
+ /** Plugin dependencies (other plugin names) */
767
+ dependencies?: string[];
768
+ }
769
+
770
+ /**
771
+ * @nextrush/types - Router Type Definitions
772
+ *
773
+ * Types for the NextRush router system.
774
+ * The router uses a radix tree for efficient route matching.
775
+ *
776
+ * @packageDocumentation
777
+ */
778
+
779
+ /**
780
+ * Route definition
781
+ */
782
+ interface Route {
783
+ /** HTTP method */
784
+ method: HttpMethod;
785
+ /** Route path pattern */
786
+ path: string;
787
+ /** Route handler */
788
+ handler: RouteHandler;
789
+ /** Optional route-level middleware */
790
+ middleware?: Middleware[];
791
+ }
792
+ /**
793
+ * Matched route result
794
+ */
795
+ interface RouteMatch {
796
+ /** Matched handler */
797
+ handler: RouteHandler;
798
+ /** Extracted route parameters */
799
+ params: Record<string, string>;
800
+ /** Router-level middleware stack (route-specific middleware is in the executor) */
801
+ middleware: Middleware[];
802
+ /** Pre-compiled executor for fast dispatch (internal) */
803
+ executor?: (ctx: Context) => Promise<void>;
804
+ }
805
+ /**
806
+ * Router interface for route registration
807
+ *
808
+ * @example
809
+ * ```typescript
810
+ * const router = createRouter();
811
+ *
812
+ * router.get('/users', listUsers);
813
+ * router.get('/users/:id', getUser);
814
+ * router.post('/users', createUser);
815
+ *
816
+ * app.use(router.routes());
817
+ * ```
818
+ */
819
+ interface Router {
820
+ /**
821
+ * Register a GET route
822
+ */
823
+ get(path: string, ...handlers: RouteHandler[]): this;
824
+ /**
825
+ * Register a POST route
826
+ */
827
+ post(path: string, ...handlers: RouteHandler[]): this;
828
+ /**
829
+ * Register a PUT route
830
+ */
831
+ put(path: string, ...handlers: RouteHandler[]): this;
832
+ /**
833
+ * Register a DELETE route
834
+ */
835
+ delete(path: string, ...handlers: RouteHandler[]): this;
836
+ /**
837
+ * Register a PATCH route
838
+ */
839
+ patch(path: string, ...handlers: RouteHandler[]): this;
840
+ /**
841
+ * Register a HEAD route
842
+ */
843
+ head(path: string, ...handlers: RouteHandler[]): this;
844
+ /**
845
+ * Register an OPTIONS route
846
+ */
847
+ options(path: string, ...handlers: RouteHandler[]): this;
848
+ /**
849
+ * Register a route for any HTTP method
850
+ */
851
+ all(path: string, ...handlers: RouteHandler[]): this;
852
+ /**
853
+ * Register a route for specific method
854
+ */
855
+ route(method: HttpMethod, path: string, ...handlers: RouteHandler[]): this;
856
+ /**
857
+ * Mount router middleware
858
+ */
859
+ use(path: string, router: Router): this;
860
+ use(middleware: Middleware): this;
861
+ /**
862
+ * Register a redirect from one path to another
863
+ *
864
+ * @param from - Source path to redirect from
865
+ * @param to - Target path or URL to redirect to
866
+ * @param status - HTTP status code (default: 301)
867
+ */
868
+ redirect(from: string, to: string, status?: 301 | 302 | 303 | 307 | 308): this;
869
+ /**
870
+ * Get routes middleware function
871
+ * Mount this on the application
872
+ */
873
+ routes(): Middleware;
874
+ /**
875
+ * Match a route
876
+ */
877
+ match(method: HttpMethod, path: string): RouteMatch | null;
878
+ }
879
+ /**
880
+ * Router configuration options
881
+ */
882
+ interface RouterOptions {
883
+ /**
884
+ * Prefix for all routes
885
+ * @example '/api/v1'
886
+ */
887
+ prefix?: string;
888
+ /**
889
+ * Whether to enable case-sensitive routing
890
+ * @default false
891
+ */
892
+ caseSensitive?: boolean;
893
+ /**
894
+ * Whether to enable strict routing (trailing slashes matter)
895
+ * @default false
896
+ */
897
+ strict?: boolean;
898
+ }
899
+ /**
900
+ * Supported route pattern types
901
+ */
902
+ type RoutePattern = `/${string}` | `${string}/:${string}` | `${string}/*` | `${string}/:${string}/*`;
903
+ /**
904
+ * Route parameter definition
905
+ */
906
+ interface RouteParam {
907
+ /** Parameter name (without colon) */
908
+ name: string;
909
+ /** Whether the parameter is optional */
910
+ optional?: boolean;
911
+ /** Regex pattern for validation */
912
+ pattern?: RegExp;
913
+ }
914
+
915
+ export { type ApplicationLike, type BodySource, type BodySourceOptions, type CommonHttpMethod, ContentType, type ContentTypeValue, type Context, type ContextOptions, type ContextState, HTTP_METHODS, type HttpMethod, HttpStatus, type HttpStatusCode, type IncomingHeaders, type Middleware, type Next, type NodeStreamLike, type OutgoingHeaders, type ParsedBody, type Plugin, type PluginFactory, type PluginMeta, type PluginWithHooks, type QueryParams, type RawHttp, type ResponseBody, type Route, type RouteHandler, type RouteMatch, type RouteParam, type RouteParams, type RoutePattern, type Router, type RouterOptions, type Runtime, type RuntimeCapabilities, type RuntimeInfo, type WebStreamLike };