blaizejs 0.3.4 → 0.5.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.
- package/dist/{chunk-EE2VJ6JY.js → chunk-2LP25IUP.js} +3 -3
- package/dist/chunk-2LP25IUP.js.map +1 -0
- package/dist/{chunk-TL4GIFTB.js → chunk-6A3MHG3V.js} +3 -3
- package/dist/chunk-6A3MHG3V.js.map +1 -0
- package/dist/{chunk-HSLLYUVO.js → chunk-6XBGCGAR.js} +3 -3
- package/dist/chunk-6XBGCGAR.js.map +1 -0
- package/dist/{chunk-VLVWNGUO.js → chunk-J7KS32ZT.js} +3 -3
- package/dist/chunk-J7KS32ZT.js.map +1 -0
- package/dist/chunk-QD45PRU4.js +11 -0
- package/dist/chunk-QD45PRU4.js.map +1 -0
- package/dist/index.cjs +22 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1664 -220
- package/dist/index.d.ts +1664 -220
- package/dist/index.js +22 -9
- package/dist/index.js.map +1 -1
- package/dist/{internal-server-error-GWBNT3OO.js → internal-server-error-BDHJW7WB.js} +3 -3
- package/dist/{payload-too-large-error-EBM5BNWG.js → payload-too-large-error-PX6RP7T6.js} +3 -3
- package/dist/{unsupported-media-type-error-YQ7GCZ32.js → unsupported-media-type-error-IXHPPRCO.js} +3 -3
- package/dist/{validation-error-6JDCGV2S.js → validation-error-FNJKIDG6.js} +3 -3
- package/package.json +2 -2
- package/dist/chunk-DTDGIBMA.js +0 -11
- package/dist/chunk-DTDGIBMA.js.map +0 -1
- package/dist/chunk-EE2VJ6JY.js.map +0 -1
- package/dist/chunk-HSLLYUVO.js.map +0 -1
- package/dist/chunk-TL4GIFTB.js.map +0 -1
- package/dist/chunk-VLVWNGUO.js.map +0 -1
- /package/dist/{internal-server-error-GWBNT3OO.js.map → internal-server-error-BDHJW7WB.js.map} +0 -0
- /package/dist/{payload-too-large-error-EBM5BNWG.js.map → payload-too-large-error-PX6RP7T6.js.map} +0 -0
- /package/dist/{unsupported-media-type-error-YQ7GCZ32.js.map → unsupported-media-type-error-IXHPPRCO.js.map} +0 -0
- /package/dist/{validation-error-6JDCGV2S.js.map → validation-error-FNJKIDG6.js.map} +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as zod from 'zod';
|
|
1
2
|
import { z } from 'zod';
|
|
2
3
|
import http, { IncomingMessage, ServerResponse } from 'node:http';
|
|
3
4
|
import http2, { Http2ServerRequest, Http2ServerResponse } from 'node:http2';
|
|
@@ -180,6 +181,8 @@ declare enum ErrorType {
|
|
|
180
181
|
UNAUTHORIZED = "UNAUTHORIZED",
|
|
181
182
|
/** Access forbidden (403) */
|
|
182
183
|
FORBIDDEN = "FORBIDDEN",
|
|
184
|
+
/** SSE Not Acceptable (406) */
|
|
185
|
+
SSE_NOT_ACCEPTABLE = "SSE_NOT_ACCEPTABLE",
|
|
183
186
|
/** Resource conflict (409) */
|
|
184
187
|
CONFLICT = "CONFLICT",
|
|
185
188
|
/** Rate limit exceeded (429) */
|
|
@@ -201,7 +204,13 @@ declare enum ErrorType {
|
|
|
201
204
|
/** Response parsing failure (0) */
|
|
202
205
|
PARSE_ERROR = "PARSE_ERROR",
|
|
203
206
|
/** Generic HTTP error (varies) */
|
|
204
|
-
HTTP_ERROR = "HTTP_ERROR"
|
|
207
|
+
HTTP_ERROR = "HTTP_ERROR",
|
|
208
|
+
/** SSE connection failed (502) */
|
|
209
|
+
SSE_CONNECTION_ERROR = "SSE_CONNECTION_ERROR",
|
|
210
|
+
/** SSE buffer overflow (503) */
|
|
211
|
+
SSE_BUFFER_OVERFLOW = "SSE_BUFFER_OVERFLOW",
|
|
212
|
+
/** SSE stream closed (410) */
|
|
213
|
+
SSE_STREAM_CLOSED = "SSE_STREAM_CLOSED"
|
|
205
214
|
}
|
|
206
215
|
/**
|
|
207
216
|
* Error severity levels for logging and monitoring
|
|
@@ -356,7 +365,7 @@ interface ForbiddenErrorDetails {
|
|
|
356
365
|
/** Action being attempted */
|
|
357
366
|
action?: string;
|
|
358
367
|
/** Reason for access denial */
|
|
359
|
-
reason?: 'insufficient_permissions' | 'account_suspended' | 'resource_locked' | string;
|
|
368
|
+
reason?: 'insufficient_permissions' | 'account_suspended' | 'resource_locked' | 'origin_not_allowed' | string;
|
|
360
369
|
/** Additional context */
|
|
361
370
|
[key: string]: unknown;
|
|
362
371
|
}
|
|
@@ -491,6 +500,115 @@ interface ErrorTransformContext {
|
|
|
491
500
|
responseSample?: string;
|
|
492
501
|
[key: string]: unknown;
|
|
493
502
|
}
|
|
503
|
+
/**
|
|
504
|
+
* SSE-specific error detail interfaces for BlaizeJS framework
|
|
505
|
+
*
|
|
506
|
+
* These interfaces define the structure of details for SSE errors.
|
|
507
|
+
* The actual error classes are implemented in blaize-core.
|
|
508
|
+
*/
|
|
509
|
+
/**
|
|
510
|
+
* Details for SSE connection errors
|
|
511
|
+
*/
|
|
512
|
+
interface SSEConnectionErrorDetails {
|
|
513
|
+
/** Client identifier if available */
|
|
514
|
+
clientId?: string;
|
|
515
|
+
/** Connection attempt number */
|
|
516
|
+
attemptNumber?: number;
|
|
517
|
+
/** Maximum retry attempts configured */
|
|
518
|
+
maxRetries?: number;
|
|
519
|
+
/** The underlying error that caused connection failure */
|
|
520
|
+
cause?: string;
|
|
521
|
+
/** Suggested resolution */
|
|
522
|
+
suggestion?: string;
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* Details for SSE buffer overflow errors
|
|
526
|
+
*/
|
|
527
|
+
interface SSEBufferOverflowErrorDetails {
|
|
528
|
+
/** Client identifier */
|
|
529
|
+
clientId?: string;
|
|
530
|
+
/** Current buffer size when overflow occurred */
|
|
531
|
+
currentSize: number;
|
|
532
|
+
/** Maximum buffer size configured */
|
|
533
|
+
maxSize: number;
|
|
534
|
+
/** Number of events dropped */
|
|
535
|
+
eventsDropped?: number;
|
|
536
|
+
/** Buffer strategy that was applied */
|
|
537
|
+
strategy: 'drop-oldest' | 'drop-newest' | 'close';
|
|
538
|
+
/** Event that triggered the overflow */
|
|
539
|
+
triggeringEvent?: string;
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* Details for SSE stream closed errors
|
|
543
|
+
*/
|
|
544
|
+
interface SSEStreamClosedErrorDetails {
|
|
545
|
+
/** Client identifier */
|
|
546
|
+
clientId?: string;
|
|
547
|
+
/** When the stream was closed */
|
|
548
|
+
closedAt?: string;
|
|
549
|
+
/** Reason for closure */
|
|
550
|
+
closeReason?: 'client-disconnect' | 'server-close' | 'timeout' | 'error' | 'buffer-overflow';
|
|
551
|
+
/** Whether reconnection is possible */
|
|
552
|
+
canReconnect?: boolean;
|
|
553
|
+
/** Suggested retry interval in milliseconds */
|
|
554
|
+
retryAfter?: number;
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* Context for SSE connection errors
|
|
558
|
+
*/
|
|
559
|
+
interface SSEConnectionErrorContext {
|
|
560
|
+
/** The SSE endpoint URL */
|
|
561
|
+
url: string;
|
|
562
|
+
/** Correlation ID for tracing */
|
|
563
|
+
correlationId: string;
|
|
564
|
+
/** Connection state when error occurred */
|
|
565
|
+
state: 'connecting' | 'connected' | 'disconnected' | 'closed';
|
|
566
|
+
/** Number of reconnection attempts made */
|
|
567
|
+
reconnectAttempts?: number;
|
|
568
|
+
/** The original error if available */
|
|
569
|
+
originalError?: Error;
|
|
570
|
+
/** Additional SSE-specific details */
|
|
571
|
+
sseDetails?: {
|
|
572
|
+
/** Whether credentials were included */
|
|
573
|
+
withCredentials?: boolean;
|
|
574
|
+
/** Last received event ID */
|
|
575
|
+
lastEventId?: string;
|
|
576
|
+
/** EventSource ready state */
|
|
577
|
+
readyState?: number;
|
|
578
|
+
};
|
|
579
|
+
}
|
|
580
|
+
/**
|
|
581
|
+
* Context for SSE stream errors (server-sent errors)
|
|
582
|
+
*/
|
|
583
|
+
interface SSEStreamErrorContext {
|
|
584
|
+
/** The SSE endpoint URL */
|
|
585
|
+
url: string;
|
|
586
|
+
/** Correlation ID from server or client */
|
|
587
|
+
correlationId: string;
|
|
588
|
+
/** Error message from server */
|
|
589
|
+
message: string;
|
|
590
|
+
/** Error code if provided */
|
|
591
|
+
code?: string;
|
|
592
|
+
/** Error name/type from server */
|
|
593
|
+
name?: string;
|
|
594
|
+
/** Raw error data from server */
|
|
595
|
+
rawData?: any;
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* Context for SSE heartbeat timeout errors
|
|
599
|
+
*/
|
|
600
|
+
interface SSEHeartbeatErrorContext {
|
|
601
|
+
/** The SSE endpoint URL */
|
|
602
|
+
url: string;
|
|
603
|
+
/** Correlation ID for tracing */
|
|
604
|
+
correlationId: string;
|
|
605
|
+
/** Configured heartbeat timeout in ms */
|
|
606
|
+
heartbeatTimeout: number;
|
|
607
|
+
/** Time since last event in ms */
|
|
608
|
+
timeSinceLastEvent?: number;
|
|
609
|
+
/** Last event ID received */
|
|
610
|
+
lastEventId?: string;
|
|
611
|
+
}
|
|
494
612
|
|
|
495
613
|
/**
|
|
496
614
|
* Represents an uploaded file in a multipart/form-data request
|
|
@@ -706,9 +824,17 @@ interface State {
|
|
|
706
824
|
*/
|
|
707
825
|
_bodyError?: BodyParseError;
|
|
708
826
|
}
|
|
827
|
+
/**
|
|
828
|
+
* Services container for storing injectable services/dependencies
|
|
829
|
+
* Allows middleware to contribute services that are accessible throughout the request lifecycle
|
|
830
|
+
*/
|
|
831
|
+
interface Services {
|
|
832
|
+
[key: string]: unknown;
|
|
833
|
+
}
|
|
709
834
|
interface ContextResponse<S extends State = State> {
|
|
710
835
|
raw: UnifiedResponse;
|
|
711
836
|
sent: boolean;
|
|
837
|
+
statusCode: number;
|
|
712
838
|
status: (code: number) => ContextResponse<S>;
|
|
713
839
|
header: (name: string, value: string) => ContextResponse<S>;
|
|
714
840
|
headers: (headers: Record<string, string>) => ContextResponse<S>;
|
|
@@ -744,8 +870,12 @@ interface ContextRequest<TBody = unknown> {
|
|
|
744
870
|
}
|
|
745
871
|
/**
|
|
746
872
|
* Context object representing a request/response cycle
|
|
873
|
+
* @template S - Type of the state object
|
|
874
|
+
* @template Svc - Type of the services object
|
|
875
|
+
* @template TBody - Type of the request body
|
|
876
|
+
* @template TQuery - Type of the query parameters
|
|
747
877
|
*/
|
|
748
|
-
interface Context<S extends State = State, TBody = unknown, TQuery = QueryParams> {
|
|
878
|
+
interface Context<S extends State = State, Svc extends Services = Services, TBody = unknown, TQuery = QueryParams> {
|
|
749
879
|
/**
|
|
750
880
|
* Request information
|
|
751
881
|
*/
|
|
@@ -761,6 +891,11 @@ interface Context<S extends State = State, TBody = unknown, TQuery = QueryParams
|
|
|
761
891
|
* Request-scoped state for storing data during the request lifecycle
|
|
762
892
|
*/
|
|
763
893
|
state: S;
|
|
894
|
+
/**
|
|
895
|
+
* Services container for accessing injected services/dependencies
|
|
896
|
+
* Populated by middleware that contribute services
|
|
897
|
+
*/
|
|
898
|
+
services: Svc;
|
|
764
899
|
}
|
|
765
900
|
type MultipartLimits = {
|
|
766
901
|
maxFileSize?: number;
|
|
@@ -777,9 +912,15 @@ interface ContextOptions {
|
|
|
777
912
|
*/
|
|
778
913
|
parseBody?: boolean;
|
|
779
914
|
/**
|
|
780
|
-
*
|
|
915
|
+
* Initial state to include in the context
|
|
916
|
+
*
|
|
781
917
|
*/
|
|
782
918
|
initialState?: State;
|
|
919
|
+
/**
|
|
920
|
+
* Initial services to include in the context
|
|
921
|
+
*
|
|
922
|
+
*/
|
|
923
|
+
initialServices?: Services;
|
|
783
924
|
/**
|
|
784
925
|
* Limits for various body types to prevent abuse
|
|
785
926
|
*/
|
|
@@ -794,7 +935,7 @@ interface ContextOptions {
|
|
|
794
935
|
/**
|
|
795
936
|
* Function to get the current context from AsyncLocalStorage
|
|
796
937
|
*/
|
|
797
|
-
type GetContextFn = <S extends State = State>() => Context<S> | undefined;
|
|
938
|
+
type GetContextFn = <S extends State = State, Svc extends Services = Services>() => Context<S, Svc> | undefined;
|
|
798
939
|
/**
|
|
799
940
|
* Factory function for creating a new context
|
|
800
941
|
*/
|
|
@@ -826,18 +967,21 @@ interface MiddlewareOptions {
|
|
|
826
967
|
/** The middleware handler function */
|
|
827
968
|
handler: MiddlewareFunction;
|
|
828
969
|
/** Skip function to conditionally bypass middleware */
|
|
829
|
-
skip?: ((ctx: Context) => boolean) | undefined;
|
|
970
|
+
skip?: ((ctx: Context<any, any>) => boolean) | undefined;
|
|
830
971
|
/** Enable debugging for this middleware */
|
|
831
972
|
debug?: boolean;
|
|
832
973
|
}
|
|
833
974
|
/**
|
|
834
|
-
* Middleware type
|
|
975
|
+
* Middleware type with generic parameters for type-safe state and service contributions
|
|
976
|
+
* @template TState - Type of state this middleware contributes to the context
|
|
977
|
+
* @template TServices - Type of services this middleware contributes to the context
|
|
835
978
|
*/
|
|
836
|
-
interface Middleware {
|
|
979
|
+
interface Middleware<TState = {}, TServices = {}> {
|
|
837
980
|
name: string;
|
|
838
981
|
execute: MiddlewareFunction;
|
|
839
982
|
skip?: ((ctx: Context) => boolean) | undefined;
|
|
840
983
|
debug?: boolean | undefined;
|
|
984
|
+
_services?: TServices;
|
|
841
985
|
}
|
|
842
986
|
|
|
843
987
|
/**
|
|
@@ -870,7 +1014,8 @@ ED extends z.ZodType = z.ZodType<any>> {
|
|
|
870
1014
|
/**
|
|
871
1015
|
* Route handler function with strongly typed params and response
|
|
872
1016
|
*/
|
|
873
|
-
type RouteHandler<TParams = Record<string, string>, TQuery = Record<string, string | string[] | undefined>, TBody = unknown, TResponse = unknown
|
|
1017
|
+
type RouteHandler<TParams = Record<string, string>, TQuery = Record<string, string | string[] | undefined>, TBody = unknown, TResponse = unknown, TState extends State = State, // NEW in v0.4.0
|
|
1018
|
+
TServices extends Services = Services> = (ctx: Context<TState, TServices, TBody, TQuery>, params: TParams) => Promise<TResponse> | TResponse;
|
|
874
1019
|
/**
|
|
875
1020
|
* Options for a route method with schema-based type inference
|
|
876
1021
|
*/
|
|
@@ -1084,32 +1229,29 @@ interface FindRouteFilesOptions {
|
|
|
1084
1229
|
ignore?: string[] | undefined;
|
|
1085
1230
|
}
|
|
1086
1231
|
/**
|
|
1087
|
-
* GET route creator
|
|
1088
|
-
*
|
|
1232
|
+
* GET route creator with state and services support
|
|
1233
|
+
* Now returns a higher-order function to handle generics properly
|
|
1089
1234
|
*/
|
|
1090
|
-
type CreateGetRoute = <P = never,
|
|
1091
|
-
Q = never, // Changed from z.ZodType<any>
|
|
1092
|
-
R = never>(config: {
|
|
1235
|
+
type CreateGetRoute = <TState extends State = State, TServices extends Services = Services>() => <P = never, Q = never, R = never>(config: {
|
|
1093
1236
|
schema?: {
|
|
1094
1237
|
params?: P extends never ? never : P;
|
|
1095
1238
|
query?: Q extends never ? never : Q;
|
|
1096
1239
|
response?: R extends never ? never : R;
|
|
1097
1240
|
};
|
|
1098
|
-
handler: RouteHandler<P extends z.ZodType ? Infer<P> : Record<string, string>, Q extends z.ZodType ? Infer<Q> : QueryParams, never,
|
|
1241
|
+
handler: RouteHandler<P extends z.ZodType ? Infer<P> : Record<string, string>, Q extends z.ZodType ? Infer<Q> : QueryParams, never, // GET never has body
|
|
1242
|
+
[
|
|
1099
1243
|
R
|
|
1100
|
-
] extends [never] ? void : R extends z.ZodType ? Infer<R> : void>;
|
|
1244
|
+
] extends [never] ? void : R extends z.ZodType ? Infer<R> : void, TState, TServices>;
|
|
1101
1245
|
middleware?: Middleware[];
|
|
1102
1246
|
options?: Record<string, unknown>;
|
|
1103
1247
|
}) => {
|
|
1104
|
-
GET: RouteMethodOptions<P extends never ? never : P extends z.ZodType ? P : never, Q extends never ? never : Q extends z.ZodType ? Q : never, never,
|
|
1105
|
-
R extends never ? never : R extends z.ZodType ? R : never>;
|
|
1248
|
+
GET: RouteMethodOptions<P extends never ? never : P extends z.ZodType ? P : never, Q extends never ? never : Q extends z.ZodType ? Q : never, never, R extends never ? never : R extends z.ZodType ? R : never>;
|
|
1106
1249
|
path: string;
|
|
1107
1250
|
};
|
|
1108
1251
|
/**
|
|
1109
|
-
* POST route creator
|
|
1110
|
-
* FIXED: Default type parameters to never
|
|
1252
|
+
* POST route creator with state and services support
|
|
1111
1253
|
*/
|
|
1112
|
-
type CreatePostRoute = <P = never, Q = never, B = never, R = never>(config: {
|
|
1254
|
+
type CreatePostRoute = <TState extends State = State, TServices extends Services = Services>() => <P = never, Q = never, B = never, R = never>(config: {
|
|
1113
1255
|
schema?: {
|
|
1114
1256
|
params?: P extends never ? never : P;
|
|
1115
1257
|
query?: Q extends never ? never : Q;
|
|
@@ -1118,7 +1260,7 @@ type CreatePostRoute = <P = never, Q = never, B = never, R = never>(config: {
|
|
|
1118
1260
|
};
|
|
1119
1261
|
handler: RouteHandler<P extends z.ZodType ? Infer<P> : Record<string, string>, Q extends z.ZodType ? Infer<Q> : QueryParams, B extends z.ZodType ? Infer<B> : unknown, [
|
|
1120
1262
|
R
|
|
1121
|
-
] extends [never] ? void : R extends z.ZodType ? Infer<R> : void>;
|
|
1263
|
+
] extends [never] ? void : R extends z.ZodType ? Infer<R> : void, TState, TServices>;
|
|
1122
1264
|
middleware?: Middleware[];
|
|
1123
1265
|
options?: Record<string, unknown>;
|
|
1124
1266
|
}) => {
|
|
@@ -1126,10 +1268,9 @@ type CreatePostRoute = <P = never, Q = never, B = never, R = never>(config: {
|
|
|
1126
1268
|
path: string;
|
|
1127
1269
|
};
|
|
1128
1270
|
/**
|
|
1129
|
-
* PUT route creator
|
|
1130
|
-
* FIXED: Default type parameters to never
|
|
1271
|
+
* PUT route creator with state and services support
|
|
1131
1272
|
*/
|
|
1132
|
-
type CreatePutRoute = <P = never, Q = never, B = never, R = never>(config: {
|
|
1273
|
+
type CreatePutRoute = <TState extends State = State, TServices extends Services = Services>() => <P = never, Q = never, B = never, R = never>(config: {
|
|
1133
1274
|
schema?: {
|
|
1134
1275
|
params?: P extends never ? never : P;
|
|
1135
1276
|
query?: Q extends never ? never : Q;
|
|
@@ -1138,7 +1279,7 @@ type CreatePutRoute = <P = never, Q = never, B = never, R = never>(config: {
|
|
|
1138
1279
|
};
|
|
1139
1280
|
handler: RouteHandler<P extends z.ZodType ? Infer<P> : Record<string, string>, Q extends z.ZodType ? Infer<Q> : QueryParams, B extends z.ZodType ? Infer<B> : unknown, [
|
|
1140
1281
|
R
|
|
1141
|
-
] extends [never] ? void : R extends z.ZodType ? Infer<R> : void>;
|
|
1282
|
+
] extends [never] ? void : R extends z.ZodType ? Infer<R> : void, TState, TServices>;
|
|
1142
1283
|
middleware?: Middleware[];
|
|
1143
1284
|
options?: Record<string, unknown>;
|
|
1144
1285
|
}) => {
|
|
@@ -1146,30 +1287,28 @@ type CreatePutRoute = <P = never, Q = never, B = never, R = never>(config: {
|
|
|
1146
1287
|
path: string;
|
|
1147
1288
|
};
|
|
1148
1289
|
/**
|
|
1149
|
-
* DELETE route creator
|
|
1150
|
-
* FIXED: Default type parameters to never
|
|
1290
|
+
* DELETE route creator with state and services support
|
|
1151
1291
|
*/
|
|
1152
|
-
type CreateDeleteRoute = <P = never, Q = never, R = never>(config: {
|
|
1292
|
+
type CreateDeleteRoute = <TState extends State = State, TServices extends Services = Services>() => <P = never, Q = never, R = never>(config: {
|
|
1153
1293
|
schema?: {
|
|
1154
1294
|
params?: P extends never ? never : P;
|
|
1155
1295
|
query?: Q extends never ? never : Q;
|
|
1156
1296
|
response?: R extends never ? never : R;
|
|
1157
1297
|
};
|
|
1158
|
-
handler: RouteHandler<P extends z.ZodType ? Infer<P> : Record<string, string>, Q extends z.ZodType ? Infer<Q> : QueryParams, never,
|
|
1298
|
+
handler: RouteHandler<P extends z.ZodType ? Infer<P> : Record<string, string>, Q extends z.ZodType ? Infer<Q> : QueryParams, never, // DELETE never has body
|
|
1299
|
+
[
|
|
1159
1300
|
R
|
|
1160
|
-
] extends [never] ? void : R extends z.ZodType ? Infer<R> : void>;
|
|
1301
|
+
] extends [never] ? void : R extends z.ZodType ? Infer<R> : void, TState, TServices>;
|
|
1161
1302
|
middleware?: Middleware[];
|
|
1162
1303
|
options?: Record<string, unknown>;
|
|
1163
1304
|
}) => {
|
|
1164
|
-
DELETE: RouteMethodOptions<P extends never ? never : P extends z.ZodType ? P : never, Q extends never ? never : Q extends z.ZodType ? Q : never, never,
|
|
1165
|
-
R extends never ? never : R extends z.ZodType ? R : never>;
|
|
1305
|
+
DELETE: RouteMethodOptions<P extends never ? never : P extends z.ZodType ? P : never, Q extends never ? never : Q extends z.ZodType ? Q : never, never, R extends never ? never : R extends z.ZodType ? R : never>;
|
|
1166
1306
|
path: string;
|
|
1167
1307
|
};
|
|
1168
1308
|
/**
|
|
1169
|
-
* PATCH route creator
|
|
1170
|
-
* FIXED: Default type parameters to never
|
|
1309
|
+
* PATCH route creator with state and services support
|
|
1171
1310
|
*/
|
|
1172
|
-
type CreatePatchRoute = <P = never, Q = never, B = never, R = never>(config: {
|
|
1311
|
+
type CreatePatchRoute = <TState extends State = State, TServices extends Services = Services>() => <P = never, Q = never, B = never, R = never>(config: {
|
|
1173
1312
|
schema?: {
|
|
1174
1313
|
params?: P extends never ? never : P;
|
|
1175
1314
|
query?: Q extends never ? never : Q;
|
|
@@ -1178,7 +1317,7 @@ type CreatePatchRoute = <P = never, Q = never, B = never, R = never>(config: {
|
|
|
1178
1317
|
};
|
|
1179
1318
|
handler: RouteHandler<P extends z.ZodType ? Infer<P> : Record<string, string>, Q extends z.ZodType ? Infer<Q> : QueryParams, B extends z.ZodType ? Infer<B> : unknown, [
|
|
1180
1319
|
R
|
|
1181
|
-
] extends [never] ? void : R extends z.ZodType ? Infer<R> : void>;
|
|
1320
|
+
] extends [never] ? void : R extends z.ZodType ? Infer<R> : void, TState, TServices>;
|
|
1182
1321
|
middleware?: Middleware[];
|
|
1183
1322
|
options?: Record<string, unknown>;
|
|
1184
1323
|
}) => {
|
|
@@ -1186,43 +1325,41 @@ type CreatePatchRoute = <P = never, Q = never, B = never, R = never>(config: {
|
|
|
1186
1325
|
path: string;
|
|
1187
1326
|
};
|
|
1188
1327
|
/**
|
|
1189
|
-
* HEAD route creator
|
|
1190
|
-
* FIXED: Default type parameters to never
|
|
1328
|
+
* HEAD route creator with state and services support
|
|
1191
1329
|
*/
|
|
1192
|
-
type CreateHeadRoute = <P = never, Q = never, R = never>(config: {
|
|
1330
|
+
type CreateHeadRoute = <TState extends State = State, TServices extends Services = Services>() => <P = never, Q = never, R = never>(config: {
|
|
1193
1331
|
schema?: {
|
|
1194
1332
|
params?: P extends never ? never : P;
|
|
1195
1333
|
query?: Q extends never ? never : Q;
|
|
1196
1334
|
response?: R extends never ? never : R;
|
|
1197
1335
|
};
|
|
1198
|
-
handler: RouteHandler<P extends z.ZodType ? Infer<P> : Record<string, string>, Q extends z.ZodType ? Infer<Q> : QueryParams, never,
|
|
1336
|
+
handler: RouteHandler<P extends z.ZodType ? Infer<P> : Record<string, string>, Q extends z.ZodType ? Infer<Q> : QueryParams, never, // HEAD never has body
|
|
1337
|
+
[
|
|
1199
1338
|
R
|
|
1200
|
-
] extends [never] ? void : R extends z.ZodType ? Infer<R> : void>;
|
|
1339
|
+
] extends [never] ? void : R extends z.ZodType ? Infer<R> : void, TState, TServices>;
|
|
1201
1340
|
middleware?: Middleware[];
|
|
1202
1341
|
options?: Record<string, unknown>;
|
|
1203
1342
|
}) => {
|
|
1204
|
-
HEAD: RouteMethodOptions<P extends never ? never : P extends z.ZodType ? P : never, Q extends never ? never : Q extends z.ZodType ? Q : never, never,
|
|
1205
|
-
R extends never ? never : R extends z.ZodType ? R : never>;
|
|
1343
|
+
HEAD: RouteMethodOptions<P extends never ? never : P extends z.ZodType ? P : never, Q extends never ? never : Q extends z.ZodType ? Q : never, never, R extends never ? never : R extends z.ZodType ? R : never>;
|
|
1206
1344
|
path: string;
|
|
1207
1345
|
};
|
|
1208
1346
|
/**
|
|
1209
|
-
* OPTIONS route creator
|
|
1210
|
-
* FIXED: Default type parameters to never
|
|
1347
|
+
* OPTIONS route creator with state and services support
|
|
1211
1348
|
*/
|
|
1212
|
-
type CreateOptionsRoute = <P = never, Q = never, R = never>(config: {
|
|
1349
|
+
type CreateOptionsRoute = <TState extends State = State, TServices extends Services = Services>() => <P = never, Q = never, R = never>(config: {
|
|
1213
1350
|
schema?: {
|
|
1214
1351
|
params?: P extends never ? never : P;
|
|
1215
1352
|
query?: Q extends never ? never : Q;
|
|
1216
1353
|
response?: R extends never ? never : R;
|
|
1217
1354
|
};
|
|
1218
|
-
handler: RouteHandler<P extends z.ZodType ? Infer<P> : Record<string, string>, Q extends z.ZodType ? Infer<Q> : QueryParams, never,
|
|
1355
|
+
handler: RouteHandler<P extends z.ZodType ? Infer<P> : Record<string, string>, Q extends z.ZodType ? Infer<Q> : QueryParams, never, // OPTIONS never has body
|
|
1356
|
+
[
|
|
1219
1357
|
R
|
|
1220
|
-
] extends [never] ? void : R extends z.ZodType ? Infer<R> : void>;
|
|
1358
|
+
] extends [never] ? void : R extends z.ZodType ? Infer<R> : void, TState, TServices>;
|
|
1221
1359
|
middleware?: Middleware[];
|
|
1222
1360
|
options?: Record<string, unknown>;
|
|
1223
1361
|
}) => {
|
|
1224
|
-
OPTIONS: RouteMethodOptions<P extends never ? never : P extends z.ZodType ? P : never, Q extends never ? never : Q extends z.ZodType ? Q : never, never,
|
|
1225
|
-
R extends never ? never : R extends z.ZodType ? R : never>;
|
|
1362
|
+
OPTIONS: RouteMethodOptions<P extends never ? never : P extends z.ZodType ? P : never, Q extends never ? never : Q extends z.ZodType ? Q : never, never, R extends never ? never : R extends z.ZodType ? R : never>;
|
|
1226
1363
|
path: string;
|
|
1227
1364
|
};
|
|
1228
1365
|
|
|
@@ -1234,214 +1371,466 @@ declare function compose(middlewareStack: Middleware[]): MiddlewareFunction;
|
|
|
1234
1371
|
/**
|
|
1235
1372
|
* Create a middleware
|
|
1236
1373
|
*/
|
|
1237
|
-
declare function create$2(handlerOrOptions: MiddlewareFunction | MiddlewareOptions): Middleware
|
|
1238
|
-
|
|
1374
|
+
declare function create$2<TState = {}, TServices = {}>(handlerOrOptions: MiddlewareFunction | MiddlewareOptions): Middleware<TState, TServices>;
|
|
1375
|
+
/**
|
|
1376
|
+
* Create a middleware that only contributes state (no services)
|
|
1377
|
+
* Convenience helper for state-only middleware
|
|
1378
|
+
*
|
|
1379
|
+
* @template T - Type of state to contribute
|
|
1380
|
+
* @param handler - Middleware function that adds state
|
|
1381
|
+
* @returns Middleware that contributes state only
|
|
1382
|
+
*
|
|
1383
|
+
*/
|
|
1384
|
+
declare function stateMiddleware<T = {}>(handler: MiddlewareFunction): Middleware<T, {}>;
|
|
1239
1385
|
/**
|
|
1240
|
-
*
|
|
1386
|
+
* Create a middleware that only contributes services (no state)
|
|
1387
|
+
* Convenience helper for service-only middleware
|
|
1388
|
+
*
|
|
1389
|
+
* @template T - Type of services to contribute
|
|
1390
|
+
* @param handler - Middleware function that adds services
|
|
1391
|
+
* @returns Middleware that contributes services only
|
|
1241
1392
|
*
|
|
1242
|
-
* Provides the core HTTP/2 server implementation with HTTP/1.1 fallback.
|
|
1243
1393
|
*/
|
|
1394
|
+
declare function serviceMiddleware<T = {}>(handler: MiddlewareFunction): Middleware<{}, T>;
|
|
1244
1395
|
|
|
1245
|
-
interface Http2Options {
|
|
1246
|
-
enabled?: boolean | undefined;
|
|
1247
|
-
keyFile?: string | undefined;
|
|
1248
|
-
certFile?: string | undefined;
|
|
1249
|
-
}
|
|
1250
|
-
interface StartOptions {
|
|
1251
|
-
port?: number;
|
|
1252
|
-
host?: string;
|
|
1253
|
-
}
|
|
1254
|
-
interface StopOptions {
|
|
1255
|
-
timeout?: number;
|
|
1256
|
-
plugins?: Plugin[];
|
|
1257
|
-
onStopping?: () => Promise<void> | void;
|
|
1258
|
-
onStopped?: () => Promise<void> | void;
|
|
1259
|
-
}
|
|
1260
1396
|
/**
|
|
1261
|
-
*
|
|
1397
|
+
* Represents a single Server-Sent Event
|
|
1398
|
+
* @template T - The type of data payload
|
|
1399
|
+
*
|
|
1400
|
+
* @example
|
|
1401
|
+
* ```typescript
|
|
1402
|
+
* const event: SSEEvent<{ message: string }> = {
|
|
1403
|
+
* id: '123',
|
|
1404
|
+
* event: 'message',
|
|
1405
|
+
* data: { message: 'Hello, world!' },
|
|
1406
|
+
* retry: 5000
|
|
1407
|
+
* };
|
|
1408
|
+
* ```
|
|
1262
1409
|
*/
|
|
1263
|
-
interface
|
|
1264
|
-
/**
|
|
1265
|
-
|
|
1266
|
-
/**
|
|
1267
|
-
|
|
1268
|
-
/**
|
|
1269
|
-
|
|
1270
|
-
/**
|
|
1271
|
-
|
|
1272
|
-
/** Enable HTTP/2 (default: true) */
|
|
1273
|
-
enabled?: boolean | undefined;
|
|
1274
|
-
/** Path to key file for HTTPS/HTTP2 */
|
|
1275
|
-
keyFile?: string | undefined;
|
|
1276
|
-
/** Path to certificate file for HTTPS/HTTP2 */
|
|
1277
|
-
certFile?: string | undefined;
|
|
1278
|
-
};
|
|
1279
|
-
/** Global middleware to apply to all routes */
|
|
1280
|
-
middleware?: Middleware[];
|
|
1281
|
-
/** Plugins to register */
|
|
1282
|
-
plugins?: Plugin[];
|
|
1410
|
+
interface SSEEvent<T = unknown> {
|
|
1411
|
+
/** Unique identifier for the event */
|
|
1412
|
+
id: string;
|
|
1413
|
+
/** Event type/name for client-side event listeners */
|
|
1414
|
+
event: string;
|
|
1415
|
+
/** The actual data payload of the event */
|
|
1416
|
+
data: T;
|
|
1417
|
+
/** Optional retry interval in milliseconds for reconnection */
|
|
1418
|
+
retry?: number;
|
|
1283
1419
|
}
|
|
1284
1420
|
/**
|
|
1285
|
-
*
|
|
1421
|
+
* Backpressure handling strategies for SSE streams
|
|
1422
|
+
*
|
|
1423
|
+
* - `drop-oldest`: Remove oldest events from buffer when full
|
|
1424
|
+
* - `drop-newest`: Reject new events when buffer is full
|
|
1425
|
+
* - `close`: Close the stream when buffer limit is reached
|
|
1286
1426
|
*/
|
|
1287
|
-
|
|
1288
|
-
/** Port to listen on (default: 3000) */
|
|
1289
|
-
port: number;
|
|
1290
|
-
/** Host to bind to (default: localhost) */
|
|
1291
|
-
host: string;
|
|
1292
|
-
/** Directory containing route files (default: ./routes) */
|
|
1293
|
-
routesDir: string;
|
|
1294
|
-
/** HTTP/2 options */
|
|
1295
|
-
http2?: {
|
|
1296
|
-
/** Enable HTTP/2 (default: true) */
|
|
1297
|
-
enabled?: boolean | undefined;
|
|
1298
|
-
/** Path to key file for HTTPS/HTTP2 */
|
|
1299
|
-
keyFile?: string | undefined;
|
|
1300
|
-
/** Path to certificate file for HTTPS/HTTP2 */
|
|
1301
|
-
certFile?: string | undefined;
|
|
1302
|
-
};
|
|
1303
|
-
/** Global middleware to apply to all routes */
|
|
1304
|
-
middleware?: Middleware[];
|
|
1305
|
-
/** Plugins to register */
|
|
1306
|
-
plugins?: Plugin[];
|
|
1307
|
-
}
|
|
1427
|
+
type SSEBufferStrategy = 'drop-oldest' | 'drop-newest' | 'close';
|
|
1308
1428
|
/**
|
|
1309
|
-
*
|
|
1429
|
+
* Configuration options for SSE streams
|
|
1430
|
+
*
|
|
1431
|
+
* @example
|
|
1432
|
+
* ```typescript
|
|
1433
|
+
* const options: SSEOptions = {
|
|
1434
|
+
* autoClose: true,
|
|
1435
|
+
* maxBufferSize: 100,
|
|
1436
|
+
* bufferStrategy: 'drop-oldest'
|
|
1437
|
+
* };
|
|
1438
|
+
* ```
|
|
1310
1439
|
*/
|
|
1311
|
-
interface
|
|
1312
|
-
/**
|
|
1313
|
-
|
|
1314
|
-
/**
|
|
1315
|
-
|
|
1316
|
-
/**
|
|
1317
|
-
|
|
1318
|
-
events
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
middleware: Middleware[];
|
|
1323
|
-
/** Internal property for signal hanlders */
|
|
1324
|
-
_signalHandlers?: {
|
|
1325
|
-
unregister: () => void;
|
|
1326
|
-
};
|
|
1327
|
-
/** Start the server and listen for connections */
|
|
1328
|
-
listen: (port?: number, host?: string) => Promise<Server>;
|
|
1329
|
-
/** Stop the server */
|
|
1330
|
-
close: (stopOptions?: StopOptions) => Promise<void>;
|
|
1331
|
-
/** Add global middleware */
|
|
1332
|
-
use: (middleware: Middleware | Middleware[]) => Server;
|
|
1333
|
-
/** Register a plugin */
|
|
1334
|
-
register: (plugin: Plugin) => Promise<Server>;
|
|
1335
|
-
/** Access to the routing system */
|
|
1336
|
-
router: Router;
|
|
1337
|
-
/** Context storage system */
|
|
1338
|
-
context: AsyncLocalStorage<Context>;
|
|
1339
|
-
pluginManager: PluginLifecycleManager;
|
|
1440
|
+
interface SSEOptions {
|
|
1441
|
+
/** ms between heartbeat pings (0 to disable) */
|
|
1442
|
+
heartbeatInterval?: number;
|
|
1443
|
+
/** Maximum size in bytes for a single event */
|
|
1444
|
+
maxEventSize?: number;
|
|
1445
|
+
/** Automatically close stream when client disconnects */
|
|
1446
|
+
autoClose?: boolean;
|
|
1447
|
+
/** Maximum number of events to buffer before applying strategy */
|
|
1448
|
+
maxBufferSize?: number;
|
|
1449
|
+
/** Strategy to handle buffer overflow conditions */
|
|
1450
|
+
bufferStrategy?: SSEBufferStrategy;
|
|
1340
1451
|
}
|
|
1341
|
-
type RequestHandler = (req: http.IncomingMessage | http2.Http2ServerRequest, res: http.ServerResponse | http2.Http2ServerResponse) => Promise<void>;
|
|
1342
|
-
|
|
1343
1452
|
/**
|
|
1344
|
-
*
|
|
1345
|
-
*
|
|
1346
|
-
* Provides the plugin system for extending framework functionality.
|
|
1453
|
+
* Connection states for SSE streams
|
|
1347
1454
|
*/
|
|
1348
|
-
|
|
1455
|
+
type SSEConnectionState = 'connecting' | 'connected' | 'disconnected' | 'closed';
|
|
1349
1456
|
/**
|
|
1350
|
-
*
|
|
1457
|
+
* SSE stream interface for managing server-sent events
|
|
1458
|
+
*
|
|
1459
|
+
* @example
|
|
1460
|
+
* ```typescript
|
|
1461
|
+
* const stream: SSEStream = createSSEStream(response);
|
|
1462
|
+
*
|
|
1463
|
+
* // Send typed event
|
|
1464
|
+
* stream.send('notification', { type: 'info', message: 'Update available' });
|
|
1465
|
+
*
|
|
1466
|
+
* // Send error event
|
|
1467
|
+
* stream.sendError(new Error('Processing failed'));
|
|
1468
|
+
*
|
|
1469
|
+
* // Clean up on close
|
|
1470
|
+
* stream.onClose(() => {
|
|
1471
|
+
* console.log('Client disconnected');
|
|
1472
|
+
* });
|
|
1473
|
+
*
|
|
1474
|
+
* // Close stream
|
|
1475
|
+
* stream.close();
|
|
1476
|
+
* ```
|
|
1351
1477
|
*/
|
|
1352
|
-
interface
|
|
1353
|
-
/**
|
|
1354
|
-
|
|
1478
|
+
interface SSEStream {
|
|
1479
|
+
/**
|
|
1480
|
+
* Send an event with typed data to the client
|
|
1481
|
+
* @template T - Type of the data payload
|
|
1482
|
+
* @param event - Event name/type
|
|
1483
|
+
* @param data - Event data payload
|
|
1484
|
+
*/
|
|
1485
|
+
send<T>(event: string, data: T): void;
|
|
1486
|
+
/**
|
|
1487
|
+
* Send an error event to the client
|
|
1488
|
+
* @param error - Error object to send
|
|
1489
|
+
*/
|
|
1490
|
+
sendError(error: Error): void;
|
|
1491
|
+
/**
|
|
1492
|
+
* Close the SSE stream connection
|
|
1493
|
+
*/
|
|
1494
|
+
close(): void;
|
|
1495
|
+
/**
|
|
1496
|
+
* Register a callback for stream closure
|
|
1497
|
+
* @param cb - Callback function to execute on close
|
|
1498
|
+
*/
|
|
1499
|
+
onClose(cb: () => void): void;
|
|
1355
1500
|
}
|
|
1356
1501
|
/**
|
|
1357
|
-
*
|
|
1502
|
+
* Extended SSE stream with additional control methods
|
|
1358
1503
|
*/
|
|
1359
|
-
interface
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
/**
|
|
1363
|
-
|
|
1364
|
-
/**
|
|
1365
|
-
|
|
1366
|
-
/**
|
|
1367
|
-
|
|
1368
|
-
/**
|
|
1369
|
-
|
|
1504
|
+
interface SSEStreamExtended extends SSEStream {
|
|
1505
|
+
readonly id: string;
|
|
1506
|
+
[Symbol.asyncIterator](): AsyncGenerator<BufferedEvent, void, unknown>;
|
|
1507
|
+
/** Current connection state */
|
|
1508
|
+
readonly state: SSEConnectionState;
|
|
1509
|
+
/** Number of events in the buffer */
|
|
1510
|
+
readonly bufferSize: number;
|
|
1511
|
+
/** Check if stream is writable */
|
|
1512
|
+
readonly isWritable: boolean;
|
|
1513
|
+
/**
|
|
1514
|
+
* Ping the client to keep connection alive
|
|
1515
|
+
* @param comment - Optional comment to include in ping
|
|
1516
|
+
*/
|
|
1517
|
+
ping(comment?: string): void;
|
|
1518
|
+
/**
|
|
1519
|
+
* Set retry interval for client reconnection
|
|
1520
|
+
* @param milliseconds - Retry interval in milliseconds
|
|
1521
|
+
*/
|
|
1522
|
+
setRetry(milliseconds: number): void;
|
|
1523
|
+
/**
|
|
1524
|
+
* Flush any buffered events immediately
|
|
1525
|
+
*/
|
|
1526
|
+
flush(): void;
|
|
1527
|
+
getMetrics(): StreamMetrics;
|
|
1370
1528
|
}
|
|
1371
1529
|
/**
|
|
1372
|
-
*
|
|
1530
|
+
* SSE event serialization format
|
|
1373
1531
|
*/
|
|
1374
|
-
interface
|
|
1375
|
-
/**
|
|
1376
|
-
|
|
1377
|
-
/**
|
|
1378
|
-
|
|
1532
|
+
interface SSESerializedEvent {
|
|
1533
|
+
/** Event ID field */
|
|
1534
|
+
id?: string;
|
|
1535
|
+
/** Event type field */
|
|
1536
|
+
event?: string;
|
|
1537
|
+
/** Data field (can be multi-line) */
|
|
1538
|
+
data: string;
|
|
1539
|
+
/** Retry field */
|
|
1540
|
+
retry?: number;
|
|
1541
|
+
/** Comment field for keep-alive */
|
|
1542
|
+
comment?: string;
|
|
1379
1543
|
}
|
|
1380
1544
|
/**
|
|
1381
|
-
*
|
|
1545
|
+
* SSE event handler function type
|
|
1546
|
+
* @template T - Type of the event data
|
|
1382
1547
|
*/
|
|
1383
|
-
type
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
debug?: boolean;
|
|
1395
|
-
/** Custom error handler for plugin failures */
|
|
1396
|
-
onError?: (plugin: Plugin, phase: string, error: Error) => void;
|
|
1548
|
+
type SSEEventHandler<T = unknown> = (event: SSEEvent<T>) => void | Promise<void>;
|
|
1549
|
+
/**
|
|
1550
|
+
* SSE event listener registration
|
|
1551
|
+
*/
|
|
1552
|
+
interface SSEEventListener {
|
|
1553
|
+
/** Event type to listen for (use '*' for all events) */
|
|
1554
|
+
event: string;
|
|
1555
|
+
/** Handler function for the event */
|
|
1556
|
+
handler: SSEEventHandler;
|
|
1557
|
+
/** Optional listener identifier for removal */
|
|
1558
|
+
id?: string;
|
|
1397
1559
|
}
|
|
1398
|
-
|
|
1399
1560
|
/**
|
|
1400
|
-
*
|
|
1561
|
+
* SSE metrics for monitoring stream performance
|
|
1401
1562
|
*/
|
|
1402
|
-
|
|
1403
|
-
|
|
1563
|
+
interface SSEMetrics {
|
|
1564
|
+
/** Total number of events sent */
|
|
1565
|
+
eventsSent: number;
|
|
1566
|
+
/** Total number of events dropped */
|
|
1567
|
+
eventsDropped: number;
|
|
1568
|
+
/** Current number of connected clients */
|
|
1569
|
+
activeConnections: number;
|
|
1570
|
+
/** Total bytes sent */
|
|
1571
|
+
bytesSent: number;
|
|
1572
|
+
/** Average event send latency in milliseconds */
|
|
1573
|
+
averageLatency: number;
|
|
1574
|
+
/** Connection duration in milliseconds */
|
|
1575
|
+
connectionDuration: number;
|
|
1576
|
+
}
|
|
1404
1577
|
/**
|
|
1405
|
-
*
|
|
1406
|
-
* SIMPLER FIX: Just pass the config through, TypeScript will handle the types
|
|
1578
|
+
* SSE stream manager for handling multiple clients
|
|
1407
1579
|
*/
|
|
1408
|
-
|
|
1580
|
+
interface SSEStreamManager {
|
|
1581
|
+
/**
|
|
1582
|
+
* Create a new SSE stream for a client
|
|
1583
|
+
* @param clientId - Unique identifier for the client
|
|
1584
|
+
* @param options - Stream configuration options
|
|
1585
|
+
*/
|
|
1586
|
+
createStream(clientId: string, options?: SSEOptions): SSEStream;
|
|
1587
|
+
/**
|
|
1588
|
+
* Get an existing stream by client ID
|
|
1589
|
+
* @param clientId - Client identifier
|
|
1590
|
+
*/
|
|
1591
|
+
getStream(clientId: string): SSEStream | undefined;
|
|
1592
|
+
/**
|
|
1593
|
+
* Broadcast an event to all connected clients
|
|
1594
|
+
* @template T - Type of the event data
|
|
1595
|
+
* @param event - Event name
|
|
1596
|
+
* @param data - Event data
|
|
1597
|
+
*/
|
|
1598
|
+
broadcast<T>(event: string, data: T): void;
|
|
1599
|
+
/**
|
|
1600
|
+
* Broadcast to specific clients
|
|
1601
|
+
* @template T - Type of the event data
|
|
1602
|
+
* @param clientIds - Array of client IDs
|
|
1603
|
+
* @param event - Event name
|
|
1604
|
+
* @param data - Event data
|
|
1605
|
+
*/
|
|
1606
|
+
multicast<T>(clientIds: string[], event: string, data: T): void;
|
|
1607
|
+
/**
|
|
1608
|
+
* Close a specific client stream
|
|
1609
|
+
* @param clientId - Client identifier
|
|
1610
|
+
*/
|
|
1611
|
+
closeStream(clientId: string): void;
|
|
1612
|
+
/**
|
|
1613
|
+
* Close all active streams
|
|
1614
|
+
*/
|
|
1615
|
+
closeAll(): void;
|
|
1616
|
+
/**
|
|
1617
|
+
* Get metrics for all streams
|
|
1618
|
+
*/
|
|
1619
|
+
getMetrics(): SSEMetrics;
|
|
1620
|
+
}
|
|
1409
1621
|
/**
|
|
1410
|
-
*
|
|
1622
|
+
* Result type for operations that can fail
|
|
1411
1623
|
*/
|
|
1412
|
-
|
|
1624
|
+
type RegistryResult<T> = {
|
|
1625
|
+
success: true;
|
|
1626
|
+
value: T;
|
|
1627
|
+
} | {
|
|
1628
|
+
success: false;
|
|
1629
|
+
error: string;
|
|
1630
|
+
};
|
|
1413
1631
|
/**
|
|
1414
|
-
*
|
|
1632
|
+
* Connection metadata stored in the registry
|
|
1415
1633
|
*/
|
|
1416
|
-
|
|
1634
|
+
interface ConnectionEntry {
|
|
1635
|
+
stream: SSEStream;
|
|
1636
|
+
connectedAt: number;
|
|
1637
|
+
lastActivity: number;
|
|
1638
|
+
clientIp?: string;
|
|
1639
|
+
userAgent?: string;
|
|
1640
|
+
}
|
|
1417
1641
|
/**
|
|
1418
|
-
*
|
|
1642
|
+
* Internal connection registry interface
|
|
1419
1643
|
*/
|
|
1420
|
-
|
|
1644
|
+
interface ConnectionRegistry {
|
|
1645
|
+
/** Add a new connection to the registry */
|
|
1646
|
+
add: (id: string, stream: SSEStream, metadata?: {
|
|
1647
|
+
clientIp?: string;
|
|
1648
|
+
userAgent?: string;
|
|
1649
|
+
}) => void;
|
|
1650
|
+
/** Remove a connection from the registry */
|
|
1651
|
+
remove: (id: string) => void;
|
|
1652
|
+
/** Get current connection count */
|
|
1653
|
+
count: () => number;
|
|
1654
|
+
/** Clean up inactive or closed connections */
|
|
1655
|
+
cleanup: () => void;
|
|
1656
|
+
/** Get connection by ID (for internal use) */
|
|
1657
|
+
get: (id: string) => SSEStream | undefined;
|
|
1658
|
+
/** Check if a connection exists */
|
|
1659
|
+
has: (id: string) => boolean;
|
|
1660
|
+
/** Get all connection IDs */
|
|
1661
|
+
getIds: () => string[];
|
|
1662
|
+
/** Shutdown the registry and close all connections */
|
|
1663
|
+
shutdown: () => void;
|
|
1664
|
+
}
|
|
1421
1665
|
/**
|
|
1422
|
-
*
|
|
1666
|
+
* Extended stream interface for typed events
|
|
1423
1667
|
*/
|
|
1424
|
-
|
|
1668
|
+
interface TypedSSEStream<TEvents extends Record<string, z.ZodType>> extends SSEStreamExtended {
|
|
1669
|
+
send<K extends keyof TEvents>(event: K & string, data: z.infer<TEvents[K]>): void;
|
|
1670
|
+
}
|
|
1425
1671
|
/**
|
|
1426
|
-
*
|
|
1672
|
+
* Schema for SSE route validation with generic type parameters
|
|
1427
1673
|
*/
|
|
1428
|
-
|
|
1674
|
+
interface SSERouteSchema<P extends z.ZodType = z.ZodType<any>, Q extends z.ZodType = z.ZodType<any>, E = any> {
|
|
1675
|
+
/** Parameter schema for validation */
|
|
1676
|
+
params?: P;
|
|
1677
|
+
/** Query schema for validation */
|
|
1678
|
+
query?: Q;
|
|
1679
|
+
/** Events schema for validation (SSE-specific, replaces response) */
|
|
1680
|
+
events?: E;
|
|
1681
|
+
}
|
|
1429
1682
|
/**
|
|
1430
|
-
*
|
|
1683
|
+
* SSE route handler function with stream as first parameter
|
|
1684
|
+
* This is the user-facing API - they write handlers with this signature
|
|
1431
1685
|
*/
|
|
1432
|
-
|
|
1433
|
-
|
|
1686
|
+
type SSERouteHandler<TStream extends SSEStreamExtended = SSEStreamExtended, TParams = Record<string, string>, TQuery = Record<string, string | string[] | undefined>, TState extends State = State, TServices extends Services = Services> = (stream: TStream, ctx: Context<TState, TServices, never, TQuery>, // SSE never has body
|
|
1687
|
+
params: TParams) => Promise<void> | void;
|
|
1434
1688
|
/**
|
|
1435
|
-
*
|
|
1689
|
+
* SSE route creator with state and services support
|
|
1690
|
+
* Returns a higher-order function to handle generics properly
|
|
1691
|
+
*
|
|
1692
|
+
* The return type matches what the implementation actually returns:
|
|
1693
|
+
* - A route object with a GET property
|
|
1694
|
+
* - The GET property contains the wrapped handler and schemas
|
|
1695
|
+
* - The wrapped handler has the standard (ctx, params) signature expected by the router
|
|
1436
1696
|
*/
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1697
|
+
type CreateSSERoute = <TState extends State = State, TServices extends Services = Services>() => <P = never, Q = never, E = never>(config: {
|
|
1698
|
+
schema?: {
|
|
1699
|
+
params?: P extends never ? never : P;
|
|
1700
|
+
query?: Q extends never ? never : Q;
|
|
1701
|
+
events?: E extends never ? never : E;
|
|
1702
|
+
};
|
|
1703
|
+
handler: SSERouteHandler<E extends Record<string, z.ZodType> ? TypedSSEStream<E> : SSEStreamExtended, P extends z.ZodType ? Infer<P> : Record<string, string>, Q extends z.ZodType ? Infer<Q> : QueryParams, TState, TServices>;
|
|
1704
|
+
middleware?: Middleware[];
|
|
1705
|
+
options?: Record<string, unknown>;
|
|
1706
|
+
}) => {
|
|
1707
|
+
GET: {
|
|
1708
|
+
handler: (ctx: any, params: any) => Promise<void>;
|
|
1709
|
+
schema?: {
|
|
1710
|
+
params?: P extends never ? undefined : P;
|
|
1711
|
+
query?: Q extends never ? undefined : Q;
|
|
1712
|
+
};
|
|
1713
|
+
middleware?: Middleware[];
|
|
1714
|
+
options?: Record<string, unknown>;
|
|
1715
|
+
};
|
|
1716
|
+
path: string;
|
|
1717
|
+
};
|
|
1718
|
+
/**
|
|
1719
|
+
* Buffered event with metadata
|
|
1720
|
+
*/
|
|
1721
|
+
interface BufferedEvent {
|
|
1722
|
+
id: string;
|
|
1723
|
+
event: string;
|
|
1724
|
+
data: unknown;
|
|
1725
|
+
size: number;
|
|
1726
|
+
timestamp: number;
|
|
1727
|
+
correlationId: string;
|
|
1728
|
+
}
|
|
1729
|
+
/**
|
|
1730
|
+
* Stream metrics for monitoring
|
|
1731
|
+
*/
|
|
1732
|
+
interface StreamMetrics {
|
|
1733
|
+
eventsSent: number;
|
|
1734
|
+
eventsDropped: number;
|
|
1735
|
+
bytesWritten: number;
|
|
1736
|
+
bufferHighWatermark: number;
|
|
1737
|
+
lastEventTime: number;
|
|
1738
|
+
}
|
|
1739
|
+
|
|
1740
|
+
/**
|
|
1741
|
+
* SSE Client Types for BlaizeJS
|
|
1742
|
+
* Location: packages/blaize-client/src/sse/types.ts
|
|
1743
|
+
*/
|
|
1744
|
+
|
|
1745
|
+
/**
|
|
1746
|
+
* Event handlers map
|
|
1747
|
+
*/
|
|
1748
|
+
interface EventHandlers {
|
|
1749
|
+
[event: string]: Set<(data: any) => void>;
|
|
1750
|
+
}
|
|
1751
|
+
/**
|
|
1752
|
+
* SSE connection configuration options
|
|
1753
|
+
*/
|
|
1754
|
+
interface SSEClientOptions {
|
|
1755
|
+
headers?: Record<string, string>;
|
|
1756
|
+
withCredentials?: boolean;
|
|
1757
|
+
reconnect?: {
|
|
1758
|
+
enabled: boolean;
|
|
1759
|
+
maxAttempts?: number;
|
|
1760
|
+
strategy?: ReconnectStrategy;
|
|
1761
|
+
initialDelay?: number;
|
|
1762
|
+
};
|
|
1763
|
+
bufferMissedEvents?: boolean;
|
|
1764
|
+
maxMissedEvents?: number;
|
|
1765
|
+
heartbeatTimeout?: number;
|
|
1766
|
+
parseJSON?: boolean;
|
|
1767
|
+
/**
|
|
1768
|
+
* Whether to wait for connection before resolving the promise.
|
|
1769
|
+
* If false, returns the client immediately without waiting.
|
|
1770
|
+
* Default: true
|
|
1771
|
+
*/
|
|
1772
|
+
waitForConnection?: boolean;
|
|
1773
|
+
/**
|
|
1774
|
+
* Optional timeout for initial connection in milliseconds.
|
|
1775
|
+
* If not set, no timeout is applied (relies on EventSource native timeout).
|
|
1776
|
+
* Only applies if waitForConnection is true.
|
|
1777
|
+
*/
|
|
1778
|
+
connectionTimeout?: number;
|
|
1779
|
+
}
|
|
1780
|
+
/**
|
|
1781
|
+
* Metrics for SSE connection monitoring
|
|
1782
|
+
*/
|
|
1783
|
+
interface SSEClientMetrics {
|
|
1784
|
+
eventsReceived: number;
|
|
1785
|
+
bytesReceived: number;
|
|
1786
|
+
connectionDuration: number;
|
|
1787
|
+
reconnectAttempts: number;
|
|
1788
|
+
lastEventId?: string;
|
|
1789
|
+
}
|
|
1790
|
+
/**
|
|
1791
|
+
* Reconnection delay calculation strategy
|
|
1792
|
+
*/
|
|
1793
|
+
type ReconnectStrategy = (attempt: number) => number;
|
|
1794
|
+
/**
|
|
1795
|
+
* SSE Client interface with type-safe event handling
|
|
1796
|
+
*/
|
|
1797
|
+
interface SSEClient<TEvents extends Record<string, unknown> = Record<string, unknown>> {
|
|
1798
|
+
on<K extends keyof TEvents>(event: K & string, handler: (data: TEvents[K]) => void): void;
|
|
1799
|
+
on(event: 'error', handler: (error: BlaizeError) => void): void;
|
|
1800
|
+
on(event: 'open', handler: () => void): void;
|
|
1801
|
+
on(event: 'close', handler: (event: CloseEvent) => void): void;
|
|
1802
|
+
off<K extends keyof TEvents>(event: K & string, handler?: (data: TEvents[K]) => void): void;
|
|
1803
|
+
off(event: 'error', handler?: (error: BlaizeError) => void): void;
|
|
1804
|
+
off(event: 'open', handler?: () => void): void;
|
|
1805
|
+
off(event: 'close', handler?: (event: CloseEvent) => void): void;
|
|
1806
|
+
once<K extends keyof TEvents>(event: K & string, handler: (data: TEvents[K]) => void): void;
|
|
1807
|
+
once(event: 'error', handler: (error: BlaizeError) => void): void;
|
|
1808
|
+
once(event: 'open', handler: () => void): void;
|
|
1809
|
+
once(event: 'close', handler: (event: CloseEvent) => void): void;
|
|
1810
|
+
close(): void;
|
|
1811
|
+
readonly state: SSEConnectionState;
|
|
1812
|
+
readonly metrics: SSEClientMetrics;
|
|
1813
|
+
readonly lastEventId?: string;
|
|
1814
|
+
}
|
|
1815
|
+
/**
|
|
1816
|
+
* Close event for SSE connections
|
|
1817
|
+
*/
|
|
1818
|
+
interface CloseEvent {
|
|
1819
|
+
reconnect: boolean;
|
|
1820
|
+
reason?: string;
|
|
1821
|
+
}
|
|
1822
|
+
/**
|
|
1823
|
+
* Internal SSE connection factory
|
|
1824
|
+
* Returns a Promise that resolves to an SSEClient instance
|
|
1825
|
+
*/
|
|
1826
|
+
type SSEConnectionFactory<TEvents extends Record<string, unknown> = Record<string, unknown>> = (options?: SSEClientOptions) => Promise<SSEClient<TEvents>>;
|
|
1827
|
+
|
|
1828
|
+
type ExtractMethod<T> = T extends {
|
|
1829
|
+
GET: any;
|
|
1830
|
+
} ? 'GET' : T extends {
|
|
1831
|
+
POST: any;
|
|
1832
|
+
} ? 'POST' : T extends {
|
|
1833
|
+
PUT: any;
|
|
1445
1834
|
} ? 'PUT' : T extends {
|
|
1446
1835
|
DELETE: any;
|
|
1447
1836
|
} ? 'DELETE' : T extends {
|
|
@@ -1471,12 +1860,12 @@ type GetRouteMethodOptions<TRoute> = TRoute extends {
|
|
|
1471
1860
|
} ? M : TRoute extends {
|
|
1472
1861
|
OPTIONS: infer M;
|
|
1473
1862
|
} ? M : never;
|
|
1474
|
-
type IsNever<T> = [T] extends [never] ? true : false;
|
|
1475
|
-
type BuildArgsObject<P, Q, B> = (IsNever<P> extends true ? {} : {
|
|
1863
|
+
type IsNever$1<T> = [T] extends [never] ? true : false;
|
|
1864
|
+
type BuildArgsObject<P, Q, B> = (IsNever$1<P> extends true ? {} : {
|
|
1476
1865
|
params: Infer<P>;
|
|
1477
|
-
}) & (IsNever<Q> extends true ? {} : {
|
|
1866
|
+
}) & (IsNever$1<Q> extends true ? {} : {
|
|
1478
1867
|
query: Infer<Q>;
|
|
1479
|
-
}) & (IsNever<B> extends true ? {} : {
|
|
1868
|
+
}) & (IsNever$1<B> extends true ? {} : {
|
|
1480
1869
|
body: Infer<B>;
|
|
1481
1870
|
});
|
|
1482
1871
|
type IsEmptyObject<T> = keyof T extends never ? true : false;
|
|
@@ -1491,6 +1880,7 @@ interface ClientConfig {
|
|
|
1491
1880
|
baseUrl: string;
|
|
1492
1881
|
defaultHeaders?: Record<string, string>;
|
|
1493
1882
|
timeout?: number;
|
|
1883
|
+
sse?: SSEClientOptions;
|
|
1494
1884
|
}
|
|
1495
1885
|
interface InternalRequestArgs {
|
|
1496
1886
|
params?: Record<string, any>;
|
|
@@ -1504,6 +1894,1049 @@ interface RequestOptions {
|
|
|
1504
1894
|
body?: string;
|
|
1505
1895
|
timeout: number;
|
|
1506
1896
|
}
|
|
1897
|
+
/**
|
|
1898
|
+
* Detect if a route has SSE support
|
|
1899
|
+
* SSE routes have a special 'SSE' method key
|
|
1900
|
+
*/
|
|
1901
|
+
type HasSSEMethod<TRoute> = TRoute extends {
|
|
1902
|
+
SSE: any;
|
|
1903
|
+
} ? true : false;
|
|
1904
|
+
/**
|
|
1905
|
+
* Extract SSE event types from route schema
|
|
1906
|
+
*/
|
|
1907
|
+
type ExtractSSEEvents<TRoute> = TRoute extends {
|
|
1908
|
+
SSE: {
|
|
1909
|
+
events?: infer E;
|
|
1910
|
+
};
|
|
1911
|
+
} ? E extends z.ZodType ? z.infer<E> : Record<string, unknown> : Record<string, unknown>;
|
|
1912
|
+
/**
|
|
1913
|
+
* Extract SSE query parameters from route
|
|
1914
|
+
*/
|
|
1915
|
+
type ExtractSSEQuery<TRoute> = TRoute extends {
|
|
1916
|
+
SSE: {
|
|
1917
|
+
schema?: {
|
|
1918
|
+
query?: infer Q;
|
|
1919
|
+
};
|
|
1920
|
+
};
|
|
1921
|
+
} ? Q extends z.ZodType ? z.infer<Q> : Record<string, unknown> : never;
|
|
1922
|
+
/**
|
|
1923
|
+
* Extract SSE params from route
|
|
1924
|
+
*/
|
|
1925
|
+
type ExtractSSEParams<TRoute> = TRoute extends {
|
|
1926
|
+
SSE: {
|
|
1927
|
+
schema?: {
|
|
1928
|
+
params?: infer P;
|
|
1929
|
+
};
|
|
1930
|
+
};
|
|
1931
|
+
} ? P extends z.ZodType ? z.infer<P> : Record<string, string> : never;
|
|
1932
|
+
/**
|
|
1933
|
+
* Build SSE method arguments
|
|
1934
|
+
*/
|
|
1935
|
+
type BuildSSEArgs<TRoute> = ExtractSSEParams<TRoute> extends never ? ExtractSSEQuery<TRoute> extends never ? {
|
|
1936
|
+
options?: SSEClientOptions;
|
|
1937
|
+
} : {
|
|
1938
|
+
query: ExtractSSEQuery<TRoute>;
|
|
1939
|
+
options?: SSEClientOptions;
|
|
1940
|
+
} : ExtractSSEQuery<TRoute> extends never ? {
|
|
1941
|
+
params: ExtractSSEParams<TRoute>;
|
|
1942
|
+
options?: SSEClientOptions;
|
|
1943
|
+
} : {
|
|
1944
|
+
params: ExtractSSEParams<TRoute>;
|
|
1945
|
+
query: ExtractSSEQuery<TRoute>;
|
|
1946
|
+
options?: SSEClientOptions;
|
|
1947
|
+
};
|
|
1948
|
+
/**
|
|
1949
|
+
* Create SSE client method
|
|
1950
|
+
*/
|
|
1951
|
+
type CreateSSEMethod<TRoute> = HasSSEMethod<TRoute> extends true ? BuildSSEArgs<TRoute> extends {
|
|
1952
|
+
options?: SSEClientOptions;
|
|
1953
|
+
} ? (args?: BuildSSEArgs<TRoute>) => Promise<SSEClient<ExtractSSEEvents<TRoute>>> : (args: BuildSSEArgs<TRoute>) => Promise<SSEClient<ExtractSSEEvents<TRoute>>> : never;
|
|
1954
|
+
/**
|
|
1955
|
+
* Extract SSE routes from registry
|
|
1956
|
+
*/
|
|
1957
|
+
type ExtractSSERoutes<TRoutes extends Record<string, any>> = {
|
|
1958
|
+
[K in keyof TRoutes as HasSSEMethod<TRoutes[K]> extends true ? K : never]: TRoutes[K];
|
|
1959
|
+
};
|
|
1960
|
+
/**
|
|
1961
|
+
* Enhanced client with SSE support
|
|
1962
|
+
*/
|
|
1963
|
+
type CreateEnhancedClient<TRoutes extends Record<string, any>, TRegistry> = TRegistry & {
|
|
1964
|
+
$sse: {
|
|
1965
|
+
[K in keyof ExtractSSERoutes<TRoutes>]: CreateSSEMethod<TRoutes[K]>;
|
|
1966
|
+
};
|
|
1967
|
+
};
|
|
1968
|
+
|
|
1969
|
+
/**
|
|
1970
|
+
* CORS Types for BlaizeJS Framework
|
|
1971
|
+
*
|
|
1972
|
+
* Comprehensive type definitions for W3C-compliant CORS middleware
|
|
1973
|
+
* with support for string, regex, and async function origin validation.
|
|
1974
|
+
*
|
|
1975
|
+
* @module @blaizejs/types/cors
|
|
1976
|
+
*/
|
|
1977
|
+
|
|
1978
|
+
/**
|
|
1979
|
+
* Origin configuration type supporting multiple validation methods
|
|
1980
|
+
*
|
|
1981
|
+
* @example
|
|
1982
|
+
* ```typescript
|
|
1983
|
+
* // String origin (exact match)
|
|
1984
|
+
* const origin: CorsOrigin = 'https://example.com';
|
|
1985
|
+
*
|
|
1986
|
+
* // RegExp pattern
|
|
1987
|
+
* const origin: CorsOrigin = /^https:\/\/.*\.example\.com$/;
|
|
1988
|
+
*
|
|
1989
|
+
* // Dynamic validation function
|
|
1990
|
+
* const origin: CorsOrigin = async (origin, ctx) => {
|
|
1991
|
+
* return await checkOriginAllowed(origin, ctx?.state.user);
|
|
1992
|
+
* };
|
|
1993
|
+
*
|
|
1994
|
+
* // Array of mixed types
|
|
1995
|
+
* const origin: CorsOrigin = [
|
|
1996
|
+
* 'https://localhost:3000',
|
|
1997
|
+
* /^https:\/\/.*\.example\.com$/,
|
|
1998
|
+
* (origin) => origin.endsWith('.trusted.com')
|
|
1999
|
+
* ];
|
|
2000
|
+
* ```
|
|
2001
|
+
*/
|
|
2002
|
+
type CorsOrigin = string | RegExp | ((origin: string, ctx?: Context<any, any>) => boolean | Promise<boolean>) | Array<string | RegExp | ((origin: string, ctx?: Context<any, any>) => boolean | Promise<boolean>)>;
|
|
2003
|
+
/**
|
|
2004
|
+
* HTTP methods that can be allowed in CORS
|
|
2005
|
+
* Based on W3C CORS specification
|
|
2006
|
+
*/
|
|
2007
|
+
type CorsHttpMethod = HttpMethod | 'CONNECT' | 'TRACE';
|
|
2008
|
+
/**
|
|
2009
|
+
* Main CORS configuration options
|
|
2010
|
+
*
|
|
2011
|
+
* @example
|
|
2012
|
+
* ```typescript
|
|
2013
|
+
* const corsOptions: CorsOptions = {
|
|
2014
|
+
* origin: 'https://example.com',
|
|
2015
|
+
* methods: ['GET', 'POST'],
|
|
2016
|
+
* credentials: true,
|
|
2017
|
+
* maxAge: 86400
|
|
2018
|
+
* };
|
|
2019
|
+
* ```
|
|
2020
|
+
*/
|
|
2021
|
+
interface CorsOptions {
|
|
2022
|
+
/**
|
|
2023
|
+
* Configures the Access-Control-Allow-Origin header
|
|
2024
|
+
*
|
|
2025
|
+
* Possible values:
|
|
2026
|
+
* - `true`: Allow all origins (sets to '*' unless credentials is true, then reflects origin)
|
|
2027
|
+
* - `false`: Disable CORS (no headers set)
|
|
2028
|
+
* - `string`: Specific origin to allow
|
|
2029
|
+
* - `RegExp`: Pattern to match origins
|
|
2030
|
+
* - `function`: Custom validation logic
|
|
2031
|
+
* - `array`: Multiple origin configurations
|
|
2032
|
+
*
|
|
2033
|
+
* @default false
|
|
2034
|
+
*/
|
|
2035
|
+
origin?: boolean | CorsOrigin;
|
|
2036
|
+
/**
|
|
2037
|
+
* Configures the Access-Control-Allow-Methods header
|
|
2038
|
+
*
|
|
2039
|
+
* @default ['GET', 'HEAD', 'PUT', 'PATCH', 'POST', 'DELETE']
|
|
2040
|
+
* @example ['GET', 'POST']
|
|
2041
|
+
*/
|
|
2042
|
+
methods?: CorsHttpMethod[] | string;
|
|
2043
|
+
/**
|
|
2044
|
+
* Configures the Access-Control-Allow-Headers header
|
|
2045
|
+
*
|
|
2046
|
+
* Pass an array of allowed headers or a comma-delimited string.
|
|
2047
|
+
*
|
|
2048
|
+
* @default Request's Access-Control-Request-Headers header value
|
|
2049
|
+
* @example ['Content-Type', 'Authorization']
|
|
2050
|
+
*/
|
|
2051
|
+
allowedHeaders?: string[] | string;
|
|
2052
|
+
/**
|
|
2053
|
+
* Configures the Access-Control-Expose-Headers header
|
|
2054
|
+
*
|
|
2055
|
+
* Headers that the browser is allowed to access.
|
|
2056
|
+
*
|
|
2057
|
+
* @default []
|
|
2058
|
+
* @example ['Content-Range', 'X-Content-Range']
|
|
2059
|
+
*/
|
|
2060
|
+
exposedHeaders?: string[] | string;
|
|
2061
|
+
/**
|
|
2062
|
+
* Configures the Access-Control-Allow-Credentials header
|
|
2063
|
+
*
|
|
2064
|
+
* Set to true to allow credentials (cookies, authorization headers, TLS client certificates).
|
|
2065
|
+
* Note: Cannot be used with origin: '*' for security reasons.
|
|
2066
|
+
*
|
|
2067
|
+
* @default false
|
|
2068
|
+
*/
|
|
2069
|
+
credentials?: boolean;
|
|
2070
|
+
/**
|
|
2071
|
+
* Configures the Access-Control-Max-Age header in seconds
|
|
2072
|
+
*
|
|
2073
|
+
* Indicates how long browsers can cache preflight response.
|
|
2074
|
+
* Set to -1 to disable caching.
|
|
2075
|
+
*
|
|
2076
|
+
* @default undefined (browser decides)
|
|
2077
|
+
* @example 86400 // 24 hours
|
|
2078
|
+
*/
|
|
2079
|
+
maxAge?: number;
|
|
2080
|
+
/**
|
|
2081
|
+
* Whether to pass the CORS preflight response to the next handler
|
|
2082
|
+
*
|
|
2083
|
+
* When false, the preflight response is sent immediately.
|
|
2084
|
+
* When true, control passes to the next middleware/handler.
|
|
2085
|
+
*
|
|
2086
|
+
* @default false
|
|
2087
|
+
*/
|
|
2088
|
+
preflightContinue?: boolean;
|
|
2089
|
+
/**
|
|
2090
|
+
* HTTP status code for successful OPTIONS requests
|
|
2091
|
+
*
|
|
2092
|
+
* Some legacy browsers require 200, while 204 is more correct.
|
|
2093
|
+
*
|
|
2094
|
+
* @default 204
|
|
2095
|
+
*/
|
|
2096
|
+
optionsSuccessStatus?: number;
|
|
2097
|
+
}
|
|
2098
|
+
/**
|
|
2099
|
+
* Internal CORS validation result
|
|
2100
|
+
* Used by middleware implementation
|
|
2101
|
+
*/
|
|
2102
|
+
interface CorsValidationResult {
|
|
2103
|
+
/**
|
|
2104
|
+
* Whether the origin is allowed
|
|
2105
|
+
*/
|
|
2106
|
+
allowed: boolean;
|
|
2107
|
+
/**
|
|
2108
|
+
* The origin value to set in the header
|
|
2109
|
+
* Can be '*', specific origin, or 'null'
|
|
2110
|
+
*/
|
|
2111
|
+
origin?: string;
|
|
2112
|
+
/**
|
|
2113
|
+
* Whether to add Vary: Origin header
|
|
2114
|
+
*/
|
|
2115
|
+
vary?: boolean;
|
|
2116
|
+
}
|
|
2117
|
+
/**
|
|
2118
|
+
* CORS preflight request information
|
|
2119
|
+
* Extracted from OPTIONS request headers
|
|
2120
|
+
*/
|
|
2121
|
+
interface CorsPreflightInfo {
|
|
2122
|
+
/**
|
|
2123
|
+
* The origin making the request
|
|
2124
|
+
*/
|
|
2125
|
+
origin?: string;
|
|
2126
|
+
/**
|
|
2127
|
+
* The method that will be used in the actual request
|
|
2128
|
+
* From Access-Control-Request-Method header
|
|
2129
|
+
*/
|
|
2130
|
+
requestedMethod?: string;
|
|
2131
|
+
/**
|
|
2132
|
+
* The headers that will be sent in the actual request
|
|
2133
|
+
* From Access-Control-Request-Headers header
|
|
2134
|
+
*/
|
|
2135
|
+
requestedHeaders?: string[];
|
|
2136
|
+
}
|
|
2137
|
+
/**
|
|
2138
|
+
* Cache entry for origin validation results
|
|
2139
|
+
* Used for performance optimization
|
|
2140
|
+
*/
|
|
2141
|
+
interface CorsOriginCacheEntry {
|
|
2142
|
+
/**
|
|
2143
|
+
* Whether the origin is allowed
|
|
2144
|
+
*/
|
|
2145
|
+
allowed: boolean;
|
|
2146
|
+
/**
|
|
2147
|
+
* When this cache entry expires (timestamp)
|
|
2148
|
+
*/
|
|
2149
|
+
expiresAt: number;
|
|
2150
|
+
/**
|
|
2151
|
+
* Optional user identifier for cache key
|
|
2152
|
+
*/
|
|
2153
|
+
userId?: string;
|
|
2154
|
+
}
|
|
2155
|
+
/**
|
|
2156
|
+
* Configuration for CORS origin validation cache
|
|
2157
|
+
*/
|
|
2158
|
+
interface CorsOriginCacheConfig {
|
|
2159
|
+
/**
|
|
2160
|
+
* Time-to-live for cache entries in milliseconds
|
|
2161
|
+
* @default 60000 (1 minute)
|
|
2162
|
+
*/
|
|
2163
|
+
ttl?: number;
|
|
2164
|
+
/**
|
|
2165
|
+
* Maximum number of entries in the cache
|
|
2166
|
+
* @default 1000
|
|
2167
|
+
*/
|
|
2168
|
+
maxSize?: number;
|
|
2169
|
+
/**
|
|
2170
|
+
* Whether to include user ID in cache key
|
|
2171
|
+
* @default true
|
|
2172
|
+
*/
|
|
2173
|
+
includeUserId?: boolean;
|
|
2174
|
+
}
|
|
2175
|
+
/**
|
|
2176
|
+
* Statistics for CORS middleware performance monitoring
|
|
2177
|
+
*/
|
|
2178
|
+
interface CorsStats {
|
|
2179
|
+
/**
|
|
2180
|
+
* Total number of CORS requests processed
|
|
2181
|
+
*/
|
|
2182
|
+
totalRequests: number;
|
|
2183
|
+
/**
|
|
2184
|
+
* Number of preflight requests handled
|
|
2185
|
+
*/
|
|
2186
|
+
preflightRequests: number;
|
|
2187
|
+
/**
|
|
2188
|
+
* Number of allowed origins
|
|
2189
|
+
*/
|
|
2190
|
+
allowedOrigins: number;
|
|
2191
|
+
/**
|
|
2192
|
+
* Number of denied origins
|
|
2193
|
+
*/
|
|
2194
|
+
deniedOrigins: number;
|
|
2195
|
+
/**
|
|
2196
|
+
* Cache hit rate for origin validation
|
|
2197
|
+
*/
|
|
2198
|
+
cacheHitRate: number;
|
|
2199
|
+
/**
|
|
2200
|
+
* Average origin validation time in milliseconds
|
|
2201
|
+
*/
|
|
2202
|
+
avgValidationTime: number;
|
|
2203
|
+
}
|
|
2204
|
+
/**
|
|
2205
|
+
* Cache entry type
|
|
2206
|
+
*/
|
|
2207
|
+
interface CacheEntry {
|
|
2208
|
+
allowed: boolean;
|
|
2209
|
+
expiresAt: number;
|
|
2210
|
+
lastAccessed: number;
|
|
2211
|
+
}
|
|
2212
|
+
/**
|
|
2213
|
+
* Cache configuration
|
|
2214
|
+
*/
|
|
2215
|
+
interface CacheConfig {
|
|
2216
|
+
ttl: number;
|
|
2217
|
+
maxSize: number;
|
|
2218
|
+
}
|
|
2219
|
+
|
|
2220
|
+
/**
|
|
2221
|
+
* BlaizeJS Server Module - Enhanced with Correlation Configuration
|
|
2222
|
+
*
|
|
2223
|
+
* Provides the core HTTP/2 server implementation with HTTP/1.1 fallback
|
|
2224
|
+
* and correlation ID tracking configuration.
|
|
2225
|
+
*/
|
|
2226
|
+
|
|
2227
|
+
type UnknownServer = Server<Record<string, unknown>, Record<string, unknown>>;
|
|
2228
|
+
interface Http2Options {
|
|
2229
|
+
enabled?: boolean | undefined;
|
|
2230
|
+
keyFile?: string | undefined;
|
|
2231
|
+
certFile?: string | undefined;
|
|
2232
|
+
}
|
|
2233
|
+
interface StartOptions {
|
|
2234
|
+
port?: number;
|
|
2235
|
+
host?: string;
|
|
2236
|
+
}
|
|
2237
|
+
interface StopOptions {
|
|
2238
|
+
timeout?: number;
|
|
2239
|
+
plugins?: Plugin[];
|
|
2240
|
+
onStopping?: () => Promise<void> | void;
|
|
2241
|
+
onStopped?: () => Promise<void> | void;
|
|
2242
|
+
}
|
|
2243
|
+
/**
|
|
2244
|
+
* Correlation ID configuration options
|
|
2245
|
+
*/
|
|
2246
|
+
interface CorrelationOptions {
|
|
2247
|
+
/**
|
|
2248
|
+
* The HTTP header name to use for correlation IDs
|
|
2249
|
+
* @default 'x-correlation-id'
|
|
2250
|
+
*/
|
|
2251
|
+
headerName?: string;
|
|
2252
|
+
/**
|
|
2253
|
+
* Custom correlation ID generator function
|
|
2254
|
+
* @default () => `req_${timestamp}_${random}`
|
|
2255
|
+
*/
|
|
2256
|
+
generator?: () => string;
|
|
2257
|
+
}
|
|
2258
|
+
/**
|
|
2259
|
+
* Server options for configuring the BlaizeJS server
|
|
2260
|
+
*/
|
|
2261
|
+
interface ServerOptionsInput {
|
|
2262
|
+
/** Port to listen on (default: 3000) */
|
|
2263
|
+
port?: number;
|
|
2264
|
+
/** Host to bind to (default: localhost) */
|
|
2265
|
+
host?: string;
|
|
2266
|
+
/** Directory containing route files (default: ./routes) */
|
|
2267
|
+
routesDir?: string;
|
|
2268
|
+
/** HTTP/2 options */
|
|
2269
|
+
http2?: {
|
|
2270
|
+
/** Enable HTTP/2 (default: true) */
|
|
2271
|
+
enabled?: boolean | undefined;
|
|
2272
|
+
/** Path to key file for HTTPS/HTTP2 */
|
|
2273
|
+
keyFile?: string | undefined;
|
|
2274
|
+
/** Path to certificate file for HTTPS/HTTP2 */
|
|
2275
|
+
certFile?: string | undefined;
|
|
2276
|
+
};
|
|
2277
|
+
/** Global middleware to apply to all routes */
|
|
2278
|
+
middleware?: Middleware[];
|
|
2279
|
+
/** Plugins to register */
|
|
2280
|
+
plugins?: Plugin[];
|
|
2281
|
+
/**
|
|
2282
|
+
* Correlation ID configuration
|
|
2283
|
+
* @since 0.4.0
|
|
2284
|
+
*/
|
|
2285
|
+
correlation?: CorrelationOptions;
|
|
2286
|
+
/**
|
|
2287
|
+
* CORS configuration
|
|
2288
|
+
*
|
|
2289
|
+
* - `true`: Enable CORS with development defaults (allow all origins)
|
|
2290
|
+
* - `false`: Disable CORS (no headers set)
|
|
2291
|
+
* - `CorsOptions`: Custom CORS configuration
|
|
2292
|
+
*
|
|
2293
|
+
* @default false (CORS disabled)
|
|
2294
|
+
* @since 0.5.0
|
|
2295
|
+
*
|
|
2296
|
+
* @example
|
|
2297
|
+
* ```typescript
|
|
2298
|
+
* // Enable with dev defaults
|
|
2299
|
+
* const server = createServer({ cors: true });
|
|
2300
|
+
*
|
|
2301
|
+
* // Custom configuration
|
|
2302
|
+
* const server = createServer({
|
|
2303
|
+
* cors: {
|
|
2304
|
+
* origin: 'https://example.com',
|
|
2305
|
+
* credentials: true,
|
|
2306
|
+
* maxAge: 86400
|
|
2307
|
+
* }
|
|
2308
|
+
* });
|
|
2309
|
+
*
|
|
2310
|
+
* // Disable CORS
|
|
2311
|
+
* const server = createServer({ cors: false });
|
|
2312
|
+
* ```
|
|
2313
|
+
*/
|
|
2314
|
+
cors?: CorsOptions | boolean;
|
|
2315
|
+
}
|
|
2316
|
+
/**
|
|
2317
|
+
* Configuration for a BlaizeJS server
|
|
2318
|
+
*/
|
|
2319
|
+
interface ServerOptions {
|
|
2320
|
+
/** Port to listen on (default: 3000) */
|
|
2321
|
+
port: number;
|
|
2322
|
+
/** Host to bind to (default: localhost) */
|
|
2323
|
+
host: string;
|
|
2324
|
+
/** Directory containing route files (default: ./routes) */
|
|
2325
|
+
routesDir: string;
|
|
2326
|
+
/** HTTP/2 options */
|
|
2327
|
+
http2?: {
|
|
2328
|
+
/** Enable HTTP/2 (default: true) */
|
|
2329
|
+
enabled?: boolean | undefined;
|
|
2330
|
+
/** Path to key file for HTTPS/HTTP2 */
|
|
2331
|
+
keyFile?: string | undefined;
|
|
2332
|
+
/** Path to certificate file for HTTPS/HTTP2 */
|
|
2333
|
+
certFile?: string | undefined;
|
|
2334
|
+
};
|
|
2335
|
+
/** Global middleware to apply to all routes */
|
|
2336
|
+
middleware?: Middleware[];
|
|
2337
|
+
/** Plugins to register */
|
|
2338
|
+
plugins?: Plugin[];
|
|
2339
|
+
/**
|
|
2340
|
+
* Correlation ID configuration
|
|
2341
|
+
* @since 0.4.0
|
|
2342
|
+
*/
|
|
2343
|
+
correlation?: CorrelationOptions;
|
|
2344
|
+
/**
|
|
2345
|
+
* CORS configuration
|
|
2346
|
+
* @since 0.5.0
|
|
2347
|
+
*/
|
|
2348
|
+
cors?: CorsOptions | boolean;
|
|
2349
|
+
}
|
|
2350
|
+
/**
|
|
2351
|
+
* BlaizeJS Server instance with generic type accumulation
|
|
2352
|
+
*
|
|
2353
|
+
* @template TState - The accumulated state type from middleware
|
|
2354
|
+
* @template TServices - The accumulated services type from middleware and plugins
|
|
2355
|
+
*
|
|
2356
|
+
*/
|
|
2357
|
+
interface Server<TState, TServices> {
|
|
2358
|
+
/** The underlying HTTP or HTTP/2 server */
|
|
2359
|
+
server: http.Server | http2.Http2Server | undefined;
|
|
2360
|
+
/** The port the server is configured to listen on */
|
|
2361
|
+
port: number;
|
|
2362
|
+
/** CORS configuration for this server */
|
|
2363
|
+
corsOptions?: CorsOptions | boolean;
|
|
2364
|
+
/** The host the server is bound to */
|
|
2365
|
+
host: string;
|
|
2366
|
+
events: EventEmitter;
|
|
2367
|
+
/** Direct access to registered plugins */
|
|
2368
|
+
plugins: Plugin[];
|
|
2369
|
+
/** Direct access to registered plugins */
|
|
2370
|
+
middleware: Middleware[];
|
|
2371
|
+
/** Internal property for signal hanlders */
|
|
2372
|
+
_signalHandlers?: {
|
|
2373
|
+
unregister: () => void;
|
|
2374
|
+
};
|
|
2375
|
+
/** Start the server and listen for connections */
|
|
2376
|
+
listen: (port?: number, host?: string) => Promise<Server<TState, TServices>>;
|
|
2377
|
+
/** Stop the server */
|
|
2378
|
+
close: (stopOptions?: StopOptions) => Promise<void>;
|
|
2379
|
+
/**
|
|
2380
|
+
* Add global middleware to the server
|
|
2381
|
+
*
|
|
2382
|
+
* @param middleware - Single middleware or array of middleware to add
|
|
2383
|
+
* @returns New Server instance with accumulated types from the middleware
|
|
2384
|
+
*
|
|
2385
|
+
* @example
|
|
2386
|
+
* ```typescript
|
|
2387
|
+
* // Single middleware
|
|
2388
|
+
* const serverWithAuth = server.use(authMiddleware);
|
|
2389
|
+
* // serverWithAuth has type Server<{user: User}, {auth: AuthService}>
|
|
2390
|
+
*
|
|
2391
|
+
* // Array of middleware
|
|
2392
|
+
* const serverWithMiddleware = server.use([authMiddleware, loggerMiddleware]);
|
|
2393
|
+
* // serverWithMiddleware has type Server<{user, requestId}, {auth, logger}>
|
|
2394
|
+
* ```
|
|
2395
|
+
*/
|
|
2396
|
+
use<MS, MSvc>(middleware: Middleware<MS, MSvc>): Server<TState & MS, TServices & MSvc>;
|
|
2397
|
+
use<MW extends readonly Middleware<any, any>[]>(middleware: MW): Server<TState & UnionToIntersection<ExtractMiddlewareState<MW[number]>>, TServices & UnionToIntersection<ExtractMiddlewareServices<MW[number]>>>;
|
|
2398
|
+
/**
|
|
2399
|
+
* Register a plugin with the server
|
|
2400
|
+
*
|
|
2401
|
+
* @param plugin - Single plugin or array of plugins to register
|
|
2402
|
+
* @returns Promise resolving to new Server instance with accumulated types
|
|
2403
|
+
*
|
|
2404
|
+
* @example
|
|
2405
|
+
* ```typescript
|
|
2406
|
+
* // Single plugin
|
|
2407
|
+
* const serverWithDb = await server.register(databasePlugin);
|
|
2408
|
+
* // serverWithDb has type Server<{}, {db: DatabaseService}>
|
|
2409
|
+
*
|
|
2410
|
+
* // Array of plugins
|
|
2411
|
+
* const serverWithPlugins = await server.register([dbPlugin, cachePlugin]);
|
|
2412
|
+
* // serverWithPlugins has type Server<{}, {db, cache}>
|
|
2413
|
+
* ```
|
|
2414
|
+
*/
|
|
2415
|
+
register<PS, PSvc>(plugin: Plugin<PS, PSvc>): Promise<Server<TState & PS, TServices & PSvc>>;
|
|
2416
|
+
register<P extends readonly Plugin<any, any>[]>(plugin: P): Promise<Server<TState & UnionToIntersection<ExtractPluginState<P[number]>>, TServices & UnionToIntersection<ExtractPluginServices<P[number]>>>>;
|
|
2417
|
+
/** Access to the routing system */
|
|
2418
|
+
router: Router;
|
|
2419
|
+
/** Context storage system */
|
|
2420
|
+
context: AsyncLocalStorage<Context>;
|
|
2421
|
+
pluginManager: PluginLifecycleManager;
|
|
2422
|
+
}
|
|
2423
|
+
type RequestHandler = (req: http.IncomingMessage | http2.Http2ServerRequest, res: http.ServerResponse | http2.Http2ServerResponse) => Promise<void>;
|
|
2424
|
+
|
|
2425
|
+
/**
|
|
2426
|
+
* BlaizeJS Plugin Module
|
|
2427
|
+
*
|
|
2428
|
+
* Provides the plugin system for extending framework functionality.
|
|
2429
|
+
*/
|
|
2430
|
+
|
|
2431
|
+
/**
|
|
2432
|
+
* Plugin options
|
|
2433
|
+
*/
|
|
2434
|
+
interface PluginOptions<_T = any> {
|
|
2435
|
+
/** Plugin configuration */
|
|
2436
|
+
[key: string]: any;
|
|
2437
|
+
}
|
|
2438
|
+
/**
|
|
2439
|
+
* Plugin lifecycle hooks
|
|
2440
|
+
*/
|
|
2441
|
+
interface PluginHooks {
|
|
2442
|
+
/** Called when the plugin is registered */
|
|
2443
|
+
register: (app: Server<any, any>) => void | Promise<void>;
|
|
2444
|
+
/** Called when the server is initialized */
|
|
2445
|
+
initialize?: (app?: Server<any, any>) => void | Promise<void>;
|
|
2446
|
+
/** Called when the server is terminated */
|
|
2447
|
+
terminate?: (app?: Server<any, any>) => void | Promise<void>;
|
|
2448
|
+
/** Called when the server starts */
|
|
2449
|
+
onServerStart?: (server: any) => void | Promise<void>;
|
|
2450
|
+
/** Called when the server stops */
|
|
2451
|
+
onServerStop?: (server: any) => void | Promise<void>;
|
|
2452
|
+
}
|
|
2453
|
+
/**
|
|
2454
|
+
* Plugin interface
|
|
2455
|
+
*/
|
|
2456
|
+
interface Plugin<TState = {}, TServices = {}> extends PluginHooks {
|
|
2457
|
+
/** Plugin name */
|
|
2458
|
+
name: string;
|
|
2459
|
+
/** Plugin version */
|
|
2460
|
+
version: string;
|
|
2461
|
+
/**
|
|
2462
|
+
* Type carriers for compile-time type information
|
|
2463
|
+
* These are never used at runtime but allow TypeScript to track types
|
|
2464
|
+
*/
|
|
2465
|
+
_state?: TState;
|
|
2466
|
+
_services?: TServices;
|
|
2467
|
+
}
|
|
2468
|
+
/**
|
|
2469
|
+
* Plugin factory function
|
|
2470
|
+
*/
|
|
2471
|
+
type PluginFactory<T = any, TState extends Record<string, unknown> = {}, TServices extends Record<string, unknown> = {}> = (options?: T) => Plugin<TState, TServices>;
|
|
2472
|
+
interface PluginLifecycleManager {
|
|
2473
|
+
initializePlugins(server: Server<any, any>): Promise<void>;
|
|
2474
|
+
terminatePlugins(server: Server<any, any>): Promise<void>;
|
|
2475
|
+
onServerStart(server: Server<any, any>, httpServer: any): Promise<void>;
|
|
2476
|
+
onServerStop(server: Server<any, any>, httpServer: any): Promise<void>;
|
|
2477
|
+
}
|
|
2478
|
+
interface PluginLifecycleOptions {
|
|
2479
|
+
/** Continue initialization even if a plugin fails */
|
|
2480
|
+
continueOnError?: boolean;
|
|
2481
|
+
/** Log plugin lifecycle events */
|
|
2482
|
+
debug?: boolean;
|
|
2483
|
+
/** Custom error handler for plugin failures */
|
|
2484
|
+
onError?: (plugin: Plugin, phase: string, error: Error) => void;
|
|
2485
|
+
}
|
|
2486
|
+
|
|
2487
|
+
/**
|
|
2488
|
+
* Type composition utilities for extracting and composing middleware type contributions
|
|
2489
|
+
* @module composition
|
|
2490
|
+
* @since v0.4.0
|
|
2491
|
+
*/
|
|
2492
|
+
|
|
2493
|
+
/**
|
|
2494
|
+
* Extracts the State type contribution from a middleware
|
|
2495
|
+
* @template T - The middleware type to extract from
|
|
2496
|
+
* @returns The state type if present, empty object otherwise
|
|
2497
|
+
*/
|
|
2498
|
+
type ExtractMiddlewareState<T> = T extends Middleware<infer S, any> ? S : {};
|
|
2499
|
+
/**
|
|
2500
|
+
* Extracts the State type contribution from a plugin
|
|
2501
|
+
* @template T - The plugin type to extract from
|
|
2502
|
+
* @returns The state type if present, empty object otherwise
|
|
2503
|
+
*/
|
|
2504
|
+
type ExtractPluginState<T> = T extends Plugin<infer S, any> ? S : {};
|
|
2505
|
+
/**
|
|
2506
|
+
* Extracts the Services type contribution from a middleware
|
|
2507
|
+
* @template T - The middleware type to extract from
|
|
2508
|
+
* @returns The services type if present, empty object otherwise
|
|
2509
|
+
*/
|
|
2510
|
+
type ExtractMiddlewareServices<T> = T extends Middleware<any, infer S> ? S : {};
|
|
2511
|
+
/**
|
|
2512
|
+
* Extracts the Services type contribution from a plugin
|
|
2513
|
+
* @template T - The plugin type to extract from
|
|
2514
|
+
* @returns The services type if present, empty object otherwise
|
|
2515
|
+
*/
|
|
2516
|
+
type ExtractPluginServices<T> = T extends Plugin<any, infer S> ? S : {};
|
|
2517
|
+
/**
|
|
2518
|
+
* Utility type to convert a union type to an intersection type
|
|
2519
|
+
* This is the magic that allows us to compose multiple middleware contributions
|
|
2520
|
+
*
|
|
2521
|
+
* @example
|
|
2522
|
+
* type U = { a: string } | { b: number }
|
|
2523
|
+
* type I = UnionToIntersection<U> // { a: string } & { b: number }
|
|
2524
|
+
*
|
|
2525
|
+
*/
|
|
2526
|
+
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
2527
|
+
/**
|
|
2528
|
+
* Composes state contributions from an array of middleware
|
|
2529
|
+
* Merges all state types into a single intersection type
|
|
2530
|
+
*
|
|
2531
|
+
* @template T - ReadonlyArray of Middleware
|
|
2532
|
+
* @returns Intersection of all state contributions
|
|
2533
|
+
*
|
|
2534
|
+
* @example
|
|
2535
|
+
* const middlewares = [authMiddleware, loggerMiddleware] as const;
|
|
2536
|
+
* type ComposedState = ComposeStates<typeof middlewares>;
|
|
2537
|
+
* // Result: { user: User } & { requestId: string }
|
|
2538
|
+
*/
|
|
2539
|
+
type ComposeMiddlewareStates<T extends ReadonlyArray<Middleware>> = T extends readonly [] ? {} : UnionToIntersection<ExtractMiddlewareState<T[number]>>;
|
|
2540
|
+
/**
|
|
2541
|
+
* Composes state contributions from an array of plugins
|
|
2542
|
+
* Merges all state types into a single intersection type
|
|
2543
|
+
*
|
|
2544
|
+
* @template T - ReadonlyArray of Plugin
|
|
2545
|
+
* @returns Intersection of all state contributions
|
|
2546
|
+
*
|
|
2547
|
+
* @example
|
|
2548
|
+
* const plugins = [authPlugin, dbPlugin] as const;
|
|
2549
|
+
* type ComposedState = ComposePluginStates<typeof plugins>;
|
|
2550
|
+
* // Result: { config: AuthConfig } & { dbConnected: boolean }
|
|
2551
|
+
*/
|
|
2552
|
+
type ComposePluginStates<T extends ReadonlyArray<Plugin<any, any>>> = T extends readonly [] ? {} : UnionToIntersection<ExtractPluginState<T[number]>>;
|
|
2553
|
+
/**
|
|
2554
|
+
* Composes service contributions from an array of middleware
|
|
2555
|
+
* Merges all service types into a single intersection type
|
|
2556
|
+
*
|
|
2557
|
+
* @template T - ReadonlyArray of Middleware
|
|
2558
|
+
* @returns Intersection of all service contributions
|
|
2559
|
+
*
|
|
2560
|
+
* @example
|
|
2561
|
+
* const middlewares = [dbMiddleware, cacheMiddleware] as const;
|
|
2562
|
+
* type ComposedServices = ComposeServices<typeof middlewares>;
|
|
2563
|
+
* // Result: { db: Database } & { cache: Cache }
|
|
2564
|
+
*/
|
|
2565
|
+
type ComposeMiddlewareServices<T extends ReadonlyArray<Middleware>> = T extends readonly [] ? {} : UnionToIntersection<ExtractMiddlewareServices<T[number]>>;
|
|
2566
|
+
/**
|
|
2567
|
+
* Composes service contributions from an array of plugins
|
|
2568
|
+
* Merges all service types into a single intersection type
|
|
2569
|
+
*
|
|
2570
|
+
* @template T - ReadonlyArray of Plugin
|
|
2571
|
+
* @returns Intersection of all service contributions
|
|
2572
|
+
*
|
|
2573
|
+
* @example
|
|
2574
|
+
* const plugins = [dbPlugin, cachePlugin] as const;
|
|
2575
|
+
* type ComposedServices = ComposePluginServices<typeof plugins>;
|
|
2576
|
+
* // Result: { db: Database } & { cache: Cache }
|
|
2577
|
+
*/
|
|
2578
|
+
type ComposePluginServices<T extends ReadonlyArray<Plugin<any, any>>> = T extends readonly [] ? {} : UnionToIntersection<ExtractPluginServices<T[number]>>;
|
|
2579
|
+
/**
|
|
2580
|
+
* Safe version of ExtractState that handles edge cases
|
|
2581
|
+
* @template T - The middleware type to extract from
|
|
2582
|
+
* @returns The state type, handling never/any/unknown gracefully
|
|
2583
|
+
*/
|
|
2584
|
+
type SafeExtractMiddlewareState<T> = IsNever<T> extends true ? {} : IsAny<T> extends true ? {} : T extends Middleware<infer S, any> ? unknown extends S ? {} : S : {};
|
|
2585
|
+
/**
|
|
2586
|
+
* Safe version of ExtractPluginState that handles edge cases
|
|
2587
|
+
* @template T - The plugin type to extract from
|
|
2588
|
+
* @returns The state type, handling never/any/unknown gracefully
|
|
2589
|
+
*/
|
|
2590
|
+
type SafeExtractPluginState<T> = IsNever<T> extends true ? {} : IsAny<T> extends true ? {} : T extends Plugin<infer S, any> ? unknown extends S ? {} : S : {};
|
|
2591
|
+
/**
|
|
2592
|
+
* Safe version of ExtractServices that handles edge cases
|
|
2593
|
+
* @template T - The middleware type to extract from
|
|
2594
|
+
* @returns The services type, handling never/any/unknown gracefully
|
|
2595
|
+
*/
|
|
2596
|
+
type SafeExtractMiddlewareServices<T> = IsNever<T> extends true ? {} : IsAny<T> extends true ? {} : T extends Middleware<any, infer S> ? unknown extends S ? {} : S : {};
|
|
2597
|
+
/**
|
|
2598
|
+
* Safe version of ExtractPluginServices that handles edge cases
|
|
2599
|
+
* @template T - The plugin type to extract from
|
|
2600
|
+
* @returns The services type, handling never/any/unknown gracefully
|
|
2601
|
+
*/
|
|
2602
|
+
type SafeExtractPluginServices<T> = IsNever<T> extends true ? {} : IsAny<T> extends true ? {} : T extends Plugin<any, infer S> ? unknown extends S ? {} : S : {};
|
|
2603
|
+
/**
|
|
2604
|
+
* Composes state with better edge case handling
|
|
2605
|
+
* @template T - ReadonlyArray of Middleware
|
|
2606
|
+
* @returns Safely composed state types
|
|
2607
|
+
*/
|
|
2608
|
+
type SafeComposeMiddlewareStates<T extends ReadonlyArray<Middleware>> = T extends readonly [] ? {} : T extends readonly [infer First, ...infer Rest] ? First extends Middleware ? Rest extends ReadonlyArray<Middleware> ? SafeExtractMiddlewareState<First> & SafeComposeMiddlewareStates<Rest> : SafeExtractMiddlewareState<First> : {} : UnionToIntersection<SafeExtractMiddlewareState<T[number]>>;
|
|
2609
|
+
/**
|
|
2610
|
+
* Composes plugin state with better edge case handling
|
|
2611
|
+
* @template T - ReadonlyArray of Plugin
|
|
2612
|
+
* @returns Safely composed state types
|
|
2613
|
+
*/
|
|
2614
|
+
type SafeComposePluginStates<T extends ReadonlyArray<Plugin<any, any>>> = T extends readonly [] ? {} : T extends readonly [infer First, ...infer Rest] ? First extends Plugin<any, any> ? Rest extends ReadonlyArray<Plugin<any, any>> ? SafeExtractPluginState<First> & SafeComposePluginStates<Rest> : SafeExtractPluginState<First> : {} : UnionToIntersection<SafeExtractPluginState<T[number]>>;
|
|
2615
|
+
/**
|
|
2616
|
+
* Composes services with better edge case handling
|
|
2617
|
+
* @template T - ReadonlyArray of Middleware
|
|
2618
|
+
* @returns Safely composed service types
|
|
2619
|
+
*/
|
|
2620
|
+
type SafeComposeMiddlewareServices<T extends ReadonlyArray<Middleware>> = T extends readonly [] ? {} : T extends readonly [infer First, ...infer Rest] ? First extends Middleware ? Rest extends ReadonlyArray<Middleware> ? SafeExtractMiddlewareServices<First> & SafeComposeMiddlewareServices<Rest> : SafeExtractMiddlewareServices<First> : {} : UnionToIntersection<SafeExtractMiddlewareServices<T[number]>>;
|
|
2621
|
+
/**
|
|
2622
|
+
* Composes plugin services with better edge case handling
|
|
2623
|
+
* @template T - ReadonlyArray of Plugin
|
|
2624
|
+
* @returns Safely composed service types
|
|
2625
|
+
*/
|
|
2626
|
+
type SafeComposePluginServices<T extends ReadonlyArray<Plugin<any, any>>> = T extends readonly [] ? {} : T extends readonly [infer First, ...infer Rest] ? First extends Plugin<any, any> ? Rest extends ReadonlyArray<Plugin<any, any>> ? SafeExtractPluginServices<First> & SafeComposePluginServices<Rest> : SafeExtractPluginServices<First> : {} : UnionToIntersection<SafeExtractPluginServices<T[number]>>;
|
|
2627
|
+
/**
|
|
2628
|
+
* Utility to merge two state types
|
|
2629
|
+
* Handles conflicts by using the rightmost (latest) type
|
|
2630
|
+
*
|
|
2631
|
+
* @template A - First state type
|
|
2632
|
+
* @template B - Second state type
|
|
2633
|
+
* @returns Merged state with B taking precedence
|
|
2634
|
+
*/
|
|
2635
|
+
type MergeStates<A, B> = Omit<A, keyof B> & B;
|
|
2636
|
+
/**
|
|
2637
|
+
* Utility to merge two service types
|
|
2638
|
+
* Handles conflicts by using the rightmost (latest) type
|
|
2639
|
+
*
|
|
2640
|
+
* @template A - First services type
|
|
2641
|
+
* @template B - Second services type
|
|
2642
|
+
* @returns Merged services with B taking precedence
|
|
2643
|
+
*/
|
|
2644
|
+
type MergeServices<A, B> = Omit<A, keyof B> & B;
|
|
2645
|
+
/**
|
|
2646
|
+
* Extract both state and services from a middleware at once
|
|
2647
|
+
* @template T - The middleware type
|
|
2648
|
+
* @returns Object with state and services types
|
|
2649
|
+
*/
|
|
2650
|
+
type ExtractMiddlewareTypes<T> = {
|
|
2651
|
+
state: ExtractMiddlewareState<T>;
|
|
2652
|
+
services: ExtractMiddlewareServices<T>;
|
|
2653
|
+
};
|
|
2654
|
+
/**
|
|
2655
|
+
* Extract both state and services from a plugin at once
|
|
2656
|
+
* @template T - The plugin type
|
|
2657
|
+
* @returns Object with state and services types
|
|
2658
|
+
*/
|
|
2659
|
+
type ExtractPluginTypes<T> = {
|
|
2660
|
+
state: ExtractPluginState<T>;
|
|
2661
|
+
services: ExtractPluginServices<T>;
|
|
2662
|
+
};
|
|
2663
|
+
/**
|
|
2664
|
+
* Compose both state and services from middleware array at once
|
|
2665
|
+
* @template T - ReadonlyArray of Middleware
|
|
2666
|
+
* @returns Object with composed state and services
|
|
2667
|
+
*/
|
|
2668
|
+
type ComposeMiddlewareTypes<T extends ReadonlyArray<Middleware>> = {
|
|
2669
|
+
state: ComposeMiddlewareStates<T>;
|
|
2670
|
+
services: ComposeMiddlewareServices<T>;
|
|
2671
|
+
};
|
|
2672
|
+
/**
|
|
2673
|
+
* Compose both state and services from plugin array at once
|
|
2674
|
+
* @template T - ReadonlyArray of Plugin
|
|
2675
|
+
* @returns Object with composed state and services
|
|
2676
|
+
*/
|
|
2677
|
+
type ComposePluginTypes<T extends ReadonlyArray<Plugin<any, any>>> = {
|
|
2678
|
+
state: ComposePluginStates<T>;
|
|
2679
|
+
services: ComposePluginServices<T>;
|
|
2680
|
+
};
|
|
2681
|
+
/**
|
|
2682
|
+
* Type guard to check if a value is a Middleware
|
|
2683
|
+
* @param value - Value to check
|
|
2684
|
+
* @returns True if value is a Middleware
|
|
2685
|
+
*/
|
|
2686
|
+
declare function isMiddleware(value: unknown): value is Middleware;
|
|
2687
|
+
/**
|
|
2688
|
+
* Type guard to check if a value is a Plugin
|
|
2689
|
+
* @param value - Value to check
|
|
2690
|
+
* @returns True if value is a Plugin
|
|
2691
|
+
*/
|
|
2692
|
+
declare function isPlugin(value: unknown): value is Plugin;
|
|
2693
|
+
/**
|
|
2694
|
+
* Type helper for middleware arrays
|
|
2695
|
+
* Ensures proper readonly array typing for composition
|
|
2696
|
+
*
|
|
2697
|
+
* @example
|
|
2698
|
+
* const middlewares = asMiddlewareArray([auth, logger, cache]);
|
|
2699
|
+
* type State = ComposeStates<typeof middlewares>;
|
|
2700
|
+
*/
|
|
2701
|
+
declare function asMiddlewareArray<T extends ReadonlyArray<Middleware>>(middlewares: T): T;
|
|
2702
|
+
/**
|
|
2703
|
+
* Type helper for plugin arrays
|
|
2704
|
+
* Ensures proper readonly array typing for composition
|
|
2705
|
+
*
|
|
2706
|
+
* @example
|
|
2707
|
+
* const plugins = asPluginArray([dbPlugin, cachePlugin]);
|
|
2708
|
+
* type Services = ComposePluginServices<typeof plugins>;
|
|
2709
|
+
*/
|
|
2710
|
+
declare function asPluginArray<T extends ReadonlyArray<Plugin<any, any>>>(plugins: T): T;
|
|
2711
|
+
/**
|
|
2712
|
+
* Create a typed middleware array with inferred types
|
|
2713
|
+
* Useful for getting proper const assertions
|
|
2714
|
+
*
|
|
2715
|
+
* @example
|
|
2716
|
+
* const middlewares = createMiddlewareArray(auth, logger, cache);
|
|
2717
|
+
* type State = ComposeStates<typeof middlewares>;
|
|
2718
|
+
*/
|
|
2719
|
+
declare function createMiddlewareArray<T extends ReadonlyArray<Middleware>>(...middlewares: T): T;
|
|
2720
|
+
/**
|
|
2721
|
+
* Create a typed plugin array with inferred types
|
|
2722
|
+
* Useful for getting proper const assertions
|
|
2723
|
+
*
|
|
2724
|
+
* @example
|
|
2725
|
+
* const plugins = createPluginArray(dbPlugin, cachePlugin);
|
|
2726
|
+
* type Services = ComposePluginServices<typeof plugins>;
|
|
2727
|
+
*/
|
|
2728
|
+
declare function createPluginArray<T extends ReadonlyArray<Plugin<any, any>>>(...plugins: T): T;
|
|
2729
|
+
|
|
2730
|
+
/**
|
|
2731
|
+
* Create a plugin with the given name, version, and setup function
|
|
2732
|
+
*/
|
|
2733
|
+
declare function create$1<T = any>(name: string, version: string, setup: (app: UnknownServer, options: T) => void | Partial<PluginHooks> | Promise<void> | Promise<Partial<PluginHooks>>, defaultOptions?: Partial<T>): PluginFactory<T>;
|
|
2734
|
+
|
|
2735
|
+
/**
|
|
2736
|
+
* Create a GET route
|
|
2737
|
+
* SIMPLER FIX: Just pass the config through, TypeScript will handle the types
|
|
2738
|
+
*/
|
|
2739
|
+
declare const createGetRoute: CreateGetRoute;
|
|
2740
|
+
/**
|
|
2741
|
+
* Create a POST route
|
|
2742
|
+
*/
|
|
2743
|
+
declare const createPostRoute: CreatePostRoute;
|
|
2744
|
+
/**
|
|
2745
|
+
* Create a PUT route
|
|
2746
|
+
*/
|
|
2747
|
+
declare const createPutRoute: CreatePutRoute;
|
|
2748
|
+
/**
|
|
2749
|
+
* Create a DELETE route
|
|
2750
|
+
*/
|
|
2751
|
+
declare const createDeleteRoute: CreateDeleteRoute;
|
|
2752
|
+
/**
|
|
2753
|
+
* Create a PATCH route
|
|
2754
|
+
*/
|
|
2755
|
+
declare const createPatchRoute: CreatePatchRoute;
|
|
2756
|
+
/**
|
|
2757
|
+
* Create a HEAD route (same signature as GET - no body)
|
|
2758
|
+
*/
|
|
2759
|
+
declare const createHeadRoute: CreateHeadRoute;
|
|
2760
|
+
/**
|
|
2761
|
+
* Create an OPTIONS route (same signature as GET - no body)
|
|
2762
|
+
*/
|
|
2763
|
+
declare const createOptionsRoute: CreateOptionsRoute;
|
|
2764
|
+
/**
|
|
2765
|
+
* Factory that creates all route methods with consistent types
|
|
2766
|
+
* This is the RECOMMENDED approach for most applications
|
|
2767
|
+
*
|
|
2768
|
+
* Usage in server.ts:
|
|
2769
|
+
* ```typescript
|
|
2770
|
+
* export const route = createRouteFactory<AppState, AppServices>();
|
|
2771
|
+
* ```
|
|
2772
|
+
*
|
|
2773
|
+
* Usage in route files:
|
|
2774
|
+
* ```typescript
|
|
2775
|
+
* import { route } from '../server';
|
|
2776
|
+
*
|
|
2777
|
+
* export const GET = route.get({
|
|
2778
|
+
* handler: async (ctx) => {
|
|
2779
|
+
* // ctx.state and ctx.services are fully typed!
|
|
2780
|
+
* }
|
|
2781
|
+
* });
|
|
2782
|
+
* ```
|
|
2783
|
+
*/
|
|
2784
|
+
declare function createRouteFactory<TState extends State = State, TServices extends Services = Services>(): {
|
|
2785
|
+
readonly get: <P = never, Q = never, R = never>(config: {
|
|
2786
|
+
schema?: {
|
|
2787
|
+
params?: (P extends never ? never : P) | undefined;
|
|
2788
|
+
query?: (Q extends never ? never : Q) | undefined;
|
|
2789
|
+
response?: (R extends never ? never : R) | undefined;
|
|
2790
|
+
} | undefined;
|
|
2791
|
+
handler: RouteHandler<P extends zod.ZodType<any, zod.ZodTypeDef, any> ? Infer<P> : Record<string, string>, Q extends zod.ZodType<any, zod.ZodTypeDef, any> ? Infer<Q> : QueryParams, never, [R] extends [never] ? void : R extends zod.ZodType<any, zod.ZodTypeDef, any> ? Infer<R> : void, TState, TServices>;
|
|
2792
|
+
middleware?: Middleware[];
|
|
2793
|
+
options?: Record<string, unknown>;
|
|
2794
|
+
}) => {
|
|
2795
|
+
GET: RouteMethodOptions<P extends never ? never : P extends zod.ZodType<any, zod.ZodTypeDef, any> ? P : never, Q extends never ? never : Q extends zod.ZodType<any, zod.ZodTypeDef, any> ? Q : never, never, R extends never ? never : R extends zod.ZodType<any, zod.ZodTypeDef, any> ? R : never, zod.ZodType<any, zod.ZodTypeDef, any>>;
|
|
2796
|
+
path: string;
|
|
2797
|
+
};
|
|
2798
|
+
readonly post: <P = never, Q = never, B = never, R = never>(config: {
|
|
2799
|
+
schema?: {
|
|
2800
|
+
params?: (P extends never ? never : P) | undefined;
|
|
2801
|
+
query?: (Q extends never ? never : Q) | undefined;
|
|
2802
|
+
body?: (B extends never ? never : B) | undefined;
|
|
2803
|
+
response?: (R extends never ? never : R) | undefined;
|
|
2804
|
+
} | undefined;
|
|
2805
|
+
handler: RouteHandler<P extends zod.ZodType<any, zod.ZodTypeDef, any> ? Infer<P> : Record<string, string>, Q extends zod.ZodType<any, zod.ZodTypeDef, any> ? Infer<Q> : QueryParams, B extends zod.ZodType<any, zod.ZodTypeDef, any> ? Infer<B> : unknown, [R] extends [never] ? void : R extends zod.ZodType<any, zod.ZodTypeDef, any> ? Infer<R> : void, TState, TServices>;
|
|
2806
|
+
middleware?: Middleware[];
|
|
2807
|
+
options?: Record<string, unknown>;
|
|
2808
|
+
}) => {
|
|
2809
|
+
POST: RouteMethodOptions<P extends never ? never : P extends zod.ZodType<any, zod.ZodTypeDef, any> ? P : never, Q extends never ? never : Q extends zod.ZodType<any, zod.ZodTypeDef, any> ? Q : never, B extends never ? never : B extends zod.ZodType<any, zod.ZodTypeDef, any> ? B : never, R extends never ? never : R extends zod.ZodType<any, zod.ZodTypeDef, any> ? R : never, zod.ZodType<any, zod.ZodTypeDef, any>>;
|
|
2810
|
+
path: string;
|
|
2811
|
+
};
|
|
2812
|
+
readonly put: <P = never, Q = never, B = never, R = never>(config: {
|
|
2813
|
+
schema?: {
|
|
2814
|
+
params?: (P extends never ? never : P) | undefined;
|
|
2815
|
+
query?: (Q extends never ? never : Q) | undefined;
|
|
2816
|
+
body?: (B extends never ? never : B) | undefined;
|
|
2817
|
+
response?: (R extends never ? never : R) | undefined;
|
|
2818
|
+
} | undefined;
|
|
2819
|
+
handler: RouteHandler<P extends zod.ZodType<any, zod.ZodTypeDef, any> ? Infer<P> : Record<string, string>, Q extends zod.ZodType<any, zod.ZodTypeDef, any> ? Infer<Q> : QueryParams, B extends zod.ZodType<any, zod.ZodTypeDef, any> ? Infer<B> : unknown, [R] extends [never] ? void : R extends zod.ZodType<any, zod.ZodTypeDef, any> ? Infer<R> : void, TState, TServices>;
|
|
2820
|
+
middleware?: Middleware[];
|
|
2821
|
+
options?: Record<string, unknown>;
|
|
2822
|
+
}) => {
|
|
2823
|
+
PUT: RouteMethodOptions<P extends never ? never : P extends zod.ZodType<any, zod.ZodTypeDef, any> ? P : never, Q extends never ? never : Q extends zod.ZodType<any, zod.ZodTypeDef, any> ? Q : never, B extends never ? never : B extends zod.ZodType<any, zod.ZodTypeDef, any> ? B : never, R extends never ? never : R extends zod.ZodType<any, zod.ZodTypeDef, any> ? R : never, zod.ZodType<any, zod.ZodTypeDef, any>>;
|
|
2824
|
+
path: string;
|
|
2825
|
+
};
|
|
2826
|
+
readonly delete: <P = never, Q = never, R = never>(config: {
|
|
2827
|
+
schema?: {
|
|
2828
|
+
params?: (P extends never ? never : P) | undefined;
|
|
2829
|
+
query?: (Q extends never ? never : Q) | undefined;
|
|
2830
|
+
response?: (R extends never ? never : R) | undefined;
|
|
2831
|
+
} | undefined;
|
|
2832
|
+
handler: RouteHandler<P extends zod.ZodType<any, zod.ZodTypeDef, any> ? Infer<P> : Record<string, string>, Q extends zod.ZodType<any, zod.ZodTypeDef, any> ? Infer<Q> : QueryParams, never, [R] extends [never] ? void : R extends zod.ZodType<any, zod.ZodTypeDef, any> ? Infer<R> : void, TState, TServices>;
|
|
2833
|
+
middleware?: Middleware[];
|
|
2834
|
+
options?: Record<string, unknown>;
|
|
2835
|
+
}) => {
|
|
2836
|
+
DELETE: RouteMethodOptions<P extends never ? never : P extends zod.ZodType<any, zod.ZodTypeDef, any> ? P : never, Q extends never ? never : Q extends zod.ZodType<any, zod.ZodTypeDef, any> ? Q : never, never, R extends never ? never : R extends zod.ZodType<any, zod.ZodTypeDef, any> ? R : never, zod.ZodType<any, zod.ZodTypeDef, any>>;
|
|
2837
|
+
path: string;
|
|
2838
|
+
};
|
|
2839
|
+
readonly patch: <P = never, Q = never, B = never, R = never>(config: {
|
|
2840
|
+
schema?: {
|
|
2841
|
+
params?: (P extends never ? never : P) | undefined;
|
|
2842
|
+
query?: (Q extends never ? never : Q) | undefined;
|
|
2843
|
+
body?: (B extends never ? never : B) | undefined;
|
|
2844
|
+
response?: (R extends never ? never : R) | undefined;
|
|
2845
|
+
} | undefined;
|
|
2846
|
+
handler: RouteHandler<P extends zod.ZodType<any, zod.ZodTypeDef, any> ? Infer<P> : Record<string, string>, Q extends zod.ZodType<any, zod.ZodTypeDef, any> ? Infer<Q> : QueryParams, B extends zod.ZodType<any, zod.ZodTypeDef, any> ? Infer<B> : unknown, [R] extends [never] ? void : R extends zod.ZodType<any, zod.ZodTypeDef, any> ? Infer<R> : void, TState, TServices>;
|
|
2847
|
+
middleware?: Middleware[];
|
|
2848
|
+
options?: Record<string, unknown>;
|
|
2849
|
+
}) => {
|
|
2850
|
+
PATCH: RouteMethodOptions<P extends never ? never : P extends zod.ZodType<any, zod.ZodTypeDef, any> ? P : never, Q extends never ? never : Q extends zod.ZodType<any, zod.ZodTypeDef, any> ? Q : never, B extends never ? never : B extends zod.ZodType<any, zod.ZodTypeDef, any> ? B : never, R extends never ? never : R extends zod.ZodType<any, zod.ZodTypeDef, any> ? R : never, zod.ZodType<any, zod.ZodTypeDef, any>>;
|
|
2851
|
+
path: string;
|
|
2852
|
+
};
|
|
2853
|
+
readonly head: <P = never, Q = never, R = never>(config: {
|
|
2854
|
+
schema?: {
|
|
2855
|
+
params?: (P extends never ? never : P) | undefined;
|
|
2856
|
+
query?: (Q extends never ? never : Q) | undefined;
|
|
2857
|
+
response?: (R extends never ? never : R) | undefined;
|
|
2858
|
+
} | undefined;
|
|
2859
|
+
handler: RouteHandler<P extends zod.ZodType<any, zod.ZodTypeDef, any> ? Infer<P> : Record<string, string>, Q extends zod.ZodType<any, zod.ZodTypeDef, any> ? Infer<Q> : QueryParams, never, [R] extends [never] ? void : R extends zod.ZodType<any, zod.ZodTypeDef, any> ? Infer<R> : void, TState, TServices>;
|
|
2860
|
+
middleware?: Middleware[];
|
|
2861
|
+
options?: Record<string, unknown>;
|
|
2862
|
+
}) => {
|
|
2863
|
+
HEAD: RouteMethodOptions<P extends never ? never : P extends zod.ZodType<any, zod.ZodTypeDef, any> ? P : never, Q extends never ? never : Q extends zod.ZodType<any, zod.ZodTypeDef, any> ? Q : never, never, R extends never ? never : R extends zod.ZodType<any, zod.ZodTypeDef, any> ? R : never, zod.ZodType<any, zod.ZodTypeDef, any>>;
|
|
2864
|
+
path: string;
|
|
2865
|
+
};
|
|
2866
|
+
readonly options: <P = never, Q = never, R = never>(config: {
|
|
2867
|
+
schema?: {
|
|
2868
|
+
params?: (P extends never ? never : P) | undefined;
|
|
2869
|
+
query?: (Q extends never ? never : Q) | undefined;
|
|
2870
|
+
response?: (R extends never ? never : R) | undefined;
|
|
2871
|
+
} | undefined;
|
|
2872
|
+
handler: RouteHandler<P extends zod.ZodType<any, zod.ZodTypeDef, any> ? Infer<P> : Record<string, string>, Q extends zod.ZodType<any, zod.ZodTypeDef, any> ? Infer<Q> : QueryParams, never, [R] extends [never] ? void : R extends zod.ZodType<any, zod.ZodTypeDef, any> ? Infer<R> : void, TState, TServices>;
|
|
2873
|
+
middleware?: Middleware[];
|
|
2874
|
+
options?: Record<string, unknown>;
|
|
2875
|
+
}) => {
|
|
2876
|
+
OPTIONS: RouteMethodOptions<P extends never ? never : P extends zod.ZodType<any, zod.ZodTypeDef, any> ? P : never, Q extends never ? never : Q extends zod.ZodType<any, zod.ZodTypeDef, any> ? Q : never, never, R extends never ? never : R extends zod.ZodType<any, zod.ZodTypeDef, any> ? R : never, zod.ZodType<any, zod.ZodTypeDef, any>>;
|
|
2877
|
+
path: string;
|
|
2878
|
+
};
|
|
2879
|
+
readonly sse: <P = never, Q = never, E = never>(config: {
|
|
2880
|
+
schema?: {
|
|
2881
|
+
params?: (P extends never ? never : P) | undefined;
|
|
2882
|
+
query?: (Q extends never ? never : Q) | undefined;
|
|
2883
|
+
events?: (E extends never ? never : E) | undefined;
|
|
2884
|
+
} | undefined;
|
|
2885
|
+
handler: SSERouteHandler<E extends Record<string, zod.ZodType<any, zod.ZodTypeDef, any>> ? TypedSSEStream<E> : SSEStreamExtended, P extends zod.ZodType<any, zod.ZodTypeDef, any> ? Infer<P> : Record<string, string>, Q extends zod.ZodType<any, zod.ZodTypeDef, any> ? Infer<Q> : QueryParams, TState, TServices>;
|
|
2886
|
+
middleware?: Middleware[];
|
|
2887
|
+
options?: Record<string, unknown>;
|
|
2888
|
+
}) => {
|
|
2889
|
+
GET: {
|
|
2890
|
+
handler: (ctx: any, params: any) => Promise<void>;
|
|
2891
|
+
schema?: {
|
|
2892
|
+
params?: (P extends never ? undefined : P) | undefined;
|
|
2893
|
+
query?: (Q extends never ? undefined : Q) | undefined;
|
|
2894
|
+
} | undefined;
|
|
2895
|
+
middleware?: Middleware[];
|
|
2896
|
+
options?: Record<string, unknown>;
|
|
2897
|
+
};
|
|
2898
|
+
path: string;
|
|
2899
|
+
};
|
|
2900
|
+
};
|
|
2901
|
+
|
|
2902
|
+
/**
|
|
2903
|
+
* Creates a BlaizeJS server instance
|
|
2904
|
+
*/
|
|
2905
|
+
declare function create<const TMw extends readonly Middleware<any, any>[] = [], const TP extends readonly Plugin<any, any>[] = []>(options?: ServerOptionsInput & {
|
|
2906
|
+
middleware?: TMw;
|
|
2907
|
+
plugins?: TP;
|
|
2908
|
+
}): Server<ComposeMiddlewareStates<TMw> & ComposePluginStates<TP>, ComposeMiddlewareServices<TMw> & ComposePluginServices<TP>>;
|
|
2909
|
+
|
|
2910
|
+
/**
|
|
2911
|
+
* Type inference utilities for BlaizeJS
|
|
2912
|
+
* Minimal set of utilities needed for type-safe routing
|
|
2913
|
+
*/
|
|
2914
|
+
|
|
2915
|
+
/**
|
|
2916
|
+
* Infers the context type from a server instance
|
|
2917
|
+
*
|
|
2918
|
+
* @example
|
|
2919
|
+
* ```typescript
|
|
2920
|
+
* const server = createServer().use(authMiddleware);
|
|
2921
|
+
* type AppContext = InferContext<typeof server>;
|
|
2922
|
+
* ```
|
|
2923
|
+
*/
|
|
2924
|
+
type InferContext<T> = T extends Server<infer TState, infer TServices> ? TState extends State ? TServices extends Services ? Context<TState, TServices, any, any> : Context<State, Services, any, any> : Context<State, Services, any, any> : Context<State, Services, any, any>;
|
|
2925
|
+
/**
|
|
2926
|
+
* Runtime helper that provides type hints for development
|
|
2927
|
+
* Returns an empty object but gives TypeScript the correct context type
|
|
2928
|
+
*
|
|
2929
|
+
* @param _server - The server instance (not used at runtime)
|
|
2930
|
+
* @returns An empty object typed as the server's context
|
|
2931
|
+
*/
|
|
2932
|
+
declare function inferContext<TState extends State, TServices extends Services>(_server: Server<TState, TServices>): InferContext<Server<TState, TServices>>;
|
|
2933
|
+
|
|
2934
|
+
/**
|
|
2935
|
+
* Gets the current correlation ID from AsyncLocalStorage
|
|
2936
|
+
*
|
|
2937
|
+
* @returns The current correlation ID, or 'unknown' if none is set
|
|
2938
|
+
*/
|
|
2939
|
+
declare function getCorrelationId(): string;
|
|
1507
2940
|
|
|
1508
2941
|
/**
|
|
1509
2942
|
* ValidationError class for request validation failures
|
|
@@ -1822,6 +3255,7 @@ declare class UnprocessableEntityError extends BlaizeError {
|
|
|
1822
3255
|
declare const VERSION = "0.1.0";
|
|
1823
3256
|
declare const ServerAPI: {
|
|
1824
3257
|
createServer: typeof create;
|
|
3258
|
+
inferContext: typeof inferContext;
|
|
1825
3259
|
};
|
|
1826
3260
|
declare const RouterAPI: {
|
|
1827
3261
|
createDeleteRoute: CreateDeleteRoute;
|
|
@@ -1831,9 +3265,12 @@ declare const RouterAPI: {
|
|
|
1831
3265
|
createPatchRoute: CreatePatchRoute;
|
|
1832
3266
|
createPostRoute: CreatePostRoute;
|
|
1833
3267
|
createPutRoute: CreatePutRoute;
|
|
3268
|
+
createRouteFactory: typeof createRouteFactory;
|
|
1834
3269
|
};
|
|
1835
3270
|
declare const MiddlewareAPI: {
|
|
1836
3271
|
createMiddleware: typeof create$2;
|
|
3272
|
+
createServiceMiddleware: typeof serviceMiddleware;
|
|
3273
|
+
createStateMiddleware: typeof stateMiddleware;
|
|
1837
3274
|
compose: typeof compose;
|
|
1838
3275
|
};
|
|
1839
3276
|
declare const PluginsAPI: {
|
|
@@ -1843,9 +3280,13 @@ declare const PluginsAPI: {
|
|
|
1843
3280
|
declare const Blaize: {
|
|
1844
3281
|
createServer: typeof create;
|
|
1845
3282
|
createMiddleware: typeof create$2;
|
|
3283
|
+
createServiceMiddleware: typeof serviceMiddleware;
|
|
3284
|
+
createStateMiddleware: typeof stateMiddleware;
|
|
1846
3285
|
createPlugin: typeof create$1;
|
|
3286
|
+
getCorrelationId: typeof getCorrelationId;
|
|
1847
3287
|
Server: {
|
|
1848
3288
|
createServer: typeof create;
|
|
3289
|
+
inferContext: typeof inferContext;
|
|
1849
3290
|
};
|
|
1850
3291
|
Router: {
|
|
1851
3292
|
createDeleteRoute: CreateDeleteRoute;
|
|
@@ -1855,9 +3296,12 @@ declare const Blaize: {
|
|
|
1855
3296
|
createPatchRoute: CreatePatchRoute;
|
|
1856
3297
|
createPostRoute: CreatePostRoute;
|
|
1857
3298
|
createPutRoute: CreatePutRoute;
|
|
3299
|
+
createRouteFactory: typeof createRouteFactory;
|
|
1858
3300
|
};
|
|
1859
3301
|
Middleware: {
|
|
1860
3302
|
createMiddleware: typeof create$2;
|
|
3303
|
+
createServiceMiddleware: typeof serviceMiddleware;
|
|
3304
|
+
createStateMiddleware: typeof stateMiddleware;
|
|
1861
3305
|
compose: typeof compose;
|
|
1862
3306
|
};
|
|
1863
3307
|
Plugins: {
|
|
@@ -1866,4 +3310,4 @@ declare const Blaize: {
|
|
|
1866
3310
|
VERSION: string;
|
|
1867
3311
|
};
|
|
1868
3312
|
|
|
1869
|
-
export { Blaize, BlaizeError, type BlaizeErrorResponse, type BodyParseError, type BuildRoutesRegistry, type ClientConfig, ConflictError, type ConflictErrorDetails, type Context, type ContextOptions, type ContextRequest, type ContextResponse, type CreateClient, type CreateContextFn, type CreateDeleteRoute, type CreateGetRoute, type CreateHeadRoute, type CreateOptionsRoute, type CreatePatchRoute, type CreatePostRoute, type CreatePutRoute, type ErrorHandlerOptions, ErrorSeverity, type ErrorTransformContext, ErrorType, type ExtractMethod, type FileCache, type FindRouteFilesOptions, ForbiddenError, type ForbiddenErrorDetails, type GetContextFn, type Http2Options, type HttpMethod, type Infer, type InternalRequestArgs, InternalServerError, type InternalServerErrorDetails, type Matcher, type Middleware, MiddlewareAPI, type MiddlewareFunction, type MiddlewareOptions, type MultipartData, type MultipartError, type MultipartLimits, type NetworkErrorContext, type NextFunction, NotFoundError, type NotFoundErrorDetails, type ParseErrorContext, type ParseOptions, type ParseResult, type ParsedRoute, type ParserState, PayloadTooLargeError, type PayloadTooLargeErrorDetails, type Plugin, type PluginFactory, type PluginHooks, type PluginLifecycleManager, type PluginLifecycleOptions, type PluginOptions, PluginsAPI, type ProcessResponseOptions, type ProcessingConfig, type QueryParams, RateLimitError, type RateLimitErrorDetails, type ReloadMetrics, type RequestHandler, type RequestOptions, type RequestParams, RequestTimeoutError, type Result, type Route, type RouteDefinition, type RouteEntry, type RouteHandler, type RouteMatch, type RouteMethodOptions, type RouteNode, type RouteOptions, type RouteRegistry, type RouteSchema, type Router, RouterAPI, type RouterOptions, type Server, ServerAPI, type ServerOptions, type ServerOptionsInput, type StandardErrorResponse, type StartOptions, type State, type StopOptions, type StreamOptions, type TimeoutErrorContext, UnauthorizedError, type UnauthorizedErrorDetails, type UnifiedRequest, type UnifiedResponse, type UnknownFunction, UnprocessableEntityError, UnsupportedMediaTypeError, type UnsupportedMediaTypeErrorDetails, type UploadProgress, type UploadedFile, VERSION, type ValidationConfig, ValidationError, type ValidationErrorDetails, type ValidationFieldError, type WatchOptions, compose, createDeleteRoute, createGetRoute, createHeadRoute, create$2 as createMiddleware, createOptionsRoute, createPatchRoute, create$1 as createPlugin, createPostRoute, createPutRoute, create as createServer, isBodyParseError };
|
|
3313
|
+
export { Blaize, BlaizeError, type BlaizeErrorResponse, type BodyParseError, type BufferedEvent, type BuildRoutesRegistry, type BuildSSEArgs, type CacheConfig, type CacheEntry, type ClientConfig, type CloseEvent, type ComposeMiddlewareServices, type ComposeMiddlewareStates, type ComposeMiddlewareTypes, type ComposePluginServices, type ComposePluginStates, type ComposePluginTypes, ConflictError, type ConflictErrorDetails, type ConnectionEntry, type ConnectionRegistry, type Context, type ContextOptions, type ContextRequest, type ContextResponse, type CorrelationOptions, type CorsHttpMethod, type CorsOptions, type CorsOrigin, type CorsOriginCacheConfig, type CorsOriginCacheEntry, type CorsPreflightInfo, type CorsStats, type CorsValidationResult, type CreateClient, type CreateContextFn, type CreateDeleteRoute, type CreateEnhancedClient, type CreateGetRoute, type CreateHeadRoute, type CreateOptionsRoute, type CreatePatchRoute, type CreatePostRoute, type CreatePutRoute, type CreateSSEMethod, type CreateSSERoute, type ErrorHandlerOptions, ErrorSeverity, type ErrorTransformContext, ErrorType, type EventHandlers, type ExtractMethod, type ExtractMiddlewareServices, type ExtractMiddlewareState, type ExtractMiddlewareTypes, type ExtractPluginServices, type ExtractPluginState, type ExtractPluginTypes, type ExtractSSEEvents, type ExtractSSEParams, type ExtractSSEQuery, type ExtractSSERoutes, type FileCache, type FindRouteFilesOptions, ForbiddenError, type ForbiddenErrorDetails, type GetContextFn, type HasSSEMethod, type Http2Options, type HttpMethod, type Infer, type InferContext, type InternalRequestArgs, InternalServerError, type InternalServerErrorDetails, type Matcher, type MergeServices, type MergeStates, type Middleware, MiddlewareAPI, type MiddlewareFunction, type MiddlewareOptions, type MultipartData, type MultipartError, type MultipartLimits, type NetworkErrorContext, type NextFunction, NotFoundError, type NotFoundErrorDetails, type ParseErrorContext, type ParseOptions, type ParseResult, type ParsedRoute, type ParserState, PayloadTooLargeError, type PayloadTooLargeErrorDetails, type Plugin, type PluginFactory, type PluginHooks, type PluginLifecycleManager, type PluginLifecycleOptions, type PluginOptions, PluginsAPI, type ProcessResponseOptions, type ProcessingConfig, type QueryParams, RateLimitError, type RateLimitErrorDetails, type ReconnectStrategy, type RegistryResult, type ReloadMetrics, type RequestHandler, type RequestOptions, type RequestParams, RequestTimeoutError, type Result, type Route, type RouteDefinition, type RouteEntry, type RouteHandler, type RouteMatch, type RouteMethodOptions, type RouteNode, type RouteOptions, type RouteRegistry, type RouteSchema, type Router, RouterAPI, type RouterOptions, type SSEBufferOverflowErrorDetails, type SSEBufferStrategy, type SSEClient, type SSEClientMetrics, type SSEClientOptions, type SSEConnectionErrorContext, type SSEConnectionErrorDetails, type SSEConnectionFactory, type SSEConnectionState, type SSEEvent, type SSEEventHandler, type SSEEventListener, type SSEHeartbeatErrorContext, type SSEMetrics, type SSEOptions, type SSERouteHandler, type SSERouteSchema, type SSESerializedEvent, type SSEStream, type SSEStreamClosedErrorDetails, type SSEStreamErrorContext, type SSEStreamExtended, type SSEStreamManager, type SafeComposeMiddlewareServices, type SafeComposeMiddlewareStates, type SafeComposePluginServices, type SafeComposePluginStates, type SafeExtractMiddlewareServices, type SafeExtractMiddlewareState, type SafeExtractPluginServices, type SafeExtractPluginState, type Server, ServerAPI, type ServerOptions, type ServerOptionsInput, type Services, type StandardErrorResponse, type StartOptions, type State, type StopOptions, type StreamMetrics, type StreamOptions, type TimeoutErrorContext, type TypedSSEStream, UnauthorizedError, type UnauthorizedErrorDetails, type UnifiedRequest, type UnifiedResponse, type UnionToIntersection, type UnknownFunction, type UnknownServer, UnprocessableEntityError, UnsupportedMediaTypeError, type UnsupportedMediaTypeErrorDetails, type UploadProgress, type UploadedFile, VERSION, type ValidationConfig, ValidationError, type ValidationErrorDetails, type ValidationFieldError, type WatchOptions, asMiddlewareArray, asPluginArray, compose, createDeleteRoute, createGetRoute, createHeadRoute, create$2 as createMiddleware, createMiddlewareArray, createOptionsRoute, createPatchRoute, create$1 as createPlugin, createPluginArray, createPostRoute, createPutRoute, createRouteFactory, create as createServer, serviceMiddleware as createServiceMiddleware, stateMiddleware as createStateMiddleware, getCorrelationId, inferContext, isBodyParseError, isMiddleware, isPlugin };
|